Skip to content

Commit 7dcb529

Browse files
ref: fix types for mentions serializer (#83424)
-1 mixins! <!-- Describe your PR here. -->
1 parent ca71de7 commit 7dcb529

File tree

5 files changed

+56
-140
lines changed

5 files changed

+56
-140
lines changed

Diff for: pyproject.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,6 @@ module = [
163163
"sentry.api.serializers.models.project",
164164
"sentry.api.serializers.models.role",
165165
"sentry.api.serializers.models.rule",
166-
"sentry.api.serializers.rest_framework.mentions",
167166
"sentry.auth.helper",
168167
"sentry.auth.provider",
169168
"sentry.auth.system",
@@ -340,6 +339,7 @@ module = [
340339
"sentry.api.helpers.group_index.update",
341340
"sentry.api.helpers.source_map_helper",
342341
"sentry.api.serializers.models.organization_member.*",
342+
"sentry.api.serializers.rest_framework.group_notes",
343343
"sentry.audit_log.services.*",
344344
"sentry.auth.services.*",
345345
"sentry.auth.view",

Diff for: src/sentry/api/serializers/rest_framework/__init__.py

-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
from .group_notes import * # noqa: F401,F403
66
from .json import * # noqa: F401,F403
77
from .list import * # noqa: F401,F403
8-
from .mentions import * # noqa: F401,F403
98
from .origin import * # noqa: F401,F403
109
from .project import * # noqa: F401,F403
1110
from .project_key import * # noqa: F401,F403
+55-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,64 @@
1+
from __future__ import annotations
2+
3+
from typing import TypedDict
4+
15
from rest_framework import serializers
26
from rest_framework.serializers import ListField
37

48
from sentry.api.fields.actor import ActorField
5-
from sentry.api.serializers.rest_framework.mentions import MentionsMixin
9+
from sentry.models.organizationmember import OrganizationMember
10+
from sentry.models.team import Team
11+
from sentry.types.actor import Actor
12+
13+
14+
class _SeparatedActors(TypedDict):
15+
users: list[Actor]
16+
teams: list[Actor]
17+
18+
19+
def separate_actors(actors: list[Actor]) -> _SeparatedActors:
20+
users = [actor for actor in actors if actor.is_user]
21+
teams = [actor for actor in actors if actor.is_team]
22+
23+
return {"users": users, "teams": teams}
624

725

8-
class NoteSerializer(serializers.Serializer, MentionsMixin):
26+
class NoteSerializer(serializers.Serializer[None]):
927
text = serializers.CharField()
1028
mentions = ListField(child=ActorField(), required=False)
1129
external_id = serializers.CharField(allow_null=True, required=False)
30+
31+
def validate_mentions(self, mentions: list[Actor]) -> list[Actor]:
32+
if mentions and "projects" in self.context:
33+
34+
separated_actors = separate_actors(mentions)
35+
# Validate that all mentioned users exist and are on the project.
36+
users = separated_actors["users"]
37+
38+
mentioned_user_ids = {user.id for user in users}
39+
40+
projects = self.context["projects"]
41+
user_ids = list(
42+
OrganizationMember.objects.filter(
43+
teams__projectteam__project__in=[p.id for p in projects],
44+
user_id__in=mentioned_user_ids,
45+
).values_list("user_id", flat=True)
46+
)
47+
48+
if len(mentioned_user_ids) > len(user_ids):
49+
raise serializers.ValidationError("Cannot mention a non team member")
50+
51+
# Validate that all mentioned teams exist and are on the project.
52+
teams = separated_actors["teams"]
53+
mentioned_team_ids = {team.id for team in teams}
54+
if (
55+
len(mentioned_team_ids)
56+
> Team.objects.filter(
57+
id__in=mentioned_team_ids, projectteam__project__in=projects
58+
).count()
59+
):
60+
raise serializers.ValidationError(
61+
"Mentioned team not found or not associated with project"
62+
)
63+
64+
return mentions

Diff for: src/sentry/api/serializers/rest_framework/mentions.py

-93
This file was deleted.

Diff for: tests/sentry/api/serializers/rest_framework/test_mentions.py

-43
This file was deleted.

0 commit comments

Comments
 (0)