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]);
+ }
+}