snaptrade 3.0.13 → 3.0.15
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/README.md +5 -5
- data/lib/snaptrade/api/account_information_api.rb +6 -6
- data/lib/snaptrade/api/connections_api.rb +4 -4
- data/lib/snaptrade/api_client_custom.rb +1 -1
- data/lib/snaptrade/models/account_position.rb +1 -1
- data/lib/snaptrade/models/brokerage_authorization.rb +1 -2
- data/lib/snaptrade/models/{line_of_credit_account_credit_details.rb → brokerage_authorization_data_freshness_mode.rb} +30 -12
- data/lib/snaptrade/models/deposit_account.rb +10 -10
- data/lib/snaptrade/models/institution.rb +37 -0
- data/lib/snaptrade/models/instrument.rb +1 -0
- data/lib/snaptrade/models/investment_account.rb +10 -10
- data/lib/snaptrade/models/line_of_credit_account.rb +17 -17
- data/lib/snaptrade/models/{line_of_credit_account_credit_details_minimum_payment_amount.rb → line_of_credit_account_minimum_payment_amount.rb} +4 -4
- data/lib/snaptrade/models/other_instrument.rb +1 -1
- data/lib/snaptrade/models/other_instrument_kind.rb +2 -1
- data/lib/snaptrade/models/snaptrade.rb +37 -0
- data/lib/snaptrade/models/underlying_cfd_instrument.rb +1 -0
- data/lib/snaptrade/models/underlying_option_instrument.rb +1 -0
- data/lib/snaptrade/version.rb +1 -1
- data/lib/snaptrade.rb +4 -2
- data/spec/api/account_information_api_spec.rb +1 -1
- data/spec/api/connections_api_spec.rb +1 -1
- data/spec/models/brokerage_authorization_data_freshness_mode_spec.rb +35 -0
- data/spec/models/connection_account_spec.rb +1 -1
- data/spec/models/deposit_account_spec.rb +1 -1
- data/spec/models/institution_spec.rb +23 -0
- data/spec/models/instrument_spec.rb +1 -1
- data/spec/models/investment_account_spec.rb +1 -1
- data/spec/models/{line_of_credit_account_credit_details_minimum_payment_amount_spec.rb → line_of_credit_account_minimum_payment_amount_spec.rb} +6 -6
- data/spec/models/line_of_credit_account_spec.rb +2 -2
- data/spec/models/snaptrade_spec.rb +23 -0
- data/spec/models/underlying_cfd_instrument_spec.rb +1 -1
- data/spec/models/underlying_option_instrument_spec.rb +1 -1
- data/spec/regression/all_account_positions_spec.rb +86 -0
- data/spec/regression/fixtures/all_account_positions.json +33 -0
- data/spec/regression/request_signing_spec.rb +46 -0
- metadata +228 -217
- data/Gemfile.lock +0 -91
- data/spec/models/line_of_credit_account_credit_details_spec.rb +0 -29
|
@@ -11,8 +11,8 @@ require 'date'
|
|
|
11
11
|
require 'time'
|
|
12
12
|
|
|
13
13
|
module SnapTrade
|
|
14
|
-
# The minimum payment due on the account's next statement.
|
|
15
|
-
class
|
|
14
|
+
# The minimum payment due on the account's next statement. Omitted when no such data is available.
|
|
15
|
+
class LineOfCreditAccountMinimumPaymentAmount
|
|
16
16
|
attr_accessor :amount
|
|
17
17
|
|
|
18
18
|
attr_accessor :currency
|
|
@@ -50,13 +50,13 @@ module SnapTrade
|
|
|
50
50
|
# @param [Hash] attributes Model attributes in the form of hash
|
|
51
51
|
def initialize(attributes = {})
|
|
52
52
|
if (!attributes.is_a?(Hash))
|
|
53
|
-
fail ArgumentError, "The input argument (attributes) must be a hash in `SnapTrade::
|
|
53
|
+
fail ArgumentError, "The input argument (attributes) must be a hash in `SnapTrade::LineOfCreditAccountMinimumPaymentAmount` initialize method"
|
|
54
54
|
end
|
|
55
55
|
|
|
56
56
|
# check to see if the attribute exists and convert string to symbol for hash key
|
|
57
57
|
attributes = attributes.each_with_object({}) { |(k, v), h|
|
|
58
58
|
if (!self.class.attribute_map.key?(k.to_sym))
|
|
59
|
-
fail ArgumentError, "`#{k}` is not a valid attribute in `SnapTrade::
|
|
59
|
+
fail ArgumentError, "`#{k}` is not a valid attribute in `SnapTrade::LineOfCreditAccountMinimumPaymentAmount`. Please check the name to make sure it's valid. List of attributes: " + self.class.attribute_map.keys.inspect
|
|
60
60
|
end
|
|
61
61
|
h[k.to_sym] = v
|
|
62
62
|
}
|
|
@@ -11,7 +11,7 @@ require 'date'
|
|
|
11
11
|
require 'time'
|
|
12
12
|
|
|
13
13
|
module SnapTrade
|
|
14
|
-
# Security instrument metadata for other mapped security positions.
|
|
14
|
+
# Security instrument metadata for bonds and other mapped security positions.
|
|
15
15
|
class OtherInstrument
|
|
16
16
|
# Type of security instrument.
|
|
17
17
|
attr_accessor :kind
|
|
@@ -12,10 +12,11 @@ require 'time'
|
|
|
12
12
|
|
|
13
13
|
module SnapTrade
|
|
14
14
|
class OtherInstrumentKind
|
|
15
|
+
BOND = "bond".freeze
|
|
15
16
|
OTHER = "other".freeze
|
|
16
17
|
|
|
17
18
|
def self.all_vars
|
|
18
|
-
@all_vars ||= [OTHER].freeze
|
|
19
|
+
@all_vars ||= [BOND, OTHER].freeze
|
|
19
20
|
end
|
|
20
21
|
|
|
21
22
|
# Builds the enum from string
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
=begin
|
|
2
|
+
#SnapTrade
|
|
3
|
+
|
|
4
|
+
#Connect brokerage accounts to your app for live positions and trading
|
|
5
|
+
|
|
6
|
+
The version of the OpenAPI document: 1.0.0
|
|
7
|
+
Contact: api@snaptrade.com
|
|
8
|
+
=end
|
|
9
|
+
|
|
10
|
+
require 'date'
|
|
11
|
+
require 'time'
|
|
12
|
+
|
|
13
|
+
module SnapTrade
|
|
14
|
+
class Snaptrade
|
|
15
|
+
REALTIME = "realtime".freeze
|
|
16
|
+
DELAYED = "delayed".freeze
|
|
17
|
+
|
|
18
|
+
def self.all_vars
|
|
19
|
+
@all_vars ||= [REALTIME, DELAYED].freeze
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Builds the enum from string
|
|
23
|
+
# @param [String] The enum value in the form of the string
|
|
24
|
+
# @return [String] The enum value
|
|
25
|
+
def self.build_from_hash(value)
|
|
26
|
+
new.build_from_hash(value)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Builds the enum from string
|
|
30
|
+
# @param [String] The enum value in the form of the string
|
|
31
|
+
# @return [String] The enum value
|
|
32
|
+
def build_from_hash(value)
|
|
33
|
+
return value if Snaptrade.all_vars.include?(value)
|
|
34
|
+
raise "Invalid ENUM value #{value} for class #Snaptrade"
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
data/lib/snaptrade/version.rb
CHANGED
data/lib/snaptrade.rb
CHANGED
|
@@ -60,6 +60,7 @@ require 'snaptrade/models/balance'
|
|
|
60
60
|
require 'snaptrade/models/balance_currency'
|
|
61
61
|
require 'snaptrade/models/brokerage'
|
|
62
62
|
require 'snaptrade/models/brokerage_authorization'
|
|
63
|
+
require 'snaptrade/models/brokerage_authorization_data_freshness_mode'
|
|
63
64
|
require 'snaptrade/models/brokerage_authorization_disabled_confirmation'
|
|
64
65
|
require 'snaptrade/models/brokerage_authorization_refresh_confirmation'
|
|
65
66
|
require 'snaptrade/models/brokerage_authorization_transactions_sync_confirmation'
|
|
@@ -113,14 +114,14 @@ require 'snaptrade/models/figi_instrument'
|
|
|
113
114
|
require 'snaptrade/models/future_instrument'
|
|
114
115
|
require 'snaptrade/models/future_instrument_kind'
|
|
115
116
|
require 'snaptrade/models/holdings_status'
|
|
117
|
+
require 'snaptrade/models/institution'
|
|
116
118
|
require 'snaptrade/models/instrument'
|
|
117
119
|
require 'snaptrade/models/investment_account'
|
|
118
120
|
require 'snaptrade/models/investment_account_net_value'
|
|
119
121
|
require 'snaptrade/models/kind'
|
|
120
122
|
require 'snaptrade/models/line_of_credit_account'
|
|
121
|
-
require 'snaptrade/models/line_of_credit_account_credit_details'
|
|
122
|
-
require 'snaptrade/models/line_of_credit_account_credit_details_minimum_payment_amount'
|
|
123
123
|
require 'snaptrade/models/line_of_credit_account_kind'
|
|
124
|
+
require 'snaptrade/models/line_of_credit_account_minimum_payment_amount'
|
|
124
125
|
require 'snaptrade/models/line_of_credit_account_net_value'
|
|
125
126
|
require 'snaptrade/models/line_of_credit_account_sync_status'
|
|
126
127
|
require 'snaptrade/models/login_redirect_uri'
|
|
@@ -211,6 +212,7 @@ require 'snaptrade/models/snap_trade_holdings_account'
|
|
|
211
212
|
require 'snaptrade/models/snap_trade_holdings_total_value'
|
|
212
213
|
require 'snaptrade/models/snap_trade_login_user_request_body'
|
|
213
214
|
require 'snaptrade/models/snap_trade_register_user_request_body'
|
|
215
|
+
require 'snaptrade/models/snaptrade'
|
|
214
216
|
require 'snaptrade/models/status'
|
|
215
217
|
require 'snaptrade/models/stock_instrument'
|
|
216
218
|
require 'snaptrade/models/stock_instrument_figi_instrument'
|
|
@@ -62,7 +62,7 @@ describe 'AccountInformationApi' do
|
|
|
62
62
|
|
|
63
63
|
# unit tests for get_all_account_positions
|
|
64
64
|
# List all account positions
|
|
65
|
-
# Returns a list of all positions in the specified account. The `results` list can contain multiple instrument types in the same response, including stocks, ADRs, ETFs, mutual funds, closed-end funds, crypto, futures, option positions, and CFD positions. Use the `instrument.kind` discriminator to determine the schema for each position's `instrument`.
|
|
65
|
+
# Returns a list of all positions in the specified account. The `results` list can contain multiple instrument types in the same response, including stocks, ADRs, ETFs, mutual funds, closed-end funds, bonds, crypto, futures, option positions, and CFD positions. Use the `instrument.kind` discriminator to determine the schema for each position's `instrument`. Positions counted in account cash balance or buying power include `cash_equivalent: true`. `stock`, `adr`, `etf`, `mutualfund`, and `crypto` positions may include `tax_lots` when tax lot data is enabled for the account. To see which institutions support tax lot data, please see our [supported institutions doc](https://support.snaptrade.com/brokerages). If the connection has become disabled, it can no longer access the latest data from the brokerage, but will continue to return the last available cached state. Please see [this guide](/docs/fix-broken-connections) on how to fix a disabled connection.
|
|
66
66
|
# @param user_id
|
|
67
67
|
# @param user_secret
|
|
68
68
|
# @param account_id
|
|
@@ -98,7 +98,7 @@ describe 'ConnectionsApi' do
|
|
|
98
98
|
|
|
99
99
|
# unit tests for refresh_brokerage_authorization
|
|
100
100
|
# Refresh holdings for a connection
|
|
101
|
-
# Trigger a holdings update for all accounts under this connection. Updates will be queued asynchronously. [`ACCOUNT_HOLDINGS_UPDATED` webhook](/docs/webhooks#webhooks-account_holdings_updated) will be sent once the sync completes for each account under the connection. This endpoint will also trigger a transaction sync for the past day if one has not yet occurred. **Because of the cost of refreshing a connection, each call to this endpoint incurs an additional charge. You can find the exact cost for your API key on the [Customer Dashboard billing page](https://dashboard.snaptrade.com/settings/billing)** **Please note this endpoint is disabled for Real-time plans (Personal and Pay as you go) unless the connection
|
|
101
|
+
# Trigger a holdings update for all accounts under this connection. Updates will be queued asynchronously. [`ACCOUNT_HOLDINGS_UPDATED` webhook](/docs/webhooks#webhooks-account_holdings_updated) will be sent once the sync completes for each account under the connection. This endpoint will also trigger a transaction sync for the past day if one has not yet occurred. **Because of the cost of refreshing a connection, each call to this endpoint incurs an additional charge. You can find the exact cost for your API key on the [Customer Dashboard billing page](https://dashboard.snaptrade.com/settings/billing)** **Please note this endpoint is disabled for Real-time plans (Personal and Pay as you go) unless SnapTrade uses delayed data for the connection. Real-time connections do not benefit from this feature since data is refreshed when calls are made. Refer to `data_freshness_mode.snaptrade` on a connection to determine this.**
|
|
102
102
|
# @param authorization_id
|
|
103
103
|
# @param user_id
|
|
104
104
|
# @param user_secret
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
=begin
|
|
2
|
+
#SnapTrade
|
|
3
|
+
|
|
4
|
+
#Connect brokerage accounts to your app for live positions and trading
|
|
5
|
+
|
|
6
|
+
The version of the OpenAPI document: 1.0.0
|
|
7
|
+
Contact: api@snaptrade.com
|
|
8
|
+
=end
|
|
9
|
+
|
|
10
|
+
require 'spec_helper'
|
|
11
|
+
require 'json'
|
|
12
|
+
require 'date'
|
|
13
|
+
|
|
14
|
+
# Unit tests for SnapTrade::BrokerageAuthorizationDataFreshnessMode
|
|
15
|
+
describe SnapTrade::BrokerageAuthorizationDataFreshnessMode do
|
|
16
|
+
let(:instance) { SnapTrade::BrokerageAuthorizationDataFreshnessMode.new }
|
|
17
|
+
|
|
18
|
+
describe 'test an instance of BrokerageAuthorizationDataFreshnessMode' do
|
|
19
|
+
it 'should create an instance of BrokerageAuthorizationDataFreshnessMode' do
|
|
20
|
+
expect(instance).to be_instance_of(SnapTrade::BrokerageAuthorizationDataFreshnessMode)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
describe 'test attribute "institution"' do
|
|
24
|
+
it 'should work' do
|
|
25
|
+
# assertion here. ref: https://www.relishapp.com/rspec/rspec-expectations/docs/built-in-matchers
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
describe 'test attribute "snaptrade"' do
|
|
30
|
+
it 'should work' do
|
|
31
|
+
# assertion here. ref: https://www.relishapp.com/rspec/rspec-expectations/docs/built-in-matchers
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
end
|
|
@@ -27,7 +27,7 @@ describe SnapTrade::ConnectionAccount do
|
|
|
27
27
|
|
|
28
28
|
describe '.openapi_discriminator_mapping' do
|
|
29
29
|
it 'returns the key/values of the "mapping" property' do
|
|
30
|
-
expect(described_class.openapi_discriminator_mapping.values.sort).to eq(described_class.openapi_one_of.sort)
|
|
30
|
+
expect(described_class.openapi_discriminator_mapping.values.uniq.sort).to eq(described_class.openapi_one_of.sort)
|
|
31
31
|
end
|
|
32
32
|
end
|
|
33
33
|
|
|
@@ -44,7 +44,7 @@ describe SnapTrade::DepositAccount do
|
|
|
44
44
|
end
|
|
45
45
|
end
|
|
46
46
|
|
|
47
|
-
describe 'test attribute "
|
|
47
|
+
describe 'test attribute "masked_account_number"' do
|
|
48
48
|
it 'should work' do
|
|
49
49
|
# assertion here. ref: https://www.relishapp.com/rspec/rspec-expectations/docs/built-in-matchers
|
|
50
50
|
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
=begin
|
|
2
|
+
#SnapTrade
|
|
3
|
+
|
|
4
|
+
#Connect brokerage accounts to your app for live positions and trading
|
|
5
|
+
|
|
6
|
+
The version of the OpenAPI document: 1.0.0
|
|
7
|
+
Contact: api@snaptrade.com
|
|
8
|
+
=end
|
|
9
|
+
|
|
10
|
+
require 'spec_helper'
|
|
11
|
+
require 'json'
|
|
12
|
+
require 'date'
|
|
13
|
+
|
|
14
|
+
# Unit tests for SnapTrade::Institution
|
|
15
|
+
describe SnapTrade::Institution do
|
|
16
|
+
let(:instance) { SnapTrade::Institution.new }
|
|
17
|
+
|
|
18
|
+
describe 'test an instance of Institution' do
|
|
19
|
+
it 'should create an instance of Institution' do
|
|
20
|
+
expect(instance).to be_instance_of(SnapTrade::Institution)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -27,7 +27,7 @@ describe SnapTrade::Instrument do
|
|
|
27
27
|
|
|
28
28
|
describe '.openapi_discriminator_mapping' do
|
|
29
29
|
it 'returns the key/values of the "mapping" property' do
|
|
30
|
-
expect(described_class.openapi_discriminator_mapping.values.sort).to eq(described_class.openapi_one_of.sort)
|
|
30
|
+
expect(described_class.openapi_discriminator_mapping.values.uniq.sort).to eq(described_class.openapi_one_of.sort)
|
|
31
31
|
end
|
|
32
32
|
end
|
|
33
33
|
|
|
@@ -44,7 +44,7 @@ describe SnapTrade::InvestmentAccount do
|
|
|
44
44
|
end
|
|
45
45
|
end
|
|
46
46
|
|
|
47
|
-
describe 'test attribute "
|
|
47
|
+
describe 'test attribute "masked_account_number"' do
|
|
48
48
|
it 'should work' do
|
|
49
49
|
# assertion here. ref: https://www.relishapp.com/rspec/rspec-expectations/docs/built-in-matchers
|
|
50
50
|
end
|
|
@@ -11,13 +11,13 @@ require 'spec_helper'
|
|
|
11
11
|
require 'json'
|
|
12
12
|
require 'date'
|
|
13
13
|
|
|
14
|
-
# Unit tests for SnapTrade::
|
|
15
|
-
describe SnapTrade::
|
|
16
|
-
let(:instance) { SnapTrade::
|
|
14
|
+
# Unit tests for SnapTrade::LineOfCreditAccountMinimumPaymentAmount
|
|
15
|
+
describe SnapTrade::LineOfCreditAccountMinimumPaymentAmount do
|
|
16
|
+
let(:instance) { SnapTrade::LineOfCreditAccountMinimumPaymentAmount.new }
|
|
17
17
|
|
|
18
|
-
describe 'test an instance of
|
|
19
|
-
it 'should create an instance of
|
|
20
|
-
expect(instance).to be_instance_of(SnapTrade::
|
|
18
|
+
describe 'test an instance of LineOfCreditAccountMinimumPaymentAmount' do
|
|
19
|
+
it 'should create an instance of LineOfCreditAccountMinimumPaymentAmount' do
|
|
20
|
+
expect(instance).to be_instance_of(SnapTrade::LineOfCreditAccountMinimumPaymentAmount)
|
|
21
21
|
end
|
|
22
22
|
end
|
|
23
23
|
describe 'test attribute "amount"' do
|
|
@@ -44,7 +44,7 @@ describe SnapTrade::LineOfCreditAccount do
|
|
|
44
44
|
end
|
|
45
45
|
end
|
|
46
46
|
|
|
47
|
-
describe 'test attribute "
|
|
47
|
+
describe 'test attribute "masked_account_number"' do
|
|
48
48
|
it 'should work' do
|
|
49
49
|
# assertion here. ref: https://www.relishapp.com/rspec/rspec-expectations/docs/built-in-matchers
|
|
50
50
|
end
|
|
@@ -86,7 +86,7 @@ describe SnapTrade::LineOfCreditAccount do
|
|
|
86
86
|
end
|
|
87
87
|
end
|
|
88
88
|
|
|
89
|
-
describe 'test attribute "
|
|
89
|
+
describe 'test attribute "minimum_payment_amount"' do
|
|
90
90
|
it 'should work' do
|
|
91
91
|
# assertion here. ref: https://www.relishapp.com/rspec/rspec-expectations/docs/built-in-matchers
|
|
92
92
|
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
=begin
|
|
2
|
+
#SnapTrade
|
|
3
|
+
|
|
4
|
+
#Connect brokerage accounts to your app for live positions and trading
|
|
5
|
+
|
|
6
|
+
The version of the OpenAPI document: 1.0.0
|
|
7
|
+
Contact: api@snaptrade.com
|
|
8
|
+
=end
|
|
9
|
+
|
|
10
|
+
require 'spec_helper'
|
|
11
|
+
require 'json'
|
|
12
|
+
require 'date'
|
|
13
|
+
|
|
14
|
+
# Unit tests for SnapTrade::Snaptrade
|
|
15
|
+
describe SnapTrade::Snaptrade do
|
|
16
|
+
let(:instance) { SnapTrade::Snaptrade.new }
|
|
17
|
+
|
|
18
|
+
describe 'test an instance of Snaptrade' do
|
|
19
|
+
it 'should create an instance of Snaptrade' do
|
|
20
|
+
expect(instance).to be_instance_of(SnapTrade::Snaptrade)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -27,7 +27,7 @@ describe SnapTrade::UnderlyingCfdInstrument do
|
|
|
27
27
|
|
|
28
28
|
describe '.openapi_discriminator_mapping' do
|
|
29
29
|
it 'returns the key/values of the "mapping" property' do
|
|
30
|
-
expect(described_class.openapi_discriminator_mapping.values.sort).to eq(described_class.openapi_one_of.sort)
|
|
30
|
+
expect(described_class.openapi_discriminator_mapping.values.uniq.sort).to eq(described_class.openapi_one_of.sort)
|
|
31
31
|
end
|
|
32
32
|
end
|
|
33
33
|
|
|
@@ -27,7 +27,7 @@ describe SnapTrade::UnderlyingOptionInstrument do
|
|
|
27
27
|
|
|
28
28
|
describe '.openapi_discriminator_mapping' do
|
|
29
29
|
it 'returns the key/values of the "mapping" property' do
|
|
30
|
-
expect(described_class.openapi_discriminator_mapping.values.sort).to eq(described_class.openapi_one_of.sort)
|
|
30
|
+
expect(described_class.openapi_discriminator_mapping.values.uniq.sort).to eq(described_class.openapi_one_of.sort)
|
|
31
31
|
end
|
|
32
32
|
end
|
|
33
33
|
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'json'
|
|
3
|
+
|
|
4
|
+
describe 'All account positions response deserialization' do
|
|
5
|
+
let(:payload) do
|
|
6
|
+
JSON.parse(File.read(File.join(__dir__, 'fixtures/all_account_positions.json')))
|
|
7
|
+
end
|
|
8
|
+
let(:body) { JSON.generate(payload) }
|
|
9
|
+
let(:configuration) do
|
|
10
|
+
SnapTrade::Configuration.new.tap do |config|
|
|
11
|
+
config.host = 'https://sdk-test.invalid'
|
|
12
|
+
config.client_id = 'TEST_CLIENT'
|
|
13
|
+
config.consumer_key = 'TEST_KEY'
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
let(:api_client) { SnapTrade::ApiClient.new(configuration) }
|
|
17
|
+
let(:api) { SnapTrade::AccountInformationApi.new(api_client) }
|
|
18
|
+
let(:arguments) do
|
|
19
|
+
{ user_id: 12345, user_secret: 'TEST_SECRET', account_id: 'TEST_ACCOUNT' }
|
|
20
|
+
end
|
|
21
|
+
let(:stubs) do
|
|
22
|
+
Faraday::Adapter::Test::Stubs.new do |stub|
|
|
23
|
+
stub.get('/accounts/TEST_ACCOUNT/positions/all') do
|
|
24
|
+
[200, { 'content-type' => 'application/json' }, body]
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
let(:connection) do
|
|
29
|
+
Faraday.new(url: configuration.base_url) { |conn| conn.adapter :test, stubs }
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
before do
|
|
33
|
+
allow(api_client).to receive(:connection).and_return(connection)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
after do
|
|
37
|
+
stubs.verify_stubbed_calls
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
[:get_all_account_positions, :get_all_account_positions_with_http_info].each do |operation|
|
|
41
|
+
context operation.to_s do
|
|
42
|
+
let(:data) do
|
|
43
|
+
result = api.public_send(operation, **arguments)
|
|
44
|
+
if operation == :get_all_account_positions_with_http_info
|
|
45
|
+
parsed, status, headers, response = result
|
|
46
|
+
expect(status).to eq(200)
|
|
47
|
+
expect(headers['content-type']).to eq('application/json')
|
|
48
|
+
expect(response.body).to eq(body)
|
|
49
|
+
parsed
|
|
50
|
+
else
|
|
51
|
+
result
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
it 'returns the full response and both bond instruments from a populated HTTP 200 body' do
|
|
56
|
+
expect(data).to be_a(SnapTrade::AllAccountPositionsResponse)
|
|
57
|
+
expect(data.data_freshness.as_of).to eq(Time.utc(2026, 9, 8, 11, 2, 57))
|
|
58
|
+
expect(data.results.length).to eq(2)
|
|
59
|
+
expect(data.results.map(&:units)).to eq([70.0, 70.0])
|
|
60
|
+
expect(data.results.map(&:price)).to eq([99.768, 100.025])
|
|
61
|
+
expect(data.results.map(&:cost_basis)).to eq([97.51, 100.25])
|
|
62
|
+
expect(data.results.map(&:instrument)).to all(be_a(SnapTrade::OtherInstrument))
|
|
63
|
+
expect(data.results.map { |position| position.instrument.kind }).to eq(['bond', 'bond'])
|
|
64
|
+
expect(data.results.map { |position| position.instrument.symbol }).to eq(['912797SA6', '91282CJT9'])
|
|
65
|
+
expect(data.to_hash[:results].map { |position| position[:instrument][:kind] }).to eq(['bond', 'bond'])
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
it 'keeps a response object when there are no positions' do
|
|
69
|
+
payload['results'] = []
|
|
70
|
+
|
|
71
|
+
expect(data).to be_a(SnapTrade::AllAccountPositionsResponse)
|
|
72
|
+
expect(data.results).to eq([])
|
|
73
|
+
expect(data.data_freshness.as_of).to eq(Time.utc(2026, 9, 8, 11, 2, 57))
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
it 'retains instruments when bond and other positions appear together' do
|
|
77
|
+
payload['results'][1]['instrument']['kind'] = 'other'
|
|
78
|
+
|
|
79
|
+
expect(data).to be_a(SnapTrade::AllAccountPositionsResponse)
|
|
80
|
+
expect(data.results.map(&:instrument)).to all(be_a(SnapTrade::OtherInstrument))
|
|
81
|
+
expect(data.results.map { |position| position.instrument.kind }).to eq(['bond', 'other'])
|
|
82
|
+
expect(data.results.map { |position| position.instrument.symbol }).to eq(['912797SA6', '91282CJT9'])
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"results": [
|
|
3
|
+
{
|
|
4
|
+
"instrument": {
|
|
5
|
+
"kind": "bond",
|
|
6
|
+
"id": "a7ade77d-74f4-4d8a-a1f8-1a582c2f4e3b",
|
|
7
|
+
"symbol": "912797SA6",
|
|
8
|
+
"raw_symbol": "912797SA6",
|
|
9
|
+
"description": "UNITED STATES TREAS BILLS ZERO CPN 0.00000% 10/01/2026",
|
|
10
|
+
"currency": "USD"
|
|
11
|
+
},
|
|
12
|
+
"units": "70",
|
|
13
|
+
"price": "99.768",
|
|
14
|
+
"cost_basis": "97.51",
|
|
15
|
+
"currency": "USD"
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"instrument": {
|
|
19
|
+
"kind": "bond",
|
|
20
|
+
"id": "e538a57c-2bb8-40e2-812d-d07ee525b1cf",
|
|
21
|
+
"symbol": "91282CJT9",
|
|
22
|
+
"raw_symbol": "91282CJT9",
|
|
23
|
+
"description": "UNITED STATES TREAS SER AJ-2027 4.00000% 01/15/2027 NTS NOTE",
|
|
24
|
+
"currency": "USD"
|
|
25
|
+
},
|
|
26
|
+
"units": "70",
|
|
27
|
+
"price": "100.025",
|
|
28
|
+
"cost_basis": "100.25",
|
|
29
|
+
"currency": "USD"
|
|
30
|
+
}
|
|
31
|
+
],
|
|
32
|
+
"data_freshness": { "as_of": "2026-09-08T11:02:57Z" }
|
|
33
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe SnapTrade::ApiClientCustom do
|
|
4
|
+
let(:configuration) do
|
|
5
|
+
SnapTrade::Configuration.new.tap { |config| config.consumer_key = 'TEST_KEY' }
|
|
6
|
+
end
|
|
7
|
+
let(:request) do
|
|
8
|
+
Faraday::Request.create(:post) do |req|
|
|
9
|
+
req.path = path
|
|
10
|
+
req.body = body
|
|
11
|
+
req.headers = {}
|
|
12
|
+
req.params = {
|
|
13
|
+
clientId: 'TEST_CLIENT',
|
|
14
|
+
userId: 'TEST_USER',
|
|
15
|
+
userSecret: 'TEST_SECRET'
|
|
16
|
+
}
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
before do
|
|
21
|
+
allow(Time).to receive(:now).and_return(Time.at(1_700_000_000))
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
context 'without a request body' do
|
|
25
|
+
let(:path) { '/accounts/TEST_ACCOUNT/positions/all' }
|
|
26
|
+
let(:body) { nil }
|
|
27
|
+
|
|
28
|
+
it 'preserves the existing signature bytes' do
|
|
29
|
+
described_class.request_hook(request, configuration)
|
|
30
|
+
|
|
31
|
+
expect(request.params[:timestamp]).to eq(1_700_000_000)
|
|
32
|
+
expect(request.headers[:Signature]).to eq('R7iYdxifiq/4joFEkOkaQj9QiW8LsgxmSDXco44gqtk=')
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
context 'with unsorted JSON body keys' do
|
|
37
|
+
let(:path) { '/orders' }
|
|
38
|
+
let(:body) { '{"z":2,"a":1}' }
|
|
39
|
+
|
|
40
|
+
it 'preserves body key sorting and the existing signature bytes' do
|
|
41
|
+
described_class.request_hook(request, configuration)
|
|
42
|
+
|
|
43
|
+
expect(request.headers[:Signature]).to eq('Zs3cXbvLmIEVPi69lHV6rah6wZ1phfk9cK6kbTYnSf4=')
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|