Tests refactor
This commit is contained in:
parent
245520fb50
commit
99134d8556
165 changed files with 911 additions and 531 deletions
|
|
@ -0,0 +1,215 @@
|
|||
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
||||
import { MedicineForm, StrengthUnit, MedicineCategory } from '@meshitrack/shared';
|
||||
|
||||
const {
|
||||
mockExec,
|
||||
_mockLean,
|
||||
mockFind,
|
||||
mockFindOne,
|
||||
mockFindOneAndUpdate,
|
||||
mockSave,
|
||||
_mockSort,
|
||||
_mockLimit,
|
||||
} = vi.hoisted(() => {
|
||||
const mockExec = vi.fn();
|
||||
const mockLean = vi.fn(() => ({ exec: mockExec }));
|
||||
const mockLimit = vi.fn(() => ({ lean: mockLean }));
|
||||
const mockSort = vi.fn(() => ({ limit: mockLimit }));
|
||||
return {
|
||||
mockExec,
|
||||
mockLean,
|
||||
mockFind: vi.fn(() => ({ sort: mockSort })),
|
||||
mockFindOne: vi.fn(() => ({ lean: mockLean })),
|
||||
mockFindOneAndUpdate: vi.fn(() => ({ exec: mockExec })),
|
||||
mockSave: vi.fn(),
|
||||
mockSort,
|
||||
mockLimit,
|
||||
};
|
||||
});
|
||||
|
||||
vi.mock('../../../src/schemas/medicine.schema.js', () => {
|
||||
class MockMedicineModel {
|
||||
_data: Record<string, unknown>;
|
||||
constructor(data: Record<string, unknown>) {
|
||||
this._data = data;
|
||||
Object.assign(this, data);
|
||||
}
|
||||
save() {
|
||||
mockSave();
|
||||
return Promise.resolve(this);
|
||||
}
|
||||
toObject() {
|
||||
return { _id: 'med-new', ...this._data };
|
||||
}
|
||||
static find = mockFind;
|
||||
static findOne = mockFindOne;
|
||||
static findOneAndUpdate = mockFindOneAndUpdate;
|
||||
}
|
||||
return { MedicineModel: MockMedicineModel };
|
||||
});
|
||||
|
||||
import { MedicinesRepository } from '../../../src/modules/medicines/medicines.repository.js';
|
||||
|
||||
describe(MedicinesRepository.name, () => {
|
||||
let repo: MedicinesRepository;
|
||||
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
repo = new MedicinesRepository();
|
||||
});
|
||||
|
||||
describe('findByHousehold', () => {
|
||||
it('returns paginated results', async () => {
|
||||
const items = [
|
||||
{ _id: 'med-1', name: 'Aspirin' },
|
||||
{ _id: 'med-2', name: 'Ibuprofen' },
|
||||
];
|
||||
mockExec.mockResolvedValue(items);
|
||||
|
||||
const result = await repo.findByHousehold('hh1', { limit: 20 });
|
||||
|
||||
expect(mockFind).toHaveBeenCalledWith({ householdId: 'hh1', isDeleted: false });
|
||||
expect(result.data).toHaveLength(2);
|
||||
expect(result.pagination.hasMore).toBe(false);
|
||||
});
|
||||
|
||||
it('applies partial name search when q is provided', async () => {
|
||||
mockExec.mockResolvedValue([]);
|
||||
|
||||
await repo.findByHousehold('hh1', { q: 'asp', limit: 20 });
|
||||
|
||||
expect(mockFind).toHaveBeenCalledWith(
|
||||
expect.objectContaining({ name: { $regex: 'asp', $options: 'i' } }),
|
||||
);
|
||||
});
|
||||
|
||||
it('applies category filter', async () => {
|
||||
mockExec.mockResolvedValue([]);
|
||||
|
||||
await repo.findByHousehold('hh1', { category: MedicineCategory.PRESCRIPTION, limit: 20 });
|
||||
|
||||
expect(mockFind).toHaveBeenCalledWith(
|
||||
expect.objectContaining({ category: MedicineCategory.PRESCRIPTION }),
|
||||
);
|
||||
});
|
||||
|
||||
it('applies form filter', async () => {
|
||||
mockExec.mockResolvedValue([]);
|
||||
|
||||
await repo.findByHousehold('hh1', { form: MedicineForm.TABLET, limit: 20 });
|
||||
|
||||
expect(mockFind).toHaveBeenCalledWith(expect.objectContaining({ form: MedicineForm.TABLET }));
|
||||
});
|
||||
|
||||
it('detects hasMore when extra item returned', async () => {
|
||||
const items = Array.from({ length: 3 }, (_, i) => ({ _id: `med-${i}`, name: `Med ${i}` }));
|
||||
mockExec.mockResolvedValue(items);
|
||||
|
||||
const result = await repo.findByHousehold('hh1', { limit: 2 });
|
||||
|
||||
expect(result.data).toHaveLength(2);
|
||||
expect(result.pagination.hasMore).toBe(true);
|
||||
expect(result.pagination.cursor).toBeTruthy();
|
||||
});
|
||||
|
||||
it('decodes cursor for pagination', async () => {
|
||||
mockExec.mockResolvedValue([]);
|
||||
const cursor = Buffer.from('med-5').toString('base64');
|
||||
|
||||
await repo.findByHousehold('hh1', { cursor, limit: 20 });
|
||||
|
||||
expect(mockFind).toHaveBeenCalledWith(expect.objectContaining({ _id: { $gt: 'med-5' } }));
|
||||
});
|
||||
});
|
||||
|
||||
describe('findById', () => {
|
||||
it('finds by id and householdId', async () => {
|
||||
const medicine = { _id: 'med-1', name: 'Aspirin' };
|
||||
mockExec.mockResolvedValue(medicine);
|
||||
|
||||
const result = await repo.findById('med-1', 'hh1');
|
||||
|
||||
expect(mockFindOne).toHaveBeenCalledWith({
|
||||
_id: 'med-1',
|
||||
householdId: 'hh1',
|
||||
isDeleted: false,
|
||||
});
|
||||
expect(result).toEqual(medicine);
|
||||
});
|
||||
});
|
||||
|
||||
describe('findDuplicate', () => {
|
||||
it('finds medicine with matching fields', async () => {
|
||||
mockExec.mockResolvedValue({ _id: 'med-1' });
|
||||
|
||||
const result = await repo.findDuplicate('hh1', 'Aspirin', 500, 'mg', 'tablet');
|
||||
|
||||
expect(mockFindOne).toHaveBeenCalledWith({
|
||||
householdId: 'hh1',
|
||||
name: 'Aspirin',
|
||||
strength: 500,
|
||||
strengthUnit: 'mg',
|
||||
form: 'tablet',
|
||||
isDeleted: false,
|
||||
});
|
||||
expect(result).toBeTruthy();
|
||||
});
|
||||
|
||||
it('excludes specified id', async () => {
|
||||
mockExec.mockResolvedValue(null);
|
||||
|
||||
await repo.findDuplicate('hh1', 'Aspirin', 500, 'mg', 'tablet', 'med-1');
|
||||
|
||||
expect(mockFindOne).toHaveBeenCalledWith(expect.objectContaining({ _id: { $ne: 'med-1' } }));
|
||||
});
|
||||
});
|
||||
|
||||
describe('create', () => {
|
||||
it('creates a medicine', async () => {
|
||||
mockSave.mockResolvedValue({});
|
||||
|
||||
const data = {
|
||||
name: 'Aspirin',
|
||||
form: MedicineForm.TABLET,
|
||||
strength: 500,
|
||||
strengthUnit: StrengthUnit.MG,
|
||||
category: MedicineCategory.OTC,
|
||||
tags: [],
|
||||
};
|
||||
|
||||
const result = await repo.create(data, 'hh1', 'kc-1');
|
||||
|
||||
expect(mockSave).toHaveBeenCalled();
|
||||
expect(result).toMatchObject({ name: 'Aspirin', householdId: 'hh1', createdBy: 'kc-1' });
|
||||
});
|
||||
});
|
||||
|
||||
describe('update', () => {
|
||||
it('updates a medicine', async () => {
|
||||
mockExec.mockResolvedValue({ _id: 'med-1', name: 'Updated' });
|
||||
|
||||
const result = await repo.update('med-1', 'hh1', { name: 'Updated' });
|
||||
|
||||
expect(mockFindOneAndUpdate).toHaveBeenCalledWith(
|
||||
{ _id: 'med-1', householdId: 'hh1', isDeleted: false },
|
||||
{ $set: { name: 'Updated' } },
|
||||
{ new: true, lean: true },
|
||||
);
|
||||
expect(result).toEqual({ _id: 'med-1', name: 'Updated' });
|
||||
});
|
||||
});
|
||||
|
||||
describe('softDelete', () => {
|
||||
it('sets isDeleted to true', async () => {
|
||||
mockExec.mockResolvedValue({ _id: 'med-1', isDeleted: true });
|
||||
|
||||
await repo.softDelete('med-1', 'hh1');
|
||||
|
||||
expect(mockFindOneAndUpdate).toHaveBeenCalledWith(
|
||||
{ _id: 'med-1', householdId: 'hh1', isDeleted: false },
|
||||
{ $set: { isDeleted: true } },
|
||||
{ new: true, lean: true },
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue