Skip to content

Commit 9687baf

Browse files
authored
Fix #822: add new sync_keywords_label step (#835)
* Fix #822: add new sync_keywords_label step * Fix lint
1 parent bac8cc7 commit 9687baf

File tree

2 files changed

+136
-2
lines changed

2 files changed

+136
-2
lines changed

jbi/steps.py

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
import logging
1414
from enum import Enum, auto
15-
from typing import TYPE_CHECKING, Optional
15+
from typing import TYPE_CHECKING, Iterable, Optional
1616

1717
from requests import exceptions as requests_exceptions
1818

@@ -385,9 +385,41 @@ def sync_whiteboard_labels(
385385
added=context.bug.whiteboard, labels_brackets=parameters.labels_brackets
386386
)
387387

388+
return _update_issue_labels(context, jira_service, additions, removals)
389+
390+
391+
def sync_keywords_labels(
392+
context: ActionContext, *, parameters: ActionParams, jira_service: JiraService
393+
) -> StepResult:
394+
"""
395+
Set keywords as labels on the Jira issue.
396+
"""
397+
if context.event.changes:
398+
changes_by_field = {change.field: change for change in context.event.changes}
399+
if change := changes_by_field.get("keywords"):
400+
additions = [x.strip() for x in change.added.split(",")]
401+
removed = [x.strip() for x in change.removed.split(",")]
402+
removals = sorted(
403+
set(removed).difference(set(additions))
404+
) # sorted for unit testing
405+
else:
406+
return (StepStatus.NOOP, context)
407+
else:
408+
# On creation, just add them all.
409+
additions = context.bug.keywords or []
410+
removals = []
411+
412+
return _update_issue_labels(context, jira_service, additions, removals)
413+
414+
415+
def _update_issue_labels(
416+
context: ActionContext,
417+
jira_service: JiraService,
418+
additions: Iterable[str],
419+
removals: Iterable[str],
420+
) -> StepResult:
388421
if not context.jira.issue:
389422
raise ValueError("Jira issue unset in Action Context")
390-
391423
try:
392424
resp = jira_service.update_issue_labels(
393425
issue_key=context.jira.issue, add=additions, remove=removals

tests/unit/test_steps.py

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1095,3 +1095,105 @@ def test_sync_whiteboard_labels_failing(
10951095
assert capturelogs.messages == [
10961096
"Could not set labels on issue JBI-123: some message"
10971097
]
1098+
1099+
1100+
def test_sync_keywords_labels(
1101+
action_context_factory,
1102+
mocked_jira,
1103+
action_params_factory,
1104+
):
1105+
action_context = action_context_factory(
1106+
operation=Operation.CREATE,
1107+
jira__issue="JBI-123",
1108+
bug__keywords=["devtests", "bugzilla"],
1109+
)
1110+
1111+
callable_object = Executor(
1112+
action_params_factory(
1113+
jira_project_key=action_context.jira.project,
1114+
steps={"new": ["sync_whiteboard_labels"]},
1115+
)
1116+
)
1117+
callable_object(context=action_context)
1118+
1119+
mocked_jira.update_issue.assert_called_once_with(
1120+
issue_key=action_context.jira.issue,
1121+
update={
1122+
"update": {
1123+
"labels": [
1124+
{"add": "bugzilla"},
1125+
{"add": "devtest"},
1126+
]
1127+
}
1128+
},
1129+
)
1130+
1131+
1132+
def test_sync_keywords_labels_update(
1133+
action_context_factory,
1134+
mocked_jira,
1135+
action_params_factory,
1136+
webhook_event_change_factory,
1137+
):
1138+
action_context = action_context_factory(
1139+
operation=Operation.UPDATE,
1140+
jira__issue="JBI-123",
1141+
event__changes=[
1142+
webhook_event_change_factory(
1143+
field="keywords",
1144+
removed="interface, sprint, next",
1145+
added="sprint",
1146+
)
1147+
],
1148+
)
1149+
1150+
callable_object = Executor(
1151+
action_params_factory(
1152+
jira_project_key=action_context.jira.project,
1153+
steps={"existing": ["sync_keywords_labels"]},
1154+
)
1155+
)
1156+
callable_object(context=action_context)
1157+
1158+
mocked_jira.update_issue.assert_called_once_with(
1159+
issue_key=action_context.jira.issue,
1160+
update={
1161+
"update": {
1162+
"labels": [
1163+
{"add": "sprint"},
1164+
{"remove": "interface"},
1165+
{"remove": "next"},
1166+
]
1167+
}
1168+
},
1169+
)
1170+
1171+
1172+
def test_sync_keywords_labels_failing(
1173+
action_context_factory,
1174+
mocked_jira,
1175+
capturelogs,
1176+
action_params_factory,
1177+
):
1178+
mocked_jira.update_issue.side_effect = requests.exceptions.HTTPError(
1179+
"some message", response=mock.MagicMock(status_code=400)
1180+
)
1181+
action_context = action_context_factory(
1182+
current_step="sync_keywords_labels", jira__issue="JBI-123"
1183+
)
1184+
1185+
action_params = action_params_factory(
1186+
jira_project_key=action_context.jira.project,
1187+
)
1188+
1189+
with capturelogs.for_logger("jbi.steps").at_level(logging.DEBUG):
1190+
result, context = steps.sync_keywords_labels(
1191+
context=action_context,
1192+
parameters=action_params,
1193+
jira_service=JiraService(mocked_jira),
1194+
)
1195+
assert result == steps.StepStatus.INCOMPLETE
1196+
1197+
assert capturelogs.messages == [
1198+
"Could not set labels on issue JBI-123: some message"
1199+
]

0 commit comments

Comments
 (0)