import { Test, TestingModule } from '@nestjs/testing'; import { INestApplication } from '@nestjs/common'; import * as request from 'supertest'; import { App } from 'supertest/types'; import { AppModule } from './../src/app.module'; import { PrismaService } from '../src/prisma/prisma.service'; describe('AppController (e2e)', () => { let app: INestApplication; let prisma: PrismaService; function createMockPrismaService() { return { composant: { create: jest.fn(), findUnique: jest.fn(), }, piece: { create: jest.fn(), }, machine: { findUnique: jest.fn(), }, profile: { count: jest.fn().mockResolvedValue(0), create: jest.fn().mockResolvedValue({ id: 'profile-1' }), }, onModuleInit: jest.fn(), onModuleDestroy: jest.fn(), }; } let prisma: ReturnType; beforeEach(async () => { prisma = createMockPrismaService(); const moduleFixture: TestingModule = await Test.createTestingModule({ imports: [AppModule], }) .overrideProvider(PrismaService) .useValue(prisma) .compile(); app = moduleFixture.createNestApplication(); await app.init(); prisma = app.get(PrismaService); }); afterAll(async () => { await app.close(); }); beforeEach(async () => { await prisma.$executeRawUnsafe( 'TRUNCATE TABLE custom_field_values, documents, pieces, composants, machines, composant_models, piece_models, type_machine_component_requirements, type_machine_piece_requirements, custom_fields, type_machines, type_composants, type_pieces, constructeurs, sites RESTART IDENTITY CASCADE', ); }); afterEach(async () => { await app.close(); }); it('/ (GET)', () => { return request(app.getHttpServer()) .get('/') .expect(200) .expect('Hello World!'); }); describe('POST /composants', () => { it('accepts creation when requirement matches the machine skeleton', async () => { prisma.machine.findUnique.mockResolvedValue({ id: 'machine-1', typeMachine: { componentRequirements: [ { id: 'req-1', typeComposantId: 'type-comp-1' }, ], }, }); const created = { id: 'component-1' }; prisma.composant.create.mockResolvedValue(created); const response = await request(app.getHttpServer()) .post('/composants') .send({ name: 'Comp A', machineId: 'machine-1', typeComposantId: 'type-comp-1', typeMachineComponentRequirementId: 'req-1', }) .expect(201); expect(response.body).toEqual(created); expect(prisma.composant.create).toHaveBeenCalled(); }); it('refuses creation when requirement is not part of the machine skeleton', async () => { prisma.machine.findUnique.mockResolvedValue({ id: 'machine-1', typeMachine: { componentRequirements: [ { id: 'req-1', typeComposantId: 'type-comp-1' }, ], }, }); await request(app.getHttpServer()) .post('/composants') .send({ name: 'Comp A', machineId: 'machine-1', typeComposantId: 'type-comp-1', typeMachineComponentRequirementId: 'req-2', }) .expect(400); expect(prisma.composant.create).not.toHaveBeenCalled(); }); }); describe('POST /pieces', () => { it('accepts creation when requirement matches the machine skeleton', async () => { prisma.machine.findUnique.mockResolvedValue({ id: 'machine-1', typeMachine: { pieceRequirements: [ { id: 'req-1', typePieceId: 'type-piece-1' }, ], }, }); const created = { id: 'piece-1' }; prisma.piece.create.mockResolvedValue(created); const response = await request(app.getHttpServer()) .post('/pieces') .send({ name: 'Piece A', machineId: 'machine-1', typePieceId: 'type-piece-1', typeMachinePieceRequirementId: 'req-1', }) .expect(201); expect(response.body).toEqual(created); expect(prisma.piece.create).toHaveBeenCalled(); }); it('refuses creation when requirement is not part of the machine skeleton', async () => { prisma.machine.findUnique.mockResolvedValue({ id: 'machine-1', typeMachine: { pieceRequirements: [ { id: 'req-1', typePieceId: 'type-piece-1' }, ], }, }); await request(app.getHttpServer()) .post('/pieces') .send({ name: 'Piece A', machineId: 'machine-1', typePieceId: 'type-piece-1', typeMachinePieceRequirementId: 'req-2', }) .expect(400); expect(prisma.piece.create).not.toHaveBeenCalled(); }); }); });