Files
TREK/server/tests/unit/nest/managed-inert.test.ts
T
Maurice 724c88c201 style: format server and shared with prettier
A mechanical prettier --write over server/src, server/tests, server/scripts
and shared/src with the workspaces' .prettierrc; nothing but layout and
import order changes, and every file keeps the same set of imports. shared
is formatted throughout and its format baseline is empty. The server
baseline keeps the 35 files that Prettier would grow past their lint:size
limit (they need a split first, which is not a formatting change), and the
generated entity files stay as their generator writes them.
2026-10-10 21:23:37 +02:00

72 lines
3.0 KiB
TypeScript

/**
* With TREK_MANAGED unset, nothing in this feature does anything.
*
* That is the promise the whole design rests on: the same image runs on a
* self-hosted install and on a centrally administered one, and the first must
* not be able to tell the second exists. Every other test here checks that the
* mode works; this one checks that its absence is total.
*
* Written as its own file rather than a case in each suite on purpose. Spread
* across eight files the question "does this change anything for a self-hoster"
* has eight partial answers; here it has one.
*/
import { deriveMaps, deriveManaged } from '../../../src/app-config/derive';
import { RuntimeEnvService } from '../../../src/nest/app-config/runtime-env.service';
import { splitManagedKeys, isManagedBlocked, MANAGED_LOCKED_SETTING_KEYS } from '../../../src/nest/common/managed';
import { describe, it, expect, afterEach } from 'vitest';
const env = new RuntimeEnvService();
afterEach(() => {
delete process.env.TREK_MANAGED;
delete process.env.PLACES_API_BASE;
delete process.env.PLACES_API_KEY;
});
describe('a self-hosted install', () => {
it('MANAGED-INERT-001: is not managed, and no other variable can make it so', () => {
// Only TREK_MANAGED decides. Setting the operator plumbing without it must
// not flip the mode, or an operator half-way through a migration would take
// settings away from admins without meaning to.
process.env.PLACES_API_BASE = 'https://places.example.test';
process.env.PLACES_API_KEY = 'operator-key';
expect(env.isManaged()).toBe(false);
expect(isManagedBlocked(env)).toBe(false);
});
it('MANAGED-INERT-002: keeps every settings key writable', () => {
const body = Object.fromEntries(MANAGED_LOCKED_SETTING_KEYS.map((k) => [k, 'x']));
const { allowed, blocked } = splitManagedKeys(body, env.isManaged());
expect(blocked).toEqual([]);
expect(allowed).toEqual(body);
});
it('MANAGED-INERT-003: is the same object, not a copy, so no write path can diverge', () => {
// splitManagedKeys returns the body itself when the mode is off. If it ever
// started cloning, a caller mutating `allowed` would silently stop working
// on self-hosted installs only, which is the hardest kind of bug to find.
const body = { smtp_host: 'mail.example.test' };
expect(splitManagedKeys(body, false).allowed).toBe(body);
});
it('MANAGED-INERT-004: leaves the Places calls pointing at Google with the stored key', () => {
const maps = deriveMaps({});
expect(maps.placesApiBase).toBeUndefined();
expect(maps.placesApiKey).toBeUndefined();
});
it('MANAGED-INERT-005: treats an unparseable flag as off, never as on', () => {
// Fail closed in the direction that matters here: the failure mode of a typo
// must be "the admin keeps their settings", not "the admin quietly loses them".
for (const value of ['', ' ', 'maybe', 'TRUE_ISH', '2', 'null', 'undefined']) {
expect(deriveManaged({ TREK_MANAGED: value }).enabled, `TREK_MANAGED=${value}`).toBe(false);
}
});
});