Implement currencies endpoint

This commit is contained in:
Hakan Ensari 2018-10-10 13:39:25 +01:00
parent 8d61d97c69
commit c1e1644c52
7 changed files with 84 additions and 11 deletions

View File

@ -4,6 +4,7 @@ source 'http://rubygems.org'
ruby '2.5.1' ruby '2.5.1'
gem 'money'
gem 'oj' gem 'oj'
gem 'ox' gem 'ox'
gem 'rack-cors' gem 'rack-cors'

View File

@ -6,6 +6,7 @@ GEM
ast (2.4.0) ast (2.4.0)
builder (3.2.3) builder (3.2.3)
coderay (1.1.2) coderay (1.1.2)
concurrent-ruby (1.0.5)
crack (0.4.3) crack (0.4.3)
safe_yaml (~> 1.0.0) safe_yaml (~> 1.0.0)
et-orbi (1.1.6) et-orbi (1.1.6)
@ -15,12 +16,16 @@ GEM
et-orbi (~> 1.1, >= 1.1.6) et-orbi (~> 1.1, >= 1.1.6)
raabro (~> 1.1) raabro (~> 1.1)
hashdiff (0.3.7) hashdiff (0.3.7)
i18n (1.1.0)
concurrent-ruby (~> 1.0)
jaro_winkler (1.5.1) jaro_winkler (1.5.1)
kgio (2.11.2) kgio (2.11.2)
method_source (0.9.0) method_source (0.9.0)
minitest (5.11.3) minitest (5.11.3)
minitest-around (0.4.1) minitest-around (0.4.1)
minitest (~> 5.0) minitest (~> 5.0)
money (6.13.0)
i18n (>= 0.6.4, <= 2)
mustermann (1.0.3) mustermann (1.0.3)
oj (3.6.11) oj (3.6.11)
ox (2.10.0) ox (2.10.0)
@ -64,7 +69,7 @@ GEM
sass-listen (4.0.0) sass-listen (4.0.0)
rb-fsevent (~> 0.9, >= 0.9.4) rb-fsevent (~> 0.9, >= 0.9.4)
rb-inotify (~> 0.9, >= 0.9.7) rb-inotify (~> 0.9, >= 0.9.7)
sequel (5.12.0) sequel (5.13.0)
sequel_pg (1.11.0) sequel_pg (1.11.0)
pg (>= 0.18.0) pg (>= 0.18.0)
sequel (>= 4.38.0) sequel (>= 4.38.0)
@ -97,6 +102,7 @@ PLATFORMS
DEPENDENCIES DEPENDENCIES
minitest minitest
minitest-around minitest-around
money
oj oj
ox ox
pry pry

View File

@ -32,6 +32,12 @@ Get historical rates for a time period up to the present.
GET /2010-01-01.. HTTP/1.1 GET /2010-01-01.. HTTP/1.1
``` ```
Get a list of available currency symbols, along with their full names.
```http
GET /currencies HTTP/1.1
```
Rates quote against the Euro by default. Quote against a different currency. Rates quote against the Euro by default. Quote against a different currency.
```http ```http

30
lib/currency_names.rb Normal file
View File

@ -0,0 +1,30 @@
# frozen_string_literal: true
require 'currency'
require 'money/currency'
class CurrencyNames
def cache_key
Digest::MD5.hexdigest(currencies.first.date.to_s)
end
def formatted
iso_codes.each_with_object({}) do |iso_code, result|
result[iso_code] = Money::Currency.find(iso_code).name
end
end
private
def iso_codes
currencies.map(&:iso_code).append('EUR').sort
end
def currencies
@currencies ||= find_currencies
end
def find_currencies
Currency.latest.all
end
end

View File

@ -6,6 +6,7 @@ require 'redcarpet'
require 'sass/plugin/rack' require 'sass/plugin/rack'
require 'sinatra' require 'sinatra'
require 'currency_names'
require 'query' require 'query'
require 'quote' require 'quote'
@ -102,6 +103,12 @@ get '/(?<start_date>\d{4}-\d{2}-\d{2})\.\.(?<end_date>\d{4}-\d{2}-\d{2})?',
json interval_quote.formatted json interval_quote.formatted
end end
get '/currencies' do
currency_names = CurrencyNames.new
etag currency_names.cache_key
json currency_names.formatted
end
not_found do not_found do
halt 404 halt 404
end end

View File

@ -0,0 +1,18 @@
# frozen_string_literal: true
require_relative 'helper'
require 'currency_names'
describe CurrencyNames do
let(:currency_names) do
CurrencyNames.new
end
it 'returns currency codes and names' do
currency_names.formatted['USD'].must_equal 'United States Dollar'
end
it 'has a cache key' do
currency_names.cache_key.wont_be :empty?
end
end

View File

@ -16,25 +16,25 @@ describe 'the server' do
last_response.must_be :ok? last_response.must_be :ok?
end end
it 'returns current quotes' do it 'returns latest quotes' do
get '/current' get '/latest'
last_response.must_be :ok? last_response.must_be :ok?
end end
it 'sets base currency' do it 'sets base currency' do
get '/current' get '/latest'
res = Oj.load(last_response.body) res = Oj.load(last_response.body)
get '/current?from=USD' get '/latest?from=USD'
json.wont_equal res json.wont_equal res
end end
it 'sets base amount' do it 'sets base amount' do
get '/current?amount=10' get '/latest?amount=10'
json['rates']['USD'].must_be :>, 10 json['rates']['USD'].must_be :>, 10
end end
it 'filters symbols' do it 'filters symbols' do
get '/current?to=USD' get '/latest?to=USD'
json['rates'].keys.must_equal %w[USD] json['rates'].keys.must_equal %w[USD]
end end
@ -50,14 +50,14 @@ describe 'the server' do
end end
it 'returns an ETag' do it 'returns an ETag' do
%w[/current /2012-11-20].each do |path| %w[/latest /2012-11-20].each do |path|
get path get path
headers['ETag'].wont_be_nil headers['ETag'].wont_be_nil
end end
end end
it 'allows cross-origin requests' do it 'allows cross-origin requests' do
%w[/ /current /2012-11-20].each do |path| %w[/ /latest /2012-11-20].each do |path|
header 'Origin', '*' header 'Origin', '*'
get path get path
assert headers.key?('Access-Control-Allow-Methods') assert headers.key?('Access-Control-Allow-Methods')
@ -65,7 +65,7 @@ describe 'the server' do
end end
it 'responds to preflight requests' do it 'responds to preflight requests' do
%w[/ /current /2012-11-20].each do |path| %w[/ /latest /2012-11-20].each do |path|
header 'Origin', '*' header 'Origin', '*'
header 'Access-Control-Request-Method', 'GET' header 'Access-Control-Request-Method', 'GET'
header 'Access-Control-Request-Headers', 'Content-Type' header 'Access-Control-Request-Headers', 'Content-Type'
@ -75,7 +75,7 @@ describe 'the server' do
end end
it 'converts an amount' do it 'converts an amount' do
get '/current?from=GBP&to=USD&amount=100' get '/latest?from=GBP&to=USD&amount=100'
json['rates']['USD'].must_be :>, 100 json['rates']['USD'].must_be :>, 100
end end
@ -92,4 +92,9 @@ describe 'the server' do
json['end_date'].wont_be :empty? json['end_date'].wont_be :empty?
json['rates'].wont_be :empty? json['rates'].wont_be :empty?
end end
it 'returns currencies' do
get '/currencies'
json['USD'].must_equal 'United States Dollar'
end
end end