Files
ds-galo/frontend/src/lib/viewer-source.test.ts
T
iu 2b8d329a3e fix(photos): убрать мигание предпросмотра и задержку сброса правок
- фото и photo.updated несут edit_pending: рендер сохранённых правок ещё идёт
- клиент держит предпросмотр, пока серверная версия не загружена и не
  декодирована, поэтому оригинал не мелькает при подмене
- сброс возвратом контролов в значения по умолчанию виден сразу, не через 10 с
- Viewer берёт URL из актуального объекта (SSE), fresh остаётся фолбэком
- попутно исправлен порядок чтения tags и album_title в ListTrash
2026-10-25 10:02:04 +03:00

121 lines
3.2 KiB
TypeScript

import { describe, expect, it } from 'vitest';
import type { Photo } from './types';
import { computeViewerSource, editPendingOf } from './viewer-source';
const BASE = {
originalUrl: '/orig.jpg',
previewUrl: '/preview.jpg',
editUrl: '/edit.jpg',
editPreviewUrl: '/edit-preview.jpg'
};
describe('computeViewerSource', () => {
it('shows the server render when it matches the saved edits', () => {
const src = computeViewerSource({
zoomed: false,
dirty: false,
editPending: false,
localParamsEmpty: false,
...BASE
});
expect(src.useBase).toBe(false);
expect(src.serverSrc).toBe('/edit-preview.jpg');
expect(src.baseSrc).toBe('/preview.jpg');
});
it('uses the full-size variants in zoom', () => {
const src = computeViewerSource({
zoomed: true,
dirty: false,
editPending: false,
localParamsEmpty: false,
...BASE
});
expect(src.serverSrc).toBe('/edit.jpg');
expect(src.baseSrc).toBe('/orig.jpg');
});
it('keeps the client preview while local edits are unsaved', () => {
const src = computeViewerSource({
zoomed: true,
dirty: true,
editPending: false,
localParamsEmpty: false,
...BASE
});
expect(src.useBase).toBe(true);
expect(src.drawCanvas).toBe(true);
expect(src.baseSrc).toBe('/orig.jpg');
});
it('shows the base version immediately when the edits are reset to defaults', () => {
const src = computeViewerSource({
zoomed: true,
dirty: true,
editPending: false,
localParamsEmpty: true,
...BASE
});
expect(src.useBase).toBe(true);
expect(src.drawCanvas).toBe(false);
expect(src.baseSrc).toBe('/orig.jpg');
});
it('ignores a stale server render while the saved edits are still rendering', () => {
const src = computeViewerSource({
zoomed: false,
dirty: false,
editPending: true,
localParamsEmpty: false,
...BASE
});
expect(src.useBase).toBe(true);
expect(src.drawCanvas).toBe(true);
});
it('keeps the client preview when a second edit is pending over an old render', () => {
const src = computeViewerSource({
zoomed: true,
dirty: false,
editPending: true,
localParamsEmpty: false,
...BASE
});
expect(src.useBase).toBe(true);
expect(src.drawCanvas).toBe(true);
expect(src.baseSrc).toBe('/orig.jpg');
});
it('falls back to the base version when there is no edit render', () => {
const src = computeViewerSource({
zoomed: false,
dirty: false,
editPending: false,
localParamsEmpty: true,
originalUrl: '/orig.jpg',
previewUrl: '/preview.jpg'
});
expect(src.useBase).toBe(true);
expect(src.drawCanvas).toBe(false);
expect(src.serverSrc).toBe('/preview.jpg');
});
it('prefers the full-size base when zoomed without a preview', () => {
const src = computeViewerSource({
zoomed: true,
dirty: false,
editPending: false,
localParamsEmpty: true,
originalUrl: '/orig.jpg'
});
expect(src.baseSrc).toBe('/orig.jpg');
expect(src.serverSrc).toBe('/orig.jpg');
});
it('treats the old backend without edit_pending as a finished render', () => {
expect(editPendingOf(undefined)).toBe(false);
expect(editPendingOf({ id: 'p' } as Photo)).toBe(false);
expect(editPendingOf({ id: 'p', edit_pending: true } as Photo)).toBe(true);
});
});