File: test_sprint.py

package info (click to toggle)
python-jira 3.10.5-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,024 kB
  • sloc: python: 8,877; sh: 13; makefile: 7; xml: 4
file content (143 lines) | stat: -rw-r--r-- 5,392 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
from __future__ import annotations

from collections.abc import Iterator
from contextlib import contextmanager
from functools import lru_cache

import pytest as pytest

from jira.exceptions import JIRAError
from jira.resources import Board, Filter, Sprint
from tests.conftest import JiraTestCase, rndstr


class SprintTests(JiraTestCase):
    def setUp(self):
        super().setUp()
        self.issue_1 = self.test_manager.project_b_issue1
        self.issue_2 = self.test_manager.project_b_issue2
        self.issue_3 = self.test_manager.project_b_issue3

        uniq = rndstr()
        self.board_name = f"board-{uniq}"
        self.sprint_name = f"sprint-{uniq}"
        self.filter_name = f"filter-{uniq}"
        self.sprint_goal = f"goal-{uniq}"

        self.board, self.filter = self._create_board_and_filter()

    def tearDown(self) -> None:
        self.board.delete()
        self.filter.delete()  # must do AFTER deleting board referencing the filter
        super().tearDown()

    def _create_board_and_filter(self) -> tuple[Board, Filter]:
        """Helper method to create a board and filter"""
        filter = self.jira.create_filter(
            self.filter_name, "description", f"project={self.project_b}", True
        )

        board = self.jira.create_board(
            name=self.board_name, filter_id=filter.id, project_ids=self.project_b
        )
        return board, filter

    @contextmanager
    def _create_sprint(self) -> Iterator[Sprint]:
        """Helper method to create a Sprint."""
        sprint = None
        try:
            sprint = self.jira.create_sprint(self.sprint_name, self.board.id)
            yield sprint
        finally:
            if sprint is not None:
                sprint.delete()

    @lru_cache
    def _sprint_customfield(self) -> str:
        """Helper method to return the customfield_ name for a sprint.
        This is needed as it is implemented as a plugin to Jira, (Jira Agile).
        """
        sprint_field_name = "Sprint"
        sprint_field_id = [
            f["schema"]["customId"]
            for f in self.jira.fields()
            if f["name"] == sprint_field_name
        ][0]
        return f"customfield_{sprint_field_id}"

    def test_create_and_delete(self):
        # GIVEN: the board and filter
        # WHEN: we create the sprint
        with self._create_sprint() as sprint:
            sprint = self.jira.create_sprint(self.sprint_name, self.board.id)
            # THEN: we get a sprint with some reasonable defaults
            assert isinstance(sprint.id, int)
            assert sprint.name == self.sprint_name
            assert sprint.state.upper() == "FUTURE"
        # THEN: the sprint .delete() is called successfully

    def test_create_with_goal(self):
        # GIVEN: The board, sprint name, and goal
        # WHEN: we create the sprint
        sprint = self.jira.create_sprint(
            self.sprint_name, self.board.id, goal=self.sprint_goal
        )
        # THEN: we create the sprint with a goal
        assert isinstance(sprint.id, int)
        assert sprint.name == self.sprint_name
        assert sprint.goal == self.sprint_goal

    def test_update_sprint(self):
        # GIVEN: The sprint ID
        # WHEN: we update the sprint
        sprint = self.jira.create_sprint(
            self.sprint_name, self.board.id, goal=self.sprint_goal
        )
        assert isinstance(sprint.id, int)
        assert sprint.name == self.sprint_name
        assert sprint.goal == self.sprint_goal
        # THEN: the name changes
        updated_sprint = self.jira.update_sprint(
            sprint.id,
            "new_name",
            state="future",
            startDate="2015-04-11T15:22:00.000+10:00",
            endDate="2015-04-20T01:22:00.000+10:00",
        )
        assert updated_sprint["name"] == "new_name"

    def test_add_issue_to_sprint(self):
        # GIVEN: The sprint
        with self._create_sprint() as sprint:
            # WHEN: we add an issue to the sprint
            self.jira.add_issues_to_sprint(sprint.id, [self.issue_1])

            updated_issue_1 = self.jira.issue(self.issue_1)
            serialised_sprint = updated_issue_1.get_field(self._sprint_customfield())[0]

            # THEN: We find this sprint in the Sprint field of the Issue
            assert f"[id={sprint.id}," in serialised_sprint

    def test_move_issue_to_backlog(self):
        with self._create_sprint() as sprint:
            # GIVEN: we have an issue in a sprint
            self.jira.add_issues_to_sprint(sprint.id, [self.issue_1])
            updated_issue_1 = self.jira.issue(self.issue_1)
            assert updated_issue_1.get_field(self._sprint_customfield()) is not None

            # WHEN: We move it to the backlog
            self.jira.move_to_backlog([updated_issue_1.key])
            updated_issue_1 = self.jira.issue(updated_issue_1)

            # THEN: There is no longer the sprint assigned
            updated_issue_1 = self.jira.issue(self.issue_1)
            assert updated_issue_1.get_field(self._sprint_customfield()) is None

    def test_two_sprints_with_the_same_name_raise_a_jira_error_when_sprints_by_name_is_called(
        self,
    ):
        with self._create_sprint():
            with self._create_sprint():
                with pytest.raises(JIRAError):
                    self.jira.sprints_by_name(self.board.id)