Passed
Push — master ( cacbf1...74b6c9 )
by
unknown
34:14
created

testFindProductConcretePricesWithoutPriceExtractionByConcreteAbstractMapShouldRes()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 32
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 19
nc 1
nop 0
dl 0
loc 32
rs 9.6333
c 1
b 0
f 0
1
<?php
2
3
/**
4
 * Copyright © 2016-present Spryker Systems GmbH. All rights reserved.
5
 * Use of this software requires acceptance of the Evaluation License Agreement. See LICENSE file.
6
 */
7
8
namespace SprykerTest\Zed\PriceProduct\Business\Facade;
9
10
use ArrayObject;
11
use Codeception\Test\Unit;
12
use Generated\Shared\Transfer\PriceProductTransfer;
13
use Generated\Shared\Transfer\PriceTypeTransfer;
14
use Generated\Shared\Transfer\ProductConcreteTransfer;
15
use SprykerTest\Zed\PriceProduct\PriceProductBusinessTester;
16
17
/**
18
 * Auto-generated group annotations
19
 *
20
 * @group SprykerTest
21
 * @group Zed
22
 * @group PriceProduct
23
 * @group Business
24
 * @group Facade
25
 * @group FindProductConcretePricesWithoutPriceExtractionByConcreteAbstractMapTest
26
 * Add your own group annotations below this line
27
 */
