defmodule Mix.Tasks.Geoip.ImportUnitTest do use ExUnit.Case, async: true alias Mix.Tasks.Geoip.Import describe "parse_geoname_id/1" do test "empty string returns nil" do assert nil == Import.parse_geoname_id("") end test "valid integer returns the integer" do assert 12_345 == Import.parse_geoname_id("12345") end test "invalid format returns nil" do assert nil == Import.parse_geoname_id("abc") end test "partial integer parses leading number" do assert 123 == Import.parse_geoname_id("123abc") end end describe "parse_cidr/1" do test "valid IPv4 /24 CIDR" do assert {:ok, start_int, end_int} = Import.parse_cidr("192.168.1.0/24") # 192.168.1.0 = 3232235776 assert start_int == 3_232_235_776 # 192.168.1.255 = 3232236031 assert end_int == 3_232_236_031 assert end_int - start_int == 255 end test "valid /32 host address" do assert {:ok, same, same} = Import.parse_cidr("10.0.0.1/32") assert same == 10 * 16_777_216 + 1 end test "valid /0 full range" do assert {:ok, 0, end_int} = Import.parse_cidr("0.0.0.0/0") assert end_int == 4_294_967_295 end test "invalid CIDR returns :error" do assert :error == Import.parse_cidr("not a cidr") assert :error == Import.parse_cidr("192.168.1.0") assert :error == Import.parse_cidr("256.256.256.256/24") end end describe "parse_block_line/1" do test "well-formed line with geoname_id" do line = "192.168.1.0/24,12345,67890,,,,0,1,,\n" result = Import.parse_block_line(line) assert result.network == "192.168.1.0/24" assert result.geoname_id == 12_345 assert result.registered_country_geoname_id == 67_890 end test "empty geoname_id falls back to registered" do line = "192.168.1.0/24,,67890,,,,,,,\n" result = Import.parse_block_line(line) assert result.geoname_id == 67_890 assert result.registered_country_geoname_id == 67_890 end test "both empty returns nil" do line = "192.168.1.0/24,,,,,,,,,\n" assert nil == Import.parse_block_line(line) end test "malformed line returns nil" do assert nil == Import.parse_block_line("no commas\n") end test "invalid CIDR returns nil" do line = "not-a-cidr,12345,67890,,\n" assert nil == Import.parse_block_line(line) end end describe "parse_location_line/1" do test "parses a standard location row" do line = "5332921,en,NA,North America,US,United States,CA,California,,,San Jose,,America/Los_Angeles,false" result = Import.parse_location_line(line) assert result.geoname_id == 5_332_921 assert result.country_code == "US" assert result.country_name == "United States" assert result.city_name == "San Jose" assert result.subdivision_1_name == "California" end test "empty city becomes nil" do line = "5332921,en,NA,North America,US,United States,CA,California,,,,,,false" result = Import.parse_location_line(line) assert result.city_name == nil end test "missing country_code skips the row" do line = "5332921,en,NA,,,United States,CA,California,,,San Jose,,tz,false" assert nil == Import.parse_location_line(line) end test "missing geoname_id skips the row" do line = ",en,NA,North America,US,United States,CA,California,,,San Jose,,tz,false" assert nil == Import.parse_location_line(line) end test "malformed short line returns nil" do assert nil == Import.parse_location_line("too,few,fields") end end describe "build_block_entry/3" do test "nil geoname_id returns nil" do assert nil == Import.build_block_entry("192.168.1.0/24", nil, 67_890) end test "invalid CIDR returns nil" do assert nil == Import.build_block_entry("garbage", 12_345, 67_890) end test "valid inputs produce a complete entry" do entry = Import.build_block_entry("10.0.0.0/8", 12_345, 67_890) assert entry.network == "10.0.0.0/8" assert entry.geoname_id == 12_345 assert entry.registered_country_geoname_id == 67_890 assert entry.start_ip_int < entry.end_ip_int end end end