7
7
8
8
namespace Magento \GraphQl \CatalogInventory ;
9
9
10
+ use Magento \Catalog \Test \Fixture \Product as ProductFixture ;
10
11
use Magento \Config \Model \ResourceModel \Config ;
12
+ use Magento \ConfigurableProduct \Test \Fixture \Attribute as AttributeFixture ;
13
+ use Magento \ConfigurableProduct \Test \Fixture \Product as ConfigurableProductFixture ;
14
+ use Magento \Eav \Api \Data \AttributeInterface ;
15
+ use Magento \Eav \Api \Data \AttributeOptionInterface ;
11
16
use Magento \Framework \App \Config \ReinitableConfigInterface ;
12
17
use Magento \Catalog \Api \ProductRepositoryInterface ;
13
- use Magento \Framework \App \Config \ScopeConfigInterface ;
18
+ use Magento \Framework \DataObject ;
19
+ use Magento \Quote \Test \Fixture \GuestCart as GuestCartFixture ;
20
+ use Magento \Quote \Test \Fixture \QuoteIdMask as QuoteMaskFixture ;
21
+ use Magento \TestFramework \App \ApiMutableScopeConfig ;
22
+ use Magento \TestFramework \Fixture \DataFixture ;
23
+ use Magento \TestFramework \Fixture \DataFixtureStorage ;
24
+ use Magento \TestFramework \Fixture \DataFixtureStorageManager ;
14
25
use Magento \TestFramework \ObjectManager ;
15
26
use Magento \TestFramework \TestCase \GraphQlAbstract ;
16
27
use Magento \CatalogInventory \Model \Configuration ;
20
31
*/
21
32
class ProductOnlyXLeftInStockTest extends GraphQlAbstract
22
33
{
34
+ private const PARENT_SKU_CONFIGURABLE = 'parent_configurable ' ;
35
+
36
+ private const SKU = 'simple_10 ' ;
37
+
23
38
/**
24
39
* @var ProductRepositoryInterface
25
40
*/
@@ -30,7 +45,7 @@ class ProductOnlyXLeftInStockTest extends GraphQlAbstract
30
45
private $ resourceConfig ;
31
46
32
47
/**
33
- * @var ScopeConfigInterface
48
+ * @var ApiMutableScopeConfig
34
49
*/
35
50
private $ scopeConfig ;
36
51
@@ -39,6 +54,11 @@ class ProductOnlyXLeftInStockTest extends GraphQlAbstract
39
54
*/
40
55
private $ reinitConfig ;
41
56
57
+ /**
58
+ * @var DataFixtureStorage
59
+ */
60
+ private $ fixtures ;
61
+
42
62
/**
43
63
* @inheritdoc
44
64
*/
@@ -49,8 +69,9 @@ protected function setUp(): void
49
69
$ objectManager = ObjectManager::getInstance ();
50
70
$ this ->productRepository = $ objectManager ->create (ProductRepositoryInterface::class);
51
71
$ this ->resourceConfig = $ objectManager ->get (Config::class);
52
- $ this ->scopeConfig = $ objectManager ->get (ScopeConfigInterface ::class);
72
+ $ this ->scopeConfig = $ objectManager ->get (ApiMutableScopeConfig ::class);
53
73
$ this ->reinitConfig = $ objectManager ->get (ReinitableConfigInterface::class);
74
+ $ this ->fixtures = DataFixtureStorageManager::getStorage ();
54
75
}
55
76
56
77
/**
@@ -91,7 +112,7 @@ public function testQueryProductOnlyXLeftInStockEnabled()
91
112
products(filter: {sku: {eq: " {$ productSku }"}})
92
113
{
93
114
items {
94
- only_x_left_in_stock
115
+ only_x_left_in_stock
95
116
}
96
117
}
97
118
}
@@ -118,13 +139,13 @@ public function testQueryProductOnlyXLeftInStockOutstock()
118
139
// need to resave product to reindex it with new configuration.
119
140
$ product = $ this ->productRepository ->get ($ productSku );
120
141
$ this ->productRepository ->save ($ product );
121
-
142
+
122
143
$ query = <<<QUERY
123
144
{
124
145
products(filter: {sku: {eq: " {$ productSku }"}})
125
146
{
126
147
items {
127
- only_x_left_in_stock
148
+ only_x_left_in_stock
128
149
}
129
150
}
130
151
}
@@ -138,4 +159,111 @@ public function testQueryProductOnlyXLeftInStockOutstock()
138
159
$ this ->assertArrayHasKey ('only_x_left_in_stock ' , $ response ['products ' ]['items ' ][0 ]);
139
160
$ this ->assertEquals (0 , $ response ['products ' ]['items ' ][0 ]['only_x_left_in_stock ' ]);
140
161
}
162
+
163
+ #[
164
+ DataFixture(ProductFixture::class, ['sku ' => self ::SKU ], as: 'product ' ),
165
+ DataFixture(AttributeFixture::class, as: 'attribute ' ),
166
+ DataFixture(
167
+ ConfigurableProductFixture::class,
168
+ [
169
+ 'sku ' => self ::PARENT_SKU_CONFIGURABLE ,
170
+ '_options ' => ['$attribute$ ' ],
171
+ '_links ' => ['$product$ ' ],
172
+ ],
173
+ 'configurable_product '
174
+ ),
175
+ DataFixture(GuestCartFixture::class, as: 'cart ' ),
176
+ DataFixture(QuoteMaskFixture::class, ['cart_id ' => '$cart.id$ ' ], 'quoteIdMask ' ),
177
+ ]
178
+ /**
179
+ * @dataProvider stockThresholdQtyProvider
180
+ */
181
+ public function testOnlyXLeftInStockConfigurableProduct (string $ stockThresholdQty , ?int $ expected ): void
182
+ {
183
+ $ this ->scopeConfig ->setValue ('cataloginventory/options/stock_threshold_qty ' , $ stockThresholdQty );
184
+ $ maskedQuoteId = $ this ->fixtures ->get ('quoteIdMask ' )->getMaskedId ();
185
+ /** @var AttributeInterface $attribute */
186
+ $ attribute = $ this ->fixtures ->get ('attribute ' );
187
+ /** @var AttributeOptionInterface $option */
188
+ $ option = $ attribute ->getOptions ()[1 ];
189
+ $ selectedOption = base64_encode ("configurable/ {$ attribute ->getAttributeId ()}/ {$ option ->getValue ()}" );
190
+ $ query = $ this ->mutationAddConfigurableProduct (
191
+ $ maskedQuoteId ,
192
+ self ::PARENT_SKU_CONFIGURABLE ,
193
+ $ selectedOption ,
194
+ 100
195
+ );
196
+
197
+ $ this ->graphQlMutation ($ query );
198
+
199
+ $ query = <<<QUERY
200
+ {
201
+ cart(cart_id: " $ maskedQuoteId") {
202
+ total_quantity
203
+ itemsV2 {
204
+ items {
205
+ uid
206
+ product {
207
+ name
208
+ sku
209
+ stock_status
210
+ only_x_left_in_stock
211
+ }
212
+ }
213
+ }
214
+ }
215
+ }
216
+ QUERY ;
217
+
218
+ $ response = $ this ->graphQlQuery ($ query );
219
+ $ responseDataObject = new DataObject ($ response );
220
+ self ::assertEquals (
221
+ $ expected ,
222
+ $ responseDataObject ->getData ('cart/itemsV2/items/0/product/only_x_left_in_stock ' ),
223
+ );
224
+ }
225
+
226
+ public function stockThresholdQtyProvider (): array
227
+ {
228
+ return [
229
+ ['0 ' , null ],
230
+ ['200 ' , 100 ]
231
+ ];
232
+ }
233
+
234
+ private function mutationAddConfigurableProduct (
235
+ string $ cartId ,
236
+ string $ sku ,
237
+ string $ selectedOption ,
238
+ int $ qty = 1
239
+ ): string {
240
+ return <<<QUERY
241
+ mutation {
242
+ addProductsToCart(
243
+ cartId: " {$ cartId }",
244
+ cartItems: [
245
+ {
246
+ sku: " {$ sku }"
247
+ quantity: $ qty
248
+ selected_options: [
249
+ " $ selectedOption"
250
+ ]
251
+ }]
252
+ ) {
253
+ cart {
254
+ items {
255
+ is_available
256
+ product {
257
+ sku
258
+ }
259
+ }
260
+ }
261
+ user_errors {
262
+ code
263
+ message
264
+ }
265
+ }
266
+ }
267
+ QUERY ;
268
+ }
141
269
}
0 commit comments