Failed Conditions
Push — master ( 12e8b5...0c68f2 )
by Sylvain
18s queued 15s
created

HasOtpTest.php$1 ➔ testVerifySecret()   A

Complexity

Conditions 1

Size

Total Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 16
rs 9.7333
cc 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace EcodevTests\Felix\Model\Traits;
6
7
use Ecodev\Felix\Model\Traits\HasOtp;
8
use OTPHP\Factory;
9
use OTPHP\TOTPInterface;
10
use PHPUnit\Framework\TestCase;
11
12
final class HasOtpTest extends TestCase
13
{
14
    private \Ecodev\Felix\Model\HasOtp $user;
15
16
    protected function setUp(): void
17
    {
18
        $this->user = new class() implements \Ecodev\Felix\Model\HasOtp {
19
            use HasOtp;
20
21
            public function getLogin(): ?string
22
            {
23
                return '[email protected]';
24
            }
25
        };
26
    }
27
28
    public function testCreateOtpSecret(): void
29
    {
30
        self::assertNull($this->user->getOtpUri(), 'should have no OTP secret at first');
31
        self::assertFalse($this->user->isOtp(), 'should have OTP disabled at first');
32
33
        $this->user->createOtpSecret('felix.lan');
34
        $otp1 = $this->user->getOtpUri();
35
        self::assertIsString($otp1);
36
        self::assertStringStartsWith('otpauth://totp/', $otp1, 'TOTP provisionning URI was generated and stored');
0 ignored issues
show
Bug introduced by
It seems like $otp1 can also be of type null; however, parameter $string of PHPUnit\Framework\Assert::assertStringStartsWith() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

36
        self::assertStringStartsWith('otpauth://totp/', /** @scrutinizer ignore-type */ $otp1, 'TOTP provisionning URI was generated and stored');
Loading history...
37
38
        $this->user->createOtpSecret('felix.lan');
39
        $otp2 = $this->user->getOtpUri();
40
        self::assertIsString($otp2);
41
        self::assertNotSame($otp1, $otp2, 'TOTP provisionning URI was changed');
42
43
        $this->user->setOtp(true);
44
        self::assertTrue($this->user->isOtp());
45
    }
46
47
    public function testCreateOtpSecretWillThrowWithoutSecret(): void
48
    {
49
        $this->expectExceptionMessage('Cannot enable OTP without a secret');
50
        $this->user->setOtp(true);
51
    }
52
53
    public function testCreateOtpSecretWillThrowWithoutLogin(): void
54
    {
55
        $user = new class() implements \Ecodev\Felix\Model\HasOtp {
56
            use HasOtp;
57
58
            public function getLogin(): ?string
59
            {
60
                return null;
61
            }
62
        };
63
64
        $this->expectExceptionMessage('User must have a login to initialize OTP');
65
        $user->createOtpSecret('felix.lan');
66
    }
67
68
    public function testRevokeSecret(): void
69
    {
70
        $this->user->createOtpSecret('felix.lan');
71
        $this->user->revokeOtpSecret();
72
73
        self::assertFalse($this->user->isOtp());
74
        self::assertNull($this->user->getOtpUri());
75
    }
76
77
    public function testVerifySecret(): void
78
    {
79
        $this->user->setOtp(false);
80
        self::assertFalse($this->user->verifyOtp('123456'), 'Cannot verify OTP with 2FA disabled');
81
82
        $this->user->createOtpSecret('felix.lan');
83
        $this->user->setOtp(true);
84
85
        self::assertFalse($this->user->verifyOtp('123456'), 'Wrong OTP given');
86
87
        $uri = $this->user->getOtpUri();
88
        self::assertNotNull($uri);
89
90
        $otp = Factory::loadFromProvisioningUri($uri);
0 ignored issues
show
Bug introduced by
It seems like $uri can also be of type null; however, parameter $uri of OTPHP\Factory::loadFromProvisioningUri() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

90
        $otp = Factory::loadFromProvisioningUri(/** @scrutinizer ignore-type */ $uri);
Loading history...
91
        self::assertInstanceOf(TOTPInterface::class, $otp);
92
        self::assertTrue($this->user->verifyOtp($otp->now()), 'Correct OTP given');
0 ignored issues
show
Bug introduced by
The method now() does not exist on OTPHP\HOTP. ( Ignorable by Annotation )

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

92
        self::assertTrue($this->user->verifyOtp($otp->/** @scrutinizer ignore-call */ now()), 'Correct OTP given');

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
93
    }
94
}
95