Completed
Push — master ( e32eeb...714cda )
by
unknown
89:50 queued 46:29
created

OperationTest   A

Complexity

Total Complexity 19

Size/Duplication

Total Lines 559
Duplicated Lines 5.72 %

Coupling/Cohesion

Components 1
Dependencies 9
Metric Value
wmc 19
lcom 1
cbo 9
dl 32
loc 559
rs 10

16 Methods

Rating   Name   Duplication   Size   Complexity  
A testIsEnabled() 0 8 1
A testGetDefinition() 0 4 1
A testInit() 0 22 1
B setUp() 0 32 1
A testGetName() 0 8 1
A testExecute() 0 49 3
A executeProvider() 0 55 1
A testIsAvailable() 0 18 1
B isAvailableProvider() 0 150 1
B testGetFormOptions() 0 29 2
A testHasForm() 0 7 1
A hasFormProvider() 0 17 1
A getFormOptionsDataProvider() 0 13 1
A createAction() 15 15 1
A createCondition() 17 17 1
A testGetAttributeManager() 0 23 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
3
namespace Oro\Bundle\ActionBundle\Tests\Unit\Model;
4
5
use Doctrine\Common\Collections\ArrayCollection;
6
7
use Oro\Bundle\ActionBundle\Model\ActionData;
8
use Oro\Bundle\ActionBundle\Model\Assembler\AttributeAssembler;
9
use Oro\Bundle\ActionBundle\Model\Assembler\FormOptionsAssembler;
10
use Oro\Bundle\ActionBundle\Model\Attribute;
11
use Oro\Bundle\ActionBundle\Model\Operation;
12
use Oro\Bundle\ActionBundle\Model\OperationDefinition;
13
14
use Oro\Component\Action\Action\ActionFactory;
15
use Oro\Component\Action\Action\ActionInterface;
16
use Oro\Component\Action\Condition\Configurable as ConfigurableCondition;
17
use Oro\Component\ConfigExpression\ExpressionFactory;
18
19
/**
20
 * @SuppressWarnings(PHPMD.TooManyMethods)
21
 */
