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

UserSettingsMapperTest::getMockFieldLayout()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 19
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 19
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 13
nc 1
nop 0
1
<?php
2
3
namespace NerdsAndCompany\Schematic\Mappers;
4
5
use Craft;
6
use craft\base\Field;
7
use craft\base\Volume;
8
use craft\elements\User;
9
use craft\models\FieldLayout;
10
use craft\models\FieldLayoutTab;
11
use Codeception\Test\Unit;
12
13
/**
14
 * Class UserSettingsMapperTest.
15
 *
16
 * @author    Nerds & Company
17
 * @copyright Copyright (c) 2015-2018, Nerds & Company
18
 * @license   MIT
19
 *
20
 * @see      http://www.nerds.company
21
 */
22
class UserSettingsMapperTest extends Unit
23
{
24
    /**
25
     * @var UserSettingsMapper
26
     */
27
    private $mapper;
28
29
    /**
30
     * Set the mapper.
31
     *
32
     * @SuppressWarnings(PHPMD.CamelCaseMethodName)
33
     */
34
    protected function _before()
35
    {
36
        $this->mapper = new UserSettingsMapper();
37
    }
38
39
    //==============================================================================================================
40
    //=================================================  TESTS  ====================================================
41
    //==============================================================================================================
42
43
    /**
44
     * Test UserSettings service export.
45
     */
46
    public function testUserSettingsServiceExport()
47
    {
48
        $this->setMockServicesForExport();
49
50
        $definition = $this->getUserSettingsDefinition();
51
        $result = $this->mapper->export();
52
53
        $this->assertSame($definition, $result);
54
    }
55
56
    /**
57
     * Test UserSettings service import.
58
     */
59
    public function testUserSettingsServiceImportWithoutFieldLayout()
60
    {
61
        $this->setMockServicesForImport(false, false);
62
63
        $definition = $this->getUserSettingsDefinition();
64
        unset($definition['fieldLayout']);
65
        $import = $this->mapper->import($definition);
66
67
        $this->assertSame([], $import);
68
    }
69
70
    /**
71
     * Test UserSettings service import.
72
     */
73
    public function testUserSettingsServiceImportWithImportError()
74
    {
75
        $this->setMockServicesForImport(true, true, true);
76
77
        $definition = $this->getUserSettingsDefinition();
78
        $import = $this->mapper->import($definition);
79
80
        $this->assertSame([], $import);
81
    }
82
83
    //==============================================================================================================
84
    //================================================  HELPERS  ===================================================
85
    //==============================================================================================================
86
87
    /**
88
     * [getUserSettingsDefinition description].
89
     *
90
     * @return [type] [description]
0 ignored issues
show
Documentation introduced by
The doc-type [type] could not be parsed: Unknown type name "" at position 0. [(view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
91
     */
92
    private function getUserSettingsDefinition()
93
    {
94
        return [
95
            'settings' => [
96
                'requireEmailVerification' => true,
97
                'allowPublicRegistration' => false,
98
                'defaultGroup' => null,
99
                'photoSubpath' => 'profile',
100
                'photoVolume' => 'volumeHandle',
101
            ],
102
            'fieldLayout' => [
103
                'tabs' => [
104
                    'Content' => [
105
                        'fieldHandle1' => true,
106
                        'fieldHandle2' => false,
107
                    ],
108
                ],
109
            ],
110
        ];
111
    }
112
113
    /**
114
     * Set mock services for export.
115
     */
116
    private function setMockServicesForExport()
117
    {
118
        $mockFieldLayout = $this->getMockFieldLayout();
119
        Craft::$app->fields->expects($this->exactly(1))
120
                           ->method('getLayoutByType')
121
                           ->with(User::class)
122
                           ->willReturn($mockFieldLayout);
123
124
        $settings = [
125
            'requireEmailVerification' => true,
126
            'allowPublicRegistration' => false,
127
            'defaultGroup' => null,
128
            'photoSubpath' => 'profile',
129
            'photoVolumeId' => 1,
130
        ];
131
132
        Craft::$app->systemSettings->expects($this->exactly(1))
133
                                   ->method('getSettings')
134
                                   ->with('users')
135
                                   ->willReturn($settings);
136
137
        Craft::$app->volumes->expects($this->exactly(1))
138
                            ->method('getVolumeById')
139
                            ->with(1)
140
                            ->willReturn($this->getMockVolume());
141
    }
142
143
    /**
144
     * @param bool $saveLayout
145
     * @param bool $deleteLayoutsByType
146
     */
147
    private function setMockServicesForImport($saveLayout = true, $deleteLayoutsByType = true, $errors = false)
148
    {
149
        Craft::$app->fields->expects($this->exactly($saveLayout ? 1 : 0))->method('saveLayout')->willReturn(!$errors);
150
        Craft::$app->fields->expects($this->exactly($deleteLayoutsByType ? 1 : 0))->method('deleteLayoutsByType')->willReturn(true);
151
        $mockFieldLayout = $this->getMockFieldLayout();
152
        if ($errors) {
153
            $mockFieldLayout->expects($this->exactly(1))->method('getErrors')->willReturn([
154
                'errors' => ['error 1', 'error 2', 'error 3'],
155
            ]);
156
        }
157
158
        Craft::$app->fields->expects($this->exactly($saveLayout ? 1 : 0))->method('assembleLayout')->willReturn($mockFieldLayout);
159
    }
160
161
    /**
162
     * @return Mock|FieldLayout
163
     */
164
    private function getMockFieldLayout()
165
    {
166
        $mockFieldLayout = $this->getMockBuilder(FieldLayout::class)->getMock();
167
        $mockFieldLayoutTab = $this->getMockBuilder(FieldLayoutTab::class)->getMock();
168
        $mockFieldLayoutTab->name = 'Content';
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
        $mockFieldLayout->expects($this->any())
171
                        ->method('getTabs')
172
                        ->willReturn([$mockFieldLayoutTab]);
173
174
        $mockFieldLayoutTab->expects($this->any())
175
                           ->method('getFields')
176
                           ->willReturn([
177
                               $this->getMockField(1, true),
178
                               $this->getMockField(2, false),
179
                           ]);
180
181
        return $mockFieldLayout;
182
    }
183
184
    /**
185
     * Get a mock field.
186
     *
187
     * @param int  $fieldId
188
     * @param bool $required
189
     *
190
     * @return Mock|Field
191
     */
192
    private function getMockField(int $fieldId, bool $required)
193
    {
194
        $mockField = $this->getMockbuilder(Field::class)
195
                         ->setMethods([])
196
                         ->getMock();
197
198
        $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...
199
        $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...
200
        $mockField->required = $required;
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...
201
202
        return $mockField;
203
    }
204
205
    /**
206
     * Get mock volume.
207
     *
208
     * @return Mock|Volume
209
     */
210
    private function getMockVolume()
211
    {
212
        $mockVolume = $this->getMockBuilder(Volume::class)->getMock();
213
        $mockVolume->handle = 'volumeHandle';
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...
214
215
        return $mockVolume;
216
    }
217
}
218