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.
111 lines
3.2 KiB
Elixir
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
|