PR #120 rewrote auth.controller.spec.ts and environment.service.spec.ts in a leaner style but dropped several edge cases that PR #116 covered. Port the gaps so the server coverage matches the original review intent: - auth.controller: returnToken=false must behave like the omitted case (no token in the response body, cookie still set) — guards an `!== undefined`-style regression. - environment.getCorsAllowedOrigins: empty string -> [], single origin, and leading/trailing/duplicate commas with spaces -> trimmed list. - environment.isSwaggerEnabled: mixed-case "True" -> true; "false"/""/"1" -> false. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
104 lines
3.2 KiB
TypeScript
104 lines
3.2 KiB
TypeScript
import { EnvironmentService } from './environment.service';
|
|
|
|
// Direct instantiation with a stub ConfigService, mirroring the rest of these
|
|
// unit specs.
|
|
describe('EnvironmentService', () => {
|
|
let service: EnvironmentService;
|
|
|
|
// Build a service over a stub ConfigService whose get(key, def) returns
|
|
// values from the supplied env map (falling back to the provided default).
|
|
const makeService = (env: Record<string, string>) =>
|
|
new EnvironmentService({
|
|
get: (k: string, d?: string) => (k in env ? env[k] : d),
|
|
} as any);
|
|
|
|
beforeEach(() => {
|
|
service = new EnvironmentService(
|
|
{} as any, // configService
|
|
);
|
|
});
|
|
|
|
it('should be defined', () => {
|
|
expect(service).toBeDefined();
|
|
});
|
|
|
|
describe('getCorsAllowedOrigins', () => {
|
|
it('splits, trims, and drops empty entries', () => {
|
|
const svc = makeService({
|
|
CORS_ALLOWED_ORIGINS: 'https://a.com, https://b.com ,, https://c.com',
|
|
});
|
|
expect(svc.getCorsAllowedOrigins()).toEqual([
|
|
'https://a.com',
|
|
'https://b.com',
|
|
'https://c.com',
|
|
]);
|
|
});
|
|
|
|
it('returns an empty array when the var is absent', () => {
|
|
const svc = makeService({});
|
|
expect(svc.getCorsAllowedOrigins()).toEqual([]);
|
|
});
|
|
|
|
it('returns an empty array for an empty string', () => {
|
|
const svc = makeService({ CORS_ALLOWED_ORIGINS: '' });
|
|
expect(svc.getCorsAllowedOrigins()).toEqual([]);
|
|
});
|
|
|
|
it('returns a single origin unchanged', () => {
|
|
const svc = makeService({
|
|
CORS_ALLOWED_ORIGINS: 'https://app.example',
|
|
});
|
|
expect(svc.getCorsAllowedOrigins()).toEqual(['https://app.example']);
|
|
});
|
|
|
|
// Adversarial case: leading/trailing/duplicate commas with surrounding
|
|
// spaces must be dropped, exercising both .map(trim) and .filter(Boolean).
|
|
it('drops leading/trailing commas with surrounding spaces', () => {
|
|
const svc = makeService({ CORS_ALLOWED_ORIGINS: ' , a , , b ' });
|
|
expect(svc.getCorsAllowedOrigins()).toEqual(['a', 'b']);
|
|
});
|
|
});
|
|
|
|
describe('isSwaggerEnabled', () => {
|
|
it('is true for "true"', () => {
|
|
expect(makeService({ SWAGGER_ENABLED: 'true' }).isSwaggerEnabled()).toBe(
|
|
true,
|
|
);
|
|
});
|
|
|
|
it('is true case-insensitively for "TRUE"', () => {
|
|
expect(makeService({ SWAGGER_ENABLED: 'TRUE' }).isSwaggerEnabled()).toBe(
|
|
true,
|
|
);
|
|
});
|
|
|
|
it('is true for mixed-case "True"', () => {
|
|
expect(makeService({ SWAGGER_ENABLED: 'True' }).isSwaggerEnabled()).toBe(
|
|
true,
|
|
);
|
|
});
|
|
|
|
it('defaults to false when absent', () => {
|
|
expect(makeService({}).isSwaggerEnabled()).toBe(false);
|
|
});
|
|
|
|
it('is false for non-"true" values', () => {
|
|
expect(makeService({ SWAGGER_ENABLED: '0' }).isSwaggerEnabled()).toBe(
|
|
false,
|
|
);
|
|
expect(makeService({ SWAGGER_ENABLED: 'yes' }).isSwaggerEnabled()).toBe(
|
|
false,
|
|
);
|
|
expect(makeService({ SWAGGER_ENABLED: 'false' }).isSwaggerEnabled()).toBe(
|
|
false,
|
|
);
|
|
expect(makeService({ SWAGGER_ENABLED: '' }).isSwaggerEnabled()).toBe(
|
|
false,
|
|
);
|
|
expect(makeService({ SWAGGER_ENABLED: '1' }).isSwaggerEnabled()).toBe(
|
|
false,
|
|
);
|
|
});
|
|
});
|
|
});
|