コード例 #1
0
 def setUp(self):
     self.client.force_login(self.user)
     # NOTE: this element gets modified by some of those tests, so this shall NOT be created in setUpTestData()
     self.project = Project(creator=self.user, name_short='PRJ')
     self.project.save()
     self.project.developer.add(self.user)
     self.project.developer.add(self.user2)
     # NOTE: this element gets modified by some of those tests, so this shall NOT be created in setUpTestData()
     self.kanbancol = KanbanColumn(project=self.project,
                                   position=4,
                                   name='test')
     self.kanbancol.save()
     # NOTE: this element gets modified by some of those tests, so this shall NOT be created in setUpTestData()
     self.issue = Issue(
         title='a very very very very very very very long issue title',
         project=self.project,
         due_date='2016-12-16',
         kanbancol=self.kanbancol,
         storypoints='3')
     self.issue.save()
     self.issue2 = Issue(title='issue title',
                         project=self.project,
                         due_date='2016-12-16',
                         kanbancol=self.kanbancol,
                         storypoints='3')
     self.issue2.save()
     self.issue.assignee.add(self.user)
コード例 #2
0
    def setUp(self):
        self.user = get_user_model().objects.create_user('a', 'b', 'c')
        self.project = Project(creator=self.user,
                               name="asdf",
                               name_short="PRJ")
        self.project.save()
        self.project.manager.add(self.user)
        self.project.developer.add(self.user)
        self.project2 = Project(creator=self.user,
                                name="2ndproj",
                                name_short="PRJ2")
        self.project2.save()
        self.project2.developer.add(self.user)
        self.kanban = KanbanColumn(name='KanCol',
                                   project=self.project2,
                                   position=4)
        self.kanban.save()

        # Uses the cookie hack from:
        # https://stackoverflow.com/questions/22494583/login-with-code-when-using-liveservertestcase-with-django
        client = Client()
        client.login(username='******', password='******')
        self.cookie = client.cookies['sessionid']
        self.selenium.get("{}{}".format(self.live_server_url,
                                        reverse('invite_users:invite_users')))
        self.selenium.add_cookie({
            'name': 'sessionid',
            'value': self.cookie.value,
            'secure': False,
            'path': '/'
        })
        self.selenium.refresh()
コード例 #3
0
    def test_add_and_remove_issue_from_sprint(self):
        kanbancol = KanbanColumn(name='Column', position=1, project=self.project)
        kanbancol.save()
        issue = Issue(title="Test-Issue", kanbancol=kanbancol, project=self.project, type="Bug")
        issue.save()

        # add to sprint
        response = self.client.post(reverse('sprint:assigntosprint', kwargs={'project': self.project.name_short}),
                                    {'sqn_i': issue.number}, follow=True,
                                    HTTP_REFERER=reverse('backlog:backlog',
                                                         kwargs={'project': self.project.name_short}))
        self.assertRedirects(response, reverse('backlog:backlog', kwargs={'project': self.project.name_short,
                                                                          'sqn_s': self.sprint.seqnum}))

        self.assertEqual(Issue.objects.get(pk=issue.pk).sprint, Sprint.objects.get(pk=self.sprint.pk))

        # remove from sprint
        response = self.client.post(reverse('sprint:assigntosprint', kwargs={'project': self.project.name_short}),
                                    {'sqn_s': self.sprint.seqnum, 'sqn_i': issue.number}, follow=True,
                                    HTTP_REFERER=reverse('backlog:backlog', kwargs={'project': self.project.name_short})
                                    )
        self.assertRedirects(response, reverse('backlog:backlog', kwargs={'project': self.project.name_short,
                                                                          'sqn_s': self.sprint.seqnum}))

        self.assertEqual(Issue.objects.get(pk=issue.pk).sprint, None)
コード例 #4
0
    def setUp(self):
        self.client.force_login(self.user)
        # NOTE: this element gets modified by some of those tests, so this shall NOT be created in setUpTestData()
        self.project = Project(creator=self.user, name_short='PRJ', activity_only_for_managers=False)
        self.project.save()
        self.project.developer.add(self.user)

        self.project2 = Project(creator=self.user, activity_only_for_managers=True, name_short='PRJJ')
        self.project2.save()
        self.project2.manager.add(self.user)
        self.project2.developer.add(self.user, self.user2)

        # NOTE: this element gets modified by some of those tests, so this shall NOT be created in setUpTestData()
        self.kanbancol = KanbanColumn(project=self.project, position=4, name='test')
        self.kanbancol.save()
        # NOTE: this element gets modified by some of those tests, so this shall NOT be created in setUpTestData()
        self.issue = Issue(title='a very very very very very very very long issue title',
                           project=self.project,
                           due_date='2016-12-16',
                           kanbancol=self.kanbancol,
                           storypoints='3'
                           )
        self.issue.save()
        self.issue.assignee.add(self.user)
        self.issue2 = Issue(title='second_issue', project=self.project)
        self.issue2.save()
        self.issue2.assignee.add(self.user)
        self.time = now().strftime("%Y-%m-%d %H:%M:%S")
コード例 #5
0
    def setUp(self):
        self.client.force_login(self.user)
        # NOTE: these elements get modified by some testcases, so they should NOT be created in setUpTestData()
        self.project = Project(creator=self.user, name_short='PRJ', activity_only_for_managers=False)
        self.project.save()
        self.project.developer.add(self.user)

        self.project2 = Project(creator=self.user, activity_only_for_managers=True, name_short='PRJJ')
        self.project2.save()
        self.project2.manager.add(self.user)
        self.project2.developer.add(self.user, self.user2)

        self.kanbancol = KanbanColumn(project=self.project, position=4, name='test')
        self.kanbancol.save()
        self.issue = Issue(title='a very very very very very very very long issue title',
                           project=self.project,
                           due_date='2016-12-16',
                           kanbancol=self.kanbancol,
                           storypoints='3'
                           )
        self.issue.save()
        self.issue.assignee.add(self.user)
        self.issue2 = Issue(title='second_issue', project=self.project)
        self.issue2.save()
        self.issue2.assignee.add(self.user)
        self.time = now().strftime("%Y-%m-%d %H:%M:%S")

        # success logedit_address_kwargs
        self.sqn_l1_address_kwarg = {"project": self.issue.project.name_short,
                                     "sqn_i": self.issue.number,
                                     "sqn_l": 1
                                     }
コード例 #6
0
def create_project_default_columns(sender, **kwargs):
    if kwargs['created']:
        KanbanColumn(name='Todo', type='ToDo',
                     project=kwargs['instance']).save()
        KanbanColumn(name='In Progress',
                     type='InProgress',
                     project=kwargs['instance']).save()
        KanbanColumn(name='Done', type='Done',
                     project=kwargs['instance']).save()
コード例 #7
0
 def setUp(self):
     translation.activate('en')
     self.client.force_login(self.user)
     self.project = Project(creator=self.user,
                            name_short='test',
                            name='Testproject',
                            description='asdf')
     self.project.save()
     self.project.manager.add(self.user)
     self.column = KanbanColumn(name='Column', project=self.project)
     self.column.save()
コード例 #8
0
 def setUp(self):
     # NOTE: these element gets modified by some of those tests, so they should NOT be created in setUpTestData()
     self.client.force_login(self.user)
     self.project = Project(creator=self.user, name_short=proj_short)
     self.project.save()
     self.project.manager.add(self.user)
     self.project.developer.add(self.user)
     self.column = KanbanColumn(name='Column', position=4, project=self.project)
     self.column.save()
     self.issue = Issue(title="Test-Issue", project=self.project, kanbancol=self.column, type="Bug")
     self.issue.save()
コード例 #9
0
 def setUp(self):
     self.client.force_login(self.user)
     # NOTE: these elements get modified by some testcases, so they should NOT be created in setUpTestData()
     self.project = Project(creator=self.user, name_short='PRJ')
     self.project.save()
     self.project.manager.add(self.user)
     self.project.developer.add(self.user)
     self.column = KanbanColumn(name='Column',
                                position=4,
                                project=self.project)
     self.column.save()
コード例 #10
0
 def setUp(self):
     self.client.force_login(self.user)
     # NOTE: this element gets modified by some of those tests, so this shall NOT be created in setUpTestData()
     self.project = Project(creator=self.user, name_short=proj_short)
     self.project.save()
     self.project.manager.add(self.user)
     self.project.developer.add(self.user)
     # NOTE: this element gets modified by some of those tests, so this shall NOT be created in setUpTestData()
     self.column = KanbanColumn(name='Column',
                                position=4,
                                project=self.project)
     self.column.save()
コード例 #11
0
 def setUp(self):
     # NOTE: these elements get modified by some testcases, so they should NOT be created in setUpTestData()
     translation.activate('en')
     self.client.force_login(self.user)
     self.project = Project(creator=self.user,
                            name_short='test',
                            name='Testproject',
                            description='asdf')
     self.project.save()
     self.project.manager.add(self.user)
     self.column = KanbanColumn(name='Column', project=self.project)
     self.column.save()
コード例 #12
0
    def test_flags(self):
        kanbancol = KanbanColumn(name='Column', position=1, project=self.project)
        kanbancol.save()
        issue = Issue(title="Test-Issue", kanbancol=kanbancol, project=self.project, type="Bug", sprint=self.sprint)
        issue.save()
        self.assertEqual(issue.was_in_sprint, False)

        response = self.client.post(
                reverse('sprint:stopsprint', kwargs={'project': self.project.name_short, 'sqn_s': self.sprint.seqnum}))
        self.assertEqual(Issue.objects.get(pk=issue.pk).was_in_sprint, True)

        issue.save()  # unset the flag
        self.assertEqual(issue.was_in_sprint, False)
コード例 #13
0
ファイル: test_sprint.py プロジェクト: asdfkaba/iguana
 def test_storypoints_in_backlog(self):
     kanbancol = KanbanColumn(name='Column',
                              position=1,
                              project=self.project)
     kanbancol.save()
     issue = Issue(title="Test-Issue",
                   kanbancol=kanbancol,
                   project=self.project,
                   type="Bug",
                   sprint=self.sprint)
     issue.save()
     response = self.client.get(
         reverse('backlog:backlog',
                 kwargs={'project': self.project.name_short}))
     self.assertNotContains(response, 'Storypoints:')
     issue.storypoints = 5
     issue.save()
     response = self.client.get(
         reverse('backlog:backlog',
                 kwargs={'project': self.project.name_short}))
     self.assertNotContains(response, 'Storypoints:')
     issue.assignee.add(self.user)
     response = self.client.get(
         reverse('backlog:backlog',
                 kwargs={'project': self.project.name_short}))
     self.assertContains(response, 'Storypoints:')
     self.assertContains(response, str(self.user.username) + ': 5')
     user2 = get_user_model().objects.create_user('a2', 'b2', 'c2')
     user2.save()
     self.project.developer.add(user2)
     issue.assignee.add(user2)
     response = self.client.get(
         reverse('backlog:backlog',
                 kwargs={'project': self.project.name_short}))
     self.assertContains(response, str(user2.username) + ': 2.5')
     self.assertContains(response, str(self.user.username) + ': 2.5')
     issue2 = Issue(title="Test-Issue",
                    kanbancol=kanbancol,
                    project=self.project,
                    type="Bug",
                    sprint=self.sprint,
                    storypoints=5)
     issue2.save()
     issue2.assignee.add(self.user)
     response = self.client.get(
         reverse('backlog:backlog',
                 kwargs={'project': self.project.name_short}))
     self.assertContains(response, str(user2.username) + ': 2.5')
     self.assertContains(response, str(self.user.username) + ': 7.5')
