mirror of
https://github.com/Sylius/Sylius.git
synced 2026-07-14 17:10:53 +00:00
[API] Extend PUT endpoint for updating the product
This commit is contained in:
parent
1536fd3d71
commit
24f56b3d6f
8 changed files with 213 additions and 17 deletions
|
|
@ -115,7 +115,10 @@
|
|||
<attribute name="method">PUT</attribute>
|
||||
<attribute name="path">/admin/products/{code}</attribute>
|
||||
<attribute name="denormalization_context">
|
||||
<attribute name="groups">admin:product:update</attribute>
|
||||
<attribute name="groups">admin:product:create</attribute>
|
||||
</attribute>
|
||||
<attribute name="normalization_context">
|
||||
<attribute name="groups">admin:product:read</attribute>
|
||||
</attribute>
|
||||
</itemOperation>
|
||||
|
||||
|
|
|
|||
|
|
@ -92,10 +92,12 @@
|
|||
<attribute name="attributes">
|
||||
<group>admin:product:read</group>
|
||||
<group>admin:product:create</group>
|
||||
<group>admin:product:update</group>
|
||||
</attribute>
|
||||
<attribute name="channels">
|
||||
<group>admin:product:read</group>
|
||||
<group>admin:product:create</group>
|
||||
<group>admin:product:update</group>
|
||||
</attribute>
|
||||
<attribute name="createdAt">
|
||||
<group>admin:product:read</group>
|
||||
|
|
|
|||
|
|
@ -23,16 +23,19 @@
|
|||
<attribute name="attribute">
|
||||
<group>admin:product:read</group>
|
||||
<group>admin:product:create</group>
|
||||
<group>admin:product:update</group>
|
||||
<group>shop:product_attribute_value:read</group>
|
||||
</attribute>
|
||||
<attribute name="value">
|
||||
<group>admin:product:read</group>
|
||||
<group>admin:product:create</group>
|
||||
<group>admin:product:update</group>
|
||||
<group>shop:product_attribute_value:read</group>
|
||||
</attribute>
|
||||
<attribute name="localeCode">
|
||||
<group>admin:product:read</group>
|
||||
<group>admin:product:create</group>
|
||||
<group>admin:product:update</group>
|
||||
<group>shop:product_attribute_value:read</group>
|
||||
</attribute>
|
||||
<attribute name="name">
|
||||
|
|
|
|||
|
|
@ -25,11 +25,16 @@ final class ProductsTest extends JsonApiTestCase
|
|||
/** @test */
|
||||
public function it_gets_a_product(): void
|
||||
{
|
||||
$fixtures = $this->loadFixturesFromFiles(['authentication/api_administrator.yaml', 'channel.yaml', 'product/product.yaml']);
|
||||
$fixtures = $this->loadFixturesFromFiles([
|
||||
'authentication/api_administrator.yaml',
|
||||
'channel.yaml',
|
||||
'product/product.yaml',
|
||||
]);
|
||||
$header = array_merge($this->logInAdminUser('api@example.com'), self::CONTENT_TYPE_HEADER);
|
||||
|
||||
/** @var ProductInterface $product */
|
||||
$product = $fixtures['product_mug'];
|
||||
|
||||
$this->client->request(
|
||||
method: 'GET',
|
||||
uri: sprintf('/api/v2/admin/products/%s', $product->getCode()),
|
||||
|
|
@ -121,4 +126,84 @@ final class ProductsTest extends JsonApiTestCase
|
|||
Response::HTTP_CREATED,
|
||||
);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_updates_the_existing_product(): void
|
||||
{
|
||||
$fixtures = $this->loadFixturesFromFiles([
|
||||
'authentication/api_administrator.yaml',
|
||||
'channel.yaml',
|
||||
'product/product.yaml',
|
||||
'product/product_attribute.yaml',
|
||||
]);
|
||||
$header = array_merge($this->logInAdminUser('api@example.com'), self::CONTENT_TYPE_HEADER);
|
||||
|
||||
/** @var ProductInterface $product */
|
||||
$product = $fixtures['product_mug'];
|
||||
|
||||
$this->client->request(
|
||||
method: 'PUT',
|
||||
uri: sprintf('/api/v2/admin/products/%s', $product->getCode()),
|
||||
server: $header,
|
||||
content: json_encode([
|
||||
'enabled' => false,
|
||||
'mainTaxon' => '/api/v2/admin/taxons/CAPS',
|
||||
'channels' => [
|
||||
'/api/v2/admin/channels/MOBILE',
|
||||
],
|
||||
'attributes' => [
|
||||
[
|
||||
'@id' => sprintf(
|
||||
'/api/v2/admin/product-attribute-values/%s',
|
||||
$product->getAttributeByCodeAndLocale('MATERIAL', 'en_US')->getId()
|
||||
),
|
||||
'attribute' => '/api/v2/admin/product-attributes/MATERIAL',
|
||||
'value' => 'Cotton',
|
||||
'localeCode' => 'en_US',
|
||||
],
|
||||
[
|
||||
'@id' => sprintf(
|
||||
'/api/v2/admin/product-attribute-values/%s',
|
||||
$product->getAttributeByCodeAndLocale('MATERIAL', 'pl_PL')->getId()
|
||||
),
|
||||
'attribute' => '/api/v2/admin/product-attributes/MATERIAL',
|
||||
'value' => 'Bawełna',
|
||||
'localeCode' => 'pl_PL',
|
||||
],
|
||||
[
|
||||
'attribute' => '/api/v2/admin/product-attributes/dishwasher_safe',
|
||||
'value' => true,
|
||||
]
|
||||
],
|
||||
'translations' => [
|
||||
'en_US' => [
|
||||
'@id' => sprintf('/api/v2/admin/product-translations/%s', $product->getTranslation('en_US')->getId()),
|
||||
'locale' => 'en_US',
|
||||
'slug' => 'caps/cap',
|
||||
'name' => 'Cap',
|
||||
'description' => 'This is a cap',
|
||||
'shortDescription' => 'Short cap description',
|
||||
'metaKeywords' => 'cap',
|
||||
'metaDescription' => 'Cap description',
|
||||
],
|
||||
'pl_PL' => [
|
||||
'@id' => sprintf('/api/v2/admin/product-translations/%s', $product->getTranslation('pl_PL')->getId()),
|
||||
'locale' => 'pl_PL',
|
||||
'slug' => 'czapki/czapka',
|
||||
'name' => 'Czapka',
|
||||
'description' => 'To jest czapka',
|
||||
'shortDescription' => 'Krótki opis czapki',
|
||||
'metaKeywords' => 'czapka',
|
||||
'metaDescription' => 'Opis czapki',
|
||||
],
|
||||
],
|
||||
], JSON_THROW_ON_ERROR),
|
||||
);
|
||||
|
||||
$this->assertResponse(
|
||||
$this->client->getResponse(),
|
||||
'admin/product/put_product_response',
|
||||
Response::HTTP_OK,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,17 @@
|
|||
Sylius\Component\Core\Model\Product:
|
||||
product_mug:
|
||||
code: 'MUG'
|
||||
channels: ['@channel_web']
|
||||
enabled: true
|
||||
options: ['@product_option_color']
|
||||
mainTaxon: '@taxon_mugs'
|
||||
channels: ['@channel_web']
|
||||
currentLocale: 'en_US'
|
||||
translations:
|
||||
en_US: '@product_translation_mug_en_US'
|
||||
pl_PL: '@product_translation_mug_pl_PL'
|
||||
options: ['@product_option_color']
|
||||
attributes:
|
||||
- '@product_attribute_value_material_en_US'
|
||||
- '@product_attribute_value_material_pl_PL'
|
||||
product_cap:
|
||||
code: 'CAP'
|
||||
channels: ['@channel_web']
|
||||
|
|
@ -63,6 +67,7 @@ Sylius\Component\Core\Model\ProductVariant:
|
|||
optionValues: ['@product_option_value_color_blue']
|
||||
channelPricings:
|
||||
WEB: '@channel_pricing_mug_blue_web'
|
||||
MOBILE: '@channel_pricing_mug_blue_mobile'
|
||||
product_variant_mug_red:
|
||||
code: 'MUG_RED'
|
||||
product: '@product_mug'
|
||||
|
|
@ -72,6 +77,7 @@ Sylius\Component\Core\Model\ProductVariant:
|
|||
optionValues: ['@product_option_value_color_red']
|
||||
channelPricings:
|
||||
WEB: '@channel_pricing_mug_red_web'
|
||||
MOBILE: '@channel_pricing_mug_red_mobile'
|
||||
|
||||
Sylius\Component\Product\Model\ProductVariantTranslation:
|
||||
product_variant_translation_mug_blue:
|
||||
|
|
@ -91,6 +97,13 @@ Sylius\Component\Core\Model\ChannelPricing:
|
|||
channel_pricing_mug_red_web:
|
||||
channelCode: 'WEB'
|
||||
price: 2000
|
||||
channel_pricing_mug_blue_mobile:
|
||||
channelCode: 'MOBILE'
|
||||
price: 2500
|
||||
originalPrice: 3500
|
||||
channel_pricing_mug_red_mobile:
|
||||
channelCode: 'MOBILE'
|
||||
price: 2500
|
||||
|
||||
Sylius\Component\Product\Model\ProductOption:
|
||||
product_option_color:
|
||||
|
|
@ -125,6 +138,8 @@ Sylius\Component\Product\Model\ProductOptionValueTranslation:
|
|||
Sylius\Component\Core\Model\Taxon:
|
||||
taxon_mugs:
|
||||
code: 'MUGS'
|
||||
taxon_caps:
|
||||
code: 'CAPS'
|
||||
|
||||
Sylius\Component\Core\Model\ProductTaxon:
|
||||
product_taxon:
|
||||
|
|
@ -156,33 +171,33 @@ Sylius\Component\Core\Model\Customer:
|
|||
emailCanonical: 'john.doe@example.com'
|
||||
|
||||
Sylius\Component\Product\Model\ProductAttribute:
|
||||
product_attribute_mug_material:
|
||||
product_attribute_material:
|
||||
translatable: true
|
||||
fallbackLocale: 'en_US'
|
||||
currentLocale: 'en_US'
|
||||
code: 'MUG_MATERIAL'
|
||||
code: 'MATERIAL'
|
||||
type: 'text'
|
||||
storageType: 'text'
|
||||
translations:
|
||||
- '@product_attribute_translation_mug_material_en_US'
|
||||
- '@product_attribute_translation_material_en_US'
|
||||
|
||||
Sylius\Component\Product\Model\ProductAttributeValue:
|
||||
product_attribute_value_mug_material_en_US:
|
||||
product_attribute_value_material_en_US:
|
||||
localeCode: 'en_US'
|
||||
product: '@product_mug'
|
||||
attribute: '@product_attribute_mug_material'
|
||||
attribute: '@product_attribute_material'
|
||||
value: 'Ceramic'
|
||||
product_attribute_value_mug_material_pl_PL:
|
||||
product_attribute_value_material_pl_PL:
|
||||
localeCode: 'pl_PL'
|
||||
product: '@product_mug'
|
||||
attribute: '@product_attribute_mug_material'
|
||||
attribute: '@product_attribute_material'
|
||||
value: 'Ceramika'
|
||||
|
||||
Sylius\Component\Product\Model\ProductAttributeTranslation:
|
||||
product_attribute_translation_mug_material_en_US:
|
||||
product_attribute_translation_material_en_US:
|
||||
locale: 'en_US'
|
||||
name: 'Mug material'
|
||||
translatable: '@product_attribute_mug_material'
|
||||
translatable: '@product_attribute_material'
|
||||
|
||||
Sylius\Component\Core\Model\ProductImage:
|
||||
product_mug_thumbnail:
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
"@id": "\/api\/v2\/admin\/product-attribute-values\/@integer@",
|
||||
"@type": "ProductAttributeValue",
|
||||
"id": @integer@,
|
||||
"attribute": "\/api\/v2\/admin\/product-attributes\/MUG_MATERIAL",
|
||||
"attribute": "\/api\/v2\/admin\/product-attributes\/MATERIAL",
|
||||
"value": "Ceramic",
|
||||
"localeCode": "en_US"
|
||||
},
|
||||
|
|
@ -37,7 +37,7 @@
|
|||
"@id": "\/api\/v2\/admin\/product-attribute-values\/@integer@",
|
||||
"@type": "ProductAttributeValue",
|
||||
"id": @integer@,
|
||||
"attribute": "\/api\/v2\/admin\/product-attributes\/MUG_MATERIAL",
|
||||
"attribute": "\/api\/v2\/admin\/product-attributes\/MATERIAL",
|
||||
"value": "Ceramika",
|
||||
"localeCode": "pl_PL"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@
|
|||
"@id": "\/api\/v2\/admin\/product-attribute-values\/@integer@",
|
||||
"@type": "ProductAttributeValue",
|
||||
"id": @integer@,
|
||||
"attribute": "\/api\/v2\/admin\/product-attributes\/MUG_MATERIAL",
|
||||
"attribute": "\/api\/v2\/admin\/product-attributes\/MATERIAL",
|
||||
"value": "Ceramic",
|
||||
"localeCode": "en_US"
|
||||
},
|
||||
|
|
@ -76,7 +76,7 @@
|
|||
"@id": "\/api\/v2\/admin\/product-attribute-values\/@integer@",
|
||||
"@type": "ProductAttributeValue",
|
||||
"id": @integer@,
|
||||
"attribute": "\/api\/v2\/admin\/product-attributes\/MUG_MATERIAL",
|
||||
"attribute": "\/api\/v2\/admin\/product-attributes\/MATERIAL",
|
||||
"value": "Ceramika",
|
||||
"localeCode": "pl_PL"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,88 @@
|
|||
{
|
||||
"@context": "\/api\/v2\/contexts\/Product",
|
||||
"@id": "\/api\/v2\/admin\/products\/MUG",
|
||||
"@type": "Product",
|
||||
"id": @integer@,
|
||||
"code": "MUG",
|
||||
"variantSelectionMethod": "choice",
|
||||
"enabled": false,
|
||||
"options": [
|
||||
"\/api\/v2\/admin\/product-options\/COLOR"
|
||||
],
|
||||
"variants": [
|
||||
"\/api\/v2\/admin\/product-variants\/MUG_BLUE",
|
||||
"\/api\/v2\/admin\/product-variants\/MUG_RED"
|
||||
],
|
||||
"mainTaxon": "\/api\/v2\/admin\/taxons\/CAPS",
|
||||
"productTaxons": [
|
||||
"\/api\/v2\/admin\/product-taxons\/@integer@"
|
||||
],
|
||||
"channels": [
|
||||
"\/api\/v2\/admin\/channels\/MOBILE"
|
||||
],
|
||||
"reviews": [
|
||||
"\/api\/v2\/admin\/product-reviews\/@integer@",
|
||||
"\/api\/v2\/admin\/product-reviews\/@integer@"
|
||||
],
|
||||
"attributes": [
|
||||
{
|
||||
"@id": "\/api\/v2\/admin\/product-attribute-values\/@integer@",
|
||||
"@type": "ProductAttributeValue",
|
||||
"id": @integer@,
|
||||
"attribute": "\/api\/v2\/admin\/product-attributes\/MATERIAL",
|
||||
"value": "Cotton",
|
||||
"localeCode": "en_US"
|
||||
},
|
||||
{
|
||||
"@id": "\/api\/v2\/admin\/product-attribute-values\/@integer@",
|
||||
"@type": "ProductAttributeValue",
|
||||
"id": @integer@,
|
||||
"attribute": "\/api\/v2\/admin\/product-attributes\/MATERIAL",
|
||||
"value": "Bawełna",
|
||||
"localeCode": "pl_PL"
|
||||
},
|
||||
{
|
||||
"@id": "\/api\/v2\/admin\/product-attribute-values\/@integer@",
|
||||
"@type": "ProductAttributeValue",
|
||||
"id": @integer@,
|
||||
"attribute": "\/api\/v2\/admin\/product-attributes\/dishwasher_safe",
|
||||
"value": true,
|
||||
"localeCode": null
|
||||
}
|
||||
],
|
||||
"images": [
|
||||
{
|
||||
"@id": "\/api\/v2\/admin\/product-images\/@integer@",
|
||||
"@type": "ProductImage",
|
||||
"id": @integer@,
|
||||
"type": "thumbnail",
|
||||
"path": "\/media\/image\/product.jpg"
|
||||
}
|
||||
],
|
||||
"translations": {
|
||||
"en_US": {
|
||||
"@id": "\/api\/v2\/admin\/product-translations\/@integer@",
|
||||
"@type": "ProductTranslation",
|
||||
"id": @integer@,
|
||||
"name": "Cap",
|
||||
"slug": "caps/cap",
|
||||
"description": "This is a cap",
|
||||
"shortDescription": "Short cap description",
|
||||
"metaKeywords": "cap",
|
||||
"metaDescription": "Cap description"
|
||||
},
|
||||
"pl_PL": {
|
||||
"@id": "\/api\/v2\/admin\/product-translations\/@integer@",
|
||||
"@type": "ProductTranslation",
|
||||
"id": @integer@,
|
||||
"name": "Czapka",
|
||||
"slug": "czapki/czapka",
|
||||
"description": "To jest czapka",
|
||||
"shortDescription": "Krótki opis czapki",
|
||||
"metaKeywords": "czapka",
|
||||
"metaDescription": "Opis czapki"
|
||||
}
|
||||
},
|
||||
"createdAt": @date@,
|
||||
"updatedAt": @date@
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue