testCantAccessWithoutPermission()   A
last analyzed

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 SilverStripe\Forms\Form;
6
use SilverStripe\Core\Convert;
7
use SilverStripe\Security\Group;
8
use SilverStripe\Security\Member;
9
use SilverStripe\Control\Director;
10
use SilverStripe\Security\Security;
11
use SilverStripe\Core\Config\Config;
12
use SilverStripe\Dev\FunctionalTest;
13
use SilverStripe\Core\Injector\Injector;
14
use FSWebWorks\SilverStripe\UserInvitations\Model\UserInvitation;
15
use FSWebWorks\SilverStripe\UserInvitations\Control\UserController;
16
17
class UserControllerTest extends FunctionalTest
18
{
19
20
    public static $fixture_file = 'UserControllerTest.yml';
21
22
    /**
23
     * @var UserController
24
     */
25
    private $controller;
26
27
    public function setUp()
28
    {
29
        parent::setUp();
30
        $this->autoFollowRedirection = false;
31
        $this->logInWithPermission('ADMIN');
32
        $this->controller = new UserController();
33
    }
34
35
    private function logoutMember()
36
    {
37
        Security::setCurrentUser(null);
38
    }
39
40
    /**
41
     * Tests redirected to a login screen if you're logged out.
42
     */
43
    public function testCantAccessWhenLoggedOut()
44
    {
45
        $this->logOut();
46
        $response = $this->get($this->controller->Link('index'));
47
        $this->assertFalse($response->isError());
48
        $this->assertEquals(302, $response->getStatusCode());
49
        $this->autoFollowRedirection = true;
50
    }
51
52
    /**
53
     * Tests that you can't access the index action without the requisite permission
54
     */
55
    public function testCantAccessWithoutPermission()
56
    {
57
        $this->loginInAsSomeone('john');
58
        $response = $this->get($this->controller->Link('index'));
59
        $this->assertEquals(403, $response->getStatusCode());
60
        $this->autoFollowRedirection = true;
61
    }
62
63
    /**
64
     * Tests if a form is returned and that expected fields are present
65
     */
66
    public function testInvitationForm()
67
    {
68
        $form = $this->controller->InvitationForm();
69
        $this->assertInstanceOf(Form::class, $form);
70
        $this->assertNotNull($form->Fields()->fieldByName('FirstName'));
71
        $this->assertNotNull($form->Fields()->fieldByName('Email'));
72
        $this->assertNotNull($form->Fields()->fieldByName('Groups'));
73
    }
74
75
    /**
76
     * Tests whether an email is sent and that an invitation record is created
77
     */
78
    public function testSendInvite()
79
    {
80
        $this->loginInAsSomeone('jane');
81
        /** @var Form $form */
82
        $data = $this->invitationData();
83
        $response = $this->controller->sendInvite($data,
84
            $this->controller->InvitationForm()->loadDataFrom($data));
85
        $invitation = UserInvitation::get()->filter('Email', $data['Email']);
86
        $this->assertCount(1, $invitation);
87
        /** @var UserInvitation $invitation */
88
        $joe = $invitation->first();
89
        $this->assertEquals('Joe', $joe->FirstName);
90
        $this->assertEquals('[email protected]', $joe->Email);
91
        $this->assertEquals("[\"test1\",\"test2\"]", $joe->Groups);
92
        $this->assertEquals(302, $response->getStatusCode());
93
    }
94
95
    public function invitationData()
96
    {
97
        return [
98
            'FirstName' => 'Joe',
99
            'Email' => '[email protected]',
100
            'Groups' => ['test1', 'test2']
101
        ];
102
    }
103
104
    /**
105
     * Tests that no invitation gets sent out without requisite permissions.
106
     */
107
    public function testSendInvitePermissionDenied()
108
    {
109
        $this->loginInAsSomeone('john');
110
        /** @var Form $form */
111
        $data = $this->invitationData();
112
        $response = $this->controller->sendInvite($data,
113
            $this->controller->InvitationForm()->loadDataFrom($data));
114
        $invitation = UserInvitation::get()->filter('Email', $data['Email']);
115
        $this->assertCount(0, $invitation);
116
        $this->assertEquals(302, $response->getStatusCode());
117
    }
118
119
    /**
120
     * Tests whether switching the UserInvitation::force_require_group has an effect or not
121
     */
122
    public function testGroupFieldNotRequired()
123
    {
124
        $this->loginInAsSomeone('jane');
125
        $data = [
126
            'FirstName' => 'Joe',
127
            'Email' => '[email protected]',
128
            'Groups' => ['test1', 'test2']
129
        ];
130
        $form = $this->controller->InvitationForm()->loadDataFrom($data);
131
        $this->assertTrue($form->validationResult()->isValid());
132
133
        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

133
        Config::inst()->/** @scrutinizer ignore-call */ update(UserInvitation::class, 'force_require_group',
Loading history...
134
            true);
135
        unset($data['Groups']);
136
        $form = $this->controller->InvitationForm()->loadDataFrom($data);
137
        $this->assertFalse($form->validationResult()->isValid());
138
    }
139
140
    private function loginInAsSomeone($name)
141
    {
142
        /** @var Member $member */
143
        $member = $this->objFromFixture(Member::class, $name);
144
        $this->logInAs($member);
145
    }
146
147
    /**
148
     * Tests for 403 if no ID parameter given
149
     */
150
    public function testAcceptForbiddenError()
151
    {
152
        $response = $this->get($this->controller->Link('accept'));
153
        $this->assertEquals(403, $response->getStatusCode());
154
    }
155
156
    /**
157
     * Tests for expired TempHash and that it redirects to the expired page
158
     */
159
    public function testAcceptExpiredTempHash()
160
    {
161
        /** @var UserInvitation $invitation */
162
        $invitation = $this->objFromFixture(UserInvitation::class, 'expired');
163
        $response = $this->get($this->controller->Link('accept/' . $invitation->TempHash));
164
        $this->assertEquals(302, $response->getStatusCode());
165
        $base = Director::absoluteBaseURL();
166
        $this->assertEquals('user/expired',
167
            str_replace($base, '', $response->getHeader('Location')));
168
    }
169
170
    /**
171
     * Tests if a form is returned and that expected fields are present
172
     */
173
    public function testAcceptForm()
174
    {
175
        $form = $this->controller->AcceptForm();
176
        $this->assertInstanceOf(Form::class, $form);
177
        $this->assertNotNull($form->Fields()->fieldByName('FirstName'));
178
        $this->assertNull($form->Fields()->fieldByName('Email'));
179
        $this->assertNotNull($form->Fields()->fieldByName('HashID'));
180
        $this->assertNotNull($form->Fields()->fieldByName('Surname'));
181
    }
182
183
    /**
184
     * Tests that redirected to not found if has not found
185
     */
186
    public function testSaveInviteWrongHashError()
187
    {
188
        $data = [
189
            'HashID' => '432'
190
        ];
191
        $response = $this->controller->saveInvite($data,
192
            $this->controller->AcceptForm()->loadDataFrom($data));
193
        $this->assertEquals(302, $response->getStatusCode());
194
        $base = Director::absoluteBaseURL();
195
        $this->assertEquals('user/notfound',
196
            str_replace($base, '', $response->getHeader('Location')));
197
    }
198
199
    public function testSaveInvite()
200
    {
201
        /** @var UserInvitation $invitation */
202
        $invitation = $this->objFromFixture(UserInvitation::class, 'joe');
203
        $data = [
204
            'HashID' => $invitation->TempHash,
205
            'FirstName' => $invitation->FirstName,
206
            'Surname' => 'Soap',
207
            'Password' => [
208
                '_Password' => 'password',
209
                '_ConfirmPassword' => 'password'
210
            ]
211
        ];
212
213
        $response = $this->controller->saveInvite($data,
214
            $this->controller->AcceptForm()->loadDataFrom($data));
215
        $this->assertEquals(302, $response->getStatusCode());
216
        $base = Director::absoluteBaseURL();
217
        $this->assertEquals('user/success',
218
            str_replace($base, '', $response->getHeader('Location')));
219
220
        // Assert that invitation is deleted
221
        $this->assertNull(UserInvitation::get()->filter('Email',
222
            $invitation->Email)->first());
223
224
        /** @var Member $joe */
225
        $joe = Member::get()->filter('Email', $invitation->Email)->first();
226
        // Assert that member is created
227
        $this->assertTrue($joe->exists());
228
229
        // Assert that member belongs to the groups selected
230
        $this->assertTrue($joe->inGroup($this->objFromFixture(Group::class,
231
            'test1')));
232
        $this->assertTrue($joe->inGroup($this->objFromFixture(Group::class,
233
            'test2')));
234
    }
235
236
    /**
237
     * Tests that a login link is presented to the user
238
     */
239
    public function testSuccess()
240
    {
241
        $this->logoutMember();
242
        $response = $this->get($this->controller->Link('success'));
243
        $body = Convert::nl2os($response->getBody(), '');
244
        $this->assertContains('Congratulations!', $body);
245
        $this->assertContains('You are now a registered member', $body);
246
        $security = Injector::inst()->get(Security::class);
247
        $link = $security->Link('login');
248
        $this->assertContains("<a href=\"{$link}\">", $body);
249
    }
250
251
    /**
252
     * Tests that the expired action is shown
253
     */
254
    public function testExpired()
255
    {
256
        $this->logoutMember();
257
        $response = $this->get($this->controller->Link('expired'));
258
        $body = Convert::nl2os($response->getBody(), '');
259
        $this->assertContains('Invitation expired', $body);
260
        $this->assertContains('Oops, you took too long to accept this invitation',
261
            $body);
262
    }
263
264
    /**
265
     * Tests that the notfound action is shown.
266
     */
267
    public function testNotFound()
268
    {
269
        $this->logoutMember();
270
        $response = $this->get($this->controller->Link('notfound'));
271
        $body = Convert::nl2os($response->getBody(), '');
272
        $this->assertContains('Invitation not found', $body);
273
        $this->assertContains('Oops, the invitation ID was not found.', $body);
274
    }
275
276
    /**
277
     * Tests whether links are correctly re-written.
278
     */
279
    public function testLink()
280
    {
281
        $this->assertEquals('user/accept', $this->controller->Link('accept'));
282
        $this->assertEquals('user/index', $this->controller->Link('index'));
283
    }
284
285
    /**
286
     * Tests that the array key is returned
287
     */
288
    public function testProvidePermissions()
289
    {
290
        $permissions = $this->controller->providePermissions();
291
        $this->assertArrayHasKey('ACCESS_USER_INVITATIONS', $permissions);
292
        $this->assertArrayHasKey('name',
293
            $permissions['ACCESS_USER_INVITATIONS']);
294
        $this->assertArrayHasKey('category',
295
            $permissions['ACCESS_USER_INVITATIONS']);
296
    }
297
}
298