コード例 #14
0
class TestActivityPermissions(TestCase):
    @classmethod
    def setUpTestData(cls):
        # NOTE: if you modify these elements they need to be created in setUp(), instead of here
        cls.user = get_user_model().objects.create_user(
            'test', '*****@*****.**', 'test1234')
        cls.user2 = get_user_model().objects.create_user(
            'foo', '*****@*****.**', 'foo1234')

    def setUp(self):
        self.client.force_login(self.user)
        # NOTE: these elements get modified by some testcases, so they should NOT be created in setUpTestData()
        # create a default project
        project_settings["manager"] = (self.user.pk)
        self.client.post(reverse('project:create'), project_settings)
        self.project = Project.objects.filter(
            name_short=project_settings['name_short']).first()

        # create a kanban column for the issue
        self.column = KanbanColumn(name='Column',
                                   position=4,
                                   project=self.project)
        self.column.save()

        # create an issue
        issue_settings['kanbancol'] = self.column.pk
        self.client.post(
            reverse('issue:create',
                    kwargs={'project': self.project.name_short}),
            issue_settings)
        self.issue = Issue.objects.filter(project=self.project.pk).first()

    def test_user_has_permissions(self):
        clean_actions = actor_stream(self.user)
        filtered_actions = check_activity_permissions(self.user, clean_actions)
        # the two query sets must be equal when the user has permissions on the issue/project
        self.assertQuerysetEqual(clean_actions,
                                 [a.__repr__() for a in filtered_actions])

    def test_user_has_no_permissions(self):
        self.client.force_login(self.user2)
        clean_actions = actor_stream(self.user)
        filtered_actions = check_activity_permissions(self.user2,
                                                      clean_actions)
        # the filtered actions must be empty because the user2 has no permissions
        self.assertEqual(filtered_actions.count(), 0)
        pass
コード例 #15
0
 def setUpTestData(cls):
     # NOTE: if you modify those element they need to be created in setUp, instead of here
     cls.user = get_user_model().objects.create_user('test', '*****@*****.**', 'test1234')
     cls.project = Project(creator=cls.user, name_short='PRJ')
     cls.project.save()
     cls.project.developer.add(cls.user)
     cls.kanbancol = KanbanColumn(project=cls.project, position=4, name='test')
     cls.kanbancol.save()
コード例 #16
0
 def setUp(self):
     # NOTE: these elements get modified by some testcases, so they should NOT be created in setUpTestData()
     self.user = get_user_model().objects.create_user('a', 'b', 'c')
     self.user.first_name = 'Alice'
     self.user.last_name = 'Bla'
     self.user.save()
     self.user2 = get_user_model().objects.create_user('d', 'e', 'f')
     self.user2.first_name = 'Bob'
     self.user2.last_name = 'Blub'
     self.user2.save()
     self.project = Project(creator=self.user, name_short='PRJ')
     self.project.save()
     self.project2 = Project(creator=self.user, name_short='TPJ')
     self.project2.save()
     self.project.developer.add(self.user)
     self.project2.developer.add(self.user)
     self.project.developer.add(self.user2)
     kanbancol = KanbanColumn(project=self.project, position=4, name='ReallyDone')
     kanbancol.save()
コード例 #17
0
 def setUp(self):
     self.user = get_user_model().objects.create_user('a', 'b', 'c')
     self.user.first_name = 'Alice'
     self.user.last_name = 'Bla'
     self.user.save()
     self.user2 = get_user_model().objects.create_user('d', 'e', 'f')
     self.user2.first_name = 'Bob'
     self.user2.last_name = 'Blub'
     self.user2.save()
     self.project = Project(creator=self.user, name_short='PRJ')
     self.project.save()
     self.project2 = Project(creator=self.user, name_short='TPJ')
     self.project2.save()
     self.project.developer.add(self.user)
     self.project2.developer.add(self.user)
     self.project.developer.add(self.user2)
     kanbancol = KanbanColumn(project=self.project,
                              position=4,
                              name='ReallyDone')
     kanbancol.save()
コード例 #18
0
    def setUp(self):
        self.client.force_login(self.user)
        # create a default project
        project_settings["manager"] = (self.user.pk)
        self.client.post(reverse('project:create'), project_settings)
        self.project = Project.objects.filter(
            name_short=project_settings['name_short']).first()

        # create a kanban column for the issue
        self.column = KanbanColumn(name='Column',
                                   position=4,
                                   project=self.project)
        self.column.save()

        # create an issue
        issue_settings['kanbancol'] = self.column.pk
        self.client.post(
            reverse('issue:create',
                    kwargs={'project': self.project.name_short}),
            issue_settings)
        self.issue = Issue.objects.filter(project=self.project.pk).first()
コード例 #19
0
    def setUp(self):
        self.client.force_login(self.user)
        # NOTE: these elements get modified by some testcases, so they should NOT be created in setUpTestData()
        # create a default project
        project_settings["manager"] = (self.user.pk)
        self.client.post(reverse('project:create'), project_settings)
        self.project = Project.objects.filter(
            name_short=project_settings['name_short']).first()

        # create a kanban column for the issue
        self.column = KanbanColumn(name='Column',
                                   position=4,
                                   project=self.project)
        self.column.save()

        # create an issue
        issue_settings['kanbancol'] = self.column.pk
        self.client.post(
            reverse('issue:create',
                    kwargs={'project': self.project.name_short}),
            issue_settings)
        self.issue = Issue.objects.filter(project=self.project.pk).first()
コード例 #20
0
 def setUpTestData(cls):
     # NOTE: if you modify these elements they need to be created in setUp(), instead of here
     cls.user = get_user_model().objects.create_user('test', '*****@*****.**', 'test1234')
     cls.project = Project(creator=cls.user, name_short='PRJ')
     cls.project.save()
     cls.project.developer.add(cls.user)
     cls.kanbancol = KanbanColumn(project=cls.project, position=4, name='test')
     cls.kanbancol.save()
     cls.issue = Issue(project=cls.project, due_date='2016-12-16', kanbancol=cls.kanbancol, storypoints='3')
     cls.issue.save()
     cls.issue2 = Issue(project=cls.project, due_date='2016-12-16', kanbancol=cls.kanbancol, storypoints='3')
     cls.time = timezone.now().replace(microsecond=100000)
     cls.timestamp = cls.time.timestamp()
コード例 #21
0
ファイル: test_timelog_api.py プロジェクト: yasir2000/iguana
 def setUpTestData(cls):
     # NOTE: if you modify these elements they need to be created in setUp(), instead of here
     cls.user = get_user_model().objects.create_user(
         'test', '*****@*****.**', 'test1234')
     cls.project = Project(creator=cls.user, name_short='PRJ')
     cls.project.save()
     cls.project.developer.add(cls.user)
     cls.project2 = Project(creator=cls.user, name_short='PRJ2')
     cls.project2.save()
     cls.project2.developer.add(cls.user)
     cls.kanbancol = KanbanColumn(project=cls.project,
                                  position=4,
                                  name='test')
     cls.kanbancol.save()
     cls.time = timezone.now().replace(microsecond=100000)
     cls.timestring = cls.time.strftime("%Y-%m-%d %H:%M:%S")
     cls.timestamp = cls.time.timestamp()
コード例 #22
0
    def setUpTestData(cls):
        # NOTE: if you modify those elements they need to be created in setUp, instead of here
        cls.user = get_user_model().objects.create_user(
            'test', '*****@*****.**', 'test1234')
        cls.user2 = get_user_model().objects.create_user(
            'tast', '*****@*****.**', 'test1234')
        cls.user3 = get_user_model().objects.create_user(
            'tust', '*****@*****.**', 'test1234')

        cls.project = Project(creator=cls.user, name_short=proj_short)
        cls.project.save()
        cls.project.developer.add(cls.user)

        cls.tag1 = Tag(project=cls.project, tag_text='backend', color='RED')
        cls.tag2 = Tag(project=cls.project, tag_text='frontend', color='BLUE')
        cls.tag1.save()
        cls.tag2.save()
        cls.kanbancol = KanbanColumn(project=cls.project,
                                     position=4,
                                     name='test')
        cls.kanbancol.save()
