mirror of
https://github.com/kikootwo/ReadMeABook.git
synced 2026-06-02 20:30:10 +00:00
eca24e46a8
Add missing mocks used by updated code paths: mock PreferencesContext in profile page tests and add useReplaceWithTorrent/replaceWithTorrent mock for InteractiveTorrentSearchModal tests. Update Audiobookshelf API test to expect DELETE to include ?hard=1 and Authorization header. Extend the prisma test helper in audiobook-matcher tests with a reportedIssue.findMany mock and ensure it resolves to an empty array for the test.
176 lines
5.3 KiB
TypeScript
176 lines
5.3 KiB
TypeScript
/**
|
|
* Component: Interactive Torrent Search Modal Tests
|
|
* Documentation: documentation/frontend/components.md
|
|
*/
|
|
|
|
// @vitest-environment jsdom
|
|
|
|
import React from 'react';
|
|
import { fireEvent, render, screen, waitFor } from '@testing-library/react';
|
|
import { describe, expect, it, vi } from 'vitest';
|
|
|
|
const searchByRequestMock = vi.hoisted(() => vi.fn());
|
|
const selectTorrentMock = vi.hoisted(() => vi.fn());
|
|
const searchByAudiobookMock = vi.hoisted(() => vi.fn());
|
|
const requestWithTorrentMock = vi.hoisted(() => vi.fn());
|
|
const searchEbooksMock = vi.hoisted(() => vi.fn());
|
|
const selectEbookMock = vi.hoisted(() => vi.fn());
|
|
const searchEbooksByAsinMock = vi.hoisted(() => vi.fn());
|
|
const selectEbookByAsinMock = vi.hoisted(() => vi.fn());
|
|
const replaceWithTorrentMock = vi.hoisted(() => vi.fn());
|
|
|
|
vi.mock('@/lib/hooks/useReportedIssues', () => ({
|
|
useReplaceWithTorrent: () => ({
|
|
replaceWithTorrent: replaceWithTorrentMock,
|
|
isLoading: false,
|
|
error: null,
|
|
}),
|
|
}));
|
|
|
|
vi.mock('@/lib/hooks/useRequests', () => ({
|
|
useInteractiveSearch: () => ({
|
|
searchTorrents: searchByRequestMock,
|
|
isLoading: false,
|
|
error: null,
|
|
}),
|
|
useSelectTorrent: () => ({
|
|
selectTorrent: selectTorrentMock,
|
|
isLoading: false,
|
|
error: null,
|
|
}),
|
|
useSearchTorrents: () => ({
|
|
searchTorrents: searchByAudiobookMock,
|
|
isLoading: false,
|
|
error: null,
|
|
}),
|
|
useRequestWithTorrent: () => ({
|
|
requestWithTorrent: requestWithTorrentMock,
|
|
isLoading: false,
|
|
error: null,
|
|
}),
|
|
useInteractiveSearchEbook: () => ({
|
|
searchEbooks: searchEbooksMock,
|
|
isLoading: false,
|
|
error: null,
|
|
}),
|
|
useSelectEbook: () => ({
|
|
selectEbook: selectEbookMock,
|
|
isLoading: false,
|
|
error: null,
|
|
}),
|
|
useInteractiveSearchEbookByAsin: () => ({
|
|
searchEbooks: searchEbooksByAsinMock,
|
|
isLoading: false,
|
|
error: null,
|
|
}),
|
|
useSelectEbookByAsin: () => ({
|
|
selectEbook: selectEbookByAsinMock,
|
|
isLoading: false,
|
|
error: null,
|
|
}),
|
|
}));
|
|
|
|
const baseResult = {
|
|
guid: 'torrent-1',
|
|
rank: 1,
|
|
title: 'Test Torrent',
|
|
size: 2.4 * 1024 ** 3,
|
|
score: 88,
|
|
bonusPoints: 5,
|
|
seeders: 42,
|
|
indexer: 'ProIndexer',
|
|
format: 'M4B',
|
|
infoUrl: 'https://example.com/torrent',
|
|
};
|
|
|
|
describe('InteractiveTorrentSearchModal', () => {
|
|
it('searches by request id on open and confirms download', async () => {
|
|
searchByRequestMock.mockResolvedValueOnce([baseResult]);
|
|
selectTorrentMock.mockResolvedValueOnce(undefined);
|
|
const onClose = vi.fn();
|
|
const onSuccess = vi.fn();
|
|
const { InteractiveTorrentSearchModal } = await import('@/components/requests/InteractiveTorrentSearchModal');
|
|
|
|
render(
|
|
<InteractiveTorrentSearchModal
|
|
isOpen={true}
|
|
onClose={onClose}
|
|
onSuccess={onSuccess}
|
|
requestId="req-123"
|
|
audiobook={{ title: 'Test Book', author: 'Test Author' }}
|
|
/>
|
|
);
|
|
|
|
await waitFor(() => {
|
|
expect(searchByRequestMock).toHaveBeenCalledWith('req-123', undefined);
|
|
});
|
|
|
|
expect(await screen.findByText('Test Torrent')).toBeInTheDocument();
|
|
|
|
fireEvent.click(screen.getByRole('button', { name: 'Get' }));
|
|
fireEvent.click(await screen.findByRole('button', { name: 'Download' }));
|
|
|
|
await waitFor(() => {
|
|
expect(selectTorrentMock).toHaveBeenCalledWith('req-123', baseResult);
|
|
});
|
|
expect(onSuccess).toHaveBeenCalled();
|
|
expect(onClose).toHaveBeenCalled();
|
|
});
|
|
|
|
it('searches by audiobook data and requests with torrent', async () => {
|
|
searchByAudiobookMock.mockResolvedValueOnce([baseResult]);
|
|
requestWithTorrentMock.mockResolvedValueOnce(undefined);
|
|
const onClose = vi.fn();
|
|
const fullAudiobook = { asin: 'ASIN-1', title: 'Test Book', author: 'Test Author' };
|
|
const { InteractiveTorrentSearchModal } = await import('@/components/requests/InteractiveTorrentSearchModal');
|
|
|
|
render(
|
|
<InteractiveTorrentSearchModal
|
|
isOpen={true}
|
|
onClose={onClose}
|
|
audiobook={{ title: 'Test Book', author: 'Test Author' }}
|
|
fullAudiobook={fullAudiobook as any}
|
|
/>
|
|
);
|
|
|
|
await waitFor(() => {
|
|
expect(searchByAudiobookMock).toHaveBeenCalledWith('Test Book', 'Test Author', 'ASIN-1');
|
|
});
|
|
|
|
fireEvent.click(screen.getByRole('button', { name: 'Get' }));
|
|
fireEvent.click(await screen.findByRole('button', { name: 'Download' }));
|
|
|
|
await waitFor(() => {
|
|
expect(requestWithTorrentMock).toHaveBeenCalledWith(fullAudiobook, baseResult);
|
|
});
|
|
expect(onClose).toHaveBeenCalled();
|
|
});
|
|
|
|
it('uses a custom title when pressing Enter', async () => {
|
|
searchByRequestMock.mockResolvedValueOnce([]);
|
|
searchByRequestMock.mockResolvedValueOnce([]);
|
|
const { InteractiveTorrentSearchModal } = await import('@/components/requests/InteractiveTorrentSearchModal');
|
|
|
|
render(
|
|
<InteractiveTorrentSearchModal
|
|
isOpen={true}
|
|
onClose={vi.fn()}
|
|
requestId="req-456"
|
|
audiobook={{ title: 'Original Title', author: 'Author' }}
|
|
/>
|
|
);
|
|
|
|
await waitFor(() => {
|
|
expect(searchByRequestMock).toHaveBeenCalledWith('req-456', undefined);
|
|
});
|
|
|
|
const input = screen.getByPlaceholderText('Search title...');
|
|
fireEvent.change(input, { target: { value: 'Custom Title' } });
|
|
fireEvent.keyDown(input, { key: 'Enter', code: 'Enter' });
|
|
|
|
await waitFor(() => {
|
|
expect(searchByRequestMock).toHaveBeenNthCalledWith(2, 'req-456', 'Custom Title');
|
|
});
|
|
});
|
|
});
|