def snapshot_userstories_in_bulk(bulk_data, user): for us_data in bulk_data: try: us = models.UserStory.objects.get(pk=us_data['us_id']) take_snapshot(us, user=user) except models.UserStory.DoesNotExist: pass
def test_assigned_to_user_story_timeline(): membership = factories.MembershipFactory.create() user_story = factories.UserStoryFactory.create(subject="test us timeline", assigned_to=membership.user, project=membership.project) history_services.take_snapshot(user_story, user=user_story.owner) user_timeline = service.get_profile_timeline(user_story.assigned_to) assert user_timeline[0].event_type == "userstories.userstory.create" assert user_timeline[0].data["userstory"]["subject"] == "test us timeline"
def test_create_project_timeline(): project = factories.ProjectFactory.create(name="test project timeline") history_services.take_snapshot(project, user=project.owner) project_timeline = service.get_project_timeline(project) assert project_timeline[0].event_type == "projects.project.create" assert project_timeline[0].data["project"]["name"] == "test project timeline" assert project_timeline[0].data["user"]["id"] == project.owner.id
def create_task(self, project, milestone, us, min_date, max_date, closed=False): task = Task(subject=self.sd.choice(SUBJECT_CHOICES), description=self.sd.paragraph(), project=project, owner=self.sd.db_object_from_queryset(project.memberships.filter(user__isnull=False)).user, milestone=milestone, user_story=us, finished_date=None, assigned_to = self.sd.db_object_from_queryset( project.memberships.filter(user__isnull=False)).user, tags=self.sd.words(1, 10).split(" ")) if closed: task.status = project.task_statuses.get(order=4) else: task.status = self.sd.db_object_from_queryset(project.task_statuses.all()) if task.status.is_closed: task.finished_date = self.sd.datetime_between(min_date, max_date) task.save() for i in range(self.sd.int(*NUM_ATTACHMENTS)): attachment = self.create_attachment(task, i+1) take_snapshot(task, comment=self.sd.paragraph(), user=task.owner) return task
def store_wiki_page(project, wiki_page): wiki_page["slug"] = slugify(unidecode(wiki_page.get("slug", ""))) validator = validators.WikiPageExportValidator(data=wiki_page) if validator.is_valid(): validator.object.project = project if validator.object.owner is None: validator.object.owner = validator.object.project.owner validator.object._importing = True validator.object._not_notify = True validator.save() validator.save_watchers() for attachment in wiki_page.get("attachments", []): _store_attachment(project, validator.object, attachment) history_entries = wiki_page.get("history", []) for history in history_entries: _store_history(project, validator.object, history) if not history_entries: take_snapshot(validator.object, user=validator.object.owner) return validator add_errors("wiki_pages", validator.errors) return None
def test_webhooks_when_update_assigned_users_user_story(settings): settings.WEBHOOKS_ENABLED = True project = f.ProjectFactory() f.WebhookFactory.create(project=project) f.WebhookFactory.create(project=project) obj = f.UserStoryFactory.create(project=project) with patch('taiga.webhooks.tasks._send_request') as send_request_mock: services.take_snapshot(obj, user=obj.owner) assert send_request_mock.call_count == 2 user = f.create_user() obj.assigned_users.add(user) obj.save() with patch('taiga.webhooks.tasks._send_request') as send_request_mock: services.take_snapshot(obj, user=obj.owner,) assert send_request_mock.call_count == 2 (webhook_id, url, key, data) = send_request_mock.call_args[0] assert data["action"] == "change" assert data["type"] == "userstory" assert data["by"]["id"] == obj.owner.id assert len(data["data"]["assigned_users"]) == \ obj.assigned_users.count() assert data["data"]["assigned_users"] == [user.id] assert not data["change"]["diff"]["assigned_users"]["from"] assert data["change"]["diff"]["assigned_users"]["to"] == user.username
def test_create_user_story_timeline(): user_story = factories.UserStoryFactory.create(subject="test us timeline") history_services.take_snapshot(user_story, user=user_story.owner) project_timeline = service.get_project_timeline(user_story.project) assert project_timeline[0].event_type == "userstories.userstory.create" assert project_timeline[0].data["userstory"]["subject"] == "test us timeline" assert project_timeline[0].data["user"]["id"] == user_story.owner.id
def test_push_event_user_story_mention(client): creation_status = f.UserStoryStatusFactory() role = f.RoleFactory(project=creation_status.project, permissions=["view_us"]) f.MembershipFactory(project=creation_status.project, role=role, user=creation_status.project.owner) user_story = f.UserStoryFactory.create( status=creation_status, project=creation_status.project, owner=creation_status.project.owner ) take_snapshot(user_story, user=creation_status.project.owner) payload = { "commits": [ { "message": """test message test TG-%s ok bye! """ % (user_story.ref) } ] } mail.outbox = [] ev_hook = event_hooks.PushEventHook(user_story.project, payload) ev_hook.process_event() us_history = get_history_queryset_by_model_instance(user_story) assert us_history.count() == 1 assert us_history[0].comment.startswith("This user story has been mentioned by") assert len(mail.outbox) == 1
def test_push_event_user_story_mention(client): creation_status = f.UserStoryStatusFactory() role = f.RoleFactory(project=creation_status.project, permissions=["view_us"]) f.MembershipFactory(project=creation_status.project, role=role, user=creation_status.project.owner) user_story = f.UserStoryFactory.create( status=creation_status, project=creation_status.project, owner=creation_status.project.owner ) take_snapshot(user_story, user=creation_status.project.owner) payload = { "actor": { "user": { "uuid": "{ce1054cd-3f43-49dc-8aea-d3085ee7ec9b}", "username": "******", "links": {"html": {"href": "http://bitbucket.com/test-user"}}, } }, "push": {"changes": [{"commits": [{"message": "test message test TG-%s ok bye!" % (user_story.ref)}]}]}, } mail.outbox = [] ev_hook = event_hooks.PushEventHook(user_story.project, payload) ev_hook.process_event() us_history = get_history_queryset_by_model_instance(user_story) assert us_history.count() == 1 assert us_history[0].comment.startswith("This user story has been mentioned by") assert len(mail.outbox) == 1
def test_create_task_timeline(): task = factories.TaskFactory.create(subject="test task timeline") history_services.take_snapshot(task, user=task.owner) project_timeline = service.get_project_timeline(task.project) assert project_timeline[0].event_type == "tasks.task.create" assert project_timeline[0].data["task"]["subject"] == "test task timeline" assert project_timeline[0].data["user"]["id"] == task.owner.id
def process_event(self): if self.ignore(): return data = self.get_data() if not all([data['subject'], data['url']]): raise ActionSyntaxException(_("Invalid issue information")) user = self.get_user(data['user_id'], self.platform_slug) issue = Issue.objects.create( project=self.project, subject=data['subject'], description=data['description'], status=self.project.default_issue_status, type=self.project.default_issue_type, severity=self.project.default_severity, priority=self.project.default_priority, external_reference=[self.platform_slug, data['url']], owner=user ) take_snapshot(issue, user=user) comment = self.generate_new_issue_comment(**data) snapshot = take_snapshot(issue, comment=comment, user=user) send_notifications(issue, history=snapshot)
def process_event(self): if self.payload.get('object_attributes', {}).get("action", "") != "open": return subject = self.payload.get('object_attributes', {}).get('title', None) description = self.payload.get('object_attributes', {}).get('description', None) gitlab_reference = self.payload.get('object_attributes', {}).get('url', None) project_url = None if gitlab_reference: project_url = os.path.basename(os.path.basename(gitlab_reference)) if not all([subject, gitlab_reference, project_url]): raise ActionSyntaxException(_("Invalid issue information")) issue = Issue.objects.create( project=self.project, subject=subject, description=replace_gitlab_references(project_url, description), status=self.project.default_issue_status, type=self.project.default_issue_type, severity=self.project.default_severity, priority=self.project.default_priority, external_reference=['gitlab', gitlab_reference], owner=get_gitlab_user(None) ) take_snapshot(issue, user=get_gitlab_user(None)) snapshot = take_snapshot(issue, comment=_("Created from GitLab"), user=get_gitlab_user(None)) send_notifications(issue, history=snapshot)
def create_project(self, counter, is_private=None): if is_private is None: is_private=self.sd.boolean() anon_permissions = not is_private and list(map(lambda perm: perm[0], ANON_PERMISSIONS)) or [] public_permissions = not is_private and list(map(lambda perm: perm[0], ANON_PERMISSIONS)) or [] project = Project.objects.create(slug='project-%s'%(counter), name='Project Example {0}'.format(counter), description='Project example {0} description'.format(counter), owner=random.choice(self.users), is_private=is_private, anon_permissions=anon_permissions, public_permissions=public_permissions, total_story_points=self.sd.int(600, 3000), total_milestones=self.sd.int(5,10), tags=self.sd.words(1, 10).split(" ")) project.is_kanban_activated = True project.save() take_snapshot(project, user=project.owner) self.create_likes(project) self.create_watchers(project, NotifyLevel.involved) return project
def test_issues_event_bad_comment(client): issue = f.IssueFactory.create(external_reference=["bitbucket", "10"]) take_snapshot(issue, user=issue.owner) payload = { "actor": { "user": { "uuid": "{ce1054cd-3f43-49dc-8aea-d3085ee7ec9b}", "username": "******", "links": {"html": {"href": "http://bitbucket.com/test-user"}} } }, "issue": { "id": "10", "title": "test-title", "links": {"html": {"href": "http://bitbucket.com/site/master/issue/10"}}, "content": {"raw": "test-content"} }, "comment": { }, "repository": { "links": {"html": {"href": "http://bitbucket.com/test-user/test-project"}} } } ev_hook = event_hooks.IssueCommentEventHook(issue.project, payload) mail.outbox = [] with pytest.raises(ActionSyntaxException) as excinfo: ev_hook.process_event() assert str(excinfo.value) == "Invalid issue comment information" assert Issue.objects.count() == 1 assert len(mail.outbox) == 0
def snapshot_tasks_in_bulk(bulk_data, user): for task_data in bulk_data: try: task = models.Task.objects.get(pk=task_data['task_id']) take_snapshot(task, user=user) except models.Task.DoesNotExist: pass
def snapshot_issues_in_bulk(bulk_data, user): for issue_data in bulk_data: try: issue = models.Issue.objects.get(pk=issue_data['issue_id']) take_snapshot(issue, user=user) except models.Issue.DoesNotExist: pass
def test_webhooks_when_update_task(settings): settings.WEBHOOKS_ENABLED = True project = f.ProjectFactory() f.WebhookFactory.create(project=project) f.WebhookFactory.create(project=project) obj = f.TaskFactory.create(project=project) with patch("taiga.webhooks.tasks._send_request") as send_request_mock: services.take_snapshot(obj, user=obj.owner) assert send_request_mock.call_count == 2 obj.subject = "test webhook update" obj.save() with patch("taiga.webhooks.tasks._send_request") as send_request_mock: services.take_snapshot(obj, user=obj.owner, comment="test_comment") assert send_request_mock.call_count == 2 (webhook_id, url, key, data) = send_request_mock.call_args[0] assert data["action"] == "change" assert data["type"] == "task" assert data["by"]["id"] == obj.owner.id assert "date" in data assert data["data"]["id"] == obj.id assert data["data"]["subject"] == obj.subject assert data["change"]["comment"] == "test_comment" assert data["change"]["diff"]["subject"]["to"] == data["data"]["subject"] assert data["change"]["diff"]["subject"]["from"] != data["data"]["subject"]
def create_us(self, project, milestone=None, computable_project_roles=list(Role.objects.all())): us = UserStory.objects.create(subject=self.sd.choice(SUBJECT_CHOICES), project=project, owner=self.sd.db_object_from_queryset( project.memberships.filter(user__isnull=False)).user, description=self.sd.paragraph(), milestone=milestone, status=self.sd.db_object_from_queryset(project.us_statuses.filter( is_closed=False)), tags=self.sd.words(1, 3).split(" ")) for role_points in us.role_points.filter(role__in=computable_project_roles): if milestone: role_points.points = self.sd.db_object_from_queryset( us.project.points.exclude(value=None)) else: role_points.points = self.sd.db_object_from_queryset( us.project.points.all()) role_points.save() for i in range(self.sd.int(*NUM_ATTACHMENTS)): attachment = self.create_attachment(us, i+1) if self.sd.choice([True, True, False, True, True]): us.assigned_to = self.sd.db_object_from_queryset(project.memberships.filter(user__isnull=False)).user us.save() take_snapshot(us, comment=self.sd.paragraph(), user=us.owner) return us
def test_issues_event_bad_comment(client): issue = f.IssueFactory.create(external_reference=["gitlab", "10"]) take_snapshot(issue, user=issue.owner) payload = { "user": { "username": "******" }, "issue": { "iid": "10", "title": "test-title", }, "object_attributes": { "noteable_type": "Issue", }, "repository": { "homepage": "test", }, } ev_hook = event_hooks.IssueCommentEventHook(issue.project, payload) mail.outbox = [] with pytest.raises(ActionSyntaxException) as excinfo: ev_hook.process_event() assert str(excinfo.value) == "Invalid issue comment information" assert Issue.objects.count() == 1 assert len(mail.outbox) == 0
def test_create_wiki_page_timeline(): page = factories.WikiPageFactory.create(slug="test wiki page timeline") history_services.take_snapshot(page, user=page.owner) project_timeline = service.get_project_timeline(page.project) assert project_timeline[0].event_type == "wiki.wikipage.create" assert project_timeline[0].data["wikipage"]["slug"] == "test wiki page timeline" assert project_timeline[0].data["user"]["id"] == page.owner.id
def _import_user_stories_data(self, project, repo, options): users_bindings = options.get('users_bindings', {}) page = 1 while True: issues = self._client.get("/repos/{}/issues".format(repo['full_name']), { "state": "all", "sort": "created", "direction": "asc", "page": page, "per_page": 100 }) page += 1 for issue in issues: tags = [] for label in issue['labels']: tags.append(label['name'].lower()) assigned_to = users_bindings.get(issue['assignee']['id'] if issue['assignee'] else None, None) external_reference = None if options.get('keep_external_reference', False): external_reference = ["github", issue['html_url']] us = UserStory.objects.create( ref=issue['number'], project=project, owner=users_bindings.get(issue['user']['id'], self._user), milestone=project.milestones.get(name=issue['milestone']['title']) if issue['milestone'] else None, assigned_to=assigned_to, status=project.us_statuses.get(slug=issue['state']), kanban_order=issue['number'], sprint_order=issue['number'], backlog_order=issue['number'], subject=issue['title'], description=issue.get("body", "") or "", tags=tags, external_reference=external_reference, modified_date=issue['updated_at'], created_date=issue['created_at'], ) assignees = issue.get('assignees', []) if len(assignees) > 1: for assignee in assignees: if assignee['id'] != issue.get('assignee', {}).get('id', None): assignee_user = users_bindings.get(assignee['id'], None) if assignee_user is not None: us.add_watcher(assignee_user) UserStory.objects.filter(id=us.id).update( ref=issue['number'], modified_date=issue['updated_at'], created_date=issue['created_at'] ) take_snapshot(us, comment="", user=None, delete=False) if len(issues) < 100: break
def test_send_request_one_webhook_signal(settings): settings.WEBHOOKS_ENABLED = True project = f.ProjectFactory() f.WebhookFactory.create(project=project) objects = [ f.IssueFactory.create(project=project), f.TaskFactory.create(project=project), f.UserStoryFactory.create(project=project), f.WikiPageFactory.create(project=project) ] response = Mock(status_code=200, headers={}, text="ok") response.elapsed.total_seconds.return_value = 100 for obj in objects: with patch("taiga.webhooks.tasks.requests.Session.send", return_value=response) as session_send_mock, \ patch("taiga.base.utils.urls.validate_private_url", return_value=True): services.take_snapshot(obj, user=obj.owner, comment="test") assert session_send_mock.call_count == 1 for obj in objects: with patch("taiga.webhooks.tasks.requests.Session.send", return_value=response) as session_send_mock, \ patch("taiga.base.utils.urls.validate_private_url", return_value=True): services.take_snapshot(obj, user=obj.owner, comment="test", delete=True) assert session_send_mock.call_count == 1
def _process_opened(self, number, subject, github_url, user, github_user_name, github_user_url, project_url, description): issue = Issue.objects.create( project=self.project, subject=subject, description=description, status=self.project.default_issue_status, type=self.project.default_issue_type, severity=self.project.default_severity, priority=self.project.default_priority, external_reference=['github', github_url], owner=user ) take_snapshot(issue, user=user) if number and subject and github_user_name and github_user_url: comment = _("Issue created by [@{github_user_name}]({github_user_url} " "\"See @{github_user_name}'s GitHub profile\") " "from GitHub.\nOrigin GitHub issue: [gh#{number} - {subject}]({github_url} " "\"Go to 'gh#{number} - {subject}'\"):\n\n" "{description}").format(github_user_name=github_user_name, github_user_url=github_user_url, number=number, subject=subject, github_url=github_url, description=description) else: comment = _("Issue created from GitHub.") snapshot = take_snapshot(issue, comment=comment, user=user) send_notifications(issue, history=snapshot)
def test_create_issue_timeline(): issue = factories.IssueFactory.create(subject="test issue timeline") history_services.take_snapshot(issue, user=issue.owner) project_timeline = service.get_project_timeline(issue.project) assert project_timeline[0].event_type == "issues.issue.create" assert project_timeline[0].data["issue"]["subject"] == "test issue timeline" assert project_timeline[0].data["user"]["id"] == issue.owner.id
def store_wiki_page(project, wiki_page): wiki_page["slug"] = slugify(unidecode(wiki_page.get("slug", ""))) serialized = serializers.WikiPageExportSerializer(data=wiki_page) if serialized.is_valid(): serialized.object.project = project if serialized.object.owner is None: serialized.object.owner = serialized.object.project.owner serialized.object._importing = True serialized.object._not_notify = True serialized.save() serialized.save_watchers() for attachment in wiki_page.get("attachments", []): store_attachment(project, serialized.object, attachment) history_entries = wiki_page.get("history", []) for history in history_entries: store_history(project, serialized.object, history) if not history_entries: take_snapshot(serialized.object, user=serialized.object.owner) return serialized add_errors("wiki_pages", serialized.errors) return None
def test_create_milestone_timeline(): milestone = factories.MilestoneFactory.create(name="test milestone timeline") history_services.take_snapshot(milestone, user=milestone.owner) milestone_timeline = service.get_project_timeline(milestone.project) assert milestone_timeline[0].event_type == "milestones.milestone.create" assert milestone_timeline[0].data["milestone"]["name"] == "test milestone timeline" assert milestone_timeline[0].data["user"]["id"] == milestone.owner.id
def test_webhooks_when_update_epic_related_userstory(settings): settings.WEBHOOKS_ENABLED = True project = f.ProjectFactory() f.WebhookFactory.create(project=project) f.WebhookFactory.create(project=project) epic = f.EpicFactory.create(project=project) obj = f.RelatedUserStory.create(epic=epic, order=33) with patch('taiga.webhooks.tasks._send_request') as send_request_mock: services.take_snapshot(obj, user=epic.owner) assert send_request_mock.call_count == 2 obj.order = 66 obj.save() with patch('taiga.webhooks.tasks._send_request') as send_request_mock: services.take_snapshot(obj, user=epic.owner) assert send_request_mock.call_count == 2 (webhook_id, url, key, data) = send_request_mock.call_args[0] assert data["action"] == "change" assert data["type"] == "relateduserstory" assert data["by"]["id"] == epic.owner.id assert "date" in data assert data["data"]["id"] == obj.id assert data["data"]["order"] == obj.order assert data["change"]["diff"]["order"]["to"] == 66 assert data["change"]["diff"]["order"]["from"] == 33
def create_project(self, counter, is_private=None, blocked_code=None): if is_private is None: is_private=self.sd.boolean() anon_permissions = not is_private and list(map(lambda perm: perm[0], ANON_PERMISSIONS)) or [] public_permissions = not is_private and list(map(lambda perm: perm[0], ANON_PERMISSIONS)) or [] project = Project.objects.create(slug='project-%s'%(counter), name='Project Example {0}'.format(counter), description='Project example {0} description'.format(counter), owner=self.sd.choice(self.users), is_private=is_private, anon_permissions=anon_permissions, public_permissions=public_permissions, total_story_points=self.sd.int(600, 3000), total_milestones=self.sd.int(5,10), tags=self.sd.words(1, 10).split(" "), blocked_code=blocked_code) project.is_looking_for_people = counter in LOOKING_FOR_PEOPLE_PROJECTS_POSITIONS if project.is_looking_for_people: project.looking_for_people_note = self.sd.short_sentence() project.is_featured = counter in FEATURED_PROJECTS_POSITIONS project.is_kanban_activated = True project.is_epics_activated = True project.save() take_snapshot(project, user=project.owner) self.create_likes(project) self.create_watchers(project, NotifyLevel.involved) return project
def create_bug(self, project): bug = Issue.objects.create(project=project, subject=self.sd.choice(SUBJECT_CHOICES), description=self.sd.paragraph(), owner=self.sd.db_object_from_queryset( project.memberships.filter(user__isnull=False)).user, severity=self.sd.db_object_from_queryset(Severity.objects.filter( project=project)), status=self.sd.db_object_from_queryset(IssueStatus.objects.filter( project=project)), priority=self.sd.db_object_from_queryset(Priority.objects.filter( project=project)), type=self.sd.db_object_from_queryset(IssueType.objects.filter( project=project)), tags=self.sd.words(1, 10).split(" ")) for i in range(self.sd.int(*NUM_ATTACHMENTS)): attachment = self.create_attachment(bug, i+1) if bug.status.order != 1: bug.assigned_to = self.sd.db_object_from_queryset(project.memberships.filter( user__isnull=False)).user bug.save() take_snapshot(bug, comment=self.sd.paragraph(), user=bug.owner) return bug
def test_not_send_notifications_on_unassigned_if_executer_and_unassigned_match(client, mail): project = f.ProjectFactory.create() role = f.RoleFactory.create(project=project, permissions=['modify_issue', 'view_issues', 'view_us', 'view_tasks', 'view_wiki_pages']) member1 = f.MembershipFactory.create(project=project, role=role) member2 = f.MembershipFactory.create(project=project, role=role) issue = f.IssueFactory.create(project=project, owner=member1.user, milestone=None, status=project.default_issue_status, severity=project.default_severity, priority=project.default_priority, type=project.default_issue_type) take_snapshot(issue, user=issue.owner) client.login(member1.user) url = reverse("issues-detail", args=[issue.pk]) data = { "assigned_to": member1.user.id, "version": issue.version } response = client.json.patch(url, json.dumps(data)) assert len(mail.outbox) == 0 mail.outbox = [] data = { "assigned_to": None, "version": issue.version + 1 } response = client.json.patch(url, json.dumps(data)) assert len(mail.outbox) == 0
def create_wiki_page(self, project, slug): wiki_page = WikiPage.objects.create( project=project, slug=slug, content=self.sd.paragraphs(3, 15), owner=self.sd.db_object_from_queryset( project.memberships.filter(user__isnull=False)).user) for i in range(self.sd.int(*NUM_ATTACHMENTS)): attachment = self.create_attachment(wiki_page, i + 1) take_snapshot(wiki_page, user=wiki_page.owner) # Add history entry wiki_page.content = self.sd.paragraphs(3, 15) wiki_page.save() take_snapshot(wiki_page, comment=self.sd.paragraph(), user=wiki_page.owner) return wiki_page
def _import_history(self, obj, task, options): users_bindings = options.get('users_bindings', {}) stories = self._client.stories.find_by_task(task['id']) for story in stories: if story['type'] == "comment": snapshot = take_snapshot( obj, comment=story['text'], user=users_bindings.get(story['created_by']['id'], User(full_name=story['created_by']['name'])), delete=False ) HistoryEntry.objects.filter(id=snapshot.id).update(created_at=story['created_at'])
def create_us(self, project, milestone=None, computable_project_roles=[]): us = UserStory.objects.create( subject=self.sd.choice(SUBJECT_CHOICES), project=project, owner=self.sd.db_object_from_queryset( project.memberships.filter(user__isnull=False)).user, description=self.sd.paragraph(), milestone=milestone, status=self.sd.db_object_from_queryset( project.us_statuses.filter(is_closed=False)), tags=self.sd.words(1, 3).split(" ")) for role_points in us.role_points.filter( role__in=computable_project_roles): if milestone: role_points.points = self.sd.db_object_from_queryset( us.project.points.exclude(value=None)) else: role_points.points = self.sd.db_object_from_queryset( us.project.points.all()) role_points.save() for i in range(self.sd.int(*NUM_ATTACHMENTS)): attachment = self.create_attachment(us, i + 1) if self.sd.choice([True, True, False, True, True]): us.assigned_to = self.sd.db_object_from_queryset( project.memberships.filter(user__isnull=False)).user us.save() take_snapshot(us, comment=self.sd.paragraph(), user=us.owner) # Add history entry us.status = self.sd.db_object_from_queryset( project.us_statuses.filter(is_closed=False)) us.save() take_snapshot(us, comment=self.sd.paragraph(), user=us.owner) return us
def test_issue_comment_event_on_not_existing_issue_task_and_us(client): issue = f.IssueFactory.create(external_reference=["gitlab", "10"]) take_snapshot(issue, user=issue.owner) task = f.TaskFactory.create(project=issue.project, external_reference=["gitlab", "10"]) take_snapshot(task, user=task.owner) us = f.UserStoryFactory.create(project=issue.project, external_reference=["gitlab", "10"]) take_snapshot(us, user=us.owner) payload = deepcopy(issue_comment_base_payload) payload["user"]["username"] = "******" payload["issue"]["iid"] = "99999" payload["issue"]["title"] = "test-title" payload["object_attributes"]["noteable_type"] = "Issue" payload["object_attributes"]["note"] = "test comment" payload["repository"]["homepage"] = "test" mail.outbox = [] assert get_history_queryset_by_model_instance(issue).count() == 0 assert get_history_queryset_by_model_instance(task).count() == 0 assert get_history_queryset_by_model_instance(us).count() == 0 ev_hook = event_hooks.IssueCommentEventHook(issue.project, payload) ev_hook.process_event() assert get_history_queryset_by_model_instance(issue).count() == 0 assert get_history_queryset_by_model_instance(task).count() == 0 assert get_history_queryset_by_model_instance(us).count() == 0 assert len(mail.outbox) == 0
def duplicate_project(project, **new_project_extra_args): owner = new_project_extra_args.get("owner") users = new_project_extra_args.pop("users") disconnect_projects_signals() Project = apps.get_model("projects", "Project") new_project = Project.objects.create(**new_project_extra_args) connect_projects_signals() permissions_services.set_base_permissions_for_project(new_project) # Cloning the structure from the old project using templates Template = apps.get_model("projects", "ProjectTemplate") template = Template() template.load_data_from_project(project) template.apply_to_project(new_project) new_project.creation_template = project.creation_template new_project.save() # Creating the membership for the new owner Membership = apps.get_model("projects", "Membership") Membership.objects.create( user=owner, is_admin=True, role=new_project.roles.get(slug=template.default_owner_role), project=new_project) # Creating the extra memberships for user in users: project_memberships = project.memberships.exclude(user_id=owner.id) membership = get_object_or_404(project_memberships, user_id=user["id"]) Membership.objects.create( user=membership.user, is_admin=membership.is_admin, role=new_project.roles.get(slug=membership.role.slug), project=new_project) # Take initial snapshot for the project take_snapshot(new_project, user=owner) return new_project
def test_push_event_task_mention(client): creation_status = f.TaskStatusFactory() role = f.RoleFactory(project=creation_status.project, permissions=["view_tasks"]) f.MembershipFactory(project=creation_status.project, role=role, user=creation_status.project.owner) task = f.TaskFactory.create(status=creation_status, project=creation_status.project, owner=creation_status.project.owner) take_snapshot(task, user=creation_status.project.owner) payload = { "actor": { "user": { "uuid": "{ce1054cd-3f43-49dc-8aea-d3085ee7ec9b}", "username": "******", "links": { "html": { "href": "http://bitbucket.com/test-user" } } } }, "push": { "changes": [{ "commits": [{ "message": "test message test TG-%s ok bye!" % (task.ref) }] }] } } mail.outbox = [] ev_hook = event_hooks.PushEventHook(task.project, payload) ev_hook.process_event() task_history = get_history_queryset_by_model_instance(task) assert task_history.count() == 1 assert task_history[0].comment.startswith( "This task has been mentioned by") assert len(mail.outbox) == 1
def test_issue_comment_event_on_not_existing_issue_task_and_us(client): issue = f.IssueFactory.create(external_reference=["github", "10"]) take_snapshot(issue, user=issue.owner) task = f.TaskFactory.create(project=issue.project, external_reference=["github", "10"]) take_snapshot(task, user=task.owner) us = f.UserStoryFactory.create(project=issue.project, external_reference=["github", "10"]) take_snapshot(us, user=us.owner) payload = { "action": "created", "issue": { "html_url": "http://github.com/test/project/issues/11", }, "comment": { "body": "Test body", }, "repository": { "html_url": "test", }, } mail.outbox = [] assert get_history_queryset_by_model_instance(issue).count() == 0 assert get_history_queryset_by_model_instance(task).count() == 0 assert get_history_queryset_by_model_instance(us).count() == 0 ev_hook = event_hooks.IssueCommentEventHook(issue.project, payload) ev_hook.process_event() assert get_history_queryset_by_model_instance(issue).count() == 0 assert get_history_queryset_by_model_instance(task).count() == 0 assert get_history_queryset_by_model_instance(us).count() == 0 assert len(mail.outbox) == 0
def _change_status(self, ref, status_slug, github_user, commit): if Issue.objects.filter(project=self.project, ref=ref).exists(): modelClass = Issue statusClass = IssueStatus elif Task.objects.filter(project=self.project, ref=ref).exists(): modelClass = Task statusClass = TaskStatus elif UserStory.objects.filter(project=self.project, ref=ref).exists(): modelClass = UserStory statusClass = UserStoryStatus else: raise ActionSyntaxException( _("The referenced element doesn't exist")) element = modelClass.objects.get(project=self.project, ref=ref) try: status = statusClass.objects.get(project=self.project, slug=status_slug) except statusClass.DoesNotExist: raise ActionSyntaxException(_("The status doesn't exist")) element.status = status element.save() github_user_id = github_user.get('id', None) github_user_name = github_user.get('login', None) github_user_url = github_user.get('html_url', None) commit_id = commit.get("id", None) commit_url = commit.get("url", None) commit_message = commit.get("message", None) if (github_user_id and github_user_name and github_user_url and commit_id and commit_url and commit_message): comment = _( "Status changed by [@{github_user_name}]({github_user_url} " "\"See @{github_user_name}'s GitHub profile\") " "from GitHub commit [#{commit_id}]({commit_url} " "\"See commit '#{commit_id}: {commit_message}'\").").format( github_user_name=github_user_name, github_user_url=github_user_url, commit_id=commit_id[:7], commit_url=commit_url, commit_message=commit_message) else: comment = _("Status changed from GitHub commit.") snapshot = take_snapshot(element, comment=comment, user=get_github_user(github_user_id)) send_notifications(element, history=snapshot)
def test_assigned_users_user_story_timeline(): membership = factories.MembershipFactory.create() user_story = factories.UserStoryFactory.create(subject="test us timeline", project=membership.project) history_services.take_snapshot(user_story, user=user_story.owner) user_timeline = service.get_profile_timeline(user_story.owner) assert user_timeline[0].event_type == "userstories.userstory.create" assert user_timeline[0].data["userstory"]["subject"] == "test us timeline" user_story.assigned_to = membership.user user_story.assigned_users.set([membership.user]) user_story.save() history_services.take_snapshot(user_story, user=user_story.owner) user_timeline = service.get_profile_timeline(user_story.owner) assert user_timeline[0].event_type == "userstories.userstory.change" assert "assigned_to" not in user_timeline[0].data["values_diff"].keys() assert user_timeline[0].data["values_diff"]['assigned_users'] == \ [None, membership.user.username]
def test_timeline_error_use_member_ids_instead_of_memberships_ids(): user_story = factories.UserStoryFactory.create( subject="test error use member ids instead of " "memberships ids") member_user = user_story.owner external_user = factories.UserFactory.create() membership = factories.MembershipFactory.create(project=user_story.project, user=member_user, id=external_user.id) history_services.take_snapshot(user_story, user=member_user) user_timeline = service.get_profile_timeline(member_user) assert len(user_timeline) == 2 assert user_timeline[0].event_type == "userstories.userstory.create" assert user_timeline[1].event_type == "users.user.create" external_user_timeline = service.get_profile_timeline(external_user) assert len(external_user_timeline) == 1 assert external_user_timeline[0].event_type == "users.user.create"
def process_event(self): if self.payload.get('object_attributes', {}).get( "noteable_type", None) != "Issue": return number = self.payload.get('issue', {}).get('iid', None) subject = self.payload.get('issue', {}).get('title', None) project_url = self.payload.get('repository', {}).get('homepage', None) gitlab_url = os.path.join(project_url, "issues", str(number)) gitlab_user_name = self.payload.get('user', {}).get('username', None) gitlab_user_url = os.path.join( os.path.dirname(os.path.dirname(project_url)), "u", gitlab_user_name) comment_message = self.payload.get('object_attributes', {}).get('note', None) comment_message = replace_gitlab_references(project_url, comment_message) user = get_gitlab_user(None) if not all([comment_message, gitlab_url, project_url]): raise ActionSyntaxException(_("Invalid issue comment information")) issues = Issue.objects.filter( external_reference=["gitlab", gitlab_url]) tasks = Task.objects.filter(external_reference=["gitlab", gitlab_url]) uss = UserStory.objects.filter( external_reference=["gitlab", gitlab_url]) for item in list(issues) + list(tasks) + list(uss): if number and subject and gitlab_user_name and gitlab_user_url: comment = _( "Comment by [@{gitlab_user_name}]({gitlab_user_url} " "\"See @{gitlab_user_name}'s GitLab profile\") " "from GitLab.\nOrigin GitLab issue: [gl#{number} - {subject}]({gitlab_url} " "\"Go to 'gl#{number} - {subject}'\")\n\n" "{message}").format(gitlab_user_name=gitlab_user_name, gitlab_user_url=gitlab_user_url, number=number, subject=subject, gitlab_url=gitlab_url, message=comment_message) else: comment = _("Comment From GitLab:\n\n{message}").format( message=comment_message) snapshot = take_snapshot(item, comment=comment, user=user) send_notifications(item, history=snapshot)
def test_webhooks_when_update_user_story_points(settings): settings.WEBHOOKS_ENABLED = True project = f.ProjectFactory() f.WebhookFactory.create(project=project) f.WebhookFactory.create(project=project) role1 = f.RoleFactory.create(project=project) role2 = f.RoleFactory.create(project=project) points1 = f.PointsFactory.create(project=project, value=None) points2 = f.PointsFactory.create(project=project, value=1) points3 = f.PointsFactory.create(project=project, value=2) obj = f.UserStoryFactory.create(project=project) obj.role_points.all().delete() with patch('taiga.webhooks.tasks._send_request') as send_request_mock: services.take_snapshot(obj, user=obj.owner) assert send_request_mock.call_count == 2 # Set points f.RolePointsFactory.create(user_story=obj, role=role1, points=points1) f.RolePointsFactory.create(user_story=obj, role=role2, points=points2) with patch('taiga.webhooks.tasks._send_request') as send_request_mock: services.take_snapshot(obj, user=obj.owner) assert send_request_mock.call_count == 2 (webhook_id, url, key, data) = send_request_mock.call_args[0] assert data["action"] == "change" assert data["type"] == "userstory" assert data["by"]["id"] == obj.owner.id assert "date" in data assert data["data"]["id"] == obj.id assert data["change"]["comment"] == "" assert data["change"]["diff"]["points"][role1.name]["from"] == None assert data["change"]["diff"]["points"][role1.name]["to"] == points1.name assert data["change"]["diff"]["points"][role2.name]["from"] == None assert data["change"]["diff"]["points"][role2.name]["to"] == points2.name # Change points obj.role_points.all().update(points=points3) with patch('taiga.webhooks.tasks._send_request') as send_request_mock: services.take_snapshot(obj, user=obj.owner) assert send_request_mock.call_count == 2 (webhook_id, url, key, data) = send_request_mock.call_args[0] assert data["action"] == "change" assert data["type"] == "userstory" assert data["by"]["id"] == obj.owner.id assert "date" in data assert data["data"]["id"] == obj.id assert data["change"]["comment"] == "" assert data["change"]["diff"]["points"][role1.name]["from"] == points1.name assert data["change"]["diff"]["points"][role1.name]["to"] == points3.name assert data["change"]["diff"]["points"][role2.name]["from"] == points2.name assert data["change"]["diff"]["points"][role2.name]["to"] == points3.name
def test_issues_event_bad_comment(client): issue = f.IssueFactory.create(external_reference=["github", "10"]) take_snapshot(issue, user=issue.owner) payload = { "action": "created", "issue": {}, "comment": {}, "repository": { "html_url": "test", }, } ev_hook = event_hooks.IssueCommentEventHook(issue.project, payload) mail.outbox = [] with pytest.raises(ActionSyntaxException) as excinfo: ev_hook.process_event() assert str(excinfo.value) == "Invalid issue comment information" assert Issue.objects.count() == 1 assert len(mail.outbox) == 0
def test_issues_event_bad_comment(client): issue = f.IssueFactory.create(external_reference=["gitlab", "10"]) take_snapshot(issue, user=issue.owner) payload = deepcopy(issue_comment_base_payload) payload["user"]["username"] = "******" payload["issue"]["iid"] = "10" payload["issue"]["title"] = "test-title" payload["object_attributes"]["noteable_type"] = "Issue" del payload["object_attributes"]["note"] payload["repository"]["homepage"] = "test" ev_hook = event_hooks.IssueCommentEventHook(issue.project, payload) mail.outbox = [] with pytest.raises(ActionSyntaxException) as excinfo: ev_hook.process_event() assert str(excinfo.value) == "Invalid issue comment information" assert Issue.objects.count() == 1 assert len(mail.outbox) == 0
def test_issue_comment_event_on_existing_issue_task_and_us(client): project = f.ProjectFactory() role = f.RoleFactory(project=project, permissions=["view_tasks", "view_issues", "view_us"]) f.MembershipFactory(project=project, role=role, user=project.owner) user = f.UserFactory() issue = f.IssueFactory.create(external_reference=["bitbucket", "http://bitbucket.com/site/master/issue/11"], owner=project.owner, project=project) take_snapshot(issue, user=user) task = f.TaskFactory.create(external_reference=["bitbucket", "http://bitbucket.com/site/master/issue/11"], owner=project.owner, project=project) take_snapshot(task, user=user) us = f.UserStoryFactory.create(external_reference=["bitbucket", "http://bitbucket.com/site/master/issue/11"], owner=project.owner, project=project) take_snapshot(us, user=user) payload = { "actor": { "user": { "uuid": "{ce1054cd-3f43-49dc-8aea-d3085ee7ec9b}", "username": "******", "links": {"html": {"href": "http://bitbucket.com/test-user"}} } }, "issue": { "id": "11", "title": "test-title", "links": {"html": {"href": "http://bitbucket.com/site/master/issue/11"}}, "content": {"raw": "test-content"} }, "comment": { "content": {"raw": "Test body"}, }, "repository": { "links": {"html": {"href": "http://bitbucket.com/test-user/test-project"}} } } mail.outbox = [] assert get_history_queryset_by_model_instance(issue).count() == 0 assert get_history_queryset_by_model_instance(task).count() == 0 assert get_history_queryset_by_model_instance(us).count() == 0 ev_hook = event_hooks.IssueCommentEventHook(issue.project, payload) ev_hook.process_event() issue_history = get_history_queryset_by_model_instance(issue) assert issue_history.count() == 1 assert "Test body" in issue_history[0].comment task_history = get_history_queryset_by_model_instance(task) assert task_history.count() == 1 assert "Test body" in issue_history[0].comment us_history = get_history_queryset_by_model_instance(us) assert us_history.count() == 1 assert "Test body" in issue_history[0].comment assert len(mail.outbox) == 3
def test_issue_comment_event_on_existing_issue_task_and_us(client): project = f.ProjectFactory() role = f.RoleFactory(project=project, permissions=["view_tasks", "view_issues", "view_us"]) f.MembershipFactory(project=project, role=role, user=project.owner) user = f.UserFactory() issue = f.IssueFactory.create(external_reference=[ "gitlab", "http://gitlab.com/test/project/issues/11" ], owner=project.owner, project=project) take_snapshot(issue, user=user) task = f.TaskFactory.create(external_reference=[ "gitlab", "http://gitlab.com/test/project/issues/11" ], owner=project.owner, project=project) take_snapshot(task, user=user) us = f.UserStoryFactory.create(external_reference=[ "gitlab", "http://gitlab.com/test/project/issues/11" ], owner=project.owner, project=project) take_snapshot(us, user=user) payload = deepcopy(issue_comment_base_payload) payload["user"]["username"] = "******" payload["issue"]["iid"] = "11" payload["issue"]["title"] = "test-title" payload["object_attributes"]["noteable_type"] = "Issue" payload["object_attributes"]["note"] = "Test body" payload["repository"]["homepage"] = "http://gitlab.com/test/project" mail.outbox = [] assert get_history_queryset_by_model_instance(issue).count() == 0 assert get_history_queryset_by_model_instance(task).count() == 0 assert get_history_queryset_by_model_instance(us).count() == 0 ev_hook = event_hooks.IssueCommentEventHook(issue.project, payload) ev_hook.process_event() issue_history = get_history_queryset_by_model_instance(issue) assert issue_history.count() == 1 assert "Test body" in issue_history[0].comment task_history = get_history_queryset_by_model_instance(task) assert task_history.count() == 1 assert "Test body" in issue_history[0].comment us_history = get_history_queryset_by_model_instance(us) assert us_history.count() == 1 assert "Test body" in issue_history[0].comment assert len(mail.outbox) == 3
def test_send_notifications_on_unassigned_and_notifications_are_disabled( client, mail): project = f.ProjectFactory.create() role = f.RoleFactory.create(project=project, permissions=[ 'modify_issue', 'view_issues', 'view_us', 'view_tasks', 'view_wiki_pages' ]) member1 = f.MembershipFactory.create(project=project, role=role) member2 = f.MembershipFactory.create(project=project, role=role) member2_notify_policy = member2.user.notify_policies.get(project=project) member2_notify_policy.notify_level = NotifyLevel.none member2_notify_policy.save() issue = f.IssueFactory.create(project=project, owner=member1.user, milestone=None, status=project.default_issue_status, severity=project.default_severity, priority=project.default_priority, type=project.default_issue_type) take_snapshot(issue, user=issue.owner) client.login(member1.user) url = reverse("issues-detail", args=[issue.pk]) data = {"assigned_to": member2.user.id, "version": issue.version} response = client.json.patch(url, json.dumps(data)) assert len(mail.outbox) == 0 mail.outbox = [] data = {"assigned_to": None, "version": issue.version + 1} response = client.json.patch(url, json.dumps(data)) assert len(mail.outbox) == 0
def test_send_request_one_webhook(settings): settings.WEBHOOKS_ENABLED = True project = f.ProjectFactory() f.WebhookFactory.create(project=project) objects = [ f.IssueFactory.create(project=project), f.TaskFactory.create(project=project), f.UserStoryFactory.create(project=project), f.WikiPageFactory.create(project=project) ] for obj in objects: with patch('taiga.webhooks.tasks._send_request') as _send_request_mock: services.take_snapshot(obj, user=obj.owner, comment="test") assert _send_request_mock.call_count == 1 for obj in objects: with patch('taiga.webhooks.tasks._send_request') as _send_request_mock: services.take_snapshot(obj, user=obj.owner, comment="test", delete=True) assert _send_request_mock.call_count == 1
def test_update_wiki_page_timeline(): user_watcher = factories.UserFactory() page = factories.WikiPageFactory.create(slug="test wiki page timeline") history_services.take_snapshot(page, user=page.owner) page.add_watcher(user_watcher) page.slug = "test wiki page timeline updated" page.save() history_services.take_snapshot(page, user=page.owner) project_timeline = service.get_project_timeline(page.project) assert project_timeline[0].event_type == "wiki.wikipage.change" assert project_timeline[0].data["wikipage"][ "slug"] == "test wiki page timeline updated" assert project_timeline[0].data["values_diff"]["slug"][ 0] == "test wiki page timeline" assert project_timeline[0].data["values_diff"]["slug"][ 1] == "test wiki page timeline updated" user_watcher_timeline = service.get_profile_timeline(user_watcher) assert user_watcher_timeline[0].event_type == "wiki.wikipage.change" assert user_watcher_timeline[0].data["wikipage"][ "slug"] == "test wiki page timeline updated" assert user_watcher_timeline[0].data["values_diff"]["slug"][ 0] == "test wiki page timeline" assert user_watcher_timeline[0].data["values_diff"]["slug"][ 1] == "test wiki page timeline updated"
def test_update_task_timeline(): user_watcher = factories.UserFactory() task = factories.TaskFactory.create(subject="test task timeline") history_services.take_snapshot(task, user=task.owner) task.add_watcher(user_watcher) task.subject = "test task timeline updated" task.save() history_services.take_snapshot(task, user=task.owner) project_timeline = service.get_project_timeline(task.project) assert project_timeline[0].event_type == "tasks.task.change" assert project_timeline[0].data["task"][ "subject"] == "test task timeline updated" assert project_timeline[0].data["values_diff"]["subject"][ 0] == "test task timeline" assert project_timeline[0].data["values_diff"]["subject"][ 1] == "test task timeline updated" user_watcher_timeline = service.get_profile_timeline(user_watcher) assert user_watcher_timeline[0].event_type == "tasks.task.change" assert user_watcher_timeline[0].data["task"][ "subject"] == "test task timeline updated" assert user_watcher_timeline[0].data["values_diff"]["subject"][ 0] == "test task timeline" assert user_watcher_timeline[0].data["values_diff"]["subject"][ 1] == "test task timeline updated"
def test_update_issue_timeline(): user_watcher = factories.UserFactory() issue = factories.IssueFactory.create(subject="test issue timeline") history_services.take_snapshot(issue, user=issue.owner) issue.add_watcher(user_watcher) issue.subject = "test issue timeline updated" issue.save() history_services.take_snapshot(issue, user=issue.owner) project_timeline = service.get_project_timeline(issue.project) assert project_timeline[0].event_type == "issues.issue.change" assert project_timeline[0].data["issue"][ "subject"] == "test issue timeline updated" assert project_timeline[0].data["values_diff"]["subject"][ 0] == "test issue timeline" assert project_timeline[0].data["values_diff"]["subject"][ 1] == "test issue timeline updated" user_watcher_timeline = service.get_profile_timeline(user_watcher) assert user_watcher_timeline[0].event_type == "issues.issue.change" assert user_watcher_timeline[0].data["issue"][ "subject"] == "test issue timeline updated" assert user_watcher_timeline[0].data["values_diff"]["subject"][ 0] == "test issue timeline" assert user_watcher_timeline[0].data["values_diff"]["subject"][ 1] == "test issue timeline updated"
def test_update_project_timeline(): user_watcher = factories.UserFactory() project = factories.ProjectFactory.create(name="test project timeline") history_services.take_snapshot(project, user=project.owner) project.add_watcher(user_watcher) project.name = "test project timeline updated" project.save() history_services.take_snapshot(project, user=project.owner) project_timeline = service.get_project_timeline(project) assert project_timeline[0].event_type == "projects.project.change" assert project_timeline[0].data["project"][ "name"] == "test project timeline updated" assert project_timeline[0].data["values_diff"]["name"][ 0] == "test project timeline" assert project_timeline[0].data["values_diff"]["name"][ 1] == "test project timeline updated" user_watcher_timeline = service.get_profile_timeline(user_watcher) assert user_watcher_timeline[0].event_type == "projects.project.change" assert user_watcher_timeline[0].data["project"][ "name"] == "test project timeline updated" assert user_watcher_timeline[0].data["values_diff"]["name"][ 0] == "test project timeline" assert user_watcher_timeline[0].data["values_diff"]["name"][ 1] == "test project timeline updated"
def create_project(self, counter): is_private=self.sd.boolean() anon_permissions = not is_private and list(map(lambda perm: perm[0], ANON_PERMISSIONS)) or [] public_permissions = not is_private and list(map(lambda perm: perm[0], ANON_PERMISSIONS)) or [] project = Project.objects.create(slug='project-%s'%(counter), name='Project Example {0}'.format(counter), description='Project example {0} description'.format(counter), owner=random.choice(self.users), is_private=is_private, anon_permissions=anon_permissions, public_permissions=public_permissions, total_story_points=self.sd.int(600, 3000), total_milestones=self.sd.int(5,10), tags=self.sd.words(1, 10).split(" ")) project.is_kanban_activated = True project.save() take_snapshot(project, user=project.owner) for i in range(self.sd.int(*NUM_PROJECT_WATCHERS)): watching_user = self.sd.db_object_from_queryset(User.objects.all()) project.add_watcher(watching_user) return project
def create_epic_context(project, owner): epic = f.EpicFactory.create(project=project, owner=owner) key = make_key_from_model_object(epic) hc1 = f.HistoryEntryFactory.create( project=project, user={"pk": owner.id}, comment="", type=HistoryType.create, key=key, is_hidden=False, diff={"description": "new description"}, ) hc2 = f.HistoryEntryFactory.create( project=project, user={"pk": owner.id}, comment="test: change", type=HistoryType.change, key=key, is_hidden=False, diff={"content": "change content"}, ) hc3 = f.HistoryEntryFactory.create( project=project, user={"pk": owner.id}, comment="", type=HistoryType.change, key=key, is_hidden=False, diff={"blocked_note": "blocked note"}, ) take_snapshot(epic, user=epic.owner) return create_notification(project, key, owner, [hc1, hc2, hc3])
def test_send_request_one_webhook_signal(settings): settings.WEBHOOKS_ENABLED = True project = f.ProjectFactory() f.WebhookFactory.create(project=project) objects = [ f.IssueFactory.create(project=project), f.TaskFactory.create(project=project), f.UserStoryFactory.create(project=project), f.WikiPageFactory.create(project=project) ] response = Mock(status_code=200, headers={}, content="ok") response.elapsed.total_seconds.return_value = 100 for obj in objects: with patch("taiga.webhooks.tasks.requests.Session.send", return_value=response) as session_send_mock: services.take_snapshot(obj, user=obj.owner, comment="test") assert session_send_mock.call_count == 1 for obj in objects: with patch("taiga.webhooks.tasks.requests.Session.send", return_value=response) as session_send_mock: services.take_snapshot(obj, user=obj.owner, comment="test", delete=True) assert session_send_mock.call_count == 1
def process_event(self): if self.ignore(): return data = self.get_data() for commit in data: consumed_refs = [] # Status changes p = re.compile(r"tg-(\d+) +#([-\w]+)") for m in p.finditer(commit['commit_message'].lower()): ref = m.group(1) status_slug = m.group(2) (element, src_status, dst_status) = self.set_item_status(ref, status_slug) comment = self.generate_status_change_comment(src_status=src_status, dst_status=dst_status, **commit) snapshot = take_snapshot(element, comment=comment, user=self.get_user(commit["user_id"], self.platform_slug)) send_notifications(element, history=snapshot) consumed_refs.append(ref) # Reference on commit p = re.compile(r"tg-(\d+)") for m in p.finditer(commit['commit_message'].lower()): ref = m.group(1) if ref in consumed_refs: continue element = self.get_item_by_ref(ref) type_name = element.__class__._meta.verbose_name comment = self.generate_commit_reference_comment(type_name=type_name, **commit) snapshot = take_snapshot(element, comment=comment, user=self.get_user(commit['user_id'], self.platform_slug)) send_notifications(element, history=snapshot) consumed_refs.append(ref)
def create_epic(self, project): epic = Epic.objects.create( subject=self.sd.choice(SUBJECT_CHOICES), project=project, owner=self.sd.db_object_from_queryset( project.memberships.filter(user__isnull=False)).user, description=self.sd.paragraph(), status=self.sd.db_object_from_queryset( project.epic_statuses.filter(is_closed=False)), tags=self.sd.words(1, 3).split(" ")) epic.save() custom_attributes_values = { str(ca.id): self.get_custom_attributes_value(ca.type) for ca in project.epiccustomattributes.all().order_by("id") if self.sd.boolean() } if custom_attributes_values: epic.custom_attributes_values.attributes_values = custom_attributes_values epic.custom_attributes_values.save() for i in range(self.sd.int(*NUM_ATTACHMENTS)): attachment = self.create_attachment(epic, i + 1) if self.sd.choice([True, True, False, True, True]): epic.assigned_to = self.sd.db_object_from_queryset( project.memberships.filter(user__isnull=False)).user epic.save() take_snapshot(epic, comment=self.sd.paragraph(), user=epic.owner) # Add history entry epic.status = self.sd.db_object_from_queryset( project.epic_statuses.filter(is_closed=False)) epic.save() take_snapshot(epic, comment=self.sd.paragraph(), user=epic.owner) self.create_votes(epic) self.create_watchers(epic) if self.sd.choice([True, True, False, True, True]): filters = {} if self.sd.choice([True, True, False, True, True]): filters = {"project": epic.project} n = self.sd.choice(list(range(self.sd.int(*NUM_USS_EPICS)))) user_stories = UserStory.objects.filter( **filters).order_by("?")[:n] for idx, us in enumerate(list(user_stories)): RelatedUserStory.objects.create(epic=epic, user_story=us, order=idx + 1) # Add history entry take_snapshot(epic, comment=self.sd.paragraph(), user=epic.owner) return epic
def create_task(self, project, milestone, us, min_date, max_date, closed=False): task = Task(subject=self.sd.choice(SUBJECT_CHOICES), description=self.sd.paragraph(), project=project, owner=self.sd.db_object_from_queryset( project.memberships.filter(user__isnull=False)).user, milestone=milestone, user_story=us, finished_date=None, assigned_to=self.sd.db_object_from_queryset( project.memberships.filter(user__isnull=False)).user, tags=self.sd.words(1, 10).split(" ")) if closed: task.status = project.task_statuses.get(order=4) else: task.status = self.sd.db_object_from_queryset( project.task_statuses.all()) if task.status.is_closed: task.finished_date = self.sd.datetime_between(min_date, max_date) task.save() for i in range(self.sd.int(*NUM_ATTACHMENTS)): attachment = self.create_attachment(task, i + 1) take_snapshot(task, comment=self.sd.paragraph(), user=task.owner) return task
def create(self, *args, **kwargs): response = super().create(*args, **kwargs) # Added comment to the origin (issue) if response.status_code == status.HTTP_201_CREATED and self.object.generated_from_issue: self.object.generated_from_issue.save() comment = _("Generating the user story #{ref} - {subject}") comment = comment.format(ref=self.object.ref, subject=self.object.subject) history = take_snapshot(self.object.generated_from_issue, comment=comment, user=self.request.user) self.send_notifications(self.object.generated_from_issue, history) return response
def _process_label_changed(self, user, github_url): issues = Issue.objects.filter(external_reference=["github", github_url]) l = self.payload.get('issue', {}).get('labels', []) labels = [x['name'] for x in l] issueType = IssueType.objects.filter(project=self.project, name__in=labels).order_by('order').first() for issue in list(issues): issue.tags = labels issue.type = issueType issue.save() snapshot = take_snapshot(issue, comment="Edited from GitHub.", user=user) send_notifications(issue, history=snapshot)