import { NotImplementedException } from '@nestjs/common'; import { Reflector } from '@nestjs/core'; import { ConfigService } from '@nestjs/config'; import { SettingsController } from './settings.controller'; import { REQUIRED_ROLE_KEY } from '../auth/decorators/auth.decorators'; import { ApiKeyRole } from '../auth/entities/api-key.entity'; // ConfigService stub: return the supplied default for every key. const configStub = { get: (_key: string, def?: T): T | undefined => def, } as unknown as ConfigService; describe('SettingsController', () => { it('GET /settings returns the environment-derived settings', () => { const settings = new SettingsController(configStub).get(); expect(settings).toHaveProperty('general'); expect(settings.general).not.toHaveProperty('sessionTimeout'); expect(settings).toHaveProperty('api'); expect(settings).toHaveProperty('notifications'); }); it('reports enableDocs from the real ENABLE_SWAGGER gate, not a hardcoded true', () => { const prev = process.env.ENABLE_SWAGGER; try { process.env.ENABLE_SWAGGER = 'false'; expect(new SettingsController(configStub).get().api.enableDocs).toBe(false); process.env.ENABLE_SWAGGER = 'true'; expect(new SettingsController(configStub).get().api.enableDocs).toBe(true); } finally { if (prev === undefined) delete process.env.ENABLE_SWAGGER; else process.env.ENABLE_SWAGGER = prev; } }); it('reports apiBaseUrl from BASE_URL when the operator configured one', () => { const prev = process.env.BASE_URL; try { process.env.BASE_URL = 'https://wa.example.com'; expect(new SettingsController(configStub).get().general.apiBaseUrl).toBe('https://wa.example.com'); } finally { if (prev === undefined) delete process.env.BASE_URL; else process.env.BASE_URL = prev; } }); // The previous PUT mutated an in-memory field and returned 200 'updated' while persisting // nothing and applying nothing to the runtime — a false success. Settings are env-derived and // read-only at runtime, so the write path must say so (501) rather than fake success. it('PUT /settings is read-only and throws 501 instead of a false-success 200', () => { const controller = new SettingsController(configStub); expect(() => controller.update()).toThrow(NotImplementedException); }); it('PUT /settings still requires the ADMIN role', () => { const proto = SettingsController.prototype as unknown as Record unknown>; const role = new Reflector().get(REQUIRED_ROLE_KEY, proto.update); expect(role).toBe(ApiKeyRole.ADMIN); }); it('GET /settings requires the ADMIN role (env-derived config is not for low-privilege keys)', () => { const proto = SettingsController.prototype as unknown as Record unknown>; const role = new Reflector().get(REQUIRED_ROLE_KEY, proto.get); expect(role).toBe(ApiKeyRole.ADMIN); }); });