28
class FindProductConcretePricesWithoutPriceExtractionByConcreteAbstractMapTest extends Unit
29
{
30
    /**
31
     * @var \SprykerTest\Zed\PriceProduct\PriceProductBusinessTester
32
     */
33
    protected PriceProductBusinessTester $tester;
34
35
    /**
36
     * @return void
37
     */
38
    public function testFindProductConcretePricesWithoutPriceExtractionByConcreteAbstractMapShouldReturnPricesGroupedByConcreteProductId(): void
39
    {
40
        // Arrange
41
        $priceProductFacade = $this->tester->getFacade();
42
43
        $priceTypeTransfer = new PriceTypeTransfer();
44
        $priceTypeTransfer->setName($priceProductFacade->getDefaultPriceTypeName());
45
46
        $productConcreteTransfer1 = $this->tester->haveProduct();
47
        $prices1 = new ArrayObject();
48
        $prices1[] = $this->tester->createPriceProductTransfer($productConcreteTransfer1, $priceTypeTransfer, 100, 90, PriceProductBusinessTester::EUR_ISO_CODE);
49
        $productConcreteTransfer1->setPrices($prices1);
50
        $productConcreteTransfer1 = $priceProductFacade->persistProductConcretePriceCollection($productConcreteTransfer1);
51
52
        $productConcreteTransfer2 = $this->tester->haveProduct();
53
        $prices2 = new ArrayObject();
54
        $prices2[] = $this->tester->createPriceProductTransfer($productConcreteTransfer2, $priceTypeTransfer, 200, 180, PriceProductBusinessTester::EUR_ISO_CODE);
55
        $productConcreteTransfer2->setPrices($prices2);
56
        $productConcreteTransfer2 = $priceProductFacade->persistProductConcretePriceCollection($productConcreteTransfer2);
57
58
        $productAbstractIdMap = [
59
            $productConcreteTransfer1->getIdProductConcrete() => $productConcreteTransfer1->getFkProductAbstract(),
60
            $productConcreteTransfer2->getIdProductConcrete() => $productConcreteTransfer2->getFkProductAbstract(),
61
        ];
62
63
        $priceProductCriteriaTransfer = $this->tester->createPriceProductCriteriaTransfer();
64
        $priceProductCriteriaTransfer->setProductConcreteToAbstractIdMaps($productAbstractIdMap);
65
66
        // Act
67
        $result = $priceProductFacade->findProductConcretePricesWithoutPriceExtractionByConcreteAbstractMap($priceProductCriteriaTransfer);
68
69
        // Assert
70
        $this->assertIsArray($result);
71
        $this->assertCount(2, $result);
72
        $this->assertArrayHasKey($productConcreteTransfer1->getIdProductConcrete(), $result);
73
        $this->assertArrayHasKey($productConcreteTransfer2->getIdProductConcrete(), $result);
74
75
        $prices1Result = $result[$productConcreteTransfer1->getIdProductConcrete()];
76
        $this->assertIsArray($prices1Result);
77
        $this->assertNotEmpty($prices1Result);
78
79
        $prices2Result = $result[$productConcreteTransfer2->getIdProductConcrete()];
80
        $this->assertIsArray($prices2Result);
81
        $this->assertNotEmpty($prices2Result);
82
    }
83
84
    /**
85
     * @return void
86
     */
87
    public function testFindProductConcretePricesWithoutPriceExtractionByConcreteAbstractMapShouldReturnEmptyArrayForEmptyInput(): void
88
    {
89
        // Arrange
90
        $priceProductFacade = $this->tester->getFacade();
91
        $productAbstractIdMap = [];
92
        $priceProductCriteriaTransfer = $this->tester->createPriceProductCriteriaTransfer();
93
        $priceProductCriteriaTransfer->setProductConcreteToAbstractIdMaps($productAbstractIdMap);
94
95
        // Act
96
        $result = $priceProductFacade->findProductConcretePricesWithoutPriceExtractionByConcreteAbstractMap($priceProductCriteriaTransfer);
97
98
        // Assert
99
        $this->assertIsArray($result);
100
        $this->assertEmpty($result);
101
    }
102
103
    /**
104
     * @return void
105
     */
106
    public function testFindProductConcretePricesWithoutPriceExtractionByConcreteAbstractMapShouldReturnEmptyPricesForNonExistentProducts(): void
107
    {
108
        // Arrange
109
        $priceProductFacade = $this->tester->getFacade();
110
        $nonExistentProductId1 = 99999;
111
        $nonExistentProductId2 = 99998;
112
        $productAbstractIdMap = [
113
            $nonExistentProductId1 => 88888,
114
            $nonExistentProductId2 => 88887,
115
        ];
116
        $priceProductCriteriaTransfer = $this->tester->createPriceProductCriteriaTransfer();
117
        $priceProductCriteriaTransfer->setProductConcreteToAbstractIdMaps($productAbstractIdMap);
118
119
        // Act
120
        $result = $priceProductFacade->findProductConcretePricesWithoutPriceExtractionByConcreteAbstractMap($priceProductCriteriaTransfer);
121
122
        // Assert
123
        $this->assertIsArray($result);
124
        $this->assertEmpty($result);
125
    }
126
127
    /**
128
     * @return void
129
     */
130
    public function testFindProductConcretePricesWithoutPriceExtractionByConcreteAbstractMapShouldRespectPriceProductCriteria(): void
131
    {
132
        // Arrange
133
        $priceProductFacade = $this->tester->getFacade();
134
135
        $priceTypeTransfer = new PriceTypeTransfer();
136
        $priceTypeTransfer->setName($priceProductFacade->getDefaultPriceTypeName());
137
138
        // Create product with prices in multiple stores
139
        $productConcreteTransfer = $this->tester->haveProduct();
140
        $prices = new ArrayObject();
141
        $prices[] = $this->tester->createPriceProductTransfer($productConcreteTransfer, $priceTypeTransfer, 100, 90, PriceProductBusinessTester::EUR_ISO_CODE);
142
        $prices[] = $this->tester->createPriceProductTransfer($productConcreteTransfer, $priceTypeTransfer, 120, 110, PriceProductBusinessTester::USD_ISO_CODE);
143
        $productConcreteTransfer->setPrices($prices);
144
        $productConcreteTransfer = $priceProductFacade->persistProductConcretePriceCollection($productConcreteTransfer);
145
146
        $productAbstractIdMap = [
147
            $productConcreteTransfer->getIdProductConcrete() => $productConcreteTransfer->getFkProductAbstract(),
148
        ];
149
        $priceProductCriteriaTransfer = $this->tester->createPriceProductCriteriaTransfer();
150
        $priceProductCriteriaTransfer->setProductConcreteToAbstractIdMaps($productAbstractIdMap);
151
152
        // Act
153
        $result = $priceProductFacade->findProductConcretePricesWithoutPriceExtractionByConcreteAbstractMap($priceProductCriteriaTransfer);
154
155
        // Assert
156
        $this->assertIsArray($result);
157
        $this->assertCount(1, $result);
158
        $this->assertArrayHasKey($productConcreteTransfer->getIdProductConcrete(), $result);
159
160
        $pricesResult = $result[$productConcreteTransfer->getIdProductConcrete()];
161
        $this->assertIsArray($pricesResult);
162
    }
163
164
    /**
165
     * @return void
166
     */
167
    public function testFindProductConcretePricesWithoutPriceExtractionByConcreteAbstractMapShouldIncludeAbstractPricesWhenConcreteHasNone(): void
168
    {
169
        // Arrange
170
        $priceProductFacade = $this->tester->getFacade();
171
172
        $priceTypeTransfer = new PriceTypeTransfer();
173
        $priceTypeTransfer->setName($priceProductFacade->getDefaultPriceTypeName());
174
175
        // Create product abstract with prices
176
        $productAbstractTransfer = $this->tester->haveProductAbstract();
177
        $abstractPrices = new ArrayObject();
178
        $abstractPrices[] = $this->tester->havePriceProductAbstract(
179
            $productAbstractTransfer->getIdProductAbstractOrFail(),
180
            [
181
                PriceProductTransfer::SKU_PRODUCT_ABSTRACT => $productAbstractTransfer->getSku(),
182
            ],
183
        );
184
        $productAbstractTransfer->setPrices($abstractPrices);
185
        $productAbstractTransfer = $priceProductFacade->persistProductAbstractPriceCollection($productAbstractTransfer);
186
187
        // Create product concrete without prices (will inherit from abstract)
188
        $productConcreteTransfer = $this->tester->haveProduct([ProductConcreteTransfer::FK_PRODUCT_ABSTRACT => $productAbstractTransfer->getIdProductAbstract()]);
189
190
        $productAbstractIdMap = [
191
            $productConcreteTransfer->getIdProductConcrete() => $productAbstractTransfer->getIdProductAbstract(),
192
        ];
193
194
        $priceProductCriteriaTransfer = $this->tester->createPriceProductCriteriaTransfer();
195
        $priceProductCriteriaTransfer->setOnlyConcretePrices(false);
196
        $priceProductCriteriaTransfer->setProductConcreteToAbstractIdMaps($productAbstractIdMap);
197
198
        // Act
199
        $result = $priceProductFacade->findProductConcretePricesWithoutPriceExtractionByConcreteAbstractMap($priceProductCriteriaTransfer);
200
201
        // Assert
202
        $this->assertIsArray($result);
203
        $this->assertCount(1, $result);
204
        $this->assertArrayHasKey($productConcreteTransfer->getIdProductConcrete(), $result);
205
206
        $pricesResult = $result[$productConcreteTransfer->getIdProductConcrete()];
207
        $this->assertIsArray($pricesResult);
208
        $this->assertNotEmpty($pricesResult);
209
210
        // Verify that abstract prices are returned for concrete product
211
        foreach ($pricesResult as $priceProductTransfer) {
212
            $this->assertEquals($productAbstractTransfer->getIdProductAbstract(), $priceProductTransfer->getIdProductAbstract());
213
            $this->assertNull($priceProductTransfer->getIdProduct());
214
        }
215
    }
216
217
    /**
218
     * @return void
219
     */
220
    public function testFindProductConcretePricesWithoutPriceExtractionByConcreteAbstractMapShouldOnlyReturnConcretePricesWhenCriteriaSpecifies(): void
221
    {
222
        // Arrange
223
        $priceProductFacade = $this->tester->getFacade();
224
225
        $priceTypeTransfer = new PriceTypeTransfer();
226
        $priceTypeTransfer->setName($priceProductFacade->getDefaultPriceTypeName());
227
228
        // Create product abstract with prices
229
        $productAbstractTransfer = $this->tester->haveProductAbstract();
230
        $abstractPrices = new ArrayObject();
231
        $abstractPrices[] = $this->tester->havePriceProductAbstract(
232
            $productAbstractTransfer->getIdProductAbstractOrFail(),
233
            [
234
                PriceProductTransfer::SKU_PRODUCT_ABSTRACT => $productAbstractTransfer->getSku(),
235
            ],
236
        );
237
238
        // Create product concrete with prices
239
        $productConcreteTransfer = $this->tester->haveProduct([ProductConcreteTransfer::FK_PRODUCT_ABSTRACT => $productAbstractTransfer->getIdProductAbstract()]);
240
        $concretePrices = new ArrayObject();
241
        $concretePrices[] = $this->tester->createPriceProductTransfer($productConcreteTransfer, $priceTypeTransfer, 100, 90, PriceProductBusinessTester::EUR_ISO_CODE);
242
        $productConcreteTransfer->setPrices($concretePrices);
243
        $productConcreteTransfer = $priceProductFacade->persistProductConcretePriceCollection($productConcreteTransfer);
244
245
        $productAbstractIdMap = [
246
            $productConcreteTransfer->getIdProductConcrete() => $productConcreteTransfer->getFkProductAbstract(),
247
        ];
248
249
        // Create criteria that specifies only concrete prices
250
        $priceProductCriteriaTransfer = $this->tester->createPriceProductCriteriaTransfer();
251
        $priceProductCriteriaTransfer->setOnlyConcretePrices(true);
252
        $priceProductCriteriaTransfer->setProductConcreteToAbstractIdMaps($productAbstractIdMap);
253
254
        // Act
255
        $result = $priceProductFacade->findProductConcretePricesWithoutPriceExtractionByConcreteAbstractMap($priceProductCriteriaTransfer);
256
257
        // Assert
258
        $this->assertIsArray($result);
259
        $this->assertCount(1, $result);
260
        $this->assertArrayHasKey($productConcreteTransfer->getIdProductConcrete(), $result);
261
262
        $pricesResult = $result[$productConcreteTransfer->getIdProductConcrete()];
263
        $this->assertIsArray($pricesResult);
264
        $this->assertNotEmpty($pricesResult);
265
266
        // Verify that only concrete prices are returned
267
        foreach ($pricesResult as $priceProductTransfer) {
268
            $this->assertEquals($productConcreteTransfer->getIdProductConcrete(), $priceProductTransfer->getIdProduct());
269
            $this->assertNotNull($priceProductTransfer->getIdProduct());
270
        }
271
    }
272
273
    /**
274
     * @return void
275
     */
276
    public function testFindProductConcretePricesWithoutPriceExtractionByConcreteAbstractMapShouldHandleLargeProductMap(): void
277
    {
278
        // Arrange
279
        $priceProductFacade = $this->tester->getFacade();
280
281
        $priceTypeTransfer = new PriceTypeTransfer();
282
        $priceTypeTransfer->setName($priceProductFacade->getDefaultPriceTypeName());
283
284
        $productAbstractIdMap = [];
285
        $expectedProductIds = [];
286
287
        // Create multiple products with prices
288
        for ($i = 0; $i < 5; $i++) {
289
            $productConcreteTransfer = $this->tester->haveProduct();
290
            $prices = new ArrayObject();
291
            $prices[] = $this->tester->createPriceProductTransfer($productConcreteTransfer, $priceTypeTransfer, 100 + $i * 10, 90 + $i * 10, PriceProductBusinessTester::EUR_ISO_CODE);
292
            $productConcreteTransfer->setPrices($prices);
293
            $productConcreteTransfer = $priceProductFacade->persistProductConcretePriceCollection($productConcreteTransfer);
294
295
            $productAbstractIdMap[$productConcreteTransfer->getIdProductConcrete()] = $productConcreteTransfer->getFkProductAbstract();
296
            $expectedProductIds[] = $productConcreteTransfer->getIdProductConcrete();
297
        }
298
299
        $priceProductCriteriaTransfer = $this->tester->createPriceProductCriteriaTransfer();
300
        $priceProductCriteriaTransfer->setProductConcreteToAbstractIdMaps($productAbstractIdMap);
301
302
        // Act
303
        $result = $priceProductFacade->findProductConcretePricesWithoutPriceExtractionByConcreteAbstractMap($priceProductCriteriaTransfer);
304
305
        // Assert
306
        $this->assertIsArray($result);
307
        $this->assertCount(5, $result);
308
309
        foreach ($expectedProductIds as $productId) {
310
            $this->assertArrayHasKey($productId, $result);
311
            $this->assertIsArray($result[$productId]);
312
            $this->assertNotEmpty($result[$productId]);
313
        }
314
    }
315
316
    /**
317
     * @return void
318
     */
319
    public function testFindProductConcretePricesWithoutPriceExtractionByConcreteAbstractMapShouldWorkWithDifferentPriceDimensions(): void
320
    {
321
        // Arrange
322
        $priceProductFacade = $this->tester->getFacade();
323
324
        $priceTypeTransfer = new PriceTypeTransfer();
325
        $priceTypeTransfer->setName($priceProductFacade->getDefaultPriceTypeName());
326
327
        $productConcreteTransfer = $this->tester->haveProduct();
328
        $prices = new ArrayObject();
329
        $prices[] = $this->tester->createPriceProductTransfer($productConcreteTransfer, $priceTypeTransfer, 100, 90, PriceProductBusinessTester::EUR_ISO_CODE);
330
        $productConcreteTransfer->setPrices($prices);
331
        $productConcreteTransfer = $priceProductFacade->persistProductConcretePriceCollection($productConcreteTransfer);
332
333
        $productAbstractIdMap = [
334
            $productConcreteTransfer->getIdProductConcrete() => $productConcreteTransfer->getFkProductAbstract(),
335
        ];
336
337
        $priceProductCriteriaTransfer = $this->tester->createPriceProductCriteriaTransfer();
338
        $priceProductCriteriaTransfer->setProductConcreteToAbstractIdMaps($productAbstractIdMap);
339
        // Act
340
        $result = $priceProductFacade->findProductConcretePricesWithoutPriceExtractionByConcreteAbstractMap($priceProductCriteriaTransfer);
341
342
        // Assert
343
        $this->assertIsArray($result);
344
        $this->assertCount(1, $result);
345
        $this->assertArrayHasKey($productConcreteTransfer->getIdProductConcrete(), $result);
346
347
        $pricesResult = $result[$productConcreteTransfer->getIdProductConcrete()];
348
        $this->assertIsArray($pricesResult);
349
350
        $priceDimension = $this->tester->createSharedPriceProductConfig()->getPriceDimensionDefault();
351
        foreach ($pricesResult as $priceProductTransfer) {
352
            $this->assertEquals($priceDimension, $priceProductTransfer->getPriceDimension()->getType());
353
        }
354
    }
355
}
356