Completed
Pull Request — master (#114)
by Bart
02:13
created

MatrixBlockTypeTest   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 203
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 7

Importance

Changes 0
Metric Value
wmc 9
lcom 1
cbo 7
dl 0
loc 203
rs 10
c 0
b 0
f 0

9 Methods

Rating   Name   Duplication   Size   Complexity  
A _before() 0 4 1
A testGetRecordDefinition() 0 11 1
A testSetRecordAttributes() 0 15 1
B testSaveRecord() 0 24 1
A testDeleteRecord() 0 8 1
A provideMatrixBlockTypes() 0 12 1
A getMockMatrixBlockTypeDefinition() 0 14 1
B getMockMatrixBlockType() 0 26 1
A getMockField() 0 12 1
1
<?php
2
3
namespace NerdsAndCompany\Schematic\Converters\Models;
4
5
use Craft;
6
use craft\base\Field as FieldModel;
7
use craft\models\MatrixBlockType as MatrixBlockTypeModel;
8
use craft\models\FieldLayout;
9
use Codeception\Test\Unit;
10
11
/**
12
 * Class MatrixBlockTypeTest.
13
 *
14
 * @author    Nerds & Company
15
 * @copyright Copyright (c) 2015-2017, Nerds & Company
16
 * @license   MIT
17
 *
18
 * @see      http://www.nerds.company
19
 */
20
class MatrixBlockTypeTest extends Unit
21
{
22
    /**
23
     * @var MatrixBlockTypes
24
     */
25
    private $converter;
26
27
    /**
28
     * Set the converter.
29
     *
30
     * @SuppressWarnings(PHPMD.CamelCaseMethodName)
31
     */
32
    protected function _before()
33
    {
34
        $this->converter = new MatrixBlockType();
0 ignored issues
show
Documentation Bug introduced by
It seems like new \NerdsAndCompany\Sch...odels\MatrixBlockType() of type object<NerdsAndCompany\S...Models\MatrixBlockType> is incompatible with the declared type object<NerdsAndCompany\S...odels\MatrixBlockTypes> of property $converter.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
35
    }
36
37
    //==============================================================================================================
38
    //=================================================  TESTS  ====================================================
39
    //==============================================================================================================
40
41
    /**
42
     * @dataProvider provideMatrixBlockTypes
43
     *
44
     * @param MatrixBlockTypeModel $blockType
45
     * @param array                $definition
46
     */
47
    public function testGetRecordDefinition(MatrixBlockTypeModel $blockType, array $definition)
48
    {
49
        Craft::$app->controller->module->modelMapper->expects($this->exactly(1))
50
                                     ->method('export')
51
                                     ->with($blockType->getFieldLayout()->getFields())
52
                                     ->willReturn($definition['fields']);
53
54
        $result = $this->converter->getRecordDefinition($blockType);
55
56
        $this->assertSame($definition, $result);
57
    }
58
59
    /**
60
     * @dataProvider provideMatrixBlockTypes
61
     *
62
     * @param MatrixBlockTypeModel $blockType
63
     * @param array                $definition
64
     * @param array                $defaultAttributes
65
     */
66
    public function testSetRecordAttributes(MatrixBlockTypeModel $blockType, array $definition, array $defaultAttributes)
67
    {
68
        $newMatrixBlockType = $this->getMockBuilder(MatrixBlockTypeModel::class)
69
                                   ->setMethods(['setFieldLayout'])
70
                                   ->getMock();
71
72
        $newMatrixBlockType->expects($this->exactly(0))
73
                           ->method('setFieldLayout');
74
75
        $this->converter->setRecordAttributes($newMatrixBlockType, $definition, $defaultAttributes);
76
77
        $this->assertSame($defaultAttributes['fieldId'], $newMatrixBlockType->fieldId);
0 ignored issues
show
Bug introduced by
Accessing fieldId on the interface PHPUnit\Framework\MockObject\MockObject suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
78
        $this->assertSame($blockType->name, $newMatrixBlockType->name);
0 ignored issues
show
Bug introduced by
Accessing name on the interface PHPUnit\Framework\MockObject\MockObject suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
79
        $this->assertSame($blockType->handle, $newMatrixBlockType->handle);
0 ignored issues
show
Bug introduced by
Accessing handle on the interface PHPUnit\Framework\MockObject\MockObject suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
80
    }
81
82
    /**
83
     * @dataProvider provideMatrixBlockTypes
84
     *
85
     * @param MatrixBlockTypeModel $blockType
86
     * @param array                $definition
87
     */
88
    public function testSaveRecord(MatrixBlockTypeModel $blockType, array $definition)
89
    {
90
        Craft::$app->matrix->expects($this->exactly(1))
91
                           ->method('saveBlockType')
92
                           ->with($blockType, false)
93
                           ->willReturn(true);
94
95
        $context = 'matrixBlockType:'.$blockType->id;
96
        $existingFields = $blockType->getFieldLayout()->getFields();
97
98
        Craft::$app->fields->expects($this->exactly(1))
99
                           ->method('getAllFields')
100
                           ->with($context)
101
                           ->willReturn($existingFields);
102
103
        Craft::$app->controller->module->modelMapper->expects($this->exactly(1))
104
                                     ->method('import')
105
                                     ->with($definition['fields'], $existingFields, ['context' => $context], false)
106
                                     ->willReturn($existingFields);
107
108
        $result = $this->converter->saveRecord($blockType, $definition);
109
110
        $this->assertTrue($result);
111
    }
112
113
    /**
114
     * @dataProvider provideMatrixBlockTypes
115
     *
116
     * @param MatrixBlockTypeModel $blockType
117
     */
118
    public function testDeleteRecord(MatrixBlockTypeModel $blockType)
119
    {
120
        Craft::$app->matrix->expects($this->exactly(1))
121
                           ->method('deleteBlockType')
122
                           ->with($blockType);
123
124
        $this->converter->deleteRecord($blockType);
125
    }
126
127
    //==============================================================================================================
128
    //==============================================  PROVIDERS  ===================================================
129
    //==============================================================================================================
130
131
    /**
132
     * @return array
133
     */
134
    public function provideMatrixBlockTypes()
135
    {
136
        $mockMatrixBlockType = $this->getMockMatrixBlockType(1);
137
138
        return [
139
            'valid blockType' => [
140
                'blockType' => $mockMatrixBlockType,
141
                'definition' => $this->getMockMatrixBlockTypeDefinition($mockMatrixBlockType),
0 ignored issues
show
Documentation introduced by
$mockMatrixBlockType is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<craft\models\MatrixBlockType>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
142
                'defaultAttributes' => ['fieldId' => 1],
143
            ],
144
        ];
145
    }
146
147
    //==============================================================================================================
148
    //================================================  HELPERS  ===================================================
149
    //==============================================================================================================
150
151
    /**
152
     * @param MatrixBlockTypeModel $mockMatrixBlockType
153
     *
154
     * @return array
155
     */
156
    private function getMockMatrixBlockTypeDefinition(MatrixBlockTypeModel $mockMatrixBlockType)
157
    {
158
        return [
159
            'class' => get_class($mockMatrixBlockType),
160
            'attributes' => [
161
                'name' => 'blockTypeName'.$mockMatrixBlockType->id,
162
                'handle' => 'blockTypeHandle'.$mockMatrixBlockType->id,
163
                'sortOrder' => null,
164
            ],
165
            'fields' => [
166
                'fieldDefinition',
167
            ],
168
        ];
169
    }
170
171
    /**
172
     * @param int $blockTypeId
173
     *
174
     * @return Mock|MatrixBlockTypeModel
175
     */
176
    private function getMockMatrixBlockType(int $blockTypeId)
177
    {
178
        $mockMatrixBlockType = $this->getMockBuilder(MatrixBlockTypeModel::class)
179
                              ->setMethods(['getFieldLayout'])
180
                              ->disableOriginalConstructor()
181
                              ->getMock();
182
183
        $mockMatrixBlockType->id = $blockTypeId;
0 ignored issues
show
Bug introduced by
Accessing id on the interface PHPUnit\Framework\MockObject\MockObject suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
184
        $mockMatrixBlockType->fieldLayoutId = $blockTypeId;
0 ignored issues
show
Bug introduced by
Accessing fieldLayoutId on the interface PHPUnit\Framework\MockObject\MockObject suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
185
        $mockMatrixBlockType->handle = 'blockTypeHandle'.$blockTypeId;
0 ignored issues
show
Bug introduced by
Accessing handle on the interface PHPUnit\Framework\MockObject\MockObject suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
186
        $mockMatrixBlockType->name = 'blockTypeName'.$blockTypeId;
0 ignored issues
show
Bug introduced by
Accessing name on the interface PHPUnit\Framework\MockObject\MockObject suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
187
188
        $mockField = $this->getMockField($blockTypeId);
189
190
        $mockFieldLayout = $this->getMockBuilder(FieldLayout::class)->getMock();
191
192
        $mockFieldLayout->expects($this->any())
193
                        ->method('getFields')
194
                        ->willReturn([$mockField]);
195
196
        $mockMatrixBlockType->expects($this->any())
197
                   ->method('getFieldLayout')
198
                   ->willReturn($mockFieldLayout);
199
200
        return $mockMatrixBlockType;
201
    }
202
203
    /**
204
     * Get a mock field.
205
     *
206
     * @param int $fieldId
207
     *
208
     * @return Mock|FieldModel
209
     */
210
    private function getMockField(int $fieldId)
211
    {
212
        $mockField = $this->getMockbuilder(FieldModel::class)
213
                         ->setMethods([])
214
                         ->getMock();
215
216
        $mockField->id = $fieldId;
0 ignored issues
show
Bug introduced by
Accessing id on the interface PHPUnit\Framework\MockObject\MockObject suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
217
        $mockField->handle = 'field'.$fieldId;
0 ignored issues
show
Bug introduced by
Accessing handle on the interface PHPUnit\Framework\MockObject\MockObject suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
218
        $mockField->required = true;
0 ignored issues
show
Bug introduced by
Accessing required on the interface PHPUnit\Framework\MockObject\MockObject suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
219
220
        return $mockField;
221
    }
222
}
223