Completed
Pull Request — master (#114)
by Bart
09:10
created

SitesTest::provideValidSiteDefinitions()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 27
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 27
rs 8.8571
c 0
b 0
f 0
cc 1
eloc 18
nc 1
nop 0
1
<?php
2
3
namespace NerdsAndCompany\Schematic\Services;
4
5
use Craft;
6
use craft\models\Site;
7
use craft\models\SiteGroup;
8
use Codeception\Test\Unit;
9
use NerdsAndCompany\Schematic\Schematic;
10
11
/**
12
 * Class SitesTest.
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 SitesTest extends Unit
21
{
22
    /**
23
     * @var Sites
24
     */
25
    private $service;
26
27
    /**
28
     * Set the service.
29
     *
30
     * @SuppressWarnings(PHPMD.CamelCaseMethodName)
31
     */
32
    protected function _before()
33
    {
34
        Craft::$app->sites->expects($this->any())
35
                          ->method('getAllGroups')
36
                          ->willReturn([$this->getMockSiteGroup(1)]);
37
38
        Craft::$app->sites->expects($this->any())
39
                          ->method('saveGroup')
40
                          ->willReturn(true);
41
42
        $this->service = new ModelProcessor();
0 ignored issues
show
Documentation Bug introduced by
It seems like new \NerdsAndCompany\Sch...rvices\ModelProcessor() of type object<NerdsAndCompany\S...ervices\ModelProcessor> is incompatible with the declared type object<NerdsAndCompany\Schematic\Services\Sites> of property $service.

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...
43
    }
44
45
    //==============================================================================================================
46
    //=================================================  TESTS  ====================================================
47
    //==============================================================================================================
48
49
    /**
50
     * @dataProvider provideValidSites
51
     *
52
     * @param SiteModel[] $sites
53
     * @param array       $expectedResult
54
     */
55
    public function testSuccessfulExport(array $sites, array $expectedResult = [])
56
    {
57
        $actualResult = $this->service->export($sites);
58
59
        $this->assertSame($expectedResult, $actualResult);
60
    }
61
62
    /**
63
     * @dataProvider provideValidSiteDefinitions
64
     *
65
     * @param array $siteDefinitions
66
     */
67
    public function testSuccessfulImport(array $siteDefinitions, array $existingsites, int $saveCount)
68
    {
69
        $this->expectSaves($saveCount);
70
        $this->expectDeletes(0);
71
72
        $this->service->import($siteDefinitions, $existingsites);
73
    }
74
75
    /**
76
     * @dataProvider provideValidSiteDefinitions
77
     *
78
     * @param array $siteDefinitions
79
     */
80
    public function testImportWithForceOption(array $siteDefinitions, array $existingsites, int $saveCount, int $deleteCount)
81
    {
82
        Schematic::$force = true;
83
        $this->expectSaves($saveCount);
84
        $this->expectDeletes($deleteCount);
85
86
        $this->service->import($siteDefinitions, $existingsites);
87
    }
88
89
    //==============================================================================================================
90
    //==============================================  PROVIDERS  ===================================================
91
    //==============================================================================================================
92
93
    /**
94
     * @return array
95
     */
96
    public function provideValidSites()
97
    {
98
        $mockSite1 = $this->getMockSite(1, 1);
99
        $mockSite2 = $this->getMockSite(2, 1);
100
101
        return [
102
            'emptyArray' => [
103
                'sites' => [],
104
                'expectedResult' => [],
105
            ],
106
            'single site' => [
107
                'sites' => [
108
                    'site1' => $mockSite1,
109
                ],
110
                'expectedResult' => [
111
                    'siteHandle1' => $this->getMockSiteDefinition($mockSite1),
0 ignored issues
show
Documentation introduced by
$mockSite1 is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<craft\models\Site>.

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
                ],
113
            ],
114
            'multiple sites' => [
115
                'sites' => [
116
                    'site1' => $mockSite1,
117
                    'site2' => $mockSite2,
118
                ],
119
                'expectedResult' => [
120
                    'siteHandle1' => $this->getMockSiteDefinition($mockSite1),
0 ignored issues
show
Documentation introduced by
$mockSite1 is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<craft\models\Site>.

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...
121
                    'siteHandle2' => $this->getMockSiteDefinition($mockSite2),
0 ignored issues
show
Documentation introduced by
$mockSite2 is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<craft\models\Site>.

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...
122
                ],
123
            ],
124
        ];
125
    }
126
127
    /**
128
     * @return array
129
     */
130
    public function provideValidSiteDefinitions()
131
    {
132
        $mockSite1 = $this->getMockSite(1, 1);
133
        $mockSite2 = $this->getMockSite(2, 2);
134
135
        return [
136
            'emptyArray' => [
137
                'siteDefinitions' => [],
138
                'existingsites' => [
139
                    $mockSite1,
140
                ],
141
                'saveCount' => 0,
142
                'deleteCount' => 1,
143
            ],
144
            'single new site' => [
145
                'siteDefinitions' => [
146
                    'siteHandle1' => $this->getMockSiteDefinition($mockSite1),
0 ignored issues
show
Documentation introduced by
$mockSite1 is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<craft\models\Site>.

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...
147
                    'siteHandle2' => $this->getMockSiteDefinition($mockSite2),
0 ignored issues
show
Documentation introduced by
$mockSite2 is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<craft\models\Site>.

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...
148
                ],
149
                'existingsites' => [
150
                    $mockSite1,
151
                ],
152
                'saveCount' => 1,
153
                'deleteCount' => 0,
154
            ],
155
        ];
156
    }
157
158
    //==============================================================================================================
159
    //================================================  HELPERS  ===================================================
160
    //==============================================================================================================
161
162
    /**
163
     * @param Site $mockSite
164
     *
165
     * @return array
166
     */
167
    private function getMockSiteDefinition(Site $mockSite)
168
    {
169
        return [
170
            'class' => get_class($mockSite),
171
            'attributes' => [
172
                'name' => $mockSite->name,
173
                'handle' => $mockSite->handle,
174
                'language' => 'nl',
175
                'primary' => true,
176
                'hasUrls' => true,
177
                'originalName' => null,
178
                'originalBaseUrl' => null,
179
                'baseUrl' => '@web/',
180
                'sortOrder' => 1,
181
            ],
182
            'group' => $mockSite->group->name,
183
        ];
184
    }
185
186
    /**
187
     * @param int $siteId
188
     *
189
     * @return Mock|Site
190
     */
191
    private function getMockSite(int $siteId, int $groupId)
192
    {
193
        $mockSite = $this->getMockBuilder(Site::class)
194
                                    ->setMethods(['getGroup'])
195
                                    ->disableOriginalConstructor()
196
                                    ->getMock();
197
198
        $mockSite->id = $siteId;
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...
199
        $mockSite->groupId = 1;
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...
200
        $mockSite->handle = 'siteHandle'.$siteId;
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...
201
        $mockSite->language = 'nl';
0 ignored issues
show
Bug introduced by
Accessing language 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...
202
        $mockSite->primary = true;
0 ignored issues
show
Bug introduced by
Accessing primary 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...
203
        $mockSite->hasUrls = true;
0 ignored issues
show
Bug introduced by
Accessing hasUrls 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...
204
        $mockSite->originalName = null;
0 ignored issues
show
Bug introduced by
Accessing originalName 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...
205
        $mockSite->originalBaseUrl = null;
0 ignored issues
show
Bug introduced by
Accessing originalBaseUrl 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...
206
        $mockSite->baseUrl = '@web/';
0 ignored issues
show
Bug introduced by
Accessing baseUrl 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...
207
        $mockSite->sortOrder = 1;
0 ignored issues
show
Bug introduced by
Accessing sortOrder 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...
208
209
        $mockSite->expects($this->any())
210
                 ->method('getGroup')
211
                 ->willReturn($this->getMockSiteGroup($groupId));
212
213
        return $mockSite;
214
    }
215
216
    /**
217
     * Get a mock site group.
218
     *
219
     * @param int $groupId
220
     *
221
     * @return Mock|SiteGroup
222
     */
223
    private function getMockSiteGroup(int $groupId)
224
    {
225
        $mockGroup = $this->getMockBuilder(SiteGroup::class)
226
                        ->disableOriginalConstructor()
227
                        ->getmock();
228
229
        $mockGroup->id = $groupId;
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...
230
        $mockGroup->name = 'siteGroup'.$groupId;
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...
231
232
        return $mockGroup;
233
    }
234
235
    /**
236
     * Expect a number of site saves.
237
     *
238
     * @param int $saveCount
239
     */
240
    private function expectSaves(int $saveCount)
241
    {
242
        Craft::$app->sites
243
                   ->expects($this->exactly($saveCount))
244
                   ->method('saveSite')
245
                   ->willReturn(true);
246
    }
247
248
    /**
249
     * Expect a number of site deletes.
250
     *
251
     * @param int $deleteCount
252
     */
253
    private function expectDeletes(int $deleteCount)
254
    {
255
        Craft::$app->sites
256
                    ->expects($this->exactly($deleteCount))
257
                    ->method('deleteSiteById');
258
    }
259
}
260