diff --git a/.ci/Jenkinsfile b/.ci/Jenkinsfile index 1f43117a..2438cf8c 100644 --- a/.ci/Jenkinsfile +++ b/.ci/Jenkinsfile @@ -385,6 +385,9 @@ def runPim2IntegrationTest(String phpVersion, String client, String psrImplem, S def files = [] // Find and store PHP test integration files to launch them in parallels + if ("2.1" == pimVersion) { + files += sh (returnStdout: true, script: 'find /home/jenkins/php-api-client/tests/v2_1/Api -name "*Integration.php"').tokenize('\n') + } files += sh (returnStdout: true, script: 'find /home/jenkins/php-api-client/tests/v2_0/Api -name "*Integration.php"').tokenize('\n') files += sh (returnStdout: true, script: 'find /home/jenkins/php-api-client/tests/Common/Api -name "*Integration.php"').tokenize('\n') for (file in files) { diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 774edcf0..3363f85d 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -25,4 +25,10 @@ tests/v2_0/Api/* + + tests/Common/Api/* + tests/v2_0/Api/* + tests/v2_1/Api/* + + diff --git a/spec/Api/AttributeOptionApiSpec.php b/spec/Api/AttributeOptionApiSpec.php index 171f29c5..881d187c 100644 --- a/spec/Api/AttributeOptionApiSpec.php +++ b/spec/Api/AttributeOptionApiSpec.php @@ -10,6 +10,7 @@ use Akeneo\Pim\ApiClient\Pagination\PageInterface; use Akeneo\Pim\ApiClient\Pagination\ResourceCursorFactoryInterface; use Akeneo\Pim\ApiClient\Pagination\ResourceCursorInterface; +use Akeneo\Pim\ApiClient\Stream\UpsertResourceListResponse; use PhpSpec\ObjectBehavior; class AttributeOptionApiSpec extends ObjectBehavior @@ -149,4 +150,17 @@ function it_upserts_an_attribute_option($resourceClient) ->upsert('foo', 'bar', ['code' => 'bar', 'attribute' => 'foo', 'sort_order' => 42]) ->shouldReturn(204); } + + function it_upserts_a_list_of_attribute_options($resourceClient, UpsertResourceListResponse $response) + { + $resourceClient->upsertResourceList(AttributeOptionApi::ATTRIBUTE_OPTIONS_URI, ['foo'], [ + ['code' => 'bar', 'attribute' => 'foo', 'sort_order' => 42], + ['code' => 'fighters', 'attribute' => 'foo', 'sort_order' => 43] + ])->willReturn($response); + + $this->upsertList('foo', [ + ['code' => 'bar', 'attribute' => 'foo', 'sort_order' => 42], + ['code' => 'fighters', 'attribute' => 'foo', 'sort_order' => 43] + ])->shouldReturn($response); + } } diff --git a/src/Api/AttributeOptionApi.php b/src/Api/AttributeOptionApi.php index e5081223..6fd47e95 100644 --- a/src/Api/AttributeOptionApi.php +++ b/src/Api/AttributeOptionApi.php @@ -98,4 +98,12 @@ public function upsert($attributeCode, $attributeOptionCode, array $data = []) { return $this->resourceClient->upsertResource(static::ATTRIBUTE_OPTION_URI, [$attributeCode, $attributeOptionCode], $data); } + + /** + * {@inheritdoc} + */ + public function upsertList($attributeCode, $attributeOptions) + { + return $this->resourceClient->upsertResourceList(static::ATTRIBUTE_OPTIONS_URI, [$attributeCode], $attributeOptions); + } } diff --git a/src/Api/AttributeOptionApiInterface.php b/src/Api/AttributeOptionApiInterface.php index ce9bb642..c0884bff 100644 --- a/src/Api/AttributeOptionApiInterface.php +++ b/src/Api/AttributeOptionApiInterface.php @@ -85,4 +85,16 @@ public function create($attributeCode, $attributeOptionCode, array $data = []); * @return int returns either http code 201 if the attribute option has been created or 204 if it has been updated */ public function upsert($attributeCode, $attributeOptionCode, array $data = []); + + /** + * Updates or creates several attribute options at once. + * + * @param string $attributeCode code of the attribute + * @param array|StreamInterface $attributeOptions array or StreamInterface object containing data of the attribute options to create or update + * + * @throws HttpException + * + * @return \Traversable returns an iterable object, each entry corresponding to the response of the upserted attribute options + */ + public function upsertList($attributeCode, $attributeOptions); } diff --git a/tests/v2_1/Api/AttributeOption/UpsertListAttributeOptionIntegration.php b/tests/v2_1/Api/AttributeOption/UpsertListAttributeOptionIntegration.php new file mode 100644 index 00000000..567844d0 --- /dev/null +++ b/tests/v2_1/Api/AttributeOption/UpsertListAttributeOptionIntegration.php @@ -0,0 +1,94 @@ +createClient()->getAttributeOptionApi(); + $response = $api->upsertList('weather_conditions', [ + [ + 'code' => 'hot', + 'attribute' => 'weather_conditions', + 'sort_order' => 34, + 'labels' => [ + 'en_US' => 'Hot!', + ], + ], + [ + 'code' => 'cloudy', + 'attribute' => 'weather_conditions', + 'sort_order' => 35, + 'labels' => [ + 'en_US' => 'Cloudy', + ], + + ], + ]); + + $this->assertInstanceOf('\Iterator', $response); + + $responseLines = iterator_to_array($response); + $this->assertCount(2, $responseLines); + + $this->assertSame([ + 'line' => 1, + 'code' => 'hot', + 'status_code' => 204, + ], $responseLines[1]); + + $this->assertSame([ + 'line' => 2, + 'code' => 'cloudy', + 'status_code' => 201, + ], $responseLines[2]); + } + + public function testUpsertListFailed() + { + $api = $this->createClient()->getAttributeOptionApi(); + $response = $api->upsertList('weather_conditions', [ + [ + 'attribute' => 'weather_conditions', + 'sort_order' => 34, + 'labels' => [ + 'en_US' => 'Hot!', + ], + ], + [ + 'code' => 'cloudy!', + 'attribute' => 'weather_conditions', + 'sort_order' => 35, + 'labels' => [ + 'en_US' => 'Cloudy', + ], + + ], + ]); + + $this->assertInstanceOf('\Iterator', $response); + + $responseLines = iterator_to_array($response); + $this->assertCount(2, $responseLines); + + $this->assertSame([ + 'line' => 1, + 'status_code' => 422, + 'message' => 'Code is missing.', + ], $responseLines[1]); + + $this->assertSame([ + 'line' => 2, + 'code' => 'cloudy!', + 'status_code' => 422, + 'message' => 'Validation failed.', + 'errors' => [[ + 'property' => 'code', + 'message' => 'Option code may contain only letters, numbers and underscores' + ]] + ], $responseLines[2]); + } +}