TransitionAssemblerTest::testAssemble()   F
last analyzed

Complexity

Conditions 14
Paths 1152

Size

Total Lines 144
Code Lines 96

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 144
rs 2
cc 14
eloc 96
nc 1152
nop 2

How to fix   Long Method    Complexity   

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 Oro\Bundle\WorkflowBundle\Tests\Unit\Model;
4
5
use Oro\Bundle\WorkflowBundle\Configuration\WorkflowConfiguration;
6
use Oro\Bundle\WorkflowBundle\Form\Type\WorkflowTransitionType;
7
use Oro\Bundle\WorkflowBundle\Model\Transition;
8
use Oro\Bundle\WorkflowBundle\Model\TransitionAssembler;
9
10
use Oro\Component\Action\Action\Configurable as ConfigurableAction;
11
use Oro\Component\Action\Condition\Configurable as ConfigurableCondition;
12
13
class TransitionAssemblerTest extends \PHPUnit_Framework_TestCase
14
{
15
    /**
16
     * @var \PHPUnit_Framework_MockObject_MockObject
17
     */
18
    protected $formOptionsAssembler;
19
20
    /**
21
     * @var \PHPUnit_Framework_MockObject_MockObject
22
     */
23
    protected $conditionFactory;
24
25
    /**
26
     * @var \PHPUnit_Framework_MockObject_MockObject
27
     */
28
    protected $actionFactory;
29
30
    /**
31
     * @var TransitionAssembler
32
     */
33
    protected $assembler;
34
35
    /**
36
     * @var array
37
     */
38
    protected $transitionDefinitions = array(
39
        'empty_definition' => array(),
40
        'with_pre_condition' => array(
41
            'pre_conditions' => array('@true' => null)
42
        ),
43
        'with_condition' => array(
44
            'conditions' => array('@true' => null)
45
        ),
46
        'with_post_actions' => array(
47
            'post_actions' => array('@assign_value' => array('parameters' => array('$attribute', 'first_value')))
48
        ),
49
        'full_definition' => array(
50
            'page_template' => 'Test:Page:template',
51
            'dialog_template' => 'Test:Dialog:template',
52
            'pre_conditions' => array('@true' => null),
53
            'conditions' => array('@true' => null),
54
            'post_actions' => array('@assign_value' => array('parameters' => array('$attribute', 'first_value'))),
55
        )
56
    );
57
58
    protected function setUp()
59
    {
60
        $this->formOptionsAssembler = $this->getMockBuilder('Oro\Bundle\WorkflowBundle\Model\FormOptionsAssembler')
61
            ->disableOriginalConstructor()
62
            ->setMethods(array('assemble'))
63
            ->getMock();
64
65
        $this->conditionFactory = $this->getMockBuilder('Oro\Component\ConfigExpression\ExpressionFactory')
66
            ->disableOriginalConstructor()
67
            ->getMock();
68
        $this->actionFactory = $this->getMockBuilder('Oro\Component\Action\Action\ActionFactory')
69
            ->disableOriginalConstructor()
70
            ->getMock();
71
        $this->assembler = new TransitionAssembler(
72
            $this->formOptionsAssembler,
73
            $this->conditionFactory,
74
            $this->actionFactory
75
        );
76
    }
77
78
    /**
79
     * @expectedException \Oro\Component\Action\Exception\AssemblerException
80
     * @dataProvider missedTransitionDefinitionDataProvider
81
     * @param array $configuration
82
     */
83
    public function testAssembleNoRequiredTransitionDefinitionException($configuration)
84
    {
85
        $this->assembler->assemble($configuration, array(), array(), array());
86
    }
87
88
    public function missedTransitionDefinitionDataProvider()
89
    {
90
        return array(
91
            'no options' => array(
92
                array(
93
                    'name' => array()
94
                )
95
            ),
96
            'no transition_definition' => array(
97
                array(
98
                    'name' => array(
99
                        '' => 'test'
100
                    )
101
                )
102
            )
103
        );
104
    }
105
106
    /**
107
     * @expectedException \Oro\Component\Action\Exception\AssemblerException
108
     * @dataProvider incorrectTransitionDefinitionDataProvider
109
     * @param array $definitions
110
     */
111
    public function testUnknownTransitionDefinitionAssembler($definitions)
112
    {
113
        $configuration = array(
114
            'test' => array(
115
                'transition_definition' => 'unknown'
116
            )
117
        );
118
        $this->assembler->assemble($configuration, $definitions, array(), array());
119
    }
120
121
    public function incorrectTransitionDefinitionDataProvider()
122
    {
123
        return array(
124
            'no definitions' => array(
125
                array()
126
            ),
127
            'definitions as null' => array(
128
                array('some' => null)
129
            ),
130
            'unknown definition' => array(
131
                array('known' => array())
132
            )
133
        );
134
    }
135
136
    /**
137
     * @expectedException \Oro\Component\Action\Exception\AssemblerException
138
     * @dataProvider incorrectStepsDataProvider
139
     * @param array $steps
140
     */
141
    public function testUnknownStepException($steps)
142
    {
143
        $configuration = array(
144
            'test' => array(
145
                'transition_definition' => 'transition_definition',
146
                'label' => 'label',
147
                'step_to' => 'unknown'
148
            )
149
        );
150
        $definitions = array('transition_definition' => array());
151
        $this->assembler->assemble($configuration, $definitions, $steps, array());
152
    }
153
154
    public function incorrectStepsDataProvider()
155
    {
156
        return array(
157
            'no steps' => array(
158
                array()
159
            ),
160
            'unknown step' => array(
161
                array('known' => $this->createStep())
162
            )
163
        );
164
    }
165
166
    /**
167
     * @dataProvider configurationDataProvider
168
     * @param array $configuration
169
     * @param array $transitionDefinition
170
     * @SuppressWarnings(PHPMD.NPathComplexity)
171
     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
172
     */
173
    public function testAssemble(array $configuration, array $transitionDefinition)
174
    {
175
        $steps = array(
176
            'step' => $this->createStep()
177
        );
178
179
        $attributes = array(
180
            'attribute' => $this->createAttribute()
181
        );
182
183
        $expectedCondition      = null;
184
        $expectedPreCondition   = $this->createCondition();
185
        $expectedAction         = null;
186
        $defaultAclPrecondition = array();
187
        $preConditions          = array();
188
189
        if (isset($configuration['acl_resource'])) {
190
            $defaultAclPrecondition = array(
191
                '@acl_granted' => array(
192
                    'parameters' => array($configuration['acl_resource'])
193
                )
194
            );
195
196
            if (isset($configuration['acl_message'])) {
197
                $defaultAclPrecondition['@acl_granted']['message'] = $configuration['acl_message'];
198
            }
199
        }
200
201
        if (isset($transitionDefinition['pre_conditions']) && $defaultAclPrecondition) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $defaultAclPrecondition 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...
202
            $preConditions = array(
203
                '@and' => array(
204
                    $defaultAclPrecondition,
205
                    $transitionDefinition['pre_conditions']
206
                )
207
            );
208
        } elseif (isset($transitionDefinition['pre_conditions'])) {
209
            $preConditions = $transitionDefinition['pre_conditions'];
210
        }
211
212
        $count = 0;
213
214
        if ($preConditions) {
215
            $this->conditionFactory->expects($this->at($count))
216
                ->method('create')
217
                ->with(ConfigurableCondition::ALIAS, $preConditions)
218
                ->will($this->returnValue($expectedPreCondition));
219
            $count++;
220
        }
221
222
        if (array_key_exists('conditions', $transitionDefinition)) {
223
            $expectedCondition = $this->createCondition();
224
            $this->conditionFactory->expects($this->at($count))
225
                ->method('create')
226
                ->with(ConfigurableCondition::ALIAS, $transitionDefinition['conditions'])
227
                ->will($this->returnValue($expectedCondition));
228
        }
229
230
        $actionFactoryCallCount = 0;
231
232
        if (array_key_exists('post_actions', $transitionDefinition)) {
233
            $actionFactoryCallCount++;
234
        }
235
236
        if (array_key_exists('init_actions', $transitionDefinition)) {
237
            $actionFactoryCallCount++;
238
        }
239
240
        if ($actionFactoryCallCount) {
241
            $expectedAction = $this->createAction();
242
            $this->actionFactory->expects($this->exactly($actionFactoryCallCount))
243
                ->method('create')
244
                ->with(ConfigurableAction::ALIAS, $transitionDefinition['post_actions'])
245
                ->will($this->returnValue($this->createAction()));
246
        }
247
248
        $this->formOptionsAssembler->expects($this->once())
249
            ->method('assemble')
250
            ->with(
251
                isset($configuration['form_options']) ? $configuration['form_options'] : array(),
252
                $attributes,
253
                'transition',
254
                'test'
255
            )
256
            ->will($this->returnArgument(0));
257
258
        $transitions = $this->assembler->assemble(
259
            array('test' => $configuration),
260
            $this->transitionDefinitions,
261
            $steps,
262
            $attributes
263
        );
264
265
        $configuration = array_merge(
266
            array(
267
                'is_start' => false,
268
                'form_type' => WorkflowTransitionType::NAME,
269
                'form_options' => array(),
270
                'frontend_options' => array(),
271
            ),
272
            $configuration
273
        );
274
275
        $this->assertInstanceOf('Doctrine\Common\Collections\ArrayCollection', $transitions);
276
        $this->assertCount(1, $transitions);
277
        $this->assertTrue($transitions->containsKey('test'));
278
279
        /** @var Transition $actualTransition */
280
        $actualTransition = $transitions->get('test');
281
        $this->assertEquals('test', $actualTransition->getName(), 'Incorrect name');
282
        $this->assertEquals($steps['step'], $actualTransition->getStepTo(), 'Incorrect step_to');
283
        $this->assertEquals($configuration['label'], $actualTransition->getLabel(), 'Incorrect label');
284
285
        $expectedDisplayType = WorkflowConfiguration::DEFAULT_TRANSITION_DISPLAY_TYPE;
286
287
        if (isset($configuration['display_type'])) {
288
            $expectedDisplayType = $configuration['display_type'];
289
        }
290
291
        $this->assertEquals($expectedDisplayType, $actualTransition->getDisplayType(), 'Incorrect display type');
292
        $this->assertEquals(
293
            $configuration['frontend_options'],
294
            $actualTransition->getFrontendOptions(),
295
            'Incorrect frontend_options'
296
        );
297
        $this->assertEquals($configuration['is_start'], $actualTransition->isStart(), 'Incorrect is_start');
298
        $this->assertEquals($configuration['form_type'], $actualTransition->getFormType(), 'Incorrect form_type');
299
        $this->assertEquals(
300
            $configuration['form_options'],
301
            $actualTransition->getFormOptions(),
302
            'Incorrect form_options'
303
        );
304
305
        $this->assertTemplate('page', $configuration, $actualTransition);
306
        $this->assertTemplate('dialog', $configuration, $actualTransition);
307
308
        if ($preConditions) {
309
            $this->assertEquals($expectedPreCondition, $actualTransition->getPreCondition(), 'Incorrect Precondition');
310
        } else {
311
            $this->assertNull($actualTransition->getPreCondition(), 'Incorrect Precondition');
312
        }
313
314
        $this->assertEquals($expectedCondition, $actualTransition->getCondition(), 'Incorrect condition');
315
        $this->assertEquals($expectedAction, $actualTransition->getPostAction(), 'Incorrect post_action');
316
    }
