defmodule MicrowavepropWeb.MetricsPlugTest do @moduledoc """ MetricsPlug mounts as a `forward "/metrics"` in the router, with an optional bearer-token gate read from `Application.get_env/2`. These tests exercise both the open and gated paths end-to-end. """ use MicrowavepropWeb.ConnCase, async: false setup do previous = Application.get_env(:microwaveprop, :prometheus_auth_token) on_exit(fn -> Application.put_env(:microwaveprop, :prometheus_auth_token, previous) end) :ok end describe "GET /metrics (no token configured)" do test "returns 200 with Prometheus text-exposition body", %{conn: conn} do Application.put_env(:microwaveprop, :prometheus_auth_token, nil) conn = get(conn, ~p"/metrics") assert conn.status == 200 assert [ctype] = get_resp_header(conn, "content-type") assert ctype =~ "text/plain" # PromEx's text body starts with '# HELP ...' or '# TYPE ...' metrics # metadata lines. Exact metrics depend on what's registered, but # any non-empty Prometheus body contains at least one '#' comment. assert conn.resp_body =~ "#" end test "blank-string token behaves the same as an unset token", %{conn: conn} do Application.put_env(:microwaveprop, :prometheus_auth_token, "") conn = get(conn, ~p"/metrics") assert conn.status == 200 end end describe "GET /metrics (bearer-token gated)" do setup do Application.put_env(:microwaveprop, :prometheus_auth_token, "s3cret-token") :ok end test "401s without an Authorization header", %{conn: conn} do conn = get(conn, ~p"/metrics") assert conn.status == 401 assert conn.resp_body == "unauthorized" # Standards-compliant www-authenticate challenge. assert [challenge] = get_resp_header(conn, "www-authenticate") assert challenge =~ ~s(Bearer realm="metrics") end test "401s when the Authorization header isn't a Bearer scheme", %{conn: conn} do conn = conn |> put_req_header("authorization", "Basic dXNlcjpwYXNz") |> get(~p"/metrics") assert conn.status == 401 end test "401s on a wrong bearer token", %{conn: conn} do conn = conn |> put_req_header("authorization", "Bearer wrong-token") |> get(~p"/metrics") assert conn.status == 401 end test "200s and serves the body when the bearer token matches", %{conn: conn} do conn = conn |> put_req_header("authorization", "Bearer s3cret-token") |> get(~p"/metrics") assert conn.status == 200 assert conn.resp_body =~ "#" end end end