22
class OperationTest extends \PHPUnit_Framework_TestCase
23
{
24
    /** @var \PHPUnit_Framework_MockObject_MockObject|OperationDefinition */
25
    protected $definition;
26
27
    /** @var \PHPUnit_Framework_MockObject_MockObject|ActionFactory */
28
    protected $actionFactory;
29
30
    /** @var \PHPUnit_Framework_MockObject_MockObject|ExpressionFactory */
31
    protected $conditionFactory;
32
33
    /** @var \PHPUnit_Framework_MockObject_MockObject|AttributeAssembler */
34
    protected $attributeAssembler;
35
36
    /** @var \PHPUnit_Framework_MockObject_MockObject|FormOptionsAssembler */
37
    protected $formOptionsAssembler;
38
39
    /** @var Operation */
40
    protected $operation;
41
42
    /** @var ActionData */
43
    protected $data;
44
45
    protected function setUp()
46
    {
47
        $this->definition = $this->getMockBuilder('Oro\Bundle\ActionBundle\Model\OperationDefinition')
48
            ->disableOriginalConstructor()
49
            ->getMock();
50
51
        $this->actionFactory = $this->getMockBuilder('Oro\Component\Action\Action\ActionFactory')
52
            ->disableOriginalConstructor()
53
            ->getMock();
54
55
        $this->conditionFactory = $this->getMockBuilder('Oro\Component\ConfigExpression\ExpressionFactory')
56
            ->disableOriginalConstructor()
57
            ->getMock();
58
59
        $this->attributeAssembler = $this->getMockBuilder('Oro\Bundle\ActionBundle\Model\Assembler\AttributeAssembler')
60
            ->disableOriginalConstructor()
61
            ->getMock();
62
63
        $this->formOptionsAssembler = $this->getMockBuilder(
64
            'Oro\Bundle\ActionBundle\Model\Assembler\FormOptionsAssembler'
65
        )->disableOriginalConstructor()->getMock();
66
67
        $this->operation = new Operation(
68
            $this->actionFactory,
69
            $this->conditionFactory,
70
            $this->attributeAssembler,
71
            $this->formOptionsAssembler,
72
            $this->definition
73
        );
74
75
        $this->data = new ActionData();
76
    }
77
78
    public function testGetName()
79
    {
80
        $this->definition->expects($this->once())
81
            ->method('getName')
82
            ->willReturn('test name');
83
84
        $this->assertEquals('test name', $this->operation->getName());
85
    }
86
87
    public function testIsEnabled()
88
    {
89
        $this->definition->expects($this->once())
90
            ->method('isEnabled')
91
            ->willReturn(true);
92
93
        $this->assertEquals(true, $this->operation->isEnabled());
94
    }
95
96
    public function testGetDefinition()
97
    {
98
        $this->assertInstanceOf('Oro\Bundle\ActionBundle\Model\OperationDefinition', $this->operation->getDefinition());
99
    }
100
101
    public function testInit()
102
    {
103
        $config = [
104
            ['form_init', ['form_init']],
105
        ];
106
107
        $actions = [
108
            'form_init' => $this->createAction($this->once(), $this->data),
109
        ];
110
111
        $this->definition->expects($this->any())
112
            ->method('getActions')
113
            ->willReturnMap($config);
114
115
        $this->actionFactory->expects($this->any())
116
            ->method('create')
117
            ->willReturnCallback(function ($type, $config) use ($actions) {
118
                return $actions[$config[0]];
119
            });
120
121
        $this->operation->init($this->data);
122
    }
123
124
    /**
125
     * @param ActionData $data
126
     * @param array $config
127
     * @param array $actions
128
     * @param array $conditions
129
     * @param string $operationName
130
     * @param string $exceptionMessage
131
     *
132
     * @dataProvider executeProvider
133
     */
134
    public function testExecute(
135
        ActionData $data,
136
        array $config,
137
        array $actions,
138
        array $conditions,
139
        $operationName,
140
        $exceptionMessage = ''
141
    ) {
142
        $this->definition->expects($this->any())->method('getName')->willReturn($operationName);
143
        $this->definition->expects($this->any())->method('getConditions')->will($this->returnValueMap($config));
144
145
        $this->definition->expects($this->any())
146
            ->method('getActions')
147
            ->willReturnCallback(function ($name) {
148
                return [$name];
149
            });
150
151
        $this->actionFactory->expects($this->any())
152
            ->method('create')
153
            ->willReturnCallback(function ($type, $config) use ($actions) {
154
                return $actions[$config[0]];
155
            });
156
157
        $this->conditionFactory->expects($this->any())
158
            ->method('create')
159
            ->willReturnCallback(function ($type, $config) use ($conditions) {
160
                return $conditions[$config[0]];
161
            });
162
163
        if ($exceptionMessage) {
164
            $this->setExpectedException(
165
                'Oro\Bundle\ActionBundle\Exception\ForbiddenOperationException',
166
                $exceptionMessage
167
            );
168
        }
169
170
        $errors = new ArrayCollection();
171
172
        $this->assertArrayNotHasKey('errors', $data);
173
174
        $this->operation->execute($data, $errors);
175
176
        $this->assertEmpty($errors->toArray());
177
178
        if ($exceptionMessage) {
179
            $this->assertArrayHasKey('errors', $data);
180
            $this->assertSame($errors, $data['errors']);
181
        }
182
    }
183
184
    /**
185
     * @return array
186
     */
187
    public function executeProvider()
188
    {
189
        $data = new ActionData();
190
191
        $config = [
192
            ['preactions', ['preactions']],
193
            ['actions', ['actions']],
194
            ['preconditions', ['preconditions']],
195
            ['conditions', ['conditions']],
196
        ];
197
198
        return [
199
            '!isPreConditionAllowed' => [
200
                'data' => $data,
201
                'config' => $config,
202
                'actions' => [
203
                    'preactions' => $this->createAction($this->once(), $data),
204
                    'actions' => $this->createAction($this->never(), $data),
205
                ],
206
                'conditions' => [
207
                    'preconditions' => $this->createCondition($this->once(), $data, false),
208
                    'conditions' => $this->createCondition($this->never(), $data, true),
209
                ],
210
                'operationName' => 'TestName1',
211
                'exception' => 'Operation "TestName1" is not allowed.'
212
            ],
213
            '!isConditionAllowed' => [
214
                'data' => $data,
215
                'config' => $config,
216
                'actions' => [
217
                    'preactions' => $this->createAction($this->once(), $data),
218
                    'actions' => $this->createAction($this->never(), $data),
219
                ],
220
                'conditions' => [
221
                    'preconditions' => $this->createCondition($this->once(), $data, true),
222
                    'conditions' => $this->createCondition($this->once(), $data, false),
223
                ],
224
                'operationName' => 'TestName2',
225
                'exception' => 'Operation "TestName2" is not allowed.'
226
            ],
227
            'isAllowed' => [
228
                'data' => $data,
229
                'config' => $config,
230
                'actions' => [
231
                    'preactions' => $this->createAction($this->once(), $data),
232
                    'actions' => $this->createAction($this->once(), $data),
233
                ],
234
                'conditions' => [
235
                    'preconditions' => $this->createCondition($this->once(), $data, true),
236
                    'conditions' => $this->createCondition($this->once(), $data, true),
237
                ],
238
                'operationName' => 'TestName3',
239
            ],
240
        ];
241
    }
242
243
    /**
244
     * @param array $inputData
245
     * @param array $expectedData
246
     *
247
     * @dataProvider isAvailableProvider
248
     */
249
    public function testIsAvailable(array $inputData, array $expectedData)
250
    {
251
        $this->definition->expects($this->any())
252
            ->method('getConditions')
253
            ->will($this->returnValueMap($inputData['config']['conditions']));
254
255
        $this->definition->expects($this->any())
256
            ->method('getFormOptions')
257
            ->willReturn($inputData['config']['form_options']);
258
259
        $this->conditionFactory->expects($expectedData['conditionFactory'])
260
            ->method('create')
261
            ->willReturnCallback(function ($type, $config) use ($inputData) {
262
                return $inputData['conditions'][$config[0]];
263
            });
264
265
        $this->assertEquals($expectedData['available'], $this->operation->isAvailable($inputData['data']));
266
    }
267
268
    /**
269
     * @return array
270
     *
271
     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
272
     */
273
    public function isAvailableProvider()
274
    {
275
        $data = new ActionData();
276
277
        return [
278
            'no conditions' => [
279
                'input' => [
280
                    'data' => $data,
281
                    'config' => [
282
                        'conditions' => [],
283
                        'form_options' => [],
284
                    ],
285
                ],
286
                'expected' => [
287
                    'conditionFactory' => $this->never(),
288
                    'available' => true,
289
                    'errors' => [],
290
                ],
291
            ],
292
            '!isPreConditionAllowed' => [
293
                'input' => [
294
                    'data' => $data,
295
                    'config' => [
296
                        'conditions' => [
297
                            ['preconditions', ['preconditions']],
298
                            ['conditions', ['conditions']],
299
                        ],
300
                        'form_options' => [],
301
                    ],
302
                    'conditions' => [
303
                        'preconditions' => $this->createCondition($this->once(), $data, false),
304
                        'conditions' => $this->createCondition($this->never(), $data, true),
305
                    ],
306
                ],
307
                'expected' => [
308
                    'conditionFactory' => $this->exactly(1),
309
                    'available' => false,
310
                ],
311
            ],
312
            '!isConditionAllowed' => [
313
                'input' => [
314
                    'data' => $data,
315
                    'config' => [
316
                        'conditions' => [
317
                            ['preconditions', ['preconditions']],
318
                            ['conditions', ['conditions']],
319
                        ],
320
                        'form_options' => [],
321
                    ],
322
                    'conditions' => [
323
                        'preconditions' => $this->createCondition($this->once(), $data, true),
324
                        'conditions' => $this->createCondition($this->once(), $data, false),
325
                    ],
326
                ],
327
                'expected' => [
328
                    'conditionFactory' => $this->exactly(2),
329
                    'available' => false,
330
                    'errors' => ['error3', 'error4'],
331
                ],
332
            ],
333
            'allowed' => [
334
                'input' => [
335
                    'data' => $data,
336
                    'config' => [
337
                        'conditions' => [
338
                            ['preconditions', ['preconditions']],
339
                            ['conditions', ['conditions']],
340
                        ],
341
                        'form_options' => [],
342
                    ],
343
                    'conditions' => [
344
                        'preconditions' => $this->createCondition($this->once(), $data, true),
345
                        'conditions' => $this->createCondition($this->once(), $data, true),
346
                    ],
347
                ],
348
                'expected' => [
349
                    'conditionFactory' => $this->exactly(2),
350
                    'available' => true,
351
                    'errors' => [],
352
                ],
353
            ],
354
            'hasForm and no conditions' => [
355
                'input' => [
356
                    'data' => $data,
357
                    'config' => [
358
                        'conditions' => [],
359
                        'form_options' => [
360
                            'attribute_fields' => [
361
                                'attribute1' => [],
362
                            ],
363
                        ],
364
                    ],
365
                ],
366
                'expected' => [
367
                    'conditionFactory' => $this->never(),
368
                    'available' => true,
369
                    'errors' => [],
370
                ],
371
            ],
372
            'hasForm and !isPreConditionAllowed' => [
373
                'input' => [
374
                    'data' => $data,
375
                    'config' => [
376
                        'conditions' => [
377
                            ['preconditions', ['preconditions']],
378
                            ['conditions', ['conditions']],
379
                        ],
380
                        'form_options' => [
381
                            'attribute_fields' => [
382
                                'attribute2' => [],
383
                            ],
384
                        ],
385
                    ],
386
                    'conditions' => [
387
                        'preconditions' => $this->createCondition($this->once(), $data, false),
388
                        'conditions' => $this->createCondition($this->never(), $data, true),
389
                    ],
390
                ],
391
                'expected' => [
392
                    'conditionFactory' => $this->exactly(1),
393
                    'available' => false,
394
                ],
395
            ],
396
            'hasForm and allowed' => [
397
                'input' => [
398
                    'data' => $data,
399
                    'config' => [
400
                        'conditions' => [
401
                            ['preconditions', ['preconditions']],
402
                            ['conditions', ['conditions']],
403
                        ],
404
                        'form_options' => [
405
                            'attribute_fields' => [
406
                                'attribute3' => [],
407
                            ],
408
                        ],
409
                    ],
410
                    'conditions' => [
411
                        'preconditions' => $this->createCondition($this->once(), $data, true),
412
                        'conditions' => $this->createCondition($this->never(), $data, true),
413
                    ],
414
                ],
415
                'expected' => [
416
                    'conditionFactory' => $this->exactly(1),
417
                    'available' => true,
418
                    'errors' => [],
419
                ],
420
            ],
421
        ];
422
    }
423
424
    /**
425
     * @param array $input
426
     * @param array $expected
427
     *
428
     * @dataProvider getFormOptionsDataProvider
429
     */
430
    public function testGetFormOptions(array $input, array $expected)
431
    {
432
        $this->definition->expects($this->once())
433
            ->method('getFormOptions')
434
            ->willReturn($input);
435
436
        if ($input) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $input of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
437
            $attributes = ['attribute' => ['label' => 'attr_label']];
438
439
            $this->definition->expects($this->once())
440
                ->method('getAttributes')
441
                ->willReturn($attributes);
442
443
            $attribute = new Attribute();
444
            $attribute->setName('test_attr');
445
446
            $this->attributeAssembler->expects($this->once())
447
                ->method('assemble')
448
                ->with($this->data, $attributes)
449
                ->willReturn(new ArrayCollection(['test_attr' => $attribute]));
450
451
            $this->formOptionsAssembler->expects($this->once())
452
                ->method('assemble')
453
                ->with($input, new ArrayCollection(['test_attr' => $attribute]))
454
                ->willReturn($expected);
455
        }
456
457
        $this->assertEquals($expected, $this->operation->getFormOptions($this->data));
458
    }
