fix(web): возврат в сервер после кика виден в рейке без перезагрузки

По GUILD_CREATE клиент забирал сводку серверов через fetchQuery, а список
myGuilds кэшируется на 30 секунд: после кика и повторного входа сервер
возвращался на сервере, но плитка в рейке не появлялась до перезагрузки
(AGENT.md 11.6).

Теперь обработчик GUILD_CREATE сначала помечает список серверов устаревшим и
только потом читает его, поэтому запрос уходит в REST даже при свежем кэше.
Сценарий кика в пункте 11 матрицы проверяет плитку в рейке, а не только
состав участников по ответу сервера.

Тест: «GUILD_CREATE перечитывает список серверов, а не берёт свежий кэш».
This commit is contained in:
2026-09-22 21:52:12 +03:00
parent a6cec5919a
commit ea1b4a7a90
+36
View File
@@ -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();