Skip to content

Commit ce04e79

Browse files
committed
Fix CurrencyLayer and add test coverage
1 parent ac2dab1 commit ce04e79

File tree

4 files changed

+139
-48
lines changed

4 files changed

+139
-48
lines changed

src/Drivers/CurrencyLayer.php

Lines changed: 48 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,10 @@ class CurrencyLayer extends BaseCurrencyDriver implements CurrencyDriverContract
1919
/** @var string $baseCurrency CurrencyLayer's Free Plan base currency is 'USD' */
2020
protected $baseCurrency = Symbol::USD;
2121

22-
protected $httpParams = [
23-
'format' => 1
22+
protected $httpParams = [
23+
'format' => 1,
2424
];
2525

26-
2726
/**
2827
* @param string|array $forCurrency
2928
*
@@ -40,12 +39,45 @@ public function get($forCurrency = []): ConversionResult
4039
// Get API response
4140
$response = $this->apiRequest('live', [
4241
'source' => $this->getBaseCurrency(),
43-
'currencies' => join(',', $this->getSymbols())
42+
'currencies' => join(',', $this->getSymbols()),
4443
]);
4544

4645
// Transform rates response
4746
$rates = [];
48-
foreach($response['quotes'] as $currency => $rate) {
47+
foreach ($response['quotes'] as $currency => $rate) {
48+
$rates[substr($currency, 3, 3)] = $rate;
49+
}
50+
51+
return new ConversionResult($response['source'], $response['timestamp'], $rates);
52+
}
53+
54+
/**
55+
* @param int|string|DateTime $date
56+
* @param string|array $forCurrency
57+
*
58+
* @return ConversionResult
59+
*
60+
* @throws CurrencyException
61+
*/
62+
public function historical($date = null, $forCurrency = []): ConversionResult
63+
{
64+
// Set date
65+
$this->date($date);
66+
67+
if (!empty((array)$forCurrency)) {
68+
$this->currencies((array)$forCurrency);
69+
}
70+
71+
// Get API response
72+
$response = $this->apiRequest('historical', [
73+
'date' => $this->date,
74+
'source' => $this->getBaseCurrency(),
75+
'currencies' => join(',', $this->getSymbols()),
76+
]);
77+
78+
// Transform rates response
79+
$rates = [];
80+
foreach ($response['quotes'] as $currency => $rate) {
4981
$rates[substr($currency, 3, 3)] = $rate;
5082
}
5183

@@ -69,64 +101,35 @@ public function convert(float $amount = null, string $fromCurrency = null, strin
69101
$this->date($date);
70102

71103
// Overwrite/set params
72-
if($amount !== null) {
104+
if ($amount !== null) {
73105
$this->amount = $amount;
74106
}
75107

76-
if($fromCurrency !== null) {
108+
if ($fromCurrency !== null) {
77109
$this->baseCurrency = $fromCurrency;
78110
}
79111

80-
if($toCurrency !== null) {
112+
if ($toCurrency !== null) {
81113
$this->currencies = [$toCurrency];
82114
}
83115

84-
// Get API response
85-
$response = $this->apiRequest('convert', [
116+
$params = [
86117
'from' => $this->getBaseCurrency(),
87118
'to' => reset($this->currencies),
88-
'amount' => $this->amount
89-
]);
90-
91-
// Return the rate as a float
92-
return floatval($response['info']['rate']);
93-
}
94-
95-
/**
96-
* @param int|string|DateTime $date
97-
* @param string|array $forCurrency
98-
*
99-
* @return ConversionResult
100-
*
101-
* @throws CurrencyException
102-
* @throws \GuzzleHttp\Exception\GuzzleException
103-
*/
104-
public function historical($date = null, $forCurrency = []): ConversionResult
105-
{
106-
// Set date
107-
$this->date($date);
119+
'amount' => $this->amount,
120+
];
108121

109-
if (!empty((array)$forCurrency)) {
110-
$this->currencies((array)$forCurrency);
122+
if (null !== $this->getDate()) {
123+
$params['date'] = $this->getDate();
111124
}
112125

113126
// Get API response
114-
$response = $this->apiRequest('historical', [
115-
'date' => $this->date,
116-
'source' => $this->getBaseCurrency(),
117-
'currencies' => join(',', $this->getSymbols())
118-
]);
119-
120-
// Transform rates response
121-
$rates = [];
122-
foreach($response['quotes'] as $currency => $rate) {
123-
$rates[substr($currency, 3, 3)] = $rate;
124-
}
127+
$response = $this->apiRequest('convert', $params);
125128

126-
return new ConversionResult($response['source'], $response['timestamp'], $rates);
129+
// Return the rate as a float
130+
return floatval($response['result']);
127131
}
128132

129-
130133
/**
131134
* Performs an HTTP request.
132135
*
@@ -150,5 +153,4 @@ function apiRequest(string $endpoint, array $params = [], string $method = 'GET'
150153

151154
return $response;
152155
}
153-
154156
}

src/Drivers/FixerIo.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ class FixerIo extends BaseCurrencyDriver implements CurrencyDriverContract
1919
/** @var string $baseCurrency Fixer.io's Free Plan base currency is 'EUR' */
2020
protected $baseCurrency = Symbol::EUR;
2121

22+
2223
/**
2324
* @param string|array $forCurrency
2425
*

tests/Drivers/CurrencyLayerTest.php

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
<?php
2+
3+
use GuzzleHttp\Client;
4+
use GuzzleHttp\Handler\MockHandler;
5+
use GuzzleHttp\Psr7\Response;
6+
use Otherguy\Currency\DriverFactory;
7+
use Otherguy\Currency\Drivers\CurrencyLayer;
8+
use Otherguy\Currency\Exceptions\ApiException;
9+
use Otherguy\Currency\Results\ConversionResult;
10+
use Otherguy\Currency\Symbol;
11+
use PHPUnit\Framework\TestCase;
12+
13+
/**
14+
* CurrencyLayerTest
15+
*/
16+
class CurrencyLayerTest extends TestCase
17+
{
18+
/** @var CurrencyLayer */
19+
private $currencyLayer;
20+
21+
private $mockHandler;
22+
23+
protected function setUp()
24+
{
25+
$this->mockHandler = new MockHandler();
26+
$this->currencyLayer = DriverFactory::make('currencylayer', new Client(['handler' => $this->mockHandler]));
27+
}
28+
29+
/** @test */
30+
public function can_get_latest_rates()
31+
{
32+
// Response from https://currencylayer.com/documentation
33+
$this->mockHandler->append(new Response(200, [], '{"success":true,"terms":"https://currencylayer.com/terms","privacy":"https://currencylayer.com/privacy","timestamp":1432400348,"source":"USD","quotes":{"USDAUD":1.278342,"USDEUR":1.278342,"USDGBP":0.908019,"USDPLN":3.731504}}'));
34+
35+
$result = $this->currencyLayer->from(Symbol::USD)->get([Symbol::AUD, Symbol::EUR, Symbol::GBP, Symbol::PLN]);
36+
37+
$this->assertInstanceOf(ConversionResult::class, $result);
38+
39+
$this->assertEquals(Symbol::USD, $result->getBaseCurrency());
40+
$this->assertEquals('2015-05-23', $result->getDate());
41+
42+
$this->assertEquals(1.278342, $result->rate(Symbol::AUD));
43+
$this->assertEquals(1.278342, $result->rate(Symbol::EUR));
44+
$this->assertEquals(0.908019, $result->rate(Symbol::GBP));
45+
$this->assertEquals(3.731504, $result->rate(Symbol::PLN));
46+
}
47+
48+
49+
/** @test */
50+
public function can_get_historical_rates()
51+
{
52+
// Response from https://currencylayer.com/documentation
53+
$this->mockHandler->append(new Response(200, [], '{"success":true,"terms":"https://currencylayer.com/terms","privacy":"https://currencylayer.com/privacy","historical":true,"date":"2005-02-01","timestamp":1107302399,"source":"USD","quotes":{"USDAED":3.67266,"USDALL":96.848753,"USDAMD":475.798297,"USDANG":1.790403,"USDARS":2.918969,"USDAUD":1.293878}}'));
54+
55+
$result = $this->currencyLayer->from(Symbol::USD)->historical('2005-02-01', [Symbol::AED, Symbol::ALL, Symbol::AMD, Symbol::ANG, Symbol::ARS, Symbol::AUD]);
56+
57+
$this->assertInstanceOf(ConversionResult::class, $result);
58+
59+
$this->assertEquals(Symbol::USD, $result->getBaseCurrency());
60+
$this->assertEquals('2005-02-01', $result->getDate());
61+
62+
$this->assertEquals(3.67266, $result->rate(Symbol::AED));
63+
$this->assertEquals(96.848753, $result->rate(Symbol::ALL));
64+
$this->assertEquals(475.798297, $result->rate(Symbol::AMD));
65+
$this->assertEquals(1.790403, $result->rate(Symbol::ANG));
66+
$this->assertEquals(2.918969, $result->rate(Symbol::ARS));
67+
$this->assertEquals(1.293878, $result->rate(Symbol::AUD));
68+
}
69+
70+
/** @test */
71+
public function can_convert_currency_amounts()
72+
{
73+
// Response from https://currencylayer.com/documentation
74+
$this->mockHandler->append(new Response(200, [], '{"success":true,"terms":"https://currencylayer.com/terms","privacy":"https://currencylayer.com/privacy","query":{"from":"USD","to":"GBP","amount":10},"info":{"timestamp":1430068515,"quote":0.658443},"result":6.58443}'));
75+
76+
$result = $this->currencyLayer->from(Symbol::USD)->date(1430068515)->convert(10, Symbol::USD, Symbol::GBP);
77+
$this->assertEquals(6.58443, $result);
78+
}
79+
80+
/** @test */
81+
public function can_handle_response_failures()
82+
{
83+
// Response from https://currencylayer.com/documentation
84+
$this->mockHandler->append(new Response(200, [], '{"success":false,"error":{"code":104,"info":"Your monthly usage limit has been reached. Please upgrade your subscription plan."}}'));
85+
86+
$this->expectException(ApiException::class);
87+
$this->currencyLayer->from(Symbol::USD)->to(Symbol::LTL)->get();
88+
}
89+
}

tests/Drivers/FixerIoTest.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
use GuzzleHttp\Client;
44
use GuzzleHttp\Handler\MockHandler;
5-
use GuzzleHttp\HandlerStack;
65
use GuzzleHttp\Psr7\Response;
76
use Otherguy\Currency\DriverFactory;
87
use Otherguy\Currency\Drivers\FixerIo;
@@ -64,7 +63,7 @@ public function can_get_historical_rates()
6463
}
6564

6665
/** @test */
67-
public function can_get_conversion_rates()
66+
public function can_convert_currency_amounts()
6867
{
6968
// Response from https://fixer.io/documentation
7069
$this->mockHandler->append(new Response(200, [], '{ "success": true, "query": { "from": "GBP", "to": "JPY", "amount": 25 }, "info": { "timestamp": 1519328414, "rate": 148.972231 }, "historical": "true", "date": "2018-02-22", "result": 3724.305775 }'));

0 commit comments

Comments
 (0)