示例#1
0
    def test_task_depends(self, jira_mock):
        '''Test for dual happy flow: one task depends on the other'''
        jira_mock_object = MagicMock(spec=JIRA)
        jira_mock.return_value = jira_mock_object
        juggler = dut.JiraJuggler(self.URL, self.USER, self.PASSWD, self.QUERY)
        self.assertEqual(self.QUERY, juggler.query)

        jira_mock_object.search_issues.side_effect = [[
            self._mock_jira_issue(self.KEY1, self.SUMMARY1, self.ASSIGNEE1,
                                  self.ESTIMATE1, self.DEPENDS1),
            self._mock_jira_issue(self.KEY2, self.SUMMARY2, self.ASSIGNEE2,
                                  self.ESTIMATE2, self.DEPENDS2),
        ], []]
        issues = juggler.juggle()
        jira_mock_object.search_issues.assert_has_calls([
            call(self.QUERY, maxResults=dut.JIRA_PAGE_SIZE, startAt=0),
            call(self.QUERY, maxResults=dut.JIRA_PAGE_SIZE, startAt=2)
        ])
        self.assertEqual(2, len(issues))
        self.assertEqual(self.KEY1, issues[0].key)
        self.assertEqual(self.SUMMARY1, issues[0].summary)
        self.assertEqual(self.ASSIGNEE1,
                         issues[0].properties['allocate'].get_value())
        self.assertEqual(self.ESTIMATE1 / self.SECS_PER_DAY,
                         issues[0].properties['effort'].get_value())
        self.assertEqual(self.DEPENDS1,
                         issues[0].properties['depends'].get_value())
        self.assertEqual(self.KEY2, issues[1].key)
        self.assertEqual(self.SUMMARY2, issues[1].summary)
        self.assertEqual(self.ASSIGNEE2,
                         issues[1].properties['allocate'].get_value())
        self.assertEqual(self.ESTIMATE2 / self.SECS_PER_DAY,
                         issues[1].properties['effort'].get_value())
        self.assertEqual(self.DEPENDS2,
                         issues[1].properties['depends'].get_value())
示例#2
0
    def test_broken_depends(self, jira_mock):
        '''Test for removing a broken link to a dependant task'''
        jira_mock_object = MagicMock(spec=JIRA)
        jira_mock.return_value = jira_mock_object
        juggler = dut.JiraJuggler(self.URL, self.USER, self.PASSWD, self.QUERY)
        self.assertEqual(self.QUERY, juggler.query)

        jira_mock_object.search_issues.side_effect = [[
            self._mock_jira_issue(self.KEY1,
                                  self.SUMMARY1,
                                  depends=['non-existing-key-of-issue'])
        ], []]
        issues = juggler.juggle()
        jira_mock_object.search_issues.assert_has_calls([
            call(self.QUERY,
                 maxResults=dut.JIRA_PAGE_SIZE,
                 startAt=0,
                 expand='changelog'),
            call(self.QUERY,
                 maxResults=dut.JIRA_PAGE_SIZE,
                 startAt=1,
                 expand='changelog')
        ])
        self.assertEqual(1, len(issues))
        self.assertEqual(self.KEY1, issues[0].key)
        self.assertEqual(self.SUMMARY1, issues[0].summary)
        self.assertEqual([], issues[0].properties['depends'].value)
示例#3
0
    def test_estimate_too_low(self, jira_mock):
        '''Test for correcting an estimate which is too low'''
        jira_mock_object = MagicMock(spec=JIRA)
        jira_mock.return_value = jira_mock_object
        juggler = dut.JiraJuggler(self.URL, self.USER, self.PASSWD, self.QUERY)
        self.assertEqual(self.QUERY, juggler.query)

        jira_mock_object.search_issues.side_effect = [[
            self._mock_jira_issue(self.KEY1,
                                  self.SUMMARY1,
                                  estimates=[1, None, None])
        ], []]
        issues = juggler.juggle()
        jira_mock_object.search_issues.assert_has_calls([
            call(self.QUERY,
                 maxResults=dut.JIRA_PAGE_SIZE,
                 startAt=0,
                 expand='changelog'),
            call(self.QUERY,
                 maxResults=dut.JIRA_PAGE_SIZE,
                 startAt=1,
                 expand='changelog')
        ])
        self.assertEqual(1, len(issues))
        self.assertEqual(self.KEY1, issues[0].key)
        self.assertEqual(self.SUMMARY1, issues[0].summary)
        self.assertEqual(dut.JugglerTaskEffort.MINIMAL_VALUE,
                         issues[0].properties['effort'].value)
