oanda_api_v20 1.5.0 → 2.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.
@@ -3,62 +3,81 @@ require 'spec_helper'
3
3
  describe OandaApiV20::Client do
4
4
  describe '#initialize' do
5
5
  it 'sets the access_token attribute when supplied' do
6
- c = OandaApiV20::Client.new(access_token: 'my_access_token')
7
- expect(c.access_token).to eq('my_access_token')
6
+ client = OandaApiV20::Client.new(access_token: 'my_access_token')
7
+ expect(client.access_token).to eq('my_access_token')
8
+ end
9
+
10
+ it 'sets the connection_pool_size attribute when supplied' do
11
+ client = OandaApiV20::Client.new(connection_pool_size: 5)
12
+ expect(client.connection_pool_size).to eq(5)
13
+ end
14
+
15
+ it 'sets the connection_pool_size attribute to the default value of 2 when not supplied' do
16
+ client = OandaApiV20::Client.new
17
+ expect(client.connection_pool_size).to eq(2)
18
+ end
19
+
20
+ it 'sets the max_requests_per_second attribute when supplied' do
21
+ client = OandaApiV20::Client.new(max_requests_per_second: 10)
22
+ expect(client.max_requests_per_second).to eq(10)
23
+ end
24
+
25
+ it 'sets the max_requests_per_second attribute to the default value of 100 when not supplied' do
26
+ client = OandaApiV20::Client.new
27
+ expect(client.max_requests_per_second).to eq(100)
8
28
  end
9
29
 
10
30
  it 'sets the proxy_url attribute when supplied' do
11
- c = OandaApiV20::Client.new(proxy_url: 'https://user:pass@proxy.com:80')
12
- expect(c.proxy_url).to eq('https://user:pass@proxy.com:80')
31
+ client = OandaApiV20::Client.new(proxy_url: 'https://user:pass@proxy.com:80')
32
+ expect(client.proxy_url).to eq('https://user:pass@proxy.com:80')
13
33
  end
14
34
 
15
35
  it 'sets the base_uri to practice when the practice option was supplied and set to true' do
16
- c = OandaApiV20::Client.new(practice: true)
17
- expect(c.base_uri).to eq('https://api-fxpractice.oanda.com/v3')
36
+ client = OandaApiV20::Client.new(practice: true)
37
+ expect(client.base_uri).to eq('https://api-fxpractice.oanda.com/v3')
18
38
  end
19
39
 
20
40
  it 'sets the base_uri to live when the practice option was supplied and set to false' do
21
- c = OandaApiV20::Client.new(practice: false)
22
- expect(c.base_uri).to eq('https://api-fxtrade.oanda.com/v3')
41
+ client = OandaApiV20::Client.new(practice: false)
42
+ expect(client.base_uri).to eq('https://api-fxtrade.oanda.com/v3')
23
43
  end
24
44
 
25
45
  it 'sets the base_uri to live when the practice option was not supplied' do
26
- c = OandaApiV20::Client.new
27
- expect(c.base_uri).to eq('https://api-fxtrade.oanda.com/v3')
46
+ client = OandaApiV20::Client.new
47
+ expect(client.base_uri).to eq('https://api-fxtrade.oanda.com/v3')
28
48
  end
29
49
 
30
50
  it 'set the headers attribute to a hash' do
31
- c = OandaApiV20::Client.new
32
- expect(c.send(:headers)).to be_an_instance_of(Hash)
51
+ client = OandaApiV20::Client.new
52
+ expect(client.send(:headers)).to be_an_instance_of(Hash)
33
53
  end
34
54
  end
35
55
 
36
56
  describe '#method_missing' do
37
- let!(:c) { OandaApiV20::Client.new(access_token: 'my_access_token') }
57
+ let!(:client) { OandaApiV20::Client.new(access_token: 'my_access_token') }
38
58
 
39
- context 'when an OandaApiV20::Api method has been called' do
40
- it 'saves the method called' do
41
- c.accounts
42
- expect(c.send(:last_action)).to eq(:accounts)
43
- end
59
+ it 'returns an OandaApiV20::Api instance when an API method has been called' do
60
+ expect(client.accounts).to be_an_instance_of(OandaApiV20::Api)
61
+ end
44
62
 
45
- it 'saves the attributes supplied' do
46
- c.account('100-100-100')
47
- expect(c.send(:last_action)).to eq(:account)
48
- expect(c.send(:last_arguments)).to eq(['100-100-100'])
49
- end
63
+ it 'sets the OandaApiV20::Api account_id attribute when method account was called' do
64
+ expect(client.account('100-100-100').account_id).to eq('100-100-100')
65
+ end
50
66
 
