tarakan/test/tarakan_web/live/repository_commits_live_test.exs
Maxfield Luke af6077b9c3
All checks were successful
CI and deploy / Test (push) Successful in 4m52s
CI and deploy / Deploy production (push) Successful in 23s
Initial commit on Forgejo
Fresh repository history for elektrine/tarakan hosted at
https://git.elektrine.com/elektrine/tarakan.
2026-07-29 04:43:40 -04:00

273 lines
8.8 KiB
Elixir

defmodule TarakanWeb.RepositoryCommitsLiveTest do
use TarakanWeb.ConnCase, async: false
import Phoenix.LiveViewTest
alias Tarakan.Accounts
alias Tarakan.HostedRepositories
alias Tarakan.HostedRepositories.Storage
@moduletag :tmp_dir
setup %{tmp_dir: tmp_dir} do
on_exit(fn ->
File.rm_rf(Application.fetch_env!(:tarakan, Tarakan.HostedRepositories)[:root])
end)
Tarakan.RepositoryCode.Cache.clear()
account = account_fixture()
scope = Accounts.scope_for_account(account)
{:ok, repository} = HostedRepositories.create(scope, %{"name" => "history"})
%{repository: repository, tmp_dir: tmp_dir}
end
defp push_commit(repository, tmp_dir, dir_name, message) do
work = Path.join(tmp_dir, dir_name)
{_output, 0} =
System.cmd("git", ["clone", "--quiet", Storage.dir(repository), work],
stderr_to_stdout: true
)
File.write!(Path.join(work, "README.md"), "# #{message}\n")
env = [
{"GIT_AUTHOR_NAME", "t"},
{"GIT_AUTHOR_EMAIL", "t@example.com"},
{"GIT_COMMITTER_NAME", "t"},
{"GIT_COMMITTER_EMAIL", "t@example.com"}
]
{_output, 0} = System.cmd("git", ["-C", work, "add", "."], env: env)
{_output, 0} = System.cmd("git", ["-C", work, "commit", "--quiet", "-m", message], env: env)
{_output, 0} =
System.cmd("git", ["-C", work, "push", "--quiet", "origin", "HEAD"],
env: env,
stderr_to_stdout: true
)
{sha, 0} = System.cmd("git", ["-C", work, "rev-parse", "HEAD"])
String.trim(sha)
end
defp push_merge_commit(repository, tmp_dir, dir_name, branch, message) do
work = Path.join(tmp_dir, dir_name)
{_output, 0} =
System.cmd("git", ["clone", "--quiet", Storage.dir(repository), work],
stderr_to_stdout: true
)
env = [
{"GIT_AUTHOR_NAME", "t"},
{"GIT_AUTHOR_EMAIL", "t@example.com"},
{"GIT_COMMITTER_NAME", "t"},
{"GIT_COMMITTER_EMAIL", "t@example.com"}
]
{main, 0} = System.cmd("git", ["-C", work, "rev-parse", "--abbrev-ref", "HEAD"])
main = String.trim(main)
{_output, 0} = System.cmd("git", ["-C", work, "checkout", "--quiet", "-b", branch], env: env)
File.write!(Path.join(work, "side.txt"), "side\n")
{_output, 0} = System.cmd("git", ["-C", work, "add", "."], env: env)
{_output, 0} =
System.cmd("git", ["-C", work, "commit", "--quiet", "-m", "side change"], env: env)
{_output, 0} = System.cmd("git", ["-C", work, "checkout", "--quiet", main], env: env)
File.write!(Path.join(work, "main.txt"), "main\n")
{_output, 0} = System.cmd("git", ["-C", work, "add", "."], env: env)
{_output, 0} =
System.cmd("git", ["-C", work, "commit", "--quiet", "-m", "main change"], env: env)
{_output, 0} =
System.cmd("git", ["-C", work, "merge", "--quiet", "--no-ff", "-m", message, branch],
env: env,
stderr_to_stdout: true
)
{_output, 0} =
System.cmd("git", ["-C", work, "push", "--quiet", "origin", "HEAD"],
env: env,
stderr_to_stdout: true
)
{sha, 0} = System.cmd("git", ["-C", work, "rev-parse", "HEAD"])
String.trim(sha)
end
defp push_branch_commit(repository, tmp_dir, dir_name, branch, message) do
work = Path.join(tmp_dir, dir_name)
{_output, 0} =
System.cmd("git", ["clone", "--quiet", Storage.dir(repository), work],
stderr_to_stdout: true
)
File.write!(Path.join(work, "FEATURE.md"), "# #{message}\n")
env = [
{"GIT_AUTHOR_NAME", "t"},
{"GIT_AUTHOR_EMAIL", "t@example.com"},
{"GIT_COMMITTER_NAME", "t"},
{"GIT_COMMITTER_EMAIL", "t@example.com"}
]
{_output, 0} = System.cmd("git", ["-C", work, "checkout", "--quiet", "-b", branch], env: env)
{_output, 0} = System.cmd("git", ["-C", work, "add", "."], env: env)
{_output, 0} = System.cmd("git", ["-C", work, "commit", "--quiet", "-m", message], env: env)
{_output, 0} =
System.cmd("git", ["-C", work, "push", "--quiet", "origin", branch],
env: env,
stderr_to_stdout: true
)
{sha, 0} = System.cmd("git", ["-C", work, "rev-parse", "HEAD"])
String.trim(sha)
end
test "lists the default branch history and links each commit to its detail page", %{
conn: conn,
repository: repository,
tmp_dir: tmp_dir
} do
first_sha = push_commit(repository, tmp_dir, "work-first", "initial")
tip = push_commit(repository, tmp_dir, "work-second", "second")
{:ok, view, _html} = live(conn, "/#{repository.owner}/#{repository.name}/commits")
render_async(view, 1_000)
assert has_element?(view, "#repository-commits-tab[aria-current='page']")
# The active tab is still a link: from a commit detail page it points at the
# commit list, which is the obvious way back and used to be unclickable.
assert has_element?(view, "a#repository-commits-tab[aria-current='page'][href]")
assert has_element?(view, "#commits-list a", "second")
assert has_element?(view, "#commits-list a", "initial")
assert has_element?(
view,
"#commits-list a[href='/#{repository.owner}/#{repository.name}/commits/#{tip}']"
)
assert has_element?(
view,
"#commits-list a[href='/#{repository.owner}/#{repository.name}/commits/#{first_sha}']"
)
refute has_element?(view, "#commits-load-more")
end
test "the commit detail page shows the full message, patch, and code link", %{
conn: conn,
repository: repository,
tmp_dir: tmp_dir
} do
_first_sha = push_commit(repository, tmp_dir, "work-first", "initial")
tip = push_commit(repository, tmp_dir, "work-second", "second")
{:ok, view, _html} =
live(conn, "/#{repository.owner}/#{repository.name}/commits/#{tip}")
render_async(view, 1_000)
assert has_element?(view, "#commit-subject", "second")
assert has_element?(view, "#commit-detail-sha", String.slice(tip, 0, 7))
assert has_element?(view, "#commit-patch", "+# second")
assert has_element?(
view,
"#commit-browse-code[href='/#{repository.owner}/#{repository.name}/code/#{tip}']"
)
# The code link opens the browser pinned at this exact commit.
{:ok, code_view, _html} = live(conn, "/#{repository.owner}/#{repository.name}/code/#{tip}")
render_async(code_view, 1_000)
assert has_element?(code_view, "#code-tree")
end
test "merge commits render with an empty patch state", %{
conn: conn,
repository: repository,
tmp_dir: tmp_dir
} do
_main_sha = push_commit(repository, tmp_dir, "work-first", "initial")
merge_sha = push_merge_commit(repository, tmp_dir, "work-merge", "side", "merge side")
{:ok, view, _html} =
live(conn, "/#{repository.owner}/#{repository.name}/commits/#{merge_sha}")
render_async(view, 1_000)
assert has_element?(view, "#commit-subject", "merge side")
assert has_element?(view, "#commit-patch-empty", "No textual changes")
refute has_element?(view, "#commits-error")
end
test "the commit detail page rejects unreachable commits", %{
conn: conn,
repository: repository,
tmp_dir: tmp_dir
} do
_sha = push_commit(repository, tmp_dir, "work-first", "initial")
unknown = String.duplicate("d", 40)
{:ok, view, _html} =
live(conn, "/#{repository.owner}/#{repository.name}/commits/#{unknown}")
render_async(view, 1_000)
assert has_element?(view, "#commits-error", "Commit not found")
refute has_element?(view, "#commit-detail")
end
test "the branch picker switches the listed history", %{
conn: conn,
repository: repository,
tmp_dir: tmp_dir
} do
_main_sha = push_commit(repository, tmp_dir, "work-first", "initial")
feature_sha =
push_branch_commit(repository, tmp_dir, "work-feature", "feature", "feature work")
{:ok, view, _html} = live(conn, "/#{repository.owner}/#{repository.name}/commits")
render_async(view, 1_000)
assert has_element?(view, "#commits-branch-select")
refute has_element?(view, "#commits-list a", "feature work")
view
|> form("#commits-branch-form", %{branch: "feature"})
|> render_change()
render_async(view, 1_000)
assert has_element?(view, "#commits-list a", "feature work")
assert has_element?(
view,
"#commits-list a[href='/#{repository.owner}/#{repository.name}/commits/#{feature_sha}']"
)
end
test "an empty repository shows an empty state", %{conn: conn, repository: repository} do
{:ok, view, _html} = live(conn, "/#{repository.owner}/#{repository.name}/commits")
render_async(view, 1_000)
assert has_element?(view, "#commits-error", "No commits yet")
refute has_element?(view, "#commits-list")
end
test "unknown repositories 404", %{conn: conn} do
assert_raise Ecto.NoResultsError, fn ->
live(conn, "/nobody/here/commits")
end
end
end