Files
TREK/server/tests/unit/plugins/plugin-route-normalize.test.ts
T
Maurice 57404dee17 test(server): seed the plugin specs through the repositories
The plugin service, instance and user settings, OAuth, audit, route
profile, host state and request context suites seeded plugin rows,
settings fields, actions, tokens and audit entries with raw statements
and read them back the same way. They now go through the ORM factories
and readers over the suite's own test ORM.

Two raw statements stay, marked: the PRAGMA table_info read that proves
the actions scope column exists, and the audit insert that reproduces
the pre-conversion appendAudit byte for byte for the hash chain parity
check. The instance settings suite's stubbed isActive now follows the
status the test flips through markActive instead of a synchronous read.
2026-10-08 18:45:32 +02:00

53 lines
2.4 KiB
TypeScript

/**
* SV4 (R-survivors) — `declaredProfiles`, Plan 3j Task 3's conversion of the one
* literal `SELECT capabilities FROM plugins WHERE id = ?` backing all three
* external callers (`roadtrip-router.service.ts`'s RRT1/RRT2,
* `plugin-routes.controller.ts`), now via `PluginsRepository#findCapabilities`
* (PR52/PR53 — the same method `plugin-runtime.service.ts`'s
* `capabilityList`/`mcpToolCapabilities` use for the same column).
*/
import { describe, it, expect, beforeAll, beforeEach, afterAll } from 'vitest';
import { createSnapshotTestDb } from '../../helpers/db-mock';
import { resetTestDb } from '../../helpers/test-db';
import { createTestOrm, type TestOrm } from '../../helpers/test-orm';
import { Plugins } from '../../../src/db/entities/Plugins.entity';
import { insertRow } from '../../helpers/factories/rows';
import type { PluginsRepository } from '../../../src/db/repositories/Plugins.repository';
import { declaredProfiles } from '../../../src/nest/plugins/contributions/plugin-route-normalize';
const testDb = createSnapshotTestDb();
let t: TestOrm;
let plugins: PluginsRepository;
beforeAll(async () => {
t = await createTestOrm(testDb);
plugins = t.repo(Plugins);
});
beforeEach(() => { resetTestDb(testDb); t.clear(); });
afterAll(async () => { await t.close(); testDb.close(); });
async function seedPlugin(id: string, capabilities: unknown): Promise<void> {
await insertRow(t, Plugins, { id, name: id, capabilities: JSON.stringify(capabilities) });
}
describe('declaredProfiles', () => {
it('RN-001: returns the declared routeProfiles ids, filtered to the safe id pattern', async () => {
await seedPlugin('roadtrip-plugin', { routeProfiles: [{ id: 'eco' }, { id: 'fast-ev' }, { id: 'BAD ID' }, { id: '' }] });
expect(await declaredProfiles(plugins, 'roadtrip-plugin')).toEqual(['eco', 'fast-ev']);
});
it('RN-002: no routeProfiles capability → empty list', async () => {
await seedPlugin('no-routes', { widget: { slot: 'sidebar' } });
expect(await declaredProfiles(plugins, 'no-routes')).toEqual([]);
});
it('RN-003: a missing plugin row → empty list, never throws', async () => {
expect(await declaredProfiles(plugins, 'does-not-exist')).toEqual([]);
});
it('RN-004: malformed capabilities JSON → empty list, never throws', async () => {
await insertRow(t, Plugins, { id: 'bad-json', name: 'bad-json', capabilities: 'not json' });
expect(await declaredProfiles(plugins, 'bad-json')).toEqual([]);
});
});