51
- it 'saves the account ID when calling the account method' do
52
- c.account('100-100-100')
53
- expect(c.send(:account_id)).to eq('100-100-100')
54
- end
67
+ it 'sets the OandaApiV20::Api intrument variable when method instrument was called' do
68
+ instrument = 'EUR_USD'
69
+ expect(client.instrument(instrument).instance_variable_get(:@instrument)).to eq(instrument)
70
+ end
55
71
 
56
- it 'returns a OandaApiV20::Client instance' do
57
- expect(c.account('100-100-100')).to be_an_instance_of(OandaApiV20::Client)
58
- end
72
+ it 'raises a NoMethodError exception when a method other than an OandaApiV20::Api method has been called' do
73
+ expect{ client.this_method_definitely_does_not_exist }.to raise_error(NoMethodError)
59
74
  end
60
75
 
61
- context 'when an action method has been called' do
76
+ it 'raises a NoMethodError exception when a method other than an OandaApiV20::Api action method has been called' do
77
+ expect{ client.accounts.show_me_the_money }.to raise_error(NoMethodError)
78
+ end
79
+
80
+ context 'network' do
62
81
  let(:response_account) { '{"account":{"id":"100-100-100","NAV":"100000.0000","balance":"100000.0000","lastTransactionID":"99","orders":[],"positions":[],"trades":[],"pendingOrderCount":0},"lastTransactionID":"99"}' }
63
82
  let!(:request_account) { stub_request(:get, 'https://api-fxtrade.oanda.com/v3/accounts/100-100-100').to_return(status: 200, body: response_account, headers: {}) }
64
83
 
@@ -66,121 +85,93 @@ describe OandaApiV20::Client do
66
85
  let!(:request_accounts) { stub_request(:get, 'https://api-fxtrade.oanda.com/v3/accounts').to_return(status: 200, body: response_accounts, headers: {}) }
67
86
 
68
87
  before(:each) do
69
- allow(c).to receive(:sleep)
88
+ allow(client).to receive(:sleep)
70
89
  end
71
90
 
72
- describe 'network' do
73
- it 'makes a request to Oanda API' do
74
- c.accounts.show
75
- expect(request_accounts).to have_been_requested
76
- expect(request_accounts).to have_been_requested.at_most_once
77
- end
78
-
79
- it 'returns the response from Oanda API' do
80
- expect(c.accounts.show).to eq(JSON.parse(response_accounts))
81
- expect(c.account('100-100-100').show).to eq(JSON.parse(response_account))
82
- end
83
- end
84
-
85
- describe 'attributes' do
86
- it 'sets the equivalent HTTP verb' do
87
- c.accounts.show
88
- expect(c.send(:http_verb)).to eq(:get)
89
- end
90
-
91
- it 'sets the current account ID' do
92
- c.account('100-100-100').show
93
- expect(c.send(:account_id)).to eq('100-100-100')
94
- end
95
-
96
- it 'sets the last transaction ID when returned' do
97
- c.account('100-100-100').show
98
- expect(c.send(:last_transaction_id)).to eq('99')
99
- end
100
-
101
- it 'sets the last request made at time' do
102
- expect(c.send(:last_api_request_at).last).to be_nil
103
- c.accounts.show
104
- expect(c.send(:last_api_request_at).last).to_not be_nil
105
- expect(Time.parse(c.send(:last_api_request_at).last.to_s)).to be_an_instance_of(Time)
106
- end
91
+ it 'raises an OandaApiV20::RequestError exception when receiving anything other than a 2xx response from Oanda API' do
92
+ stub_request(:get, 'https://api-fxtrade.oanda.com/v3/accounts/100-100-109').to_return(status: 401, body: '', headers: {})
93
+ expect{ client.account('100-100-109').show }.to raise_error(OandaApiV20::RequestError)
107
94
  end
108
95
 
109
96
  describe 'headers' do
110
97
  it 'sets authentication header' do
111
- c.accounts.show
98
+ client.accounts.show
112
99
  expect(a_request(:get, 'https://api-fxtrade.oanda.com/v3/accounts').with(headers: { 'Authorization' => 'Bearer my_access_token' })).to have_been_made.once
113
100
  end
114
101
 
115
102
  it 'sets content type header to json' do
116
- c.accounts.show
103
+ client.accounts.show
117
104
  expect(a_request(:get, 'https://api-fxtrade.oanda.com/v3/accounts').with(headers: { 'Content-Type' => 'application/json' })).to have_been_made.once
118
105
  end
119
106
 
120
107
  it 'sets date time format header to RFC3339' do
121
- c.accounts.show
108
+ client.accounts.show
122
109
  expect(a_request(:get, 'https://api-fxtrade.oanda.com/v3/accounts').with(headers: { 'X-Accept-Datetime-Format' => 'RFC3339' })).to have_been_made.once
