feat(web): статус комнаты в шапке
Описание комнаты жило только в настройках: в шапке были имя и медленный режим, поэтому «статус комнаты» из матрицы 11.6 приходилось проверять по REST. Теперь описание показывается рядом с названием (длинное усекается, полный текст — в подсказке), а само поле приходит и в READY, и в событиях комнат (AGENT.md 7.5, 11.6). - `Channel.description` и разбор `description` в `parseChannelPayload`; - `channel-description` в шапке комнаты; - vitest `tests/channelHeader.test.tsx`: статус из снапшота, отсутствие статуса без описания и обновление по `CHANNEL_UPDATE` без перезагрузки.
This commit is contained in:
@@ -0,0 +1,110 @@
|
||||
import { beforeEach, describe, expect, it } from 'vitest';
|
||||
import { act, screen, waitFor } from '@testing-library/react';
|
||||
|
||||
import {
|
||||
installFetch,
|
||||
installGatewaySocket,
|
||||
json,
|
||||
makeReadySnapshot,
|
||||
makeUser,
|
||||
renderApp,
|
||||
resetStores,
|
||||
type FetchRoute,
|
||||
} from './helpers';
|
||||
|
||||
/**
|
||||
* Шапка комнаты показывает статус комнаты — описание рядом с названием
|
||||
* (AGENT.md 7.5, 11.6): раньше описание жило только в настройках, и проверить
|
||||
* «статус комнаты в шапке» было нечем.
|
||||
*/
|
||||
|
||||
const user = makeUser();
|
||||
|
||||
/** Текущий список комнат: его перечитывает клиент по CHANNEL_UPDATE. */
|
||||
let channels: Record<string, unknown>[] = [];
|
||||
|
||||
function routes(): FetchRoute[] {
|
||||
return [
|
||||
{ match: '/api/v1/users/@me/guilds', response: () => json({ guilds: [] }) },
|
||||
{ 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: [] }),
|
||||
},
|
||||
{ match: '/api/v1/guilds/g-1/roles', response: () => json({ roles: [] }) },
|
||||
{ match: '/api/v1/guilds/g-1/channels', response: () => json({ channels }) },
|
||||
{
|
||||
match: '/api/v1/guilds/g-1',
|
||||
response: () => json({ guild: { id: 'g-1', name: 'Сервер', owner_id: 'user-1' } }),
|
||||
},
|
||||
{ match: '/api/v1/channels/c-1/messages', response: () => json({ messages: [] }) },
|
||||
];
|
||||
}
|
||||
|
||||
/** Поднимает приложение на комнате `c-1` с заданными полями комнаты. */
|
||||
async function boot(channel: Record<string, unknown>) {
|
||||
channels = [{ id: 'c-1', name: 'общий', type: 'text', position: 0, ...channel }];
|
||||
const snapshot = makeReadySnapshot([
|
||||
{
|
||||
id: 'g-1',
|
||||
name: 'Сервер',
|
||||
is_main: true,
|
||||
owner_id: 'user-1',
|
||||
my_permissions: ['MANAGE_CHANNELS', 'SEND_MESSAGES'],
|
||||
channels: [channel as { id: string; name: string }],
|
||||
},
|
||||
]);
|
||||
installFetch(routes());
|
||||
const gateway = installGatewaySocket(snapshot);
|
||||
renderApp('/app/g-1/c-1');
|
||||
await gateway.greet();
|
||||
await screen.findByTestId('guild-rail');
|
||||
return { gateway };
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
resetStores();
|
||||
});
|
||||
|
||||
describe('статус комнаты в шапке', () => {
|
||||
it('показывает описание комнаты из снапшота', async () => {
|
||||
await boot({ id: 'c-1', name: 'общий', description: 'Статус комнаты' });
|
||||
|
||||
const header = await screen.findByTestId('channel-header');
|
||||
const description = await screen.findByTestId('channel-description');
|
||||
expect(description).toHaveTextContent('Статус комнаты');
|
||||
expect(description.getAttribute('title')).toBe('Статус комнаты');
|
||||
expect(header).toHaveTextContent('общий');
|
||||
});
|
||||
|
||||
it('не показывает статус у комнаты без описания', async () => {
|
||||
await boot({ id: 'c-1', name: 'общий' });
|
||||
|
||||
await screen.findByTestId('channel-header');
|
||||
expect(screen.queryByTestId('channel-description')).toBeNull();
|
||||
});
|
||||
|
||||
it('обновляет статус по CHANNEL_UPDATE без перезагрузки', async () => {
|
||||
const { gateway } = await boot({ id: 'c-1', name: 'общий', description: 'Старый статус' });
|
||||
await screen.findByTestId('channel-description');
|
||||
|
||||
// Сервер перечитал комнаты: клиент по событию запрашивает список заново.
|
||||
channels = [
|
||||
{ id: 'c-1', name: 'общий', type: 'text', position: 0, description: 'Новый статус' },
|
||||
];
|
||||
act(() => {
|
||||
gateway.dispatch('CHANNEL_UPDATE', {
|
||||
id: 'c-1',
|
||||
guild_id: 'g-1',
|
||||
name: 'общий',
|
||||
type: 'text',
|
||||
description: 'Новый статус',
|
||||
});
|
||||
});
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByTestId('channel-description')).toHaveTextContent('Новый статус');
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user