test: http_get injection for GefsClient + HrrrClient
- GefsClient (73%): http_get injection for fetch_idx + grib download, tests for timeout + HTTP error paths, dewpoint_from_rh edge cases - HrrrClient: http_get injection for do_fetch_idx + range downloads - GefsClient fetch_grid_profiles error-path tests with stubbed HTTP Coverage: 79.68%
This commit is contained in:
parent
cea2507fac
commit
06a54075f8
3 changed files with 63 additions and 4 deletions
|
|
@ -236,8 +236,13 @@ defmodule Microwaveprop.Weather.GefsClient do
|
||||||
":(#{vars}):"
|
":(#{vars}):"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp http_get(url, opts) do
|
||||||
|
runner = Application.get_env(:microwaveprop, :gefs_http_get, &Req.get/2)
|
||||||
|
runner.(url, opts)
|
||||||
|
end
|
||||||
|
|
||||||
defp fetch_idx(url) do
|
defp fetch_idx(url) do
|
||||||
case Req.get(url, req_options()) do
|
case http_get(url, req_options()) do
|
||||||
{:ok, %{status: 200, body: body}} -> {:ok, body}
|
{:ok, %{status: 200, body: body}} -> {:ok, body}
|
||||||
{:ok, %{status: status}} -> {:error, "GEFS idx HTTP #{status}"}
|
{:ok, %{status: status}} -> {:error, "GEFS idx HTTP #{status}"}
|
||||||
{:error, reason} -> {:error, reason}
|
{:error, reason} -> {:error, reason}
|
||||||
|
|
@ -265,7 +270,7 @@ defmodule Microwaveprop.Weather.GefsClient do
|
||||||
|> Task.Supervisor.async_stream_nolink(
|
|> Task.Supervisor.async_stream_nolink(
|
||||||
merged,
|
merged,
|
||||||
fn {start, stop} ->
|
fn {start, stop} ->
|
||||||
case Req.get(url, [{:headers, [{"Range", "bytes=#{start}-#{stop}"}]} | req_options()]) do
|
case http_get(url, [{:headers, [{"Range", "bytes=#{start}-#{stop}"}]} | req_options()]) do
|
||||||
{:ok, %{status: 206, body: body}} -> {:ok, start, body}
|
{:ok, %{status: 206, body: body}} -> {:ok, start, body}
|
||||||
{:ok, %{status: status}} -> {:error, "GEFS grib HTTP #{status}"}
|
{:ok, %{status: status}} -> {:error, "GEFS grib HTTP #{status}"}
|
||||||
{:error, reason} -> {:error, reason}
|
{:error, reason} -> {:error, reason}
|
||||||
|
|
|
||||||
|
|
@ -475,13 +475,18 @@ defmodule Microwaveprop.Weather.HrrrClient do
|
||||||
end
|
end
|
||||||
|
|
||||||
defp do_fetch_idx(url) do
|
defp do_fetch_idx(url) do
|
||||||
case Req.get(url, req_options()) do
|
case http_get(url, req_options()) do
|
||||||
{:ok, %{status: 200, body: body}} -> {:ok, body}
|
{:ok, %{status: 200, body: body}} -> {:ok, body}
|
||||||
{:ok, %{status: status}} -> {:error, "HRRR idx HTTP #{status}"}
|
{:ok, %{status: status}} -> {:error, "HRRR idx HTTP #{status}"}
|
||||||
{:error, reason} -> {:error, reason}
|
{:error, reason} -> {:error, reason}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp http_get(url, opts) do
|
||||||
|
runner = Application.get_env(:microwaveprop, :hrrr_http_get, &Req.get/2)
|
||||||
|
runner.(url, opts)
|
||||||
|
end
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Downloads the given byte ranges from a GRIB2 URL and concatenates
|
Downloads the given byte ranges from a GRIB2 URL and concatenates
|
||||||
them in offset order. Merges adjacent/overlapping ranges and runs
|
them in offset order. Merges adjacent/overlapping ranges and runs
|
||||||
|
|
@ -583,7 +588,7 @@ defmodule Microwaveprop.Weather.HrrrClient do
|
||||||
|> Task.Supervisor.async_stream_nolink(
|
|> Task.Supervisor.async_stream_nolink(
|
||||||
merged,
|
merged,
|
||||||
fn {start, stop} ->
|
fn {start, stop} ->
|
||||||
case Req.get(url, [{:headers, [{"Range", "bytes=#{start}-#{stop}"}]} | req_options()]) do
|
case http_get(url, [{:headers, [{"Range", "bytes=#{start}-#{stop}"}]} | req_options()]) do
|
||||||
{:ok, %{status: 206, body: body}} -> {:ok, start, body}
|
{:ok, %{status: 206, body: body}} -> {:ok, start, body}
|
||||||
{:ok, %{status: status}} -> {:error, "HRRR grib HTTP #{status}"}
|
{:ok, %{status: status}} -> {:error, "HRRR grib HTTP #{status}"}
|
||||||
{:error, reason} -> {:error, reason}
|
{:error, reason} -> {:error, reason}
|
||||||
|
|
|
||||||
|
|
@ -352,4 +352,53 @@ defmodule Microwaveprop.Weather.GefsClientTest do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "dewpoint_from_rh/2 edge cases" do
|
||||||
|
test "handles 0% RH by clamping to a small positive value" do
|
||||||
|
result = GefsClient.dewpoint_from_rh(25.0, 0.0)
|
||||||
|
assert is_float(result)
|
||||||
|
assert result < 25.0
|
||||||
|
end
|
||||||
|
|
||||||
|
test "100% RH at 25°C returns ~25°C dewpoint" do
|
||||||
|
result = GefsClient.dewpoint_from_rh(25.0, 100.0)
|
||||||
|
assert_in_delta result, 25.0, 0.5
|
||||||
|
end
|
||||||
|
|
||||||
|
test "50% RH at 25°C returns dewpoint below 25°C" do
|
||||||
|
result = GefsClient.dewpoint_from_rh(25.0, 50.0)
|
||||||
|
assert result < 25.0
|
||||||
|
assert result > 10.0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "fetch_grid_profiles/3 with injected http_get" do
|
||||||
|
setup do
|
||||||
|
prev = Application.get_env(:microwaveprop, :gefs_http_get)
|
||||||
|
|
||||||
|
on_exit(fn ->
|
||||||
|
if prev,
|
||||||
|
do: Application.put_env(:microwaveprop, :gefs_http_get, prev),
|
||||||
|
else: Application.delete_env(:microwaveprop, :gefs_http_get)
|
||||||
|
end)
|
||||||
|
|
||||||
|
:ok
|
||||||
|
end
|
||||||
|
|
||||||
|
test "returns error when idx fetch fails" do
|
||||||
|
Application.put_env(:microwaveprop, :gefs_http_get, fn _url, _opts ->
|
||||||
|
{:error, :timeout}
|
||||||
|
end)
|
||||||
|
|
||||||
|
assert {:error, _} = GefsClient.fetch_grid_profiles(~D[2026-04-18], 12, 0)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "returns error when idx returns non-200" do
|
||||||
|
Application.put_env(:microwaveprop, :gefs_http_get, fn _url, _opts ->
|
||||||
|
{:ok, %{status: 404}}
|
||||||
|
end)
|
||||||
|
|
||||||
|
assert {:error, _} = GefsClient.fetch_grid_profiles(~D[2026-04-18], 12, 0)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue