Files
immich-folio/app/api/admin/__tests__/settings-write.test.ts

78 lines
2.3 KiB
TypeScript
Raw Normal View History

import { describe, it, expect, vi, beforeEach } from 'vitest';
vi.mock('@/lib/admin/auth', () => ({
isAdminEnabled: vi.fn(() => true),
isAdminAuthenticated: vi.fn(async () => true),
COOKIE_NAME: 'folio_admin_session',
}));
vi.mock('@/lib/admin/yaml-service', () => ({
readSettingsYaml: vi.fn(async () => ({})),
writeSettingsYaml: vi.fn(async () => undefined),
}));
vi.mock('@/lib/config', () => ({
invalidateConfigCache: vi.fn(),
getConfigOrNull: vi.fn(() => null),
}));
vi.mock('@/lib/immich', () => ({
immich: { invalidateAll: vi.fn() },
}));
vi.mock('next/cache', () => ({ revalidatePath: vi.fn() }));
import { writeSettingsYaml } from '@/lib/admin/yaml-service';
import { PUT } from '../settings/route';
const put = (settings: unknown) =>
PUT(
new Request('http://localhost/api/admin/settings', {
method: 'PUT',
body: JSON.stringify({ settings }),
}),
);
/**
* The point of the check is not that a bad payload is reported — it is that
* nothing is written. settings.yaml is read by every public page, so a
* malformed save is discovered by visitors rather than by the person who made
* it (#599).
*/
describe('PUT /api/admin/settings', () => {
beforeEach(() => vi.clearAllMocks());
it('writes a valid payload', async () => {
const res = await put({ title: 'Folio', theme: 'minimal' });
expect(res.status).toBe(200);
expect(writeSettingsYaml).toHaveBeenCalledOnce();
});
it('leaves the file untouched when the payload is malformed', async () => {
const res = await put({ title: { de: 'Folio' }, grid: 3 });
expect(res.status).toBe(400);
expect(writeSettingsYaml).not.toHaveBeenCalled();
});
it('answers with the offending fields, so the panel can point at them', async () => {
const res = await put({ title: 1, theme: { fonts: { heading: 42 } } });
const body = await res.json();
expect(body.fields.map((f: { field: string }) => f.field).sort()).toEqual([
'theme.fonts.heading',
'title',
]);
});
it('still writes settings carrying keys this version does not know', async () => {
// Older and newer configs are both in the wild, and there is no
// schemaVersion to tell them apart.
const res = await put({ title: 'Folio', fromALaterRelease: { nested: true } });
expect(res.status).toBe(200);
expect(writeSettingsYaml).toHaveBeenCalledOnce();
});
});