123
110
  end
124
111
 
125
112
  it 'sets persisten connection header' do
126
- c.accounts.show
113
+ client.accounts.show
127
114
  expect(a_request(:get, 'https://api-fxtrade.oanda.com/v3/accounts').with(headers: { 'Connection' => 'keep-alive' })).to have_been_made.once
128
115
  end
129
116
  end
117
+ end
118
+ end
130
119
 
131
- describe 'exceptions' do
132
- it 'raises an OandaApiV20::RequestError exception when receiving anything other than a 2xx response from Oanda API' do
133
- stub_request(:get, 'https://api-fxtrade.oanda.com/v3/accounts/100-100-109').to_return(status: 401, body: '', headers: {})
134
- expect{ c.account('100-100-109').show }.to raise_error(OandaApiV20::RequestError)
135
- end
136
- end
120
+ describe 'public methods' do
121
+ let!(:client) { OandaApiV20::Client.new(access_token: 'my_access_token') }
137
122
 
138
- describe 'governing request rate' do
139
- before(:each) do
140
- Timecop.freeze(Time.local('2016-08-01 06:00:00'))
141
- end
123
+ let(:response_account) { '{"account":{"id":"100-100-100","NAV":"100000.0000","balance":"100000.0000","lastTransactionID":"99","orders":[],"positions":[],"trades":[],"pendingOrderCount":0},"lastTransactionID":"99"}' }
124
+ let!(:request_account) { stub_request(:get, 'https://api-fxtrade.oanda.com/v3/accounts/100-100-100').to_return(status: 200, body: response_account, headers: {}) }
142
125
 
143
- after(:each) do
144
- Timecop.return
145
- end
126
+ let(:response_accounts) { '{"accounts":[{"id":"100-100-100","tags":[]}]}' }
127
+ let!(:request_accounts) { stub_request(:get, 'https://api-fxtrade.oanda.com/v3/accounts').to_return(status: 200, body: response_accounts, headers: {}) }
146
128
 
147
- it 'is not allowed to make 30 requests or more per second' do
148
- expect(c).to receive(:sleep).at_least(:twice)
149
- 30.times { c.accounts.show }
150
- Timecop.freeze('2016-08-01 06:00:01')
151
- 30.times { c.accounts.show }
152
- end
129
+ before(:each) do
130
+ allow(client).to receive(:sleep)
131
+ end
153
132
 
154
- it 'is allowed to make less than 30 requests per second' do
155
- expect(c).to_not receive(:sleep)
156
- 29.times { c.accounts.show }
157
- Timecop.freeze('2016-08-01 06:00:01')
158
- 29.times { c.accounts.show }
159
- Timecop.freeze('2016-08-01 06:00:02')
160
- 29.times { c.accounts.show }
161
- end
133
+ describe '#govern_api_request_rate' do
134
+ before(:each) do
135
+ Timecop.freeze(Time.local('2016-08-01 06:00:00'))
136
+ end
162
137
 
163
- it 'halts all API requests for the remainder of the second when 30 requests have been made in one second' do
164
- expect(c).to receive(:sleep).with(0.7)
165
- Timecop.freeze('2016-08-01 06:00:00.0')
166
- 10.times { c.accounts.show }
167
- Timecop.freeze('2016-08-01 06:00:00.1')
168
- 10.times { c.accounts.show }
169
- Timecop.freeze('2016-08-01 06:00:00.3')
170
- 10.times { c.accounts.show }
171
- end
138
+ after(:each) do
139
+ Timecop.return
140
+ end
141
+
142
+ it 'is not allowed to make 100 requests or more per second' do
143
+ expect(client).to receive(:sleep).at_least(:twice)
144
+ 100.times { client.accounts.show }
145
+ Timecop.freeze('2016-08-01 06:00:01')
146
+ 100.times { client.accounts.show }
147
+ end
148
+
149
+ it 'is allowed to make less than 100 requests per second' do
150
+ expect(client).to_not receive(:sleep)
151
+ 99.times { client.accounts.show }
152
+ Timecop.freeze('2016-08-01 06:00:01')
153
+ 99.times { client.accounts.show }
154
+ Timecop.freeze('2016-08-01 06:00:02')
155
+ 99.times { client.accounts.show }
172
156
  end
173
- end
174
157
 
