134 lines
4.6 KiB
JavaScript
134 lines
4.6 KiB
JavaScript
const request = require('supertest');
|
|
|
|
jest.mock('../src/lib/prisma', () => require('./__mocks__/prisma'));
|
|
const prisma = require('../src/lib/prisma');
|
|
const app = require('../src/app');
|
|
|
|
const ANIMAL_ID = 'dddddddd-0000-0000-0000-000000000001';
|
|
const STATUS = {
|
|
id: 'eeeeeeee-0000-0000-0000-000000000001',
|
|
animal_id: ANIMAL_ID,
|
|
date: new Date('2024-06-01').toISOString(),
|
|
experiment_description: 'Baseline measurement',
|
|
vitals: 'HR 72, Temp 37.2',
|
|
treatment: 'Control',
|
|
notes: 'Healthy',
|
|
};
|
|
|
|
beforeEach(() => jest.clearAllMocks());
|
|
|
|
describe('GET /api/daily-statuses', () => {
|
|
it('returns statuses filtered by animalId', async () => {
|
|
prisma.dailyStatus.findMany.mockResolvedValue([STATUS]);
|
|
const res = await request(app).get(`/api/daily-statuses?animalId=${ANIMAL_ID}`);
|
|
expect(res.status).toBe(200);
|
|
expect(res.body).toHaveLength(1);
|
|
expect(res.body[0].vitals).toBe('HR 72, Temp 37.2');
|
|
});
|
|
|
|
it('returns 422 for invalid animalId UUID', async () => {
|
|
const res = await request(app).get('/api/daily-statuses?animalId=invalid');
|
|
expect(res.status).toBe(422);
|
|
});
|
|
});
|
|
|
|
describe('GET /api/daily-statuses/:id', () => {
|
|
it('returns a single status entry', async () => {
|
|
prisma.dailyStatus.findUnique.mockResolvedValue({ ...STATUS, animal: {} });
|
|
const res = await request(app).get(`/api/daily-statuses/${STATUS.id}`);
|
|
expect(res.status).toBe(200);
|
|
expect(res.body.id).toBe(STATUS.id);
|
|
});
|
|
|
|
it('returns 404 for unknown id', async () => {
|
|
prisma.dailyStatus.findUnique.mockResolvedValue(null);
|
|
const res = await request(app).get('/api/daily-statuses/00000000-0000-0000-0000-000000000000');
|
|
expect(res.status).toBe(404);
|
|
});
|
|
});
|
|
|
|
describe('POST /api/daily-statuses', () => {
|
|
it('creates status and returns 201 with UUID', async () => {
|
|
prisma.dailyStatus.create.mockResolvedValue(STATUS);
|
|
prisma.auditLog.create.mockResolvedValue({});
|
|
|
|
const res = await request(app)
|
|
.post('/api/daily-statuses')
|
|
.send({ animal_id: ANIMAL_ID, date: '2024-06-01', vitals: 'HR 72' });
|
|
|
|
expect(res.status).toBe(201);
|
|
expect(res.body.id).toMatch(/^[0-9a-f-]{36}$/i);
|
|
expect(prisma.auditLog.create).toHaveBeenCalled();
|
|
});
|
|
|
|
it('returns 422 when animal_id is missing', async () => {
|
|
const res = await request(app)
|
|
.post('/api/daily-statuses')
|
|
.send({ date: '2024-06-01' });
|
|
expect(res.status).toBe(422);
|
|
expect(res.body.details).toEqual(
|
|
expect.arrayContaining([expect.objectContaining({ field: 'animal_id' })])
|
|
);
|
|
});
|
|
|
|
it('returns 422 when date is missing', async () => {
|
|
const res = await request(app)
|
|
.post('/api/daily-statuses')
|
|
.send({ animal_id: ANIMAL_ID });
|
|
expect(res.status).toBe(422);
|
|
expect(res.body.details).toEqual(
|
|
expect.arrayContaining([expect.objectContaining({ field: 'date' })])
|
|
);
|
|
});
|
|
|
|
it('returns 422 when date is not a valid ISO date', async () => {
|
|
const res = await request(app)
|
|
.post('/api/daily-statuses')
|
|
.send({ animal_id: ANIMAL_ID, date: 'not-a-date' });
|
|
expect(res.status).toBe(422);
|
|
});
|
|
});
|
|
|
|
describe('PUT /api/daily-statuses/:id', () => {
|
|
it('updates status and writes UPDATE audit log', async () => {
|
|
const updated = { ...STATUS, vitals: 'HR 80' };
|
|
prisma.dailyStatus.findUnique
|
|
.mockResolvedValueOnce(STATUS)
|
|
.mockResolvedValueOnce(updated);
|
|
prisma.dailyStatus.update.mockResolvedValue(updated);
|
|
prisma.auditLog.create.mockResolvedValue({});
|
|
|
|
const res = await request(app)
|
|
.put(`/api/daily-statuses/${STATUS.id}`)
|
|
.send({ vitals: 'HR 80' });
|
|
|
|
expect(res.status).toBe(200);
|
|
expect(res.body.vitals).toBe('HR 80');
|
|
expect(prisma.auditLog.create).toHaveBeenCalledWith(
|
|
expect.objectContaining({ data: expect.objectContaining({ action: 'UPDATE' }) })
|
|
);
|
|
});
|
|
|
|
it('returns 422 when date format is invalid', async () => {
|
|
prisma.dailyStatus.findUnique.mockResolvedValue(STATUS);
|
|
const res = await request(app)
|
|
.put(`/api/daily-statuses/${STATUS.id}`)
|
|
.send({ date: 'garbage' });
|
|
expect(res.status).toBe(422);
|
|
});
|
|
});
|
|
|
|
describe('DELETE /api/daily-statuses/:id', () => {
|
|
it('deletes status and writes DELETE audit log', async () => {
|
|
prisma.dailyStatus.findUnique.mockResolvedValue(STATUS);
|
|
prisma.dailyStatus.delete.mockResolvedValue(STATUS);
|
|
prisma.auditLog.create.mockResolvedValue({});
|
|
|
|
const res = await request(app).delete(`/api/daily-statuses/${STATUS.id}`);
|
|
expect(res.status).toBe(204);
|
|
expect(prisma.auditLog.create).toHaveBeenCalledWith(
|
|
expect.objectContaining({ data: expect.objectContaining({ action: 'DELETE' }) })
|
|
);
|
|
});
|
|
});
|