defmodule Microwaveprop.Radio.AdifImportTest do use Microwaveprop.DataCase, async: true alias Microwaveprop.Radio.AdifImport alias Microwaveprop.Terrain.ElevationClient alias Microwaveprop.Weather.HrrrClient alias Microwaveprop.Weather.IemClient setup do Req.Test.stub(IemClient, fn conn -> case conn.request_path do "/cgi-bin/request/asos.py" -> Req.Test.text(conn, "#DEBUG,\nstation,valid,tmpf\n") _ -> Req.Test.json(conn, %{"profiles" => []}) end end) Req.Test.stub(HrrrClient, fn conn -> Plug.Conn.send_resp(conn, 404, "not found") end) Req.Test.stub(ElevationClient, fn conn -> params = Plug.Conn.fetch_query_params(conn).query_params lat_count = params["latitude"] |> String.split(",") |> length() Req.Test.json(conn, %{"elevation" => List.duplicate(200.0, lat_count)}) end) :ok end @submitter "test@example.com" @valid_adif """ W5XDK5TREM00EM1210368.000CW20260328180000 """ describe "preview/2" do test "parses a valid ADIF record" do assert {:ok, preview} = AdifImport.preview(@valid_adif, @submitter) assert length(preview.valid) == 1 assert preview.invalid == [] assert preview.duplicates == [] [row] = preview.valid assert row.attrs["station1"] == "W5XD" assert row.attrs["station2"] == "K5TR" assert row.attrs["grid1"] == "EM12" assert row.attrs["grid2"] == "EM00" assert row.attrs["band"] == "10000" assert row.attrs["mode"] == "CW" end test "parses ADIF with BAND field instead of FREQ" do adif = """ W5XDK5TREM00EM1223cmCW20260328180000 """ assert {:ok, preview} = AdifImport.preview(adif, @submitter) assert [row] = preview.valid assert row.attrs["band"] == "1296" end test "maps ADIF frequency to correct band" do for {freq, expected_band} <- [ {"1296.200", "1296"}, {"2304.000", "2304"}, {"5760.100", "5760"}, {"10368.000", "10000"}, {"24192.000", "24000"}, {"47088.000", "47000"}, {"76032.000", "75000"} ] do adif = """ W5XDK5TREM00EM12#{freq}CW20260328180000 """ assert {:ok, preview} = AdifImport.preview(adif, @submitter) assert [row] = preview.valid assert row.attrs["band"] == expected_band, "FREQ #{freq} should map to band #{expected_band}, got #{row.attrs["band"]}" end end test "handles multiple records" do adif = """ W5XDK5TREM00EM1210368.000CW20260328180000 W5XDN5DUPEM13EM1210368.000SSB20260328190000 """ assert {:ok, preview} = AdifImport.preview(adif, @submitter) assert length(preview.valid) == 2 end test "skips ADIF header before " do adif = """ ADIF Export from Logger32 3.1.4 Logger32 W5XDK5TREM00EM1210368.000CW20260328180000 """ assert {:ok, preview} = AdifImport.preview(adif, @submitter) assert length(preview.valid) == 1 end test "returns error for empty ADIF" do assert {:error, :no_records} = AdifImport.preview("", @submitter) end test "returns error for header-only ADIF" do adif = """ ADIF Export 3.1.4 """ assert {:error, :no_records} = AdifImport.preview(adif, @submitter) end test "marks record invalid when missing required fields" do adif = """ K5TRCW20260328180000 """ assert {:ok, preview} = AdifImport.preview(adif, @submitter) assert preview.valid == [] assert length(preview.invalid) == 1 end test "skips non-microwave contacts" do adif = """ W5XDK5TREM00EM12144.200CW20260328180000 """ assert {:ok, preview} = AdifImport.preview(adif, @submitter) assert preview.valid == [] assert length(preview.invalid) == 1 end test "deduplicates against existing DB contacts" do # Insert one via CSV import path {:ok, _} = Microwaveprop.Radio.create_contact(%{ station1: "W5XD", station2: "K5TR", grid1: "EM12", grid2: "EM00", band: "10000", mode: "CW", qso_timestamp: ~U[2026-03-28 18:00:00Z], submitter_email: @submitter }) assert {:ok, preview} = AdifImport.preview(@valid_adif, @submitter) assert preview.valid == [] assert length(preview.duplicates) == 1 end test "is case-insensitive for field names" do adif = """ W5XDK5TREM00EM1210368.000CW20260328180000 """ assert {:ok, preview} = AdifImport.preview(adif, @submitter) assert length(preview.valid) == 1 end test "handles TIME_ON with 4 digits (HHMM)" do adif = """ W5XDK5TREM00EM1210368.000CW202603281800 """ assert {:ok, preview} = AdifImport.preview(adif, @submitter) assert [row] = preview.valid assert row.timestamp == ~U[2026-03-28 18:00:00Z] end test "uses OPERATOR field when STATION_CALLSIGN is missing" do adif = """ W5XDK5TREM00EM1210368.000CW20260328180000 """ assert {:ok, preview} = AdifImport.preview(adif, @submitter) assert [row] = preview.valid assert row.attrs["station1"] == "W5XD" end end end