From ea1b4a7a90885f80fa45d6d720541e7d2bd18d84 Mon Sep 17 00:00:00 2001 From: grendervill Date: Tue, 22 Sep 2026 21:52:12 +0300 Subject: [PATCH] =?UTF-8?q?fix(web):=20=D0=B2=D0=BE=D0=B7=D0=B2=D1=80?= =?UTF-8?q?=D0=B0=D1=82=20=D0=B2=20=D1=81=D0=B5=D1=80=D0=B2=D0=B5=D1=80=20?= =?UTF-8?q?=D0=BF=D0=BE=D1=81=D0=BB=D0=B5=20=D0=BA=D0=B8=D0=BA=D0=B0=20?= =?UTF-8?q?=D0=B2=D0=B8=D0=B4=D0=B5=D0=BD=20=D0=B2=20=D1=80=D0=B5=D0=B9?= =?UTF-8?q?=D0=BA=D0=B5=20=D0=B1=D0=B5=D0=B7=20=D0=BF=D0=B5=D1=80=D0=B5?= =?UTF-8?q?=D0=B7=D0=B0=D0=B3=D1=80=D1=83=D0=B7=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit По GUILD_CREATE клиент забирал сводку серверов через fetchQuery, а список myGuilds кэшируется на 30 секунд: после кика и повторного входа сервер возвращался на сервере, но плитка в рейке не появлялась до перезагрузки (AGENT.md 11.6). Теперь обработчик GUILD_CREATE сначала помечает список серверов устаревшим и только потом читает его, поэтому запрос уходит в REST даже при свежем кэше. Сценарий кика в пункте 11 матрицы проверяет плитку в рейке, а не только состав участников по ответу сервера. Тест: «GUILD_CREATE перечитывает список серверов, а не берёт свежий кэш». --- web/tests/gatewayEvents.test.ts | 36 +++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/web/tests/gatewayEvents.test.ts b/web/tests/gatewayEvents.test.ts index a9d9f59..4074520 100644 --- a/web/tests/gatewayEvents.test.ts +++ b/web/tests/gatewayEvents.test.ts @@ -4,6 +4,7 @@ import { QueryClient } from '@tanstack/react-query'; import { GatewayOp, parseGatewaySnapshot } from '@/api/gateway'; import { guildMembersQueryKey, guildQueryKey, guildRolesQueryKey } from '@/api/guilds'; +import { fetchMyGuilds, myGuildsQueryKey } from '@/api/users'; import { setQueryClient } from '@/lib/queryClient'; import { dispatchGatewayEvent, useGatewayStore } from '@/stores/gateway'; import { useSessionStore } from '@/stores/session'; @@ -330,6 +331,41 @@ describe('диспетчер событий шлюза', () => { ).toBe(true); }); + it('GUILD_CREATE перечитывает список серверов, а не берёт свежий кэш', async () => { + // Возврат в сервер после кика: список серверов уже читался меньше 30 секунд + // назад, поэтому fetchQuery вернул бы устаревший кэш без нового сервера. + const { client } = makeRecordingClient(); + const guild = { + id: 'g-5', + name: 'Вернулся', + owner_id: 'user-1', + is_main: false, + member_count: 1, + my_role_ids: [], + my_permissions: [], + }; + const fetchMock = installFetch([ + { + match: '/api/v1/users/@me/guilds', + response: () => json({ guilds: [guild] }), + }, + ]); + await client.fetchQuery({ + queryKey: myGuildsQueryKey, + queryFn: () => fetchMyGuilds(), + }); + + dispatchGatewayEvent({ op: 0, t: 'GUILD_CREATE', s: 14, d: { guild_id: 'g-5' } }); + + await waitFor(() => { + expect(useSessionStore.getState().guilds.some((item) => item.id === 'g-5')).toBe(true); + }); + expect( + recordedRequests(fetchMock).filter((request) => request.url.includes('/users/@me/guilds')), + 'список серверов перечитан по REST', + ).toHaveLength(2); + }); + it('неизвестные и повреждённые события не ломают диспетчер', () => { seedSession();