Passed
Pull Request — master (#5)
by Matthew
02:17
created

UserControllerTest::testGetLayoutTemplates()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 24
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 17
nc 1
nop 0
dl 0
loc 24
rs 9.7
c 0
b 0
f 0
1
<?php
2
3
namespace FSWebWorks\SilverStripe\UserInvitations\Tests;
4
5
use FSWebWorks\SilverStripe\UserInvitations\Control\UserController;
6
use FSWebWorks\SilverStripe\UserInvitations\Model\UserInvitation;
7
use SilverStripe\Control\Director;
8
use SilverStripe\Core\Config\Config;
9
use SilverStripe\Core\Convert;
10
use SilverStripe\Core\Injector\Injector;
11
use SilverStripe\Dev\FunctionalTest;
12
use SilverStripe\Forms\Form;
13
use SilverStripe\ORM\FieldType\DBHTMLText;
14
use SilverStripe\Security\Group;
15
use SilverStripe\Security\Member;
16
use SilverStripe\Security\Security;
17
18
class UserControllerTest extends FunctionalTest
19
{
20
21
    public static $fixture_file = 'UserControllerTest.yml';
22
23
    /**
24
     * @var UserController $controller
25
     */
26
    private $controller;
27
28
    public function setUp()
29
    {
30
        parent::setUp();
31
        $this->autoFollowRedirection = false;
32
        $this->logInWithPermission('ADMIN');
33
        $this->controller = new UserController();
34
    }
35
36
    private function logoutMember()
37
    {
38
        Security::setCurrentUser(null);
39
    }
40
41
    /**
42
     * Tests redirected to a login screen if you're logged out.
43
     */
44
    public function testCantAccessWhenLoggedOut()
45
    {
46
        $this->logOut();
47
        $response = $this->get($this->controller->Link('index'));
48
        $this->assertFalse($response->isError());
49
        $this->assertEquals(302, $response->getStatusCode());
50
        $this->autoFollowRedirection = true;
51
    }
52
53
    /**
54
     * Tests that a user can access other actions
55
     */
56
    public function testCanAccessWhenLoggedOut()
57
    {
58
        $this->logOut();
59
        $response = $this->get($this->controller->Link('accept'));
60
        $this->assertFalse($response->isError());
61
        $this->assertEquals(200, $response->getStatusCode());
62
    }
63
64
    /**
65
     * Tests that you can't access the index action without the requisite permission
66
     */
67
    public function testCantAccessWithoutPermission()
68
    {
69
        $this->loginInAsSomeone('john');
70
        $response = $this->get($this->controller->Link('index'));
71
        $this->assertEquals(403, $response->getStatusCode());
72
        $this->autoFollowRedirection = true;
73
    }
74
75
    /**
76
     * Tests if a form is returned and that expected fields are present
77
     */
78
    public function testInvitationForm()
79
    {
80
        $form = $this->controller->InvitationForm();
81
        $this->assertInstanceOf(Form::class, $form);
82
        $this->assertNotNull($form->Fields()->fieldByName('FirstName'));
83
        $this->assertNotNull($form->Fields()->fieldByName('Email'));
84
        $this->assertNotNull($form->Fields()->fieldByName('Groups'));
85
    }
86
87
    /**
88
     * Tests whether an email is sent and that an invitation record is created
89
     */
90
    public function testSendInvite()
91
    {
92
        $this->loginInAsSomeone('jane');
93
        /** @var Form $form */
94
        $data = $this->invitationData();
95
        $response = $this->controller->sendInvite(
96
            $data,
97
            $this->controller->InvitationForm()->loadDataFrom($data)
98
        );
99
        $invitation = UserInvitation::get()->filter('Email', $data['Email']);
100
        $this->assertCount(1, $invitation);
101
        /** @var UserInvitation $invitation */
102
        $joe = $invitation->first();
103
        $this->assertEquals('Joe', $joe->FirstName);
104
        $this->assertEquals('[email protected]', $joe->Email);
105
        $this->assertEquals("[\"test1\",\"test2\"]", $joe->Groups);
106
        $this->assertEquals(302, $response->getStatusCode());
107
    }
108
109
    public function invitationData()
110
    {
111
        return [
112
            'FirstName' => 'Joe',
113
            'Email' => '[email protected]',
114
            'Groups' => ['test1', 'test2']
115
        ];
116
    }
117
118
    /**
119
     * Tests that no invitation gets sent out without requisite permissions.
120
     */
121
    public function testSendInvitePermissionDenied()
122
    {
123
        $this->loginInAsSomeone('john');
124
        /** @var Form $form */
125
        $data = $this->invitationData();
126
        $response = $this->controller->sendInvite(
127
            $data,
128
            $this->controller->InvitationForm()->loadDataFrom($data)
129
        );
130
        $invitation = UserInvitation::get()->filter('Email', $data['Email']);
131
        $this->assertCount(0, $invitation);
132
        $this->assertEquals(302, $response->getStatusCode());
133
    }
134
135
    /**
136
     * Tests whether switching the UserInvitation::force_require_group has an effect or not
137
     */
138
    public function testGroupFieldNotRequired()
139
    {
140
        $this->loginInAsSomeone('jane');
141
        $data = [
142
            'FirstName' => 'Joe',
143
            'Email' => '[email protected]',
144
            'Groups' => ['test1', 'test2']
145
        ];
146
        $form = $this->controller->InvitationForm()->loadDataFrom($data);
147
        $this->assertTrue($form->validationResult()->isValid());
148
149
        Config::inst()->update(
0 ignored issues
show
Bug introduced by
The method update() does not exist on SilverStripe\Config\Coll...nfigCollectionInterface. It seems like you code against a sub-type of SilverStripe\Config\Coll...nfigCollectionInterface such as SilverStripe\Config\Coll...\MemoryConfigCollection. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

149
        Config::inst()->/** @scrutinizer ignore-call */ update(
Loading history...
150
            UserInvitation::class,
151
            'force_require_group',
152
            true
153
        );
154
        unset($data['Groups']);
155
        $form = $this->controller->InvitationForm()->loadDataFrom($data);
156
        $this->assertFalse($form->validationResult()->isValid());
157
    }
158
159
    private function loginInAsSomeone($name)
160
    {
161
        /** @var Member $member */
162
        $member = $this->objFromFixture(Member::class, $name);
163
        $this->logInAs($member);
164
    }
165
166
    /**
167
     * Tests for 403 if no ID parameter given
168
     */
169
    public function testAcceptForbiddenError()
170
    {
171
        $response = $this->get($this->controller->Link('accept'));
172
        $this->assertEquals(403, $response->getStatusCode());
173
    }
174
175
    /**
176
     * Tests for expired TempHash and that it redirects to the expired page
177
     */
178
    public function testAcceptExpiredTempHash()
179
    {
180
        /** @var UserInvitation $invitation */
181
        $invitation = $this->objFromFixture(UserInvitation::class, 'expired');
182
        $response = $this->get($this->controller->Link('accept/' . $invitation->TempHash));
183
        $this->assertEquals(302, $response->getStatusCode());
184
        $base = Director::absoluteBaseURL();
185
        $this->assertEquals(
186
            'user/expired',
187
            str_replace($base, '', $response->getHeader('Location'))
188
        );
189
    }
190
191
    /**
192
     * Tests if a form is returned and that expected fields are present
193
     */
194
    public function testAcceptForm()
195
    {
196
        $form = $this->controller->AcceptForm();
197
        $this->assertInstanceOf(Form::class, $form);
198
        $this->assertNotNull($form->Fields()->fieldByName('FirstName'));
199
        $this->assertNull($form->Fields()->fieldByName('Email'));
200
        $this->assertNotNull($form->Fields()->fieldByName('HashID'));
201
        $this->assertNotNull($form->Fields()->fieldByName('Surname'));
202
    }
203
204
    /**
205
     * Tests that redirected to not found if has not found
206
     */
207
    public function testSaveInviteWrongHashError()
208
    {
209
        $data = [
210
            'HashID' => '432'
211
        ];
212
        $response = $this->controller->saveInvite(
213
            $data,
214
            $this->controller->AcceptForm()->loadDataFrom($data)
215
        );
216
        $this->assertEquals(302, $response->getStatusCode());
217
        $base = Director::absoluteBaseURL();
218
        $this->assertEquals(
219
            'user/notfound',
220
            str_replace($base, '', $response->getHeader('Location'))
221
        );
222
    }
223
224
    public function testSaveInvite()
225
    {
226
        /** @var UserInvitation $invitation */
227
        $invitation = $this->objFromFixture(UserInvitation::class, 'joe');
228
        $data = [
229
            'HashID' => $invitation->TempHash,
230
            'FirstName' => $invitation->FirstName,
231
            'Surname' => 'Soap',
232
            'Password' => [
233
                '_Password' => 'password',
234
                '_ConfirmPassword' => 'password'
235
            ]
236
        ];
237
238
        $response = $this->controller->saveInvite(
239
            $data,
240
            $this->controller->AcceptForm()->loadDataFrom($data)
241
        );
242
        $this->assertEquals(302, $response->getStatusCode());
243
        $base = Director::absoluteBaseURL();
244
        $this->assertEquals(
245
            'user/success',
246
            str_replace($base, '', $response->getHeader('Location'))
247
        );
248
249
        // Assert that invitation is deleted
250
        $this->assertNull(UserInvitation::get()->filter(
251
            'Email',
252
            $invitation->Email
253
        )->first());
254
255
        /** @var Member $joe */
256
        $joe = Member::get()->filter('Email', $invitation->Email)->first();
257
        // Assert that member is created
258
        $this->assertTrue($joe->exists());
259
260
        // Assert that member belongs to the groups selected
261
        $this->assertTrue($joe->inGroup($this->objFromFixture(
262
            Group::class,
263
            'test1'
264
        )));
265
        $this->assertTrue($joe->inGroup($this->objFromFixture(
266
            Group::class,
267
            'test2'
268
        )));
269
    }
270
271
    /**
272
     * Tests that a login link is presented to the user
273
     */
274
    public function testSuccess()
275
    {
276
        $this->logoutMember();
277
        $response = $this->get($this->controller->Link('success'));
278
        $body = Convert::nl2os($response->getBody(), '');
279
        $this->assertContains('Congratulations!', $body);
280
        $this->assertContains('You are now a registered member', $body);
281
        $security = Injector::inst()->get(Security::class);
282
        $link = $security->Link('login');
283
        $this->assertContains("<a href=\"{$link}\">", $body);
284
    }
285
286
    /**
287
     * Tests that the expired action is shown
288
     */
289
    public function testExpired()
290
    {
291
        $this->logoutMember();
292
        $response = $this->get($this->controller->Link('expired'));
293
        $body = Convert::nl2os($response->getBody(), '');
294
        $this->assertContains('Invitation expired', $body);
295
        $this->assertContains(
296
            'Oops, you took too long to accept this invitation',
297
            $body
298
        );
299
    }
300
301
    /**
302
     * Tests that the notfound action is shown.
303
     */
304
    public function testNotFound()
305
    {
306
        $this->logoutMember();
307
        $response = $this->get($this->controller->Link('notfound'));
308
        $body = Convert::nl2os($response->getBody(), '');
309
        $this->assertContains('Invitation not found', $body);
310
        $this->assertContains('Oops, the invitation ID was not found.', $body);
311
    }
312
313
    /**
314
     * Tests whether links are correctly re-written.
315
     */
316
    public function testLink()
317
    {
318
        $this->assertEquals('user/accept', $this->controller->Link('accept'));
319
        $this->assertEquals('user/index', $this->controller->Link('index'));
320
    }
321
322
    /**
323
     * Tests that the array key is returned
324
     */
325
    public function testProvidePermissions()
326
    {
327
        $permissions = $this->controller->providePermissions();
328
        $this->assertArrayHasKey('ACCESS_USER_INVITATIONS', $permissions);
329
        $this->assertArrayHasKey(
330
            'name',
331
            $permissions['ACCESS_USER_INVITATIONS']
332
        );
333
        $this->assertArrayHasKey(
334
            'category',
335
            $permissions['ACCESS_USER_INVITATIONS']
336
        );
337
    }
338
339
    /**
340
     *
341
     */
342
    public function testRenderWithLayout()
343
    {
344
        $render = $this->controller->renderWithLayout([]);
345
        $this->assertInstanceOf(DBHTMLText::class, $render);
346
    }
347
348
    /**
349
     *
350
     */
351
    public function testGetLayoutTemplates()
352
    {
353
        // test string to template array
354
        $templates = $this->controller->getLayoutTemplates('NewPage');
355
        $this->assertEquals([
356
            'type' => 'Layout',
357
            'NewPage',
358
            'Page',
359
        ], $templates);
360
361
        // test empty array to template array
362
        $templates = $this->controller->getLayoutTemplates([]);
363
        $this->assertEquals([
364
            'type' => 'Layout',
365
            'Page',
366
        ], $templates);
367
368
        // test empty array to template array
369
        $templates = $this->controller->getLayoutTemplates(['NewPage']);
370
        $this->assertEquals([
371
            'type' => 'Layout',
372
            'NewPage',
373
            'Page',
374
        ], $templates);
375
    }
376
}
377