refactor(nest): inject DatabaseService in access-check services and controllers

This commit is contained in:
jubnl
2026-07-25 18:14:53 +02:00
parent 718022c7ba
commit def6b84938
26 changed files with 92 additions and 46 deletions
@@ -1,6 +1,6 @@
import { Injectable } from '@nestjs/common';
import { broadcast } from '../../websocket';
import { canAccessTrip } from '../../db/database';
import { DatabaseService } from '../database/database.service';
import { checkPermission } from '../../services/permissions';
import type { User } from '../../types';
import * as svc from '../../services/assignmentService';
@@ -16,8 +16,10 @@ type Trip = { user_id: number };
*/
@Injectable()
export class AssignmentsService {
constructor(private readonly dbs: DatabaseService) {}
verifyTripAccess(tripId: string, userId: number) {
return canAccessTrip(Number(tripId), userId) as Trip | null | undefined;
return this.dbs.canAccessTrip(Number(tripId), userId) as Trip | null | undefined;
}
canEdit(trip: Trip, user: User): boolean {
+4 -2
View File
@@ -1,6 +1,6 @@
import { Injectable } from '@nestjs/common';
import { broadcast } from '../../websocket';
import { canAccessTrip } from '../../db/database';
import { DatabaseService } from '../database/database.service';
import { checkPermission } from '../../services/permissions';
import type { User } from '../../types';
import * as dayService from '../../services/dayService';
@@ -15,8 +15,10 @@ type Trip = { user_id: number };
*/
@Injectable()
export class DaysService {
constructor(private readonly dbs: DatabaseService) {}
verifyTripAccess(tripId: string, userId: number) {
return canAccessTrip(Number(tripId), userId) as Trip | null | undefined;
return this.dbs.canAccessTrip(Number(tripId), userId) as Trip | null | undefined;
}
canEdit(trip: Trip, user: User): boolean {
+4 -2
View File
@@ -1,6 +1,6 @@
import { Injectable } from '@nestjs/common';
import { broadcast } from '../../websocket';
import { canAccessTrip } from '../../db/database';
import { DatabaseService } from '../database/database.service';
import { checkPermission } from '../../services/permissions';
import type { User } from '../../types';
import * as svc from '../../services/placeService';
@@ -16,8 +16,10 @@ type Trip = { user_id: number };
*/
@Injectable()
export class PlacesService {
constructor(private readonly dbs: DatabaseService) {}
verifyTripAccess(tripId: string, userId: number) {
return canAccessTrip(Number(tripId), userId) as Trip | null | undefined;
return this.dbs.canAccessTrip(Number(tripId), userId) as Trip | null | undefined;
}
canEdit(trip: Trip, user: User): boolean {
@@ -1,6 +1,6 @@
import { Controller, Get, Param, Req, UseGuards } from '@nestjs/common';
import type { Request } from 'express';
import { canAccessTrip } from '../../db/database';
import { DatabaseService } from '../database/database.service';
import { JwtAuthGuard } from '../auth/jwt-auth.guard';
import { pluginsEnabled } from './kill-switch';
import { PluginRuntimeService } from './plugin-runtime.service';
@@ -145,7 +145,10 @@ function normalize(pluginId: string, raw: unknown): MapLayer[] {
@Controller('api/map-layers')
@UseGuards(JwtAuthGuard)
export class MapLayersController {
constructor(private readonly runtime: PluginRuntimeService) {}
constructor(
private readonly runtime: PluginRuntimeService,
private readonly dbs: DatabaseService,
) {}
@Get(':tripId')
async get(
@@ -155,7 +158,7 @@ export class MapLayersController {
if (!pluginsEnabled()) return { layers: [] };
const tripId = Number(tripIdRaw);
const userId = req.user?.id;
if (!Number.isFinite(tripId) || userId == null || !canAccessTrip(tripId, userId)) return { layers: [] };
if (!Number.isFinite(tripId) || userId == null || !this.dbs.canAccessTrip(tripId, userId)) return { layers: [] };
const ids = this.runtime.providersOf('mapLayerProvider');
const perProvider = await Promise.all(
@@ -1,6 +1,6 @@
import { Controller, Get, Param, Req, UseGuards } from '@nestjs/common';
import type { Request } from 'express';
import { canAccessTrip } from '../../db/database';
import { DatabaseService } from '../database/database.service';
import { JwtAuthGuard } from '../auth/jwt-auth.guard';
import { pluginsEnabled } from './kill-switch';
import { PluginRuntimeService } from './plugin-runtime.service';
@@ -78,7 +78,10 @@ function normalize(pluginId: string, raw: unknown): MapMarker[] {
@Controller('api/map-markers')
@UseGuards(JwtAuthGuard)
export class MapMarkersController {
constructor(private readonly runtime: PluginRuntimeService) {}
constructor(
private readonly runtime: PluginRuntimeService,
private readonly dbs: DatabaseService,
) {}
@Get(':tripId')
async get(
@@ -88,7 +91,7 @@ export class MapMarkersController {
if (!pluginsEnabled()) return { markers: [] };
const tripId = Number(tripIdRaw);
const userId = req.user?.id;
if (!Number.isFinite(tripId) || userId == null || !canAccessTrip(tripId, userId)) return { markers: [] };
if (!Number.isFinite(tripId) || userId == null || !this.dbs.canAccessTrip(tripId, userId)) return { markers: [] };
const ids = this.runtime.providersOf('mapMarkerProvider');
const perProvider = await Promise.all(
@@ -1,6 +1,6 @@
import { Controller, Get, Param, Req, UseGuards } from '@nestjs/common';
import type { Request } from 'express';
import { canAccessTrip } from '../../db/database';
import { DatabaseService } from '../database/database.service';
import { JwtAuthGuard } from '../auth/jwt-auth.guard';
import { pluginsEnabled } from './kill-switch';
import { PluginRuntimeService } from './plugin-runtime.service';
@@ -74,7 +74,10 @@ function normalize(pluginId: string, raw: unknown): PdfSection[] {
@Controller('api/pdf-sections')
@UseGuards(JwtAuthGuard)
export class PdfSectionsController {
constructor(private readonly runtime: PluginRuntimeService) {}
constructor(
private readonly runtime: PluginRuntimeService,
private readonly dbs: DatabaseService,
) {}
@Get(':tripId')
async get(
@@ -84,7 +87,7 @@ export class PdfSectionsController {
if (!pluginsEnabled()) return { sections: [] };
const tripId = Number(tripIdRaw);
const userId = req.user?.id;
if (!Number.isFinite(tripId) || userId == null || !canAccessTrip(tripId, userId)) return { sections: [] };
if (!Number.isFinite(tripId) || userId == null || !this.dbs.canAccessTrip(tripId, userId)) return { sections: [] };
const ids = this.runtime.providersOf('pdfSectionProvider');
const perProvider = await Promise.all(
@@ -1,6 +1,6 @@
import { Controller, Get, Query, Req, UseGuards } from '@nestjs/common';
import type { Request } from 'express';
import { canAccessTrip } from '../../db/database';
import { DatabaseService } from '../database/database.service';
import { JwtAuthGuard } from '../auth/jwt-auth.guard';
import { pluginsEnabled } from './kill-switch';
import { PluginRuntimeService } from './plugin-runtime.service';
@@ -82,7 +82,10 @@ function normalize(pluginId: string, raw: unknown, allowed: Set<number>): TripCa
@Controller('api/trip-card-contributions')
@UseGuards(JwtAuthGuard)
export class TripCardContributionsController {
constructor(private readonly runtime: PluginRuntimeService) {}
constructor(
private readonly runtime: PluginRuntimeService,
private readonly dbs: DatabaseService,
) {}
@Get()
async get(
@@ -100,7 +103,7 @@ export class TripCardContributionsController {
.map((s) => Number(s.trim()))
.filter((n) => Number.isInteger(n) && n > 0)
.slice(0, MAX_TRIP_IDS);
const accessible = [...new Set(requested)].filter((id) => canAccessTrip(id, userId));
const accessible = [...new Set(requested)].filter((id) => this.dbs.canAccessTrip(id, userId));
if (accessible.length === 0) return { contributions: [] };
const allowed = new Set(accessible);
@@ -1,6 +1,6 @@
import { Controller, Get, Param, Req, UseGuards } from '@nestjs/common';
import type { Request } from 'express';
import { canAccessTrip } from '../../db/database';
import { DatabaseService } from '../database/database.service';
import { JwtAuthGuard } from '../auth/jwt-auth.guard';
import { pluginsEnabled } from './kill-switch';
import { PluginRuntimeService } from './plugin-runtime.service';
@@ -27,7 +27,10 @@ const MESSAGE_MAX = 300;
@Controller('api/trip-warnings')
@UseGuards(JwtAuthGuard)
export class TripWarningsController {
constructor(private readonly runtime: PluginRuntimeService) {}
constructor(
private readonly runtime: PluginRuntimeService,
private readonly dbs: DatabaseService,
) {}
@Get(':tripId')
async get(
@@ -37,7 +40,7 @@ export class TripWarningsController {
if (!pluginsEnabled()) return { warnings: [] };
const tripId = Number(tripIdRaw);
const userId = req.user?.id;
if (!Number.isFinite(tripId) || userId == null || !canAccessTrip(tripId, userId)) return { warnings: [] };
if (!Number.isFinite(tripId) || userId == null || !this.dbs.canAccessTrip(tripId, userId)) return { warnings: [] };
const ids = this.runtime.providersOf('warningProvider');
const perProvider = await Promise.all(
@@ -1,6 +1,6 @@
import { Controller, Get, Param, Req, UseGuards } from '@nestjs/common';
import type { Request } from 'express';
import { canAccessTrip } from '../../db/database';
import { DatabaseService } from '../database/database.service';
import { JwtAuthGuard } from '../auth/jwt-auth.guard';
import { pluginsEnabled } from './kill-switch';
import { PluginRuntimeService } from './plugin-runtime.service';
@@ -102,7 +102,10 @@ function normalize(pluginId: string, raw: unknown): Contribution[] {
@Controller('api/view-contributions')
@UseGuards(JwtAuthGuard)
export class ViewContributionsController {
constructor(private readonly runtime: PluginRuntimeService) {}
constructor(
private readonly runtime: PluginRuntimeService,
private readonly dbs: DatabaseService,
) {}
@Get(':view/:tripId')
async get(
@@ -113,7 +116,7 @@ export class ViewContributionsController {
if (!pluginsEnabled() || !VIEWS.has(view)) return { contributions: [] };
const tripId = Number(tripIdRaw);
const userId = req.user?.id;
if (!Number.isFinite(tripId) || userId == null || !canAccessTrip(tripId, userId)) return { contributions: [] };
if (!Number.isFinite(tripId) || userId == null || !this.dbs.canAccessTrip(tripId, userId)) return { contributions: [] };
const ids = this.runtime.providersOf('tableContributor');
const perProvider = await Promise.all(
@@ -1,6 +1,6 @@
import { Injectable } from '@nestjs/common';
import { broadcast } from '../../websocket';
import { canAccessTrip } from '../../db/database';
import { DatabaseService } from '../database/database.service';
import { checkPermission } from '../../services/permissions';
import type { User } from '../../types';
import * as dayService from '../../services/dayService';
@@ -15,9 +15,11 @@ type Trip = { user_id: number };
*/
@Injectable()
export class AccommodationsService {
constructor(private readonly dbs: DatabaseService) {}
/** Mirrors the requireTripAccess middleware (owner or member), returning the trip. */
verifyTripAccess(tripId: string, userId: number) {
return canAccessTrip(Number(tripId), userId) as Trip | null | undefined;
return this.dbs.canAccessTrip(Number(tripId), userId) as Trip | null | undefined;
}
canEdit(trip: Trip, user: User): boolean {
+6 -3
View File
@@ -1,10 +1,11 @@
import { Injectable } from '@nestjs/common';
import { canAccessTrip } from '../../db/database';
import { DatabaseService } from '../database/database.service';
import type { TripAccess } from '../database/database.service';
import { checkPermission } from '../../services/permissions';
import type { User } from '../../types';
import * as svc from '../../services/shareService';
type Trip = NonNullable<ReturnType<typeof canAccessTrip>>;
type Trip = TripAccess;
/**
* Thin Nest wrapper around the existing share service. Trip access, the
@@ -12,8 +13,10 @@ type Trip = NonNullable<ReturnType<typeof canAccessTrip>>;
*/
@Injectable()
export class ShareService {
constructor(private readonly dbs: DatabaseService) {}
verifyTripAccess(tripId: string, userId: number) {
return canAccessTrip(tripId, userId);
return this.dbs.canAccessTrip(tripId, userId);
}
canManage(trip: Trip, user: User): boolean {
@@ -1,11 +1,12 @@
import { Injectable } from '@nestjs/common';
import { canAccessTrip } from '../../db/database';
import { DatabaseService } from '../database/database.service';
import type { TripAccess } from '../database/database.service';
import { checkPermission } from '../../services/permissions';
import { joinTripAsMember } from '../../services/tripMembership';
import type { User } from '../../types';
import * as svc from '../../services/tripInviteService';
type Trip = NonNullable<ReturnType<typeof canAccessTrip>>;
type Trip = TripAccess;
/**
* Thin Nest wrapper around the trip invite-link service. Trip access and the
@@ -14,8 +15,10 @@ type Trip = NonNullable<ReturnType<typeof canAccessTrip>>;
*/
@Injectable()
export class TripInviteService {
constructor(private readonly dbs: DatabaseService) {}
verifyTripAccess(tripId: string, userId: number) {
return canAccessTrip(tripId, userId);
return this.dbs.canAccessTrip(tripId, userId);
}
canManage(trip: Trip, user: User): boolean {
+2 -1
View File
@@ -8,6 +8,7 @@ import { describe, it, expect, beforeAll, afterAll, beforeEach, vi } from 'vites
import request from 'supertest';
import cookieParser from 'cookie-parser';
import type { Server } from 'http';
import { DatabaseModule } from '../../src/nest/database/database.module';
import { Test } from '@nestjs/testing';
import { seedUser, sessionCookie } from './harness';
@@ -41,7 +42,7 @@ describe('Admin e2e (real auth + admin guard + temp SQLite)', () => {
let app: Awaited<ReturnType<typeof build>>;
async function build() {
const moduleRef = await Test.createTestingModule({ imports: [AdminModule] }).compile();
const moduleRef = await Test.createTestingModule({ imports: [DatabaseModule, AdminModule] }).compile();
const nest = moduleRef.createNestApplication();
nest.use(cookieParser());
nest.useGlobalFilters(new TrekExceptionFilter());
+2 -1
View File
@@ -7,6 +7,7 @@ import { describe, it, expect, beforeAll, afterAll, beforeEach, vi } from 'vites
import request from 'supertest';
import cookieParser from 'cookie-parser';
import type { Server } from 'http';
import { DatabaseModule } from '../../src/nest/database/database.module';
import { Test } from '@nestjs/testing';
import { seedUser, sessionCookie } from './harness';
@@ -49,7 +50,7 @@ describe('Assignments e2e (real auth guard + temp SQLite)', () => {
let app: Awaited<ReturnType<typeof build>>;
async function build() {
const moduleRef = await Test.createTestingModule({ imports: [AssignmentsModule] }).compile();
const moduleRef = await Test.createTestingModule({ imports: [DatabaseModule, AssignmentsModule] }).compile();
const nest = moduleRef.createNestApplication();
nest.use(cookieParser());
nest.useGlobalFilters(new TrekExceptionFilter());
+2 -1
View File
@@ -7,6 +7,7 @@ import { describe, it, expect, beforeAll, afterAll, beforeEach, vi } from 'vites
import request from 'supertest';
import cookieParser from 'cookie-parser';
import type { Server } from 'http';
import { DatabaseModule } from '../../src/nest/database/database.module';
import { Test } from '@nestjs/testing';
import { seedUser, sessionCookie } from './harness';
@@ -47,7 +48,7 @@ describe('Days + day-notes e2e (real auth guard + temp SQLite)', () => {
let app: Awaited<ReturnType<typeof build>>;
async function build() {
const moduleRef = await Test.createTestingModule({ imports: [DaysModule] }).compile();
const moduleRef = await Test.createTestingModule({ imports: [DatabaseModule, DaysModule] }).compile();
const nest = moduleRef.createNestApplication();
nest.use(cookieParser());
nest.useGlobalFilters(new TrekExceptionFilter());
+2 -1
View File
@@ -8,6 +8,7 @@ import { describe, it, expect, beforeAll, afterAll, beforeEach, vi } from 'vites
import request from 'supertest';
import cookieParser from 'cookie-parser';
import type { Server } from 'http';
import { DatabaseModule } from '../../src/nest/database/database.module';
import { Test } from '@nestjs/testing';
import { seedUser, sessionCookie } from './harness';
@@ -48,7 +49,7 @@ describe('Places e2e (real auth guard + temp SQLite)', () => {
let app: Awaited<ReturnType<typeof build>>;
async function build() {
const moduleRef = await Test.createTestingModule({ imports: [PlacesModule] }).compile();
const moduleRef = await Test.createTestingModule({ imports: [DatabaseModule, PlacesModule] }).compile();
const nest = moduleRef.createNestApplication();
nest.use(cookieParser());
nest.useGlobalFilters(new TrekExceptionFilter());
+2 -1
View File
@@ -7,6 +7,7 @@
import { TrekExceptionFilter } from '../../src/nest/common/trek-exception.filter';
import { ReservationsModule } from '../../src/nest/reservations/reservations.module';
import { seedUser, sessionCookie } from './harness';
import { DatabaseModule } from '../../src/nest/database/database.module';
import { Test } from '@nestjs/testing';
import cookieParser from 'cookie-parser';
@@ -76,7 +77,7 @@ describe('Reservations + accommodations e2e (real auth guard + temp SQLite)', ()
let app: Awaited<ReturnType<typeof build>>;
async function build() {
const moduleRef = await Test.createTestingModule({ imports: [ReservationsModule] }).compile();
const moduleRef = await Test.createTestingModule({ imports: [DatabaseModule, ReservationsModule] }).compile();
const nest = moduleRef.createNestApplication();
nest.use(cookieParser());
nest.useGlobalFilters(new TrekExceptionFilter());
+2 -1
View File
@@ -12,6 +12,7 @@ import os from 'node:os';
import path from 'node:path';
import fs from 'node:fs';
import type { Server } from 'http';
import { DatabaseModule } from '../../src/nest/database/database.module';
import { Test } from '@nestjs/testing';
import { seedUser, sessionCookie } from './harness';
@@ -43,7 +44,7 @@ describe('Share-link e2e (real auth guard + temp SQLite)', () => {
let app: Awaited<ReturnType<typeof build>>;
async function build() {
const moduleRef = await Test.createTestingModule({ imports: [ShareModule] }).compile();
const moduleRef = await Test.createTestingModule({ imports: [DatabaseModule, ShareModule] }).compile();
const nest = moduleRef.createNestApplication();
nest.use(cookieParser());
nest.useGlobalFilters(new TrekExceptionFilter());
+2 -1
View File
@@ -9,6 +9,7 @@ import { describe, it, expect, beforeAll, afterAll, beforeEach, vi } from 'vites
import request from 'supertest';
import cookieParser from 'cookie-parser';
import type { Server } from 'http';
import { DatabaseModule } from '../../src/nest/database/database.module';
import { Test } from '@nestjs/testing';
import { seedUser, sessionCookie } from './harness';
@@ -50,7 +51,7 @@ describe('Trip invite-link e2e (real auth guard + temp SQLite)', () => {
let app: Awaited<ReturnType<typeof build>>;
async function build() {
const moduleRef = await Test.createTestingModule({ imports: [TripInviteModule] }).compile();
const moduleRef = await Test.createTestingModule({ imports: [DatabaseModule, TripInviteModule] }).compile();
const nest = moduleRef.createNestApplication();
nest.use(cookieParser());
nest.useGlobalFilters(new TrekExceptionFilter());
+2 -1
View File
@@ -19,10 +19,11 @@ const { share } = vi.hoisted(() => ({
vi.mock('../../../src/services/shareService', () => share);
import { ShareService } from '../../../src/nest/share/share.service';
import type { DatabaseService } from '../../../src/nest/database/database.service';
import type { User } from '../../../src/types';
function svc() {
return new ShareService();
return new ShareService({ canAccessTrip } as unknown as DatabaseService);
}
beforeEach(() => vi.clearAllMocks());
@@ -16,6 +16,7 @@ vi.mock('../../../src/nest/plugins/kill-switch', () => ({ pluginsEnabled }));
import { MapLayersController } from '../../../src/nest/plugins/map-layers.controller';
import type { PluginRuntimeService } from '../../../src/nest/plugins/plugin-runtime.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;
@@ -24,7 +25,7 @@ function controller(invoke: (id: string) => unknown, providers = ['p1']) {
providersOf: vi.fn(() => providers),
invokeHook: vi.fn(async (id: string) => invoke(id)),
} as unknown as PluginRuntimeService;
return { c: new MapLayersController(runtime), runtime };
return { c: new MapLayersController(runtime, { canAccessTrip } as unknown as DatabaseService), runtime };
}
const line = (n = 3, over: Record<string, unknown> = {}) => ({
type: 'polyline',
@@ -15,6 +15,7 @@ vi.mock('../../../src/nest/plugins/kill-switch', () => ({ pluginsEnabled }));
import { MapMarkersController } from '../../../src/nest/plugins/map-markers.controller';
import type { PluginRuntimeService } from '../../../src/nest/plugins/plugin-runtime.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;
@@ -23,7 +24,7 @@ function controller(invoke: (id: string) => unknown, providers = ['p1']) {
providersOf: vi.fn(() => providers),
invokeHook: vi.fn(async (id: string) => invoke(id)),
} as unknown as PluginRuntimeService;
return { c: new MapMarkersController(runtime), runtime };
return { c: new MapMarkersController(runtime, { canAccessTrip } as unknown as DatabaseService), runtime };
}
const mk = (over: Record<string, unknown> = {}) => ({ id: 'm1', lat: 48.85, lng: 2.35, ...over });
@@ -16,6 +16,7 @@ vi.mock('../../../src/nest/plugins/kill-switch', () => ({ pluginsEnabled }));
import { PdfSectionsController } from '../../../src/nest/plugins/pdf-sections.controller';
import type { PluginRuntimeService } from '../../../src/nest/plugins/plugin-runtime.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;
@@ -24,7 +25,7 @@ function controller(invoke: (id: string) => unknown, providers = ['p1']) {
providersOf: vi.fn(() => providers),
invokeHook: vi.fn(async (id: string) => invoke(id)),
} as unknown as PluginRuntimeService;
return { c: new PdfSectionsController(runtime), runtime };
return { c: new PdfSectionsController(runtime, { canAccessTrip } as unknown as DatabaseService), runtime };
}
const sec = (over: Record<string, unknown> = {}) => ({ title: 'Weather', ...over });
@@ -17,6 +17,7 @@ vi.mock('../../../src/nest/plugins/kill-switch', () => ({ pluginsEnabled }));
import { TripCardContributionsController } from '../../../src/nest/plugins/trip-card-contributions.controller';
import type { PluginRuntimeService } from '../../../src/nest/plugins/plugin-runtime.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;
@@ -25,7 +26,7 @@ function controller(invoke: (id: string, args: unknown[]) => unknown, providers
providersOf: vi.fn(() => providers),
invokeHook: vi.fn(async (id: string, _h: string, _fn: string, args: unknown[]) => invoke(id, args)),
} as unknown as PluginRuntimeService;
return { c: new TripCardContributionsController(runtime), runtime };
return { c: new TripCardContributionsController(runtime, { canAccessTrip } as unknown as DatabaseService), runtime };
}
const badge = (over: Record<string, unknown> = {}) => ({ tripId: 1, id: 'b1', label: 'Visa', ...over });
@@ -9,6 +9,7 @@ vi.mock('../../../src/nest/plugins/kill-switch', () => ({ pluginsEnabled }));
import { TripWarningsController } from '../../../src/nest/plugins/trip-warnings.controller';
import type { PluginRuntimeService } from '../../../src/nest/plugins/plugin-runtime.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;
@@ -19,7 +20,7 @@ function controller(over: Partial<PluginRuntimeService> = {}) {
id === 'p2' ? [{ level: 'error', message: 'Day 3 is overpacked', dayId: 3 }] : [{ level: 'warning', message: 'Museum closed Mon', placeId: 7 }]),
...over,
} as unknown as PluginRuntimeService;
return { c: new TripWarningsController(runtime), runtime };
return { c: new TripWarningsController(runtime, { canAccessTrip } as unknown as DatabaseService), runtime };
}
describe('TripWarningsController', () => {
@@ -16,6 +16,7 @@ vi.mock('../../../src/nest/plugins/kill-switch', () => ({ pluginsEnabled }));
import { ViewContributionsController } from '../../../src/nest/plugins/view-contributions.controller';
import type { PluginRuntimeService } from '../../../src/nest/plugins/plugin-runtime.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;
@@ -24,7 +25,7 @@ function controller(invoke: (id: string) => unknown, providers = ['p1']) {
providersOf: vi.fn(() => providers),
invokeHook: vi.fn(async (id: string) => invoke(id)),
} as unknown as PluginRuntimeService;
return { c: new ViewContributionsController(runtime), runtime };
return { c: new ViewContributionsController(runtime, { canAccessTrip } as unknown as DatabaseService), runtime };
}
const col = (over: Record<string, unknown> = {}) => ({ kind: 'column', entityId: 1, id: 'c1', label: 'X', ...over });
const act = (over: Record<string, unknown> = {}) => ({ kind: 'action', entityId: 1, id: 'a1', label: 'Go', target: { kind: 'frame', sub: '/ui' }, ...over });