Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(slack): fix disappearing tags for issue button actions #75789

Merged
merged 1 commit into from
Aug 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions src/sentry/integrations/slack/webhooks/action.py
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,7 @@ def open_resolve_dialog(self, slack_request: SlackActionRequest, group: Group) -
"issue": group.id,
"orig_response_url": slack_request.data["response_url"],
"is_message": _is_message(slack_request.data),
"tags": list(slack_request.get_tags()),
}
if slack_request.data.get("channel"):
callback_id["channel_id"] = slack_request.data["channel"]["id"]
Expand Down Expand Up @@ -426,6 +427,7 @@ def open_archive_dialog(self, slack_request: SlackActionRequest, group: Group) -
"orig_response_url": slack_request.data["response_url"],
"is_message": _is_message(slack_request.data),
"rule": slack_request.callback_data.get("rule"),
"tags": list(slack_request.get_tags()),
}

if slack_request.data.get("channel"):
Expand Down Expand Up @@ -530,6 +532,10 @@ def _handle_group_actions(
except client.ApiError as error:
return self.api_error(slack_request, group, identity_user, error, "status_dialog")

view = View(**slack_request.data["view"])
private_metadata = orjson.loads(view.private_metadata)
original_tags_from_request = set(private_metadata["tags"])

blocks = SlackIssuesMessageBuilder(
group,
identity=identity,
Expand All @@ -542,9 +548,7 @@ def _handle_group_actions(

# use the original response_url to update the link attachment
json_blocks = orjson.dumps(blocks.get("blocks")).decode()
view = View(**slack_request.data["view"])
try:
private_metadata = orjson.loads(view.private_metadata)
webhook_client = WebhookClient(private_metadata["orig_response_url"])
webhook_client.send(
blocks=json_blocks, delete_original=False, replace_original=True
Expand Down
61 changes: 46 additions & 15 deletions tests/sentry/integrations/slack/webhooks/actions/test_status.py
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,8 @@ def test_ask_linking(self):
assert resp.data["response_type"] == "ephemeral"
assert resp.data["text"] == LINK_IDENTITY_MESSAGE.format(associate_url=associate_url)

def test_archive_issue_until_escalating(self):
@patch("sentry.integrations.slack.message_builder.issues.get_tags", return_value=[])
def test_archive_issue_until_escalating(self, mock_tags):
original_message = self.get_original_message(self.group.id)
self.archive_issue(original_message, "ignored:archived_until_escalating")

Expand All @@ -244,13 +245,16 @@ def test_archive_issue_until_escalating(self):

blocks = orjson.loads(self.mock_post.call_args.kwargs["blocks"])

assert mock_tags.call_args.kwargs["tags"] == self.tags

expect_status = f"*Issue archived by <@{self.external_id}>*"
assert self.notification_text in blocks[1]["text"]["text"]
assert blocks[2]["text"]["text"].endswith(expect_status)
assert "via" not in blocks[4]["elements"][0]["text"]
assert ":white_circle:" in blocks[0]["text"]["text"]

def test_archive_issue_until_escalating_through_unfurl(self):
@patch("sentry.integrations.slack.message_builder.issues.get_tags", return_value=[])
def test_archive_issue_until_escalating_through_unfurl(self, mock_tags):
original_message = self.get_original_message(self.group.id)
payload_data = self.get_unfurl_data(original_message["blocks"])
self.archive_issue(original_message, "ignored:archived_until_escalating", payload_data)
Expand All @@ -260,12 +264,14 @@ def test_archive_issue_until_escalating_through_unfurl(self):
assert self.group.substatus == GroupSubStatus.UNTIL_ESCALATING

blocks = orjson.loads(self.mock_post.call_args.kwargs["blocks"])
assert mock_tags.call_args.kwargs["tags"] == self.tags

expect_status = f"*Issue archived by <@{self.external_id}>*"
assert self.notification_text in blocks[1]["text"]["text"]
assert blocks[2]["text"]["text"].endswith(expect_status)

def test_archive_issue_until_condition_met(self):
@patch("sentry.integrations.slack.message_builder.issues.get_tags", return_value=[])
def test_archive_issue_until_condition_met(self, mock_tags):
original_message = self.get_original_message(self.group.id)
self.archive_issue(original_message, "ignored:archived_until_condition_met:10")

Expand All @@ -276,12 +282,14 @@ def test_archive_issue_until_condition_met(self):
assert group_snooze.count == 10

blocks = orjson.loads(self.mock_post.call_args.kwargs["blocks"])
assert mock_tags.call_args.kwargs["tags"] == self.tags

expect_status = f"*Issue archived by <@{self.external_id}>*"
assert self.notification_text in blocks[1]["text"]["text"]
assert blocks[2]["text"]["text"].endswith(expect_status)

def test_archive_issue_until_condition_met_through_unfurl(self):
@patch("sentry.integrations.slack.message_builder.issues.get_tags", return_value=[])
def test_archive_issue_until_condition_met_through_unfurl(self, mock_tags):
original_message = self.get_original_message(self.group.id)
payload_data = self.get_unfurl_data(original_message["blocks"])
self.archive_issue(
Expand All @@ -295,12 +303,14 @@ def test_archive_issue_until_condition_met_through_unfurl(self):
assert group_snooze.count == 100

blocks = orjson.loads(self.mock_post.call_args.kwargs["blocks"])
assert mock_tags.call_args.kwargs["tags"] == self.tags

expect_status = f"*Issue archived by <@{self.external_id}>*"
assert self.notification_text in blocks[1]["text"]["text"]
assert blocks[2]["text"]["text"].endswith(expect_status)

def test_archive_issue_forever_with(self):
@patch("sentry.integrations.slack.message_builder.issues.get_tags", return_value=[])
def test_archive_issue_forever(self, mock_tags):
original_message = self.get_original_message(self.group.id)
self.archive_issue(original_message, "ignored:archived_forever")

Expand All @@ -309,6 +319,7 @@ def test_archive_issue_forever_with(self):
assert self.group.substatus == GroupSubStatus.FOREVER

blocks = orjson.loads(self.mock_post.call_args.kwargs["blocks"])
assert mock_tags.call_args.kwargs["tags"] == self.tags

expect_status = f"*Issue archived by <@{self.external_id}>*"
assert self.notification_text in blocks[1]["text"]["text"]
Expand All @@ -328,7 +339,8 @@ def test_archive_issue_forever_error(self, mock_access):
assert self.group.get_status() == GroupStatus.UNRESOLVED
assert self.group.substatus == GroupSubStatus.ONGOING

def test_archive_issue_forever_through_unfurl(self):
@patch("sentry.integrations.slack.message_builder.issues.get_tags", return_value=[])
def test_archive_issue_forever_through_unfurl(self, mock_tags):
original_message = self.get_original_message(self.group.id)
payload_data = self.get_unfurl_data(original_message["blocks"])
self.archive_issue(original_message, "ignored:archived_forever", payload_data)
Expand All @@ -338,6 +350,7 @@ def test_archive_issue_forever_through_unfurl(self):
assert self.group.substatus == GroupSubStatus.FOREVER

blocks = orjson.loads(self.mock_post.call_args.kwargs["blocks"])
assert mock_tags.call_args.kwargs["tags"] == self.tags

expect_status = f"*Issue archived by <@{self.external_id}>*"
assert self.notification_text in blocks[1]["text"]["text"]
Expand Down Expand Up @@ -389,7 +402,8 @@ def test_archive_issue_with_additional_user_auth_through_unfurl(self):
assert self.notification_text in blocks[1]["text"]["text"]
assert blocks[2]["text"]["text"].endswith(expect_status)

def test_unarchive_issue(self):
@patch("sentry.integrations.slack.message_builder.issues.get_tags", return_value=[])
def test_unarchive_issue(self, mock_tags):
self.group.status = GroupStatus.IGNORED
self.group.substatus = GroupSubStatus.UNTIL_ESCALATING
self.group.save(update_fields=["status", "substatus"])
Expand All @@ -407,12 +421,14 @@ def test_unarchive_issue(self):
assert self.group.substatus == GroupSubStatus.NEW # the issue is less than 7 days old

blocks = orjson.loads(self.mock_post.call_args.kwargs["blocks"])
assert mock_tags.call_args.kwargs["tags"] == self.tags

expect_status = f"*Issue re-opened by <@{self.external_id}>*"
assert self.notification_text in blocks[1]["text"]["text"]
assert blocks[2]["text"]["text"].endswith(expect_status)

def test_unarchive_issue_through_unfurl(self):
@patch("sentry.integrations.slack.message_builder.issues.get_tags", return_value=[])
def test_unarchive_issue_through_unfurl(self, mock_tags):
self.group.status = GroupStatus.IGNORED
self.group.substatus = GroupSubStatus.UNTIL_ESCALATING
self.group.save(update_fields=["status", "substatus"])
Expand All @@ -431,6 +447,7 @@ def test_unarchive_issue_through_unfurl(self):
assert self.group.substatus == GroupSubStatus.NEW # the issue is less than 7 days old

blocks = orjson.loads(self.mock_post.call_args.kwargs["blocks"])
assert mock_tags.call_args.kwargs["tags"] == self.tags

expect_status = f"*Issue re-opened by <@{self.external_id}>*"
assert self.notification_text in blocks[1]["text"]["text"]
Expand Down Expand Up @@ -683,7 +700,8 @@ def test_assign_user_with_multiple_identities_through_unfurl(self):
assert self.notification_text in blocks[1]["text"]["text"]
assert blocks[2]["text"]["text"].endswith(expect_status), text

def test_resolve_issue(self):
@patch("sentry.integrations.slack.message_builder.issues.get_tags", return_value=[])
def test_resolve_issue(self, mock_tags):
original_message = self.get_original_message(self.group.id)
self.resolve_issue(original_message, "resolved")

Expand All @@ -692,13 +710,15 @@ def test_resolve_issue(self):
assert not GroupResolution.objects.filter(group=self.group)

blocks = orjson.loads(self.mock_post.call_args.kwargs["blocks"])
assert mock_tags.call_args.kwargs["tags"] == self.tags

expect_status = f"*Issue resolved by <@{self.external_id}>*"
assert self.notification_text in blocks[1]["text"]["text"]
assert blocks[2]["text"]["text"] == expect_status
assert ":white_circle:" in blocks[0]["text"]["text"]

def test_resolve_perf_issue(self):
@patch("sentry.integrations.slack.message_builder.issues.get_tags", return_value=[])
def test_resolve_perf_issue(self, mock_tags):
group_fingerprint = f"{PerformanceNPlusOneGroupType.type_id}-group1"

event_data_2 = load_data("transaction-n-plus-one", fingerprint=[group_fingerprint])
Expand All @@ -720,6 +740,7 @@ def test_resolve_perf_issue(self):
assert not GroupResolution.objects.filter(group=self.group)

blocks = orjson.loads(self.mock_post.call_args.kwargs["blocks"])
assert mock_tags.call_args.kwargs["tags"] == self.tags

expect_status = f"*Issue resolved by <@{self.external_id}>*"
assert (
Expand All @@ -729,7 +750,8 @@ def test_resolve_perf_issue(self):
assert blocks[3]["text"]["text"] == expect_status
assert ":white_circle: :chart_with_upwards_trend:" in blocks[0]["text"]["text"]

def test_resolve_issue_through_unfurl(self):
@patch("sentry.integrations.slack.message_builder.issues.get_tags", return_value=[])
def test_resolve_issue_through_unfurl(self, mock_tags):
original_message = self.get_original_message(self.group.id)
payload_data = self.get_unfurl_data(original_message["blocks"])
self.resolve_issue(original_message, "resolved", payload_data)
Expand All @@ -739,12 +761,14 @@ def test_resolve_issue_through_unfurl(self):
assert not GroupResolution.objects.filter(group=self.group)

blocks = orjson.loads(self.mock_post.call_args.kwargs["blocks"])
assert mock_tags.call_args.kwargs["tags"] == self.tags

expect_status = f"*Issue resolved by <@{self.external_id}>*"
assert self.notification_text in blocks[1]["text"]["text"]
assert blocks[2]["text"]["text"] == expect_status

def test_resolve_issue_in_current_release(self):
@patch("sentry.integrations.slack.message_builder.issues.get_tags", return_value=[])
def test_resolve_issue_in_current_release(self, mock_tags):
release = Release.objects.create(
organization_id=self.organization.id,
version="1.0",
Expand All @@ -761,12 +785,14 @@ def test_resolve_issue_in_current_release(self):
assert resolution.release == release

blocks = orjson.loads(self.mock_post.call_args.kwargs["blocks"])
assert mock_tags.call_args.kwargs["tags"] == self.tags

expect_status = f"*Issue resolved by <@{self.external_id}>*"
assert self.notification_text in blocks[1]["text"]["text"]
assert blocks[2]["text"]["text"].endswith(expect_status)

def test_resolve_issue_in_current_release_through_unfurl(self):
@patch("sentry.integrations.slack.message_builder.issues.get_tags", return_value=[])
def test_resolve_issue_in_current_release_through_unfurl(self, mock_tags):
release = Release.objects.create(
organization_id=self.organization.id,
version="1.0",
Expand All @@ -784,12 +810,14 @@ def test_resolve_issue_in_current_release_through_unfurl(self):
assert resolution.release == release

blocks = orjson.loads(self.mock_post.call_args.kwargs["blocks"])
assert mock_tags.call_args.kwargs["tags"] == self.tags

expect_status = f"*Issue resolved by <@{self.external_id}>*"
assert self.notification_text in blocks[1]["text"]["text"]
assert blocks[2]["text"]["text"].endswith(expect_status)

def test_resolve_in_next_release(self):
@patch("sentry.integrations.slack.message_builder.issues.get_tags", return_value=[])
def test_resolve_in_next_release(self, mock_tags):
release = Release.objects.create(
organization_id=self.organization.id,
version="1.0",
Expand All @@ -805,12 +833,14 @@ def test_resolve_in_next_release(self):
assert resolution.release == release

blocks = orjson.loads(self.mock_post.call_args.kwargs["blocks"])
assert mock_tags.call_args.kwargs["tags"] == self.tags

expect_status = f"*Issue resolved by <@{self.external_id}>*"
assert self.notification_text in blocks[1]["text"]["text"]
assert blocks[2]["text"]["text"].endswith(expect_status)

def test_resolve_in_next_release_through_unfurl(self):
@patch("sentry.integrations.slack.message_builder.issues.get_tags", return_value=[])
def test_resolve_in_next_release_through_unfurl(self, mock_tags):
release = Release.objects.create(
organization_id=self.organization.id,
version="1.0",
Expand All @@ -827,6 +857,7 @@ def test_resolve_in_next_release_through_unfurl(self):
assert resolution.release == release

blocks = orjson.loads(self.mock_post.call_args.kwargs["blocks"])
assert mock_tags.call_args.kwargs["tags"] == self.tags

expect_status = f"*Issue resolved by <@{self.external_id}>*"
assert self.notification_text in blocks[1]["text"]["text"]
Expand Down
Loading