mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-19 05:26:47 +00:00
81 lines
4.2 KiB
TypeScript
81 lines
4.2 KiB
TypeScript
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
|
|
const { canAccessTrip, pluginsEnabled } = vi.hoisted(() => ({
|
|
canAccessTrip: vi.fn(async (tripId: number, userId: number) => (tripId === 1 && userId === 5 ? { id: 1 } : undefined)),
|
|
pluginsEnabled: vi.fn(() => true),
|
|
}));
|
|
vi.mock('../../../src/db/database', () => ({ db: {}, canAccessTrip }));
|
|
vi.mock('../../../src/nest/plugins/kill-switch', () => ({ pluginsEnabled }));
|
|
|
|
import { TripWarningsController } from '../../../src/nest/plugins/contributions/trip-warnings.controller';
|
|
import type { PluginHooks } from '../../../src/nest/plugins/plugin-hooks.service';
|
|
import type { DatabaseService } from '../../../src/nest/database/database.service';
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
const req = (id?: number) => ({ user: id === undefined ? undefined : { id } }) as any;
|
|
function controller(over: Partial<PluginHooks> = {}) {
|
|
const runtime = {
|
|
providersOf: vi.fn(() => ['p1', 'p2']),
|
|
tripWarnings: vi.fn(async (id: string) =>
|
|
id === 'p2' ? [{ level: 'error', message: 'Day 3 is overpacked', dayId: 3 }] : [{ level: 'warning', message: 'Museum closed Mon', placeId: 7 }]),
|
|
...over,
|
|
} as unknown as PluginHooks;
|
|
return { c: new TripWarningsController(runtime, { canAccessTrip } as unknown as DatabaseService), runtime };
|
|
}
|
|
|
|
describe('TripWarningsController', () => {
|
|
beforeEach(() => { pluginsEnabled.mockReturnValue(true); canAccessTrip.mockResolvedValue({ id: 1 } as never); });
|
|
|
|
it('returns [] when disabled / no user / no access', async () => {
|
|
pluginsEnabled.mockReturnValue(false);
|
|
expect(await controller().c.get('1', req(5))).toEqual({ warnings: [] });
|
|
pluginsEnabled.mockReturnValue(true);
|
|
expect(await controller().c.get('1', req(undefined))).toEqual({ warnings: [] });
|
|
canAccessTrip.mockResolvedValue(undefined as never);
|
|
expect(await controller().c.get('1', req(5))).toEqual({ warnings: [] });
|
|
});
|
|
|
|
it('merges provider warnings, tags each with the plugin id, defaults an odd level to warning', async () => {
|
|
const { c } = controller({
|
|
tripWarnings: vi.fn(async (id: string) =>
|
|
id === 'p1' ? [{ level: 'bogus', message: 'Check timings' }, { message: '' }] : [{ level: 'info', message: 'Rainy week' }]) as unknown as PluginHooks['tripWarnings'],
|
|
});
|
|
const res = await c.get('1', req(5));
|
|
expect(res.warnings).toEqual([
|
|
{ pluginId: 'p1', level: 'warning', message: 'Check timings', dayId: undefined, placeId: undefined }, // unknown level → warning; empty-message row dropped
|
|
{ pluginId: 'p2', level: 'info', message: 'Rainy week', dayId: undefined, placeId: undefined },
|
|
]);
|
|
});
|
|
|
|
it('skips a provider that throws (graceful) and calls the hook with the trip + acting user', async () => {
|
|
const { c, runtime } = controller({
|
|
tripWarnings: vi.fn(async (id: string) => { if (id === 'p2') throw new Error('slow'); return [{ level: 'warning', message: 'ok' }]; }) as unknown as PluginHooks['tripWarnings'],
|
|
});
|
|
const res = await c.get('1', req(5));
|
|
expect(res.warnings).toEqual([{ pluginId: 'p1', level: 'warning', message: 'ok', dayId: undefined, placeId: undefined }]);
|
|
expect(runtime.tripWarnings).toHaveBeenCalledWith('p1', 1, 5);
|
|
});
|
|
|
|
it('strips emojis from the warning message (rendered natively in TREK chrome)', async () => {
|
|
const { c } = controller({
|
|
providersOf: vi.fn(() => ['p1']),
|
|
tripWarnings: vi.fn(async () => [{ level: 'error', message: '🔥 Overbooked!' }]) as unknown as PluginHooks['tripWarnings'],
|
|
});
|
|
const res = await c.get('1', req(5));
|
|
expect(res.warnings[0].message).toBe('Overbooked!');
|
|
});
|
|
|
|
it('caps a flooding provider at 20 warnings and truncates an oversized message', async () => {
|
|
const { c } = controller({
|
|
providersOf: vi.fn(() => ['flood']),
|
|
tripWarnings: vi.fn(async () => [
|
|
{ level: 'warning', message: 'z'.repeat(1000) },
|
|
...Array.from({ length: 50 }, (_v, i) => ({ level: 'info', message: `w${i}` })),
|
|
]) as unknown as PluginHooks['tripWarnings'],
|
|
});
|
|
const res = await c.get('1', req(5));
|
|
expect(res.warnings).toHaveLength(20); // per-provider count cap
|
|
expect(res.warnings[0].message).toHaveLength(300); // message length cap
|
|
});
|
|
});
|