コード例 #23
0
class CreateEditDetailTest(TestCase):
    @classmethod
    def setUpTestData(cls):
        # NOTE: if you modify those elements they need to be created in setUp, instead of here
        cls.user = get_user_model().objects.create_user('lalala', 'b', 'c')
        cls.user2 = get_user_model().objects.create_user('lululu', 'e', 'f')

    def setUp(self):
        self.client.force_login(self.user)
        # NOTE: this element gets modified by some of those tests, so this shall NOT be created in setUpTestData()
        self.project = Project(creator=self.user, name_short='PRJ')
        self.project.save()
        self.project.manager.add(self.user)
        self.project.developer.add(self.user)
        # NOTE: this element gets modified by some of those tests, so this shall NOT be created in setUpTestData()
        self.column = KanbanColumn(name='Column',
                                   position=4,
                                   project=self.project)
        self.column.save()

    def test_view_and_template(self):
        # TODO TESTCASE see invite_users/testcases/test_invite_users.py as example
        pass

    def test_redirect_to_login_and_login_required(self):
        # TODO TESTCASE see invite_users/testcases/test_invite_users.py as example
        pass

    def test_user_passes_test_mixin(self):
        # TODO TESTCASE
        pass

    def test_create_and_edit_issues_with_get_requests_disabled(self):
        # TODO TESTCASE
        pass

    def test_title_required(self):
        # TODO TESTCASE
        pass

    def test_only_issues_of_this_project_visible(self):
        # TODO TESTCASE
        pass

    def test_detail_view(self):
        # TODO TESTCASE
        pass

    def test_delete(self):
        # TODO TESTCASE
        pass

    def test_delete_with_timelog(self):
        issue = Issue(title="foo")
        issue.project = self.project
        issue.save()
        Timelog(user=self.user, issue=issue, time=timedelta(1)).save()

        response = self.client.post(reverse('issue:delete',
                                            kwargs={
                                                'project':
                                                self.project.name_short,
                                                'sqn_i': issue.number
                                            }), {'delete': 'true'},
                                    follow=True)
        self.assertRedirects(
            response,
            reverse('issue:backlog',
                    kwargs={'project': self.project.name_short}))
        self.assertContains(response, "foo")
        self.assertContains(response, "logged time")

    def test_archive_and_unarchive_single_issue_function(self):
        issue = Issue(title="bar", project=self.project)
        issue.save()
        self.assertFalse(issue.archived)
        n = Issue.objects.archived().count()

        values = {'sqn_i': issue.number}
        response = self.client.post(
            reverse('issue:archiveissue',
                    kwargs={'project': self.project.name_short}), values)
        self.assertRedirects(
            response,
            reverse('issue:detail',
                    kwargs={
                        'project': self.project.name_short,
                        'sqn_i': issue.number
                    }))
        issue.refresh_from_db()

        self.assertEqual(Issue.objects.archived().count(), (n + 1))
        self.assertTrue(issue.archived)

        values = {'sqn_i': issue.number}
        response = self.client.post(
            reverse('issue:unarchiveissue',
                    kwargs={'project': self.project.name_short}), values)
        self.assertRedirects(
            response,
            reverse('issue:detail',
                    kwargs={
                        'project': self.project.name_short,
                        'sqn_i': issue.number
                    }))
        issue.refresh_from_db()

        self.assertEqual(Issue.objects.archived().count(), n)
        self.assertFalse(issue.archived)

    def test_archive_and_unarchive_multiple_issue_function(self):
        # TODO TESTCASE
        pass

    def test_delete_issue(self):
        issue = Issue(title="foo123")
        issue.project = self.project
        issue.save()

        response = self.client.post(
            reverse('issue:delete',
                    kwargs={
                        'project': self.project.name_short,
                        'sqn_i': issue.number
                    }), {'delete': 'true'})
        self.assertRedirects(
            response,
            reverse('issue:backlog',
                    kwargs={'project': self.project.name_short}))
        response = self.client.get(response['location'])
        self.assertTemplateUsed(response, 'issue/backlog_list.html')
        self.assertNotContains(response, "foo123")

    def test_keep_and_dont_delete_issue(self):
        issue = Issue(title="foo123", project=self.project)
        issue.save()

        response = self.client.post(
            reverse('issue:delete',
                    kwargs={
                        'project': self.project.name_short,
                        'sqn_i': issue.number
                    }), {'keep': 'true'})
        self.assertRedirects(
            response,
            reverse('issue:detail',
                    kwargs={
                        'project': self.project.name_short,
                        'sqn_i': issue.number
                    }))
        response = self.client.get(response['location'])
        self.assertTemplateUsed(response, 'issue/issue_detail_view.html')
        self.assertContains(response, "foo123")

    def test_create_and_edit_issue(self):
        values = {
            'title': "Test-Issue",
            'kanbancol': self.column.pk,
            'due_date': datetime.date.today(),
            'type': "Bug",
            'assignee': (self.user.pk),
            'priority': 2,
            'description': "Fancy description",
            'storypoints': 5,
        }
        response = self.client.post(
            reverse('issue:create',
                    kwargs={'project': self.project.name_short}), values)
        self.assertRedirects(
            response,
            reverse('issue:backlog',
                    kwargs={'project': self.project.name_short}))
        response = self.client.get(response['location'])
        self.assertEqual(response.status_code, 200)
        self.assertEqual(self.project.issue.count(), 1)

        # assert that values and especially ticket ID was written correctly
        self.assertEqual(Issue.objects.count(), 1)
        currentIssue = Issue.objects.get(pk=1)
        for key in values:
            if key == 'kanbancol':
                self.assertEqual(
                    currentIssue.__getattribute__(key).pk, values[key])
            elif key == 'assignee':
                self.assertEqual(
                    currentIssue.__getattribute__(key).all().count(), 1)
                self.assertEqual(
                    currentIssue.__getattribute__(key).all().get(pk=1).pk,
                    values[key])
            else:
                self.assertEqual(currentIssue.__getattribute__(key),
                                 values[key])

        self.assertEqual(currentIssue.__str__(), values['title'])
        self.assertEqual(Project.objects.get(pk=1).nextTicketId, 2)
        self.assertEqual(currentIssue.number, 1)

        # edit issue
        values['priority'] = 3

        response = self.client.post(
            reverse('issue:edit',
                    kwargs={
                        'project': self.project.name_short,
                        'sqn_i': 1
                    }), values)
        self.assertRedirects(
            response,
            reverse('issue:detail',
                    kwargs={
                        'project': self.project.name_short,
                        'sqn_i': 1
                    }))
        response = self.client.get(response['location'])
        self.assertEqual(response.status_code, 200)
        self.assertEqual(currentIssue.number, 1)

        currentIssue = Issue.objects.get(pk=1)
        for key in values:
            if key == 'kanbancol':
                self.assertEqual(
                    currentIssue.__getattribute__(key).pk, values[key])
            elif key == 'assignee':
                self.assertEqual(
                    currentIssue.__getattribute__(key).all().count(), 1)
                self.assertEqual(
                    currentIssue.__getattribute__(key).all().get(pk=1).pk,
                    values[key])
            else:
                self.assertEqual(currentIssue.__getattribute__(key),
                                 values[key])

        # ticket ID must not change!
        self.assertEqual(currentIssue.number, 1)
        self.assertEqual(Project.objects.get(pk=1).nextTicketId, 2)

        # check if blank fields are working
        values['assignee'] = ()
        values['due_date'] = ''
        values['description'] = ''

        response = self.client.post(
            reverse('issue:edit',
                    kwargs={
                        'project': self.project.name_short,
                        'sqn_i': 1
                    }), values)
        self.assertRedirects(
            response,
            reverse('issue:detail',
                    kwargs={
                        'project': self.project.name_short,
                        'sqn_i': 1
                    }))
        response = self.client.get(response['location'])
        self.assertEqual(response.status_code, 200)

        currentIssue = Issue.objects.get(pk=1)
        for key in values:
            if key == 'kanbancol':
                self.assertEqual(
                    currentIssue.__getattribute__(key).pk, values[key])
            elif key == 'assignee':
                self.assertEqual(
                    currentIssue.__getattribute__(key).all().count(), 0)
            elif key == 'due_date':
                self.assertEqual(currentIssue.__getattribute__(key), None)
            elif key == 'storypoints':
                self.assertEqual(currentIssue.__getattribute__(key), 5)
            else:
                self.assertEqual(currentIssue.__getattribute__(key),
                                 values[key])

        # ticket ID must not change!
        self.assertEqual(currentIssue.number, 1)
        self.assertEqual(Project.objects.get(pk=1).nextTicketId, 2)

    def test_validation(self):
        values = {
            'title': "Test-Issue",
            'kanbancol': self.column.pk,
            'due_date': datetime.date(2016, 10, 1),
            'type': "Bug",
            'assignee': (self.user.pk),
            'priority': 2,
            'description': "Fancy description",
            'storypoints': -1,
        }

        errormsg = "Enter a positive storypoints amount!"

        response = self.client.post(
            reverse('issue:create',
                    kwargs={'project': self.project.name_short}), values)
        self.assertFormError(response, 'form', 'storypoints', errormsg)

        # set date to yesterday
        values['storypoints'] = 1
        values['due_date'] = datetime.date.today() - timedelta(1)

        errormsg = "Enter a date starting from today"

        response = self.client.post(
            reverse('issue:create',
                    kwargs={'project': self.project.name_short}), values)
        self.assertFormError(response, 'form', 'due_date', errormsg)

    def test_dependsOn(self):
        values = {
            'title': "Issue 1",
            'kanbancol': self.column.pk,
            'due_date': datetime.date.today(),
            'type': "Bug",
            'assignee': (self.user.pk),
            'priority': 2,
            'description': "Fancy description",
            'storypoints': 5,
            'dependsOn': (),
        }
        response = self.client.post(
            reverse('issue:create',
                    kwargs={'project': self.project.name_short}), values)
        self.assertRedirects(
            response,
            reverse('issue:backlog',
                    kwargs={'project': self.project.name_short}))
        response = self.client.get(response['location'])
        self.assertEqual(response.status_code, 200)

        # create second issue depending on first issue
        values['title'] = "Issue 2"
        values['dependsOn'] = (1)

        response = self.client.post(
            reverse('issue:create',
                    kwargs={'project': self.project.name_short}), values)
        self.assertRedirects(
            response,
            reverse('issue:backlog',
                    kwargs={'project': self.project.name_short}))
        response = self.client.get(response['location'])
        self.assertEqual(response.status_code, 200)

        self.assertEqual(Issue.objects.get(pk=2).dependsOn.count(), 1)
        self.assertEqual(
            Issue.objects.get(pk=2).dependsOn.first().title, 'Issue 1')

        # check that dependsOn works unidirectional
        self.assertEqual(Issue.objects.get(pk=1).dependsOn.count(), 0)

    # TODO TODO TODO TODO TODO TESTCASE broken test, is not tested yet
    def test_assign_tag_view(self):
        issue = Issue(title="Test-Issue",
                      project=self.project,
                      kanbancol=self.column,
                      type="Bug")
        issue.save()
        t0 = 'first_tag'
        tag0 = Tag(tag_text=t0, project=self.project)
        tag0.save()
        t1 = 'second_tag'
        tag1 = Tag(tag_text=t1, project=self.project)
        tag1.save()
        t2 = 'third_tag'
        tag2 = Tag(tag_text=t2, project=self.project)
        tag2.save()
        values = {
            # first_tag
            'tags': (1)
        }
        response = self.client.post(
            reverse('issue:edit',
                    kwargs={
                        'project': self.project.name_short,
                        'sqn_i': 1
                    }), values)
        # please don't ask me why the following (which would be a way better assert) doesn't work
        # self.assertContains(response, t0)
        self.assertIn(t0, str(response.content))
        self.assertEqual(Issue.objects.count(), 1)
        # TODO
        """
        self.assertEqual(issue.tags.count(), 1)
        self.assertEqual(issue.tags.first().text, t0)
        """
        response = self.client.get(
            reverse('issue:edit',
                    kwargs={
                        'project': self.project.name_short,
                        'sqn_i': 1
                    }))

        return
        # TODO TODO TODO the following doesn't work because t0 doesn't appear in the response anymore
        self.assertContains(response, t0)
        # self.assertIn(t0, str(response.content))
        values = {
            # 'tags': [t2, t1],
            'tags': [(3), (2)],
        }
        response = self.client.post(
            reverse('issue:edit',
                    kwargs={
                        'project': self.project.name_short,
                        'sqn_i': 1
                    }), values)
        self.assertContains(response, t0)
        self.assertContains(response, t2)
        self.assertContains(response, t1)

        response = self.client.get(
            reverse('issue:edit',
                    kwargs={
                        'project': self.project.name_short,
                        'sqn_i': 1
                    }))
        self.assertContains(response, t0)
        self.assertContains(response, t2)
        self.assertContains(response, t1)

        # TODO TESTCASE
        # TODO test delete
        # TODO test assign is only possible for tags of relative project

    # TODO also test this for creation of tags, because the url-scheme differs a bit

    def test_managerfunctions(self):
        issue1 = Issue(title="issue1",
                       project=self.project,
                       kanbancol=self.column)
        issue1.save()
        sprint_current = Sprint(project=self.project,
                                startdate=(timezone.now() - timedelta(days=1)))
        sprint_current.save()
        sprint_old = Sprint(project=self.project,
                            startdate=(timezone.now() - timedelta(days=14)),
                            enddate=(timezone.now() - timedelta(days=1)))
        sprint_old.save()

        issues_wo_sprint = Issue.objects.without_sprint()
        self.assertTrue(issue1 in issues_wo_sprint)

        issue1.sprint = sprint_current
        issue1.save()
        issues_cur_sprint = Issue.objects.current_sprint()
        self.assertTrue(issue1 in issues_cur_sprint)
        issue1.sprint = sprint_old
        issue1.save()
        issues_cur_sprint = Issue.objects.current_sprint()
        issues_wo_sprint = Issue.objects.without_sprint()
        self.assertFalse(issue1 in issues_cur_sprint)
        self.assertFalse(issue1 in issues_wo_sprint)

    def test_assign_to_me_remove_from_me(self):
        issue = Issue(title="Test-Issue",
                      project=self.project,
                      kanbancol=self.column,
                      type="Bug")
        issue.save()
        response = self.client.post(
            reverse('issue:assigntome',
                    kwargs={'project': self.project.name_short}),
            {'sqn_i': issue.number})
        self.assertIn(self.user, issue.assignee.all())
        response = self.client.post(
            reverse('issue:rmfromme',
                    kwargs={'project': self.project.name_short}),
            {'sqn_i': issue.number})
        self.assertNotIn(self.user, issue.assignee.all())
        response = self.client.post(reverse(
            'issue:rmfromme', kwargs={'project': self.project.name_short}),
                                    {'sqn_i': issue.number},
                                    follow=True)

        self.assertContains(
            response,
            'Issue was not in selected sprint, not performing any action')

    def test_add_and_remove_to_kanbancol(self):
        # TODO TESTCASE
        pass

    def test_next_parameter_in_post_requests(self):
        issue = Issue(title="Test-Issue",
                      project=self.project,
                      kanbancol=self.column,
                      type="Bug")
        issue.save()
        response = self.client.post(reverse(
            'issue:assigntome', kwargs={'project': self.project.name_short}), {
                'sqn_i': issue.number,
                'next': '/timelog'
            },
                                    follow=True)
        self.assertRedirects(response, reverse('timelog:loginfo'))
        response = self.client.post(reverse(
            'issue:rmfromme', kwargs={'project': self.project.name_short}), {
                'sqn_i': issue.number,
                'next': '/timelog'
            },
                                    follow=True)
        self.assertRedirects(response, reverse('timelog:loginfo'))
        response = self.client.post(
            reverse('issue:archiveissue',
                    kwargs={'project': self.project.name_short}), {
                        'sqn_i': issue.number,
                        'next': '/timelog'
                    },
            follow=True)
        self.assertRedirects(response, reverse('timelog:loginfo'))
        response = self.client.post(reverse(
            'issue:unarchiveissue',
            kwargs={'project': self.project.name_short}), {
                'sqn_i': issue.number,
                'next': '/timelog'
            },
                                    follow=True)
        self.assertRedirects(response, reverse('timelog:loginfo'))
