68 lines
3.4 KiB
TypeScript
68 lines
3.4 KiB
TypeScript
import { AuthSession } from '@pipu/core';
|
|
import { createI18n } from '@pipu/i18n';
|
|
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
|
import { cleanup, render, screen } from '@testing-library/react';
|
|
import userEvent from '@testing-library/user-event';
|
|
import { I18nextProvider } from 'react-i18next';
|
|
import { afterEach, expect, it } from 'vitest';
|
|
import { SessionProvider } from '../../app/session';
|
|
import { GeniusPanel } from './GeniusPanel';
|
|
|
|
afterEach(cleanup);
|
|
|
|
const initial = {
|
|
configured: true, paused: false, running: true,
|
|
total: 100, pending: 80, matched: 17, lyrics: 15, annotations: 5, images: 17,
|
|
unmatched: 2, errors: 1, last_error: '', cooldown_until: '2000-01-01T00:00:00Z',
|
|
};
|
|
|
|
async function fixture(overrides: Partial<typeof initial> = {}) {
|
|
let data = { ...initial, ...overrides };
|
|
const actions: string[] = [];
|
|
const session = new AuthSession({ baseUrl: 'http://localhost', clientType: 'web', fetch: async (url, init) => {
|
|
const request = new Request(url, init);
|
|
if (request.method === 'POST') {
|
|
const { action } = await request.json() as { action: string };
|
|
actions.push(action);
|
|
data = { ...data, paused: action === 'pause' };
|
|
}
|
|
return new Response(JSON.stringify(data), { headers: { 'Content-Type': 'application/json' } });
|
|
} });
|
|
const client = new QueryClient({ defaultOptions: { queries: { retry: false, staleTime: Infinity } } });
|
|
client.setQueryData(['genius-stats'], data);
|
|
const i18n = await createI18n('ru');
|
|
render(<I18nextProvider i18n={i18n}><SessionProvider session={session}><QueryClientProvider client={client}>
|
|
<GeniusPanel />
|
|
</QueryClientProvider></SessionProvider></I18nextProvider>);
|
|
return { actions, user: userEvent.setup() };
|
|
}
|
|
|
|
it.each<[Partial<typeof initial>, string]>([
|
|
[{}, 'Получение данных из Genius…'],
|
|
[{ running: false }, 'Очередь ожидает обработки'],
|
|
[{ paused: true }, 'Обработка приостановлена'],
|
|
[{ cooldown_until: '2099-01-01T00:00:00Z' }, 'Ожидание после ограничения Genius'],
|
|
[{ running: false, pending: 0 }, 'Ожидание новых треков'],
|
|
])('shows queue state and progress for %j', async (overrides, status) => {
|
|
await fixture(overrides);
|
|
expect(screen.getByRole('status')).toHaveTextContent(status);
|
|
const progress = screen.getByRole('progressbar', { name: 'Прогресс обработки Genius' });
|
|
expect(progress).toHaveAttribute('max', '100');
|
|
expect(progress).toHaveAttribute('value', String(100 - (overrides.pending ?? 80)));
|
|
});
|
|
|
|
it('pauses and resumes the existing queue without requesting a retry', async () => {
|
|
const { user, actions } = await fixture();
|
|
await user.click(screen.getByRole('button', { name: 'Приостановить обработку' }));
|
|
await user.click(await screen.findByRole('button', { name: 'Продолжить обработку' }));
|
|
expect(actions).toEqual(['pause', 'start']);
|
|
expect(screen.getByRole('progressbar')).toHaveAttribute('value', '20');
|
|
});
|
|
|
|
it('explains the retry scope and sends the retry action', async () => {
|
|
const { user, actions } = await fixture();
|
|
expect(screen.getByText(/Повтор добавит в очередь только/)).toBeVisible();
|
|
await user.click(screen.getByRole('button', { name: 'Добавить проблемные треки в очередь' }));
|
|
expect(actions).toEqual(['retry']);
|
|
});
|