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

SitesTest::provideValidSites()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 30
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 30
rs 8.8571
c 0
b 0
f 0
cc 1
eloc 19
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 Sites();
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
        $this->expectList($sites);
58
59
        $actualResult = $this->service->export();
60
61
        $this->assertSame($expectedResult, $actualResult);
62
    }
63
64
    /**
65
     * @dataProvider provideValidSiteDefinitions
66
     *
67
     * @param array $siteDefinitions
68
     */
69
    public function testSuccessfulImport(array $siteDefinitions, array $existingsites, int $saveCount)
70
    {
71
        $this->expectList($existingsites);
72
        $this->expectSaves($saveCount);
73
        $this->expectDeletes(0);
74
75
        $this->service->import($siteDefinitions);
76
    }
77
78
    /**
79
     * @dataProvider provideValidSiteDefinitions
80
     *
81
     * @param array $siteDefinitions
82
     */
83
    public function testImportWithForceOption(array $siteDefinitions, array $existingsites, int $saveCount, int $deleteCount)
84
    {
85
        Schematic::$force = true;
86
        $this->expectList($existingsites);
87
        $this->expectSaves($saveCount);
88
        $this->expectDeletes($deleteCount);
89
90
        $this->service->import($siteDefinitions);
91
    }
92
93
    //==============================================================================================================
94
    //==============================================  PROVIDERS  ===================================================
95
    //==============================================================================================================
96
97
    /**
98
     * @return array
99
     */
100
    public function provideValidSites()
101
    {
102
        $mockSite1 = $this->getMockSite(1, 1);
103
        $mockSite2 = $this->getMockSite(2, 1);
104
105
        return [
106
            'emptyArray' => [
107
                'sites' => [],
108
                'expectedResult' => [],
109
            ],
110
            'single site' => [
111
                'sites' => [
112
                    'site1' => $mockSite1,
113
                ],
114
                'expectedResult' => [
115
                    '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...
116
                ],
117
            ],
118
            'multiple sites' => [
119
                'sites' => [
120
                    'site1' => $mockSite1,
121
                    'site2' => $mockSite2,
122
                ],
123
                'expectedResult' => [
124
                    '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...
125
                    '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...
126
                ],
127
            ],
128
        ];
129
    }
130
131
    /**
132
     * @return array
133
     */
134
    public function provideValidSiteDefinitions()
135
    {
136
        $mockSite1 = $this->getMockSite(1, 1);
137
        $mockSite2 = $this->getMockSite(2, 2);
138
139
        return [
140
            'emptyArray' => [
141
                'siteDefinitions' => [],
142
                'existingsites' => [
143
                    $mockSite1,
144
                ],
145
                'saveCount' => 0,
146
                'deleteCount' => 1,
147
            ],
148
            'single new site' => [
149
                'siteDefinitions' => [
150
                    '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...
151
                    '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...
152
                ],
153
                'existingsites' => [
154
                    $mockSite1,
155
                ],
156
                'saveCount' => 1,
157
                'deleteCount' => 0,
158
            ],
159
        ];
160
    }
161
162
    //==============================================================================================================
163
    //================================================  HELPERS  ===================================================
164
    //==============================================================================================================
165
166
    /**
167
     * @param Site $mockSite
168
     *
169
     * @return array
170
     */
171
    private function getMockSiteDefinition(Site $mockSite)
172
    {
173
        return [
174
            'class' => get_class($mockSite),
175
            'attributes' => [
176
                'name' => $mockSite->name,
177
                'handle' => $mockSite->handle,
178
                'language' => 'nl',
179
                'primary' => true,
180
                'hasUrls' => true,
181
                'originalName' => null,
182
                'originalBaseUrl' => null,
183
                'baseUrl' => '@web/',
184
                'sortOrder' => 1,
185
            ],
186
            'group' => $mockSite->group->name,
187
        ];
188
    }
189
190
    /**
191
     * @param int $siteId
192
     *
193
     * @return Mock|Site
194
     */
195
    private function getMockSite(int $siteId, int $groupId)
196
    {
197
        $mockSite = $this->getMockBuilder(Site::class)
198
                                    ->setMethods(['getGroup'])
199
                                    ->disableOriginalConstructor()
200
                                    ->getMock();
201
202
        $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...
203
        $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...
204
        $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...
205
        $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...
206
        $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...
207
        $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...
208
        $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...
209
        $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...
210
        $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...
211
        $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...
212
213
        $mockSite->expects($this->any())
214
                 ->method('getGroup')
215
                 ->willReturn($this->getMockSiteGroup($groupId));
216
217
        return $mockSite;
218
    }
219
220
    /**
221
     * Get a mock site group.
222
     *
223
     * @param int $groupId
224
     *
225
     * @return Mock|SiteGroup
226
     */
227
    private function getMockSiteGroup(int $groupId)
228
    {
229
        $mockGroup = $this->getMockBuilder(SiteGroup::class)
230
                        ->disableOriginalConstructor()
231
                        ->getmock();
232
233
        $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...
234
        $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...
235
236
        return $mockGroup;
237
    }
238
239
    /**
240
     * Expect a list of sites.
241
     *
242
     * @param Site[] $sites
243
     */
244
    private function expectList(array $sites)
245
    {
246
        Craft::$app->sites
247
                   ->expects($this->exactly(1))
248
                   ->method('getAllSites')
249
                   ->willReturn($sites);
250
    }
251
252
    /**
253
     * Expect a number of site saves.
254
     *
255
     * @param int $saveCount
256
     */
257
    private function expectSaves(int $saveCount)
258
    {
259
        Craft::$app->sites
260
                   ->expects($this->exactly($saveCount))
261
                   ->method('saveSite')
262
                   ->willReturn(true);
263
    }
264
265
    /**
266
     * Expect a number of site deletes.
267
     *
268
     * @param int $deleteCount
269
     */
270
    private function expectDeletes(int $deleteCount)
271
    {
272
        Craft::$app->sites
273
                    ->expects($this->exactly($deleteCount))
274
                    ->method('deleteSiteById');
275
    }
276
}
277