Repository: hikari-py/hikari
Pull request #958 (2022-01-09 16:49:26)

Add new message content related application flags
### Summary
<!-- Small summary of the merge request -->

### Checklist
<!-- Make sure to tick all the following boxes by putting an `x` in between (like this `[x]`) -->
- [ ] I have run `nox` and all the pipelines have passed.
- [ ] I have made unittests according to the code I have added/modified/deleted.

### Related issues
<!--
To mention an issue use `#issue-id` and to mention a merge request use `!merge-request-id`
To close/fix an issue use `Close #issue-id` or `Fix #issue-id` (depending on the merge request)
-->



Patch:
diff --git a/changes/955.feature.md b/changes/955.feature.md
new file mode 100644
index 00000000..6caee945
--- /dev/null
+++ b/changes/955.feature.md
@@ -0,0 +1,1 @@
+Added support for GET /users/@me/guilds/{guild}/member
diff --git a/changes/957.feature.md b/changes/957.feature.md
new file mode 100644
index 00000000..d2de0c58
--- /dev/null
+++ b/changes/957.feature.md
@@ -0,0 +1,1 @@
+Add the SUPPRESS_USER_JOIN_REPLIES system channel flag flag.
diff --git a/changes/958.feature.md b/changes/958.feature.md
new file mode 100644
index 00000000..cfea499f
--- /dev/null
+++ b/changes/958.feature.md
@@ -0,0 +1,1 @@
+Add new message content intent related application flags.
diff --git a/changes/959.feature.md b/changes/959.feature.md
new file mode 100644
index 00000000..3cf1a1cc
--- /dev/null
+++ b/changes/959.feature.md
@@ -0,0 +1,1 @@
+Add the BOT_HTTP_INTERACTIONS user flag.
diff --git a/changes/960.feature.md b/changes/960.feature.md
new file mode 100644
index 00000000..bc9ce30e
--- /dev/null
+++ b/changes/960.feature.md
@@ -0,0 +1,1 @@
+Add new presence activity flags.
diff --git a/changes/962.feature.md b/changes/962.feature.md
new file mode 100644
index 00000000..36f94575
--- /dev/null
+++ b/changes/962.feature.md
@@ -0,0 +1,1 @@
+Add locale and guild_locale properties to interactions.
diff --git a/changes/963.bugfix.md b/changes/963.bugfix.md
new file mode 100644
index 00000000..a5060cf2
--- /dev/null
+++ b/changes/963.bugfix.md
@@ -0,0 +1,1 @@
+UTF-8 characters are now properly handled for audit-log reasons in REST requests.
diff --git a/dev-requirements.txt b/dev-requirements.txt
index 6d4c46dc..eed57021 100644
--- a/dev-requirements.txt
+++ b/dev-requirements.txt
@@ -7,9 +7,9 @@ mock==4.0.3
 
 # Py.test stuff.
 pytest==6.2.5
-pytest-asyncio==0.16.0
+pytest-asyncio==0.17.0
 pytest-cov==3.0.0
-pytest-randomly==3.10.3
+pytest-randomly==3.11.0
 
 # Coverage testing.
 coverage[toml]==6.2
@@ -28,7 +28,7 @@ sphobjinv==2.1
 # TYPE CHECKING #
 #################
 
-mypy==0.930
+mypy==0.931
 pyright==0.0.13
 
 #######################
diff --git a/flake8-requirements.txt b/flake8-requirements.txt
index 0a252ae5..8afc4343 100644
--- a/flake8-requirements.txt
+++ b/flake8-requirements.txt
@@ -8,7 +8,7 @@ flake8-black==0.2.3                     # runs black
 flake8-broken-line==0.4.0               # forbey "\" linebreaks
 flake8-builtins==1.5.3                  # builtin shadowing checks
 flake8-coding==1.3.2                    # coding magic-comment detection
-flake8-comprehensions==3.7.0            # comprehension checks
+flake8-comprehensions==3.8.0            # comprehension checks
 flake8-deprecated==1.3                  # deprecated call checks
 flake8-docstrings==1.6.0                # pydocstyle support
 flake8-executable==2.1.1                # shebangs
