Adds ~800 new tests (incl. 27 StreamData properties) across 22 modules that previously had little or no coverage. Highlights: - Pure utility modules (LogSanitizer, PacketFieldWhitelist, PacketSanitizer, DeviceParser, CoordinateUtils, BoundsUtils, ParamUtils, Convert, WeatherUnits) get thorough unit + property coverage including UTF-8 truncation boundaries, antimeridian longitude wrap, Haversine symmetry, and unit-conversion inverses. - JSON view modules (CallsignJSON, ErrorJSON, ChangesetJSON) verified for envelope shape and error templating. - Plugs (HealthCheck, RateLimiter, ApiCSRF) exercised for happy-path and halt paths. - GenServer modules (RegexCache, CleanupScheduler, DeploymentNotifier) tested without touching the supervised singleton where possible. - Drops the orphaned map_live/map_helpers_test.exs whose module name collided with the new live/shared/coordinate_utils_test.exs.
89 lines
2.5 KiB
Elixir
89 lines
2.5 KiB
Elixir
defmodule AprsmeWeb.Plugs.ApiCSRFTest do
|
|
use AprsmeWeb.ConnCase, async: true
|
|
|
|
alias AprsmeWeb.Plugs.ApiCSRF
|
|
|
|
test "allows JSON requests with XMLHttpRequest header", %{conn: conn} do
|
|
conn =
|
|
conn
|
|
|> init_test_session(%{})
|
|
|> put_req_header("content-type", "application/json")
|
|
|> put_req_header("x-requested-with", "XMLHttpRequest")
|
|
|> ApiCSRF.call([])
|
|
|
|
refute conn.halted
|
|
end
|
|
|
|
test "rejects JSON requests with arbitrary bearer token", %{conn: conn} do
|
|
conn =
|
|
conn
|
|
|> init_test_session(%{})
|
|
|> put_req_header("content-type", "application/json")
|
|
|> put_req_header("authorization", "Bearer definitely-not-valid")
|
|
|> ApiCSRF.call([])
|
|
|
|
assert conn.halted
|
|
assert conn.status == 403
|
|
assert Jason.decode!(conn.resp_body)["error"] == "CSRF protection failed"
|
|
end
|
|
|
|
test "allows non-JSON requests without CSRF headers", %{conn: conn} do
|
|
conn =
|
|
conn
|
|
|> init_test_session(%{})
|
|
|> put_req_header("content-type", "text/plain")
|
|
|> ApiCSRF.call([])
|
|
|
|
refute conn.halted
|
|
end
|
|
|
|
test "allows JSON with utf-8 content type and XHR header", %{conn: conn} do
|
|
conn =
|
|
conn
|
|
|> init_test_session(%{})
|
|
|> put_req_header("content-type", "application/json; charset=utf-8")
|
|
|> put_req_header("x-requested-with", "XMLHttpRequest")
|
|
|> ApiCSRF.call([])
|
|
|
|
refute conn.halted
|
|
end
|
|
|
|
test "rejects JSON request with empty csrf-token header", %{conn: conn} do
|
|
conn =
|
|
conn
|
|
|> init_test_session(%{})
|
|
|> put_req_header("content-type", "application/json")
|
|
|> put_req_header("x-csrf-token", "")
|
|
|> ApiCSRF.call([])
|
|
|
|
assert conn.halted
|
|
assert conn.status == 403
|
|
end
|
|
|
|
test "rejects JSON request with token but no session token", %{conn: conn} do
|
|
conn =
|
|
conn
|
|
|> init_test_session(%{})
|
|
|> put_req_header("content-type", "application/json")
|
|
|> put_req_header("x-csrf-token", "any-token")
|
|
|> ApiCSRF.call([])
|
|
|
|
assert conn.halted
|
|
end
|
|
|
|
test "rejects JSON request with mismatched csrf token", %{conn: conn} do
|
|
conn =
|
|
conn
|
|
|> init_test_session(%{"_csrf_token" => "a-session-token"})
|
|
|> put_req_header("content-type", "application/json")
|
|
|> put_req_header("x-csrf-token", "wrong-token")
|
|
|> ApiCSRF.call([])
|
|
|
|
assert conn.halted
|
|
end
|
|
|
|
test "init/1 returns opts unchanged" do
|
|
assert ApiCSRF.init([]) == []
|
|
assert ApiCSRF.init(foo: :bar) == [foo: :bar]
|
|
end
|
|
end
|