mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-19 05:26:47 +00:00
test(server): plan 4 — constructor ripple for the rosterUserIds/getPlaceWithTags inline
Hand-built BudgetService/BudgetMcp/TodoService call sites drop the removed DatabaseService constructor arg (budgetRepoArgs() now appends a TripMembersRepository so most spread call sites need no other change); budget.service.test.ts's rosterHas() helper and svc() factory move from a spied DatabaseService to a stubbed TripMembersRepository. The AccommodationsService helper (tests/helpers/accommodations-service.ts) and its two direct callers drop the same arg. PackingService call sites are untouched (its new param is optional, so every existing hand-built instance still resolves rosterUserIds through the DatabaseService fallback).
This commit is contained in:
@@ -30,9 +30,11 @@ import {
|
||||
* why this is a helper and not five copies across the suites.
|
||||
*
|
||||
* Plan 3c Task 0b: the `DatabaseService` built here needs a real
|
||||
* `EntityManager` now — `AccommodationsService.stampLodging` reaches
|
||||
* `getPlaceWithTags`, which is `PlacesRepository.findWithTagsAndRatings`
|
||||
* (not `db/database.ts`'s deleted free function).
|
||||
* `EntityManager` now (its `.connection` backs every repository factory
|
||||
* below, and `JourneyDomainService` still takes a full `DatabaseService`).
|
||||
* `AccommodationsService` itself no longer holds one (Plan 4 Task 3 —
|
||||
* `stampLodging`'s old `getPlaceWithTags` delegate is
|
||||
* `PlacesRepository.findWithTagsAndRatings` directly now).
|
||||
*/
|
||||
export async function makeAccommodationsService(conn: Database): Promise<AccommodationsService> {
|
||||
return accommodationsOver(new DatabaseService(conn, (await sharedTestOrm(conn)).em));
|
||||
@@ -68,10 +70,11 @@ export async function accommodationsOver(dbs: DatabaseService): Promise<Accommod
|
||||
await createTestRoadtripViasRepo(dbs.connection),
|
||||
);
|
||||
return new AccommodationsService(
|
||||
dbs, permissions, realtime, assignments, await createTestUnitOfWork(dbs.connection),
|
||||
permissions, realtime, assignments, await createTestUnitOfWork(dbs.connection),
|
||||
// Plan 4 Task 2 — AccommodationsService's own canAccessTrip delegate is now
|
||||
// TripsRepository.findAccessible; `dbs` itself stays (still needed for
|
||||
// stampLodging's getPlaceWithTags).
|
||||
// TripsRepository.findAccessible. Plan 4 Task 3 — stampLodging's
|
||||
// getPlaceWithTags is PlacesRepository.findWithTagsAndRatings directly
|
||||
// (`placesRepo` below, already injected); `dbs` no longer needed here.
|
||||
await createTestTripsRepo(dbs.connection),
|
||||
await createTestDayAccommodationsRepo(dbs.connection),
|
||||
await createTestDayAssignmentsRepo(dbs.connection),
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type Database from 'better-sqlite3';
|
||||
import { sharedTestOrm, createTestReservationsRepo, createTestPlacesRepo, createTestTripsRepo } from './test-uow';
|
||||
import { sharedTestOrm, createTestReservationsRepo, createTestPlacesRepo, createTestTripsRepo, createTestTripMembersRepo } from './test-uow';
|
||||
import { createTestBudgetItemsRepo } from './files-repos';
|
||||
import { BudgetItemMembers } from '../../src/db/entities/BudgetItemMembers.entity';
|
||||
import type { BudgetItemMembersRepository } from '../../src/db/repositories/BudgetItemMembers.repository';
|
||||
@@ -13,6 +13,7 @@ import type { BudgetItemsRepository } from '../../src/db/repositories/BudgetItem
|
||||
import type { ReservationsRepository } from '../../src/db/repositories/Reservations.repository';
|
||||
import type { PlacesRepository } from '../../src/db/repositories/Places.repository';
|
||||
import type { TripsRepository } from '../../src/db/repositories/Trips.repository';
|
||||
import type { TripMembersRepository } from '../../src/db/repositories/TripMembers.repository';
|
||||
|
||||
/**
|
||||
* Plan 3e Task 2 (budget) test-only repository factories, bound to a suite's
|
||||
@@ -44,16 +45,18 @@ export function createTestBudgetCategoryOrderRepo(db: Database.Database): Promis
|
||||
}
|
||||
|
||||
/**
|
||||
* The 8 repository arguments `BudgetService`'s constructor appends after
|
||||
* The 9 repository arguments `BudgetService`'s constructor appends after
|
||||
* `uow` (`budgetItemsRepo`, `budgetItemMembersRepo`, `budgetItemPayersRepo`,
|
||||
* `budgetSettlementsRepo`, `budgetCategoryOrderRepo`, `reservationsRepo`,
|
||||
* `placesRepo`, `tripsRepo`), built over the SAME connection in one call —
|
||||
* every hand-built `new BudgetService(...)` test call site spreads this
|
||||
* (`...(await budgetRepoArgs(conn))`) instead of repeating all 8 factories.
|
||||
* `placesRepo`, `tripsRepo`, `tripMembersRepo` — Plan 4 Task 3's own,
|
||||
* appended last when `rosterUserIds` inlined off `DatabaseService`), built
|
||||
* over the SAME connection in one call — every hand-built
|
||||
* `new BudgetService(...)` test call site spreads this
|
||||
* (`...(await budgetRepoArgs(conn))`) instead of repeating all 9 factories.
|
||||
*/
|
||||
export async function budgetRepoArgs(db: Database.Database): Promise<[
|
||||
BudgetItemsRepository, BudgetItemMembersRepository, BudgetItemPayersRepository, BudgetSettlementsRepository,
|
||||
BudgetCategoryOrderRepository, ReservationsRepository, PlacesRepository, TripsRepository,
|
||||
BudgetCategoryOrderRepository, ReservationsRepository, PlacesRepository, TripsRepository, TripMembersRepository,
|
||||
]> {
|
||||
return [
|
||||
await createTestBudgetItemsRepo(db),
|
||||
@@ -64,5 +67,6 @@ export async function budgetRepoArgs(db: Database.Database): Promise<[
|
||||
await createTestReservationsRepo(db),
|
||||
await createTestPlacesRepo(db),
|
||||
await createTestTripsRepo(db),
|
||||
await createTestTripMembersRepo(db),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -218,7 +218,7 @@ export async function createMcpTestRegistry(): Promise<McpRegistry> {
|
||||
// moved off `DatabaseService` onto `TripsRepository`/`UsersRepository`.
|
||||
const guards = new McpToolGuardsService(mcpOrm.repo(Trips), usersRepo, permissionsService, realtimeService);
|
||||
const exchangeRatesService = new ExchangeRatesService();
|
||||
const budgetService = new BudgetService(dbService, permissionsService, exchangeRatesService, realtimeService, await createTestUnitOfWork(dbService.connection), ...(await budgetRepoArgs(dbService.connection)));
|
||||
const budgetService = new BudgetService(permissionsService, exchangeRatesService, realtimeService, await createTestUnitOfWork(dbService.connection), ...(await budgetRepoArgs(dbService.connection)));
|
||||
const authService = new AuthService(
|
||||
permissionsService,
|
||||
new TripMembershipService(await createTestTripsRepo(dbService.connection), await createTestTripMembersRepo(dbService.connection)),
|
||||
@@ -243,7 +243,7 @@ export async function createMcpTestRegistry(): Promise<McpRegistry> {
|
||||
await createTestReservationEndpointsRepo(dbService.connection),
|
||||
await createTestDayAccommodationsRepo(dbService.connection),
|
||||
);
|
||||
const todoService = new TodoService(dbService, permissionsService, realtimeService, await createTestUnitOfWork(dbService.connection), await createTestTodoItemsRepo(dbService.connection), await createTestTodoCategoryAssigneesRepo(dbService.connection), await createTestTripsRepo(dbService.connection));
|
||||
const todoService = new TodoService(permissionsService, realtimeService, await createTestUnitOfWork(dbService.connection), await createTestTodoItemsRepo(dbService.connection), await createTestTodoCategoryAssigneesRepo(dbService.connection), await createTestTripsRepo(dbService.connection), await createTestTripMembersRepo(dbService.connection));
|
||||
const packingService = new PackingService(
|
||||
dbService, permissionsService, realtimeService, notificationsStub(), await createTestUnitOfWork(dbService.connection),
|
||||
await createTestPackingItemsRepo(dbService.connection), await createTestPackingItemContributorsRepo(dbService.connection), await createTestPackingBagsRepo(dbService.connection),
|
||||
@@ -292,7 +292,7 @@ export async function createMcpTestRegistry(): Promise<McpRegistry> {
|
||||
await createTestRoadtripViasRepo(dbService.connection),
|
||||
);
|
||||
const accommodationsService = new AccommodationsService(
|
||||
dbService, permissionsService, realtimeService, assignmentsService, await createTestUnitOfWork(dbService.connection),
|
||||
permissionsService, realtimeService, assignmentsService, await createTestUnitOfWork(dbService.connection),
|
||||
await createTestTripsRepo(dbService.connection),
|
||||
await createTestDayAccommodationsRepo(dbService.connection),
|
||||
await createTestDayAssignmentsRepo(dbService.connection),
|
||||
@@ -397,7 +397,7 @@ export async function createMcpTestRegistry(): Promise<McpRegistry> {
|
||||
new AuthMcp(),
|
||||
new TodoMcp(todoService, authService, addonsService, guards),
|
||||
new PackingMcp(packingService, authService, addonsService, guards),
|
||||
new BudgetMcp(budgetService, exchangeRatesService, dbService, new RuntimeEnvService(), new TripMembershipService(await createTestTripsRepo(dbService.connection), await createTestTripMembersRepo(dbService.connection)), addonsService, guards, await createTestUnitOfWork(dbService.connection), await createTestPlacesRepo(dbService.connection), await createTestTripsRepo(dbService.connection), demoService),
|
||||
new BudgetMcp(budgetService, exchangeRatesService, new RuntimeEnvService(), new TripMembershipService(await createTestTripsRepo(dbService.connection), await createTestTripMembersRepo(dbService.connection)), addonsService, guards, await createTestUnitOfWork(dbService.connection), await createTestPlacesRepo(dbService.connection), await createTestTripsRepo(dbService.connection), demoService, await createTestTripMembersRepo(dbService.connection)),
|
||||
new ReservationsMcp(reservationsService, daysService, budgetService, authService, assignmentsService, guards),
|
||||
new DayNotesMcp(new DayNotesService(await createTestTripsRepo(dbService.connection), permissionsService, realtimeService, await createTestDayNotesRepo(dbService.connection), await createTestDaysRepo(dbService.connection)), authService, guards),
|
||||
new DaysMcp(daysService, authService, guards),
|
||||
|
||||
@@ -158,10 +158,10 @@ export async function createPluginRpcHostFactory(dbs: DatabaseService): Promise<
|
||||
const permissions = new PermissionsService(await createTestAppSettingsRepo(dbs.connection), await createTestUnitOfWork(dbs.connection));
|
||||
const exchangeRates = new ExchangeRatesService();
|
||||
const realtime = new RealtimeService();
|
||||
const budget = new BudgetService(dbs, permissions, exchangeRates, realtime, await createTestUnitOfWork(dbs.connection), ...(await budgetRepoArgs(dbs.connection)));
|
||||
const budget = new BudgetService(permissions, exchangeRates, realtime, await createTestUnitOfWork(dbs.connection), ...(await budgetRepoArgs(dbs.connection)));
|
||||
const addons = await createTestAddonsService(dbs.connection, dbs);
|
||||
const queryHelpers = new QueryHelpersService(await createTestTagsRepo(dbs.connection), await createTestPlaceRatingsRepo(dbs.connection), await createTestAssignmentParticipantsRepo(dbs.connection));
|
||||
const todos = new TodoService(dbs, permissions, realtime, await createTestUnitOfWork(dbs.connection), await createTestTodoItemsRepo(dbs.connection), await createTestTodoCategoryAssigneesRepo(dbs.connection), await createTestTripsRepo(dbs.connection));
|
||||
const todos = new TodoService(permissions, realtime, await createTestUnitOfWork(dbs.connection), await createTestTodoItemsRepo(dbs.connection), await createTestTodoCategoryAssigneesRepo(dbs.connection), await createTestTripsRepo(dbs.connection), await createTestTripMembersRepo(dbs.connection));
|
||||
const packing = new PackingService(
|
||||
dbs, permissions, realtime, notificationsStub(), await createTestUnitOfWork(dbs.connection),
|
||||
await createTestPackingItemsRepo(dbs.connection), await createTestPackingItemContributorsRepo(dbs.connection), await createTestPackingBagsRepo(dbs.connection),
|
||||
@@ -266,7 +266,7 @@ export async function createPluginRpcHostFactory(dbs: DatabaseService): Promise<
|
||||
const pluginOrm = await sharedTestOrm(dbs.connection);
|
||||
const oauth = new PluginOAuthService(pluginOrm.repo(Plugins), pluginOrm.repo(PluginOauthTokens), pluginOrm.repo(PluginOauthState), pluginOrm.repo(PluginSettingsFields));
|
||||
const accommodations = new AccommodationsService(
|
||||
dbs, permissions, realtime, assignments, await createTestUnitOfWork(dbs.connection),
|
||||
permissions, realtime, assignments, await createTestUnitOfWork(dbs.connection),
|
||||
await createTestTripsRepo(dbs.connection),
|
||||
await createTestDayAccommodationsRepo(dbs.connection),
|
||||
await createTestDayAssignmentsRepo(dbs.connection),
|
||||
|
||||
@@ -337,7 +337,7 @@ describe('Settlement tools', () => {
|
||||
|
||||
const dbService = new DatabaseService(testDb);
|
||||
const controller = new BudgetController(
|
||||
new BudgetService(dbService, new PermissionsService(await createTestAppSettingsRepo(dbService.connection), await createTestUnitOfWork(dbService.connection)), new ExchangeRatesService(), new RealtimeService(), await createTestUnitOfWork(dbService.connection), ...(await budgetRepoArgs(dbService.connection))),
|
||||
new BudgetService(new PermissionsService(await createTestAppSettingsRepo(dbService.connection), await createTestUnitOfWork(dbService.connection)), new ExchangeRatesService(), new RealtimeService(), await createTestUnitOfWork(dbService.connection), ...(await budgetRepoArgs(dbService.connection))),
|
||||
);
|
||||
const rest = await controller.settlement(
|
||||
{ id: user.id } as User,
|
||||
|
||||
@@ -154,9 +154,8 @@ beforeAll(async () => {
|
||||
);
|
||||
packingMcp = new PackingMcp(promptPackingService, authStub, addonsStub, promptGuards);
|
||||
budgetMcp = new BudgetMcp(
|
||||
new BudgetService(promptDbs(), new PermissionsService(await createTestAppSettingsRepo(promptDbs().connection), await createTestUnitOfWork(promptDbs().connection)), new ExchangeRatesService(), new RealtimeService(), await createTestUnitOfWork(promptDbs().connection), ...(await budgetRepoArgs(promptDbs().connection))),
|
||||
new BudgetService(new PermissionsService(await createTestAppSettingsRepo(promptDbs().connection), await createTestUnitOfWork(promptDbs().connection)), new ExchangeRatesService(), new RealtimeService(), await createTestUnitOfWork(promptDbs().connection), ...(await budgetRepoArgs(promptDbs().connection))),
|
||||
new ExchangeRatesService(),
|
||||
promptDbs(),
|
||||
new RuntimeEnvService(),
|
||||
new TripMembershipService(await createTestTripsRepo(promptDbs().connection), await createTestTripMembersRepo(promptDbs().connection)),
|
||||
addonsStub,
|
||||
@@ -165,6 +164,7 @@ beforeAll(async () => {
|
||||
await createTestPlacesRepo(promptDbs().connection),
|
||||
await createTestTripsRepo(promptDbs().connection),
|
||||
new DemoService(new RuntimeEnvService(), promptEm),
|
||||
await createTestTripMembersRepo(promptDbs().connection),
|
||||
);
|
||||
tripPromptsMcp = new TripPromptsMcp(tripsStub, readModelStub, promptPackingService, addonsStub);
|
||||
});
|
||||
|
||||
@@ -128,7 +128,7 @@ let auditLogRepo: AuditLogRepository;
|
||||
beforeAll(async () => {
|
||||
webauthn = new WebauthnConfigService(await createTestAppSettingsRepo(dbs.connection));
|
||||
permissions = new PermissionsService(await createTestAppSettingsRepo(dbs.connection), await createTestUnitOfWork(dbs.connection));
|
||||
userCleanup = new UserCleanupService(dbs, new BudgetService(dbs, permissions, new ExchangeRatesService(), realtime, await createTestUnitOfWork(dbs.connection), ...(await budgetRepoArgs(dbs.connection))), await createTestUnitOfWork(dbs.connection), await createTestUsersRepo(dbs.connection), await createTestTripMembersRepo(dbs.connection), await createTestBudgetItemsRepo(dbs.connection), await createTestJourneyShareTokensRepo(dbs.connection), await createTestJourneysRepo(dbs.connection), await createTestJourneyEntriesRepo(dbs.connection), await createTestJourneyContributorsRepo(dbs.connection), await createTestShareTokensRepo(dbs.connection));
|
||||
userCleanup = new UserCleanupService(dbs, new BudgetService(permissions, new ExchangeRatesService(), realtime, await createTestUnitOfWork(dbs.connection), ...(await budgetRepoArgs(dbs.connection))), await createTestUnitOfWork(dbs.connection), await createTestUsersRepo(dbs.connection), await createTestTripMembersRepo(dbs.connection), await createTestBudgetItemsRepo(dbs.connection), await createTestJourneyShareTokensRepo(dbs.connection), await createTestJourneysRepo(dbs.connection), await createTestJourneyEntriesRepo(dbs.connection), await createTestJourneyContributorsRepo(dbs.connection), await createTestShareTokensRepo(dbs.connection));
|
||||
auth = new AuthService(
|
||||
permissions, new TripMembershipService(await createTestTripsRepo(dbs.connection), await createTestTripMembersRepo(dbs.connection)), webauthn, userCleanup, new MailerService(await createTestUsersRepo(dbs.connection), await createTestSettingsRepo(dbs.connection), await createTestAppSettingsRepo(dbs.connection)), new EphemeralTokenService(), new AllowedFileTypesService(await createTestAppSettingsRepo(dbs.connection)), await createTestUnitOfWork(dbs.connection),
|
||||
await createTestAppSettingsRepo(dbs.connection), await createTestUsersRepo(dbs.connection), await createTestInviteTokensRepo(dbs.connection), await createTestMcpTokensRepo(dbs.connection),
|
||||
|
||||
@@ -103,7 +103,7 @@ let svc: AdminService;
|
||||
beforeAll(async () => {
|
||||
webauthn = new WebauthnConfigService(await createTestAppSettingsRepo(dbs.connection));
|
||||
permissions = new PermissionsService(await createTestAppSettingsRepo(dbs.connection), await createTestUnitOfWork(dbs.connection));
|
||||
userCleanup = new UserCleanupService(dbs, new BudgetService(dbs, permissions, new ExchangeRatesService(), realtime, await createTestUnitOfWork(dbs.connection), ...(await budgetRepoArgs(dbs.connection))), await createTestUnitOfWork(dbs.connection), await createTestUsersRepo(dbs.connection), await createTestTripMembersRepo(dbs.connection), await createTestBudgetItemsRepo(dbs.connection), await createTestJourneyShareTokensRepo(dbs.connection), await createTestJourneysRepo(dbs.connection), await createTestJourneyEntriesRepo(dbs.connection), await createTestJourneyContributorsRepo(dbs.connection), await createTestShareTokensRepo(dbs.connection));
|
||||
userCleanup = new UserCleanupService(dbs, new BudgetService(permissions, new ExchangeRatesService(), realtime, await createTestUnitOfWork(dbs.connection), ...(await budgetRepoArgs(dbs.connection))), await createTestUnitOfWork(dbs.connection), await createTestUsersRepo(dbs.connection), await createTestTripMembersRepo(dbs.connection), await createTestBudgetItemsRepo(dbs.connection), await createTestJourneyShareTokensRepo(dbs.connection), await createTestJourneysRepo(dbs.connection), await createTestJourneyEntriesRepo(dbs.connection), await createTestJourneyContributorsRepo(dbs.connection), await createTestShareTokensRepo(dbs.connection));
|
||||
auth = new AuthService(
|
||||
permissions, new TripMembershipService(await createTestTripsRepo(dbs.connection), await createTestTripMembersRepo(dbs.connection)), webauthn, userCleanup, new MailerService(await createTestUsersRepo(dbs.connection), await createTestSettingsRepo(dbs.connection), await createTestAppSettingsRepo(dbs.connection)), new EphemeralTokenService(), new AllowedFileTypesService(await createTestAppSettingsRepo(dbs.connection)), await createTestUnitOfWork(dbs.connection),
|
||||
await createTestAppSettingsRepo(dbs.connection), await createTestUsersRepo(dbs.connection), await createTestInviteTokensRepo(dbs.connection), await createTestMcpTokensRepo(dbs.connection),
|
||||
|
||||
@@ -117,7 +117,7 @@ beforeAll(async () => {
|
||||
new PermissionsService(await createTestAppSettingsRepo(testDb), await createTestUnitOfWork(testDb)),
|
||||
membershipStub,
|
||||
new WebauthnConfigService(await createTestAppSettingsRepo(testDb)),
|
||||
new UserCleanupService(new DatabaseService(testDb), new BudgetService(new DatabaseService(testDb), new PermissionsService(await createTestAppSettingsRepo(testDb), await createTestUnitOfWork(testDb)), new ExchangeRatesService(), new RealtimeService(), await createTestUnitOfWork(testDb), ...(await budgetRepoArgs(testDb))), await createTestUnitOfWork(testDb), await createTestUsersRepo(testDb), await createTestTripMembersRepo(testDb), await createTestBudgetItemsRepo(testDb), await createTestJourneyShareTokensRepo(testDb), await createTestJourneysRepo(testDb), await createTestJourneyEntriesRepo(testDb), await createTestJourneyContributorsRepo(testDb), await createTestShareTokensRepo(testDb)),
|
||||
new UserCleanupService(new DatabaseService(testDb), new BudgetService(new PermissionsService(await createTestAppSettingsRepo(testDb), await createTestUnitOfWork(testDb)), new ExchangeRatesService(), new RealtimeService(), await createTestUnitOfWork(testDb), ...(await budgetRepoArgs(testDb))), await createTestUnitOfWork(testDb), await createTestUsersRepo(testDb), await createTestTripMembersRepo(testDb), await createTestBudgetItemsRepo(testDb), await createTestJourneyShareTokensRepo(testDb), await createTestJourneysRepo(testDb), await createTestJourneyEntriesRepo(testDb), await createTestJourneyContributorsRepo(testDb), await createTestShareTokensRepo(testDb)),
|
||||
mailerStub,
|
||||
new EphemeralTokenService(),
|
||||
new AllowedFileTypesService(await createTestAppSettingsRepo(testDb)), await createTestUnitOfWork(testDb),
|
||||
|
||||
@@ -41,7 +41,6 @@ vi.mock('../../../src/websocket', () => ({ broadcast: vi.fn() }));
|
||||
const mockRates = { getRates: vi.fn() };
|
||||
|
||||
import { BudgetService } from '../../../src/nest/budget/budget.service';
|
||||
import { DatabaseService } from '../../../src/nest/database/database.service';
|
||||
import type { PermissionsService } from '../../../src/nest/permissions/permissions.service';
|
||||
import type { ExchangeRatesService } from '../../../src/nest/budget/exchange-rates.service';
|
||||
import type { BudgetItem, BudgetItemMember, BudgetItemPayer } from '../../../src/types';
|
||||
@@ -105,7 +104,6 @@ const tripsRepoStub = {
|
||||
} as unknown as import('../../../src/db/repositories/Trips.repository').TripsRepository;
|
||||
|
||||
const budget = new BudgetService(
|
||||
new DatabaseService(mockDb.db as unknown as Database.Database),
|
||||
permissionsStub,
|
||||
mockRates as unknown as ExchangeRatesService,
|
||||
new RealtimeService(),
|
||||
@@ -118,6 +116,7 @@ const budget = new BudgetService(
|
||||
{} as unknown as import('../../../src/db/repositories/Reservations.repository').ReservationsRepository,
|
||||
{} as unknown as import('../../../src/db/repositories/Places.repository').PlacesRepository,
|
||||
tripsRepoStub,
|
||||
{} as unknown as import('../../../src/db/repositories/TripMembers.repository').TripMembersRepository,
|
||||
);
|
||||
|
||||
// ── Helpers ──────────────────────────────────────────────────────────────────
|
||||
|
||||
@@ -105,7 +105,6 @@ beforeAll(async () => {
|
||||
budgetItemPayersRepoDirect = await createTestBudgetItemPayersRepo(testDb);
|
||||
budgetSettlementsRepoDirect = await createTestBudgetSettlementsRepo(testDb);
|
||||
budget = new BudgetService(
|
||||
dbs(),
|
||||
new PermissionsService(await createTestAppSettingsRepo(testDb), await createTestUnitOfWork(testDb)),
|
||||
new ExchangeRatesService(),
|
||||
new RealtimeService(),
|
||||
|
||||
@@ -22,8 +22,6 @@ vi.mock('../../../src/db/database', () => ({
|
||||
getPlaceWithTags: () => null,
|
||||
isOwner: () => false,
|
||||
}));
|
||||
import { db as dbConn } from '../../../src/db/database';
|
||||
import { DatabaseService } from '../../../src/nest/database/database.service';
|
||||
import type { PermissionsService } from '../../../src/nest/permissions/permissions.service';
|
||||
|
||||
const { broadcast } = vi.hoisted(() => ({ broadcast: vi.fn() }));
|
||||
@@ -48,6 +46,7 @@ import type { BudgetCategoryOrderRepository } from '../../../src/db/repositories
|
||||
import type { ReservationsRepository } from '../../../src/db/repositories/Reservations.repository';
|
||||
import type { PlacesRepository } from '../../../src/db/repositories/Places.repository';
|
||||
import type { TripsRepository } from '../../../src/db/repositories/Trips.repository';
|
||||
import type { TripMembersRepository } from '../../../src/db/repositories/TripMembers.repository';
|
||||
|
||||
/**
|
||||
* There is no database behind this suite — every statement is served by the
|
||||
@@ -73,9 +72,12 @@ const reservationsRepoStub = {
|
||||
getFull: async (id: number) => dbMock.prepare().get(id),
|
||||
} as unknown as ReservationsRepository;
|
||||
|
||||
function svc(db: DatabaseService = new DatabaseService(dbConn), tripsRepo: TripsRepository = {} as unknown as TripsRepository) {
|
||||
function svc(
|
||||
tripMembersRepo: TripMembersRepository = {} as unknown as TripMembersRepository,
|
||||
tripsRepo: TripsRepository = {} as unknown as TripsRepository,
|
||||
) {
|
||||
return new BudgetService(
|
||||
db, permissionsStub, exchangeRatesStub, new RealtimeService(), uowStub,
|
||||
permissionsStub, exchangeRatesStub, new RealtimeService(), uowStub,
|
||||
{} as unknown as BudgetItemsRepository,
|
||||
{} as unknown as BudgetItemMembersRepository,
|
||||
{} as unknown as BudgetItemPayersRepository,
|
||||
@@ -84,6 +86,7 @@ function svc(db: DatabaseService = new DatabaseService(dbConn), tripsRepo: Trips
|
||||
reservationsRepoStub,
|
||||
{} as unknown as PlacesRepository,
|
||||
tripsRepo,
|
||||
tripMembersRepo,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -191,17 +194,13 @@ describe('BudgetService', () => {
|
||||
// anything, so the roster lookup has to answer for these to reach the write
|
||||
// at all. Users 1 and 2 are the two parties every case here settles between.
|
||||
//
|
||||
// Plan 3c Task 0b: `DatabaseService.rosterUserIds` is `TripMembersRepository
|
||||
// .rosterUserIds` now (not `this.conn`/the `dbMock._stmt.all` prepare stub,
|
||||
// which no longer intercepts it) — a real `DatabaseService` (so its other
|
||||
// methods, still served by the `dbMock._stmt` prepare stub, keep working)
|
||||
// with `rosterUserIds` spied directly, same fix as `verifyTripAccess`'s
|
||||
// Plan 4 Task 3: `DatabaseService.rosterUserIds` inlined onto
|
||||
// `TripMembersRepository.rosterUserIds` directly — a stub repository
|
||||
// with `rosterUserIds` mocked directly, same fix as `verifyTripAccess`'s
|
||||
// test above.
|
||||
const rosterHas = (...userIds: number[]) => {
|
||||
const db = new DatabaseService(dbConn);
|
||||
vi.spyOn(db, 'rosterUserIds').mockResolvedValue(new Set(userIds));
|
||||
return db;
|
||||
};
|
||||
const rosterHas = (...userIds: number[]) => ({
|
||||
rosterUserIds: vi.fn().mockResolvedValue(new Set(userIds)),
|
||||
} as unknown as TripMembersRepository);
|
||||
|
||||
it('createSettlement freezes the FX rate (await) before the raw insert', async () => {
|
||||
const s = svc(rosterHas(1, 2));
|
||||
|
||||
@@ -64,7 +64,7 @@ const dbs = () => new DatabaseService(testDb);
|
||||
let budgetSvc: BudgetService;
|
||||
let svc: CalendarService;
|
||||
beforeAll(async () => {
|
||||
budgetSvc = new BudgetService(dbs(), new PermissionsService(await createTestAppSettingsRepo(dbs().connection), await createTestUnitOfWork(dbs().connection)), new ExchangeRatesService(), new RealtimeService(), await createTestUnitOfWork(dbs().connection), ...(await budgetRepoArgs(dbs().connection)));
|
||||
budgetSvc = new BudgetService(new PermissionsService(await createTestAppSettingsRepo(dbs().connection), await createTestUnitOfWork(dbs().connection)), new ExchangeRatesService(), new RealtimeService(), await createTestUnitOfWork(dbs().connection), ...(await budgetRepoArgs(dbs().connection)));
|
||||
svc = new CalendarService(
|
||||
new ReservationsService(new PermissionsService(await createTestAppSettingsRepo(dbs().connection), await createTestUnitOfWork(dbs().connection)), budgetSvc, new RealtimeService(), notificationsStub(), new ReservationsReadService(await createTestReservationsRepo(dbs().connection), await createTestReservationEndpointsRepo(dbs().connection), await createTestReservationTravelersRepo(dbs().connection)), await accommodationsOver(dbs()), await createTestUnitOfWork(dbs().connection), await createTestReservationsRepo(dbs().connection), await createTestReservationEndpointsRepo(dbs().connection), await createTestReservationTravelersRepo(dbs().connection), await createTestReservationDayPositionsRepo(dbs().connection), await createTestDayAccommodationsRepo(dbs().connection), await createTestDaysRepo(dbs().connection), await createTestPlacesRepo(dbs().connection), await createTestDayAssignmentsRepo(dbs().connection), await createTestTripMembersRepo(dbs().connection), await createTestUsersRepo(dbs().connection), await createTestTripsRepo(dbs().connection), await createTestBudgetItemsRepo(dbs().connection)),
|
||||
await createTestTripsRepo(dbs().connection), await createTestDaysRepo(dbs().connection), await createTestDayNotesRepo(dbs().connection), await createTestReservationsRepo(dbs().connection),
|
||||
|
||||
@@ -49,7 +49,7 @@ describe('Plan 3i Task 3 — isDemoUserId survivor sites: exact refusal body per
|
||||
});
|
||||
|
||||
it('DEMO-SURVIVOR-004 (budget.mcp.ts): create_budget_item refuses byte-for-byte in demo mode', async () => {
|
||||
const mcp = new BudgetMcp(stub, stub, stub, stub, stub, stub, stub, stub, stub, stub, demoBlocked);
|
||||
const mcp = new BudgetMcp(stub, stub, stub, stub, stub, stub, stub, stub, stub, demoBlocked, stub);
|
||||
const res = await mcp.createBudgetItem({ tripId: 1, name: 'Test', total_price: 10 }, ctx);
|
||||
expect(res).toEqual(DEMO_REFUSAL);
|
||||
});
|
||||
|
||||
@@ -138,7 +138,7 @@ beforeAll(async () => {
|
||||
new PermissionsService(await createTestAppSettingsRepo(testDb), await createTestUnitOfWork(testDb)),
|
||||
membership,
|
||||
new WebauthnConfigService(await createTestAppSettingsRepo(testDb)),
|
||||
new UserCleanupService(new DatabaseService(testDb), new BudgetService(new DatabaseService(testDb), new PermissionsService(await createTestAppSettingsRepo(testDb), await createTestUnitOfWork(testDb)), new ExchangeRatesService(), new RealtimeService(), await createTestUnitOfWork(testDb), ...(await budgetRepoArgs(testDb))), await createTestUnitOfWork(testDb), await createTestUsersRepo(testDb), await createTestTripMembersRepo(testDb), await createTestBudgetItemsRepo(testDb), await createTestJourneyShareTokensRepo(testDb), await createTestJourneysRepo(testDb), await createTestJourneyEntriesRepo(testDb), await createTestJourneyContributorsRepo(testDb), await createTestShareTokensRepo(testDb)),
|
||||
new UserCleanupService(new DatabaseService(testDb), new BudgetService(new PermissionsService(await createTestAppSettingsRepo(testDb), await createTestUnitOfWork(testDb)), new ExchangeRatesService(), new RealtimeService(), await createTestUnitOfWork(testDb), ...(await budgetRepoArgs(testDb))), await createTestUnitOfWork(testDb), await createTestUsersRepo(testDb), await createTestTripMembersRepo(testDb), await createTestBudgetItemsRepo(testDb), await createTestJourneyShareTokensRepo(testDb), await createTestJourneysRepo(testDb), await createTestJourneyEntriesRepo(testDb), await createTestJourneyContributorsRepo(testDb), await createTestShareTokensRepo(testDb)),
|
||||
mailerStub,
|
||||
new EphemeralTokenService(),
|
||||
new AllowedFileTypesService(await createTestAppSettingsRepo(testDb)), await createTestUnitOfWork(testDb),
|
||||
|
||||
@@ -132,7 +132,7 @@ beforeAll(async () => {
|
||||
new PermissionsService(await createTestAppSettingsRepo(testDb), await createTestUnitOfWork(testDb)),
|
||||
new TripMembershipService(await createTestTripsRepo(testDb), await createTestTripMembersRepo(testDb)),
|
||||
new WebauthnConfigService(await createTestAppSettingsRepo(testDb)),
|
||||
new UserCleanupService(new DatabaseService(testDb), new BudgetService(new DatabaseService(testDb), new PermissionsService(await createTestAppSettingsRepo(testDb), await createTestUnitOfWork(testDb)), new ExchangeRatesService(), new RealtimeService(), await createTestUnitOfWork(testDb), ...(await budgetRepoArgs(testDb))), await createTestUnitOfWork(testDb), await createTestUsersRepo(testDb), await createTestTripMembersRepo(testDb), await createTestBudgetItemsRepo(testDb), await createTestJourneyShareTokensRepo(testDb), await createTestJourneysRepo(testDb), await createTestJourneyEntriesRepo(testDb), await createTestJourneyContributorsRepo(testDb), await createTestShareTokensRepo(testDb)),
|
||||
new UserCleanupService(new DatabaseService(testDb), new BudgetService(new PermissionsService(await createTestAppSettingsRepo(testDb), await createTestUnitOfWork(testDb)), new ExchangeRatesService(), new RealtimeService(), await createTestUnitOfWork(testDb), ...(await budgetRepoArgs(testDb))), await createTestUnitOfWork(testDb), await createTestUsersRepo(testDb), await createTestTripMembersRepo(testDb), await createTestBudgetItemsRepo(testDb), await createTestJourneyShareTokensRepo(testDb), await createTestJourneysRepo(testDb), await createTestJourneyEntriesRepo(testDb), await createTestJourneyContributorsRepo(testDb), await createTestShareTokensRepo(testDb)),
|
||||
mailerStub,
|
||||
new EphemeralTokenService(),
|
||||
new AllowedFileTypesService(await createTestAppSettingsRepo(testDb)), await createTestUnitOfWork(testDb),
|
||||
|
||||
@@ -41,11 +41,10 @@ vi.mock('../../../src/websocket', () => ({ broadcast: vi.fn() }));
|
||||
import { db as testDb } from '../../../src/db/database';
|
||||
import { resetTestDb } from '../../helpers/test-db';
|
||||
import { createUser, createTrip, addTripMember } from '../../helpers/factories';
|
||||
import { DatabaseService } from '../../../src/nest/database/database.service';
|
||||
import { PermissionsService } from '../../../src/nest/permissions/permissions.service';
|
||||
import { TodoService } from '../../../src/nest/todo/todo.service';
|
||||
import { RealtimeService } from '../../../src/nest/realtime/realtime.service';
|
||||
import { createTestUnitOfWork, createTestAppSettingsRepo, createTestDatabaseService, createTestTripsRepo } from '../../helpers/test-uow';
|
||||
import { createTestUnitOfWork, createTestAppSettingsRepo, createTestTripsRepo, createTestTripMembersRepo } from '../../helpers/test-uow';
|
||||
import { createTestTodoItemsRepo, createTestTodoCategoryAssigneesRepo } from '../../helpers/todo-repos';
|
||||
|
||||
let svc: TodoService;
|
||||
@@ -54,11 +53,14 @@ beforeAll(async () => {
|
||||
const uow = await createTestUnitOfWork(testDb);
|
||||
todoItemsRepoDirect = await createTestTodoItemsRepo(testDb);
|
||||
svc = new TodoService(
|
||||
await createTestDatabaseService(testDb), new PermissionsService(await createTestAppSettingsRepo(testDb), uow), new RealtimeService(), uow,
|
||||
new PermissionsService(await createTestAppSettingsRepo(testDb), uow), new RealtimeService(), uow,
|
||||
todoItemsRepoDirect, await createTestTodoCategoryAssigneesRepo(testDb),
|
||||
// Plan 4 Task 2 — TodoService's own canAccessTrip delegate is now
|
||||
// TripsRepository.findAccessible, a new trailing constructor param.
|
||||
await createTestTripsRepo(testDb),
|
||||
// Plan 4 Task 3 — DatabaseService.rosterUserIds inlined onto
|
||||
// TripMembersRepository.rosterUserIds directly.
|
||||
await createTestTripMembersRepo(testDb),
|
||||
);
|
||||
});
|
||||
|
||||
@@ -397,9 +399,9 @@ describe('TodoService.canEdit', () => {
|
||||
const checkPermission = vi.fn(() => true);
|
||||
const permissions = { checkPermission } as unknown as PermissionsService;
|
||||
const withStub = new TodoService(
|
||||
new DatabaseService(testDb), permissions, new RealtimeService(), await createTestUnitOfWork(testDb),
|
||||
permissions, new RealtimeService(), await createTestUnitOfWork(testDb),
|
||||
await createTestTodoItemsRepo(testDb), await createTestTodoCategoryAssigneesRepo(testDb),
|
||||
await createTestTripsRepo(testDb),
|
||||
await createTestTripsRepo(testDb), await createTestTripMembersRepo(testDb),
|
||||
);
|
||||
const trip = { id: 1, user_id: 1 } as never;
|
||||
|
||||
|
||||
@@ -96,7 +96,7 @@ beforeAll(async () => {
|
||||
tripsRepo = await createTestTripsRepo(testDb);
|
||||
usersRepo = await createTestUsersRepo(testDb);
|
||||
tripMembersRepo = await createTestTripMembersRepo(testDb);
|
||||
budgetSvc = new BudgetService(dbs(), new PermissionsService(await createTestAppSettingsRepo(dbs().connection), await createTestUnitOfWork(dbs().connection)), new ExchangeRatesService(), new RealtimeService(), await createTestUnitOfWork(dbs().connection), ...(await budgetRepoArgs(dbs().connection)));
|
||||
budgetSvc = new BudgetService(new PermissionsService(await createTestAppSettingsRepo(dbs().connection), await createTestUnitOfWork(dbs().connection)), new ExchangeRatesService(), new RealtimeService(), await createTestUnitOfWork(dbs().connection), ...(await budgetRepoArgs(dbs().connection)));
|
||||
roster = new TripMembersService(
|
||||
budgetSvc,
|
||||
new UserCleanupService(dbs(), budgetSvc, await createTestUnitOfWork(dbs().connection), usersRepo, await createTestTripMembersRepo(dbs().connection), await createTestBudgetItemsRepo(dbs().connection), await createTestJourneyShareTokensRepo(dbs().connection), await createTestJourneysRepo(dbs().connection), await createTestJourneyEntriesRepo(dbs().connection), await createTestJourneyContributorsRepo(dbs().connection), await createTestShareTokensRepo(dbs().connection)),
|
||||
|
||||
@@ -136,7 +136,7 @@ beforeAll(async () => {
|
||||
await createTestPlacesRepo(dbs().connection),
|
||||
await createTestCollectionPlacesRepo(dbs().connection),
|
||||
);
|
||||
budgetSvc = new BudgetService(dbs(), new PermissionsService(await createTestAppSettingsRepo(dbs().connection), await createTestUnitOfWork(dbs().connection)), new ExchangeRatesService(), new RealtimeService(), await createTestUnitOfWork(dbs().connection), ...(await budgetRepoArgs(dbs().connection)));
|
||||
budgetSvc = new BudgetService(new PermissionsService(await createTestAppSettingsRepo(dbs().connection), await createTestUnitOfWork(dbs().connection)), new ExchangeRatesService(), new RealtimeService(), await createTestUnitOfWork(dbs().connection), ...(await budgetRepoArgs(dbs().connection)));
|
||||
daysSvc = new DaysService(
|
||||
new PermissionsService(await createTestAppSettingsRepo(dbs().connection), await createTestUnitOfWork(dbs().connection)),
|
||||
new RealtimeService(),
|
||||
@@ -196,11 +196,14 @@ const buildReadModel = async (tripsRepo: TripsRepository, roster: TripMembersSer
|
||||
),
|
||||
placesSvc,
|
||||
new TodoService(
|
||||
dbs(), new PermissionsService(await createTestAppSettingsRepo(dbs().connection), await createTestUnitOfWork(dbs().connection)), new RealtimeService(), await createTestUnitOfWork(dbs().connection),
|
||||
new PermissionsService(await createTestAppSettingsRepo(dbs().connection), await createTestUnitOfWork(dbs().connection)), new RealtimeService(), await createTestUnitOfWork(dbs().connection),
|
||||
await createTestTodoItemsRepo(dbs().connection), await createTestTodoCategoryAssigneesRepo(dbs().connection),
|
||||
// Plan 4 Task 2 — TodoService's own canAccessTrip delegate is now
|
||||
// TripsRepository.findAccessible, a new trailing constructor param.
|
||||
await createTestTripsRepo(dbs().connection),
|
||||
// Plan 4 Task 3 — DatabaseService.rosterUserIds inlined onto
|
||||
// TripMembersRepository.rosterUserIds directly.
|
||||
await createTestTripMembersRepo(dbs().connection),
|
||||
),
|
||||
new FilesService(
|
||||
// Plan 4 Task 2 — FilesService's own canAccessTrip delegate is now
|
||||
|
||||
@@ -173,7 +173,7 @@ beforeAll(async () => {
|
||||
await createTestPlacesRepo(dbs().connection),
|
||||
await createTestCollectionPlacesRepo(dbs().connection),
|
||||
);
|
||||
budgetSvc = new BudgetService(dbs(), new PermissionsService(await createTestAppSettingsRepo(dbs().connection), await createTestUnitOfWork(dbs().connection)), new ExchangeRatesService(), new RealtimeService(), await createTestUnitOfWork(dbs().connection), ...(await budgetRepoArgs(dbs().connection)));
|
||||
budgetSvc = new BudgetService(new PermissionsService(await createTestAppSettingsRepo(dbs().connection), await createTestUnitOfWork(dbs().connection)), new ExchangeRatesService(), new RealtimeService(), await createTestUnitOfWork(dbs().connection), ...(await budgetRepoArgs(dbs().connection)));
|
||||
daysSvc = new DaysService(
|
||||
new PermissionsService(await createTestAppSettingsRepo(dbs().connection), await createTestUnitOfWork(dbs().connection)),
|
||||
new RealtimeService(),
|
||||
@@ -255,9 +255,10 @@ beforeAll(async () => {
|
||||
),
|
||||
placesSvc,
|
||||
new TodoService(
|
||||
dbs(), new PermissionsService(await createTestAppSettingsRepo(dbs().connection), await createTestUnitOfWork(dbs().connection)), new RealtimeService(), await createTestUnitOfWork(dbs().connection),
|
||||
new PermissionsService(await createTestAppSettingsRepo(dbs().connection), await createTestUnitOfWork(dbs().connection)), new RealtimeService(), await createTestUnitOfWork(dbs().connection),
|
||||
await createTestTodoItemsRepo(dbs().connection), await createTestTodoCategoryAssigneesRepo(dbs().connection),
|
||||
await createTestTripsRepo(dbs().connection),
|
||||
await createTestTripMembersRepo(dbs().connection),
|
||||
),
|
||||
new FilesService(
|
||||
// Plan 4 Task 2 — FilesService's own canAccessTrip delegate is now
|
||||
|
||||
@@ -76,7 +76,7 @@ beforeAll(async () => {
|
||||
vi.spyOn(dbs, 'isOwner').mockImplementation((...a) => real.isOwner(...a));
|
||||
vi.spyOn(dbs, 'rosterUserIds').mockImplementation((...a) => real.rosterUserIds(...a));
|
||||
vi.spyOn(dbs, 'getPlaceWithTags').mockImplementation((...a) => real.getPlaceWithTags(...a));
|
||||
budget = new BudgetService(dbs, new PermissionsService(await createTestAppSettingsRepo(dbs.connection), await createTestUnitOfWork(dbs.connection)), new ExchangeRatesService(), new RealtimeService(), await createTestUnitOfWork(dbs.connection), ...(await budgetRepoArgs(dbs.connection)));
|
||||
budget = new BudgetService(new PermissionsService(await createTestAppSettingsRepo(dbs.connection), await createTestUnitOfWork(dbs.connection)), new ExchangeRatesService(), new RealtimeService(), await createTestUnitOfWork(dbs.connection), ...(await budgetRepoArgs(dbs.connection)));
|
||||
svc = new UserCleanupService(
|
||||
dbs, budget, await createTestUnitOfWork(dbs.connection), await createTestUsersRepo(dbs.connection),
|
||||
// Plan 4 Task 1 constructor-ripple: UC4's repository.
|
||||
|
||||
@@ -44,7 +44,7 @@ async function makeImportService(): Promise<AirtrailImportService> {
|
||||
realtime,
|
||||
new ReservationsService(
|
||||
permissions,
|
||||
new BudgetService(dbs(), permissions, new ExchangeRatesService(), realtime, await createTestUnitOfWork(dbs().connection), ...(await budgetRepoArgs(dbs().connection))),
|
||||
new BudgetService(permissions, new ExchangeRatesService(), realtime, await createTestUnitOfWork(dbs().connection), ...(await budgetRepoArgs(dbs().connection))),
|
||||
realtime,
|
||||
notificationsStub(),
|
||||
new ReservationsReadService(await createTestReservationsRepo(dbs().connection), await createTestReservationEndpointsRepo(dbs().connection), await createTestReservationTravelersRepo(dbs().connection)),
|
||||
|
||||
Reference in New Issue
Block a user