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; beforeAll(async () => { const moduleFixture: TestingModule = await Test.createTestingModule({ imports: [AppModule], }).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', ); }); it('/ (GET)', () => { return request(app.getHttpServer()) .get('/') .expect(200) .expect('Hello World!'); }); describe('Machines skeleton reconfiguration', () => { it('reconfigures machine skeleton according to updated requirements', async () => { const site = await prisma.site.create({ data: { name: 'Site principal', contactName: 'Jane Doe', contactPhone: '0102030405', contactAddress: '1 rue Principale', contactPostalCode: '75000', contactCity: 'Paris', }, }); const typeComposant = await prisma.typeComposant.create({ data: { name: 'Module', description: 'Module principal', }, }); await prisma.customField.create({ data: { name: 'Serial', type: 'text', required: false, options: [], typeComposantId: typeComposant.id, }, }); const typePiece = await prisma.typePiece.create({ data: { name: 'Pièce de rechange', description: 'Pièce critique', }, }); await prisma.customField.create({ data: { name: 'Batch', type: 'text', required: false, options: [], typePieceId: typePiece.id, }, }); const componentModelV1 = await prisma.composantModel.create({ data: { name: 'Module V1', typeComposantId: typeComposant.id, structure: { name: 'Module V1', customFields: [{ name: 'Serial', defaultValue: 'SERIAL-V1' }], }, }, }); const componentModelV2 = await prisma.composantModel.create({ data: { name: 'Module V2', typeComposantId: typeComposant.id, structure: { name: 'Module V2', customFields: [{ name: 'Serial', defaultValue: 'SERIAL-V2' }], }, }, }); const pieceModelV1 = await prisma.pieceModel.create({ data: { name: 'Pièce V1', typePieceId: typePiece.id, structure: { name: 'Pièce V1', customFields: [{ name: 'Batch', defaultValue: 'BATCH-V1' }], }, }, }); const pieceModelV2 = await prisma.pieceModel.create({ data: { name: 'Pièce V2', typePieceId: typePiece.id, structure: { name: 'Pièce V2', customFields: [{ name: 'Batch', defaultValue: 'BATCH-V2' }], }, }, }); const typeMachine = await prisma.typeMachine.create({ data: { name: 'Type Machine A', componentRequirements: { create: [ { label: 'Module initial', minCount: 1, maxCount: 1, required: true, allowNewModels: false, typeComposantId: typeComposant.id, }, ], }, pieceRequirements: { create: [ { label: 'Pièce initiale', minCount: 1, maxCount: 1, required: true, allowNewModels: false, typePieceId: typePiece.id, }, ], }, }, include: { componentRequirements: true, pieceRequirements: true, }, }); const initialComponentRequirement = typeMachine.componentRequirements[0]; const initialPieceRequirement = typeMachine.pieceRequirements[0]; const createResponse = await request(app.getHttpServer()) .post('/machines') .send({ name: 'Machine Alpha', siteId: site.id, typeMachineId: typeMachine.id, componentSelections: [ { requirementId: initialComponentRequirement.id, componentModelId: componentModelV1.id, }, ], pieceSelections: [ { requirementId: initialPieceRequirement.id, pieceModelId: pieceModelV1.id, }, ], }) .expect(201); const machineId = createResponse.body.id as string; const initialComponents = await prisma.composant.findMany({ where: { machineId } }); expect(initialComponents).toHaveLength(1); const initialComponentId = initialComponents[0].id; const initialPieces = await prisma.piece.findMany({ where: { machineId } }); expect(initialPieces).toHaveLength(1); const initialPieceId = initialPieces[0].id; expect( await prisma.customFieldValue.count({ where: { composantId: initialComponentId } }), ).toBe(1); expect(await prisma.customFieldValue.count({ where: { pieceId: initialPieceId } })).toBe(1); await prisma.typeMachineComponentRequirement.deleteMany({ where: { typeMachineId: typeMachine.id }, }); await prisma.typeMachinePieceRequirement.deleteMany({ where: { typeMachineId: typeMachine.id }, }); const newComponentRequirement = await prisma.typeMachineComponentRequirement.create({ data: { label: 'Modules mis à jour', minCount: 2, maxCount: 2, required: true, allowNewModels: true, typeMachineId: typeMachine.id, typeComposantId: typeComposant.id, }, }); const newPieceRequirement = await prisma.typeMachinePieceRequirement.create({ data: { label: 'Pièce mise à jour', minCount: 1, maxCount: 1, required: true, allowNewModels: false, typeMachineId: typeMachine.id, typePieceId: typePiece.id, }, }); const reconfigureResponse = await request(app.getHttpServer()) .patch(`/machines/${machineId}/skeleton`) .send({ componentSelections: [ { requirementId: newComponentRequirement.id, componentModelId: componentModelV2.id, }, { requirementId: newComponentRequirement.id, definition: { name: 'Module personnalisé', customFields: [{ name: 'Serial', defaultValue: 'SERIAL-CUSTOM' }], }, }, ], pieceSelections: [ { requirementId: newPieceRequirement.id, pieceModelId: pieceModelV2.id, }, ], }) .expect(200); expect(reconfigureResponse.body.composants).toHaveLength(2); expect(reconfigureResponse.body.pieces).toHaveLength(1); const componentsAfter = await prisma.composant.findMany({ where: { machineId } }); expect(componentsAfter).toHaveLength(2); const componentIdsAfter = componentsAfter.map((component) => component.id); expect(componentIdsAfter).not.toContain(initialComponentId); componentsAfter.forEach((component) => { expect(component.typeMachineComponentRequirementId).toBe(newComponentRequirement.id); }); const componentValueCount = await prisma.customFieldValue.count({ where: { composantId: { in: componentIdsAfter } }, }); expect(componentValueCount).toBe(2); expect( await prisma.customFieldValue.count({ where: { composantId: initialComponentId } }), ).toBe(0); const piecesAfter = await prisma.piece.findMany({ where: { machineId } }); expect(piecesAfter).toHaveLength(1); const [updatedPiece] = piecesAfter; expect(updatedPiece.typeMachinePieceRequirementId).toBe(newPieceRequirement.id); expect(updatedPiece.id).not.toBe(initialPieceId); expect( await prisma.customFieldValue.count({ where: { pieceId: updatedPiece.id } }), ).toBe(1); expect(await prisma.customFieldValue.count({ where: { pieceId: initialPieceId } })).toBe(0); }); }); });