ClientTest::getClientEntityFailureProvider()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 6
c 1
b 0
f 0
dl 0
loc 8
rs 10
cc 1
nc 1
nop 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace AbterPhp\Admin\Oauth2\Repository;
6
7
use AbterPhp\Admin\Exception\Database;
8
use AbterPhp\Admin\Oauth2\Entity\Client as Entity;
9
use AbterPhp\Framework\Crypto\Crypto;
10
use AbterPhp\Framework\TestCase\Database\QueryTestCase;
11
use AbterPhp\Framework\TestDouble\Database\MockStatementFactory;
12
use PHPUnit\Framework\MockObject\MockObject;
13
14
class ClientTest extends QueryTestCase
15
{
16
    /** @var Client - System Under Test */
17
    protected $sut;
18
19
    /** @var Crypto|MockObject */
20
    protected $cryptoMock;
21
22
    public function setUp(): void
23
    {
24
        parent::setUp();
25
26
        $this->cryptoMock = $this->createMock(Crypto::class);
27
        $this->cryptoMock->expects($this->any())->method('prepareSecret')->willReturnArgument(0);
28
29
        $this->sut = new Client($this->cryptoMock, $this->connectionPoolMock);
30
    }
31
32
    /**
33
     * @return array
34
     */
35
    public function getClientEntitySuccessProvider(): array
36
    {
37
        return [
38
            'no-null'             => ['grant-type-0', 'client-secret-0', false, ['secret' => 'secret-0']],
39
            'null-grant-type'     => [null, 'client-secret-0', false, ['secret' => 'secret-0']],
40
            'null-client-secret'  => ['grant-type-0', null, false, ['secret' => 'secret-0']],
41
            'validate-no-null'    => ['grant-type-0', 'client-secret-0', true, ['secret' => 'secret-0']],
42
            'validate-grant-null' => [null, 'client-secret-0', true, ['secret' => 'secret-0']],
43
        ];
44
    }
45
46
    /**
47
     * @dataProvider getClientEntitySuccessProvider
48
     *
49
     * @param string|null $grantType
50
     * @param string|null $clientSecret
51
     * @param bool        $mustValidateSecret
52
     * @param array       $clientData
53
     */
54
    public function testGetClientEntitySuccess(
55
        ?string $grantType,
56
        ?string $clientSecret,
57
        bool $mustValidateSecret,
58
        array $clientData
59
    ) {
60
        $clientIdentifier = 'client-0';
61
62
        $this->cryptoMock->expects($this->any())->method('verifySecret')->willReturn(true);
63
64
        $sql0          = 'SELECT ac.secret FROM api_clients AS ac WHERE (ac.deleted_at IS NULL) AND (ac.id = :clientId)'; // phpcs:ignore
65
        $valuesToBind0 = [
66
            'clientId' => [$clientIdentifier, \PDO::PARAM_STR],
67
        ];
68
        $statement0    = MockStatementFactory::createReadRowStatement($this, $valuesToBind0, $clientData);
69
70
        $this->readConnectionMock
71
            ->expects($this->exactly(1))
72
            ->method('prepare')
73
            ->withConsecutive([$sql0])
74
            ->willReturnOnConsecutiveCalls($statement0);
75
76
        $actualResult = $this->sut->getClientEntity($clientIdentifier, $grantType, $clientSecret, $mustValidateSecret);
77
78
        $this->assertInstanceOf(Entity::class, $actualResult);
79
    }
80
81
    /**
82
     * @return array
83
     */
84
    public function getClientEntityFailureProvider(): array
85
    {
86
        return [
87
            'weird-secret-stored'  => ['foo', false, [], true],
88
            'no-secret-stored'     => ['foo', false, ['secret' => ''], true],
89
            'validate-wo-secret-1' => ['', true, ['secret' => 'secret-0'], true],
90
            'validate-wo-secret-2' => [null, true, ['secret' => 'secret-0'], true],
91
            'secrets-dont-match'   => ['foo', true, ['secret' => 'secret-0'], false],
92
        ];
93
    }
94
95
    /**
96
     * @dataProvider getClientEntityFailureProvider
97
     *
98
     * @param string|null $clientSecret
99
     * @param bool        $mustValidateSecret
100
     * @param array       $clientData
101
     * @param bool        $secretsMatch
102
     */
103
    public function testGetClientEntityFailure(
104
        ?string $clientSecret,
105
        bool $mustValidateSecret,
106
        array $clientData,
107
        bool $secretsMatch
108
    ) {
109
        $clientIdentifier = 'client-0';
110
        $grantType        = 'grant-type-0';
111
112
        $this->cryptoMock->expects($this->any())->method('verifySecret')->willReturn($secretsMatch);
113
114
        $sql0          = 'SELECT ac.secret FROM api_clients AS ac WHERE (ac.deleted_at IS NULL) AND (ac.id = :clientId)'; // phpcs:ignore
115
        $valuesToBind0 = [
116
            'clientId' => [$clientIdentifier, \PDO::PARAM_STR],
117
        ];
118
        $statement0    = MockStatementFactory::createReadRowStatement($this, $valuesToBind0, $clientData);
119
120
        $this->readConnectionMock
121
            ->expects($this->exactly(1))
122
            ->method('prepare')
123
            ->withConsecutive([$sql0])
124
            ->willReturnOnConsecutiveCalls($statement0);
125
126
        $actualResult = $this->sut->getClientEntity($clientIdentifier, $grantType, $clientSecret, $mustValidateSecret);
127
128
        $this->assertNull($actualResult);
129
    }
130
131
    public function testGetClientEntityThrowsExceptionOnDbFailure()
132
    {
133
        $expectedCode    = 17;
134
        $expectedMessage = 'Foo is great before: FROM api_clients AS ac';
135
136
        $this->expectException(Database::class);
137
        $this->expectExceptionCode($expectedCode);
138
        $this->expectExceptionMessage($expectedMessage);
139
140
        $clientSecret       = 'client-secret-0';
141
        $mustValidateSecret = false;
142
        $secretsMatch       = true;
143
144
        $clientIdentifier = 'client-0';
145
        $grantType        = 'grant-type-0';
146
147
        $this->cryptoMock->expects($this->any())->method('verifySecret')->willReturn($secretsMatch);
148
149
        $sql0          = 'SELECT ac.secret FROM api_clients AS ac WHERE (ac.deleted_at IS NULL) AND (ac.id = :clientId)'; // phpcs:ignore
150
        $valuesToBind0 = [
151
            'clientId' => [$clientIdentifier, \PDO::PARAM_STR],
152
        ];
153
        $errorInfo0    = ['FOO', $expectedCode, $expectedMessage];
154
        $statement0    = MockStatementFactory::createErrorStatement($this, $valuesToBind0, $errorInfo0);
155
156
        $this->readConnectionMock
157
            ->expects($this->once())
158
            ->method('prepare')
159
            ->with($sql0)
160
            ->willReturn($statement0);
161
162
        $this->sut->getClientEntity($clientIdentifier, $grantType, $clientSecret, $mustValidateSecret);
163
    }
164
}
165