Issues (3641)

Zed/OauthClient/Business/OauthClientFacadeTest.php (2 issues)

1
<?php
2
3
/**
4
 * Copyright © 2016-present Spryker Systems GmbH. All rights reserved.
5
 * Use of this software requires acceptance of the Evaluation License Agreement. See LICENSE file.
6
 */
7
8
namespace SprykerTest\Zed\OauthClient\Business;
9
10
use Codeception\Test\Unit;
11
use Generated\Shared\Transfer\AccessTokenErrorTransfer;
12
use Generated\Shared\Transfer\AccessTokenRequestOptionsTransfer;
13
use Generated\Shared\Transfer\AccessTokenRequestTransfer;
14
use Generated\Shared\Transfer\AccessTokenResponseTransfer;
15
use Generated\Shared\Transfer\HttpRequestTransfer;
16
use Orm\Zed\OauthClient\Persistence\SpyOauthClientAccessTokenCacheQuery;
17
use Spryker\Shared\OauthClient\OauthClientConstants;
18
use Spryker\Zed\OauthClient\Business\Exception\AccessTokenProviderNotFoundException;
19
use Spryker\Zed\OauthClient\Business\Provider\OauthAccessTokenProviderInterface;
20
21
/**
22
 * Auto-generated group annotations
23
 *
24
 * @group SprykerTest
25
 * @group Zed
26
 * @group OauthClient
27
 * @group Business
28
 * @group Facade
29
 * @group OauthClientFacadeTest
30
 * Add your own group annotations below this line
31
 */
