hospital-log/backend/api/src/modules/obat/obat.service.spec.ts

249 lines
6.3 KiB
TypeScript

import { BadRequestException } from '@nestjs/common';
import { Test, TestingModule } from '@nestjs/testing';
import { PrismaService } from '../prisma/prisma.service';
import { LogService } from '../log/log.service';
import { ActiveUserPayload } from '../auth/decorator/current-user.decorator';
import { CreateObatDto } from './dto/create-obat-dto';
import { UpdateObatDto } from './dto/update-obat-dto';
import { ObatService } from './obat.service';
type PrismaDelegate<T> = {
findMany: jest.Mock;
findUnique: jest.Mock;
count: jest.Mock;
create: jest.Mock;
update: jest.Mock;
};
const createPrismaMock = () => ({
pemberian_obat: {
findMany: jest.fn(),
findUnique: jest.fn(),
count: jest.fn(),
create: jest.fn(),
update: jest.fn(),
} as PrismaDelegate<any>,
rekam_medis: {
findUnique: jest.fn(),
},
});
const createLogServiceMock = () => ({
storeLog: jest.fn(),
getLogById: jest.fn(),
});
const mockUser: ActiveUserPayload = {
sub: 1,
username: 'tester',
role: 'admin' as any,
csrf: 'token',
};
describe('ObatService', () => {
let service: ObatService;
let prisma: ReturnType<typeof createPrismaMock>;
let logService: ReturnType<typeof createLogServiceMock>;
beforeEach(async () => {
prisma = createPrismaMock();
logService = createLogServiceMock();
const module: TestingModule = await Test.createTestingModule({
providers: [
ObatService,
{ provide: PrismaService, useValue: prisma },
{ provide: LogService, useValue: logService },
],
}).compile();
service = module.get<ObatService>(ObatService);
});
it('should be defined', () => {
expect(service).toBeDefined();
});
describe('getAllObat', () => {
it('returns paginated data and total count', async () => {
prisma.pemberian_obat.findMany.mockResolvedValueOnce([
{ id: 1, obat: 'Paracetamol' },
]);
prisma.pemberian_obat.count.mockResolvedValueOnce(10);
const result = await service.getAllObat({
take: 10,
page: 1,
orderBy: { id: 'asc' },
order: 'asc',
obat: 'Para',
});
expect(prisma.pemberian_obat.findMany).toHaveBeenCalledWith({
skip: 0,
take: 10,
where: {
obat: { contains: 'Para' },
},
orderBy: { id: 'asc' },
});
expect(prisma.pemberian_obat.count).toHaveBeenCalledWith({
where: {
obat: { contains: 'Para' },
},
});
expect(result).toEqual({
0: { id: 1, obat: 'Paracetamol' },
totalCount: 10,
});
});
});
describe('createObat', () => {
const payload: CreateObatDto = {
id_visit: 'VISIT-1',
obat: 'Amoxicillin',
jumlah_obat: 2,
aturan_pakai: '3x1',
};
it('throws when visit not found', async () => {
prisma.rekam_medis.findUnique.mockResolvedValueOnce(null);
await expect(service.createObat(payload, mockUser)).rejects.toThrow(
BadRequestException,
);
expect(prisma.pemberian_obat.create).not.toHaveBeenCalled();
});
it('creates obat and stores log', async () => {
prisma.rekam_medis.findUnique.mockResolvedValueOnce({
id_visit: 'VISIT-1',
});
prisma.pemberian_obat.create.mockResolvedValueOnce({
id: 42,
...payload,
});
logService.storeLog.mockResolvedValueOnce({ txId: 'abc' });
const result = await service.createObat(payload, mockUser);
expect(prisma.pemberian_obat.create).toHaveBeenCalledWith({
data: {
id_visit: 'VISIT-1',
obat: 'Amoxicillin',
jumlah_obat: 2,
aturan_pakai: '3x1',
},
});
expect(logService.storeLog).toHaveBeenCalledWith({
id: 'OBAT_42',
event: 'obat_created',
user_id: mockUser.sub,
payload: expect.any(String),
});
expect(result).toEqual({
id: 42,
id_visit: 'VISIT-1',
obat: 'Amoxicillin',
jumlah_obat: 2,
aturan_pakai: '3x1',
txId: 'abc',
});
});
});
describe('updateObatById', () => {
const updatePayload: UpdateObatDto = {
id_visit: 'VISIT-1',
obat: 'Ibuprofen',
jumlah_obat: 1,
aturan_pakai: '2x1',
};
it('updates obat and stores log', async () => {
prisma.pemberian_obat.update.mockResolvedValueOnce({
id: 99,
...updatePayload,
id_visit: 'VISIT-1',
});
logService.storeLog.mockResolvedValueOnce({ txId: 'updated' });
const result = await service.updateObat(99, updatePayload, mockUser);
expect(prisma.pemberian_obat.update).toHaveBeenCalledWith({
where: { id: 99 },
data: {
obat: 'Ibuprofen',
jumlah_obat: 1,
aturan_pakai: '2x1',
},
});
expect(logService.storeLog).toHaveBeenCalledWith({
id: 'OBAT_99',
event: 'obat_updated',
user_id: mockUser.sub,
payload: expect.any(String),
});
expect(result).toEqual({
id: 99,
id_visit: 'VISIT-1',
obat: 'Ibuprofen',
jumlah_obat: 1,
aturan_pakai: '2x1',
txId: 'updated',
});
});
});
describe('getLogObatById', () => {
it('returns processed logs and tamper status', async () => {
prisma.pemberian_obat.findUnique.mockResolvedValueOnce({
id: 5,
obat: 'Paracetamol',
jumlah_obat: 1,
aturan_pakai: '3x1',
});
const expectedHash = service.createHashingPayload({
obat: 'Paracetamol',
jumlah_obat: 1,
aturan_pakai: '3x1',
});
logService.getLogById.mockResolvedValueOnce([
{
value: {
event: 'obat_created',
payload: expectedHash,
timestamp: '2024-01-01T00:00:00Z',
user_id: 1,
},
txId: 'abc',
},
]);
const result = await service.getLogObatById('5');
expect(logService.getLogById).toHaveBeenCalledWith('OBAT_5');
expect(result).toEqual({
logs: [
{
event: 'obat_created',
payload: expectedHash,
timestamp: '2024-01-01T00:00:00Z',
user_id: 1,
txId: 'abc',
status: 'ORIGINAL',
},
],
isTampered: false,
currentDataHash: expectedHash,
});
});
});
});