コード例 #24
0
class TimelogTest(TestCase):
    @classmethod
    def setUpTestData(cls):
        # NOTE: if you modify these elements they need to be created in setUp(), instead of here
        cls.user = get_user_model().objects.create_user('test', '*****@*****.**', 'test1234')
        cls.user2 = get_user_model().objects.create_user('test2', '*****@*****.**', 'test1234')
        cls.user.save()
        cls.user2.save()

    def setUp(self):
        self.client.force_login(self.user)
        # NOTE: these elements get modified by some testcases, so they should NOT be created in setUpTestData()
        self.project = Project(creator=self.user, name_short='PRJ', activity_only_for_managers=False)
        self.project.save()
        self.project.developer.add(self.user)

        self.project2 = Project(creator=self.user, activity_only_for_managers=True, name_short='PRJJ')
        self.project2.save()
        self.project2.manager.add(self.user)
        self.project2.developer.add(self.user, self.user2)

        self.kanbancol = KanbanColumn(project=self.project, position=4, name='test')
        self.kanbancol.save()
        self.issue = Issue(title='a very very very very very very very long issue title',
                           project=self.project,
                           due_date='2016-12-16',
                           kanbancol=self.kanbancol,
                           storypoints='3'
                           )
        self.issue.save()
        self.issue.assignee.add(self.user)
        self.issue2 = Issue(title='second_issue', project=self.project)
        self.issue2.save()
        self.issue2.assignee.add(self.user)
        self.time = now().strftime("%Y-%m-%d %H:%M:%S")

        # success logedit_address_kwargs
        self.sqn_l1_address_kwarg = {"project": self.issue.project.name_short,
                                     "sqn_i": self.issue.number,
                                     "sqn_l": 1
                                     }

    def test_view_and_template(self):
        # TODO TESTCASE see invite_users
        #      use view_and_template()
        # TODO which views?
        #      - timelog:loginfo
        #      - timelog:archiv
        #      - issue:log
        #      - issue:logs with (?P<sqn_l>[0-9]+)/edit/ (logedit)
        #      - issue:logs with  (?P<sqn_l>[0-9]+)/delete/? (logdelete)
        #      - issue:logedit
        #      - issue:logdelete
        #      - ProjectUserTimelogView - project:usertimelog
        #      - ProjectDetailTimelogView - project:timelog
        #      - ...
        pass

    def test_redirect_to_login_and_login_required(self):
        self.client.logout()
        # TODO TESTCASE see invite_users
        #      redirect_to_login_and_login_required()
        # TODO which views?
        #      - timelog:loginfo
        #      - timelog:archiv
        #      - issue:log
        #      - issue:logs with (?P<sqn_l>[0-9]+)/edit/ (logedit)
        #      - issue:logs with  (?P<sqn_l>[0-9]+)/delete/? (logdelete)
        #      - issue:logedit
        #      - issue:logdelete
        #      - ProjectUserTimelogView - project:usertimelog
        #      - ProjectDetailTimelogView - project:timelog
        #      - ...
        pass

    def test_user_passes_test_mixin(self):
        # TODO TESTCASE
        #      - timelog:loginfo
        #      - timelog:archiv
        #      - issue:log
        #      - issue:logs with (?P<sqn_l>[0-9]+)/edit/ (logedit)
        #      - issue:logs with  (?P<sqn_l>[0-9]+)/delete/? (logdelete)
        #      - issue:logedit
        #      - issue:logdelete
        #      - ProjectUserTimelogView - project:usertimelog
        #      - ProjectDetailTimelogView - project:timelog
        #      - ...
        pass

    def test_log_time_and_redirect(self):
        response = self.client.post(reverse('issue:log', kwargs={"project": self.issue.project.name_short,
                                                                 "sqn_i": self.issue.number}),
                                    {'time': '1h30m', 'created_at': self.time},
                                    follow=True)
        self.assertRedirects(response, reverse('issue:detail', kwargs={'project': self.project.name_short,
                                                                       'sqn_i': 1}))

    # PER USER START
    def test_timelog_loginfo_per_user_only_visible_for_own_user(self):
        response = self.client.post(reverse('issue:log', kwargs={"project": self.issue.project.name_short,
                                                                 "sqn_i": self.issue.number}),
                                    {'time': '1h30m', 'created_at': self.time},
                                    follow=True)
        response = self.client.get(reverse('timelog:loginfo'))
        self.assertContains(response, "1 Hour and 30 Minutes")

        # tag filter issue title short
        self.assertContains(response, "...")

        self.client.logout()
        self.client.force_login(self.user2)

        response = self.client.post(reverse('issue:log', kwargs={"project": self.issue.project.name_short,
                                                                 "sqn_i": self.issue.number,
                                                                 }),
                                    {'time': '15m', 'created_at': self.time})
        self.client.logout()
        self.client.force_login(self.user)
        response = self.client.get(reverse('timelog:loginfo'))
        # first log
        self.assertContains(response, "1 Hour and 30 Minutes")
        # second log - different user
        self.assertNotContains(response, "15 Minutes")

    def test_timelog_loginfo_and_issue_loginfo_log_time_in_multiple_issues_and_projects_for_own_user(self):
        response = self.client.post(reverse('issue:log', kwargs={"project": self.issue.project.name_short,
                                                                 "sqn_i": self.issue.number}),
                                    {'time': '1h30m', 'created_at': self.time},
                                    follow=True)
        response = self.client.post(reverse('issue:log', kwargs={"project": self.issue.project.name_short,
                                                                 "sqn_i": self.issue2.number}),
                                    {'time': '15m', 'created_at': self.time},
                                    follow=True)
        response = self.client.get(reverse('timelog:loginfo'))
        # first log
        self.assertContains(response, "1 Hour and 30 Minutes")
        # second log - second issue
        self.assertContains(response, "15 Minutes")

        project2 = Project(creator=self.user, name_short='PRJ2')
        project2.save()
        project2.developer.add(self.user)
        # both are shown in timelog:loginfo
        response = self.client.get(reverse('timelog:loginfo'))
        self.assertContains(response, "1 Hour and 30 Minutes")
        self.assertContains(response, "15 Minutes")

        # additional log for a different project
        issue3 = Issue(title='third_issue', project=project2)
        issue3.save()
        issue3.assignee.add(self.user)
        response = self.client.post(reverse('issue:log', kwargs={"project": project2.name_short,
                                                                 "sqn_i": issue3.number}),
                                    {'time': '20m', 'created_at': self.time},
                                    follow=True)

        # all three are shown in timelog:loginfo
        response = self.client.get(reverse('timelog:loginfo'))
        self.assertContains(response, "1 Hour and 30 Minutes")
        self.assertContains(response, "15 Minutes")
        self.assertContains(response, "20 Minutes")

    # PER ISSUE START
    def test_log_time_per_issue_even_from_other_user(self):
        response = self.client.post(reverse('issue:log', kwargs={"project": self.issue.project.name_short,
                                                                 "sqn_i": self.issue.number}),
                                    {'time': '1h30m', 'created_at': self.time})
        response = self.client.post(reverse('issue:log', kwargs={"project": self.issue.project.name_short,
                                                                 "sqn_i": self.issue.number}),
                                    {'time': '15m', 'created_at': self.time})
        self.client.logout()
        self.project.developer.add(self.user2)
        self.issue.assignee.add(self.user2)
        self.client.force_login(self.user2)
        # second user log
        response = self.client.post(reverse('issue:log', kwargs={"project": self.issue.project.name_short,
                                                                 "sqn_i": self.issue.number}),
                                    {'time': '20m', 'created_at': self.time})
        response = self.client.get(reverse('issue:detail', kwargs={"project": self.issue.project.name_short,
                                                                   "sqn_i": self.issue.number}))
        # first log -  first user
        self.assertContains(response, "1 Hour and 30 Minutes")
        # second log - first user
        self.assertContains(response, "15 Minutes")
        # third log - second user
        self.assertContains(response, "20 Minutes")

    def test_log_time_in_future_fails(self):
        response = self.client.post(reverse('issue:log', kwargs={"project": self.issue.project.name_short,
                                                                 "sqn_i": self.issue.number}),
                                    {'time': '1h30m',
                                     'created_at': (now() + timedelta(days=1)).strftime("%Y-%m-%d %H:%M:%S")})
        self.assertEqual(response.status_code, 200)
        # still on the same page (issue:log)
        self.assertTemplateUsed(response, 'timelog/timelog_create.html')
        self.assertContains(response, 'The date entered must be today or lesser.')

    def test_log_time_delete_log_per_issue(self):
        response = self.client.post(reverse('issue:log', kwargs={"project": self.issue.project.name_short,
                                                                 "sqn_i": self.issue.number}),
                                    {'time': '1h30m', 'created_at': self.time})
        response = self.client.post(reverse('issue:log', kwargs={"project": self.issue.project.name_short,
                                                                 "sqn_i": self.issue.number}),
                                    {'time': '2h', 'created_at': self.time})

        response = self.client.post(reverse('issue:logdelete', kwargs={"project": self.issue.project.name_short,
                                                                       "sqn_i": self.issue.number,
                                                                       "sqn_l": 2}),
                                    {'delete': 'true'}, follow=True)
        self.assertTemplateUsed(response, 'timelog/timelog_list_peruser.html')
        self.assertContains(response, "1 Hour and 30 Minutes")
        self.assertNotContains(response, "2 Hours")

    def test_log_time_keep_log_per_issue(self):
        response = self.client.post(reverse('issue:log', kwargs={"project": self.issue.project.name_short,
                                                                 "sqn_i": self.issue.number}),
                                    {'time': '1h30m', 'created_at': self.time})
        response = self.client.post(reverse('issue:logdelete', kwargs=self.sqn_l1_address_kwarg),
                                    {'keep': 'true'}, follow=True)
        self.assertTemplateUsed(response, 'timelog/timelog_list_peruser.html')
        self.assertContains(response, "1 Hour and 30 Minutes")

    def test_log_time_edit_log_per_issue(self):
        response = self.client.post(reverse('issue:log', kwargs={"project": self.issue.project.name_short,
                                                                 "sqn_i": self.issue.number}),
                                    {'time': '1d1h30m', 'created_at': self.time})

        response = self.client.get(reverse('issue:detail', kwargs={"project": self.issue.project.name_short,
                                                                   "sqn_i": self.issue.number}))
        self.assertContains(response, "1 Day, 1 Hour and 30 Minutes")

        response = self.client.get(reverse('issue:logedit', kwargs=self.sqn_l1_address_kwarg))
        self.assertContains(response, "1d 1h 30m")

        response = self.client.post(reverse('issue:logedit', kwargs=self.sqn_l1_address_kwarg),
                                    {'time': '3h', 'created_at': self.time, 'save_timelog_change': 'true'})
        response = self.client.get(reverse('issue:detail', kwargs={"project": self.issue.project.name_short,
                                                                   "sqn_i": self.issue.number}))
        self.assertContains(response, "3 Hours")

    def test_edit_and_delete_as_other_user(self):
        response = self.client.post(reverse('issue:log', kwargs={"project": self.issue.project.name_short,
                                                                 "sqn_i": self.issue.number}),
                                    {'time': '1h30m', 'created_at': self.time})
        self.assertEqual(str(Timelog.objects.filter(issue=self.issue)[0].time), "1:30:00")
        # test to edit or delete as other user - should not be possible
        self.client.logout()
        self.client.force_login(self.user2)

        user_doesnt_pass_test_and_gets_404(self, 'issue:logedit', address_kwargs=self.sqn_l1_address_kwarg)
        self.assertEqual(str(Timelog.objects.filter(issue=self.issue)[0].time), "1:30:00")
        user_doesnt_pass_test_and_gets_404(self, 'issue:logdelete', address_kwargs=self.sqn_l1_address_kwarg)
        self.assertEqual(str(Timelog.objects.filter(issue=self.issue)[0].time), "1:30:00")

    # PROJECT START
    def test_project_detail_timelog_from_different_issuesss_of_project_even_from_other_users(self):
        cases = ['2d 2h 5m', '1d 1h 5m', '2d 5m', '1d 3h']
        mappings = ['2 Days, 2 Hours and 5 Minutes', '1 Day, 1 Hour and 5 Minutes',
                    '2 Days and 5 Minutes', '1 Day and 3 Hours']
        sums = ['3 Days, 3 Hours and 10 Minutes', '3 Days, 3 Hours and 5 Minutes']
        # first user, first issue
        response = self.client.post(reverse('timelog:loginfo'),
                                    {'time': cases[0], 'created_at': self.time, 'issue': self.issue.id},
                                    follow=True)
        # first user, second issue
        response = self.client.post(reverse('timelog:loginfo'),
                                    {'time': cases[1], 'created_at': self.time, 'issue': self.issue2.id},
                                    follow=True)
        self.client.logout()
        self.project.developer.add(self.user2)
        self.issue.assignee.add(self.user2)
        self.issue2.assignee.add(self.user2)
        self.client.force_login(self.user2)
        # second user
        # first user, first issue
        response = self.client.post(reverse('timelog:loginfo'),
                                    {'time': cases[2], 'created_at': self.time, 'issue': self.issue.id},
                                    follow=True)
        # first user, second issue
        response = self.client.post(reverse('timelog:loginfo'),
                                    {'time': cases[3], 'created_at': self.time, 'issue': self.issue2.id},
                                    follow=True)

        response = self.client.get(reverse('project:timelog', kwargs={"project": self.issue.project.name_short}))
        for user in self.project.developer.all():
            self.assertContains(response, user.username)

        for i in range(4):
            self.assertContains(response, mappings[i])

        # sums of both users
        self.assertContains(response, 'total: '+sums[0])
        self.assertContains(response, 'total: '+sums[1])

    def test_project_detail_timelog_username_appears(self):
        for dev in self.project.developer.all():
            response = self.client.get(reverse('project:usertimelog', kwargs={"project": self.issue.project.name_short,
                                                                              "username": dev.username}))
        self.assertContains(response, dev.username)

    def test_timelog_edit_render_value_issue_logedit(self):
        cases = ['1d 1h 5m', '1d 5m', '1d 3h',
                 '1h 5m', '1d', '3h', '5m'
                 ]
        for i in range(len(cases)):
            response = self.client.post(reverse('timelog:loginfo'),
                                        {'time': cases[i], 'created_at': self.time, 'issue': self.issue.id},
                                        follow=True)
            response = self.client.get(reverse('issue:logedit',
                                               kwargs={"project": self.issue.project.name_short,
                                                       "sqn_i": self.issue.number, "sqn_l": i+1}))
            self.assertContains(response, cases[i])

    def test_timelog_loginfo(self):
        cases = ['2d 2h 5m', '1d 1h 5m', '1d 5m', '1d 3h',
                 '1h 5m', '1d', '3h', '5m', '1m'
                 ]
        for i in range(len(cases)):
            response = self.client.post(reverse('timelog:loginfo'),
                                        {'time': cases[i], 'created_at': self.time, 'issue': self.issue.id},
                                        follow=True)
            log = Timelog.objects.get(id=i+1)
            response = self.client.get(reverse('timelog:loginfo'))
            self.assertContains(response, duration(log.time))

    def test_timelog_model_str_method(self):
        response = self.client.post(reverse('timelog:loginfo'),
                                    {'time': '2h30m', 'created_at': self.time, 'issue': self.issue.id},
                                    follow=True)
        log = Timelog.objects.get(id=1)
        self.assertEqual(str(log), "logged time: {} for issue: {}".format(log.time, log.issue))

    def test_project_timelogs_only_for_manager_setting(self):
        response = self.client.get(reverse('project:timelog', kwargs={"project": self.project2.name_short}))
        for user in self.project2.developer.all():
            self.assertContains(response, user.username)
        response = self.client.get(reverse('project:usertimelog',
                                   kwargs={"project": self.project2.name_short, "username": self.user2.username}),
                                   follow=True)
        self.assertContains(response, self.user2.username)
        self.client.force_login(self.user2)
        response = self.client.get(reverse('project:timelog', kwargs={"project": self.project2.name_short}))
        self.assertRedirects(response,
                             reverse('project:usertimelog',
                                     kwargs={"project": self.project2.name_short, "username": self.user2.username}
                                     )
                             )
        response = self.client.get(reverse('project:usertimelog',
                                   kwargs={"project": self.project2.name_short, "username": self.user.username}),
                                   follow=True)
        self.assertRedirects(response,
                             reverse('project:usertimelog',
                                     kwargs={"project": self.project2.name_short, "username": self.user2.username}
                                     )
                             )
        self.project2.activity_only_for_managers = False
        self.project2.save()
        response = self.client.get(reverse('project:timelog', kwargs={"project": self.project2.name_short}))
        for user in self.project2.developer.all():
            self.assertContains(response, user.username)
        response = self.client.get(reverse('project:usertimelog',
                                   kwargs={"project": self.project2.name_short, "username": self.user.username}),
                                   follow=True)
        self.assertContains(response, self.user.username)

    def test_timelog_archiv(self):
        response = self.client.get(reverse('timelog:archiv'))
        response = self.client.get(reverse('timelog:archiv')+'?page=2')
