Skip to content

Commit e7ff49d

Browse files
committed
MC-20668: Edit custom options of simple product
1 parent 0714971 commit e7ff49d

File tree

15 files changed

+1334
-0
lines changed

15 files changed

+1334
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\Catalog\Controller\Adminhtml\Product\Save;
9+
10+
use Magento\Catalog\Api\Data\ProductCustomOptionInterface;
11+
use Magento\Catalog\Api\Data\ProductCustomOptionInterfaceFactory;
12+
use Magento\Catalog\Api\ProductCustomOptionRepositoryInterface;
13+
use Magento\Catalog\Api\ProductRepositoryInterface;
14+
use Magento\Framework\App\Request\Http as HttpRequest;
15+
use Magento\Framework\Message\MessageInterface;
16+
use Magento\TestFramework\TestCase\AbstractBackendController;
17+
18+
/**
19+
* Base test cases for update product custom options with type "field".
20+
* Option updating via dispatch product controller action save with updated options data in POST data.
21+
*
22+
* @magentoAppArea adminhtml
23+
* @magentoDbIsolation enabled
24+
*/
25+
class UpdateCustomOptionsTest extends AbstractBackendController
26+
{
27+
/**
28+
* @var ProductRepositoryInterface
29+
*/
30+
private $productRepository;
31+
32+
/**
33+
* @var ProductCustomOptionRepositoryInterface
34+
*/
35+
private $optionRepository;
36+
37+
/**
38+
* @var ProductCustomOptionInterfaceFactory
39+
*/
40+
private $optionRepositoryFactory;
41+
42+
/**
43+
* @inheritdoc
44+
*/
45+
protected function setUp()
46+
{
47+
parent::setUp();
48+
49+
$this->productRepository = $this->_objectManager->create(ProductRepositoryInterface::class);
50+
$this->optionRepository = $this->_objectManager->create(ProductCustomOptionRepositoryInterface::class);
51+
$this->optionRepositoryFactory = $this->_objectManager->create(ProductCustomOptionInterfaceFactory::class);
52+
}
53+
54+
/**
55+
* Test add to product custom option with type "field".
56+
*
57+
* @magentoDataFixture Magento/Catalog/_files/product_without_options.php
58+
*
59+
* @dataProvider \Magento\Catalog\Model\Product\Option\Create\DataProvider\Type\Text\Field::getDataForUpdateOptions
60+
*
61+
* @param array $optionData
62+
* @param array $updateData
63+
*/
64+
public function testUpdateCustomOptionWithTypeField(array $optionData, array $updateData): void
65+
{
66+
$product = $this->productRepository->get('simple');
67+
$option = $this->optionRepositoryFactory->create(['data' => $optionData]);
68+
$option->setProductSku($product->getSku());
69+
$product->setOptions([$option]);
70+
$this->productRepository->save($product);
71+
$currentProductOptions = $this->optionRepository->getProductOptions($product);
72+
$this->assertCount(1, $currentProductOptions);
73+
/** @var ProductCustomOptionInterface $currentOption */
74+
$currentOption = reset($currentProductOptions);
75+
$postData = [
76+
'product' => [
77+
'options' => [
78+
[
79+
'option_id' => $currentOption->getOptionId(),
80+
'product_id' => $product->getId(),
81+
'type' => $currentOption->getType(),
82+
'is_require' => $currentOption->getIsRequire(),
83+
'sku' => $currentOption->getSku(),
84+
'max_characters' => $currentOption->getMaxCharacters(),
85+
'title' => $currentOption->getTitle(),
86+
'sort_order' => $currentOption->getSortOrder(),
87+
'price' => $currentOption->getPrice(),
88+
'price_type' => $currentOption->getPriceType(),
89+
'is_use_default' => false,
90+
]
91+
]
92+
]
93+
];
94+
95+
foreach ($updateData as $methodKey => $newValue) {
96+
$postData = array_replace_recursive(
97+
$postData,
98+
[
99+
'product' => [
100+
'options' => [
101+
0 => [
102+
$methodKey => $newValue,
103+
]
104+
],
105+
],
106+
]
107+
);
108+
$this->getRequest()->setPostValue($postData);
109+
$this->getRequest()->setMethod(HttpRequest::METHOD_POST);
110+
$this->dispatch('backend/catalog/product/save/id/' . $product->getEntityId());
111+
$this->assertSessionMessages(
112+
$this->contains('You saved the product.'),
113+
MessageInterface::TYPE_SUCCESS
114+
);
115+
$updatedOptions = $this->optionRepository->getProductOptions($product);
116+
$this->assertCount(1, $updatedOptions);
117+
/** @var ProductCustomOptionInterface $updatedOption */
118+
$updatedOption = reset($updatedOptions);
119+
$methodName = str_replace('_', '', ucwords($methodKey, '_'));
120+
$this->assertEquals($newValue, $updatedOption->{'get' . $methodName}());
121+
$this->assertEquals($option->getOptionId(), $updatedOption->getOptionId());
122+
$this->assertNotEquals($option->{'get' . $methodName}(), $updatedOption->{'get' . $methodName}());
123+
}
124+
}
125+
}
Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\Catalog\Model\Product\Option\Create\DataProvider;
9+
10+
/**
11+
* Base custom options data provider.
12+
*/
13+
abstract class AbstractBase
14+
{
15+
/**
16+
* Return data for create options for all cases.
17+
*
18+
* @return array
19+
*/
20+
public function getDataForCreateOptions(): array
21+
{
22+
return [
23+
"type_{$this->getType()}_title" => [
24+
[
25+
'record_id' => 0,
26+
'sort_order' => 1,
27+
'is_require' => 1,
28+
'sku' => 'test-option-title-1',
29+
'max_characters' => 50,
30+
'title' => 'Test option title 1',
31+
'type' => $this->getType(),
32+
'price' => 10,
33+
'price_type' => 'fixed',
34+
],
35+
],
36+
"type_{$this->getType()}_required_options" => [
37+
[
38+
'record_id' => 0,
39+
'sort_order' => 1,
40+
'is_require' => 1,
41+
'sku' => 'test-option-title-1',
42+
'max_characters' => 50,
43+
'title' => 'Test option title 1',
44+
'type' => $this->getType(),
45+
'price' => 10,
46+
'price_type' => 'fixed',
47+
],
48+
],
49+
"type_{$this->getType()}_not_required_options" => [
50+
[
51+
'record_id' => 0,
52+
'sort_order' => 1,
53+
'is_require' => 0,
54+
'sku' => 'test-option-title-1',
55+
'max_characters' => 50,
56+
'title' => 'Test option title 1',
57+
'type' => $this->getType(),
58+
'price' => 10,
59+
'price_type' => 'fixed',
60+
],
61+
],
62+
"type_{$this->getType()}_options_with_fixed_price" => [
63+
[
64+
'record_id' => 0,
65+
'sort_order' => 1,
66+
'is_require' => 1,
67+
'sku' => 'test-option-title-1',
68+
'max_characters' => 50,
69+
'title' => 'Test option title 1',
70+
'type' => $this->getType(),
71+
'price' => 10,
72+
'price_type' => 'fixed',
73+
],
74+
],
75+
"type_{$this->getType()}_options_with_percent_price" => [
76+
[
77+
'record_id' => 0,
78+
'sort_order' => 1,
79+
'is_require' => 1,
80+
'sku' => 'test-option-title-1',
81+
'max_characters' => 50,
82+
'title' => 'Test option title 1',
83+
'type' => $this->getType(),
84+
'price' => 10,
85+
'price_type' => 'percent',
86+
],
87+
],
88+
"type_{$this->getType()}_price" => [
89+
[
90+
'record_id' => 0,
91+
'sort_order' => 1,
92+
'is_require' => 1,
93+
'sku' => 'test-option-title-1',
94+
'max_characters' => 50,
95+
'title' => 'Test option title 1',
96+
'type' => $this->getType(),
97+
'price' => 22,
98+
'price_type' => 'percent',
99+
],
100+
],
101+
"type_{$this->getType()}_sku" => [
102+
[
103+
'record_id' => 0,
104+
'sort_order' => 1,
105+
'is_require' => 1,
106+
'sku' => 'test-option-title-1',
107+
'max_characters' => 50,
108+
'title' => 'Test option title 1',
109+
'type' => $this->getType(),
110+
'price' => 22,
111+
'price_type' => 'percent',
112+
],
113+
],
114+
];
115+
}
116+
117+
/**
118+
* Return data for create options for all cases.
119+
*
120+
* @return array
121+
*/
122+
public function getDataForUpdateOptions(): array
123+
{
124+
return array_merge_recursive(
125+
$this->getDataForCreateOptions(),
126+
[
127+
"type_{$this->getType()}_title" => [
128+
[
129+
'title' => 'Test updated option title',
130+
]
131+
],
132+
"type_{$this->getType()}_required_options" => [
133+
[
134+
'is_require' => 0,
135+
],
136+
],
137+
"type_{$this->getType()}_not_required_options" => [
138+
[
139+
'is_require' => 1,
140+
],
141+
],
142+
"type_{$this->getType()}_options_with_fixed_price" => [
143+
[
144+
'price_type' => 'percent',
145+
],
146+
],
147+
"type_{$this->getType()}_options_with_percent_price" => [
148+
[
149+
'price_type' => 'fixed',
150+
],
151+
],
152+
"type_{$this->getType()}_price" => [
153+
[
154+
'price' => 60,
155+
],
156+
],
157+
"type_{$this->getType()}_sku" => [
158+
[
159+
'sku' => 'Updated option sku',
160+
],
161+
],
162+
]
163+
);
164+
}
165+
166+
/**
167+
* Return option type.
168+
*
169+
* @return string
170+
*/
171+
abstract protected function getType(): string;
172+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\Catalog\Model\Product\Option\Create\DataProvider\Type\Date;
9+
10+
use Magento\Catalog\Model\Product\Option\Create\DataProvider\AbstractBase;
11+
12+
/**
13+
* Data provider for custom options from date group with type "date".
14+
*/
15+
class Date extends AbstractBase
16+
{
17+
/**
18+
* @inheritdoc
19+
*/
20+
protected function getType(): string
21+
{
22+
return 'date';
23+
}
24+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\Catalog\Model\Product\Option\Create\DataProvider\Type\Date;
9+
10+
use Magento\Catalog\Model\Product\Option\Create\DataProvider\AbstractBase;
11+
12+
/**
13+
* Data provider for custom options from date group with type "date & time".
14+
*/
15+
class DateTime extends AbstractBase
16+
{
17+
/**
18+
* @inheritdoc
19+
*/
20+
protected function getType(): string
21+
{
22+
return 'date_time';
23+
}
24+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\Catalog\Model\Product\Option\Create\DataProvider\Type\Date;
9+
10+
use Magento\Catalog\Model\Product\Option\Create\DataProvider\AbstractBase;
11+
12+
/**
13+
* Data provider for custom options from date group with type "time".
14+
*/
15+
class Time extends AbstractBase
16+
{
17+
/**
18+
* @inheritdoc
19+
*/
20+
protected function getType(): string
21+
{
22+
return 'time';
23+
}
24+
}

0 commit comments

Comments
 (0)