better-coinbase 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,315 @@
1
+ require 'httparty'
2
+ require 'multi_json'
3
+ require 'hashie'
4
+ require 'money'
5
+ require 'monetize'
6
+ require 'time'
7
+ require 'securerandom'
8
+
9
+ module BetterCoinbase
10
+ class Client
11
+ include HTTParty
12
+
13
+ BASE_URI = 'https://coinbase.com/api/v1'
14
+
15
+ def initialize(api_key, api_secret, options={})
16
+ @api_key = api_key
17
+ @api_secret = api_secret
18
+
19
+ # defaults
20
+ options[:base_uri] ||= BASE_URI
21
+ @base_uri = options[:base_uri]
22
+ options[:format] ||= :json
23
+ options.each do |k,v|
24
+ self.class.send k, v
25
+ end
26
+ end
27
+
28
+ # Account
29
+
30
+ def balance options={}
31
+ h = get '/account/balance', options
32
+ h['amount'].to_money(h['currency'])
33
+ end
34
+
35
+ def accounts options={}
36
+ accts = get '/accounts', options
37
+ accts = convert_money_objects(accts)
38
+ accts
39
+ end
40
+
41
+ def receive_address options={}
42
+ get '/account/receive_address', options
43
+ end
44
+
45
+ def generate_receive_address options={}
46
+ post '/account/generate_receive_address', options
47
+ end
48
+
49
+ # Buttons
50
+
51
+ def create_button name, price, description=nil, custom=nil, options={}
52
+ options[:button] ||= {}
53
+ options[:button][:name] ||= name
54
+ price = price.to_money("BTC") unless price.is_a?(Money)
55
+ options[:button][:price_string] ||= price.to_s
56
+ options[:button][:price_currency_iso] ||= price.currency.iso_code
57
+ options[:button][:description] ||= description
58
+ options[:button][:custom] ||= custom
59
+ r = post '/buttons', options
60
+ if r.success?
61
+ r.embed_html = case options[:button_mode]
62
+ when 'page'
63
+ %[<a href="https://coinbase.com/checkouts/#{r.button.code}" target="_blank"><img alt="#{r.button.text}" src="https://coinbase.com/assets/buttons/#{r.button.style}.png"></a>]
64
+ when 'iframe'
65
+ %[<iframe src="https://coinbase.com/inline_payments/#{r.button.code}" style="width:500px;height:160px;border:none;box-shadow:0 1px 3px rgba(0,0,0,0.25);overflow:hidden;" scrolling="no" allowtransparency="true" frameborder="0"></iframe>]
66
+ else
67
+ %[<div class="coinbase-button" data-code="#{r.button.code}"></div><script src="https://coinbase.com/assets/button.js" type="text/javascript"></script>]
68
+ end
69
+ end
70
+ r
71
+ end
72
+
73
+ def create_order_for_button button_id
74
+ post "/buttons/#{button_id}/create_order"
75
+ end
76
+
77
+ # Addresses
78
+
79
+ def addresses page=1, options={}
80
+ get '/addresses', {page: page}.merge(options)
81
+ end
82
+
83
+ # Currencies
84
+
85
+ def exchange_rates
86
+ get('/currencies/exchange_rates')
87
+ end
88
+
89
+ def currencies_short
90
+ currencies.collect { |c| c[1] }
91
+ end
92
+
93
+ def currencies_long
94
+ currencies.collect { |c| c[0] }
95
+ end
96
+
97
+ def currencies
98
+ eval(self.class.send(:get, '/currencies'))
99
+ end
100
+ private :currencies
101
+
102
+ # Transactions
103
+
104
+ def transactions page=1, options ={}
105
+ r = get '/transactions', {page: page}.merge(options)
106
+ r.transactions ||= []
107
+ convert_money_objects(r.transactions)
108
+ r
109
+ end
110
+
111
+ def transaction transaction_id
112
+ r = get "/transactions/#{transaction_id}"
113
+ convert_money_objects(r.transaction)
114
+ r
115
+ end
116
+
117
+ def send_money to, amount, notes=nil, options={}
118
+ options[:transaction] ||= {}
119
+ options[:transaction][:to] ||= to
120
+ amount = amount.to_money("BTC") unless amount.is_a?(Money)
121
+ options[:transaction][:amount_string] ||= amount.to_s
122
+ options[:transaction][:amount_currency_iso] ||= amount.currency.iso_code
123
+ options[:transaction][:notes] ||= notes
124
+ r = post '/transactions/send_money', options
125
+ if amt = r.transaction.amount
126
+ r.transaction.amount = amt.amount.to_money(amt.currency)
127
+ end
128
+ r
129
+ end
130
+
131
+ def request_money from, amount, notes=nil, options={}
132
+ options[:transaction] ||= {}
133
+ options[:transaction][:from] ||= from
134
+ amount = amount.to_money("BTC") unless amount.is_a?(Money)
135
+ options[:transaction][:amount_string] ||= amount.to_s
136
+ options[:transaction][:amount_currency_iso] ||= amount.currency.iso_code
137
+ options[:transaction][:notes] ||= notes
138
+ r = post '/transactions/request_money', options
139
+ if amt = r.transaction.amount
140
+ r.transaction.amount = amt.amount.to_money(amt.currency)
141
+ end
142
+ r
143
+ end
144
+
145
+ def resend_request transaction_id
146
+ put "/transactions/#{transaction_id}/resend_request"
147
+ end
148
+
149
+ def cancel_request transaction_id
150
+ delete "/transactions/#{transaction_id}/cancel_request"
151
+ end
152
+
153
+ def complete_request transaction_id
154
+ put "/transactions/#{transaction_id}/complete_request"
155
+ end
156
+
157
+ # Users
158
+
159
+ def create_user email, password=nil, client_id=nil, scopes=nil
160
+ password ||= SecureRandom.urlsafe_base64(12)
161
+ options = {user: {email: email, password: password}}
162
+ if client_id
163
+ options[:client_id] = client_id
164
+ raise Error.new("Invalid scopes parameter; must be an array") if !scopes.is_a?(Array)
165
+ options[:scopes] = scopes.join(' ')
166
+ end
167
+ post '/users', options
168
+ end
169
+
170
+ # Prices
171
+
172
+ def buy_price qty=1
173
+ r = get '/prices/buy', {qty: qty}
174
+ r['amount'].to_money(r['currency'])
175
+ end
176
+
177
+ def sell_price qty=1
178
+ r = get '/prices/sell', {qty: qty}
179
+ r['amount'].to_money(r['currency'])
180
+ end
181
+
182
+ def spot_price currency='USD'
183
+ r = get '/prices/spot_rate', {currency: currency}
184
+ r['amount'].to_money(r['currency'])
185
+ end
186
+
187
+ # Buys
188
+
189
+ def buy! qty
190
+ r = post '/buys', {qty: qty}
191
+ r = convert_money_objects(r)
192
+ r.transfer.payout_date = Time.parse(r.transfer.payout_date) rescue nil
193
+ r
194
+ end
195
+
196
+ # Sells
197
+
198
+ def sell! qty
199
+ r = post '/sells', {qty: qty}
200
+ r = convert_money_objects(r)
201
+ r.transfer.payout_date = Time.parse(r.transfer.payout_date) rescue nil
202
+ r
203
+ end
204
+
205
+ # Transfers
206
+
207
+ def transfers options={}
208
+ r = get '/transfers', options
209
+ r = convert_money_objects(r)
210
+ r.transfers.each do |t|
211
+ t.transfer.payout_date = Time.parse(t.transfer.payout_date) rescue nil
212
+ end
213
+ r
214
+ end
215
+
216
+ # Wrappers for the main HTTP verbs
217
+
218
+ def get(path, options={})
219
+ http_verb :get, path, options
220
+ end
221
+
222
+ def post(path, options={})
223
+ http_verb :post, path, options
224
+ end
225
+
226
+ def put(path, options={})
227
+ http_verb :put, path, options
228
+ end
229
+
230
+ def delete(path, options={})
231
+ http_verb :delete, path, options
232
+ end
233
+
234
+ def self.whitelisted_cert_store
235
+ @@cert_store ||= build_whitelisted_cert_store
236
+ end
237
+
238
+ def self.build_whitelisted_cert_store
239
+ path = File.expand_path(File.join(File.dirname(__FILE__), 'ca-coinbase.crt'))
240
+
241
+ certs = [ [] ]
242
+ File.readlines(path).each{|line|
243
+ next if ["\n","#"].include?(line[0])
244
+ certs.last << line
245
+ certs << [] if line == "-----END CERTIFICATE-----\n"
246
+ }
247
+
248
+ result = OpenSSL::X509::Store.new
249
+
250
+ certs.each{|lines|
251
+ next if lines.empty?
252
+ cert = OpenSSL::X509::Certificate.new(lines.join)
253
+ result.add_cert(cert)
254
+ }
255
+
256
+ result
257
+ end
258
+
259
+ def ssl_options
260
+ { verify: true, cert_store: self.class.whitelisted_cert_store }
261
+ end
262
+
263
+ def http_verb(verb, path, options={})
264
+
265
+ nonce = options[:nonce] || (Time.now.to_f * 1e6).to_i
266
+
267
+ if [:get, :delete].include? verb
268
+ request_options = {}
269
+ path = "#{path}?#{URI.encode_www_form(options)}" if !options.empty?
270
+ hmac_message = nonce.to_s + @base_uri + path
271
+ else
272
+ request_options = {body: options.to_json}
273
+ hmac_message = nonce.to_s + @base_uri + path + options.to_json
274
+ end
275
+
276
+ signature = OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), @api_secret, hmac_message)
277
+
278
+ headers = {
279
+ 'ACCESS_KEY' => @api_key,
280
+ 'ACCESS_SIGNATURE' => signature,
281
+ 'ACCESS_NONCE' => nonce.to_s,
282
+ "Content-Type" => "application/json",
283
+ }
284
+
285
+ request_options[:headers] = headers
286
+
287
+ r = self.class.send(verb, path, request_options.merge(ssl_options))
288
+ hash = Hashie::Mash.new(JSON.parse(r.body))
289
+ raise Error.new(hash.error) if hash.error
290
+ raise Error.new(hash.errors.join(", ")) if hash.errors
291
+ hash
292
+ end
293
+
294
+ class Error < StandardError; end
295
+
296
+ private
297
+
298
+ def convert_money_objects obj
299
+ if obj.is_a?(Array)
300
+ obj.each_with_index do |o, i|
301
+ obj[i] = convert_money_objects(o)
302
+ end
303
+ elsif obj.is_a?(Hash)
304
+ if obj[:amount] && (obj[:currency] || obj[:currency_iso])
305
+ obj = obj[:amount].to_money((obj[:currency] || obj[:currency_iso]))
306
+ else
307
+ obj.each do |k,v|
308
+ obj[k] = convert_money_objects(v)
309
+ end
310
+ end
311
+ end
312
+ obj
313
+ end
314
+ end
315
+ end
@@ -0,0 +1,77 @@
1
+ require 'oauth2'
2
+
3
+ module BetterCoinbase
4
+ class OAuthClient < Client
5
+
6
+ AUTHORIZE_URL = 'https://coinbase.com/oauth/authorize'
7
+ TOKEN_URL = 'https://coinbase.com/oauth/token'
8
+
9
+ # Initializes a Coinbase Client using OAuth 2.0 credentials
10
+ #
11
+ # @param [String] client_id this application's Coinbase OAuth2 CLIENT_ID
12
+ # @param [String] client_secret this application's Coinbase OAuth2 CLIENT_SECRET
13
+ # @param [Hash] user_credentials OAuth 2.0 credentials to use
14
+ # @option user_credentials [String] access_token Must pass either this or token
15
+ # @option user_credentials [String] token Must pass either this or access_token
16
+ # @option user_credentials [String] refresh_token Optional
17
+ # @option user_credentials [Integer] expires_at Optional
18
+ # @option user_credentials [Integer] expires_in Optional
19
+ #
20
+ # Please note access tokens will be automatically refreshed when expired
21
+ # Use the credentials method when finished with the client to retrieve up-to-date credentials
22
+ def initialize(client_id, client_secret, user_credentials, options={})
23
+ client_opts = {
24
+ :site => options[:base_uri] || BASE_URI,
25
+ :authorize_url => options[:authorize_url] || AUTHORIZE_URL,
26
+ :token_url => options[:token_url] || TOKEN_URL,
27
+ :ssl => {
28
+ :verify => true,
29
+ :cert_store => ::BetterCoinbase::Client.whitelisted_cert_store
30
+ }
31
+ }
32
+ @oauth_client = OAuth2::Client.new(client_id, client_secret, client_opts)
33
+ token_hash = user_credentials.dup
34
+ token_hash[:access_token] ||= token_hash[:token]
35
+ token_hash.delete :expires
36
+ raise "No access token provided" unless token_hash[:access_token]
37
+ @oauth_token = OAuth2::AccessToken.from_hash(@oauth_client, token_hash)
38
+ end
39
+
40
+ def http_verb(verb, path, options={})
41
+ path = remove_leading_slash(path)
42
+
43
+ if [:get, :delete].include? verb
44
+ request_options = {params: options}
45
+ else
46
+ request_options = {headers: {"Content-Type" => "application/json"}, body: options.to_json}
47
+ end
48
+ response = oauth_token.request(verb, path, request_options)
49
+
50
+ hash = Hashie::Mash.new(JSON.parse(response.body))
51
+ raise Error.new(hash.error) if hash.error
52
+ raise Error.new(hash.errors.join(", ")) if hash.errors
53
+ hash
54
+ end
55
+
56
+ def refresh!
57
+ raise "Access token not initialized." unless @oauth_token
58
+ @oauth_token = @oauth_token.refresh!
59
+ end
60
+
61
+ def oauth_token
62
+ raise "Access token not initialized." unless @oauth_token
63
+ refresh! if @oauth_token.expired?
64
+ @oauth_token
65
+ end
66
+
67
+ def credentials
68
+ @oauth_token.to_hash
69
+ end
70
+
71
+ private
72
+
73
+ def remove_leading_slash(path)
74
+ path.sub(/^\//, '')
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,3 @@
1
+ module BetterCoinbase
2
+ VERSION = "0.1.1"
3
+ end
@@ -0,0 +1,429 @@
1
+ require 'fakeweb'
2
+ require 'better-coinbase'
3
+
4
+ describe BetterCoinbase::Client do
5
+ BASE_URI = 'http://fake.com/api/v1' # switching to http (instead of https) seems to help FakeWeb
6
+
7
+ before :all do
8
+ @c = BetterCoinbase::Client.new 'api key', 'api secret', {base_uri: BASE_URI}
9
+ FakeWeb.allow_net_connect = false
10
+ end
11
+
12
+ # Auth and Errors
13
+
14
+ it "raise errors" do
15
+ fake :get, '/account/balance', {error: "some error"}
16
+ expect{ @c.balance }.to raise_error(BetterCoinbase::Client::Error, 'some error')
17
+ fake :get, '/account/balance', {errors: ["some", "error"]}
18
+ expect{ @c.balance }.to raise_error(BetterCoinbase::Client::Error, 'some, error')
19
+ end
20
+
21
+ # Account
22
+
23
+ it "should get balance" do
24
+ fake :get, '/account/balance', {amount: "50.00000000", currency: 'BTC'}
25
+ @c.balance.should == 50.to_money('BTC')
26
+ end
27
+
28
+ it "should get a receive address" do
29
+ fake :get, '/account/receive_address', {address: "muVu2JZo8PbewBHRp6bpqFvVD87qvqEHWA", callback_url: nil}
30
+ a = @c.receive_address
31
+ a.address.should == "muVu2JZo8PbewBHRp6bpqFvVD87qvqEHWA"
32
+ a.callback_url.should == nil
33
+ end
34
+
35
+ it "should generate new receive addresses" do
36
+ fake :post, '/account/generate_receive_address', {address: "mmxJyTdxHUJUDoptwLHAGxLEd1rAxDJ7EV", callback_url: "http://example.com/callback"}
37
+ a = @c.generate_receive_address
38
+ a.address.should == "mmxJyTdxHUJUDoptwLHAGxLEd1rAxDJ7EV"
39
+ a.callback_url.should == "http://example.com/callback"
40
+ end
41
+
42
+ it "should list accounts" do
43
+ accounts_response = <<-eos
44
+ {
45
+ "accounts": [
46
+ {
47
+ "id": "536a541fa9393bb3c7000023",
48
+ "name": "My Wallet",
49
+ "balance": {
50
+ "amount": "50.00000000",
51
+ "currency": "BTC"
52
+ },
53
+ "native_balance": {
54
+ "amount": "500.12",
55
+ "currency": "USD"
56
+ },
57
+ "created_at": "2014-05-07T08:41:19-07:00",
58
+ "primary": true,
59
+ "active": true
60
+ },
61
+ {
62
+ "id": "536a541fa9393bb3c7000034",
63
+ "name": "Savings",
64
+ "balance": {
65
+ "amount": "0.00000000",
66
+ "currency": "BTC"
67
+ },
68
+ "native_balance": {
69
+ "amount": "0.00",
70
+ "currency": "USD"
71
+ },
72
+ "created_at": "2014-05-07T08:50:10-07:00",
73
+ "primary": false,
74
+ "active": true
75
+ }
76
+ ],
77
+ "total_count": 2,
78
+ "num_pages": 1,
79
+ "current_page": 1
80
+ }
81
+ eos
82
+
83
+ fake :get, '/accounts', JSON.parse(accounts_response)
84
+ r = @c.accounts
85
+ r.total_count.should == 2
86
+ primary_account = r.accounts.select { |acct| acct.primary }.first
87
+ primary_account.id.should == "536a541fa9393bb3c7000023"
88
+ primary_account.balance.should == 50.to_money("BTC")
89
+
90
+ # Make sure paging works
91
+ fake :get, '/accounts?page=2', JSON.parse(accounts_response)
92
+ r = @c.accounts :page => 2
93
+ FakeWeb.last_request.path.should include("page=2")
94
+ end
95
+
96
+ # Buttons
97
+
98
+ it "should create a new button" do
99
+ response = {:success=>true, :button=>{:code=>"93865b9cae83706ae59220c013bc0afd", :type=>"buy_now", :style=>"custom_large", :text=>"Pay With Bitcoin", :name=>"Order 123", :description=>"Sample description", :custom=>"Order123", :price=>{:cents=>123, :currency_iso=>"BTC"}}}
100
+ fake :post, '/buttons', response
101
+ r = @c.create_button "Order 123", 1.23, "Sample description"
102
+
103
+ # Ensure BTC is assumed to be the default currency
104
+ post_params = JSON.parse(FakeWeb.last_request.body)
105
+ post_params['button']['price_currency_iso'].should == "BTC"
106
+ post_params['button']['price_string'].should == "1.23000000"
107
+
108
+ r.success?.should == true
109
+ r.button.name.should == "Order 123"
110
+ r.embed_html.should == %[<div class="coinbase-button" data-code="93865b9cae83706ae59220c013bc0afd"></div><script src="https://coinbase.com/assets/button.js" type="text/javascript"></script>]
111
+
112
+ r = @c.create_button "Order 123", 1.23, "Sample description", nil, button_mode: 'page'
113
+ r.success?.should == true
114
+ r.button.name.should == "Order 123"
115
+ r.embed_html.should == %[<a href="https://coinbase.com/checkouts/93865b9cae83706ae59220c013bc0afd" target="_blank"><img alt="Pay With Bitcoin" src="https://coinbase.com/assets/buttons/custom_large.png"></a>]
116
+
117
+ r = @c.create_button "Order 123", 1.23, "Sample description", nil, button_mode: 'iframe'
118
+ r.success?.should == true
119
+ r.button.name.should == "Order 123"
120
+ r.embed_html.should == %[<iframe src="https://coinbase.com/inline_payments/93865b9cae83706ae59220c013bc0afd" style="width:500px;height:160px;border:none;box-shadow:0 1px 3px rgba(0,0,0,0.25);overflow:hidden;" scrolling="no" allowtransparency="true" frameborder="0"></iframe>]
121
+ end
122
+
123
+ it "should create a new button with price in USD" do
124
+ response = {:success=>true, :button=>{:code=>"93865b9cae83706ae59220c013bc0afd", :type=>"buy_now", :style=>"custom_large", :text=>"Pay With Bitcoin", :name=>"Order 123", :description=>"Sample description", :custom=>"Order123", :price=>{:cents=>123, :currency_iso=>"USD"}}}
125
+ fake :post, '/buttons', response
126
+ r = @c.create_button "Order 123", 1.23.to_money("USD"), "Sample description"
127
+
128
+ post_params = JSON.parse(FakeWeb.last_request.body)
129
+ post_params['button']['price_currency_iso'].should == "USD"
130
+ post_params['button']['price_string'].should == "1.23"
131
+
132
+ r.success?.should == true
133
+ r.button.name.should == "Order 123"
134
+ r.embed_html.should == %[<div class="coinbase-button" data-code="93865b9cae83706ae59220c013bc0afd"></div><script src="https://coinbase.com/assets/button.js" type="text/javascript"></script>]
135
+ end
136
+
137
+ it "should create order for the button" do
138
+ response = {"success"=>true, "order"=>{"id"=>"UAHXEK24", "created_at"=>"2013-12-13T01:15:56-08:00", "status"=>"new", "total_btc"=>{"cents"=>123, "currency_iso"=>"BTC"}, "total_native"=>{"cents"=>123, "currency_iso"=>"BTC"}, "custom"=>"Order123", "receive_address"=>"1EWxf61QGAkQDNUDq6XynH2PdFRyZUm111", "button"=>{"type"=>"buy_now", "name"=>"Order 123", "description"=>"Sample description", "id"=>"93865b9cae83706ae59220c013bc0afd"}, "transaction"=>nil}}
139
+ fake :post, '/buttons/93865b9cae83706ae59220c013bc0afd/create_order', response
140
+ r = @c.create_order_for_button "93865b9cae83706ae59220c013bc0afd"
141
+ r.order.button.id.should == "93865b9cae83706ae59220c013bc0afd"
142
+ r.order.status.should == "new"
143
+ end
144
+
145
+ # Transactions
146
+
147
+ it "should get transaction list" do
148
+ response = {"current_user"=>{"id"=>"5011f33df8182b142400000e", "email"=>"user2@example.com", "name"=>"user2@example.com"}, "balance"=>{"amount"=>"50.00000000", "currency"=>"BTC"}, "total_count"=>2, "num_pages"=>1, "current_page"=>1, "transactions"=>[{"transaction"=>{"id"=>"5018f833f8182b129c00002f", "created_at"=>"2012-08-01T02:34:43-07:00", "amount"=>{"amount"=>"-1.10000000", "currency"=>"BTC"}, "request"=>true, "status"=>"pending", "sender"=>{"id"=>"5011f33df8182b142400000e", "name"=>"User Two", "email"=>"user2@example.com"}, "recipient"=>{"id"=>"5011f33df8182b142400000a", "name"=>"User One", "email"=>"user1@example.com"}}}, {"transaction"=>{"id"=>"5018f833f8182b129c00002e", "created_at"=>"2012-08-01T02:36:43-07:00", "hsh" => "9d6a7d1112c3db9de5315b421a5153d71413f5f752aff75bf504b77df4e646a3", "amount"=>{"amount"=>"-1.00000000", "currency"=>"BTC"}, "request"=>false, "status"=>"complete", "sender"=>{"id"=>"5011f33df8182b142400000e", "name"=>"User Two", "email"=>"user2@example.com"}, "recipient_address"=>"37muSN5ZrukVTvyVh3mT5Zc5ew9L9CBare"}}]}
149
+ fake :get, '/transactions?page=1', response
150
+ r = @c.transactions
151
+ r.transactions.first.transaction.id.should == '5018f833f8182b129c00002f'
152
+ r.transactions.last.transaction.hsh.should == '9d6a7d1112c3db9de5315b421a5153d71413f5f752aff75bf504b77df4e646a3'
153
+ r.transactions.first.transaction.amount.should == "-1.1".to_money("BTC")
154
+ end
155
+
156
+ it "should get transaction detail" do
157
+ response = {"transaction"=>{"id"=>"5011f33df8182b142400000e", "created_at"=>"2013-12-19T05:20:15-08:00", "hsh"=>"ff11a892bc6f7c345a5d74d52b0878f6a7e5011f33df8182b142400000e", "amount"=>{"amount"=>"-0.01000000", "currency"=>"BTC"}, "request"=>false, "status"=>"pending", "sender"=>{"id"=>"5011f33df8182b142400000e", "email"=>"tuser2@example.com", "name"=>"User Two"}, "recipient_address"=>"1EWxf61QGAkQDNUDq6XynH2PdFRyZUm111", "notes"=>""}}
158
+ fake :get, "/transactions/5011f33df8182b142400000e", response
159
+ r = @c.transaction "5011f33df8182b142400000e"
160
+ r.transaction.id.should == "5011f33df8182b142400000e"
161
+ r.transaction.status.should == "pending"
162
+ r.transaction.amount.should == "-0.01".to_money("BTC")
163
+ end
164
+
165
+ it "should not fail if there are no transactions" do
166
+ response = {"current_user"=>{"id"=>"5011f33df8182b142400000e", "email"=>"user2@example.com", "name"=>"user2@example.com"}, "balance"=>{"amount"=>"0.00000000", "currency"=>"BTC"}, "total_count"=>0, "num_pages"=>0, "current_page"=>1}
167
+ fake :get, '/transactions?page=1', response
168
+ r = @c.transactions
169
+ r.transactions.should_not be_nil
170
+ end
171
+
172
+ it "should send money in BTC" do
173
+ response = {"success"=>true, "transaction"=>{"id"=>"501a1791f8182b2071000087", "created_at"=>"2012-08-01T23:00:49-07:00", "notes"=>"Sample transaction for you!", "amount"=>{"amount"=>"-1.23400000", "currency"=>"BTC"}, "request"=>false, "status"=>"pending", "sender"=>{"id"=>"5011f33df8182b142400000e", "name"=>"User Two", "email"=>"user2@example.com"}, "recipient"=>{"id"=>"5011f33df8182b142400000a", "name"=>"User One", "email"=>"user1@example.com"}}}
174
+ fake :post, '/transactions/send_money', response
175
+ r = @c.send_money "user1@example.com", 1.2345, "Sample transaction for you"
176
+
177
+ # Ensure BTC is assumed to be the default currency
178
+ post_params = JSON.parse(FakeWeb.last_request.body)
179
+ post_params['transaction']['amount_currency_iso'].should == "BTC"
180
+ post_params['transaction']['amount_string'].should == "1.23450000"
181
+
182
+ r.success.should == true
183
+ r.transaction.id.should == '501a1791f8182b2071000087'
184
+ end
185
+
186
+ it "should send money in USD" do
187
+ response = {"success"=>true, "transaction"=>{"id"=>"501a1791f8182b2071000087", "created_at"=>"2012-08-01T23:00:49-07:00", "notes"=>"Sample transaction for you!", "amount"=>{"amount"=>"-1.23400000", "currency"=>"BTC"}, "request"=>false, "status"=>"pending", "sender"=>{"id"=>"5011f33df8182b142400000e", "name"=>"User Two", "email"=>"user2@example.com"}, "recipient"=>{"id"=>"5011f33df8182b142400000a", "name"=>"User One", "email"=>"user1@example.com"}}}
188
+ fake :post, '/transactions/send_money', response
189
+ r = @c.send_money "user1@example.com", 500.to_money("USD"), "Sample transaction for you"
190
+
191
+ post_params = JSON.parse(FakeWeb.last_request.body)
192
+ post_params['transaction']['amount_currency_iso'].should == "USD"
193
+ post_params['transaction']['amount_string'].should == "500.00"
194
+
195
+ r.success.should == true
196
+ r.transaction.id.should == '501a1791f8182b2071000087'
197
+ end
198
+
199
+ it "should request money" do
200
+ response = {"success"=>true, "transaction"=>{"id"=>"501a3554f8182b2754000003", "created_at"=>"2012-08-02T01:07:48-07:00", "notes"=>"Sample request for you!", "amount"=>{"amount"=>"1.23400000", "currency"=>"BTC"}, "request"=>true, "status"=>"pending", "sender"=>{"id"=>"5011f33df8182b142400000a", "name"=>"User One", "email"=>"user1@example.com"}, "recipient"=>{"id"=>"5011f33df8182b142400000e", "name"=>"User Two", "email"=>"user2@example.com"}}}
201
+ fake :post, '/transactions/request_money', response
202
+ r = @c.request_money "user1@example.com", 1.2345, "Sample transaction for you"
203
+
204
+ # Ensure BTC is assumed to be the default currency
205
+ post_params = JSON.parse(FakeWeb.last_request.body)
206
+ post_params['transaction']['amount_currency_iso'].should == "BTC"
207
+ post_params['transaction']['amount_string'].should == "1.23450000"
208
+
209
+ r.success.should == true
210
+ r.transaction.id.should == '501a3554f8182b2754000003'
211
+ end
212
+
213
+ it "should request money in USD" do
214
+ response = {"success"=>true, "transaction"=>{"id"=>"501a3554f8182b2754000003", "created_at"=>"2012-08-02T01:07:48-07:00", "notes"=>"Sample request for you!", "amount"=>{"amount"=>"1.23400000", "currency"=>"BTC"}, "request"=>true, "status"=>"pending", "sender"=>{"id"=>"5011f33df8182b142400000a", "name"=>"User One", "email"=>"user1@example.com"}, "recipient"=>{"id"=>"5011f33df8182b142400000e", "name"=>"User Two", "email"=>"user2@example.com"}}}
215
+ fake :post, '/transactions/request_money', response
216
+ r = @c.request_money "user1@example.com", 500.to_money("USD"), "Sample transaction for you"
217
+
218
+ # Ensure BTC is assumed to be the default currency
219
+ post_params = JSON.parse(FakeWeb.last_request.body)
220
+ post_params['transaction']['amount_currency_iso'].should == "USD"
221
+ post_params['transaction']['amount_string'].should == "500.00"
222
+
223
+ r.success.should == true
224
+ r.transaction.id.should == '501a3554f8182b2754000003'
225
+ end
226
+
227
+ it "should resend requests" do
228
+ response = {"success"=>true}
229
+ fake :put, "/transactions/501a3554f8182b2754000003/resend_request", response
230
+ r = @c.resend_request '501a3554f8182b2754000003'
231
+ r.success.should == true
232
+ end
233
+
234
+ it "should cancel requests" do
235
+ response = {"success"=>true}
236
+ fake :delete, "/transactions/501a3554f8182b2754000003/cancel_request", response
237
+ r = @c.cancel_request '501a3554f8182b2754000003'
238
+ r.success.should == true
239
+ end
240
+
241
+ it "should resend requests" do
242
+ response = {"success"=>true}
243
+ fake :put, "/transactions/501a3554f8182b2754000003/complete_request", response
244
+ r = @c.complete_request '501a3554f8182b2754000003'
245
+ r.success.should == true
246
+ end
247
+
248
+ # Users
249
+
250
+ it "should let you create users" do
251
+ response = {"success"=>true, "user"=>{"id"=>"501a3d22f8182b2754000011", "name"=>"New User", "email"=>"newuser@example.com", "receive_address"=>"mpJKwdmJKYjiyfNo26eRp4j6qGwuUUnw9x"}}
252
+ fake :post, "/users", response
253
+ r = @c.create_user "newuser@example.com"
254
+ r.success.should == true
255
+ r.user.email.should == "newuser@example.com"
256
+ r.user.receive_address.should == "mpJKwdmJKYjiyfNo26eRp4j6qGwuUUnw9x"
257
+ end
258
+
259
+ it "should let you create users with OAuth" do
260
+ response = {
261
+ "success"=>true,
262
+ "oauth" => {
263
+ "access_token" => "the_access_token",
264
+ "refresh_token" => "the_refresh_token",
265
+ "scope" => "transactions buy sell",
266
+ "token_type" => "bearer"
267
+ },
268
+ "user" => {
269
+ "id"=>"501a3d22f8182b2754000011",
270
+ "name"=>"New User",
271
+ "email"=>"newuser@example.com",
272
+ "receive_address"=>"mpJKwdmJKYjiyfNo26eRp4j6qGwuUUnw9x"
273
+ }
274
+ }
275
+ fake :post, "/users", response
276
+ r = @c.create_user "newuser@example.com", "newpassword", "the_client_id", ['transactions', 'buy', 'sell']
277
+ r.success.should == true
278
+ r.oauth.access_token.should == "the_access_token"
279
+ r.user.email.should == "newuser@example.com"
280
+ r.user.receive_address.should == "mpJKwdmJKYjiyfNo26eRp4j6qGwuUUnw9x"
281
+ end
282
+
283
+ it "should not let you specify client_id without scopes" do
284
+ expect{ @c.create_user "newuser@example.com", "newpassword", "the_client_id" }.to raise_error(BetterCoinbase::Client::Error)
285
+ end
286
+
287
+ # Prices
288
+
289
+ it "should let you get buy, sell, and spot prices" do
290
+ fake :get, "/prices/buy?qty=1", {"amount"=>"13.85", "currency"=>"USD"}
291
+ r = @c.buy_price 1
292
+ r.to_f.should == 13.85
293
+
294
+ fake :get, "/prices/sell?qty=1", {"amount"=>"13.83", "currency"=>"USD"}
295
+ r = @c.sell_price 1
296
+ r.to_f.should == 13.83
297
+
298
+ fake :get, "/prices/spot_rate?currency=USD", {"amount"=>"13.84", "currency"=>"USD"}
299
+ r = @c.spot_price
300
+ r.to_f.should == 13.84
301
+ end
302
+
303
+ # Buys
304
+
305
+ it "should let you buy bitcoin" do
306
+ response = {"success"=>true, "transfer"=>{"_type"=>"AchDebit", "code"=>"6H7GYLXZ", "created_at"=>"2013-01-28T16:08:58-08:00", "fees"=>{"coinbase"=>{"cents"=>14, "currency_iso"=>"USD"}, "bank"=>{"cents"=>15, "currency_iso"=>"USD"}}, "status"=>"created", "payout_date"=>"2013-02-01T18:00:00-08:00", "btc"=>{"amount"=>"1.00000000", "currency"=>"BTC"}, "subtotal"=>{"amount"=>"13.55", "currency"=>"USD"}, "total"=>{"amount"=>"13.84", "currency"=>"USD"}}}
307
+ fake :post, "/buys", response
308
+ r = @c.buy! 1
309
+ r.success?.should == true
310
+ r.transfer.code.should == '6H7GYLXZ'
311
+ r.transfer.status.should == 'created'
312
+ r.transfer.btc.should == 1.to_money("BTC")
313
+ end
314
+
315
+ # Sells
316
+
317
+ it "should let you sell bitcoin" do
318
+ response = {"success"=>true, "transfer"=>{"_type"=>"AchCredit", "code"=>"RD2OC8AL", "created_at"=>"2013-01-28T16:32:35-08:00", "fees"=>{"coinbase"=>{"cents"=>14, "currency_iso"=>"USD"}, "bank"=>{"cents"=>15, "currency_iso"=>"USD"}}, "status"=>"created", "payout_date"=>"2013-02-01T18:00:00-08:00", "btc"=>{"amount"=>"1.00000000", "currency"=>"BTC"}, "subtotal"=>{"amount"=>"13.50", "currency"=>"USD"}, "total"=>{"amount"=>"13.21", "currency"=>"USD"}}}
319
+ fake :post, "/sells", response
320
+ r = @c.sell! 1
321
+ r.success?.should == true
322
+ r.transfer.code.should == 'RD2OC8AL'
323
+ r.transfer.status.should == 'created'
324
+ r.transfer.btc.should == 1.to_money("BTC")
325
+ end
326
+
327
+ # Transfers
328
+
329
+ it "should get recent transfers" do
330
+ response = {"transfers" => [{"transfer" => {"type" => "Buy", "code" => "QPCUCZHR", "created_at" => "2013-02-27T23:28:18-08:00", "fees" => {"coinbase" => {"cents" => 14, "currency_iso" => "USD"}, "bank" => {"cents" => 15, "currency_iso" => "USD"} }, "payout_date" => "2013-03-05T18:00:00-08:00", "transaction_id" => "5011f33df8182b142400000e", "status" => "Pending", "btc" => {"amount" => "1.00000000", "currency" => "BTC"}, "subtotal" => {"amount" => "13.55", "currency" => "USD"}, "total" => {"amount" => "13.84", "currency" => "USD"}, "description" => "Paid for with $13.84 from Test xxxxx3111."} } ], "total_count" => 1, "num_pages" => 1, "current_page" => 1 }
331
+ fake :get, "/transfers", response
332
+ r = @c.transfers
333
+ t = r.transfers.first.transfer
334
+ t.type.should == "Buy"
335
+ t.code.should == "QPCUCZHR"
336
+ t.status.should == "Pending"
337
+ t.btc.should == 1.to_money("BTC")
338
+ end
339
+
340
+ it "should support pagination" do
341
+ response = {"transfers" => [{"transfer" => {"type" => "Buy", "code" => "QPCUCZHZ", "created_at" => "2013-02-27T23:28:18-08:00", "fees" => {"coinbase" => {"cents" => 14, "currency_iso" => "USD"}, "bank" => {"cents" => 15, "currency_iso" => "USD"} }, "payout_date" => "2013-03-05T18:00:00-08:00", "transaction_id" => "5011f33df8182b142400000e", "status" => "Pending", "btc" => {"amount" => "1.00000000", "currency" => "BTC"}, "subtotal" => {"amount" => "13.55", "currency" => "USD"}, "total" => {"amount" => "13.84", "currency" => "USD"}, "description" => "Paid for with $13.84 from Test xxxxx3111."} } ], "total_count" => 1, "num_pages" => 1, "current_page" => 1 }
342
+ fake :get, "/transfers?page=2", response
343
+ r = @c.transfers :page => 2
344
+ t = r.transfers.first.transfer
345
+ t.type.should == "Buy"
346
+ t.code.should == "QPCUCZHZ"
347
+ t.status.should == "Pending"
348
+ t.btc.should == 1.to_money("BTC")
349
+ FakeWeb.last_request.path.should include("page=2")
350
+ end
351
+
352
+ # Addresses
353
+
354
+ it 'should read addresses json' do
355
+ raw_addresses = <<-eos
356
+ {
357
+ "addresses": [
358
+ {
359
+ "address": {
360
+ "address": "moLxGrqWNcnGq4A8Caq8EGP4n9GUGWanj4",
361
+ "callback_url": null,
362
+ "label": "My Label",
363
+ "created_at": "2013-05-09T23:07:08-07:00"
364
+ }
365
+ },
366
+ {
367
+ "address": {
368
+ "address": "mwigfecvyG4MZjb6R5jMbmNcs7TkzhUaCj",
369
+ "callback_url": null,
370
+ "label": null,
371
+ "created_at": "2013-05-09T17:50:37-07:00"
372
+ }
373
+ }
374
+ ],
375
+ "total_count": 2,
376
+ "num_pages": 1,
377
+ "current_page": 1
378
+ }
379
+ eos
380
+
381
+ fake :get, '/addresses?page=1', JSON.parse(raw_addresses)
382
+
383
+ r = @c.addresses
384
+ r.total_count.should == 2
385
+ r.num_pages.should == 1
386
+ r.current_page.should == 1
387
+ r.addresses.size.should == 2
388
+ r.addresses.first.address.address.should == 'moLxGrqWNcnGq4A8Caq8EGP4n9GUGWanj4'
389
+ r.addresses.first.address.callback_url.should == nil
390
+ r.addresses.first.address.label.should == 'My Label'
391
+ r.addresses.first.addresscreated_at == '2013-05-09T23:07:08-07:00'
392
+ r.addresses[1].address.address.should == 'mwigfecvyG4MZjb6R5jMbmNcs7TkzhUaCj'
393
+ r.addresses[1].address.callback_url.should == nil
394
+ r.addresses[1].address.label.should == nil
395
+ r.addresses[1].address.created_at.should == '2013-05-09T17:50:37-07:00'
396
+ end
397
+
398
+ it 'should get a list of currency exchanges' do
399
+ response = {'gbp_to_usd'=>'1.633667', 'usd_to_bwp'=>'8.62852', 'usd_to_azn'=>'0.784167', 'eur_to_usd'=>'1.35924', 'usd_to_czk'=>'20.11621', 'czk_to_btc'=>'5.6e-05', 'btc_to_mga'=>'1999686.885067', 'btc_to_djf'=>'158147.411834', 'idr_to_btc'=>'0.0', 'mnt_to_usd'=>'0.00058', 'usd_to_ngn'=>'158.682199', 'usd_to_gbp'=>'0.61212', 'irr_to_btc'=>'0.0', 'ils_to_usd'=>'0.282751', 'ars_to_usd'=>'0.163763', 'usd_to_uyu'=>'21.16168', 'uyu_to_btc'=>'5.3e-05', 'pyg_to_btc'=>'0.0', 'usd_to_yer'=>'215.006099', 'pgk_to_usd'=>'0.387254', 'xcd_to_btc'=>'0.000416', 'usd_to_fjd'=>'1.870015', 'dop_to_btc'=>'2.7e-05', 'mvr_to_usd'=>'0.06503', 'eek_to_usd'=>'0.085636', 'nzd_to_btc'=>'0.000918', 'gnf_to_btc'=>'0.0', 'usd_to_gtq'=>'7.88508', 'bmd_to_usd'=>'1.0', 'btc_to_lbp'=>'1338220.674541', 'usd_to_omr'=>'0.385012', 'usd_to_sos'=>'1207.4067', 'usd_to_thb'=>'32.11708', 'srd_to_btc'=>'0.000343', 'btc_to_all'=>'91888.63729', 'usd_to_vnd'=>'21106.95', 'htg_to_usd'=>'0.025083', 'btc_to_bmd'=>'888.93805', 'kpw_to_usd'=>'0.0', 'lyd_to_usd'=>'0.804161', 'tzs_to_btc'=>'1.0e-06', 'lak_to_usd'=>'0.000125', 'usd_to_idr'=>'11907.583333', 'btc_to_bzd'=>'1770.195675', 'usd_to_gel'=>'1.6904', 'usd_to_kzt'=>'153.658001', 'uah_to_usd'=>'0.121707', 'usd_to_lkr'=>'131.201499', 'btc_to_zwl'=>'286553.630441', 'php_to_btc'=>'2.6e-05', 'ron_to_usd'=>'0.306263', 'btc_to_kyd'=>'734.803304', 'btc_to_cad'=>'940.246665', 'hkd_to_btc'=>'0.000145', 'usd_to_btc'=>'0.001125', 'nok_to_btc'=>'0.000185', 'top_to_usd'=>'0.548145', 'btc_to_xpf'=>'78126.987338', 'usd_to_kgs'=>'48.862875', 'usd_to_bnd'=>'1.25468', 'dzd_to_usd'=>'0.012516', 'vef_to_btc'=>'0.000179', 'usd_to_ars'=>'6.106376', 'syp_to_btc'=>'8.0e-06', 'ngn_to_btc'=>'7.0e-06', 'bgn_to_btc'=>'0.000782', 'lak_to_btc'=>'0.0', 'btc_to_cve'=>'71977.305019', 'mga_to_btc'=>'1.0e-06', 'idr_to_usd'=>'8.4e-05', 'btc_to_htg'=>'35439.725263', 'btc_to_ils'=>'3143.884978', 'mad_to_btc'=>'0.000136', 'usd_to_hnl'=>'20.52386', 'svc_to_btc'=>'0.000129', 'btc_to_ang'=>'1590.274614', 'hkd_to_usd'=>'0.12899', 'usd_to_nad'=>'10.20123', 'szl_to_btc'=>'0.00011', 'etb_to_usd'=>'0.052406', 'pkr_to_btc'=>'1.0e-05', 'usd_to_khr'=>'4003.966833', 'gnf_to_usd'=>'0.000144', 'btc_to_myr'=>'2870.615643', 'btc_to_top'=>'1621.720797', 'nad_to_btc'=>'0.00011', 'huf_to_usd'=>'0.004546', 'mkd_to_btc'=>'2.5e-05', 'lkr_to_btc'=>'9.0e-06', 'svc_to_usd'=>'0.114311', 'btc_to_lyd'=>'1105.422911', 'usd_to_bam'=>'1.440026', 'usd_to_svc'=>'8.74805', 'usd_to_tzs'=>'1609.666667', 'gbp_to_btc'=>'0.001838', 'btc_to_mop'=>'7097.761418', 'btc_to_jod'=>'629.416142', 'clp_to_usd'=>'0.001896', 'cad_to_usd'=>'0.945431', 'cny_to_btc'=>'0.000184', 'jod_to_btc'=>'0.001589', 'syp_to_usd'=>'0.007141', 'lvl_to_btc'=>'0.002175', 'btc_to_cny'=>'5422.419877', 'shp_to_btc'=>'0.001838', 'vef_to_usd'=>'0.158944', 'php_to_usd'=>'0.022869', 'mro_to_usd'=>'0.003427', 'tjs_to_btc'=>'0.000236', 'fkp_to_btc'=>'0.001838', 'bdt_to_usd'=>'0.012869', 'mkd_to_usd'=>'0.021979', 'lrd_to_usd'=>'0.012418', 'usd_to_kes'=>'87.034389', 'btc_to_ars'=>'5428.189974', 'usd_to_chf'=>'0.906341', 'usd_to_lak'=>'7987.781667', 'usd_to_bzd'=>'1.99136', 'usd_to_nzd'=>'1.225977', 'mvr_to_btc'=>'7.3e-05', 'usd_to_wst'=>'2.344837', 'nok_to_usd'=>'0.164135', 'tjs_to_usd'=>'0.209516', 'bob_to_usd'=>'0.144729', 'btc_to_cup'=>'20163.676005', 'afn_to_btc'=>'2.0e-05', 'vnd_to_btc'=>'0.0', 'bnd_to_usd'=>'0.797016', 'byr_to_btc'=>'0.0', 'aed_to_btc'=>'0.000306', 'hnl_to_btc'=>'5.5e-05', 'mmk_to_usd'=>'0.001018', 'zmk_to_btc'=>'0.0', 'usd_to_myr'=>'3.229264', 'usd_to_ils'=>'3.536675', 'usd_to_mdl'=>'13.1323', 'djf_to_usd'=>'0.005621', 'mnt_to_btc'=>'1.0e-06', 'usd_to_sbd'=>'7.143096', 'lbp_to_usd'=>'0.000664', 'aoa_to_btc'=>'1.2e-05', 'btc_to_vnd'=>'18762770.974447', 'btc_to_lak'=>'7100643.058889', 'dkk_to_usd'=>'0.182213', 'inr_to_btc'=>'1.8e-05', 'lrd_to_btc'=>'1.4e-05', 'pab_to_btc'=>'0.001125', 'usd_to_mga'=>'2249.523333', 'btc_to_awg'=>'1591.065769', 'usd_to_try'=>'2.015658', 'usd_to_qar'=>'3.641038', 'usd_to_lvl'=>'0.517161', 'bmd_to_btc'=>'0.001125', 'vuv_to_btc'=>'1.2e-05', 'usd_to_pen'=>'2.80238', 'usd_to_zmk'=>'5253.075255', 'usd_to_ttd'=>'6.41373', 'mwk_to_btc'=>'3.0e-06', 'btc_to_scr'=>'10736.55821', 'egp_to_btc'=>'0.000163', 'bam_to_btc'=>'0.000781', 'usd_to_kmf'=>'362.286958', 'btc_to_aed'=>'3264.928117', 'usd_to_shp'=>'0.61212', 'bbd_to_btc'=>'0.0', 'kes_to_usd'=>'0.01149', 'jpy_to_btc'=>'1.1e-05', 'wst_to_usd'=>'0.426469', 'gyd_to_usd'=>'0.004843', 'kgs_to_btc'=>'2.3e-05', 'btc_to_eek'=>'10380.418515', 'usd_to_php'=>'43.72676', 'sdg_to_usd'=>'0.225802', 'usd_to_isk'=>'120.165', 'scr_to_btc'=>'9.3e-05', 'cup_to_usd'=>'0.044086', 'std_to_btc'=>'0.0', 'usd_to_gip'=>'0.61212', 'usd_to_aud'=>'1.0963', 'usd_to_dzd'=>'79.89655', 'usd_to_xaf'=>'483.051199', 'usd_to_mro'=>'291.7967', 'clp_to_btc'=>'2.0e-06', 'bbd_to_usd'=>'0.0', 'mdl_to_btc'=>'8.6e-05', 'btc_to_pyg'=>'3929049.928111', 'xof_to_btc'=>'2.0e-06', 'kzt_to_btc'=>'7.0e-06', 'usd_to_irr'=>'24785.667967', 'usd_to_vuv'=>'96.5375', 'bif_to_btc'=>'1.0e-06', 'btc_to_gtq'=>'7009.347639', 'usd_to_bif'=>'1551.3184', 'btc_to_xof'=>'429968.666639', 'btc_to_ghs'=>'2020.911763', 'btc_to_kes'=>'77368.180041', 'usd_to_bbd'=>'2', 'usd_to_afn'=>'57.430025', 'usd_to_sdg'=>'4.428657', 'uzs_to_usd'=>'0.00046', 'btc_to_dzd'=>'71023.083359', 'btc_to_uyu'=>'18811.422554', 'usd_to_mnt'=>'1725.083333', 'egp_to_usd'=>'0.145211', 'btc_to_nio'=>'22379.602108', 'usd_to_mur'=>'30.35621', 'usd_to_fkp'=>'0.61212', 'twd_to_usd'=>'0.033739', 'btc_to_bif'=>'1379025.953425', 'nio_to_btc'=>'4.5e-05', 'bhd_to_usd'=>'2.652604', 'aoa_to_usd'=>'0.010273', 'tmm_to_usd'=>'0.350652', 'btc_to_bhd'=>'335.118978', 'kyd_to_btc'=>'0.001361', 'usd_to_mzn'=>'29.89945', 'jmd_to_btc'=>'1.1e-05', 'lbp_to_btc'=>'1.0e-06', 'btc_to_ngn'=>'141058.644549', 'sek_to_btc'=>'0.000171', 'try_to_usd'=>'0.496116', 'btc_to_mkd'=>'40444.556713', 'btc_to_gbp'=>'544.136759', 'aud_to_btc'=>'0.001026', 'xpf_to_usd'=>'0.011378', 'bzd_to_btc'=>'0.000565', 'usd_to_cdf'=>'921.303003', 'btc_to_bdt'=>'69075.748998', 'cup_to_btc'=>'5.0e-05', 'usd_to_lsl'=>'10.19269', 'btc_to_tnd'=>'1481.973513', 'btc_to_pln'=>'2744.550005', 'usd_to_btn'=>'62.405663', 'zar_to_btc'=>'0.00011', 'bob_to_btc'=>'0.000163', 'usd_to_top'=>'1.824335', 'amd_to_btc'=>'3.0e-06', 'btc_to_syp'=>'124475.771907', 'szl_to_usd'=>'0.098101', 'gip_to_usd'=>'1.633667', 'usd_to_mvr'=>'15.37749', 'thb_to_usd'=>'0.031136', 'bgn_to_usd'=>'0.694751', 'btc_to_gnf'=>'6165712.835153', 'rwf_to_btc'=>'2.0e-06', 'cny_to_usd'=>'0.163938', 'btc_to_mzn'=>'26578.758779', 'btc_to_bob'=>'6142.090788', 'btc_to_etb'=>'16962.395852', 'ern_to_usd'=>'0.066235', 'mmk_to_btc'=>'1.0e-06', 'btc_to_uzs'=>'1931941.125176', 'usd_to_kwd'=>'0.282781', 'btc_to_twd'=>'26347.794895', 'usd_to_clp'=>'527.4221', 'ghs_to_usd'=>'0.43987', 'brl_to_btc'=>'0.000485', 'btc_to_try'=>'1791.795092', 'usd_to_dkk'=>'5.488097', 'myr_to_btc'=>'0.000348', 'btc_to_svc'=>'7776.474508', 'kmf_to_btc'=>'3.0e-06', 'mxn_to_btc'=>'8.6e-05', 'nio_to_usd'=>'0.039721', 'uah_to_btc'=>'0.000137', 'ttd_to_btc'=>'0.000175', 'usd_to_sgd'=>'1.254902', 'usd_to_hrk'=>'5.615268', 'btc_to_thb'=>'28550.094467', 'mwk_to_usd'=>'0.002446', 'btc_to_aud'=>'974.542784', 'btc_to_vuv'=>'85815.857002', 'btc_to_php'=>'38870.380767', 'pyg_to_usd'=>'0.000226', 'scr_to_usd'=>'0.082795', 'btc_to_kwd'=>'251.374791', 'ugx_to_usd'=>'0.000396', 'btc_to_gmd'=>'33591.155476', 'zwl_to_btc'=>'3.0e-06', 'btc_to_zar'=>'9069.212668', 'btc_to_hkd'=>'6891.55268', 'btc_to_afn'=>'51051.734435', 'btc_to_fkp'=>'544.136759', 'xaf_to_btc'=>'2.0e-06', 'usd_to_nok'=>'6.092554', 'btc_to_kzt'=>'136592.443776', 'btc_to_btn'=>'55474.768376', 'amd_to_usd'=>'0.002449', 'usd_to_syp'=>'140.027499', 'usd_to_jpy'=>'102.181201', 'usd_to_sek'=>'6.570703', 'btc_to_clp'=>'468845.573101', 'sgd_to_usd'=>'0.796875', 'btc_to_qar'=>'3236.65722', 'czk_to_usd'=>'0.049711', 'usd_to_aoa'=>'97.343626', 'krw_to_usd'=>'0.000942', 'sar_to_usd'=>'0.266627', 'hnl_to_usd'=>'0.048724', 'bwp_to_usd'=>'0.115895', 'usd_to_brl'=>'2.319796', 'btc_to_bbd'=>'1777.8761', 'ngn_to_usd'=>'0.006302', 'azn_to_usd'=>'1.275239', 'btc_to_mnt'=>'1533492.214125', 'usd_to_rub'=>'33.12431', 'btc_to_lvl'=>'459.724091', 'usd_to_ron'=>'3.265171', 'btc_to_azn'=>'697.075884', 'sll_to_usd'=>'0.000232', 'usd_to_dop'=>'42.3681', 'pab_to_usd'=>'1.0', 'pkr_to_usd'=>'0.009223', 'usd_to_scr'=>'12.07796', 'usd_to_huf'=>'219.952799', 'bdt_to_btc'=>'1.4e-05', 'btc_to_crc'=>'439769.207752', 'std_to_usd'=>'5.5e-05', 'mzn_to_usd'=>'0.033445', 'mzn_to_btc'=>'3.8e-05', 'nzd_to_usd'=>'0.815676', 'btc_to_npr'=>'88656.014961', 'btc_to_bwp'=>'7670.219743', 'kwd_to_usd'=>'3.536305', 'omr_to_usd'=>'2.597322', 'btc_to_rwf'=>'600360.508519', 'kgs_to_usd'=>'0.020465', 'afn_to_usd'=>'0.017412', 'btc_to_egp'=>'6121.693216', 'aud_to_usd'=>'0.912159', 'usd_to_mwk'=>'408.8331', 'usd_to_cny'=>'6.099885', 'rwf_to_usd'=>'0.001481', 'usd_to_zwl'=>'322.355006', 'btc_to_cdf'=>'818981.294946', 'usd_to_tjs'=>'4.7729', 'usd_to_all'=>'103.369', 'bhd_to_btc'=>'0.002984', 'kpw_to_btc'=>'0.0', 'bam_to_usd'=>'0.694432', 'btc_to_szl'=>'9061.452238', 'usd_to_pyg'=>'4419.936719', 'gel_to_btc'=>'0.000666', 'xcd_to_usd'=>'0.370165', 'usd_to_lrd'=>'80.528251', 'sos_to_usd'=>'0.000828', 'usd_to_uzs'=>'2173.313568', 'btc_to_fjd'=>'1662.327488', 'btc_to_iqd'=>'1034670.598364', 'usd_to_bsd'=>'1', 'cve_to_btc'=>'1.4e-05', 'rub_to_btc'=>'3.4e-05', 'usd_to_rsd'=>'83.906211', 'sar_to_btc'=>'0.0003', 'eek_to_btc'=>'9.6e-05', 'btc_to_ugx'=>'2244746.378083', 'awg_to_btc'=>'0.000629', 'btc_to_mwk'=>'363427.298689', 'huf_to_btc'=>'5.0e-06', 'ang_to_usd'=>'0.558984', 'usd_to_djf'=>'177.905999', 'usd_to_cad'=>'1.057719', 'btc_to_brl'=>'2062.154933', 'usd_to_ern'=>'15.097825', 'iqd_to_btc'=>'1.0e-06', 'btc_to_pgk'=>'2295.489615', 'usd_to_xcd'=>'2.7015', 'btn_to_btc'=>'1.8e-05', 'myr_to_usd'=>'0.309668', 'lsl_to_usd'=>'0.09811', 'crc_to_usd'=>'0.002021', 'usd_to_egp'=>'6.886524', 'btc_to_rsd'=>'74587.423589', 'gel_to_usd'=>'0.591576', 'jmd_to_usd'=>'0.009719', 'btc_to_ltl'=>'2258.393341', 'lyd_to_btc'=>'0.000905', 'nad_to_usd'=>'0.098027', 'usd_to_kyd'=>'0.826608', 'btc_to_bsd'=>'888.93805', 'ltl_to_btc'=>'0.000443', 'usd_to_srd'=>'3.283333', 'usd_to_awg'=>'1.78985', 'usd_to_szl'=>'10.19357', 'chf_to_btc'=>'0.001241', 'zwl_to_usd'=>'0.003102', 'sll_to_btc'=>'0.0', 'usd_to_cop'=>'1927.433333', 'usd_to_tmm'=>'2.851833', 'btc_to_tjs'=>'4242.812419', 'sbd_to_btc'=>'0.000157', 'ern_to_btc'=>'7.5e-05', 'btc_to_bam'=>'1280.093904', 'btc_to_gip'=>'544.136759', 'sbd_to_usd'=>'0.139995', 'mad_to_usd'=>'0.121088', 'btc_to_ern'=>'13421.031115', 'usd_to_ltl'=>'2.540552', 'qar_to_usd'=>'0.274647', 'usd_to_kpw'=>'900', 'usd_to_crc'=>'494.712998', 'usd_to_xpf'=>'87.888', 'yer_to_btc'=>'5.0e-06', 'chf_to_usd'=>'1.103337', 'jpy_to_usd'=>'0.009787', 'ars_to_btc'=>'0.000184', 'usd_to_pgk'=>'2.582283', 'gyd_to_btc'=>'5.0e-06', 'aed_to_usd'=>'0.272269', 'usd_to_mop'=>'7.98454', 'usd_to_aed'=>'3.672841', 'qar_to_btc'=>'0.000309', 'btc_to_sll'=>'3837842.02269', 'btc_to_dkk'=>'4878.578245', 'gtq_to_usd'=>'0.126822', 'sos_to_btc'=>'1.0e-06', 'dop_to_usd'=>'0.023603', 'awg_to_usd'=>'0.558706', 'btc_to_gel'=>'1502.66088', 'btc_to_lkr'=>'116630.004678', 'btc_to_lrd'=>'71584.626414', 'khr_to_usd'=>'0.00025', 'btc_to_hrk'=>'4991.625386', 'usd_to_etb'=>'19.08164', 'btc_to_sos'=>'1073309.757455', 'btc_to_eur'=>'653.996168', 'usd_to_krw'=>'1061.26498', 'btc_to_dop'=>'37662.616196', 'usd_to_bob'=>'6.90947', 'btc_to_kgs'=>'43436.06882', 'cve_to_usd'=>'0.01235', 'fjd_to_usd'=>'0.534755', 'btc_to_jpy'=>'90832.757564', 'btc_to_omr'=>'342.251817', 'usd_to_gyd'=>'206.501249', 'pen_to_btc'=>'0.000401', 'btc_to_jmd'=>'91465.502779', 'npr_to_usd'=>'0.010027', 'usd_to_tnd'=>'1.667128', 'usd_to_twd'=>'29.63963', 'btc_to_nad'=>'9068.261504', 'azn_to_btc'=>'0.001435', 'btc_to_sgd'=>'1115.530137', 'twd_to_btc'=>'3.8e-05', 'btc_to_sek'=>'5840.947912', 'inr_to_usd'=>'0.016031', 'crc_to_btc'=>'2.0e-06', 'usd_to_mxn'=>'13.10359', 'xaf_to_usd'=>'0.00207', 'btc_to_idr'=>'10585103.90825', 'btc_to_hnl'=>'18244.440087', 'eur_to_btc'=>'0.001529', 'btc_to_sbd'=>'6349.769829', 'hrk_to_usd'=>'0.178086', 'pln_to_btc'=>'0.000364', 'gtq_to_btc'=>'0.000143', 'zmk_to_usd'=>'0.00019', 'thb_to_btc'=>'3.5e-05', 'btc_to_mvr'=>'13669.635974', 'ghs_to_btc'=>'0.000495', 'usd_to_gmd'=>'37.78796', 'usd_to_mkd'=>'45.49761', 'usd_to_eur'=>'0.735705', 'cop_to_btc'=>'1.0e-06', 'btc_to_xcd'=>'2401.466142', 'sdg_to_btc'=>'0.000254', 'btc_to_nzd'=>'1089.817604', 'usd_to_uah'=>'8.21647', 'rsd_to_btc'=>'1.3e-05', 'cdf_to_btc'=>'1.0e-06', 'btn_to_usd'=>'0.016024', 'krw_to_btc'=>'1.0e-06', 'tzs_to_usd'=>'0.000621', 'pgk_to_btc'=>'0.000436', 'btc_to_byr'=>'8303422.168412', 'bsd_to_usd'=>'1.0', 'irr_to_usd'=>'4.0e-05', 'uyu_to_usd'=>'0.047255', 'mop_to_btc'=>'0.000141', 'usd_to_ghs'=>'2.2734', 'btc_to_khr'=>'3559278.468792', 'kyd_to_usd'=>'1.209763', 'btc_to_zmk'=>'4669658.473683', 'cop_to_usd'=>'0.000519', 'btc_to_mad'=>'7341.276218', 'try_to_btc'=>'0.000558', 'xpf_to_btc'=>'1.3e-05', 'kzt_to_usd'=>'0.006508', 'usd_to_bhd'=>'0.376988', 'top_to_btc'=>'0.000617', 'ugx_to_btc'=>'0.0', 'usd_to_mmk'=>'982.69002', 'usd_to_jod'=>'0.708054', 'btc_to_vef'=>'5592.762631', 'gip_to_btc'=>'0.001838', 'btc_to_mmk'=>'873550.550133', 'usd_to_xof'=>'483.687999', 'wst_to_btc'=>'0.00048', 'mdl_to_usd'=>'0.076148', 'ltl_to_usd'=>'0.393615', 'bnd_to_btc'=>'0.000897', 'usd_to_sll'=>'4317.3335', 'usd_to_nio'=>'25.17566', 'btc_to_mro'=>'259389.189494', 'srd_to_usd'=>'0.304569', 'usd_to_lbp'=>'1505.415', 'btc_to_pkr'=>'96380.691049', 'rsd_to_usd'=>'0.011918', 'sgd_to_btc'=>'0.000896', 'yer_to_usd'=>'0.004651', 'lvl_to_usd'=>'1.933634', 'usd_to_ang'=>'1.78896', 'usd_to_sar'=>'3.750561', 'usd_to_iqd'=>'1163.94005', 'btc_to_kmf'=>'322050.661985', 'usd_to_bmd'=>'1', 'kes_to_btc'=>'1.3e-05', 'btc_to_irr'=>'22032923.350532', 'btc_to_aoa'=>'86532.453076', 'btc_to_shp'=>'544.136759', 'btc_to_sdg'=>'3936.801718', 'kmf_to_usd'=>'0.00276', 'btc_to_krw'=>'943398.821854', 'btc_to_srd'=>'2918.679635', 'usd_to_bdt'=>'77.70592', 'usd_to_zar'=>'10.2023', 'bwp_to_btc'=>'0.00013', 'byr_to_usd'=>'0.000107', 'vnd_to_usd'=>'4.7e-05', 'usd_to_cve'=>'80.96999', 'btc_to_btc'=>'1.000055', 'btc_to_pen'=>'2491.142213', 'usd_to_hkd'=>'7.752568', 'isk_to_btc'=>'9.0e-06', 'pen_to_usd'=>'0.35684', 'btc_to_kpw'=>'800044.245', 'btc_to_tmm'=>'0.0', 'bzd_to_usd'=>'0.502169', 'npr_to_btc'=>'1.1e-05', 'btc_to_chf'=>'805.681001', 'btc_to_bgn'=>'1279.506316', 'btc_to_uah'=>'7303.93282', 'pln_to_usd'=>'0.323892', 'btc_to_inr'=>'55450.142125', 'htg_to_btc'=>'2.8e-05', 'btc_to_wst'=>'2084.41483', 'btc_to_ron'=>'2902.534742', 'xof_to_usd'=>'0.002067', 'btc_to_mur'=>'26984.790123', 'usd_to_rwf'=>'675.36822', 'usd_to_pab'=>'1', 'btc_to_mxn'=>'11648.279743', 'all_to_btc'=>'1.1e-05', 'dkk_to_btc'=>'0.000205', 'usd_to_ugx'=>'2525.200016', 'tnd_to_usd'=>'0.599834', 'usd_to_lyd'=>'1.243532', 'usd_to_pkr'=>'108.422281', 'omr_to_btc'=>'0.002922', 'mga_to_usd'=>'0.000445', 'mur_to_btc'=>'3.7e-05', 'usd_to_amd'=>'408.364003', 'jod_to_usd'=>'1.412322', 'tnd_to_btc'=>'0.000675', 'shp_to_usd'=>'1.633667', 'vuv_to_usd'=>'0.010359', 'khr_to_btc'=>'0.0', 'usd_to_htg'=>'39.867486', 'iqd_to_usd'=>'0.000859', 'btc_to_sar'=>'3334.016382', 'mur_to_usd'=>'0.032942', 'lsl_to_btc'=>'0.00011', 'usd_to_jmd'=>'102.893', 'ils_to_btc'=>'0.000318', 'zar_to_usd'=>'0.098017', 'usd_to_pln'=>'3.087448', 'bsd_to_btc'=>'0.001125', 'btc_to_rub'=>'29445.459539', 'usd_to_mad'=>'8.258479', 'usd_to_inr'=>'62.37796', 'btc_to_czk'=>'17882.064491', 'isk_to_usd'=>'0.008322', 'rub_to_usd'=>'0.030189', 'usd_to_usd'=>'1.0', 'fkp_to_usd'=>'1.633667', 'all_to_usd'=>'0.009674', 'mop_to_usd'=>'0.125242', 'usd_to_cup'=>'22.682881', 'mro_to_btc'=>'4.0e-06', 'tmm_to_btc'=>'0.0', 'fjd_to_btc'=>'0.000602', 'usd_to_gnf'=>'6936.043333', 'btc_to_huf'=>'195524.412235', 'usd_to_byr'=>'9340.833333', 'usd_to_bgn'=>'1.439365', 'ang_to_btc'=>'0.000629', 'gmd_to_usd'=>'0.026463', 'bif_to_usd'=>'0.000645', 'etb_to_btc'=>'5.9e-05', 'usd_to_std'=>'18145.400667', 'btc_to_std'=>'16130137.085392', 'btc_to_ttd'=>'5701.408639', 'ron_to_btc'=>'0.000345', 'gmd_to_btc'=>'3.0e-05', 'kwd_to_btc'=>'0.003978', 'btc_to_amd'=>'363010.300517', 'btc_to_gyd'=>'183566.817609', 'btc_to_nok'=>'5415.903072', 'btc_to_yer'=>'191127.102383', 'cdf_to_usd'=>'0.001085', 'btc_to_usd'=>'888.9380499999999', 'hrk_to_btc'=>'0.0002', 'btc_to_xaf'=>'429402.590889', 'btc_to_bnd'=>'1115.332793', 'btc_to_lsl'=>'9060.669973', 'usd_to_eek'=>'11.677325', 'brl_to_usd'=>'0.431072', 'lkr_to_usd'=>'0.007622', 'btc_to_pab'=>'888.93805', 'ttd_to_usd'=>'0.155916', 'btc_to_cop'=>'1713368.828542', 'btc_to_isk'=>'106819.240778', 'uzs_to_btc'=>'1.0e-06', 'mxn_to_usd'=>'0.076315', 'btc_to_mdl'=>'11673.801154', 'djf_to_btc'=>'6.0e-06', 'usd_to_npr'=>'99.732501', 'btc_to_tzs'=>'1430893.948113', 'usd_to_vef'=>'6.29151', 'cad_to_btc'=>'0.001064', 'dzd_to_btc'=>'1.4e-05', 'sek_to_usd'=>'0.152191'}
400
+ fake :get, '/currencies/exchange_rates', response
401
+ r = @c.exchange_rates
402
+ r.usd_to_btc.should == '0.001125'
403
+ r.btc_to_usd.should == '888.9380499999999'
404
+ end
405
+
406
+ it 'should let you get short list of accepted currencies' do
407
+ response = "[['Afghan Afghani (AFN)','AFN'],['Albanian Lek (ALL)','ALL'],['Algerian Dinar (DZD)','DZD'],['Angolan Kwanza (AOA)','AOA'],['Argentine Peso (ARS)','ARS'],['Armenian Dram (AMD)','AMD'],['Aruban Florin (AWG)','AWG'],['Australian Dollar (AUD)','AUD'],['Azerbaijani Manat (AZN)','AZN'],['Bahamian Dollar (BSD)','BSD'],['Bahraini Dinar (BHD)','BHD'],['Bangladeshi Taka (BDT)','BDT'],['Barbadian Dollar (BBD)','BBD'],['Belarusian Ruble (BYR)','BYR'],['Belize Dollar (BZD)','BZD'],['Bermudian Dollar (BMD)','BMD'],['Bhutanese Ngultrum (BTN)','BTN'],['Bolivian Boliviano (BOB)','BOB'],['Bosnia and Herzegovina Convertible Mark (BAM)','BAM'],['Botswana Pula (BWP)','BWP'],['Brazilian Real (BRL)','BRL'],['British Pound (GBP)','GBP'],['Brunei Dollar (BND)','BND'],['Bulgarian Lev (BGN)','BGN'],['Burundian Franc (BIF)','BIF'],['Cambodian Riel (KHR)','KHR'],['Canadian Dollar (CAD)','CAD'],['Cape Verdean Escudo (CVE)','CVE'],['Cayman Islands Dollar (KYD)','KYD'],['Central African Cfa Franc (XAF)','XAF'],['Cfp Franc (XPF)','XPF'],['Chilean Peso (CLP)','CLP'],['Chinese Renminbi Yuan (CNY)','CNY'],['Colombian Peso (COP)','COP'],['Comorian Franc (KMF)','KMF'],['Congolese Franc (CDF)','CDF'],['Costa Rican Col\u00f3n (CRC)','CRC'],['Croatian Kuna (HRK)','HRK'],['Cuban Peso (CUP)','CUP'],['Czech Koruna (CZK)','CZK'],['Danish Krone (DKK)','DKK'],['Djiboutian Franc (DJF)','DJF'],['Dominican Peso (DOP)','DOP'],['East Caribbean Dollar (XCD)','XCD'],['Egyptian Pound (EGP)','EGP'],['Eritrean Nakfa (ERN)','ERN'],['Estonian Kroon (EEK)','EEK'],['Ethiopian Birr (ETB)','ETB'],['Euro (EUR)','EUR'],['Falkland Pound (FKP)','FKP'],['Fijian Dollar (FJD)','FJD'],['Gambian Dalasi (GMD)','GMD'],['Georgian Lari (GEL)','GEL'],['Ghanaian Cedi (GHS)','GHS'],['Ghanaian Cedi (GHS)','GHS'],['Gibraltar Pound (GIP)','GIP'],['Guatemalan Quetzal (GTQ)','GTQ'],['Guinean Franc (GNF)','GNF'],['Guyanese Dollar (GYD)','GYD'],['Haitian Gourde (HTG)','HTG'],['Honduran Lempira (HNL)','HNL'],['Hong Kong Dollar (HKD)','HKD'],['Hungarian Forint (HUF)','HUF'],['Icelandic Kr\u00f3na (ISK)','ISK'],['Indian Rupee (INR)','INR'],['Indonesian Rupiah (IDR)','IDR'],['Iranian Rial (IRR)','IRR'],['Iraqi Dinar (IQD)','IQD'],['Israeli New Sheqel (ILS)','ILS'],['Jamaican Dollar (JMD)','JMD'],['Japanese Yen (JPY)','JPY'],['Japanese Yen (JPY)','JPY'],['Jordanian Dinar (JOD)','JOD'],['Kazakhstani Tenge (KZT)','KZT'],['Kenyan Shilling (KES)','KES'],['Kuwaiti Dinar (KWD)','KWD'],['Kyrgyzstani Som (KGS)','KGS'],['Lao Kip (LAK)','LAK'],['Latvian Lats (LVL)','LVL'],['Lebanese Pound (LBP)','LBP'],['Lesotho Loti (LSL)','LSL'],['Liberian Dollar (LRD)','LRD'],['Libyan Dinar (LYD)','LYD'],['Lithuanian Litas (LTL)','LTL'],['Macanese Pataca (MOP)','MOP'],['Macedonian Denar (MKD)','MKD'],['Malagasy Ariary (MGA)','MGA'],['Malawian Kwacha (MWK)','MWK'],['Malaysian Ringgit (MYR)','MYR'],['Maldivian Rufiyaa (MVR)','MVR'],['Mauritanian Ouguiya (MRO)','MRO'],['Mauritian Rupee (MUR)','MUR'],['Mexican Peso (MXN)','MXN'],['Moldovan Leu (MDL)','MDL'],['Mongolian T\u00f6gr\u00f6g (MNT)','MNT'],['Moroccan Dirham (MAD)','MAD'],['Mozambican Metical (MZN)','MZN'],['Myanmar Kyat (MMK)','MMK'],['Namibian Dollar (NAD)','NAD'],['Nepalese Rupee (NPR)','NPR'],['Netherlands Antillean Gulden (ANG)','ANG'],['New Taiwan Dollar (TWD)','TWD'],['New Zealand Dollar (NZD)','NZD'],['Nicaraguan C\u00f3rdoba (NIO)','NIO'],['Nigerian Naira (NGN)','NGN'],['North Korean Won (KPW)','KPW'],['Norwegian Krone (NOK)','NOK'],['Omani Rial (OMR)','OMR'],['Pakistani Rupee (PKR)','PKR'],['Panamanian Balboa (PAB)','PAB'],['Papua New Guinean Kina (PGK)','PGK'],['Paraguayan Guaran\u00ed (PYG)','PYG'],['Peruvian Nuevo Sol (PEN)','PEN'],['Philippine Peso (PHP)','PHP'],['Polish Z\u0142oty (PLN)','PLN'],['Qatari Riyal (QAR)','QAR'],['Romanian Leu (RON)','RON'],['Russian Ruble (RUB)','RUB'],['Rwandan Franc (RWF)','RWF'],['Saint Helenian Pound (SHP)','SHP'],['Salvadoran Col\u00f3n (SVC)','SVC'],['Samoan Tala (WST)','WST'],['Saudi Riyal (SAR)','SAR'],['Serbian Dinar (RSD)','RSD'],['Seychellois Rupee (SCR)','SCR'],['Sierra Leonean Leone (SLL)','SLL'],['Singapore Dollar (SGD)','SGD'],['Solomon Islands Dollar (SBD)','SBD'],['Somali Shilling (SOS)','SOS'],['South African Rand (ZAR)','ZAR'],['South Korean Won (KRW)','KRW'],['Sri Lankan Rupee (LKR)','LKR'],['Sudanese Pound (SDG)','SDG'],['Surinamese Dollar (SRD)','SRD'],['Swazi Lilangeni (SZL)','SZL'],['Swedish Krona (SEK)','SEK'],['Swiss Franc (CHF)','CHF'],['Syrian Pound (SYP)','SYP'],['S\u00e3o Tom\u00e9 and Pr\u00edncipe Dobra (STD)','STD'],['Tajikistani Somoni (TJS)','TJS'],['Tanzanian Shilling (TZS)','TZS'],['Thai Baht (THB)','THB'],['Tongan Pa\u02bbanga (TOP)','TOP'],['Trinidad and Tobago Dollar (TTD)','TTD'],['Tunisian Dinar (TND)','TND'],['Turkish Lira (TRY)','TRY'],['Turkmenistani Manat (TMM)','TMM'],['Turkmenistani Manat (TMM)','TMM'],['Ugandan Shilling (UGX)','UGX'],['Ukrainian Hryvnia (UAH)','UAH'],['United Arab Emirates Dirham (AED)','AED'],['United States Dollar (USD)','USD'],['Uruguayan Peso (UYU)','UYU'],['Uzbekistani Som (UZS)','UZS'],['Vanuatu Vatu (VUV)','VUV'],['Venezuelan Bol\u00edvar (VEF)','VEF'],['Vietnamese \u0110\u1ed3ng (VND)','VND'],['West African Cfa Franc (XOF)','XOF'],['Yemeni Rial (YER)','YER'],['Zambian Kwacha (ZMK)','ZMK'],['Zimbabwean Dollar (ZWL)','ZWL']]"
408
+ fake :get, '/currencies', response
409
+ r = @c.currencies_short
410
+ r.first.should == 'AFN'
411
+ r[1].should == 'ALL'
412
+ r.last.should == 'ZWL'
413
+ end
414
+
415
+ it 'should let you get long list of accepted currencies' do
416
+ response = '[["Afghan Afghani (AFN)","AFN"],["Albanian Lek (ALL)","ALL"],["Algerian Dinar (DZD)","DZD"],["Angolan Kwanza (AOA)","AOA"],["Argentine Peso (ARS)","ARS"],["Armenian Dram (AMD)","AMD"],["Aruban Florin (AWG)","AWG"],["Australian Dollar (AUD)","AUD"],["Azerbaijani Manat (AZN)","AZN"],["Bahamian Dollar (BSD)","BSD"],["Bahraini Dinar (BHD)","BHD"],["Bangladeshi Taka (BDT)","BDT"],["Barbadian Dollar (BBD)","BBD"],["Belarusian Ruble (BYR)","BYR"],["Belize Dollar (BZD)","BZD"],["Bermudian Dollar (BMD)","BMD"],["Bhutanese Ngultrum (BTN)","BTN"],["Bolivian Boliviano (BOB)","BOB"],["Bosnia and Herzegovina Convertible Mark (BAM)","BAM"],["Botswana Pula (BWP)","BWP"],["Brazilian Real (BRL)","BRL"],["British Pound (GBP)","GBP"],["Brunei Dollar (BND)","BND"],["Bulgarian Lev (BGN)","BGN"],["Burundian Franc (BIF)","BIF"],["Cambodian Riel (KHR)","KHR"],["Canadian Dollar (CAD)","CAD"],["Cape Verdean Escudo (CVE)","CVE"],["Cayman Islands Dollar (KYD)","KYD"],["Central African Cfa Franc (XAF)","XAF"],["Cfp Franc (XPF)","XPF"],["Chilean Peso (CLP)","CLP"],["Chinese Renminbi Yuan (CNY)","CNY"],["Colombian Peso (COP)","COP"],["Comorian Franc (KMF)","KMF"],["Congolese Franc (CDF)","CDF"],["Costa Rican Col\u00f3n (CRC)","CRC"],["Croatian Kuna (HRK)","HRK"],["Cuban Peso (CUP)","CUP"],["Czech Koruna (CZK)","CZK"],["Danish Krone (DKK)","DKK"],["Djiboutian Franc (DJF)","DJF"],["Dominican Peso (DOP)","DOP"],["East Caribbean Dollar (XCD)","XCD"],["Egyptian Pound (EGP)","EGP"],["Eritrean Nakfa (ERN)","ERN"],["Estonian Kroon (EEK)","EEK"],["Ethiopian Birr (ETB)","ETB"],["Euro (EUR)","EUR"],["Falkland Pound (FKP)","FKP"],["Fijian Dollar (FJD)","FJD"],["Gambian Dalasi (GMD)","GMD"],["Georgian Lari (GEL)","GEL"],["Ghanaian Cedi (GHS)","GHS"],["Ghanaian Cedi (GHS)","GHS"],["Gibraltar Pound (GIP)","GIP"],["Guatemalan Quetzal (GTQ)","GTQ"],["Guinean Franc (GNF)","GNF"],["Guyanese Dollar (GYD)","GYD"],["Haitian Gourde (HTG)","HTG"],["Honduran Lempira (HNL)","HNL"],["Hong Kong Dollar (HKD)","HKD"],["Hungarian Forint (HUF)","HUF"],["Icelandic Kr\u00f3na (ISK)","ISK"],["Indian Rupee (INR)","INR"],["Indonesian Rupiah (IDR)","IDR"],["Iranian Rial (IRR)","IRR"],["Iraqi Dinar (IQD)","IQD"],["Israeli New Sheqel (ILS)","ILS"],["Jamaican Dollar (JMD)","JMD"],["Japanese Yen (JPY)","JPY"],["Japanese Yen (JPY)","JPY"],["Jordanian Dinar (JOD)","JOD"],["Kazakhstani Tenge (KZT)","KZT"],["Kenyan Shilling (KES)","KES"],["Kuwaiti Dinar (KWD)","KWD"],["Kyrgyzstani Som (KGS)","KGS"],["Lao Kip (LAK)","LAK"],["Latvian Lats (LVL)","LVL"],["Lebanese Pound (LBP)","LBP"],["Lesotho Loti (LSL)","LSL"],["Liberian Dollar (LRD)","LRD"],["Libyan Dinar (LYD)","LYD"],["Lithuanian Litas (LTL)","LTL"],["Macanese Pataca (MOP)","MOP"],["Macedonian Denar (MKD)","MKD"],["Malagasy Ariary (MGA)","MGA"],["Malawian Kwacha (MWK)","MWK"],["Malaysian Ringgit (MYR)","MYR"],["Maldivian Rufiyaa (MVR)","MVR"],["Mauritanian Ouguiya (MRO)","MRO"],["Mauritian Rupee (MUR)","MUR"],["Mexican Peso (MXN)","MXN"],["Moldovan Leu (MDL)","MDL"],["Mongolian T\u00f6gr\u00f6g (MNT)","MNT"],["Moroccan Dirham (MAD)","MAD"],["Mozambican Metical (MZN)","MZN"],["Myanmar Kyat (MMK)","MMK"],["Namibian Dollar (NAD)","NAD"],["Nepalese Rupee (NPR)","NPR"],["Netherlands Antillean Gulden (ANG)","ANG"],["New Taiwan Dollar (TWD)","TWD"],["New Zealand Dollar (NZD)","NZD"],["Nicaraguan C\u00f3rdoba (NIO)","NIO"],["Nigerian Naira (NGN)","NGN"],["North Korean Won (KPW)","KPW"],["Norwegian Krone (NOK)","NOK"],["Omani Rial (OMR)","OMR"],["Pakistani Rupee (PKR)","PKR"],["Panamanian Balboa (PAB)","PAB"],["Papua New Guinean Kina (PGK)","PGK"],["Paraguayan Guaran\u00ed (PYG)","PYG"],["Peruvian Nuevo Sol (PEN)","PEN"],["Philippine Peso (PHP)","PHP"],["Polish Z\u0142oty (PLN)","PLN"],["Qatari Riyal (QAR)","QAR"],["Romanian Leu (RON)","RON"],["Russian Ruble (RUB)","RUB"],["Rwandan Franc (RWF)","RWF"],["Saint Helenian Pound (SHP)","SHP"],["Salvadoran Col\u00f3n (SVC)","SVC"],["Samoan Tala (WST)","WST"],["Saudi Riyal (SAR)","SAR"],["Serbian Dinar (RSD)","RSD"],["Seychellois Rupee (SCR)","SCR"],["Sierra Leonean Leone (SLL)","SLL"],["Singapore Dollar (SGD)","SGD"],["Solomon Islands Dollar (SBD)","SBD"],["Somali Shilling (SOS)","SOS"],["South African Rand (ZAR)","ZAR"],["South Korean Won (KRW)","KRW"],["Sri Lankan Rupee (LKR)","LKR"],["Sudanese Pound (SDG)","SDG"],["Surinamese Dollar (SRD)","SRD"],["Swazi Lilangeni (SZL)","SZL"],["Swedish Krona (SEK)","SEK"],["Swiss Franc (CHF)","CHF"],["Syrian Pound (SYP)","SYP"],["S\u00e3o Tom\u00e9 and Pr\u00edncipe Dobra (STD)","STD"],["Tajikistani Somoni (TJS)","TJS"],["Tanzanian Shilling (TZS)","TZS"],["Thai Baht (THB)","THB"],["Tongan Pa\u02bbanga (TOP)","TOP"],["Trinidad and Tobago Dollar (TTD)","TTD"],["Tunisian Dinar (TND)","TND"],["Turkish Lira (TRY)","TRY"],["Turkmenistani Manat (TMM)","TMM"],["Turkmenistani Manat (TMM)","TMM"],["Ugandan Shilling (UGX)","UGX"],["Ukrainian Hryvnia (UAH)","UAH"],["United Arab Emirates Dirham (AED)","AED"],["United States Dollar (USD)","USD"],["Uruguayan Peso (UYU)","UYU"],["Uzbekistani Som (UZS)","UZS"],["Vanuatu Vatu (VUV)","VUV"],["Venezuelan Bol\u00edvar (VEF)","VEF"],["Vietnamese \u0110\u1ed3ng (VND)","VND"],["West African Cfa Franc (XOF)","XOF"],["Yemeni Rial (YER)","YER"],["Zambian Kwacha (ZMK)","ZMK"],["Zimbabwean Dollar (ZWL)","ZWL"]]'
417
+ fake :get, '/currencies', response
418
+ r = @c.currencies_long
419
+ r.first.should == 'Afghan Afghani (AFN)'
420
+ r[1].should == 'Albanian Lek (ALL)'
421
+ r.last.should == 'Zimbabwean Dollar (ZWL)'
422
+ end
423
+
424
+ private
425
+ def fake method, path, body
426
+ FakeWeb.register_uri(method, "#{BASE_URI}#{path}", body: body.to_json)
427
+ end
428
+
429
+ end