targo-backend/test/expenses.e2e-spec.ts

121 lines
4.0 KiB
TypeScript

import * as request from 'supertest';
import { INestApplication } from '@nestjs/common';
import { createApp } from './utils/testing-app';
import { PrismaService } from 'src/prisma/prisma.service';
import { makeExpense, makeInvalidExpense } from './factories/expense.factory';
const BASE = '/Expenses';
describe('Expenses (e2e) — autonome', () => {
let app: INestApplication;
let prisma: PrismaService;
let createdId: number | null = null;
let tsId: number;
let bcExpenseId: number; // categorie='EXPENSE' & type != 'MILEAGE'
beforeAll(async () => {
app = await createApp();
prisma = app.get(PrismaService);
const ts = await prisma.timesheets.findFirst({ select: { id: true } });
if (!ts) throw new Error('No timesheet found — seed timesheets first.');
tsId = ts.id;
const bc = await prisma.bankCodes.findFirst({
where: {
categorie: 'EXPENSE',
NOT: { type: 'MILEAGE' }, // évite la branche mileageService
},
select: { id: true },
});
if (!bc) throw new Error("No non-MILEAGE EXPENSE bank code found — seed bank codes first.");
bcExpenseId = bc.id;
});
afterAll(async () => {
if (createdId) {
try { await prisma.expenses.delete({ where: { id: createdId } }); } catch {}
}
await app.close();
await prisma.$disconnect();
});
it(`GET ${BASE} → 200 (array)`, async () => {
const res = await request(app.getHttpServer()).get(BASE);
expect(res.status).toBe(200);
expect(Array.isArray(res.body)).toBe(true);
});
it(`POST ${BASE} (valid) → 201 puis GET /:id → 200`, async () => {
const payload = makeExpense(tsId, bcExpenseId);
const createRes = await request(app.getHttpServer()).post(BASE).send(payload);
if (createRes.status !== 201) {
console.log('Create error:', createRes.body || createRes.text);
}
expect(createRes.status).toBe(201);
expect(createRes.body).toEqual(
expect.objectContaining({
id: expect.any(Number),
timesheet_id: tsId,
bank_code_id: bcExpenseId,
})
);
createdId = createRes.body.id;
const getRes = await request(app.getHttpServer()).get(`${BASE}/${createdId}`);
expect(getRes.status).toBe(200);
expect(getRes.body).toEqual(expect.objectContaining({ id: createdId }));
});
it(`PATCH ${BASE}/:id → 200 (amount/description mis à jour)`, async () => {
if (!createdId) {
const created = await request(app.getHttpServer())
.post(BASE)
.send(makeExpense(tsId, bcExpenseId));
expect(created.status).toBe(201);
createdId = created.body.id;
}
const updated = { amount: 123, description: 'Updated expense' }; // amount INT
const patchRes = await request(app.getHttpServer())
.patch(`${BASE}/${createdId}`)
.send(updated);
expect([200, 204]).toContain(patchRes.status);
const getRes = await request(app.getHttpServer()).get(`${BASE}/${createdId}`);
expect(getRes.status).toBe(200);
if (getRes.body?.amount !== undefined) {
expect(Number(getRes.body.amount)).toBe(updated.amount);
}
if (getRes.body?.description !== undefined) expect(getRes.body.description).toBe(updated.description);
});
it(`GET ${BASE}/999999 (not found) → 404/400`, async () => {
const res = await request(app.getHttpServer()).get(`${BASE}/999999`);
expect([404, 400]).toContain(res.status);
});
it(`POST ${BASE} (invalid payload) → 400`, async () => {
const res = await request(app.getHttpServer()).post(BASE).send(makeInvalidExpense());
expect(res.status).toBeGreaterThanOrEqual(400);
expect(res.status).toBeLessThan(500);
});
it(`DELETE ${BASE}/:id → 200/204`, async () => {
let id = createdId;
if (!id) {
const created = await request(app.getHttpServer())
.post(BASE)
.send(makeExpense(tsId, bcExpenseId));
expect(created.status).toBe(201);
id = created.body.id;
}
const del = await request(app.getHttpServer()).delete(`${BASE}/${id}`);
expect([200, 204]).toContain(del.status);
if (createdId === id) createdId = null;
});
});