release: v0.16.0
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>
This commit is contained in:
116
lib/__tests__/grid-columns-clamp.test.ts
Normal file
116
lib/__tests__/grid-columns-clamp.test.ts
Normal file
@@ -0,0 +1,116 @@
|
||||
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);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user