VerifyHandlerTest   A
last analyzed

Complexity

Total Complexity 5

Size/Duplication

Total Lines 72
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 5
eloc 32
dl 0
loc 72
rs 10
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
A testVerifyValidatesCodes() 0 7 1
A getVerifyTests() 0 8 1
A testVerifySendsNotification() 0 6 1
A scaffoldVerifyParams() 0 17 1
A testVerifyInvalidatesCodesThatHaveBeenUsed() 0 17 1
1
<?php
2
3
namespace SilverStripe\MFA\Tests\BackupCode;
4
5
use PHPUnit_Framework_MockObject_MockObject;
6
use SilverStripe\Control\HTTPRequest;
7
use SilverStripe\Dev\SapphireTest;
8
use SilverStripe\MFA\BackupCode\VerifyHandler;
9
use SilverStripe\MFA\Extension\MemberExtension;
10
use SilverStripe\MFA\Model\RegisteredMethod;
11
use SilverStripe\MFA\Service\Notification;
12
use SilverStripe\MFA\Store\StoreInterface;
13
use SilverStripe\ORM\DataObject;
14
use SilverStripe\Security\Member;
15
16
class VerifyHandlerTest extends SapphireTest
17
{
18
    protected static $fixture_file = 'VerifyHandlerTest.yml';
19
20
    /**
21
     * @dataProvider getVerifyTests
22
     */
23
    public function testVerifyValidatesCodes($expectedResult, $input, $message)
24
    {
25
        $handler = (new VerifyHandler())->setNotificationService($this->createMock(Notification::class));
26
27
        // Test a code with invalid characters
28
        list ($request, $store, $method) = $this->scaffoldVerifyParams($input);
29
        $this->assertSame($expectedResult, $handler->verify($request, $store, $method)->isSuccessful(), $message);
30
    }
31
32
    public function testVerifySendsNotification()
33
    {
34
        $handler = (new VerifyHandler())->setNotificationService((Notification::create()));
35
        list ($request, $store, $method) = $this->scaffoldVerifyParams('123456');
36
        $this->assertTrue($handler->verify($request, $store, $method)->isSuccessful());
37
        $this->assertEmailSent($store->getMember()->Email, null, '/recovery code was used/');
38
    }
39
40
    public function testVerifyInvalidatesCodesThatHaveBeenUsed()
41
    {
42
        $handler = (new VerifyHandler())->setNotificationService($this->createMock(Notification::class));
43
44
        // Test a code with invalid characters
45
        list ($request, $store, $method) = $this->scaffoldVerifyParams('123456');
46
        $this->assertTrue($handler->verify($request, $store, $method)->isSuccessful());
47
48
        $method = DataObject::get_by_id(RegisteredMethod::class, $method->ID);
49
        $codes = json_decode($method->Data, true);
50
51
        $this->assertCount(3, $codes, 'Only 3 codes remain against the method');
52
53
        list ($request, $store, $method) = $this->scaffoldVerifyParams('123456');
54
        $this->assertFalse(
55
            $handler->verify($request, $store, $method)->isSuccessful(),
56
            'Attempting to validate the previously used code now returns false'
57
        );
58
    }
59
60
    public function getVerifyTests()
61
    {
62
        return [
63
            [false, 'asw123', 'Invalid characters are handled'],
64
            [false, '', 'Empty codes are handled'],
65
            [false, null, 'Null input is handled'],
66
            [false, str_pad('', 10000, 'code'), 'Long codes are handled'],
67
            [true, '123456', 'Valid codes are valid'],
68
        ];
69
    }
70
71
    protected function scaffoldVerifyParams($userInput)
72
    {
73
        /** @var Member|MemberExtension $member */
74
        $member = $this->objFromFixture(Member::class, 'guy');
75
76
        /** @var HTTPRequest|PHPUnit_Framework_MockObject_MockObject $request */
77
        $request = $this->createMock(HTTPRequest::class);
78
        $request->expects($this->once())->method('getBody')->willReturn("{\"code\":\"{$userInput}\"}");
79
80
        /** @var StoreInterface|PHPUnit_Framework_MockObject_MockObject $store */
81
        $store = $this->createMock(StoreInterface::class);
82
        $store->expects($this->any())->method('getMember')->willReturn($member);
83
84
        /** @var RegisteredMethod $registeredMethod */
85
        $registeredMethod = $member->RegisteredMFAMethods()->first();
86
87
        return [$request, $store, $registeredMethod];
88
    }
89
}
90