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

UserControllerTest::testCanAccessWhenLoggedOut()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 4
nc 1
nop 0
dl 0
loc 6
rs 10
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($data,
96
            $this->controller->InvitationForm()->loadDataFrom($data));
97
        $invitation = UserInvitation::get()->filter('Email', $data['Email']);
98
        $this->assertCount(1, $invitation);
99
        /** @var UserInvitation $invitation */
100
        $joe = $invitation->first();
101
        $this->assertEquals('Joe', $joe->FirstName);
102
        $this->assertEquals('[email protected]', $joe->Email);
103
        $this->assertEquals("[\"test1\",\"test2\"]", $joe->Groups);
104
        $this->assertEquals(302, $response->getStatusCode());
105
    }
106
107
    public function invitationData()
108
    {
109
        return [
110
            'FirstName' => 'Joe',
111
            'Email' => '[email protected]',
112
            'Groups' => ['test1', 'test2']
113
        ];
114
    }
115
116
    /**
117
     * Tests that no invitation gets sent out without requisite permissions.
118
     */
119
    public function testSendInvitePermissionDenied()
120
    {
121
        $this->loginInAsSomeone('john');
122
        /** @var Form $form */
123
        $data = $this->invitationData();
124
        $response = $this->controller->sendInvite($data,
125
            $this->controller->InvitationForm()->loadDataFrom($data));
126
        $invitation = UserInvitation::get()->filter('Email', $data['Email']);
127
        $this->assertCount(0, $invitation);
128
        $this->assertEquals(302, $response->getStatusCode());
129
    }
130
131
    /**
132
     * Tests whether switching the UserInvitation::force_require_group has an effect or not
133
     */
134
    public function testGroupFieldNotRequired()
135
    {
136
        $this->loginInAsSomeone('jane');
137
        $data = [
138
            'FirstName' => 'Joe',
139
            'Email' => '[email protected]',
140
            'Groups' => ['test1', 'test2']
141
        ];
142
        $form = $this->controller->InvitationForm()->loadDataFrom($data);
143
        $this->assertTrue($form->validationResult()->isValid());
144
145
        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

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