Completed
Push — master ( 64f4aa...2c8981 )
by Kamil
23:00
created

it_removes_adjustments_recursively_properly()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 13
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
c 1
b 1
f 0
dl 0
loc 13
rs 9.4285
cc 1
eloc 8
nc 1
nop 2
1
<?php
2
3
/*
4
 * This file is part of the Sylius package.
5
 *
6
 * (c) Paweł Jędrzejewski
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace spec\Sylius\Component\Order\Model;
13
14
use PhpSpec\ObjectBehavior;
15
use Prophecy\Argument;
16
use Sylius\Component\Order\Model\AdjustableInterface;
17
use Sylius\Component\Order\Model\AdjustmentInterface;
18
use Sylius\Component\Order\Model\IdentityInterface;
19
use Sylius\Component\Order\Model\OrderInterface;
20
use Sylius\Component\Order\Model\OrderItemInterface;
21
use Sylius\Component\Resource\Model\TimestampableInterface;
22
23
/**
24
 * @author Paweł Jędrzejewski <[email protected]>
25
 */
26
class OrderSpec extends ObjectBehavior
27
{
28
    function it_is_initializable()
29
    {
30
        $this->shouldHaveType('Sylius\Component\Order\Model\Order');
31
    }
32
33
    function it_implements_Sylius_order_interface()
34
    {
35
        $this->shouldImplement(OrderInterface::class);
36
    }
37
38
    function it_implements_Sylius_adjustable_interface()
39
    {
40
        $this->shouldImplement(AdjustableInterface::class);
41
    }
42
43
    function it_implements_Sylius_timestampable_interface()
44
    {
45
        $this->shouldImplement(TimestampableInterface::class);
46
    }
47
48
    function it_has_no_id_by_default()
49
    {
50
        $this->getId()->shouldReturn(null);
51
    }
52
53
    function it_is_not_completed_by_default()
54
    {
55
        $this->shouldNotBeCompleted();
56
    }
57
58
    function it_can_be_completed()
59
    {
60
        $this->complete();
61
        $this->shouldBeCompleted();
62
    }
63
64
    function it_is_completed_when_completion_date_is_set()
65
    {
66
        $this->shouldNotBeCompleted();
67
        $this->setCompletedAt(new \DateTime('2 days ago'));
68
        $this->shouldBeCompleted();
69
    }
70
71
    function it_has_no_completion_date_by_default()
72
    {
73
        $this->getCompletedAt()->shouldReturn(null);
74
    }
75
76
    function its_completion_date_is_mutable()
77
    {
78
        $date = new \DateTime('1 hour ago');
79
80
        $this->setCompletedAt($date);
81
        $this->getCompletedAt()->shouldReturn($date);
82
    }
83
84
    function it_has_no_number_by_default()
85
    {
86
        $this->getNumber()->shouldReturn(null);
87
    }
88
89
    function its_number_is_mutable()
90
    {
91
        $this->setNumber('001351');
92
        $this->getNumber()->shouldReturn('001351');
93
    }
94
95
    function it_creates_items_collection_by_default()
96
    {
97
        $this->getItems()->shouldHaveType('Doctrine\\Common\\Collections\\Collection');
98
    }
99
100
    function it_creates_identities_collection_by_default()
101
    {
102
        $this->getIdentities()->shouldHaveType('Doctrine\\Common\\Collections\\Collection');
103
    }
104
105
    function it_adds_identities_properly(IdentityInterface $identity)
106
    {
107
        $this->hasIdentity($identity)->shouldReturn(false);
108
109
        $this->addIdentity($identity);
110
        $this->hasIdentity($identity)->shouldReturn(true);
111
    }
112
113
    function it_adds_items_properly(OrderItemInterface $item)
114
    {
115
        $this->hasItem($item)->shouldReturn(false);
116
117
        $this->addItem($item);
118
        $this->hasItem($item)->shouldReturn(true);
119
    }
120
121
    function it_removes_identities_properly(IdentityInterface $identity)
122
    {
123
        $this->hasIdentity($identity)->shouldReturn(false);
124
125
        $this->addIdentity($identity);
126
        $this->hasIdentity($identity)->shouldReturn(true);
127
128
        $this->removeIdentity($identity);
129
        $this->hasIdentity($identity)->shouldReturn(false);
130
    }
131
132
    function it_removes_items_properly(OrderItemInterface $item)
133
    {
134
        $this->hasItem($item)->shouldReturn(false);
135
136
        $this->addItem($item);
137
        $this->hasItem($item)->shouldReturn(true);
138
139
        $this->removeItem($item);
140
        $this->hasItem($item)->shouldReturn(false);
141
    }
142
143
    function it_has_items_total_equal_to_0_by_default()
144
    {
145
        $this->getItemsTotal()->shouldReturn(0);
146
    }
147
148
    function it_calculates_correct_items_total(
149
        OrderItemInterface $item1,
150
        OrderItemInterface $item2,
151
        OrderItemInterface $item3
152
    ) {
153
        $item1->getTotal()->willReturn(29999);
154
        $item2->getTotal()->willReturn(45000);
155
        $item3->getTotal()->willReturn(250);
156
157
        $item1->setOrder($this)->shouldBeCalled();
158
        $item2->setOrder($this)->shouldBeCalled();
159
        $item3->setOrder($this)->shouldBeCalled();
160
161
        $item1->equals(Argument::any())->willReturn(false);
162
        $item2->equals(Argument::any())->willReturn(false);
163
        $item3->equals(Argument::any())->willReturn(false);
164
165
        $this->addItem($item1);
166
        $this->addItem($item2);
167
        $this->addItem($item3);
168
169
        $this->getItemsTotal()->shouldReturn(75249);
170
    }
171
172
    function it_creates_adjustments_collection_by_default()
173
    {
174
        $this->getAdjustments()->shouldHaveType('Doctrine\Common\Collections\Collection');
175
    }
176
177
    function it_adds_adjustments_properly(AdjustmentInterface $adjustment)
178
    {
179
        $adjustment->setAdjustable($this)->shouldBeCalled();
180
        $adjustment->isNeutral()->willReturn(true);
181
182
        $this->hasAdjustment($adjustment)->shouldReturn(false);
183
        $this->addAdjustment($adjustment);
184
        $this->hasAdjustment($adjustment)->shouldReturn(true);
185
    }
186
187
    function it_removes_adjustments_properly(AdjustmentInterface $adjustment)
188
    {
189
        $this->hasAdjustment($adjustment)->shouldReturn(false);
190
191
        $adjustment->setAdjustable($this)->shouldBeCalled();
192
        $adjustment->isNeutral()->willReturn(true);
193
194
        $this->addAdjustment($adjustment);
195
        $this->hasAdjustment($adjustment)->shouldReturn(true);
196
197
        $adjustment->isLocked()->willReturn(false);
198
        $adjustment->setAdjustable(null)->shouldBeCalled();
199
        $this->removeAdjustment($adjustment);
200
201
        $this->hasAdjustment($adjustment)->shouldReturn(false);
202
    }
203
204
    function it_removes_adjustments_recursively_properly(
205
        AdjustmentInterface $orderAdjustment,
206
        OrderItemInterface $item
207
    ) {
208
        $this->addAdjustment($orderAdjustment);
209
        $this->addItem($item);
210
211
        $item->removeAdjustmentsRecursively(null)->shouldBeCalled();
212
213
        $this->removeAdjustmentsRecursively();
214
215
        $this->hasAdjustment($orderAdjustment)->shouldReturn(false);
216
    }
217
218
    function it_removes_adjustments_recursively_by_type_properly(
219
        AdjustmentInterface $orderPromotionAdjustment,
220
        AdjustmentInterface $orderTaxAdjustment,
221
        OrderItemInterface $item
222
    ) {
223
        $orderPromotionAdjustment->getType()->willReturn('promotion');
224
        $orderPromotionAdjustment->isNeutral()->willReturn(true);
225
        $orderPromotionAdjustment->setAdjustable($this)->shouldBeCalled();
226
        $orderPromotionAdjustment->isLocked()->willReturn(false);
227
228
        $orderTaxAdjustment->getType()->willReturn('tax');
229
        $orderTaxAdjustment->isNeutral()->willReturn(true);
230
        $orderTaxAdjustment->setAdjustable($this)->shouldBeCalled();
231
        $orderTaxAdjustment->isLocked()->willReturn(false);
232
233
        $this->addAdjustment($orderPromotionAdjustment);
234
        $this->addAdjustment($orderTaxAdjustment);
235
        $this->addItem($item);
236
237
        $item->removeAdjustmentsRecursively('tax')->shouldBeCalled();
238
        $orderTaxAdjustment->setAdjustable(null)->shouldBeCalled();
239
240
        $this->removeAdjustmentsRecursively('tax');
241
242
        $this->hasAdjustment($orderPromotionAdjustment)->shouldReturn(true);
243
        $this->hasAdjustment($orderTaxAdjustment)->shouldReturn(false);
244
    }
245
246
    function it_returns_adjustments_recursively(
247
        AdjustmentInterface $orderAdjustment,
248
        AdjustmentInterface $itemAdjustment1,
249
        AdjustmentInterface $itemAdjustment2,
250
        OrderItemInterface $item1,
251
        OrderItemInterface $item2
252
    ) {
253
        $item1->setOrder($this)->shouldBeCalled();
254
        $item1->getTotal()->willReturn(100);
255
        $item1->getAdjustmentsRecursively(null)->willReturn([$itemAdjustment1]);
256
257
        $item2->setOrder($this)->shouldBeCalled();
258
        $item2->getTotal()->willReturn(100);
259
        $item2->getAdjustmentsRecursively(null)->willReturn([$itemAdjustment2]);
260
261
        $this->addItem($item1);
262
        $this->addItem($item2);
263
264
        $orderAdjustment->setAdjustable($this)->shouldBeCalled();
265
        $orderAdjustment->isNeutral()->willReturn(true);
266
267
        $this->addAdjustment($orderAdjustment);
268
269
        $this->getAdjustmentsRecursively()->shouldReturn([$orderAdjustment, $itemAdjustment1, $itemAdjustment2]);
270
    }
271
272
    function it_has_adjustments_total_equal_to_0_by_default()
273
    {
274
        $this->getAdjustmentsTotal()->shouldReturn(0);
275
    }
276
277
    function it_calculates_correct_adjustments_total(AdjustmentInterface $adjustment1, AdjustmentInterface $adjustment2, AdjustmentInterface $adjustment3)
278
    {
279
        $adjustment1->getAmount()->willReturn(10000);
280
        $adjustment2->getAmount()->willReturn(-4999);
281
        $adjustment3->getAmount()->willReturn(1929);
282
283
        $adjustment1->isNeutral()->willReturn(false);
284
        $adjustment2->isNeutral()->willReturn(false);
285
        $adjustment3->isNeutral()->willReturn(false);
286
287
        $adjustment1->setAdjustable($this)->shouldBeCalled();
288
        $adjustment2->setAdjustable($this)->shouldBeCalled();
289
        $adjustment3->setAdjustable($this)->shouldBeCalled();
290
291
        $this->addAdjustment($adjustment1);
292
        $this->addAdjustment($adjustment2);
293
        $this->addAdjustment($adjustment3);
294
295
        $this->getAdjustmentsTotal()->shouldReturn(6930);
296
    }
297
298
    function it_returns_adjustments_total_recursively(
299
        AdjustmentInterface $itemAdjustment,
300
        AdjustmentInterface $orderAdjustment,
301
        OrderItemInterface $orderItem
302
    ) {
303
        $itemAdjustment->getAmount()->willReturn(10000);
304
        $orderAdjustment->getAmount()->willReturn(5000);
305
306
        $itemAdjustment->isNeutral()->willReturn(false);
307
        $orderAdjustment->isNeutral()->willReturn(false);
308
309
        $orderAdjustment->setAdjustable($this)->shouldBeCalled();
310
311
        $orderItem->getAdjustmentsRecursively(null)->willReturn([$itemAdjustment]);
312
        $orderItem->setOrder($this)->shouldBeCalled();
313
        $orderItem->getTotal()->willReturn(15000);
314
315
        $this->addItem($orderItem);
316
        $this->addAdjustment($orderAdjustment);
317
318
        $this->getAdjustmentsTotalRecursively()->shouldReturn(15000);
319
    }
320
321
    function it_has_total_equal_to_0_by_default()
322
    {
323
        $this->getTotal()->shouldReturn(0);
324
    }
325
326
    function it_has_total_quantity(OrderItemInterface $orderItem1, OrderItemInterface $orderItem2)
327
    {
328
        $orderItem1->getQuantity()->willReturn(10);
329
        $orderItem1->setOrder($this)->shouldBeCalled();
330
        $orderItem1->getTotal()->willReturn(500);
331
332
        $orderItem2->getQuantity()->willReturn(30);
333
        $orderItem2->setOrder($this)->shouldBeCalled();
334
        $orderItem2->equals($orderItem1)->willReturn(false);
335
        $orderItem2->getTotal()->willReturn(1000);
336
337
        $this->addItem($orderItem1);
338
        $this->addItem($orderItem2);
339
340
        $this->getTotalQuantity()->shouldReturn(40);
341
    }
342
343
    function it_calculates_correct_total(OrderItemInterface $item1, OrderItemInterface $item2, AdjustmentInterface $adjustment1, AdjustmentInterface $adjustment2)
344
    {
345
        $item1->getTotal()->willReturn(29999);
346
        $item2->getTotal()->willReturn(45000);
347
348
        $item1->equals(Argument::any())->willReturn(false);
349
        $item2->equals(Argument::any())->willReturn(false);
350
351
        $item1->setOrder($this)->shouldBeCalled();
352
        $item2->setOrder($this)->shouldBeCalled();
353
354
        $adjustment1->isNeutral()->willReturn(false);
355
        $adjustment1->getAmount()->willReturn(10000);
356
        $adjustment2->isNeutral()->willReturn(false);
357
        $adjustment2->getAmount()->willReturn(-4999);
358
359
        $adjustment1->setAdjustable($this)->shouldBeCalled();
360
        $adjustment2->setAdjustable($this)->shouldBeCalled();
361
362
        $this->addItem($item1);
363
        $this->addItem($item2);
364
        $this->addAdjustment($adjustment1);
365
        $this->addAdjustment($adjustment2);
366
367
        $this->getTotal()->shouldReturn(80000);
368
    }
369
370
    function it_calculates_correct_total_after_items_and_adjustments_changes(
371
        AdjustmentInterface $adjustment1,
372
        AdjustmentInterface $adjustment2,
373
        OrderItemInterface $item1,
374
        OrderItemInterface $item2,
375
        OrderItemInterface $item3
376
    ) {
377
        $item1->getTotal()->willReturn(29999);
378
        $item2->getTotal()->willReturn(45000);
379
380
        $item1->equals(Argument::any())->willReturn(false);
381
        $item2->equals(Argument::any())->willReturn(false);
382
383
        $item1->setOrder($this)->shouldBeCalled();
384
        $item2->setOrder($this)->shouldBeCalled();
385
386
        $adjustment1->isNeutral()->willReturn(false);
387
        $adjustment1->getAmount()->willReturn(10000);
388
        $adjustment1->setAdjustable($this)->shouldBeCalled();
389
390
        $this->addItem($item1);
391
        $this->addItem($item2);
392
        $this->addAdjustment($adjustment1);
393
394
        $this->getTotal()->shouldReturn(84999);
395
396
        $item2->setOrder(null)->shouldBeCalled();
397
398
        $this->removeItem($item2);
399
400
        $adjustment1->setAdjustable(null)->shouldBeCalled();
401
        $adjustment1->isLocked()->willReturn(false);
402
403
        $adjustment2->isNeutral()->willReturn(false);
404
        $adjustment2->getAmount()->willReturn(-4999);
405
        $adjustment2->setAdjustable($this)->shouldBeCalled();
406
407
        $this->removeAdjustment($adjustment1);
408
        $this->addAdjustment($adjustment2);
409
410
        $item3->getTotal()->willReturn(55000);
411
        $item3->equals(Argument::any())->willReturn(false);
412
        $item3->setOrder($this)->shouldBeCalled();
413
414
        $this->addItem($item3);
415
416
        $this->getTotal()->shouldReturn(80000);
417
    }
418
419
    function it_ignores_neutral_adjustments_when_calculating_total(OrderItemInterface $item1, OrderItemInterface $item2, AdjustmentInterface $adjustment1, AdjustmentInterface $adjustment2)
420
    {
421
        $item1->getTotal()->willReturn(29999);
422
        $item2->getTotal()->willReturn(45000);
423
424
        $item1->equals(Argument::any())->willReturn(false);
425
        $item2->equals(Argument::any())->willReturn(false);
426
427
        $item1->setOrder($this)->shouldBeCalled();
428
        $item2->setOrder($this)->shouldBeCalled();
429
430
        $adjustment1->isNeutral()->willReturn(true);
431
        $adjustment1->getAmount()->willReturn(10000);
432
        $adjustment2->isNeutral()->willReturn(false);
433
        $adjustment2->getAmount()->willReturn(-4999);
434
435
        $adjustment1->setAdjustable($this)->shouldBeCalled();
436
        $adjustment2->setAdjustable($this)->shouldBeCalled();
437
438
        $this->addItem($item1);
439
        $this->addItem($item2);
440
        $this->addAdjustment($adjustment1);
441
        $this->addAdjustment($adjustment2);
442
443
        $this->getTotal()->shouldReturn(70000);
444
    }
445
446
    function it_calculates_correct_total_when_adjustment_is_bigger_than_cost(OrderItemInterface $item, AdjustmentInterface $adjustment)
447
    {
448
        $item->getTotal()->willReturn(45000);
449
450
        $item->equals(Argument::any())->willReturn(false);
451
452
        $item->setOrder($this)->shouldBeCalled();
453
454
        $adjustment->isNeutral()->willReturn(false);
455
        $adjustment->getAmount()->willReturn(-100000);
456
457
        $adjustment->setAdjustable($this)->shouldBeCalled();
458
459
        $this->addItem($item);
460
        $this->addAdjustment($adjustment);
461
462
        $this->getTotal()->shouldReturn(0);
463
    }
464
465
    function it_initializes_creation_date_by_default()
466
    {
467
        $this->getCreatedAt()->shouldHaveType('DateTime');
468
    }
469
470
    function it_has_no_last_update_date_by_default()
471
    {
472
        $this->getUpdatedAt()->shouldReturn(null);
473
    }
474
475
    function it_is_empty_by_default()
476
    {
477
        $this->countItems()->shouldReturn(0);
478
        $this->shouldBeEmpty();
479
    }
480
481
    function it_should_be_able_to_clear_items(OrderItemInterface $item)
482
    {
483
        $this->shouldBeEmpty();
484
        $this->addItem($item);
485
        $this->countItems()->shouldReturn(1);
486
        $this->clearItems();
487
        $this->shouldBeEmpty();
488
    }
489
}
490