import { Test, TestingModule } from '@nestjs/testing'; import { ObatController } from './obat.controller'; import { ObatService } from './obat.service'; import { AuthGuard } from '../auth/guard/auth.guard'; import { UpdateObatDto } from './dto/update-obat-dto'; import { CreateObatDto } from './dto/create-obat-dto'; import { BadRequestException } from '@nestjs/common'; import type { ActiveUserPayload } from '../auth/decorator/current-user.decorator'; describe('ObatController', () => { let controller: ObatController; let obatService: jest.Mocked; const mockUser: ActiveUserPayload = { sub: 1, username: 'testuser', role: 'admin' as any, csrf: 'test-csrf-token', }; const mockObat = { id: 1, id_visit: 'VISIT001', obat: 'Paracetamol', jumlah_obat: 10, aturan_pakai: '3x1', deleted_status: null, }; const mockObatService = { getAllObat: jest.fn(), getObatById: jest.fn(), createObat: jest.fn(), updateObat: jest.fn(), getLogObatById: jest.fn(), deleteObat: jest.fn(), }; beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ controllers: [ObatController], providers: [ { provide: ObatService, useValue: mockObatService, }, ], }) .overrideGuard(AuthGuard) .useValue({ canActivate: () => true }) .compile(); controller = module.get(ObatController); obatService = module.get(ObatService); jest.clearAllMocks(); }); it('should be defined', () => { expect(controller).toBeDefined(); }); describe('getAllObat', () => { it('should return all obat with pagination', async () => { const expectedResult = { 0: mockObat, totalCount: 1, }; mockObatService.getAllObat.mockResolvedValue(expectedResult); const result = await controller.getAllObat( 10, 0, 1, 'id', 'Paracetamol', 'asc', ); expect(result).toEqual(expectedResult); expect(obatService.getAllObat).toHaveBeenCalledWith({ take: 10, skip: 0, page: 1, orderBy: { id: 'asc' }, obat: 'Paracetamol', order: 'asc', }); }); it('should handle undefined orderBy parameter', async () => { const expectedResult = { 0: mockObat, totalCount: 1 }; mockObatService.getAllObat.mockResolvedValue(expectedResult); await controller.getAllObat( 10, 0, 1, undefined as unknown as string, undefined as unknown as string, undefined as unknown as 'asc' | 'desc', ); expect(obatService.getAllObat).toHaveBeenCalledWith({ take: 10, skip: 0, page: 1, orderBy: undefined, obat: undefined, order: undefined, }); }); it('should pass order parameter when orderBy is provided', async () => { mockObatService.getAllObat.mockResolvedValue({ totalCount: 0 }); await controller.getAllObat( 10, 0, 1, 'obat', undefined as unknown as string, 'desc', ); expect(obatService.getAllObat).toHaveBeenCalledWith( expect.objectContaining({ orderBy: { obat: 'desc' }, order: 'desc', }), ); }); }); describe('getObatById', () => { it('should return obat by id', async () => { mockObatService.getObatById.mockResolvedValue(mockObat); const result = await controller.getObatById(1); expect(result).toEqual(mockObat); expect(obatService.getObatById).toHaveBeenCalledWith(1); }); it('should return null when obat not found', async () => { mockObatService.getObatById.mockResolvedValue(null); const result = await controller.getObatById(999); expect(result).toBeNull(); }); }); describe('createObat', () => { it('should create obat successfully', async () => { const createDto: CreateObatDto = { id_visit: 'VISIT001', obat: 'Paracetamol', jumlah_obat: 10, aturan_pakai: '3x1', }; const expectedResult = { id: 1, ...createDto, status: 'PENDING' }; mockObatService.createObat.mockResolvedValue(expectedResult); const result = await controller.createObat(createDto, mockUser); expect(result).toEqual(expectedResult); expect(obatService.createObat).toHaveBeenCalledWith(createDto, mockUser); }); it('should throw BadRequestException when visit ID not found', async () => { const createDto: CreateObatDto = { id_visit: 'INVALID', obat: 'Paracetamol', jumlah_obat: 10, aturan_pakai: '3x1', }; mockObatService.createObat.mockRejectedValue( new BadRequestException('Visit ID INVALID not found'), ); await expect(controller.createObat(createDto, mockUser)).rejects.toThrow( BadRequestException, ); }); }); describe('updateObatById', () => { it('should update obat successfully', async () => { const updateDto: UpdateObatDto = { obat: 'Ibuprofen', jumlah_obat: 20, aturan_pakai: '2x1', }; const expectedResult = { id: 1, status: 'PENDING' }; mockObatService.updateObat.mockResolvedValue(expectedResult); const result = await controller.updateObatById(1, updateDto, mockUser); expect(result).toEqual(expectedResult); expect(obatService.updateObat).toHaveBeenCalledWith( 1, updateDto, mockUser, ); }); it('should throw BadRequestException when obat not found', async () => { const updateDto: UpdateObatDto = { obat: 'Ibuprofen', jumlah_obat: 20, aturan_pakai: '2x1', }; mockObatService.updateObat.mockRejectedValue( new BadRequestException('Medicine with ID 999 not found'), ); await expect( controller.updateObatById(999, updateDto, mockUser), ).rejects.toThrow(BadRequestException); }); it('should throw BadRequestException when no changes detected', async () => { const updateDto: UpdateObatDto = { obat: 'Paracetamol', jumlah_obat: 10, aturan_pakai: '3x1', }; mockObatService.updateObat.mockRejectedValue( new BadRequestException('No changes in medicine data detected'), ); await expect( controller.updateObatById(1, updateDto, mockUser), ).rejects.toThrow('No changes in medicine data detected'); }); }); describe('getObatLogs', () => { it('should return obat logs', async () => { const expectedLogs = { logs: [ { id: 'OBAT_1', event: 'obat_created', status: 'ORIGINAL', }, ], isTampered: false, currentDataHash: 'abc123', }; mockObatService.getLogObatById.mockResolvedValue(expectedLogs); const result = await controller.getObatLogs('1'); expect(result).toEqual(expectedLogs); expect(obatService.getLogObatById).toHaveBeenCalledWith('1'); }); it('should handle tampered data detection', async () => { const expectedLogs = { logs: [], isTampered: true, currentDataHash: 'abc123', }; mockObatService.getLogObatById.mockResolvedValue(expectedLogs); const result = await controller.getObatLogs('1'); expect(result.isTampered).toBe(true); }); }); describe('deleteObatById', () => { it('should delete obat successfully', async () => { const expectedResult = { id: 1, status: 'PENDING', action: 'DELETE' }; mockObatService.deleteObat.mockResolvedValue(expectedResult); const result = await controller.deleteObatById(1, mockUser); expect(result).toEqual(expectedResult); expect(obatService.deleteObat).toHaveBeenCalledWith(1, mockUser); }); it('should throw BadRequestException when obat not found', async () => { mockObatService.deleteObat.mockRejectedValue( new BadRequestException('Obat with id 999 not found'), ); await expect(controller.deleteObatById(999, mockUser)).rejects.toThrow( BadRequestException, ); }); }); });