createSite(name: 'Site Structure'); $machine = $this->createMachine(name: 'Machine Structure', site: $site, reference: 'REF-STRUCT'); $composant = $this->createComposant(name: 'Composant Alpha'); $piece = $this->createPiece(name: 'Piece Alpha', reference: 'REF-P1'); $product = $this->createProduct(name: 'Product Alpha', reference: 'REF-PR1'); $componentLink = $this->createMachineComponentLink($machine, $composant); $this->createMachinePieceLink($machine, $piece, $componentLink, quantity: 3); $this->createMachineProductLink($machine, $product); $session = $this->createMcpClient('ROLE_VIEWER'); $data = $this->callMcpTool($session, 'get_machine_structure', [ 'machineId' => $machine->getId(), ]); $this->assertArrayHasKey('_parsed', $data); $parsed = $data['_parsed']; // Machine info $this->assertSame('Machine Structure', $parsed['machine']['name']); $this->assertSame('REF-STRUCT', $parsed['machine']['reference']); $this->assertSame($site->getId(), $parsed['machine']['siteId']); // Component links $this->assertCount(1, $parsed['componentLinks']); $this->assertSame($composant->getId(), $parsed['componentLinks'][0]['composantId']); $this->assertSame('Composant Alpha', $parsed['componentLinks'][0]['composant']['name']); // Piece links $this->assertCount(1, $parsed['pieceLinks']); $this->assertSame($piece->getId(), $parsed['pieceLinks'][0]['pieceId']); $this->assertSame('Piece Alpha', $parsed['pieceLinks'][0]['piece']['name']); $this->assertSame(3, $parsed['pieceLinks'][0]['quantity']); // Product links $this->assertCount(1, $parsed['productLinks']); $this->assertSame($product->getId(), $parsed['productLinks'][0]['productId']); $this->assertSame('Product Alpha', $parsed['productLinks'][0]['product']['name']); } public function testGetMachineStructureNotFound(): void { $session = $this->createMcpClient('ROLE_VIEWER'); $data = $this->callMcpTool($session, 'get_machine_structure', [ 'machineId' => 'nonexistent-id', ]); $this->assertArrayHasKey('error', $data); } public function testGetMachineStructureWithOverrides(): void { $site = $this->createSite(name: 'Site Overrides'); $machine = $this->createMachine(name: 'Machine Overrides', site: $site); $composant = $this->createComposant(name: 'Composant Override'); $componentLink = $this->createMachineComponentLink($machine, $composant); $componentLink->setNameOverride('Custom Name'); $componentLink->setReferenceOverride('CUSTOM-REF'); $this->getEntityManager()->flush(); $session = $this->createMcpClient('ROLE_VIEWER'); $data = $this->callMcpTool($session, 'get_machine_structure', [ 'machineId' => $machine->getId(), ]); $this->assertArrayHasKey('_parsed', $data); $overrides = $data['_parsed']['componentLinks'][0]['overrides']; $this->assertSame('Custom Name', $overrides['name']); $this->assertSame('CUSTOM-REF', $overrides['reference']); } public function testCloneMachine(): void { $site = $this->createSite(name: 'Site Source'); $targetSite = $this->createSite(name: 'Site Target'); $machine = $this->createMachine(name: 'Machine Source', site: $site, reference: 'REF-SRC'); $composant = $this->createComposant(name: 'Composant Clone'); $piece = $this->createPiece(name: 'Piece Clone'); $product = $this->createProduct(name: 'Product Clone'); $componentLink = $this->createMachineComponentLink($machine, $composant); $this->createMachinePieceLink($machine, $piece, $componentLink, quantity: 2); $this->createMachineProductLink($machine, $product); $session = $this->createMcpClient('ROLE_GESTIONNAIRE'); $data = $this->callMcpTool($session, 'clone_machine', [ 'machineId' => $machine->getId(), 'name' => 'Machine Cloned', 'siteId' => $targetSite->getId(), 'reference' => 'REF-CLN', ]); $this->assertArrayHasKey('_parsed', $data); $parsed = $data['_parsed']; $this->assertSame('Machine Cloned', $parsed['name']); $this->assertSame('REF-CLN', $parsed['reference']); $this->assertSame($targetSite->getId(), $parsed['siteId']); $this->assertSame($machine->getId(), $parsed['clonedFrom']); $this->assertNotSame($machine->getId(), $parsed['id']); // Verify the cloned machine has links by fetching its structure $structureData = $this->callMcpTool($session, 'get_machine_structure', [ 'machineId' => $parsed['id'], ]); $this->assertArrayHasKey('_parsed', $structureData); $structure = $structureData['_parsed']; $this->assertCount(1, $structure['componentLinks']); $this->assertSame($composant->getId(), $structure['componentLinks'][0]['composantId']); $this->assertCount(1, $structure['pieceLinks']); $this->assertCount(1, $structure['productLinks']); } public function testCloneMachineRequiresGestionnaire(): void { $site = $this->createSite(name: 'Site Forbidden'); $machine = $this->createMachine(name: 'Machine Forbidden', site: $site); $session = $this->createMcpClient('ROLE_VIEWER'); $data = $this->callMcpTool($session, 'clone_machine', [ 'machineId' => $machine->getId(), 'name' => 'Should Fail', 'siteId' => $site->getId(), ]); $this->assertArrayHasKey('error', $data, 'Should fail with VIEWER role'); } public function testCloneMachineNotFound(): void { $site = $this->createSite(name: 'Site Clone NF'); $session = $this->createMcpClient('ROLE_GESTIONNAIRE'); $data = $this->callMcpTool($session, 'clone_machine', [ 'machineId' => 'nonexistent-id', 'name' => 'Should Fail', 'siteId' => $site->getId(), ]); $this->assertArrayHasKey('error', $data); } }