defmodule GitGudWeb.PackageRetentionUiTest do
@moduledoc """
The two places a non-admin touches retention: pins and a package's
own policy, on the repository's packages page — plus the org view
that tells them why they should care.
"""
use GitGudWeb.ConnCase, async: false
import Phoenix.LiveViewTest
import GitGud.AccountsFixtures
import GitGud.ForgeFixtures
alias GitGud.Packages
alias GitGud.Packages.PackageVersion
alias GitGud.Packages.Retention
alias GitGud.Repo
alias GitGud.Settings
setup :register_and_log_in_user
setup %{user: user} do
{:ok, repo} =
GitGud.Repositories.create_repository(user, %{
"name" => "pkgs#{System.unique_integer([:positive])}",
"visibility" => "public"
})
repo = Repo.preload(repo, [:owner, :organization])
publish(repo, "widget", 30)
package = Packages.get_package(repo, "pypi", "widget")
%{repo: repo, package: package, path: "/r/#{user.handle}/#{repo.name}/packages"}
end
test "shows what the registry is using, per format and in total", ctx do
{:ok, _lv, html} = live(ctx.conn, ctx.path)
assert html =~ "30 versions"
# A size, rather than a raw byte count.
assert html =~ ~r/\d+(\.\d+)? (B|KiB|MiB|GiB)/
end
test "an owner can pin a version out of retention's reach", ctx do
{:ok, lv, _html} = live(ctx.conn, ctx.path)
lv
|> element(~s|button[phx-click="toggle"][phx-value-id="#{ctx.package.id}"]|)
|> render_click()
oldest = version(ctx.package, "1.0.0")
html =
lv |> element(~s|button[phx-click="pin"][phx-value-id="#{oldest.id}"]|) |> render_click()
assert html =~ "pinned"
assert Repo.reload(oldest).pinned_at
# And retention now spares it.
plan = Retention.plan(Repo.reload(ctx.package))
refute Enum.any?(plan.prune, &(&1.version == "1.0.0"))
end
test "the pin limit is reported in the page, not swallowed", ctx do
{:ok, _} = Settings.put("packages.max_pins", 1)
{:ok, lv, _html} = live(ctx.conn, ctx.path)
lv
|> element(~s|button[phx-click="toggle"][phx-value-id="#{ctx.package.id}"]|)
|> render_click()
{:ok, _} = Retention.pin(version(ctx.package, "1.0.0"), ctx.user)
html =
lv
|> element(~s|button[phx-click="pin"][phx-value-id="#{version(ctx.package, "1.0.1").id}"]|)
|> render_click()
assert html =~ "1 pins already"
end
test "a package can tighten its own policy but not loosen it", ctx do
{:ok, lv, _html} = live(ctx.conn, ctx.path)
lv
|> element(~s|button[phx-click="toggle"][phx-value-id="#{ctx.package.id}"]|)
|> render_click()
lv
|> form("form[phx-submit=set_retention]", %{
"package_id" => ctx.package.id,
"retention_mode" => "keep_last",
"retention_keep" => "5",
"retention_bytes" => ""
})
|> render_submit()
assert Repo.reload(ctx.package).retention_keep == 5
html =
lv
|> form("form[phx-submit=set_retention]", %{
"package_id" => ctx.package.id,
"retention_mode" => "keep_last",
"retention_keep" => "500",
"retention_bytes" => ""
})
|> render_submit()
assert html =~ "keeps at most 24 versions"
assert Repo.reload(ctx.package).retention_keep == 5
end
test "a visitor who can't administer the repo gets no controls", ctx do
other = user_fixture()
conn = log_in_user(build_conn(), other)
{:ok, lv, _html} = live(conn, ctx.path)
html =
lv
|> element(~s|button[phx-click="toggle"][phx-value-id="#{ctx.package.id}"]|)
|> render_click()
refute html =~ "phx-click=\"pin\""
refute html =~ "set_retention"
end
describe "the org view" do
setup %{user: user} do
{:ok, org} =
GitGud.Organizations.create_organization(user, %{
"handle" => "acme#{System.unique_integer([:positive])}",
"visibility" => "public"
})
{:ok, repo} =
GitGud.Repositories.create_repository_for_org(org, user, %{
"name" => "orgpkgs#{System.unique_integer([:positive])}",
"visibility" => "public"
})
publish(Repo.preload(repo, [:owner, :organization]), "orgwidget", 30)
%{org: org}
end
test "totals an organization's registries", %{conn: conn, org: org} do
{:ok, lv, _html} = live(conn, ~p"/orgs/#{org.handle}/packages/storage")
html = render_async(lv)
assert html =~ "orgwidget"
assert html =~ "would remove 6 version(s)"
end
end
defp publish(repo, name, count) do
for i <- 0..(count - 1) do
{:ok, _, _, _} =
Packages.publish_file(repo, "pypi", name, "1.0.#{i}", %{
filename: "#{name}-1.0.#{i}.tar.gz",
body: :crypto.strong_rand_bytes(128),
content_type: "application/gzip",
pushed_at: DateTime.add(~U[2026-01-01 00:00:00Z], i, :second)
})
end
end
defp version(package, version),
do: Repo.get_by!(PackageVersion, package_id: package.id, version: version)
end
neiam
/gitgud
Git Gud
public · Issues · Pulls · Labels · Forks · Compare · Actions success · Badges · Packages
⭐
1
Log in to mark this repository.
4.9 KiB · text
History
b868907