Skip to content

Commit

Permalink
- adding copy_fix_version_from_epic_to_all_items_in_epic (#15)
Browse files Browse the repository at this point in the history
* - adding copy_fix_version_from_epic_to_all_items_in_epic
- reworking so multiple labels are properly supported

* small cleanup
  • Loading branch information
studioj authored Jun 5, 2021
1 parent 12cb441 commit 88dee6a
Show file tree
Hide file tree
Showing 4 changed files with 133 additions and 12 deletions.
41 changes: 37 additions & 4 deletions jira_agile_toolbox/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,13 @@ def add_labels_to_all_sub_items_of_epic(self, epic, labels):
this will append the "label_to_set" to all existing labels of all Issues in Epic
"""
labels_to_set = self._input_validation_labels(labels)
items_to_update = self.get_all_issues_in_epic(epic, fields=["labels"])
for item in items_to_update:
for label in labels_to_set:
item.add_field_value("labels", label)

def _input_validation_labels(self, labels):
labels_to_set = []
bad_input = ""
if isinstance(labels, list):
Expand All @@ -239,7 +246,33 @@ def add_labels_to_all_sub_items_of_epic(self, epic, labels):
bad_input = "labels, should be a list or a string"
if bad_input:
raise ValueError(bad_input)
items_to_update = self.get_all_issues_in_epic(epic, fields=["labels"])
for item in items_to_update:
item.fields.labels += labels_to_set
item.update(fields={"labels": item.fields.labels})
return labels_to_set

def copy_fix_version_from_epic_to_all_items_in_epic(self, epic):
"""
copies fixVersions from the epic to all 'Issues in Epic'
:param epic: and epic key as a string or the epic as a jira.Issue
:type epic: str jira.Issue
:return: None
``Example``
.. code-block:: python
>>> from jira_agile_toolbox import JiraAgileToolBox
>>> from jira import JIRA
>>> my_jira_client = JIRA("https://my-jira-server.com", basic_auth=("MYUSERNAME","MYPASSWORD")
>>> tb = JiraAgileToolBox(my_jira_client)
>>> epic = my_jira_client.issue("PROJ001-001")
>>> epic.fields.fixVersions
[<JIRA Version: name='0.0.10', id='31063'>]
>>> tb.copy_fix_version_from_epic_to_all_items_in_epic(epic)
>>> tb.get_all_issues_in_epic("JAT-001")[0].fields.fixVersions
[<JIRA Version: name='0.0.10', id='31063'>]
"""
jira_epic = epic # if isinstance(epic, jira.Issue) else self._jira_client.issue(epic)
versions = [version.raw for version in jira_epic.fields.fixVersions]
for issue in self.get_all_issues_in_epic(jira_epic, fields=["fixVersions"]):
for version in versions:
issue.add_field_value("fixVersions", version)
5 changes: 4 additions & 1 deletion tests/lib_for_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,12 @@


class MockedJiraIssue(jira.Issue):
def __init__(self, story_points=None, status="Reported", labels=[]):
def __init__(self, story_points=None, status="Reported", labels=[], fix_versions=[]):
self.fields = MagicMock()
self.fields.customfield_10282 = story_points
self.fields.status.name = status
self.fields.labels = labels
self.fields.fixVersions = fix_versions
self.update = Mock()
self.__getattr__ = Mock()
self.add_field_value = Mock()
85 changes: 85 additions & 0 deletions tests/test_epic_interactions.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,20 @@
from unittest.mock import Mock

import jira
import jira.resources

from jira_agile_toolbox import JiraAgileToolBox
from lib_for_tests import DEFAULT_FIELDS_RETURN_VALUE, MockedJiraIssue

VERSION_RAW = {
"self": "https://atlassian-jira.com/rest/api/2/version/31063",
"id": "31063",
"description": "",
"name": "JAT 0.0.9",
"archived": False,
"released": True,
}


class TestEpicStoryPointRetrieval(TestCase):
def setUp(self) -> None:
Expand Down Expand Up @@ -259,3 +269,78 @@ def test_get_issues_from_epic_takes_a_string_field_or_a_list_of_fields(self):

# Then
self.jira_client.search_issues.assert_called_with(f"'Epic Link' = PROJ001-001", fields=["a_specific_field"], maxResults=0)


class TestSetVersionNumberForAllItemsInEpic(TestCase):
def setUp(self) -> None:
self.jira_client = Mock(spec=jira.JIRA)

def test_copy_fix_version_from_epic_to_all_items_in_epic(self):
# Given
sub_issue1 = MockedJiraIssue(story_points=0)
version1 = Mock(spec=jira.resources.Version)
version1.raw = VERSION_RAW
epic = MockedJiraIssue()
epic.fields.fixVersions = [version1]
epic.key = "PROJ001-001"
self.jira_client.search_issues.return_value = [sub_issue1]
jat = JiraAgileToolBox(self.jira_client)

# When
jat.copy_fix_version_from_epic_to_all_items_in_epic(epic)

# Then
sub_issue1.add_field_value.assert_called_with("fixVersions", version1.raw)

def test_copy_fix_version_from_epic_to_all_items_in_epic_for_multiple_versions(self):
# Given
sub_issue1 = MockedJiraIssue(story_points=0)
version1 = Mock(spec=jira.resources.Version)
version1.raw = VERSION_RAW
version2 = Mock(spec=jira.resources.Version)
version2.raw = {
"self": "https://atlassian-jira.com/rest/api/2/version/31064",
"id": "31064",
"description": "",
"name": "JAT 0.0.10",
"archived": False,
"released": False,
}
epic = MockedJiraIssue()
epic.fields.fixVersions = [version1, version2]
epic.key = "PROJ001-001"
self.jira_client.search_issues.return_value = [sub_issue1]
jat = JiraAgileToolBox(self.jira_client)

# When
jat.copy_fix_version_from_epic_to_all_items_in_epic(epic)

# Then
sub_issue1.add_field_value.assert_any_call("fixVersions", version1.raw)
sub_issue1.add_field_value.assert_any_call("fixVersions", version2.raw)

def test_copy_fix_version_from_epic_to_multiple_items_in_epic(self):
# Given
sub_issue1 = MockedJiraIssue()
sub_issue2 = MockedJiraIssue()
version1 = Mock(spec=jira.resources.Version)
version1.raw = {
"self": "https://atlassian-jira.com/rest/api/2/version/31063",
"id": "31063",
"description": "",
"name": "JAT 0.0.9",
"archived": False,
"released": True,
}
epic = MockedJiraIssue()
epic.fields.fixVersions = [version1]
epic.key = "PROJ001-001"
self.jira_client.search_issues.return_value = [sub_issue1, sub_issue2]
jat = JiraAgileToolBox(self.jira_client)

# When
jat.copy_fix_version_from_epic_to_all_items_in_epic(epic)

# Then
sub_issue1.add_field_value.assert_called_with("fixVersions", version1.raw)
sub_issue2.add_field_value.assert_called_with("fixVersions", version1.raw)
14 changes: 7 additions & 7 deletions tests/test_label_interactions.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import unittest
from unittest.mock import Mock
from unittest.mock import Mock, call

import jira

Expand All @@ -23,22 +23,22 @@ def test_setting_a_label_for_all_sub_items(self):
jat.add_labels_to_all_sub_items_of_epic("PROJ001-001", ["label_to_set"])

# Then
self.assertEqual(sub_story.fields.labels, ["label_to_set"])
sub_story.update.assert_called_once_with(fields={"labels": sub_story.fields.labels})
sub_story.add_field_value.assert_called_with("labels", "label_to_set")

def test_setting_a_label_for_all_sub_items_which_have_labels_already(self):
def test_setting_a_label_for_all_sub_items_multiple_labels(self):
# Given
sub_story = MockedJiraIssue(labels=["some_other_label"])
sub_story = MockedJiraIssue()
self.jira_client.search_issues.return_value = [
sub_story,
]
jat = JiraAgileToolBox(self.jira_client)

# When
jat.add_labels_to_all_sub_items_of_epic("PROJ001-001", ["label_to_set"])
jat.add_labels_to_all_sub_items_of_epic("PROJ001-001", ["label_to_set", "label2"])

# Then
self.assertEqual(sub_story.fields.labels, ["some_other_label", "label_to_set"])
sub_story.add_field_value.assert_any_call("labels", "label_to_set")
sub_story.add_field_value.assert_any_call("labels", "label2")

def test_setting_a_label_for_all_sub_items_raises_an_exception_on_a_label_with_a_space(self):
# Given
Expand Down

0 comments on commit 88dee6a

Please sign in to comment.