From 5a5baf13451e514c0beefffb92a4859289662e30 Mon Sep 17 00:00:00 2001 From: Saifallak Date: Fri, 29 Sep 2023 03:32:23 +0300 Subject: [PATCH 01/11] exchange rate fix. --- config/exchange.php | 15 +++++++++++++++ .../ExchangeRateHostProvider.php | 4 ++-- src/Support/ExchangeRateManager.php | 7 +++++++ 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/config/exchange.php b/config/exchange.php index 64f13e5..5657b7e 100644 --- a/config/exchange.php +++ b/config/exchange.php @@ -30,6 +30,21 @@ 'access_key' => env('FIXER_ACCESS_KEY'), ], + /* + |-------------------------------------------------------------------------- + | ExchangeRate.host + |-------------------------------------------------------------------------- + | + | ExchangeRate is a paid service for converting currency codes. To use ExchangeRate, you'll + | need an API Access Key from the ExchangeRate dashboard. Set that here, and then + | change the 'default' to 'exchange_rate' or set EXCHANGE_DRIVER to 'exchange_rate'. + | + */ + + 'exchange_rate' => [ + 'access_key' => env('EXCHANGE_RATE_ACCESS_KEY'), + ], + /* |-------------------------------------------------------------------------- | Cache diff --git a/src/ExchangeRateProviders/ExchangeRateHostProvider.php b/src/ExchangeRateProviders/ExchangeRateHostProvider.php index 1eb45a4..cb2b04d 100644 --- a/src/ExchangeRateProviders/ExchangeRateHostProvider.php +++ b/src/ExchangeRateProviders/ExchangeRateHostProvider.php @@ -12,9 +12,9 @@ final class ExchangeRateHostProvider implements ExchangeRateProvider { private FixerProvider $fixerProvider; - public function __construct(private Factory $client) + public function __construct(private Factory $client, private string $accessKey) { - $this->fixerProvider = new FixerProvider($this->client, '', 'https://api.exchangerate.host'); + $this->fixerProvider = new FixerProvider($this->client, $this->accessKey, 'https://api.exchangerate.host'); } public function getRates(string $baseCurrency, array $currencies): Rates diff --git a/src/Support/ExchangeRateManager.php b/src/Support/ExchangeRateManager.php index 2436efe..77b0815 100644 --- a/src/Support/ExchangeRateManager.php +++ b/src/Support/ExchangeRateManager.php @@ -42,8 +42,15 @@ public function createFixerDriver(): FixerProvider public function createExchangeRateDriver(): ExchangeRateHostProvider { + $apiKey = $this->config->get('exchange.services.exchange_rate.access_key'); + + throw_unless(is_string($apiKey), new InvalidConfigurationException( + 'You haven\'t set up an API key for ExchangeRate!' + )); + return new ExchangeRateHostProvider( $this->container->make(Factory::class), + $apiKey, ); } From 476a9904ca32b13a267fd11ac51714feccf46ebb Mon Sep 17 00:00:00 2001 From: Saifallak Date: Fri, 29 Sep 2023 04:29:00 +0300 Subject: [PATCH 02/11] CurrencyGeo --- config/exchange.php | 15 +++++ .../CurrencyGEOProvider.php | 65 +++++++++++++++++++ src/Support/ExchangeRateManager.php | 15 +++++ 3 files changed, 95 insertions(+) create mode 100644 src/ExchangeRateProviders/CurrencyGEOProvider.php diff --git a/config/exchange.php b/config/exchange.php index 5657b7e..cd13333 100644 --- a/config/exchange.php +++ b/config/exchange.php @@ -45,6 +45,21 @@ 'access_key' => env('EXCHANGE_RATE_ACCESS_KEY'), ], + /* + |-------------------------------------------------------------------------- + | CurrencyGeo.com + |-------------------------------------------------------------------------- + | + | CurrencyGeo is a paid service for converting currency codes. To use CurrencyGeo, you'll + | need an API Access Key from the CurrencyGeo dashboard. Set that here, and then + | change the 'default' to 'exchange_rate' or set EXCHANGE_DRIVER to 'exchange_rate'. + | + */ + + 'currency_geo' => [ + 'access_key' => env('CURRENCY_GEO_ACCESS_KEY'), + ], + /* |-------------------------------------------------------------------------- | Cache diff --git a/src/ExchangeRateProviders/CurrencyGEOProvider.php b/src/ExchangeRateProviders/CurrencyGEOProvider.php new file mode 100644 index 0000000..b18650d --- /dev/null +++ b/src/ExchangeRateProviders/CurrencyGEOProvider.php @@ -0,0 +1,65 @@ +makeRequest($baseCurrency, $currencies); + + return new Rates( + $baseCurrency, + // @phpstan-ignore-next-line + collect($data->get('rates'))->map(fn(mixed $value) => floatval($value['rate']))->all(), + now(), + ); + } + + /** + * @param array $currencies + * + * @return Collection + * + * @throws RequestException + */ + private function makeRequest(string $baseCurrency, array $currencies): Collection + { + return $this->client() + ->get('/currency/convert', [ + 'api_key' => $this->accessKey, + 'from' => $baseCurrency, + 'to' => implode(',', $currencies), + ]) + ->throw() + ->collect(); + } + + private function client(): PendingRequest + { + return $this->client + ->baseUrl($this->baseUrl) + ->asJson() + ->acceptJson(); + } +} diff --git a/src/Support/ExchangeRateManager.php b/src/Support/ExchangeRateManager.php index 77b0815..4e4c9b4 100644 --- a/src/Support/ExchangeRateManager.php +++ b/src/Support/ExchangeRateManager.php @@ -9,6 +9,7 @@ use Illuminate\Support\Manager; use Worksome\Exchange\Exceptions\InvalidConfigurationException; use Worksome\Exchange\ExchangeRateProviders\CachedProvider; +use Worksome\Exchange\ExchangeRateProviders\CurrencyGEOProvider; use Worksome\Exchange\ExchangeRateProviders\ExchangeRateHostProvider; use Worksome\Exchange\ExchangeRateProviders\FixerProvider; use Worksome\Exchange\ExchangeRateProviders\FrankfurterProvider; @@ -54,6 +55,20 @@ public function createExchangeRateDriver(): ExchangeRateHostProvider ); } + public function createCurrencyGeoDriver(): CurrencyGEOProvider + { + $apiKey = $this->config->get('exchange.services.currency_geo.access_key'); + + throw_unless(is_string($apiKey), new InvalidConfigurationException( + 'You haven\'t set up an API key for CurrencyGEO!' + )); + + return new CurrencyGEOProvider( + $this->container->make(Factory::class), + $apiKey, + ); + } + public function createFrankfurterDriver(): FrankfurterProvider { return new FrankfurterProvider( From 9f6f1b834c739e73a2f6431777122755c4074fe1 Mon Sep 17 00:00:00 2001 From: Saifallak Date: Fri, 29 Sep 2023 04:37:20 +0300 Subject: [PATCH 03/11] lower api calls --- .../CurrencyGEOProvider.php | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/ExchangeRateProviders/CurrencyGEOProvider.php b/src/ExchangeRateProviders/CurrencyGEOProvider.php index b18650d..162b956 100644 --- a/src/ExchangeRateProviders/CurrencyGEOProvider.php +++ b/src/ExchangeRateProviders/CurrencyGEOProvider.php @@ -4,7 +4,6 @@ namespace Worksome\Exchange\ExchangeRateProviders; -use Carbon\CarbonImmutable; use Illuminate\Http\Client\Factory; use Illuminate\Http\Client\PendingRequest; use Illuminate\Http\Client\RequestException; @@ -16,9 +15,10 @@ final class CurrencyGEOProvider implements ExchangeRateProvider { public function __construct( private Factory $client, - private string $accessKey, - private string $baseUrl = 'https://api.getgeoapi.com/v2', - ) { + private string $accessKey, + private string $baseUrl = 'https://api.getgeoapi.com/v2', + ) + { } /** @@ -26,6 +26,16 @@ public function __construct( */ public function getRates(string $baseCurrency, array $currencies): Rates { + // if its the same currency return it. + if (sizeof($currencies) == 0 || (sizeof($currencies) == 1 && $baseCurrency == $currencies[0])) { + return new Rates( + $baseCurrency, + // @phpstan-ignore-next-line + [$baseCurrency => 1], + now(), + ); + } + $data = $this->makeRequest($baseCurrency, $currencies); return new Rates( From f12599fdbeaec33dc6ca44ed9aaaf7cc3f67c05f Mon Sep 17 00:00:00 2001 From: Saifallak Date: Thu, 21 Mar 2024 17:50:29 +0200 Subject: [PATCH 04/11] revert exchange key fix. --- config/exchange.php | 15 --------------- .../ExchangeRateHostProvider.php | 4 ++-- src/Support/ExchangeRateManager.php | 7 ------- 3 files changed, 2 insertions(+), 24 deletions(-) diff --git a/config/exchange.php b/config/exchange.php index cd13333..fd84a29 100644 --- a/config/exchange.php +++ b/config/exchange.php @@ -30,21 +30,6 @@ 'access_key' => env('FIXER_ACCESS_KEY'), ], - /* - |-------------------------------------------------------------------------- - | ExchangeRate.host - |-------------------------------------------------------------------------- - | - | ExchangeRate is a paid service for converting currency codes. To use ExchangeRate, you'll - | need an API Access Key from the ExchangeRate dashboard. Set that here, and then - | change the 'default' to 'exchange_rate' or set EXCHANGE_DRIVER to 'exchange_rate'. - | - */ - - 'exchange_rate' => [ - 'access_key' => env('EXCHANGE_RATE_ACCESS_KEY'), - ], - /* |-------------------------------------------------------------------------- | CurrencyGeo.com diff --git a/src/ExchangeRateProviders/ExchangeRateHostProvider.php b/src/ExchangeRateProviders/ExchangeRateHostProvider.php index cb2b04d..01ab089 100644 --- a/src/ExchangeRateProviders/ExchangeRateHostProvider.php +++ b/src/ExchangeRateProviders/ExchangeRateHostProvider.php @@ -12,9 +12,9 @@ final class ExchangeRateHostProvider implements ExchangeRateProvider { private FixerProvider $fixerProvider; - public function __construct(private Factory $client, private string $accessKey) + public function __construct(private Factory $client) { - $this->fixerProvider = new FixerProvider($this->client, $this->accessKey, 'https://api.exchangerate.host'); + $this->fixerProvider = new FixerProvider($this->client, 'https://api.exchangerate.host'); } public function getRates(string $baseCurrency, array $currencies): Rates diff --git a/src/Support/ExchangeRateManager.php b/src/Support/ExchangeRateManager.php index 4e4c9b4..f6752ca 100644 --- a/src/Support/ExchangeRateManager.php +++ b/src/Support/ExchangeRateManager.php @@ -43,15 +43,8 @@ public function createFixerDriver(): FixerProvider public function createExchangeRateDriver(): ExchangeRateHostProvider { - $apiKey = $this->config->get('exchange.services.exchange_rate.access_key'); - - throw_unless(is_string($apiKey), new InvalidConfigurationException( - 'You haven\'t set up an API key for ExchangeRate!' - )); - return new ExchangeRateHostProvider( $this->container->make(Factory::class), - $apiKey, ); } From 46e6c9f3924a8b654ad639578af79f511a2f239b Mon Sep 17 00:00:00 2001 From: Saifallak Date: Thu, 21 Mar 2024 17:51:27 +0200 Subject: [PATCH 05/11] revert exchange key fix. --- src/ExchangeRateProviders/ExchangeRateHostProvider.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ExchangeRateProviders/ExchangeRateHostProvider.php b/src/ExchangeRateProviders/ExchangeRateHostProvider.php index 01ab089..1eb45a4 100644 --- a/src/ExchangeRateProviders/ExchangeRateHostProvider.php +++ b/src/ExchangeRateProviders/ExchangeRateHostProvider.php @@ -14,7 +14,7 @@ final class ExchangeRateHostProvider implements ExchangeRateProvider public function __construct(private Factory $client) { - $this->fixerProvider = new FixerProvider($this->client, 'https://api.exchangerate.host'); + $this->fixerProvider = new FixerProvider($this->client, '', 'https://api.exchangerate.host'); } public function getRates(string $baseCurrency, array $currencies): Rates From a6ddd7abbdd528d36b795866bad5ec16a7dfb092 Mon Sep 17 00:00:00 2001 From: Saifallak Date: Fri, 22 Mar 2024 15:08:28 +0200 Subject: [PATCH 06/11] revert changes. --- config/exchange.php | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/config/exchange.php b/config/exchange.php index cd13333..ea5a3cf 100644 --- a/config/exchange.php +++ b/config/exchange.php @@ -11,7 +11,7 @@ * Supported: 'null', 'fixer', 'exchange_rate', 'frankfurter', 'cache' */ - 'default' => env('EXCHANGE_DRIVER', 'exchange_rate'), + 'default' => env('EXCHANGE_DRIVER', 'frankfurter'), 'services' => [ @@ -36,8 +36,8 @@ |-------------------------------------------------------------------------- | | ExchangeRate is a paid service for converting currency codes. To use ExchangeRate, you'll - | need an API Access Key from the ExchangeRate dashboard. Set that here, and then - | change the 'default' to 'exchange_rate' or set EXCHANGE_DRIVER to 'exchange_rate'. + | need an API Access Key from the ExchangeRate dashboard. Set that here, and then change + | the 'default' to 'exchange_rate' or set EXCHANGE_DRIVER to 'exchange_rate'. | */ @@ -73,9 +73,10 @@ */ 'cache' => [ - 'strategy' => 'exchange_rate', - 'ttl' => 60 * 60 * 24, // 24 hours - 'key' => 'cached_exchange_rates', + 'strategy' => env('EXCHANGE_RATES_CACHE_STRATEGY', 'frankfurter'), + 'ttl' => env('EXCHANGE_RATES_CACHE_TTL', 60 * 60 * 24), // 24 hours + 'key' => env('EXCHANGE_RATES_CACHE_KEY', 'cached_exchange_rates'), + 'store' => env('EXCHANGE_RATES_CACHE_STORE'), ], ], From cd4ec7d124bbd265040a306831d4c4748be4a3ac Mon Sep 17 00:00:00 2001 From: Saifallak Date: Fri, 22 Mar 2024 15:24:09 +0200 Subject: [PATCH 07/11] test for currency geo. --- .../CurrencyGEOProviderTest.php | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 tests/Unit/ExchangeRateProviders/CurrencyGEOProviderTest.php diff --git a/tests/Unit/ExchangeRateProviders/CurrencyGEOProviderTest.php b/tests/Unit/ExchangeRateProviders/CurrencyGEOProviderTest.php new file mode 100644 index 0000000..9993bdf --- /dev/null +++ b/tests/Unit/ExchangeRateProviders/CurrencyGEOProviderTest.php @@ -0,0 +1,77 @@ +getRates('EUR', currencies()); + + expect($rates)->toBeInstanceOf(Rates::class); +}) + ->skip(getenv('CURRENCY_GEO_ACCESS_KEY') === false, 'No CURRENCY_GEO_ACCESS_KEY was defined.') + ->group('integration'); + +it('makes a HTTP request to the correct endpoint', function () { + $client = new Factory(); + $client->fake(['*' => [ + 'timestamp' => now()->subDay()->timestamp, + 'rates' => [ + 'EUR' => 1, // Even though this is an int, it should be converted to a float + 'GBP' => 2.5 + ], + ]]); + + $fixerProvider = new CurrencyGEOProvider($client, 'password'); + $fixerProvider->getRates('EUR', currencies()); + + $client->assertSent(function (Request $request) { + return str_starts_with($request->url(), 'https://api.getgeoapi.com/v2/currency/convert'); + }); +}); + +it('returns floats for all rates', function () { + $client = new Factory(); + $client->fake(['*' => [ + 'timestamp' => now()->subDay()->timestamp, + 'rates' => [ + 'EUR' => 1, // Even though this is an int, it should be converted to a float + 'GBP' => 2.5 + ], + ]]); + + $fixerProvider = new CurrencyGEOProvider($client, 'password'); + $rates = $fixerProvider->getRates('EUR', currencies()); + + expect($rates->getRates())->each->toBeFloat(); +}); + +it('sets the returned timestamp as the retrievedAt timestamp', function () { + Carbon::setTestNow(now()); + + $client = new Factory(); + $client->fake(['*' => [ + 'timestamp' => now()->subDay()->timestamp, + 'rates' => [], + ]]); + + $fixerProvider = new CurrencyGEOProvider($client, 'password'); + $rates = $fixerProvider->getRates('EUR', currencies()); + + expect($rates->getRetrievedAt()->timestamp)->toBe(now()->subDay()->timestamp); +}); + +it('throws a RequestException if a 500 error occurs', function () { + $client = new Factory(); + $client->fake(['*' => Create::promiseFor(new Response(500))]); + + $fixerProvider = new CurrencyGEOProvider($client, 'password'); + $fixerProvider->getRates('EUR', currencies()); +})->throws(RequestException::class); From 6bbdb45ef679610a6b9460550537b41304c6fe81 Mon Sep 17 00:00:00 2001 From: Saifallak Date: Fri, 22 Mar 2024 15:27:20 +0200 Subject: [PATCH 08/11] tests. --- tests/Feature/Support/ExchangeRateManagerTest.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/Feature/Support/ExchangeRateManagerTest.php b/tests/Feature/Support/ExchangeRateManagerTest.php index 2d16d3e..e96ce6f 100644 --- a/tests/Feature/Support/ExchangeRateManagerTest.php +++ b/tests/Feature/Support/ExchangeRateManagerTest.php @@ -3,6 +3,7 @@ use Worksome\Exchange\Contracts\ExchangeRateProvider; use Worksome\Exchange\Exceptions\InvalidConfigurationException; use Worksome\Exchange\ExchangeRateProviders\CachedProvider; +use Worksome\Exchange\ExchangeRateProviders\CurrencyGEOProvider; use Worksome\Exchange\ExchangeRateProviders\ExchangeRateHostProvider; use Worksome\Exchange\ExchangeRateProviders\FixerProvider; use Worksome\Exchange\ExchangeRateProviders\FrankfurterProvider; @@ -25,6 +26,7 @@ ['fixer', FixerProvider::class], ['exchange_rate', ExchangeRateHostProvider::class], ['frankfurter', FrankfurterProvider::class], + ['currency_geo', CurrencyGEOProvider::class], ['cache', CachedProvider::class], ]); @@ -43,3 +45,10 @@ $manager = new ExchangeRateManager($this->app); $manager->driver('fixer'); })->throws(InvalidConfigurationException::class, 'You haven\'t set up an API key for Fixer!'); + +it('will throw the right exception if no geo currency API key has been configured', function () { + config()->set('exchange.services.currency_geo.access_key', null); + + $manager = new ExchangeRateManager($this->app); + $manager->driver('currency_geo'); +})->throws(InvalidConfigurationException::class, 'You haven\'t set up an API key for CurrencyGEO!'); From 45e65fee25a23325d1d5a3a5041980460b238736 Mon Sep 17 00:00:00 2001 From: Saifallak Date: Fri, 22 Mar 2024 15:44:33 +0200 Subject: [PATCH 09/11] fix test. --- .github/workflows/tests.yml | 1 + README.md | 10 +++++++++ .../CurrencyGEOProvider.php | 4 ++-- .../CurrencyGEOProviderTest.php | 22 +++++++++---------- 4 files changed, 24 insertions(+), 13 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index f239fb7..2e4b424 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -13,6 +13,7 @@ jobs: # Fixer and ExchangeRate.host use the same API token FIXER_ACCESS_KEY: ${{ secrets.FIXER_ACCESS_KEY }} EXCHANGE_RATE_ACCESS_KEY: ${{ secrets.FIXER_ACCESS_KEY }} + CURRENCY_GEO_ACCESS_KEY: ${{ secrets.CURRENCY_GEO_ACCESS_KEY }} strategy: fail-fast: true matrix: diff --git a/README.md b/README.md index 3bfc3da..5c26a41 100644 --- a/README.md +++ b/README.md @@ -75,6 +75,16 @@ Set `EXCHANGE_RATE_ACCESS_KEY` to your provided access key from exchangerate.hos With that task completed, you're ready to start using [exchangerate.host](https://exchangerate.host) for retrieving up-to-date exchange rates. +### Currency.GetGeoApi.com + +[Currency.GetGeoApi.com](https://currency.getgeoapi.com) is an alternative option you can use with suitable free quota. + +In your `exchange.php` config file, set `default` to `currency_geo`, or set `EXCHANGE_DRIVER` to `currency_geo` in your `.env` file. +Set `CURRENCY_GEO_ACCESS_KEY` to your provided access key from Currency.GetGeoApi.com. + +With that task completed, you're ready to start using [Currency.GetGeoApi.com](https://currency.getgeoapi.com) for retrieving up-to-date +exchange rates. + ### Frankfurter.app [frankfurter.app](https://frankfurter.app) is an open-source API for current and historical foreign exchange rates published by the European Central Bank, which can be used without an API key. diff --git a/src/ExchangeRateProviders/CurrencyGEOProvider.php b/src/ExchangeRateProviders/CurrencyGEOProvider.php index 162b956..f55b611 100644 --- a/src/ExchangeRateProviders/CurrencyGEOProvider.php +++ b/src/ExchangeRateProviders/CurrencyGEOProvider.php @@ -32,7 +32,7 @@ public function getRates(string $baseCurrency, array $currencies): Rates $baseCurrency, // @phpstan-ignore-next-line [$baseCurrency => 1], - now(), + now()->startOfDay(), ); } @@ -42,7 +42,7 @@ public function getRates(string $baseCurrency, array $currencies): Rates $baseCurrency, // @phpstan-ignore-next-line collect($data->get('rates'))->map(fn(mixed $value) => floatval($value['rate']))->all(), - now(), + now()->startOfDay(), ); } diff --git a/tests/Unit/ExchangeRateProviders/CurrencyGEOProviderTest.php b/tests/Unit/ExchangeRateProviders/CurrencyGEOProviderTest.php index 9993bdf..373bcd9 100644 --- a/tests/Unit/ExchangeRateProviders/CurrencyGEOProviderTest.php +++ b/tests/Unit/ExchangeRateProviders/CurrencyGEOProviderTest.php @@ -11,8 +11,8 @@ it('is able to make a real call to the API', function () { $client = new Factory(); - $fixerProvider = new CurrencyGEOProvider($client, getenv('CURRENCY_GEO_ACCESS_KEY')); - $rates = $fixerProvider->getRates('EUR', currencies()); + $currencyGeoProvider = new CurrencyGEOProvider($client, getenv('CURRENCY_GEO_ACCESS_KEY')); + $rates = $currencyGeoProvider->getRates('EUR', currencies()); expect($rates)->toBeInstanceOf(Rates::class); }) @@ -29,8 +29,8 @@ ], ]]); - $fixerProvider = new CurrencyGEOProvider($client, 'password'); - $fixerProvider->getRates('EUR', currencies()); + $currencyGeoProvider = new CurrencyGEOProvider($client, 'password'); + $currencyGeoProvider->getRates('EUR', currencies()); $client->assertSent(function (Request $request) { return str_starts_with($request->url(), 'https://api.getgeoapi.com/v2/currency/convert'); @@ -47,8 +47,8 @@ ], ]]); - $fixerProvider = new CurrencyGEOProvider($client, 'password'); - $rates = $fixerProvider->getRates('EUR', currencies()); + $currencyGeoProvider = new CurrencyGEOProvider($client, 'password'); + $rates = $currencyGeoProvider->getRates('EUR', currencies()); expect($rates->getRates())->each->toBeFloat(); }); @@ -62,16 +62,16 @@ 'rates' => [], ]]); - $fixerProvider = new CurrencyGEOProvider($client, 'password'); - $rates = $fixerProvider->getRates('EUR', currencies()); + $currencyGeoProvider = new CurrencyGEOProvider($client, 'password'); + $rates = $currencyGeoProvider->getRates('EUR', currencies()); - expect($rates->getRetrievedAt()->timestamp)->toBe(now()->subDay()->timestamp); + expect($rates->getRetrievedAt()->timestamp)->toBe(now()->startOfDay()->timestamp); }); it('throws a RequestException if a 500 error occurs', function () { $client = new Factory(); $client->fake(['*' => Create::promiseFor(new Response(500))]); - $fixerProvider = new CurrencyGEOProvider($client, 'password'); - $fixerProvider->getRates('EUR', currencies()); + $currencyGeoProvider = new CurrencyGEOProvider($client, 'password'); + $currencyGeoProvider->getRates('EUR', currencies()); })->throws(RequestException::class); From 3342850519bb9fa3dc80950b6d36990f67e5dba6 Mon Sep 17 00:00:00 2001 From: Saifallak Date: Fri, 22 Mar 2024 15:51:58 +0200 Subject: [PATCH 10/11] before each. --- tests/Feature/Support/ExchangeRateManagerTest.php | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/Feature/Support/ExchangeRateManagerTest.php b/tests/Feature/Support/ExchangeRateManagerTest.php index e96ce6f..c9f4f2b 100644 --- a/tests/Feature/Support/ExchangeRateManagerTest.php +++ b/tests/Feature/Support/ExchangeRateManagerTest.php @@ -13,6 +13,7 @@ beforeEach(function () { config()->set('exchange.services.fixer.access_key', 'password'); config()->set('exchange.services.exchange_rate.access_key', 'password'); + config()->set('exchange.services.currency_geo.access_key', 'password'); }); it('can instantiate all drivers', function (string $driver, string $expectedClass) { From 1bb1cf4e3831eda743c51f078341231b0b65bf9d Mon Sep 17 00:00:00 2001 From: Owen Voke Date: Fri, 22 Mar 2024 14:24:30 +0000 Subject: [PATCH 11/11] test: resolve tests for CurrencyGEO driver --- README.md | 4 ++-- config/exchange.php | 6 ++--- .../CurrencyGEOProvider.php | 14 +++++------ .../CurrencyGEOProviderTest.php | 24 +++++++++++++++---- 4 files changed, 31 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 5c26a41..6ca58c8 100644 --- a/README.md +++ b/README.md @@ -77,10 +77,10 @@ exchange rates. ### Currency.GetGeoApi.com -[Currency.GetGeoApi.com](https://currency.getgeoapi.com) is an alternative option you can use with suitable free quota. +[Currency.GetGeoApi.com](https://currency.getgeoapi.com) is an alternative option you can use with a free quota. In your `exchange.php` config file, set `default` to `currency_geo`, or set `EXCHANGE_DRIVER` to `currency_geo` in your `.env` file. -Set `CURRENCY_GEO_ACCESS_KEY` to your provided access key from Currency.GetGeoApi.com. +Set `CURRENCY_GEO_ACCESS_KEY` to your provided access key from currency.getgeoapi.com. With that task completed, you're ready to start using [Currency.GetGeoApi.com](https://currency.getgeoapi.com) for retrieving up-to-date exchange rates. diff --git a/config/exchange.php b/config/exchange.php index ea5a3cf..c597ad3 100644 --- a/config/exchange.php +++ b/config/exchange.php @@ -8,7 +8,7 @@ * Go ahead and select a default exchange driver to be used when * looking up exchange rates. * - * Supported: 'null', 'fixer', 'exchange_rate', 'frankfurter', 'cache' + * Supported: 'null', 'fixer', 'exchange_rate', 'frankfurter', 'currency_geo', 'cache' */ 'default' => env('EXCHANGE_DRIVER', 'frankfurter'), @@ -51,8 +51,8 @@ |-------------------------------------------------------------------------- | | CurrencyGeo is a paid service for converting currency codes. To use CurrencyGeo, you'll - | need an API Access Key from the CurrencyGeo dashboard. Set that here, and then - | change the 'default' to 'exchange_rate' or set EXCHANGE_DRIVER to 'exchange_rate'. + | need an API Access Key from the CurrencyGeo dashboard. Set that here, and then change + | the 'default' to 'currency_geo' or set EXCHANGE_DRIVER to 'currency_geo'. | */ diff --git a/src/ExchangeRateProviders/CurrencyGEOProvider.php b/src/ExchangeRateProviders/CurrencyGEOProvider.php index f55b611..a776927 100644 --- a/src/ExchangeRateProviders/CurrencyGEOProvider.php +++ b/src/ExchangeRateProviders/CurrencyGEOProvider.php @@ -15,10 +15,9 @@ final class CurrencyGEOProvider implements ExchangeRateProvider { public function __construct( private Factory $client, - private string $accessKey, - private string $baseUrl = 'https://api.getgeoapi.com/v2', - ) - { + private string $accessKey, + private string $baseUrl = 'https://api.getgeoapi.com/v2', + ) { } /** @@ -26,11 +25,10 @@ public function __construct( */ public function getRates(string $baseCurrency, array $currencies): Rates { - // if its the same currency return it. - if (sizeof($currencies) == 0 || (sizeof($currencies) == 1 && $baseCurrency == $currencies[0])) { + // If it's the same currency return it. + if (count($currencies) === 1 && $baseCurrency === $currencies[0]) { return new Rates( $baseCurrency, - // @phpstan-ignore-next-line [$baseCurrency => 1], now()->startOfDay(), ); @@ -41,7 +39,7 @@ public function getRates(string $baseCurrency, array $currencies): Rates return new Rates( $baseCurrency, // @phpstan-ignore-next-line - collect($data->get('rates'))->map(fn(mixed $value) => floatval($value['rate']))->all(), + collect($data->get('rates'))->map(fn (mixed $value) => floatval($value['rate']))->all(), now()->startOfDay(), ); } diff --git a/tests/Unit/ExchangeRateProviders/CurrencyGEOProviderTest.php b/tests/Unit/ExchangeRateProviders/CurrencyGEOProviderTest.php index 373bcd9..e29d0a0 100644 --- a/tests/Unit/ExchangeRateProviders/CurrencyGEOProviderTest.php +++ b/tests/Unit/ExchangeRateProviders/CurrencyGEOProviderTest.php @@ -24,8 +24,16 @@ $client->fake(['*' => [ 'timestamp' => now()->subDay()->timestamp, 'rates' => [ - 'EUR' => 1, // Even though this is an int, it should be converted to a float - 'GBP' => 2.5 + 'EUR' => [ + 'currency_name' => 'Euro', + 'rate' => 1, + 'rate_for_amount' => 1, + ], + 'GBP' => [ + 'currency_name' => 'Pound sterling', + 'rate' => 2.5, + 'rate_for_amount' => 2.5, + ], ], ]]); @@ -42,8 +50,16 @@ $client->fake(['*' => [ 'timestamp' => now()->subDay()->timestamp, 'rates' => [ - 'EUR' => 1, // Even though this is an int, it should be converted to a float - 'GBP' => 2.5 + 'EUR' => [ + 'currency_name' => 'Euro', + 'rate' => 1, + 'rate_for_amount' => 1, + ], + 'GBP' => [ + 'currency_name' => 'Pound sterling', + 'rate' => 2.5, + 'rate_for_amount' => 2.5, + ], ], ]]);