459
460
    /**
461
     * @param array $input
462
     * @param bool $expected
463
     *
464
     * @dataProvider hasFormProvider
465
     */
466
    public function testHasForm(array $input, $expected)
467
    {
468
        $this->definition->expects($this->once())
469
            ->method('getFormOptions')
470
            ->willReturn($input);
471
        $this->assertEquals($expected, $this->operation->hasForm());
472
    }
473
474
    /**
475
     * @return array
476
     */
477
    public function hasFormProvider()
478
    {
479
        return [
480
            'empty' => [
481
                'input' => [],
482
                'expected' => false,
483
            ],
484
            'empty attribute_fields' => [
485
                'input' => ['attribute_fields' => []],
486
                'expected' => false,
487
            ],
488
            'filled' => [
489
                'input' => ['attribute_fields' => ['attribute' => []]],
490
                'expected' => true,
491
            ],
492
        ];
493
    }
494
495
    /**
496
     * @return array
497
     */
498
    public function getFormOptionsDataProvider()
499
    {
500
        return [
501
            'empty' => [
502
                'input' => [],
503
                'expected' => [],
504
            ],
505
            'filled' => [
506
                'input' => ['attribute_fields' => ['attribute' => []]],
507
                'expected' => ['attribute_fields' => ['attribute' => []]],
508
            ],
509
        ];
510
    }
