diff --git a/src/EventSubscriber/AbstractAuditSubscriber.php b/src/EventSubscriber/AbstractAuditSubscriber.php index 91627d3..a064f1f 100644 --- a/src/EventSubscriber/AbstractAuditSubscriber.php +++ b/src/EventSubscriber/AbstractAuditSubscriber.php @@ -31,7 +31,7 @@ use function method_exists; abstract class AbstractAuditSubscriber implements EventSubscriber { public function __construct( - private readonly ActorProfileResolver $actorProfileResolver, + protected readonly ActorProfileResolver $actorProfileResolver, ) {} public function getSubscribedEvents(): array diff --git a/src/Service/EntityVersionService.php b/src/Service/EntityVersionService.php index 5e837d4..01da962 100644 --- a/src/Service/EntityVersionService.php +++ b/src/Service/EntityVersionService.php @@ -957,5 +957,4 @@ final class EntityVersionService return $serialized; } - } diff --git a/src/Service/ModelTypeCategoryConversionService.php b/src/Service/ModelTypeCategoryConversionService.php index 928f871..e30e941 100644 --- a/src/Service/ModelTypeCategoryConversionService.php +++ b/src/Service/ModelTypeCategoryConversionService.php @@ -451,5 +451,4 @@ final class ModelTypeCategoryConversionService ], ); } - } diff --git a/tests/Api/Entity/MachineContextCustomFieldTest.php b/tests/Api/Entity/MachineContextCustomFieldTest.php index 05bf451..68f634b 100644 --- a/tests/Api/Entity/MachineContextCustomFieldTest.php +++ b/tests/Api/Entity/MachineContextCustomFieldTest.php @@ -7,6 +7,9 @@ namespace App\Tests\Api\Entity; use App\Enum\ModelCategory; use App\Tests\AbstractApiTestCase; +/** + * @internal + */ class MachineContextCustomFieldTest extends AbstractApiTestCase { public function testStructureReturnsContextFieldsOnComponentLink(): void @@ -56,7 +59,7 @@ class MachineContextCustomFieldTest extends AbstractApiTestCase $normalFields = array_filter( $componentLink['composant']['customFields'], - fn (array $f) => $f['name'] === 'Serial', + fn (array $f) => 'Serial' === $f['name'], ); $this->assertCount(1, $normalFields); } @@ -65,8 +68,8 @@ class MachineContextCustomFieldTest extends AbstractApiTestCase { $client = $this->createGestionnaireClient(); - $site = $this->createSite('Site B'); - $modelType = $this->createModelType('Bearing', 'BRG', ModelCategory::PIECE); + $site = $this->createSite('Site B'); + $modelType = $this->createModelType('Bearing', 'BRG', ModelCategory::PIECE); $contextField = $this->createCustomField( name: 'Wear Level', type: 'select', @@ -101,8 +104,8 @@ class MachineContextCustomFieldTest extends AbstractApiTestCase { $client = $this->createGestionnaireClient(); - $site = $this->createSite('Site C'); - $modelType = $this->createModelType('Pump', 'PMP', ModelCategory::COMPONENT); + $site = $this->createSite('Site C'); + $modelType = $this->createModelType('Pump', 'PMP', ModelCategory::COMPONENT); $contextField = $this->createCustomField( name: 'Flow Rate', type: 'number', @@ -131,8 +134,8 @@ class MachineContextCustomFieldTest extends AbstractApiTestCase { $client = $this->createGestionnaireClient(); - $site = $this->createSite('Site D'); - $modelType = $this->createModelType('Valve', 'VLV', ModelCategory::COMPONENT); + $site = $this->createSite('Site D'); + $modelType = $this->createModelType('Valve', 'VLV', ModelCategory::COMPONENT); $contextField = $this->createCustomField( name: 'Pressure', type: 'number', @@ -171,8 +174,8 @@ class MachineContextCustomFieldTest extends AbstractApiTestCase { $client = $this->createGestionnaireClient(); - $site = $this->createSite('Site E'); - $modelType = $this->createModelType('Sensor', 'SNS', ModelCategory::COMPONENT); + $site = $this->createSite('Site E'); + $modelType = $this->createModelType('Sensor', 'SNS', ModelCategory::COMPONENT); $contextField = $this->createCustomField( name: 'Calibration Date', type: 'date', @@ -190,8 +193,8 @@ class MachineContextCustomFieldTest extends AbstractApiTestCase { $client = $this->createGestionnaireClient(); - $site = $this->createSite('Site F'); - $modelType = $this->createModelType('Motor Clone', 'MOTC', ModelCategory::COMPONENT); + $site = $this->createSite('Site F'); + $modelType = $this->createModelType('Motor Clone', 'MOTC', ModelCategory::COMPONENT); $contextField = $this->createCustomField( name: 'RPM Setting', type: 'number', @@ -225,4 +228,84 @@ class MachineContextCustomFieldTest extends AbstractApiTestCase $this->assertCount(1, $clonedLink['contextCustomFieldValues']); $this->assertSame('3000', $clonedLink['contextCustomFieldValues'][0]['value']); } + + public function testCloneMachineCopiesPieceContextFieldValues(): void + { + $client = $this->createGestionnaireClient(); + + $site = $this->createSite('Site G'); + $modelType = $this->createModelType('Bearing Clone', 'BRGC', ModelCategory::PIECE); + $contextField = $this->createCustomField( + name: 'Wear Level', + type: 'text', + typePiece: $modelType, + machineContextOnly: true, + ); + + $source = $this->createMachine('Source Piece Machine', $site); + $piece = $this->createPiece('Bearing C', 'BRGC-001', $modelType); + $link = $this->createMachinePieceLink($source, $piece); + + $this->createCustomFieldValue( + customField: $contextField, + value: 'Fair', + piece: $piece, + machinePieceLink: $link, + ); + + $response = $client->request('POST', '/api/machines/'.$source->getId().'/clone', [ + 'json' => [ + 'name' => 'Cloned Piece Machine', + 'siteId' => $site->getId(), + ], + ]); + + $this->assertResponseStatusCodeSame(201); + $data = $response->toArray(); + + $clonedLink = $data['pieceLinks'][0] ?? null; + $this->assertNotNull($clonedLink, 'Clone should expose at least one pieceLink'); + $this->assertCount(1, $clonedLink['contextCustomFieldValues']); + $this->assertSame('Fair', $clonedLink['contextCustomFieldValues'][0]['value']); + } + + public function testCloneMachineLeavesSourceContextFieldValuesIntact(): void + { + $client = $this->createGestionnaireClient(); + + $site = $this->createSite('Site H'); + $modelType = $this->createModelType('Motor Source', 'MOTS', ModelCategory::COMPONENT); + $contextField = $this->createCustomField( + name: 'RPM', + type: 'number', + typeComposant: $modelType, + machineContextOnly: true, + ); + + $source = $this->createMachine('Original Machine', $site); + $composant = $this->createComposant('Motor S', 'MOTS-001', $modelType); + $link = $this->createMachineComponentLink($source, $composant); + + $this->createCustomFieldValue( + customField: $contextField, + value: '1500', + composant: $composant, + machineComponentLink: $link, + ); + + $client->request('POST', '/api/machines/'.$source->getId().'/clone', [ + 'json' => [ + 'name' => 'Clone Machine', + 'siteId' => $site->getId(), + ], + ]); + $this->assertResponseStatusCodeSame(201); + + // Source must still expose its original context field value + $sourceData = $client->request('GET', '/api/machines/'.$source->getId().'/structure')->toArray(); + $sourceLink = $sourceData['componentLinks'][0] ?? null; + $this->assertNotNull($sourceLink, 'Source machine should still expose its component link'); + $this->assertCount(1, $sourceLink['contextCustomFieldValues']); + $this->assertSame('1500', $sourceLink['contextCustomFieldValues'][0]['value']); + } }