immich/web/src/lib/components/asset-viewer/photo-viewer.spec.ts
Michel Heusschen e459d524a4
fix(web): high resolution image on zoom (#9818)
Co-authored-by: Alex <alex.tran1502@gmail.com>
2024-05-28 07:15:50 -04:00

84 lines
2.9 KiB
TypeScript

import * as utils from '$lib/utils';
import type { AssetResponseDto } from '@immich/sdk';
import { assetFactory } from '@test-data/factories/asset-factory';
import '@testing-library/jest-dom';
import { fireEvent, render, screen, waitFor } from '@testing-library/svelte';
import type { Mock, MockInstance } from 'vitest';
import PhotoViewer from './photo-viewer.svelte';
vi.mock('$lib/utils', async (originalImport) => {
const meta = await originalImport<typeof import('$lib/utils')>();
return {
...meta,
downloadRequest: vi.fn(),
};
});
describe('PhotoViewer component', () => {
let downloadRequestMock: MockInstance;
let createObjectURLMock: Mock<[obj: Blob], string>;
let asset: AssetResponseDto;
beforeAll(() => {
downloadRequestMock = vi.spyOn(utils, 'downloadRequest').mockResolvedValue({
data: new Blob(),
status: 200,
});
createObjectURLMock = vi.fn();
window.URL.createObjectURL = createObjectURLMock;
asset = assetFactory.build({ originalPath: 'image.png' });
});
afterAll(() => {
vi.resetAllMocks();
});
it('initially shows a loading spinner', () => {
render(PhotoViewer, { asset });
expect(screen.getByRole('status')).toBeInTheDocument();
});
it('loads and shows a photo', async () => {
createObjectURLMock.mockReturnValueOnce('url-one');
render(PhotoViewer, { asset });
expect(downloadRequestMock).toBeCalledWith(
expect.objectContaining({
url: `/api/asset/file/${asset.id}?isThumb=false&isWeb=true&c=${asset.checksum}`,
}),
);
await waitFor(() => expect(screen.getByRole('img')).toBeInTheDocument());
expect(screen.getByRole('img')).toHaveAttribute('src', 'url-one');
});
it('loads high resolution photo when zoomed', async () => {
createObjectURLMock.mockReturnValueOnce('url-one');
render(PhotoViewer, { asset });
createObjectURLMock.mockReturnValueOnce('url-two');
await waitFor(() => expect(screen.getByRole('img')).toBeInTheDocument());
await fireEvent(window, new CustomEvent('zoomImage'));
await waitFor(() => expect(screen.getByRole('img')).toHaveAttribute('src', 'url-two'));
expect(downloadRequestMock).toBeCalledWith(
expect.objectContaining({
url: `/api/asset/file/${asset.id}?isThumb=false&isWeb=false&c=${asset.checksum}`,
}),
);
});
it('reloads photo when checksum changes', async () => {
const { component } = render(PhotoViewer, { asset });
createObjectURLMock.mockReturnValueOnce('url-two');
await waitFor(() => expect(screen.getByRole('img')).toBeInTheDocument());
component.$set({ asset: { ...asset, checksum: 'new-checksum' } });
await waitFor(() => expect(screen.getByRole('img')).toHaveAttribute('src', 'url-two'));
expect(downloadRequestMock).toBeCalledWith(
expect.objectContaining({
url: `/api/asset/file/${asset.id}?isThumb=false&isWeb=true&c=new-checksum`,
}),
);
});
});