Files
sure/test/models/akahu_account/processor_test.rb
Brad 1b8b21760b feat(provider): Akahu integration (#1921)
* First pass of Akahu

* fix up sync all

* conflicts

* fix db migration issue? - fix auto selection of akahu account type

* Address Akahu PR feedback

* Complete provider metadata

* Fix PR 1921 CI tests

* PR feedback

* PR feedback

* post merge

---------

Co-authored-by: failing <failing@users.noreply.github.com>
Co-authored-by: Juan José Mata <jjmata@jjmata.com>
Co-authored-by: sure-admin <sure-admin@splashblot.com>
2026-06-02 21:44:57 +02:00

139 lines
4.1 KiB
Ruby

require "test_helper"
class AkahuAccount::ProcessorTest < ActiveSupport::TestCase
setup do
@family = families(:empty)
@akahu_item = AkahuItem.create!(
family: @family,
name: "Test Akahu",
app_token: "akahu-app-credential",
user_token: "akahu-user-credential"
)
@akahu_account = AkahuAccount.create!(
akahu_item: @akahu_item,
name: "Test Invest - Portfolio",
account_id: "investment_123",
currency: "NZD",
current_balance: 12_345.67
)
@account = Account.create!(
family: @family,
name: "Portfolio",
accountable: Investment.new,
balance: 0,
cash_balance: 999,
currency: "NZD"
)
AccountProvider.create!(account: @account, provider: @akahu_account)
end
test "updates investment account balance without treating portfolio value as cash" do
AkahuAccount::Processor.new(@akahu_account).process
@account.reload
assert_equal BigDecimal("12345.67"), @account.balance
assert_equal BigDecimal("0"), @account.cash_balance
assert_equal "NZD", @account.currency
end
test "logs account processing failures without raw exception message" do
sensitive_message = "provider returned account holder details"
error = RuntimeError.new(sensitive_message)
@akahu_account.stubs(:current_account).returns(@account)
@account.stubs(:update!).raises(error)
scope = RecordingSentryScope.new
Sentry.expects(:capture_exception).with do |captured_error|
captured_error.is_a?(AkahuAccount::Processor::SanitizedProcessingError) &&
!captured_error.equal?(error) &&
captured_error.cause.nil? &&
captured_error.message == "Akahu account processing failed" &&
!captured_error.message.include?(sensitive_message)
end.yields(scope).once
Rails.logger.expects(:error).with do |message|
message.include?("akahu_account_id=#{@akahu_account.id}") &&
message.include?("error_class=RuntimeError") &&
!message.include?(sensitive_message)
end.once
assert_raises(RuntimeError) do
AkahuAccount::Processor.new(@akahu_account).process
end
assert_equal(
{
akahu_account_id: @akahu_account.id,
context: "account",
error_class: "RuntimeError"
},
scope.tags
)
assert_equal(
{
akahu_account_id: @akahu_account.id,
context: "account",
error_class: "RuntimeError"
},
scope.contexts["akahu_account_processor"]
)
end
test "logs transaction processing failures without raw exception message" do
sensitive_message = "provider returned account number 12-3456"
error = RuntimeError.new(sensitive_message)
AkahuAccount::Transactions::Processor.any_instance.stubs(:process).raises(error)
scope = RecordingSentryScope.new
Sentry.expects(:capture_exception).with do |captured_error|
captured_error.is_a?(AkahuAccount::Processor::SanitizedProcessingError) &&
!captured_error.equal?(error) &&
captured_error.cause.nil? &&
captured_error.message == "Akahu account processing failed" &&
!captured_error.message.include?(sensitive_message)
end.yields(scope).once
Rails.logger.expects(:error).with do |message|
message.include?("akahu_account_id=#{@akahu_account.id}") &&
message.include?("error_class=RuntimeError") &&
!message.include?(sensitive_message)
end.once
result = AkahuAccount::Processor.new(@akahu_account).process
assert_equal false, result[:success]
assert_equal(
{
akahu_account_id: @akahu_account.id,
context: "transactions",
error_class: "RuntimeError"
},
scope.tags
)
assert_equal(
{
akahu_account_id: @akahu_account.id,
context: "transactions",
error_class: "RuntimeError"
},
scope.contexts["akahu_account_processor"]
)
end
class RecordingSentryScope
attr_reader :tags, :contexts
def initialize
@tags = {}
@contexts = {}
end
def set_tags(tags)
@tags.merge!(tags)
end
def set_context(name, context)
@contexts[name] = context
end
end
end