mirror of
https://github.com/Sylius/Sylius.git
synced 2026-07-14 17:10:53 +00:00
[API][Admin] Extend POST endpoint for creating a product
This commit is contained in:
parent
85a25557ab
commit
1536fd3d71
10 changed files with 209 additions and 44 deletions
|
|
@ -59,6 +59,9 @@
|
|||
<attribute name="denormalization_context">
|
||||
<attribute name="groups">admin:product:create</attribute>
|
||||
</attribute>
|
||||
<attribute name="normalization_context">
|
||||
<attribute name="groups">admin:product:read</attribute>
|
||||
</attribute>
|
||||
</collectionOperation>
|
||||
</collectionOperations>
|
||||
|
||||
|
|
|
|||
|
|
@ -21,16 +21,17 @@
|
|||
<group>shop:product:read</group>
|
||||
</attribute>
|
||||
<attribute name="code">
|
||||
<group>admin:product:create</group>
|
||||
<group>admin:product:read</group>
|
||||
<group>admin:product:create</group>
|
||||
<group>shop:product:read</group>
|
||||
</attribute>
|
||||
<attribute name="variantSelectionMethod">
|
||||
<group>admin:product:read</group>
|
||||
<group>admin:product:create</group>
|
||||
</attribute>
|
||||
<attribute name="enabled">
|
||||
<group>admin:product:create</group>
|
||||
<group>admin:product:read</group>
|
||||
<group>admin:product:create</group>
|
||||
<group>admin:product:update</group>
|
||||
</attribute>
|
||||
<attribute name="name">
|
||||
|
|
@ -46,19 +47,19 @@
|
|||
<group>shop:product:read</group>
|
||||
</attribute>
|
||||
<attribute name="translations">
|
||||
<group>admin:product:create</group>
|
||||
<group>admin:product:read</group>
|
||||
<group>admin:product:create</group>
|
||||
<group>admin:product:update</group>
|
||||
</attribute>
|
||||
<attribute name="mainTaxon">
|
||||
<group>admin:product:create</group>
|
||||
<group>admin:product:read</group>
|
||||
<group>admin:product:create</group>
|
||||
<group>admin:product:update</group>
|
||||
<group>shop:product:read</group>
|
||||
</attribute>
|
||||
<attribute name="productTaxons">
|
||||
<group>admin:product:create</group>
|
||||
<group>admin:product:read</group>
|
||||
<group>admin:product:create</group>
|
||||
<group>admin:product:update</group>
|
||||
<group>shop:product:read</group>
|
||||
</attribute>
|
||||
|
|
@ -90,9 +91,11 @@
|
|||
</attribute>
|
||||
<attribute name="attributes">
|
||||
<group>admin:product:read</group>
|
||||
<group>admin:product:create</group>
|
||||
</attribute>
|
||||
<attribute name="channels">
|
||||
<group>admin:product:read</group>
|
||||
<group>admin:product:create</group>
|
||||
</attribute>
|
||||
<attribute name="createdAt">
|
||||
<group>admin:product:read</group>
|
||||
|
|
|
|||
|
|
@ -17,9 +17,22 @@
|
|||
>
|
||||
<class name="Sylius\Component\Product\Model\ProductAttributeValue">
|
||||
<attribute name="id">
|
||||
<group>admin:product:read</group>
|
||||
<group>shop:product_attribute_value:read</group>
|
||||
</attribute>
|
||||
<attribute name="attribute">
|
||||
<group>admin:product:read</group>
|
||||
<group>admin:product:create</group>
|
||||
<group>shop:product_attribute_value:read</group>
|
||||
</attribute>
|
||||
<attribute name="value">
|
||||
<group>admin:product:read</group>
|
||||
<group>admin:product:create</group>
|
||||
<group>shop:product_attribute_value:read</group>
|
||||
</attribute>
|
||||
<attribute name="localeCode">
|
||||
<group>admin:product:read</group>
|
||||
<group>admin:product:create</group>
|
||||
<group>shop:product_attribute_value:read</group>
|
||||
</attribute>
|
||||
<attribute name="name">
|
||||
|
|
@ -31,11 +44,5 @@
|
|||
<attribute name="code">
|
||||
<group>shop:product_attribute_value:read</group>
|
||||
</attribute>
|
||||
<attribute name="value">
|
||||
<group>shop:product_attribute_value:read</group>
|
||||
</attribute>
|
||||
<attribute name="localeCode">
|
||||
<group>shop:product_attribute_value:read</group>
|
||||
</attribute>
|
||||
</class>
|
||||
</serializer>
|
||||
|
|
|
|||
|
|
@ -24,34 +24,36 @@
|
|||
<group>admin:product:create</group>
|
||||
</attribute>
|
||||
<attribute name="name">
|
||||
<group>admin:product:create</group>
|
||||
<group>admin:product:read</group>
|
||||
<group>admin:product:create</group>
|
||||
<group>admin:product:update</group>
|
||||
<group>shop:product:read</group>
|
||||
</attribute>
|
||||
<attribute name="slug">
|
||||
<group>admin:product:create</group>
|
||||
<group>admin:product:read</group>
|
||||
<group>admin:product:create</group>
|
||||
<group>admin:product:update</group>
|
||||
<group>shop:product:read</group>
|
||||
</attribute>
|
||||
<attribute name="description">
|
||||
<group>admin:product:read</group>
|
||||
<group>admin:product:create</group>
|
||||
<group>shop:product:read</group>
|
||||
</attribute>
|
||||
<attribute name="shortDescription">
|
||||
<group>admin:product:read</group>
|
||||
<group>admin:product:create</group>
|
||||
<group>shop:product:read</group>
|
||||
</attribute>
|
||||
<attribute name="metaKeywords">
|
||||
<group>admin:product:create</group>
|
||||
<group>admin:product:read</group>
|
||||
<group>admin:product:create</group>
|
||||
<group>admin:product:update</group>
|
||||
<group>shop:product:read</group>
|
||||
</attribute>
|
||||
<attribute name="metaDescription">
|
||||
<group>admin:product:create</group>
|
||||
<group>admin:product:read</group>
|
||||
<group>admin:product:create</group>
|
||||
<group>admin:product:update</group>
|
||||
<group>shop:product:read</group>
|
||||
</attribute>
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ final class ProductsTest extends JsonApiTestCase
|
|||
/** @test */
|
||||
public function it_gets_a_product(): void
|
||||
{
|
||||
$fixtures = $this->loadFixturesFromFiles(['authentication/api_administrator.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 */
|
||||
|
|
@ -46,7 +46,7 @@ final class ProductsTest extends JsonApiTestCase
|
|||
/** @test */
|
||||
public function it_gets_products(): void
|
||||
{
|
||||
$this->loadFixturesFromFiles(['authentication/api_administrator.yaml', 'product/product.yaml']);
|
||||
$this->loadFixturesFromFiles(['authentication/api_administrator.yaml', 'channel.yaml', 'product/product.yaml']);
|
||||
$header = array_merge($this->logInAdminUser('api@example.com'), self::CONTENT_TYPE_HEADER);
|
||||
|
||||
$this->client->request(
|
||||
|
|
@ -61,4 +61,64 @@ final class ProductsTest extends JsonApiTestCase
|
|||
Response::HTTP_OK,
|
||||
);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_creates_a_product(): void
|
||||
{
|
||||
$this->loadFixturesFromFiles([
|
||||
'authentication/api_administrator.yaml',
|
||||
'taxonomy.yaml',
|
||||
'product/product_option.yaml',
|
||||
'product/product_attribute.yaml',
|
||||
]);
|
||||
$header = array_merge($this->logInAdminUser('api@example.com'), self::CONTENT_TYPE_HEADER);
|
||||
|
||||
$this->client->request(
|
||||
method: 'POST',
|
||||
uri: '/api/v2/admin/products',
|
||||
server: $header,
|
||||
content: json_encode([
|
||||
'code' => 'MUG',
|
||||
'variantSelectionMethod' => ProductInterface::VARIANT_SELECTION_MATCH,
|
||||
'enabled' => true,
|
||||
'options' => [
|
||||
'/api/v2/admin/product-options/COLOR',
|
||||
],
|
||||
'mainTaxon' => '/api/v2/admin/taxons/MUG',
|
||||
'channels' => [
|
||||
'/api/v2/admin/channels/WEB_GB',
|
||||
],
|
||||
'attributes' => [[
|
||||
'attribute' => '/api/v2/admin/product-attributes/dishwasher_safe',
|
||||
'value' => true,
|
||||
]],
|
||||
'translations' => [
|
||||
'en_US' => [
|
||||
'locale' => 'en_US',
|
||||
'slug' => 'mug',
|
||||
'name' => 'Mug',
|
||||
'description' => 'This is a mug',
|
||||
'shortDescription' => 'Short mug description',
|
||||
'metaKeywords' => 'mug',
|
||||
'metaDescription' => 'Mug description',
|
||||
],
|
||||
'pl_PL' => [
|
||||
'locale' => 'pl_PL',
|
||||
'slug' => 'kubek',
|
||||
'name' => 'Kubek',
|
||||
'description' => 'To jest kubek',
|
||||
'shortDescription' => 'Krótki opis kubka',
|
||||
'metaKeywords' => 'kubek',
|
||||
'metaDescription' => 'Opis kubka',
|
||||
],
|
||||
],
|
||||
], JSON_THROW_ON_ERROR),
|
||||
);
|
||||
|
||||
$this->assertResponse(
|
||||
$this->client->getResponse(),
|
||||
'admin/product/post_product_response',
|
||||
Response::HTTP_CREATED,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,29 +23,6 @@ Sylius\Component\Core\Model\Product:
|
|||
en_US: '@product_translation_socks_en_US'
|
||||
options: ['@product_option_color']
|
||||
|
||||
Sylius\Component\Core\Model\Channel:
|
||||
channel_web:
|
||||
code: 'WEB'
|
||||
name: 'Web Channel'
|
||||
hostname: 'localhost'
|
||||
description: 'Lorem ipsum'
|
||||
baseCurrency: '@currency_usd'
|
||||
defaultLocale: '@locale_en'
|
||||
locales: ['@locale_en', '@locale_pl']
|
||||
color: 'black'
|
||||
enabled: true
|
||||
taxCalculationStrategy: 'order_item_units_based'
|
||||
|
||||
Sylius\Component\Currency\Model\Currency:
|
||||
currency_usd:
|
||||
code: 'USD'
|
||||
|
||||
Sylius\Component\Locale\Model\Locale:
|
||||
locale_en:
|
||||
code: 'en_US'
|
||||
locale_pl:
|
||||
code: 'pl_PL'
|
||||
|
||||
Sylius\Component\Core\Model\ProductTranslation:
|
||||
product_translation_mug_en_US:
|
||||
locale: 'en_US'
|
||||
|
|
|
|||
29
tests/Api/DataFixtures/ORM/product/product_option.yaml
Normal file
29
tests/Api/DataFixtures/ORM/product/product_option.yaml
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
Sylius\Component\Product\Model\ProductOption:
|
||||
product_option_color:
|
||||
code: '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'
|
||||
|
|
@ -25,8 +25,22 @@
|
|||
"\/api\/v2\/admin\/product-reviews\/@integer@"
|
||||
],
|
||||
"attributes": [
|
||||
"\/api\/v2\/admin\/product-attribute-values\/@integer@",
|
||||
"\/api\/v2\/admin\/product-attribute-values\/@integer@"
|
||||
{
|
||||
"@id": "\/api\/v2\/admin\/product-attribute-values\/@integer@",
|
||||
"@type": "ProductAttributeValue",
|
||||
"id": @integer@,
|
||||
"attribute": "\/api\/v2\/admin\/product-attributes\/MUG_MATERIAL",
|
||||
"value": "Ceramic",
|
||||
"localeCode": "en_US"
|
||||
},
|
||||
{
|
||||
"@id": "\/api\/v2\/admin\/product-attribute-values\/@integer@",
|
||||
"@type": "ProductAttributeValue",
|
||||
"id": @integer@,
|
||||
"attribute": "\/api\/v2\/admin\/product-attributes\/MUG_MATERIAL",
|
||||
"value": "Ceramika",
|
||||
"localeCode": "pl_PL"
|
||||
}
|
||||
],
|
||||
"images": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -64,8 +64,22 @@
|
|||
"\/api\/v2\/admin\/product-reviews\/@integer@"
|
||||
],
|
||||
"attributes": [
|
||||
"\/api\/v2\/admin\/product-attribute-values\/@integer@",
|
||||
"\/api\/v2\/admin\/product-attribute-values\/@integer@"
|
||||
{
|
||||
"@id": "\/api\/v2\/admin\/product-attribute-values\/@integer@",
|
||||
"@type": "ProductAttributeValue",
|
||||
"id": @integer@,
|
||||
"attribute": "\/api\/v2\/admin\/product-attributes\/MUG_MATERIAL",
|
||||
"value": "Ceramic",
|
||||
"localeCode": "en_US"
|
||||
},
|
||||
{
|
||||
"@id": "\/api\/v2\/admin\/product-attribute-values\/@integer@",
|
||||
"@type": "ProductAttributeValue",
|
||||
"id": @integer@,
|
||||
"attribute": "\/api\/v2\/admin\/product-attributes\/MUG_MATERIAL",
|
||||
"value": "Ceramika",
|
||||
"localeCode": "pl_PL"
|
||||
}
|
||||
],
|
||||
"images": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -0,0 +1,56 @@
|
|||
{
|
||||
"@context": "\/api\/v2\/contexts\/Product",
|
||||
"@id": "\/api\/v2\/admin\/products\/MUG",
|
||||
"@type": "Product",
|
||||
"id": @integer@,
|
||||
"code": "MUG",
|
||||
"variantSelectionMethod": "match",
|
||||
"enabled": true,
|
||||
"options": [
|
||||
"\/api\/v2\/admin\/product-options\/COLOR"
|
||||
],
|
||||
"variants": [],
|
||||
"mainTaxon": "\/api\/v2\/admin\/taxons\/MUG",
|
||||
"productTaxons": [],
|
||||
"channels": [
|
||||
"\/api\/v2\/admin\/channels\/WEB_GB"
|
||||
],
|
||||
"reviews": [],
|
||||
"attributes": [
|
||||
{
|
||||
"@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": [],
|
||||
"translations": {
|
||||
"en_US": {
|
||||
"@id": "\/api\/v2\/admin\/product-translations\/@integer@",
|
||||
"@type": "ProductTranslation",
|
||||
"id": @integer@,
|
||||
"name": "Mug",
|
||||
"slug": "mug",
|
||||
"description": "This is a mug",
|
||||
"shortDescription": "Short mug description",
|
||||
"metaKeywords": "mug",
|
||||
"metaDescription": "Mug description"
|
||||
},
|
||||
"pl_PL": {
|
||||
"@id": "\/api\/v2\/admin\/product-translations\/@integer@",
|
||||
"@type": "ProductTranslation",
|
||||
"id": @integer@,
|
||||
"name": "Kubek",
|
||||
"slug": "kubek",
|
||||
"description": "To jest kubek",
|
||||
"shortDescription": "Krótki opis kubka",
|
||||
"metaKeywords": "kubek",
|
||||
"metaDescription": "Opis kubka"
|
||||
}
|
||||
},
|
||||
"createdAt": @date@,
|
||||
"updatedAt": @date@
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue