From f2ab02ce76310c502dbac536a5015c7202d702df Mon Sep 17 00:00:00 2001 From: German Velasco Date: Wed, 10 Apr 2024 19:52:39 -0400 Subject: [PATCH] Add `PhoenixTest.assert_path` and `refute_path` (#60) What changed? ============ We add two new assertion helpers to assert on the current path: `assert_path` and `refute_path`. Both helpers have a 2 and 3 arity versions. The 3-arity version takes a `query_params` key to assert on the query params. We do not handle other optional arguments (such as `host` or `scheme`), though we could see this being extensible in the future with those options. --- lib/phoenix_test.ex | 51 ++++++++++++++++ lib/phoenix_test/assertions.ex | 82 ++++++++++++++++++++++++++ test/phoenix_test/assertions_test.exs | 84 +++++++++++++++++++++++++++ 3 files changed, 217 insertions(+) diff --git a/lib/phoenix_test.ex b/lib/phoenix_test.ex index a18e7aa5..c8253360 100644 --- a/lib/phoenix_test.ex +++ b/lib/phoenix_test.ex @@ -433,4 +433,55 @@ defmodule PhoenixTest do ``` """ defdelegate refute_has(session, selector, opts), to: Assertions + + @doc """ + Assert helper to verify current request path. Takes an optional `query_params` + map. + + ## Examples + + ```elixir + # assert we're at /users + conn + |> visit("/users") + |> assert_path("/users") + + # assert we're at /users?name=frodo + conn + |> visit("/users") + |> assert_path("/users", query_params: %{name: "frodo"}) + ``` + """ + defdelegate assert_path(session, path), to: Assertions + + @doc """ + Same as `assert_path/2` but takes an optional `query_params` map. + """ + defdelegate assert_path(session, path, opts), to: Assertions + + @doc """ + Verifies current request path is NOT the one provided. Takes an optional + `query_params` map for more specificity. + + ## Examples + + ```elixir + # refute we're at /posts + conn + |> visit("/users") + |> refute_path("/posts") + + # refute we're at /users?name=frodo + conn + |> visit("/users?name=aragorn") + |> refute_path("/users", query_params: %{name: "frodo"}) + ``` + """ + defdelegate refute_path(session, path), to: Assertions + + @doc """ + Same as `refute_path/2` but takes an optional `query_params` for more specific + refutation. + """ + defdelegate refute_path(session, path, opts), to: Assertions end diff --git a/lib/phoenix_test/assertions.ex b/lib/phoenix_test/assertions.ex index 3b4eee19..80ec4109 100644 --- a/lib/phoenix_test/assertions.ex +++ b/lib/phoenix_test/assertions.ex @@ -202,6 +202,88 @@ defmodule PhoenixTest.Assertions do session end + def assert_path(session, path) do + request_path = session.conn.request_path + + if request_path == path do + assert true + else + msg = """ + Expected path to be #{inspect(path)} but got #{inspect(request_path)} + """ + + raise AssertionError, msg + end + + session + end + + def assert_path(session, path, opts) do + params = Keyword.get(opts, :query_params) + + session + |> assert_path(path) + |> assert_query_params(params) + end + + defp assert_query_params(session, params) do + conn = session.conn + + if conn.query_params == params do + assert true + else + params_string = URI.encode_query(params) + + msg = """ + Expected query params to be #{inspect(params_string)} but got #{inspect(conn.query_string)} + """ + + raise AssertionError, msg + end + + session + end + + def refute_path(session, path) do + request_path = session.conn.request_path + + if request_path == path do + msg = """ + Expected path not to be #{inspect(path)} + """ + + raise AssertionError, msg + else + refute false + end + + session + end + + def refute_path(session, path, opts) do + params = Keyword.get(opts, :query_params) + + refute_query_params(session, params) || refute_path(session, path) + end + + defp refute_query_params(session, params) do + conn = session.conn + + if conn.query_params == params do + params_string = URI.encode_query(params) + + msg = """ + Expected query params not to be #{inspect(params_string)} + """ + + raise AssertionError, msg + else + refute false + end + + session + end + defp assert_incorrect_count_error_msg(selector, opts, found) do text = Keyword.get(opts, :text, :no_text) expected_count = Keyword.get(opts, :count, :any) diff --git a/test/phoenix_test/assertions_test.exs b/test/phoenix_test/assertions_test.exs index 335a3976..e7c9bcf7 100644 --- a/test/phoenix_test/assertions_test.exs +++ b/test/phoenix_test/assertions_test.exs @@ -572,4 +572,88 @@ defmodule PhoenixTest.AssertionsTest do end end end + + describe "assert_path" do + test "asserts that the given path is the current path", %{conn: conn} do + conn + |> visit("/page/index") + |> assert_path("/page/index") + end + + test "asserts query params are the same", %{conn: conn} do + conn + |> visit("/page/index?hello=world") + |> assert_path("/page/index", query_params: %{"hello" => "world"}) + end + + test "raises helpful error if path doesn't match", %{conn: conn} do + msg = + """ + Expected path to be "/page/not-index" but got "/page/index" + """ + |> ignore_whitespace() + + assert_raise AssertionError, msg, fn -> + conn + |> visit("/page/index") + |> assert_path("/page/not-index") + end + end + + test "raises helpful error if query params don't match", %{conn: conn} do + msg = + """ + Expected query params to be "goodbye=world&hi=bye" but got "hello=world&hi=bye" + """ + |> ignore_whitespace() + + assert_raise AssertionError, msg, fn -> + conn + |> visit("/page/index?hello=world&hi=bye") + |> assert_path("/page/index", query_params: %{"goodbye" => "world", "hi" => "bye"}) + end + end + end + + describe "refute_path" do + test "refute that the given path is the current path", %{conn: conn} do + conn + |> visit("/page/index") + |> refute_path("/page/page_2") + end + + test "refutes query params are the same", %{conn: conn} do + conn + |> visit("/page/index?hello=world") + |> refute_path("/page/index", query_params: %{"hello" => "not-world"}) + end + + test "raises helpful error if path matches", %{conn: conn} do + msg = + """ + Expected path not to be "/page/index" + """ + |> ignore_whitespace() + + assert_raise AssertionError, msg, fn -> + conn + |> visit("/page/index") + |> refute_path("/page/index") + end + end + + test "raises helpful error if query params don't match", %{conn: conn} do + msg = + """ + Expected query params not to be "hello=world&hi=bye" + """ + |> ignore_whitespace() + + assert_raise AssertionError, msg, fn -> + conn + |> visit("/page/index?hello=world&hi=bye") + |> refute_path("/page/index", query_params: %{"hello" => "world", "hi" => "bye"}) + end + end + end end