DataMapperAdapterTest   D
last analyzed

Complexity

Total Complexity 59

Size/Duplication

Total Lines 1097
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 11

Importance

Changes 31
Bugs 4 Features 4
Metric Value
wmc 59
c 31
b 4
f 4
lcom 1
cbo 11
dl 0
loc 1097
rs 4.7673

48 Methods

Rating   Name   Duplication   Size   Complexity  
A setUp() 0 20 2
A testConstructor() 0 7 1
B testGetAccessToken() 0 24 1
A testGetAccessTokenWithNullUser() 0 23 1
A testGetAccessTokenWithInvalidToken() 0 17 1
A testSetAccessToken() 0 52 1
B testSetAccessTokenWithExistingToken() 0 31 1
B testGetAuthorizationCode() 0 25 1
A testGetAuthorizationCodeWithInvalidToken() 0 17 1
A testSetAuthorizationCode() 0 61 1
B testSetAuthorizationCodeWithExistingToken() 0 39 1
B testExpireAuthorizationCode() 0 24 1
B testCheckClientCredentials() 0 24 3
A checkClientCredentialsProvider() 0 9 1
A testIsPublicClient() 0 17 3
A isPublicClientProvider() 0 9 1
A testGetClientDetails() 0 15 2
A getClientDetailsProvider() 0 20 1
A testGetClientScope() 0 17 1
A testGetClientScopeWithInvalidId() 0 16 1
A testCheckRestrictedGrantType() 0 17 2
A checkRestrictedGrantTypeProvider() 0 11 1
B testGetRefreshToken() 0 25 1
A testGetRefreshTokenWithNullUser() 0 20 1
A testGetRefreshTokenWithInvalidToken() 0 17 1
A testSetRefreshToken() 0 52 1
B testSetRefreshTokenWithExistingToken() 0 31 1
A testUnsetRefreshToken() 0 21 1
A testUnsetRefreshTokenWithInvalidToken() 0 18 1
B testScopeExists() 0 25 2
A scopeExistsProvider() 0 12 1
A testGetDefaultScope() 0 17 1
B getDefaultScopeProvider() 0 46 1
A testCheckUserCredentials() 0 23 2
A checkUserCredentialsProvider() 0 9 1
A testGetUserDetails() 0 15 2
A getUserDetailsProvider() 0 13 1
A testUserClassSetterChangesUserDataMapper() 0 15 1
A testUserClassSetterThrowsException() 0 14 1
A testHasDefaultUserCredentialsStrategy() 0 8 1
A testCanDisableDefaultUserCredentialsStrategyViaConstructor() 0 5 1
A testAddUserCredentialsStrategy() 0 11 2
A strategyProvider() 0 8 1
A testRemoveUserCredentialsStrategy() 0 6 1
B testCheckUserCredentialsWillUseStrategyIfAvailable() 0 25 1
B testCheckUserCredentialsWillUseStrategyCallableIfAvailable() 0 27 1
A testCheckUserCredentialsThrowsIfInvalidDataMapperIsUsed() 0 9 1
A setDataMapperMock() 0 4 1

How to fix   Complexity   

Complex Class

