mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-06-19 13:21:46 +00:00
7266ad99ae
* 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
89 lines
4.9 KiB
TypeScript
89 lines
4.9 KiB
TypeScript
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
|
|
const { dbMock } = vi.hoisted(() => {
|
|
const stmt = { get: vi.fn(() => ({ id: 42 })), all: vi.fn(() => []), run: vi.fn() };
|
|
return { dbMock: { prepare: vi.fn(() => stmt), _stmt: stmt } };
|
|
});
|
|
const { canAccessTrip } = vi.hoisted(() => ({ canAccessTrip: vi.fn(() => ({ user_id: 1 })) }));
|
|
vi.mock('../../../src/db/database', () => ({ db: dbMock, canAccessTrip, closeDb: () => {}, reinitialize: () => {} }));
|
|
|
|
const { broadcast } = vi.hoisted(() => ({ broadcast: vi.fn() }));
|
|
vi.mock('../../../src/websocket', () => ({ broadcast }));
|
|
const { checkPermission } = vi.hoisted(() => ({ checkPermission: vi.fn(() => true) }));
|
|
vi.mock('../../../src/services/permissions', () => ({ checkPermission }));
|
|
|
|
const { tripSvc } = vi.hoisted(() => ({
|
|
tripSvc: {
|
|
listTrips: vi.fn(), createTrip: vi.fn(), getTrip: vi.fn(), updateTrip: vi.fn(), deleteTrip: vi.fn(),
|
|
getTripRaw: vi.fn(), getTripOwner: vi.fn(), deleteOldCover: vi.fn(), updateCoverImage: vi.fn(),
|
|
listMembers: vi.fn(() => ({ owner: { id: 1 }, members: [] })), addMember: vi.fn(), removeMember: vi.fn(),
|
|
exportICS: vi.fn(), copyTripById: vi.fn(), TRIP_SELECT: 'SELECT * FROM trips t',
|
|
},
|
|
}));
|
|
vi.mock('../../../src/services/tripService', () => tripSvc);
|
|
vi.mock('../../../src/services/dayService', () => ({ listDays: () => ({ days: [1] }), listAccommodations: () => [] }));
|
|
vi.mock('../../../src/services/placeService', () => ({ listPlaces: () => [] }));
|
|
vi.mock('../../../src/services/packingService', () => ({ listItems: () => [] }));
|
|
vi.mock('../../../src/services/todoService', () => ({ listItems: () => [] }));
|
|
vi.mock('../../../src/services/budgetService', () => ({ listBudgetItems: () => [] }));
|
|
vi.mock('../../../src/services/reservationService', () => ({ listReservations: () => [] }));
|
|
vi.mock('../../../src/services/fileService', () => ({ listFiles: () => [] }));
|
|
|
|
import { TripsService } from '../../../src/nest/trips/trips.service';
|
|
|
|
function svc() { return new TripsService(); }
|
|
beforeEach(() => vi.clearAllMocks());
|
|
|
|
describe('TripsService (wrapper delegation + bundle/copy/notify helpers)', () => {
|
|
it('delegates the simple wrappers to tripService', () => {
|
|
const s = svc();
|
|
s.list(1, 0); expect(tripSvc.listTrips).toHaveBeenCalledWith(1, 0);
|
|
s.create(1, { title: 'T' } as never); expect(tripSvc.createTrip).toHaveBeenCalledWith(1, { title: 'T' });
|
|
s.get('9', 1); expect(tripSvc.getTrip).toHaveBeenCalledWith('9', 1);
|
|
s.getRaw('9'); expect(tripSvc.getTripRaw).toHaveBeenCalledWith('9');
|
|
s.getOwner('9'); expect(tripSvc.getTripOwner).toHaveBeenCalledWith('9');
|
|
s.update('9', 1, {} as never, 'user'); expect(tripSvc.updateTrip).toHaveBeenCalledWith('9', 1, {}, 'user');
|
|
s.remove('9', 1, 'user'); expect(tripSvc.deleteTrip).toHaveBeenCalledWith('9', 1, 'user');
|
|
s.deleteOldCover('/old.jpg'); expect(tripSvc.deleteOldCover).toHaveBeenCalledWith('/old.jpg');
|
|
s.updateCoverImage('9', '/n.jpg'); expect(tripSvc.updateCoverImage).toHaveBeenCalledWith('9', '/n.jpg');
|
|
s.copy('9', 1, 'C'); expect(tripSvc.copyTripById).toHaveBeenCalledWith('9', 1, 'C');
|
|
s.listMembers('9', 1); expect(tripSvc.listMembers).toHaveBeenCalledWith('9', 1);
|
|
s.addMember('9', 'b@x.y', 1, 1); expect(tripSvc.addMember).toHaveBeenCalledWith('9', 'b@x.y', 1, 1);
|
|
s.removeMember('9', 2); expect(tripSvc.removeMember).toHaveBeenCalledWith('9', 2);
|
|
s.exportICS('9'); expect(tripSvc.exportICS).toHaveBeenCalledWith('9');
|
|
});
|
|
|
|
it('canAccessTrip delegates to the db helper', () => {
|
|
canAccessTrip.mockReturnValueOnce({ user_id: 7 });
|
|
expect(svc().canAccessTrip('9', 7)).toEqual({ user_id: 7 });
|
|
expect(canAccessTrip).toHaveBeenCalledWith('9', 7);
|
|
});
|
|
|
|
it('can() delegates to checkPermission; broadcast forwards', () => {
|
|
svc().can('trip_edit', 'user', 1, 1, false);
|
|
expect(checkPermission).toHaveBeenCalledWith('trip_edit', 'user', 1, 1, false);
|
|
svc().broadcast('9', 'trip:updated', { a: 1 }, 'sock');
|
|
expect(broadcast).toHaveBeenCalledWith('9', 'trip:updated', { a: 1 }, 'sock');
|
|
});
|
|
|
|
it('getCopiedTrip re-reads via the TRIP_SELECT query', () => {
|
|
expect(svc().getCopiedTrip(42, 1)).toEqual({ id: 42 });
|
|
expect(dbMock.prepare).toHaveBeenCalledWith(expect.stringContaining('SELECT * FROM trips t'));
|
|
});
|
|
|
|
it('bundle aggregates every sub-collection + the member list', () => {
|
|
const result = svc().bundle('9', { user_id: 1 });
|
|
expect(result).toMatchObject({ trip: { user_id: 1 }, days: [1], places: [], members: [{ id: 1 }] });
|
|
});
|
|
|
|
it('bundle tolerates a null member list', () => {
|
|
tripSvc.listMembers.mockReturnValueOnce({ owner: { id: 1 }, members: null });
|
|
const result = svc().bundle('9', { user_id: 1 });
|
|
expect(result).toMatchObject({ members: [{ id: 1 }] });
|
|
});
|
|
|
|
it('notifyInvite is fire-and-forget (no throw)', () => {
|
|
expect(() => svc().notifyInvite('9', { id: 1, email: 'a@b.c' } as never, 2, 'T', 'b@x.y')).not.toThrow();
|
|
});
|
|
});
|