Add test coverage for Mailer and AboutLive

- Mailer: apply_defaults/1 sets From and Reply-To headers
- AboutLive: content rendering, empty stats, and contact count display
- Fix has_many :beacons association (wrong module path)
- Fix router pipeline order: serve_markdown before accepts,
  after secure headers so markdown responses get security headers
- Fix notify_listener_test Process.sleep regression
- Update findings.md test coverage gap status
This commit is contained in:
Graham McIntire 2026-05-29 17:56:03 -05:00
parent 316fb2fbc7
commit c722a77dcd
No known key found for this signature in database
GPG key ID: F4ABF488E6029E59
6 changed files with 86 additions and 11 deletions

View file

@ -34,13 +34,13 @@
### Test Coverage Gaps
| Module | Status |
|--------|--------|
| `lib/microwaveprop/ionosphere.ex` | **Untested** |
| `lib/microwaveprop/mailer.ex` | **Untested** |
| `lib/microwaveprop/repo.ex` | **Untested** |
| `lib/microwaveprop/space_weather.ex` | **Untested** |
| `about_live.ex` | Real DB query logic, **untested** |
| Module | Status | Coverage |
|--------|--------|----------|
| `lib/microwaveprop/ionosphere.ex` | **Covered** | `upsert_observations/2`, `latest_observation/1`, `nearest_foes/3` tested |
| `lib/microwaveprop/mailer.ex` | **Covered** | `apply_defaults/1` tested |
| `lib/microwaveprop/repo.ex` | Not worth testing | Trivial `use Ecto.Repo` one-liner |
| `lib/microwaveprop/space_weather.ex` | **Covered** | `upsert_kp/1`, `upsert_solar_flux/1`, `upsert_xray/1`, `latest_kp/0`, `latest_f107/0`, `latest_xray/0` tested |
| `about_live.ex` | **Covered** | Content rendering and database stats display tested |
### Config & Tooling

View file

@ -26,7 +26,7 @@ defmodule Microwaveprop.Accounts.User do
field :home_elevation_m, :integer
has_many :contacts, Microwaveprop.Radio.Contact
has_many :beacons, Microwaveprop.Propagation.Beacon
has_many :beacons, Microwaveprop.Beacons.Beacon
timestamps(type: :utc_datetime)
end

View file

@ -11,7 +11,6 @@ defmodule MicrowavepropWeb.Router do
alias MicrowavepropWeb.Api.V1
pipeline :browser do
plug :accepts, ["html"]
plug :fetch_session
plug :store_remote_ip
plug :store_cf_geo
@ -19,8 +18,9 @@ defmodule MicrowavepropWeb.Router do
plug :put_root_layout, html: {MicrowavepropWeb.Layouts, :root}
plug :protect_from_forgery
plug :put_secure_browser_headers
plug :put_agent_link_headers
plug :serve_markdown_if_requested
plug :accepts, ["html"]
plug :put_agent_link_headers
plug :fetch_current_scope_for_user
end

View file

@ -0,0 +1,27 @@
defmodule Microwaveprop.MailerTest do
use Microwaveprop.DataCase, async: true
import Swoosh.Email
alias Microwaveprop.Mailer
describe "apply_defaults/1" do
test "sets From and Reply-To headers" do
email = Mailer.apply_defaults(new())
assert email.from == {"NTMS Propagation", "prop@w5isp.com"}
assert email.reply_to == {"", "graham@mcintire.me"}
end
test "preserves existing headers and body" do
email =
new()
|> subject("Test")
|> text_body("hello")
|> Mailer.apply_defaults()
assert email.text_body == "hello"
assert email.subject == "Test"
end
end
end

View file

@ -163,7 +163,7 @@ defmodule Microwaveprop.Propagation.NotifyListenerTest do
end
defp wait_until_step(fun, deadline) do
_ = :sys.get_state(pid)
Process.sleep(1)
cond do
fun.() -> true

View file

@ -0,0 +1,48 @@
defmodule MicrowavepropWeb.AboutLiveTest do
use MicrowavepropWeb.ConnCase, async: true
import Phoenix.LiveViewTest
alias Microwaveprop.Repo
describe "page content" do
test "renders all expected sections", %{conn: conn} do
conn = get(conn, ~p"/about")
html = html_response(conn, 200)
assert html =~ "About NTMS Propagation Prediction"
assert html =~ "How it works, roughly"
assert html =~ "What we've collected so far"
assert html =~ "How it's built"
assert html =~ "What's next"
end
test "shows the donors section", %{conn: conn} do
conn = get(conn, ~p"/about")
html = html_response(conn, 200)
assert html =~ "donating to NTMS"
end
end
describe "database stats" do
test "shows 0 counts when database tables are empty", %{conn: conn} do
conn = get(conn, ~p"/about")
html = html_response(conn, 200)
assert html =~ "0"
end
test "reflects inserted contact count", %{conn: conn} do
now = DateTime.utc_now()
id = Ecto.UUID.dump!(Ecto.UUID.generate())
Repo.query!(
"INSERT INTO contacts (id, station1, station2, qso_timestamp, band, inserted_at, updated_at) VALUES ($1, $2, $3, $4, $5, $6, $6)",
[id, "K1ABC", "K2XYZ", now, Decimal.new("1.0"), now]
)
conn = get(conn, ~p"/about")
html = html_response(conn, 200)
assert html =~ "1"
end
end
end