defmodule AprsmeWeb.Api.V1.FallbackControllerTest do use AprsmeWeb.ConnCase, async: true import Phoenix.Controller, only: [put_format: 2] alias AprsmeWeb.Api.V1.FallbackController defp invalid_changeset do %Aprsme.Devices{} |> Aprsme.Devices.changeset(%{}) |> Map.put(:action, :insert) end # Phoenix's render/3 looks up `_format` in conn.params. The bare build_conn # hasn't fetched params — put_format/2 short-circuits that lookup so the # fallback controller can be exercised in isolation. defp prep(conn), do: put_format(conn, "json") defp json(conn), do: Jason.decode!(conn.resp_body) describe "call/2" do test "handles {:error, changeset}", %{conn: conn} do conn = FallbackController.call(prep(conn), {:error, invalid_changeset()}) assert conn.status == 422 body = json(conn) assert body["error"]["code"] == "validation_error" assert is_map(body["error"]["details"]) end test "handles {:error, :not_found}", %{conn: conn} do conn = FallbackController.call(prep(conn), {:error, :not_found}) assert conn.status == 404 assert json(conn)["error"]["code"] == "not_found" end test "handles {:error, :unauthorized}", %{conn: conn} do conn = FallbackController.call(prep(conn), {:error, :unauthorized}) assert conn.status == 401 assert json(conn)["error"]["code"] == "generic_error" end test "handles {:error, :forbidden}", %{conn: conn} do conn = FallbackController.call(prep(conn), {:error, :forbidden}) assert conn.status == 403 end test "handles {:error, :bad_request}", %{conn: conn} do conn = FallbackController.call(prep(conn), {:error, :bad_request}) assert conn.status == 400 end test "unknown atom reasons produce 500", %{conn: conn} do conn = FallbackController.call(prep(conn), {:error, :totally_unknown}) assert conn.status == 500 end test "handles {:error, atom, message}", %{conn: conn} do conn = FallbackController.call(prep(conn), {:error, :bad_request, "specific message"}) assert conn.status == 400 assert json(conn)["error"]["message"] == "specific message" end test "handles {:error, binary}", %{conn: conn} do conn = FallbackController.call(prep(conn), {:error, "custom error"}) assert conn.status == 400 assert json(conn)["error"]["message"] == "custom error" end test "handles :timeout", %{conn: conn} do conn = FallbackController.call(prep(conn), :timeout) assert conn.status == 408 end test "handles unknown errors with 500", %{conn: conn} do conn = FallbackController.call(prep(conn), :some_weird_thing) assert conn.status == 500 assert json(conn)["error"]["code"] == "internal_server_error" end end end