defmodule GitGudWeb.RepoLive.IndexTest do
use GitGudWeb.ConnCase, async: false
import Phoenix.LiveViewTest
import GitGud.AccountsFixtures
import GitGud.ForgeFixtures
alias GitGud.Repositories
setup :register_and_log_in_user
test "cards carry description, visibility and push recency", %{conn: conn, user: user} do
{_user, repo} =
repository_fixture(%{owner: user, name: "index-card", visibility: "private"})
{:ok, repo} = Repositories.update_repository(repo, %{"description" => "A described repo"})
{:ok, _lv, html} = live(conn, ~p"/repositories")
assert html =~ "#{user.handle}/index-card"
assert html =~ "A described repo"
assert html =~ "private"
# Never pushed, so the footer says so rather than showing a date.
assert html =~ "never pushed"
refute repo.pushed_at
end
test "public repos are visible without an account", %{user: user} do
{_user, _repo} =
repository_fixture(%{owner: user, name: "index-public", visibility: "public"})
{:ok, _lv, html} = live(build_conn(), ~p"/repositories")
assert html =~ "#{user.handle}/index-public"
end
test "the filter box narrows the list", %{conn: conn, user: user} do
{_user, _} = repository_fixture(%{owner: user, name: "alpha-widget"})
{_user, _} = repository_fixture(%{owner: user, name: "beta-gadget"})
{:ok, lv, html} = live(conn, ~p"/repositories")
assert html =~ "alpha-widget"
assert html =~ "beta-gadget"
html = lv |> form("form[phx-change=filter]", %{query: "alpha"}) |> render_change()
assert html =~ "alpha-widget"
refute html =~ "beta-gadget"
end
test "a filter matching nothing says so", %{conn: conn, user: user} do
{_user, _} = repository_fixture(%{owner: user, name: "only-one"})
{:ok, lv, _html} = live(conn, ~p"/repositories")
html = lv |> form("form[phx-change=filter]", %{query: "zzz-no-match"}) |> render_change()
assert html =~ "Nothing matches that filter."
end
test "the Yours scope hides other people's repos", %{conn: conn, user: user} do
{_user, _} = repository_fixture(%{owner: user, name: "mine-repo", visibility: "public"})
other = user_fixture()
{_other, _} = repository_fixture(%{owner: other, name: "theirs-repo", visibility: "public"})
{:ok, lv, html} = live(conn, ~p"/repositories")
assert html =~ "theirs-repo"
html = lv |> element("button[phx-value-scope=mine]") |> render_click()
assert html =~ "mine-repo"
refute html =~ "theirs-repo"
end
test "sorting by name reorders the list", %{conn: conn, user: user} do
{_user, _} = repository_fixture(%{owner: user, name: "zzz-last"})
{_user, _} = repository_fixture(%{owner: user, name: "aaa-first"})
{:ok, lv, _html} = live(conn, ~p"/repositories")
html = lv |> form("form[phx-change=filter]", %{sort: "name"}) |> render_change()
assert :binary.match(html, "aaa-first") < :binary.match(html, "zzz-last")
end
test "the anonymous view offers no scope toggle", %{user: user} do
{_user, _} = repository_fixture(%{owner: user, name: "anon-visible", visibility: "public"})
{:ok, lv, _html} = live(build_conn(), ~p"/repositories")
refute has_element?(lv, "button[phx-value-scope=mine]")
end
test "a fork names its parent", %{conn: conn, user: user} do
{_user, parent} =
repository_fixture(%{owner: user, name: "upstream-repo", visibility: "public"})
{_user, fork} = repository_fixture(%{owner: user, name: "downstream-repo"})
{:ok, _fork} =
fork
|> Ecto.Changeset.change(parent_repository_id: parent.id)
|> GitGud.Repo.update()
{:ok, _lv, html} = live(conn, ~p"/repositories")
assert html =~ "forked from"
assert html =~ "#{user.handle}/upstream-repo"
end
test "archived repos are badged", %{conn: conn, user: user} do
{_user, repo} = repository_fixture(%{owner: user, name: "old-repo"})
{:ok, _repo} = Repositories.update_repository(repo, %{"archived" => true})
{:ok, _lv, html} = live(conn, ~p"/repositories")
assert html =~ "archived"
end
test "the header counts shown against total", %{conn: conn, user: user} do
{_user, _} = repository_fixture(%{owner: user, name: "counted-one"})
{_user, _} = repository_fixture(%{owner: user, name: "counted-two"})
{:ok, lv, _html} = live(conn, ~p"/repositories")
html = lv |> form("form[phx-change=filter]", %{query: "counted-one"}) |> render_change()
assert html =~ "1 of 2 shown"
end
describe "tags" do
test "a repo's tags show on its card and link to the listing", %{conn: conn, user: user} do
{_user, repo} = repository_fixture(%{owner: user, name: "tagged-repo"})
{:ok, _} = GitGud.Tags.set_tags(repo, ["elixir", "git"])
{:ok, _lv, html} = live(log_in_user(conn, user), ~p"/repositories")
assert html =~ "tagged-repo"
assert html =~ ~s(href="/tags/elixir")
assert html =~ ~s(href="/tags/git")
end
test "an untagged repo shows no tag row", %{conn: conn, user: user} do
{_user, _repo} = repository_fixture(%{owner: user, name: "plain-repo"})
{:ok, _lv, html} = live(log_in_user(conn, user), ~p"/repositories")
assert html =~ "plain-repo"
refute html =~ ~s(href="/tags/)
end
test "the filter matches on tag as well as name", %{conn: conn, user: user} do
{_user, tagged} = repository_fixture(%{owner: user, name: "alpha"})
{_user, _other} = repository_fixture(%{owner: user, name: "beta"})
{:ok, _} = GitGud.Tags.set_tags(tagged, ["elixir"])
{:ok, lv, _html} = live(log_in_user(conn, user), ~p"/repositories")
html = lv |> form("form[phx-change=filter]", %{query: "elixir"}) |> render_change()
assert html =~ "alpha"
refute html =~ "beta"
end
test "filtering by name still works alongside", %{conn: conn, user: user} do
{_user, tagged} = repository_fixture(%{owner: user, name: "alpha"})
{_user, _other} = repository_fixture(%{owner: user, name: "beta"})
{:ok, _} = GitGud.Tags.set_tags(tagged, ["elixir"])
{:ok, lv, _html} = live(log_in_user(conn, user), ~p"/repositories")
html = lv |> form("form[phx-change=filter]", %{query: "beta"}) |> render_change()
assert html =~ "beta"
refute html =~ ">alpha<"
end
end
describe "pagination" do
defp many_repos(user, n) do
for i <- 1..n do
{_u, repo} = repository_fixture(%{owner: user, name: "paged-#{100 + i}"})
repo
end
end
test "no pager while everything fits on one page", %{conn: conn, user: user} do
_ = many_repos(user, GitGudWeb.RepoLive.Index.per_page())
{:ok, lv, _html} = live(log_in_user(conn, user), ~p"/repositories")
refute has_element?(lv, "nav[aria-label=Pagination]")
end
test "a pager appears once there's one too many", %{conn: conn, user: user} do
_ = many_repos(user, GitGudWeb.RepoLive.Index.per_page() + 1)
{:ok, lv, html} = live(log_in_user(conn, user), ~p"/repositories")
assert has_element?(lv, "nav[aria-label=Pagination]")
assert html =~ "page 1 of 2"
end
test "only a page's worth renders at a time", %{conn: conn, user: user} do
per = GitGudWeb.RepoLive.Index.per_page()
_ = many_repos(user, per + 1)
{:ok, lv, _html} = live(log_in_user(conn, user), ~p"/repositories")
shown = lv |> render() |> String.split("id=\"repo-") |> length()
assert shown - 1 == per
end
test "a deep link to page 2 shows the rest", %{conn: conn, user: user} do
per = GitGudWeb.RepoLive.Index.per_page()
_ = many_repos(user, per + 1)
{:ok, _lv, html} = live(log_in_user(conn, user), ~p"/repositories/2")
assert html =~ "page 2 of 2"
end
test "a deep link past the end lands on the last page", %{conn: conn, user: user} do
_ = many_repos(user, GitGudWeb.RepoLive.Index.per_page() + 1)
{:ok, _lv, html} = live(log_in_user(conn, user), ~p"/repositories/99")
assert html =~ "page 2 of 2"
end
test "a nonsense page falls back to the first", %{conn: conn, user: user} do
_ = many_repos(user, GitGudWeb.RepoLive.Index.per_page() + 1)
{:ok, _lv, html} = live(log_in_user(conn, user), ~p"/repositories/banana")
assert html =~ "page 1 of 2"
end
test "the filter travels in the link, so a page keeps its list", %{conn: conn, user: user} do
{_u, _match} = repository_fixture(%{owner: user, name: "needle-one"})
_ = many_repos(user, GitGudWeb.RepoLive.Index.per_page() + 1)
{:ok, _lv, html} = live(log_in_user(conn, user), ~p"/repositories?query=needle")
assert html =~ "needle-one"
refute html =~ "paged-101"
# One match, so no pager.
refute html =~ "aria-label=\"Pagination\""
end
test "changing the filter returns to page 1", %{conn: conn, user: user} do
_ = many_repos(user, GitGudWeb.RepoLive.Index.per_page() + 1)
{:ok, lv, _html} = live(log_in_user(conn, user), ~p"/repositories/2")
html = lv |> form("form[phx-change=filter]", %{query: "paged"}) |> render_change()
assert html =~ "page 1 of 2"
end
test "the page is a path segment, not a query parameter", %{conn: conn, user: user} do
_ = many_repos(user, GitGudWeb.RepoLive.Index.per_page() + 1)
{:ok, lv, _html} = live(log_in_user(conn, user), ~p"/repositories")
assert has_element?(lv, ~s{nav[aria-label=Pagination] a[href="/repositories/2"]})
end
test "a filtered page keeps the filter in the query string", %{conn: conn, user: user} do
_ = many_repos(user, GitGudWeb.RepoLive.Index.per_page() + 1)
{:ok, lv, _html} = live(log_in_user(conn, user), ~p"/repositories?query=paged")
assert has_element?(
lv,
~s{nav[aria-label=Pagination] a[href="/repositories/2?query=paged"]}
)
end
test "an unfiltered first page keeps a bare URL", %{conn: conn, user: user} do
_ = many_repos(user, GitGudWeb.RepoLive.Index.per_page() + 1)
{:ok, lv, _html} = live(log_in_user(conn, user), ~p"/repositories/2")
# Back to page 1 — the link carries no leftover defaults.
assert lv |> element("nav[aria-label=Pagination] a", "1") |> render_click() =~ "page 1 of 2"
end
end
end
neiam /gitgud
Git Gud
public · Issues · Pulls · Labels · Forks · Compare · Actions success · Packages
⭐
Log in to mark this repository.
10.1 KiB · text
History
6280797