77
88namespace Magento \Catalog \Test \Unit \Ui \DataProvider \Product \Form \Modifier ;
99
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 ;
1017use 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 ;
1121
22+ /**
23+ * Test related/upsell/crosssel products UI modifier
24+ */
1225class RelatedTest extends AbstractModifierTest
1326{
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+
1465 /**
1566 * @return Related
1667 */
1768 protected function createModel ()
1869 {
1970 return $ this ->objectManager ->getObject (Related::class, [
2071 'locator ' => $ this ->locatorMock ,
72+ 'productLinkRepository ' => $ this ->productLinkRepository ,
73+ 'productRepository ' => $ this ->productRepository ,
74+ 'imageHelper ' => $ this ->imageHelper ,
75+ 'status ' => $ this ->status ,
76+ 'attributeSetRepository ' => $ this ->attributeSetRepository ,
2177 ]);
2278 }
2379
@@ -38,4 +94,237 @@ public function testModifyData()
3894
3995 $ this ->assertSame ($ data , $ this ->getModel ()->modifyData ($ data ));
4096 }
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+ }
41330}
0 commit comments