|
@@ -13,6 +13,7 @@ from sentry.integrations.discord.requests.base import (
|
|
from sentry.integrations.discord.webhooks.message_component import (
|
|
from sentry.integrations.discord.webhooks.message_component import (
|
|
ARCHIVE_UNTIL_ESCALATES,
|
|
ARCHIVE_UNTIL_ESCALATES,
|
|
ASSIGNEE_UPDATED,
|
|
ASSIGNEE_UPDATED,
|
|
|
|
+ INVALID_GROUP_ID,
|
|
MARKED_ONGOING,
|
|
MARKED_ONGOING,
|
|
NO_IDENTITY,
|
|
NO_IDENTITY,
|
|
NOT_IN_ORG,
|
|
NOT_IN_ORG,
|
|
@@ -23,11 +24,14 @@ from sentry.integrations.discord.webhooks.message_component import (
|
|
UNRESOLVED,
|
|
UNRESOLVED,
|
|
)
|
|
)
|
|
from sentry.models.release import Release
|
|
from sentry.models.release import Release
|
|
|
|
+from sentry.silo.base import SiloMode
|
|
from sentry.testutils.cases import APITestCase
|
|
from sentry.testutils.cases import APITestCase
|
|
|
|
+from sentry.testutils.silo import assume_test_silo_mode, region_silo_test
|
|
|
|
|
|
WEBHOOK_URL = "/extensions/discord/interactions/"
|
|
WEBHOOK_URL = "/extensions/discord/interactions/"
|
|
|
|
|
|
|
|
|
|
|
|
+@region_silo_test
|
|
class DiscordMessageComponentInteractionTest(APITestCase):
|
|
class DiscordMessageComponentInteractionTest(APITestCase):
|
|
def setUp(self):
|
|
def setUp(self):
|
|
patcher = mock.patch(
|
|
patcher = mock.patch(
|
|
@@ -79,25 +83,61 @@ class DiscordMessageComponentInteractionTest(APITestCase):
|
|
def get_select_options(self, response: Any) -> Any:
|
|
def get_select_options(self, response: Any) -> Any:
|
|
return self.get_message_components(response)[0]["components"][0]["options"]
|
|
return self.get_message_components(response)[0]["components"][0]["options"]
|
|
|
|
|
|
- def test_unknown_id_interaction(self):
|
|
|
|
|
|
+ def test_unknown_custom_id_interaction(self):
|
|
response = self.send_interaction({"custom_id": f"unknown:{self.group.id}"})
|
|
response = self.send_interaction({"custom_id": f"unknown:{self.group.id}"})
|
|
- assert response.status_code == 404
|
|
|
|
|
|
+ assert response.status_code == 200
|
|
|
|
+ assert self.get_message_content(response) == INVALID_GROUP_ID
|
|
|
|
+
|
|
|
|
+ def test_empty_custom_id_interaction(self):
|
|
|
|
+ response = self.send_interaction({"custom_id": ""})
|
|
|
|
+ assert response.status_code == 200
|
|
|
|
+ assert self.get_message_content(response) == INVALID_GROUP_ID
|
|
|
|
|
|
def test_no_user(self):
|
|
def test_no_user(self):
|
|
response = self.send_interaction(member={"user": {"id": "not-our-user"}})
|
|
response = self.send_interaction(member={"user": {"id": "not-our-user"}})
|
|
|
|
+ assert response.status_code == 200
|
|
|
|
+ assert self.get_message_content(response) == NO_IDENTITY
|
|
|
|
+
|
|
|
|
+ def test_no_guild_id(self):
|
|
|
|
+ response = self.client.post(
|
|
|
|
+ path=WEBHOOK_URL,
|
|
|
|
+ data={
|
|
|
|
+ "type": DiscordRequestTypes.MESSAGE_COMPONENT,
|
|
|
|
+ },
|
|
|
|
+ format="json",
|
|
|
|
+ HTTP_X_SIGNATURE_ED25519="signature",
|
|
|
|
+ HTTP_X_SIGNATURE_TIMESTAMP="timestamp",
|
|
|
|
+ )
|
|
|
|
+ assert response.status_code == 200
|
|
|
|
+ assert self.get_message_content(response) == NO_IDENTITY
|
|
|
|
+
|
|
|
|
+ def test_invalid_guild_id(self):
|
|
|
|
+ response = self.client.post(
|
|
|
|
+ path=WEBHOOK_URL,
|
|
|
|
+ data={
|
|
|
|
+ "type": DiscordRequestTypes.MESSAGE_COMPONENT,
|
|
|
|
+ "guild_id": "invalid_guild_id",
|
|
|
|
+ },
|
|
|
|
+ format="json",
|
|
|
|
+ HTTP_X_SIGNATURE_ED25519="signature",
|
|
|
|
+ HTTP_X_SIGNATURE_TIMESTAMP="timestamp",
|
|
|
|
+ )
|
|
|
|
+ assert response.status_code == 200
|
|
assert self.get_message_content(response) == NO_IDENTITY
|
|
assert self.get_message_content(response) == NO_IDENTITY
|
|
|
|
|
|
def test_not_in_org(self):
|
|
def test_not_in_org(self):
|
|
other_user = self.create_user()
|
|
other_user = self.create_user()
|
|
other_user_discord_id = "other-user1234"
|
|
other_user_discord_id = "other-user1234"
|
|
other_org = self.create_organization()
|
|
other_org = self.create_organization()
|
|
- self.discord_integration.add_organization(other_org)
|
|
|
|
|
|
+ with assume_test_silo_mode(SiloMode.CONTROL):
|
|
|
|
+ self.discord_integration.add_organization(other_org)
|
|
self.create_identity(
|
|
self.create_identity(
|
|
user=other_user, identity_provider=self.provider, external_id=other_user_discord_id
|
|
user=other_user, identity_provider=self.provider, external_id=other_user_discord_id
|
|
)
|
|
)
|
|
|
|
|
|
response = self.send_interaction(member={"user": {"id": other_user_discord_id}})
|
|
response = self.send_interaction(member={"user": {"id": other_user_discord_id}})
|
|
|
|
|
|
|
|
+ assert response.status_code == 200
|
|
assert self.get_message_content(response) == NOT_IN_ORG
|
|
assert self.get_message_content(response) == NOT_IN_ORG
|
|
|
|
|
|
def test_assign_dialog(self):
|
|
def test_assign_dialog(self):
|
|
@@ -107,11 +147,22 @@ class DiscordMessageComponentInteractionTest(APITestCase):
|
|
"custom_id": f"{CustomIds.ASSIGN_DIALOG}:{self.group.id}",
|
|
"custom_id": f"{CustomIds.ASSIGN_DIALOG}:{self.group.id}",
|
|
}
|
|
}
|
|
)
|
|
)
|
|
|
|
+ assert response.status_code == 200
|
|
assert self.get_select_options(response) == [
|
|
assert self.get_select_options(response) == [
|
|
{"label": f"#{self.team.slug}", "value": f"team:{self.team.id}", "default": False},
|
|
{"label": f"#{self.team.slug}", "value": f"team:{self.team.id}", "default": False},
|
|
{"label": self.user.email, "value": f"user:{self.user.id}", "default": False},
|
|
{"label": self.user.email, "value": f"user:{self.user.id}", "default": False},
|
|
]
|
|
]
|
|
|
|
|
|
|
|
+ def test_assign_dialog_invalid_group_id(self):
|
|
|
|
+ response = self.send_interaction(
|
|
|
|
+ {
|
|
|
|
+ "component_type": DiscordMessageComponentTypes.BUTTON,
|
|
|
|
+ "custom_id": f"{CustomIds.ASSIGN_DIALOG}:invalid",
|
|
|
|
+ }
|
|
|
|
+ )
|
|
|
|
+ assert response.status_code == 200
|
|
|
|
+ assert self.get_message_content(response) == INVALID_GROUP_ID
|
|
|
|
+
|
|
def test_assign(self):
|
|
def test_assign(self):
|
|
response = self.send_interaction(
|
|
response = self.send_interaction(
|
|
{
|
|
{
|
|
@@ -120,6 +171,7 @@ class DiscordMessageComponentInteractionTest(APITestCase):
|
|
"values": [f"user:{self.user.id}"],
|
|
"values": [f"user:{self.user.id}"],
|
|
}
|
|
}
|
|
)
|
|
)
|
|
|
|
+ assert response.status_code == 200
|
|
assert self.get_message_content(response) == ASSIGNEE_UPDATED
|
|
assert self.get_message_content(response) == ASSIGNEE_UPDATED
|
|
|
|
|
|
def test_resolve_dialog(self):
|
|
def test_resolve_dialog(self):
|
|
@@ -129,6 +181,7 @@ class DiscordMessageComponentInteractionTest(APITestCase):
|
|
"custom_id": f"{CustomIds.RESOLVE_DIALOG}:{self.group.id}",
|
|
"custom_id": f"{CustomIds.RESOLVE_DIALOG}:{self.group.id}",
|
|
}
|
|
}
|
|
)
|
|
)
|
|
|
|
+ assert response.status_code == 200
|
|
assert self.get_select_options(response) == [
|
|
assert self.get_select_options(response) == [
|
|
option.build() for option in RESOLVE_DIALOG_OPTIONS
|
|
option.build() for option in RESOLVE_DIALOG_OPTIONS
|
|
]
|
|
]
|
|
@@ -140,6 +193,7 @@ class DiscordMessageComponentInteractionTest(APITestCase):
|
|
"custom_id": f"{CustomIds.RESOLVE}:{self.group.id}",
|
|
"custom_id": f"{CustomIds.RESOLVE}:{self.group.id}",
|
|
}
|
|
}
|
|
)
|
|
)
|
|
|
|
+ assert response.status_code == 200
|
|
assert self.get_message_content(response) == RESOLVED
|
|
assert self.get_message_content(response) == RESOLVED
|
|
|
|
|
|
def test_resolve_now_from_dialog(self):
|
|
def test_resolve_now_from_dialog(self):
|
|
@@ -150,6 +204,7 @@ class DiscordMessageComponentInteractionTest(APITestCase):
|
|
"values": [""],
|
|
"values": [""],
|
|
}
|
|
}
|
|
)
|
|
)
|
|
|
|
+ assert response.status_code == 200
|
|
assert self.get_message_content(response) == RESOLVED
|
|
assert self.get_message_content(response) == RESOLVED
|
|
|
|
|
|
def test_resolve_in_next_release(self):
|
|
def test_resolve_in_next_release(self):
|
|
@@ -165,6 +220,7 @@ class DiscordMessageComponentInteractionTest(APITestCase):
|
|
"values": ["inNextRelease"],
|
|
"values": ["inNextRelease"],
|
|
}
|
|
}
|
|
)
|
|
)
|
|
|
|
+ assert response.status_code == 200
|
|
assert self.get_message_content(response) == RESOLVED_IN_NEXT_RELEASE
|
|
assert self.get_message_content(response) == RESOLVED_IN_NEXT_RELEASE
|
|
|
|
|
|
def test_resolve_in_current_release(self):
|
|
def test_resolve_in_current_release(self):
|
|
@@ -180,6 +236,7 @@ class DiscordMessageComponentInteractionTest(APITestCase):
|
|
"values": ["inCurrentRelease"],
|
|
"values": ["inCurrentRelease"],
|
|
}
|
|
}
|
|
)
|
|
)
|
|
|
|
+ assert response.status_code == 200
|
|
assert self.get_message_content(response) == RESOLVED_IN_CURRENT_RELEASE
|
|
assert self.get_message_content(response) == RESOLVED_IN_CURRENT_RELEASE
|
|
|
|
|
|
def test_unresolve(self):
|
|
def test_unresolve(self):
|
|
@@ -189,6 +246,7 @@ class DiscordMessageComponentInteractionTest(APITestCase):
|
|
"custom_id": f"{CustomIds.UNRESOLVE}:{self.group.id}",
|
|
"custom_id": f"{CustomIds.UNRESOLVE}:{self.group.id}",
|
|
}
|
|
}
|
|
)
|
|
)
|
|
|
|
+ assert response.status_code == 200
|
|
assert self.get_message_content(response) == UNRESOLVED
|
|
assert self.get_message_content(response) == UNRESOLVED
|
|
|
|
|
|
def test_mark_ongoing(self):
|
|
def test_mark_ongoing(self):
|
|
@@ -198,6 +256,7 @@ class DiscordMessageComponentInteractionTest(APITestCase):
|
|
"custom_id": f"{CustomIds.MARK_ONGOING}:{self.group.id}",
|
|
"custom_id": f"{CustomIds.MARK_ONGOING}:{self.group.id}",
|
|
}
|
|
}
|
|
)
|
|
)
|
|
|
|
+ assert response.status_code == 200
|
|
assert self.get_message_content(response) == MARKED_ONGOING
|
|
assert self.get_message_content(response) == MARKED_ONGOING
|
|
|
|
|
|
def test_archive(self):
|
|
def test_archive(self):
|
|
@@ -207,4 +266,5 @@ class DiscordMessageComponentInteractionTest(APITestCase):
|
|
"custom_id": f"{CustomIds.ARCHIVE}:{self.group.id}",
|
|
"custom_id": f"{CustomIds.ARCHIVE}:{self.group.id}",
|
|
}
|
|
}
|
|
)
|
|
)
|
|
|
|
+ assert response.status_code == 200
|
|
assert self.get_message_content(response) == ARCHIVE_UNTIL_ESCALATES
|
|
assert self.get_message_content(response) == ARCHIVE_UNTIL_ESCALATES
|