示例#4
0
    def test_single_task_minimal(self, jira_mock):
        '''Test for minimal happy flow: single task with minimal content is returned by Jira

        Note: the default effort is choosen.
        '''
        jira_mock_object = MagicMock(spec=JIRA)
        jira_mock.return_value = jira_mock_object
        juggler = dut.JiraJuggler(self.URL, self.USER, self.PASSWD, self.QUERY)
        self.assertEqual(self.QUERY, juggler.query)

        jira_mock_object.search_issues.side_effect = [[
            self._mock_jira_issue(self.KEY1, self.SUMMARY1)
        ], []]
        issues = juggler.juggle()
        jira_mock_object.search_issues.assert_has_calls([
            call(self.QUERY,
                 maxResults=dut.JIRA_PAGE_SIZE,
                 startAt=0,
                 expand='changelog'),
            call(self.QUERY,
                 maxResults=dut.JIRA_PAGE_SIZE,
                 startAt=1,
                 expand='changelog')
        ])
        self.assertEqual(1, len(issues))
        self.assertEqual(self.KEY1, issues[0].key)
        self.assertEqual(self.SUMMARY1, issues[0].summary)
        self.assertEqual(dut.JugglerTaskEffort.DEFAULT_VALUE,
                         issues[0].properties['effort'].value)
示例#5
0
    def test_single_task_happy(self, jira_mock):
        '''Test for simple happy flow: single task is returned by Jira'''
        jira_mock_object = MagicMock(spec=JIRA)
        jira_mock.return_value = jira_mock_object
        juggler = dut.JiraJuggler(self.URL, self.USER, self.PASSWD, self.QUERY)
        self.assertEqual(self.QUERY, juggler.query)

        jira_mock_object.search_issues.side_effect = [[
            self._mock_jira_issue(self.KEY1, self.SUMMARY1, self.ASSIGNEE1,
                                  [self.ESTIMATE1, None, None], self.DEPENDS1)
        ], []]
        issues = juggler.juggle()
        jira_mock_object.search_issues.assert_has_calls([
            call(self.QUERY,
                 maxResults=dut.JIRA_PAGE_SIZE,
                 startAt=0,
                 expand='changelog'),
            call(self.QUERY,
                 maxResults=dut.JIRA_PAGE_SIZE,
                 startAt=1,
                 expand='changelog')
        ])
        self.assertEqual(1, len(issues))
        self.assertEqual(self.KEY1, issues[0].key)
        self.assertEqual(self.SUMMARY1, issues[0].summary)
        self.assertEqual(self.ASSIGNEE1,
                         issues[0].properties['allocate'].value)
        self.assertEqual(self.ESTIMATE1 / self.SECS_PER_DAY,
                         issues[0].properties['effort'].value)
        self.assertEqual(self.DEPENDS1, issues[0].properties['depends'].value)
示例#6
0
    def test_empty_query_result(self, jira_mock):
        '''Test for Jira not returning any task on the given query'''
        jira_mock_object = MagicMock(spec=JIRA)
        jira_mock.return_value = jira_mock_object
        juggler = dut.JiraJuggler(self.URL, self.USER, self.PASSWD, self.QUERY)
        self.assertEqual(self.QUERY, juggler.query)

        jira_mock_object.search_issues.return_value = []
        juggler.juggle()
        jira_mock_object.search_issues.assert_called_once_with(
            self.QUERY, maxResults=dut.JIRA_PAGE_SIZE, startAt=0)
