diff --git a/src/Exchanger.php b/src/Exchanger.php index aa06e07..19445e3 100755 --- a/src/Exchanger.php +++ b/src/Exchanger.php @@ -88,7 +88,7 @@ public function getExchangeRate(ExchangeRateQueryContract $exchangeQuery): Excha // Replace characters reserved in PSR-6 $cacheKeyPrefix = preg_replace('#[\{\}\(\)/\\\@\:]#', '-', $cacheKeyPrefix); - $cacheKey = $cacheKeyPrefix.sha1(serialize($exchangeQuery)); + $cacheKey = $this->generateCacheKey($cacheKeyPrefix, $exchangeQuery); if (\strlen($cacheKey) > 64) { throw new CacheException("Cache key length exceeds 64 characters ('$cacheKey'). This violates PSR-6 standard"); } @@ -106,4 +106,17 @@ public function getExchangeRate(ExchangeRateQueryContract $exchangeQuery): Excha return $rate; } + + private function generateCacheKey($cacheKeyPrefix, ExchangeRateQueryContract $exchangeQuery): string + { + $base = $exchangeQuery->getCurrencyPair()->getBaseCurrency().$exchangeQuery->getCurrencyPair()->getQuoteCurrency(); + + $date = ''; + + if ($exchangeQuery instanceof \Exchanger\Contract\HistoricalExchangeRateQuery) { + $date = $exchangeQuery->getDate()->format('Y-m-d'); + } + + return $cacheKeyPrefix.sha1($base.$date); + } } diff --git a/tests/Tests/ExchangerTest.php b/tests/Tests/ExchangerTest.php index b218909..a688a48 100644 --- a/tests/Tests/ExchangerTest.php +++ b/tests/Tests/ExchangerTest.php @@ -19,6 +19,7 @@ use Exchanger\Exception\CacheException; use Exchanger\Exception\UnsupportedExchangeQueryException; use Exchanger\Exchanger; +use Exchanger\HistoricalExchangeRateQuery; use PHPUnit\Framework\TestCase; class ExchangerTest extends TestCase @@ -139,7 +140,49 @@ public function it_caches_a_rate() $exchangeRateQuery = new ExchangeRateQuery($pair); $rate = new ExchangeRate($pair, 1, new \DateTime(), __CLASS__); $ttl = 3600; - $key = sha1(serialize($exchangeRateQuery)); + $key = sha1("{$exchangeRateQuery->getCurrencyPair()->getBaseCurrency()}{$exchangeRateQuery->getCurrencyPair()->getQuoteCurrency()}"); + + $service = $this->createMock('Exchanger\Contract\ExchangeRateService'); + + $service + ->expects($this->any()) + ->method('supportQuery') + ->willReturn(true); + + $service + ->expects($this->once()) + ->method('getExchangeRate') + ->willReturn($rate); + + $cache = $this->createMock('Psr\SimpleCache\CacheInterface'); + + $cache + ->expects($this->once()) + ->method('get') + ->willReturn(null); + + $cache + ->expects($this->once()) + ->method('set') + ->with($key, $rate, $ttl); + + $exchanger = new Exchanger($service, $cache, ['cache_ttl' => $ttl]); + + $returnedRate = $exchanger->getExchangeRate($exchangeRateQuery); + + $this->assertSame($rate, $returnedRate); + } + + /** + * @test + */ + public function it_caches_a_rate_historical_rate() + { + $pair = CurrencyPair::createFromString('EUR/USD'); + $exchangeRateQuery = new HistoricalExchangeRateQuery($pair, new \DateTime('2020-12-01', new \DateTimeZone('UTC'))); + $rate = new ExchangeRate($pair, 1, new \DateTime('2020-12-01', new \DateTimeZone('UTC')), __CLASS__); + $ttl = 3600; + $key = sha1("{$exchangeRateQuery->getCurrencyPair()->getBaseCurrency()}{$exchangeRateQuery->getCurrencyPair()->getQuoteCurrency()}2020-12-01"); $service = $this->createMock('Exchanger\Contract\ExchangeRateService'); @@ -213,7 +256,7 @@ public function it_supports_overrding_ttl_per_query() $pair = CurrencyPair::createFromString('EUR/USD'); $exchangeRateQuery = new ExchangeRateQuery($pair, ['cache_ttl' => $ttl]); $rate = new ExchangeRate($pair, 1, new \DateTime(), __CLASS__); - $key = sha1(serialize($exchangeRateQuery)); + $key = sha1("{$exchangeRateQuery->getCurrencyPair()->getBaseCurrency()}{$exchangeRateQuery->getCurrencyPair()->getQuoteCurrency()}"); $service = $this->createMock('Exchanger\Contract\ExchangeRateService');