straight 0.1.0 → 0.2.0
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.
- checksums.yaml +4 -4
- data/Gemfile +1 -0
- data/Gemfile.lock +5 -1
- data/README.md +20 -10
- data/VERSION +1 -1
- data/lib/straight.rb +10 -1
- data/lib/straight/blockchain_adapter.rb +2 -13
- data/lib/straight/blockchain_adapters/biteasy_adapter.rb +74 -0
- data/lib/straight/blockchain_adapters/blockchain_info_adapter.rb +37 -17
- data/lib/straight/blockchain_adapters/mycelium_adapter.rb +144 -0
- data/lib/straight/exchange_rate_adapter.rb +20 -1
- data/lib/straight/exchange_rate_adapters/average_rate_adapter.rb +54 -0
- data/lib/straight/exchange_rate_adapters/bitpay_adapter.rb +5 -2
- data/lib/straight/exchange_rate_adapters/bitstamp_adapter.rb +2 -1
- data/lib/straight/exchange_rate_adapters/btce_adapter.rb +18 -0
- data/lib/straight/exchange_rate_adapters/coinbase_adapter.rb +2 -4
- data/lib/straight/exchange_rate_adapters/kraken_adapter.rb +18 -0
- data/lib/straight/exchange_rate_adapters/localbitcoins_adapter.rb +17 -0
- data/lib/straight/exchange_rate_adapters/okcoin_adapter.rb +18 -0
- data/lib/straight/gateway.rb +20 -9
- data/lib/straight/order.rb +46 -13
- data/spec/lib/blockchain_adapters/{helloblock_io_spec.rb → biteasy_adapter_spec.rb} +23 -18
- data/spec/lib/blockchain_adapters/{blockchain_info_spec.rb → blockchain_info_adapter_spec.rb} +8 -3
- data/spec/lib/blockchain_adapters/mycelium_adapter_spec.rb +54 -0
- data/spec/lib/exchange_rate_adapter_spec.rb +6 -1
- data/spec/lib/exchange_rate_adapters/average_rate_adapter_spec.rb +43 -0
- data/spec/lib/exchange_rate_adapters/bitpay_adapter_spec.rb +14 -1
- data/spec/lib/exchange_rate_adapters/bitstamp_adapter_spec.rb +14 -1
- data/spec/lib/exchange_rate_adapters/btce_adapter_spec.rb +27 -0
- data/spec/lib/exchange_rate_adapters/coinbase_adapter_spec.rb +14 -1
- data/spec/lib/exchange_rate_adapters/kraken_adapter_spec.rb +27 -0
- data/spec/lib/exchange_rate_adapters/localbitcoins_adapter_spec.rb +27 -0
- data/spec/lib/exchange_rate_adapters/okcoin_adapter_spec.rb +27 -0
- data/spec/lib/gateway_spec.rb +23 -5
- data/spec/lib/order_spec.rb +18 -2
- data/straight.gemspec +95 -0
- metadata +33 -6
- data/lib/straight/blockchain_adapters/helloblock_io_adapter.rb +0 -53
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe Straight::Blockchain::MyceliumAdapter do
|
4
|
+
|
5
|
+
subject(:adapter) { Straight::Blockchain::MyceliumAdapter.mainnet_adapter }
|
6
|
+
|
7
|
+
it "fetches all transactions for the current address" do
|
8
|
+
address = "3B1QZ8FpAaHBgkSB5gFt76ag5AW9VeP8xp"
|
9
|
+
expect(adapter).to receive(:straighten_transaction).with(anything, address: address).at_least(:once)
|
10
|
+
expect(adapter.fetch_transactions_for(address)).not_to be_empty
|
11
|
+
end
|
12
|
+
|
13
|
+
it "fetches the balance for a given address" do
|
14
|
+
address = "1NX8bgWdPq2NahtTbTUAAdsTwpMpvt7nLy"
|
15
|
+
expect(adapter.fetch_balance_for(address)).to be_kind_of(Integer)
|
16
|
+
end
|
17
|
+
|
18
|
+
it "fetches a single transaction" do
|
19
|
+
tid = 'ae0d040f48d75fdc46d9035236a1782164857d6f0cca1f864640281115898560'
|
20
|
+
expect(adapter.fetch_transaction(tid)[:total_amount]).to eq(832947)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "calculates the number of confirmations for each transaction" do
|
24
|
+
tid = 'ae0d040f48d75fdc46d9035236a1782164857d6f0cca1f864640281115898560'
|
25
|
+
expect(adapter.fetch_transaction(tid)[:confirmations]).to be > 0
|
26
|
+
end
|
27
|
+
|
28
|
+
it "gets a transaction id among other data" do
|
29
|
+
tid = 'ae0d040f48d75fdc46d9035236a1782164857d6f0cca1f864640281115898560'
|
30
|
+
expect(adapter.fetch_transaction(tid)[:tid]).to eq(tid)
|
31
|
+
end
|
32
|
+
|
33
|
+
it "caches blockchain.info latestblock requests" do
|
34
|
+
latest_block_response = double('Blockchain info latest block response')
|
35
|
+
expect(latest_block_response).to receive(:body).and_return('{ "height": 1 }')
|
36
|
+
expect(HTTParty).to receive(:get).with("https://blockchain.info/latestblock", timeout: 4, verify: false).once.and_return(latest_block_response)
|
37
|
+
adapter.send(:calculate_confirmations, 1, force_latest_block_reload: true)
|
38
|
+
adapter.send(:calculate_confirmations, 1)
|
39
|
+
adapter.send(:calculate_confirmations, 1)
|
40
|
+
adapter.send(:calculate_confirmations, 1)
|
41
|
+
adapter.send(:calculate_confirmations, 1)
|
42
|
+
end
|
43
|
+
|
44
|
+
it "raises an exception when something goes wrong with fetching datd" do
|
45
|
+
expect( -> { adapter.send(:api_request, "/a-404-request") }).to raise_error(Straight::Blockchain::Adapter::RequestError)
|
46
|
+
end
|
47
|
+
|
48
|
+
it "uses the same Singleton instance" do
|
49
|
+
a = Straight::Blockchain::MyceliumAdapter.mainnet_adapter
|
50
|
+
b = Straight::Blockchain::MyceliumAdapter.mainnet_adapter
|
51
|
+
expect(a).to eq(b)
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
@@ -7,7 +7,7 @@ RSpec.describe Straight::ExchangeRate::Adapter do
|
|
7
7
|
end
|
8
8
|
|
9
9
|
before(:each) do
|
10
|
-
@exchange_adapter = Straight::ExchangeRate::Adapter.
|
10
|
+
@exchange_adapter = Straight::ExchangeRate::Adapter.instance
|
11
11
|
end
|
12
12
|
|
13
13
|
describe "converting currencies" do
|
@@ -47,4 +47,9 @@ RSpec.describe Straight::ExchangeRate::Adapter do
|
|
47
47
|
@exchange_adapter.rate_for('USD')
|
48
48
|
end
|
49
49
|
|
50
|
+
it "raises exception if rate is nil" do
|
51
|
+
rate = nil
|
52
|
+
expect( -> { @exchange_adapter.rate_to_f(rate) }).to raise_error(Straight::ExchangeRate::Adapter::CurrencyNotSupported)
|
53
|
+
end
|
54
|
+
|
50
55
|
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe Straight::ExchangeRate::AverageRateAdapter do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
@average_rates_adapter = Straight::ExchangeRate::AverageRateAdapter.instance(
|
7
|
+
Straight::ExchangeRate::BitstampAdapter,
|
8
|
+
Straight::ExchangeRate::BitpayAdapter.instance,
|
9
|
+
)
|
10
|
+
end
|
11
|
+
|
12
|
+
it "calculates average rate" do
|
13
|
+
json_response_bistamp = '{"high": "232.89", "last": "100", "timestamp": "1423457015", "bid": "224.00", "vwap": "224.57", "volume": "14810.41127494", "low": "217.28", "ask": "224.13"}'
|
14
|
+
json_response_bitpay = '[{"code":"USD","name":"US Dollar","rate":200},{"code":"EUR","name":"Eurozone Euro","rate":197.179544}]'
|
15
|
+
uri_mock = double('uri mock')
|
16
|
+
allow(uri_mock).to receive(:read).with(read_timeout: 4).and_return(json_response_bistamp, json_response_bitpay)
|
17
|
+
allow(URI).to receive(:parse).and_return(uri_mock)
|
18
|
+
expect(@average_rates_adapter.rate_for('USD')).to eq 150
|
19
|
+
end
|
20
|
+
|
21
|
+
it "fetches rates for all adapters" do
|
22
|
+
expect(@average_rates_adapter.fetch_rates!).not_to be_empty
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'raises error if all adapters failed to fetch rates' do
|
26
|
+
adapter_mocks = [double('adapter_1'), double('adapter_2')]
|
27
|
+
adapter_mocks.each do |adapter|
|
28
|
+
expect(adapter).to receive(:fetch_rates!).and_raise(Straight::ExchangeRate::Adapter::FetchingFailed)
|
29
|
+
end
|
30
|
+
average_rates_adapter = Straight::ExchangeRate::AverageRateAdapter.instance(*adapter_mocks)
|
31
|
+
expect( -> { average_rates_adapter.fetch_rates! }).to raise_error(Straight::ExchangeRate::Adapter::FetchingFailed)
|
32
|
+
end
|
33
|
+
|
34
|
+
it "raises exception if all adapters fail to get rates" do
|
35
|
+
expect( -> { @average_rates_adapter.rate_for('FEDcoin') }).to raise_error(Straight::ExchangeRate::Adapter::CurrencyNotSupported)
|
36
|
+
end
|
37
|
+
|
38
|
+
it "raises exception if unallowed method is called" do # fetch_rates! is not to be used in AverageRateAdapter itself
|
39
|
+
expect( -> { @average_rates_adapter.get_rate_value_from_hash(nil, 'nothing') }).to raise_error("This method is not supposed to be used in #{@average_rates_adapter.class}.")
|
40
|
+
expect( -> { @average_rates_adapter.rate_to_f(nil) }).to raise_error("This method is not supposed to be used in #{@average_rates_adapter.class}.")
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
@@ -3,7 +3,7 @@ require 'spec_helper'
|
|
3
3
|
RSpec.describe Straight::ExchangeRate::BitpayAdapter do
|
4
4
|
|
5
5
|
before(:each) do
|
6
|
-
@exchange_adapter = Straight::ExchangeRate::BitpayAdapter.
|
6
|
+
@exchange_adapter = Straight::ExchangeRate::BitpayAdapter.instance
|
7
7
|
end
|
8
8
|
|
9
9
|
it "finds the rate for currency code" do
|
@@ -11,4 +11,17 @@ RSpec.describe Straight::ExchangeRate::BitpayAdapter do
|
|
11
11
|
expect( -> { @exchange_adapter.rate_for('FEDcoin') }).to raise_error(Straight::ExchangeRate::Adapter::CurrencyNotSupported)
|
12
12
|
end
|
13
13
|
|
14
|
+
it "raises exception if rate is nil" do
|
15
|
+
json_response_1 = '[{},{}]'
|
16
|
+
json_response_2 = '[{"code":"USD","name":"US Dollar","rat":223.59},{"code":"EUR","name":"Eurozone Euro","rate":197.179544}]'
|
17
|
+
json_response_3 = '[{"code":"USD","name":"US Dollar","rate":null},{"code":"EUR","name":"Eurozone Euro","rate":197.179544}]'
|
18
|
+
uri_mock = double('uri mock')
|
19
|
+
allow(uri_mock).to receive(:read).with(read_timeout: 4).and_return(json_response_1, json_response_2, json_response_3)
|
20
|
+
allow(URI).to receive(:parse).and_return(uri_mock)
|
21
|
+
3.times do
|
22
|
+
@exchange_adapter.fetch_rates!
|
23
|
+
expect( -> { @exchange_adapter.rate_for('USD') }).to raise_error(Straight::ExchangeRate::Adapter::CurrencyNotSupported)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
14
27
|
end
|
@@ -3,7 +3,7 @@ require 'spec_helper'
|
|
3
3
|
RSpec.describe Straight::ExchangeRate::BitstampAdapter do
|
4
4
|
|
5
5
|
before(:each) do
|
6
|
-
@exchange_adapter = Straight::ExchangeRate::BitstampAdapter.
|
6
|
+
@exchange_adapter = Straight::ExchangeRate::BitstampAdapter.instance
|
7
7
|
end
|
8
8
|
|
9
9
|
it "finds the rate for currency code" do
|
@@ -11,4 +11,17 @@ RSpec.describe Straight::ExchangeRate::BitstampAdapter do
|
|
11
11
|
expect( -> { @exchange_adapter.rate_for('FEDcoin') }).to raise_error(Straight::ExchangeRate::Adapter::CurrencyNotSupported)
|
12
12
|
end
|
13
13
|
|
14
|
+
it "raises exception if rate is nil" do
|
15
|
+
json_response_1 = '{}'
|
16
|
+
json_response_2 = '{"high": "232.89", "list": "224.13", "timestamp": "1423457015", "bid": "224.00", "vwap": "224.57", "volume": "14810.41127494", "low": "217.28", "ask": "224.13"}'
|
17
|
+
json_response_3 = '{"high": "232.89", "last": null, "timestamp": "1423457015", "bid": "224.00", "vwap": "224.57", "volume": "14810.41127494", "low": "217.28", "ask": "224.13"}'
|
18
|
+
uri_mock = double('uri mock')
|
19
|
+
allow(uri_mock).to receive(:read).with(read_timeout: 4).and_return(json_response_1, json_response_2, json_response_3)
|
20
|
+
allow(URI).to receive(:parse).and_return(uri_mock)
|
21
|
+
3.times do
|
22
|
+
@exchange_adapter.fetch_rates!
|
23
|
+
expect( -> { @exchange_adapter.rate_for('USD') }).to raise_error(Straight::ExchangeRate::Adapter::CurrencyNotSupported)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
14
27
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe Straight::ExchangeRate::BtceAdapter do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
@exchange_adapter = Straight::ExchangeRate::BtceAdapter.instance
|
7
|
+
end
|
8
|
+
|
9
|
+
it "finds the rate for currency code" do
|
10
|
+
expect(@exchange_adapter.rate_for('USD')).to be_kind_of(Float)
|
11
|
+
expect( -> { @exchange_adapter.rate_for('FEDcoin') }).to raise_error(Straight::ExchangeRate::Adapter::CurrencyNotSupported)
|
12
|
+
end
|
13
|
+
|
14
|
+
it "rases exception if rate is nil" do
|
15
|
+
json_response_1 = '{"ticker":{}}'
|
16
|
+
json_response_2 = '{"ticker":{"high":235,"low":215.89999,"avg":225.449995,"vol":2848293.72397,"vol_cur":12657.55799,"bambo":221.444,"buy":221.629,"sell":220.98,"updated":1422678812,"server_time":1422678813}}'
|
17
|
+
json_response_3 = '{"ticker":{"high":235,"low":215.89999,"avg":225.449995,"vol":2848293.72397,"vol_cur":12657.55799,"last":null,"buy":221.629,"sell":220.98,"updated":1422678812,"server_time":1422678813}}'
|
18
|
+
uri_mock = double('uri mock')
|
19
|
+
allow(uri_mock).to receive(:read).with(read_timeout: 4).and_return(json_response_1, json_response_2, json_response_3)
|
20
|
+
allow(URI).to receive(:parse).and_return(uri_mock)
|
21
|
+
3.times do
|
22
|
+
@exchange_adapter.fetch_rates!
|
23
|
+
expect( -> { @exchange_adapter.rate_for('USD') }).to raise_error(Straight::ExchangeRate::Adapter::CurrencyNotSupported)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
@@ -3,7 +3,7 @@ require 'spec_helper'
|
|
3
3
|
RSpec.describe Straight::ExchangeRate::CoinbaseAdapter do
|
4
4
|
|
5
5
|
before(:each) do
|
6
|
-
@exchange_adapter = Straight::ExchangeRate::CoinbaseAdapter.
|
6
|
+
@exchange_adapter = Straight::ExchangeRate::CoinbaseAdapter.instance
|
7
7
|
end
|
8
8
|
|
9
9
|
it "finds the rate for currency code" do
|
@@ -11,4 +11,17 @@ RSpec.describe Straight::ExchangeRate::CoinbaseAdapter do
|
|
11
11
|
expect( -> { @exchange_adapter.rate_for('FEDcoin') }).to raise_error(Straight::ExchangeRate::Adapter::CurrencyNotSupported)
|
12
12
|
end
|
13
13
|
|
14
|
+
it "raises exception if rate is nil" do
|
15
|
+
json_response_1 = '{}'
|
16
|
+
json_response_2 = '{"btc_to_urd":"224.41","usd_to_xpf":"105.461721","bsd_to_btc":"0.004456"}'
|
17
|
+
json_response_3 = '{"btc_to_usd":null,"usd_to_xpf":"105.461721","bsd_to_btc":"0.004456"}'
|
18
|
+
uri_mock = double('uri mock')
|
19
|
+
allow(uri_mock).to receive(:read).with(read_timeout: 4).and_return(json_response_1, json_response_2, json_response_3)
|
20
|
+
allow(URI).to receive(:parse).and_return(uri_mock)
|
21
|
+
3.times do
|
22
|
+
@exchange_adapter.fetch_rates!
|
23
|
+
expect( -> { @exchange_adapter.rate_for('USD') }).to raise_error(Straight::ExchangeRate::Adapter::CurrencyNotSupported)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
14
27
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe Straight::ExchangeRate::KrakenAdapter do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
@exchange_adapter = Straight::ExchangeRate::KrakenAdapter.instance
|
7
|
+
end
|
8
|
+
|
9
|
+
it "finds the rate for currency code" do
|
10
|
+
expect(@exchange_adapter.rate_for('USD')).to be_kind_of(Float)
|
11
|
+
expect( -> { @exchange_adapter.rate_for('FEDcoin') }).to raise_error(Straight::ExchangeRate::Adapter::CurrencyNotSupported)
|
12
|
+
end
|
13
|
+
|
14
|
+
it "raises exception if rate is nil" do
|
15
|
+
json_response_1 = '{"error":[],"result":{}}'
|
16
|
+
json_response_2 = '{"error":[],"result":{"XXBTZUSD":{"a":["244.95495","1"],"b":["227.88761","1"],"abc":["228.20494","0.10000000"],"v":["5.18645337","24.04033530"],"p":["234.92296","234.41356"],"t":[45,74],"l":["228.20494","228.20494"],"h":["239.36069","239.36069"],"o":"231.82976"}}}'
|
17
|
+
json_response_3 = '{"error":[],"result":{"XXBTZUSD":{"a":["244.95495","1"],"b":["227.88761","1"],"c":[null,"0.10000000"],"v":["5.18645337","24.04033530"],"p":["234.92296","234.41356"],"t":[45,74],"l":["228.20494","228.20494"],"h":["239.36069","239.36069"],"o":"231.82976"}}}'
|
18
|
+
uri_mock = double('uri mock')
|
19
|
+
allow(uri_mock).to receive(:read).with(read_timeout: 4).and_return(json_response_1, json_response_2, json_response_3)
|
20
|
+
allow(URI).to receive(:parse).and_return(uri_mock)
|
21
|
+
3.times do
|
22
|
+
@exchange_adapter.fetch_rates!
|
23
|
+
expect( -> { @exchange_adapter.rate_for('USD') }).to raise_error(Straight::ExchangeRate::Adapter::CurrencyNotSupported)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe Straight::ExchangeRate::LocalbitcoinsAdapter do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
@exchange_adapter = Straight::ExchangeRate::LocalbitcoinsAdapter.instance
|
7
|
+
end
|
8
|
+
|
9
|
+
it "finds the rate for currency code" do
|
10
|
+
expect(@exchange_adapter.rate_for('USD')).to be_kind_of(Float)
|
11
|
+
expect( -> { @exchange_adapter.rate_for('FEDcoin') }).to raise_error(Straight::ExchangeRate::Adapter::CurrencyNotSupported)
|
12
|
+
end
|
13
|
+
|
14
|
+
it "rases exception if rate is nil" do
|
15
|
+
json_response_1 = '{"USD": {}}'
|
16
|
+
json_response_2 = '{"USD": {"volume_btc": "2277.85", "rates": {"bambo": "263.78"}, "avg_1h": 287.6003904801631, "avg_24h": 253.58144543993674, "avg_12h": 252.29202866050034}}'
|
17
|
+
json_response_3 = '{"USD": {"volume_btc": "2277.85", "rates": {"last": null}, "avg_1h": 287.6003904801631, "avg_24h": 253.58144543993674, "avg_12h": 252.29202866050034}}'
|
18
|
+
uri_mock = double('uri mock')
|
19
|
+
allow(uri_mock).to receive(:read).with(read_timeout: 4).and_return(json_response_1, json_response_2, json_response_3)
|
20
|
+
allow(URI).to receive(:parse).and_return(uri_mock)
|
21
|
+
3.times do
|
22
|
+
@exchange_adapter.fetch_rates!
|
23
|
+
expect( -> { @exchange_adapter.rate_for('USD') }).to raise_error(Straight::ExchangeRate::Adapter::CurrencyNotSupported)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe Straight::ExchangeRate::OkcoinAdapter do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
@exchange_adapter = Straight::ExchangeRate::OkcoinAdapter.instance
|
7
|
+
end
|
8
|
+
|
9
|
+
it "finds the rate for currency code" do
|
10
|
+
expect(@exchange_adapter.rate_for('USD')).to be_kind_of(Float)
|
11
|
+
expect( -> { @exchange_adapter.rate_for('FEDcoin') }).to raise_error(Straight::ExchangeRate::Adapter::CurrencyNotSupported)
|
12
|
+
end
|
13
|
+
|
14
|
+
it "rases exception if rate is nil" do
|
15
|
+
json_response_1 = '{"date":"1422679981","ticker":{}}'
|
16
|
+
json_response_2 = '{"date":"1422679981","ticker":{"buy":"227.27","high":"243.55","bambo":"226.89","low":"226.0","sell":"227.74","vol":"16065.2085"}}'
|
17
|
+
json_response_3 = '{"date":"1422679981","ticker":{"buy":"227.27","high":"243.55","last":null,"low":"226.0","sell":"227.74","vol":"16065.2085"}}'
|
18
|
+
uri_mock = double('uri mock')
|
19
|
+
allow(uri_mock).to receive(:read).with(read_timeout: 4).and_return(json_response_1, json_response_2, json_response_3)
|
20
|
+
allow(URI).to receive(:parse).and_return(uri_mock)
|
21
|
+
3.times do
|
22
|
+
@exchange_adapter.fetch_rates!
|
23
|
+
expect( -> { @exchange_adapter.rate_for('USD') }).to raise_error(Straight::ExchangeRate::Adapter::CurrencyNotSupported)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
data/spec/lib/gateway_spec.rb
CHANGED
@@ -12,6 +12,20 @@ RSpec.describe Straight::Gateway do
|
|
12
12
|
@gateway.order_callbacks = []
|
13
13
|
end
|
14
14
|
|
15
|
+
it "shares exchange rate adapter(s) instances between all/multiple gateway instances" do
|
16
|
+
gateway_2 = Straight::Gateway.new.tap do |g|
|
17
|
+
g.pubkey = "pubkey"
|
18
|
+
g.order_class = "Straight::Order"
|
19
|
+
g.blockchain_adapters = [@mock_adapter]
|
20
|
+
g.status_check_schedule = Straight::Gateway::DEFAULT_STATUS_CHECK_SCHEDULE
|
21
|
+
g.order_callbacks = []
|
22
|
+
end
|
23
|
+
# Checking if exchange rate adapters are the same objects for both gateways
|
24
|
+
@gateway.instance_variable_get(:@exchange_rate_adapters).each_with_index do |adapter, i|
|
25
|
+
expect(gateway_2.instance_variable_get(:@exchange_rate_adapters)[i]).to be adapter
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
15
29
|
it "passes methods on to the available adapter" do
|
16
30
|
@gateway.instance_variable_set('@blockchain_adapters', [@mock_adapter])
|
17
31
|
expect(@mock_adapter).to receive(:fetch_transaction).once
|
@@ -27,8 +41,8 @@ RSpec.describe Straight::Gateway do
|
|
27
41
|
end
|
28
42
|
|
29
43
|
it "creates new orders and addresses for them" do
|
30
|
-
@gateway.pubkey =
|
31
|
-
expected_address =
|
44
|
+
@gateway.pubkey = 'xpub661MyMwAqRbcFhUeRviyfia1NdfX4BAv5zCsZ6HqsprRjdBDK8vwh3kfcnTvqNbmi5S1yZ5qL9ugZTyVqtyTZxccKZzMVMCQMhARycvBZvx'
|
45
|
+
expected_address = '1NEvrcxS3REbJgup8rMA4QvMFFSdWTLvM'
|
32
46
|
expect(@gateway.order_for_keychain_id(amount: 1, keychain_id: 1).address).to eq(expected_address)
|
33
47
|
end
|
34
48
|
|
@@ -47,15 +61,15 @@ RSpec.describe Straight::Gateway do
|
|
47
61
|
describe "exchange rate calculation" do
|
48
62
|
|
49
63
|
it "sets order amount in satoshis calculated from another currency" do
|
50
|
-
adapter = Straight::ExchangeRate::BitpayAdapter.
|
64
|
+
adapter = Straight::ExchangeRate::BitpayAdapter.instance
|
51
65
|
allow(adapter).to receive(:rate_for).and_return(450.5412)
|
52
66
|
@gateway.exchange_rate_adapters = [adapter]
|
53
67
|
expect(@gateway.amount_from_exchange_rate(2252.706, currency: 'USD')).to eq(500000000)
|
54
68
|
end
|
55
69
|
|
56
70
|
it "tries various exchange adapters until one of them actually returns an exchange rate" do
|
57
|
-
adapter1 = Straight::ExchangeRate::BitpayAdapter.
|
58
|
-
adapter2 = Straight::ExchangeRate::BitpayAdapter.
|
71
|
+
adapter1 = Straight::ExchangeRate::BitpayAdapter.instance
|
72
|
+
adapter2 = Straight::ExchangeRate::BitpayAdapter.instance
|
59
73
|
allow(adapter1).to receive(:rate_for).and_return( -> { raise "connection problem" })
|
60
74
|
allow(adapter2).to receive(:rate_for).and_return(450.5412)
|
61
75
|
@gateway.exchange_rate_adapters = [adapter1, adapter2]
|
@@ -70,6 +84,10 @@ RSpec.describe Straight::Gateway do
|
|
70
84
|
expect(@gateway.amount_from_exchange_rate('0.5', currency: 'BTC', btc_denomination: :btc)).to eq(50000000)
|
71
85
|
end
|
72
86
|
|
87
|
+
it "simply fetches current exchange rate for 1 BTC" do
|
88
|
+
expect(@gateway.current_exchange_rate('USD')).not_to be_nil
|
89
|
+
end
|
90
|
+
|
73
91
|
end
|
74
92
|
|
75
93
|
end
|
data/spec/lib/order_spec.rb
CHANGED
@@ -26,9 +26,9 @@ RSpec.describe Straight::Order do
|
|
26
26
|
allow(@gateway).to receive(:fetch_transactions_for).with('address').and_return([])
|
27
27
|
allow(@gateway).to receive(:status_check_schedule).and_return(Straight::Gateway::DEFAULT_STATUS_CHECK_SCHEDULE)
|
28
28
|
[10, 20, 40, 80, 160, 320, 640].each do |i|
|
29
|
-
expect(@order).to receive(:sleep).with(i).exactly(
|
29
|
+
expect(@order).to receive(:sleep).with(i).exactly(20).times
|
30
30
|
end
|
31
|
-
@order.
|
31
|
+
@order.start_periodic_status_check(duration: 25400)
|
32
32
|
end
|
33
33
|
|
34
34
|
it "gets the last transaction for the current address, caches the request" do
|
@@ -53,6 +53,12 @@ RSpec.describe Straight::Order do
|
|
53
53
|
expect(@order.to_json).to eq('{"status":1,"amount":10,"address":"address","tid":null}')
|
54
54
|
end
|
55
55
|
|
56
|
+
it "returns amount in btc as a string" do
|
57
|
+
@order.amount = 1
|
58
|
+
expect(@order.amount_in_btc).to eq(0.00000001)
|
59
|
+
expect(@order.amount_in_btc(as: :string)).to eq('0.00000001')
|
60
|
+
end
|
61
|
+
|
56
62
|
describe "assigning statuses" do
|
57
63
|
|
58
64
|
before(:each) do
|
@@ -65,6 +71,11 @@ RSpec.describe Straight::Order do
|
|
65
71
|
@order.status
|
66
72
|
end
|
67
73
|
|
74
|
+
it "sets status to :new upon order creation" do
|
75
|
+
expect(@order.instance_variable_get(:@status)).to eq(0)
|
76
|
+
expect(@order.instance_variable_get(:@old_status)).to eq(nil)
|
77
|
+
end
|
78
|
+
|
68
79
|
it "sets status to :new if no transaction issued" do
|
69
80
|
expect(@order).to receive(:transaction).at_most(3).times.and_return(nil)
|
70
81
|
expect(@order.status(reload: true)).to eq(0)
|
@@ -107,6 +118,11 @@ RSpec.describe Straight::Order do
|
|
107
118
|
expect(@order.instance_variable_get(:@original_status_setter_called)).to be_truthy
|
108
119
|
end
|
109
120
|
|
121
|
+
it "saves the old status in the old_status property" do
|
122
|
+
@order.status = 2
|
123
|
+
expect(@order.old_status).to eq(0)
|
124
|
+
end
|
125
|
+
|
110
126
|
end
|
111
127
|
|
112
128
|
end
|
data/straight.gemspec
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
# stub: straight 0.2.0 ruby lib
|
6
|
+
|
7
|
+
Gem::Specification.new do |s|
|
8
|
+
s.name = "straight"
|
9
|
+
s.version = "0.2.0"
|
10
|
+
|
11
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
12
|
+
s.require_paths = ["lib"]
|
13
|
+
s.authors = ["Roman Snitko"]
|
14
|
+
s.date = "2015-05-05"
|
15
|
+
s.description = "An engine for the Straight payment gateway software. Requires no state to be saved (that is, no storage or DB). Its responsibilities only include processing data coming from an actual gateway."
|
16
|
+
s.email = "roman.snitko@gmail.com"
|
17
|
+
s.extra_rdoc_files = [
|
18
|
+
"LICENSE.txt",
|
19
|
+
"README.md"
|
20
|
+
]
|
21
|
+
s.files = [
|
22
|
+
".document",
|
23
|
+
".rspec",
|
24
|
+
"Gemfile",
|
25
|
+
"Gemfile.lock",
|
26
|
+
"LICENSE.txt",
|
27
|
+
"README.md",
|
28
|
+
"Rakefile",
|
29
|
+
"VERSION",
|
30
|
+
"lib/straight.rb",
|
31
|
+
"lib/straight/blockchain_adapter.rb",
|
32
|
+
"lib/straight/blockchain_adapters/biteasy_adapter.rb",
|
33
|
+
"lib/straight/blockchain_adapters/blockchain_info_adapter.rb",
|
34
|
+
"lib/straight/blockchain_adapters/mycelium_adapter.rb",
|
35
|
+
"lib/straight/exchange_rate_adapter.rb",
|
36
|
+
"lib/straight/exchange_rate_adapters/average_rate_adapter.rb",
|
37
|
+
"lib/straight/exchange_rate_adapters/bitpay_adapter.rb",
|
38
|
+
"lib/straight/exchange_rate_adapters/bitstamp_adapter.rb",
|
39
|
+
"lib/straight/exchange_rate_adapters/btce_adapter.rb",
|
40
|
+
"lib/straight/exchange_rate_adapters/coinbase_adapter.rb",
|
41
|
+
"lib/straight/exchange_rate_adapters/kraken_adapter.rb",
|
42
|
+
"lib/straight/exchange_rate_adapters/localbitcoins_adapter.rb",
|
43
|
+
"lib/straight/exchange_rate_adapters/okcoin_adapter.rb",
|
44
|
+
"lib/straight/gateway.rb",
|
45
|
+
"lib/straight/order.rb",
|
46
|
+
"spec/lib/blockchain_adapters/biteasy_adapter_spec.rb",
|
47
|
+
"spec/lib/blockchain_adapters/blockchain_info_adapter_spec.rb",
|
48
|
+
"spec/lib/blockchain_adapters/mycelium_adapter_spec.rb",
|
49
|
+
"spec/lib/exchange_rate_adapter_spec.rb",
|
50
|
+
"spec/lib/exchange_rate_adapters/average_rate_adapter_spec.rb",
|
51
|
+
"spec/lib/exchange_rate_adapters/bitpay_adapter_spec.rb",
|
52
|
+
"spec/lib/exchange_rate_adapters/bitstamp_adapter_spec.rb",
|
53
|
+
"spec/lib/exchange_rate_adapters/btce_adapter_spec.rb",
|
54
|
+
"spec/lib/exchange_rate_adapters/coinbase_adapter_spec.rb",
|
55
|
+
"spec/lib/exchange_rate_adapters/kraken_adapter_spec.rb",
|
56
|
+
"spec/lib/exchange_rate_adapters/localbitcoins_adapter_spec.rb",
|
57
|
+
"spec/lib/exchange_rate_adapters/okcoin_adapter_spec.rb",
|
58
|
+
"spec/lib/gateway_spec.rb",
|
59
|
+
"spec/lib/order_spec.rb",
|
60
|
+
"spec/spec_helper.rb",
|
61
|
+
"straight.gemspec"
|
62
|
+
]
|
63
|
+
s.homepage = "http://github.com/snitko/straight"
|
64
|
+
s.licenses = ["MIT"]
|
65
|
+
s.rubygems_version = "2.4.5"
|
66
|
+
s.summary = "An engine for the Straight payment gateway software"
|
67
|
+
|
68
|
+
if s.respond_to? :specification_version then
|
69
|
+
s.specification_version = 4
|
70
|
+
|
71
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
72
|
+
s.add_runtime_dependency(%q<money-tree>, [">= 0"])
|
73
|
+
s.add_runtime_dependency(%q<satoshi-unit>, [">= 0"])
|
74
|
+
s.add_runtime_dependency(%q<httparty>, [">= 0"])
|
75
|
+
s.add_development_dependency(%q<bundler>, ["~> 1.0"])
|
76
|
+
s.add_development_dependency(%q<jeweler>, ["~> 2.0.1"])
|
77
|
+
s.add_development_dependency(%q<github_api>, ["= 0.11.3"])
|
78
|
+
else
|
79
|
+
s.add_dependency(%q<money-tree>, [">= 0"])
|
80
|
+
s.add_dependency(%q<satoshi-unit>, [">= 0"])
|
81
|
+
s.add_dependency(%q<httparty>, [">= 0"])
|
82
|
+
s.add_dependency(%q<bundler>, ["~> 1.0"])
|
83
|
+
s.add_dependency(%q<jeweler>, ["~> 2.0.1"])
|
84
|
+
s.add_dependency(%q<github_api>, ["= 0.11.3"])
|
85
|
+
end
|
86
|
+
else
|
87
|
+
s.add_dependency(%q<money-tree>, [">= 0"])
|
88
|
+
s.add_dependency(%q<satoshi-unit>, [">= 0"])
|
89
|
+
s.add_dependency(%q<httparty>, [">= 0"])
|
90
|
+
s.add_dependency(%q<bundler>, ["~> 1.0"])
|
91
|
+
s.add_dependency(%q<jeweler>, ["~> 2.0.1"])
|
92
|
+
s.add_dependency(%q<github_api>, ["= 0.11.3"])
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|