Completed
Pull Request — master (#336)
by Stefan
05:11
created

ProductFromShopTest::testOnPerformSync()   B

Complexity

Conditions 3
Paths 4

Size

Total Lines 124
Code Lines 61

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 124
rs 8.2857
cc 3
eloc 61
nc 4
nop 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Tests\ShopwarePlugins\Connect\Component;
4
5
use Shopware\Connect\Struct\Address;
6
use Shopware\Connect\Struct\Change\FromShop\Availability;
7
use Shopware\Connect\Struct\Change\FromShop\Update;
8
use Shopware\Connect\Struct\Change\FromShop\Delete;
9
use Shopware\Connect\Struct\Order;
10
use Shopware\Connect\Struct\OrderItem;
11
use Shopware\Connect\Struct\Product;
12
use Shopware\CustomModels\Connect\Attribute;
13
use Shopware\Models\Article\Article;
14
use ShopwarePlugins\Connect\Components\Logger;
15
use ShopwarePlugins\Connect\Components\ProductFromShop;
16
use Shopware\Connect\Struct\Change\FromShop\Insert;
17
use Shopware\Bundle\AttributeBundle\Service\CrudService;
18
use Tests\ShopwarePlugins\Connect\ConnectTestHelper;
19
20
class ProductFromShopTest extends ConnectTestHelper
21
{
22
    /**
23
     * @var array
24
     */
25
    private $user;
26
27
    /**
28
     * @var ProductFromShop
29
     */
30
    private $productFromShop;
31
32
    public static function setUpBeforeClass()
33
    {
34
        parent::setUpBeforeClass();
35
36
        $manager = Shopware()->Models();
37
        /** @var \Shopware\Models\Shop\Shop $defaultShop */
38
        $defaultShop = $manager->getRepository('Shopware\Models\Shop\Shop')->find(1);
39
        /** @var \Shopware\Models\Shop\Shop $fallbackShop */
40
        $fallbackShop = $manager->getRepository('Shopware\Models\Shop\Shop')->find(2);
41
        $defaultShop->setFallback($fallbackShop);
42
        $manager->persist($defaultShop);
43
        $manager->flush();
44
45
        $translator = new \Shopware_Components_Translation();
46
        $translationData = array(
47
            'dispatch_name' => 'Standard delivery',
48
            'dispatch_status_link' => 'http://track.me',
49
            'dispatch_description' => 'Standard delivery description',
50
        );
51
        $translator->write(2, 'config_dispatch', 9, $translationData, true);
52
    }
53
54
    public function setUp()
55
    {
56
        parent::setUp();
57
58
        $this->user = $this->getRandomUser();
59
        $this->user['billingaddress']['country'] = $this->user['billingaddress']['countryID'];
60
        Shopware()->Events()->addListener('Shopware_Modules_Admin_GetUserData_FilterResult', [$this, 'onGetUserData']);
61
62
63
        $this->productFromShop = new ProductFromShop(
64
            $this->getHelper(),
65
            Shopware()->Models(),
66
            new \Shopware\Connect\Gateway\PDO(Shopware()->Db()->getConnection()),
67
            new Logger(Shopware()->Db()),
68
            Shopware()->Container()->get('events')
69
        );
70
    }
71
72
    public function onGetUserData(\Enlight_Event_EventArgs $args)
73
    {
74
        $args->setReturn($this->user);
75
    }
76
77
    public function testBuy()
78
    {
79
        $address = new Address(array(
80
            'firstName' => 'John',
81
            'surName' => 'Doe',
82
            'zip' => '48153',
83
            'street' => 'Eggeroderstraße',
84
            'streetNumber' => '6',
85
            'city' => 'Schöppingen',
86
            'country' => 'DEU',
87
            'email' => '[email protected]',
88
            'phone' => '0000123'
89
        ));
90
        $orderNumber = $this->productFromShop->buy(new Order(array(
91
            'orderShop' => '3',
92
            'localOrderId' => rand(0, 99999),
93
            'deliveryAddress' => $address,
94
            'billingAddress' => $address,
95
            'products' => array(
96
                new OrderItem(array(
97
                    'count' => 1,
98
                    'product' => new Product(array(
99
                        'shopId' => '3',
100
                        'sourceId' => '2',
101
                        'price' => 44.44,
102
                        'purchasePrice' => 33.33,
103
                        'fixedPrice' => false,
104
                        'currency' => 'EUR',
105
                        'availability' => 3,
106
                        'title' => 'Milchschnitte',
107
                        'categories' => array()
108
                    ))
109
                ))
110
            )
111
        )));
112
113
        $order = $this->getOrderByNumber($orderNumber);
114
        $this->assertEquals($orderNumber, $order->getNumber());
115
    }
116
117
    /**
118
     * @param $orderNumber
119
     * @return \Shopware\Models\Order\Order
120
     */
121
    public function getOrderByNumber($orderNumber)
122
    {
123
        return Shopware()->Models()->getRepository('Shopware\Models\Order\Order')->findOneBy(array('number' => $orderNumber));
124
    }
125
126
    public function testCalculateShippingCosts()
127
    {
128
        $mockGateway = $this->getMockBuilder('Shopware\Connect\Gateway\PDO')
129
            ->disableOriginalConstructor()
130
            ->getMock();
131
        $mockGateway->expects($this->any())->method('getShopId')->willReturn(25);
132
133
        $fromShop = new ProductFromShop(
134
            $this->getHelper(),
135
            Shopware()->Models(),
136
            $mockGateway,
137
            new Logger(Shopware()->Db()),
138
            Shopware()->Container()->get('events')
139
        );
140
141
        // hack for static variable $cache in sAdmin::sGetCountry
142
        // undefined index countryId when it's called for the first time
143
        @Shopware()->Modules()->Admin()->sGetCountry(2);
144
145
        $localArticle = $this->getLocalArticle();
146
        $order = $this->createOrder($localArticle);
147
        Shopware()->Db()->executeQuery(
148
            'INSERT INTO `s_order_basket`(`sessionID`, `userID`, `articlename`, `articleID`, `ordernumber`, `quantity`, `price`, `netprice`, `tax_rate`, `currencyFactor`)
149
            VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)',
150
            [
151
                Shopware()->Session()->get('sessionId'),
152
                $this->user['user']['id'],
153
                $localArticle->getName(),
154
                $localArticle->getId(),
155
                $localArticle->getMainDetail()->getNumber(),
156
                1,
157
                49.99,
158
                42.008403361345,
159
                19,
160
                1,
161
            ]
162
        );
163
164
        $request = new \Enlight_Controller_Request_RequestTestCase();
165
        Shopware()->Front()->setRequest($request);
166
167
        Shopware()->Session()->offsetSet('sDispatch', 9);
168
        Shopware()->Session()->offsetSet('sRegister', ['billing' => $this->user['billingaddress']]);
169
170
        $result = $fromShop->calculateShippingCosts($order);
171
172
        $this->assertInstanceOf('Shopware\Connect\Struct\Shipping', $result);
173
        $this->assertTrue($result->isShippable);
174
        $this->assertEquals($result->shippingCosts, 3.28);
175
        $this->assertEquals($result->grossShippingCosts, 3.9);
176
        $this->assertEquals(25, $result->shopId);
177
        $this->assertEquals('Standard Versand', $result->service);
178
    }
179
180
    public function testCalculateShippingCostsWithoutCountry()
181
    {
182
        $order = new Order();
183
        $shippingCosts = $this->productFromShop->calculateShippingCosts($order);
184
        $this->assertFalse($shippingCosts->isShippable);
185
    }
186
187
    /**
188
     * @expectedException        \InvalidArgumentException
189
     * @expectedExceptionMessage ProductList is not allowed to be empty
190
     */
191
    public function testCalculateShippingCostsWithoutOrderItems()
192
    {
193
        $order = $this->createOrder();
194
        $order->orderItems = array();
195
196
        $request = new \Enlight_Controller_Request_RequestTestCase();
197
        Shopware()->Front()->setRequest($request);
198
199
        Shopware()->Session()->offsetSet('sDispatch', 9);
200
201
        $shippingCosts = $this->productFromShop->calculateShippingCosts($order);
202
203
        $this->assertFalse($shippingCosts->isShippable);
204
    }
205
206
    private function createOrder(Article $localArticle = null)
207
    {
208
        if (!$localArticle) {
209
            $localArticle = $this->getLocalArticle();
210
        }
211
212
        $address = new Address(array(
213
            'firstName' => 'John',
214
            'surName' => 'Doe',
215
            'zip' => '48153',
216
            'street' => 'Eggeroderstraße',
217
            'streetNumber' => '6',
218
            'city' => 'Schöppingen',
219
            'country' => 'DEU',
220
            'email' => '[email protected]',
221
            'phone' => '0000123'
222
        ));
223
224
        $localOrderId = rand(0, 99999);
225
226
        $repository = Shopware()->Models()->getRepository('Shopware\CustomModels\Connect\Attribute');
227
        $attribute = $repository->findOneBy(array('articleDetailId' => $localArticle->getMainDetail()->getId(), 'shopId' => null));
228
229
        return new Order(array(
230
            'orderShop' => '3',
231
            'localOrderId' => $localOrderId,
232
            'deliveryAddress' => $address,
233
            'billingAddress' => $address,
234
            'products' => array(
235
                new OrderItem(array(
236
                    'count' => 1,
237
                    'product' => new Product(array(
238
                        'shopId' => '3',
239
                        'sourceId' => $attribute->getSourceId(),
240
                        'price' => 44.44,
241
                        'purchasePrice' => 33.33,
242
                        'fixedPrice' => false,
243
                        'currency' => 'EUR',
244
                        'availability' => 3,
245
                        'title' => 'Milchschnitte',
246
                        'categories' => array()
247
                    ))
248
                ))
249
            )
250
        ));
251
    }
252
253
    /**
254
     * @expectedException \RuntimeException
255
     */
256
    public function testByShouldThrowException()
257
    {
258
        $address = new Address(array());
259
        $this->productFromShop->buy(new Order(array(
260
            'billingAddress' => $address,
261
            'deliveryAddress' => $address,
262
        )));
263
    }
264
265
    public function testOnPerformSync()
266
    {
267
        // reset export_status for all local products
268
        Shopware()->Db()->executeQuery(
269
            'UPDATE s_plugin_connect_items SET export_status = NULL WHERE shop_id IS NULL'
270
        );
271
272
        $time = microtime(true);
273
        $iteration = 0;
274
        $changes = [];
275
276
        // create local product and set revision lower than $since
277
        // that means the product is already exported to Connect
278
        // and his status is "insert".
279
        // When onPerformSync method is called, this product should be with status "synced"
280
        $syncedProduct = $this->getLocalArticle();
281
        Shopware()->Db()->executeQuery(
282
            'UPDATE s_plugin_connect_items SET revision = ?, export_status = ? WHERE source_id = ? AND shop_id IS NULL',
283
            [
284
                sprintf('%.5f%05d', $time, $iteration++),
285
                Attribute::STATUS_INSERT,
286
                $syncedProduct->getId()
287
            ]
288
        );
289
290
        // create local product and set revision lower than $since
291
        // that means the product is already synced with connect.
292
        // current status is "delete".
293
        // When onPerformSync method is called, this product should be with status "NULL"
294
        $deletedProduct = $this->getLocalArticle();
295
        Shopware()->Db()->executeQuery(
296
            'UPDATE s_plugin_connect_items SET revision = ?, export_status = ? WHERE source_id = ? AND shop_id IS NULL',
297
            [
298
                sprintf('%.5f%05d', $time, $iteration++),
299
                Attribute::STATUS_DELETE,
300
                $deletedProduct->getId()
301
            ]
302
        );
303
304
        $since = sprintf('%.5f%05d', $time, $iteration++);
305
306
        // generate 5 changes
307
        // their status is "insert" or "update"
308
        // and it won't be changed, because revision is greater than $since
309
        for ($i = 0; $i < 5; $i++) {
310
            $product = $this->getLocalArticle();
311
            Shopware()->Db()->executeQuery(
312
                'UPDATE s_plugin_connect_items SET export_status = ? WHERE source_id = ? AND shop_id IS NULL',
313
                [
314
                    Attribute::STATUS_INSERT,
315
                    $product->getId()
316
                ]
317
            );
318
            $changes[] = new Insert([
319
                'product' => $product,
320
                'sourceId' => $product->getId(),
321
                'revision' => sprintf('%.5f%05d', $time, $iteration++)
322
            ]);
323
        }
324
325
        $product = $this->getLocalArticle();
326
        Shopware()->Db()->executeQuery(
327
            'UPDATE s_plugin_connect_items SET export_status = ? WHERE source_id = ? AND shop_id IS NULL',
328
            [
329
                Attribute::STATUS_UPDATE,
330
                $product->getId()
331
            ]
332
        );
333
        $changes[] = new Update([
334
            'product' => $product,
335
            'sourceId' => $product->getId(),
336
            'revision' => sprintf('%.5f%05d', $time, $iteration++)
337
        ]);
338
339
        $product = $this->getLocalArticle();
340
        Shopware()->Db()->executeQuery(
341
            'UPDATE s_plugin_connect_items SET export_status = ? WHERE source_id = ? AND shop_id IS NULL',
342
            [
343
                Attribute::STATUS_UPDATE,
344
                $product->getId()
345
            ]
346
        );
347
        $changes[] = new Availability([
348
            'availability' => 5,
349
            'sourceId' => $product->getId(),
350
            'revision' => sprintf('%.5f%05d', $time, $iteration++)
351
        ]);
352
353
        $this->productFromShop->onPerformSync($since, $changes);
354
355
        $result = Shopware()->Db()->fetchAll(
356
            'SELECT source_id
357
                FROM s_plugin_connect_items
358
                WHERE shop_id IS NULL AND export_status = "synced"'
359
        );
360
361
        // verify that only 1 product has status "synced"
362
        $this->assertEquals(1, count($result));
363
        // verify that this product is exactly the same
364
        $this->assertEquals($syncedProduct->getId(), $result[0]['source_id']);
365
366
        // verify that deleted product has export_status NULL
367
        $result = Shopware()->Db()->fetchCol(
368
            'SELECT export_status
369
                FROM s_plugin_connect_items
370
                WHERE source_id = ? AND shop_id IS NULL',
371
            [$deletedProduct->getId()]
372
        );
373
        $this->assertEmpty(reset($result));
374
375
        // verify that each of these 5 changes have
376
        // correct revision in s_plugin_connect_items table
377
        // after onPerformSync
378
        foreach ($changes as $change) {
379
            $result = Shopware()->Db()->fetchCol(
380
                'SELECT revision
381
                FROM s_plugin_connect_items
382
                WHERE source_id = ? AND shop_id IS NULL',
383
                [$change->sourceId]
384
            );
385
386
            $this->assertEquals($change->revision, reset($result));
387
        }
388
    }
389
390
    public function testBuyShouldFireFilterEventWithOrder()
391
    {
392
        $order = $this->createOrder();
393
394
        /** @var \Enlight_Event_EventManager|\PHPUnit_Framework_MockObject_MockObject $eventManagerMock */
395
        $eventManagerMock = $this->createMock(\Enlight_Event_EventManager::class);
396
        $eventManagerMock->method('filter')
397
            ->with('Connect_Components_ProductFromShop_Buy_OrderFilter', $order)
398
            ->willReturn($order);
399
400
        $fromShop = new ProductFromShop(
401
            $this->getHelper(),
402
            Shopware()->Models(),
403
            new \Shopware\Connect\Gateway\PDO(Shopware()->Db()->getConnection()),
404
            new Logger(Shopware()->Db()),
405
            $eventManagerMock
406
        );
407
408
        $result = $fromShop->buy($order);
409
410
        $this->assertStringStartsWith('SC-', $result);
411
    }
412
}