5
5
*/
6
6
namespace Magento \GroupedProduct \Model \Product \Type ;
7
7
8
+ use Magento \Catalog \Api \ProductRepositoryInterface ;
9
+ use Magento \Catalog \Model \Product ;
10
+ use Magento \CatalogInventory \Model \Configuration ;
11
+ use Magento \Framework \App \Config \ReinitableConfigInterface ;
12
+ use Magento \Framework \App \Config \Value ;
13
+
8
14
class GroupedTest extends \PHPUnit \Framework \TestCase
9
15
{
16
+ /**
17
+ * @var ReinitableConfigInterface
18
+ */
19
+ private $ reinitableConfig ;
20
+
10
21
/**
11
22
* @var \Magento\Framework\ObjectManagerInterface
12
23
*/
@@ -20,16 +31,21 @@ class GroupedTest extends \PHPUnit\Framework\TestCase
20
31
protected function setUp ()
21
32
{
22
33
$ this ->objectManager = \Magento \TestFramework \Helper \Bootstrap::getObjectManager ();
23
-
24
34
$ this ->_productType = $ this ->objectManager ->get (\Magento \Catalog \Model \Product \Type::class);
35
+ $ this ->reinitableConfig = $ this ->objectManager ->get (ReinitableConfigInterface::class);
36
+ }
37
+
38
+ protected function tearDown ()
39
+ {
40
+ $ this ->dropConfigValue (Configuration::XML_PATH_SHOW_OUT_OF_STOCK );
25
41
}
26
42
27
43
public function testFactory ()
28
44
{
29
45
$ product = new \Magento \Framework \DataObject ();
30
- $ product ->setTypeId (\ Magento \ GroupedProduct \ Model \ Product \ Type \ Grouped::TYPE_CODE );
46
+ $ product ->setTypeId (Grouped::TYPE_CODE );
31
47
$ type = $ this ->_productType ->factory ($ product );
32
- $ this ->assertInstanceOf (\ Magento \ GroupedProduct \ Model \ Product \ Type \ Grouped::class, $ type );
48
+ $ this ->assertInstanceOf (Grouped::class, $ type );
33
49
}
34
50
35
51
/**
@@ -38,12 +54,12 @@ public function testFactory()
38
54
*/
39
55
public function testGetAssociatedProducts ()
40
56
{
41
- $ productRepository = $ this ->objectManager ->create (\ Magento \ Catalog \ Api \ ProductRepositoryInterface::class);
57
+ $ productRepository = $ this ->objectManager ->create (ProductRepositoryInterface::class);
42
58
43
- /** @var \Magento\Catalog\Model\ Product $product */
59
+ /** @var Product $product */
44
60
$ product = $ productRepository ->get ('grouped-product ' );
45
61
$ type = $ product ->getTypeInstance ();
46
- $ this ->assertInstanceOf (\ Magento \ GroupedProduct \ Model \ Product \ Type \ Grouped::class, $ type );
62
+ $ this ->assertInstanceOf (Grouped::class, $ type );
47
63
48
64
$ associatedProducts = $ type ->getAssociatedProducts ($ product );
49
65
$ this ->assertCount (2 , $ associatedProducts );
@@ -53,7 +69,7 @@ public function testGetAssociatedProducts()
53
69
}
54
70
55
71
/**
56
- * @param \Magento\Catalog\Model\ Product $product
72
+ * @param Product $product
57
73
*/
58
74
private function assertProductInfo ($ product )
59
75
{
@@ -92,25 +108,25 @@ public function testPrepareProduct()
92
108
\Magento \Framework \DataObject::class,
93
109
['data ' => ['value ' => ['qty ' => 2 ]]]
94
110
);
95
- /** @var \Magento\Catalog\Api\ ProductRepositoryInterface $productRepository */
96
- $ productRepository = $ this ->objectManager ->get (\ Magento \ Catalog \ Api \ ProductRepositoryInterface::class);
111
+ /** @var ProductRepositoryInterface $productRepository */
112
+ $ productRepository = $ this ->objectManager ->get (ProductRepositoryInterface::class);
97
113
$ product = $ productRepository ->get ('grouped-product ' );
98
114
99
- /** @var \Magento\GroupedProduct\Model\Product\Type\ Grouped $type */
100
- $ type = $ this ->objectManager ->get (\ Magento \ GroupedProduct \ Model \ Product \ Type \ Grouped::class);
115
+ /** @var Grouped $type */
116
+ $ type = $ this ->objectManager ->get (Grouped::class);
101
117
102
118
$ processModes = [
103
- \ Magento \ GroupedProduct \ Model \ Product \ Type \ Grouped::PROCESS_MODE_FULL ,
104
- \ Magento \ GroupedProduct \ Model \ Product \ Type \ Grouped::PROCESS_MODE_LITE
119
+ Grouped::PROCESS_MODE_FULL ,
120
+ Grouped::PROCESS_MODE_LITE
105
121
];
106
122
$ expectedData = [
107
- \ Magento \ GroupedProduct \ Model \ Product \ Type \ Grouped::PROCESS_MODE_FULL => [
123
+ Grouped::PROCESS_MODE_FULL => [
108
124
1 => '{"super_product_config":{"product_type":"grouped","product_id":" '
109
125
. $ product ->getId () . '"}} ' ,
110
126
21 => '{"super_product_config":{"product_type":"grouped","product_id":" '
111
127
. $ product ->getId () . '"}} ' ,
112
128
],
113
- \ Magento \ GroupedProduct \ Model \ Product \ Type \ Grouped::PROCESS_MODE_LITE => [
129
+ Grouped::PROCESS_MODE_LITE => [
114
130
$ product ->getId () => '{"value":{"qty":2}} ' ,
115
131
]
116
132
];
@@ -127,4 +143,152 @@ public function testPrepareProduct()
127
143
}
128
144
}
129
145
}
146
+
147
+ /**
148
+ * Test adding grouped product to cart when one of subproducts is out of stock.
149
+ *
150
+ * @magentoDataFixture Magento/GroupedProduct/_files/product_grouped_with_out_of_stock.php
151
+ * @magentoAppArea frontend
152
+ * @magentoAppIsolation enabled
153
+ * @magentoDbIsolation enabled
154
+ * @dataProvider outOfStockSubProductDataProvider
155
+ * @param bool $outOfStockShown
156
+ * @param array $data
157
+ * @param array $expected
158
+ */
159
+ public function testOutOfStockSubProduct (bool $ outOfStockShown , array $ data , array $ expected )
160
+ {
161
+ $ this ->changeConfigValue (Configuration::XML_PATH_SHOW_OUT_OF_STOCK , $ outOfStockShown );
162
+ $ buyRequest = new \Magento \Framework \DataObject ($ data );
163
+ $ productRepository = $ this ->objectManager ->create (ProductRepositoryInterface::class);
164
+ /** @var Product $product */
165
+ $ product = $ productRepository ->get ('grouped-product ' );
166
+ /** @var Grouped $groupedProduct */
167
+ $ groupedProduct = $ this ->objectManager ->get (Grouped::class);
168
+ $ actual = $ groupedProduct ->prepareForCartAdvanced ($ buyRequest , $ product , Grouped::PROCESS_MODE_FULL );
169
+ self ::assertEquals (
170
+ count ($ expected ),
171
+ count ($ actual )
172
+ );
173
+ /** @var Product $product */
174
+ foreach ($ actual as $ product ) {
175
+ $ sku = $ product ->getSku ();
176
+ self ::assertEquals (
177
+ $ expected [$ sku ],
178
+ $ product ->getCartQty (),
179
+ "Failed asserting that Product Cart Quantity matches expected "
180
+ );
181
+ }
182
+ }
183
+
184
+ /**
185
+ * Data provider for testOutOfStockSubProduct.
186
+ *
187
+ * @return array
188
+ */
189
+ public function outOfStockSubProductDataProvider ()
190
+ {
191
+ return [
192
+ 'Out of stock product are shown #1 ' => [
193
+ true ,
194
+ [
195
+ 'product ' => 3 ,
196
+ 'qty ' => 1 ,
197
+ 'super_group ' => [
198
+ 1 => 4 ,
199
+ 21 => 5 ,
200
+ ],
201
+ ],
202
+ [
203
+ 'virtual-product ' => 5 ,
204
+ 'simple ' => 4
205
+ ],
206
+ ],
207
+ 'Out of stock product are shown #2 ' => [
208
+ true ,
209
+ [
210
+ 'product ' => 3 ,
211
+ 'qty ' => 1 ,
212
+ 'super_group ' => [
213
+ 1 => 0 ,
214
+ ],
215
+ ],
216
+ [
217
+ 'virtual-product ' => 2.5 , // This is a default quantity.
218
+ ],
219
+ ],
220
+ 'Out of stock product are hidden #1 ' => [
221
+ false ,
222
+ [
223
+ 'product ' => 3 ,
224
+ 'qty ' => 1 ,
225
+ 'super_group ' => [
226
+ 1 => 4 ,
227
+ 21 => 5 ,
228
+ ],
229
+ ],
230
+ [
231
+ 'virtual-product ' => 5 ,
232
+ 'simple ' => 4 ,
233
+ ],
234
+ ],
235
+ 'Out of stock product are hidden #2 ' => [
236
+ false ,
237
+ [
238
+ 'product ' => 3 ,
239
+ 'qty ' => 1 ,
240
+ 'super_group ' => [
241
+ 1 => 0 ,
242
+ ],
243
+ ],
244
+ [
245
+ 'virtual-product ' => 2.5 , // This is a default quantity.
246
+ ],
247
+ ],
248
+ ];
249
+ }
250
+
251
+ /**
252
+ * Write config value to database.
253
+ *
254
+ * @param string $path
255
+ * @param string $value
256
+ * @param string $scope
257
+ * @param int $scopeId
258
+ */
259
+ private function changeConfigValue (string $ path , string $ value , string $ scope = 'default ' , int $ scopeId = 0 )
260
+ {
261
+ $ configValue = $ this ->objectManager ->create (Value::class);
262
+ $ configValue ->setPath ($ path )
263
+ ->setValue ($ value )
264
+ ->setScope ($ scope )
265
+ ->setScopeId ($ scopeId )
266
+ ->save ();
267
+ $ this ->reinitConfig ();
268
+ }
269
+
270
+ /**
271
+ * Delete config value from database.
272
+ *
273
+ * @param string $path
274
+ */
275
+ private function dropConfigValue (string $ path )
276
+ {
277
+ $ configValue = $ this ->objectManager ->create (Value::class);
278
+ try {
279
+ $ configValue ->load ($ path , 'path ' );
280
+ $ configValue ->delete ();
281
+ } catch (\Magento \Framework \Exception \NoSuchEntityException $ e ) {
282
+ // do nothing
283
+ }
284
+ $ this ->reinitConfig ();
285
+ }
286
+
287
+ /**
288
+ * Reinit config.
289
+ */
290
+ private function reinitConfig ()
291
+ {
292
+ $ this ->reinitableConfig ->reinit ();
293
+ }
130
294
}
0 commit comments