Completed
Branch master (b23e60)
by Kamil
35:19
created

OrderSpec::it_adds_adjustments_properly()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 6

Duplication

Lines 9
Ratio 100 %

Importance

Changes 0
Metric Value
dl 9
loc 9
c 0
b 0
f 0
rs 9.6666
cc 1
eloc 6
nc 1
nop 1
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()
0 ignored issues
show
Coding Style introduced by
function it_implements_Sylius_order_interface() does not seem to conform to the naming convention (^(?:(?:[a-z]|__)[a-zA-Z0-9]*|[a-z][a-z0-9_]*)$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
34
    {
35
        $this->shouldImplement(OrderInterface::class);
36
    }
37
38
    function it_implements_Sylius_adjustable_interface()
0 ignored issues
show
Coding Style introduced by
function it_implements_S..._adjustable_interface() does not seem to conform to the naming convention (^(?:(?:[a-z]|__)[a-zA-Z0-9]*|[a-z][a-z0-9_]*)$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
39
    {
40
        $this->shouldImplement(AdjustableInterface::class);
41
    }
42
43
    function it_implements_Sylius_timestampable_interface()
0 ignored issues
show
Coding Style introduced by
function it_implements_S...mestampable_interface() does not seem to conform to the naming convention (^(?:(?:[a-z]|__)[a-zA-Z0-9]*|[a-z][a-z0-9_]*)$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
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 View Code Duplication
    function it_adds_adjustments_properly(AdjustmentInterface $adjustment)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
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 View Code Duplication
    function it_removes_adjustments_recursively_properly(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
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,
0 ignored issues
show
Comprehensibility Naming introduced by
The variable name $orderPromotionAdjustment exceeds the maximum configured length of 20.

Very long variable names usually make code harder to read. It is therefore recommended not to make variable names too verbose.

Loading history...
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 View Code Duplication
    function it_has_total_quantity(OrderItemInterface $orderItem1, OrderItemInterface $orderItem2)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
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 View Code Duplication
    function it_calculates_correct_total(OrderItemInterface $item1, OrderItemInterface $item2, AdjustmentInterface $adjustment1, AdjustmentInterface $adjustment2)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
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 View Code Duplication
    function it_ignores_neutral_adjustments_when_calculating_total(OrderItemInterface $item1, OrderItemInterface $item2, AdjustmentInterface $adjustment1, AdjustmentInterface $adjustment2)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
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 View Code Duplication
    function it_calculates_correct_total_when_adjustment_is_bigger_than_cost(OrderItemInterface $item, AdjustmentInterface $adjustment)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
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
    function it_has_notes()
491
    {
492
        $this->setNotes('something squishy');
493
        $this->getNotes()->shouldReturn('something squishy');
494
    }
495
}
496