示例#7
0
    def test_task_double_depends(self, jira_mock):
        '''Test for extended happy flow: one task depends on two others'''
        jira_mock_object = MagicMock(spec=JIRA)
        jira_mock.return_value = jira_mock_object
        juggler = dut.JiraJuggler(self.URL, self.USER, self.PASSWD, self.QUERY)
        self.assertEqual(self.QUERY, juggler.query)

        jira_mock_object.search_issues.side_effect = [[
            self._mock_jira_issue(self.KEY1, self.SUMMARY1, self.ASSIGNEE1,
                                  [self.ESTIMATE1, None, None], self.DEPENDS1),
            self._mock_jira_issue(self.KEY2, self.SUMMARY2, self.ASSIGNEE2,
                                  [self.ESTIMATE2, None, None], self.DEPENDS2),
            self._mock_jira_issue(self.KEY3, self.SUMMARY3, self.ASSIGNEE3,
                                  [self.ESTIMATE3, None, None], self.DEPENDS3),
        ], []]
        issues = juggler.juggle()
        jira_mock_object.search_issues.assert_has_calls([
            call(self.QUERY,
                 maxResults=dut.JIRA_PAGE_SIZE,
                 startAt=0,
                 expand='changelog'),
            call(self.QUERY,
                 maxResults=dut.JIRA_PAGE_SIZE,
                 startAt=3,
                 expand='changelog')
        ])
        self.assertEqual(3, len(issues))
        self.assertEqual(self.KEY1, issues[0].key)
        self.assertEqual(self.SUMMARY1, issues[0].summary)
        self.assertEqual(self.ASSIGNEE1,
                         issues[0].properties['allocate'].value)
        self.assertEqual(self.ESTIMATE1 / self.SECS_PER_DAY,
                         issues[0].properties['effort'].value)
        self.assertEqual(self.DEPENDS1, issues[0].properties['depends'].value)
        self.assertEqual(self.KEY2, issues[1].key)
        self.assertEqual(self.SUMMARY2, issues[1].summary)
        self.assertEqual(self.ASSIGNEE2,
                         issues[1].properties['allocate'].value)
        self.assertEqual(self.ESTIMATE2 / self.SECS_PER_DAY,
                         issues[1].properties['effort'].value)
        self.assertEqual(self.DEPENDS2, issues[1].properties['depends'].value)
        self.assertEqual(self.KEY3, issues[2].key)
        self.assertEqual(self.SUMMARY3, issues[2].summary)
        self.assertEqual(self.ASSIGNEE3,
                         issues[2].properties['allocate'].value)
        self.assertEqual(self.ESTIMATE3 / self.SECS_PER_DAY,
                         issues[2].properties['effort'].value)
        self.assertEqual(self.DEPENDS3, issues[2].properties['depends'].value)
示例#8
0
    def test_closed_task(self, jira_mock):
        '''
        Test that a change of assignee after Resolved status has no effect and that the original time estimate is
        used when no time has been logged.
        '''
        jira_mock_object = MagicMock(spec=JIRA)
        jira_mock.return_value = jira_mock_object
        juggler = dut.JiraJuggler(self.URL, self.USER, self.PASSWD, self.QUERY)
        histories = [
            {
                'items': [{
                    'field': 'status',
                    'toString': 'Resolved',
                }],
                'created': '2022-04-12T13:04:11.449+0200',
            },
            {
                'items': [{
                    'field': 'assignee',
                    'to': self.ASSIGNEE2,
                }],
                'created': '2022-05-25T14:07:11.974+0200',
            },
        ]

        jira_mock_object.search_issues.side_effect = [[
            self._mock_jira_issue(self.KEY1,
                                  self.SUMMARY1,
                                  self.ASSIGNEE1,
                                  [self.ESTIMATE1, None, self.ESTIMATE3],
                                  self.DEPENDS1,
                                  histories=histories,
                                  status="Closed"),
        ], []]
        issues = juggler.juggle()
        jira_mock_object.search_issues.assert_has_calls([
            call(self.QUERY,
                 maxResults=dut.JIRA_PAGE_SIZE,
                 startAt=0,
                 expand='changelog')
        ])
        self.assertEqual(1, len(issues))
        self.assertEqual(self.ASSIGNEE1,
                         issues[0].properties['allocate'].value)
        self.assertEqual(self.ESTIMATE1 / self.SECS_PER_DAY,
                         issues[0].properties['effort'].value)
