144 lines
4.7 KiB
TypeScript
144 lines
4.7 KiB
TypeScript
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
import { CabinetEventsService } from '../../../src/modules/cabinet-events/cabinet-events.service.js';
|
|
|
|
describe(CabinetEventsService.name, () => {
|
|
const mockCabinetEventsRepo = {
|
|
create: vi.fn(),
|
|
createMany: vi.fn(),
|
|
findByHousehold: vi.fn(),
|
|
findByCabinetItem: vi.fn(),
|
|
getSpendingSummary: vi.fn(),
|
|
getAvgUnitPriceByMedicine: vi.fn(),
|
|
};
|
|
|
|
let service: CabinetEventsService;
|
|
|
|
const baseEventData = {
|
|
householdId: 'hh1',
|
|
userId: 'user-1',
|
|
cabinetItemId: 'ci-1',
|
|
medicineId: 'med-1',
|
|
medicineName: 'Metformin',
|
|
eventType: 'purchased' as const,
|
|
quantity: 10,
|
|
quantityBefore: 0,
|
|
quantityAfter: 10,
|
|
sourceType: 'manual' as const,
|
|
};
|
|
|
|
beforeEach(() => {
|
|
vi.clearAllMocks();
|
|
service = new CabinetEventsService({
|
|
cabinetEventsRepository: mockCabinetEventsRepo as never,
|
|
});
|
|
});
|
|
|
|
describe('logEvent', () => {
|
|
it('delegates to repository create', async () => {
|
|
const created = { _id: 'ev-1', ...baseEventData };
|
|
mockCabinetEventsRepo.create.mockResolvedValue(created);
|
|
|
|
const result = await service.logEvent(baseEventData);
|
|
|
|
expect(result).toEqual(created);
|
|
expect(mockCabinetEventsRepo.create).toHaveBeenCalledWith(baseEventData);
|
|
});
|
|
});
|
|
|
|
describe('logEvents', () => {
|
|
it('delegates to repository createMany', async () => {
|
|
const events = [baseEventData, { ...baseEventData, quantity: 5 }];
|
|
const inserted = events.map((e, i) => ({ _id: `ev-${i}`, ...e }));
|
|
mockCabinetEventsRepo.createMany.mockResolvedValue(inserted);
|
|
|
|
const result = await service.logEvents(events);
|
|
|
|
expect(result).toEqual(inserted);
|
|
expect(mockCabinetEventsRepo.createMany).toHaveBeenCalledWith(events);
|
|
});
|
|
|
|
it('returns empty array for empty input without calling repository', async () => {
|
|
const result = await service.logEvents([]);
|
|
|
|
expect(result).toEqual([]);
|
|
expect(mockCabinetEventsRepo.createMany).not.toHaveBeenCalled();
|
|
});
|
|
});
|
|
|
|
describe('listEvents', () => {
|
|
it('delegates to repository findByHousehold', async () => {
|
|
const expected = {
|
|
data: [{ _id: 'ev-1' }],
|
|
pagination: { cursor: null, hasMore: false },
|
|
};
|
|
mockCabinetEventsRepo.findByHousehold.mockResolvedValue(expected);
|
|
|
|
const query = { limit: 20 };
|
|
const result = await service.listEvents('hh1', query);
|
|
|
|
expect(result).toEqual(expected);
|
|
expect(mockCabinetEventsRepo.findByHousehold).toHaveBeenCalledWith('hh1', query);
|
|
});
|
|
});
|
|
|
|
describe('getEventsByItem', () => {
|
|
it('delegates to repository findByCabinetItem', async () => {
|
|
const expected = {
|
|
data: [{ _id: 'ev-1', cabinetItemId: 'ci-1' }],
|
|
pagination: { cursor: null, hasMore: false },
|
|
};
|
|
mockCabinetEventsRepo.findByCabinetItem.mockResolvedValue(expected);
|
|
|
|
const query = { limit: 20 };
|
|
const result = await service.getEventsByItem('hh1', 'ci-1', query);
|
|
|
|
expect(result).toEqual(expected);
|
|
expect(mockCabinetEventsRepo.findByCabinetItem).toHaveBeenCalledWith('hh1', 'ci-1', query);
|
|
});
|
|
|
|
it('passes cursor through to repository', async () => {
|
|
const expected = {
|
|
data: [],
|
|
pagination: { cursor: null, hasMore: false },
|
|
};
|
|
mockCabinetEventsRepo.findByCabinetItem.mockResolvedValue(expected);
|
|
|
|
const query = { cursor: 'abc123', limit: 10 };
|
|
await service.getEventsByItem('hh1', 'ci-1', query);
|
|
|
|
expect(mockCabinetEventsRepo.findByCabinetItem).toHaveBeenCalledWith('hh1', 'ci-1', query);
|
|
});
|
|
});
|
|
|
|
describe('getSpendingSummary', () => {
|
|
it('delegates to repository getSpendingSummary', async () => {
|
|
const expected = {
|
|
totalSpent: 100,
|
|
currency: 'USD',
|
|
byMedicine: [],
|
|
byPeriod: [],
|
|
};
|
|
mockCabinetEventsRepo.getSpendingSummary.mockResolvedValue(expected);
|
|
|
|
const query = { period: 'month' as const };
|
|
const result = await service.getSpendingSummary('hh1', query);
|
|
|
|
expect(result).toEqual(expected);
|
|
expect(mockCabinetEventsRepo.getSpendingSummary).toHaveBeenCalledWith('hh1', query);
|
|
});
|
|
});
|
|
|
|
describe('getAvgUnitPrices', () => {
|
|
it('delegates to repository getAvgUnitPriceByMedicine', async () => {
|
|
const expected = new Map([['med-1', { avgUnitPrice: 10, currency: 'USD' }]]);
|
|
mockCabinetEventsRepo.getAvgUnitPriceByMedicine.mockResolvedValue(expected);
|
|
|
|
const result = await service.getAvgUnitPrices('hh1', ['med-1']);
|
|
|
|
expect(result).toEqual(expected);
|
|
expect(mockCabinetEventsRepo.getAvgUnitPriceByMedicine).toHaveBeenCalledWith('hh1', [
|
|
'med-1',
|
|
]);
|
|
});
|
|
});
|
|
});
|