From 62c9600f675914a163a6626d2c1b10a5a82bc048 Mon Sep 17 00:00:00 2001 From: Graham McIntire Date: Mon, 6 Apr 2026 10:13:46 -0500 Subject: [PATCH] Add Tier 2 test coverage: SolarIndexWorker, HrrrFetchWorker, IemClient MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SolarIndexWorker 36→100% (date-arg clause), HrrrFetchWorker 38→42% (batch skip, backoff), IemClient 65→74% (fetch_current_asos). --- .../microwaveprop/weather/iem_client_test.exs | 41 +++++++++++++++++++ .../workers/hrrr_fetch_worker_test.exs | 28 +++++++++++++ .../workers/solar_index_worker_test.exs | 22 ++++++++++ 3 files changed, 91 insertions(+) diff --git a/test/microwaveprop/weather/iem_client_test.exs b/test/microwaveprop/weather/iem_client_test.exs index 0e68cdfe..eddac93c 100644 --- a/test/microwaveprop/weather/iem_client_test.exs +++ b/test/microwaveprop/weather/iem_client_test.exs @@ -223,6 +223,47 @@ defmodule Microwaveprop.Weather.IemClientTest do end end + describe "fetch_current_asos/1" do + test "returns parsed observations from multiple networks" do + Req.Test.stub(IemClient, fn conn -> + Req.Test.json(conn, %{ + "data" => [ + %{ + "station" => "KDFW", + "lat" => 32.9, + "lon" => -97.0, + "utc_valid" => "2026-03-28T18:00:00Z", + "tmpf" => 75.0, + "dwpf" => 55.0, + "sknt" => 10, + "skyc1" => "CLR", + "mslp" => 1013.2, + "alti" => 29.92, + "phour" => 0.0 + } + ] + }) + end) + + assert {:ok, observations} = IemClient.fetch_current_asos(["TX_ASOS"]) + assert length(observations) == 1 + assert hd(observations).station_code == "KDFW" + assert hd(observations).temp_f == 75.0 + end + + test "skips observations with missing core data" do + Req.Test.stub(IemClient, fn conn -> + Req.Test.json(conn, %{ + "data" => [ + %{"station" => "KDFW", "lat" => nil, "lon" => nil, "tmpf" => nil, "dwpf" => nil} + ] + }) + end) + + assert {:ok, []} = IemClient.fetch_current_asos(["TX_ASOS"]) + end + end + describe "parse_network_json/1" do test "parses station list from network JSON response" do json = %{ diff --git a/test/microwaveprop/workers/hrrr_fetch_worker_test.exs b/test/microwaveprop/workers/hrrr_fetch_worker_test.exs index 20aa6ea1..ff633280 100644 --- a/test/microwaveprop/workers/hrrr_fetch_worker_test.exs +++ b/test/microwaveprop/workers/hrrr_fetch_worker_test.exs @@ -89,6 +89,34 @@ defmodule Microwaveprop.Workers.HrrrFetchWorkerTest do end end + describe "perform/1 batch mode" do + test "skips all points when profiles already exist" do + Weather.upsert_hrrr_profile(%{ + valid_time: ~U[2026-03-28 18:00:00Z], + lat: 32.90, + lon: -97.04, + profile: @sample_profile + }) + + job = %Oban.Job{ + args: %{ + "points" => [%{"lat" => 32.90, "lon" => -97.04}], + "valid_time" => "2026-03-28T18:00:00Z" + } + } + + assert :ok = HrrrFetchWorker.perform(job) + end + end + + describe "backoff/1" do + test "returns exponential backoff capped at 6 hours" do + assert HrrrFetchWorker.backoff(%Oban.Job{attempt: 1}) == 120 + assert HrrrFetchWorker.backoff(%Oban.Job{attempt: 2}) == 240 + assert HrrrFetchWorker.backoff(%Oban.Job{attempt: 10}) <= 21_600 + end + end + describe "permanent_failure?/1" do test "cancels on 404 idx" do job = %Oban.Job{ diff --git a/test/microwaveprop/workers/solar_index_worker_test.exs b/test/microwaveprop/workers/solar_index_worker_test.exs index 2a09c7a7..da06662a 100644 --- a/test/microwaveprop/workers/solar_index_worker_test.exs +++ b/test/microwaveprop/workers/solar_index_worker_test.exs @@ -46,4 +46,26 @@ defmodule Microwaveprop.Workers.SolarIndexWorkerTest do assert Repo.aggregate(SolarIndex, :count) == 2 end end + + describe "perform/1 with date arg" do + test "fetches and upserts only the matching date" do + today = Date.utc_today() |> Date.to_iso8601() + + Req.Test.stub(SolarClient, fn conn -> + Req.Test.text(conn, gfz_body_with_recent_dates()) + end) + + assert :ok = SolarIndexWorker.perform(%Oban.Job{args: %{"date" => today}}) + assert Repo.aggregate(SolarIndex, :count) == 1 + end + + test "returns error when HTTP request fails" do + Req.Test.stub(SolarClient, fn conn -> + Plug.Conn.send_resp(conn, 500, "Internal Server Error") + end) + + today = Date.utc_today() |> Date.to_iso8601() + assert {:error, "HTTP 500"} = SolarIndexWorker.perform(%Oban.Job{args: %{"date" => today}}) + end + end end