7
7
8
8
namespace Magento \Catalog \Test \Unit \Ui \DataProvider \Product \Form \Modifier ;
9
9
10
+ use Magento \Catalog \Api \Data \ProductInterface ;
11
+ use Magento \Catalog \Api \ProductLinkRepositoryInterface ;
12
+ use Magento \Catalog \Api \ProductRepositoryInterface ;
13
+ use Magento \Catalog \Helper \Image as ImageHelper ;
14
+ use Magento \Catalog \Model \Product \Attribute \Source \Status ;
15
+ use Magento \Catalog \Model \ProductLink \Link ;
16
+ use Magento \Catalog \Ui \Component \Listing \Columns \Price ;
10
17
use Magento \Catalog \Ui \DataProvider \Product \Form \Modifier \Related ;
18
+ use Magento \Eav \Api \AttributeSetRepositoryInterface ;
19
+ use Magento \Eav \Api \Data \AttributeSetInterface ;
20
+ use PHPUnit \Framework \MockObject \MockObject ;
11
21
22
+ /**
23
+ * Test related/upsell/crosssel products UI modifier
24
+ */
12
25
class RelatedTest extends AbstractModifierTest
13
26
{
27
+ /**
28
+ * @var ProductLinkRepositoryInterface|MockObject
29
+ */
30
+ private $ productLinkRepository ;
31
+
32
+ /**
33
+ * @var ProductRepositoryInterface|MockObject
34
+ */
35
+ private $ productRepository ;
36
+
37
+ /**
38
+ * @var ImageHelper|MockObject
39
+ */
40
+ private $ imageHelper ;
41
+
42
+ /**
43
+ * @var Status|MockObject
44
+ */
45
+ private $ status ;
46
+
47
+ /**
48
+ * @var AttributeSetRepositoryInterface|MockObject
49
+ */
50
+ private $ attributeSetRepository ;
51
+
52
+ /**
53
+ * @inheritdoc
54
+ */
55
+ protected function setUp (): void
56
+ {
57
+ parent ::setUp ();
58
+ $ this ->productLinkRepository = $ this ->createMock (ProductLinkRepositoryInterface::class);
59
+ $ this ->productRepository = $ this ->createMock (ProductRepositoryInterface::class);
60
+ $ this ->imageHelper = $ this ->createMock (ImageHelper::class);
61
+ $ this ->status = $ this ->createMock (Status::class);
62
+ $ this ->attributeSetRepository = $ this ->createMock (AttributeSetRepositoryInterface::class);
63
+ }
64
+
14
65
/**
15
66
* @return Related
16
67
*/
17
68
protected function createModel ()
18
69
{
19
70
return $ this ->objectManager ->getObject (Related::class, [
20
71
'locator ' => $ this ->locatorMock ,
72
+ 'productLinkRepository ' => $ this ->productLinkRepository ,
73
+ 'productRepository ' => $ this ->productRepository ,
74
+ 'imageHelper ' => $ this ->imageHelper ,
75
+ 'status ' => $ this ->status ,
76
+ 'attributeSetRepository ' => $ this ->attributeSetRepository ,
21
77
]);
22
78
}
23
79
@@ -38,4 +94,237 @@ public function testModifyData()
38
94
39
95
$ this ->assertSame ($ data , $ this ->getModel ()->modifyData ($ data ));
40
96
}
97
+
98
+ /**
99
+ * @return void
100
+ * @dataProvider sortingDataProvider
101
+ */
102
+ public function testSorting (array $ productLinks , array $ expectedLinks ): void
103
+ {
104
+ $ currentProductId = 1 ;
105
+ $ currentStoreId = 1 ;
106
+ $ thumnailUrl = '/path/to/thumnail ' ;
107
+ $ model = $ this ->getModel ();
108
+ $ priceModifier = $ this ->createMock (Price::class);
109
+ $ attributeSet = $ this ->createConfiguredMock (AttributeSetInterface::class, ['getAttributeSetName ' => 'Default ' ]);
110
+ $ this ->objectManager ->setBackwardCompatibleProperty ($ model , 'priceModifier ' , $ priceModifier );
111
+ $ products = $ this ->getProducts ();
112
+ $ priceModifier ->method ('prepareDataSource ' )
113
+ ->willReturnArgument (0 );
114
+ $ this ->productMock ->method ('getId ' )
115
+ ->willReturn ($ currentProductId );
116
+ $ this ->storeMock ->method ('getId ' )
117
+ ->willReturn ($ currentStoreId );
118
+ $ this ->imageHelper ->method ('init ' )
119
+ ->willReturnSelf ();
120
+ $ this ->imageHelper ->method ('getUrl ' )
121
+ ->willReturn ($ thumnailUrl );
122
+ $ this ->status ->method ('getOptionText ' )
123
+ ->willReturn ('Enabled ' );
124
+ $ this ->attributeSetRepository ->method ('get ' )
125
+ ->willReturn ($ attributeSet );
126
+ $ this ->productRepository
127
+ ->method ('get ' )
128
+ ->willReturnCallback (
129
+ function (string $ sku ) use ($ products ) {
130
+ return $ products [$ sku ];
131
+ }
132
+ );
133
+ $ this ->productLinkRepository ->method ('getList ' )
134
+ ->willReturn (
135
+ array_map (
136
+ function (array $ linkData ) {
137
+ $ link = $ this ->createPartialMock (Link::class, []);
138
+ $ link ->setData ($ linkData );
139
+ return $ link ;
140
+ },
141
+ $ productLinks
142
+ )
143
+ );
144
+ $ data = $ this ->getSampleData ();
145
+ $ expected = $ data ;
146
+ $ expected [$ currentProductId ]['links ' ] = $ expectedLinks ;
147
+ $ expected [$ currentProductId ]['product ' ] = [
148
+ 'current_product_id ' => $ currentProductId ,
149
+ 'current_store_id ' => $ currentStoreId ,
150
+ ];
151
+
152
+ $ this ->assertSame ($ expected , $ this ->getModel ()->modifyData ($ data ));
153
+ }
154
+
155
+ /**
156
+ * @return ProductInterface[]
157
+ */
158
+ private function getProducts (): array
159
+ {
160
+ $ products = [];
161
+ $ n = 1 ;
162
+ do {
163
+ $ sku = 'simple- ' . $ n ;
164
+ $ product = $ this ->createMock (ProductInterface::class);
165
+ $ product ->method ('getId ' )->willReturn ($ n );
166
+ $ product ->method ('getSku ' )->willReturn ($ sku );
167
+ $ product ->method ('getName ' )->willReturn ('Simple ' . $ n );
168
+ $ product ->method ('getPrice ' )->willReturn ($ n % 10 );
169
+ $ products [$ sku ] = $ product ;
170
+ } while (++$ n < 20 );
171
+ return $ products ;
172
+ }
173
+
174
+ /**
175
+ * @return array
176
+ * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
177
+ */
178
+ public function sortingDataProvider (): array
179
+ {
180
+ return [
181
+ [
182
+ [
183
+ [
184
+ 'link_type ' => Related::DATA_SCOPE_RELATED ,
185
+ 'linked_product_sku ' => 'simple-3 ' ,
186
+ 'position ' => 2 ,
187
+ ],
188
+ [
189
+ 'link_type ' => Related::DATA_SCOPE_CROSSSELL ,
190
+ 'linked_product_sku ' => 'simple-6 ' ,
191
+ 'position ' => 3 ,
192
+ ],
193
+ [
194
+ 'link_type ' => Related::DATA_SCOPE_UPSELL ,
195
+ 'linked_product_sku ' => 'simple-9 ' ,
196
+ 'position ' => 1 ,
197
+ ],
198
+ [
199
+ 'link_type ' => Related::DATA_SCOPE_RELATED ,
200
+ 'linked_product_sku ' => 'simple-13 ' ,
201
+ 'position ' => 3 ,
202
+ ],
203
+ [
204
+ 'link_type ' => Related::DATA_SCOPE_CROSSSELL ,
205
+ 'linked_product_sku ' => 'simple-17 ' ,
206
+ 'position ' => 2 ,
207
+ ],
208
+ [
209
+ 'link_type ' => Related::DATA_SCOPE_UPSELL ,
210
+ 'linked_product_sku ' => 'simple-19 ' ,
211
+ 'position ' => 2 ,
212
+ ],
213
+ [
214
+ 'link_type ' => Related::DATA_SCOPE_RELATED ,
215
+ 'linked_product_sku ' => 'simple-2 ' ,
216
+ 'position ' => 1 ,
217
+ ],
218
+ [
219
+ 'link_type ' => Related::DATA_SCOPE_CROSSSELL ,
220
+ 'linked_product_sku ' => 'simple-11 ' ,
221
+ 'position ' => 1 ,
222
+ ],
223
+ [
224
+ 'link_type ' => Related::DATA_SCOPE_UPSELL ,
225
+ 'linked_product_sku ' => 'simple-7 ' ,
226
+ 'position ' => 3 ,
227
+ ],
228
+ ],
229
+ [
230
+ Related::DATA_SCOPE_RELATED => [
231
+ [
232
+ 'id ' => 2 ,
233
+ 'thumbnail ' => '/path/to/thumnail ' ,
234
+ 'name ' => 'Simple 2 ' ,
235
+ 'status ' => 'Enabled ' ,
236
+ 'attribute_set ' => 'Default ' ,
237
+ 'sku ' => 'simple-2 ' ,
238
+ 'price ' => 2 ,
239
+ 'position ' => 1 ,
240
+ ],
241
+ [
242
+ 'id ' => 3 ,
243
+ 'thumbnail ' => '/path/to/thumnail ' ,
244
+ 'name ' => 'Simple 3 ' ,
245
+ 'status ' => 'Enabled ' ,
246
+ 'attribute_set ' => 'Default ' ,
247
+ 'sku ' => 'simple-3 ' ,
248
+ 'price ' => 3 ,
249
+ 'position ' => 2 ,
250
+ ],
251
+ [
252
+ 'id ' => 13 ,
253
+ 'thumbnail ' => '/path/to/thumnail ' ,
254
+ 'name ' => 'Simple 13 ' ,
255
+ 'status ' => 'Enabled ' ,
256
+ 'attribute_set ' => 'Default ' ,
257
+ 'sku ' => 'simple-13 ' ,
258
+ 'price ' => 3 ,
259
+ 'position ' => 3 ,
260
+ ],
261
+ ],
262
+ Related::DATA_SCOPE_CROSSSELL => [
263
+ [
264
+ 'id ' => 11 ,
265
+ 'thumbnail ' => '/path/to/thumnail ' ,
266
+ 'name ' => 'Simple 11 ' ,
267
+ 'status ' => 'Enabled ' ,
268
+ 'attribute_set ' => 'Default ' ,
269
+ 'sku ' => 'simple-11 ' ,
270
+ 'price ' => 1 ,
271
+ 'position ' => 1 ,
272
+ ],
273
+ [
274
+ 'id ' => 17 ,
275
+ 'thumbnail ' => '/path/to/thumnail ' ,
276
+ 'name ' => 'Simple 17 ' ,
277
+ 'status ' => 'Enabled ' ,
278
+ 'attribute_set ' => 'Default ' ,
279
+ 'sku ' => 'simple-17 ' ,
280
+ 'price ' => 7 ,
281
+ 'position ' => 2 ,
282
+ ],
283
+ [
284
+ 'id ' => 6 ,
285
+ 'thumbnail ' => '/path/to/thumnail ' ,
286
+ 'name ' => 'Simple 6 ' ,
287
+ 'status ' => 'Enabled ' ,
288
+ 'attribute_set ' => 'Default ' ,
289
+ 'sku ' => 'simple-6 ' ,
290
+ 'price ' => 6 ,
291
+ 'position ' => 3 ,
292
+ ],
293
+ ],
294
+ Related::DATA_SCOPE_UPSELL => [
295
+ [
296
+ 'id ' => 9 ,
297
+ 'thumbnail ' => '/path/to/thumnail ' ,
298
+ 'name ' => 'Simple 9 ' ,
299
+ 'status ' => 'Enabled ' ,
300
+ 'attribute_set ' => 'Default ' ,
301
+ 'sku ' => 'simple-9 ' ,
302
+ 'price ' => 9 ,
303
+ 'position ' => 1 ,
304
+ ],
305
+ [
306
+ 'id ' => 19 ,
307
+ 'thumbnail ' => '/path/to/thumnail ' ,
308
+ 'name ' => 'Simple 19 ' ,
309
+ 'status ' => 'Enabled ' ,
310
+ 'attribute_set ' => 'Default ' ,
311
+ 'sku ' => 'simple-19 ' ,
312
+ 'price ' => 9 ,
313
+ 'position ' => 2 ,
314
+ ],
315
+ [
316
+ 'id ' => 7 ,
317
+ 'thumbnail ' => '/path/to/thumnail ' ,
318
+ 'name ' => 'Simple 7 ' ,
319
+ 'status ' => 'Enabled ' ,
320
+ 'attribute_set ' => 'Default ' ,
321
+ 'sku ' => 'simple-7 ' ,
322
+ 'price ' => 7 ,
323
+ 'position ' => 3 ,
324
+ ],
325
+ ],
326
+ ],
327
+ ],
328
+ ];
329
+ }
41
330
}
0 commit comments