Exemple #1
0
    def post(self, request, *args, **kwargs):
        project = get_r_object_or_404(self.request.user,
                                      Project,
                                      name_short=self.kwargs.get('project'))
        try:
            parser.compile(self.request.POST.get('expression'), project,
                           self.request.user)

            # add to sprint if currentsprint is set and issue was newly created
            if self.request.POST.get(
                    'currentsprint') != "" and parser.issue_created:
                sprint = Sprint.objects.get(
                    project__name_short=self.kwargs.get('project'),
                    seqnum=self.request.POST.get('currentsprint'))
                parser.issue_to_change.sprint = sprint
                parser.issue_to_change.save()
        except Exception as e:
            messages.add_message(
                request, messages.ERROR,
                _("An error occurred when processing your request") + ": " +
                str(e))
            # store expression in session data to give edit ability to user
            self.request.session['oleaexpression'] = self.request.POST.get(
                'expression')

        # set focus to olea bar
        self.request.session['oleafocus'] = 'autofocus'

        return redirect(self.request.POST.get('next'))
Exemple #2
0
 def test_modify_issue_backlog_bar(self):
     parser.compile('>1 @user2', self.issue.project, self.user)
     self.assertCalled(
         "chat.postMessage",
         channel="channel",
         attachments=[{
             'fallback':
             "username changed issue proj-1 sometitle.",
             'pretext':
             'Issue changed:',
             'title':
             "proj-1 sometitle",
             'title_link':
             "http://localhost:8000" + self.issue.get_absolute_url(),
             'author_name':
             "username",
             'author_link':
             "http://localhost:8000" + self.user.get_absolute_url(),
             'author_icon':
             "http://localhost:8000" + self.user.avatar.url,
             'fields': [
                 {
                     "title":
                     "Assignee",
                     "value":
                     "{} → {}, {}".format(self.user, self.user, self.user2),
                     "short":
                     True
                 },
             ],
             'color':
             'good',
         }])
Exemple #3
0
 def test_create_issue_without_params_backlog_bar(self):
     parser.compile('sometitle', self.issue.project, self.user)
     self.assertCalled(
         "chat.postMessage",
         channel="channel",
         attachments=[{
             'fallback':
             "username created issue proj-4 sometitle.",
             'pretext':
             'New Issue:',
             'text':
             "",
             'title':
             "proj-4 sometitle",
             'title_link':
             "http://localhost:8000" +
             self.issue.get_absolute_url().replace("1", "4"),
             'author_name':
             "username",
             'author_link':
             "http://localhost:8000" + self.user.get_absolute_url(),
             'author_icon':
             "http://localhost:8000" + self.user.avatar.url,
             'color':
             'good',
         }])