コード例 #25
0
class AttachmentTest(TestCase):
    @classmethod
    def setUpTestData(cls):
        # NOTE: if you modify those elements they need to be created in setUp, instead of here
        cls.user = get_user_model().objects.create_user('a', 'b', 'c')
        cls.user2 = get_user_model().objects.create_user('d', 'e', 'f')

    def setUp(self):
        # NOTE: these element gets modified by some of those tests, so they should NOT be created in setUpTestData()
        self.client.force_login(self.user)
        self.project = Project(creator=self.user, name_short=proj_short)
        self.project.save()
        self.project.manager.add(self.user)
        self.project.developer.add(self.user)
        self.column = KanbanColumn(name='Column', position=4, project=self.project)
        self.column.save()
        self.issue = Issue(title="Test-Issue", project=self.project, kanbancol=self.column, type="Bug")
        self.issue.save()

    def test_view_and_template(self):
        # TODO TESTCASE invite_users
        #      use view_and_template()
        # TODO which views?
        #      - issue:download_attachment
        #      - issue:delete_attachment
        #      - ...
        pass

    def test_redirect_to_login_and_login_required(self):
        self.client.logout()
        # TODO TESTCASE invite_users
        #      redirect_to_login_and_login_required()
        # TODO which views?
        #      - issue:download_attachment
        pass

    def test_attachments_from_other_issues_of_same_project_invisible(self):
        # TODO TESTCASE
        pass

    def test_upload_attachment_with_get_request_disabled(self):
        # TODO TESTCASE
        pass

    def test_file_size_restriction(self):
        # verify that the allowed file size (attachment) is actually limited
        huge_file = TEST_FILE_PATH+'/16mb.txt'
        f = open(huge_file, "r")
        file_dict = {
            "file": f,
        }
        response = self.client.post(reverse('issue:detail', kwargs={'project': self.project.name_short,
                                            'sqn_i': self.issue.number}), file_dict)
        f.close()
        # TODO TESTCASE execute in try-except block and delete the file in except
        self.assertContains(response, "The uploaded file exceeds the allowed file size of: ")

    def test_create_and_download_attachment(self):
        # create file for uploading
        filecontent = 'Hello World'
        temp = tempfile.NamedTemporaryFile(delete=False)
        temp.write(filecontent.encode())
        temp.close()

        f = File(open(temp.name, 'r'))
        attachment = Attachment(file=f, creator=self.user, issue=self.issue)
        attachment.save()
        f.close()
        # delete the uploaded file locally
        os.unlink(temp.name)

        issue = Issue.objects.get(pk=self.issue.pk)
        self.assertEqual(self.issue.attachments.count(), 1)
        attachment = self.issue.attachments.first()
        self.assertEqual(attachment.creator, self.user)
        self.assertEqual(attachment.seqnum, 1)
        self.assertEqual(attachment.issue.nextAttachmentId, 2)

        response = self.client.get(reverse('issue:download_attachment',
                                   kwargs={'project': proj_short, 'sqn_i': 1, 'sqn_a': attachment.seqnum}))
        self.assertEqual(response.status_code, 200)
        self.assertEqual("application/octet-stream", response.get('Content-Type'))
        self.assertEqual(response.resolver_match.func.__name__, AttachmentDownloadView.as_view().__name__)
        # delete the uploaded file from the server
        os.unlink(MEDIA_ROOT + '/' + attachment.file.name)

    def test_attachment_delete(self):
        # create sample attachment
        filecontent = 'Hello World'
        temp = tempfile.NamedTemporaryFile(delete=False)
        temp.write(filecontent.encode())
        temp.close()
        f = File(open(temp.name, 'r'))
        attachment = Attachment(file=f, creator=self.user, issue=self.issue)
        attachment.save()
        f.close()
        filePath = attachment.file.path
        self.assertTrue(os.path.isfile(filePath))

        # delete the attachment
        response = self.client.get(reverse('issue:delete_attachment',
                                           kwargs={'project': self.project.name_short,
                                                   'sqn_i': self.issue.number,
                                                   'sqn_a': attachment.seqnum}),
                                   follow=True)
        self.assertRedirects(response, reverse('issue:detail', kwargs={'project': self.project.name_short,
                                                                       'sqn_i': self.issue.number}))
        self.assertFalse(self.issue.attachments.all().exists())
        self.assertFalse(os.path.isfile(filePath))

        # delete temp file locally
        os.unlink(temp.name)
コード例 #26
0
class ColumnTest(TestCase):
    @classmethod
    def setUpTestData(cls):
        # NOTE: if you modify this element it needs to be created in setUp, instead of here
        cls.user = get_user_model().objects.create_user(
            'test', '*****@*****.**', 'test1234')

    def setUp(self):
        translation.activate('en')
        self.client.force_login(self.user)
        self.project = Project(creator=self.user,
                               name_short='test',
                               name='Testproject',
                               description='asdf')
        self.project.save()
        self.project.manager.add(self.user)
        self.column = KanbanColumn(name='Column', project=self.project)
        self.column.save()

    def test_view_and_template(self):
        # TODO TESTCASE see invite_users/testcases/test_invite_users.py as example
        pass

    def test_redirect_to_login_and_login_required(self):
        # TODO TESTCASE see invite_users/testcases/test_invite_users.py as example
        pass

    def test_user_passes_test_mixin(self):
        # TODO TESTCASE
        pass

    def test_create_and_edit_kanban_with_get_request_disabled(self):
        # TODO TESTCASE
        pass

    def test_issues_from_other_projects_invisible(self):
        # TODO TESTCASE
        pass

    def test_default_columns(self):
        # create
        response = self.client.get(
            reverse('project:edit',
                    kwargs={'project': self.project.name_short}))
        self.assertContains(response, 'Todo', count=1)
        self.assertContains(response, 'In Progress', count=1)
        self.assertContains(response, 'Done', count=1)

        # delete
        response = self.client.post(
            reverse('project:delete',
                    kwargs={'project': self.project.name_short}),
            {'delete': 'true'})
        self.assertEqual(KanbanColumn.objects.count(), 0)

    def test_create_column(self):
        # TODO TESTCASE
        pass

    def test_update_column(self):
        # TODO TESTCASE
        pass

    def test_delete_column(self):
        # TODO TESTCASE
        pass

    def test_delete_column_rejected_cuz_issues_assigned(self):
        # TODO TESTCASE
        pass

    def test_issue_kanban_moveleftright(self):
        self.assertEqual(self.project.kanbancol.count(), 4)
        issue1 = Issue(title="issue1",
                       project=self.project,
                       kanbancol=self.project.kanbancol.first())
        issue1.save()

        self.assertEqual(issue1.get_left_kCol_for_issue(), -1)
        self.assertEqual(issue1.get_right_kCol_for_issue(), 1)

        # move issue to next row and check results
        issue1.kanbancol = self.project.kanbancol.get(position='1')
        issue1.save()
        self.assertEqual(issue1.get_left_kCol_for_issue(), 0)
        self.assertEqual(issue1.get_right_kCol_for_issue(), 2)

        # move issue to last row and check results
        issue1.kanbancol = self.project.kanbancol.get(position='3')
        issue1.save()
        self.assertEqual(issue1.get_left_kCol_for_issue(), 2)
        self.assertEqual(issue1.get_right_kCol_for_issue(), -1)

        # test view function
        response = self.client.post(
            reverse('issue:setkanbancol',
                    kwargs={'project': self.project.name_short}), {
                        'sqn_k': '0',
                        'sqn_i': issue1.number,
                    },
            follow=True)
        self.assertRedirects(
            response,
            reverse('issue:projList',
                    kwargs={'project': self.project.name_short}))
        issue1.refresh_from_db()
        self.assertEqual(issue1.kanbancol.position, 0)

        # check if error handling works (set col too high)
        response = self.client.post(
            reverse('issue:setkanbancol',
                    kwargs={'project': self.project.name_short}), {
                        'sqn_k': '4',
                        'sqn_i': issue1.number,
                    },
            follow=True)
        self.assertRedirects(
            response,
            reverse('issue:projList',
                    kwargs={'project': self.project.name_short}))
        self.assertEqual(len(list(response.context['messages'])), 1)
        issue1.refresh_from_db()
        self.assertEqual(issue1.kanbancol.position, 0)

        # check with invalid issue
        response = self.client.post(
            reverse('issue:setkanbancol',
                    kwargs={'project': self.project.name_short}), {
                        'sqn_k': '2',
                        'sqn_i': issue1.number + 1,
                    },
            follow=True)
        self.assertRedirects(
            response,
            reverse('issue:projList',
                    kwargs={'project': self.project.name_short}))
        self.assertEqual(len(list(response.context['messages'])), 1)
        issue1.refresh_from_db()
        self.assertEqual(issue1.kanbancol.position, 0)
