mirror of
https://github.com/Sylius/Sylius.git
synced 2026-07-14 17:10:53 +00:00
[API][Admin] Extend GET endpoints for getting product variants
This commit is contained in:
parent
a88c39a9de
commit
dead3ac6cd
9 changed files with 511 additions and 237 deletions
|
|
@ -27,8 +27,8 @@
|
|||
<group>shop:product_variant:read</group>
|
||||
</attribute>
|
||||
<attribute name="translations">
|
||||
<group>admin:product_variant:create</group>
|
||||
<group>admin:product_variant:read</group>
|
||||
<group>admin:product_variant:create</group>
|
||||
<group>admin:product_variant:update</group>
|
||||
</attribute>
|
||||
<attribute name="optionValues">
|
||||
|
|
@ -36,8 +36,8 @@
|
|||
<group>shop:product_variant:read</group>
|
||||
</attribute>
|
||||
<attribute name="channelPricings">
|
||||
<group>admin:product_variant:create</group>
|
||||
<group>admin:product_variant:read</group>
|
||||
<group>admin:product_variant:create</group>
|
||||
<group>admin:product_variant:update</group>
|
||||
</attribute>
|
||||
<attribute name="name">
|
||||
|
|
@ -48,5 +48,44 @@
|
|||
<group>admin:product_variant:create</group>
|
||||
<group>admin:product_variant:update</group>
|
||||
</attribute>
|
||||
<attribute name="position">
|
||||
<group>admin:product_variant:read</group>
|
||||
</attribute>
|
||||
<attribute name="tracked">
|
||||
<group>admin:product_variant:read</group>
|
||||
</attribute>
|
||||
<attribute name="onHold">
|
||||
<group>admin:product_variant:read</group>
|
||||
</attribute>
|
||||
<attribute name="onHand">
|
||||
<group>admin:product_variant:read</group>
|
||||
</attribute>
|
||||
<attribute name="weight">
|
||||
<group>admin:product_variant:read</group>
|
||||
</attribute>
|
||||
<attribute name="width">
|
||||
<group>admin:product_variant:read</group>
|
||||
</attribute>
|
||||
<attribute name="height">
|
||||
<group>admin:product_variant:read</group>
|
||||
</attribute>
|
||||
<attribute name="depth">
|
||||
<group>admin:product_variant:read</group>
|
||||
</attribute>
|
||||
<attribute name="taxCategory">
|
||||
<group>admin:product_variant:read</group>
|
||||
</attribute>
|
||||
<attribute name="shippingCategory">
|
||||
<group>admin:product_variant:read</group>
|
||||
</attribute>
|
||||
<attribute name="shippingRequired">
|
||||
<group>admin:product_variant:read</group>
|
||||
</attribute>
|
||||
<attribute name="createdAt">
|
||||
<group>admin:product_variant:read</group>
|
||||
</attribute>
|
||||
<attribute name="updatedAt">
|
||||
<group>admin:product_variant:read</group>
|
||||
</attribute>
|
||||
</class>
|
||||
</serializer>
|
||||
|
|
|
|||
|
|
@ -17,25 +17,26 @@
|
|||
>
|
||||
<class name="Sylius\Component\Product\Model\ProductVariantTranslation">
|
||||
<attribute name="id">
|
||||
<group>shop:order:account:read</group>
|
||||
<group>admin:product_variant:read</group>
|
||||
<group>admin:order:read</group>
|
||||
<group>shop:product_variant:read</group>
|
||||
<group>shop:order:account:read</group>
|
||||
</attribute>
|
||||
<attribute name="name">
|
||||
<group>shop:order:account:read</group>
|
||||
<group>admin:order:read</group>
|
||||
<group>admin:product_variant:read</group>
|
||||
<group>admin:product_variant:create</group>
|
||||
<group>admin:product_variant:update</group>
|
||||
<group>admin:product_variant:read</group>
|
||||
<group>admin:order:read</group>
|
||||
<group>shop:product_variant:read</group>
|
||||
<group>shop:order:account:read</group>
|
||||
</attribute>
|
||||
<attribute name="locale">
|
||||
<group>shop:order:account:read</group>
|
||||
<group>admin:order:read</group>
|
||||
<group>admin:product_variant:read</group>
|
||||
<group>admin:product_variant:create</group>
|
||||
<group>admin:product_variant:update</group>
|
||||
<group>admin:product_variant:read</group>
|
||||
<group>admin:order:read</group>
|
||||
<group>shop:product_variant:read</group>
|
||||
<group>shop:order:account:read</group>
|
||||
</attribute>
|
||||
</class>
|
||||
</serializer>
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@ declare(strict_types=1);
|
|||
namespace Sylius\Tests\Api\Admin;
|
||||
|
||||
use Sylius\Component\Core\Model\ChannelInterface;
|
||||
use Sylius\Component\Core\Model\ProductInterface;
|
||||
use Sylius\Component\Core\Model\ProductVariantInterface;
|
||||
use Sylius\Tests\Api\JsonApiTestCase;
|
||||
use Sylius\Tests\Api\Utils\AdminUserLoginTrait;
|
||||
|
|
@ -25,9 +24,14 @@ final class ProductVariantsTest extends JsonApiTestCase
|
|||
use AdminUserLoginTrait;
|
||||
|
||||
/** @test */
|
||||
public function it_denies_access_to_a_products_list_for_not_authenticated_user(): void
|
||||
public function it_denies_access_to_a_product_variants_list_for_not_authenticated_user(): void
|
||||
{
|
||||
$this->loadFixturesFromFiles(['channel.yaml', 'product/product_variant.yaml']);
|
||||
$this->loadFixturesFromFiles([
|
||||
'channel.yaml',
|
||||
'tax_category.yaml',
|
||||
'shipping_category.yaml',
|
||||
'product/product_variant.yaml',
|
||||
]);
|
||||
|
||||
$this->client->request('GET', '/api/v2/admin/product-variants');
|
||||
|
||||
|
|
@ -38,7 +42,13 @@ final class ProductVariantsTest extends JsonApiTestCase
|
|||
/** @test */
|
||||
public function it_gets_all_product_variants(): void
|
||||
{
|
||||
$this->loadFixturesFromFiles(['channel.yaml', 'product/product_variant.yaml', 'authentication/api_administrator.yaml']);
|
||||
$this->loadFixturesFromFiles([
|
||||
'authentication/api_administrator.yaml',
|
||||
'channel.yaml',
|
||||
'tax_category.yaml',
|
||||
'shipping_category.yaml',
|
||||
'product/product_variant.yaml',
|
||||
]);
|
||||
$header = array_merge($this->logInAdminUser('api@example.com'), self::CONTENT_TYPE_HEADER);
|
||||
|
||||
$this->client->request(
|
||||
|
|
@ -54,7 +64,13 @@ final class ProductVariantsTest extends JsonApiTestCase
|
|||
/** @test */
|
||||
public function it_gets_a_product_variant(): void
|
||||
{
|
||||
$fixtures = $this->loadFixturesFromFiles(['channel.yaml', 'product/product_variant.yaml', 'authentication/api_administrator.yaml']);
|
||||
$fixtures = $this->loadFixturesFromFiles([
|
||||
'authentication/api_administrator.yaml',
|
||||
'channel.yaml',
|
||||
'tax_category.yaml',
|
||||
'shipping_category.yaml',
|
||||
'product/product_variant.yaml',
|
||||
]);
|
||||
$header = array_merge($this->logInAdminUser('api@example.com'), self::CONTENT_TYPE_HEADER);
|
||||
|
||||
/** @var ProductVariantInterface $productVariant */
|
||||
|
|
@ -70,10 +86,217 @@ final class ProductVariantsTest extends JsonApiTestCase
|
|||
$this->assertResponse($response, 'admin/product_variant/get_product_variant_response', Response::HTTP_OK);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_creates_product_variant_enabled_by_default(): void
|
||||
{
|
||||
$this->loadFixturesFromFiles([
|
||||
'authentication/api_administrator.yaml',
|
||||
'channel.yaml',
|
||||
'tax_category.yaml',
|
||||
'shipping_category.yaml',
|
||||
'product/product_variant.yaml',
|
||||
]);
|
||||
$header = array_merge($this->logInAdminUser('api@example.com'), self::CONTENT_TYPE_HEADER);
|
||||
|
||||
$this->client->request(
|
||||
method: 'POST',
|
||||
uri: '/api/v2/admin/product-variants',
|
||||
server: $header,
|
||||
content: json_encode([
|
||||
'code' => 'MUG_3',
|
||||
'position' => 1,
|
||||
'product' => '/api/v2/admin/products/MUG_SW',
|
||||
'channelPricings' => ['WEB' => [
|
||||
'channelCode' => 'WEB',
|
||||
'price' => 4000,
|
||||
'originalPrice' => 5000,
|
||||
'minimumPrice' => 2000,
|
||||
]],
|
||||
'translations' => [
|
||||
'en_US' => [
|
||||
'locale' => 'en_US',
|
||||
'name' => 'Yellow mug',
|
||||
],
|
||||
],
|
||||
], JSON_THROW_ON_ERROR),
|
||||
);
|
||||
|
||||
$this->assertResponse(
|
||||
$this->client->getResponse(),
|
||||
'admin/product_variant/post_product_variant_response',
|
||||
Response::HTTP_CREATED,
|
||||
);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_creates_disabled_product_variant(): void
|
||||
{
|
||||
$this->loadFixturesFromFiles([
|
||||
'authentication/api_administrator.yaml',
|
||||
'channel.yaml',
|
||||
'tax_category.yaml',
|
||||
'shipping_category.yaml',
|
||||
'product/product_variant.yaml',
|
||||
]);
|
||||
$header = array_merge($this->logInAdminUser('api@example.com'), self::CONTENT_TYPE_HEADER);
|
||||
|
||||
$this->client->request(
|
||||
method: 'POST',
|
||||
uri: '/api/v2/admin/product-variants',
|
||||
server: $header,
|
||||
content: json_encode([
|
||||
'code' => 'MUG_3',
|
||||
'position' => 1,
|
||||
'product' => '/api/v2/admin/products/MUG_SW',
|
||||
'channelPricings' => ['WEB' => [
|
||||
'channelCode' => 'WEB',
|
||||
'price' => 4000,
|
||||
'originalPrice' => 5000,
|
||||
'minimumPrice' => 2000,
|
||||
]],
|
||||
'enabled' => false,
|
||||
], JSON_THROW_ON_ERROR),
|
||||
);
|
||||
|
||||
$this->assertResponse(
|
||||
$this->client->getResponse(),
|
||||
'admin/product_variant/post_product_variant_disabled_response',
|
||||
Response::HTTP_CREATED,
|
||||
);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_does_not_allow_to_create_product_variant_with_invalid_channel_code(): void
|
||||
{
|
||||
$this->loadFixturesFromFiles([
|
||||
'authentication/api_administrator.yaml',
|
||||
'channel.yaml',
|
||||
'tax_category.yaml',
|
||||
'shipping_category.yaml',
|
||||
'product/product_variant.yaml',
|
||||
]);
|
||||
$header = array_merge($this->logInAdminUser('api@example.com'), self::CONTENT_TYPE_HEADER);
|
||||
|
||||
$this->client->request(
|
||||
method: 'POST',
|
||||
uri: '/api/v2/admin/product-variants',
|
||||
server: $header,
|
||||
content: json_encode([
|
||||
'code' => 'CUP',
|
||||
'product' => '/api/v2/admin/products/MUG_SW',
|
||||
'channelPricings' => ['NON-EXISTING-CHANNEL' => [
|
||||
'channelCode' => 'NON-EXISTING-CHANNEL',
|
||||
'price' => 4000,
|
||||
]],
|
||||
], JSON_THROW_ON_ERROR),
|
||||
);
|
||||
|
||||
$this->assertResponseCode($this->client->getResponse(), Response::HTTP_UNPROCESSABLE_ENTITY);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_does_not_allow_to_create_product_variant_without_channel_code(): void
|
||||
{
|
||||
$this->loadFixturesFromFiles([
|
||||
'authentication/api_administrator.yaml',
|
||||
'channel.yaml',
|
||||
'tax_category.yaml',
|
||||
'shipping_category.yaml',
|
||||
'product/product_variant.yaml',
|
||||
]);
|
||||
$header = array_merge($this->logInAdminUser('api@example.com'), self::CONTENT_TYPE_HEADER);
|
||||
|
||||
$this->client->request(
|
||||
method: 'POST',
|
||||
uri: '/api/v2/admin/product-variants',
|
||||
server: $header,
|
||||
content: json_encode([
|
||||
'code' => 'CUP',
|
||||
'product' => '/api/v2/admin/products/MUG_SW',
|
||||
'channelPricings' => [
|
||||
'NON-EXISTING-CHANNEL' => ['price' => 4000]
|
||||
],
|
||||
], JSON_THROW_ON_ERROR),
|
||||
);
|
||||
|
||||
$this->assertResponseCode($this->client->getResponse(), Response::HTTP_UNPROCESSABLE_ENTITY);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_does_not_allow_to_create_product_variant_without_product(): void
|
||||
{
|
||||
$this->loadFixturesFromFiles([
|
||||
'authentication/api_administrator.yaml',
|
||||
'channel.yaml',
|
||||
'tax_category.yaml',
|
||||
'shipping_category.yaml',
|
||||
'product/product_variant.yaml',
|
||||
]);
|
||||
$header = array_merge($this->logInAdminUser('api@example.com'), self::CONTENT_TYPE_HEADER);
|
||||
|
||||
$this->client->request(
|
||||
method: 'POST',
|
||||
uri: '/api/v2/admin/product-variants',
|
||||
server: $header,
|
||||
content: json_encode([
|
||||
'code' => 'CUP',
|
||||
'channelPricings' => ['WEB' => [
|
||||
'channelCode' => 'WEB',
|
||||
'price' => 4000,
|
||||
]],
|
||||
], JSON_THROW_ON_ERROR),
|
||||
);
|
||||
|
||||
$this->assertResponseCode($this->client->getResponse(), Response::HTTP_UNPROCESSABLE_ENTITY);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_does_not_allow_to_create_product_variant_with_invalid_locale_code(): void
|
||||
{
|
||||
$this->loadFixturesFromFiles([
|
||||
'authentication/api_administrator.yaml',
|
||||
'channel.yaml',
|
||||
'tax_category.yaml',
|
||||
'shipping_category.yaml',
|
||||
'product/product_variant.yaml',
|
||||
]);
|
||||
$header = array_merge($this->logInAdminUser('api@example.com'), self::CONTENT_TYPE_HEADER);
|
||||
|
||||
$this->client->request(
|
||||
method: 'POST',
|
||||
uri: '/api/v2/admin/product-variants',
|
||||
server: $header,
|
||||
content: json_encode([
|
||||
'code' => 'CUP',
|
||||
'product' => '/api/v2/admin/products/MUG_SW',
|
||||
'channelPricings' => ['WEB' => [
|
||||
'channelCode' => 'WEB',
|
||||
'price' => 4000,
|
||||
'originalPrice' => 5000,
|
||||
'minimumPrice' => 2000,
|
||||
]],
|
||||
'translations' => [
|
||||
'NON-EXISTING-LOCALE-CODE' => [
|
||||
'locale' => 'NON-EXISTING-LOCALE-CODE',
|
||||
'name' => 'Yellow mug',
|
||||
],
|
||||
],
|
||||
], JSON_THROW_ON_ERROR),
|
||||
);
|
||||
|
||||
$this->assertResponseCode($this->client->getResponse(), Response::HTTP_UNPROCESSABLE_ENTITY);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_updates_channel_pricing_and_translation_of_a_product_variant(): void
|
||||
{
|
||||
$fixtures = $this->loadFixturesFromFiles(['channel.yaml', 'product/product_variant.yaml', 'authentication/api_administrator.yaml']);
|
||||
$fixtures = $this->loadFixturesFromFiles([
|
||||
'authentication/api_administrator.yaml',
|
||||
'channel.yaml',
|
||||
'tax_category.yaml',
|
||||
'shipping_category.yaml',
|
||||
'product/product_variant.yaml',
|
||||
]);
|
||||
$header = array_merge($this->logInAdminUser('api@example.com'), self::CONTENT_TYPE_HEADER);
|
||||
|
||||
/** @var ProductVariantInterface $productVariant */
|
||||
|
|
@ -113,190 +336,16 @@ final class ProductVariantsTest extends JsonApiTestCase
|
|||
);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_creates_product_variant_enabled_by_default(): void
|
||||
{
|
||||
$fixtures = $this->loadFixturesFromFiles(['channel.yaml', 'product/product_variant.yaml', 'authentication/api_administrator.yaml']);
|
||||
$header = array_merge($this->logInAdminUser('api@example.com'), self::CONTENT_TYPE_HEADER);
|
||||
|
||||
/** @var ProductInterface $product */
|
||||
$product = $fixtures['product'];
|
||||
|
||||
$this->client->request(
|
||||
method: 'POST',
|
||||
uri: '/api/v2/admin/product-variants',
|
||||
server: $header,
|
||||
content: json_encode([
|
||||
'code' => 'MUG_2',
|
||||
'position' => 1,
|
||||
'product' => sprintf('/api/v2/admin/products/%s', $product->getCode()),
|
||||
'channelPricings' => ['WEB' => [
|
||||
'channelCode' => 'WEB',
|
||||
'price' => 4000,
|
||||
'originalPrice' => 5000,
|
||||
'minimumPrice' => 2000,
|
||||
]],
|
||||
'translations' => [
|
||||
'en_US' => [
|
||||
'locale' => 'en_US',
|
||||
'name' => 'Yellow mug',
|
||||
],
|
||||
],
|
||||
], JSON_THROW_ON_ERROR),
|
||||
);
|
||||
|
||||
$this->assertResponse(
|
||||
$this->client->getResponse(),
|
||||
'admin/product_variant/post_product_variant_response',
|
||||
Response::HTTP_CREATED,
|
||||
);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_creates_disabled_product_variant(): void
|
||||
{
|
||||
$fixtures = $this->loadFixturesFromFiles(['channel.yaml', 'product/product_variant.yaml', 'authentication/api_administrator.yaml']);
|
||||
$header = array_merge($this->logInAdminUser('api@example.com'), self::CONTENT_TYPE_HEADER);
|
||||
|
||||
/** @var ProductInterface $product */
|
||||
$product = $fixtures['product'];
|
||||
|
||||
$this->client->request(
|
||||
method: 'POST',
|
||||
uri: '/api/v2/admin/product-variants',
|
||||
server: $header,
|
||||
content: json_encode([
|
||||
'code' => 'MUG_2',
|
||||
'position' => 1,
|
||||
'product' => sprintf('/api/v2/admin/products/%s', $product->getCode()),
|
||||
'channelPricings' => ['WEB' => [
|
||||
'channelCode' => 'WEB',
|
||||
'price' => 4000,
|
||||
'originalPrice' => 5000,
|
||||
'minimumPrice' => 2000,
|
||||
]],
|
||||
'enabled' => false,
|
||||
], JSON_THROW_ON_ERROR),
|
||||
);
|
||||
|
||||
$this->assertResponse(
|
||||
$this->client->getResponse(),
|
||||
'admin/product_variant/post_product_variant_disabled_response',
|
||||
Response::HTTP_CREATED,
|
||||
);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_does_not_allow_to_create_product_variant_with_invalid_channel_code(): void
|
||||
{
|
||||
$fixtures = $this->loadFixturesFromFiles(['channel.yaml', 'product/product_variant.yaml', 'authentication/api_administrator.yaml']);
|
||||
$header = array_merge($this->logInAdminUser('api@example.com'), self::CONTENT_TYPE_HEADER);
|
||||
|
||||
/** @var ProductInterface $product */
|
||||
$product = $fixtures['product'];
|
||||
|
||||
$this->client->request(
|
||||
method: 'POST',
|
||||
uri: '/api/v2/admin/product-variants',
|
||||
server: $header,
|
||||
content: json_encode([
|
||||
'code' => 'CUP',
|
||||
'product' => sprintf('/api/v2/admin/products/%s', $product->getCode()),
|
||||
'channelPricings' => ['NON-EXISTING-CHANNEL' => [
|
||||
'channelCode' => 'NON-EXISTING-CHANNEL',
|
||||
'price' => 4000,
|
||||
]],
|
||||
], JSON_THROW_ON_ERROR),
|
||||
);
|
||||
|
||||
$this->assertResponseCode($this->client->getResponse(), Response::HTTP_UNPROCESSABLE_ENTITY);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_does_not_allow_to_create_product_variant_without_channel_code(): void
|
||||
{
|
||||
$fixtures = $this->loadFixturesFromFiles(['channel.yaml', 'product/product_variant.yaml', 'authentication/api_administrator.yaml']);
|
||||
$header = array_merge($this->logInAdminUser('api@example.com'), self::CONTENT_TYPE_HEADER);
|
||||
|
||||
/** @var ProductInterface $product */
|
||||
$product = $fixtures['product'];
|
||||
|
||||
$this->client->request(
|
||||
method: 'POST',
|
||||
uri: '/api/v2/admin/product-variants',
|
||||
server: $header,
|
||||
content: json_encode([
|
||||
'code' => 'CUP',
|
||||
'product' => sprintf('/api/v2/admin/products/%s', $product->getCode()),
|
||||
'channelPricings' => [
|
||||
'NON-EXISTING-CHANNEL' => ['price' => 4000]
|
||||
],
|
||||
], JSON_THROW_ON_ERROR),
|
||||
);
|
||||
|
||||
$this->assertResponseCode($this->client->getResponse(), Response::HTTP_UNPROCESSABLE_ENTITY);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_does_not_allow_to_create_product_variant_without_product(): void
|
||||
{
|
||||
$this->loadFixturesFromFiles(['channel.yaml', 'product/product_variant.yaml', 'authentication/api_administrator.yaml']);
|
||||
$header = array_merge($this->logInAdminUser('api@example.com'), self::CONTENT_TYPE_HEADER);
|
||||
|
||||
$this->client->request(
|
||||
method: 'POST',
|
||||
uri: '/api/v2/admin/product-variants',
|
||||
server: $header,
|
||||
content: json_encode([
|
||||
'code' => 'CUP',
|
||||
'channelPricings' => ['WEB' => [
|
||||
'channelCode' => 'WEB',
|
||||
'price' => 4000,
|
||||
]],
|
||||
], JSON_THROW_ON_ERROR),
|
||||
);
|
||||
|
||||
$this->assertResponseCode($this->client->getResponse(), Response::HTTP_UNPROCESSABLE_ENTITY);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_does_not_allow_to_create_product_variant_with_invalid_locale_code(): void
|
||||
{
|
||||
$fixtures = $this->loadFixturesFromFiles(['channel.yaml', 'product/product_variant.yaml', 'authentication/api_administrator.yaml']);
|
||||
$header = array_merge($this->logInAdminUser('api@example.com'), self::CONTENT_TYPE_HEADER);
|
||||
|
||||
/** @var ProductInterface $product */
|
||||
$product = $fixtures['product'];
|
||||
|
||||
$this->client->request(
|
||||
method: 'POST',
|
||||
uri: '/api/v2/admin/product-variants',
|
||||
server: $header,
|
||||
content: json_encode([
|
||||
'code' => 'CUP',
|
||||
'product' => sprintf('/api/v2/admin/products/%s', $product->getCode()),
|
||||
'channelPricings' => ['WEB' => [
|
||||
'channelCode' => 'WEB',
|
||||
'price' => 4000,
|
||||
'originalPrice' => 5000,
|
||||
'minimumPrice' => 2000,
|
||||
]],
|
||||
'translations' => [
|
||||
'NON-EXISTING-LOCALE-CODE' => [
|
||||
'locale' => 'NON-EXISTING-LOCALE-CODE',
|
||||
'name' => 'Yellow mug',
|
||||
],
|
||||
],
|
||||
], JSON_THROW_ON_ERROR),
|
||||
);
|
||||
|
||||
$this->assertResponseCode($this->client->getResponse(), Response::HTTP_UNPROCESSABLE_ENTITY);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_does_not_allow_to_update_product_variant_with_invalid_locale_code(): void
|
||||
{
|
||||
$fixtures = $this->loadFixturesFromFiles(['channel.yaml', 'product/product_variant.yaml', 'authentication/api_administrator.yaml']);
|
||||
$fixtures = $this->loadFixturesFromFiles([
|
||||
'authentication/api_administrator.yaml',
|
||||
'channel.yaml',
|
||||
'tax_category.yaml',
|
||||
'shipping_category.yaml',
|
||||
'product/product_variant.yaml',
|
||||
]);
|
||||
$header = array_merge($this->logInAdminUser('api@example.com'), self::CONTENT_TYPE_HEADER);
|
||||
|
||||
/** @var ProductVariantInterface $productVariant */
|
||||
|
|
|
|||
|
|
@ -2,28 +2,96 @@ Sylius\Component\Core\Model\Product:
|
|||
product:
|
||||
fallbackLocale: en_US
|
||||
currentLocale: en
|
||||
code: MUG_SW
|
||||
code: 'MUG_SW'
|
||||
|
||||
Sylius\Component\Product\Model\ProductVariantTranslation:
|
||||
product_variant_translation:
|
||||
name: 'Mug'
|
||||
locale: en_US
|
||||
translatable: '@product_variant'
|
||||
product_variant_2_translation:
|
||||
name: 'Mug 2'
|
||||
locale: en_US
|
||||
translatable: '@product_variant_2'
|
||||
|
||||
Sylius\Component\Core\Model\ProductVariant:
|
||||
product_variant:
|
||||
code: MUG
|
||||
code: 'MUG'
|
||||
version: 1
|
||||
product: '@product'
|
||||
fallbackLocale: en_US
|
||||
currentLocale: en
|
||||
position: 1
|
||||
optionValues: ['@product_option_value_color_blue']
|
||||
channelPricings:
|
||||
channel_web: '@product_variant_channel_web_pricing'
|
||||
translations:
|
||||
- '@product_variant_translation'
|
||||
enabled: true
|
||||
tracked: true
|
||||
onHold: 0
|
||||
onHand: 10
|
||||
weight: 100.50
|
||||
width: 100.50
|
||||
height: 100.50
|
||||
depth: 100.50
|
||||
taxCategory: '@tax_category_default'
|
||||
shippingCategory: '@shipping_category_default'
|
||||
shippingRequired: true
|
||||
product_variant_2:
|
||||
code: 'MUG_2'
|
||||
product: '@product'
|
||||
fallbackLocale: en_US
|
||||
currentLocale: en
|
||||
position: 2
|
||||
channelPricings:
|
||||
channel_web: '@product_variant_2_channel_web_pricing'
|
||||
translations:
|
||||
- '@product_variant_2_translation'
|
||||
|
||||
Sylius\Component\Core\Model\ChannelPricing:
|
||||
product_variant_channel_web_pricing:
|
||||
channelCode: 'WEB'
|
||||
price: 2000
|
||||
product_variant_2_channel_web_pricing:
|
||||
channelCode: 'WEB'
|
||||
price: 3000
|
||||
|
||||
Sylius\Component\Product\Model\ProductOption:
|
||||
product_option_color:
|
||||
code: 'COLOR'
|
||||
currentLocale: 'en_US'
|
||||
translations:
|
||||
- '@product_option_translation_en_EN'
|
||||
|
||||
Sylius\Component\Product\Model\ProductOptionTranslation:
|
||||
product_option_translation_en_EN:
|
||||
locale: 'en_US'
|
||||
name: 'Color'
|
||||
translatable: '@product_option_color'
|
||||
|
||||
Sylius\Component\Product\Model\ProductOptionValue:
|
||||
product_option_value_color_blue:
|
||||
code: 'COLOR_BLUE'
|
||||
currentLocale: 'en_US'
|
||||
fallbackLocale: 'en_US'
|
||||
option: '@product_option_color'
|
||||
translations:
|
||||
- '@product_option_value_translation_blue'
|
||||
product_option_value_color_red:
|
||||
code: 'COLOR_RED'
|
||||
currentLocale: 'en_US'
|
||||
fallbackLocale: 'en_US'
|
||||
option: '@product_option_color'
|
||||
translations:
|
||||
- '@product_option_value_translation_red'
|
||||
|
||||
Sylius\Component\Product\Model\ProductOptionValueTranslation:
|
||||
product_option_value_translation_blue:
|
||||
locale: 'en_US'
|
||||
value: 'Blue'
|
||||
translatable: '@product_option_value_color_blue'
|
||||
product_option_value_translation_red:
|
||||
locale: 'en_US'
|
||||
value: 'Red'
|
||||
translatable: '@product_option_value_color_red'
|
||||
|
|
|
|||
|
|
@ -1,9 +1,12 @@
|
|||
{
|
||||
"@context":"\/api\/v2\/contexts\/ProductVariant",
|
||||
"@id":"\/api\/v2\/admin\/product-variants\/MUG",
|
||||
"@type":"ProductVariant",
|
||||
"code":"MUG",
|
||||
"product":"\/api\/v2\/admin\/products\/MUG_SW",
|
||||
"@context": "\/api\/v2\/contexts\/ProductVariant",
|
||||
"@id": "\/api\/v2\/admin\/product-variants\/MUG",
|
||||
"@type": "ProductVariant",
|
||||
"code": "MUG",
|
||||
"product": "\/api\/v2\/admin\/products\/MUG_SW",
|
||||
"optionValues":[
|
||||
"\/api\/v2\/admin\/product-option-values\/COLOR_BLUE"
|
||||
],
|
||||
"channelPricings": {
|
||||
"WEB": {
|
||||
"@id": "/api/v2/admin/channel-pricings/@integer@",
|
||||
|
|
@ -15,14 +18,27 @@
|
|||
"minimumPrice": 0
|
||||
}
|
||||
},
|
||||
"optionValues":[],
|
||||
"translations": {
|
||||
"en_US": {
|
||||
"@id":"\/api\/v2\/admin\/product-variant-translations\/@integer@",
|
||||
"@type":"ProductVariantTranslation",
|
||||
"name":"Mug",
|
||||
"locale":"en_US"
|
||||
"@id": "\/api\/v2\/admin\/product-variant-translations\/@integer@",
|
||||
"@type": "ProductVariantTranslation",
|
||||
"id": @integer@,
|
||||
"name": "Mug",
|
||||
"locale": "en_US"
|
||||
}
|
||||
},
|
||||
"enabled": true
|
||||
"enabled": true,
|
||||
"position": 1,
|
||||
"tracked": true,
|
||||
"onHold": 0,
|
||||
"onHand": 10,
|
||||
"weight": 100.5,
|
||||
"width": 100.5,
|
||||
"height": 100.5,
|
||||
"depth": 100.5,
|
||||
"taxCategory": "\/api\/v2\/admin\/tax-categories\/default",
|
||||
"shippingCategory": "\/api\/v2\/admin\/shipping-categories\/default",
|
||||
"shippingRequired": true,
|
||||
"createdAt": @date@,
|
||||
"updatedAt": @date@
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,9 @@
|
|||
"@type": "ProductVariant",
|
||||
"code": "MUG",
|
||||
"product": "\/api\/v2\/admin\/products\/MUG_SW",
|
||||
"optionValues":[
|
||||
"\/api\/v2\/admin\/product-option-values\/COLOR_BLUE"
|
||||
],
|
||||
"channelPricings": {
|
||||
"WEB": {
|
||||
"@id": "/api/v2/admin/channel-pricings/@integer@",
|
||||
|
|
@ -19,19 +22,73 @@
|
|||
"minimumPrice": 0
|
||||
}
|
||||
},
|
||||
"optionValues": [],
|
||||
"enabled": true,
|
||||
"translations": {
|
||||
"en_US": {
|
||||
"@id": "\/api\/v2\/admin\/product-variant-translations\/@integer@",
|
||||
"@type": "ProductVariantTranslation",
|
||||
"id": @integer@,
|
||||
"name": "Mug",
|
||||
"locale": "en_US"
|
||||
}
|
||||
}
|
||||
},
|
||||
"enabled": true,
|
||||
"position": 1,
|
||||
"tracked": true,
|
||||
"onHold": 0,
|
||||
"onHand": 10,
|
||||
"weight": 100.5,
|
||||
"width": 100.5,
|
||||
"height": 100.5,
|
||||
"depth": 100.5,
|
||||
"taxCategory": "\/api\/v2\/admin\/tax-categories\/default",
|
||||
"shippingCategory": "\/api\/v2\/admin\/shipping-categories\/default",
|
||||
"shippingRequired": true,
|
||||
"createdAt": @date@,
|
||||
"updatedAt": @date@
|
||||
},
|
||||
{
|
||||
"@id": "\/api\/v2\/admin\/product-variants/MUG_2",
|
||||
"@type": "ProductVariant",
|
||||
"code": "MUG_2",
|
||||
"product": "\/api\/v2\/admin\/products\/MUG_SW",
|
||||
"optionValues": [],
|
||||
"channelPricings": {
|
||||
"WEB": {
|
||||
"@id": "/api/v2/admin/channel-pricings/@integer@",
|
||||
"@type": "ChannelPricing",
|
||||
"channelCode": "WEB",
|
||||
"price": 3000,
|
||||
"originalPrice": null,
|
||||
"lowestPriceBeforeDiscount": null,
|
||||
"minimumPrice": 0
|
||||
}
|
||||
},
|
||||
"translations": {
|
||||
"en_US": {
|
||||
"@id": "\/api\/v2\/admin\/product-variant-translations\/@integer@",
|
||||
"@type": "ProductVariantTranslation",
|
||||
"id": @integer@,
|
||||
"name": "Mug 2",
|
||||
"locale": "en_US"
|
||||
}
|
||||
},
|
||||
"enabled": true,
|
||||
"position": 2,
|
||||
"tracked": false,
|
||||
"onHold": 0,
|
||||
"onHand": 0,
|
||||
"weight": null,
|
||||
"width": null,
|
||||
"height": null,
|
||||
"depth": null,
|
||||
"taxCategory": null,
|
||||
"shippingCategory": null,
|
||||
"shippingRequired": true,
|
||||
"createdAt": @date@,
|
||||
"updatedAt": @date@
|
||||
}
|
||||
],
|
||||
"hydra:totalItems": 1,
|
||||
"hydra:totalItems": 2,
|
||||
"hydra:search": {
|
||||
"@type": "hydra:IriTemplate",
|
||||
"hydra:template": "\/api\/v2\/admin\/product-variants{?catalogPromotion}",
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
{
|
||||
"@context":"\/api\/v2\/contexts\/ProductVariant",
|
||||
"@id":"\/api\/v2\/admin\/product-variants\/MUG_2",
|
||||
"@type":"ProductVariant",
|
||||
"code":"MUG_2",
|
||||
"product":"\/api\/v2\/admin\/products\/MUG_SW",
|
||||
"@context": "\/api\/v2\/contexts\/ProductVariant",
|
||||
"@id": "\/api\/v2\/admin\/product-variants\/MUG_3",
|
||||
"@type": "ProductVariant",
|
||||
"code": "MUG_3",
|
||||
"product": "\/api\/v2\/admin\/products\/MUG_SW",
|
||||
"optionValues": [],
|
||||
"channelPricings": {
|
||||
"WEB": {
|
||||
"@id": "\/api\/v2\/admin\/channel-pricings\/@integer@",
|
||||
|
|
@ -15,7 +16,19 @@
|
|||
"lowestPriceBeforeDiscount": null
|
||||
}
|
||||
},
|
||||
"translations": [],
|
||||
"enabled": false,
|
||||
"optionValues": [],
|
||||
"translations": []
|
||||
"position": 3,
|
||||
"tracked": false,
|
||||
"onHold": 0,
|
||||
"onHand": 0,
|
||||
"weight": null,
|
||||
"width": null,
|
||||
"height": null,
|
||||
"depth": null,
|
||||
"taxCategory": null,
|
||||
"shippingCategory": null,
|
||||
"shippingRequired": true,
|
||||
"createdAt": @date@,
|
||||
"updatedAt": @date@
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
{
|
||||
"@context":"\/api\/v2\/contexts\/ProductVariant",
|
||||
"@id":"\/api\/v2\/admin\/product-variants\/MUG_2",
|
||||
"@type":"ProductVariant",
|
||||
"code":"MUG_2",
|
||||
"product":"\/api\/v2\/admin\/products\/MUG_SW",
|
||||
"@context": "\/api\/v2\/contexts\/ProductVariant",
|
||||
"@id": "\/api\/v2\/admin\/product-variants\/MUG_3",
|
||||
"@type": "ProductVariant",
|
||||
"code": "MUG_3",
|
||||
"product": "\/api\/v2\/admin\/products\/MUG_SW",
|
||||
"optionValues": [],
|
||||
"channelPricings": {
|
||||
"WEB": {
|
||||
"@id": "\/api\/v2\/admin\/channel-pricings\/@integer@",
|
||||
|
|
@ -15,14 +16,27 @@
|
|||
"lowestPriceBeforeDiscount": null
|
||||
}
|
||||
},
|
||||
"enabled": true,
|
||||
"optionValues": [],
|
||||
"translations": {
|
||||
"en_US": {
|
||||
"@id":"\/api\/v2\/admin\/product-variant-translations\/@integer@",
|
||||
"@type":"ProductVariantTranslation",
|
||||
"name":"Yellow mug",
|
||||
"locale":"en_US"
|
||||
"@id": "\/api\/v2\/admin\/product-variant-translations\/@integer@",
|
||||
"@type": "ProductVariantTranslation",
|
||||
"id":@integer@,
|
||||
"name": "Yellow mug",
|
||||
"locale": "en_US"
|
||||
}
|
||||
}
|
||||
},
|
||||
"enabled": true,
|
||||
"position": 3,
|
||||
"tracked": false,
|
||||
"onHold": 0,
|
||||
"onHand": 0,
|
||||
"weight": null,
|
||||
"width": null,
|
||||
"height": null,
|
||||
"depth": null,
|
||||
"taxCategory": null,
|
||||
"shippingCategory": null,
|
||||
"shippingRequired": true,
|
||||
"createdAt": @date@,
|
||||
"updatedAt": @date@
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,11 @@
|
|||
"@context": "\/api\/v2\/contexts\/ProductVariant",
|
||||
"@id": "\/api\/v2\/admin\/product-variants\/MUG",
|
||||
"@type": "ProductVariant",
|
||||
"code": "MUG",
|
||||
"product": "\/api\/v2\/admin\/products\/MUG_SW",
|
||||
"optionValues":[
|
||||
"\/api\/v2\/admin\/product-option-values\/COLOR_BLUE"
|
||||
],
|
||||
"channelPricings": {
|
||||
"WEB": {
|
||||
"@id": "\/api\/v2\/admin\/channel-pricings\/@integer@",
|
||||
|
|
@ -13,22 +18,34 @@
|
|||
"minimumPrice": 210
|
||||
}
|
||||
},
|
||||
"code": "MUG",
|
||||
"product": "\/api\/v2\/admin\/products\/MUG_SW",
|
||||
"optionValues": [],
|
||||
"enabled": true,
|
||||
"translations": {
|
||||
"de_DE": {
|
||||
"@id": "\/api\/v2\/admin\/product-variant-translations\/@integer@",
|
||||
"@type": "ProductVariantTranslation",
|
||||
"id": @integer@,
|
||||
"name": "Orange Tasse",
|
||||
"locale": "de_DE"
|
||||
},
|
||||
"pl_PL": {
|
||||
"@id": "\/api\/v2\/admin\/product-variant-translations\/@integer@",
|
||||
"@type": "ProductVariantTranslation",
|
||||
"id": @integer@,
|
||||
"name": "Pomarańczowy kubek",
|
||||
"locale": "pl_PL"
|
||||
}
|
||||
}
|
||||
},
|
||||
"enabled": true,
|
||||
"position": 1,
|
||||
"tracked": true,
|
||||
"onHold": 0,
|
||||
"onHand": 10,
|
||||
"weight": 100.5,
|
||||
"width": 100.5,
|
||||
"height": 100.5,
|
||||
"depth": 100.5,
|
||||
"taxCategory": "\/api\/v2\/admin\/tax-categories\/default",
|
||||
"shippingCategory": "\/api\/v2\/admin\/shipping-categories\/default",
|
||||
"shippingRequired": true,
|
||||
"createdAt": @date@,
|
||||
"updatedAt": @date@
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue