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:
77
app/api/admin/__tests__/settings-write.test.ts
Normal file
77
app/api/admin/__tests__/settings-write.test.ts
Normal file
@@ -0,0 +1,77 @@
|
||||
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();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user