-
Notifications
You must be signed in to change notification settings - Fork 43
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #538 from naymspace/feature/demo-testing
Add tests for demo application
- Loading branch information
Showing
9 changed files
with
336 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
defmodule DemoWeb.TagLiveTest do | ||
use DemoWeb.ConnCase, async: false | ||
|
||
import Demo.Factory | ||
import Phoenix.LiveViewTest | ||
import DemoWeb.LiveResourceTests | ||
|
||
describe "tags live resource index" do | ||
test "is rendered", %{conn: conn} do | ||
insert_list(3, :tag) | ||
|
||
conn | ||
|> visit("/admin/tags") | ||
|> assert_has("h1", text: "Tags", exact: true) | ||
|> assert_has("button", text: "New Tag", exact: true) | ||
|> assert_has("button[disabled]", text: "Delete", exact: true) | ||
|> assert_has("div", text: "Items 1 to 3 (3 total)", exact: true) | ||
end | ||
|
||
test "search for items", %{conn: conn} do | ||
insert(:tag, %{name: "Elixir"}) | ||
insert(:tag, %{name: "Phoenix"}) | ||
|
||
conn | ||
|> visit("/admin/tags") | ||
|> assert_has(".table tbody tr", count: 2) | ||
|> unwrap(fn view -> | ||
view | ||
|> form("#index-search-form", index_search: %{value: "Elixir"}) | ||
|> render_change() | ||
end) | ||
|> assert_has(".table tbody tr", count: 1) | ||
|> refute_has("tr", text: "Phoenix") | ||
|> assert_has("tr", text: "Elixir") | ||
end | ||
|
||
test "basic functionality", %{conn: conn} do | ||
tags = insert_list(3, :tag) | ||
|
||
test_table_rows_count(conn, "/admin/tags", Enum.count(tags)) | ||
test_delete_button_disabled_enabled(conn, "/admin/tags", tags) | ||
test_show_action_redirect(conn, "/admin/tags", tags) | ||
test_edit_action_redirect(conn, "/admin/tags", tags) | ||
end | ||
end | ||
|
||
describe "tags live resource show" do | ||
test "is rendered", %{conn: conn} do | ||
tag = insert(:tag) | ||
|
||
conn | ||
|> visit("/admin/tags/#{tag.id}/show") | ||
|> assert_has("h1", text: "Tag", exact: true) | ||
|> assert_has("p", text: "Name", exact: true) | ||
|> assert_has("p", text: "Inserted At", exact: true) | ||
|> assert_has("p", text: tag.name, exact: true) | ||
end | ||
end | ||
|
||
describe "tags live resource edit" do | ||
test "is rendered", %{conn: conn} do | ||
tag = insert(:tag) | ||
|
||
conn | ||
|> visit("/admin/tags/#{tag.id}/edit") | ||
|> assert_has("h1", text: "Edit Tag", exact: true) | ||
|> assert_has("button", text: "Cancel", exact: true) | ||
|> assert_has("button", text: "Save", exact: true) | ||
end | ||
|
||
test "submit form", %{conn: conn} do | ||
tag = insert(:tag, %{name: "Elixir"}) | ||
|
||
conn | ||
|> visit("/admin/tags/#{tag.id}/edit") | ||
|> unwrap(fn view -> | ||
view | ||
|> form("#resource-form", change: %{name: "Phoenix"}) | ||
|> put_submitter("button[value=save]") | ||
|> render_submit() | ||
end) | ||
|> assert_has(".table tbody tr", count: 1) | ||
|> assert_has("p", text: "Phoenix", exact: true) | ||
end | ||
end | ||
|
||
describe "tags live resource new" do | ||
test "is rendered", %{conn: conn} do | ||
conn | ||
|> visit("/admin/tags/new") | ||
|> assert_has("h1", text: "New Tag", exact: true) | ||
|> assert_has("button", text: "Cancel", exact: true) | ||
|> assert_has("button", text: "Save", exact: true) | ||
end | ||
|
||
test "submit form", %{conn: conn} do | ||
conn | ||
|> visit("/admin/tags/new") | ||
|> unwrap(fn view -> | ||
view | ||
|> form("#resource-form", change: %{name: "Phoenix"}) | ||
|> put_submitter("button[value=save]") | ||
|> render_submit() | ||
end) | ||
|> assert_has(".table tbody tr", count: 1) | ||
|> assert_has("p", text: "Phoenix", exact: true) | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
defmodule DemoWeb.ConnCase do | ||
@moduledoc """ | ||
This module defines the test case to be used by | ||
tests that require setting up a connection. | ||
Such tests rely on `Phoenix.ConnTest` and also | ||
import other functionality to make it easier | ||
to build common data structures and query the data layer. | ||
Finally, if the test case interacts with the database, | ||
we enable the SQL sandbox, so changes done to the database | ||
are reverted at the end of every test. If you are using | ||
PostgreSQL, you can even run database tests asynchronously | ||
by setting `use DemoWeb.ConnCase, async: true`, although | ||
this option is not recommended for other databases. | ||
""" | ||
|
||
use ExUnit.CaseTemplate | ||
|
||
using do | ||
quote do | ||
# The default endpoint for testing | ||
@endpoint DemoWeb.Endpoint | ||
|
||
use DemoWeb, :verified_routes | ||
|
||
import PhoenixTest | ||
|
||
# Import conveniences for testing with connections | ||
import Plug.Conn | ||
import Phoenix.ConnTest | ||
import DemoWeb.ConnCase | ||
end | ||
end | ||
|
||
setup tags do | ||
Demo.DataCase.setup_sandbox(tags) | ||
{:ok, conn: Phoenix.ConnTest.build_conn()} | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
defmodule Demo.DataCase do | ||
@moduledoc """ | ||
This module defines the setup for tests requiring | ||
access to the application's data layer. | ||
You may define functions here to be used as helpers in | ||
your tests. | ||
Finally, if the test case interacts with the database, | ||
we enable the SQL sandbox, so changes done to the database | ||
are reverted at the end of every test. If you are using | ||
PostgreSQL, you can even run database tests asynchronously | ||
by setting `use Demo.DataCase, async: true`, although | ||
this option is not recommended for other databases. | ||
""" | ||
|
||
use ExUnit.CaseTemplate | ||
|
||
alias Ecto.Adapters.SQL.Sandbox | ||
|
||
using do | ||
quote do | ||
alias Demo.Repo | ||
|
||
import Ecto | ||
import Ecto.Changeset | ||
import Ecto.Query | ||
import Demo.DataCase | ||
end | ||
end | ||
|
||
setup tags do | ||
Demo.DataCase.setup_sandbox(tags) | ||
:ok | ||
end | ||
|
||
@doc """ | ||
Sets up the sandbox based on the test tags. | ||
""" | ||
def setup_sandbox(tags) do | ||
pid = Sandbox.start_owner!(Demo.Repo, shared: not tags[:async]) | ||
on_exit(fn -> Sandbox.stop_owner(pid) end) | ||
end | ||
|
||
@doc """ | ||
A helper that transforms changeset errors into a map of messages. | ||
assert {:error, changeset} = Accounts.create_user(%{password: "short"}) | ||
assert "password is too short" in errors_on(changeset).password | ||
assert %{password: ["password is too short"]} = errors_on(changeset) | ||
""" | ||
def errors_on(changeset) do | ||
Ecto.Changeset.traverse_errors(changeset, fn {message, opts} -> | ||
Regex.replace(~r"%{(\w+)}", message, fn _match, key -> | ||
opts |> Keyword.get(String.to_existing_atom(key), key) |> to_string() | ||
end) | ||
end) | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
defmodule DemoWeb.LiveResourceTests do | ||
@moduledoc """ | ||
Defines macros that can be used to include basic live resource tests. | ||
""" | ||
|
||
@doc """ | ||
Tests whether the table body contains expected amount of rows. | ||
""" | ||
defmacro test_table_rows_count(conn, base_path, expected_rows_count) do | ||
quote do | ||
conn = unquote(conn) | ||
base_path = unquote(base_path) | ||
expected_rows_count = unquote(expected_rows_count) | ||
|
||
conn | ||
|> visit(base_path) | ||
|> assert_has(".table tbody tr", count: expected_rows_count) | ||
end | ||
end | ||
|
||
@doc """ | ||
Tests whether delete button becomes enabled when clicking checkbox. | ||
""" | ||
defmacro test_delete_button_disabled_enabled(conn, base_path, items) do | ||
quote do | ||
conn = unquote(conn) | ||
base_path = unquote(base_path) | ||
items = unquote(items) | ||
|
||
if Enum.empty?(items) do | ||
raise "Cannot test delete button with 0 items" | ||
end | ||
|
||
[%{id: first_item_id} | _items] = items | ||
|
||
conn | ||
|> visit(base_path) | ||
|> refute_has("button:not([disabled])", text: "Delete") | ||
|> assert_has("#select-input-#{first_item_id}") | ||
|> unwrap(fn view -> | ||
view | ||
|> element("#select-input-#{first_item_id}") | ||
|> render_click() | ||
end) | ||
|> assert_has("button:not([disabled])", text: "Delete", exact: true) | ||
end | ||
end | ||
|
||
@doc """ | ||
Tests whether the show item action actually redirects to the show view. | ||
""" | ||
defmacro test_show_action_redirect(conn, base_path, items) do | ||
quote do | ||
conn = unquote(conn) | ||
base_path = unquote(base_path) | ||
items = unquote(items) | ||
|
||
if Enum.empty?(items) do | ||
raise "Cannot test show redirect with 0 items" | ||
end | ||
|
||
[%{id: first_item_id} | _items] = items | ||
|
||
conn | ||
|> visit(base_path) | ||
|> unwrap(fn view -> | ||
view | ||
|> element("button[aria-label='Show'][phx-value-item-id='#{first_item_id}']") | ||
|> render_click() | ||
end) | ||
|> assert_path("#{base_path}/#{first_item_id}/show") | ||
end | ||
end | ||
|
||
@doc """ | ||
Tests whether the edit item action actually redirects to the edit view. | ||
""" | ||
defmacro test_edit_action_redirect(conn, base_path, items) do | ||
quote do | ||
conn = unquote(conn) | ||
base_path = unquote(base_path) | ||
items = unquote(items) | ||
|
||
if Enum.empty?(items) do | ||
raise "Cannot test edit redirect with 0 items" | ||
end | ||
|
||
[%{id: first_item_id} | _items] = items | ||
|
||
conn | ||
|> visit(base_path) | ||
|> unwrap(fn view -> | ||
view | ||
|> element("button[aria-label='Edit'][phx-value-item-id='#{first_item_id}']") | ||
|> render_click() | ||
end) | ||
|> assert_path("#{base_path}/#{first_item_id}/edit") | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters