mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-19 13:36:48 +00:00
95 lines
4.0 KiB
TypeScript
95 lines
4.0 KiB
TypeScript
/**
|
|
* The account defaults, after the two routes moved off AdminController next to
|
|
* SettingsService, which owns them. Same path, same audit action, same 400 envelope on
|
|
* a rejected write — these cases came over with the routes.
|
|
*/
|
|
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
import { HttpException } from '@nestjs/common';
|
|
import { AdminDefaultUserSettingsController } from '../../../src/nest/settings/settings.controller';
|
|
import { SettingsModule } from '../../../src/nest/settings/settings.module';
|
|
import type { SettingsService } from '../../../src/nest/settings/settings.service';
|
|
import type { AuditService } from '../../../src/nest/audit/audit.service';
|
|
import type { User } from '../../../src/types';
|
|
import { expectRegisteredController } from '../../helpers/module-providers';
|
|
import type { RuntimeEnvService } from '../../../src/nest/app-config/runtime-env.service';
|
|
|
|
const user = { id: 1, role: 'admin' } as User;
|
|
const req = { headers: {}, socket: {} } as never;
|
|
const writeAudit = vi.fn();
|
|
|
|
function controller(over: Partial<SettingsService> = {}) {
|
|
const settings = {
|
|
getAdminUserDefaults: vi.fn(() => ({ theme: 'dark' })),
|
|
setAdminUserDefaults: vi.fn(),
|
|
...over,
|
|
} as unknown as SettingsService;
|
|
return { c: new AdminDefaultUserSettingsController(settings, { writeAudit } as unknown as AuditService, { isManaged: () => false } as unknown as RuntimeEnvService), settings };
|
|
}
|
|
|
|
const thrown = async (run: () => unknown) => {
|
|
try {
|
|
await run();
|
|
return null;
|
|
} catch (e) {
|
|
return e instanceof HttpException ? { status: e.getStatus(), body: e.getResponse() } : e;
|
|
}
|
|
};
|
|
|
|
describe('AdminDefaultUserSettingsController', () => {
|
|
beforeEach(() => {
|
|
vi.clearAllMocks();
|
|
});
|
|
|
|
it('DEFAULTS-001 GET returns the stored defaults verbatim', async () => {
|
|
expect(await controller().c.get()).toEqual({ theme: 'dark' });
|
|
});
|
|
|
|
it('DEFAULTS-002 PUT writes, audits, and answers with the STORED defaults', async () => {
|
|
const { c, settings } = controller();
|
|
// Not the request body: the service normalises and drops unknown keys, and the
|
|
// admin panel renders straight from this response.
|
|
expect(await c.update(user, { theme: 'light' } as never, req)).toEqual({ theme: 'dark' });
|
|
expect(settings.setAdminUserDefaults).toHaveBeenCalledWith({ theme: 'light' });
|
|
expect(writeAudit).toHaveBeenCalledWith(
|
|
expect.objectContaining({ userId: 1, action: 'admin.default_user_settings_update', details: { theme: 'light' } }),
|
|
);
|
|
});
|
|
|
|
it('DEFAULTS-003 a rejected write is a 400 carrying the message, and is not audited', async () => {
|
|
const { c } = controller({
|
|
setAdminUserDefaults: vi.fn(() => {
|
|
throw new Error('unknown setting: nope');
|
|
}),
|
|
} as Partial<SettingsService>);
|
|
expect(await thrown(() => c.update(user, { nope: 1 } as never, req))).toEqual({
|
|
status: 400,
|
|
body: { error: 'unknown setting: nope' },
|
|
});
|
|
expect(writeAudit).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it('DEFAULTS-004 a non-Error throw is stringified rather than swallowed', async () => {
|
|
const { c } = controller({
|
|
setAdminUserDefaults: vi.fn(() => {
|
|
throw 'plain string';
|
|
}),
|
|
} as Partial<SettingsService>);
|
|
expect(await thrown(() => c.update(user, {} as never, req))).toEqual({ status: 400, body: { error: 'plain string' } });
|
|
});
|
|
|
|
it('DEFAULTS-005 the class is listed in its module controllers', () => {
|
|
expectRegisteredController(SettingsModule, AdminDefaultUserSettingsController);
|
|
});
|
|
|
|
it('DEFAULTS-006 a rejected read-back after a successful write is still a 400, not a 500', async () => {
|
|
const { c, settings } = controller({
|
|
getAdminUserDefaults: vi.fn(() => Promise.reject(new Error('read-back failed'))),
|
|
} as Partial<SettingsService>);
|
|
expect(await thrown(() => c.update(user, { theme: 'light' } as never, req))).toEqual({
|
|
status: 400,
|
|
body: { error: 'read-back failed' },
|
|
});
|
|
expect(settings.setAdminUserDefaults).toHaveBeenCalledWith({ theme: 'light' });
|
|
});
|
|
});
|