317
318
    /**
319
     * @param string $templateType
320
     * @param array $configuration
321
     * @param $actualTransition
322
     */
323
    protected function assertTemplate($templateType, $configuration, $actualTransition)
324
    {
325
        $configKey = $templateType . '_template';
326
        $getter    = 'get' . ucfirst($templateType) . 'Template';
327
328
        if (array_key_exists($configKey, $configuration)) {
329
            $this->assertEquals($configuration[$configKey], $actualTransition->$getter());
330
        } else {
331
            $this->assertNull($actualTransition->$getter());
332
        }
333
    }
334
335
    public function configurationDataProvider()
336
    {
337
        return array(
338
            'empty_definition' => array(
339
                'configuration' => array(
340
                    'transition_definition' => 'empty_definition',
341
                    'label' => 'label',
342
                    'step_to' => 'step',
343
                    'form_type' => 'custom_workflow_transition',
344
                    'display_type' => 'page',
345
                    'form_options' => array(
346
                        'attribute_fields' => array(
347
                            'attribute_on_be' => array('type' => 'text')
348
                        )
349
                    ),
350
                    'frontend_options' => array('class' => 'foo', 'icon' => 'bar'),
351
                ),
352
                'transitionDefinition' => $this->transitionDefinitions['empty_definition'],
353
            ),
354
            'with_condition' => array(
355
                'configuration' => array(
356
                    'transition_definition' => 'with_condition',
357
                    'label' => 'label',
358
                    'step_to' => 'step',
359
                ),
360
                'transitionDefinition' => $this->transitionDefinitions['with_condition'],
361
            ),
362
            'with_post_actions' => array(
363
                'configuration' => array(
364
                    'transition_definition' => 'with_post_actions',
365
                    'label' => 'label',
366
                    'step_to' => 'step',
367
                ),
368
                'transitionDefinition' => $this->transitionDefinitions['with_post_actions'],
369
            ),
370
            'full_definition' => array(
371
                'configuration' => array(
372
                    'transition_definition' => 'full_definition',
373
                    'acl_resource' => 'test_acl',
374
                    'acl_message' => 'test acl message',
375
                    'label' => 'label',
376
                    'step_to' => 'step',
377
                ),
378
                'transitionDefinition' => $this->transitionDefinitions['full_definition'],
379
            ),
380
            'start_transition' => array(
381
                'configuration' => array(
382
                    'transition_definition' => 'empty_definition',
383
                    'acl_resource' => 'test_acl',
384
                    'acl_message' => 'test acl message',
385
                    'label' => 'label',
386
                    'step_to' => 'step',
387
                    'is_start' => true,
388
                ),
389
                'transitionDefinition' => $this->transitionDefinitions['empty_definition'],
390
            ),
391
        );
392
    }
393
394
    protected function createStep()
395
    {
396
        return $this->getMockBuilder('Oro\Bundle\WorkflowBundle\Model\Step')
397
            ->disableOriginalConstructor()
398
            ->getMock();
399
    }
400
401
    protected function createAttribute()
402
    {
403
        return $this->getMockBuilder('Oro\Bundle\ActionBundle\Model\Attribute')
404
            ->disableOriginalConstructor()
405
            ->getMock();
406
    }
407
408
    protected function createCondition()
409
    {
410
        return $this->getMockBuilder('Oro\Component\ConfigExpression\ExpressionInterface')
411
            ->getMockForAbstractClass();
412
    }
413
414
    protected function createAction()
415
    {
416
        return $this->getMockBuilder('Oro\Component\Action\Action\ActionInterface')
417
            ->getMockForAbstractClass();
418
    }
419
}
420