示例#9
0
    def test_depend_on_preceding(self, jira_mock):
        '''Test --depends-on-preceding, --weeklymax and --current-date options'''
        jira_mock_object = MagicMock(spec=JIRA)
        jira_mock.return_value = jira_mock_object
        juggler = dut.JiraJuggler(self.URL, self.USER, self.PASSWD, self.QUERY)
        histories = [
            {
                'created': '2021-08-18T18:30:15.338+0200',
                'items': [{
                    'field': 'status',
                    'toString': 'Resolved',
                }]
            },
        ]

        jira_mock_object.search_issues.side_effect = [[
            self._mock_jira_issue(self.KEY1,
                                  self.SUMMARY1,
                                  self.ASSIGNEE1, [self.ESTIMATE1, None, None],
                                  self.DEPENDS1,
                                  histories=histories,
                                  status="Resolved"),
            self._mock_jira_issue(
                self.KEY2,
                self.SUMMARY2,
                self.ASSIGNEE1,
                [self.SECS_PER_DAY * val for val in [5, 3.2, 2.4]],
                self.DEPENDS1,
                status="Open"),
            self._mock_jira_issue(self.KEY3,
                                  self.SUMMARY3,
                                  self.ASSIGNEE1,
                                  [self.ESTIMATE2, None, self.ESTIMATE3],
                                  self.DEPENDS1,
                                  status="Open"),
        ], []]
        issues = juggler.juggle(
            depend_on_preceding=True,
            weeklymax=1.0,
            current_date=parser.isoparse('2021-08-23T13:30'))
        jira_mock_object.search_issues.assert_has_calls([
            call(self.QUERY,
                 maxResults=dut.JIRA_PAGE_SIZE,
                 startAt=0,
                 expand='changelog')
        ])
        self.assertEqual(3, len(issues))
        self.assertEqual(self.ASSIGNEE1,
                         issues[0].properties['allocate'].value)
        self.assertEqual(self.ESTIMATE1 / self.SECS_PER_DAY,
                         issues[0].properties['effort'].value)
        self.assertEqual('    end 2021-08-18-18:00-+0200\n',
                         str(issues[0].properties['depends']))

        self.assertEqual(self.ASSIGNEE1,
                         issues[1].properties['allocate'].value)
        self.assertEqual(3.2 + 2.4, issues[1].properties['effort'].value)
        self.assertEqual(
            '    start %{2021-08-23-13:00 - 9.125d}\n',
            str(issues[1].properties['depends']))  # 3.2 days spent

        self.assertEqual(self.ASSIGNEE1,
                         issues[2].properties['allocate'].value)
        self.assertEqual(self.ESTIMATE3 / self.SECS_PER_DAY,
                         issues[2].properties['effort'].value)
        self.assertEqual(f'    depends !{self.KEY2}\n',
                         str(issues[2].properties['depends']))
示例#10
0
 def test_resolved_task(self, jira_mock):
     '''Test that the last assignee in the Analyzed state is used and the Time Spent is used as effort
     Test that the most recent transition to the Approved/Resolved state is used to mark the end'''
     jira_mock_object = MagicMock(spec=JIRA)
     jira_mock.return_value = jira_mock_object
     juggler = dut.JiraJuggler(self.URL, self.USER, self.PASSWD, self.QUERY)
     histories = [
         {
             'items': [{
                 'field': 'assignee',
                 'to': self.ASSIGNEE1,
             }],
             'created': '2022-04-08T13:11:47.749+0200',
         },
         {
             'items': [{
                 'field': 'status',
                 'toString': 'Resolved',
             }],
             'created': '2022-04-11T08:13:14.350+0200',
         },
         {
             'items': [{
                 'field': 'assignee',
                 'to': self.ASSIGNEE3,
                 # 'from': self.ASSIGNEE1,  # cannot use 'from' as key to test
             }],
             'created':
             '2022-04-12T13:04:11.449+0200',
         },
         {
             'items': [{
                 'field': 'status',
                 'toString': 'Analyzed',
             }],
             'created': '2022-04-13T14:10:43.632+0200',
         },
         {
             'items': [{
                 'field': 'assignee',
                 'to': self.ASSIGNEE2,
             }],
             'created': '2022-05-02T09:20:36.310+0200',
         },
         {
             'items': [{
                 'field': 'status',
                 'toString': 'Approved',
             }],
             'created': '2022-05-25T14:07:11.974+0200',
         },
     ]
     jira_mock_object.search_issues.side_effect = [[
         self._mock_jira_issue(
             self.KEY1,
             self.SUMMARY1,
             self.ASSIGNEE1,
             [self.ESTIMATE1, self.ESTIMATE2, self.ESTIMATE3],
             self.DEPENDS1,
             histories=histories,
             status="Resolved"),
     ], []]
     issues = juggler.juggle()
     jira_mock_object.search_issues.assert_has_calls([
         call(self.QUERY,
              maxResults=dut.JIRA_PAGE_SIZE,
              startAt=0,
              expand='changelog')
     ])
     self.assertEqual(1, len(issues))
     self.assertEqual(self.ASSIGNEE2,
                      issues[0].properties['allocate'].value)
     self.assertEqual(self.ESTIMATE2 / self.SECS_PER_DAY,
                      issues[0].properties['effort'].value)
     self.assertEqual('2022-05-25 14:07:11.974000+02:00',
                      str(issues[0].resolved_at_date))