Restore nest coverage to >=80% after the #1209 dep bump (istanbul provider + branch tests) (#1213)

* fix(server): set oxc:false in vitest so the SWC transform survives the Vite 8 bump

* fix(server): switch coverage to the istanbul provider (v8 under-reports branches on Vite 8 + Vitest 4)

* test(nest): cover controller/service branches to clear the 80% coverage gate
This commit is contained in:
Maurice
2026-06-16 21:36:39 +02:00
committed by GitHub
parent 79057ea603
commit 7266ad99ae
35 changed files with 4897 additions and 207 deletions
@@ -0,0 +1,513 @@
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
import { NotFoundException } from '@nestjs/common';
// --- hoisted mock fns so the vi.mock factories can reference them -----------------
const h = vi.hoisted(() => ({
verifyJwtAndLoadUser: vi.fn(),
isAddonEnabled: vi.fn(),
getMcpSafeUrl: vi.fn(() => 'https://trek.example.test'),
dbPrepare: vi.fn(),
existsSync: vi.fn(),
// SDK middleware spies — each returns a tagged handler so we can identify which
// app.use call received it.
metaRouter: vi.fn(),
authorizeHandler: vi.fn(),
registerHandler: vi.fn(),
mcpHandler: vi.fn(),
}));
vi.mock('../../../src/middleware/auth', () => ({ verifyJwtAndLoadUser: h.verifyJwtAndLoadUser }));
vi.mock('../../../src/db/database', () => ({ db: { prepare: h.dbPrepare } }));
vi.mock('../../../src/mcp', () => ({ mcpHandler: h.mcpHandler }));
vi.mock('../../../src/mcp/oauthProvider', () => ({ trekOAuthProvider: {}, trekClientsStore: {} }));
vi.mock('../../../src/services/adminService', () => ({ isAddonEnabled: h.isAddonEnabled }));
vi.mock('../../../src/services/notifications', () => ({ getMcpSafeUrl: h.getMcpSafeUrl }));
// SDK router/handler factories return distinct tagged middleware so we never hit
// real new URL(...) wiring during registration.
vi.mock('@modelcontextprotocol/sdk/server/auth/router', () => ({
mcpAuthMetadataRouter: vi.fn(() => h.metaRouter),
}));
vi.mock('@modelcontextprotocol/sdk/server/auth/handlers/authorize', () => ({
authorizationHandler: vi.fn(() => h.authorizeHandler),
}));
vi.mock('@modelcontextprotocol/sdk/server/auth/handlers/register', () => ({
clientRegistrationHandler: vi.fn(() => h.registerHandler),
}));
vi.mock('node:fs', async (orig) => {
const real = (await orig()) as Record<string, unknown>;
return { ...real, default: { ...(real.default as object), existsSync: h.existsSync }, existsSync: h.existsSync };
});
import {
applyPlatformUploads,
applyPlatformTransport,
applyPlatformSpa,
applyPlatformStatic,
} from '../../../src/nest/platform/platform.routes';
import { SpaFallbackFilter } from '../../../src/nest/platform/spa-fallback.filter';
// Tagged sentinel for express.static — we only need to know it was registered on
// the right path, not run it.
vi.mock('express', async () => {
const staticFn = vi.fn(() => 'STATIC' as unknown);
const fn: unknown = () => ({});
Object.assign(fn as object, { static: staticFn });
return { default: fn, static: staticFn };
});
type Handler = (...args: unknown[]) => unknown;
/**
* A fake express.Application that records every route/middleware registration so
* individual handlers can be pulled out and exercised in isolation.
*/
function fakeApp() {
const calls: Array<{ method: string; path?: string; handlers: Handler[] }> = [];
const record = (method: string) => (...args: unknown[]) => {
if (typeof args[0] === 'string' || args[0] instanceof RegExp) {
calls.push({ method, path: String(args[0]), handlers: args.slice(1) as Handler[] });
} else {
calls.push({ method, handlers: args as Handler[] });
}
};
const app = {
use: record('use'),
get: record('get'),
post: record('post'),
delete: record('delete'),
} as never;
return { app, calls };
}
function makeRes() {
const res = {
statusCode: 200,
body: undefined as unknown,
headers: {} as Record<string, string>,
status: vi.fn(function (this: typeof res, c: number) { this.statusCode = c; return this; }),
json: vi.fn(function (this: typeof res, b: unknown) { this.body = b; return this; }),
send: vi.fn(function (this: typeof res, b: unknown) { this.body = b; return this; }),
end: vi.fn(function (this: typeof res) { return this; }),
sendFile: vi.fn(function (this: typeof res, p: string) { this.body = `FILE:${p}`; return this; }),
setHeader: vi.fn(function (this: typeof res, k: string, v: string) { this.headers[k] = v; return this; }),
};
return res;
}
beforeEach(() => {
vi.clearAllMocks();
h.getMcpSafeUrl.mockReturnValue('https://trek.example.test');
});
describe('applyPlatformUploads', () => {
it('registers the static avatar/cover/journey mounts + the files block', () => {
const { app, calls } = fakeApp();
applyPlatformUploads(app);
const paths = calls.filter((c) => c.method === 'use').map((c) => c.path);
expect(paths).toEqual(
expect.arrayContaining(['/uploads/avatars', '/uploads/covers', '/uploads/journey', '/uploads/files']),
);
});
it('the /uploads/files block always answers 401', () => {
const { app, calls } = fakeApp();
applyPlatformUploads(app);
const filesBlock = calls.find((c) => c.path === '/uploads/files')!.handlers[0];
const res = makeRes();
filesBlock({}, res);
expect(res.statusCode).toBe(401);
expect(res.body).toBe('Authentication required');
});
describe('GET /uploads/photos/:filename', () => {
function photoHandler() {
const { app, calls } = fakeApp();
applyPlatformUploads(app);
return calls.find((c) => c.method === 'get' && c.path === '/uploads/photos/:filename')!.handlers[0];
}
it('403 when the resolved path escapes the photos dir', () => {
// basename() strips the traversal, but feed a name that resolves outside by
// stubbing path indirectly is hard — instead exercise the existsSync 404 etc.
// The startsWith guard is defensive; cover it via a filename of '..'.
const handler = photoHandler();
const res = makeRes();
// path.basename('..') === '..' -> join(photos,'..') resolves to uploads -> not under photos
handler({ params: { filename: '..' }, headers: {}, query: {} }, res);
expect(res.statusCode).toBe(403);
expect(res.body).toBe('Forbidden');
});
it('404 when the file does not exist', () => {
h.existsSync.mockReturnValue(false);
const res = makeRes();
photoHandler()({ params: { filename: 'a.jpg' }, headers: {}, query: {} }, res);
expect(res.statusCode).toBe(404);
expect(res.body).toBe('Not found');
});
it('401 when no token is supplied', () => {
h.existsSync.mockReturnValue(true);
const res = makeRes();
photoHandler()({ params: { filename: 'a.jpg' }, headers: {}, query: {} }, res);
expect(res.statusCode).toBe(401);
expect(res.body).toBe('Authentication required');
});
it('serves the file for a valid JWT session (Bearer header)', () => {
h.existsSync.mockReturnValue(true);
h.verifyJwtAndLoadUser.mockReturnValue({ id: 1 });
const res = makeRes();
photoHandler()(
{ params: { filename: 'a.jpg' }, headers: { authorization: 'Bearer jwt123' }, query: {} },
res,
);
expect(h.verifyJwtAndLoadUser).toHaveBeenCalledWith('jwt123');
expect(String(res.body)).toContain('FILE:');
});
it('reads the token from the query string when there is no Bearer header', () => {
h.existsSync.mockReturnValue(true);
h.verifyJwtAndLoadUser.mockReturnValue({ id: 1 });
const res = makeRes();
photoHandler()({ params: { filename: 'a.jpg' }, headers: {}, query: { token: 'qtok' } }, res);
expect(h.verifyJwtAndLoadUser).toHaveBeenCalledWith('qtok');
expect(String(res.body)).toContain('FILE:');
});
it('401 when the token is not a session and the photo row is missing', () => {
h.existsSync.mockReturnValue(true);
h.verifyJwtAndLoadUser.mockReturnValue(null);
h.dbPrepare.mockReturnValue({ get: vi.fn().mockReturnValue(undefined) });
const res = makeRes();
photoHandler()({ params: { filename: 'a.jpg' }, headers: {}, query: { token: 'share1' } }, res);
expect(res.statusCode).toBe(401);
});
it('401 when a share token does not cover the photo trip', () => {
h.existsSync.mockReturnValue(true);
h.verifyJwtAndLoadUser.mockReturnValue(null);
const photoStmt = { get: vi.fn().mockReturnValue({ trip_id: 7 }) };
const shareStmt = { get: vi.fn().mockReturnValue({ trip_id: 8 }) };
h.dbPrepare.mockImplementationOnce(() => photoStmt).mockImplementationOnce(() => shareStmt);
const res = makeRes();
photoHandler()({ params: { filename: 'a.jpg' }, headers: {}, query: { token: 'share1' } }, res);
expect(res.statusCode).toBe(401);
});
it('401 when there is no matching share token at all', () => {
h.existsSync.mockReturnValue(true);
h.verifyJwtAndLoadUser.mockReturnValue(null);
const photoStmt = { get: vi.fn().mockReturnValue({ trip_id: 7 }) };
const shareStmt = { get: vi.fn().mockReturnValue(undefined) };
h.dbPrepare.mockImplementationOnce(() => photoStmt).mockImplementationOnce(() => shareStmt);
const res = makeRes();
photoHandler()({ params: { filename: 'a.jpg' }, headers: {}, query: { token: 'share1' } }, res);
expect(res.statusCode).toBe(401);
});
it('serves the file when the share token covers the photo trip', () => {
h.existsSync.mockReturnValue(true);
h.verifyJwtAndLoadUser.mockReturnValue(null);
const photoStmt = { get: vi.fn().mockReturnValue({ trip_id: 7 }) };
const shareStmt = { get: vi.fn().mockReturnValue({ trip_id: 7 }) };
h.dbPrepare.mockImplementationOnce(() => photoStmt).mockImplementationOnce(() => shareStmt);
const res = makeRes();
photoHandler()(
{ params: { filename: 'a.jpg' }, headers: { authorization: 'Bearer share1' }, query: {} },
res,
);
expect(String(res.body)).toContain('FILE:');
});
});
});
describe('applyPlatformTransport', () => {
function build() {
const { app, calls } = fakeApp();
applyPlatformTransport(app);
return calls;
}
it('GET /api/health sets no-store and returns ok', () => {
const calls = build();
const health = calls.find((c) => c.method === 'get' && c.path === '/api/health')!.handlers[0];
const res = makeRes();
health({}, res);
expect(res.headers['Cache-Control']).toBe('no-store, must-revalidate');
expect(res.body).toEqual({ status: 'ok' });
});
describe('the /.well-known metadata middleware', () => {
function wellKnownMw(calls: ReturnType<typeof build>) {
// first app.use with no path, registered right after /api/health
return calls.find((c) => c.method === 'use' && c.path === undefined)!.handlers[0];
}
it('404s a /.well-known path when MCP is disabled', () => {
h.isAddonEnabled.mockReturnValue(false);
const mw = wellKnownMw(build());
const res = makeRes();
const next = vi.fn();
mw({ path: '/.well-known/oauth-authorization-server' }, res, next);
expect(res.statusCode).toBe(404);
expect(next).not.toHaveBeenCalled();
});
it('delegates to the SDK meta router for a non-well-known path', () => {
h.isAddonEnabled.mockReturnValue(true);
const mw = wellKnownMw(build());
const res = makeRes();
const next = vi.fn();
mw({ path: '/anything' }, res, next);
expect(h.metaRouter).toHaveBeenCalled();
});
it('delegates to the SDK meta router for a well-known path when MCP is enabled', () => {
h.isAddonEnabled.mockReturnValue(true);
const mw = wellKnownMw(build());
const res = makeRes();
const next = vi.fn();
mw({ path: '/.well-known/oauth-authorization-server' }, res, next);
expect(h.metaRouter).toHaveBeenCalled();
});
});
it('GET /.well-known/openid-configuration returns AS metadata + userinfo_endpoint', () => {
const calls = build();
const handler = calls.find((c) => c.path === '/.well-known/openid-configuration')!.handlers[0];
const res = makeRes();
handler({}, res);
const body = res.body as { issuer: string; userinfo_endpoint: string };
expect(body.issuer).toBe('https://trek.example.test');
expect(body.userinfo_endpoint).toBe('https://trek.example.test/oauth/userinfo');
});
it('trims trailing slashes off the configured base URL', () => {
h.getMcpSafeUrl.mockReturnValue('https://trek.example.test///');
const calls = build();
const handler = calls.find((c) => c.path === '/.well-known/openid-configuration')!.handlers[0];
const res = makeRes();
handler({}, res);
expect((res.body as { issuer: string }).issuer).toBe('https://trek.example.test');
});
describe('GET /.well-known/oauth-protected-resource (flat)', () => {
function handler() {
return build().find((c) => c.method === 'get' && c.path === '/.well-known/oauth-protected-resource')!.handlers[0];
}
it('404 when MCP is disabled', () => {
h.isAddonEnabled.mockReturnValue(false);
const res = makeRes();
handler()({}, res);
expect(res.statusCode).toBe(404);
});
it('returns the PRM document when MCP is enabled', () => {
h.isAddonEnabled.mockReturnValue(true);
const res = makeRes();
handler()({}, res);
const body = res.body as { resource: string; authorization_servers: string[] };
expect(body.resource).toBe('https://trek.example.test/mcp');
expect(body.authorization_servers).toEqual(['https://trek.example.test']);
});
});
describe('mcpAddonGate (used on /oauth/authorize + /oauth/register)', () => {
function gate() {
// The gate is the first handler on the /oauth/authorize use registration.
return build().find((c) => c.method === 'use' && c.path === '/oauth/authorize')!.handlers[0];
}
it('404 when MCP is disabled', () => {
h.isAddonEnabled.mockReturnValue(false);
const res = makeRes();
const next = vi.fn();
gate()({}, res, next);
expect(res.statusCode).toBe(404);
expect(next).not.toHaveBeenCalled();
});
it('calls next() when MCP is enabled', () => {
h.isAddonEnabled.mockReturnValue(true);
const res = makeRes();
const next = vi.fn();
gate()({}, res, next);
expect(next).toHaveBeenCalled();
});
});
it('wires the SDK authorize + register handlers behind the gate', () => {
const calls = build();
const authorize = calls.find((c) => c.path === '/oauth/authorize')!;
const register = calls.find((c) => c.path === '/oauth/register')!;
expect(authorize.handlers).toContain(h.authorizeHandler);
expect(register.handlers).toContain(h.registerHandler);
});
it('mounts the MCP handler on POST/GET/DELETE /mcp', () => {
const calls = build();
expect(calls.find((c) => c.method === 'post' && c.path === '/mcp')!.handlers[0]).toBe(h.mcpHandler);
expect(calls.find((c) => c.method === 'get' && c.path === '/mcp')!.handlers[0]).toBe(h.mcpHandler);
expect(calls.find((c) => c.method === 'delete' && c.path === '/mcp')!.handlers[0]).toBe(h.mcpHandler);
});
describe('the terminal /.well-known JSON-404 middleware', () => {
function mw() {
// The pathless app.use registered after the /mcp routes.
const calls = build();
const pathless = calls.filter((c) => c.method === 'use' && c.path === undefined);
// first pathless = meta router; second = the JSON 404.
return pathless[1].handlers[0];
}
it('404 JSON for an unhandled /.well-known path', () => {
const res = makeRes();
const next = vi.fn();
mw()({ path: '/.well-known/unknown' }, res, next);
expect(res.statusCode).toBe(404);
expect(res.body).toEqual({ error: 'not_found' });
expect(next).not.toHaveBeenCalled();
});
it('calls next() for any non-well-known path', () => {
const res = makeRes();
const next = vi.fn();
mw()({ path: '/dashboard' }, res, next);
expect(next).toHaveBeenCalled();
});
});
it('the /oauth/consent middleware relaxes COOP then continues', () => {
const calls = build();
const mw = calls.find((c) => c.method === 'use' && c.path === '/oauth/consent')!.handlers[0];
const res = makeRes();
const next = vi.fn();
mw({}, res, next);
expect(res.headers['Cross-Origin-Opener-Policy']).toBe('unsafe-none');
expect(next).toHaveBeenCalled();
});
it('caches the OAuth metadata + SDK router across requests (lazy init runs once)', async () => {
const router = await import('@modelcontextprotocol/sdk/server/auth/router');
const calls = build();
const openid = calls.find((c) => c.path === '/.well-known/openid-configuration')!.handlers[0];
h.getMcpSafeUrl.mockClear();
openid({}, makeRes());
openid({}, makeRes());
// getMcpSafeUrl is only consulted on the first lazy build of the metadata.
expect(h.getMcpSafeUrl).toHaveBeenCalledTimes(1);
// Trigger the meta router lazy build twice; the SDK factory runs once.
const metaMw = calls.find((c) => c.method === 'use' && c.path === undefined)!.handlers[0];
h.isAddonEnabled.mockReturnValue(true);
metaMw({ path: '/x' }, makeRes(), vi.fn());
metaMw({ path: '/y' }, makeRes(), vi.fn());
expect(router.mcpAuthMetadataRouter).toHaveBeenCalledTimes(1);
});
});
describe('applyPlatformStatic', () => {
const original = process.env.NODE_ENV;
afterEach(() => { process.env.NODE_ENV = original; });
it('is a no-op outside production', () => {
process.env.NODE_ENV = 'development';
const { app, calls } = fakeApp();
applyPlatformStatic(app);
expect(calls).toHaveLength(0);
});
it('serves the built client statics in production', () => {
process.env.NODE_ENV = 'production';
const { app, calls } = fakeApp();
applyPlatformStatic(app);
expect(calls.some((c) => c.method === 'use')).toBe(true);
});
it('the static setHeaders callback adds no-cache for index.html only', async () => {
process.env.NODE_ENV = 'production';
const expressMod = (await import('express')).default as unknown as { static: ReturnType<typeof vi.fn> };
expressMod.static.mockClear();
const { app } = fakeApp();
applyPlatformStatic(app);
const opts = expressMod.static.mock.calls[0][1] as { setHeaders: (res: unknown, p: string) => void };
const indexRes = makeRes();
opts.setHeaders(indexRes, '/some/index.html');
expect(indexRes.headers['Cache-Control']).toBe('no-cache, no-store, must-revalidate');
const assetRes = makeRes();
opts.setHeaders(assetRes, '/some/app.js');
expect(assetRes.headers['Cache-Control']).toBeUndefined();
});
});
describe('applyPlatformSpa', () => {
const original = process.env.NODE_ENV;
afterEach(() => { process.env.NODE_ENV = original; });
it('only serves statics (no catch-all) outside production', () => {
process.env.NODE_ENV = 'development';
const { app, calls } = fakeApp();
applyPlatformSpa(app);
expect(calls.some((c) => c.method === 'get' && c.path === '/.*/' )).toBe(false);
});
it('registers the index.html catch-all in production', () => {
process.env.NODE_ENV = 'production';
const { app, calls } = fakeApp();
applyPlatformSpa(app);
const catchAll = calls.find((c) => c.method === 'get');
expect(catchAll).toBeDefined();
const res = makeRes();
catchAll!.handlers[0]({}, res);
expect(res.headers['Cache-Control']).toBe('no-cache, no-store, must-revalidate');
expect(String(res.body)).toContain('FILE:');
expect(String(res.body)).toContain('index.html');
});
});
describe('SpaFallbackFilter', () => {
const original = process.env.NODE_ENV;
afterEach(() => { process.env.NODE_ENV = original; });
function host(req: { method: string }, res: ReturnType<typeof makeRes>) {
return { switchToHttp: () => ({ getRequest: () => req, getResponse: () => res }) } as never;
}
it('serves index.html for an unmatched GET in production', () => {
process.env.NODE_ENV = 'production';
const res = makeRes();
new SpaFallbackFilter().catch(new NotFoundException('nope'), host({ method: 'GET' }, res));
expect(res.headers['Cache-Control']).toBe('no-cache, no-store, must-revalidate');
expect(String(res.body)).toContain('index.html');
});
it('keeps the JSON 404 envelope for a non-GET miss in production', () => {
process.env.NODE_ENV = 'production';
const res = makeRes();
new SpaFallbackFilter().catch(new NotFoundException('gone'), host({ method: 'POST' }, res));
expect(res.statusCode).toBe(404);
expect(res.body).toEqual({ error: 'gone' });
});
it('keeps the JSON 404 envelope outside production even for GET', () => {
process.env.NODE_ENV = 'development';
const res = makeRes();
new SpaFallbackFilter().catch(new NotFoundException('missing'), host({ method: 'GET' }, res));
expect(res.statusCode).toBe(404);
expect(res.body).toEqual({ error: 'missing' });
});
it('falls back to Not Found when the exception has no message', () => {
process.env.NODE_ENV = 'development';
const res = makeRes();
const exc = new NotFoundException();
// force an empty message so the || branch is taken
Object.defineProperty(exc, 'message', { value: '' });
new SpaFallbackFilter().catch(exc, host({ method: 'GET' }, res));
expect(res.body).toEqual({ error: 'Not Found' });
});
});