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