mirror of
https://github.com/kikootwo/ReadMeABook.git
synced 2026-06-02 20:30:10 +00:00
a97979358f
Adds file hash-based matching for Audiobookshelf library items to ensure 100% accurate ASIN assignment for RMAB-organized content. Removes fuzzy matching from library availability checks, making all matching ASIN-only to eliminate false positives and race conditions. Updates database schema, processors, and matcher utilities; adds new tests and documentation for the new matching strategy. Removes obsolete scripts, Dockerfile, and related tests; updates docker-compose for test environments.
128 lines
3.8 KiB
TypeScript
128 lines
3.8 KiB
TypeScript
/**
|
|
* Component: Admin Logs Page Tests
|
|
* Documentation: documentation/admin-dashboard.md
|
|
*/
|
|
|
|
// @vitest-environment jsdom
|
|
|
|
import React from 'react';
|
|
import { fireEvent, render, screen, waitFor } from '@testing-library/react';
|
|
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
import AdminLogsPage from '@/app/admin/logs/page';
|
|
|
|
const useSWRMock = vi.hoisted(() => vi.fn());
|
|
|
|
vi.mock('swr', () => ({
|
|
default: (...args: any[]) => useSWRMock(...args),
|
|
}));
|
|
|
|
vi.mock('@/lib/utils/api', () => ({
|
|
authenticatedFetcher: vi.fn(),
|
|
}));
|
|
|
|
describe('AdminLogsPage', () => {
|
|
beforeEach(() => {
|
|
useSWRMock.mockReset();
|
|
});
|
|
|
|
it('renders logs and toggles detail rows', async () => {
|
|
useSWRMock.mockImplementation(() => ({
|
|
data: {
|
|
logs: [
|
|
{
|
|
id: 'log-1',
|
|
bullJobId: 'bull-1',
|
|
type: 'search_indexers',
|
|
status: 'failed',
|
|
priority: 1,
|
|
attempts: 2,
|
|
maxAttempts: 3,
|
|
errorMessage: 'Search failed',
|
|
startedAt: '2024-01-01T00:00:00Z',
|
|
completedAt: '2024-01-01T00:02:00Z',
|
|
createdAt: '2024-01-01T00:00:00Z',
|
|
updatedAt: '2024-01-01T00:02:00Z',
|
|
result: { retries: 2 },
|
|
events: [
|
|
{
|
|
id: 'event-1',
|
|
level: 'error',
|
|
context: 'SearchJob',
|
|
message: 'Indexer timeout',
|
|
metadata: { indexer: 'Example' },
|
|
createdAt: '2024-01-01T00:01:00Z',
|
|
},
|
|
],
|
|
request: {
|
|
id: 'req-1',
|
|
audiobook: { title: 'Search Book', author: 'Author' },
|
|
user: { plexUsername: 'User' },
|
|
},
|
|
},
|
|
],
|
|
pagination: { page: 1, limit: 50, total: 1, totalPages: 1 },
|
|
},
|
|
error: undefined,
|
|
}));
|
|
|
|
render(<AdminLogsPage />);
|
|
|
|
expect(await screen.findByText('System Logs')).toBeInTheDocument();
|
|
expect(screen.getByText('Search Book')).toBeInTheDocument();
|
|
|
|
fireEvent.click(screen.getByRole('button', { name: 'Show Details' }));
|
|
expect(screen.getByText('Event Log')).toBeInTheDocument();
|
|
expect(screen.getByText('Job Result')).toBeInTheDocument();
|
|
expect(screen.getByText('Error')).toBeInTheDocument();
|
|
|
|
fireEvent.click(screen.getByRole('button', { name: 'Hide Details' }));
|
|
expect(screen.queryByText('Event Log')).not.toBeInTheDocument();
|
|
});
|
|
|
|
it('updates the swr key when filters change', async () => {
|
|
useSWRMock.mockImplementation(() => ({
|
|
data: { logs: [], pagination: { page: 1, limit: 50, total: 0, totalPages: 1 } },
|
|
error: undefined,
|
|
}));
|
|
|
|
render(<AdminLogsPage />);
|
|
|
|
const statusSelect = screen
|
|
.getByText('Status', { selector: 'label' })
|
|
.parentElement?.querySelector('select');
|
|
expect(statusSelect).not.toBeNull();
|
|
fireEvent.change(statusSelect as HTMLSelectElement, { target: { value: 'completed' } });
|
|
|
|
await waitFor(() => {
|
|
expect(useSWRMock).toHaveBeenCalledWith(
|
|
'/api/admin/logs?page=1&limit=50&status=completed&type=all',
|
|
expect.any(Function),
|
|
expect.any(Object)
|
|
);
|
|
});
|
|
});
|
|
|
|
it('renders error state when logs fail to load', async () => {
|
|
useSWRMock.mockImplementation(() => ({
|
|
data: undefined,
|
|
error: new Error('Log failure'),
|
|
}));
|
|
|
|
render(<AdminLogsPage />);
|
|
|
|
expect(await screen.findByText('Error Loading Logs')).toBeInTheDocument();
|
|
expect(screen.getByText('Log failure')).toBeInTheDocument();
|
|
});
|
|
|
|
it('renders empty state when no logs are returned', async () => {
|
|
useSWRMock.mockImplementation(() => ({
|
|
data: { logs: [], pagination: { page: 1, limit: 50, total: 0, totalPages: 1 } },
|
|
error: undefined,
|
|
}));
|
|
|
|
render(<AdminLogsPage />);
|
|
|
|
expect(await screen.findByText('No logs found')).toBeInTheDocument();
|
|
});
|
|
});
|