コード例 #27
0
class CreateGlobalTest(TestCase):
    @classmethod
    def setUpTestData(cls):
        # NOTE: if you modify these elements they need to be created in setUp(), instead of here
        cls.user = get_user_model().objects.create_user('a', 'b', 'c')
        cls.user2 = get_user_model().objects.create_user('d', 'e', 'f')

    def setUp(self):
        self.client.force_login(self.user)
        # NOTE: these elements get modified by some testcases, so they should NOT be created in setUpTestData()
        self.project = Project(creator=self.user, name_short='PRJ')
        self.project.save()
        self.project.manager.add(self.user)
        self.project.developer.add(self.user)
        self.project2 = Project(creator=self.user, name_short='TP')
        self.project2.save()
        self.project2.manager.add(self.user)
        self.project2.developer.add(self.user)
        self.column = KanbanColumn(name='Column', position=4, project=self.project)
        self.column.save()

    # helper function
    def create_some_issues(self):
        col = KanbanColumn.objects.filter(project=self.project)
        col2 = KanbanColumn.objects.filter(project=self.project2)
        iss = []
        iss.append(Issue(title='asd', kanbancol=col.get(pk=1), priority=0, type='Bug', project=self.project))
        iss.append(Issue(title='asd2', kanbancol=col.get(pk=2), priority=1, type='Story', project=self.project))
        iss.append(Issue(title='asd3', kanbancol=col.get(pk=3), priority=2, type='Task', project=self.project))
        iss.append(Issue(title='asd4', kanbancol=col.get(pk=3), priority=3, archived=True, project=self.project))
        iss.append(Issue(title='asd5', kanbancol=col2.first(), priority=4, project=self.project2))
        for issue in iss:
            issue.save()
            issue.assignee.add(self.user)
        return iss

    def test_view_and_template(self):
        # TODO TESTCASE simplify testcase with view_and_template()
        #      view_and_template(self, , , )
        # TODO which views?
        #      - url(r'^$', views.IssueListAllView.as_view(), name='issue_list_all_view'),
        #      - url(r'^project/'+project_pattern+r'issue/', include([
        #      -   url(r'assigntome/?$', views.AssignIssueToMeView.as_view(), name='assigntome',),
        #      -   url(r'^rmfromme/?$', views.RemoveIssueFromMeView.as_view(), name='rmfromme',),
        #      -   url(r'^setkanbancol/?$', views.AddIssueToKanbancolView.as_view(), name='setkanbancol',),
        #      -   url(r'^archivecol/?$', views.ArchiveMultipleIssueView.as_view(), name='archivecol',),
        #      -   url(r'^archiveissue/?$', views.ArchiveSingleIssueView.as_view(), name='archiveissue',),
        #      -   url(r'^unarchiveissue/?$', views.UnArchiveSingleIssueView.as_view(), name='unarchiveissue',),
        #      - url(r'^(?P<sqn_i>[0-9]+)/', include([
        #      -     url(r'^delete/?$', views.IssueDeleteView.as_view(), name='delete'),
        #      - ]))
        #      - url(r'^(?P<sqn_i>[0-9]+)/', include([
        #      -    url(r'^punch/?$', tl_views.PunchView.as_view(), name='punch'),
        pass

    def test_redirect_to_login_and_loign_required(self):
        # TODO TESTCASE simplify testcase with view_and_template()
        #      redirect_to_login_and_login_required(self, address_pattern, address_kwargs=None, get_kwargs=None,
        #                                 alternate_error_message=None):
        # TODO which views?
        #      - url(r'^$', views.IssueListAllView.as_view(), name='issue_list_all_view'),
        #      - url(r'^project/'+project_pattern+r'issue/', include([
        #      -   url(r'assigntome/?$', views.AssignIssueToMeView.as_view(), name='assigntome',),
        #      -   url(r'^rmfromme/?$', views.RemoveIssueFromMeView.as_view(), name='rmfromme',),
        #      -   url(r'^setkanbancol/?$', views.AddIssueToKanbancolView.as_view(), name='setkanbancol',),
        #      -   url(r'^archivecol/?$', views.ArchiveMultipleIssueView.as_view(), name='archivecol',),
        #      -   url(r'^archiveissue/?$', views.ArchiveSingleIssueView.as_view(), name='archiveissue',),
        #      -   url(r'^unarchiveissue/?$', views.UnArchiveSingleIssueView.as_view(), name='unarchiveissue',),
        #      - url(r'^(?P<sqn_i>[0-9]+)/', include([
        #      -     url(r'^delete/?$', views.IssueDeleteView.as_view(), name='delete'),
        #      - ]))
        #      - url(r'^(?P<sqn_i>[0-9]+)/', include([
        #      -    url(r'^punch/?$', tl_views.PunchView.as_view(), name='punch'),
        pass

    def test_issue_properties(self):
        issues = self.create_some_issues()

        # archived issue is not in context
        response = self.client.get(reverse('issue:issue_list_all_view'))
        self.assertIn(issues[0], response.context['issues'].object_list)
        self.assertNotIn(issues[3], response.context['issues'].object_list)

        # done issue is not in context
        response = self.client.get(reverse('issue:issue_list_all_view'))
        self.assertNotIn(issues[2], response.context['issues'].object_list)

        # archived/done issue is not in context, done issue is in context
        response = self.client.get(reverse('issue:issue_list_all_view'))
        self.assertIn(issues[0], response.context['issues'].object_list)
        self.assertIn(issues[1], response.context['issues'].object_list)
        self.assertIn(issues[4], response.context['issues'].object_list)
        self.assertNotIn(issues[3], response.context['issues'].object_list)
        self.assertNotIn(issues[2], response.context['issues'].object_list)

        # filter project
        response = self.client.get(reverse('issue:issue_list_all_view')+'?show_done=false'+'&project=PRJ')

        # issue from second project not in context
        self.assertNotIn(issues[4], response.context['issues'].object_list)
        # not done issues from first project in context
        self.assertEqual(2, len(response.context['issues'].object_list))

        # filter not existing project
        response = self.client.get(reverse('issue:issue_list_all_view')+'?show_done=false'+'&project=PRJ2')
        self.assertIn(issues[4], response.context['issues'].object_list)
        self.assertEqual(3, len(response.context['issues'].object_list))

        # filter in running sprint
        sprint = Sprint(project=self.project)
        sprint.save()
        issues[0].sprint = sprint
        issues[0].save()
        response = self.client.get(reverse('issue:issue_list_all_view') + '?show_done=true' +
                                   '&project=PRJ&sprint_only=true')
        self.assertEqual(0, len(response.context['issues'].object_list))
        sprint.set_active()
        response = self.client.get(reverse('issue:issue_list_all_view') + '?show_done=true' +
                                   '&project=PRJ&sprint_only=true')
        self.assertEqual(1, len(response.context['issues'].object_list))
        self.assertIn(issues[0], response.context['issues'].object_list)
        sprint.set_inactive()
        response = self.client.get(reverse('issue:issue_list_all_view') + '?show_done=true' +
                                   '&project=PRJ&sprint_only=true')
        self.assertEqual(0, len(response.context['issues'].object_list))

        # order_by title
        response = self.client.get(reverse('issue:issue_list_all_view') + '?show_done=true' +
                                   '&order_by=title' + '&project=PRJ')
        self.assertEqual(issues[0], response.context['issues'].object_list.pop(0))
        response = self.client.get(reverse('issue:issue_list_all_view') + '?show_done=true' +
                                   '&order_by=title' + '&project=PRJ&reverse=true')
        self.assertEqual(issues[2], response.context['issues'].object_list.pop(0))

        # order_by priority
        response = self.client.get(reverse('issue:issue_list_all_view') + '?show_done=true' +
                                   '&order_by=priority&reverse=false')
        self.assertEqual(issues[4], response.context['issues'].object_list.pop(0))
        response = self.client.get(reverse('issue:issue_list_all_view') + '?show_done=true' +
                                   '&order_by=priority&reverse=true')
        self.assertEqual(issues[0], response.context['issues'].object_list.pop(0))

        # order_by type
        response = self.client.get(reverse('issue:issue_list_all_view') + '?show_done=true' +
                                   '&order_by=type&project=PRJ&reverse=false')
        self.assertEqual(3, len(response.context['issues'].object_list))
        self.assertEqual(issues[0], response.context['issues'].object_list.pop(0))
        self.assertEqual(issues[2], response.context['issues'].object_list.pop(1))
        response = self.client.get(reverse('issue:issue_list_all_view') + '?show_done=true' +
                                   '&order_by=type&reverse=true&project=PRJ')
        self.assertEqual(3, len(response.context['issues'].object_list))
        self.assertEqual(issues[2], response.context['issues'].object_list.pop(0))
        self.assertEqual(issues[0], response.context['issues'].object_list.pop(1))

        # order_by status
        response = self.client.get(reverse('issue:issue_list_all_view') + '?show_done=true' +
                                   '&order_by=status&project=PRJ')
        self.assertEqual(3, len(response.context['issues'].object_list))
        self.assertEqual(issues[0], response.context['issues'].object_list.pop(0))
        self.assertEqual(issues[2], response.context['issues'].object_list.pop(1))
        response = self.client.get(reverse('issue:issue_list_all_view') + '?show_done=true' +
                                   '&order_by=status&reverse=true&project=PRJ')
        self.assertEqual(3, len(response.context['issues'].object_list))
        self.assertEqual(issues[0], response.context['issues'].object_list.pop(0))
        self.assertEqual(issues[2], response.context['issues'].object_list.pop(1))

        # test pagination PageNotInteger exception
        response = self.client.get(reverse('issue:issue_list_all_view') +
                                   '?page=asd' + '&show_done=true', follow=True)
        self.assertEqual(4, len(response.context['issues'].object_list))

        # test pagination EmptyPage exception
        response = self.client.get(reverse('issue:issue_list_all_view') +
                                   '?page=5' + '&show_done=true', follow=True)
        self.assertEqual(4, len(response.context['issues'].object_list))

    def test_save_filters(self):
        issues = self.create_some_issues()
        vals = {
                'typ': 'issue_list_all_view',
        }
        response = self.client.get(reverse('issue:issue_list_all_view') + '?show_done=true' +
                                   '&order_by=status&reverse=true&project=PRJ')
        string = response.request.get('QUERY_STRING')
        vals.update({'string': string, 'name': 'asdf'})
        response = self.client.post(reverse('common:create_filter'), vals, follow=True)
        self.assertEqual(self.user.filters.count(), 1)
        self.assertContains(response, 'asdf')
        vals.update({'string': string, 'name': 'ghjk'})
        response = self.client.post(reverse('common:create_filter'), vals, follow=True)
        self.assertEqual(self.user.filters.count(), 1)
        vals.update({'string': '?order_by=priority', 'name': 'asdf'})
        response = self.client.post(reverse('common:create_filter'), vals, follow=True)
        self.assertEqual(self.user.filters.count(), 1)
        vals.update({'typ': 'lalala', 'name': 'yoyo'})
        response = self.client.post(reverse('common:create_filter'), vals, follow=True)
        self.assertEqual(self.user.filters.count(), 2)
        self.assertNotContains(response, 'yoyo')
