better-coinbase 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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