defmodule Microwaveprop.Workers.PropagationGridWorkerTest do @moduledoc """ Tests the chain-orchestration behavior of PropagationGridWorker. The worker processes forecast hours f00–f18 across the CONUS grid, but a single full sweep takes ~2 hours of wall time — longer than a typical pod restart window. To survive deploys, the worker processes ONE forecast hour per `perform/1` call and enqueues the next hour as a fresh Oban job. The tests here cover the dispatch + chain logic without mocking the full HRRR / scoring stack. """ use Microwaveprop.DataCase, async: false use Oban.Testing, repo: Microwaveprop.Repo alias Microwaveprop.Workers.PropagationGridWorker alias Microwaveprop.Workers.PropagationPruneWorker describe "queue priority" do test "PropagationGridWorker runs at the highest priority on :propagation" do assert PropagationGridWorker.__opts__()[:priority] == 0 end test "PropagationPruneWorker yields to the grid chain" do # Same :propagation queue — must be lower priority so hourly chain # steps jump ahead of a pruner backlog. assert PropagationPruneWorker.__opts__()[:priority] > 0 end end describe "compute_scores_algorithm/3" do test "accepts a map of {{lat, lon} => profile} without raising" do # grid_data is a map keyed by {lat, lon}, not a list. # A regression guard against using length/1 on the map. valid_time = ~U[2026-04-19 15:00:00Z] assert [] = PropagationGridWorker.compute_scores_algorithm( %{}, valid_time, false ) end end describe "perform/1 — chain seeding (empty args)" do test "enqueues only f00 in Oban; f01..f18 go to grid_tasks for Rust" do Oban.Testing.with_testing_mode(:manual, fn -> import Ecto.Query assert :ok = PropagationGridWorker.perform(%Oban.Job{args: %{}}) jobs = all_enqueued(worker: PropagationGridWorker) assert length(jobs) == 1 [job] = jobs assert job.args["forecast_hour"] == 0 # run_time is normalized to top-of-hour UTC. {:ok, dt, _} = DateTime.from_iso8601(job.args["run_time"]) assert dt.minute == 0 assert dt.second == 0 assert DateTime.before?(dt, DateTime.utc_now()) # The Rust worker picks up f01..f18 from the grid_tasks table. task_fhs = Microwaveprop.Repo.all( from t in "grid_tasks", where: t.run_time == ^DateTime.truncate(dt, :second), select: t.forecast_hour, order_by: t.forecast_hour ) assert task_fhs == Enum.to_list(1..18) end) end end end