Skip to content

Commit

Permalink
Merge pull request florianv#131 from fastforex/feature/add-fastforex-…
Browse files Browse the repository at this point in the history
…service

Add fastFOREX.io service
  • Loading branch information
florianv authored Feb 18, 2021
2 parents cfc57b7 + 583dc55 commit 00f7d4f
Show file tree
Hide file tree
Showing 6 changed files with 190 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ Here is the complete list of the currently implemented services:
| [Xignite](https://www.xignite.com) | * | * | Yes |
| [Currency Converter API](https://www.currencyconverterapi.com) | * | * | Yes (free but limited or paid) |
| [xChangeApi.com](https://xchangeapi.com) | * | * | Yes |
| [fastFOREX.io](https://www.fastforex.io) | USD (free), * (paid) | * | No |
| Array | * | * | Yes |

## Credits
Expand Down
90 changes: 90 additions & 0 deletions src/Service/FastForex.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
<?php

declare(strict_types=1);

/*
* This file is part of Exchanger.
*
* (c) Florian Voutzinos <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Exchanger\Service;

use Exchanger\Contract\CurrencyPair;
use Exchanger\Contract\ExchangeRateQuery;
use Exchanger\Contract\HistoricalExchangeRateQuery;
use Exchanger\Exception\Exception;
use Exchanger\Exception\UnsupportedCurrencyPairException;
use Exchanger\ExchangeRate;
use Exchanger\StringUtil;
use Exchanger\Contract\ExchangeRate as ExchangeRateContract;

/**
* fastFOREX.io Service.
*
* @author Tom <[email protected]>
*/
final class FastForex extends HttpService
{

const FETCH_ONE_URL = 'https://api.fastforex.io/fetch-one?from=%s&to=%s&api_key=%s';

/**
* {@inheritdoc}
*/
public function processOptions(array &$options): void
{
if (!isset($options['api_key'])) {
throw new \InvalidArgumentException('The "api_key" option must be provided.');
}
}

/**
* {@inheritdoc}
*/
public function supportQuery(ExchangeRateQuery $exchangeQuery): bool
{
return !$exchangeQuery instanceof \Exchanger\HistoricalExchangeRateQuery;
}

/**
* {@inheritdoc}
*/
public function getExchangeRate(ExchangeRateQuery $exchangeRateQuery): ExchangeRateContract
{
$currencyPair = $exchangeRateQuery->getCurrencyPair();
$baseCurrency = $currencyPair->getBaseCurrency();
$quoteCurrency = $currencyPair->getQuoteCurrency();
$url = sprintf(self::FETCH_ONE_URL, $baseCurrency, $quoteCurrency, $this->options['api_key']);

$content = $this->request($url);
$result = StringUtil::jsonToArray($content);

if (!isset($result['error'])) {
try {
$date = new \DateTime($result['updated']);
} catch (\Throwable $thrown) {
$date = new \DateTime();
}
if (isset($result['base']) && $result['base'] == $baseCurrency) {
if (isset($result['result'][$quoteCurrency])) {
return $this->createRate($currencyPair, (float)($result['result'][$quoteCurrency]), $date);
}
}
}

throw new UnsupportedCurrencyPairException($currencyPair, $this);
}

/**
* {@inheritdoc}
*/
public function getName(): string
{
return 'fastforex';
}

}
1 change: 1 addition & 0 deletions src/Service/Registry.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ public static function getServices(): array
'national_bank_of_ukraine' => NationalBankOfUkraine::class,
'coin_layer' => CoinLayer::class,
'xchangeapi' => XchangeApi::class,
'fastforex' => FastForex::class,
];
}
}
3 changes: 3 additions & 0 deletions tests/Fixtures/Service/FastForex/error-unsupported.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"error": "Invalid/unsupported target currency: [ZZZ]"
}
8 changes: 8 additions & 0 deletions tests/Fixtures/Service/FastForex/one-usd-eur.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"base": "USD",
"result": {
"EUR": 0.8258
},
"updated": "2021-02-16 17:28:56",
"ms": 4
}
87 changes: 87 additions & 0 deletions tests/Tests/Service/FastForexTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
<?php

declare(strict_types=1);

/*
* This file is part of Exchanger.
*
* (c) Florian Voutzinos <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Exchanger\Tests\Service;

use Exchanger\Exception\Exception;
use Exchanger\HistoricalExchangeRateQuery;
use Exchanger\CurrencyPair;
use Exchanger\ExchangeRateQuery;
use Exchanger\Service\FastForex;

class FastForexTest extends ServiceTestCase
{
/**
* @test
*/
public function it_does_not_support_all_queries()
{
$service = new FastForex($this->createMock('Http\Client\HttpClient'), null, ['api_key' => 'secret']);

$this->assertTrue($service->supportQuery(new ExchangeRateQuery(CurrencyPair::createFromString('EUR/USD'))));
$this->assertFalse($service->supportQuery(new HistoricalExchangeRateQuery(CurrencyPair::createFromString('EUR/USD'), new \DateTime())));
}

/**
* @test
*/
public function it_throws_an_exception_when_rate_not_supported()
{
$this->expectException(Exception::class);
$url = 'https://api.fastforex.io/fetch-one?from=EUR&to=ZZZ&api_key=secret';
$content = file_get_contents(__DIR__.'/../../Fixtures/Service/FastForex/error-unsupported.json');
$service = new FastForex($this->getHttpAdapterMock($url, $content), null, ['api_key' => 'secret']);

$service->getExchangeRate(new ExchangeRateQuery(CurrencyPair::createFromString('EUR/ZZZ')));
}

/**
* @test
*/
public function it_fetches_a_rate_when_response_symbol_matches()
{
$pair = CurrencyPair::createFromString('USD/EUR');
$url = 'https://api.fastforex.io/fetch-one?from=USD&to=EUR&api_key=secret';
$content = file_get_contents(__DIR__.'/../../Fixtures/Service/FastForex/one-usd-eur.json');
$service = new FastForex($this->getHttpAdapterMock($url, $content), null, ['api_key' => 'secret']);

$rate = $service->getExchangeRate(new ExchangeRateQuery($pair));
$this->assertSame(0.8258, $rate->getValue());
$this->assertEquals('2021-02-16', $rate->getDate()->format('Y-m-d'));
$this->assertEquals('fastforex', $rate->getProviderName());
$this->assertSame($pair, $rate->getCurrencyPair());
}

/**
* @test
*/
public function it_throws_an_exception_when_response_symbol_does_not_match()
{
$this->expectException(Exception::class);
$url = 'https://api.fastforex.io/fetch-one?from=USD&to=AED&api_key=secret';
$content = file_get_contents(__DIR__.'/../../Fixtures/Service/FastForex/one-usd-eur.json');
$service = new FastForex($this->getHttpAdapterMock($url, $content), null, ['api_key' => 'secret']);

$service->getExchangeRate(new ExchangeRateQuery(CurrencyPair::createFromString('USD/AED')));
}

/**
* @test
*/
public function it_has_a_name()
{
$service = new FastForex($this->createMock('Http\Client\HttpClient'), null, ['api_key' => 'secret']);

$this->assertSame('fastforex', $service->getName());
}
}

0 comments on commit 00f7d4f

Please sign in to comment.