mirror of
https://github.com/we-promise/sure.git
synced 2026-04-08 14:54:49 +00:00
* Feat(CoinStats): Scaffold implementation, not yet functional * Feat(CoinStats): Implement crypto wallet balance and transactions * Feat(CoinStats): Add tests, Minor improvements * Feat(CoinStats): Utilize bulk fetch API endpoints * Feat(CoinStats): Migrate strings to i8n * Feat(CoinStats): Fix error handling in wallet link modal * Feat(CoinStats): Implement hourly provider sync job * Feat(CoinStats): Generate docstrings * Fix(CoinStats): Validate API Key on provider update * Fix(Providers): Safely handle race condition in merchance creation * Fix(CoinStats): Don't catch system signals in account processor * Fix(CoinStats): Preload before iterating accounts * Fix(CoinStats): Add no opener / referrer to API dashboard link * Fix(CoinStats): Use strict matching for symbols * Fix(CoinStats): Remove dead code in transactions importer * Fix(CoinStats): Avoid transaction fallback ID collisions * Fix(CoinStats): Improve Blockchains fetch error handling * Fix(CoinStats): Enforce NOT NULL constraint for API Key schema * Fix(CoinStats): Migrate sync status strings to i8n * Fix(CoinStats): Use class name rather than hardcoded string * Fix(CoinStats): Use account currency rather than hardcoded USD * Fix(CoinStats): Migrate from standalone to Provider class * Fix(CoinStats): Fix test failures due to string changes
178 lines
5.8 KiB
Ruby
178 lines
5.8 KiB
Ruby
require "test_helper"
|
|
|
|
class CoinstatsItem::SyncerTest < ActiveSupport::TestCase
|
|
setup do
|
|
@family = families(:dylan_family)
|
|
@coinstats_item = CoinstatsItem.create!(
|
|
family: @family,
|
|
name: "Test CoinStats Connection",
|
|
api_key: "test_api_key_123"
|
|
)
|
|
@syncer = CoinstatsItem::Syncer.new(@coinstats_item)
|
|
end
|
|
|
|
test "perform_sync imports data from coinstats api" do
|
|
mock_sync = mock("sync")
|
|
mock_sync.stubs(:respond_to?).with(:status_text).returns(true)
|
|
mock_sync.stubs(:respond_to?).with(:sync_stats).returns(true)
|
|
mock_sync.stubs(:window_start_date).returns(nil)
|
|
mock_sync.stubs(:window_end_date).returns(nil)
|
|
mock_sync.expects(:update!).at_least_once
|
|
|
|
@coinstats_item.expects(:import_latest_coinstats_data).once
|
|
|
|
@syncer.perform_sync(mock_sync)
|
|
end
|
|
|
|
test "perform_sync updates pending_account_setup when unlinked accounts exist" do
|
|
# Create an unlinked coinstats account (no AccountProvider)
|
|
@coinstats_item.coinstats_accounts.create!(
|
|
name: "Unlinked Wallet",
|
|
currency: "USD"
|
|
)
|
|
|
|
mock_sync = mock("sync")
|
|
mock_sync.stubs(:respond_to?).with(:status_text).returns(true)
|
|
mock_sync.stubs(:respond_to?).with(:sync_stats).returns(true)
|
|
mock_sync.stubs(:window_start_date).returns(nil)
|
|
mock_sync.stubs(:window_end_date).returns(nil)
|
|
mock_sync.expects(:update!).at_least_once
|
|
|
|
@coinstats_item.expects(:import_latest_coinstats_data).once
|
|
|
|
@syncer.perform_sync(mock_sync)
|
|
|
|
assert @coinstats_item.reload.pending_account_setup?
|
|
end
|
|
|
|
test "perform_sync clears pending_account_setup when all accounts linked" do
|
|
@coinstats_item.update!(pending_account_setup: true)
|
|
|
|
# Create a linked coinstats account
|
|
crypto = Crypto.create!
|
|
account = @family.accounts.create!(
|
|
accountable: crypto,
|
|
name: "Test Crypto",
|
|
balance: 1000,
|
|
currency: "USD"
|
|
)
|
|
coinstats_account = @coinstats_item.coinstats_accounts.create!(
|
|
name: "Linked Wallet",
|
|
currency: "USD"
|
|
)
|
|
AccountProvider.create!(account: account, provider: coinstats_account)
|
|
|
|
mock_sync = mock("sync")
|
|
mock_sync.stubs(:respond_to?).with(:status_text).returns(true)
|
|
mock_sync.stubs(:respond_to?).with(:sync_stats).returns(true)
|
|
mock_sync.stubs(:window_start_date).returns(nil)
|
|
mock_sync.stubs(:window_end_date).returns(nil)
|
|
mock_sync.expects(:update!).at_least_once
|
|
|
|
@coinstats_item.expects(:import_latest_coinstats_data).once
|
|
@coinstats_item.expects(:process_accounts).once
|
|
@coinstats_item.expects(:schedule_account_syncs).once
|
|
|
|
@syncer.perform_sync(mock_sync)
|
|
|
|
refute @coinstats_item.reload.pending_account_setup?
|
|
end
|
|
|
|
test "perform_sync processes accounts when linked accounts exist" do
|
|
# Create a linked coinstats account
|
|
crypto = Crypto.create!
|
|
account = @family.accounts.create!(
|
|
accountable: crypto,
|
|
name: "Test Crypto",
|
|
balance: 1000,
|
|
currency: "USD"
|
|
)
|
|
coinstats_account = @coinstats_item.coinstats_accounts.create!(
|
|
name: "Linked Wallet",
|
|
currency: "USD"
|
|
)
|
|
AccountProvider.create!(account: account, provider: coinstats_account)
|
|
|
|
mock_sync = mock("sync")
|
|
mock_sync.stubs(:respond_to?).with(:status_text).returns(true)
|
|
mock_sync.stubs(:respond_to?).with(:sync_stats).returns(true)
|
|
mock_sync.stubs(:window_start_date).returns(nil)
|
|
mock_sync.stubs(:window_end_date).returns(nil)
|
|
mock_sync.expects(:update!).at_least_once
|
|
|
|
@coinstats_item.expects(:import_latest_coinstats_data).once
|
|
@coinstats_item.expects(:process_accounts).once
|
|
@coinstats_item.expects(:schedule_account_syncs).with(
|
|
parent_sync: mock_sync,
|
|
window_start_date: nil,
|
|
window_end_date: nil
|
|
).once
|
|
|
|
@syncer.perform_sync(mock_sync)
|
|
end
|
|
|
|
test "perform_sync skips processing when no linked accounts" do
|
|
mock_sync = mock("sync")
|
|
mock_sync.stubs(:respond_to?).with(:status_text).returns(true)
|
|
mock_sync.stubs(:respond_to?).with(:sync_stats).returns(true)
|
|
mock_sync.stubs(:window_start_date).returns(nil)
|
|
mock_sync.stubs(:window_end_date).returns(nil)
|
|
mock_sync.expects(:update!).at_least_once
|
|
|
|
@coinstats_item.expects(:import_latest_coinstats_data).once
|
|
@coinstats_item.expects(:process_accounts).never
|
|
@coinstats_item.expects(:schedule_account_syncs).never
|
|
|
|
@syncer.perform_sync(mock_sync)
|
|
end
|
|
|
|
test "perform_sync records sync stats" do
|
|
# Create one linked and one unlinked account
|
|
crypto = Crypto.create!
|
|
account = @family.accounts.create!(
|
|
accountable: crypto,
|
|
name: "Test Crypto",
|
|
balance: 1000,
|
|
currency: "USD"
|
|
)
|
|
linked_account = @coinstats_item.coinstats_accounts.create!(
|
|
name: "Linked Wallet",
|
|
currency: "USD"
|
|
)
|
|
AccountProvider.create!(account: account, provider: linked_account)
|
|
|
|
@coinstats_item.coinstats_accounts.create!(
|
|
name: "Unlinked Wallet",
|
|
currency: "USD"
|
|
)
|
|
|
|
recorded_stats = nil
|
|
mock_sync = mock("sync")
|
|
mock_sync.stubs(:respond_to?).with(:status_text).returns(true)
|
|
mock_sync.stubs(:respond_to?).with(:sync_stats).returns(true)
|
|
mock_sync.stubs(:window_start_date).returns(nil)
|
|
mock_sync.stubs(:window_end_date).returns(nil)
|
|
mock_sync.expects(:update!).at_least_once.with do |args|
|
|
recorded_stats = args[:sync_stats] if args.key?(:sync_stats)
|
|
true
|
|
end
|
|
|
|
@coinstats_item.expects(:import_latest_coinstats_data).once
|
|
@coinstats_item.expects(:process_accounts).once
|
|
@coinstats_item.expects(:schedule_account_syncs).once
|
|
|
|
@syncer.perform_sync(mock_sync)
|
|
|
|
assert_equal 2, recorded_stats[:total_accounts]
|
|
assert_equal 1, recorded_stats[:linked_accounts]
|
|
assert_equal 1, recorded_stats[:unlinked_accounts]
|
|
end
|
|
|
|
test "perform_post_sync is a no-op" do
|
|
# Just ensure it doesn't raise
|
|
assert_nothing_raised do
|
|
@syncer.perform_post_sync
|
|
end
|
|
end
|
|
end
|