コード例 #28
0
class TimelogTest(TestCase):
    @classmethod
    def setUpTestData(cls):
        # NOTE: if you modify those element they need to be created in setUp, instead of here
        cls.user = get_user_model().objects.create_user(
            'test', '*****@*****.**', 'test1234')
        cls.user2 = get_user_model().objects.create_user(
            'test2', '*****@*****.**', 'test1234')
        cls.user.save()
        cls.user2.save()

    def setUp(self):
        self.client.force_login(self.user)
        # NOTE: this element gets modified by some of those tests, so this shall NOT be created in setUpTestData()
        self.project = Project(creator=self.user, name_short='PRJ')
        self.project.save()
        self.project.developer.add(self.user)
        self.project.developer.add(self.user2)
        # NOTE: this element gets modified by some of those tests, so this shall NOT be created in setUpTestData()
        self.kanbancol = KanbanColumn(project=self.project,
                                      position=4,
                                      name='test')
        self.kanbancol.save()
        # NOTE: this element gets modified by some of those tests, so this shall NOT be created in setUpTestData()
        self.issue = Issue(
            title='a very very very very very very very long issue title',
            project=self.project,
            due_date='2016-12-16',
            kanbancol=self.kanbancol,
            storypoints='3')
        self.issue.save()
        self.issue2 = Issue(title='issue title',
                            project=self.project,
                            due_date='2016-12-16',
                            kanbancol=self.kanbancol,
                            storypoints='3')
        self.issue2.save()
        self.issue.assignee.add(self.user)

    def test_punch_in_out_0(self):
        response = self.client.post(reverse('issue:punch',
                                            kwargs={
                                                "project":
                                                self.issue.project.name_short,
                                                "sqn_i": self.issue.number
                                            }),
                                    follow=True)
        self.assertEqual(
            Timelog.objects.filter(user=self.user, issue=self.issue).exists(),
            False)
        self.assertEqual(
            Punch.objects.filter(user=self.user, issue=self.issue).exists(),
            True)
        response = self.client.post(reverse('issue:punch',
                                            kwargs={
                                                "project":
                                                self.issue.project.name_short,
                                                "sqn_i": self.issue.number
                                            }),
                                    follow=True)
        self.assertEqual(
            Timelog.objects.filter(user=self.user, issue=self.issue).exists(),
            True)
        self.assertEqual(
            Punch.objects.filter(user=self.user, issue=self.issue).exists(),
            False)

    def test_punch_in_out_multiple_users_0(self):
        # mulitple users punch same issue
        response = self.client.post(reverse('issue:punch',
                                            kwargs={
                                                "project":
                                                self.issue.project.name_short,
                                                "sqn_i": self.issue.number
                                            }),
                                    follow=True)
        self.client.force_login(self.user2)
        response = self.client.post(reverse('issue:punch',
                                            kwargs={
                                                "project":
                                                self.issue.project.name_short,
                                                "sqn_i": self.issue.number
                                            }),
                                    follow=True)
        self.assertEqual(Punch.objects.filter(issue=self.issue).count(), 2)
        response = self.client.post(reverse('issue:punch',
                                            kwargs={
                                                "project":
                                                self.issue.project.name_short,
                                                "sqn_i": self.issue.number
                                            }),
                                    follow=True)
        self.assertEqual(Punch.objects.filter(issue=self.issue).count(), 1)
        self.client.force_login(self.user)
        response = self.client.post(reverse('issue:punch',
                                            kwargs={
                                                "project":
                                                self.issue.project.name_short,
                                                "sqn_i": self.issue.number
                                            }),
                                    follow=True)
        self.assertEqual(Punch.objects.filter(issue=self.issue).count(), 0)
        self.assertEqual(Timelog.objects.filter(issue=self.issue).count(), 2)

        self.issue.assignee.add(self.user)

    def test_punch_in_out(self):
        response = self.client.post(reverse('issue:punch',
                                            kwargs={
                                                "project":
                                                self.issue.project.name_short,
                                                "sqn_i": self.issue.number
                                            }),
                                    follow=True)
        self.assertEqual(
            Timelog.objects.filter(user=self.user, issue=self.issue).exists(),
            False)
        self.assertEqual(
            Punch.objects.filter(user=self.user, issue=self.issue).exists(),
            True)
        response = self.client.post(reverse('issue:punch',
                                            kwargs={
                                                "project":
                                                self.issue.project.name_short,
                                                "sqn_i": self.issue.number
                                            }),
                                    follow=True)
        self.assertContains(response, self.issue.get_ticket_identifier())
        self.assertEqual(
            Timelog.objects.filter(user=self.user, issue=self.issue).exists(),
            True)
        self.assertEqual(
            Punch.objects.filter(user=self.user, issue=self.issue).exists(),
            False)

    def test_punch_in_out_multiple_users(self):
        # mulitple users punch same issue
        response = self.client.post(reverse('issue:punch',
                                            kwargs={
                                                "project":
                                                self.issue.project.name_short,
                                                "sqn_i": self.issue.number
                                            }),
                                    follow=True)
        self.client.force_login(self.user2)
        response = self.client.post(reverse('issue:punch',
                                            kwargs={
                                                "project":
                                                self.issue.project.name_short,
                                                "sqn_i": self.issue.number
                                            }),
                                    follow=True)
        self.assertEqual(Punch.objects.filter(issue=self.issue).count(), 2)
        response = self.client.post(reverse('issue:punch',
                                            kwargs={
                                                "project":
                                                self.issue.project.name_short,
                                                "sqn_i": self.issue.number
                                            }),
                                    follow=True)
        self.assertEqual(Punch.objects.filter(issue=self.issue).count(), 1)
        self.client.force_login(self.user)
        response = self.client.post(reverse('issue:punch',
                                            kwargs={
                                                "project":
                                                self.issue.project.name_short,
                                                "sqn_i": self.issue.number
                                            }),
                                    follow=True)
        self.assertEqual(Punch.objects.filter(issue=self.issue).count(), 0)
        self.assertEqual(Timelog.objects.filter(issue=self.issue).count(), 2)

    def test_punch_in_on_multiple_issues_not_possible(self):
        # mulitple users punch same issue
        response = self.client.post(reverse('issue:punch',
                                            kwargs={
                                                "project":
                                                self.issue.project.name_short,
                                                "sqn_i": self.issue.number
                                            }),
                                    follow=True)
        response = self.client.post(reverse('issue:punch',
                                            kwargs={
                                                "project":
                                                self.issue2.project.name_short,
                                                "sqn_i": self.issue2.number
                                            }),
                                    follow=True)
        self.assertContains(response, self.issue.get_ticket_identifier())
コード例 #29
0
ファイル: test_comment.py プロジェクト: yasir2000/iguana
class CommentTest(TestCase):
    @classmethod
    def setUpTestData(cls):
        # NOTE: if you modify these elements they need to be created in setUp(), instead of here
        cls.user = get_user_model().objects.create_user('lalala', 'b', 'c')
        cls.user2 = get_user_model().objects.create_user('lululu', 'e', 'f')

    def setUp(self):
        self.client.force_login(self.user)
        # NOTE: these elements get modified by some testcases, so they should NOT be created in setUpTestData()
        self.project = Project(creator=self.user, name_short='PRJ')
        self.project.save()
        self.project.manager.add(self.user)
        self.project.developer.add(self.user)
        self.column = KanbanColumn(name='Column',
                                   position=4,
                                   project=self.project)
        self.column.save()
        self.issue = Issue(title="Test-Issue",
                           project=self.project,
                           kanbancol=self.column,
                           type="Bug")
        self.issue.save()

    def test_view_and_template(self):
        # create comment
        comment = Comment(text="comment text",
                          creator=self.user,
                          issue=self.issue)
        comment.save()

        # edit comment-view
        view_and_template(self,
                          IssueEditCommentView,
                          'comment/comment_edit.html',
                          'issue:edit_comment',
                          address_kwargs={
                              'project': self.project.name_short,
                              'sqn_i': 1,
                              'pk_c': 1
                          },
                          get_kwargs={'text': "comment text"})

        # TODO TESTCASE issue:delete_comment

    def test_redirect_to_login_and_login_required(self):
        # create comment + logout
        comment = Comment(text="comment text",
                          creator=self.user,
                          issue=self.issue)
        comment.save()
        self.client.logout()

        # edit comment-view
        redirect_to_login_and_login_required(self,
                                             'issue:edit_comment',
                                             address_kwargs={
                                                 'project':
                                                 self.project.name_short,
                                                 'sqn_i': 1,
                                                 'pk_c': 1
                                             })

        # TODO TESTCASE issue:delete_comment

    def test_user_passes_test_mixin(self):
        proj_name2 = "project"
        proj_short2 = "cccc"
        project2 = Project(name=proj_name2,
                           name_short=proj_short2,
                           creator=self.user)
        project2.save()
        issue = Issue(title="p1-iss", project=self.project)
        issue.save()
        issue2 = Issue(title="p2-iss", project=project2)
        issue2.save()
        comment_text = "Fancy comment text"
        comment_edit = "EDITED AND CHANGED COMMENT"
        new_comment = {'action': "commentAtt", 'text': comment_text}
        edit_comment = {'text': comment_edit}
        comment1 = Comment(creator=self.user, issue=issue, text=comment_text)
        comment1.save()
        comment2 = Comment(creator=self.user, issue=issue2, text=comment_text)
        comment2.save()

        self.client.logout()
        self.client.force_login(self.user2)

        # developer is good
        self.project.developer.add(self.user2)
        self.project.save()
        # create
        response = self.client.post(reverse('issue:detail',
                                            kwargs={
                                                'project':
                                                self.project.name_short,
                                                'sqn_i': issue.number
                                            }),
                                    new_comment,
                                    follow=True)
        self.assertNotContains(
            response,
            "Your account doesn't have access to this page. To proceed, please "
            + "login with an account that has access.")
        self.assertEqual(issue.comments.count(), 2)
        # edit
        # developer can edit only their own comments
        response = self.client.post(reverse('issue:edit_comment',
                                            kwargs={
                                                'project':
                                                self.project.name_short,
                                                'sqn_i': issue.number,
                                                'pk_c': 2
                                            }),
                                    edit_comment,
                                    follow=True)
        self.assertNotContains(
            response,
            "Your account doesn't have access to this page. To proceed, please "
            + "login with an account that has access.")
        self.assertEqual(issue.comments.count(), 2)
        self.assertEqual(issue.comments.get(seqnum=2).text, comment_edit)

        # manager is good
        project2.manager.add(self.user2)
        project2.save()
        # create
        response = self.client.post(reverse('issue:detail',
                                            kwargs={
                                                'project': proj_short2,
                                                'sqn_i': 1
                                            }),
                                    new_comment,
                                    follow=True)
        self.assertNotContains(
            response,
            "Your account doesn't have access to this page. To proceed, please "
            + "login with an account that has access.")
        self.assertEqual(issue2.comments.count(), 2)
        # edit
        # even manager can edit only their own comments
        response = self.client.post(
            reverse('issue:edit_comment',
                    kwargs={
                        'project': proj_short2,
                        'sqn_i': 1,
                        'pk_c': 2
                    }),  # TODO pkc=1 probieren s.o
            edit_comment,
            follow=True)
        self.assertNotContains(
            response,
            "Your account doesn't have access to this page. To proceed, please "
            + "login with an account that has access.")
        self.assertEqual(issue2.comments.count(), 2)
        self.assertEqual(issue2.comments.get(seqnum=2).text, comment_edit)

    def test_comments_from_other_issues_of_same_project_invisible(self):
        # TODO TESTCASE
        pass

    def test_create_and_edit_comments_with_get_requests_disabled(self):
        # TODO TESTCASE
        pass

    def test_comment_create(self):
        comment_text = "Fancy comment text"
        comment1 = Comment(creator=self.user,
                           issue=self.issue,
                           text=comment_text)
        comment1.save()

        self.assertEqual(Issue.objects.count(), 1)
        self.assertEqual(self.issue.comments.count(), 1)
        self.assertEqual(self.issue.comments.first().text, comment_text)

    def test_comment_delete(self):
        # create sample issue
        issue = Issue(title="Test-Issue",
                      project=self.project,
                      kanbancol=self.column,
                      type="Bug")
        issue.save()
        # create sample comment
        comment = Comment(text="Test Comment", creator=self.user, issue=issue)
        comment.save()

        # delete the comment
        response = self.client.get(reverse('issue:delete_comment',
                                           kwargs={
                                               'project':
                                               self.project.name_short,
                                               'sqn_i': issue.number,
                                               'pk_c': comment.pk
                                           }),
                                   follow=True)
        self.assertRedirects(
            response,
            reverse('issue:detail',
                    kwargs={
                        'project': self.project.name_short,
                        'sqn_i': issue.number
                    }))
        self.assertFalse(issue.comments.all().exists())

    def test_comment_edit(self):
        # TODO TESTCASE
        pass

    def test_comment_seqnum_stays_after_editing(self):
        self.assertEqual(self.issue.nextCommentId, 1)

        values = {'text': "comment text"}

        # create comment + logout
        comment = Comment(text=values['text'],
                          creator=self.user,
                          issue=self.issue)
        comment.save()

        issue = Issue.objects.get(pk=self.issue.pk)
        self.assertEqual(Comment.objects.count(), 1)
        self.assertEqual(Comment.objects.first().seqnum, 1)
        self.assertEqual(issue.comments.count(), 1)
        comment = issue.comments.first()
        self.assertEqual(comment.text, values['text'])
        self.assertEqual(issue.nextCommentId, 2)

        # check creator and time
        self.assertEqual(comment.creator, self.user)
        self.assertLess(comment.when, timezone.now())
        self.assertGreater(comment.when,
                           timezone.now() - timedelta(seconds=10))

        values['text'] = "new comment text"

        # edit comment and assert that seqnum stays the same
        response = self.client.post(
            reverse('issue:edit_comment',
                    kwargs={
                        'project': self.project.name_short,
                        'sqn_i': 1,
                        'pk_c': comment.seqnum
                    }), values)
        self.assertRedirects(
            response,
            reverse('issue:detail',
                    kwargs={
                        'project': self.project.name_short,
                        'sqn_i': 1
                    }) + '#comment1')
        response = self.client.get(response['location'])
        self.assertEqual(response.status_code, 200)

        issue = Issue.objects.get(pk=issue.pk)
        self.assertEqual(Comment.objects.count(), 1)
        self.assertEqual(Comment.objects.first().seqnum, 1)
        self.assertEqual(issue.comments.count(), 1)
        comment = issue.comments.first()
        self.assertEqual(comment.text, values['text'])
        self.assertEqual(issue.nextCommentId, 2)

    def test_comment_attach_log(self):
        # TODO TESTCASE move this test into an own class when splitting up the issue application
        # add a comment
        values = {
            'action': "commentAtt",  # the action is for the multiforms.py
            'text': "only a comment"
        }

        response = self.client.post(reverse('issue:detail',
                                            kwargs={
                                                'project':
                                                self.project.name_short,
                                                'sqn_i': 1
                                            }),
                                    values,
                                    follow=True)
        self.assertContains(response, values['text'])

        # add comment and a file
        filecontent = 'Hello World'
        temp = tempfile.NamedTemporaryFile(delete=False)
        temp.write(filecontent.encode())
        temp.close()
        f = open(temp.name, 'r')

        values['text'] = "a comment with a file"
        values['file'] = f
        response = self.client.post(reverse('issue:detail',
                                            kwargs={
                                                'project':
                                                self.project.name_short,
                                                'sqn_i': 1
                                            }),
                                    values,
                                    follow=True)
        self.assertContains(response, values['text'])
        for com in self.issue.comments.all():
            if com.attachment:
                self.assertEqual(path.basename(com.attachment.file.name),
                                 path.basename(temp.name))
                # deletion takes place below

        # add only a file
        del values['text']
        commentCount = len(self.issue.comments.all())
        response = self.client.post(reverse('issue:detail',
                                            kwargs={
                                                'project':
                                                self.project.name_short,
                                                'sqn_i': 1
                                            }),
                                    values,
                                    follow=True)
        self.assertEqual(commentCount, len(self.issue.comments.all()))
        for form in response.context_data['forms'].values():
            self.assertFalse(form.is_valid())

        # close the file
        f.close()
        os.remove(temp.name)

        # add single file
        filecontent = 'Hello World'
        temp = tempfile.NamedTemporaryFile(delete=False)
        temp.write(filecontent.encode())
        temp.close()
        f = open(temp.name, 'r')

        values['action'] = "attachment"
        values['file'] = f
        response = self.client.post(reverse('issue:detail',
                                            kwargs={
                                                'project':
                                                self.project.name_short,
                                                'sqn_i': 1
                                            }),
                                    values,
                                    follow=True)
        self.assertContains(response, path.basename(temp.name))

        # close the file
        f.close()
        # delete the uploaded file locally
        os.unlink(temp.name)

        # delete the uploaded files from the server
        for att in self.issue.attachments.all():
            os.unlink(MEDIA_ROOT + '/' + att.file.name)

        # add time log
        values['action'] = "timelog"
        del values['file']
        values['time'] = "1h"
        response = self.client.post(reverse('issue:detail',
                                            kwargs={
                                                'project':
                                                self.project.name_short,
                                                'sqn_i': 1
                                            }),
                                    values,
                                    follow=True)
        self.assertContains(response, "1 Hour")
