mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-21 06:26:26 +00:00
c956fe92ba
dev now runs on MikroORM, so the positional migrations, seeds.ts and DatabaseService the Tours server side was built on are gone. Behaviour is unchanged; persistence moves onto dev's architecture: - one MikroORM migration for tour_types, tours and tour_waypoints, idempotent so instances that ran the old positional steps keep their data; the hike tour type is seeded inside it, the addon row in the AddonSeeder - entities and repositories for the three tables, tours domain on repositories and UnitOfWork - tour facet joins in places, assignments and days re-applied on the repository code Fixes found while porting: - GPX import checks addon, trip access and permission in the handler instead of guards, so a refused upload gets a 403/404 instead of a connection reset - copying a trip copies its tours and waypoints - a tour cannot be moved onto a day that already has it - updateTour checks existence inside its transaction Adds tours e2e tests and rewrites the tours unit tests onto the migrated test database.
65 lines
2.9 KiB
TypeScript
65 lines
2.9 KiB
TypeScript
import { describe, it, expect, vi } from 'vitest';
|
|
import { HttpException } from '@nestjs/common';
|
|
import { Test } from '@nestjs/testing';
|
|
import { AppModule } from '../../../src/nest/app.module';
|
|
import { FeaturesController } from '../../../src/nest/health/features.controller';
|
|
import { AdminGuard } from '../../../src/nest/auth/admin.guard';
|
|
|
|
vi.mock('../../../src/config', async () => {
|
|
const { readEnv } = await import('../../../src/app-config');
|
|
const env = readEnv();
|
|
return {
|
|
ENCRYPTION_KEY: 'wiring-test-inert-encryption-key',
|
|
JWT_SECRET: 'wiring-test-inert-jwt-secret',
|
|
updateJwtSecret: vi.fn(),
|
|
DEFAULT_LANGUAGE: env.app.defaultLanguage,
|
|
SESSION_DURATION: env.session.duration,
|
|
SESSION_DURATION_MS: env.session.durationMs,
|
|
SESSION_DURATION_SECONDS: env.session.durationSeconds,
|
|
SESSION_DURATION_REMEMBER: env.session.durationRemember,
|
|
SESSION_DURATION_REMEMBER_MS: env.session.durationRememberMs,
|
|
SESSION_DURATION_REMEMBER_SECONDS: env.session.durationRememberSeconds,
|
|
};
|
|
});
|
|
|
|
function ctx(user: unknown) {
|
|
return { switchToHttp: () => ({ getRequest: () => ({ user }) }) } as never;
|
|
}
|
|
|
|
describe('AppModule wiring', () => {
|
|
it('registers the upstream feature modules and Tours exactly once', () => {
|
|
// Only plain class imports: forRoot()/forFeature() entries are dynamic
|
|
// (MikroOrmModule legitimately appears twice) and some resolve async.
|
|
const imports = Reflect.getMetadata('imports', AppModule) as unknown[];
|
|
const names = imports
|
|
.filter((entry): entry is { name: string } => typeof entry === 'function')
|
|
.map(entry => entry.name);
|
|
expect(new Set(names).size).toBe(names.length);
|
|
expect(names).toEqual(expect.arrayContaining([
|
|
'GoogleQuotaModule', 'ReceiptScanModule', 'SchoolHolidaysModule', 'DocSyncModule',
|
|
'DawarichModule', 'NotificationsModule', 'ToursModule',
|
|
]));
|
|
expect(names.filter(name => name === 'ToursModule')).toHaveLength(1);
|
|
});
|
|
|
|
it('compiles with the global filter + DB provider and resolves the controller', async () => {
|
|
// Plan 4 Task 4: `DatabaseService` is gone — nothing left in the graph
|
|
// needs overriding for this to compile.
|
|
const moduleRef = await Test.createTestingModule({ imports: [AppModule] }).compile();
|
|
// The one test that builds the whole AppModule: resolving a controller out of
|
|
// it proves every module in the graph compiled, not just this one.
|
|
expect(moduleRef.get(FeaturesController)).toBeInstanceOf(FeaturesController);
|
|
});
|
|
});
|
|
|
|
describe('AdminGuard', () => {
|
|
const guard = new AdminGuard();
|
|
it('allows admins', () => {
|
|
expect(guard.canActivate(ctx({ role: 'admin' }))).toBe(true);
|
|
});
|
|
it('blocks non-admins and anonymous with 403 { error }', () => {
|
|
expect(() => guard.canActivate(ctx({ role: 'user' }))).toThrow(HttpException);
|
|
expect(() => guard.canActivate(ctx(undefined))).toThrow(HttpException);
|
|
});
|
|
});
|