Completed
Pull Request — master (#114)
by Bart
04:26
created

FieldTest   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 178
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 7

Importance

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

8 Methods

Rating   Name   Duplication   Size   Complexity  
A _before() 0 4 1
A testGetRecordDefinition() 0 6 1
A testSaveRecord() 0 19 2
A testDeleteRecord() 0 8 1
A provideFields() 0 23 1
A getMockFieldDefinition() 0 18 1
A getMockField() 0 18 1
A getMockFieldGroup() 0 11 1
1
<?php
2
3
namespace NerdsAndCompany\Schematic\Converters\Base;
4
5
use Craft;
6
use craft\base\Field as FieldModel;
7
use Codeception\Test\Unit;
8
9
/**
10
 * Class FieldTest.
11
 *
12
 * @author    Nerds & Company
13
 * @copyright Copyright (c) 2015-2017, Nerds & Company
14
 * @license   MIT
15
 *
16
 * @see      http://www.nerds.company
17
 */
18
class FieldTest extends Unit
19
{
20
    /**
21
     * @var Fields
22
     */
23
    private $converter;
24
25
    /**
26
     * Set the converter.
27
     *
28
     * @SuppressWarnings(PHPMD.CamelCaseMethodName)
29
     */
30
    protected function _before()
31
    {
32
        $this->converter = new Field();
0 ignored issues
show
Documentation Bug introduced by
It seems like new \NerdsAndCompany\Sch...Converters\Base\Field() of type object<NerdsAndCompany\S...\Converters\Base\Field> is incompatible with the declared type object<NerdsAndCompany\S...Converters\Base\Fields> 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...
33
    }
34
35
    //==============================================================================================================
36
    //=================================================  TESTS  ====================================================
37
    //==============================================================================================================
38
39
    /**
40
     * @dataProvider provideFields
41
     *
42
     * @param FieldModel $field
43
     * @param array      $definition
44
     */
45
    public function testGetRecordDefinition(FieldModel $field, array $definition)
46
    {
47
        $result = $this->converter->getRecordDefinition($field);
48
49
        $this->assertSame($definition, $result);
50
    }
51
52
    /**
53
     * @dataProvider provideFields
54
     *
55
     * @param FieldModel $field
56
     * @param array      $definition
57
     * @param string     $groupStatus existing|new|invalid
58
     */
59
    public function testSaveRecord(FieldModel $field, array $definition, string $groupStatus)
60
    {
61
        Craft::$app->fields->expects($this->exactly(1))
62
                            ->method('getAllGroups')
63
                            ->willReturn([$this->getMockFieldGroup(1)]);
64
65
        Craft::$app->fields->expects($this->exactly('existing' == $groupStatus ? 0 : 1))
66
                          ->method('saveGroup')
67
                          ->willReturn('invalid' !== $groupStatus);
68
69
        Craft::$app->fields->expects($this->exactly(1))
70
                          ->method('saveField')
71
                          ->with($field)
72
                          ->willReturn(true);
73
74
        $result = $this->converter->saveRecord($field, $definition);
75
76
        $this->assertTrue($result);
77
    }
78
79
    /**
80
     * @dataProvider provideFields
81
     *
82
     * @param FieldModel $field
83
     */
84
    public function testDeleteRecord(FieldModel $field)
85
    {
86
        Craft::$app->fields->expects($this->exactly(1))
87
                            ->method('deleteField')
88
                            ->with($field);
89
90
        $this->converter->deleteRecord($field);
91
    }
92
93
    //==============================================================================================================
94
    //==============================================  PROVIDERS  ===================================================
95
    //==============================================================================================================
96
97
    /**
98
     * @return array
99
     */
100
    public function provideFields()
101
    {
102
        $mockField1 = $this->getMockField(1, 1);
103
        $mockField2 = $this->getMockField(1, 2);
104
105
        return [
106
            'valid field existing group' => [
107
                'field' => $mockField1,
108
                'definition' => $this->getMockFieldDefinition($mockField1),
0 ignored issues
show
Documentation introduced by
$mockField1 is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<craft\base\Field>.

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...
109
                'groupStatus' => 'existing',
110
            ],
111
            'valid field new group' => [
112
                'field' => $mockField2,
113
                'definition' => $this->getMockFieldDefinition($mockField2),
0 ignored issues
show
Documentation introduced by
$mockField2 is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<craft\base\Field>.

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...
114
                'groupStatus' => 'new',
115
            ],
116
            'valid field invalid group' => [
117
                'field' => $mockField2,
118
                'definition' => $this->getMockFieldDefinition($mockField2),
0 ignored issues
show
Documentation introduced by
$mockField2 is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<craft\base\Field>.

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...
119
                'groupStatus' => 'invalid',
120
            ],
121
        ];
122
    }
123
124
    //==============================================================================================================
125
    //================================================  HELPERS  ===================================================
126
    //==============================================================================================================
127
128
    /**
129
     * @param FieldModel $mockField
130
     *
131
     * @return array
132
     */
133
    private function getMockFieldDefinition(FieldModel $mockField)
134
    {
135
        return [
136
            'class' => get_class($mockField),
137
            'attributes' => [
138
                'name' => 'fieldName'.$mockField->id,
139
                'handle' => 'fieldHandle'.$mockField->id,
140
                'instructions' => null,
141
                'translationMethod' => 'none',
142
                'translationKeyFormat' => null,
143
                'oldHandle' => null,
144
                'columnPrefix' => null,
145
                'required' => false,
146
                'sortOrder' => null,
147
            ],
148
            'group' => $mockField->group->name,
149
        ];
150
    }
151
152
    /**
153
     * @param int $fieldId
154
     * @param int $groupId
155
     *
156
     * @return Mock|FieldModel
157
     */
158
    private function getMockField(int $fieldId, int $groupId)
159
    {
160
        $mockField = $this->getMockBuilder(FieldModel::class)
161
                           ->setMethods(['getGroup'])
162
                           ->disableOriginalConstructor()
163
                           ->getMock();
164
165
        $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...
166
        $mockField->groupId = $fieldId;
0 ignored issues
show
Bug introduced by
Accessing groupId 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...
167
        $mockField->handle = 'fieldHandle'.$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...
168
        $mockField->name = 'fieldName'.$fieldId;
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...
169
170
        $mockField->expects($this->any())
171
                 ->method('getGroup')
172
                 ->willReturn($this->getMockFieldGroup($groupId));
173
174
        return $mockField;
175
    }
176
177
    /**
178
     * Get a mock field group.
179
     *
180
     * @param int $groupId
181
     *
182
     * @return Mock|FieldGroup
183
     */
184
    private function getMockFieldGroup(int $groupId)
185
    {
186
        $mockGroup = $this->getMockBuilder(FieldGroup::class)
187
                        ->disableOriginalConstructor()
188
                        ->getmock();
189
190
        $mockGroup->id = $groupId;
191
        $mockGroup->name = 'fieldGroup'.$groupId;
192
193
        return $mockGroup;
194
    }
195
}
196