511
512
    /**
513
     * @param \PHPUnit_Framework_MockObject_Matcher_InvokedCount $expects
514
     * @param ActionData $data
515
     * @return ActionInterface|\PHPUnit_Framework_MockObject_MockObject
516
     */
517 View Code Duplication
    protected function createAction(
518
        \PHPUnit_Framework_MockObject_Matcher_InvokedCount $expects,
519
        ActionData $data
520
    ) {
521
        /* @var $action ActionInterface|\PHPUnit_Framework_MockObject_MockObject */
522
        $action = $this->getMockBuilder('Oro\Component\Action\Action\ActionInterface')
523
            ->disableOriginalConstructor()
524
            ->getMock();
525
526
        $action->expects($expects)
527
            ->method('execute')
528
            ->with($data);
529
530
        return $action;
531
    }
532
533
    /**
534
     * @param \PHPUnit_Framework_MockObject_Matcher_InvokedCount $expects
535
     * @param ActionData $data
536
     * @param bool $returnValue
537
     * @return ConfigurableCondition|\PHPUnit_Framework_MockObject_MockObject
538
     */
539 View Code Duplication
    protected function createCondition(
540
        \PHPUnit_Framework_MockObject_Matcher_InvokedCount $expects,
541
        ActionData $data,
542
        $returnValue
543
    ) {
544
        /* @var $condition ConfigurableCondition|\PHPUnit_Framework_MockObject_MockObject */
545
        $condition = $this->getMockBuilder('Oro\Component\Action\Condition\Configurable')
546
            ->disableOriginalConstructor()
547
            ->getMock();
548
549
        $condition->expects($expects)
550
            ->method('evaluate')
551
            ->with($data)
552
            ->willReturn($returnValue);
553
554
        return $condition;
555
    }
556
557
    public function testGetAttributeManager()
558
    {
559
        $attributes = ['attribute' => ['label' => 'attr_label']];
560
561
        $this->definition->expects($this->once())
562
            ->method('getAttributes')
563
            ->willReturn($attributes);
564
565
        $this->data['data'] = new \stdClass();
566
567
        $attribute = new Attribute();
568
        $attribute->setName('test_attr');
569
570
        $this->attributeAssembler->expects($this->once())
571
            ->method('assemble')
572
            ->with($this->data, $attributes)
573
            ->willReturn(new ArrayCollection([$attribute]));
574
575
        $attributeManager = $this->operation->getAttributeManager($this->data);
576
577
        $this->assertInstanceOf('Oro\Bundle\ActionBundle\Model\AttributeManager', $attributeManager);
578
        $this->assertEquals(new ArrayCollection(['test_attr' => $attribute]), $attributeManager->getAttributes());
579
    }
580
}
581