Validate component and piece requirements
This commit is contained in:
@@ -1,19 +1,84 @@
|
||||
import { BadRequestException } from '@nestjs/common';
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { ComposantsService } from './composants.service';
|
||||
import { PrismaService } from '../prisma/prisma.service';
|
||||
import { CreateComposantDto } from '../shared/dto/composant.dto';
|
||||
|
||||
describe('ComposantsService', () => {
|
||||
let service: ComposantsService;
|
||||
let prisma: any;
|
||||
|
||||
beforeEach(async () => {
|
||||
prisma = {
|
||||
composant: {
|
||||
create: jest.fn(),
|
||||
findUnique: jest.fn(),
|
||||
},
|
||||
machine: {
|
||||
findUnique: jest.fn(),
|
||||
},
|
||||
};
|
||||
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
providers: [ComposantsService, PrismaService],
|
||||
providers: [ComposantsService, { provide: PrismaService, useValue: prisma }],
|
||||
}).compile();
|
||||
|
||||
service = module.get<ComposantsService>(ComposantsService);
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(service).toBeDefined();
|
||||
afterEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it('should create a component when requirement matches the machine skeleton', async () => {
|
||||
const dto: CreateComposantDto = {
|
||||
name: 'Comp A',
|
||||
machineId: 'machine-1',
|
||||
typeComposantId: 'type-comp-1',
|
||||
typeMachineComponentRequirementId: 'req-1',
|
||||
};
|
||||
|
||||
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);
|
||||
|
||||
await expect(service.create(dto)).resolves.toEqual(created);
|
||||
|
||||
expect(prisma.composant.create).toHaveBeenCalled();
|
||||
expect(
|
||||
prisma.composant.create.mock.calls[0][0].data.typeComposantId,
|
||||
).toBe('type-comp-1');
|
||||
});
|
||||
|
||||
it('should refuse creation when requirement does not belong to machine skeleton', async () => {
|
||||
const dto: CreateComposantDto = {
|
||||
name: 'Comp A',
|
||||
machineId: 'machine-1',
|
||||
typeComposantId: 'type-comp-1',
|
||||
typeMachineComponentRequirementId: 'req-2',
|
||||
};
|
||||
|
||||
prisma.machine.findUnique.mockResolvedValue({
|
||||
id: 'machine-1',
|
||||
typeMachine: {
|
||||
componentRequirements: [
|
||||
{ id: 'req-1', typeComposantId: 'type-comp-1' },
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
await expect(service.create(dto)).rejects.toBeInstanceOf(
|
||||
BadRequestException,
|
||||
);
|
||||
|
||||
expect(prisma.composant.create).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { BadRequestException, Injectable } from '@nestjs/common';
|
||||
import { PrismaService } from '../prisma/prisma.service';
|
||||
import { CreateComposantDto, UpdateComposantDto } from '../shared/dto/composant.dto';
|
||||
|
||||
@@ -7,8 +7,75 @@ export class ComposantsService {
|
||||
constructor(private prisma: PrismaService) {}
|
||||
|
||||
async create(createComposantDto: CreateComposantDto) {
|
||||
const requirementId = createComposantDto.typeMachineComponentRequirementId;
|
||||
|
||||
let machineId = createComposantDto.machineId;
|
||||
|
||||
if (createComposantDto.parentComposantId) {
|
||||
const parentMachineId = await this.resolveMachineIdFromComposant(
|
||||
createComposantDto.parentComposantId,
|
||||
);
|
||||
|
||||
if (machineId && machineId !== parentMachineId) {
|
||||
throw new BadRequestException(
|
||||
'Le composant parent ne correspond pas à la machine ciblée.',
|
||||
);
|
||||
}
|
||||
|
||||
machineId = parentMachineId;
|
||||
}
|
||||
|
||||
if (!machineId) {
|
||||
throw new BadRequestException(
|
||||
'Un machineId ou un parentComposantId valide est requis pour créer un composant.',
|
||||
);
|
||||
}
|
||||
|
||||
const machine = await this.prisma.machine.findUnique({
|
||||
where: { id: machineId },
|
||||
include: {
|
||||
typeMachine: {
|
||||
include: {
|
||||
componentRequirements: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
if (!machine || !machine.typeMachine) {
|
||||
throw new BadRequestException(
|
||||
'La machine ciblée doit être associée à un type de machine pour valider les requirements.',
|
||||
);
|
||||
}
|
||||
|
||||
const requirement = machine.typeMachine.componentRequirements.find(
|
||||
(componentRequirement) => componentRequirement.id === requirementId,
|
||||
);
|
||||
|
||||
if (!requirement) {
|
||||
throw new BadRequestException(
|
||||
'Le requirement de composant fourni ne correspond pas au squelette de la machine.',
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
createComposantDto.typeComposantId &&
|
||||
createComposantDto.typeComposantId !== requirement.typeComposantId
|
||||
) {
|
||||
throw new BadRequestException(
|
||||
'Le type de composant fourni ne correspond pas au requirement pour cette machine.',
|
||||
);
|
||||
}
|
||||
|
||||
const data = {
|
||||
...createComposantDto,
|
||||
machineId,
|
||||
typeComposantId:
|
||||
createComposantDto.typeComposantId ?? requirement.typeComposantId,
|
||||
};
|
||||
|
||||
return this.prisma.composant.create({
|
||||
data: createComposantDto,
|
||||
data,
|
||||
include: {
|
||||
machine: true,
|
||||
parentComposant: true,
|
||||
@@ -437,6 +504,37 @@ export class ComposantsService {
|
||||
});
|
||||
}
|
||||
|
||||
private async resolveMachineIdFromComposant(
|
||||
composantId: string,
|
||||
): Promise<string> {
|
||||
const composant = await this.prisma.composant.findUnique({
|
||||
where: { id: composantId },
|
||||
select: {
|
||||
id: true,
|
||||
machineId: true,
|
||||
parentComposantId: true,
|
||||
},
|
||||
});
|
||||
|
||||
if (!composant) {
|
||||
throw new BadRequestException(
|
||||
'Le composant parent spécifié est introuvable.',
|
||||
);
|
||||
}
|
||||
|
||||
if (composant.machineId) {
|
||||
return composant.machineId;
|
||||
}
|
||||
|
||||
if (composant.parentComposantId) {
|
||||
return this.resolveMachineIdFromComposant(composant.parentComposantId);
|
||||
}
|
||||
|
||||
throw new BadRequestException(
|
||||
'Impossible de déterminer la machine associée au composant parent.',
|
||||
);
|
||||
}
|
||||
|
||||
async remove(id: string) {
|
||||
return this.prisma.composant.delete({
|
||||
where: { id },
|
||||
|
||||
Reference in New Issue
Block a user