- Add precip_1h_in and wx_codes fields to ASOS surface observations - Add IEMRE reanalysis schema for radar-derived hourly precipitation - Add IemreFetchWorker with exponential backoff and idempotency - Integrate IEMRE enqueue into cron weather backfill pipeline - All existing QSOs marked iemre_queued=false for automatic backfill
83 lines
2.5 KiB
Elixir
83 lines
2.5 KiB
Elixir
defmodule Microwaveprop.Weather.SurfaceObservationTest do
|
|
use Microwaveprop.DataCase, async: true
|
|
|
|
alias Microwaveprop.Weather.Station
|
|
alias Microwaveprop.Weather.SurfaceObservation
|
|
|
|
defp create_station do
|
|
%Station{}
|
|
|> Station.changeset(%{
|
|
station_code: "KDFW",
|
|
station_type: "asos",
|
|
name: "Dallas/Fort Worth International",
|
|
lat: 32.8998,
|
|
lon: -97.0403
|
|
})
|
|
|> Repo.insert!()
|
|
end
|
|
|
|
@valid_obs_attrs %{
|
|
observed_at: ~U[2026-03-28 18:00:00Z],
|
|
temp_f: 75.0,
|
|
dewpoint_f: 55.0,
|
|
relative_humidity: 49.0,
|
|
wind_speed_kts: 12.0,
|
|
wind_direction_deg: 180,
|
|
sea_level_pressure_mb: 1013.25,
|
|
altimeter_setting: 29.92,
|
|
sky_condition: "SCT",
|
|
precip_1h_in: 0.03,
|
|
wx_codes: "RA"
|
|
}
|
|
|
|
describe "changeset/2" do
|
|
test "valid attributes with station_id" do
|
|
station = create_station()
|
|
attrs = Map.put(@valid_obs_attrs, :station_id, station.id)
|
|
changeset = SurfaceObservation.changeset(%SurfaceObservation{}, attrs)
|
|
assert changeset.valid?
|
|
end
|
|
|
|
test "requires station_id and observed_at" do
|
|
changeset = SurfaceObservation.changeset(%SurfaceObservation{}, %{})
|
|
|
|
assert %{
|
|
station_id: ["can't be blank"],
|
|
observed_at: ["can't be blank"]
|
|
} = errors_on(changeset)
|
|
end
|
|
|
|
test "all weather fields are optional" do
|
|
station = create_station()
|
|
|
|
attrs = %{
|
|
station_id: station.id,
|
|
observed_at: ~U[2026-03-28 18:00:00Z]
|
|
}
|
|
|
|
changeset = SurfaceObservation.changeset(%SurfaceObservation{}, attrs)
|
|
assert changeset.valid?
|
|
end
|
|
|
|
test "persists to the database" do
|
|
station = create_station()
|
|
attrs = Map.put(@valid_obs_attrs, :station_id, station.id)
|
|
changeset = SurfaceObservation.changeset(%SurfaceObservation{}, attrs)
|
|
assert {:ok, obs} = Repo.insert(changeset)
|
|
assert obs.temp_f == 75.0
|
|
assert obs.sky_condition == "SCT"
|
|
assert obs.precip_1h_in == 0.03
|
|
assert obs.wx_codes == "RA"
|
|
assert obs.station_id == station.id
|
|
end
|
|
|
|
test "enforces unique station_id + observed_at" do
|
|
station = create_station()
|
|
attrs = Map.put(@valid_obs_attrs, :station_id, station.id)
|
|
|
|
assert {:ok, _} = %SurfaceObservation{} |> SurfaceObservation.changeset(attrs) |> Repo.insert()
|
|
assert {:error, changeset} = %SurfaceObservation{} |> SurfaceObservation.changeset(attrs) |> Repo.insert()
|
|
assert %{station_id: ["has already been taken"]} = errors_on(changeset)
|
|
end
|
|
end
|
|
end
|