コード例 #30
0
class CreateAndEditTest(SeleniumTestCase):
    def setUp(self):
        self.user = get_user_model().objects.create_user('a', 'b', 'c')
        self.project = Project(creator=self.user,
                               name="asdf",
                               name_short="PRJ")
        self.project.save()
        self.project.manager.add(self.user)
        self.project.developer.add(self.user)
        self.project2 = Project(creator=self.user,
                                name="2ndproj",
                                name_short="PRJ2")
        self.project2.save()
        self.project2.developer.add(self.user)
        self.kanban = KanbanColumn(name='KanCol',
                                   project=self.project2,
                                   position=4)
        self.kanban.save()

        # Uses the cookie hack from:
        # https://stackoverflow.com/questions/22494583/login-with-code-when-using-liveservertestcase-with-django
        client = Client()
        client.login(username='******', password='******')
        self.cookie = client.cookies['sessionid']
        self.selenium.get("{}{}".format(self.live_server_url,
                                        reverse('invite_users:invite_users')))
        self.selenium.add_cookie({
            'name': 'sessionid',
            'value': self.cookie.value,
            'secure': False,
            'path': '/'
        })
        self.selenium.refresh()

    def test_reachable_and_elements_exist(self):
        # TODO TESTCASE
        # TODO for each site check it is available + check (some) content like the title + check existence of forms
        #      and their form elements by their ids!
        # TODO create => form
        # TODO edit => form
        pass

    def test_title_required(self):
        # TODO TESTCASE
        # TODO create => title
        # TODO edit => title
        pass

    def test_create(self):
        driver = self.selenium
        driver.get("{}{}".format(
            self.live_server_url,
            reverse('issue:create',
                    kwargs={'project': self.project.name_short})))

        title = "title"
        driver.find_element_by_id("id_title").send_keys(title)

        # assert that initially selected kanbancol is 'Todo'
        self.assertEqual(
            Select(driver.find_element_by_id(
                "id_kanbancol")).first_selected_option.text, "Todo")

        # assert that project has 4 (3 default + --- line) kanban colums
        self.assertEqual(
            len(Select(driver.find_element_by_id("id_kanbancol")).options), 4)

        Select(driver.find_element_by_id(
            "id_kanbancol")).select_by_visible_text("Todo")
        driver.find_element_by_name("due_date").click()
        driver.find_element_by_css_selector(
            "#due_date.form-control").send_keys(str(datetime.date.today()))
        # assert that we have one assignee in selection field
        driver.find_element_by_css_selector(
            "input.select2-search__field").click()
        self.assertEqual(
            len(
                driver.find_elements_by_css_selector(
                    '#select2-id_assignee-results li')), 1)
        Select(driver.find_element_by_id(
            "id_priority")).select_by_visible_text("High")
        driver.find_element_by_id("id_storypoints").clear()
        driver.find_element_by_id("id_storypoints").send_keys("2")

        # assert that project has no related issues to choose from (only one issue present in proj2)
        # one item present: No items found
        driver.find_element_by_xpath("(//input[@type='search'])[2]").send_keys(
            Keys.RETURN)
        time.sleep(1)
        self.assertEqual(
            len(
                driver.find_elements_by_css_selector(
                    '#select2-id_dependsOn-results li')), 1)
        for i in driver.find_elements_by_css_selector(
                '#select2-id_dependsOn-results li'):
            self.assertEqual(i.text, "No results found")

        driver.find_element_by_id("id_description").clear()
        driver.find_element_by_id("id_description").send_keys("blubber")
        driver.find_element_by_id("id_submit_create").click()
        self.assertIn(title, driver.page_source)

    def test_number_kanbancolumns_for_case_not_default(self):
        driver = self.selenium
        issue = Issue(title="title",
                      kanbancol=KanbanColumn.objects.get(project=self.project,
                                                         name="Todo"),
                      due_date=str(datetime.date.today()),
                      priority=3,
                      storypoints=2,
                      description="blubber",
                      project=self.project)
        issue.save()
        issue.assignee.add(self.user)

        driver.get("{}{}".format(
            self.live_server_url,
            reverse('issue:create',
                    kwargs={'project': self.project2.name_short})))
        driver.find_element_by_id("id_title").send_keys("title")
        # assert that 2nd project has one kanban col more
        self.assertEqual(
            len(Select(driver.find_element_by_id("id_kanbancol")).options), 5)

        # assert that dependsOn now has one entry
        driver.get('{}{}'.format(
            self.live_server_url,
            reverse('backlog:backlog',
                    kwargs={'project': self.project.name_short})))
        driver.find_element_by_link_text("New issue").click()
        driver.find_element_by_xpath("(//input[@type='search'])[2]").send_keys(
            '\n')
        time.sleep(1)
        self.assertEqual(
            len(
                driver.find_elements_by_css_selector(
                    '#select2-id_dependsOn-results li')), 1)
        for i in driver.find_elements_by_css_selector(
                '#select2-id_dependsOn-results li'):
            self.assertIn("title", i.text)

    def test_edit_same_settings_as_set(self):
        driver = self.selenium
        issue = Issue(title="title",
                      kanbancol=KanbanColumn.objects.get(project=self.project,
                                                         name="Todo"),
                      due_date=str(datetime.date.today()),
                      priority=3,
                      storypoints=2,
                      description="blubber",
                      project=self.project)
        issue.save()
        issue.assignee.add(self.user)
        driver.get("{}{}".format(
            self.live_server_url,
            reverse('issue:edit',
                    kwargs={
                        'project': self.project.name_short,
                        'sqn_i': issue.number
                    })))
        self.assertEqual(
            len(Select(driver.find_element_by_id("id_kanbancol")).options), 4)

        # issue must not depend on itself
        driver.find_element_by_xpath("(//input[@type='search'])[2]").send_keys(
            '\n')
        time.sleep(1)
        self.assertEqual(
            len(
                driver.find_elements_by_css_selector(
                    '#select2-id_dependsOn-results li')), 1)
        for i in driver.find_elements_by_css_selector(
                '#select2-id_dependsOn-results li'):
            self.assertEqual(i.text, "No results found")

    def test_dependencies(self):
        driver = self.selenium

        # create two issues
        issue = Issue(title="title",
                      kanbancol=KanbanColumn.objects.get(project=self.project,
                                                         name="Todo"),
                      due_date=str(datetime.date.today()),
                      priority=3,
                      storypoints=2,
                      description="blubber",
                      project=self.project)
        issue.save()
        issue.assignee.add(self.user)
        issue = Issue(title="title",
                      kanbancol=KanbanColumn.objects.get(project=self.project,
                                                         name="Todo"),
                      due_date=str(datetime.date.today()),
                      priority=3,
                      storypoints=2,
                      description="blubber",
                      project=self.project)
        issue.save()
        issue.assignee.add(self.user)

        driver.get('{}{}'.format(
            self.live_server_url,
            reverse('backlog:backlog',
                    kwargs={'project': self.project.name_short})))

        driver.find_element_by_link_text("PRJ-1").click()
        driver.find_element_by_id("issue_detail_edit_link").click()
        driver.find_element_by_xpath("(//input[@type='search'])[2]").send_keys(
            '\n')
        time.sleep(1)
        self.assertEqual(
            len(
                driver.find_elements_by_css_selector(
                    '#select2-id_dependsOn-results li')), 1)
        for i in driver.find_elements_by_css_selector(
                '#select2-id_dependsOn-results li'):
            i.click()
        driver.find_element_by_id("id_submit_edit").click()
        self.assertIn('Depends on', driver.page_source)
        self.assertIn('PRJ-2', driver.page_source)
        url = driver.current_url
        driver.find_element_by_link_text("title").click()
        self.assertIn('Dependent issues', driver.page_source)
        self.assertIn('PRJ-1', driver.page_source)
        driver.find_element_by_link_text("title").click()
        self.assertEqual(url, driver.current_url)

    def test_edit_change_settings(self):
        # TODO TESTCASE
        pass

    def test_delete_issue(self):
        # TODO TESTCASE
        pass

    def test_keep_and_dont_delete_issue(self):
        # TODO TESTCASE
        pass