defmodule DaProductApp.Switch.RouterTest do use ExUnit.Case, async: true alias DaProductApp.Switch.Router describe "Router integration" do test "routes using legacy system by default" do # Mock legacy message format message = %{ "0" => "0200", # MTI "2" => "4111111111111111", # PAN (Visa) "3" => "000000", # Processing code "41" => "TERMINAL1", # Terminal ID "42" => "MERCHANT001" # Merchant ID } # Test routing (won't actually execute connector) result = Router.test_route(message) assert {:ok, routing_info} = result assert routing_info.routing_system == :legacy assert routing_info.connector_module == DaProductApp.Switch.Connectors.Visa end test "routes Visa card using legacy routing" do message = %{ "0" => "0200", "2" => "4111111111111111", # Visa card "3" => "000000" } result = Router.test_route(message) assert {:ok, routing_info} = result assert routing_info.connector_module == DaProductApp.Switch.Connectors.Visa assert routing_info.routing_logic.card_type == "visa" end test "routes MasterCard using legacy routing" do message = %{ "0" => "0200", "2" => "5555555555554444", # MasterCard "3" => "000000" } result = Router.test_route(message) assert {:ok, routing_info} = result assert routing_info.connector_module == DaProductApp.Switch.Connectors.Master assert routing_info.routing_logic.card_type == "mastercard" end test "routes purchase transactions to Master" do message = %{ "0" => "0200", "2" => "9999999999999999", # Unknown card type "3" => "000000" # Purchase } result = Router.test_route(message) assert {:ok, routing_info} = result assert routing_info.connector_module == DaProductApp.Switch.Connectors.Master assert String.contains?(routing_info.routing_logic.routing_reason, "Purchase") end test "routes cash withdrawal to Master" do message = %{ "0" => "0200", "2" => "9999999999999999", "3" => "010000" # Cash withdrawal } result = Router.test_route(message) assert {:ok, routing_info} = result assert routing_info.connector_module == DaProductApp.Switch.Connectors.Master assert String.contains?(routing_info.routing_logic.routing_reason, "Cash withdrawal") end test "routes balance inquiry to Master" do message = %{ "0" => "0200", "2" => "9999999999999999", "3" => "310000" # Balance inquiry } result = Router.test_route(message) assert {:ok, routing_info} = result assert routing_info.connector_module == DaProductApp.Switch.Connectors.Master assert String.contains?(routing_info.routing_logic.routing_reason, "Balance inquiry") end test "routes unknown card types to fallback" do message = %{ "0" => "0200", "2" => "9999999999999999", # Unknown BIN "3" => "999999" # Unknown processing code } result = Router.test_route(message) assert {:ok, routing_info} = result assert routing_info.connector_module == DaProductApp.Switch.Connectors.Fallback assert String.contains?(routing_info.routing_logic.routing_reason, "Default fallback") end test "detects card types correctly" do test_cases = [ {"4111111111111111", "visa"}, {"5555555555554444", "mastercard"}, {"2223000048400011", "mastercard"}, # New MasterCard range {"378282246310005", "amex"}, {"371449635398431", "amex"}, {"6011111111111117", "discover"}, {"30569309025904", "diners"}, {"35000000000001", "jcb"}, {"9999999999999999", "unknown"} ] for {pan, expected_type} do message = %{"0" => "0200", "2" => pan, "3" => "999999"} {:ok, routing_info} = Router.test_route(message) assert routing_info.routing_logic.card_type == expected_type end end test "identifies transaction types correctly" do test_cases = [ {"000000", :purchase}, {"010000", :cash_withdrawal}, {"200000", :refund}, {"310000", :balance_inquiry}, {"400000", :transfer}, {"999999", :unknown} ] for {processing_code, expected_type} do actual_type = Router.get_transaction_type(processing_code) assert actual_type == expected_type end end test "identifies network management messages" do network_mgmt_message = %{"0" => "0800"} transaction_message = %{"0" => "0200"} assert Router.is_network_management?(network_mgmt_message) == true assert Router.is_network_management?(transaction_message) == false end test "identifies transaction requests" do transaction_message = %{"0" => "0200"} reversal_message = %{"0" => "0400"} network_mgmt_message = %{"0" => "0800"} assert Router.is_transaction_request?(transaction_message) == true assert Router.is_transaction_request?(reversal_message) == true assert Router.is_transaction_request?(network_mgmt_message) == false end end describe "Enhanced routing integration" do # These tests would require the enhanced router to be running # For now, we'll test the integration points test "extracts merchant ID from message" do message = %{ "42" => "MERCHANT123", "41" => "TERMINAL1" } # This is testing a private function indirectly through test_route result = Router.test_route(message) assert {:ok, _routing_info} = result end test "builds routing context correctly" do message = %{ "0" => "0200", "2" => "4111111111111111", "3" => "000000", "41" => "TERMINAL1", "42" => "MERCHANT001" } # Test that routing context is built properly (indirectly) result = Router.test_route(message) assert {:ok, _routing_info} = result end test "maps enhanced connectors to legacy modules" do # This tests the mapping function indirectly # The actual mapping happens during enhanced routing message = %{ "0" => "0200", "2" => "4111111111111111", "3" => "000000" } result = Router.test_route(message) assert {:ok, routing_info} = result assert is_atom(routing_info.connector_module) end end describe "Error handling" do test "handles invalid message format gracefully" do invalid_message = %{} result = Router.test_route(invalid_message) assert {:ok, routing_info} = result # Should route to fallback for invalid messages assert routing_info.connector_module == DaProductApp.Switch.Connectors.Fallback end test "handles missing fields gracefully" do message = %{"0" => "0200"} # Missing PAN and processing code result = Router.test_route(message) assert {:ok, routing_info} = result # Should handle gracefully with defaults end test "handles nil values gracefully" do message = %{ "0" => "0200", "2" => nil, "3" => nil } result = Router.test_route(message) assert {:ok, routing_info} = result end end end