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('tuesmon.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('tuesmon.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 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 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_milestone(settings): settings.WEBHOOKS_ENABLED = True project = f.ProjectFactory() f.WebhookFactory.create(project=project) f.WebhookFactory.create(project=project) obj = f.MilestoneFactory.create(project=project) with patch('tuesmon.webhooks.tasks._send_request') as send_request_mock: services.take_snapshot(obj, user=obj.owner) assert send_request_mock.call_count == 2 obj.name = "test webhook update" obj.save() with patch('tuesmon.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"] == "milestone" assert data["by"]["id"] == obj.owner.id assert "date" in data assert data["data"]["id"] == obj.id assert data["data"]["name"] == obj.name assert data["change"]["comment"] == "test_comment" assert data["change"]["diff"]["name"]["to"] == data["data"]["name"] assert data["change"]["diff"]["name"]["from"] != data["data"]["name"]
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_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('tuesmon.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('tuesmon.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 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 = deepcopy(push_base_payload) payload["commits"] = [{ "message": """test message test TG-%s ok bye! """ % (user_story.ref), "id": "b6568db1bc1dcd7f8b4d5a946b0b91f9dacd7327", "url": "http://example.com/mike/diaspora/commit/b6568db1bc1dcd7f8b4d5a946b0b91f9dacd7327", }] 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 = { "commits": [{ "message": """test message test TG-%s ok bye! """ % (user_story.ref), "author": { "username": "******", }, }], "repository": { "html_url": "http://test-url/test/project" } } 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 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 update_milestone_of_tasks_when_edit_us(sender, instance, created, **kwargs): if not created: tasks = instance.tasks.exclude(milestone=instance.milestone) tasks.update(milestone=instance.milestone) for task in tasks: take_snapshot(task)
def test_update_user_story_timeline(): user_watcher = factories.UserFactory() user_story = factories.UserStoryFactory.create(subject="test us timeline") history_services.take_snapshot(user_story, user=user_story.owner) user_story.add_watcher(user_watcher) user_story.subject = "test us timeline updated" user_story.save() 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.change" assert project_timeline[0].data["userstory"][ "subject"] == "test us timeline updated" assert project_timeline[0].data["values_diff"]["subject"][ 0] == "test us timeline" assert project_timeline[0].data["values_diff"]["subject"][ 1] == "test us timeline updated" user_watcher_timeline = service.get_profile_timeline(user_watcher) assert user_watcher_timeline[ 0].event_type == "userstories.userstory.change" assert user_watcher_timeline[0].data["userstory"][ "subject"] == "test us timeline updated" assert user_watcher_timeline[0].data["values_diff"]["subject"][ 0] == "test us timeline" assert user_watcher_timeline[0].data["values_diff"]["subject"][ 1] == "test us timeline updated"
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 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 test_update_milestone_timeline(): user_watcher = factories.UserFactory() milestone = factories.MilestoneFactory.create( name="test milestone timeline") history_services.take_snapshot(milestone, user=milestone.owner) milestone.add_watcher(user_watcher) milestone.name = "test milestone timeline updated" milestone.save() history_services.take_snapshot(milestone, user=milestone.owner) project_timeline = service.get_project_timeline(milestone.project) assert project_timeline[0].event_type == "milestones.milestone.change" assert project_timeline[0].data["milestone"][ "name"] == "test milestone timeline updated" assert project_timeline[0].data["values_diff"]["name"][ 0] == "test milestone timeline" assert project_timeline[0].data["values_diff"]["name"][ 1] == "test milestone timeline updated" user_watcher_timeline = service.get_profile_timeline(user_watcher) assert user_watcher_timeline[0].event_type == "milestones.milestone.change" assert user_watcher_timeline[0].data["milestone"][ "name"] == "test milestone timeline updated" assert user_watcher_timeline[0].data["values_diff"]["name"][ 0] == "test milestone timeline" assert user_watcher_timeline[0].data["values_diff"]["name"][ 1] == "test milestone timeline updated"
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 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("tuesmon.webhooks.tasks.requests.Session.send", return_value=response) as session_send_mock, \ patch("tuesmon.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("tuesmon.webhooks.tasks.requests.Session.send", return_value=response) as session_send_mock, \ patch("tuesmon.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 store_issue(project, data): validator = validators.IssueExportValidator(data=data, context={"project": project}) if "type" not in data and project.default_issue_type: data["type"] = project.default_issue_type.name if "status" not in data and project.default_issue_status: data["status"] = project.default_issue_status.name if "priority" not in data and project.default_priority: data["priority"] = project.default_priority.name if "severity" not in data and project.default_severity: data["severity"] = project.default_severity.name 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() if validator.object.ref: sequence_name = refs.make_sequence_name(project) if not seq.exists(sequence_name): seq.create(sequence_name) seq.set_max(sequence_name, validator.object.ref) else: validator.object.ref, _ = refs.make_reference(validator.object, project) validator.object.save() for attachment in data.get("attachments", []): _store_attachment(project, validator.object, attachment) history_entries = data.get("history", []) statuses = {s.name: s.id for s in project.issue_statuses.all()} for history in history_entries: _store_history(project, validator.object, history, statuses) if not history_entries: take_snapshot(validator.object, user=validator.object.owner) custom_attributes_values = data.get("custom_attributes_values", None) if custom_attributes_values: custom_attributes = validator.object.project.issuecustomattributes.all().values('id', 'name') custom_attributes_values = \ _use_id_instead_name_as_key_in_custom_attributes_values(custom_attributes, custom_attributes_values) _store_custom_attributes_values(validator.object, custom_attributes_values, "issue", validators.IssueCustomAttributesValuesExportValidator) return validator add_errors("issues", validator.errors) return None
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 test_user_data_for_system_users(): user_story = factories.UserStoryFactory.create(subject="test us timeline") user_story.owner.is_system = True user_story.owner.save() history_services.take_snapshot(user_story, user=user_story.owner) project_timeline = service.get_project_timeline(user_story.project) serialized_obj = TimelineSerializer(project_timeline[0]) serialized_obj.data["data"]["user"]["is_profile_visible"] = False
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 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_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 _import_epics_data(self, project_id, project, options): users_bindings = options.get('users_bindings', {}) types = options.get('types_bindings', {}).get("epic", []) for issue_type in types: counter = 0 offset = 0 while True: issues = self._client.get("/search", { "jql": "project={} AND issuetype={}".format(project_id, issue_type['id']), "startAt": offset, "fields": "*all", "expand": "changelog,attachment", }) offset += issues['maxResults'] for issue in issues['issues']: issue['fields']['issuelinks'] += self._client.get("/issue/{}/remotelink".format(issue['key'])) assigned_to = users_bindings.get(issue['fields']['assignee']['key'] if issue['fields']['assignee'] else None, None) owner = users_bindings.get(issue['fields']['creator']['key'] if issue['fields']['creator'] else None, self._user) external_reference = None if options.get('keep_external_reference', False) and 'url' in issue['fields']: external_reference = ["jira", issue['fields']['url']] epic = Epic.objects.create( project=project, owner=owner, assigned_to=assigned_to, status=project.epic_statuses.get(name=issue['fields']['status']['name']), subject=issue['fields']['summary'], description=issue['fields']['description'] or '', epics_order=counter, tags=issue['fields']['labels'], external_reference=external_reference, ) self._import_to_custom_fields(epic, issue, options) epic.ref = issue['key'].split("-")[1] Epic.objects.filter(id=epic.id).update( ref=epic.ref, modified_date=issue['fields']['updated'], created_date=issue['fields']['created'] ) take_snapshot(epic, comment="", user=None, delete=False) for subtask in issue['fields']['subtasks']: print("WARNING: Ignoring subtask {} because parent isn't a User Story".format(subtask['key'])) self._import_comments(epic, issue, options) self._import_attachments(epic, issue, options) issue_with_changelog = self._client.get("/issue/{}".format(issue['key']), { "expand": "changelog" }) self._import_changelog(project, epic, issue_with_changelog, options) counter += 1 if len(issues['issues']) < issues['maxResults']: break
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 _import_task_data(self, tuesmon_project, us, assana_project, task, options): users_bindings = options.get('users_bindings', {}) tags = [] for tag in task['tags']: tags.append(tag['name'].lower()) due_date_field = tuesmon_project.taskcustomattributes.first() assigned_to = users_bindings.get(task.get('assignee', {}).get('id', None)) or None external_reference = None if options.get('keep_external_reference', False): external_url = "https://app.asana.com/0/{}/{}".format( assana_project['id'], task['id'], ) external_reference = ["asana", external_url] tuesmon_task = Task.objects.create( project=tuesmon_project, user_story=us, owner=self._user, assigned_to=assigned_to, status=tuesmon_project.task_statuses.get(slug="closed" if task['completed'] else "open"), us_order=task['id'], taskboard_order=task['id'], subject=task['name'], description=task.get('notes', ""), tags=tags, external_reference=external_reference ) if task['due_on']: tuesmon_task.custom_attributes_values.attributes_values = {due_date_field.id: task['due_on']} tuesmon_task.custom_attributes_values.save() for follower in task['followers']: follower_user = users_bindings.get(follower['id'], None) if follower_user is not None: tuesmon_task.add_watcher(follower_user) Task.objects.filter(id=tuesmon_task.id).update( modified_date=task['modified_at'], created_date=task['created_at'] ) subtasks = self._client.tasks.subtasks( task['id'], fields=["parent", "tags", "name", "notes", "tags.name", "completed", "followers", "modified_at", "created_at", "due_on"] ) for subtask in subtasks: self._import_task_data(tuesmon_project, us, assana_project, subtask, options) take_snapshot(tuesmon_task, comment="", user=None, delete=False) self._import_history(tuesmon_task, task, options) self._import_attachments(tuesmon_task, task, options)
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 store_user_story(project, data): if "status" not in data and project.default_us_status: data["status"] = project.default_us_status.name us_data = {key: value for key, value in data.items() if key not in ["role_points", "custom_attributes_values", 'generated_from_task', 'generated_from_issue']} validator = validators.UserStoryExportValidator(data=us_data, context={"project": project}) 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() if validator.object.ref: sequence_name = refs.make_sequence_name(project) if not seq.exists(sequence_name): seq.create(sequence_name) seq.set_max(sequence_name, validator.object.ref) else: validator.object.ref, _ = refs.make_reference(validator.object, project) validator.object.save() for us_attachment in data.get("attachments", []): _store_attachment(project, validator.object, us_attachment) for role_point in data.get("role_points", []): _store_role_point(project, validator.object, role_point) history_entries = data.get("history", []) statuses = {s.name: s.id for s in project.us_statuses.all()} for history in history_entries: _store_history(project, validator.object, history, statuses) if not history_entries: take_snapshot(validator.object, user=validator.object.owner) custom_attributes_values = data.get("custom_attributes_values", None) if custom_attributes_values: custom_attributes = validator.object.project.userstorycustomattributes.all().values('id', 'name') custom_attributes_values = \ _use_id_instead_name_as_key_in_custom_attributes_values(custom_attributes, custom_attributes_values) _store_custom_attributes_values(validator.object, custom_attributes_values, "user_story", validators.UserStoryCustomAttributesValuesExportValidator) return validator add_errors("user_stories", validator.errors) return None
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() custom_attributes_values = { str(ca.id): self.get_custom_attributes_value(ca.type) for ca in project.taskcustomattributes.all().order_by('id') if self.sd.boolean() } if custom_attributes_values: task.custom_attributes_values.attributes_values = custom_attributes_values task.custom_attributes_values.save() for i in range(self.sd.int(*NUM_ATTACHMENTS)): attachment = self.create_attachment(task, i + 1) take_snapshot(task, user=task.owner) # Add history entry task.status = self.sd.db_object_from_queryset( project.task_statuses.all()) task.save() take_snapshot(task, comment=self.sd.paragraph(), user=task.owner) self.create_votes(task) self.create_watchers(task) return task
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() us.save() custom_attributes_values = { str(ca.id): self.get_custom_attributes_value(ca.type) for ca in project.userstorycustomattributes.all().order_by('id') if self.sd.boolean() } if custom_attributes_values: us.custom_attributes_values.attributes_values = custom_attributes_values us.custom_attributes_values.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, 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) self.create_votes(us) self.create_watchers(us) return us
def test_delete_project_timeline(): project = factories.ProjectFactory.create(name="test project timeline") user_watcher = factories.UserFactory() project.add_watcher(user_watcher) history_services.take_snapshot(project, user=project.owner, delete=True) user_timeline = service.get_project_timeline(project) assert user_timeline[0].event_type == "projects.project.delete" assert user_timeline[0].data["project"]["id"] == project.id user_watcher_timeline = service.get_profile_timeline(user_watcher) assert user_watcher_timeline[0].event_type == "projects.project.delete" assert user_watcher_timeline[0].data["project"]["id"] == project.id