Completed
Push — master ( c2123c...66812a )
by
unknown
12:37
created

CartStrategyTest::getEntity()   C

Complexity

Conditions 8
Paths 10

Size

Total Lines 33
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 33
rs 5.3846
c 0
b 0
f 0
cc 8
eloc 19
nc 10
nop 1
1
<?php
2
3
namespace OroCRM\Bundle\MagentoBundle\Tests\Unit\ImportExport\Strategy;
4
5
use Akeneo\Bundle\BatchBundle\Item\ExecutionContext;
6
7
use Doctrine\Common\Collections\ArrayCollection;
8
9
use Symfony\Component\PropertyAccess\Exception\NoSuchPropertyException;
10
use Symfony\Component\PropertyAccess\PropertyAccess;
11
12
use Oro\Bundle\AddressBundle\Entity\Country;
13
use Oro\Bundle\IntegrationBundle\Entity\Channel;
14
use Oro\Bundle\ImportExportBundle\Context\ContextInterface;
15
16
use OroCRM\Bundle\MagentoBundle\Entity\CartAddress;
17
use OroCRM\Bundle\MagentoBundle\Entity\CartItem;
18
use OroCRM\Bundle\MagentoBundle\Entity\Cart;
19
use OroCRM\Bundle\MagentoBundle\Entity\CartStatus;
20
use OroCRM\Bundle\MagentoBundle\Entity\Customer;
21
use OroCRM\Bundle\MagentoBundle\ImportExport\Strategy\CartStrategy;
22
use OroCRM\Bundle\MagentoBundle\Entity\MagentoSoapTransport;
23
24
class CartStrategyTest extends AbstractStrategyTest
25
{
26
    /**
27
     * @var \PHPUnit_Framework_MockObject_MockObject|ContextInterface $context
28
     */
29
    protected $context;
30
31
    /**
32
     * @var \PHPUnit_Framework_MockObject_MockObject|MagentoSoapTransport $transport
33
     */
34
    protected $transport;
35
36
    /**
37
     * @var \PHPUnit_Framework_MockObject_MockObject|Channel $channel
38
     */
39
    protected $channel;
40
41
    /**
42
     * @var \PHPUnit_Framework_MockObject_MockObject|ExecutionContext $execution
43
     */
44
    protected $execution;
45
46
    protected function setUp()
47
    {
48
        parent::setUp();
49
50
        $this->context = $this->getMockBuilder('Oro\Bundle\ImportExportBundle\Context\ContextInterface')
51
            ->getMock();
52
53
        $this->transport = $this->getMockBuilder('OroCRM\Bundle\MagentoBundle\Entity\MagentoSoapTransport')
54
            ->disableOriginalConstructor()
55
            ->getMock();
56
57
        $this->channel = $this->getMockBuilder('Oro\Bundle\IntegrationBundle\Entity\Channel')
58
            ->disableOriginalConstructor()
59
            ->getMock();
60
61
        $this->execution = $this->getMockBuilder('Akeneo\Bundle\BatchBundle\Item\ExecutionContext')
62
            ->getMock();
63
    }
64
65
    /**
66
     * {@inheritdoc}
67
     */
68
    protected function getStrategy()
69
    {
70
        $strategy = new CartStrategy(
71
            $this->eventDispatcher,
72
            $this->strategyHelper,
73
            $this->fieldHelper,
74
            $this->databaseHelper,
75
            $this->chainEntityClassNameProvider,
76
            $this->translator,
77
            $this->newEntitiesHelper,
78
            $this->doctrineHelper
79
        );
80
81
        $strategy->setOwnerHelper($this->defaultOwnerHelper);
82
        $strategy->setLogger($this->logger);
83
        $strategy->setChannelHelper($this->channelHelper);
84
        $strategy->setAddressHelper($this->addressHelper);
85
86
        return $strategy;
87
    }
88
89
    /**
90
     * @param mixed $expected
91
     * @param Cart  $entity
92
     * @param mixed $databaseEntity
93
     *
94
     * @dataProvider contactInfoDataProvider
95
     */
96
    public function testContactInfo($expected, Cart $entity, $databaseEntity = null)
97
    {
98
        $strategy = $this->getStrategy();
99
        $this->jobExecution->expects($this->any())->method('getExecutionContext')
0 ignored issues
show
Bug introduced by
The method expects does only exist in PHPUnit_Framework_MockObject_MockObject, but not in Akeneo\Bundle\BatchBundle\Entity\JobExecution.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
100
            ->will($this->returnValue($this->execution));
101
        $strategy->setStepExecution($this->stepExecution);
102
        $strategy->setImportExportContext($this->context);
103
        $strategy->setEntityName('OroCRM\Bundle\MagentoBundle\Entity\Cart');
104
105
        $reflection = new \ReflectionProperty(get_class($strategy), 'existingEntity');
106
        $reflection->setAccessible(true);
107
        $reflection->setValue($strategy, $entity);
108
109
        $this->transport->expects($this->any())
0 ignored issues
show
Bug introduced by
The method expects does only exist in PHPUnit_Framework_MockObject_MockObject, but not in OroCRM\Bundle\MagentoBun...ty\MagentoSoapTransport.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
110
            ->method('getGuestCustomerSync')
111
            ->will($this->returnValue(true));
112
113
        $this->channel->expects($this->any())
0 ignored issues
show
Bug introduced by
The method expects does only exist in PHPUnit_Framework_MockObject_MockObject, but not in Oro\Bundle\IntegrationBundle\Entity\Channel.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
114
            ->method('getTransport')
115
            ->will($this->returnValue($this->transport));
116
117
        $this->databaseHelper->expects($this->once())
0 ignored issues
show
Bug introduced by
The method expects does only exist in PHPUnit_Framework_MockObject_MockObject, but not in Oro\Bundle\ImportExportBundle\Field\DatabaseHelper.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
118
            ->method('getEntityReference')
119
            ->will($this->returnArgument(0));
120
121
        $this->databaseHelper->expects($this->any())
122
            ->method('findOneByIdentity')
123
            ->will(
124
                $this->returnValueMap(
125
                    [
126
                        [
127
                            $entity->getChannel(),
128
                            $this->channel
129
                        ],
130
                        [
131
                            $entity,
132
                            $databaseEntity
133
                        ]
134
                    ]
135
                )
136
            );
137
138
        $customer = null;
139
        if (is_object($databaseEntity)) {
140
            $customer = $databaseEntity->getCustomer();
141
        }
142
        $this->databaseHelper->expects($this->any())
143
            ->method('findOneBy')
144
            ->will(
145
                $this->returnValueMap(
146
                    [
147
                        [
148
                            'OroCRM\Bundle\MagentoBundle\Entity\Customer',
149
                            [
150
                                'channel' => $entity->getChannel(),
151
                                'email' => $entity->getEmail()
152
                            ],
153
                            $customer
154
                        ]
155
                    ]
156
                )
157
            );
158
159
        $actualEntity = $strategy->process($entity);
160
        if ($actualEntity) {
161
            $expected->setImportedAt($actualEntity->getImportedAt());
162
            $expected->setSyncedAt($actualEntity->getSyncedAt());
163
        }
164
165
        $this->assertEquals($expected, $actualEntity);
166
    }
167
168
    /**
169
     * @return array
170
     *
171
     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
172
     */
173
    public function contactInfoDataProvider()
174
    {
175
        return [
176
            'items count' => [null, $this->getEntity()],
177
            'without contact info' => [null, $this->getEntity(['itemsCount' => 1])],
178
            'email' => [
179
                $this->getEntity(['itemsCount' => 1, 'email' => '[email protected]']),
180
                $this->getEntity(['itemsCount' => 1, 'email' => '[email protected]']),
181
182
            ],
183
            'do not change status' => [
184
                $this->getEntity(
185
                    ['itemsCount' => 1, 'email' => '[email protected]', 'status' => new CartStatus('custom')]
186
                ),
187
                $this->getEntity(
188
                    ['itemsCount' => 1, 'email' => '[email protected]', 'status' => new CartStatus('custom')]
189
                ),
190
                $this->getEntity(
191
                    ['itemsCount' => 1, 'email' => '[email protected]', 'status' => new CartStatus('custom')]
192
                )
193
            ],
194
            'change status' => [
195
                'expected' => $this->getEntity(
196
                    ['itemsCount' => 1, 'email' => '[email protected]', 'status' => new CartStatus('expired')]
197
                ),
198
                'entity' => $this->getEntity(
199
                    ['itemsCount' => 1, 'email' => '[email protected]', 'status' => new CartStatus('expired')]
200
                ),
201
                'databaseEntity' => $this->getEntity(
202
                    ['itemsCount' => 1, 'email' => '[email protected]', 'status' => new CartStatus('open')]
203
                )
204
            ],
205
            'update customer email' => [
206
                'expected' => $this->getEntity(
207
                    [
208
                        'itemsCount' => 1,
209
                        'email' => '[email protected]',
210
                        'customer' => $this->getCustomer('[email protected]'),
211
                        'isGuest'  => false
212
                    ]
213
                ),
214
                'entity' => $this->getEntity(
215
                    [
216
                        'itemsCount' => 1,
217
                        'email' => '[email protected]',
218
                        'customer' => $this->getCustomer(),
219
                        'isGuest'  => false
220
                    ]
221
                ),
222
                'databaseEntity' => $this->getEntity(
223
                    [
224
                        'itemsCount' => 1,
225
                        'email' => '[email protected]',
226
                        'customer' => $this->getCustomer('[email protected]'),
227
                        'isGuest'  => false
228
                    ]
229
                )
230
            ],
231
            'update customer email for guest cart' => [
232
                'expected' => $this->getEntity(
233
                    [
234
                        'itemsCount' => 1,
235
                        'email' => '[email protected]',
236
                        'customer' => $this->getCustomer('[email protected]'),
237
                        'isGuest'  => true
238
                    ]
239
                ),
240
                'entity' => $this->getEntity(
241
                    [
242
                        'itemsCount' => 1,
243
                        'email' => '[email protected]',
244
                        'customer' => $this->getCustomer(),
245
                        'isGuest'  => true
246
                    ]
247
                ),
248
                'databaseEntity' => $this->getEntity(
249
                    [
250
                        'itemsCount' => 1,
251
                        'email' => '[email protected]',
252
                        'customer' => $this->getCustomer('[email protected]'),
253
                        'isGuest'  => true
254
                    ]
255
                )
256
            ],
257
            'add new cart item and remove old' => [
258
                'expected' => $this->getEntity(
259
                    [
260
                        'itemsCount' => 1,
261
                        'email' => '[email protected]',
262
                        'cartItems' => new ArrayCollection([$this->getCartItem(1)]),
263
                        'itemsQty' => 1,
264
                    ]
265
                ),
266
                'entity' => $this->getEntity(
267
                    [
268
                        'itemsCount' => 1,
269
                        'email' => '[email protected]',
270
                        'cartItems' => new ArrayCollection([$this->getCartItem(1)]),
271
                        'itemsQty' => 1,
272
                    ]
273
                ),
274
                'databaseEntity' => $this->getEntity(
275
                    [
276
                        'itemsCount' => 1,
277
                        'email' => '[email protected]',
278
                        'cartItems' => new ArrayCollection([$this->getCartItem(2)]),
279
                        'itemsQty' => 1,
280
                    ]
281
                )
282
            ],
283
            'add new cart item and keep old one' => [
284
                'expected' => $this->getEntity(
285
                    [
286
                        'itemsCount' => 1,
287
                        'email' => '[email protected]',
288
                        'cartItems' => new ArrayCollection([$this->getCartItem(1), $this->getCartItem(2)]),
289
                        'itemsQty' => 2,
290
                    ]
291
                ),
292
                'entity' => $this->getEntity(
293
                    [
294
                        'itemsCount' => 1,
295
                        'email' => '[email protected]',
296
                        'cartItems' => new ArrayCollection([$this->getCartItem(1), $this->getCartItem(2)]),
297
                        'itemsQty' => 2,
298
                    ]
299
                ),
300
                'databaseEntity' => $this->getEntity(
301
                    [
302
                        'itemsCount' => 1,
303
                        'email' => '[email protected]',
304
                        'cartItems' => new ArrayCollection([$this->getCartItem(2)]),
305
                        'itemsQty' => 1,
306
                    ]
307
                )
308
            ],
309
            'update existing address' => [
310
                'expected' => $this->getEntity(
311
                    [
312
                        'itemsCount' => 1,
313
                        'email' => '[email protected]',
314
                        'shippingAddress' => $this->getAddress('US')
315
                    ]
316
                ),
317
                'entity' => $this->getEntity(
318
                    [
319
                        'itemsCount' => 1,
320
                        'email' => '[email protected]',
321
                        'shippingAddress' => $this->getAddress('US')
322
                    ]
323
                ),
324
                'databaseEntity' => $this->getEntity(
325
                    [
326
                        'itemsCount' => 1,
327
                        'email' => '[email protected]',
328
                        'shippingAddress' => $this->getAddress('US')
329
                    ]
330
                )
331
            ],
332
            'drop without country' => [
333
                'expected' => $this->getEntity(
334
                    [
335
                        'itemsCount' => 1,
336
                        'email' => '[email protected]',
337
                        'billingAddress' => null
338
                    ]
339
                ),
340
                'entity' => $this->getEntity(
341
                    [
342
                        'itemsCount' => 1,
343
                        'email' => '[email protected]',
344
                        'billingAddress' => $this->getAddress()
345
                    ]
346
                )
347
            ]
348
        ];
349
    }
350
351
    /**
352
     * Test setting removed field on removed cart items
353
     */
354
    public function testUpdateRemovedCartItems()
355
    {
356
        $channel = new Channel();
357
358
        $cartItem1 = new CartItem();
359
        $cartItem1->setName('Cart Item 1');
360
361
        $cartItem2 = new CartItem();
362
        $cartItem2->setName('Cart Item 2');
363
364
        $cartItem3 = new CartItem();
365
        $cartItem3->setName('Cart Item 3');
366
367
        $existingCartItems = new ArrayCollection();
368
        $existingCartItems->add($cartItem1);
369
        $existingCartItems->add($cartItem2);
370
371
        $existingCart = new Cart();
372
        $existingCart->setCartItems($existingCartItems);
373
        $existingCart->setChannel($channel);
374
        $existingCart->setItemsQty(2);
375
376
        $newCartItems = new ArrayCollection();
377
        $newCartItems->add($cartItem2);
378
        $newCartItems->add($cartItem3);
379
380
        $newCart = new Cart();
381
        $newCart->setCartItems($newCartItems);
382
        $newCart->setChannel($channel);
383
        $newCart->setItemsQty(2);
384
385
        $this->databaseHelper->expects($this->once())
0 ignored issues
show
Bug introduced by
The method expects does only exist in PHPUnit_Framework_MockObject_MockObject, but not in Oro\Bundle\ImportExportBundle\Field\DatabaseHelper.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
386
            ->method('findOneByIdentity')
387
            ->will($this->returnValue($existingCart));
388
389
        $this->databaseHelper->expects($this->once())
390
            ->method('getEntityReference')
391
            ->will($this->returnValue($channel));
392
393
        $this->databaseHelper->expects($this->once())
394
            ->method('getIdentifier')
395
            ->will($this->returnValue('identifier'));
396
397
        $this->databaseHelper->expects($this->once())
398
            ->method('find')
399
            ->with('OroCRM\Bundle\MagentoBundle\Entity\Cart', 'identifier')
400
            ->will($this->returnValue($newCart));
401
402
        $strategy = $this->getStrategy();
403
        $strategy->setImportExportContext($this->context);
404
        $strategy->setEntityName('OroCRM\Bundle\MagentoBundle\Entity\Cart');
405
        $this->jobExecution->expects($this->any())->method('getExecutionContext')
0 ignored issues
show
Bug introduced by
The method expects does only exist in PHPUnit_Framework_MockObject_MockObject, but not in Akeneo\Bundle\BatchBundle\Entity\JobExecution.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
406
            ->will($this->returnValue($this->execution));
407
        $strategy->setStepExecution($this->stepExecution);
408
409
        $strategy->process($existingCart);
410
411
        $this->assertTrue($cartItem1->isRemoved());
412
        $this->assertFalse($cartItem2->isRemoved());
413
        $this->assertFalse($cartItem3->isRemoved());
414
    }
415
416
    /**
417
     * @param int $originId
418
     *
419
     * @return CartItem
420
     */
421
    protected function getCartItem($originId)
422
    {
423
        $cartItem = new CartItem();
424
        $cartItem->setOriginId($originId);
425
426
        return $cartItem;
427
    }
428
429
    /**
430
     * @param string $countryCode
431
     * @return CartAddress
432
     */
433
    protected function getAddress($countryCode = null)
434
    {
435
        $address = new CartAddress();
436
437
        if ($countryCode) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $countryCode of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
438
            $address->setCountry(new Country($countryCode));
439
        }
440
441
        return $address;
442
    }
