mirror of
https://github.com/we-promise/sure.git
synced 2026-04-07 14:31:25 +00:00
188 lines
5.3 KiB
Ruby
188 lines
5.3 KiB
Ruby
require "test_helper"
|
|
|
|
class SnaptradeDataHelpersTest < ActiveSupport::TestCase
|
|
# Create a test class that includes the concern
|
|
class TestHelper
|
|
include SnaptradeAccount::DataHelpers
|
|
|
|
# Expose private methods for testing
|
|
def test_parse_decimal(value)
|
|
parse_decimal(value)
|
|
end
|
|
|
|
def test_parse_date(value)
|
|
parse_date(value)
|
|
end
|
|
|
|
def test_resolve_security(symbol, symbol_data)
|
|
resolve_security(symbol, symbol_data)
|
|
end
|
|
|
|
def test_extract_currency(data, symbol_data = {}, fallback = nil)
|
|
extract_currency(data, symbol_data, fallback)
|
|
end
|
|
end
|
|
|
|
setup do
|
|
@helper = TestHelper.new
|
|
end
|
|
|
|
# === parse_decimal tests ===
|
|
|
|
test "parse_decimal handles BigDecimal" do
|
|
result = @helper.test_parse_decimal(BigDecimal("123.45"))
|
|
assert_equal BigDecimal("123.45"), result
|
|
end
|
|
|
|
test "parse_decimal handles String" do
|
|
result = @helper.test_parse_decimal("456.78")
|
|
assert_equal BigDecimal("456.78"), result
|
|
end
|
|
|
|
test "parse_decimal handles Integer" do
|
|
result = @helper.test_parse_decimal(100)
|
|
assert_equal BigDecimal("100"), result
|
|
end
|
|
|
|
test "parse_decimal handles Float" do
|
|
result = @helper.test_parse_decimal(99.99)
|
|
assert_equal BigDecimal("99.99"), result
|
|
end
|
|
|
|
test "parse_decimal returns nil for nil input" do
|
|
result = @helper.test_parse_decimal(nil)
|
|
assert_nil result
|
|
end
|
|
|
|
test "parse_decimal returns nil for invalid string" do
|
|
result = @helper.test_parse_decimal("not_a_number")
|
|
assert_nil result
|
|
end
|
|
|
|
# === parse_date tests ===
|
|
|
|
test "parse_date handles Date object" do
|
|
date = Date.new(2024, 6, 15)
|
|
result = @helper.test_parse_date(date)
|
|
assert_equal date, result
|
|
end
|
|
|
|
test "parse_date handles ISO string" do
|
|
result = @helper.test_parse_date("2024-06-15")
|
|
assert_equal Date.new(2024, 6, 15), result
|
|
end
|
|
|
|
test "parse_date handles Time object" do
|
|
time = Time.zone.parse("2024-06-15 10:30:00")
|
|
result = @helper.test_parse_date(time)
|
|
assert_equal Date.new(2024, 6, 15), result
|
|
end
|
|
|
|
test "parse_date handles DateTime" do
|
|
dt = DateTime.new(2024, 6, 15, 10, 30)
|
|
result = @helper.test_parse_date(dt)
|
|
# DateTime is a subclass of Date, so it matches Date branch and returns as-is
|
|
# which is acceptable behavior - the result is still usable as a date
|
|
assert result.respond_to?(:year)
|
|
assert_equal 2024, result.year
|
|
assert_equal 6, result.month
|
|
assert_equal 15, result.day
|
|
end
|
|
|
|
test "parse_date returns nil for nil input" do
|
|
result = @helper.test_parse_date(nil)
|
|
assert_nil result
|
|
end
|
|
|
|
test "parse_date returns nil for invalid string" do
|
|
result = @helper.test_parse_date("invalid_date")
|
|
assert_nil result
|
|
end
|
|
|
|
# === resolve_security tests ===
|
|
|
|
test "resolve_security finds existing security by ticker" do
|
|
existing = Security.create!(ticker: "TEST", name: "Test Company")
|
|
|
|
result = @helper.test_resolve_security("TEST", {})
|
|
assert_equal existing, result
|
|
end
|
|
|
|
test "resolve_security creates new security when not found" do
|
|
symbol_data = { "description" => "New Corp Inc" }
|
|
|
|
result = @helper.test_resolve_security("NEWCORP", symbol_data)
|
|
|
|
assert_not_nil result
|
|
assert_equal "NEWCORP", result.ticker
|
|
assert_equal "New Corp Inc", result.name
|
|
end
|
|
|
|
test "resolve_security uppercases ticker" do
|
|
symbol_data = { "description" => "Lowercase Test" }
|
|
|
|
result = @helper.test_resolve_security("lowercase", symbol_data)
|
|
|
|
assert_equal "LOWERCASE", result.ticker
|
|
end
|
|
|
|
test "resolve_security returns nil for blank ticker" do
|
|
result = @helper.test_resolve_security("", {})
|
|
assert_nil result
|
|
|
|
result = @helper.test_resolve_security(nil, {})
|
|
assert_nil result
|
|
end
|
|
|
|
test "resolve_security handles race condition on creation" do
|
|
# Simulate race condition by creating after first check
|
|
symbol_data = { "description" => "Race Condition Test" }
|
|
|
|
# Create the security before resolve_security can
|
|
Security.create!(ticker: "RACECOND", name: "Already Created")
|
|
|
|
# Should return existing instead of raising
|
|
result = @helper.test_resolve_security("RACECOND", symbol_data)
|
|
assert_equal "RACECOND", result.ticker
|
|
end
|
|
|
|
# === extract_currency tests ===
|
|
|
|
test "extract_currency handles hash with code key (symbol access)" do
|
|
data = { currency: { code: "CAD" } }
|
|
result = @helper.test_extract_currency(data)
|
|
assert_equal "CAD", result
|
|
end
|
|
|
|
test "extract_currency handles hash with code key (string access)" do
|
|
data = { "currency" => { "code" => "EUR" } }
|
|
result = @helper.test_extract_currency(data)
|
|
assert_equal "EUR", result
|
|
end
|
|
|
|
test "extract_currency handles string currency" do
|
|
data = { currency: "GBP" }
|
|
result = @helper.test_extract_currency(data)
|
|
assert_equal "GBP", result
|
|
end
|
|
|
|
test "extract_currency falls back to symbol_data" do
|
|
data = {}
|
|
symbol_data = { currency: "JPY" }
|
|
result = @helper.test_extract_currency(data, symbol_data)
|
|
assert_equal "JPY", result
|
|
end
|
|
|
|
test "extract_currency uses fallback when no currency found" do
|
|
data = {}
|
|
result = @helper.test_extract_currency(data, {}, "USD")
|
|
assert_equal "USD", result
|
|
end
|
|
|
|
test "extract_currency returns nil when no currency and no fallback" do
|
|
data = {}
|
|
result = @helper.test_extract_currency(data, {}, nil)
|
|
assert_nil result
|
|
end
|
|
end
|