Completed
Pull Request — master (#114)
by Bart
02:24 queued 48s
created

GlobalSetsTest::getMockSite()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 9
rs 9.6666
c 0
b 0
f 0
cc 1
eloc 5
nc 1
nop 1
1
<?php
2
3
namespace NerdsAndCompany\Schematic\Converters\Elements;
4
5
use Craft;
6
use craft\elements\GlobalSet as GlobalSetElement;
7
use craft\base\Field;
8
use craft\models\FieldLayout;
9
use craft\models\Site;
10
use craft\services\Fields;
11
use Codeception\Test\Unit;
12
13
/**
14
 * Class GlobalSetsTest.
15
 *
16
 * @author    Nerds & Company
17
 * @copyright Copyright (c) 2015-2017, Nerds & Company
18
 * @license   MIT
19
 *
20
 * @see      http://www.nerds.company
21
 */
22
class GlobalSetsTest extends Unit
23
{
24
    /**
25
     * @var GlobalSets
26
     */
27
    private $converter;
28
29
    /**
30
     * Set the converter.
31
     *
32
     * @SuppressWarnings(PHPMD.CamelCaseMethodName)
33
     */
34
    protected function _before()
35
    {
36
        $this->converter = new GlobalSet();
0 ignored issues
show
Documentation Bug introduced by
It seems like new \NerdsAndCompany\Sch...rs\Elements\GlobalSet() of type object<NerdsAndCompany\S...ers\Elements\GlobalSet> is incompatible with the declared type object<NerdsAndCompany\S...rs\Elements\GlobalSets> 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...
37
    }
38
39
    //==============================================================================================================
40
    //=================================================  TESTS  ====================================================
41
    //==============================================================================================================
42
43
    /**
44
     * @dataProvider provideGlobalSets
45
     *
46
     * @param GlobalSetElement $set
47
     * @param array            $definition
48
     */
49
    public function testGetRecordDefinition(GlobalSetElement $set, array $definition)
50
    {
51
        $result = $this->converter->getRecordDefinition($set);
52
53
        $this->assertSame($definition, $result);
54
    }
55
56
    /**
57
     * @dataProvider provideGlobalSets
58
     *
59
     * @param GlobalSetElement $set
60
     * @param array            $definition
61
     * @param bool             $valid
62
     */
63
    public function testSaveRecord(GlobalSetElement $set, array $definition, bool $valid)
64
    {
65
        Craft::$app->sites->expects($this->any())
66
                ->method('getSiteByHandle')
67
                ->willReturnMap([
68
                  ['default', $this->getMockSite()],
69
                  ['invalid', null],
70
                ]);
71
72
        Craft::$app->globals->expects($this->exactly($valid ? 1 : 0))
73
                            ->method('saveSet')
74
                            ->with($set)
75
                            ->willReturn(true);
76
77
        $result = $this->converter->saveRecord($set, $definition);
78
79
        $this->assertSame($valid, $result);
80
    }
81
82
    /**
83
     * @dataProvider provideGlobalSets
84
     *
85
     * @param GlobalSetElement $set
86
     */
87
    public function testDeleteRecord(GlobalSetElement $set)
88
    {
89
        Craft::$app->elements->expects($this->exactly(1))
90
                             ->method('deleteElementById')
91
                             ->with($set->id);
92
93
        $this->converter->deleteRecord($set);
94
    }
95
96
    //==============================================================================================================
97
    //==============================================  PROVIDERS  ===================================================
98
    //==============================================================================================================
99
100
    /**
101
     * @return array
102
     */
103
    public function provideGlobalSets()
104
    {
105
        $mockGlobalSet1 = $this->getMockGlobalSet(1);
106
        $mockGlobalSet2 = $this->getMockGlobalSet(1, 'invalid');
107
108
        return [
109
            'Valid set' => [
110
                'set' => $mockGlobalSet1,
111
                'definition' => $this->getMockGlobalSetDefinition($mockGlobalSet1),
0 ignored issues
show
Documentation introduced by
$mockGlobalSet1 is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<craft\elements\GlobalSet>.

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...
112
                'validSave' => true,
113
            ],
114
            'Invalid set' => [
115
                'set' => $mockGlobalSet2,
116
                'definition' => $this->getMockGlobalSetDefinition($mockGlobalSet2),
0 ignored issues
show
Documentation introduced by
$mockGlobalSet2 is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<craft\elements\GlobalSet>.

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...
117
                'validSave' => false,
118
            ],
119
        ];
120
    }
121
122
    //==============================================================================================================
123
    //================================================  HELPERS  ===================================================
124
    //==============================================================================================================
125
126
    /**
127
     * @param GlobalSet $mockGlobalSet
128
     *
129
     * @return array
130
     */
131
    private function getMockGlobalSetDefinition(GlobalSetElement $mockGlobalSet)
132
    {
133
        $fieldDefs = [];
134
        foreach ($mockGlobalSet->getFieldLayout()->getFields() as $field) {
135
            $fieldDefs[$field->handle] = $field->required;
136
        }
137
138
        return [
139
            'class' => get_class($mockGlobalSet),
140
            'attributes' => [
141
                'name' => $mockGlobalSet->name,
142
                'handle' => $mockGlobalSet->handle,
143
                'enabled' => true,
144
                'archived' => false,
145
                'enabledForSite' => true,
146
                'title' => null,
147
                'slug' => null,
148
                'uri' => null,
149
            ],
150
            'fieldLayout' => [
151
                'fields' => $fieldDefs,
152
            ],
153
            'site' => $mockGlobalSet->getSite()->handle,
154
        ];
155
    }
156
157
    /**
158
     * @param int    $setId
159
     * @param string $siteHandle
160
     *
161
     * @return Mock|GlobalSet
162
     */
163
    private function getMockGlobalSet(int $setId, string $siteHandle = 'default')
164
    {
165
        $mockSet = $this->getMockBuilder(GlobalSetElement::class)
166
                                    ->setMethods(['__isset', 'getSite', 'getFieldLayout', 'fieldByHandle', 'behaviors'])
167
                                    ->disableOriginalConstructor()
168
                                    ->getMock();
169
170
        $mockSet->id = $setId;
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...
171
        $mockSet->fieldLayoutId = $setId;
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...
172
        $mockSet->handle = 'setHandle'.$setId;
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...
173
        $mockSet->name = 'setName'.$setId;
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...
174
175
        $mockSet->expects($this->any())
176
                ->method('behaviors')
177
                ->willReturn([]);
178
179
        $mockSet->expects($this->any())
180
                ->method('getSite')
181
                ->willReturn($this->getMockSite($siteHandle));
182
183
        $mockField = $this->getMockbuilder(Field::class)->getMock();
184
        $mockField->id = $setId;
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...
185
        $mockField->handle = 'field'.$setId;
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
        $mockField->required = false;
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...
187
188
        $mockFieldLayout = $this->getMockBuilder(FieldLayout::class)->getMock();
189
190
        $mockFieldLayout->expects($this->any())
191
                        ->method('getFields')
192
                        ->willReturn([$mockField]);
193
194
        $mockSet->expects($this->any())
195
                  ->method('getFieldLayout')
196
                  ->willReturn($mockFieldLayout);
197
198
        return $mockSet;
199
    }
200
201
    /**
202
     * Get a mock site.
203
     *
204
     * @param string $handle
205
     *
206
     * @return Mock|Site
207
     */
208
    private function getMockSite(string $handle = 'default')
209
    {
210
        $mockSite = new Site([
211
            'id' => 99,
212
            'handle' => $handle,
213
        ]);
214
215
        return $mockSite;
216
    }
217
}
218