Complex classes like DataMapperAdapterTest often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use DataMapperAdapterTest, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * @author Stefano Torresi (http://stefanotorresi.it)
4
 * @license See the file LICENSE.txt for copying permission.
5
 * ************************************************
6
 */
7
8
namespace Thorr\OAuth2\Test\Storage;
9
10
use DateTime;
11
use DomainException;
12
use InvalidArgumentException;
13
use PHPUnit_Framework_MockObject_MockObject as MockObject;
14
use PHPUnit_Framework_TestCase as TestCase;
15
use Thorr\OAuth2\DataMapper;
16
use Thorr\OAuth2\Entity;
17
use Thorr\OAuth2\GrantType\UserCredentials\PasswordStrategy;
18
use Thorr\OAuth2\GrantType\UserCredentials\UserCredentialsStrategyInterface;
19
use Thorr\OAuth2\Storage\DataMapperAdapter;
20
use Thorr\OAuth2\Test\Asset\ScopeAwareUser;
21
use Thorr\Persistence\DataMapper\DataMapperInterface;
22
use Thorr\Persistence\DataMapper\EntityFinderInterface;
23
use Thorr\Persistence\DataMapper\Manager\DataMapperManager;
24
use Zend\Crypt\Password\PasswordInterface;
25
use Zend\Math\Rand;
26
27
/**
28
 * @covers Thorr\OAuth2\Storage\DataMapperAdapter
29
 */
30
class DataMapperAdapterTest extends TestCase
31
{
32
    /**
33
     * @var DataMapperManager|MockObject
34
     */
35
    protected $dataMapperManager;
36
37
    /**
38
     * @var PasswordInterface|MockObject
39
     */
40
    protected $password;
41
42
    /**
43
     * @var array
44
     */
45
    protected $dataMapperMocks = [];
46
47
    /**
48
     *
49
     */
50
    protected function setUp()
51
    {
52
        $this->dataMapperManager = $this->getMock(DataMapperManager::class);
53
        $this->password          = $this->getMock(PasswordInterface::class);
54
55
        $this->dataMapperManager->expects($this->any())
56
            ->method('getDataMapperForEntity')
57
            ->willReturnCallback(function ($entityClassName) {
58
                if (! isset($this->dataMapperMocks[$entityClassName])) {
59
                    throw new DomainException(sprintf(
60
                        "Missing DataMapper mock for entity '%s'.\n" .
61
                        "You can add it to the DataMapperManager mock via '%s::setDataMapperMock()'",
62
                        $entityClassName,
63
                        __CLASS__
64
                    ));
65
                }
66
67
                return $this->dataMapperMocks[$entityClassName];
68
            });
69
    }
70
71
    public function testConstructor()
72
    {
73
        $dataMapperAdapter = new DataMapperAdapter($this->dataMapperManager, $this->password);
74
75
        $this->assertSame($this->dataMapperManager, $dataMapperAdapter->getDataMapperManager());
76
        $this->assertSame($this->password, $dataMapperAdapter->getPassword());
77
    }
78
79
    public function testGetAccessToken()
80
    {
81
        $dataMapperAdapter = new DataMapperAdapter($this->dataMapperManager, $this->password);
82
        $client            = new Entity\Client();
83
        $user              = new Entity\User();
84
        $token             = Rand::getString(32);
85
        $accessToken       = new Entity\AccessToken(null, $token, $client, $user);
86
87
        $tokenDataMapper = $this->getMock(DataMapper\TokenMapperInterface::class);
88
        $tokenDataMapper->expects($this->any())
89
            ->method('findByToken')
90
            ->with($token)
91
            ->willReturn($accessToken);
92
93
        $this->setDataMapperMock(Entity\AccessToken::class, $tokenDataMapper);
94
95
        $tokenArray = $dataMapperAdapter->getAccessToken($token);
96
97
        $this->assertInternalType('array', $tokenArray);
98
        $this->assertEquals($accessToken->getExpiryUTCTimestamp(), $tokenArray['expires']);
99
        $this->assertEquals($accessToken->getClient()->getUuid(), $tokenArray['client_id']);
100
        $this->assertEquals($accessToken->getUser()->getUuid(), $tokenArray['user_id']);
101
        $this->assertEquals($accessToken->getScopesString(), $tokenArray['scope']);
102
    }
103
104
    public function testGetAccessTokenWithNullUser()
105
    {
106
        $dataMapperAdapter = new DataMapperAdapter($this->dataMapperManager, $this->password);
107
        $client            = new Entity\Client();
108
        $token             = Rand::getString(32);
109
        $accessToken       = new Entity\AccessToken(null, $token, $client);
110
111
        $tokenDataMapper = $this->getMock(DataMapper\TokenMapperInterface::class);
112
        $tokenDataMapper->expects($this->any())
113
            ->method('findByToken')
114
            ->with($token)
115
            ->willReturn($accessToken);
116
117
        $this->setDataMapperMock(Entity\AccessToken::class, $tokenDataMapper);
118
119
        $tokenArray = $dataMapperAdapter->getAccessToken($token);
120
121
        $this->assertInternalType('array', $tokenArray);
122
        $this->assertEquals($accessToken->getExpiryUTCTimestamp(), $tokenArray['expires']);
123
        $this->assertEquals($accessToken->getClient()->getUuid(), $tokenArray['client_id']);
124
        $this->assertNull($tokenArray['user_id']);
125
        $this->assertEquals($accessToken->getScopesString(), $tokenArray['scope']);
126
    }
127
128
    public function testGetAccessTokenWithInvalidToken()
129
    {
130
        $dataMapperAdapter = new DataMapperAdapter($this->dataMapperManager, $this->password);
131
        $token             = Rand::getString(32);
132
133
        $tokenDataMapper = $this->getMock(DataMapper\TokenMapperInterface::class);
134
        $tokenDataMapper->expects($this->any())
135
            ->method('findByToken')
136
            ->with($token)
137
            ->willReturn(null);
138
139
        $this->setDataMapperMock(Entity\AccessToken::class, $tokenDataMapper);
140
141
        $tokenArray = $dataMapperAdapter->getAccessToken($token);
142
143
        $this->assertNull($tokenArray);
144
    }
145
146
    public function testSetAccessToken()
147
    {
148
        $dataMapperAdapter  = new DataMapperAdapter($this->dataMapperManager, $this->password);
149
        $token              = Rand::getString(32);
150
        $client             = new Entity\Client();
151
        $user               = new Entity\User();
152
        $expiryUTCTimestamp = time() + 1000;
153
        $scopeNames         = ['someScope', 'someOtherScope'];
154
        $scopeString        = implode(' ', $scopeNames);
155
        $scopes             = [new Entity\Scope(null, $scopeNames[0]), new Entity\Scope(null, $scopeNames[1])];
156
157
        $clientDataMapper = $this->getMock(EntityFinderInterface::class);
158
        $clientDataMapper->expects($this->any())
159
            ->method('findByUuid')
160
            ->with($client->getUuid())
161
            ->willReturn($client);
162
163
        $userDataMapper = $this->getMock(DataMapper\UserMapperInterface::class);
164
        $userDataMapper->expects($this->any())
165
            ->method('findByUuid')
166
            ->with($user->getUuid())
167
            ->willReturn($user);
168
169
        $scopeDataMapper = $this->getMock(DataMapper\ScopeMapperInterface::class);
170
        $scopeDataMapper->expects($this->any())
171
            ->method('findScopes')
172
            ->with($scopeNames)
173
            ->willReturn($scopes);
174
175
        $tokenDataMapper = $this->getMock(DataMapper\TokenMapperInterface::class);
176
        $tokenDataMapper->expects($this->atLeastOnce())
177
            ->method('save')
178
            ->with($this->callback(function ($accessToken) use ($token, $client, $user, $expiryUTCTimestamp, $scopeString) {
179
                /* @var Entity\AccessToken $accessToken */
180
                $this->assertInstanceOf(Entity\AccessToken::class, $accessToken);
181
                $this->assertEquals($token, $accessToken->getToken());
182
                $this->assertSame($client, $accessToken->getClient());
183
                $this->assertSame($user, $accessToken->getUser());
184
                $this->assertSame($expiryUTCTimestamp, $accessToken->getExpiryUTCTimestamp());
185
                $this->assertCount(2, $accessToken->getScopes());
186
                $this->assertEquals($scopeString, $accessToken->getScopesString());
187
188
                return true;
189
            }));
190
191
        $this->setDataMapperMock(Entity\Client::class, $clientDataMapper);
192
        $this->setDataMapperMock(Entity\UserInterface::class, $userDataMapper);
193
        $this->setDataMapperMock(Entity\Scope::class, $scopeDataMapper);
194
        $this->setDataMapperMock(Entity\AccessToken::class, $tokenDataMapper);
195
196
        $dataMapperAdapter->setAccessToken($token, $client->getUuid(), $user->getUuid(), $expiryUTCTimestamp, $scopeString);
197
    }
198
199
    public function testSetAccessTokenWithExistingToken()
200
    {
201
        $dataMapperAdapter = new DataMapperAdapter($this->dataMapperManager, $this->password);
202
        $token             = Rand::getString(32);
203
        $client            = new Entity\Client();
204
        $newClient         = new Entity\Client();
205
        $accessToken       = new Entity\AccessToken(null, $token, $client);
206
207
        $clientDataMapper = $this->getMock(EntityFinderInterface::class);
208
        $clientDataMapper->expects($this->any())
209
            ->method('findByUuid')
210
            ->with($newClient->getUuid())
211
            ->willReturn($newClient);
212
213
        $tokenDataMapper = $this->getMock(DataMapper\TokenMapperInterface::class);
214
        $tokenDataMapper->expects($this->any())
215
            ->method('findByToken')
216
            ->with($token)
217
            ->willReturn($accessToken);
218
219
        $tokenDataMapper->expects($this->atLeastOnce())
220
            ->method('save')
221
            ->with($accessToken);
222
223
        $this->setDataMapperMock(Entity\Client::class, $clientDataMapper);
224
        $this->setDataMapperMock(Entity\AccessToken::class, $tokenDataMapper);
225
226
        $dataMapperAdapter->setAccessToken($token, $newClient->getUuid(), null, null, null);
227
228
        $this->assertSame($newClient, $accessToken->getClient());
229
    }
230
231
    public function testGetAuthorizationCode()
232
    {
233
        $dataMapperAdapter = new DataMapperAdapter($this->dataMapperManager, $this->password);
234
        $client            = new Entity\Client();
235
        $user              = new Entity\User();
236
        $token             = Rand::getString(32);
237
        $authCode          = new Entity\AuthorizationCode(null, $token, $client, $user, null, 'someUri');
238
239
        $tokenDataMapper = $this->getMock(DataMapper\TokenMapperInterface::class);
240
        $tokenDataMapper->expects($this->any())
241
            ->method('findByToken')
242
            ->with($token)
243
            ->willReturn($authCode);
244
245
        $this->setDataMapperMock(Entity\AuthorizationCode::class, $tokenDataMapper);
246
247
        $codeArray = $dataMapperAdapter->getAuthorizationCode($token);
248
249
        $this->assertInternalType('array', $codeArray);
250
        $this->assertEquals($authCode->getExpiryUTCTimestamp(), $codeArray['expires']);
251
        $this->assertEquals($authCode->getClient()->getUuid(), $codeArray['client_id']);
252
        $this->assertEquals($authCode->getUser()->getUuid(), $codeArray['user_id']);
253
        $this->assertEquals($authCode->getScopesString(), $codeArray['scope']);
254
        $this->assertEquals($authCode->getRedirectUri(), $codeArray['redirect_uri']);
255
    }
256
257
    public function testGetAuthorizationCodeWithInvalidToken()
258
    {
259
        $dataMapperAdapter = new DataMapperAdapter($this->dataMapperManager, $this->password);
260
        $token             = Rand::getString(32);
261
262
        $tokenDataMapper = $this->getMock(DataMapper\TokenMapperInterface::class);
263
        $tokenDataMapper->expects($this->any())
264
            ->method('findByToken')
265
            ->with($token)
266
            ->willReturn(null);
267
268
        $this->setDataMapperMock(Entity\AuthorizationCode::class, $tokenDataMapper);
269
270
        $tokenArray = $dataMapperAdapter->getAuthorizationCode($token);
271
272
        $this->assertNull($tokenArray);
273
    }
274
275
    public function testSetAuthorizationCode()
276
    {
277
        $dataMapperAdapter  = new DataMapperAdapter($this->dataMapperManager, $this->password);
278
        $token              = Rand::getString(32);
279
        $client             = new Entity\Client();
280
        $user               = new Entity\User();
281
        $expiryUTCTimestamp = time() + 1000;
282
        $redirectUri        = 'someUri';
283
        $scopeNames         = ['someScope', 'someOtherScope'];
284
        $scopeString        = implode(' ', $scopeNames);
285
        $scopes             = [new Entity\Scope(null, $scopeNames[0]), new Entity\Scope(null, $scopeNames[1])];
286
287
        $clientDataMapper = $this->getMock(EntityFinderInterface::class);
288
        $clientDataMapper->expects($this->any())
289
            ->method('findByUuid')
290
            ->with($client->getUuid())
291
            ->willReturn($client);
292
293
        $userDataMapper = $this->getMock(DataMapper\UserMapperInterface::class);
294
        $userDataMapper->expects($this->any())
295
            ->method('findByUuid')
296
            ->with($user->getUuid())
297
            ->willReturn($user);
298
299
        $scopeDataMapper = $this->getMock(DataMapper\ScopeMapperInterface::class);
300
        $scopeDataMapper->expects($this->any())
301
            ->method('findScopes')
302
            ->with($scopeNames)
303
            ->willReturn($scopes);
304
305
        $tokenDataMapper = $this->getMock(DataMapper\TokenMapperInterface::class);
306
        $tokenDataMapper->expects($this->atLeastOnce())
307
            ->method('save')
308
            ->with($this->callback(function ($authCode) use ($token, $client, $user, $redirectUri, $expiryUTCTimestamp, $scopeString) {
309
                /* @var Entity\AuthorizationCode $authCode */
310
                $this->assertInstanceOf(Entity\AuthorizationCode::class, $authCode);
311
                $this->assertEquals($token, $authCode->getToken());
312
                $this->assertSame($client, $authCode->getClient());
313
                $this->assertSame($user, $authCode->getUser());
314
                $this->assertSame($expiryUTCTimestamp, $authCode->getExpiryUTCTimestamp());
315
                $this->assertCount(2, $authCode->getScopes());
316
                $this->assertEquals($redirectUri, $authCode->getRedirectUri());
317
                $this->assertEquals($scopeString, $authCode->getScopesString());
318
319
                return true;
320
            }));
321
322
        $this->setDataMapperMock(Entity\Client::class, $clientDataMapper);
323
        $this->setDataMapperMock(Entity\UserInterface::class, $userDataMapper);
324
        $this->setDataMapperMock(Entity\Scope::class, $scopeDataMapper);
325
        $this->setDataMapperMock(Entity\AuthorizationCode::class, $tokenDataMapper);
326
327
        $dataMapperAdapter->setAuthorizationCode(
328
            $token,
329
            $client->getUuid(),
330
            $user->getUuid(),
331
            $redirectUri,
332
            $expiryUTCTimestamp,
333
            $scopeString
334
        );
335
    }
336
337
    public function testSetAuthorizationCodeWithExistingToken()
338
    {
339
        $dataMapperAdapter = new DataMapperAdapter($this->dataMapperManager, $this->password);
340
        $token             = Rand::getString(32);
341
        $client            = new Entity\Client();
342
        $user              = new Entity\User();
343
        $newClient         = new Entity\Client();
344
        $authCode          = new Entity\AuthorizationCode(null, $token, $client, $user, null, 'someUri');
345
346
        $clientDataMapper = $this->getMock(EntityFinderInterface::class);
347
        $clientDataMapper->expects($this->any())
348
            ->method('findByUuid')
349
            ->with($newClient->getUuid())
350
            ->willReturn($newClient);
351
352
        $userDataMapper = $this->getMock(DataMapper\UserMapperInterface::class);
353
        $userDataMapper->expects($this->any())
354
            ->method('findByUuid')
355
            ->with($user->getUuid())
356
            ->willReturn($user);
357
358
        $tokenDataMapper = $this->getMock(DataMapper\TokenMapperInterface::class);
359
        $tokenDataMapper->expects($this->any())
360
            ->method('findByToken')
361
            ->with($token)
362
            ->willReturn($authCode);
363
364
        $tokenDataMapper->expects($this->atLeastOnce())
365
            ->method('save')
366
            ->with($authCode);
367
368
        $this->setDataMapperMock(Entity\Client::class, $clientDataMapper);
369
        $this->setDataMapperMock(Entity\UserInterface::class, $userDataMapper);
370
        $this->setDataMapperMock(Entity\AuthorizationCode::class, $tokenDataMapper);
371
372
        $dataMapperAdapter->setAuthorizationCode($token, $newClient->getUuid(), $user->getUuid(), null, null);
373
374
        $this->assertSame($newClient, $authCode->getClient());
375
    }
376
377
    public function testExpireAuthorizationCode()
378
    {
379
        $dataMapperAdapter = new DataMapperAdapter($this->dataMapperManager, $this->password);
380
        $token             = Rand::getString(32);
381
        $client            = new Entity\Client();
382
        $authCode          = new Entity\AuthorizationCode(null, $token, $client, null, null, 'someUri');
383
        $expiryDate        = new DateTime('@' . (time() + 1000));
384
        $authCode->setExpiryDate($expiryDate);
385
386
        $tokenDataMapper = $this->getMock(DataMapper\TokenMapperInterface::class);
387
        $tokenDataMapper->expects($this->any())
388
            ->method('findByToken')
389
            ->with($token)
390
            ->willReturn($authCode);
391
392
        $tokenDataMapper->expects($this->atLeastOnce())
393
            ->method('save')
394
            ->with($authCode);
395
396
        $this->setDataMapperMock(Entity\AuthorizationCode::class, $tokenDataMapper);
397
398
        $dataMapperAdapter->expireAuthorizationCode($token);
399
        $this->assertTrue($authCode->getExpiryDate() <= new DateTime());
400
    }
401
402
    /**
403
     * @param Entity\Client $client
404
     * @param string        $secretToCheck
405
     * @param bool          $expectedResult
406
     *
407
     * @dataProvider checkClientCredentialsProvider
408
     */
409
    public function testCheckClientCredentials($client, $secretToCheck, $expectedResult)
410
    {
411
        $dataMapperAdapter = new DataMapperAdapter($this->dataMapperManager, $this->password);
412
413
        $clientDataMapper = $this->getMock(EntityFinderInterface::class);
414
        $clientDataMapper->expects($this->any())
415
            ->method('findByUuid')
416
            ->with($this->callback(function ($arg) use ($client) {
417
                return $client ? $client->getUuid() === $arg : $arg === 'invalid';
418
            }))
419
            ->willReturn($client);
420
421
        $this->setDataMapperMock(Entity\Client::class, $clientDataMapper);
422
423
        $this->password->expects($this->any())
0 ignored issues
show
Bug introduced by
The method expects does only exist in PHPUnit_Framework_MockObject_MockObject, but not in Zend\Crypt\Password\PasswordInterface.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
424
            ->method('verify')
425
            ->willReturnCallback(function () use ($client, $secretToCheck) {
426
                return $client->getSecret() === $secretToCheck;
427
            })
428
        ;
429
430
        $result = $dataMapperAdapter->checkClientCredentials($client ? $client->getUuid() : 'invalid', $secretToCheck);
431
        $this->assertSame($result, $expectedResult);
432
    }
433
434
    public function checkClientCredentialsProvider()
435
    {
436
        return [
437
            //  $client                                     $secretToCheck  $expectedResult
438
            [new Entity\Client(null, 'clientSecret'),    'clientSecret', true],
439
            [new Entity\Client(null, 'clientSecret'),    'bogus',        false],
440
            [null,                                       null,           false],
441
        ];
442
    }
443
444
    /**
445
     * @param Entity\Client $client
446
     * @param bool          $expectedResult
447
     *
448
     * @dataProvider isPublicClientProvider
449
     */
450
    public function testIsPublicClient($client, $expectedResult)
451
    {
452
        $dataMapperAdapter = new DataMapperAdapter($this->dataMapperManager, $this->password);
453
454
        $clientDataMapper = $this->getMock(EntityFinderInterface::class);
455
        $clientDataMapper->expects($this->any())
456
            ->method('findByUuid')
457
            ->with($this->callback(function ($arg) use ($client) {
458
                return $client ? $client->getUuid() === $arg : $arg === 'invalid';
459
            }))
460
            ->willReturn($client);
461
462
        $this->setDataMapperMock(Entity\Client::class, $clientDataMapper);
463
464
        $result = $dataMapperAdapter->isPublicClient($client ? $client->getUuid() : 'invalid');
465
        $this->assertSame($result, $expectedResult);
466
    }
467
468
    public function isPublicClientProvider()
469
    {
470
        return [
471
            //  $client                                     $expectedResult
472
            [new Entity\Client(null, 'clientSecret'),    false],
473
            [new Entity\Client(),                        true],
474
            [null,                                       false],
475
        ];
476
    }
477
478
    /**
479
     * @param Entity\Client|null $client
480
     * @param mixed              $expectedResult
481
     *
482
     * @dataProvider getClientDetailsProvider
483
     */
484
    public function testGetClientDetails($client, $expectedResult)
485
    {
486
        $dataMapperAdapter = new DataMapperAdapter($this->dataMapperManager, $this->password);
487
        $clientUuid        = $client ? $client->getUuid() : 'invalid';
488
489
        $clientDataMapper = $this->getMock(EntityFinderInterface::class);
490
        $clientDataMapper->expects($this->any())
491
            ->method('findByUuid')
492
            ->with($clientUuid)
493
            ->willReturn($client);
494
495
        $this->setDataMapperMock(Entity\Client::class, $clientDataMapper);
496
497
        $this->assertSame($expectedResult, $dataMapperAdapter->getClientDetails($clientUuid));
498
    }
499
500
    public function getClientDetailsProvider()
501
    {
502
        $client = new Entity\Client(null, null, new Entity\User(), ['foo', 'bar'], 'uri');
503
504
        return [
505
            [
506
                $client,
507
                [
508
                    'redirect_uri' => $client->getRedirectUri(),
509
                    'client_id'    => $client->getUuid(),
510
                    'grant_types'  => $client->getGrantTypes(),
511
                    'user_id'      => $client->getUser()->getUuid(),
512
                    'scope'        => $client->getScopesString(),
513
                ],
514
            ],
515
            [
516
                null, false,
517
            ],
518
        ];
519
    }
520
521
    public function testGetClientScope()
522
    {
523
        $dataMapperAdapter = new DataMapperAdapter($this->dataMapperManager, $this->password);
524
        $client            = new Entity\Client();
525
        $scopes            = [new Entity\Scope(null, 'someScope'), new Entity\Scope(null, 'someOtherScope')];
526
        $client->setScopes($scopes);
527
528
        $clientDataMapper = $this->getMock(EntityFinderInterface::class);
529
        $clientDataMapper->expects($this->any())
530
            ->method('findByUuid')
531
            ->with($client->getUuid())
532
            ->willReturn($client);
533
534
        $this->setDataMapperMock(Entity\Client::class, $clientDataMapper);
535
536
        $this->assertEquals($client->getScopesString(), $dataMapperAdapter->getClientScope($client->getUuid()));
537
    }
538
539
    public function testGetClientScopeWithInvalidId()
540
    {
541
        $dataMapperAdapter   = new DataMapperAdapter($this->dataMapperManager, $this->password);
542
        $bogusClientUuid     = 'invalid';
543
544
        $clientDataMapper = $this->getMock(EntityFinderInterface::class);
545
        $clientDataMapper->expects($this->any())
546
            ->method('findByUuid')
547
            ->with($bogusClientUuid)
548
            ->willReturn(null);
549
550
        $this->setDataMapperMock(Entity\Client::class, $clientDataMapper);
551
552
        $this->setExpectedException(InvalidArgumentException::class, 'Invalid client uuid');
553
        $dataMapperAdapter->getClientScope($bogusClientUuid);
554
    }
555
556
    /**
557
     * @param Entity\Client $client
558
     * @param string        $grantType
559
     * @param bool          $expectedResult
560
     *
561
     * @dataProvider checkRestrictedGrantTypeProvider
562
     */
563
    public function testCheckRestrictedGrantType($client, $grantType, $expectedResult)
564
    {
565
        $dataMapperAdapter = new DataMapperAdapter($this->dataMapperManager, $this->password);
566
        $clientUuid        = $client ? $client->getUuid() : 'invalid';
567
568
        $clientDataMapper = $this->getMock(EntityFinderInterface::class);
569
        $clientDataMapper->expects($this->any())
570
            ->method('findByUuid')
571
            ->with($clientUuid)
572
            ->willReturn($client);
573
574
        $this->setDataMapperMock(Entity\Client::class, $clientDataMapper);
575
576
        $result = $dataMapperAdapter->checkRestrictedGrantType($clientUuid, $grantType);
577
578
        $this->assertSame($expectedResult, $result);
579
    }
580
581
    public function checkRestrictedGrantTypeProvider()
582
    {
583
        return [
584
            //  $client                                                 $grantType  $expectedResult
585
            [new Entity\Client(null, null, null, ['foo', 'bar']),    'foo',      true,   ],
586
            [new Entity\Client(null, null, null, ['foo', 'bar']),    'bar',      true,   ],
587
            [new Entity\Client(null, null, null, ['foo', 'bar']),    'baz',      false,  ],
588
            [null,                                                   'bogus',    false,  ],
589
            [new Entity\Client(null, null, null),                    'anything', true,   ],
590
        ];
591
    }
592
593
    public function testGetRefreshToken()
594
    {
595
        $dataMapperAdapter = new DataMapperAdapter($this->dataMapperManager, $this->password);
596
        $client            = new Entity\Client();
597
        $user              = new Entity\User();
598
        $token             = Rand::getString(32);
599
        $refreshToken      = new Entity\RefreshToken(null, $token, $client, $user);
600
601
        $tokenDataMapper = $this->getMock(DataMapper\TokenMapperInterface::class);
602
        $tokenDataMapper->expects($this->any())
603
            ->method('findByToken')
604
            ->with($token)
605
            ->willReturn($refreshToken);
606
607
        $this->setDataMapperMock(Entity\RefreshToken::class, $tokenDataMapper);
608
609
        $tokenArray = $dataMapperAdapter->getRefreshToken($token);
610
611
        $this->assertInternalType('array', $tokenArray);
612
        $this->assertEquals($refreshToken->getToken(), $tokenArray['refresh_token']);
613
        $this->assertEquals($refreshToken->getExpiryUTCTimestamp(), $tokenArray['expires']);
614
        $this->assertEquals($refreshToken->getClient()->getUuid(), $tokenArray['client_id']);
615
        $this->assertEquals($refreshToken->getUser()->getUuid(), $tokenArray['user_id']);
616
        $this->assertEquals($refreshToken->getScopesString(), $tokenArray['scope']);
617
    }
618
619
    public function testGetRefreshTokenWithNullUser()
620
    {
621
        $dataMapperAdapter = new DataMapperAdapter($this->dataMapperManager, $this->password);
622
        $client            = new Entity\Client();
623
        $token             = Rand::getString(32);
624
        $refreshToken      = new Entity\RefreshToken(null, $token, $client);
625
626
        $tokenDataMapper = $this->getMock(DataMapper\TokenMapperInterface::class);
627
        $tokenDataMapper->expects($this->any())
628
            ->method('findByToken')
629
            ->with($token)
630
            ->willReturn($refreshToken);
631
632
        $this->setDataMapperMock(Entity\RefreshToken::class, $tokenDataMapper);
633
634
        $tokenArray = $dataMapperAdapter->getRefreshToken($token);
635
636
        $this->assertInternalType('array', $tokenArray);
637
        $this->assertNull($tokenArray['user_id']);
638
    }
639
640
    public function testGetRefreshTokenWithInvalidToken()
641
    {
642
        $dataMapperAdapter = new DataMapperAdapter($this->dataMapperManager, $this->password);
643
        $token             = Rand::getString(32);
644
645
        $tokenDataMapper = $this->getMock(DataMapper\TokenMapperInterface::class);
646
        $tokenDataMapper->expects($this->any())
647
            ->method('findByToken')
648
            ->with($token)
649
            ->willReturn(null);
650
651
        $this->setDataMapperMock(Entity\RefreshToken::class, $tokenDataMapper);
652
653
        $tokenArray = $dataMapperAdapter->getRefreshToken($token);
654
655
        $this->assertNull($tokenArray);
656
    }
657
658
    public function testSetRefreshToken()
659
    {
660
        $dataMapperAdapter  = new DataMapperAdapter($this->dataMapperManager, $this->password);
661
        $token              = Rand::getString(32);
662
        $client             = new Entity\Client();
663
        $user               = new Entity\User();
664
        $expiryUTCTimestamp = time() + 1000;
665
        $scopeNames         = ['someScope', 'someOtherScope'];
666
        $scopeString        = implode(' ', $scopeNames);
667
        $scopes             = [new Entity\Scope(null, $scopeNames[0]), new Entity\Scope(null, $scopeNames[1])];
668
669
        $clientDataMapper = $this->getMock(EntityFinderInterface::class);
670
        $clientDataMapper->expects($this->any())
671
            ->method('findByUuid')
672
            ->with($client->getUuid())
673
            ->willReturn($client);
674
675
        $userDataMapper = $this->getMock(DataMapper\UserMapperInterface::class);
676
        $userDataMapper->expects($this->any())
677
            ->method('findByUuid')
678
            ->with($user->getUuid())
679
            ->willReturn($user);
680
681
        $scopeDataMapper = $this->getMock(DataMapper\ScopeMapperInterface::class);
682
        $scopeDataMapper->expects($this->any())
683
            ->method('findScopes')
684
            ->with($scopeNames)
685
            ->willReturn($scopes);
686
687
        $tokenDataMapper = $this->getMock(DataMapper\TokenMapperInterface::class);
688
        $tokenDataMapper->expects($this->atLeastOnce())
689
            ->method('save')
690
            ->with($this->callback(function ($refreshToken) use ($token, $client, $user, $expiryUTCTimestamp, $scopeString) {
691
                /* @var Entity\RefreshToken $refreshToken */
692
                $this->assertInstanceOf(Entity\RefreshToken::class, $refreshToken);
693
                $this->assertEquals($token, $refreshToken->getToken());
694
                $this->assertSame($client, $refreshToken->getClient());
695
                $this->assertSame($user, $refreshToken->getUser());
696
                $this->assertSame($expiryUTCTimestamp, $refreshToken->getExpiryUTCTimestamp());
697
                $this->assertCount(2, $refreshToken->getScopes());
698
                $this->assertEquals($scopeString, $refreshToken->getScopesString());
699
700
                return true;
701
            }));
702
703
        $this->setDataMapperMock(Entity\Client::class, $clientDataMapper);
704
        $this->setDataMapperMock(Entity\UserInterface::class, $userDataMapper);
705
        $this->setDataMapperMock(Entity\Scope::class, $scopeDataMapper);
706
        $this->setDataMapperMock(Entity\RefreshToken::class, $tokenDataMapper);
707
708
        $dataMapperAdapter->setRefreshToken($token, $client->getUuid(), $user->getUuid(), $expiryUTCTimestamp, $scopeString);
709
    }
710
711
    public function testSetRefreshTokenWithExistingToken()
712
    {
713
        $dataMapperAdapter = new DataMapperAdapter($this->dataMapperManager, $this->password);
714
        $token             = Rand::getString(32);
715
        $client            = new Entity\Client();
716
        $newClient         = new Entity\Client();
717
        $refreshToken      = new Entity\RefreshToken(null, $token, $client);
718
719
        $clientDataMapper = $this->getMock(EntityFinderInterface::class);
720
        $clientDataMapper->expects($this->any())
721
            ->method('findByUuid')
722
            ->with($newClient->getUuid())
723
            ->willReturn($newClient);
724
725
        $tokenDataMapper = $this->getMock(DataMapper\TokenMapperInterface::class);
726
        $tokenDataMapper->expects($this->any())
727
            ->method('findByToken')
728
            ->with($token)
729
            ->willReturn($refreshToken);
730
731
        $tokenDataMapper->expects($this->atLeastOnce())
732
            ->method('save')
733
            ->with($refreshToken);
734
735
        $this->setDataMapperMock(Entity\Client::class, $clientDataMapper);
736
        $this->setDataMapperMock(Entity\RefreshToken::class, $tokenDataMapper);
737
738
        $dataMapperAdapter->setRefreshToken($token, $newClient->getUuid(), null, null, null);
739
740
        $this->assertSame($newClient, $refreshToken->getClient());
741
    }
742
743
    public function testUnsetRefreshToken()
744
    {
745
        $dataMapperAdapter = new DataMapperAdapter($this->dataMapperManager, $this->password);
746
        $token             = Rand::getString(32);
747
        $client            = new Entity\Client();
748
        $refreshToken      = new Entity\RefreshToken(null, $token, $client);
749
750
        $tokenDataMapper = $this->getMock(DataMapper\TokenMapperInterface::class);
751
        $tokenDataMapper->expects($this->any())
752
            ->method('findByToken')
753
            ->with($token)
754
            ->willReturn($refreshToken);
755
756
        $tokenDataMapper->expects($this->atLeastOnce())
757
            ->method('remove')
758
            ->with($refreshToken);
759
760
        $this->setDataMapperMock(Entity\RefreshToken::class, $tokenDataMapper);
761
762
        $dataMapperAdapter->unsetRefreshToken($token);
763
    }
764
765
    public function testUnsetRefreshTokenWithInvalidToken()
766
    {
767
        $dataMapperAdapter = new DataMapperAdapter($this->dataMapperManager, $this->password);
768
        $bogusToken        = 'invalid';
769
770
        $tokenDataMapper = $this->getMock(DataMapper\TokenMapperInterface::class);
771
        $tokenDataMapper->expects($this->any())
772
            ->method('findByToken')
773
            ->with($bogusToken)
774
            ->willReturn(null);
775
776
        $tokenDataMapper->expects($this->never())->method('remove');
777
778
        $this->setDataMapperMock(Entity\RefreshToken::class, $tokenDataMapper);
779
        $this->setExpectedException(InvalidArgumentException::class, 'Invalid token');
780
781
        $dataMapperAdapter->unsetRefreshToken($bogusToken);
782
    }
783
784
    /**
785
     * @param array  $scopeNames
786
     * @param string $inputScopeString
787
     * @param bool   $expectedResult
788
     *
789
     * @dataProvider scopeExistsProvider
790
     */
791
    public function testScopeExists($scopeNames, $inputScopeString, $expectedResult)
792
    {
793
        $dataMapperAdapter = new DataMapperAdapter($this->dataMapperManager, $this->password);
794
        $scopes            = [];
795
796
        foreach ($scopeNames as $name) {
797
            $scopes[] = new Entity\Scope(null, $name);
798
        }
799
800
        $scopeDataMapper = $this->getMock(DataMapper\ScopeMapperInterface::class);
801
        $scopeDataMapper->expects($this->any())
802
            ->method('findScopes')
803
            ->with(explode(' ', $inputScopeString))
804
            ->willReturnCallback(function ($inputScopes) use ($scopes) {
805
                return array_filter($scopes, function (Entity\Scope $scope) use ($inputScopes) {
806
                    return in_array($scope, $inputScopes);
807
                });
808
            });
809
810
        $this->setDataMapperMock(Entity\Scope::class, $scopeDataMapper);
811
812
        $result = $dataMapperAdapter->scopeExists($inputScopeString);
813
814
        $this->assertSame($expectedResult, $result);
815
    }
816
817
    public function scopeExistsProvider()
818
    {
819
        return [
820
            //  $scopeNames         $inputScopeString   $expectedResult
821
            [['foo', 'bar'],    'foo',              true],
822
            [['foo', 'bar'],    'bar',              true],
823
            [['foo', 'bar'],    'baz',              false],
824
            [['foo', 'bar'],    'baz bar',          false],
825
            [['bar', 'bar'],    'baz bar',          false],
826
            [[],                 'any',              false],
827
        ];
828
    }
829
830
    /**
831
     * @param $scopes
832
     * @param $expectedResult
833
     *
834
     * @dataProvider getDefaultScopeProvider
835
     */
836
    public function testGetDefaultScope($scopes, $expectedResult)
837
    {
838
        $dataMapperAdapter = new DataMapperAdapter($this->dataMapperManager, $this->password);
839
840
        $scopeDataMapper = $this->getMock(DataMapper\ScopeMapperInterface::class);
841
        $scopeDataMapper->expects($this->any())
842
            ->method('findDefaultScopes')
843
            ->willReturnCallback(function () use ($scopes) {
844
                return array_filter($scopes, function (Entity\Scope $scope) {
845
                    return $scope->isDefaultScope();
846
                });
847
            });
848
849
        $this->setDataMapperMock(Entity\Scope::class, $scopeDataMapper);
850
851
        $this->assertSame($expectedResult, $dataMapperAdapter->getDefaultScope());
852
    }
853
854
    public function getDefaultScopeProvider()
855
    {
856
        return [
857
            [
858
                // $scopes
859
                [
860
                    new Entity\Scope(null, 'foo', true),
861
                    new Entity\Scope(null, 'bar', true),
862
                    new Entity\Scope(null, 'baz', false),
863
                ],
864
                // $expected result
865
                'foo bar',
866
            ],
867
            [
868
                // $scopes
869
                [
870
                    new Entity\Scope(null, 'foo', true),
871
                    new Entity\Scope(null, 'bar', false),
872
                ],
873
                // $expected result
874
                'foo',
875
            ],
876
            [
877
                // $scopes
878
                [
879
                    new Entity\Scope(null, 'foo', true),
880
                ],
881
                // $expected result
882
                'foo',
883
            ],
884
            [
885
                // $scopes
886
                [
887
                    new Entity\Scope(null, 'foo', false),
888
                ],
889
                // $expected result
890
                null,
891
            ],
892
            [
893
                // $scopes
894
                [],
895
                // $expected result
896
                null,
897
            ],
898
        ];
899
    }
900
901
    /**
902
     * @param Entity\User|null $user
903
     * @param string           $secretToCheck
904
     * @param bool             $expectedResult
905
     *
906
     * @dataProvider checkUserCredentialsProvider
907
     */
908
    public function testCheckUserCredentials($user, $secretToCheck, $expectedResult)
909
    {
910
        $dataMapperAdapter = new DataMapperAdapter($this->dataMapperManager, $this->password);
911
        $userUuid          = $user ? $user->getUuid() : 'invalid';
912
913
        $userDataMapper = $this->getMock(DataMapper\UserMapperInterface::class);
914
        $userDataMapper->expects($this->any())
915
            ->method('findByCredential')
916
            ->with($userUuid)
917
            ->willReturn($user);
918
919
        $this->setDataMapperMock(Entity\UserInterface::class, $userDataMapper);
920
921
        $this->password->expects($this->any())
0 ignored issues
show
Bug introduced by
The method expects does only exist in PHPUnit_Framework_MockObject_MockObject, but not in Zend\Crypt\Password\PasswordInterface.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
922
            ->method('verify')
923
            ->willReturnCallback(function () use ($user, $secretToCheck) {
924
                return $user->getPassword() === $secretToCheck;
925
            })
926
        ;
927
928
        $result = $dataMapperAdapter->checkUserCredentials($userUuid, $secretToCheck);
929
        $this->assertSame($result, $expectedResult);
930
    }
931
932
    public function checkUserCredentialsProvider()
933
    {
934
        return [
935
            //  $client                               $secretToCheck    $expectedResult
936
            [new Entity\User(null, 'password'),    'password',       true],
937
            [new Entity\User(null, 'password'),    'bogus',          false],
938
            [null,                                 null,             false],
939
        ];
940
    }
941
942
    /**
943
     * @param Entity\User|null $user
944
     * @param mixed            $expectedResult
945
     *
946
     * @dataProvider getUserDetailsProvider
947
     */
948
    public function testGetUserDetails($user, $expectedResult)
949
    {
950
        $dataMapperAdapter = new DataMapperAdapter($this->dataMapperManager, $this->password);
951
        $userUuid          = $user ? $user->getUuid() : 'invalid';
952
953
        $userDataMapper = $this->getMock(DataMapper\UserMapperInterface::class);
954
        $userDataMapper->expects($this->any())
955
            ->method('findByCredential')
956
            ->with($userUuid)
957
            ->willReturn($user);
958
959
        $this->setDataMapperMock(Entity\UserInterface::class, $userDataMapper);
960
961
        $this->assertSame($expectedResult, $dataMapperAdapter->getUserDetails($userUuid));
962
    }
963
964
    public function getUserDetailsProvider()
965
    {
966
        $normalUser     = new Entity\User();
967
        $scopeAwareUser = new ScopeAwareUser();
968
        $scopeAwareUser->setScopes([new Entity\Scope(null, 'foo'), new Entity\Scope(null, 'bar')]);
969
970
        return [
971
            //  $user               $expectedResult
972
            [$normalUser,        ['user_id' => $normalUser->getUuid(), 'scope' => null]],
973
            [$scopeAwareUser,    ['user_id' => $scopeAwareUser->getUuid(), 'scope' => 'foo bar']],
974
            [null,               false],
975
        ];
976
    }
977
978
    public function testUserClassSetterChangesUserDataMapper()
979
    {
980
        $dataMapperManager  = $this->getMock(DataMapperManager::class);
981
        $userDataMapper     = $this->getMock(DataMapper\UserMapperInterface::class);
982
983
        $dataMapperAdapter  = new DataMapperAdapter($dataMapperManager, $this->password);
984
        $dataMapperAdapter->setUserClass(Entity\User::class);
985
986
        $dataMapperManager->expects($this->atLeastOnce())
987
            ->method('getDataMapperForEntity')
988
            ->with($dataMapperAdapter->getUserClass())
989
            ->willReturn($userDataMapper);
990
991
        $dataMapperAdapter->getUserDetails(null);
992
    }
993
994
    public function testUserClassSetterThrowsException()
995
    {
996
        $dataMapperManager  = $this->getMock(DataMapperManager::class);
997
998
        $dataMapperAdapter  = new DataMapperAdapter($dataMapperManager, $this->password);
999
1000
        $this->setExpectedException(InvalidArgumentException::class, 'Invalid user class');
1001
        $dataMapperAdapter->setUserClass('foo');
1002
1003
        $dataMapperAdapter  = new DataMapperAdapter($dataMapperManager, $this->password);
1004
1005
        $this->setExpectedException(InvalidArgumentException::class, 'Invalid user class');
1006
        $dataMapperAdapter->setUserClass(\stdClass::class);
1007
    }
1008
1009
    public function testHasDefaultUserCredentialsStrategy()
1010
    {
1011
        $dataMapperAdapter = new DataMapperAdapter($this->dataMapperManager, $this->password);
1012
        $strategies        = $dataMapperAdapter->getUserCredentialsStrategies();
1013
        $this->assertNotEmpty($strategies);
1014
        $this->assertArrayHasKey('default', $strategies);
1015
        $this->assertInstanceOf(PasswordStrategy::class, $strategies['default']);
1016
    }
1017
1018
    public function testCanDisableDefaultUserCredentialsStrategyViaConstructor()
1019
    {
1020
        $dataMapperAdapter = new DataMapperAdapter($this->dataMapperManager, $this->password, false);
1021
        $this->assertEmpty($dataMapperAdapter->getUserCredentialsStrategies());
1022
    }
1023
1024
    /**
1025
     * @param callable|UserCredentialsStrategyInterface $strategy
1026
     * @param bool                                      $expectException
1027
     *
1028
     * @dataProvider strategyProvider
1029
     */
1030
    public function testAddUserCredentialsStrategy($strategy, $expectException = false)
1031
    {
1032
        $dataMapperAdapter = new DataMapperAdapter($this->dataMapperManager, $this->password, false);
1033
1034
        if ($expectException) {
1035
            $this->setExpectedException(InvalidArgumentException::class, 'User credential strategy must be a callable or implement');
1036
        }
1037
1038
        $dataMapperAdapter->addUserCredentialsStrategy($strategy, 'test');
1039
        $this->assertContains($strategy, $dataMapperAdapter->getUserCredentialsStrategies());
1040
    }
1041
1042
    public function strategyProvider()
1043
    {
1044
        return [
1045
            [ function () {} ],
1046
            [ $this->getMock(UserCredentialsStrategyInterface::class) ],
1047
            [ new \stdClass(), true ],
1048
        ];
1049
    }
1050
1051
    public function testRemoveUserCredentialsStrategy()
1052
    {
1053
        $dataMapperAdapter = new DataMapperAdapter($this->dataMapperManager, $this->password);
1054
        $dataMapperAdapter->removeUserCredentialsStrategy('default');
1055
        $this->assertEmpty($dataMapperAdapter->getUserCredentialsStrategies());
1056
    }
1057
1058
    public function testCheckUserCredentialsWillUseStrategyIfAvailable()
1059
    {
1060
        $dataMapperAdapter  = new DataMapperAdapter($this->dataMapperManager, $this->password, false);
1061
        $userDataMapper     = $this->getMock(DataMapper\UserMapperInterface::class);
1062
        $user               = new Entity\User();
1063
        $testPassword       = 'foobar';
1064
        $returnValue        = true;
1065
        $userDataMapper->expects($this->any())
1066
                       ->method('findByCredential')
1067
                       ->willReturn($user);
1068
1069
        $this->setDataMapperMock(Entity\UserInterface::class, $userDataMapper);
1070
1071
        $userCredentialStrategy = $this->getMock(UserCredentialsStrategyInterface::class);
1072
        $userCredentialStrategy
1073
            ->expects($this->atLeastOnce())
1074
            ->method('isValid')
1075
            ->with($user, $testPassword)
1076
            ->willReturn($returnValue)
1077
        ;
1078
1079
        $dataMapperAdapter->addUserCredentialsStrategy($userCredentialStrategy, 'test');
1080
        $result = $dataMapperAdapter->checkUserCredentials('foo', $testPassword);
1081
        $this->assertSame($returnValue, $result);
1082
    }
1083
1084
    public function testCheckUserCredentialsWillUseStrategyCallableIfAvailable()
1085
    {
1086
        $dataMapperAdapter  = new DataMapperAdapter($this->dataMapperManager, $this->password, false);
1087
        $userDataMapper     = $this->getMock(DataMapper\UserMapperInterface::class);
1088
        $user               = new Entity\User();
1089
        $testPassword       = 'foobar';
1090
        $returnValue        = true;
1091
        $userDataMapper->expects($this->any())
1092
                       ->method('findByCredential')
1093
                       ->willReturn($user);
1094
1095
        $this->setDataMapperMock(Entity\UserInterface::class, $userDataMapper);
1096
1097
        $args                   = [];
1098
        $userCredentialStrategy = function ($user, $password) use (&$args, $returnValue) {
1099
            $args = func_get_args();
1100
1101
            return $returnValue;
1102
        };
1103
1104
        $dataMapperAdapter->addUserCredentialsStrategy($userCredentialStrategy, 'test');
1105
        $result = $dataMapperAdapter->checkUserCredentials('foo', $testPassword);
1106
        $this->assertNotEmpty($args);
1107
        $this->assertSame($args[0], $user);
1108
        $this->assertSame($args[1], $testPassword);
1109
        $this->assertSame($returnValue, $result);
1110
    }
1111
1112
    public function testCheckUserCredentialsThrowsIfInvalidDataMapperIsUsed()
1113
    {
1114
        $dataMapper = $this->getMock(DataMapperInterface::class);
1115
        $this->setDataMapperMock(Entity\UserInterface::class, $dataMapper);
1116
        $this->setExpectedException(\Assert\InvalidArgumentException::class, 'was expected to be instanceof of "Thorr\OAuth2\DataMapper\UserMapperInterface" but is not.');
1117
1118
        $dataMapperAdapter = new DataMapperAdapter($this->dataMapperManager, $this->password);
1119
        $dataMapperAdapter->checkUserCredentials('foo', 'bar');
1120
    }
1121
1122
    protected function setDataMapperMock($entityClassName, DataMapperInterface $dataMapper)
1123
    {
1124
        $this->dataMapperMocks[$entityClassName] = $dataMapper;
1125
    }
1126
}
1127