Skip to content

Commit

Permalink
Merge pull request #23 from jbrinksmeier/master
Browse files Browse the repository at this point in the history
fixes #22 adopt to new endpoint and account structure of fixer.io
  • Loading branch information
ojhaujjwal authored Jul 5, 2018
2 parents a0f0aa4 + ebe7d9e commit 0f3a927
Show file tree
Hide file tree
Showing 6 changed files with 167 additions and 9 deletions.
4 changes: 2 additions & 2 deletions src/CurrencyConverter.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace CurrencyConverter;

use CurrencyConverter\Provider\FixerApi;
use CurrencyConverter\Provider\ExchangeRatesIo;

class CurrencyConverter implements CurrencyConverterInterface
{
Expand Down Expand Up @@ -79,7 +79,7 @@ public function isCacheable()
public function getRateProvider()
{
if (!$this->rateProvider) {
$this->setRateProvider(new FixerApi());
$this->setRateProvider(new ExchangeRatesIo());
}

return $this->rateProvider;
Expand Down
51 changes: 51 additions & 0 deletions src/Provider/ExchangeRatesIo.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php
namespace CurrencyConverter\Provider;

use CurrencyConverter\Exception\UnsupportedCurrencyException;
use GuzzleHttp\Client;

/**
* Get exchange rates from https://exchangeratesapi.io/
*/
class ExchangeRatesIo implements ProviderInterface
{
/**
* Base url of fixer api
*
* @var string
*/
const EXCHANGERATESIO_API_BASEPATH = 'https://exchangeratesapi.io/api/latest';

/**
* @var Client
*/
protected $httpClient;

/**
* FixerApi constructor.
* @param Client|null $httpClient
*/
public function __construct(Client $httpClient = null)
{
$this->httpClient = $httpClient ?: new Client();
}

/**
* {@inheritdoc}
*/
public function getRate($fromCurrency, $toCurrency)
{
$path = sprintf(
self::EXCHANGERATESIO_API_BASEPATH . '?symbols=%s&base=%s',
$toCurrency,
$fromCurrency
);
$result = json_decode($this->httpClient->get($path)->getBody(), true);

if (!isset($result['rates'][$toCurrency])) {
throw new UnsupportedCurrencyException(sprintf('Undefined rate for "%s" currency.', $toCurrency));
}

return $result['rates'][$toCurrency];
}
}
25 changes: 22 additions & 3 deletions src/Provider/FixerApi.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,37 @@ class FixerApi implements ProviderInterface
*
* @var string
*/
const FIXER_API_BASEPATH = 'https://api.fixer.io/latest';
const FIXER_API_BASEPATH = 'data.fixer.io/api/latest';

/**
* The fixer access key
*
* @var string
*/
protected $accessKey;

/**
* @var Client
*/
protected $httpClient;

/**
* Flag to switch http(s) usage. required as fixer.io enables https api endpoints for paid accounts only
* @var bool
*/
protected $useHttps = false;

/**
* FixerApi constructor.
* @param string $accessKey
* @param Client|null $httpClient
* @param bool $useHttps defaults to false
*/
public function __construct(Client $httpClient = null)
public function __construct($accessKey, Client $httpClient = null, $useHttps = false)
{
$this->accessKey = $accessKey;
$this->httpClient = $httpClient ?: new Client();
$this->useHttps = (bool)$useHttps;
}

/**
Expand All @@ -38,7 +55,9 @@ public function __construct(Client $httpClient = null)
public function getRate($fromCurrency, $toCurrency)
{
$path = sprintf(
self::FIXER_API_BASEPATH . '?symbols=%s&base=%s',
'%s' . self::FIXER_API_BASEPATH . '?access_key=%s&symbols=%s&base=%s',
($this->useHttps) ? 'https://' : 'http://',
$this->accessKey,
$toCurrency,
$fromCurrency
);
Expand Down
7 changes: 7 additions & 0 deletions tests/CurrencyConverterTest/CurrencyConverterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
namespace CurrencyConverterTest;

use CurrencyConverter\CurrencyConverter;
use CurrencyConverter\Provider\ExchangeRatesIo;

class CurrencyConverterTest extends \PHPUnit_Framework_TestCase
{
Expand Down Expand Up @@ -48,4 +49,10 @@ public function testGetExceptionWithInvalidCurrencyArgument()
$converter->convert([], []);
$converter->convert(29, 456);
}

public function testDefaultRateProvider()
{
$converter = new CurrencyConverter();
$this->assertInstanceOf(ExchangeRatesIo::class, $converter->getRateProvider());
}
}
57 changes: 57 additions & 0 deletions tests/CurrencyConverterTest/Provider/ExchangeRatesIoTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?php
namespace CurrencyConverter\Provider;

use CurrencyConverter\Exception\UnsupportedCurrencyException;
use GuzzleHttp\Client;
use GuzzleHttp\Psr7\Stream;
use Psr\Http\Message\ResponseInterface;

class ExchangeRatesIoTest extends \PHPUnit_Framework_TestCase
{
public function testGetRate()
{
$response = $this->getMock(ResponseInterface::class);
$response
->expects($this->any())
->method('getBody')
->will($this->returnValue(
new Stream(fopen('data://text/plain,{"base":"EUR","date":"2017-11-02","rates":{"USD":1.1645}}', 'r'))
));
$httpClient = $this->getMock(Client::class);
$httpClient
->expects($this->once())
->method('__call')
->with(
'get',
[ExchangeRatesIo::EXCHANGERATESIO_API_BASEPATH . '?symbols=USD&base=EUR']
)
->will($this->returnValue($response));
$this->assertEquals(
1.1645,
(new ExchangeRatesIo($httpClient))->getRate('EUR', 'USD')
);
}

public function testGetUnavailableRate()
{
$response = $this->getMock(ResponseInterface::class);
$response
->expects($this->any())
->method('getBody')
->will($this->returnValue(
new Stream(fopen('data://text/plain,{"base":"EUR","date":"2017-11-28","rates":{}}', 'r'))
));
$httpClient = $this->getMock(Client::class);
$httpClient
->expects($this->once())
->method('__call')
->with(
'get',
[ExchangeRatesIo::EXCHANGERATESIO_API_BASEPATH . '?symbols=XXX&base=EUR']
)
->will($this->returnValue($response));

$this->setExpectedException(UnsupportedCurrencyException::class);
(new ExchangeRatesIo($httpClient))->getRate('EUR', 'XXX');
}
}
32 changes: 28 additions & 4 deletions tests/CurrencyConverterTest/Provider/FixerApiTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@ public function testGetRate()
->method('__call')
->with(
'get',
[FixerApi::FIXER_API_BASEPATH . '?symbols=USD&base=EUR']
['http://' . FixerApi::FIXER_API_BASEPATH . '?access_key=SOME-ACCESS-KEY&symbols=USD&base=EUR']
)
->will($this->returnValue($response));
$this->assertEquals(
1.1645,
(new FixerApi($httpClient))->getRate('EUR', 'USD')
(new FixerApi('SOME-ACCESS-KEY', $httpClient))->getRate('EUR', 'USD')
);
}

Expand All @@ -48,12 +48,36 @@ public function testGetUnavailableRate()
->method('__call')
->with(
'get',
[FixerApi::FIXER_API_BASEPATH . '?symbols=XXX&base=EUR']
['http://' . FixerApi::FIXER_API_BASEPATH . '?access_key=SOME-ACCESS-KEY&symbols=XXX&base=EUR']
)
->will($this->returnValue($response));

$this->setExpectedException(UnsupportedCurrencyException::class);
(new FixerApi($httpClient))->getRate('EUR', 'XXX');
(new FixerApi('SOME-ACCESS-KEY', $httpClient))->getRate('EUR', 'XXX');
}

public function testHttpsUsage()
{
$response = $this->getMock(ResponseInterface::class);
$response
->expects($this->any())
->method('getBody')
->will($this->returnValue(
new Stream(fopen('data://text/plain,{"base":"EUR","date":"2017-11-02","rates":{"USD":1.1645}}', 'r'))
));
$httpClient = $this->getMock(Client::class);
$httpClient
->expects($this->once())
->method('__call')
->with(
'get',
['https://' . FixerApi::FIXER_API_BASEPATH . '?access_key=SOME-ACCESS-KEY&symbols=USD&base=EUR']
)
->will($this->returnValue($response));
$this->assertEquals(
1.1645,
(new FixerApi('SOME-ACCESS-KEY', $httpClient, true))->getRate('EUR', 'USD')
);
}

}

0 comments on commit 0f3a927

Please sign in to comment.