mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-19 05:26:47 +00:00
724c88c201
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.
77 lines
3.7 KiB
TypeScript
77 lines
3.7 KiB
TypeScript
/**
|
|
* The coverage ledger: the anchor for the whole decorator rollout.
|
|
*
|
|
* Every wire method is owned by exactly one decorated *.rpc.ts class in the registry.
|
|
* Both sets are derived by construction, so no list is maintained by hand and the test
|
|
* cannot drift.
|
|
*
|
|
* The rollout is finished, so the legacy set is empty and the ledger's job flips from
|
|
* "how far along is the move" to "nothing fell out of it": a method deleted without a
|
|
* replacement, or a new *.rpc.ts class that no one listed in allRpcControllers().
|
|
*/
|
|
import { PluginRpcRegistryService } from '../../../src/nest-rpc/rpc-kit/registry.service';
|
|
import { createTestPluginRegistry } from '../../../src/nest-rpc/rpc-kit/testing';
|
|
import { PluginRpcHost } from '../../../src/nest/plugins/host/rpc-host';
|
|
import { KNOWN_METHODS, KNOWN_PERMISSIONS, UNCONDITIONAL_METHODS } from '../../../src/nest/plugins/protocol/envelope';
|
|
import { allRpcControllers, makeDeps } from '../../helpers/rpc-host-deps';
|
|
|
|
import { describe, it, expect } from 'vitest';
|
|
|
|
/** Reads the router's private dispatch map. That map IS the thing under test. */
|
|
const boundMethods = (host: PluginRpcHost): Set<string> =>
|
|
new Set((host as unknown as { methods: Map<string, unknown> }).methods.keys());
|
|
|
|
describe('plugin RPC coverage ledger', () => {
|
|
const registry = createTestPluginRegistry(allRpcControllers());
|
|
// Every permission granted, so the router registers everything it can.
|
|
const host = new PluginRpcHost('probe', new Set<string>(KNOWN_PERMISSIONS), makeDeps(), registry);
|
|
const all = boundMethods(host);
|
|
const fromRegistry = registry.methodNames();
|
|
const vocabulary = new Set<string>([...KNOWN_METHODS, ...UNCONDITIONAL_METHODS]);
|
|
|
|
it('RPCLEDGER-001 every bound method comes from the registry, none from anywhere else', () => {
|
|
expect([...all].filter((m) => !fromRegistry.has(m))).toEqual([]);
|
|
});
|
|
|
|
it('RPCLEDGER-002 every registered method is one the wire protocol knows', () => {
|
|
expect([...all].filter((m) => !vocabulary.has(m))).toEqual([]);
|
|
});
|
|
|
|
it('RPCLEDGER-003 no method in the vocabulary is orphaned', () => {
|
|
expect([...vocabulary].filter((m) => !all.has(m))).toEqual([]);
|
|
});
|
|
|
|
it('RPCLEDGER-004 the registry covers the vocabulary exactly', () => {
|
|
expect(all).toEqual(vocabulary);
|
|
expect(fromRegistry.size).toBe(KNOWN_METHODS.length + UNCONDITIONAL_METHODS.length);
|
|
});
|
|
|
|
it('RPCLEDGER-005 the surface is the 114 methods the protocol declares', () => {
|
|
// Pinned rather than derived: a method DELETED from KNOWN_METHODS together with
|
|
// its handler would keep every test above green, and this is the line that makes
|
|
// that show up in the diff.
|
|
expect(KNOWN_METHODS.length).toBe(111);
|
|
expect(UNCONDITIONAL_METHODS.length).toBe(3);
|
|
expect(fromRegistry.size).toBe(114);
|
|
});
|
|
|
|
it('RPCLEDGER-006 boot-time total coverage is armed in production', () => {
|
|
// The rollout's closing move: the registry service now FAILS APP BOOT when a
|
|
// KNOWN_METHOD has no decorated owner, instead of letting it surface as a runtime
|
|
// PERMISSION_DENIED nobody can explain.
|
|
const options = (
|
|
new PluginRpcRegistryService({} as never, {} as never) as unknown as {
|
|
options: { requireTotalCoverage?: boolean };
|
|
}
|
|
).options;
|
|
expect(options.requireTotalCoverage).toBe(true);
|
|
});
|
|
|
|
it('RPCLEDGER-007 a registry missing a method fails validate() rather than booting', () => {
|
|
// Drops TagsRpc, a method owner. Dropping the last entry would drop PluginHooks
|
|
// instead, and the failure would be about hooks rather than methods.
|
|
const short = allRpcControllers().slice(1);
|
|
expect(() => createTestPluginRegistry(short, { requireTotalCoverage: true })).toThrow(/has no handler/);
|
|
});
|
|
});
|