towerops/test/towerops/weather/client_test.exs
Graham McIntire 3ca0834ef0 tests: raise coverage to 70% via helper promotion + new unit/property tests
Promoted pure presentation and utility helpers from `defp` to `def @doc false`
across ~20 LiveViews, Oban workers, and sync modules so they're reachable from
unit tests. Refactored several `cond` blocks into idiomatic function heads with
guards. Added ~250 new test cases in new files under test/towerops and
test/towerops_web, including DB-backed tests for CnMaestro.Sync and
AlertNotificationWorker, and removed dead LiveView tab components and
CapacityLive (no callers anywhere in lib/test).

Configured mix.exs test_coverage.ignore_modules to exclude vendored third-party
code (SnmpKit, protobuf-generated Towerops.Agent.*, Absinthe GraphQL types,
Phoenix HTML modules, Inspect protocol impls) from coverage calculations —
these are not our project code.

Coverage: 66.93% → 70.09%. Full suite: 10,127 tests, 0 failures.
2026-04-24 09:49:06 -05:00

111 lines
3.2 KiB
Elixir

defmodule Towerops.Weather.ClientTest do
use ExUnit.Case, async: false
alias Towerops.Weather.Client
@api_key "test-owm-key"
setup do
original = Application.get_env(:towerops, :openweathermap_api_key)
Application.put_env(:towerops, :openweathermap_api_key, @api_key)
on_exit(fn ->
case original do
nil -> Application.delete_env(:towerops, :openweathermap_api_key)
value -> Application.put_env(:towerops, :openweathermap_api_key, value)
end
end)
:ok
end
describe "get_current_weather/3" do
test "returns body on 200" do
response = %{
"weather" => [%{"main" => "Clear"}],
"main" => %{"temp" => 290.0}
}
Req.Test.stub(Client, fn conn ->
assert conn.query_string =~ "lat=40.7"
assert conn.query_string =~ "lon=-74.0"
assert conn.query_string =~ "appid=#{@api_key}"
Req.Test.json(conn, response)
end)
assert {:ok, body} = Client.get_current_weather(40.7, -74.0)
assert body == response
end
test "returns :invalid_api_key on 401" do
Req.Test.stub(Client, fn conn ->
conn
|> Plug.Conn.put_status(401)
|> Req.Test.json(%{"cod" => 401, "message" => "Invalid API key"})
end)
assert {:error, :invalid_api_key} = Client.get_current_weather(40.7, -74.0)
end
test "returns :rate_limited on 429" do
Req.Test.stub(Client, fn conn ->
conn
|> Plug.Conn.put_status(429)
|> Req.Test.json(%{"cod" => 429})
end)
assert {:error, :rate_limited} = Client.get_current_weather(40.7, -74.0)
end
test "returns {:api_error, status} on other non-2xx" do
Req.Test.stub(Client, fn conn ->
conn
|> Plug.Conn.put_status(500)
|> Req.Test.json(%{"cod" => 500})
end)
assert {:error, {:api_error, 500}} = Client.get_current_weather(40.7, -74.0)
end
test "returns :no_api_key when key missing in config" do
Application.delete_env(:towerops, :openweathermap_api_key)
assert {:error, :no_api_key} = Client.get_current_weather(40.7, -74.0)
end
test "returns :no_api_key when key is empty string" do
Application.put_env(:towerops, :openweathermap_api_key, "")
assert {:error, :no_api_key} = Client.get_current_weather(40.7, -74.0)
end
test "accepts api_key option override" do
Req.Test.stub(Client, fn conn ->
assert conn.query_string =~ "appid=override-key"
Req.Test.json(conn, %{})
end)
assert {:ok, _} = Client.get_current_weather(40.7, -74.0, api_key: "override-key")
end
end
describe "test_connection/1" do
test "makes request with provided api key" do
Req.Test.stub(Client, fn conn ->
assert conn.query_string =~ "appid=my-test-key"
assert conn.query_string =~ "lat=51.5074"
Req.Test.json(conn, %{"ok" => true})
end)
assert {:ok, %{"ok" => true}} = Client.test_connection("my-test-key")
end
test "returns :invalid_api_key on 401" do
Req.Test.stub(Client, fn conn ->
conn |> Plug.Conn.put_status(401) |> Req.Test.json(%{})
end)
assert {:error, :invalid_api_key} = Client.test_connection("bad-key")
end
end
end