예제 #1
0
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
예제 #2
0
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"
예제 #3
0
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
예제 #4
0
    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
예제 #5
0
파일: store.py 프로젝트: 0-T-0/taiga-back
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
예제 #7
0
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
예제 #8
0
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
예제 #9
0
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
예제 #10
0
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
예제 #11
0
    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)
예제 #12
0
    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)
예제 #13
0
    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
예제 #14
0
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
예제 #15
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
예제 #16
0
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
예제 #17
0
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"]
예제 #18
0
    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
예제 #19
0
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
예제 #20
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
예제 #21
0
    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
예제 #22
0
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
예제 #23
0
    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)
예제 #24
0
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
예제 #25
0
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
예제 #26
0
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
예제 #27
0
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
예제 #28
0
    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
예제 #29
0
    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
예제 #30
0
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
예제 #31
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
예제 #32
0
 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'])
예제 #33
0
    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
예제 #34
0
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
예제 #35
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
예제 #36
0
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
예제 #37
0
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
예제 #38
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)
예제 #39
0
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]
예제 #40
0
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"
예제 #41
0
    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
예제 #43
0
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
예제 #44
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
예제 #45
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
예제 #46
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=[
        "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
예제 #47
0
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
예제 #48
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
예제 #49
0
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"
예제 #50
0
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"
예제 #51
0
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"
예제 #52
0
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"
예제 #53
0
    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])
예제 #55
0
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
예제 #56
0
    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)
예제 #57
0
    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
예제 #58
0
    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
예제 #59
0
    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
예제 #60
0
    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)