Files
Oxicloud/frontend/src/routes/photos/page.test.ts
T
2026-07-03 00:31:36 +02:00

91 lines
2.8 KiB
TypeScript

import { it, expect, vi, beforeEach } from 'vitest';
import { render, screen, waitFor } from '@testing-library/svelte';
const { ui, confirmDialog } = vi.hoisted(() => ({
ui: { notify: vi.fn() },
confirmDialog: vi.fn()
}));
vi.mock('$lib/stores/ui.svelte', () => ({ ui }));
vi.mock('$lib/stores/dialogs.svelte', () => ({ confirmDialog }));
vi.mock('$lib/api/endpoints/photos', () => ({
batchTrash: vi.fn(),
fetchPhotos: vi.fn(),
uploadThumbnail: vi.fn()
}));
vi.mock('$lib/api/endpoints/people', () => ({ peopleEnabled: vi.fn() }));
vi.mock('$lib/api/endpoints/files', () => ({
fileDownloadUrl: () => '/dl',
fileThumbnailUrl: () => '/thumb'
}));
import { fetchPhotos } from '$lib/api/endpoints/photos';
import { peopleEnabled } from '$lib/api/endpoints/people';
import PhotosPage from './+page.svelte';
const m = (fn: unknown) => fn as ReturnType<typeof vi.fn>;
function photo(id: string) {
return {
category: 'Image',
created_at: 0,
icon_class: 'fa-image',
icon_special_class: '',
id,
mime_type: 'image/jpeg',
modified_at: 0,
name: id + '.jpg',
owner_id: 'me',
created_by: 'me',
updated_by: 'me',
folder_id: 'home',
path: '/' + id + '.jpg',
size: 100,
size_formatted: '100 B',
sort_date: 1_700_000_000,
etag: 'e',
content_hash: 'h',
width: 100,
height: 100
};
}
beforeEach(() => {
vi.clearAllMocks();
m(peopleEnabled).mockResolvedValue(false);
});
it('loads the first page of photos on mount', async () => {
m(fetchPhotos).mockResolvedValue({ items: [photo('a')], nextCursor: null });
render(PhotosPage);
await waitFor(() => expect(fetchPhotos).toHaveBeenCalled());
expect(m(fetchPhotos).mock.calls[0][0]).toBe(60);
});
it('shows an empty state when there are no photos', async () => {
m(fetchPhotos).mockResolvedValue({ items: [], nextCursor: null });
render(PhotosPage);
await waitFor(() => expect(fetchPhotos).toHaveBeenCalled());
await waitFor(() => expect(screen.getByTestId('photos-tab-moments')).toBeTruthy());
});
it('surfaces a load error', async () => {
m(fetchPhotos).mockRejectedValue(new Error('photos boom'));
render(PhotosPage);
await waitFor(() => expect(screen.getByText('photos boom')).toBeTruthy());
});
it('hides the People tab when face detection is disabled', async () => {
m(fetchPhotos).mockResolvedValue({ items: [], nextCursor: null });
m(peopleEnabled).mockResolvedValue(false);
render(PhotosPage);
await waitFor(() => expect(peopleEnabled).toHaveBeenCalled());
expect(screen.queryByTestId('photos-tab-people')).toBeNull();
});
it('shows the People tab when face detection is enabled', async () => {
m(fetchPhotos).mockResolvedValue({ items: [], nextCursor: null });
m(peopleEnabled).mockResolvedValue(true);
render(PhotosPage);
await waitFor(() => expect(screen.getByTestId('photos-tab-people')).toBeTruthy());
});