From 692574cfb72c4df4e480f81e452c2572c5b6f02d Mon Sep 17 00:00:00 2001 From: Thijs De Paepe Date: Tue, 3 Dec 2024 17:54:01 +0100 Subject: [PATCH 1/5] fix: no-content 204 check --- src/Component/Common/Client/ApiClient.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Component/Common/Client/ApiClient.php b/src/Component/Common/Client/ApiClient.php index 8b3700f1..714949e1 100644 --- a/src/Component/Common/Client/ApiClient.php +++ b/src/Component/Common/Client/ApiClient.php @@ -202,9 +202,6 @@ public function getResponse(): ApiResponse // obtain response $content = \curl_exec($this->handle); $status = \curl_getinfo($this->handle, CURLINFO_HTTP_CODE); - if (in_array($status, [200, 204]) && !$content) { - return ApiResponse::create([], $status); - } // extract body $headerSize = curl_getinfo($this->handle, CURLINFO_HEADER_SIZE); @@ -212,6 +209,10 @@ public function getResponse(): ApiResponse $content = substr($content, $headerSize); $headers = $this->getResponseHeaders($headers); + if (in_array($status, [200, 204]) && !$content) { + return ApiResponse::create([], $status); + } + $multi = []; foreach (explode("\n", $content) as $c) { $multi[] = \json_decode($c, true); From 911ef7c6cac37359f5bc43ab30f89271b2c2c2e5 Mon Sep 17 00:00:00 2001 From: Thijs De Paepe Date: Thu, 5 Dec 2024 15:36:45 +0100 Subject: [PATCH 2/5] fix: format: replace can be an empty string --- src/Component/Action/FormatAction.php | 2 +- tests/Component/Action/FormatActionTest.php | 29 +++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/Component/Action/FormatAction.php b/src/Component/Action/FormatAction.php index 76ad65ca..2c4a3694 100644 --- a/src/Component/Action/FormatAction.php +++ b/src/Component/Action/FormatAction.php @@ -59,7 +59,7 @@ private function doApply($value) foreach ($this->getOption('functions') as $function) { switch ($function) { case 'replace': - if ($this->getOption('search') && $this->getOption('replace')) { + if ($this->getOption('search') && $this->getOption('replace') !== null) { $value = str_replace($this->getOption('search'), $this->getOption('replace'), $value); } break; diff --git a/tests/Component/Action/FormatActionTest.php b/tests/Component/Action/FormatActionTest.php index ff93e0b2..e1d534b1 100644 --- a/tests/Component/Action/FormatActionTest.php +++ b/tests/Component/Action/FormatActionTest.php @@ -73,6 +73,35 @@ public function testApplyEmptyNumberFunction() $this->assertEquals(['field' => ''], $result); } + public function testEmptyReplaceFormatFunction() + { + $item = ['field' => 'A|,B|,C|,D']; + + $action = new FormatAction(); + $action->setOptions([ + 'field' => 'field', + 'functions' => ['replace'], + 'search' => '|,', + 'replace' => '', + ]); + + $result = $action->apply($item); + + $this->assertEquals(['field' => 'ABCD'], $result); + + $action = new FormatAction(); + $action->setOptions([ + 'field' => 'field', + 'functions' => ['replace'], + 'search' => '', + 'replace' => null, + ]); + + $result = $action->apply($item); + + $this->assertEquals(['field' => 'A|,B|,C|,D'], $result); + } + public function testApplyPrefixFunction() { $item = ['field' => '12345']; From 1b1813c6860acd3a76c11753e85b85c4e4d95e35 Mon Sep 17 00:00:00 2001 From: Jonas De Gauquier Date: Thu, 5 Dec 2024 15:55:16 +0100 Subject: [PATCH 3/5] Fixed store action lists (#94) * Fixed store action lists * Added test for configuration --- src/Component/Action/StoreAction.php | 11 +- .../Common/Collection/ArrayCollection.php | 12 ++ src/Component/Configurator/Configuration.php | 42 +++- .../Configurator/ReadOnlyConfiguration.php | 2 +- .../Configurator/ConfigurationTest.php | 197 ++++++++++++++++++ 5 files changed, 252 insertions(+), 12 deletions(-) create mode 100644 tests/Component/Configurator/ConfigurationTest.php diff --git a/src/Component/Action/StoreAction.php b/src/Component/Action/StoreAction.php index fba31a98..c6986d24 100644 --- a/src/Component/Action/StoreAction.php +++ b/src/Component/Action/StoreAction.php @@ -95,12 +95,11 @@ public function apply(array $item): array // start true_action // make changes list $changes = $changeManager->getChanges($identifier, $entity.'.values'); - $this->configuration->addLists([ - 'product_changes_fields_added' => $changes['added'], - 'product_changes_fields_deleted' => $changes['deleted'], - 'product_changes_fields_updated' => $changes['updated'], - 'product_changes_fields_all' => $changes['all'], - ]); + + $this->configuration->updateList('product_changes_fields_added', $changes['added']); + $this->configuration->updateList('product_changes_fields_deleted', $changes['deleted']); + $this->configuration->updateList('product_changes_fields_updated', $changes['updated']); + $this->configuration->updateList('product_changes_fields_all', $changes['all']); // see GroupAction, get ActionProcessor, process your action(s) if ([] !== $trueAction) { diff --git a/src/Component/Common/Collection/ArrayCollection.php b/src/Component/Common/Collection/ArrayCollection.php index d918a891..5b2bec40 100644 --- a/src/Component/Common/Collection/ArrayCollection.php +++ b/src/Component/Common/Collection/ArrayCollection.php @@ -65,4 +65,16 @@ public function getValues(): array { return $this->items; } + + public function addValues(array $items): void + { + foreach (array_filter($items) as $key => $item) { + $this->set($key, $item); + } + } + + public function purge(): void + { + $this->items = []; + } } \ No newline at end of file diff --git a/src/Component/Configurator/Configuration.php b/src/Component/Configurator/Configuration.php index c806ce6e..9e03197e 100644 --- a/src/Component/Configurator/Configuration.php +++ b/src/Component/Configurator/Configuration.php @@ -35,6 +35,7 @@ class Configuration private $decoders; private $reader; private $writer; + /** @var ArrayCollection[] $lists */ private $lists = []; private $mappings = []; private $filters = []; @@ -144,7 +145,7 @@ public function setActions(ItemActionProcessor $actionProcessor): void { $this->actions = $actionProcessor; } - + public function setActionFactory(ItemActionProcessorFactory $factory): void { $this->actionFactory = $factory; @@ -194,17 +195,43 @@ public function addBlueprints(ArrayCollection $collection): void public function addLists(array $lists): void { - $this->lists = array_merge($this->lists, $lists); + foreach ($lists as $listName => $list) { + $this->addList($listName, $list); + } + } + + public function addList(string $listName, array $list): void + { + $this->lists[$listName] = new ArrayCollection($list); + } + + public function updateList(string $listName, array $list): void + { + /** @var ArrayCollection $currentList */ + $currentList = $this->getListObject($listName); + if ($currentList === null) { + $this->addList($listName, $list); + return; + } + + $currentList->purge(); + $currentList->addValues($list); } public function getLists(): array { - return $this->lists; + return array_map(function ($list) { + return $list->getValues(); + }, $this->lists); } - public function getList(string $alias) + public function getList(string $alias): ?array { - return $this->lists[$alias] ?? null; + if (!isset($this->lists[$alias])) { + return null; + } + + return $this->lists[$alias]->getValues(); } public function addFilters(array $filters): void @@ -333,4 +360,9 @@ public function clear(): void $this->decoders = new ArrayCollection(); $this->blueprints = new ArrayCollection(); } + + private function getListObject(string $alias): ?ArrayCollection + { + return $this->lists[$alias] ?? null; + } } \ No newline at end of file diff --git a/src/Component/Configurator/ReadOnlyConfiguration.php b/src/Component/Configurator/ReadOnlyConfiguration.php index d60219c9..5c7083a7 100644 --- a/src/Component/Configurator/ReadOnlyConfiguration.php +++ b/src/Component/Configurator/ReadOnlyConfiguration.php @@ -49,7 +49,7 @@ public function getLists(): array public function getList(string $alias) { - return $this->lists[$alias] ?? null; + return $this->lists[$alias]?->getValues(); } public function getFilter(string $alias) diff --git a/tests/Component/Configurator/ConfigurationTest.php b/tests/Component/Configurator/ConfigurationTest.php new file mode 100644 index 00000000..178d5005 --- /dev/null +++ b/tests/Component/Configurator/ConfigurationTest.php @@ -0,0 +1,197 @@ +createMock(Pipeline::class); + + $configuration->setPipeline($pipeline); + + $this->assertSame($pipeline, $configuration->getPipeline()); + } + + public function testSetAndGetExtensions() + { + $configuration = new Configuration(); + + // Create a mock for LocalFileManager + $fileManager = $this->createMock(LocalFileManager::class); + + // Simulate a generator using a closure + $fileManager->method('listFiles')->willReturn((function () { + yield '/path/to/file1.txt'; + yield '/path/to/file2.txt'; + })()); + + // Set extensions using the mock + $configuration->setExtensions($fileManager); + + // Retrieve and verify the extensions + $extensions = $configuration->getExtensions(); + + $this->assertCount(2, $extensions); + $this->assertArrayHasKey('file1.txt', $extensions); + $this->assertArrayHasKey('file2.txt', $extensions); + $this->assertInstanceOf(\SplFileInfo::class, $extensions['file1.txt']); + $this->assertInstanceOf(\SplFileInfo::class, $extensions['file2.txt']); + } + + public function testIsMultiStep() + { + $configuration = new Configuration(); + + $this->assertFalse($configuration->isMultiStep()); + + $configuration->setAsMultiStep(); + + $this->assertTrue($configuration->isMultiStep()); + } + + public function testAddAndGetContext() + { + $configuration = new Configuration(); + $context = ['key1' => 'value1', 'key2' => 'value2']; + + $configuration->addContext($context); + + $this->assertEquals($context, $configuration->getContext()); + $this->assertEquals('value1', $configuration->getContext('key1')); + $this->assertNull($configuration->getContext('nonexistent_key')); + } + + public function testAddAndGetAccount() + { + $configuration = new Configuration(); + $apiClient = $this->createMock(ApiClientInterface::class); + + $configuration->addAccount('test', $apiClient); + + $this->assertSame($apiClient, $configuration->getAccount('test')); + $this->assertNull($configuration->getAccount('nonexistent')); + } + + public function testSetAndGetShellCommands() + { + $configuration = new Configuration(); + $shellCommands = $this->createMock(ShellCommands::class); + + $configuration->setShellCommands($shellCommands); + + $this->assertSame($shellCommands, $configuration->getShellCommands()); + + $configuration->clearShellCommands(); + + $this->assertNull($configuration->getShellCommands()); + } + + public function testAddAndGetBlueprints() + { + $configuration = new Configuration(); + $bluePrint1 = $this->createMock(BluePrint::class); + $bluePrint1->method('getName')->willReturn('blueprint1'); + $bluePrint2 = $this->createMock(BluePrint::class); + $bluePrint2->method('getName')->willReturn('blueprint2'); + + $configuration->addBlueprint($bluePrint1); + $configuration->addBlueprint($bluePrint2); + + $this->assertSame($bluePrint1, $configuration->getBlueprint('blueprint1')); + $this->assertFalse($configuration->getBlueprint('nonexistent')); + } + + public function testAddAndGetSources() + { + $configuration = new Configuration(); + $sourceCollection = $this->createMock(SourceCollection::class); + + $configuration->addSources($sourceCollection); + + $this->assertSame($sourceCollection, $configuration->getSources()); + } + + public function testSetAndGetReader() + { + $configuration = new Configuration(); + $reader = $this->createMock(ReaderInterface::class); + + $configuration->setReader($reader); + + $this->assertSame($reader, $configuration->getReader()); + } + + public function testSetAndGetWriter() + { + $configuration = new Configuration(); + $writer = $this->createMock(ItemWriterInterface::class); + + $configuration->setWriter($writer); + + $this->assertSame($writer, $configuration->getWriter()); + } + + public function testClearConfiguration() + { + $configuration = new Configuration(); + $writer = $this->createMock(ItemWriterInterface::class); + + $configuration->setWriter($writer); + + $configuration->clear(); + + $this->assertNull($configuration->getWriter()); + $this->assertNull($configuration->getPipeline()); + } + + public function testAddAndGetLists() + { + $configuration = new Configuration(); + + // Adding lists + $list1 = ['item1', 'item2', 'item3']; + $list2 = ['itemA', 'itemB', 'itemC']; + + $configuration->addList('list1', $list1); + $configuration->addList('list2', $list2); + + // Retrieving lists + $lists = $configuration->getLists(); + + $this->assertCount(2, $lists); + $this->assertArrayHasKey('list1', $lists); + $this->assertArrayHasKey('list2', $lists); + + $this->assertEquals($list1, $lists['list1']); + $this->assertEquals($list2, $lists['list2']); + + // Updating a list + $updatedList = ['itemX', 'itemY', 'itemZ']; + $configuration->updateList('list1', $updatedList); + + $updatedLists = $configuration->getLists(); + + $this->assertEquals($updatedList, $updatedLists['list1']); + + // Retrieving a single list + $retrievedList = $configuration->getList('list1'); + $this->assertEquals($updatedList, $retrievedList); + + // Non-existent list + $nonExistentList = $configuration->getList('nonexistent'); + $this->assertNull($nonExistentList); + } +} \ No newline at end of file From 1e548051a8ebbfe1a7a6ab2261cdca1422632dae Mon Sep 17 00:00:00 2001 From: Jonas De Gauquier Date: Fri, 6 Dec 2024 11:42:13 +0100 Subject: [PATCH 4/5] Fixed Call to a member function getValues() on array (#95) --- src/Component/Configurator/Configuration.php | 4 +--- src/Component/Configurator/ReadOnlyConfiguration.php | 4 +++- tests/Component/Configurator/ConfigurationTest.php | 10 +++++++--- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/Component/Configurator/Configuration.php b/src/Component/Configurator/Configuration.php index 9e03197e..3450772a 100644 --- a/src/Component/Configurator/Configuration.php +++ b/src/Component/Configurator/Configuration.php @@ -220,9 +220,7 @@ public function updateList(string $listName, array $list): void public function getLists(): array { - return array_map(function ($list) { - return $list->getValues(); - }, $this->lists); + return $this->lists; } public function getList(string $alias): ?array diff --git a/src/Component/Configurator/ReadOnlyConfiguration.php b/src/Component/Configurator/ReadOnlyConfiguration.php index 5c7083a7..9ef74977 100644 --- a/src/Component/Configurator/ReadOnlyConfiguration.php +++ b/src/Component/Configurator/ReadOnlyConfiguration.php @@ -44,7 +44,9 @@ public function getSources(): SourceCollection public function getLists(): array { - return $this->lists; + return array_map(function ($list) { + return $list->getValues(); + }, $this->lists); } public function getList(string $alias) diff --git a/tests/Component/Configurator/ConfigurationTest.php b/tests/Component/Configurator/ConfigurationTest.php index 178d5005..6e01aac7 100644 --- a/tests/Component/Configurator/ConfigurationTest.php +++ b/tests/Component/Configurator/ConfigurationTest.php @@ -2,6 +2,7 @@ namespace Tests\Misery\Component\Configurator; +use Misery\Component\Common\Collection\ArrayCollection; use PHPUnit\Framework\TestCase; use Misery\Component\Configurator\Configuration; use Misery\Component\Common\Client\ApiClientInterface; @@ -175,8 +176,10 @@ public function testAddAndGetLists() $this->assertArrayHasKey('list1', $lists); $this->assertArrayHasKey('list2', $lists); - $this->assertEquals($list1, $lists['list1']); - $this->assertEquals($list2, $lists['list2']); + $collection1 = new ArrayCollection($list1); + $collection2 = new ArrayCollection($list2); + $this->assertEquals($collection1, $lists['list1']); + $this->assertEquals($collection2, $lists['list2']); // Updating a list $updatedList = ['itemX', 'itemY', 'itemZ']; @@ -184,7 +187,8 @@ public function testAddAndGetLists() $updatedLists = $configuration->getLists(); - $this->assertEquals($updatedList, $updatedLists['list1']); + $updatedCollectionList = new ArrayCollection($updatedList); + $this->assertEquals($updatedCollectionList, $updatedLists['list1']); // Retrieving a single list $retrievedList = $configuration->getList('list1'); From dad10b7d77f680d88c9ca464829b4f5e59cbe3a1 Mon Sep 17 00:00:00 2001 From: Jonas De Gauquier Date: Fri, 6 Dec 2024 15:51:52 +0100 Subject: [PATCH 5/5] Fixed patch endpoints (#96) --- src/Component/Akeneo/Client/ApiAttributesEndpoint.php | 2 +- src/Component/Akeneo/Client/ApiCategoriesEndpoint.php | 2 +- src/Component/Akeneo/Client/ApiFamiliesEndpoint.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Component/Akeneo/Client/ApiAttributesEndpoint.php b/src/Component/Akeneo/Client/ApiAttributesEndpoint.php index c20c991a..61661614 100644 --- a/src/Component/Akeneo/Client/ApiAttributesEndpoint.php +++ b/src/Component/Akeneo/Client/ApiAttributesEndpoint.php @@ -9,7 +9,7 @@ class ApiAttributesEndpoint implements ApiEndpointInterface public const NAME = 'attributes'; private const ALL = 'attributes'; - private const ONE = 'attributes/%s'; + private const ONE = 'attributes/%code%'; public function getAll(): string { diff --git a/src/Component/Akeneo/Client/ApiCategoriesEndpoint.php b/src/Component/Akeneo/Client/ApiCategoriesEndpoint.php index e69e459a..3e26cadc 100644 --- a/src/Component/Akeneo/Client/ApiCategoriesEndpoint.php +++ b/src/Component/Akeneo/Client/ApiCategoriesEndpoint.php @@ -8,7 +8,7 @@ class ApiCategoriesEndpoint implements ApiEndpointInterface { public const NAME = 'categories'; private const ALL = 'categories'; - private const ONE = 'categories/%s'; + private const ONE = 'categories/%code%'; public function getAll(): string { diff --git a/src/Component/Akeneo/Client/ApiFamiliesEndpoint.php b/src/Component/Akeneo/Client/ApiFamiliesEndpoint.php index 089a8613..3215e7f2 100644 --- a/src/Component/Akeneo/Client/ApiFamiliesEndpoint.php +++ b/src/Component/Akeneo/Client/ApiFamiliesEndpoint.php @@ -8,7 +8,7 @@ class ApiFamiliesEndpoint implements ApiEndpointInterface { public const NAME = 'families'; private const ALL = 'families'; - private const ONE = 'families/%s'; + private const ONE = 'families/%code%'; public function getAll(): string {