32
class OauthClientFacadeTest extends Unit
33
{
34
    /**
35
     * @var \SprykerTest\Zed\OauthClient\OauthClientBusinessTester
36
     */
37
    protected $tester;
38
39
    /**
40
     * @var string
41
     */
42
    protected const TEST_SUCCESS_PROVIDER_NAME = 'test-success-provider-name';
43
44
    /**
45
     * @var string
46
     */
47
    protected const TEST_ERROR_PROVIDER_NAME = 'test-error-provider-name';
48
49
    /**
50
     * @var string
51
     */
52
    protected const TEST_UNSUPPORTED_PROVIDER_NAME = 'test-unsupported-provider-name';
53
54
    /**
55
     * @var string
56
     */
57
    protected const TEST_TOKEN_FROM_PROVIDER = 'test-token-from-provider';
58
59
    /**
60
     * @var string
61
     */
62
    protected const TEST_TOKEN_FROM_CACHE = 'test-token-from-cache';
63
64
    /**
65
     * @var int
66
     */
67
    protected const TEST_EXPIRES_IN = 86400;
68
69
    /**
70
     * @var string
71
     */
72
    protected const TEST_ERROR = 'TEST_ERROR';
73
74
    /**
75
     * @var \Generated\Shared\Transfer\AccessTokenResponseTransfer
76
     */
77
    protected $expectedSuccessAccessTokenResponseTransferFromProvider;
78
79
    /**
80
     * @var \Generated\Shared\Transfer\AccessTokenResponseTransfer
81
     */
82
    protected $expectedErrorAccessTokenResponseTransferFromProvider;
83
84
    /**
85
     * @var string
86
     */
87
    protected $expiresAt;
88
89
    /**
90
     * @return void
91
     */
92
    protected function setUp(): void
93
    {
94
        parent::setUp();
95
96
        $this->expiresAt = (string)(time() + static::TEST_EXPIRES_IN);
97
98
        $this->expectedSuccessAccessTokenResponseTransferFromProvider = $this->tester->haveAccessTokenResponseTransfer([
99
            AccessTokenResponseTransfer::IS_SUCCESSFUL => true,
100
            AccessTokenResponseTransfer::ACCESS_TOKEN => static::TEST_TOKEN_FROM_PROVIDER,
101
            AccessTokenResponseTransfer::EXPIRES_AT => $this->expiresAt,
102
        ]);
103
104
        $this->expectedErrorAccessTokenResponseTransferFromProvider = $this->tester->haveAccessTokenResponseTransfer([
105
            AccessTokenResponseTransfer::IS_SUCCESSFUL => false,
106
            AccessTokenResponseTransfer::ACCESS_TOKEN_ERROR => [
107
                AccessTokenErrorTransfer::ERROR => static::TEST_ERROR,
108
            ],
109
        ]);
110
111
        $this->tester->setOauthAccessTokenProviderPluginsDependency([
112
            $this->tester->mockOauthAccessTokenProviderPlugin(
113
                static::TEST_SUCCESS_PROVIDER_NAME,
114
                $this->expectedSuccessAccessTokenResponseTransferFromProvider,
115
            ),
116
            $this->tester->mockOauthAccessTokenProviderPlugin(
117
                static::TEST_ERROR_PROVIDER_NAME,
118
                $this->expectedErrorAccessTokenResponseTransferFromProvider,
119
            ),
120
        ]);
121
    }
122
123
    /**
124
     * @return void
125
     */
126
    public function testGetNotCachedAccessTokenReturnsValidToken(): void
127
    {
128
        // Arrange
129
        $accessTokenRequestTransfer = $this->tester->haveAccessTokenRequestTransfer([
130
            AccessTokenRequestTransfer::PROVIDER_NAME => static::TEST_SUCCESS_PROVIDER_NAME,
131
            AccessTokenRequestTransfer::ACCESS_TOKEN_REQUEST_OPTIONS => [
132
                AccessTokenRequestOptionsTransfer::STORE_REFERENCE => __FUNCTION__,
133
            ],
134
        ]);
135
136
        $spyOauthClientAccessTokenCacheEntityBeforeRequest = SpyOauthClientAccessTokenCacheQuery::create()
137
            ->findOneByCacheKey($this->tester->hashAccessTokenRequestTransfer($accessTokenRequestTransfer));
138
139
        // Act
140
        $accessTokenResponseTransfer = $this->tester->getFacade()->getAccessToken($accessTokenRequestTransfer);
141
142
        // Assert
143
        $spyOauthClientAccessTokenCacheEntityAfterRequest = SpyOauthClientAccessTokenCacheQuery::create()
144
            ->findOneByCacheKey($this->tester->hashAccessTokenRequestTransfer($accessTokenRequestTransfer));
145
        $this->tester->removeCacheEntity($this->tester->hashAccessTokenRequestTransfer($accessTokenRequestTransfer));
146
147
        $this->assertInstanceOf(AccessTokenResponseTransfer::class, $accessTokenResponseTransfer);
148
        $this->assertTrue($accessTokenResponseTransfer->getIsSuccessful());
149
        $this->assertEquals($this->expectedSuccessAccessTokenResponseTransferFromProvider, $accessTokenResponseTransfer);
150
        $this->assertNull($spyOauthClientAccessTokenCacheEntityBeforeRequest);
151
        $this->assertNotNull($spyOauthClientAccessTokenCacheEntityAfterRequest);
152
    }
153
154
    /**
155
     * @return void
156
     */
157
    public function testGetCachedAccessTokenReturnsValidToken(): void
158
    {
159
        // Arrange
160
        $accessTokenRequestTransfer = $this->tester->haveAccessTokenRequestTransfer([
161
            AccessTokenRequestTransfer::PROVIDER_NAME => static::TEST_SUCCESS_PROVIDER_NAME,
162
            AccessTokenRequestTransfer::ACCESS_TOKEN_REQUEST_OPTIONS => [
163
                AccessTokenRequestOptionsTransfer::STORE_REFERENCE => __FUNCTION__,
164
            ],
165
        ]);
166
167
        $expectedAccessTokenResponseTransferFromCache = $this->tester->haveAccessTokenResponseTransfer([
168
            AccessTokenResponseTransfer::ACCESS_TOKEN => static::TEST_TOKEN_FROM_CACHE,
169
            AccessTokenResponseTransfer::EXPIRES_AT => $this->expiresAt,
170
            AccessTokenResponseTransfer::IS_SUCCESSFUL => true,
171
        ]);
172
173
        $this->tester->haveOauthClientAccessTokenCacheEntity(
174
            $accessTokenRequestTransfer,
175
            $expectedAccessTokenResponseTransferFromCache,
176
        );
177
178
        $spyOauthClientAccessTokenCacheEntityBeforeRequest = SpyOauthClientAccessTokenCacheQuery::create()
179
            ->findOneByCacheKey($this->tester->hashAccessTokenRequestTransfer($accessTokenRequestTransfer));
180
181
        // Act
182
        $accessTokenResponseTransfer = $this->tester->getFacade()->getAccessToken($accessTokenRequestTransfer);
183
184
        // Assert
185
        $spyOauthClientAccessTokenCacheEntityAfterRequest = SpyOauthClientAccessTokenCacheQuery::create()
186
            ->findOneByCacheKey($this->tester->hashAccessTokenRequestTransfer($accessTokenRequestTransfer));
187
188
        $this->assertInstanceOf(AccessTokenResponseTransfer::class, $accessTokenResponseTransfer);
189
        $this->assertTrue($accessTokenResponseTransfer->getIsSuccessful());
190
        $this->assertEquals($expectedAccessTokenResponseTransferFromCache, $accessTokenResponseTransfer);
191
        $this->assertNotNull($spyOauthClientAccessTokenCacheEntityBeforeRequest);
192
        $this->assertNotNull($spyOauthClientAccessTokenCacheEntityAfterRequest);
193
    }
194
195
    /**
196
     * @return void
197
     */
198
    public function testGetCachedButExpiredAccessTokenReturnsValidTokenAndUpdateCache(): void
199
    {
200
        // Arrange
201
        $accessTokenRequestTransfer = $this->tester->haveAccessTokenRequestTransfer([
202
            AccessTokenRequestTransfer::PROVIDER_NAME => static::TEST_SUCCESS_PROVIDER_NAME,
203
            AccessTokenRequestTransfer::ACCESS_TOKEN_REQUEST_OPTIONS => [
204
                AccessTokenRequestOptionsTransfer::STORE_REFERENCE => __FUNCTION__,
205
            ],
206
        ]);
207
208
        $expectedAccessTokenResponseTransferFromCache = $this->tester->haveAccessTokenResponseTransfer([
209
            AccessTokenResponseTransfer::ACCESS_TOKEN => static::TEST_TOKEN_FROM_CACHE,
210
            AccessTokenResponseTransfer::EXPIRES_AT => (string)(time() - 1000),
211
        ]);
212
213
        $this->tester->haveOauthClientAccessTokenCacheEntity(
214
            $accessTokenRequestTransfer,
215
            $expectedAccessTokenResponseTransferFromCache,
216
        );
217
218
        $spyOauthClientAccessTokenCacheEntityBeforeRequest = SpyOauthClientAccessTokenCacheQuery::create()
219
            ->findOneByCacheKey($this->tester->hashAccessTokenRequestTransfer($accessTokenRequestTransfer));
220
221
        // Act
222
        $accessTokenResponseTransfer = $this->tester->getFacade()->getAccessToken($accessTokenRequestTransfer);
223
224
        // Assert
225
        $spyOauthClientAccessTokenCacheEntityAfterRequest = SpyOauthClientAccessTokenCacheQuery::create()
226
            ->findOneByCacheKey($this->tester->hashAccessTokenRequestTransfer($accessTokenRequestTransfer));
227
        $this->tester->removeCacheEntity($this->tester->hashAccessTokenRequestTransfer($accessTokenRequestTransfer));
228
229
        $this->assertInstanceOf(AccessTokenResponseTransfer::class, $accessTokenResponseTransfer);
230
        $this->assertTrue($accessTokenResponseTransfer->getIsSuccessful());
231
        $this->assertEquals($this->expectedSuccessAccessTokenResponseTransferFromProvider, $accessTokenResponseTransfer);
232
        $this->assertNotNull($spyOauthClientAccessTokenCacheEntityBeforeRequest);
233
        $this->assertNotNull($spyOauthClientAccessTokenCacheEntityAfterRequest);
234
        $this->assertNotEquals(
235
            $spyOauthClientAccessTokenCacheEntityBeforeRequest->getIdSpyOauthClientAccessTokenCache(),
236
            $spyOauthClientAccessTokenCacheEntityAfterRequest->getIdSpyOauthClientAccessTokenCache(),
237
        );
238
    }
239
240
    /**
241
     * @return void
242
     */
243
    public function testGetAccessTokenButCacheDisabledReturnsValidToken(): void
244
    {
245
        // Arrange
246
        $accessTokenRequestTransfer = $this->tester->haveAccessTokenRequestTransfer([
247
            AccessTokenRequestTransfer::IGNORE_CACHE => true,
248
            AccessTokenRequestTransfer::PROVIDER_NAME => static::TEST_SUCCESS_PROVIDER_NAME,
249
            AccessTokenRequestTransfer::ACCESS_TOKEN_REQUEST_OPTIONS => [
250
                AccessTokenRequestOptionsTransfer::STORE_REFERENCE => __FUNCTION__,
251
            ],
252
        ]);
253
254
        $spyOauthClientAccessTokenCacheEntityBeforeRequest = SpyOauthClientAccessTokenCacheQuery::create()
255
            ->findOneByCacheKey($this->tester->hashAccessTokenRequestTransfer($accessTokenRequestTransfer));
256
257
        // Act
258
        $accessTokenResponseTransfer = $this->tester->getFacade()->getAccessToken($accessTokenRequestTransfer);
259
260
        // Assert
261
        $spyOauthClientAccessTokenCacheEntityAfterRequest = SpyOauthClientAccessTokenCacheQuery::create()
262
            ->findOneByCacheKey($this->tester->hashAccessTokenRequestTransfer($accessTokenRequestTransfer));
263
264
        $this->assertInstanceOf(AccessTokenResponseTransfer::class, $accessTokenResponseTransfer);
265
        $this->assertTrue($accessTokenResponseTransfer->getIsSuccessful());
266
        $this->assertEquals($this->expectedSuccessAccessTokenResponseTransferFromProvider, $accessTokenResponseTransfer);
267
        $this->assertNull($spyOauthClientAccessTokenCacheEntityBeforeRequest);
268
        $this->assertNull($spyOauthClientAccessTokenCacheEntityAfterRequest);
269
    }
270
271
    /**
272
     * @return void
273
     */
274
    public function testGetCachedAccessTokenButCacheDisabledReturnsValidToken(): void
275
    {
276
        // Arrange
277
        $accessTokenRequestTransfer = $this->tester->haveAccessTokenRequestTransfer([
278
            AccessTokenRequestTransfer::IGNORE_CACHE => true,
279
            AccessTokenRequestTransfer::PROVIDER_NAME => static::TEST_SUCCESS_PROVIDER_NAME,
280
            AccessTokenRequestTransfer::ACCESS_TOKEN_REQUEST_OPTIONS => [
281
                AccessTokenRequestOptionsTransfer::STORE_REFERENCE => __FUNCTION__,
282
            ],
283
        ]);
284
285
        $expectedAccessTokenResponseTransferFromCache = $this->tester->haveAccessTokenResponseTransfer([
286
            AccessTokenResponseTransfer::ACCESS_TOKEN => static::TEST_TOKEN_FROM_CACHE,
287
            AccessTokenResponseTransfer::EXPIRES_AT => $this->expiresAt,
288
        ]);
289
290
        $this->tester->haveOauthClientAccessTokenCacheEntity(
291
            $accessTokenRequestTransfer,
292
            $expectedAccessTokenResponseTransferFromCache,
293
        );
294
295
        $spyOauthClientAccessTokenCacheEntityBeforeRequest = SpyOauthClientAccessTokenCacheQuery::create()
296
            ->findOneByCacheKey($this->tester->hashAccessTokenRequestTransfer($accessTokenRequestTransfer));
297
298
        // Act
299
        $accessTokenResponseTransfer = $this->tester->getFacade()->getAccessToken($accessTokenRequestTransfer);
300
301
        // Assert
302
        $spyOauthClientAccessTokenCacheEntityAfterRequest = SpyOauthClientAccessTokenCacheQuery::create()
303
            ->findOneByCacheKey($this->tester->hashAccessTokenRequestTransfer($accessTokenRequestTransfer));
304
305
        $this->assertInstanceOf(AccessTokenResponseTransfer::class, $accessTokenResponseTransfer);
306
        $this->assertTrue($accessTokenResponseTransfer->getIsSuccessful());
307
        $this->assertEquals($this->expectedSuccessAccessTokenResponseTransferFromProvider, $accessTokenResponseTransfer);
308
        $this->assertNotNull($spyOauthClientAccessTokenCacheEntityBeforeRequest);
309
        $this->assertNotNull($spyOauthClientAccessTokenCacheEntityAfterRequest);
310
        $this->assertEquals(
311
            $spyOauthClientAccessTokenCacheEntityBeforeRequest->getIdSpyOauthClientAccessTokenCache(),
312
            $spyOauthClientAccessTokenCacheEntityAfterRequest->getIdSpyOauthClientAccessTokenCache(),
313
        );
314
    }
315
316
    /**
317
     * @return void
318
     */
319
    public function testGetAccessTokenReturnsErrorWhenPluginReturnsError(): void
320
    {
321
        // Arrange
322
        $accessTokenRequestTransfer = (new AccessTokenRequestTransfer())
323
            ->setProviderName(static::TEST_ERROR_PROVIDER_NAME);
324
325
        // Act
326
        $accessTokenResponseTransfer = $this->tester->getFacade()->getAccessToken($accessTokenRequestTransfer);
327
328
        // Assert
329
        $spyOauthClientAccessTokenCacheEntityAfterRequest = SpyOauthClientAccessTokenCacheQuery::create()
330
            ->findOneByCacheKey($this->tester->hashAccessTokenRequestTransfer($accessTokenRequestTransfer));
331
332
        $this->assertInstanceOf(AccessTokenResponseTransfer::class, $accessTokenResponseTransfer);
333
        $this->assertFalse($accessTokenResponseTransfer->getIsSuccessful());
334
        $this->assertNull($spyOauthClientAccessTokenCacheEntityAfterRequest);
335
        $this->assertEquals(
336
            $this->expectedErrorAccessTokenResponseTransferFromProvider,
337
            $accessTokenResponseTransfer,
338
        );
339
    }
340
341
    /**
342
     * @return void
343
     */
344
    public function testGetAccessTokenReturnsErrorWhenPluginNotFound(): void
345
    {
346
        // Arrange
347
        $accessTokenRequestTransfer = (new AccessTokenRequestTransfer())
348
            ->setProviderName(static::TEST_UNSUPPORTED_PROVIDER_NAME);
349
350
        // Assert
351
        $this->expectException(AccessTokenProviderNotFoundException::class);
352
353
        // Act
354
        $this->tester->getFacade()->getAccessToken($accessTokenRequestTransfer);
355
    }
356
357
    /**
358
     * @return void
359
     */
360
    public function testAccessTokenRequestOptionsExpandedWithStoreReferenceTakenFromMessageAttributes(): void
361
    {
362
        // Arrange
363
        $this->tester->mockConfigMethod('isAccessTokenRequestExpandedByMessageAttributes', true);
364
365
        $mesageAttributes = $this->tester->haveMessageAttributes(
366
            [
367
                'storeReference' => 'store-reference-1',
368
            ],
369
        );
370
371
        $oauthAccessTokenProviderMock = $this->makeEmpty(OauthAccessTokenProviderInterface::class);
372
        $oauthAccessTokenProviderMock->expects($this->once())
373
            ->method('getAccessToken')
374
            ->with(static::callback(function (AccessTokenRequestTransfer $accessTokenRequestTransfer): bool {
375
                // Assert
376
                self::assertSame('store-reference-1', $accessTokenRequestTransfer->getAccessTokenRequestOptions()->getStoreReference());
377
378
                return true;
379
            }))
380
            ->willReturn(
381
                $this->tester->haveAccessTokenResponseTransfer(
382
                    [
383
                        AccessTokenResponseTransfer::IS_SUCCESSFUL => true,
384
                        AccessTokenResponseTransfer::ACCESS_TOKEN => static::TEST_TOKEN_FROM_PROVIDER,
385
                        AccessTokenResponseTransfer::EXPIRES_AT => $this->expiresAt,
386
                    ],
387
                ),
388
            );
389
390
        $this->tester->mockFactoryMethod('createOauthAccessTokenProvider', $oauthAccessTokenProviderMock);
391
392
        // Act
393
        $expandedMessageAttributes = $this->tester->getFacade()->expandMessageAttributes($mesageAttributes);
0 ignored issues
show
The assignment to $expandedMessageAttributes is dead and can be removed.
Loading history...
394
    }
395
396
    /**
397
     * @return void
398
     */
399
    public function testExpandHttpRequestReturnsExpandedTransferWhenRequestIsCorrect(): void
400
    {
401
        // Arrange
402
        $this->tester->haveDummyOauthAccessTokenProviderDependency(
403
            $this->tester->haveAccessTokenResponseTransfer(
404
                [
405
                    AccessTokenResponseTransfer::IS_SUCCESSFUL => true,
406
                    AccessTokenResponseTransfer::ACCESS_TOKEN => static::TEST_TOKEN_FROM_PROVIDER,
407
                    AccessTokenResponseTransfer::EXPIRES_AT => $this->expiresAt,
408
                ],
409
            ),
410
            true,
411
        );
412
413
        // Act
414
        $httpRequestTransfer = $this->tester->getFacade()->expandHttpChannelMessageReceiverRequest(new HttpRequestTransfer());
415
416
        // Assert
417
        $this->assertSame(
418
            sprintf('Bearer %s', static::TEST_TOKEN_FROM_PROVIDER),
419
            $httpRequestTransfer->getHeaders()['Authorization'],
420
        );
421
    }
422
423
    /**
424
     * @return void
425
     */
426
    public function testAccessTokenRequestOptionsExpandedWithCurrentStoreStoreReference(): void
427
    {
428
        // Arrange
429
        $mesageAttributes = $this->tester->haveMessageAttributes(
430
            [
431
                'storeReference' => 'store-reference-1',
432
            ],
433
        );
434
435
        $oauthAccessTokenProviderMock = $this->makeEmpty(OauthAccessTokenProviderInterface::class);
436
        $oauthAccessTokenProviderMock->expects($this->once())
437
            ->method('getAccessToken')
438
            ->with(static::callback(function (AccessTokenRequestTransfer $accessTokenRequestTransfer): bool {
439
                // Assert
440
                self::assertNull($accessTokenRequestTransfer->getAccessTokenRequestOptions()->getStoreReference());
441
442
                return true;
443
            }))
444
            ->willReturn(
445
                $this->tester->haveAccessTokenResponseTransfer(
446
                    [
447
                        AccessTokenResponseTransfer::IS_SUCCESSFUL => true,
448
                        AccessTokenResponseTransfer::ACCESS_TOKEN => static::TEST_TOKEN_FROM_PROVIDER,
449
                        AccessTokenResponseTransfer::EXPIRES_AT => $this->expiresAt,
450
                    ],
451
                ),
452
            );
453
454
        $this->tester->mockFactoryMethod('createOauthAccessTokenProvider', $oauthAccessTokenProviderMock);
455
456
        // Act
457
        $expandedMessageAttributes = $this->tester->getFacade()->expandMessageAttributes($mesageAttributes);
0 ignored issues
show
The assignment to $expandedMessageAttributes is dead and can be removed.
Loading history...
458
    }
459
460
    /**
461
     * @return void
462
     */
463
    public function testExpandAccessTokenRequestWithTenantIdentifierSuccessfullyEndsWhenTenantIdentifierExists(): void
464
    {
465
        // Arrange
466
        $tenantIdentifier = 'dev-DE';
467
        $this->tester->setConfig(OauthClientConstants::TENANT_IDENTIFIER, $tenantIdentifier);
468
469
        // Act
470
        $accessTokenRequestTransfer = $this->tester->getFacade()
471
            ->expandAccessTokenRequestWithTenantIdentifier(new AccessTokenRequestTransfer());
472
473
        // Assert
474
        $accessTokenRequestOptionsTransfer = $accessTokenRequestTransfer->getAccessTokenRequestOptions();
475
        $this->assertNotNull($accessTokenRequestOptionsTransfer);
476
        $this->assertSame($tenantIdentifier, $accessTokenRequestOptionsTransfer->getTenantIdentifier());
477
    }
478
479
    /**
480
     * @return void
481
     */
482
    public function testAccessTokenRequestWithTenantIdentifierDoesNothingWhenTenantIdentifierIsEmpty(): void
483
    {
484
        // Arrange
485
        $this->tester->setConfig(OauthClientConstants::TENANT_IDENTIFIER, '');
486
        $accessTokenRequestTransfer = new AccessTokenRequestTransfer();
487
488
        // Act
489
        $expandedAccessTokenRequestTransfer = $this->tester->getFacade()
490
            ->expandAccessTokenRequestWithTenantIdentifier($accessTokenRequestTransfer);
491
492
        // Assert
493
        $this->assertSame($accessTokenRequestTransfer, $expandedAccessTokenRequestTransfer);
494
    }
495
}
496