175
- context 'when a method other than an OandaApiV20::Api method has been called' do
176
- it 'throws a NoMethodError exception' do
177
- expect{ c.accounts.show_me_the_money }.to raise_error(NoMethodError)
158
+ it 'halts all API requests for the remainder of the second when 100 requests have been made in one second' do
159
+ expect(client).to receive(:sleep).with(0.7)
160
+ Timecop.freeze('2016-08-01 06:00:00.0')
161
+ 30.times { client.accounts.show }
162
+ Timecop.freeze('2016-08-01 06:00:00.1')
163
+ 30.times { client.accounts.show }
164
+ Timecop.freeze('2016-08-01 06:00:00.3')
165
+ 40.times { client.accounts.show }
178
166
  end
179
167
  end
180
168
 
181
- context 'when a method other than an action method has been called' do
182
- it 'throws a NoMethodError exception' do
183
- expect{ c.this_method_definitely_does_not_exist }.to raise_error(NoMethodError)
169
+ describe '#update_last_api_request_at' do
170
+ it 'sets the time of the last request made' do
171
+ expect(client.send(:last_api_request_at).last).to be_nil
172
+ client.accounts.show
173
+ expect(client.send(:last_api_request_at).last).to_not be_nil
174
+ expect(Time.parse(client.send(:last_api_request_at).last.to_s)).to be_an_instance_of(Time)
184
175
  end
185
176
  end
186
177
  end
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+
3
+ describe OandaApiV20::RequestError do
4
+ describe '#initialize' do
5
+ let(:response) { { code: 200, body: '' } }
6
+
7
+ it 'sets the message attribute' do
8
+ exception = OandaApiV20::RequestError.new('An error as occured while processing response.')
9
+ expect(exception.message).to eq('An error as occured while processing response.')
10
+ end
11
+
12
+ it 'sets the response attribute when supplied' do
13
+ exception = OandaApiV20::RequestError.new('An error as occured while processing response.', response: response)
14
+ expect(exception.response).to eq(response)
15
+ end
16
+
17
+ it 'sets the original_exception attribue when supplied' do
18
+ original_exception = OpenSSL::SSL::SSLError.new('SSL_read: sslv3 alert handshake failure')
19
+ exception = OandaApiV20::RequestError.new('An error as occured while processing response.', original_exception: original_exception)
20
+ expect(exception.original_exception).to be_an_instance_of(OpenSSL::SSL::SSLError)
21
+ expect(exception.original_exception.message).to eq('SSL_read: sslv3 alert handshake failure')
22
+ end
23
+ end
24
+ end
@@ -3,8 +3,8 @@ require 'spec_helper'
3
3
  describe OandaApiV20 do
4
4
  describe '.new' do
5
5
  it 'instantiates a new OandaApiV20::Client' do
6
- c = OandaApiV20.new
7
- expect(c).to be_an_instance_of(OandaApiV20::Client)
6
+ client = OandaApiV20.new
7
+ expect(client).to be_an_instance_of(OandaApiV20::Client)
8
8
  end
9
9
  end
10
10
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: oanda_api_v20
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.0
4
+ version: 2.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kobus Joubert
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-07-07 00:00:00.000000000 Z
11
+ date: 2021-08-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: httparty
@@ -98,16 +98,16 @@ dependencies:
98
98
  name: rake
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
- - - ">="
101
+ - - "~>"
102
102
  - !ruby/object:Gem::Version
103
- version: '0'
103
+ version: '13.0'
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
- - - ">="
108
+ - - "~>"
109
109
  - !ruby/object:Gem::Version
110
- version: '0'
110
+ version: '13.0'
111
111
  description: Ruby client that supports the Oanda REST API V20 methods.
112
112
  email: kobus@translate3d.com
113
113
  executables: []
@@ -139,6 +139,7 @@ files:
139
139
  - oanda_api_v20.gemspec
140
140
  - spec/oanda_api_v20/api_spec.rb
141
141
  - spec/oanda_api_v20/client_spec.rb
142
+ - spec/oanda_api_v20/exceptions_spec.rb
142
143
  - spec/oanda_api_v20/oanda_api_v20_spec.rb
143
144
  - spec/spec_helper.rb
144
145
  homepage: http://rubygems.org/gems/oanda_api_v20
@@ -160,13 +161,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
160
161
  - !ruby/object:Gem::Version
161
162
  version: '0'
162
163
  requirements: []
163
- rubyforge_project:
164
- rubygems_version: 2.5.1
164
+ rubygems_version: 3.1.4
165
165
  signing_key:
166
166
  specification_version: 4
167
167
  summary: Ruby Oanda REST API V20
168
168
  test_files:
169
169
  - spec/oanda_api_v20/api_spec.rb
170
170
  - spec/oanda_api_v20/client_spec.rb
171
+ - spec/oanda_api_v20/exceptions_spec.rb
171
172
  - spec/oanda_api_v20/oanda_api_v20_spec.rb
172
173
  - spec/spec_helper.rb