mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-06-21 14:21:46 +00:00
Finish the NestJS migration — drop the legacy Express app
NestJS now serves the whole surface: every /api domain plus the platform
routes (uploads, /mcp, the OAuth/MCP SDK + /.well-known metadata and the
production SPA fallback). Removed server/src/app.ts, all of
server/src/routes/* and the strangler dispatcher; index.ts and the
integration suite share a single buildApp() bootstrap so prod and tests
can't drift.
- Platform/transport routes extracted to nest/platform/platform.routes.ts
and mounted before app.init() — Nest's router answers an unmatched
request with a 404, so a route registered after init is never reached.
The SPA fallback is a NotFoundException filter and the catch-all uses a
RegExp (Express 5's path-to-regexp rejects a bare '*').
- New modules: memories (/api/integrations/memories — the Journey
gallery's Immich/Synology proxy), addons (GET /api/addons) and the
cross-trip GET /api/reservations/upcoming.
- TrekExceptionFilter reproduces the old multer / err.statusCode handling
so upload rejections keep their 400/413 { error } body and non-ASCII
filenames survive (defParamCharset).
- addTripToJourney and the MCP get_journey_share_link tool gained the
trip-access check they were missing.
- Re-pointed the 34 integration tests + the websocket test onto the Nest
app; removed the now-meaningless Express-vs-Nest parity tests and a few
orphaned client components.
This commit is contained in:
@@ -1,63 +0,0 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { swapItems } from '../../../src/utils/reorder';
|
||||
|
||||
// FE-UTIL-020 onwards
|
||||
|
||||
const items = [
|
||||
{ id: 10 },
|
||||
{ id: 20 },
|
||||
{ id: 30 },
|
||||
{ id: 40 },
|
||||
];
|
||||
|
||||
describe('swapItems', () => {
|
||||
it('FE-UTIL-020: swaps item up with its predecessor', () => {
|
||||
const result = swapItems(items, 1, 'up');
|
||||
expect(result).toEqual([20, 10, 30, 40]);
|
||||
});
|
||||
|
||||
it('FE-UTIL-021: swaps item down with its successor', () => {
|
||||
const result = swapItems(items, 1, 'down');
|
||||
expect(result).toEqual([10, 30, 20, 40]);
|
||||
});
|
||||
|
||||
it('FE-UTIL-022: returns null when moving first item up (out of bounds)', () => {
|
||||
expect(swapItems(items, 0, 'up')).toBeNull();
|
||||
});
|
||||
|
||||
it('FE-UTIL-023: returns null when moving last item down (out of bounds)', () => {
|
||||
expect(swapItems(items, items.length - 1, 'down')).toBeNull();
|
||||
});
|
||||
|
||||
it('FE-UTIL-024: swaps first and second items when moving index 1 up', () => {
|
||||
const result = swapItems(items, 1, 'up');
|
||||
expect(result![0]).toBe(20);
|
||||
expect(result![1]).toBe(10);
|
||||
});
|
||||
|
||||
it('FE-UTIL-025: returns an array of IDs (not objects)', () => {
|
||||
const result = swapItems(items, 0, 'down');
|
||||
expect(Array.isArray(result)).toBe(true);
|
||||
expect(typeof result![0]).toBe('number');
|
||||
});
|
||||
|
||||
it('FE-UTIL-026: does not mutate the original array', () => {
|
||||
const original = [{ id: 1 }, { id: 2 }, { id: 3 }];
|
||||
const snapshot = original.map((o) => o.id);
|
||||
swapItems(original, 0, 'down');
|
||||
expect(original.map((o) => o.id)).toEqual(snapshot);
|
||||
});
|
||||
|
||||
it('FE-UTIL-027: returns null for a single-element array moving down', () => {
|
||||
expect(swapItems([{ id: 5 }], 0, 'down')).toBeNull();
|
||||
});
|
||||
|
||||
it('FE-UTIL-028: returns null for a single-element array moving up', () => {
|
||||
expect(swapItems([{ id: 5 }], 0, 'up')).toBeNull();
|
||||
});
|
||||
|
||||
it('FE-UTIL-029: swaps last two items when moving second-to-last down', () => {
|
||||
const result = swapItems(items, items.length - 2, 'down');
|
||||
expect(result).toEqual([10, 20, 40, 30]);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user