Tests refactor
This commit is contained in:
parent
245520fb50
commit
99134d8556
165 changed files with 911 additions and 531 deletions
|
|
@ -0,0 +1,181 @@
|
|||
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
||||
import { MedicinePricesService } from '../../../src/modules/medicine-prices/medicine-prices.service.js';
|
||||
|
||||
describe(MedicinePricesService.name, () => {
|
||||
const mockPricesRepo = {
|
||||
create: vi.fn(),
|
||||
findByMedicine: vi.fn(),
|
||||
compareStores: vi.fn(),
|
||||
getLatestForMedicine: vi.fn(),
|
||||
getAnalytics: vi.fn(),
|
||||
};
|
||||
const mockProductsRepo = {
|
||||
findById: vi.fn(),
|
||||
};
|
||||
const mockStoresRepo = {
|
||||
findById: vi.fn(),
|
||||
};
|
||||
|
||||
let service: MedicinePricesService;
|
||||
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
service = new MedicinePricesService({
|
||||
medicinePricesRepository: mockPricesRepo as never,
|
||||
medicineProductsRepository: mockProductsRepo as never,
|
||||
storesRepository: mockStoresRepo as never,
|
||||
});
|
||||
});
|
||||
|
||||
describe('recordPrice', () => {
|
||||
const validInput = {
|
||||
medicineProductId: 'mp-1',
|
||||
medicineId: 'med-1',
|
||||
storeId: 'st-1',
|
||||
price: 10,
|
||||
currency: 'USD',
|
||||
quantity: 100,
|
||||
unit: 'tablet' as never,
|
||||
isInsurancePrice: false,
|
||||
};
|
||||
|
||||
it('creates price record with computed pricePerUnit', async () => {
|
||||
mockProductsRepo.findById.mockResolvedValue({
|
||||
medicineName: 'Acetaminophen',
|
||||
brand: 'Tylenol',
|
||||
});
|
||||
mockStoresRepo.findById.mockResolvedValue({ name: 'Walgreens' });
|
||||
const record = { _id: 'pr-1', pricePerUnit: 0.1 };
|
||||
mockPricesRepo.create.mockResolvedValue(record);
|
||||
|
||||
const result = await service.recordPrice(validInput, 'hh1', 'user-1');
|
||||
|
||||
expect(result).toEqual(record);
|
||||
expect(mockPricesRepo.create).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
pricePerUnit: 0.1,
|
||||
medicineName: 'Acetaminophen',
|
||||
storeName: 'Walgreens',
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it('uses medicineName as brand fallback when brand is not set', async () => {
|
||||
mockProductsRepo.findById.mockResolvedValue({ medicineName: 'Generic', brand: undefined });
|
||||
mockStoresRepo.findById.mockResolvedValue({ name: 'CVS' });
|
||||
mockPricesRepo.create.mockResolvedValue({ _id: 'pr-1' });
|
||||
|
||||
await service.recordPrice(validInput, 'hh1', 'user-1');
|
||||
|
||||
expect(mockPricesRepo.create).toHaveBeenCalledWith(
|
||||
expect.objectContaining({ medicineProductBrand: 'Generic' }),
|
||||
);
|
||||
});
|
||||
|
||||
it('uses provided date when given', async () => {
|
||||
mockProductsRepo.findById.mockResolvedValue({
|
||||
medicineName: 'Acetaminophen',
|
||||
brand: 'Tylenol',
|
||||
});
|
||||
mockStoresRepo.findById.mockResolvedValue({ name: 'Walgreens' });
|
||||
mockPricesRepo.create.mockResolvedValue({ _id: 'pr-1' });
|
||||
|
||||
await service.recordPrice(
|
||||
{ ...validInput, date: '2026-01-15T00:00:00.000Z' },
|
||||
'hh1',
|
||||
'user-1',
|
||||
);
|
||||
|
||||
expect(mockPricesRepo.create).toHaveBeenCalledWith(
|
||||
expect.objectContaining({ date: new Date('2026-01-15T00:00:00.000Z') }),
|
||||
);
|
||||
});
|
||||
|
||||
it('throws NotFoundError when product not found', async () => {
|
||||
mockProductsRepo.findById.mockResolvedValue(null);
|
||||
|
||||
await expect(service.recordPrice(validInput, 'hh1', 'user-1')).rejects.toThrow(
|
||||
'Medicine product not found',
|
||||
);
|
||||
});
|
||||
|
||||
it('throws NotFoundError when store not found', async () => {
|
||||
mockProductsRepo.findById.mockResolvedValue({
|
||||
medicineName: 'Acetaminophen',
|
||||
brand: 'Tylenol',
|
||||
});
|
||||
mockStoresRepo.findById.mockResolvedValue(null);
|
||||
|
||||
await expect(service.recordPrice(validInput, 'hh1', 'user-1')).rejects.toThrow(
|
||||
'Store not found',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getPriceHistory', () => {
|
||||
it('delegates to repository', async () => {
|
||||
const result = { data: [], pagination: { cursor: null, hasMore: false } };
|
||||
mockPricesRepo.findByMedicine.mockResolvedValue(result);
|
||||
|
||||
const response = await service.getPriceHistory('hh1', 'med-1', { limit: 20 });
|
||||
|
||||
expect(response).toEqual(result);
|
||||
expect(mockPricesRepo.findByMedicine).toHaveBeenCalledWith('hh1', 'med-1', { limit: 20 });
|
||||
});
|
||||
});
|
||||
|
||||
describe('compareStores', () => {
|
||||
it('delegates to repository', async () => {
|
||||
const comparisons = [{ storeId: 'st-1', storeName: 'Walgreens', latestPrice: 10 }];
|
||||
mockPricesRepo.compareStores.mockResolvedValue(comparisons);
|
||||
|
||||
const result = await service.compareStores('hh1', 'med-1');
|
||||
|
||||
expect(result).toEqual(comparisons);
|
||||
expect(mockPricesRepo.compareStores).toHaveBeenCalledWith('hh1', 'med-1');
|
||||
});
|
||||
});
|
||||
|
||||
describe('estimatePrice', () => {
|
||||
it('returns pricePerUnit of latest record', async () => {
|
||||
mockPricesRepo.getLatestForMedicine.mockResolvedValue({ pricePerUnit: 0.15 });
|
||||
|
||||
const result = await service.estimatePrice('hh1', 'med-1');
|
||||
|
||||
expect(result).toBe(0.15);
|
||||
});
|
||||
|
||||
it('returns null when no records', async () => {
|
||||
mockPricesRepo.getLatestForMedicine.mockResolvedValue(null);
|
||||
|
||||
const result = await service.estimatePrice('hh1', 'med-1');
|
||||
|
||||
expect(result).toBeNull();
|
||||
});
|
||||
|
||||
it('filters by storeId when provided', async () => {
|
||||
mockPricesRepo.getLatestForMedicine.mockResolvedValue({ pricePerUnit: 0.2 });
|
||||
|
||||
await service.estimatePrice('hh1', 'med-1', 'st-1');
|
||||
|
||||
expect(mockPricesRepo.getLatestForMedicine).toHaveBeenCalledWith('hh1', 'med-1', 'st-1');
|
||||
});
|
||||
});
|
||||
|
||||
describe('getAnalytics', () => {
|
||||
it('delegates to repository', async () => {
|
||||
const analytics = {
|
||||
spendingOverTime: [],
|
||||
topBySpending: [],
|
||||
spendingByStore: [],
|
||||
priceAlerts: [],
|
||||
};
|
||||
mockPricesRepo.getAnalytics.mockResolvedValue(analytics);
|
||||
|
||||
const result = await service.getAnalytics('hh1', { period: 'month' });
|
||||
|
||||
expect(result).toEqual(analytics);
|
||||
expect(mockPricesRepo.getAnalytics).toHaveBeenCalledWith('hh1', { period: 'month' });
|
||||
});
|
||||
});
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue