See CHANGELOG.md for the full v0.16.0 entry. --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: ralksta <ralksta@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Claude Opus 5 <noreply@anthropic.com> Co-authored-by: Ralf <rohlenbo79@gmail.com> Co-authored-by: Paul Thies <110185070+ImScheinox@users.noreply.github.com> Co-authored-by: lancetm714 <108419425+lancetm714@users.noreply.github.com>
117 lines
3.7 KiB
TypeScript
117 lines
3.7 KiB
TypeScript
import { describe, it, expect, vi, afterEach } from 'vitest';
|
|
|
|
vi.mock('@/lib/env', () => ({
|
|
env: {
|
|
IMMICH_API_URL: 'http://localhost:2283',
|
|
IMMICH_API_KEY: 'test-key',
|
|
SITE_TITLE: 'Test Gallery',
|
|
SITE_SUBTITLE: '',
|
|
CACHE_TTL: 300,
|
|
IMMICH_TIMEOUT_MS: 15000,
|
|
RATE_LIMIT_RPM: 120,
|
|
TRUSTED_PROXY_HOPS: 0,
|
|
},
|
|
normalizeApiUrl: (raw: string) => raw.replace(/\/+$/, ''),
|
|
}));
|
|
|
|
vi.mock('@/lib/secret', () => ({
|
|
resolveAuthSecret: () => 'test-auth-secret-32-chars-long-min',
|
|
}));
|
|
|
|
vi.mock('@/lib/config/parser', () => ({
|
|
loadYaml: vi.fn(),
|
|
clearYamlCache: vi.fn(),
|
|
validateUuid: (id: string) => id,
|
|
}));
|
|
|
|
import { getConfig, invalidateConfigCache, deriveGallery } from '@/lib/config';
|
|
import { loadYaml } from '@/lib/config/parser';
|
|
import type { GalleryYaml } from '@/lib/config/schema';
|
|
|
|
const ALBUM_ID = '11111111-1111-1111-1111-111111111111';
|
|
|
|
function withSettings(settings: unknown) {
|
|
vi.mocked(loadYaml).mockImplementation((filename: string) => {
|
|
if (filename === 'gallery.yaml') return { albums: [ALBUM_ID] };
|
|
if (filename === 'settings.yaml') return settings;
|
|
return null;
|
|
});
|
|
}
|
|
|
|
afterEach(() => {
|
|
invalidateConfigCache();
|
|
vi.clearAllMocks();
|
|
});
|
|
|
|
/**
|
|
* `--grid-columns` is emitted unclamped in app/[...path]/page.tsx, so a bad
|
|
* `columns` reaches `repeat()` invalid and collapses the whole grid to one
|
|
* column with no error anywhere (#633). The cover grid already clamped
|
|
* (buildCoverGridVars); the site-wide photo grid did not.
|
|
*/
|
|
describe('site-wide grid.columns / grid.gap clamping (#633)', () => {
|
|
it('clamps a negative columns count to the minimum', () => {
|
|
withSettings({ grid: { columns: -1 } });
|
|
expect(getConfig().grid.columns).toBe(1);
|
|
});
|
|
|
|
it('clamps an out-of-range columns count to the maximum', () => {
|
|
withSettings({ grid: { columns: 99 } });
|
|
expect(getConfig().grid.columns).toBe(6);
|
|
});
|
|
|
|
it('falls back to the default when columns is not a number', () => {
|
|
withSettings({ grid: { columns: 'three' as unknown as number } });
|
|
expect(getConfig().grid.columns).toBe(1); // clamp()'s min, not silently NaN
|
|
});
|
|
|
|
it('keeps a legitimate columns value', () => {
|
|
withSettings({ grid: { columns: 4 } });
|
|
expect(getConfig().grid.columns).toBe(4);
|
|
});
|
|
|
|
it('defaults columns to 3 when unset', () => {
|
|
withSettings({});
|
|
expect(getConfig().grid.columns).toBe(3);
|
|
});
|
|
|
|
it('clamps gap the same way', () => {
|
|
withSettings({ grid: { gap: -5 } });
|
|
expect(getConfig().grid.gap).toBe(0);
|
|
withSettings({ grid: { gap: 9999 } });
|
|
invalidateConfigCache();
|
|
expect(getConfig().grid.gap).toBe(48);
|
|
});
|
|
});
|
|
|
|
/**
|
|
* Same guard for a subpage's or an album's own grid override — the merged
|
|
* value (site-wide default overridden by this) is what actually reaches
|
|
* `--grid-columns`.
|
|
*/
|
|
describe('per-subpage grid override clamping (#633)', () => {
|
|
it('clamps a negative subpage columns override', () => {
|
|
const gallery = {
|
|
subpages: [{ name: 'Trips', albums: [ALBUM_ID], grid: { columns: -1 } }],
|
|
} as unknown as GalleryYaml;
|
|
const derived = deriveGallery(gallery);
|
|
expect(derived.subpages[0].grid?.columns).toBe(1);
|
|
});
|
|
|
|
it('clamps an out-of-range subpage columns override', () => {
|
|
const gallery = {
|
|
subpages: [{ name: 'Trips', albums: [ALBUM_ID], grid: { columns: 40 } }],
|
|
} as unknown as GalleryYaml;
|
|
const derived = deriveGallery(gallery);
|
|
expect(derived.subpages[0].grid?.columns).toBe(6);
|
|
});
|
|
|
|
it('keeps a legitimate subpage columns override', () => {
|
|
const gallery = {
|
|
subpages: [{ name: 'Trips', albums: [ALBUM_ID], grid: { columns: 2 } }],
|
|
} as unknown as GalleryYaml;
|
|
const derived = deriveGallery(gallery);
|
|
expect(derived.subpages[0].grid?.columns).toBe(2);
|
|
});
|
|
});
|