443
444
    /**
445
     * @param string|null $email
446
     * @return Customer
447
     */
448
    protected function getCustomer($email = null)
449
    {
450
        $customer = new Customer();
451
        if ($email) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $email of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
452
            $customer->setEmail($email);
453
        }
454
455
        return $customer;
456
    }
457
458
    /**
459
     * @param array $properties
460
     *
461
     * @return Cart
462
     */
463
    protected function getEntity(array $properties = [])
464
    {
465
        $cart = new Cart();
466
467
        $channel = new Channel();
468
        $cart->setChannel($channel);
469
470
        $propertyAccessor = PropertyAccess::createPropertyAccessor();
471
472
        foreach ($properties as $property => $value) {
473
            if ($value instanceof ArrayCollection) {
474
                foreach ($value as $item) {
475
                    try {
476
                        $propertyAccessor->setValue($item, 'cart', $cart);
477
                    } catch (NoSuchPropertyException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
478
                    }
479
                }
480
            } elseif (is_object($value)) {
481
                try {
482
                    $propertyAccessor->setValue($value, 'cart', $cart);
483
                } catch (NoSuchPropertyException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
484
                }
485
            }
486
487
            $propertyAccessor->setValue($cart, $property, $value);
488
        }
489
490
        if ($cart->getCustomer()) {
491
            $cart->getCustomer()->setChannel($channel);
492
        }
493
494
        return $cart;
0 ignored issues
show
Bug Compatibility introduced by
The expression return $cart; of type object|array is incompatible with the return type documented by OroCRM\Bundle\MagentoBun...StrategyTest::getEntity of type OroCRM\Bundle\MagentoBundle\Entity\Cart as it can also be of type array which is not included in this return type.
Loading history...
495
    }
496
}
497