Completed
Push — do-not-scrutinize-tests ( fcf005 )
by Bart
04:15 queued 02:38
created

UserSettingsMapperTest   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 201
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 6

Importance

Changes 0
Metric Value
wmc 14
c 0
b 0
f 0
lcom 1
cbo 6
dl 0
loc 201
rs 10
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
     * phpcs:disable PSR2.Methods.MethodDeclaration.Underscore
34
     */
35
    protected function _before()
36
    {
37
        $this->mapper = new UserSettingsMapper();
38
    }
39
40
    //==============================================================================================================
41
    //=================================================  TESTS  ====================================================
42
    //==============================================================================================================
43
44
    /**
45
     * Test UserSettings service export.
46
     */
47
    public function testUserSettingsServiceExport()
48
    {
49
        $this->setMockServicesForExport();
50
51
        $definition = $this->getUserSettingsDefinition();
52
        $result = $this->mapper->export();
53
54
        $this->assertSame($definition, $result);
55
    }
56
57
    /**
58
     * Test UserSettings service import without fieldlayout.
59
     */
60
    public function testUserSettingsServiceImportWithoutFieldLayout()
61
    {
62
        $this->setMockServicesForImport(false, false);
63
64
        $definition = $this->getUserSettingsDefinition();
65
        unset($definition['fieldLayout']);
66
        $import = $this->mapper->import($definition);
67
68
        $this->assertSame([], $import);
69
    }
70
71
    /**
72
     * Test UserSettings service import with import error.
73
     */
74
    public function testUserSettingsServiceImportWithImportError()
75
    {
76
        $this->setMockServicesForImport(true, true, true);
77
78
        $definition = $this->getUserSettingsDefinition();
79
        $import = $this->mapper->import($definition);
80
81
        $this->assertSame([], $import);
82
    }
83
84
    //==============================================================================================================
85
    //================================================  HELPERS  ===================================================
86
    //==============================================================================================================
87
88
    /**
89
     * Get user settings definition.
90
     *
91
     * @return array
92
     */
93
    private function getUserSettingsDefinition()
94
    {
95
        return [
96
            'settings' => [
97
                'requireEmailVerification' => true,
98
                'allowPublicRegistration' => false,
99
                'defaultGroup' => null,
100
                'photoSubpath' => 'profile',
101
                'photoVolume' => 'volumeHandle',
102
            ],
103
            'fieldLayout' => [
104
                'tabs' => [
105
                    'Content' => [
106
                        'fieldHandle1' => true,
107
                        'fieldHandle2' => false,
108
                    ],
109
                ],
110
            ],
111
        ];
112
    }
113
114
    /**
115
     * Set mock services for export.
116
     */
117
    private function setMockServicesForExport()
118
    {
119
        $mockFieldLayout = $this->getMockFieldLayout();
120
        Craft::$app->fields->expects($this->exactly(1))
121
                           ->method('getLayoutByType')
122
                           ->with(User::class)
123
                           ->willReturn($mockFieldLayout);
124
125
        $settings = [
126
            'requireEmailVerification' => true,
127
            'allowPublicRegistration' => false,
128
            'defaultGroup' => null,
129
            'photoSubpath' => 'profile',
130
            'photoVolumeId' => 1,
131
        ];
132
133
        Craft::$app->systemSettings->expects($this->exactly(1))
134
                                   ->method('getSettings')
135
                                   ->with('users')
136
                                   ->willReturn($settings);
137
138
        Craft::$app->volumes->expects($this->exactly(1))
139
                            ->method('getVolumeById')
140
                            ->with(1)
141
                            ->willReturn($this->getMockVolume());
142
    }
143
144
    /**
145
     * @param bool $saveLayout
146
     * @param bool $deleteLayoutsByType
147
     */
148
    private function setMockServicesForImport($saveLayout = true, $deleteLayoutsByType = true, $errors = false)
149
    {
150
        Craft::$app->fields->expects($this->exactly($saveLayout ? 1 : 0))->method('saveLayout')->willReturn(!$errors);
151
        Craft::$app->fields->expects($this->exactly($deleteLayoutsByType ? 1 : 0))
152
                           ->method('deleteLayoutsByType')
153
                           ->willReturn(true);
154
        $mockFieldLayout = $this->getMockFieldLayout();
155
        if ($errors) {
156
            $mockFieldLayout->expects($this->exactly(1))->method('getErrors')->willReturn([
157
                'errors' => ['error 1', 'error 2', 'error 3'],
158
            ]);
159
        }
160
161
        Craft::$app->fields->expects($this->exactly($saveLayout ? 1 : 0))
162
                           ->method('assembleLayout')
163
                           ->willReturn($mockFieldLayout);
164
    }
165
166
    /**
167
     * @return Mock|FieldLayout
168
     */
169
    private function getMockFieldLayout()
170
    {
171
        $mockFieldLayout = $this->getMockBuilder(FieldLayout::class)->getMock();
172
        $mockFieldLayoutTab = $this->getMockBuilder(FieldLayoutTab::class)->getMock();
173
        $mockFieldLayoutTab->name = 'Content';
174
175
        $mockFieldLayout->expects($this->any())
176
                        ->method('getTabs')
177
                        ->willReturn([$mockFieldLayoutTab]);
178
179
        $mockFieldLayoutTab->expects($this->any())
180
                           ->method('getFields')
181
                           ->willReturn([
182
                               $this->getMockField(1, true),
183
                               $this->getMockField(2, false),
184
                           ]);
185
186
        return $mockFieldLayout;
187
    }
188
189
    /**
190
     * Get a mock field.
191
     *
192
     * @param int  $fieldId
193
     * @param bool $required
194
     *
195
     * @return Mock|Field
196
     */
197
    private function getMockField(int $fieldId, bool $required)
198
    {
199
        $mockField = $this->getMockbuilder(Field::class)
200
                         ->setMethods([])
201
                         ->getMock();
202
203
        $mockField->id = $fieldId;
204
        $mockField->handle = 'fieldHandle'.$fieldId;
205
        $mockField->required = $required;
206
207
        return $mockField;
208
    }
209
210
    /**
211
     * Get mock volume.
212
     *
213
     * @return Mock|Volume
214
     */
215
    private function getMockVolume()
216
    {
217
        $mockVolume = $this->getMockBuilder(Volume::class)->getMock();
218
        $mockVolume->handle = 'volumeHandle';
219
220
        return $mockVolume;
221
    }
222
}
223