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\Discount\Business; |
||||
9 | |||||
10 | use ArrayObject; |
||||
11 | use Codeception\Test\Unit; |
||||
12 | use DateTime; |
||||
13 | use Generated\Shared\Transfer\CheckoutResponseTransfer; |
||||
14 | use Generated\Shared\Transfer\ClauseTransfer; |
||||
15 | use Generated\Shared\Transfer\CollectedDiscountTransfer; |
||||
16 | use Generated\Shared\Transfer\CurrencyTransfer; |
||||
17 | use Generated\Shared\Transfer\DiscountableItemTransfer; |
||||
18 | use Generated\Shared\Transfer\DiscountTransfer; |
||||
19 | use Generated\Shared\Transfer\DiscountVoucherTransfer; |
||||
20 | use Generated\Shared\Transfer\ItemTransfer; |
||||
21 | use Generated\Shared\Transfer\MoneyValueTransfer; |
||||
22 | use Generated\Shared\Transfer\QuoteTransfer; |
||||
23 | use Generated\Shared\Transfer\StoreTransfer; |
||||
24 | use Generated\Shared\Transfer\TotalsTransfer; |
||||
25 | use Orm\Zed\Discount\Persistence\SpyDiscountQuery; |
||||
26 | use Spryker\Shared\Discount\DiscountConstants; |
||||
27 | use Spryker\Zed\Discount\Business\DiscountBusinessFactory; |
||||
28 | use Spryker\Zed\Discount\Business\QueryString\ComparatorOperators; |
||||
29 | use Spryker\Zed\Discount\Business\QueryString\Specification\MetaData\MetaProviderFactory; |
||||
30 | use Spryker\Zed\Discount\Business\Voucher\VoucherValidator; |
||||
31 | use Spryker\Zed\Discount\DiscountDependencyProvider; |
||||
32 | use Spryker\Zed\DiscountExtension\Dependency\Plugin\DiscountRuleWithValueOptionsPluginInterface; |
||||
33 | use Spryker\Zed\Kernel\Container; |
||||
34 | |||||
35 | /** |
||||
36 | * Auto-generated group annotations |
||||
37 | * |
||||
38 | * @group SprykerTest |
||||
39 | * @group Zed |
||||
40 | * @group Discount |
||||
41 | * @group Business |
||||
42 | * @group Facade |
||||
43 | * @group DiscountFacadeTest |
||||
44 | * Add your own group annotations below this line |
||||
45 | */ |
||||
46 | class DiscountFacadeTest extends Unit |
||||
47 | { |
||||
48 | /** |
||||
49 | * @var string |
||||
50 | */ |
||||
51 | protected const STORE_NAME_DE = 'DE'; |
||||
52 | |||||
53 | /** |
||||
54 | * @var string |
||||
55 | */ |
||||
56 | protected const STORE_NAME_AT = 'AT'; |
||||
57 | |||||
58 | /** |
||||
59 | * @uses \Spryker\Zed\Discount\Persistence\Propel\Mapper\DiscountMapper::DATE_TIME_FORMAT |
||||
60 | * |
||||
61 | * @var string |
||||
62 | */ |
||||
63 | protected const DATE_TIME_FORMAT = 'Y-m-d H:i:s'; |
||||
64 | |||||
65 | /** |
||||
66 | * @var \SprykerTest\Zed\Discount\DiscountBusinessTester |
||||
67 | */ |
||||
68 | protected $tester; |
||||
69 | |||||
70 | /** |
||||
71 | * @return void |
||||
72 | */ |
||||
73 | public function testIsSatisfiedBySkuShouldReturnTrueWhenGiveSkuIsInQuote(): void |
||||
74 | { |
||||
75 | $discountFacade = $this->createDiscountFacade(); |
||||
76 | |||||
77 | $quoteTransfer = new QuoteTransfer(); |
||||
78 | $itemTransfer = new ItemTransfer(); |
||||
79 | $itemTransfer->setSku('123'); |
||||
80 | $quoteTransfer->addItem($itemTransfer); |
||||
81 | |||||
82 | $clauseTransfer = new ClauseTransfer(); |
||||
83 | $clauseTransfer->setOperator('='); |
||||
84 | $clauseTransfer->setValue('123'); |
||||
85 | $clauseTransfer->setAcceptedTypes([ |
||||
86 | ComparatorOperators::TYPE_STRING, |
||||
87 | ]); |
||||
88 | |||||
89 | $isSatisfied = $discountFacade->isItemSkuSatisfiedBy($quoteTransfer, $itemTransfer, $clauseTransfer); |
||||
90 | |||||
91 | $this->assertTrue($isSatisfied); |
||||
92 | } |
||||
93 | |||||
94 | /** |
||||
95 | * @return void |
||||
96 | */ |
||||
97 | public function testIsQuoteGrandTotalSatisfiedByShouldReturnTrueIfGrandTotalMatchesExpected(): void |
||||
98 | { |
||||
99 | $discountFacade = $this->createDiscountFacade(); |
||||
100 | |||||
101 | $quoteTransfer = new QuoteTransfer(); |
||||
102 | $totalTransfer = new TotalsTransfer(); |
||||
103 | $totalTransfer->setGrandTotal(1000); |
||||
104 | $quoteTransfer->setTotals($totalTransfer); |
||||
105 | |||||
106 | $clauseTransfer = new ClauseTransfer(); |
||||
107 | $clauseTransfer->setOperator('='); |
||||
108 | $clauseTransfer->setValue(10); |
||||
109 | $clauseTransfer->setAcceptedTypes([ |
||||
110 | ComparatorOperators::TYPE_NUMBER, |
||||
111 | ]); |
||||
112 | |||||
113 | $isSatisfied = $discountFacade->isQuoteGrandTotalSatisfiedBy( |
||||
114 | $quoteTransfer, |
||||
115 | new ItemTransfer(), |
||||
116 | $clauseTransfer, |
||||
117 | ); |
||||
118 | |||||
119 | $this->assertTrue($isSatisfied); |
||||
120 | } |
||||
121 | |||||
122 | /** |
||||
123 | * @return void |
||||
124 | */ |
||||
125 | public function testIsTotalQuantitySatisfiedByShouldReturnTrueWhenQuoteTotalQuantityMatchesExpected(): void |
||||
126 | { |
||||
127 | $discountFacade = $this->createDiscountFacade(); |
||||
128 | |||||
129 | $quoteTransfer = new QuoteTransfer(); |
||||
130 | $itemTransfer = new ItemTransfer(); |
||||
131 | $itemTransfer->setQuantity(2); |
||||
132 | $quoteTransfer->addItem($itemTransfer); |
||||
133 | |||||
134 | $itemTransfer = new ItemTransfer(); |
||||
135 | $itemTransfer->setQuantity(3); |
||||
136 | $quoteTransfer->addItem($itemTransfer); |
||||
137 | |||||
138 | $clauseTransfer = new ClauseTransfer(); |
||||
139 | $clauseTransfer->setOperator('='); |
||||
140 | $clauseTransfer->setValue(5); |
||||
141 | $clauseTransfer->setAcceptedTypes([ |
||||
142 | ComparatorOperators::TYPE_NUMBER, |
||||
143 | ]); |
||||
144 | |||||
145 | $isSatisfied = $discountFacade->isTotalQuantitySatisfiedBy( |
||||
146 | $quoteTransfer, |
||||
147 | $itemTransfer, |
||||
148 | $clauseTransfer, |
||||
149 | ); |
||||
150 | |||||
151 | $this->assertTrue($isSatisfied); |
||||
152 | } |
||||
153 | |||||
154 | /** |
||||
155 | * @return void |
||||
156 | */ |
||||
157 | public function testIsSubTotalSatisfiedByShouldReturnTrueWhenSubtotalMatchesExpected(): void |
||||
158 | { |
||||
159 | $discountFacade = $this->createDiscountFacade(); |
||||
160 | |||||
161 | $quoteTransfer = new QuoteTransfer(); |
||||
162 | $totalsTransfer = new TotalsTransfer(); |
||||
163 | $totalsTransfer->setSubtotal(5000); |
||||
164 | $quoteTransfer->setTotals($totalsTransfer); |
||||
165 | |||||
166 | $clauseTransfer = new ClauseTransfer(); |
||||
167 | $clauseTransfer->setOperator('='); |
||||
168 | $clauseTransfer->setValue(50); |
||||
169 | $clauseTransfer->setAcceptedTypes([ |
||||
170 | ComparatorOperators::TYPE_NUMBER, |
||||
171 | ]); |
||||
172 | |||||
173 | $isSatisfied = $discountFacade->isSubTotalSatisfiedBy( |
||||
174 | $quoteTransfer, |
||||
175 | new ItemTransfer(), |
||||
176 | $clauseTransfer, |
||||
177 | ); |
||||
178 | |||||
179 | $this->assertTrue($isSatisfied); |
||||
180 | } |
||||
181 | |||||
182 | /** |
||||
183 | * @return void |
||||
184 | */ |
||||
185 | public function testCollectBySkuShouldReturnItemMatchingGivenSku(): void |
||||
186 | { |
||||
187 | $discountFacade = $this->createDiscountFacade(); |
||||
188 | |||||
189 | $quoteTransfer = new QuoteTransfer(); |
||||
190 | $itemTransfer = new ItemTransfer(); |
||||
191 | $itemTransfer->setSku('sku'); |
||||
192 | $quoteTransfer->addItem($itemTransfer); |
||||
193 | |||||
194 | $clauseTransfer = new ClauseTransfer(); |
||||
195 | $clauseTransfer->setOperator('='); |
||||
196 | $clauseTransfer->setValue('sku'); |
||||
197 | $clauseTransfer->setAcceptedTypes([ |
||||
198 | ComparatorOperators::TYPE_NUMBER, |
||||
199 | ]); |
||||
200 | |||||
201 | $collected = $discountFacade->collectBySku($quoteTransfer, $clauseTransfer); |
||||
202 | |||||
203 | $this->assertCount(1, $collected); |
||||
204 | } |
||||
205 | |||||
206 | /** |
||||
207 | * @return void |
||||
208 | */ |
||||
209 | public function testGetQueryStringFieldsByTypeForCollectorShouldReturnListOfFieldsForGivenType(): void |
||||
210 | { |
||||
211 | $discountFacade = $this->createDiscountFacade(); |
||||
212 | $fields = $discountFacade->getQueryStringFieldsByType(MetaProviderFactory::TYPE_COLLECTOR); |
||||
213 | |||||
214 | $this->assertNotEmpty($fields); |
||||
215 | } |
||||
216 | |||||
217 | /** |
||||
218 | * @return void |
||||
219 | */ |
||||
220 | public function testGetQueryStringFieldsByTypeForDecisionRuleShouldReturnListOfFieldsForGivenType(): void |
||||
221 | { |
||||
222 | $discountFacade = $this->createDiscountFacade(); |
||||
223 | $fields = $discountFacade->getQueryStringFieldsByType(MetaProviderFactory::TYPE_DECISION_RULE); |
||||
224 | |||||
225 | $this->assertNotEmpty($fields); |
||||
226 | } |
||||
227 | |||||
228 | /** |
||||
229 | * @return void |
||||
230 | */ |
||||
231 | public function testGetQueryStringValueOptionsByTypeForCollectorShouldReturnListOfValueOptionsForGivenType(): void |
||||
232 | { |
||||
233 | $discountRulePluginMock = $this->createDiscountRuleWithValueOptionsPluginMock(); |
||||
234 | $discountRulePluginMock->method('getQueryStringValueOptions')->willReturn(['a' => 'b']); |
||||
235 | $discountRulePluginMock->method('getFieldName')->willReturn('foo'); |
||||
236 | |||||
237 | $discountFacade = $this->createDiscountFacadeForDiscountRuleWithValueOptionsPlugin( |
||||
238 | DiscountDependencyProvider::COLLECTOR_PLUGINS, |
||||
239 | $discountRulePluginMock, |
||||
240 | ); |
||||
241 | |||||
242 | $fields = $discountFacade->getQueryStringValueOptions(MetaProviderFactory::TYPE_COLLECTOR); |
||||
243 | |||||
244 | $this->assertNotEmpty($fields['foo']); |
||||
245 | } |
||||
246 | |||||
247 | /** |
||||
248 | * @return void |
||||
249 | */ |
||||
250 | public function testGetQueryStringValueOptionsByTypeForDecisionRuleShouldReturnListOfValueOptionsForGivenType(): void |
||||
251 | { |
||||
252 | $discountRulePluginMock = $this->createDiscountRuleWithValueOptionsPluginMock(); |
||||
253 | $discountRulePluginMock->method('getQueryStringValueOptions')->willReturn(['a' => 'b']); |
||||
254 | $discountRulePluginMock->method('getFieldName')->willReturn('foo'); |
||||
255 | |||||
256 | $discountFacade = $this->createDiscountFacadeForDiscountRuleWithValueOptionsPlugin( |
||||
257 | DiscountDependencyProvider::DECISION_RULE_PLUGINS, |
||||
258 | $discountRulePluginMock, |
||||
259 | ); |
||||
260 | |||||
261 | $fields = $discountFacade->getQueryStringValueOptions(MetaProviderFactory::TYPE_DECISION_RULE); |
||||
262 | |||||
263 | $this->assertNotEmpty($fields['foo']); |
||||
264 | } |
||||
265 | |||||
266 | /** |
||||
267 | * @return void |
||||
268 | */ |
||||
269 | public function testGetQueryStringFieldExpressionsForFieldCollectorShouldReturnListOfExpressions(): void |
||||
270 | { |
||||
271 | $discountFacade = $this->createDiscountFacade(); |
||||
272 | $expressions = $discountFacade->getQueryStringFieldExpressionsForField(MetaProviderFactory::TYPE_COLLECTOR, 'sku'); |
||||
273 | |||||
274 | $this->assertNotEmpty($expressions); |
||||
275 | } |
||||
276 | |||||
277 | /** |
||||
278 | * @return void |
||||
279 | */ |
||||
280 | public function testGetQueryStringFieldExpressionsForFieldDecisionRuleShouldReturnListOfExpressions(): void |
||||
281 | { |
||||
282 | $discountFacade = $this->createDiscountFacade(); |
||||
283 | $expressions = $discountFacade->getQueryStringFieldExpressionsForField(MetaProviderFactory::TYPE_DECISION_RULE, 'sku'); |
||||
284 | |||||
285 | $this->assertNotEmpty($expressions); |
||||
286 | } |
||||
287 | |||||
288 | /** |
||||
289 | * @return void |
||||
290 | */ |
||||
291 | public function testGetQueryStringComparatorExpressionsForDecisionRuleShouldReturnListOfComparatorExpressions(): void |
||||
292 | { |
||||
293 | $discountFacade = $this->createDiscountFacade(); |
||||
294 | $expressions = $discountFacade->getQueryStringComparatorExpressions(MetaProviderFactory::TYPE_DECISION_RULE); |
||||
295 | |||||
296 | $this->assertNotEmpty($expressions); |
||||
297 | } |
||||
298 | |||||
299 | /** |
||||
300 | * @return void |
||||
301 | */ |
||||
302 | public function testGetQueryStringComparatorExpressionsForCollectorShouldReturnListOfComparatorExpressions(): void |
||||
303 | { |
||||
304 | $discountFacade = $this->createDiscountFacade(); |
||||
305 | $logicalComparators = $discountFacade->getQueryStringComparatorExpressions(MetaProviderFactory::TYPE_DECISION_RULE); |
||||
306 | |||||
307 | $this->assertNotEmpty($logicalComparators); |
||||
308 | } |
||||
309 | |||||
310 | /** |
||||
311 | * @return void |
||||
312 | */ |
||||
313 | public function testGetQueryStringLogicalComparatorsShouldReturnListOfComparators(): void |
||||
314 | { |
||||
315 | $discountFacade = $this->createDiscountFacade(); |
||||
316 | $expressions = $discountFacade->getQueryStringLogicalComparators(MetaProviderFactory::TYPE_COLLECTOR); |
||||
317 | |||||
318 | $this->assertNotEmpty($expressions); |
||||
319 | } |
||||
320 | |||||
321 | /** |
||||
322 | * @return void |
||||
323 | */ |
||||
324 | public function testQueryStringCompareShouldReturnTrueWhenValuesMatches(): void |
||||
325 | { |
||||
326 | $discountFacade = $this->createDiscountFacade(); |
||||
327 | $clauseTransfer = new ClauseTransfer(); |
||||
328 | $clauseTransfer->setOperator('='); |
||||
329 | $clauseTransfer->setValue('value'); |
||||
330 | $clauseTransfer->setAcceptedTypes([ |
||||
331 | ComparatorOperators::TYPE_STRING, |
||||
332 | ]); |
||||
333 | |||||
334 | $withValue = 'value'; |
||||
335 | |||||
336 | $isMatching = $discountFacade->queryStringCompare($clauseTransfer, $withValue); |
||||
337 | |||||
338 | $this->assertTrue($isMatching); |
||||
339 | } |
||||
340 | |||||
341 | /** |
||||
342 | * @return void |
||||
343 | */ |
||||
344 | public function testQueryStringCompareShouldReturnFalseWhenValuesNotMatching(): void |
||||
345 | { |
||||
346 | $discountFacade = $this->createDiscountFacade(); |
||||
347 | $clauseTransfer = new ClauseTransfer(); |
||||
348 | $clauseTransfer->setOperator('='); |
||||
349 | $clauseTransfer->setValue('value'); |
||||
350 | $clauseTransfer->setAcceptedTypes([ |
||||
351 | ComparatorOperators::TYPE_STRING, |
||||
352 | ]); |
||||
353 | |||||
354 | $withValue = 'value2'; |
||||
355 | |||||
356 | $isMatching = $discountFacade->queryStringCompare($clauseTransfer, $withValue); |
||||
357 | |||||
358 | $this->assertFalse($isMatching); |
||||
359 | } |
||||
360 | |||||
361 | /** |
||||
362 | * @return void |
||||
363 | */ |
||||
364 | public function testValidateQueryStringByTypeShouldReturnListErrorsWhenInvalidQueryString(): void |
||||
365 | { |
||||
366 | $discountFacade = $this->createDiscountFacade(); |
||||
367 | $clauseTransfer = new ClauseTransfer(); |
||||
368 | $clauseTransfer->setOperator('='); |
||||
369 | $clauseTransfer->setValue('value'); |
||||
370 | $clauseTransfer->setAcceptedTypes([ |
||||
371 | ComparatorOperators::TYPE_STRING, |
||||
372 | ]); |
||||
373 | |||||
374 | $errors = $discountFacade->validateQueryStringByType(MetaProviderFactory::TYPE_DECISION_RULE, 'invalid ='); |
||||
375 | |||||
376 | $this->assertCount(1, $errors); |
||||
377 | } |
||||
378 | |||||
379 | /** |
||||
380 | * @return void |
||||
381 | */ |
||||
382 | public function testValidateVoucherDiscountsMaxUsageShouldReturnTrueWhenUsageLimitIsNotReached(): void |
||||
383 | { |
||||
384 | // Arrange |
||||
385 | $discountVoucherTransfer = $this->getDiscountVoucher([ |
||||
386 | DiscountVoucherTransfer::MAX_NUMBER_OF_USES => 5, |
||||
387 | DiscountVoucherTransfer::CUSTOM_CODE => 'functional spryker test voucher', |
||||
388 | DiscountVoucherTransfer::QUANTITY => 1, |
||||
389 | DiscountVoucherTransfer::RANDOM_GENERATED_CODE_LENGTH => 3, |
||||
390 | ]); |
||||
391 | $quoteTransfer = $this->getQuoteWithVoucherDiscount($discountVoucherTransfer); |
||||
392 | |||||
393 | // Act |
||||
394 | $checkoutResponseTransfer = new CheckoutResponseTransfer(); |
||||
395 | $result = $this->createDiscountFacade()->validateVoucherDiscountsMaxUsage($quoteTransfer, $checkoutResponseTransfer); |
||||
396 | |||||
397 | // Assert |
||||
398 | $this->assertCount(0, $checkoutResponseTransfer->getErrors()); |
||||
399 | $this->assertTrue($result); |
||||
400 | } |
||||
401 | |||||
402 | /** |
||||
403 | * @return void |
||||
404 | */ |
||||
405 | public function testValidateVoucherDiscountsMaxUsageShouldReturnFalseWhenUsageLimitIsReached(): void |
||||
406 | { |
||||
407 | // Arrange |
||||
408 | $maxNumberOfUses = 5; |
||||
409 | $discountVoucherTransfer = $this->getDiscountVoucher([ |
||||
410 | DiscountVoucherTransfer::MAX_NUMBER_OF_USES => $maxNumberOfUses, |
||||
411 | DiscountVoucherTransfer::CUSTOM_CODE => 'functional spryker test voucher', |
||||
412 | DiscountVoucherTransfer::QUANTITY => 1, |
||||
413 | DiscountVoucherTransfer::RANDOM_GENERATED_CODE_LENGTH => 3, |
||||
414 | ]); |
||||
415 | $this->updateVoucherCodesWithNumberOfUses($discountVoucherTransfer, $maxNumberOfUses); |
||||
416 | $quoteTransfer = $this->getQuoteWithVoucherDiscount($discountVoucherTransfer); |
||||
417 | |||||
418 | // Act |
||||
419 | $checkoutResponseTransfer = new CheckoutResponseTransfer(); |
||||
420 | $result = $this->createDiscountFacade()->validateVoucherDiscountsMaxUsage($quoteTransfer, $checkoutResponseTransfer); |
||||
421 | |||||
422 | // Assert |
||||
423 | |||||
424 | /** @var \Generated\Shared\Transfer\CheckoutErrorTransfer $checkoutErrorTransfer */ |
||||
425 | $checkoutErrorTransfer = $checkoutResponseTransfer->getErrors()[0]; |
||||
426 | |||||
427 | $this->assertCount(1, $checkoutResponseTransfer->getErrors()); |
||||
428 | $this->assertSame(399, $checkoutErrorTransfer->getErrorCode()); |
||||
429 | $this->assertSame(VoucherValidator::REASON_VOUCHER_CODE_LIMIT_REACHED, $checkoutErrorTransfer->getMessage()); |
||||
430 | $this->assertFalse($result); |
||||
431 | $this->assertFalse($checkoutResponseTransfer->getIsSuccess()); |
||||
432 | } |
||||
433 | |||||
434 | /** |
||||
435 | * @return void |
||||
436 | */ |
||||
437 | public function testValidateVoucherDiscountsMaxUsageShouldReturnFalseWhenUsageLimitIsReachedForTwoVouchers(): void |
||||
438 | { |
||||
439 | // Arrange |
||||
440 | $maxNumberOfUses = 5; |
||||
441 | $discountVoucherTransfer = $this->getDiscountVoucher([ |
||||
442 | DiscountVoucherTransfer::MAX_NUMBER_OF_USES => $maxNumberOfUses, |
||||
443 | DiscountVoucherTransfer::CUSTOM_CODE => 'functional spryker test voucher', |
||||
444 | DiscountVoucherTransfer::QUANTITY => 1, |
||||
445 | ]); |
||||
446 | $this->updateVoucherCodesWithNumberOfUses($discountVoucherTransfer, $maxNumberOfUses); |
||||
447 | $quoteTransfer = $this->getQuoteWithVoucherDiscount($discountVoucherTransfer); |
||||
448 | |||||
449 | $discountVoucherTransfer2 = $this->getDiscountVoucher([ |
||||
450 | DiscountVoucherTransfer::MAX_NUMBER_OF_USES => $maxNumberOfUses, |
||||
451 | DiscountVoucherTransfer::CUSTOM_CODE => 'second functional spryker test voucher', |
||||
452 | DiscountVoucherTransfer::QUANTITY => 1, |
||||
453 | ]); |
||||
454 | $this->updateVoucherCodesWithNumberOfUses($discountVoucherTransfer2, $maxNumberOfUses); |
||||
455 | $quoteTransfer->addVoucherDiscount( |
||||
456 | (new DiscountTransfer())->setVoucherCode($discountVoucherTransfer2->getCode()), |
||||
457 | ); |
||||
458 | |||||
459 | // Act |
||||
460 | $checkoutResponseTransfer = new CheckoutResponseTransfer(); |
||||
461 | $result = $this->createDiscountFacade()->validateVoucherDiscountsMaxUsage($quoteTransfer, $checkoutResponseTransfer); |
||||
462 | |||||
463 | // Assert |
||||
464 | $this->assertCount(2, $checkoutResponseTransfer->getErrors()); |
||||
465 | foreach ($checkoutResponseTransfer->getErrors() as $checkoutErrorTransfer) { |
||||
466 | $this->assertSame(399, $checkoutErrorTransfer->getErrorCode()); |
||||
467 | $this->assertSame(VoucherValidator::REASON_VOUCHER_CODE_LIMIT_REACHED, $checkoutErrorTransfer->getMessage()); |
||||
468 | } |
||||
469 | $this->assertFalse($result); |
||||
470 | $this->assertFalse($checkoutResponseTransfer->getIsSuccess()); |
||||
471 | } |
||||
472 | |||||
473 | /** |
||||
474 | * @return void |
||||
475 | */ |
||||
476 | public function testValidateVoucherDiscountsMaxUsageShouldReturnTrueWhenMaxUsageZeroAndNotUsed(): void |
||||
477 | { |
||||
478 | // Arrange |
||||
479 | $discountVoucherTransfer = $this->getDiscountVoucher([ |
||||
480 | DiscountVoucherTransfer::MAX_NUMBER_OF_USES => 0, |
||||
481 | DiscountVoucherTransfer::CUSTOM_CODE => 'functional spryker test voucher', |
||||
482 | DiscountVoucherTransfer::QUANTITY => 1, |
||||
483 | DiscountVoucherTransfer::RANDOM_GENERATED_CODE_LENGTH => 3, |
||||
484 | ]); |
||||
485 | $quoteTransfer = $this->getQuoteWithVoucherDiscount($discountVoucherTransfer); |
||||
486 | |||||
487 | // Act |
||||
488 | $checkoutResponseTransfer = new CheckoutResponseTransfer(); |
||||
489 | $result = $this->createDiscountFacade()->validateVoucherDiscountsMaxUsage($quoteTransfer, $checkoutResponseTransfer); |
||||
490 | |||||
491 | // Assert |
||||
492 | $this->assertTrue($result); |
||||
493 | $this->assertCount(0, $checkoutResponseTransfer->getErrors()); |
||||
494 | } |
||||
495 | |||||
496 | /** |
||||
497 | * @return void |
||||
498 | */ |
||||
499 | public function testValidateVoucherDiscountsMaxUsageShouldReturnTrueWhenMaxUsageZeroAndUsed(): void |
||||
500 | { |
||||
501 | // Arrange |
||||
502 | $discountVoucherTransfer = $this->getDiscountVoucher([ |
||||
503 | DiscountVoucherTransfer::MAX_NUMBER_OF_USES => 0, |
||||
504 | DiscountVoucherTransfer::CUSTOM_CODE => 'functional spryker test voucher', |
||||
505 | DiscountVoucherTransfer::QUANTITY => 1, |
||||
506 | DiscountVoucherTransfer::RANDOM_GENERATED_CODE_LENGTH => 3, |
||||
507 | ]); |
||||
508 | $this->updateVoucherCodesWithNumberOfUses($discountVoucherTransfer, 5); |
||||
509 | $quoteTransfer = $this->getQuoteWithVoucherDiscount($discountVoucherTransfer); |
||||
510 | |||||
511 | // Act |
||||
512 | $checkoutResponseTransfer = new CheckoutResponseTransfer(); |
||||
513 | $result = $this->createDiscountFacade()->validateVoucherDiscountsMaxUsage($quoteTransfer, $checkoutResponseTransfer); |
||||
514 | |||||
515 | // Assert |
||||
516 | $this->assertTrue($result); |
||||
517 | $this->assertCount(0, $checkoutResponseTransfer->getErrors()); |
||||
518 | } |
||||
519 | |||||
520 | /** |
||||
521 | * @return void |
||||
522 | */ |
||||
523 | public function testSaveDiscountDecisionRuleShouldPersistAllConfiguredData(): void |
||||
524 | { |
||||
525 | $discountConfiguratorTransfer = $this->tester->createDiscountConfiguratorTransfer(); |
||||
526 | |||||
527 | $discountFacade = $this->createDiscountFacade(); |
||||
528 | $idDiscount = $discountFacade->saveDiscount($discountConfiguratorTransfer); |
||||
529 | |||||
530 | $this->assertNotEmpty($idDiscount); |
||||
531 | |||||
532 | $discountEntity = SpyDiscountQuery::create()->findOneByIdDiscount($idDiscount); |
||||
533 | |||||
534 | $discountGeneralTransfer = $discountConfiguratorTransfer->getDiscountGeneral(); |
||||
535 | $this->assertSame($discountGeneralTransfer->getDisplayName(), $discountEntity->getDisplayName()); |
||||
536 | $this->assertSame($discountGeneralTransfer->getIsActive(), $discountEntity->getIsActive()); |
||||
537 | $this->assertSame($discountGeneralTransfer->getIsExclusive(), $discountEntity->getIsExclusive()); |
||||
538 | $this->assertSame($discountGeneralTransfer->getDescription(), $discountEntity->getDescription()); |
||||
539 | $this->assertSame($discountGeneralTransfer->getValidFrom(), $discountEntity->getValidFrom()->format(static::DATE_TIME_FORMAT)); |
||||
540 | $this->assertSame($discountGeneralTransfer->getValidTo(), $discountEntity->getValidTo()->format(static::DATE_TIME_FORMAT)); |
||||
541 | |||||
542 | $discountCalculatorTransfer = $discountConfiguratorTransfer->getDiscountCalculator(); |
||||
543 | $this->assertSame($discountCalculatorTransfer->getAmount(), $discountEntity->getAmount()); |
||||
544 | $this->assertSame($discountCalculatorTransfer->getCalculatorPlugin(), $discountEntity->getCalculatorPlugin()); |
||||
545 | $this->assertSame($discountCalculatorTransfer->getCollectorQueryString(), $discountEntity->getCollectorQueryString()); |
||||
546 | |||||
547 | $discountConditionTransfer = $discountConfiguratorTransfer->getDiscountCondition(); |
||||
548 | $this->assertSame($discountConditionTransfer->getDecisionRuleQueryString(), $discountEntity->getDecisionRuleQueryString()); |
||||
549 | } |
||||
550 | |||||
551 | /** |
||||
552 | * @return void |
||||
553 | */ |
||||
554 | public function testSaveDiscountVoucherShouldCreateDiscountWithEmptyVoucherPool(): void |
||||
555 | { |
||||
556 | $discountConfiguratorTransfer = $this->tester->createDiscountConfiguratorTransfer(); |
||||
557 | $discountConfiguratorTransfer->getDiscountGeneral() |
||||
558 | ->setDiscountType(DiscountConstants::TYPE_VOUCHER); |
||||
559 | |||||
560 | $discountFacade = $this->createDiscountFacade(); |
||||
561 | $idDiscount = $discountFacade->saveDiscount($discountConfiguratorTransfer); |
||||
562 | |||||
563 | $this->assertNotEmpty($idDiscount); |
||||
564 | |||||
565 | $discountEntity = SpyDiscountQuery::create()->findOneByIdDiscount($idDiscount); |
||||
566 | |||||
567 | $this->assertNotEmpty($discountEntity->getFkDiscountVoucherPool()); |
||||
568 | |||||
569 | $voucherPool = $discountEntity->getVoucherPool(); |
||||
570 | $this->assertNotEmpty($voucherPool); |
||||
571 | } |
||||
572 | |||||
573 | /** |
||||
574 | * @return void |
||||
575 | */ |
||||
576 | public function testSaveDiscountPersistsStoreRelation(): void |
||||
577 | { |
||||
578 | // Arrange |
||||
579 | $idStores = [2]; |
||||
580 | $discountFacade = $this->createDiscountFacade(); |
||||
581 | |||||
582 | $discountConfiguratorTransfer = $this->tester->createDiscountConfiguratorTransfer(); |
||||
583 | $discountConfiguratorTransfer |
||||
584 | ->getDiscountGeneral() |
||||
585 | ->setDiscountType(DiscountConstants::TYPE_VOUCHER) |
||||
586 | ->getStoreRelation() |
||||
587 | ->setIdStores($idStores); |
||||
588 | |||||
589 | // Act |
||||
590 | $idDiscount = $discountFacade->saveDiscount($discountConfiguratorTransfer); |
||||
591 | |||||
592 | // Assert |
||||
593 | $discountConfiguratorTransfer = $discountFacade->getHydratedDiscountConfiguratorByIdDiscount($idDiscount); |
||||
594 | $this->assertEquals( |
||||
595 | $discountConfiguratorTransfer->getDiscountGeneral()->getStoreRelation()->getIdStores(), |
||||
596 | $idStores, |
||||
597 | ); |
||||
598 | } |
||||
599 | |||||
600 | /** |
||||
601 | * @return void |
||||
602 | */ |
||||
603 | public function testUpdateDiscountPersistsStoreRelation(): void |
||||
604 | { |
||||
605 | // Arrange |
||||
606 | $atIdStore = $this->tester->haveStore([StoreTransfer::NAME => static::STORE_NAME_AT])->getIdStore(); |
||||
607 | $deIdStore = $this->tester->haveStore([StoreTransfer::NAME => static::STORE_NAME_DE])->getIdStore(); |
||||
608 | |||||
609 | $originalIdStores = [$atIdStore]; |
||||
610 | $expectedIdStores = [$deIdStore]; |
||||
611 | |||||
612 | $discountConfiguratorTransfer = $this->tester->createDiscountConfiguratorTransfer(); |
||||
613 | $discountConfiguratorTransfer |
||||
614 | ->getDiscountGeneral() |
||||
615 | ->setDiscountType(DiscountConstants::TYPE_VOUCHER) |
||||
616 | ->getStoreRelation() |
||||
617 | ->setIdStores($originalIdStores); |
||||
618 | |||||
619 | $discountFacade = $this->createDiscountFacade(); |
||||
620 | $idDiscount = $discountFacade->saveDiscount($discountConfiguratorTransfer); |
||||
621 | |||||
622 | $discountConfiguratorTransfer |
||||
623 | ->getDiscountGeneral() |
||||
624 | ->getStoreRelation() |
||||
625 | ->setIdStores($expectedIdStores); |
||||
626 | |||||
627 | // Act |
||||
628 | $discountFacade->updateDiscount($discountConfiguratorTransfer); |
||||
629 | |||||
630 | // Assert |
||||
631 | $discountConfiguratorTransfer = $discountFacade->getHydratedDiscountConfiguratorByIdDiscount($idDiscount); |
||||
632 | $updatedStoreIds = $discountConfiguratorTransfer->getDiscountGeneral()->getStoreRelation()->getIdStores(); |
||||
633 | sort($updatedStoreIds); |
||||
634 | sort($expectedIdStores); |
||||
635 | $this->assertEquals( |
||||
636 | $updatedStoreIds, |
||||
637 | $expectedIdStores, |
||||
638 | ); |
||||
639 | } |
||||
640 | |||||
641 | /** |
||||
642 | * @return void |
||||
643 | */ |
||||
644 | public function testValidateQueryStringByTypeShouldReturnEmptySetWhenQueryStringIsValid(): void |
||||
645 | { |
||||
646 | $discountFacade = $this->createDiscountFacade(); |
||||
647 | $clauseTransfer = new ClauseTransfer(); |
||||
648 | $clauseTransfer->setOperator('='); |
||||
649 | $clauseTransfer->setValue('value'); |
||||
650 | $clauseTransfer->setAcceptedTypes([ |
||||
651 | ComparatorOperators::TYPE_STRING, |
||||
652 | ]); |
||||
653 | |||||
654 | $errors = $discountFacade->validateQueryStringByType(MetaProviderFactory::TYPE_DECISION_RULE, 'sku = "123"'); |
||||
655 | |||||
656 | $this->assertEmpty($errors); |
||||
657 | } |
||||
658 | |||||
659 | /** |
||||
660 | * @return void |
||||
661 | */ |
||||
662 | public function testUpdateDiscountShouldUpdateExistingRecordWithNewData(): void |
||||
663 | { |
||||
664 | $discountFacade = $this->createDiscountFacade(); |
||||
665 | $discountConfiguratorTransfer = $this->tester->createDiscountConfiguratorTransfer(); |
||||
666 | $idDiscount = $discountFacade->saveDiscount($discountConfiguratorTransfer); |
||||
667 | |||||
668 | $discountConfiguratorTransfer |
||||
669 | ->getDiscountGeneral() |
||||
670 | ->setIdDiscount($idDiscount); |
||||
671 | |||||
672 | $discountGeneralTransfer = $discountConfiguratorTransfer->getDiscountGeneral(); |
||||
673 | $discountGeneralTransfer->setDisplayName('updated functional discount facade test'); |
||||
674 | $discountGeneralTransfer->setDescription('Updated description'); |
||||
675 | $discountGeneralTransfer->setIsActive(false); |
||||
676 | $discountGeneralTransfer->setIsExclusive(false); |
||||
677 | $discountGeneralTransfer->setValidFrom((new DateTime())->format(static::DATE_TIME_FORMAT)); |
||||
678 | $discountGeneralTransfer->setValidTo((new DateTime('+1 day'))->format(static::DATE_TIME_FORMAT)); |
||||
679 | |||||
680 | $discountCalculatorTransfer = $discountConfiguratorTransfer->getDiscountCalculator(); |
||||
681 | $discountCalculatorTransfer->setCalculatorPlugin(DiscountDependencyProvider::PLUGIN_CALCULATOR_FIXED); |
||||
682 | $discountCalculatorTransfer->setAmount(5); |
||||
683 | $discountCalculatorTransfer->setCollectorQueryString('sku = "new-sku"'); |
||||
684 | |||||
685 | $discountConditionTransfer = $discountConfiguratorTransfer->getDiscountCondition(); |
||||
686 | $discountConditionTransfer->setDecisionRuleQueryString('sku = "new-decision-sku"'); |
||||
687 | |||||
688 | $isUpdated = $discountFacade->updateDiscount($discountConfiguratorTransfer); |
||||
689 | |||||
690 | $this->assertTrue($isUpdated); |
||||
691 | |||||
692 | $discountEntity = SpyDiscountQuery::create()->findOneByIdDiscount($idDiscount); |
||||
693 | |||||
694 | $this->assertSame($discountGeneralTransfer->getDisplayName(), $discountEntity->getDisplayName()); |
||||
695 | $this->assertSame($discountGeneralTransfer->getIsActive(), $discountEntity->getIsActive()); |
||||
696 | $this->assertSame($discountGeneralTransfer->getIsExclusive(), $discountEntity->getIsExclusive()); |
||||
697 | $this->assertSame($discountGeneralTransfer->getDescription(), $discountEntity->getDescription()); |
||||
698 | $this->assertSame($discountGeneralTransfer->getValidFrom(), $discountEntity->getValidFrom()->format(static::DATE_TIME_FORMAT)); |
||||
699 | $this->assertSame($discountGeneralTransfer->getValidTo(), $discountEntity->getValidTo()->format(static::DATE_TIME_FORMAT)); |
||||
700 | |||||
701 | $discountCalculatorTransfer = $discountConfiguratorTransfer->getDiscountCalculator(); |
||||
702 | $this->assertSame($discountCalculatorTransfer->getAmount(), $discountEntity->getAmount()); |
||||
703 | $this->assertSame($discountCalculatorTransfer->getCalculatorPlugin(), $discountEntity->getCalculatorPlugin()); |
||||
704 | $this->assertSame($discountCalculatorTransfer->getCollectorQueryString(), $discountEntity->getCollectorQueryString()); |
||||
705 | |||||
706 | $discountConditionTransfer = $discountConfiguratorTransfer->getDiscountCondition(); |
||||
707 | $this->assertSame($discountConditionTransfer->getDecisionRuleQueryString(), $discountEntity->getDecisionRuleQueryString()); |
||||
708 | } |
||||
709 | |||||
710 | /** |
||||
711 | * @return void |
||||
712 | */ |
||||
713 | public function testGetHydratedDiscountConfiguratorByIdDiscountShouldHydrateToSameObjectWhichWasPersisted(): void |
||||
714 | { |
||||
715 | $discountFacade = $this->createDiscountFacade(); |
||||
716 | $discountConfiguratorTransfer = $this->tester->createDiscountConfiguratorTransfer(); |
||||
717 | $idDiscount = $discountFacade->saveDiscount($discountConfiguratorTransfer); |
||||
718 | $discountConfiguratorTransfer->getDiscountGeneral()->setIdDiscount($idDiscount); |
||||
719 | |||||
720 | $hydratedDiscountConfiguratorTransfer = $discountFacade->getHydratedDiscountConfiguratorByIdDiscount( |
||||
721 | $idDiscount, |
||||
722 | ); |
||||
723 | |||||
724 | $originalConfiguratorArray = $discountConfiguratorTransfer->toArray(); |
||||
725 | $hydratedConfiguratorArray = $hydratedDiscountConfiguratorTransfer->toArray(); |
||||
726 | |||||
727 | $discountEntity = SpyDiscountQuery::create()->findOneByIdDiscount($idDiscount); |
||||
728 | |||||
729 | $this->assertEquals($originalConfiguratorArray, $hydratedConfiguratorArray); |
||||
730 | $this->assertTrue($discountEntity->getIsActive()); |
||||
731 | } |
||||
732 | |||||
733 | /** |
||||
734 | * @return void |
||||
735 | */ |
||||
736 | public function testToggleDiscountVisibilityWhenDisableShouldSetToIsActiveToFalse(): void |
||||
737 | { |
||||
738 | $discountFacade = $this->createDiscountFacade(); |
||||
739 | $discountConfiguratorTransfer = $this->tester->createDiscountConfiguratorTransfer(); |
||||
740 | $idDiscount = $discountFacade->saveDiscount($discountConfiguratorTransfer); |
||||
741 | |||||
742 | $isUpdated = $discountFacade->toggleDiscountVisibility($idDiscount, false); |
||||
743 | |||||
744 | $discountEntity = SpyDiscountQuery::create()->findOneByIdDiscount($idDiscount); |
||||
745 | |||||
746 | $this->assertTrue($isUpdated); |
||||
747 | $this->assertFalse($discountEntity->getIsActive()); |
||||
748 | } |
||||
749 | |||||
750 | /** |
||||
751 | * @return void |
||||
752 | */ |
||||
753 | public function testToggleDiscountVisibilityWhenDisableShouldSetToIsActiveToTrue(): void |
||||
754 | { |
||||
755 | $discountFacade = $this->createDiscountFacade(); |
||||
756 | $discountConfiguratorTransfer = $this->tester->createDiscountConfiguratorTransfer(); |
||||
757 | $discountConfiguratorTransfer->getDiscountGeneral()->setIsActive(false); |
||||
758 | $idDiscount = $discountFacade->saveDiscount($discountConfiguratorTransfer); |
||||
759 | |||||
760 | $isUpdated = $discountFacade->toggleDiscountVisibility($idDiscount, true); |
||||
761 | |||||
762 | $this->assertTrue($isUpdated); |
||||
763 | } |
||||
764 | |||||
765 | /** |
||||
766 | * @return void |
||||
767 | */ |
||||
768 | public function testSaveVouchersShouldGenerateVouchers(): void |
||||
769 | { |
||||
770 | $discountFacade = $this->createDiscountFacade(); |
||||
771 | $discountConfiguratorTransfer = $this->tester->createDiscountConfiguratorTransfer(); |
||||
772 | $idDiscount = $discountFacade->saveDiscount($discountConfiguratorTransfer); |
||||
773 | |||||
774 | $discountVoucherTransfer = new DiscountVoucherTransfer(); |
||||
775 | $discountVoucherTransfer->setIdDiscount($idDiscount); |
||||
776 | $discountVoucherTransfer->setCustomCode('functional spryker test voucher'); |
||||
777 | $discountVoucherTransfer->setMaxNumberOfUses(0); |
||||
778 | $discountVoucherTransfer->setQuantity(5); |
||||
779 | $discountVoucherTransfer->setRandomGeneratedCodeLength(10); |
||||
780 | |||||
781 | $voucherCreateInfoTransfer = $discountFacade->saveVoucherCodes($discountVoucherTransfer); |
||||
782 | |||||
783 | $this->assertEquals($voucherCreateInfoTransfer->getType(), DiscountConstants::MESSAGE_TYPE_SUCCESS); |
||||
784 | |||||
785 | $discountEntity = SpyDiscountQuery::create()->findOneByIdDiscount($idDiscount); |
||||
786 | |||||
787 | $voucherPoolEntity = $discountEntity->getVoucherPool(); |
||||
788 | $voucherCodes = $voucherPoolEntity->getDiscountVouchers(); |
||||
789 | |||||
790 | $this->assertCount(5, $voucherCodes); |
||||
791 | } |
||||
792 | |||||
793 | /** |
||||
794 | * @return void |
||||
795 | */ |
||||
796 | public function testCalculatedPercentageShouldCalculatePercentageFromItemTotal(): void |
||||
797 | { |
||||
798 | $discountableItems = []; |
||||
799 | |||||
800 | $itemTransfer = new ItemTransfer(); |
||||
801 | $calculatedDiscounts = new ArrayObject(); |
||||
802 | $itemTransfer->setCalculatedDiscounts($calculatedDiscounts); |
||||
803 | |||||
804 | $discountableItemTransfer = new DiscountableItemTransfer(); |
||||
805 | $discountableItemTransfer->setQuantity(3); |
||||
806 | $discountableItemTransfer->setUnitPrice(30); |
||||
807 | $discountableItemTransfer->setOriginalItemCalculatedDiscounts($calculatedDiscounts); |
||||
808 | $discountableItems[] = $discountableItemTransfer; |
||||
809 | |||||
810 | $discountFacade = $this->createDiscountFacade(); |
||||
811 | |||||
812 | $discountTransfer = new DiscountTransfer(); |
||||
813 | $discountTransfer->setAmount(10 * 100); |
||||
814 | |||||
815 | $amount = $discountFacade->calculatePercentageDiscount($discountableItems, $discountTransfer); |
||||
816 | |||||
817 | $this->assertSame(9, $amount); |
||||
818 | } |
||||
819 | |||||
820 | /** |
||||
821 | * @return void |
||||
822 | */ |
||||
823 | public function testCalculatedFixedShouldUseFixedAmountGiver(): void |
||||
824 | { |
||||
825 | $discountFacade = $this->createDiscountFacade(); |
||||
826 | $discountTransfer = new DiscountTransfer(); |
||||
827 | $currencyTransfer = new CurrencyTransfer(); |
||||
828 | $currencyTransfer->setCode('EUR'); |
||||
829 | $discountTransfer->setCurrency($currencyTransfer); |
||||
830 | |||||
831 | $moneyValueTransfer = new MoneyValueTransfer(); |
||||
832 | $moneyValueTransfer->setGrossAmount(50); |
||||
833 | $moneyValueTransfer->setCurrency($currencyTransfer); |
||||
834 | $discountTransfer->addMoneyValue($moneyValueTransfer); |
||||
835 | $amount = $discountFacade->calculateFixedDiscount([], $discountTransfer); |
||||
836 | |||||
837 | $this->assertSame(50, $amount); |
||||
838 | } |
||||
839 | |||||
840 | /** |
||||
841 | * @return void |
||||
842 | */ |
||||
843 | public function testDistributeAmountShouldDistributeDiscountToDiscountableItems(): void |
||||
844 | { |
||||
845 | $collectedDiscountTransfer = new CollectedDiscountTransfer(); |
||||
846 | |||||
847 | $totalDiscountAmount = 100; |
||||
848 | $discountTransfer = new DiscountTransfer(); |
||||
849 | $discountTransfer->setAmount($totalDiscountAmount); |
||||
850 | $collectedDiscountTransfer->setDiscount($discountTransfer); |
||||
851 | |||||
852 | $discountableItems = new ArrayObject(); |
||||
853 | |||||
854 | foreach ([100, 600] as $price) { |
||||
855 | $itemTransfer = new ItemTransfer(); |
||||
856 | $calculatedDiscounts = new ArrayObject(); |
||||
857 | $itemTransfer->setCalculatedDiscounts($calculatedDiscounts); |
||||
858 | |||||
859 | $discountableItemTransfer = new DiscountableItemTransfer(); |
||||
860 | $discountableItemTransfer->setQuantity(1); |
||||
861 | $discountableItemTransfer->setUnitPrice($price); |
||||
862 | $discountableItemTransfer->setOriginalItemCalculatedDiscounts($calculatedDiscounts); |
||||
863 | $discountableItems->append($discountableItemTransfer); |
||||
864 | } |
||||
865 | |||||
866 | $collectedDiscountTransfer->setDiscountableItems($discountableItems); |
||||
867 | |||||
868 | $discountFacade = $this->createDiscountFacade(); |
||||
869 | $discountFacade->distributeAmount($collectedDiscountTransfer); |
||||
870 | |||||
871 | $firstItemDistributedAmount = $discountableItems[0]->getOriginalItemCalculatedDiscounts()[0]->getUnitAmount(); |
||||
872 | $secondItemDistributedAmount = $discountableItems[1]->getOriginalItemCalculatedDiscounts()[0]->getUnitAmount(); |
||||
873 | |||||
874 | $this->assertSame(14, $firstItemDistributedAmount); |
||||
875 | $this->assertSame(86, $secondItemDistributedAmount); |
||||
876 | $this->assertSame($totalDiscountAmount, $firstItemDistributedAmount + $secondItemDistributedAmount); |
||||
877 | } |
||||
878 | |||||
879 | /** |
||||
880 | * @return void |
||||
881 | */ |
||||
882 | public function testReleaseUsedVoucherCodesShouldSetNumberOfUsesCounterBack(): void |
||||
883 | { |
||||
884 | $discountFacade = $this->createDiscountFacade(); |
||||
885 | $discountConfiguratorTransfer = $this->tester->createDiscountConfiguratorTransfer(); |
||||
886 | $idDiscount = $discountFacade->saveDiscount($discountConfiguratorTransfer); |
||||
887 | |||||
888 | $discountVoucherTransfer = new DiscountVoucherTransfer(); |
||||
889 | $discountVoucherTransfer->setIdDiscount($idDiscount); |
||||
890 | $discountVoucherTransfer->setCustomCode('functional spryker test voucher'); |
||||
891 | $discountVoucherTransfer->setMaxNumberOfUses(5); |
||||
892 | $discountVoucherTransfer->setQuantity(1); |
||||
893 | $discountVoucherTransfer->setRandomGeneratedCodeLength(3); |
||||
894 | |||||
895 | $discountFacade->saveVoucherCodes($discountVoucherTransfer); |
||||
896 | |||||
897 | $discountEntity = SpyDiscountQuery::create()->findOneByIdDiscount($idDiscount); |
||||
898 | |||||
899 | $voucherPoolEntity = $discountEntity->getVoucherPool(); |
||||
900 | $voucherCodes = $voucherPoolEntity->getDiscountVouchers(); |
||||
901 | |||||
902 | $voucherCodeList = []; |
||||
903 | foreach ($voucherCodes as $voucherCodeEntity) { |
||||
904 | $voucherCodeEntity->setNumberOfUses(1); |
||||
905 | $voucherCodeEntity->save(); |
||||
906 | $voucherCodeList[] = $voucherCodeEntity->getCode(); |
||||
907 | } |
||||
908 | |||||
909 | $released = $discountFacade->releaseUsedVoucherCodes($voucherCodeList); |
||||
910 | |||||
911 | $this->assertSame(1, $released); |
||||
912 | } |
||||
913 | |||||
914 | /** |
||||
915 | * @return void |
||||
916 | */ |
||||
917 | public function testUseVoucherCodesShouldUpdateVoucherCounterThatItWasAlreadyUsed(): void |
||||
918 | { |
||||
919 | $discountFacade = $this->createDiscountFacade(); |
||||
920 | $discountConfiguratorTransfer = $this->tester->createDiscountConfiguratorTransfer(); |
||||
921 | $idDiscount = $discountFacade->saveDiscount($discountConfiguratorTransfer); |
||||
922 | |||||
923 | $discountVoucherTransfer = new DiscountVoucherTransfer(); |
||||
924 | $discountVoucherTransfer->setIdDiscount($idDiscount); |
||||
925 | $discountVoucherTransfer->setCustomCode('functional spryker test voucher'); |
||||
926 | $discountVoucherTransfer->setMaxNumberOfUses(5); |
||||
927 | $discountVoucherTransfer->setQuantity(1); |
||||
928 | $discountVoucherTransfer->setRandomGeneratedCodeLength(3); |
||||
929 | |||||
930 | $discountFacade->saveVoucherCodes($discountVoucherTransfer); |
||||
931 | |||||
932 | $discountEntity = SpyDiscountQuery::create()->findOneByIdDiscount($idDiscount); |
||||
933 | |||||
934 | $voucherPoolEntity = $discountEntity->getVoucherPool(); |
||||
935 | $voucherCodes = $voucherPoolEntity->getDiscountVouchers(); |
||||
936 | |||||
937 | $voucherCodeList = []; |
||||
938 | foreach ($voucherCodes as $voucherCodeEntity) { |
||||
939 | $voucherCodeList[] = $voucherCodeEntity->getCode(); |
||||
940 | } |
||||
941 | |||||
942 | $discountFacade->useVoucherCodes($voucherCodeList); |
||||
943 | |||||
944 | $voucherPoolEntity->reload(true); |
||||
945 | $voucherCodes = $voucherPoolEntity->getDiscountVouchers(); |
||||
946 | $voucherCodeEntity = $voucherCodes[0]; |
||||
947 | |||||
948 | $this->assertSame(1, $voucherCodeEntity->getNumberOfUses()); |
||||
949 | } |
||||
950 | |||||
951 | /** |
||||
952 | * @return void |
||||
953 | */ |
||||
954 | public function testAddCartCodeAddsVoucherDiscountToQuote(): void |
||||
955 | { |
||||
956 | // Arrange |
||||
957 | $quoteTransfer = $this->tester->createQuoteTransferWithoutVoucherDiscount(); |
||||
958 | |||||
959 | // Act |
||||
960 | $resultQuoteTransfer = $this->createDiscountFacade()->addCartCode($quoteTransfer, $this->tester::VOUCHER_CODE); |
||||
0 ignored issues
–
show
Bug
introduced
by
Loading history...
|
|||||
961 | |||||
962 | // Assert |
||||
963 | $this->assertCount(1, $quoteTransfer->getVoucherDiscounts()); |
||||
964 | $this->assertSame( |
||||
965 | $this->tester::VOUCHER_CODE, |
||||
966 | $resultQuoteTransfer->getVoucherDiscounts()[0]->getVoucherCode(), |
||||
967 | ); |
||||
968 | } |
||||
969 | |||||
970 | /** |
||||
971 | * @return void |
||||
972 | */ |
||||
973 | public function testAddCartCodeCantAddVoucherDiscountToQuoteWithVoucherCodeAlreadyAddedToQuote(): void |
||||
974 | { |
||||
975 | // Arrange |
||||
976 | $quoteTransfer = $this->tester->createQuoteTransferWithVoucherDiscount(); |
||||
977 | |||||
978 | // Act |
||||
979 | $resultQuoteTransfer = $this->createDiscountFacade()->addCartCode($quoteTransfer, $this->tester::VOUCHER_CODE); |
||||
980 | |||||
981 | // Assert |
||||
982 | $this->assertCount(1, $resultQuoteTransfer->getVoucherDiscounts()); |
||||
983 | } |
||||
984 | |||||
985 | /** |
||||
986 | * @return void |
||||
987 | */ |
||||
988 | public function testRemoveCartCodeRemovesVoucherDiscountFromQuote(): void |
||||
989 | { |
||||
990 | // Arrange |
||||
991 | $quoteTransfer = $this->tester->createQuoteTransferWithVoucherDiscount(); |
||||
992 | |||||
993 | // Act |
||||
994 | $resultQuoteTransfer = $this->createDiscountFacade()->removeCartCode($quoteTransfer, $this->tester::VOUCHER_CODE); |
||||
0 ignored issues
–
show
The method
removeCartCode() does not exist on Spryker\Zed\Kernel\Business\AbstractFacade . It seems like you code against a sub-type of Spryker\Zed\Kernel\Business\AbstractFacade such as Spryker\Zed\CartCode\Business\CartCodeFacade or Spryker\Zed\GiftCard\Business\GiftCardFacade or Spryker\Zed\Discount\Business\DiscountFacade or Spryker\Zed\CartCodesRes...\CartCodesRestApiFacade .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||
995 | |||||
996 | // Assert |
||||
997 | $this->assertCount(0, $resultQuoteTransfer->getVoucherDiscounts()); |
||||
998 | } |
||||
999 | |||||
1000 | /** |
||||
1001 | * @return void |
||||
1002 | */ |
||||
1003 | public function testClearCartCodesRemovesVoucherDiscountsFromQuote(): void |
||||
1004 | { |
||||
1005 | // Arrange |
||||
1006 | $quoteTransfer = $this->tester->createQuoteTransferWithVoucherDiscount(); |
||||
1007 | |||||
1008 | // Act |
||||
1009 | $resultQuoteTransfer = $this->createDiscountFacade()->clearCartCodes($quoteTransfer); |
||||
0 ignored issues
–
show
The method
clearCartCodes() does not exist on Spryker\Zed\Kernel\Business\AbstractFacade . It seems like you code against a sub-type of Spryker\Zed\Kernel\Business\AbstractFacade such as Spryker\Zed\CartCode\Business\CartCodeFacade or Spryker\Zed\GiftCard\Business\GiftCardFacade or Spryker\Zed\Discount\Business\DiscountFacade .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||
1010 | |||||
1011 | // Assert |
||||
1012 | $this->assertCount(0, $resultQuoteTransfer->getVoucherDiscounts()); |
||||
1013 | } |
||||
1014 | |||||
1015 | /** |
||||
1016 | * @return void |
||||
1017 | */ |
||||
1018 | public function testFindOperationResponseMessageReturnsMessageTransfer(): void |
||||
1019 | { |
||||
1020 | // Arrange |
||||
1021 | $quoteTransfer = $this->tester->createQuoteTransferWithVoucherDiscount(); |
||||
1022 | |||||
1023 | // Act |
||||
1024 | $messageTransfer = $this->createDiscountFacade()->findOperationResponseMessage($quoteTransfer, $this->tester::VOUCHER_CODE); |
||||
0 ignored issues
–
show
The method
findOperationResponseMessage() does not exist on Spryker\Zed\Kernel\Business\AbstractFacade . It seems like you code against a sub-type of Spryker\Zed\Kernel\Business\AbstractFacade such as Spryker\Zed\GiftCard\Business\GiftCardFacade or Spryker\Zed\Discount\Business\DiscountFacade .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||
1025 | |||||
1026 | // Assert |
||||
1027 | $this->assertNotNull($messageTransfer); |
||||
1028 | } |
||||
1029 | |||||
1030 | /** |
||||
1031 | * @param array $override |
||||
1032 | * |
||||
1033 | * @return \Generated\Shared\Transfer\DiscountVoucherTransfer|\Spryker\Shared\Kernel\Transfer\AbstractTransfer |
||||
1034 | */ |
||||
1035 | protected function getDiscountVoucher(array $override = []) |
||||
1036 | { |
||||
1037 | $discountGeneralTransfer = $this->tester->haveDiscount([ |
||||
1038 | 'discountType' => DiscountConstants::TYPE_VOUCHER, |
||||
1039 | ]); |
||||
1040 | $override['idDiscount'] = $discountGeneralTransfer->getIdDiscount(); |
||||
1041 | $discountVoucherTransfer = $this->tester->haveGeneratedVoucherCodes($override); |
||||
1042 | |||||
1043 | return $discountVoucherTransfer; |
||||
1044 | } |
||||
1045 | |||||
1046 | /** |
||||
1047 | * @param \Generated\Shared\Transfer\DiscountVoucherTransfer $discountVoucherTransfer |
||||
1048 | * |
||||
1049 | * @return \Generated\Shared\Transfer\QuoteTransfer |
||||
1050 | */ |
||||
1051 | protected function getQuoteWithVoucherDiscount(DiscountVoucherTransfer $discountVoucherTransfer): QuoteTransfer |
||||
1052 | { |
||||
1053 | $quoteTransfer = new QuoteTransfer(); |
||||
1054 | $itemTransfer = new ItemTransfer(); |
||||
1055 | $itemTransfer->setSku('123'); |
||||
1056 | $quoteTransfer->addItem($itemTransfer); |
||||
1057 | |||||
1058 | $discountTransfer = new DiscountTransfer(); |
||||
1059 | $discountTransfer->setVoucherCode($discountVoucherTransfer->getCode()); |
||||
1060 | $quoteTransfer->addVoucherDiscount($discountTransfer); |
||||
1061 | |||||
1062 | return $quoteTransfer; |
||||
1063 | } |
||||
1064 | |||||
1065 | /** |
||||
1066 | * @param \Generated\Shared\Transfer\DiscountVoucherTransfer $discountVoucherTransfer |
||||
1067 | * @param int $numberOfUses |
||||
1068 | * |
||||
1069 | * @return void |
||||
1070 | */ |
||||
1071 | protected function updateVoucherCodesWithNumberOfUses(DiscountVoucherTransfer $discountVoucherTransfer, int $numberOfUses): void |
||||
1072 | { |
||||
1073 | $voucherCodeEntities = SpyDiscountQuery::create() |
||||
1074 | ->findOneByIdDiscount($discountVoucherTransfer->getIdDiscount()) |
||||
1075 | ->getVoucherPool() |
||||
1076 | ->getDiscountVouchers(); |
||||
1077 | |||||
1078 | foreach ($voucherCodeEntities as $voucherCodeEntity) { |
||||
1079 | $voucherCodeEntity |
||||
1080 | ->setNumberOfUses($numberOfUses) |
||||
1081 | ->save(); |
||||
1082 | } |
||||
1083 | } |
||||
1084 | |||||
1085 | /** |
||||
1086 | * @return \Spryker\Zed\Discount\Business\DiscountFacadeInterface|\Spryker\Zed\Kernel\Business\AbstractFacade |
||||
1087 | */ |
||||
1088 | protected function createDiscountFacade() |
||||
1089 | { |
||||
1090 | return $this->tester->getLocator()->discount()->facade(); |
||||
1091 | } |
||||
1092 | |||||
1093 | /** |
||||
1094 | * @param string $dependencyType |
||||
1095 | * @param \Spryker\Zed\DiscountExtension\Dependency\Plugin\DiscountRuleWithValueOptionsPluginInterface|\PHPUnit\Framework\MockObject\MockObject $discountRulePluginMock |
||||
1096 | * |
||||
1097 | * @return \Spryker\Zed\Discount\Business\DiscountFacadeInterface|\Spryker\Zed\Kernel\Business\AbstractFacade |
||||
1098 | */ |
||||
1099 | protected function createDiscountFacadeForDiscountRuleWithValueOptionsPlugin(string $dependencyType, $discountRulePluginMock) |
||||
1100 | { |
||||
1101 | $discountFacade = $this->createDiscountFacade(); |
||||
1102 | $factory = new DiscountBusinessFactory(); |
||||
1103 | $container = new Container(); |
||||
1104 | $container->set($dependencyType, function () use ($discountRulePluginMock) { |
||||
1105 | return [ |
||||
1106 | $discountRulePluginMock, |
||||
1107 | ]; |
||||
1108 | }); |
||||
1109 | $factory->setContainer($container); |
||||
1110 | $discountFacade->setFactory($factory); |
||||
1111 | |||||
1112 | return $discountFacade; |
||||
1113 | } |
||||
1114 | |||||
1115 | /** |
||||
1116 | * @return \Spryker\Zed\DiscountExtension\Dependency\Plugin\DiscountRuleWithValueOptionsPluginInterface|\PHPUnit\Framework\MockObject\MockObject |
||||
1117 | */ |
||||
1118 | protected function createDiscountRuleWithValueOptionsPluginMock(): DiscountRuleWithValueOptionsPluginInterface |
||||
1119 | { |
||||
1120 | $discountRulePluginMock = $this->getMockBuilder(DiscountRuleWithValueOptionsPluginInterface::class) |
||||
1121 | ->setMethods(['getQueryStringValueOptions', 'getFieldName']) |
||||
1122 | ->getMock(); |
||||
1123 | |||||
1124 | return $discountRulePluginMock; |
||||
1125 | } |
||||
1126 | } |
||||
1127 |