money-open-exchange-rates 0.3.1 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/{README.markdown → README.md} +13 -18
- data/lib/money/bank/open_exchange_rates_bank.rb +106 -9
- data/lib/open_exchange_rates_bank/version.rb +4 -0
- data/test/data/2015-01-01.json +176 -0
- data/test/{latest.json → data/latest.json} +0 -0
- data/test/open_exchange_rates_bank_test.rb +54 -35
- data/test/test_helper.rb +10 -6
- metadata +45 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 43e935f81c5a1c3daf5f791f0f77badd5b707659
|
4
|
+
data.tar.gz: 086c4f76ec5bcacf9e1af05bfb491428c06409b0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 200b48103eca5510fa653b0d86cd72ddaae6cae6d497af0c24803b6e4e8ce96f3bc5fe5da65522eefa69fdb913fbb84e815cb1d7e11776780620e0538557439b
|
7
|
+
data.tar.gz: d6605797a0b3b162b1a50d128c0621508254bef66f62e8ab79538ee2c93140cdf60238c8a9cb22e3b52305d03d4d6ade86aa0b0bfb97e28793e963549a6e5279
|
@@ -14,12 +14,17 @@ moe.update_rates
|
|
14
14
|
|
15
15
|
# (optional)
|
16
16
|
# set the seconds after than the current rates are automatically expired
|
17
|
-
# by default, they never expire
|
17
|
+
# by default, they never expire, in this example 1 day.
|
18
18
|
moe.ttl_in_seconds = 86400
|
19
19
|
# (optional)
|
20
20
|
# use https to fetch rates from Open Exchange Rates
|
21
21
|
# disabled by default to support free-tier users
|
22
|
+
# see https://openexchangerates.org/documentation#https
|
22
23
|
moe.secure_connection = true
|
24
|
+
# (optional)
|
25
|
+
# set historical date of the rate
|
26
|
+
# see https://openexchangerates.org/documentation#historical-data
|
27
|
+
moe.date = '2015-01-01'
|
23
28
|
# Store in cache
|
24
29
|
moe.save_rates
|
25
30
|
|
@@ -42,32 +47,20 @@ end
|
|
42
47
|
|
43
48
|
## Tests
|
44
49
|
|
45
|
-
As of the end of August 2012 all requests to the Open Exchange Rates API must
|
46
|
-
have a valid app_id. You can place your own key on a file or environment
|
47
|
-
variable named TEST_APP_ID and then run:
|
48
|
-
|
49
50
|
~~~
|
50
51
|
bundle exec rake
|
51
52
|
~~~
|
52
53
|
|
53
54
|
## Refs
|
54
55
|
|
55
|
-
* https://github.com/currencybot/open-exchange-rates
|
56
|
-
* https://github.com/RubyMoney/money
|
57
|
-
* https://github.com/RubyMoney/eu_central_bank
|
58
|
-
* https://github.com/RubyMoney/google_currency
|
56
|
+
* <https://github.com/currencybot/open-exchange-rates>
|
57
|
+
* <https://github.com/RubyMoney/money>
|
58
|
+
* <https://github.com/RubyMoney/eu_central_bank>
|
59
|
+
* <https://github.com/RubyMoney/google_currency>
|
59
60
|
|
60
61
|
## Contributors
|
61
62
|
|
62
|
-
|
63
|
-
Kevin Ball (3)
|
64
|
-
Paul Robinson (2)
|
65
|
-
Michael Morris (2)
|
66
|
-
Dmitry Dedov (2)
|
67
|
-
chatgris (2)
|
68
|
-
Sam Lown (1)
|
69
|
-
Fabio Cantoni (1)
|
70
|
-
shpupti (1)
|
63
|
+
See [GitHub](https://github.com/spk/money-open-exchange-rates/graphs/contributors).
|
71
64
|
|
72
65
|
## License
|
73
66
|
|
@@ -79,3 +72,5 @@ Copyright © 2011-2015 Laurent Arnoud <laurent@spkdev.net>
|
|
79
72
|
[![Gem Version](https://badge.fury.io/rb/money-open-exchange-rates.svg)](https://rubygems.org/gems/money-open-exchange-rates)
|
80
73
|
[![Build Status](https://secure.travis-ci.org/spk/money-open-exchange-rates.svg?branch=master)](https://travis-ci.org/spk/money-open-exchange-rates)
|
81
74
|
[![Code Climate](http://img.shields.io/codeclimate/github/spk/money-open-exchange-rates.svg)](https://codeclimate.com/github/spk/money-open-exchange-rates)
|
75
|
+
[![Inline docs](http://inch-ci.org/github/spk/money-open-exchange-rates.svg?branch=master)](http://inch-ci.org/github/spk/money-open-exchange-rates)
|
76
|
+
[![License](https://img.shields.io/github/license/spk/money-open-exchange-rates.svg)](http://opensource.org/licenses/MIT)
|
@@ -1,27 +1,69 @@
|
|
1
|
-
# encoding: UTF-8
|
2
1
|
require 'open-uri'
|
3
2
|
require 'money'
|
4
3
|
require 'json'
|
4
|
+
require File.expand_path('../../../open_exchange_rates_bank/version', __FILE__)
|
5
5
|
|
6
|
+
# Money gem class
|
6
7
|
class Money
|
8
|
+
# https://github.com/RubyMoney/money#exchange-rate-stores
|
7
9
|
module Bank
|
10
|
+
# Invalid cache, file not found or cache empty
|
8
11
|
class InvalidCache < StandardError; end
|
9
12
|
|
13
|
+
# APP_ID not set error
|
10
14
|
class NoAppId < StandardError; end
|
11
15
|
|
12
16
|
# OpenExchangeRatesBank base class
|
13
17
|
class OpenExchangeRatesBank < Money::Bank::VariableExchange
|
18
|
+
VERSION = ::OpenExchangeRatesBank::VERSION
|
19
|
+
# OpenExchangeRates urls
|
14
20
|
OER_URL = 'http://openexchangerates.org/latest.json'
|
21
|
+
OER_HISTORICAL_URL = 'http://openexchangerates.org/historical/%s.json'
|
22
|
+
# OpenExchangeRates secure url
|
15
23
|
SECURE_OER_URL = OER_URL.gsub('http:', 'https:')
|
24
|
+
SECURE_OER_HISTORICAL_URL = OER_URL.gsub('http:', 'https:')
|
16
25
|
|
17
|
-
|
18
|
-
|
26
|
+
# use https to fetch rates from Open Exchange Rates
|
27
|
+
# disabled by default to support free-tier users
|
28
|
+
attr_accessor :secure_connection
|
19
29
|
|
30
|
+
# As of the end of August 2012 all requests to the Open Exchange Rates
|
31
|
+
# API must have a valid app_id
|
32
|
+
attr_accessor :app_id
|
33
|
+
|
34
|
+
# Cache accessor, can be a String or a Proc
|
35
|
+
attr_accessor :cache
|
36
|
+
|
37
|
+
# Date for historical api
|
38
|
+
# see https://openexchangerates.org/documentation#historical-data
|
39
|
+
attr_accessor :date
|
40
|
+
|
41
|
+
# Rates expiration Time
|
42
|
+
attr_reader :rates_expiration
|
43
|
+
|
44
|
+
# Parsed OpenExchangeRates result as Hash
|
45
|
+
attr_reader :oer_rates
|
46
|
+
|
47
|
+
# Seconds after than the current rates are automatically expired
|
48
|
+
attr_reader :ttl_in_seconds
|
49
|
+
|
50
|
+
# Set the seconds after than the current rates are automatically expired
|
51
|
+
# by default, they never expire.
|
52
|
+
#
|
53
|
+
# @example
|
54
|
+
# ttl_in_seconds = 86400 # will expire the rates in one day
|
55
|
+
#
|
56
|
+
# @param value [Integer] Time to live in seconds
|
57
|
+
#
|
58
|
+
# @return [Integer] Setted time to live in seconds
|
20
59
|
def ttl_in_seconds=(value)
|
21
60
|
@ttl_in_seconds = value
|
22
61
|
refresh_rates_expiration if ttl_in_seconds
|
62
|
+
@ttl_in_seconds
|
23
63
|
end
|
24
64
|
|
65
|
+
# Update all rates from openexchangerates JSON
|
66
|
+
# @return [Array] Array of exchange rates
|
25
67
|
def update_rates
|
26
68
|
exchange_rates.each do |exchange_rate|
|
27
69
|
rate = exchange_rate.last
|
@@ -32,6 +74,10 @@ class Money
|
|
32
74
|
end
|
33
75
|
end
|
34
76
|
|
77
|
+
# Save rates on cache
|
78
|
+
# Can raise InvalidCache
|
79
|
+
#
|
80
|
+
# @return [Proc,File]
|
35
81
|
def save_rates
|
36
82
|
fail InvalidCache unless cache
|
37
83
|
text = read_from_url
|
@@ -40,11 +86,17 @@ class Money
|
|
40
86
|
raise InvalidCache
|
41
87
|
end
|
42
88
|
|
89
|
+
# Override Money `get_rate` method for caching
|
90
|
+
# @param [String] from_currency Currency ISO code. ex. 'USD'
|
91
|
+
# @param [String] to_currency Currency ISO code. ex. 'CAD'
|
92
|
+
#
|
93
|
+
# @return [Numeric] rate.
|
43
94
|
def get_rate(from_currency, to_currency, opts = {})
|
44
95
|
expire_rates
|
45
96
|
super
|
46
97
|
end
|
47
98
|
|
99
|
+
# Expire rates when expired
|
48
100
|
def expire_rates
|
49
101
|
return unless ttl_in_seconds
|
50
102
|
return if rates_expiration > Time.now
|
@@ -52,17 +104,48 @@ class Money
|
|
52
104
|
refresh_rates_expiration
|
53
105
|
end
|
54
106
|
|
107
|
+
# Source url of openexchangerates
|
108
|
+
# defined with app_id and secure_connection
|
109
|
+
# @return [String] URL
|
55
110
|
def source_url
|
56
|
-
fail NoAppId if app_id.nil? || app_id.empty?
|
57
|
-
oer_url = OER_URL
|
58
|
-
oer_url = SECURE_OER_URL if secure_connection
|
59
111
|
"#{oer_url}?app_id=#{app_id}"
|
60
112
|
end
|
61
113
|
|
62
114
|
protected
|
63
115
|
|
116
|
+
# Latest url if no date given
|
117
|
+
# @return [String] URL
|
118
|
+
def oer_url
|
119
|
+
if date
|
120
|
+
historical_url
|
121
|
+
else
|
122
|
+
latest_url
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
# Historical url generated from `date` attr_accessor
|
127
|
+
# @return [String] URL
|
128
|
+
def historical_url
|
129
|
+
url = OER_HISTORICAL_URL
|
130
|
+
url = SECURE_OER_HISTORICAL_URL if secure_connection
|
131
|
+
url % date
|
132
|
+
end
|
133
|
+
|
134
|
+
# Latest url
|
135
|
+
# @return [String] URL
|
136
|
+
def latest_url
|
137
|
+
return SECURE_OER_URL if secure_connection
|
138
|
+
OER_URL
|
139
|
+
end
|
140
|
+
|
64
141
|
# Store the provided text data by calling the proc method provided
|
65
142
|
# for the cache, or write to the cache file.
|
143
|
+
#
|
144
|
+
# @example
|
145
|
+
# store_in_cache("{\"rates\": {\"AED\": 3.67304}}")
|
146
|
+
#
|
147
|
+
# @param text [String] String to cache
|
148
|
+
# @return [String,Integer]
|
66
149
|
def store_in_cache(text)
|
67
150
|
if cache.is_a?(Proc)
|
68
151
|
cache.call(text)
|
@@ -73,6 +156,7 @@ class Money
|
|
73
156
|
end
|
74
157
|
end
|
75
158
|
|
159
|
+
# Read from cache when exist
|
76
160
|
def read_from_cache
|
77
161
|
if cache.is_a?(Proc)
|
78
162
|
cache.call(nil)
|
@@ -81,10 +165,20 @@ class Money
|
|
81
165
|
end
|
82
166
|
end
|
83
167
|
|
168
|
+
# Read from url
|
169
|
+
# @return [String] JSON content
|
84
170
|
def read_from_url
|
171
|
+
fail NoAppId if app_id.nil? || app_id.empty?
|
85
172
|
open(source_url).read
|
86
173
|
end
|
87
174
|
|
175
|
+
# Check validity of rates response only for store in cache
|
176
|
+
#
|
177
|
+
# @example
|
178
|
+
# valid_rates?("{\"rates\": {\"AED\": 3.67304}}")
|
179
|
+
#
|
180
|
+
# @param [String] text is JSON content
|
181
|
+
# @return [Boolean] valid or not
|
88
182
|
def valid_rates?(text)
|
89
183
|
parsed = JSON.parse(text)
|
90
184
|
parsed && parsed.key?('rates')
|
@@ -92,12 +186,15 @@ class Money
|
|
92
186
|
false
|
93
187
|
end
|
94
188
|
|
189
|
+
# Get expire rates, first from cache and then from url
|
190
|
+
# @return [Hash] key is country code (ISO 3166-1 alpha-3) value Float
|
95
191
|
def exchange_rates
|
96
|
-
|
97
|
-
@oer_rates =
|
98
|
-
@doc['rates']
|
192
|
+
doc = JSON.parse(read_from_cache || read_from_url)
|
193
|
+
@oer_rates = doc['rates']
|
99
194
|
end
|
100
195
|
|
196
|
+
# Refresh expiration from now
|
197
|
+
# return [Time] new expiration time
|
101
198
|
def refresh_rates_expiration
|
102
199
|
@rates_expiration = Time.now + ttl_in_seconds
|
103
200
|
end
|
@@ -0,0 +1,176 @@
|
|
1
|
+
{
|
2
|
+
"disclaimer": "Exchange rates are provided for informational purposes only, and do not constitute financial advice of any kind. Although every attempt is made to ensure quality, NO guarantees are given whatsoever of accuracy, validity, availability, or fitness for any purpose - please use at your own risk. All usage is subject to your acceptance of the Terms and Conditions of Service, available at: https://openexchangerates.org/terms/",
|
3
|
+
"license": "Data sourced from various providers with public-facing APIs; copyright may apply; resale is prohibited; no warranties given of any kind. Bitcoin data provided by http://coindesk.com. All usage is subject to your acceptance of the License Agreement available at: https://openexchangerates.org/license/",
|
4
|
+
"timestamp": 1420153200,
|
5
|
+
"base": "USD",
|
6
|
+
"rates": {
|
7
|
+
"AED": 3.67295,
|
8
|
+
"AFN": 58.32125,
|
9
|
+
"ALL": 116.0569,
|
10
|
+
"AMD": 475.665,
|
11
|
+
"ANG": 1.78952,
|
12
|
+
"AOA": 103.054626,
|
13
|
+
"ARS": 8.520843,
|
14
|
+
"AUD": 1.227915,
|
15
|
+
"AWG": 1.79,
|
16
|
+
"AZN": 0.783533,
|
17
|
+
"BAM": 1.621428,
|
18
|
+
"BBD": 2,
|
19
|
+
"BDT": 78.34175,
|
20
|
+
"BGN": 1.618259,
|
21
|
+
"BHD": 0.377292,
|
22
|
+
"BIF": 1559.393383,
|
23
|
+
"BMD": 1,
|
24
|
+
"BND": 1.329743,
|
25
|
+
"BOB": 6.93672,
|
26
|
+
"BRL": 2.65757,
|
27
|
+
"BSD": 1,
|
28
|
+
"BTC": 0.0031843483,
|
29
|
+
"BTN": 63.257425,
|
30
|
+
"BWP": 9.558213,
|
31
|
+
"BYR": 10989.475,
|
32
|
+
"BZD": 2.00638,
|
33
|
+
"CAD": 1.164547,
|
34
|
+
"CDF": 925.947167,
|
35
|
+
"CHF": 0.997274,
|
36
|
+
"CLF": 0.02465,
|
37
|
+
"CLP": 606.007006,
|
38
|
+
"CNY": 6.194942,
|
39
|
+
"COP": 2385.253333,
|
40
|
+
"CRC": 542.491997,
|
41
|
+
"CUP": 1.003913,
|
42
|
+
"CVE": 91.23895,
|
43
|
+
"CZK": 22.97762,
|
44
|
+
"DJF": 178.714121,
|
45
|
+
"DKK": 6.173835,
|
46
|
+
"DOP": 44.50626,
|
47
|
+
"DZD": 88.01261,
|
48
|
+
"EEK": 12.957425,
|
49
|
+
"EGP": 7.156524,
|
50
|
+
"ERN": 15.097475,
|
51
|
+
"ETB": 20.29028,
|
52
|
+
"EUR": 0.830151,
|
53
|
+
"FJD": 1.987716,
|
54
|
+
"FKP": 0.644102,
|
55
|
+
"GBP": 0.644102,
|
56
|
+
"GEL": 1.7655,
|
57
|
+
"GGP": 0.644102,
|
58
|
+
"GHS": 3.21851,
|
59
|
+
"GIP": 0.644102,
|
60
|
+
"GMD": 43.032,
|
61
|
+
"GNF": 7039.643333,
|
62
|
+
"GTQ": 7.63037,
|
63
|
+
"GYD": 207.311252,
|
64
|
+
"HKD": 7.755168,
|
65
|
+
"HNL": 21.10808,
|
66
|
+
"HRK": 6.356716,
|
67
|
+
"HTG": 46.73391,
|
68
|
+
"HUF": 263.002701,
|
69
|
+
"IDR": 12504.416797,
|
70
|
+
"ILS": 3.9153,
|
71
|
+
"IMP": 0.644102,
|
72
|
+
"INR": 63.30198,
|
73
|
+
"IQD": 1165.625017,
|
74
|
+
"IRR": 27136.666667,
|
75
|
+
"ISK": 127.640001,
|
76
|
+
"JEP": 0.644102,
|
77
|
+
"JMD": 114.83,
|
78
|
+
"JOD": 0.709272,
|
79
|
+
"JPY": 120.2679,
|
80
|
+
"KES": 90.79789,
|
81
|
+
"KGS": 58.8957,
|
82
|
+
"KHR": 4078.688267,
|
83
|
+
"KMF": 407.643953,
|
84
|
+
"KPW": 900,
|
85
|
+
"KRW": 1100.835008,
|
86
|
+
"KWD": 0.293194,
|
87
|
+
"KYD": 0.829892,
|
88
|
+
"KZT": 183.490001,
|
89
|
+
"LAK": 8128.966667,
|
90
|
+
"LBP": 1515.466667,
|
91
|
+
"LKR": 131.277099,
|
92
|
+
"LRD": 91.49085,
|
93
|
+
"LSL": 11.62899,
|
94
|
+
"LTL": 2.864092,
|
95
|
+
"LVL": 0.582443,
|
96
|
+
"LYD": 1.205988,
|
97
|
+
"MAD": 9.088744,
|
98
|
+
"MDL": 15.66928,
|
99
|
+
"MGA": 2578.683301,
|
100
|
+
"MKD": 50.61098,
|
101
|
+
"MMK": 1033.349984,
|
102
|
+
"MNT": 1884.5,
|
103
|
+
"MOP": 8.02165,
|
104
|
+
"MRO": 293.299998,
|
105
|
+
"MTL": 0.683738,
|
106
|
+
"MUR": 31.72789,
|
107
|
+
"MVR": 15.3259,
|
108
|
+
"MWK": 472.41,
|
109
|
+
"MXN": 14.77204,
|
110
|
+
"MYR": 3.51568,
|
111
|
+
"MZN": 33.716667,
|
112
|
+
"NAD": 11.62899,
|
113
|
+
"NGN": 183.860999,
|
114
|
+
"NIO": 26.66672,
|
115
|
+
"NOK": 7.501665,
|
116
|
+
"NPR": 101.423261,
|
117
|
+
"NZD": 1.289451,
|
118
|
+
"OMR": 0.385016,
|
119
|
+
"PAB": 1,
|
120
|
+
"PEN": 2.99923,
|
121
|
+
"PGK": 2.599524,
|
122
|
+
"PHP": 44.75235,
|
123
|
+
"PKR": 101.0106,
|
124
|
+
"PLN": 3.567112,
|
125
|
+
"PYG": 4654.42666,
|
126
|
+
"QAR": 3.641389,
|
127
|
+
"RON": 3.72106,
|
128
|
+
"RSD": 100.32927,
|
129
|
+
"RUB": 60.4126,
|
130
|
+
"RWF": 692.89744,
|
131
|
+
"SAR": 3.75385,
|
132
|
+
"SBD": 7.535841,
|
133
|
+
"SCR": 13.229988,
|
134
|
+
"SDG": 5.716117,
|
135
|
+
"SEK": 7.830246,
|
136
|
+
"SGD": 1.327769,
|
137
|
+
"SHP": 0.644102,
|
138
|
+
"SLL": 4220,
|
139
|
+
"SOS": 718.299215,
|
140
|
+
"SRD": 3.2875,
|
141
|
+
"STD": 20287.666667,
|
142
|
+
"SVC": 8.80518,
|
143
|
+
"SYP": 179.645633,
|
144
|
+
"SZL": 11.62909,
|
145
|
+
"THB": 32.95636,
|
146
|
+
"TJS": 5.219,
|
147
|
+
"TMT": 2.8501,
|
148
|
+
"TND": 1.86823,
|
149
|
+
"TOP": 1.972632,
|
150
|
+
"TRY": 2.343387,
|
151
|
+
"TTD": 6.403,
|
152
|
+
"TWD": 31.75566,
|
153
|
+
"TZS": 1737.36665,
|
154
|
+
"UAH": 15.8846,
|
155
|
+
"UGX": 2782.033333,
|
156
|
+
"USD": 1,
|
157
|
+
"UYU": 24.25064,
|
158
|
+
"UZS": 2428.266634,
|
159
|
+
"VEF": 6.315625,
|
160
|
+
"VND": 21401,
|
161
|
+
"VUV": 102.95,
|
162
|
+
"WST": 2.406226,
|
163
|
+
"XAF": 544.284001,
|
164
|
+
"XAG": 0.06368617,
|
165
|
+
"XAU": 0.00084292,
|
166
|
+
"XCD": 2.70144,
|
167
|
+
"XDR": 0.691712,
|
168
|
+
"XOF": 544.450581,
|
169
|
+
"XPF": 98.78878,
|
170
|
+
"YER": 214.958,
|
171
|
+
"ZAR": 11.62723,
|
172
|
+
"ZMK": 5253.075255,
|
173
|
+
"ZMW": 6.417975,
|
174
|
+
"ZWL": 322.355006
|
175
|
+
}
|
176
|
+
}
|
File without changes
|
@@ -1,23 +1,27 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
|
3
1
|
require File.expand_path(File.join(File.dirname(__FILE__), 'test_helper'))
|
4
2
|
|
5
3
|
describe Money::Bank::OpenExchangeRatesBank do
|
6
4
|
subject { Money::Bank::OpenExchangeRatesBank.new }
|
7
|
-
let(:
|
8
|
-
let(:
|
5
|
+
let(:oer_url) { Money::Bank::OpenExchangeRatesBank::OER_URL }
|
6
|
+
let(:oer_historical_url) do
|
7
|
+
Money::Bank::OpenExchangeRatesBank::OER_HISTORICAL_URL
|
8
|
+
end
|
9
|
+
let(:oer_secure_url) { Money::Bank::OpenExchangeRatesBank::SECURE_OER_URL }
|
10
|
+
|
9
11
|
let(:temp_cache_path) do
|
10
|
-
|
12
|
+
data_file('tmp.json')
|
11
13
|
end
|
12
|
-
let(:
|
13
|
-
|
14
|
+
let(:oer_latest_path) do
|
15
|
+
data_file('latest.json')
|
16
|
+
end
|
17
|
+
let(:oer_historical_path) do
|
18
|
+
data_file('2015-01-01.json')
|
14
19
|
end
|
15
20
|
|
16
21
|
describe 'exchange' do
|
17
22
|
before do
|
18
|
-
subject
|
23
|
+
add_to_webmock(subject)
|
19
24
|
subject.cache = temp_cache_path
|
20
|
-
stub(subject).read_from_url { File.read cache_path }
|
21
25
|
subject.save_rates
|
22
26
|
end
|
23
27
|
|
@@ -64,7 +68,7 @@ describe Money::Bank::OpenExchangeRatesBank do
|
|
64
68
|
describe 'update_rates' do
|
65
69
|
before do
|
66
70
|
subject.app_id = TEST_APP_ID
|
67
|
-
subject.cache =
|
71
|
+
subject.cache = oer_latest_path
|
68
72
|
subject.update_rates
|
69
73
|
end
|
70
74
|
|
@@ -115,7 +119,6 @@ describe Money::Bank::OpenExchangeRatesBank do
|
|
115
119
|
describe 'App ID' do
|
116
120
|
before do
|
117
121
|
subject.cache = temp_cache_path
|
118
|
-
stub(OpenURI::OpenRead).open(url) { File.read cache_path }
|
119
122
|
end
|
120
123
|
|
121
124
|
it 'should raise an error if no App ID is set' do
|
@@ -130,11 +133,10 @@ describe Money::Bank::OpenExchangeRatesBank do
|
|
130
133
|
describe 'no cache' do
|
131
134
|
before do
|
132
135
|
subject.cache = nil
|
133
|
-
subject
|
136
|
+
add_to_webmock(subject)
|
134
137
|
end
|
135
138
|
|
136
139
|
it 'should get from url' do
|
137
|
-
stub(OpenURI::OpenRead).open(url) { File.read cache_path }
|
138
140
|
subject.update_rates
|
139
141
|
subject.oer_rates.wont_be_empty
|
140
142
|
end
|
@@ -145,34 +147,36 @@ describe Money::Bank::OpenExchangeRatesBank do
|
|
145
147
|
end
|
146
148
|
|
147
149
|
describe 'secure_connection' do
|
150
|
+
before do
|
151
|
+
subject.app_id = TEST_APP_ID
|
152
|
+
end
|
153
|
+
|
148
154
|
it "should use the non-secure http url if secure_connection isn't set" do
|
149
155
|
subject.secure_connection = nil
|
150
|
-
subject.app_id
|
151
|
-
subject.source_url.
|
156
|
+
subject.source_url.must_equal "#{oer_url}?app_id=#{TEST_APP_ID}"
|
157
|
+
subject.source_url.must_include 'http://'
|
152
158
|
end
|
153
159
|
|
154
160
|
it 'should use the non-secure http url if secure_connection is false' do
|
155
161
|
subject.secure_connection = false
|
156
|
-
subject.app_id
|
157
|
-
subject.source_url.
|
162
|
+
subject.source_url.must_equal "#{oer_url}?app_id=#{TEST_APP_ID}"
|
163
|
+
subject.source_url.must_include 'http://'
|
158
164
|
end
|
159
165
|
|
160
166
|
it 'should use the secure https url if secure_connection is set to true' do
|
161
167
|
subject.secure_connection = true
|
162
|
-
subject.app_id
|
163
|
-
subject.source_url.
|
164
|
-
subject.source_url.must_include "https://"
|
168
|
+
subject.source_url.must_equal "#{oer_secure_url}?app_id=#{TEST_APP_ID}"
|
169
|
+
subject.source_url.must_include 'https://'
|
165
170
|
end
|
166
171
|
end
|
167
172
|
|
168
173
|
describe 'no valid file for cache' do
|
169
174
|
before do
|
170
175
|
subject.cache = "space_dir#{rand(999_999_999)}/out_space_file.json"
|
171
|
-
subject
|
176
|
+
add_to_webmock(subject)
|
172
177
|
end
|
173
178
|
|
174
179
|
it 'should get from url' do
|
175
|
-
stub(OpenURI::OpenRead).open(url) { File.read cache_path }
|
176
180
|
subject.update_rates
|
177
181
|
subject.oer_rates.wont_be_empty
|
178
182
|
end
|
@@ -183,7 +187,7 @@ describe Money::Bank::OpenExchangeRatesBank do
|
|
183
187
|
end
|
184
188
|
|
185
189
|
describe 'using proc for cache' do
|
186
|
-
before
|
190
|
+
before do
|
187
191
|
@global_rates = nil
|
188
192
|
subject.cache = proc {|v|
|
189
193
|
if v
|
@@ -192,17 +196,15 @@ describe Money::Bank::OpenExchangeRatesBank do
|
|
192
196
|
@global_rates
|
193
197
|
end
|
194
198
|
}
|
195
|
-
subject
|
199
|
+
add_to_webmock(subject)
|
196
200
|
end
|
197
201
|
|
198
202
|
it 'should get from url normally' do
|
199
|
-
stub(subject).source_url { cache_path }
|
200
203
|
subject.update_rates
|
201
204
|
subject.oer_rates.wont_be_empty
|
202
205
|
end
|
203
206
|
|
204
207
|
it 'should save from url and get from cache' do
|
205
|
-
stub(subject).source_url { cache_path }
|
206
208
|
subject.save_rates
|
207
209
|
@global_rates.wont_be_empty
|
208
210
|
dont_allow(subject).source_url
|
@@ -213,12 +215,15 @@ describe Money::Bank::OpenExchangeRatesBank do
|
|
213
215
|
|
214
216
|
describe 'save rates' do
|
215
217
|
before do
|
216
|
-
subject
|
218
|
+
add_to_webmock(subject)
|
217
219
|
subject.cache = temp_cache_path
|
218
|
-
stub(OpenURI::OpenRead).open(url) { File.read cache_path }
|
219
220
|
subject.save_rates
|
220
221
|
end
|
221
222
|
|
223
|
+
after do
|
224
|
+
File.unlink(temp_cache_path)
|
225
|
+
end
|
226
|
+
|
222
227
|
it 'should allow update after save' do
|
223
228
|
begin
|
224
229
|
subject.update_rates
|
@@ -247,27 +252,22 @@ describe Money::Bank::OpenExchangeRatesBank do
|
|
247
252
|
subject.save_rates
|
248
253
|
File.open(temp_cache_path).read.size.must_equal initial_size
|
249
254
|
end
|
250
|
-
|
251
|
-
after do
|
252
|
-
File.delete temp_cache_path
|
253
|
-
end
|
254
255
|
end
|
255
256
|
|
256
257
|
describe '#expire_rates' do
|
257
258
|
before do
|
258
|
-
subject
|
259
|
+
add_to_webmock(subject)
|
259
260
|
subject.ttl_in_seconds = 1000
|
260
261
|
@old_usd_eur_rate = 0.655
|
261
262
|
# see test/latest.json +52
|
262
263
|
@new_usd_eur_rate = 0.79085
|
263
264
|
subject.add_rate('USD', 'EUR', @old_usd_eur_rate)
|
264
265
|
subject.cache = temp_cache_path
|
265
|
-
stub(subject).read_from_url { File.read cache_path }
|
266
266
|
subject.save_rates
|
267
267
|
end
|
268
268
|
|
269
269
|
after do
|
270
|
-
File.
|
270
|
+
File.unlink(temp_cache_path)
|
271
271
|
end
|
272
272
|
|
273
273
|
describe 'when the ttl has expired' do
|
@@ -296,4 +296,23 @@ describe Money::Bank::OpenExchangeRatesBank do
|
|
296
296
|
end
|
297
297
|
end
|
298
298
|
end
|
299
|
+
|
300
|
+
describe 'historical' do
|
301
|
+
before do
|
302
|
+
add_to_webmock(subject)
|
303
|
+
# see test/latest.json +52
|
304
|
+
@latest_usd_eur_rate = 0.79085
|
305
|
+
# see test/2015-01-01.json +52
|
306
|
+
@old_usd_eur_rate = 0.830151
|
307
|
+
subject.update_rates
|
308
|
+
end
|
309
|
+
|
310
|
+
it 'should be different than the latest' do
|
311
|
+
subject.get_rate('USD', 'EUR').must_equal @latest_usd_eur_rate
|
312
|
+
subject.date = '2015-01-01'
|
313
|
+
add_to_webmock(subject, oer_historical_path)
|
314
|
+
subject.update_rates
|
315
|
+
subject.get_rate('USD', 'EUR').must_equal @old_usd_eur_rate
|
316
|
+
end
|
317
|
+
end
|
299
318
|
end
|
data/test/test_helper.rb
CHANGED
@@ -1,15 +1,19 @@
|
|
1
|
-
# encoding: UTF-8
|
2
1
|
require 'minitest/autorun'
|
3
2
|
require 'rr'
|
3
|
+
require 'webmock/minitest'
|
4
4
|
require 'money/bank/open_exchange_rates_bank'
|
5
5
|
require 'monetize'
|
6
6
|
require 'timecop'
|
7
7
|
require 'pry'
|
8
8
|
|
9
|
-
|
10
|
-
TEST_APP_ID = ENV['TEST_APP_ID'] || File.read(TEST_APP_ID_PATH)
|
9
|
+
TEST_APP_ID = 'TEST_APP_ID'
|
11
10
|
|
12
|
-
|
13
|
-
|
14
|
-
|
11
|
+
def data_file(file)
|
12
|
+
File.expand_path(File.join(File.dirname(__FILE__), 'data', file))
|
13
|
+
end
|
14
|
+
|
15
|
+
def add_to_webmock(subject, body_path = oer_latest_path)
|
16
|
+
subject.app_id = TEST_APP_ID
|
17
|
+
stub_request(:get, subject.source_url)
|
18
|
+
.to_return(status: 200, body: File.read(body_path))
|
15
19
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: money-open-exchange-rates
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Laurent Arnoud
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-09-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: money
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '6.
|
19
|
+
version: '6.6'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '6.
|
26
|
+
version: '6.6'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: monetize
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -58,14 +58,14 @@ dependencies:
|
|
58
58
|
requirements:
|
59
59
|
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: '5.
|
61
|
+
version: '5.6'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: '5.
|
68
|
+
version: '5.6'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: minitest-line
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -81,19 +81,33 @@ dependencies:
|
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0.6'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
|
-
name:
|
84
|
+
name: timecop
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
87
|
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version: '0'
|
89
|
+
version: '0.8'
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
94
|
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version: '0'
|
96
|
+
version: '0.8'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: inch
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0.7'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0.7'
|
97
111
|
- !ruby/object:Gem::Dependency
|
98
112
|
name: rr
|
99
113
|
requirement: !ruby/object:Gem::Requirement
|
@@ -109,7 +123,21 @@ dependencies:
|
|
109
123
|
- !ruby/object:Gem::Version
|
110
124
|
version: '1.1'
|
111
125
|
- !ruby/object:Gem::Dependency
|
112
|
-
name:
|
126
|
+
name: webmock
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - "~>"
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '1.21'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - "~>"
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '1.21'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: pry
|
113
141
|
requirement: !ruby/object:Gem::Requirement
|
114
142
|
requirements:
|
115
143
|
- - "~>"
|
@@ -123,7 +151,7 @@ dependencies:
|
|
123
151
|
- !ruby/object:Gem::Version
|
124
152
|
version: '0'
|
125
153
|
- !ruby/object:Gem::Dependency
|
126
|
-
name:
|
154
|
+
name: rake
|
127
155
|
requirement: !ruby/object:Gem::Requirement
|
128
156
|
requirements:
|
129
157
|
- - "~>"
|
@@ -156,13 +184,15 @@ email: laurent@spkdev.net
|
|
156
184
|
executables: []
|
157
185
|
extensions: []
|
158
186
|
extra_rdoc_files:
|
159
|
-
- README.
|
187
|
+
- README.md
|
160
188
|
files:
|
161
189
|
- Gemfile
|
162
190
|
- LICENSE
|
163
|
-
- README.
|
191
|
+
- README.md
|
164
192
|
- lib/money/bank/open_exchange_rates_bank.rb
|
165
|
-
-
|
193
|
+
- lib/open_exchange_rates_bank/version.rb
|
194
|
+
- test/data/2015-01-01.json
|
195
|
+
- test/data/latest.json
|
166
196
|
- test/open_exchange_rates_bank_test.rb
|
167
197
|
- test/test_helper.rb
|
168
198
|
homepage: http://github.com/spk/money-open-exchange-rates
|
@@ -185,7 +215,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
185
215
|
version: '0'
|
186
216
|
requirements: []
|
187
217
|
rubyforge_project:
|
188
|
-
rubygems_version: 2.
|
218
|
+
rubygems_version: 2.4.5
|
189
219
|
signing_key:
|
190
220
|
specification_version: 4
|
191
221
|
summary: A gem that calculates the exchange rate using published rates from open-exchange-rates.
|