mirror of
https://github.com/maybe-finance/maybe.git
synced 2025-08-09 07:25:19 +02:00
Test raw payloads on plaid accounts
This commit is contained in:
parent
1ec3b594f2
commit
ed9d9d6335
4 changed files with 55 additions and 29 deletions
|
@ -41,10 +41,14 @@ class PlaidItem::AccountsSnapshot
|
||||||
def account_scoped_investments_data(account_id)
|
def account_scoped_investments_data(account_id)
|
||||||
return nil unless investments_data
|
return nil unless investments_data
|
||||||
|
|
||||||
|
transactions = investments_data.transactions.select { |t| t.account_id == account_id }
|
||||||
|
holdings = investments_data.holdings.select { |h| h.account_id == account_id }
|
||||||
|
securities = transactions.count > 0 && holdings.count > 0 ? investments_data.securities : []
|
||||||
|
|
||||||
InvestmentsData.new(
|
InvestmentsData.new(
|
||||||
transactions: investments_data.transactions.select { |t| t.account_id == account_id },
|
transactions: transactions,
|
||||||
holdings: investments_data.holdings.select { |h| h.account_id == account_id },
|
holdings: holdings,
|
||||||
securities: investments_data.securities
|
securities: securities
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -18,5 +18,18 @@ class PlaidAccount::ImporterTest < ActiveSupport::TestCase
|
||||||
assert_equal @account_snapshot.account_data.mask, @plaid_account.mask
|
assert_equal @account_snapshot.account_data.mask, @plaid_account.mask
|
||||||
assert_equal @account_snapshot.account_data.type, @plaid_account.plaid_type
|
assert_equal @account_snapshot.account_data.type, @plaid_account.plaid_type
|
||||||
assert_equal @account_snapshot.account_data.subtype, @plaid_account.plaid_subtype
|
assert_equal @account_snapshot.account_data.subtype, @plaid_account.plaid_subtype
|
||||||
|
|
||||||
|
# This account has transactions data
|
||||||
|
assert_equal PlaidMock::TRANSACTIONS.count, @plaid_account.raw_transactions_payload["added"].count
|
||||||
|
|
||||||
|
# This account does not have investment data
|
||||||
|
assert_equal 0, @plaid_account.raw_investments_payload["holdings"].count
|
||||||
|
assert_equal 0, @plaid_account.raw_investments_payload["securities"].count
|
||||||
|
assert_equal 0, @plaid_account.raw_investments_payload["transactions"].count
|
||||||
|
|
||||||
|
# This account is a credit card, so it should have liability data
|
||||||
|
assert_equal @plaid_account.plaid_id, @plaid_account.raw_liabilities_payload["credit"]["account_id"]
|
||||||
|
assert_nil @plaid_account.raw_liabilities_payload["mortgage"]
|
||||||
|
assert_nil @plaid_account.raw_liabilities_payload["student"]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -16,7 +16,8 @@ class PlaidItem::ImporterTest < ActiveSupport::TestCase
|
||||||
assert_equal PlaidMock::ITEM.institution_id, @plaid_item.institution_id
|
assert_equal PlaidMock::ITEM.institution_id, @plaid_item.institution_id
|
||||||
assert_equal PlaidMock::ITEM.available_products, @plaid_item.available_products
|
assert_equal PlaidMock::ITEM.available_products, @plaid_item.available_products
|
||||||
assert_equal PlaidMock::ITEM.billed_products, @plaid_item.billed_products
|
assert_equal PlaidMock::ITEM.billed_products, @plaid_item.billed_products
|
||||||
assert_not_nil @plaid_item.raw_payload
|
|
||||||
assert_not_nil @plaid_item.raw_institution_payload
|
assert_equal PlaidMock::ITEM.item_id, @plaid_item.raw_payload["item_id"]
|
||||||
|
assert_equal PlaidMock::INSTITUTION.institution_id, @plaid_item.raw_institution_payload["institution_id"]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,11 +1,19 @@
|
||||||
require "ostruct"
|
require "ostruct"
|
||||||
|
|
||||||
|
# Lightweight wrapper that allows Ostruct objects to properly serialize to JSON
|
||||||
|
# for storage on PlaidItem / PlaidAccount JSONB columns
|
||||||
|
class MockData < OpenStruct
|
||||||
|
def as_json(options = {})
|
||||||
|
@table.as_json(options)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# A basic Plaid provider mock that returns static payloads for testing
|
# A basic Plaid provider mock that returns static payloads for testing
|
||||||
class PlaidMock
|
class PlaidMock
|
||||||
TransactionSyncResponse = Struct.new(:added, :modified, :removed, :cursor, keyword_init: true)
|
TransactionSyncResponse = Struct.new(:added, :modified, :removed, :cursor, keyword_init: true)
|
||||||
InvestmentsResponse = Struct.new(:holdings, :transactions, :securities, keyword_init: true)
|
InvestmentsResponse = Struct.new(:holdings, :transactions, :securities, keyword_init: true)
|
||||||
|
|
||||||
ITEM = OpenStruct.new(
|
ITEM = MockData.new(
|
||||||
item_id: "item_mock_1",
|
item_id: "item_mock_1",
|
||||||
institution_id: "ins_mock",
|
institution_id: "ins_mock",
|
||||||
institution_name: "Mock Institution",
|
institution_name: "Mock Institution",
|
||||||
|
@ -13,31 +21,31 @@ class PlaidMock
|
||||||
billed_products: %w[transactions investments liabilities]
|
billed_products: %w[transactions investments liabilities]
|
||||||
)
|
)
|
||||||
|
|
||||||
INSTITUTION = OpenStruct.new(
|
INSTITUTION = MockData.new(
|
||||||
institution_id: "ins_mock",
|
institution_id: "ins_mock",
|
||||||
institution_name: "Mock Institution"
|
institution_name: "Mock Institution"
|
||||||
)
|
)
|
||||||
|
|
||||||
ACCOUNTS = [
|
ACCOUNTS = [
|
||||||
OpenStruct.new(
|
MockData.new(
|
||||||
account_id: "acc_mock_1",
|
account_id: "acc_mock_1",
|
||||||
name: "Mock Checking",
|
name: "Mock Checking",
|
||||||
mask: "1111",
|
mask: "1111",
|
||||||
type: "depository",
|
type: "depository",
|
||||||
subtype: "checking",
|
subtype: "checking",
|
||||||
balances: OpenStruct.new(
|
balances: MockData.new(
|
||||||
current: 1_000.00,
|
current: 1_000.00,
|
||||||
available: 800.00,
|
available: 800.00,
|
||||||
iso_currency_code: "USD"
|
iso_currency_code: "USD"
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
OpenStruct.new(
|
MockData.new(
|
||||||
account_id: "acc_mock_2",
|
account_id: "acc_mock_2",
|
||||||
name: "Mock Brokerage",
|
name: "Mock Brokerage",
|
||||||
mask: "2222",
|
mask: "2222",
|
||||||
type: "investment",
|
type: "investment",
|
||||||
subtype: "brokerage",
|
subtype: "brokerage",
|
||||||
balances: OpenStruct.new(
|
balances: MockData.new(
|
||||||
current: 15_000.00,
|
current: 15_000.00,
|
||||||
available: 15_000.00,
|
available: 15_000.00,
|
||||||
iso_currency_code: "USD"
|
iso_currency_code: "USD"
|
||||||
|
@ -46,7 +54,7 @@ class PlaidMock
|
||||||
]
|
]
|
||||||
|
|
||||||
SECURITIES = [
|
SECURITIES = [
|
||||||
OpenStruct.new(
|
MockData.new(
|
||||||
security_id: "sec_mock_1",
|
security_id: "sec_mock_1",
|
||||||
ticker_symbol: "AAPL",
|
ticker_symbol: "AAPL",
|
||||||
proxy_security_id: nil,
|
proxy_security_id: nil,
|
||||||
|
@ -55,7 +63,7 @@ class PlaidMock
|
||||||
is_cash_equivalent: false
|
is_cash_equivalent: false
|
||||||
),
|
),
|
||||||
# Cash security representation – used to exclude cash-equivalent holdings
|
# Cash security representation – used to exclude cash-equivalent holdings
|
||||||
OpenStruct.new(
|
MockData.new(
|
||||||
security_id: "sec_mock_cash",
|
security_id: "sec_mock_cash",
|
||||||
ticker_symbol: "CUR:USD",
|
ticker_symbol: "CUR:USD",
|
||||||
proxy_security_id: nil,
|
proxy_security_id: nil,
|
||||||
|
@ -66,7 +74,7 @@ class PlaidMock
|
||||||
]
|
]
|
||||||
|
|
||||||
TRANSACTIONS = [
|
TRANSACTIONS = [
|
||||||
OpenStruct.new(
|
MockData.new(
|
||||||
transaction_id: "txn_mock_1",
|
transaction_id: "txn_mock_1",
|
||||||
account_id: "acc_mock_1",
|
account_id: "acc_mock_1",
|
||||||
merchant_name: "Mock Coffee",
|
merchant_name: "Mock Coffee",
|
||||||
|
@ -82,7 +90,7 @@ class PlaidMock
|
||||||
]
|
]
|
||||||
|
|
||||||
INVESTMENT_TRANSACTIONS = [
|
INVESTMENT_TRANSACTIONS = [
|
||||||
OpenStruct.new(
|
MockData.new(
|
||||||
investment_transaction_id: "inv_txn_mock_1",
|
investment_transaction_id: "inv_txn_mock_1",
|
||||||
account_id: "acc_mock_2",
|
account_id: "acc_mock_2",
|
||||||
security_id: "sec_mock_1",
|
security_id: "sec_mock_1",
|
||||||
|
@ -94,7 +102,7 @@ class PlaidMock
|
||||||
iso_currency_code: "USD",
|
iso_currency_code: "USD",
|
||||||
date: Date.current.to_s
|
date: Date.current.to_s
|
||||||
),
|
),
|
||||||
OpenStruct.new(
|
MockData.new(
|
||||||
investment_transaction_id: "inv_txn_mock_cash",
|
investment_transaction_id: "inv_txn_mock_cash",
|
||||||
account_id: "acc_mock_2",
|
account_id: "acc_mock_2",
|
||||||
security_id: "sec_mock_cash",
|
security_id: "sec_mock_cash",
|
||||||
|
@ -109,14 +117,14 @@ class PlaidMock
|
||||||
]
|
]
|
||||||
|
|
||||||
HOLDINGS = [
|
HOLDINGS = [
|
||||||
OpenStruct.new(
|
MockData.new(
|
||||||
account_id: "acc_mock_2",
|
account_id: "acc_mock_2",
|
||||||
security_id: "sec_mock_1",
|
security_id: "sec_mock_1",
|
||||||
quantity: 10,
|
quantity: 10,
|
||||||
institution_price: 150.00,
|
institution_price: 150.00,
|
||||||
iso_currency_code: "USD"
|
iso_currency_code: "USD"
|
||||||
),
|
),
|
||||||
OpenStruct.new(
|
MockData.new(
|
||||||
account_id: "acc_mock_2",
|
account_id: "acc_mock_2",
|
||||||
security_id: "sec_mock_cash",
|
security_id: "sec_mock_cash",
|
||||||
quantity: 200.0,
|
quantity: 200.0,
|
||||||
|
@ -127,22 +135,22 @@ class PlaidMock
|
||||||
|
|
||||||
LIABILITIES = {
|
LIABILITIES = {
|
||||||
credit: [
|
credit: [
|
||||||
OpenStruct.new(
|
MockData.new(
|
||||||
account_id: "acc_mock_1",
|
account_id: "acc_mock_1",
|
||||||
minimum_payment_amount: 25.00,
|
minimum_payment_amount: 25.00,
|
||||||
aprs: [ OpenStruct.new(apr_percentage: 19.99) ]
|
aprs: [ MockData.new(apr_percentage: 19.99) ]
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
mortgage: [
|
mortgage: [
|
||||||
OpenStruct.new(
|
MockData.new(
|
||||||
account_id: "acc_mock_3",
|
account_id: "acc_mock_3",
|
||||||
origination_principal_amount: 250_000,
|
origination_principal_amount: 250_000,
|
||||||
origination_date: 10.years.ago.to_date.to_s,
|
origination_date: 10.years.ago.to_date.to_s,
|
||||||
interest_rate: OpenStruct.new(type: "fixed", percentage: 3.5)
|
interest_rate: MockData.new(type: "fixed", percentage: 3.5)
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
student: [
|
student: [
|
||||||
OpenStruct.new(
|
MockData.new(
|
||||||
account_id: "acc_mock_4",
|
account_id: "acc_mock_4",
|
||||||
origination_principal_amount: 50_000,
|
origination_principal_amount: 50_000,
|
||||||
origination_date: 6.years.ago.to_date.to_s,
|
origination_date: 6.years.ago.to_date.to_s,
|
||||||
|
@ -152,7 +160,7 @@ class PlaidMock
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_link_token(*, **)
|
def get_link_token(*, **)
|
||||||
OpenStruct.new(link_token: "link-mock-123")
|
MockData.new(link_token: "link-mock-123")
|
||||||
end
|
end
|
||||||
|
|
||||||
def create_public_token(username: nil)
|
def create_public_token(username: nil)
|
||||||
|
@ -160,23 +168,23 @@ class PlaidMock
|
||||||
end
|
end
|
||||||
|
|
||||||
def exchange_public_token(_token)
|
def exchange_public_token(_token)
|
||||||
OpenStruct.new(access_token: "access-mock-123")
|
MockData.new(access_token: "access-mock-123")
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_item(_access_token)
|
def get_item(_access_token)
|
||||||
OpenStruct.new(
|
MockData.new(
|
||||||
item: ITEM
|
item: ITEM
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_institution(institution_id)
|
def get_institution(institution_id)
|
||||||
OpenStruct.new(
|
MockData.new(
|
||||||
institution: INSTITUTION
|
institution: INSTITUTION
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_item_accounts(_item_or_token)
|
def get_item_accounts(_item_or_token)
|
||||||
OpenStruct.new(accounts: ACCOUNTS)
|
MockData.new(accounts: ACCOUNTS)
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_transactions(access_token, next_cursor: nil)
|
def get_transactions(access_token, next_cursor: nil)
|
||||||
|
@ -197,7 +205,7 @@ class PlaidMock
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_item_liabilities(_item_or_token)
|
def get_item_liabilities(_item_or_token)
|
||||||
OpenStruct.new(
|
MockData.new(
|
||||||
credit: LIABILITIES[:credit],
|
credit: LIABILITIES[:credit],
|
||||||
mortgage: LIABILITIES[:mortgage],
|
mortgage: LIABILITIES[:mortgage],
|
||||||
student: LIABILITIES[:student]
|
student: LIABILITIES[:student]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue