mirror of
https://github.com/maybe-finance/maybe.git
synced 2025-07-19 05:09:38 +02:00
79 lines
3.1 KiB
Ruby
79 lines
3.1 KiB
Ruby
|
require "test_helper"
|
|||
|
|
|||
|
class Security::ResolverTest < ActiveSupport::TestCase
|
|||
|
setup do
|
|||
|
@provider = mock
|
|||
|
Security.stubs(:provider).returns(@provider)
|
|||
|
end
|
|||
|
|
|||
|
test "resolves DB security" do
|
|||
|
# Given an existing security in the DB that exactly matches the lookup params
|
|||
|
db_security = Security.create!(ticker: "TSLA", exchange_operating_mic: "XNAS", country_code: "US")
|
|||
|
|
|||
|
# The resolver should return the DB record and never hit the provider
|
|||
|
Security.expects(:search_provider).never
|
|||
|
|
|||
|
resolved = Security::Resolver.new("TSLA", exchange_operating_mic: "XNAS", country_code: "US").resolve
|
|||
|
|
|||
|
assert_equal db_security, resolved
|
|||
|
end
|
|||
|
|
|||
|
test "resolves exact provider match" do
|
|||
|
# Provider returns multiple results, one of which exactly matches symbol + exchange (and country)
|
|||
|
exact_match = Security.new(ticker: "NVDA", exchange_operating_mic: "XNAS", country_code: "US")
|
|||
|
near_miss = Security.new(ticker: "NVDA", exchange_operating_mic: "XNYS", country_code: "US")
|
|||
|
|
|||
|
Security.expects(:search_provider)
|
|||
|
.with("NVDA", exchange_operating_mic: "XNAS", country_code: "US")
|
|||
|
.returns([ near_miss, exact_match ])
|
|||
|
|
|||
|
assert_difference "Security.count", 1 do
|
|||
|
resolved = Security::Resolver.new("NVDA", exchange_operating_mic: "XNAS", country_code: "US").resolve
|
|||
|
|
|||
|
assert resolved.persisted?
|
|||
|
assert_equal "NVDA", resolved.ticker
|
|||
|
assert_equal "XNAS", resolved.exchange_operating_mic
|
|||
|
assert_equal "US", resolved.country_code
|
|||
|
refute resolved.offline, "Exact provider matches should not be marked offline"
|
|||
|
end
|
|||
|
end
|
|||
|
|
|||
|
test "resolves close provider match" do
|
|||
|
# No exact match – resolver should choose the most relevant close match based on exchange + country ranking
|
|||
|
preferred = Security.new(ticker: "TEST1", exchange_operating_mic: "XNAS", country_code: "US")
|
|||
|
other = Security.new(ticker: "TEST2", exchange_operating_mic: "XNYS", country_code: "GB")
|
|||
|
|
|||
|
# Return in reverse-priority order to prove the sorter works
|
|||
|
Security.expects(:search_provider)
|
|||
|
.with("TEST", exchange_operating_mic: "XNAS")
|
|||
|
.returns([ other, preferred ])
|
|||
|
|
|||
|
assert_difference "Security.count", 1 do
|
|||
|
resolved = Security::Resolver.new("TEST", exchange_operating_mic: "XNAS").resolve
|
|||
|
|
|||
|
assert resolved.persisted?
|
|||
|
assert_equal "TEST1", resolved.ticker
|
|||
|
assert_equal "XNAS", resolved.exchange_operating_mic
|
|||
|
assert_equal "US", resolved.country_code
|
|||
|
refute resolved.offline, "Provider matches should not be marked offline"
|
|||
|
end
|
|||
|
end
|
|||
|
|
|||
|
test "resolves offline security" do
|
|||
|
Security.expects(:search_provider).returns([])
|
|||
|
|
|||
|
assert_difference "Security.count", 1 do
|
|||
|
resolved = Security::Resolver.new("FOO").resolve
|
|||
|
|
|||
|
assert resolved.persisted?, "Offline security should be saved"
|
|||
|
assert_equal "FOO", resolved.ticker
|
|||
|
assert resolved.offline, "Offline securities should be flagged offline"
|
|||
|
end
|
|||
|
end
|
|||
|
|
|||
|
test "returns nil when symbol blank" do
|
|||
|
assert_raises(ArgumentError) { Security::Resolver.new(nil).resolve }
|
|||
|
assert_raises(ArgumentError) { Security::Resolver.new("").resolve }
|
|||
|
end
|
|||
|
end
|