fix(web): права в шапке сервера обновляются после выдачи роли
По MEMBER_UPDATE/ROLE_* клиент перечитывал участников, роли и комнаты, но
не сводку сервера: `my_permissions` в сторе сессии оставались прежними, и
кнопки управления (🔗 приглашение, ⚙ настройки, + комната) появлялись
только после перезагрузки. Матрица 11.6 требует, чтобы права сразу меняли
доступные действия (AGENT.md 11.6).
- в ветках `MEMBER_UPDATE`/`MEMBER_REMOVE` и `ROLE_*` вызывается
`addGuildFromRest` — сводка сервера перечитывается и мержится;
- vitest: кнопки появляются по событию (тест падает без правки).
This commit is contained in:
@@ -295,6 +295,9 @@ export function dispatchGatewayEvent(event: GatewayDispatch): void {
|
||||
if (guildId !== null) {
|
||||
void invalidateMembershipQueries(guildId);
|
||||
session.scheduleGuildChannelsReload(guildId);
|
||||
// Свои права после выдачи роли обновляет только сводка сервера: без
|
||||
// неё кнопки управления в шапке появлялись лишь после перезагрузки.
|
||||
void addGuildFromRest(guildId);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -305,6 +308,8 @@ export function dispatchGatewayEvent(event: GatewayDispatch): void {
|
||||
if (role !== null) {
|
||||
void invalidateMembershipQueries(role.guild_id);
|
||||
session.scheduleGuildChannelsReload(role.guild_id);
|
||||
// Права роли могли измениться и у меня: обновляем сводку сервера.
|
||||
void addGuildFromRest(role.guild_id);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -33,6 +33,12 @@ const user = makeUser();
|
||||
|
||||
const channels = [{ id: 'c-general', name: 'общий', type: 'text' as const, position: 0 }];
|
||||
|
||||
/**
|
||||
* Права, которые отдаёт REST-сводка сервера: тест выдачи роли меняет их и
|
||||
* проверяет, что клиент перечитал сводку по событию MEMBER_UPDATE.
|
||||
*/
|
||||
let restPermissions: string[] | null = null;
|
||||
|
||||
function guildSummary(overrides: Record<string, unknown> = {}) {
|
||||
return {
|
||||
id: 'g-1',
|
||||
@@ -79,7 +85,17 @@ function routes(guild: Record<string, unknown> = guildDetail()): FetchRoute[] {
|
||||
method: 'POST',
|
||||
response: () => json({ guild: guildDetail({ icon_file_id: '777', banner_file_id: '555' }) }),
|
||||
},
|
||||
{ match: '/api/v1/users/@me/guilds', response: () => json({ guilds: [guildSummary(guild)] }) },
|
||||
{
|
||||
match: '/api/v1/users/@me/guilds',
|
||||
response: () =>
|
||||
json({
|
||||
guilds: [
|
||||
guildSummary(
|
||||
restPermissions === null ? guild : { ...guild, my_permissions: restPermissions },
|
||||
),
|
||||
],
|
||||
}),
|
||||
},
|
||||
{ match: '/api/v1/users/@me', response: () => json({ user }) },
|
||||
{ match: '/api/v1/instance', response: () => json({ instance: { name: 'glchat-test' } }) },
|
||||
{ match: '/api/v1/guilds/g-1/members', response: () => json({ members: [] }) },
|
||||
@@ -122,6 +138,7 @@ async function bootApp(guild: Record<string, unknown> = guildDetail()) {
|
||||
|
||||
beforeEach(() => {
|
||||
resetStores();
|
||||
restPermissions = null;
|
||||
});
|
||||
|
||||
describe('оформление сервера в шапке и рейке', () => {
|
||||
@@ -217,6 +234,25 @@ describe('приглашение из шапки сервера', () => {
|
||||
await screen.findByTestId('guild-header');
|
||||
expect(screen.queryByTestId('guild-invite')).toBeNull();
|
||||
});
|
||||
|
||||
it('появляет кнопки после выдачи роли, без перезагрузки', async () => {
|
||||
// Роль выдали уже в открытом клиенте: сводка сервера перечитывается по
|
||||
// MEMBER_UPDATE, иначе кнопки управления ждали бы перезагрузки (AGENT.md 11.6).
|
||||
const { gateway } = await bootApp(guildDetail({ my_permissions: [], owner_id: 'user-9' }));
|
||||
await screen.findByTestId('guild-header');
|
||||
expect(screen.queryByTestId('guild-invite')).toBeNull();
|
||||
|
||||
restPermissions = ['MANAGE_GUILD', 'CREATE_INVITES'];
|
||||
act(() => {
|
||||
gateway.dispatch('MEMBER_UPDATE', { guild_id: 'g-1', user_id: 'user-1' });
|
||||
});
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByTestId('guild-invite')).toBeInTheDocument();
|
||||
});
|
||||
expect(screen.getByLabelText('Настройки сервера')).toBeInTheDocument();
|
||||
expect(screen.getByLabelText('Создать комнату')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
describe('встроенные звуки интерфейса', () => {
|
||||
|
||||
Reference in New Issue
Block a user