Add support for easier centralized caching #8

Merged
merged 1 commit into from May 6, 2012
@@ -7,16 +7,13 @@ class InvalidCache < StandardError ; end
class EuCentralBank < Money::Bank::VariableExchange
+ attr_accessor :last_updated
+
ECB_RATES_URL = 'http://www.ecb.int/stats/eurofxref/eurofxref-daily.xml'
CURRENCIES = %w(USD JPY BGN CZK DKK GBP HUF LTL LVL PLN RON SEK CHF NOK HRK RUB TRY AUD BRL CAD CNY HKD IDR INR KRW MXN MYR NZD PHP SGD THB ZAR)
def update_rates(cache=nil)
- exchange_rates(cache).each do |exchange_rate|
- rate = exchange_rate.attribute("rate").value.to_f
- currency = exchange_rate.attribute("currency").value
- add_rate("EUR", currency, rate)
- end
- add_rate("EUR", "EUR", 1)
+ update_parsed_rates(exchange_rates(cache))
end
def save_rates(cache)
@@ -27,6 +24,14 @@ def save_rates(cache)
end
end
+ def update_rates_from_s(content)
+ update_parsed_rates(exchange_rates_from_s(content))
+ end
+
+ def save_rates_to_s
+ open(ECB_RATES_URL).read
+ end
+
def exchange(cents, from_currency, to_currency)
exchange_with(Money.new(cents, from_currency), to_currency)
end
@@ -49,4 +54,18 @@ def exchange_rates(cache=nil)
doc.xpath('gesmes:Envelope/xmlns:Cube/xmlns:Cube//xmlns:Cube')
end
+ def exchange_rates_from_s(content)
+ doc = Nokogiri::XML(content)
+ doc.xpath('gesmes:Envelope/xmlns:Cube/xmlns:Cube//xmlns:Cube')
+ end
+
+ def update_parsed_rates(rates)
+ rates.each do |exchange_rate|
+ rate = exchange_rate.attribute("rate").value.to_f
+ currency = exchange_rate.attribute("currency").value
+ add_rate("EUR", currency, rate)
+ end
+ add_rate("EUR", "EUR", 1)
+ @last_updated = Time.now
+ end
end
@@ -40,6 +40,26 @@
end
end
+ it "should export to a string a valid cache that can be reread" do
+ stub(OpenURI::OpenRead).open(EuCentralBank::ECB_RATES_URL) {@cache_path}
+ s = @bank.save_rates_to_s
+ @bank.update_rates_from_s(s)
+ EuCentralBank::CURRENCIES.each do |currency|
+ @bank.get_rate("EUR", currency).should > 0
+ end
+ end
+
+ it 'should set last_updated when the rates are downloaded' do
+ lu1 = @bank.last_updated
+ @bank.update_rates(@cache_path)
+ lu2 = @bank.last_updated
+ @bank.update_rates(@cache_path)
+ lu3 = @bank.last_updated
+
+ lu1.should_not eq(lu2)
+ lu2.should_not eq(lu3)
+ end
+
it "should return the correct exchange rates using exchange" do
@bank.update_rates(@cache_path)
EuCentralBank::CURRENCIES.reject{|c| %w{JPY}.include?(c) }.each do |currency|