defmodule GitGudWeb.LabelLive.IndexTest do
@moduledoc """
The repository labels page changes labels for a repository admin only,
and only this repository's labels (and its organization's, for
opting out and back in) — whatever id the client sends.
"""
use GitGudWeb.ConnCase, async: false
import Phoenix.LiveViewTest
import GitGud.AccountsFixtures
import GitGud.ForgeFixtures
alias GitGud.Labels
alias GitGud.Labels.Label
alias GitGud.Organizations
alias GitGud.Repo
alias GitGud.Repositories
defp labels_path(repo) do
handle = Repositories.Storage.repo_handle(Repo.preload(repo, [:owner, :organization]))
~p"/r/#{handle}/#{repo.name}/labels"
end
defp org_repo do
admin = user_fixture()
handle = "acme-#{System.unique_integer([:positive])}"
{:ok, org} = Organizations.create_organization(admin, %{"handle" => handle})
{:ok, repo} =
Repositories.create_repository_for_org(org, admin, %{
"name" => unique_repo_name(),
"visibility" => "public"
})
{admin, org, repo}
end
describe "a repository admin" do
test "adds and deletes the repository's own labels", %{conn: conn} do
{owner, repo} = repository_fixture()
{:ok, lv, _} = live(log_in_user(conn, owner), labels_path(repo))
lv
|> form("#label-form", %{"label" => %{"name" => "docs", "color" => "#3b82f6"}})
|> render_submit()
assert [label] = Labels.list_labels(repo)
assert has_element?(lv, "#label-#{label.id}")
lv |> element("#label-delete-#{label.id}") |> render_click()
assert Labels.list_labels(repo) == []
refute has_element?(lv, "#label-#{label.id}")
end
test "can't delete another repository's label by forging its id", %{conn: conn} do
{owner, repo} = repository_fixture()
{_, other} = repository_fixture()
foreign = label_fixture(other)
{:ok, lv, _} = live(log_in_user(conn, owner), labels_path(repo))
_ = render_hook(lv, "delete", %{"id" => to_string(foreign.id)})
assert Repo.get(Label, foreign.id)
end
test "a junk id is ignored rather than crashing the page", %{conn: conn} do
{owner, repo} = repository_fixture()
{:ok, lv, _} = live(log_in_user(conn, owner), labels_path(repo))
for event <- ~w(delete opt_out opt_in) do
_ = render_hook(lv, event, %{"id" => "nope"})
_ = render_hook(lv, event, %{"id" => "999999999"})
end
assert has_element?(lv, "#label-form")
end
test "can't delete an inherited org label from the repository page", %{conn: conn} do
{admin, org, repo} = org_repo()
{:ok, org_label} =
Labels.create_organization_label(org, %{"name" => "sec", "color" => "#ef4444"})
{:ok, lv, _} = live(log_in_user(conn, admin), labels_path(repo))
_ = render_hook(lv, "delete", %{"id" => to_string(org_label.id)})
assert Repo.get(Label, org_label.id)
end
test "opts out of and back into its organization's label", %{conn: conn} do
{admin, org, repo} = org_repo()
{:ok, org_label} =
Labels.create_organization_label(org, %{"name" => "sec", "color" => "#ef4444"})
{:ok, lv, _} = live(log_in_user(conn, admin), labels_path(repo))
lv |> element("#label-hide-#{org_label.id}") |> render_click()
assert Labels.opted_out?(repo, org_label)
lv |> element("#label-unhide-#{org_label.id}") |> render_click()
refute Labels.opted_out?(repo, org_label)
end
test "can't opt out of another organization's label", %{conn: conn} do
{admin, _org, repo} = org_repo()
{_, other_org, _} = org_repo()
{:ok, foreign} =
Labels.create_organization_label(other_org, %{"name" => "theirs", "color" => "#ef4444"})
{:ok, lv, _} = live(log_in_user(conn, admin), labels_path(repo))
_ = render_hook(lv, "opt_out", %{"id" => to_string(foreign.id)})
refute Labels.opted_out?(repo, foreign)
end
end
describe "someone who can read but not administer the repository" do
setup do
{owner, repo} = repository_fixture(%{visibility: "public"})
label = label_fixture(repo, %{"name" => "keep"})
%{owner: owner, repo: repo, label: label, reader: user_fixture()}
end
test "sees the labels without the controls", %{conn: conn} = ctx do
{:ok, lv, _} = live(log_in_user(conn, ctx.reader), labels_path(ctx.repo))
assert has_element?(lv, "#label-#{ctx.label.id}")
refute has_element?(lv, "#label-form")
refute has_element?(lv, "#label-delete-#{ctx.label.id}")
end
test "can't delete or add one by pushing the events", %{conn: conn} = ctx do
{:ok, lv, _} = live(log_in_user(conn, ctx.reader), labels_path(ctx.repo))
_ = render_hook(lv, "delete", %{"id" => to_string(ctx.label.id)})
_ =
render_hook(lv, "save", %{"label" => %{"name" => "sneaky", "color" => "#3b82f6"}})
assert [%{id: id}] = Labels.list_labels(ctx.repo)
assert id == ctx.label.id
end
test "can't opt an org repository out of its labels", %{conn: conn} do
{_admin, org, repo} = org_repo()
{:ok, org_label} =
Labels.create_organization_label(org, %{"name" => "sec", "color" => "#ef4444"})
{:ok, lv, _} = live(log_in_user(conn, user_fixture()), labels_path(repo))
refute has_element?(lv, "#label-hide-#{org_label.id}")
_ = render_hook(lv, "opt_out", %{"id" => to_string(org_label.id)})
refute Labels.opted_out?(repo, org_label)
end
end
end
neiam
/gitgud
Git Gud
public · Issues · Pulls · Labels · Forks · Compare · Actions success · Badges · Packages
⭐
1
Log in to mark this repository.
5.4 KiB · text
History
b868907