diff --git a/hikari/api/interaction_server.py b/hikari/api/interaction_server.py
index 2fc389c7..d4d17b68 100644
--- a/hikari/api/interaction_server.py
+++ b/hikari/api/interaction_server.py
@@ -195,18 +195,6 @@ def set_listener(
     ) -> None:
         ...
 
-    @typing.overload
-    @abc.abstractmethod
-    def set_listener(
-        self,
-        interaction_type: typing.Type[_InteractionT_co],
-        listener: typing.Optional[ListenerT[_InteractionT_co, special_endpoints.InteractionResponseBuilder]],
-        /,
-        *,
-        replace: bool = False,
-    ) -> None:
-        ...
-
     @abc.abstractmethod
     def set_listener(
         self,
diff --git a/hikari/api/rest.py b/hikari/api/rest.py
index 52305954..1072c3a1 100644
--- a/hikari/api/rest.py
+++ b/hikari/api/rest.py
@@ -4894,6 +4894,40 @@ def fetch_members(
             doesn't require any intents.
         """
 
+    @abc.abstractmethod
+    async def fetch_my_member(self, guild: snowflakes.SnowflakeishOr[guilds.PartialGuild]) -> guilds.Member:
+        """Fetch the Oauth token's associated member in a guild.
+
+        !!! warning
+            This endpoint can only be used with a Bearer token. Using this
+            with a Bot token will result in a `hikari.errors.UnauthorizedError`.
+
+        Returns
+        -------
+        hikari.guilds.Member
+            The associated guild member.
+
+        Raises
+        ------
+        hikari.errors.UnauthorizedError
+            If you are unauthorized to make the request (invalid/missing token).
+        hikari.errors.NotFoundError
+            If the guild is not found.
+        hikari.errors.RateLimitTooLongError
+            Raised in the event that a rate limit occurs that is
+            longer than `max_rate_limit` when making a request.
+        hikari.errors.RateLimitedError
+            Usually, Hikari will handle and retry on hitting
+            rate-limits automatically. This includes most bucket-specific
+            rate-limits and global rate-limits. In some rare edge cases,
+            however, Discord implements other undocumented rules for
+            rate-limiting, such as limits per attribute. These cannot be
+            detected or handled normally by Hikari due to their undocumented
+            nature, and will trigger this exception if they occur.
+        hikari.errors.InternalServerError
+            If an internal error occurs on Discord while handling the request.
+        """
+
     @abc.abstractmethod
     async def search_members(
         self,
diff --git a/hikari/applications.py b/hikari/applications.py
index 6566d344..b8c508c9 100644
--- a/hikari/applications.py
+++ b/hikari/applications.py
@@ -89,6 +89,12 @@ class ApplicationFlags(enums.Flag):
     EMBEDDED = 1 << 17
     """Denotes that the application has functionality that's specially embedded in Discord's client."""
 
+    MESSAGE_CONTENT_INTENT = 1 << 18
+    """Denotes that the application has message content intent enabled in it's dashboard."""
+
+    MESSAGE_CONTENT_INTENT_LIMITED = 1 << 19
+    """Denotes that the application has message content access while pending verification."""
+
 
 @typing.final
 class OAuth2Scope(str, enums.Enum):
@@ -221,6 +227,9 @@ class OAuth2Scope(str, enums.Enum):
     This is used during authorization code grants.
     """
 
+    GUILDS_MEMBERS_READ = "guilds.members.read"
+    """Used to read the current user's guild members."""
+
 
 @typing.final
 class ConnectionVisibility(int, enums.Enum):
diff --git a/hikari/guilds.py b/hikari/guilds.py
index e0aedfa7..b05dcc96 100644
--- a/hikari/guilds.py
+++ b/hikari/guilds.py
@@ -226,6 +226,9 @@ class GuildSystemChannelFlag(enums.Flag):
     SUPPRESS_GUILD_REMINDER = 1 << 2
     """Suppress displaying messages with guild setup tips."""
 
+    SUPPRESS_USER_JOIN_REPLIES = 1 << 3
+    """Suppress displaying a reply button on join notifications."""
+
 
 @typing.final
 class GuildVerificationLevel(int, enums.Enum):
diff --git a/hikari/impl/entity_factory.py b/hikari/impl/entity_factory.py
index 902d8d9d..8c655f55 100644
--- a/hikari/impl/entity_factory.py
+++ b/hikari/impl/entity_factory.py
@@ -1900,6 +1900,8 @@ def deserialize_command_interaction(
             command_name=data_payload["name"],
             options=options,
             resolved=resolved,
+            locale=payload["locale"],
+            guild_locale=payload.get("guild_locale"),
         )
 
     def deserialize_interaction(self, payload: data_binding.JSONObject) -> base_interactions.PartialInteraction:
@@ -1970,6 +1972,8 @@ def deserialize_component_interaction(
             custom_id=data_payload["custom_id"],
             component_type=message_models.ComponentType(data_payload["component_type"]),
             message=self.deserialize_message(payload["message"]),
+            locale=payload["locale"],
+            guild_locale=payload.get("guild_locale"),
         )
 
     ##################
diff --git a/hikari/impl/interaction_server.py b/hikari/impl/interaction_server.py
index e72ee330..8863624c 100644
--- a/hikari/impl/interaction_server.py
+++ b/hikari/impl/interaction_server.py
@@ -538,19 +538,6 @@ def set_listener(
     ) -> None:
         ...
 
-    @typing.overload
-    def set_listener(
-        self,
-        interaction_type: typing.Type[_InteractionT_co],
-        listener: typing.Optional[
-            interaction_server.ListenerT[_InteractionT_co, special_endpoints.InteractionResponseBuilder]
-        ],
-        /,
-        *,
-        replace: bool = False,
-    ) -> None:
-        ...
-
     def set_listener(
         self,
         interaction_type: typing.Type[_InteractionT_co],
diff --git a/hikari/impl/rest.py b/hikari/impl/rest.py
index c8d5c802..65b94b71 100644
--- a/hikari/impl/rest.py
+++ b/hikari/impl/rest.py
@@ -42,6 +42,7 @@
 import platform
 import sys
 import typing
+import urllib.parse
 
 import aiohttp
 import attr
@@ -706,7 +707,8 @@ async def _request(
                 token = await self._token.acquire(self)
                 headers[_AUTHORIZATION_HEADER] = token
 
-        headers.put(_X_AUDIT_LOG_REASON_HEADER, reason)
+        # As per the docs, UTF-8 characters are only supported here if it's url-encoded.
+        headers.put(_X_AUDIT_LOG_REASON_HEADER, reason, conversion=urllib.parse.quote)
 
         url = compiled_route.create_url(self._rest_url)
 
@@ -2678,6 +2680,12 @@ def fetch_members(
             entity_factory=self._entity_factory, request_call=self._request, guild=guild
         )
 
+    async def fetch_my_member(self, guild: snowflakes.SnowflakeishOr[guilds.PartialGuild]) -> guilds.Member:
+        route = routes.GET_MY_GUILD_MEMBER.compile(guild=guild)
+        response = await self._request(route)
+        assert isinstance(response, dict)
+        return self._entity_factory.deserialize_member(response, guild_id=snowflakes.Snowflake(guild))
+
     async def search_members(
         self,
         guild: snowflakes.SnowflakeishOr[guilds.PartialGuild],
diff --git a/hikari/impl/rest_bot.py b/hikari/impl/rest_bot.py
index 299c7164..f3dda104 100644
--- a/hikari/impl/rest_bot.py
+++ b/hikari/impl/rest_bot.py
@@ -624,19 +624,6 @@ def set_listener(
     ) -> None:
         ...
 
-    @typing.overload
-    def set_listener(
-        self,
-        interaction_type: typing.Type[_InteractionT_co],
-        listener: typing.Optional[
-            interaction_server_.ListenerT[_InteractionT_co, special_endpoints.InteractionResponseBuilder]
-        ],
-        /,
-        *,
-        replace: bool = False,
-    ) -> None:
-        ...
-
     def set_listener(
         self,
         interaction_type: typing.Type[_InteractionT_co],
@@ -647,4 +634,4 @@ def set_listener(
         *,
         replace: bool = False,
     ) -> None:
-        self._server.set_listener(interaction_type, listener, replace=replace)
+        self._server.set_listener(interaction_type, listener, replace=replace)  # type: ignore
diff --git a/hikari/interactions/command_interactions.py b/hikari/interactions/command_interactions.py
index 8f9cdf93..d274e4e0 100644
--- a/hikari/interactions/command_interactions.py
+++ b/hikari/interactions/command_interactions.py
@@ -145,6 +145,16 @@ class CommandInteraction(base_interactions.MessageResponseMixin[CommandResponseT
     This will be `builtins.None` for command interactions triggered in DMs.
     """
 
+    guild_locale: typing.Optional[str] = attr.field(eq=False, hash=False, repr=True)
+    """The preferred language of the guild this command interaction was triggered in.
+
+    This will be `builtins.None` for command interactions triggered in DMs.
+
+    !!! note
+        This value can usually only be changed if `COMMUNITY` is in `hikari.guilds.Guild.features`
+        for the guild and will otherwise default to `en-US`.
+    """
+
     member: typing.Optional[base_interactions.InteractionMember] = attr.field(eq=False, hash=False, repr=True)
     """The member who triggered this command interaction.
 
@@ -158,6 +168,9 @@ class CommandInteraction(base_interactions.MessageResponseMixin[CommandResponseT
     user: users_.User = attr.field(eq=False, hash=False, repr=True)
     """The user who triggered this command interaction."""
 
+    locale: str = attr.field(eq=False, hash=False, repr=True)
+    """The selected language of the user who triggered this command interaction."""
+
     command_id: snowflakes.Snowflake = attr.field(eq=False, hash=False, repr=True)
     """ID of the command being invoked."""
 
diff --git a/hikari/interactions/component_interactions.py b/hikari/interactions/component_interactions.py
index 8fb78c4a..b53c8560 100644
--- a/hikari/interactions/component_interactions.py
+++ b/hikari/interactions/component_interactions.py
@@ -105,8 +105,19 @@ class ComponentInteraction(base_interactions.MessageResponseMixin[ComponentRespo
     guild_id: typing.Optional[snowflakes.Snowflake] = attr.field(eq=False)
     """ID of the guild this interaction was triggered in.
 
-    This will be `builtins.None` for command interactions triggered in DMs.
+    This will be `builtins.None` for component interactions triggered in DMs.
     """
+
+    guild_locale: typing.Optional[str] = attr.field(eq=False, hash=False, repr=True)
+    """The preferred language of the guild this component interaction was triggered in.
+
+    This will be `builtins.None` for component interactions triggered in DMs.
+
+    !!! note
+        This value can usually only be changed if `COMMUNITY` is in `hikari.guilds.Guild.features`
+        for the guild and will otherwise default to `en-US`.
+    """
+
     message: messages.Message = attr.field(eq=False, repr=False)
     """Object of the message the components for this interaction are attached to."""
 
@@ -123,6 +134,9 @@ class ComponentInteraction(base_interactions.MessageResponseMixin[ComponentRespo
     user: users.User = attr.field(eq=False, hash=False, repr=True)
     """The user who triggered this interaction."""
 
+    locale: str = attr.field(eq=False, hash=False, repr=True)
+    """The selected language of the user who triggered this component interaction."""
+
     def build_response(self, type_: _ImmediateTypesT, /) -> special_endpoints.InteractionMessageBuilder:
         """Get a message response builder for use in the REST server flow.
 
diff --git a/hikari/internal/enums.pyi b/hikari/internal/enums.pyi
index 5633c147..5fbf00c9 100644
--- a/hikari/internal/enums.pyi
+++ b/hikari/internal/enums.pyi
@@ -63,19 +63,18 @@ class Flag(__enum.IntFlag):
     def __len__(self) -> int: ...
     @staticmethod
     def __new__(cls: __Type[__FlagT], value: int = 0) -> __FlagT: ...
-
     # Aliases
-    def isdisjoint(self: __FlagT, other: __Union[int, __FlagT]) -> bool: ... # is_disjoint
-    def issuperset(self: __FlagT, other: __Union[int, __FlagT]) -> bool: ... # is_superset
-    def symmetricdifference(self: __FlagT, other: __Union[int, __FlagT]) -> __FlagT: ... # symmetric_difference
+    def isdisjoint(self: __FlagT, other: __Union[int, __FlagT]) -> bool: ...  # is_disjoint
+    def issuperset(self: __FlagT, other: __Union[int, __FlagT]) -> bool: ...  # is_superset
+    def symmetricdifference(self: __FlagT, other: __Union[int, __FlagT]) -> __FlagT: ...  # symmetric_difference
     def issubset(self: __FlagT, other: __Union[int, __FlagT]) -> bool: ...  # is_subset
     def __contains__(self: __FlagT, other: __Union[int, __FlagT]) -> bool: ...  # is_subset
-    def __rand__(self: __FlagT, other: __Union[int, __FlagT]) -> __FlagT: ... # intersection
-    def __and__(self: __FlagT, other: __Union[int, __FlagT]) -> __FlagT: ... # intersection
-    def __ror__(self: __FlagT, other: __Union[int, __FlagT]) -> __FlagT: ... # union
-    def __or__(self: __FlagT, other: __Union[int, __FlagT]) -> __FlagT: ... # union
-    def __rsub__(self: __FlagT, other: __Union[int, __FlagT]) -> __FlagT: ... # difference
-    def __sub__(self: __FlagT, other: __Union[int, __FlagT]) -> __FlagT: ... # difference
-    def __rxor__(self: __FlagT, other: __Union[int, __FlagT]) -> __FlagT: ... # symmetric_difference
-    def __xor__(self: __FlagT, other: __Union[int, __FlagT]) -> __FlagT: ... # symmetric_difference
-    def __invert__(self: __FlagT) -> __FlagT: ... # invert
+    def __rand__(self: __FlagT, other: __Union[int, __FlagT]) -> __FlagT: ...  # intersection
+    def __and__(self: __FlagT, other: __Union[int, __FlagT]) -> __FlagT: ...  # intersection
+    def __ror__(self: __FlagT, other: __Union[int, __FlagT]) -> __FlagT: ...  # union
+    def __or__(self: __FlagT, other: __Union[int, __FlagT]) -> __FlagT: ...  # union
+    def __rsub__(self: __FlagT, other: __Union[int, __FlagT]) -> __FlagT: ...  # difference
+    def __sub__(self: __FlagT, other: __Union[int, __FlagT]) -> __FlagT: ...  # difference
+    def __rxor__(self: __FlagT, other: __Union[int, __FlagT]) -> __FlagT: ...  # symmetric_difference
+    def __xor__(self: __FlagT, other: __Union[int, __FlagT]) -> __FlagT: ...  # symmetric_difference
+    def __invert__(self: __FlagT) -> __FlagT: ...  # invert
diff --git a/hikari/internal/routes.py b/hikari/internal/routes.py
index b3cfd8dc..d803993e 100644
--- a/hikari/internal/routes.py
+++ b/hikari/internal/routes.py
@@ -438,6 +438,7 @@ def compile_to_file(
 # @me
 POST_MY_CHANNELS: typing.Final[Route] = Route(POST, "/users/@me/channels")
 GET_MY_CONNECTIONS: typing.Final[Route] = Route(GET, "/users/@me/connections")  # OAuth2 only
+GET_MY_GUILD_MEMBER: typing.Final[Route] = Route(GET, "/users/@me/guilds/{guild}/member")  # OAuth2 only
 DELETE_MY_GUILD: typing.Final[Route] = Route(DELETE, "/users/@me/guilds/{guild}")
 
 GET_MY_GUILDS: typing.Final[Route] = Route(GET, "/users/@me/guilds")
diff --git a/hikari/presences.py b/hikari/presences.py
index 73192e78..b6f72c49 100644
--- a/hikari/presences.py
+++ b/hikari/presences.py
@@ -176,6 +176,15 @@ class ActivityFlag(enums.Flag):
     PLAY = 1 << 5
     """Play"""
 
+    PARTY_PRIVACY_FRIENDS = 1 << 6
+    """Party privacy: friends only."""
+
+    PARTY_PRIVACY_VOICE_CHANNEL = 1 << 7
+    """Party prvacy: voice channel only."""
+
+    EMBEDDED = 1 << 8
+    """An activity that's embedded into a voice channel."""
+
 
 # TODO: add strict type checking to gateway for this type in an invariant way.
 @attr_extensions.with_copy
diff --git a/hikari/users.py b/hikari/users.py
index 343f7f14..ed123f34 100644
--- a/hikari/users.py
+++ b/hikari/users.py
@@ -98,6 +98,9 @@ class UserFlag(enums.Flag):
     DISCORD_CERTIFIED_MODERATOR = 1 << 18
     """Discord Certified Moderator."""
 
+    BOT_HTTP_INTERACTIONS = 1 << 19
+    """Bot uses only HTTP interactions and is shown in the active member list."""
+
 
 @typing.final
 class PremiumType(int, enums.Enum):


Test patch:
diff --git a/tests/hikari/impl/test_entity_factory.py b/tests/hikari/impl/test_entity_factory.py
index 1c623e6e..80d5e978 100644
--- a/tests/hikari/impl/test_entity_factory.py
+++ b/tests/hikari/impl/test_entity_factory.py
@@ -3004,6 +3004,8 @@ def command_interaction_payload(self, member_payload, user_payload, guild_role_p
             "channel_id": "49949494",
             "member": interaction_member_payload,
             "token": "moe cat girls",
+            "locale": "es-ES",
+            "guild_locale": "en-US",
             "version": 69420,
             "application_id": "76234234",
         }
@@ -3031,6 +3033,8 @@ def test_deserialize_command_interaction(
         assert interaction.version == 69420
         assert interaction.channel_id == 49949494
         assert interaction.guild_id == 43123123
+        assert interaction.locale == "es-ES"
+        assert interaction.guild_locale == "en-US"
 
         # InteractionMember
         assert interaction.member == entity_factory_impl._deserialize_interaction_member(
@@ -3243,6 +3247,8 @@ def component_interaction_payload(self, interaction_member_payload, message_payl
             "data": {"custom_id": "click_one", "component_type": 2, "values": ["1", "2", "67"]},
             "channel_id": "345626669114982999",
             "application_id": "290926444748734465",
+            "locale": "es-ES",
+            "guild_locale": "en-US",
         }
 
     def test_deserialize_component_interaction(
@@ -3266,6 +3272,8 @@ def test_deserialize_component_interaction(
         )
         assert interaction.user is interaction.member.user
         assert interaction.values == ["1", "2", "67"]
+        assert interaction.locale == "es-ES"
+        assert interaction.guild_locale == "en-US"
         assert isinstance(interaction, component_interactions.ComponentInteraction)
 
     def test_deserialize_component_interaction_with_undefined_fields(
@@ -3282,6 +3290,7 @@ def test_deserialize_component_interaction_with_undefined_fields(
                 "data": {"custom_id": "click_one", "component_type": 2},
                 "channel_id": "345626669114982999",
                 "application_id": "290926444748734465",
+                "locale": "es-ES",
             }
         )
 
@@ -3289,6 +3298,7 @@ def test_deserialize_component_interaction_with_undefined_fields(
         assert interaction.member is None
         assert interaction.user == entity_factory_impl.deserialize_user(user_payload)
         assert interaction.values == ()
+        assert interaction.guild_locale is None
         assert isinstance(interaction, component_interactions.ComponentInteraction)
 
     ##################
diff --git a/tests/hikari/impl/test_rest.py b/tests/hikari/impl/test_rest.py
index 421d7d90..ad883b04 100644
--- a/tests/hikari/impl/test_rest.py
+++ b/tests/hikari/impl/test_rest.py
@@ -1084,6 +1084,22 @@ async def test__request_builds_form_when_passed(self, rest_client, exit_exceptio
         assert kwargs["data"] is mock_form.build.return_value
         assert live_attributes.still_alive.call_count == 3
 
+    @hikari_test_helpers.timeout()
+    async def test__request_url_encodes_reason_header(self, rest_client, exit_exception, live_attributes):
+        route = routes.Route("GET", "/something/{channel}/somewhere").compile(channel=123)
+        mock_session = mock.AsyncMock(request=mock.AsyncMock(side_effect=exit_exception))
+        live_attributes.buckets.is_started = True
+        live_attributes.client_session = mock_session
+
+        with pytest.raises(exit_exception):
+            await rest_client._request(route, reason="光のenergyが　大地に降りそそぐ")
+
+        _, kwargs = mock_session.request.call_args_list[0]
+        assert kwargs["headers"][rest._X_AUDIT_LOG_REASON_HEADER] == (
+            "%E5%85%89%E3%81%AEenergy%E3%81%8C%E3%80%80%E5%A4%"
+            "A7%E5%9C%B0%E3%81%AB%E9%99%8D%E3%82%8A%E3%81%9D%E3%81%9D%E3%81%90"
+        )
+
     @hikari_test_helpers.timeout()
     async def test__request_with_strategy_token(self, rest_client, exit_exception, live_attributes):
         route = routes.Route("GET", "/something/{channel}/somewhere").compile(channel=123)
@@ -3438,6 +3454,18 @@ async def test_fetch_member(self, rest_client):
         rest_client._request.assert_awaited_once_with(expected_route)
         rest_client._entity_factory.deserialize_member.assert_called_once_with({"id": "789"}, guild_id=123)
 
+    async def test_fetch_my_member(self, rest_client) -> guilds.Member:
+        expected_route = routes.GET_MY_GUILD_MEMBER.compile(guild=45123)
+        rest_client._request = mock.AsyncMock(return_value={"id": "595995"})
+
+        result = await rest_client.fetch_my_member(StubModel(45123))
+
+        assert result is rest_client._entity_factory.deserialize_member.return_value
+        rest_client._request.assert_awaited_once_with(expected_route)
+        rest_client._entity_factory.deserialize_member.assert_called_once_with(
+            rest_client._request.return_value, guild_id=45123
+        )
+
     async def test_search_members(self, rest_client):
         member = StubModel(645234123)
         expected_route = routes.GET_GUILD_MEMBERS_SEARCH.compile(guild=645234123)
diff --git a/tests/hikari/interactions/test_command_interactions.py b/tests/hikari/interactions/test_command_interactions.py
index c8792475..055b1641 100644
--- a/tests/hikari/interactions/test_command_interactions.py
+++ b/tests/hikari/interactions/test_command_interactions.py
@@ -52,6 +52,8 @@ def mock_command_interaction(self, mock_app):
             command_name="OKOKOK",
             options=[],
             resolved=None,
+            locale="es-ES",
+            guild_locale="en-US",
         )
 
     def test_build_response(self, mock_command_interaction, mock_app):
diff --git a/tests/hikari/interactions/test_component_interactions.py b/tests/hikari/interactions/test_component_interactions.py
index 7b50e018..1eb7f8b5 100644
--- a/tests/hikari/interactions/test_component_interactions.py
+++ b/tests/hikari/interactions/test_component_interactions.py
@@ -53,6 +53,8 @@ def mock_component_interaction(self, mock_app):
             values=(),
             custom_id="OKOKOK",
             message=object(),
+            locale="es-ES",
+            guild_locale="en-US",
         )
 
     def test_build_response(self, mock_component_interaction, mock_app):