prop/test/microwaveprop/weather/sounding_test.exs
Graham McIntire 079346a1b9
Some checks failed
Build and Push / Build and Push Docker Image (push) Failing after 4m38s
fix: resolve all 281 credo issues across source and test files
- F-level (228): replace length/1 with Enum.count_until/2 or pattern
  matching; convert Enum.flat_map+if to Enum.filter+Enum.map; fix
  identity case in narr_client
- W-level (46): normalize dual atom/string key access in weather_layers,
  beacon_measurements, surface, skewt_live, contact_live/show; add
  :data_provider and weather-map assigns to ignored_assigns in credo
  config (consumed by child components credo can't trace); remove
  weak is_list assertion; remove explicit assert_receive timeout
- R-level (6): replace 'This module provides...' moduledocs with
  meaningful descriptions
- Also fix 4 compile-connected xref issues by deferring
  BandConfig.band_options() from module attribute to runtime

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-29 09:04:21 -05:00

115 lines
3.7 KiB
Elixir

defmodule Microwaveprop.Weather.SoundingTest do
use Microwaveprop.DataCase, async: true
alias Microwaveprop.Weather.Sounding
alias Microwaveprop.Weather.Station
defp create_sounding_station do
%Station{}
|> Station.changeset(%{
station_code: "FWD",
station_type: "sounding",
wmo_number: 72_249,
name: "Fort Worth",
lat: 32.83,
lon: -97.30
})
|> Repo.insert!()
end
@sample_profile [
%{"pres" => 1013.0, "hght" => 171, "tmpc" => 25.0, "dwpc" => 15.0, "drct" => 180, "sknt" => 10},
%{"pres" => 925.0, "hght" => 800, "tmpc" => 20.0, "dwpc" => 12.0, "drct" => 200, "sknt" => 15},
%{"pres" => 850.0, "hght" => 1500, "tmpc" => 15.0, "dwpc" => 8.0, "drct" => 220, "sknt" => 20}
]
@valid_sounding_attrs %{
observed_at: ~U[2026-03-28 12:00:00Z],
profile: @sample_profile,
level_count: 3,
surface_pressure_mb: 1013.0,
surface_temp_c: 25.0,
surface_dewpoint_c: 15.0,
surface_refractivity: 320.5,
min_refractivity_gradient: -45.0,
boundary_layer_depth_m: 1200.0,
precipitable_water_mm: 25.0,
k_index: 28.0,
lifted_index: -2.0,
ducting_detected: false,
duct_characteristics: nil
}
describe "changeset/2" do
test "valid attributes with station_id" do
station = create_sounding_station()
attrs = Map.put(@valid_sounding_attrs, :station_id, station.id)
changeset = Sounding.changeset(%Sounding{}, attrs)
assert changeset.valid?
end
test "requires station_id, observed_at, profile, level_count" do
changeset = Sounding.changeset(%Sounding{}, %{})
assert %{
station_id: ["can't be blank"],
observed_at: ["can't be blank"],
profile: ["can't be blank"],
level_count: ["can't be blank"]
} = errors_on(changeset)
end
test "derived params are optional" do
station = create_sounding_station()
attrs = %{
station_id: station.id,
observed_at: ~U[2026-03-28 12:00:00Z],
profile: @sample_profile,
level_count: 3
}
changeset = Sounding.changeset(%Sounding{}, attrs)
assert changeset.valid?
end
test "persists to the database with JSONB profile" do
station = create_sounding_station()
attrs = Map.put(@valid_sounding_attrs, :station_id, station.id)
changeset = Sounding.changeset(%Sounding{}, attrs)
assert {:ok, sounding} = Repo.insert(changeset)
assert Enum.count_until(sounding.profile, 4) == 3
assert hd(sounding.profile)["pres"] == 1013.0
assert sounding.ducting_detected == false
assert sounding.k_index == 28.0
end
test "persists duct_characteristics as JSONB" do
station = create_sounding_station()
duct_chars = [
%{"base" => 200, "top" => 500, "strength" => "5.2"}
]
attrs =
@valid_sounding_attrs
|> Map.put(:station_id, station.id)
|> Map.put(:ducting_detected, true)
|> Map.put(:duct_characteristics, duct_chars)
changeset = Sounding.changeset(%Sounding{}, attrs)
assert {:ok, sounding} = Repo.insert(changeset)
assert sounding.ducting_detected == true
assert [%{"base" => 200, "top" => 500}] = sounding.duct_characteristics
end
test "enforces unique station_id + observed_at" do
station = create_sounding_station()
attrs = Map.put(@valid_sounding_attrs, :station_id, station.id)
assert {:ok, _} = %Sounding{} |> Sounding.changeset(attrs) |> Repo.insert()
assert {:error, changeset} = %Sounding{} |> Sounding.changeset(attrs) |> Repo.insert()
assert %{station_id: ["has already been taken"]} = errors_on(changeset)
end
end
end