Exemple #4
0
    def test_parser(self):
        # contains test strings and the expected length of the attrs_to_set list
        # the third field indicates whether an issue shoud have been created
        tag = Tag(project=self.project, tag_text="testtag")
        tag.save()
        tag2 = Tag(project=self.project, tag_text="zweitertag")
        tag2.save()

        tests = [
            ['Fancy task :Task &Todo', 2, True],
            [
                'Another fancy task :Bug !2 #testtag @a ;with description', 5,
                True
            ],
            ['>PRJ-1 !2 :Bug', 2, False],
            ['>2 $8', 1, False],
        ]

        for t in tests:
            parser.compile(t[0], self.project, self.user)
            self.assertEqual(len(parser.attrs_to_set), t[1])
            self.assertEqual(parser.issue_created, t[2])
            # all the above expressions should set issue_changed to True
            self.assertEqual(parser.issue_changed, True)

        # now we should have two new issues, check also their numbers
        self.assertEqual(Project.objects.first().issue.count(), 2)
        self.assertEqual(Issue.objects.filter(title="Fancy task").count(), 1)
        self.assertEqual(
            Issue.objects.filter(project=self.project, number=1).count(), 1)
        self.assertEqual(
            Issue.objects.filter(project=self.project,
                                 number=1).first().creator, self.user)
        self.assertEqual(
            Issue.objects.filter(project=self.project,
                                 number=1).first().kanbancol.name, 'Todo')
        self.assertEqual(
            Issue.objects.filter(project=self.project, number=2).count(), 1)
        self.assertEqual(
            Issue.objects.filter(project=self.project,
                                 number=2).first().storypoints, 8)
        self.assertEqual(
            Issue.objects.filter(project=self.project,
                                 number=2).first().description,
            'with description')
        self.assertEqual(
            Issue.objects.filter(project=self.project,
                                 number=2).first().creator, self.user)

        # validate that fancy task is of type bug
        self.assertEqual(
            Issue.objects.filter(title="Fancy task", type="Bug").count(), 1)

        # validate that Another fancy task is of type bug with given attributes
        self.assertEqual(
            Issue.objects.filter(title="Another fancy task",
                                 type="Bug",
                                 priority=2,
                                 assignee=self.user,
                                 tags=tag).count(), 1)

        # set description of Another fancy task
        parser.compile('>PRJ-2 ;new description', self.project, self.user)
        self.assertEqual(
            Issue.objects.filter(project=self.project,
                                 number=2).first().description,
            'new description')

        # set kanbancol of Fancy task
        parser.compile('>PRJ-1 &Progr', self.project, self.user)
        self.assertEqual(
            Issue.objects.filter(project=self.project,
                                 number=1).first().kanbancol.name,
            'In Progress')

        # test icontains when setting kanbancol
        self.assertRaises(Exception, parser.compile, '>PRJ-1 &done',
                          self.project, self.user)
        self.assertEqual(
            Issue.objects.filter(project=self.project,
                                 number=1).first().kanbancol.name,
            'In Progress')

        parser.compile('>PRJ-1 &Done', self.project, self.user)
        self.assertEqual(
            Issue.objects.filter(project=self.project,
                                 number=1).first().kanbancol.name, 'Done')

        # add second tag and new assignee to PRJ2 and validate
        currentID = self.project.nextTicketId
        parser.compile('>PRJ-2 #zweitertag @d', self.project, self.user)
        issue = Issue.objects.get(title="Another fancy task")
        self.assertEqual(parser.issue_created, False)
        self.assertEqual(parser.issue_changed, True)
        self.assertEqual(parser.issue_to_change, issue)
        self.assertEqual(issue.tags.count(), 2)
        self.assertEqual(issue.assignee.count(), 2)
        self.assertIn(self.user, issue.assignee.all())
        self.assertIn(self.user2, issue.assignee.all())
        self.assertEqual(issue.number, 2)
        self.project.refresh_from_db()
        self.assertEqual(currentID, self.project.nextTicketId)

        # test permission checks and validations
        user = get_user_model().objects.create_user('g', 'h', 'i')
        issue.tags.clear()
        issue.refresh_from_db
        self.assertEqual(issue.tags.count(), 0)

        # not existing issues may not be edited and nextTicketId must not change
        currentID = self.project.nextTicketId
        self.assertRaises(Exception, parser.compile, '>PRJ-3 #zweitertag @d',
                          self.project, self.user)
        self.project.refresh_from_db()
        self.assertEqual(currentID, self.project.nextTicketId)

        # user must not edit projects to which he has no devel access
        self.assertRaises(Exception, parser.compile, '>PRJ-2 #zweitertag @d',
                          self.project, user)

        # only users with access to project may be set as assignee
        self.assertRaises(Exception, parser.compile, '>PRJ-2 #zweitertag @g',
                          self.project, self.user)

        # tags must not have changed
        issue.refresh_from_db
        self.assertEqual(issue.tags.count(), 0)

        # create another tag containing a space
        tag = Tag(project=self.project, tag_text="tag with spaces")
        tag.save()
        parser.compile('>PRJ-2 #tag with spaces @d', self.project, self.user)
        self.assertEqual(parser.issue_changed, True)
        issue.refresh_from_db()
        self.assertEqual(issue.tags.filter(pk=tag.pk).count(), 1)

        # dependent issue must exist and be in the same project
        parser.compile('Test-Issue proj2 :Bug', self.project2, self.user)
        self.assertEqual(parser.issue_created, True)
        self.assertEqual(parser.issue_changed, True)
        issue = Issue.objects.get(title="Test-Issue proj2")
        self.assertEqual(parser.issue_to_change, issue)
        self.assertEqual(
            Issue.objects.filter(project=self.project2).count(), 1)
        self.assertRaises(Exception, parser.compile, '>TPJ-1 ~PRJ-1',
                          self.project, self.user)

        # log time to issue
        parser.compile('>PRJ-1 +2h5m', self.project, self.user)
        self.assertEqual(parser.issue_created, False)
        # logging time is no change action
        self.assertEqual(parser.issue_changed, False)
        t = Timelog.objects.get(issue__title='Fancy task')
        self.assertEqual(t.time.total_seconds(), 7500)

        # log many times to issue
        parser.compile('>PRJ-1 +2h5m +1m', self.project, self.user)
        self.assertEqual(parser.issue_created, False)
        self.assertEqual(parser.issue_changed, False)
        self.assertEqual(
            Timelog.objects.filter(issue__title='Fancy task').count(), 3)
        totaltime = 0
        for log in Timelog.objects.filter(issue__title='Fancy task'):
            totaltime += log.time.total_seconds()
        self.assertEqual(totaltime, 15060)

        # log time to new issue
        issuetitle = 'Timelog-test-issue'
        parser.compile(issuetitle + ' +2h5m', self.project, self.user)
        self.assertEqual(parser.issue_created, True)
        self.assertEqual(parser.issue_changed, False)
        self.assertEqual(Issue.objects.filter(title=issuetitle).count(), 1)
        t = Timelog.objects.get(issue__title=issuetitle)
        self.assertEqual(t.time.total_seconds(), 7500)

        # test empty timelog field (must not create new timelog object, should still be 3)
        parser.compile('>PRJ-1 +', self.project, self.user)
        self.assertEqual(parser.issue_created, False)
        self.assertEqual(parser.issue_changed, False)
        self.assertEqual(
            Timelog.objects.filter(issue__title='Fancy task').count(), 3)

        # some syntactic stuff that should fail
        tests = [
            'Test-String ',
            '> @a',
            '>PRJ-2',
        ]

        for t in tests:
            self.assertRaises(Exception, parser.compile, t, self.project,
                              self.user)

        # tests for contains checks of tag
        Issue.objects.get(title='Fancy task').tags.clear()
        self.assertRaises(Exception, parser.compile, '>PRJ-1 #tag',
                          self.project, self.user)
        self.assertEqual(Issue.objects.get(title='Fancy task').tags.count(), 0)
        parser.compile('>PRJ-1 #ttag', self.project, self.user)
        self.assertEqual(Issue.objects.get(title='Fancy task').tags.count(), 1)
        self.assertEqual(parser.issue_created, False)
        self.assertEqual(parser.issue_changed, True)

        tag3 = Tag(project=self.project, tag_text="ttag")
        tag3.save()
        parser.compile('>PRJ-1 #ttag', self.project, self.user)
        self.assertEqual(parser.issue_changed, True)
        self.assertEqual(Issue.objects.filter(tags=tag3).count(), 1)
        self.assertEqual(Issue.objects.get(title='Fancy task').tags.count(), 2)

        # check that searching for tag is case insensitive
        Issue.objects.get(title='Fancy task').tags.clear()
        parser.compile('>PRJ-1 #teStTaG', self.project, self.user)
        self.assertEqual(Issue.objects.get(title='Fancy task').tags.count(), 1)
        self.assertEqual(parser.issue_created, False)
        self.assertEqual(parser.issue_changed, True)

        # same for user
        Issue.objects.get(title='Fancy task').assignee.clear()
        user3 = get_user_model().objects.create_user('jj', 'x', 'x')
        self.project.developer.add(user3)
        user4 = get_user_model().objects.create_user('jjj', 'y', 'y')
        self.project.developer.add(user4)
        user5 = get_user_model().objects.create_user('kj', 'z', 'z')
        self.project.developer.add(user5)
        self.assertRaises(Exception, parser.compile, '>PRJ-1 @j', self.project,
                          self.user)
        self.assertEqual(
            Issue.objects.get(title='Fancy task').assignee.count(), 0)
        parser.compile('>PRJ-1 @jj', self.project, self.user)
        self.assertEqual(parser.issue_created, False)
        self.assertEqual(parser.issue_changed, True)
        self.assertEqual(
            Issue.objects.filter(title='Fancy task', assignee=user3).count(),
            1)
        parser.compile('>PRJ-1 @jjj', self.project, self.user)
        self.assertEqual(parser.issue_created, False)
        self.assertEqual(parser.issue_changed, True)
        self.assertEqual(
            Issue.objects.filter(title='Fancy task', assignee=user4).count(),
            1)

        # user search case insensitive
        Issue.objects.get(title='Fancy task').assignee.clear()
        parser.compile('>PRJ-1 @jJJ', self.project, self.user)
        self.assertEqual(parser.issue_created, False)
        self.assertEqual(parser.issue_changed, True)
        self.assertEqual(
            Issue.objects.filter(title='Fancy task', assignee=user4).count(),
            1)

        # check that setting more than one assignee is possible
        parser.compile('>PRJ-1 @a @jj @kj', self.project, self.user)
        self.assertEqual(parser.issue_created, False)
        self.assertEqual(parser.issue_changed, True)
        self.assertEqual(
            Issue.objects.get(title='Fancy task').assignee.count(), 4)
        parser.compile('>PRJ-1 @jj', self.project, self.user)
        self.assertEqual(parser.issue_created, False)
        self.assertEqual(parser.issue_changed, True)
        self.assertEqual(
            Issue.objects.get(title='Fancy task').assignee.count(), 4)

        # test add depends functionality
        parser.compile('New issue depending on PRJ-1 ~PRJ-1', self.project,
                       self.user)
        self.assertEqual(parser.issue_created, True)
        self.assertEqual(parser.issue_changed, True)
        self.assertEqual(
            Issue.objects.filter(project=self.project,
                                 title='New issue depending on PRJ-1').count(),
            1)
        self.assertEqual(
            Issue.objects.get(
                project=self.project,
                title='New issue depending on PRJ-1').dependsOn.count(), 1)
        parser.compile('>PRJ-1 ~PRJ-2', self.project, self.user)
        self.assertEqual(parser.issue_created, False)
        self.assertEqual(parser.issue_changed, True)
        self.assertEqual(
            Issue.objects.get(title='Fancy task').dependsOn.count(), 1)

        # tag not existant
        Issue.objects.get(title='Fancy task').tags.clear()
        self.assertRaises(Exception, parser.compile, '>PRJ-1 #imnothere',
                          self.project, self.user)
        self.assertEqual(Issue.objects.get(title='Fancy task').tags.count(), 0)

        # user not existant
        Issue.objects.get(title='Fancy task').assignee.clear()
        self.assertRaises(Exception, parser.compile, '>PRJ-1 @imnothere',
                          self.project, self.user)
        self.assertEqual(
            Issue.objects.get(title='Fancy task').assignee.count(), 0)

        # test omitting project shortname in depends and modify tag
        Issue.objects.get(title='Fancy task').dependsOn.clear()
        parser.compile('>1 ~2', self.project, self.user)
        self.assertEqual(parser.issue_created, False)
        self.assertEqual(
            Issue.objects.get(title='Fancy task').dependsOn.count(), 1)
        self.assertEqual(
            Issue.objects.get(title='Fancy task').dependsOn.first().title,
            'Another fancy task')

        # check permissions test for issue to modify
        user5 = get_user_model().objects.create_user('tt', 'hh', 'ii')
        self.assertNotEqual(Issue.objects.get(title='Fancy task').priority, 4)
        self.assertRaises(Exception, parser.compile, '>1 !4', self.project,
                          user5)
        self.assertNotEqual(Issue.objects.get(title='Fancy task').priority, 4)

        # check that managers and (managers & developers) are valid as assignee
        u_manager = get_user_model().objects.create_user('manager', 'ma', 'ma')
        u_maneloper = get_user_model().objects.create_user(
            'maneloper', 'mar', 'mar')
        self.project.manager.add(u_manager)
        self.project.manager.add(u_maneloper)
        self.project.developer.add(u_maneloper)

        Issue.objects.get(title='Fancy task').assignee.clear()
        parser.compile('>PRJ-1 @manager @maneloper', self.project, self.user)
        self.assertEqual(parser.issue_created, False)
        self.assertEqual(parser.issue_changed, True)
        self.assertEqual(
            Issue.objects.filter(
                Q(title='Fancy task')
                & (Q(assignee=u_manager) | Q(assignee=u_maneloper))).count(),
            2)

        # check that first and last name is also valid when searching for users
        parser.compile('>PRJ-1 @alice @bob', self.project, self.user)
        issue = self.project.issue.get(number=1)
        self.assertIn(self.user, issue.assignee.all())
        self.assertIn(self.user2, issue.assignee.all())
        self.assertIn(u_manager, issue.assignee.all())
        self.assertIn(u_maneloper, issue.assignee.all())
        self.assertEqual(issue.assignee.count(), 4)
        parser.compile('>PRJ-1 @alice @Blub', self.project, self.user)
        issue.refresh_from_db()
        self.assertIn(self.user, issue.assignee.all())
        self.assertIn(self.user2, issue.assignee.all())
        self.assertIn(u_manager, issue.assignee.all())
        self.assertIn(u_maneloper, issue.assignee.all())
        self.assertEqual(issue.assignee.count(), 4)

        # check that user is not assigned more than once
        Issue.objects.get(title='Fancy task').assignee.clear()
        parser.compile('>PRJ-1 @alice @Bla', self.project, self.user)
        issue.refresh_from_db()
        self.assertIn(self.user, issue.assignee.all())
        self.assertEqual(issue.assignee.count(), 1)

        # check that no issue is created with error in change expression
        self.project.refresh_from_db()
        currentID = self.project.nextTicketId
        currentTicketCount = self.project.issue.count()
        self.assertRaises(Exception, parser.compile,
                          'New Issue #nonexistanttag', self.project, self.user)
        self.project.refresh_from_db()
        self.assertEqual(currentID, self.project.nextTicketId)
        self.assertEqual(currentTicketCount, self.project.issue.count())

        # check that issue creation without change expression is possible
        self.project.refresh_from_db()
        currentID = self.project.nextTicketId
        currentTicketCount = self.project.issue.count()
        title = 'Fancy new issue without chgxpr'
        parser.compile(title, self.project, self.user)
        self.assertEqual(parser.issue_created, True)
        self.assertEqual(parser.issue_changed, False)
        self.project.refresh_from_db()
        self.assertEqual(self.project.issue.filter(title=title).count(), 1)
        self.assertEqual(currentID + 1, self.project.nextTicketId)
        self.assertEqual(currentTicketCount + 1, self.project.issue.count())

        # check that changing an issue without change expression throws an exception
        self.assertRaises(Exception, parser.compile, '>1', self.project,
                          self.user)
Exemple #5
0
 def test_log_time(self):
     parser.compile('>1 +1m', self.issue.project, self.user)
     self.assertNotCalled()