Skip to content

Commit ad858b6

Browse files
authored
Merge pull request #15 from sensson/feat-revoked-access-token-exception
feat: add custom exception for revoked access tokens
2 parents 2e0473a + 3a95709 commit ad858b6

5 files changed

Lines changed: 77 additions & 0 deletions

File tree

src/Connectors/AuthConnector.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,26 @@
44

55
use Saloon\Helpers\OAuth2\OAuthConfig;
66
use Saloon\Http\Connector;
7+
use Saloon\Http\Response;
78
use Saloon\Traits\OAuth2\AuthorizationCodeGrant;
89
use Saloon\Traits\Plugins\AlwaysThrowOnErrors;
10+
use Sensson\Moneybird\Exceptions\AccessTokenRevokedException;
11+
use Throwable;
912

1013
class AuthConnector extends Connector
1114
{
1215
use AlwaysThrowOnErrors;
1316
use AuthorizationCodeGrant;
1417

18+
public function getRequestException(Response $response, ?Throwable $senderException): ?Throwable
19+
{
20+
if ($response->status() === 401 && str_contains($response->body(), 'access token revoked')) {
21+
return new AccessTokenRevokedException($response, previous: $senderException);
22+
}
23+
24+
return null;
25+
}
26+
1527
public function resolveBaseUrl(): string
1628
{
1729
return 'https://moneybird.com/oauth';

src/Connectors/MoneybirdConnector.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@
33
namespace Sensson\Moneybird\Connectors;
44

55
use Saloon\Http\Connector;
6+
use Saloon\Http\Response;
67
use Saloon\RateLimitPlugin\Contracts\RateLimitStore;
78
use Saloon\RateLimitPlugin\Limit;
89
use Saloon\RateLimitPlugin\Stores\MemoryStore;
910
use Saloon\RateLimitPlugin\Traits\HasRateLimits;
1011
use Saloon\Traits\Conditionable;
1112
use Saloon\Traits\Plugins\AcceptsJson;
1213
use Saloon\Traits\Plugins\AlwaysThrowOnErrors;
14+
use Sensson\Moneybird\Exceptions\AccessTokenRevokedException;
1315
use Sensson\Moneybird\Resources\AdministrationResource;
1416
use Sensson\Moneybird\Resources\ContactResource;
1517
use Sensson\Moneybird\Resources\CustomFieldResource;
@@ -18,6 +20,7 @@
1820
use Sensson\Moneybird\Resources\TaxRateResource;
1921
use Sensson\Moneybird\Resources\WebhookResource;
2022
use Sensson\Moneybird\Resources\WorkflowResource;
23+
use Throwable;
2124

2225
class MoneybirdConnector extends Connector
2326
{
@@ -51,6 +54,15 @@ protected function resolveRateLimitStore(): RateLimitStore
5154
return new MemoryStore;
5255
}
5356

57+
public function getRequestException(Response $response, ?Throwable $senderException): ?Throwable
58+
{
59+
if ($response->status() === 401 && str_contains($response->body(), 'access token revoked')) {
60+
return new AccessTokenRevokedException($response, previous: $senderException);
61+
}
62+
63+
return null;
64+
}
65+
5466
public function administration(string $administrationId): self
5567
{
5668
$this->administrationId = $administrationId;
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php
2+
3+
namespace Sensson\Moneybird\Exceptions;
4+
5+
use Saloon\Exceptions\Request\Statuses\UnauthorizedException;
6+
7+
class AccessTokenRevokedException extends UnauthorizedException {}

tests/Connectors/MoneybirdAuthConnectorTest.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
<?php
22

3+
use Saloon\Exceptions\Request\Statuses\UnauthorizedException;
34
use Saloon\Helpers\OAuth2\OAuthConfig;
5+
use Saloon\Http\Faking\MockClient;
6+
use Saloon\Http\Faking\MockResponse;
47
use Sensson\Moneybird\Connectors\AuthConnector;
8+
use Sensson\Moneybird\Exceptions\AccessTokenRevokedException;
9+
use Sensson\Moneybird\Requests\Administrations\ListAdministrations;
510

611
test('auth connector has correct base url', function () {
712
$connector = new AuthConnector;
@@ -25,3 +30,21 @@
2530
->and($oauthConfig->getAuthorizeEndpoint())->toBe('authorize')
2631
->and($oauthConfig->getTokenEndpoint())->toBe('token');
2732
});
33+
34+
it('throws AccessTokenRevokedException when access token is revoked', function () {
35+
$mockClient = new MockClient([
36+
ListAdministrations::class => MockResponse::make('access token revoked', 401),
37+
]);
38+
39+
$connector = (new AuthConnector)->withMockClient($mockClient);
40+
$connector->send(new ListAdministrations);
41+
})->throws(AccessTokenRevokedException::class);
42+
43+
it('does not throw AccessTokenRevokedException for other 401 responses', function () {
44+
$mockClient = new MockClient([
45+
ListAdministrations::class => MockResponse::make('unauthorized', 401),
46+
]);
47+
48+
$connector = (new AuthConnector)->withMockClient($mockClient);
49+
$connector->send(new ListAdministrations);
50+
})->throws(UnauthorizedException::class);

tests/Connectors/MoneybirdConnectorTest.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
<?php
22

3+
use Saloon\Exceptions\Request\Statuses\UnauthorizedException;
4+
use Saloon\Http\Faking\MockClient;
5+
use Saloon\Http\Faking\MockResponse;
36
use Sensson\Moneybird\Connectors\MoneybirdConnector;
7+
use Sensson\Moneybird\Exceptions\AccessTokenRevokedException;
8+
use Sensson\Moneybird\Requests\Administrations\ListAdministrations;
49

510
test('connector has correct base url', function () {
611
$connector = new MoneybirdConnector;
@@ -29,3 +34,21 @@
2934
$traits = class_uses_recursive(get_class($connector));
3035
expect($traits)->toContain(\Saloon\Traits\Plugins\AcceptsJson::class);
3136
});
37+
38+
it('throws AccessTokenRevokedException when access token is revoked', function () {
39+
$mockClient = new MockClient([
40+
ListAdministrations::class => MockResponse::make('access token revoked', 401),
41+
]);
42+
43+
$connector = (new MoneybirdConnector)->withMockClient($mockClient);
44+
$connector->send(new ListAdministrations);
45+
})->throws(AccessTokenRevokedException::class);
46+
47+
it('does not throw AccessTokenRevokedException for other 401 responses', function () {
48+
$mockClient = new MockClient([
49+
ListAdministrations::class => MockResponse::make('unauthorized', 401),
50+
]);
51+
52+
$connector = (new MoneybirdConnector)->withMockClient($mockClient);
53+
$connector->send(new ListAdministrations);
54+
})->throws(UnauthorizedException::class);

0 commit comments

Comments
 (0)