diff --git a/src/AmznSPAConfig.php b/src/AmznSPAConfig.php index 6b06142..9c7af2c 100644 --- a/src/AmznSPAConfig.php +++ b/src/AmznSPAConfig.php @@ -27,6 +27,7 @@ class AmznSPAConfig private GrantlessToken $grantless_token; private RestrictedDataToken $restricted_data_token; private LoggerInterface $logger; + private ?Proxy $proxy; public function __construct( string $marketplace_id, @@ -49,7 +50,7 @@ public function __construct( ?CarbonImmutable $grantless_access_token_expires_at = null, ?string $restricted_data_token = null, ?CarbonImmutable $restricted_data_token_expires_at = null, - private ?Proxy $proxy = null + ?Proxy $proxy = null ) { $this->validateStringEnum($marketplace_id, MarketplacesList::allIdentifiers()); @@ -78,6 +79,7 @@ public function __construct( ); $this->logger = $logger ?: new Logger(); + $this->proxy = $proxy; } public function getHttp(): PendingRequest @@ -140,31 +142,11 @@ public function shouldUseTestEndpoints(): bool return $this->use_test_endpoints; } - public function shouldUseProxy(): bool - { - return $this->proxy?->url && $this->proxy?->auth_token; - } - public function getProxy(): Proxy|null { return $this->proxy; } - public function setProxy(Proxy $proxy): void - { - $this->proxy = $proxy; - } - - public function getProxyUrl(): string|null - { - return $this->proxy?->url; - } - - public function getProxyAuthToken(): string|null - { - return $this->proxy?->auth_token; - } - public function shouldGetRdtTokens(): bool { return $this->get_rdt_tokens; @@ -230,6 +212,6 @@ public function setMarketplace(string $marketplace_id): void public function isPropertySet(string $property): bool { - return isset($this->$property) && !is_null($this->$property); + return isset($this->$property) && ! is_null($this->$property); } } diff --git a/src/AmznSPAHttp.php b/src/AmznSPAHttp.php index 34654d2..e69aac9 100644 --- a/src/AmznSPAHttp.php +++ b/src/AmznSPAHttp.php @@ -287,10 +287,8 @@ private function refreshRdtToken(string $url, string $method) private function setupHttp(PendingRequest $http, bool $grantless = false, string $url = '', string $method = ''): void { - if ($this->config->shouldUseProxy()) { - $this->http = $http->withHeaders([ - 'Authorization' => "Bearer {$this->config->getProxyAuthToken()}" - ]); + if ($proxy = $this->config->getProxy()) { + $this->http = $http->withHeaders($proxy->headers); } else { $this->http = $http->withHeaders([ 'x-amz-access-token' => $this->getToken($grantless, $url, $method), @@ -476,11 +474,11 @@ private function isAuthenticationException(RequestException $e): bool $message = Arr::get($e->response->json(), 'errors.0.message', ''); if (Str::contains($message, [ - 'Access to requested resource is denied', - 'Invalid partyId', - 'hasn\'t registered in FBA in marketplace', - 'No MWS Authorization exists', - 'No MWS Authorization found', + 'Access to requested resource is denied', + 'Invalid partyId', + 'hasn\'t registered in FBA in marketplace', + 'No MWS Authorization exists', + 'No MWS Authorization found', ])) { return true; } diff --git a/src/Data/Proxy.php b/src/Data/Proxy.php index 72626b5..f244dd7 100644 --- a/src/Data/Proxy.php +++ b/src/Data/Proxy.php @@ -2,13 +2,11 @@ namespace Jasara\AmznSPA\Data; -use Jasara\AmznSPA\Data\Base\Data; - -class Proxy extends Data +class Proxy { public function __construct( - public ?string $url, - public ?string $auth_token, + public readonly string $url, + public readonly array $headers, ) { } } diff --git a/src/Resources/ResourceGetter.php b/src/Resources/ResourceGetter.php index 87fdeb1..40b3d57 100644 --- a/src/Resources/ResourceGetter.php +++ b/src/Resources/ResourceGetter.php @@ -148,7 +148,7 @@ public function getListingsItems(): ListingsItemsResource private function constructResource(string $class, ?string $grantless_resource = null): ResourceContract { - $url = $this->config->shouldUseProxy() ? $this->config->getProxyUrl() : $this->config->getMarketplace()->getBaseUrl(); + $url = $this->config->getProxy() ? $this->config->getProxy()->url : $this->config->getMarketplace()->getBaseUrl(); return new $class( $this->validateAndSetupHttpForStandardResource($grantless_resource), @@ -158,10 +158,10 @@ private function constructResource(string $class, ?string $grantless_resource = private function validateAndSetupHttpForStandardResource(?string $grantless_resource = null): AmznSPAHttp { - if (!$this->config->shouldUseProxy()) { + if (! $this->config->getProxy()) { $this->validateObjectProperties($this->config->getApplicationKeys(), ['lwa_client_id', 'lwa_client_secret', 'aws_access_key', 'aws_secret_key']); - if (!$grantless_resource) { + if (! $grantless_resource) { $this->validateObjectProperties($this->config->getTokens(), ['refresh_token']); } } diff --git a/tests/Setup/SetupAmznSPAConfig.php b/tests/Setup/SetupAmznSPAConfig.php index 667900a..7155d9a 100644 --- a/tests/Setup/SetupAmznSPAConfig.php +++ b/tests/Setup/SetupAmznSPAConfig.php @@ -6,6 +6,7 @@ use Illuminate\Support\Str; use Jasara\AmznSPA\AmznSPAConfig; use Jasara\AmznSPA\Constants\MarketplacesList; +use Jasara\AmznSPA\Data\Proxy; trait SetupAmznSPAConfig { @@ -31,6 +32,32 @@ public function setupMinimalConfig(string $marketplace_id = null, Factory $http return $config; } + public function setupMinimalProxyConfig( + Proxy $proxy, + string $marketplace_id = null, + Factory $http = null, + ): AmznSPAConfig { + $config = new AmznSPAConfig( + marketplace_id: $marketplace_id ?: MarketplacesList::allIdentifiers()[rand(0, 15)], + application_id: Str::random(), + redirect_url: Str::random() . '.com', + lwa_refresh_token: Str::random(), + lwa_access_token: Str::random(), + grantless_access_token: Str::random(), + aws_access_key: Str::random(), + aws_secret_key: Str::random(), + lwa_client_id: Str::random(), + lwa_client_secret: Str::random(), + proxy: $proxy, + ); + + if ($http) { + $config->setHttp($http); + } + + return $config; + } + public function setupLiveConfig(): AmznSPAConfig { $config = new AmznSPAConfig( diff --git a/tests/Unit/AmznSPAConfigProxyTest.php b/tests/Unit/AmznSPAConfigProxyTest.php deleted file mode 100644 index 515d2f7..0000000 --- a/tests/Unit/AmznSPAConfigProxyTest.php +++ /dev/null @@ -1,86 +0,0 @@ -getIdentifier(); - - $application_id = Str::random(); - - $proxy_url = Str::random(); - $proxy_auth_token = Str::random(); - - $config = new AmznSPAConfig( - marketplace_id: $marketplace_id, - application_id: $application_id, - proxy: new Proxy( - url: $proxy_url, - auth_token: $proxy_auth_token - ) - ); - - $this->assertInstanceOf(Marketplace::class, $config->getMarketplace()); - $this->assertInstanceOf(PendingRequest::class, $config->getHttp()); - - $this->assertEquals($marketplace_id, $config->getMarketplace()->getIdentifier()); - - $this->assertTrue($config->shouldUseProxy()); - $this->assertEquals($proxy_url, $config->getProxyUrl()); - $this->assertEquals($proxy_auth_token, $config->getProxyAuthToken()); - } - - public function testSetters() - { - $marketplace = MarketplacesList::all()->random(1)->first(); - - $config = new AmznSPAConfig( - marketplace_id: $marketplace->getIdentifier(), - application_id: Str::random(), - ); - - $marketplace_2 = MarketplacesList::all()->random(1)->first(); - $config->setMarketplace($marketplace_2->getIdentifier()); - $this->assertEquals($marketplace_2->getIdentifier(), $config->getMarketplace()->getIdentifier()); - - $config->setHttp(new Factory()); - $this->assertInstanceOf(PendingRequest::class, $config->getHttp()); - - $config->setHttp((new Factory())->connectTimeout(30)); - $this->assertInstanceOf(PendingRequest::class, $config->getHttp()); - - $proxy_url = Str::random(); - $proxy_auth_token = Str::random(); - $config->setProxy(Proxy::from( - url: $proxy_url, - auth_token: $proxy_auth_token - )); - - $this->assertEquals($proxy_url, $config->getProxyUrl()); - $this->assertEquals($proxy_auth_token, $config->getProxyAuthToken()); - - $proxy_url = Str::random(); - $proxy_auth_token = Str::random(); - $config->setProxy(Proxy::from( - url: $proxy_url, - auth_token: $proxy_auth_token - )); - - $this->assertEquals($proxy_url, $config->getProxy()->url); - $this->assertEquals($proxy_auth_token, $config->getProxy()->auth_token); - } -} diff --git a/tests/Unit/AmznSPAConfigTest.php b/tests/Unit/AmznSPAConfigTest.php index eeb9ff5..51becfa 100644 --- a/tests/Unit/AmznSPAConfigTest.php +++ b/tests/Unit/AmznSPAConfigTest.php @@ -15,6 +15,7 @@ use Jasara\AmznSPA\Data\ApplicationKeys; use Jasara\AmznSPA\Data\AuthTokens; use Jasara\AmznSPA\Data\GrantlessToken; +use Jasara\AmznSPA\Data\Proxy; use Jasara\AmznSPA\Data\RestrictedDataToken; use Jasara\AmznSPA\Exceptions\AuthenticationException; use PHPUnit\Framework\Attributes\CoversClass; @@ -45,6 +46,14 @@ public function testGetNewConfig() $restricted_data_token = Str::random(); $restricted_data_token_expires_at = CarbonImmutable::now()->addSeconds(rand(100, 500)); + $proxy_auth_token = Str::random(); + $proxy = new Proxy( + url: Str::random(), + headers: [ + 'Authorization' => "Bearer {$proxy_auth_token}", + ], + ); + $config = new AmznSPAConfig( marketplace_id: $marketplace_id, application_id: $application_id, @@ -61,6 +70,7 @@ public function testGetNewConfig() restricted_data_token: $restricted_data_token, restricted_data_token_expires_at: $restricted_data_token_expires_at, use_test_endpoints: true, + proxy: $proxy, ); $this->assertInstanceOf(Marketplace::class, $config->getMarketplace()); @@ -91,6 +101,9 @@ public function testGetNewConfig() $this->assertTrue($config->shouldUseTestEndpoints()); $this->assertTrue($config->shouldGetRdtTokens()); + + $this->assertEquals($proxy->url, $config->getProxy()->url); + $this->assertEquals($proxy->headers, $config->getProxy()->headers); } public function testSetters() diff --git a/tests/Unit/AmznSPAHttpTest.php b/tests/Unit/AmznSPAHttpTest.php index 98b2bcd..e88a911 100644 --- a/tests/Unit/AmznSPAHttpTest.php +++ b/tests/Unit/AmznSPAHttpTest.php @@ -431,6 +431,41 @@ function (Request $request) { $http->assertSentInOrder($request_validation); } + public function testSetProxyHeaders() + { + $http = $this->fakeHttpStub(['orders/get-orders']); + + $proxy_auth_token = Str::random(); + $proxy = new Proxy( + url: 'https://www.example.com', + headers: [ + 'Authorization' => "Bearer {$proxy_auth_token}", + 'X-Marketplace-Id' => 'ATVPDKIKX0DER', + ], + ); + + $config = $this->setupMinimalProxyConfig($proxy, null, $http); + + $amzn = new AmznSPA($config); + $amzn = $amzn->usingMarketplace('ATVPDKIKX0DER'); + $amzn->orders->getOrders( + marketplace_ids: ['ATVPDKIKX0DER'], + ); + + $request_validation = [ + function (Request $request) use ($proxy_auth_token) { + $this->assertEquals('GET', $request->method()); + $this->assertEquals('https://www.example.com/orders/v0/orders?MarketplaceIds=ATVPDKIKX0DER', urldecode($request->url())); + $this->assertEquals("Bearer {$proxy_auth_token}", $request->header('Authorization')[0]); + $this->assertEquals('ATVPDKIKX0DER', $request->header('X-Marketplace-Id')[0]); + + return true; + }, + ]; + + $http->assertSentInOrder($request_validation); + } + public function testInvalidPartyId() { $this->expectException(AuthenticationException::class); @@ -482,13 +517,13 @@ public function testSetupHttpProxy() $config = new AmznSPAConfig( marketplace_id: MarketplacesList::allIdentifiers()[rand(0, 15)], application_id: Str::random(), - proxy: Proxy::from( + proxy: new Proxy( url: 'https://www.amazon.com', - auth_token: Str::random(), + headers: [], ) ); - $this->assertTrue($config->shouldUseProxy()); + $this->assertNotNull($config->getProxy()); $amzn = new AmznSPA($config); diff --git a/tests/Unit/Data/ProxyTest.php b/tests/Unit/Data/ProxyTest.php index 4705465..d302edd 100644 --- a/tests/Unit/Data/ProxyTest.php +++ b/tests/Unit/Data/ProxyTest.php @@ -12,14 +12,15 @@ class ProxyTest extends UnitTestCase { public function testSetupTokens() { - $proxy_url = Str::random(); $proxy_auth_token = Str::random(); $proxy = new Proxy( - url: $proxy_url, - auth_token: $proxy_auth_token + url: $proxy_url = Str::random(), + headers: [ + 'Authorization' => "Bearer {$proxy_auth_token}", + ], ); $this->assertEquals($proxy_url, $proxy->url); - $this->assertEquals($proxy_auth_token, $proxy->auth_token); + $this->assertEquals("Bearer {$proxy_auth_token}", $proxy->headers['Authorization']); } }