8.1 KiB · text History b868907
defmodule GitGudWeb.RepoLive.BadgesTest do
  use GitGudWeb.ConnCase, async: false

  import Phoenix.LiveViewTest
  import GitGud.ForgeFixtures

  alias GitGud.Repositories.Storage

  setup %{conn: conn} do
    {_user, repo} = repository_fixture(%{visibility: "public"})
    repo = GitGud.Repo.preload(repo, [:owner, :organization])
    {:ok, conn: conn, repo: repo, base: "/r/#{Storage.repo_handle(repo)}/#{repo.name}"}
  end

  test "the sheet shows every section and every theme", %{conn: conn, base: base} do
    {:ok, lv, _html} = live(conn, base <> "/badges")

    for id <-
          ~w(badge-options badges-current badges-themes badges-contrast badges-embed badges-coverage) do
      assert has_element?(lv, "##{id}")
    end

    for theme <- GitGud.Themes.all(), do: assert(has_element?(lv, "#badge-theme-#{theme}"))
    assert has_element?(lv, "#badges-current [data-badge=ci] svg.ggb")
    assert has_element?(lv, "style#badge-theme-styles")
  end

  test "options are path segments", %{conn: conn, base: base} do
    {:ok, lv, _html} = live(conn, base <> "/badges")

    lv |> element("#badge-style-dot") |> render_click()
    assert_patch(lv, base <> "/badges/dot")

    lv |> element("#badge-scale-2_5x") |> render_click()
    assert_patch(lv, base <> "/badges/dot/2.5x")

    lv |> element("#badge-gg-on") |> render_click()
    assert_patch(lv, base <> "/badges/dot/2.5x/gg")

    assert has_element?(lv, "#badge-style-dot[aria-current=page]")

    assert has_element?(
             lv,
             ~s(#badge-theme-forest img[src="/badges/sample/ci/passing/dot/2.5x/gg/forest.svg"])
           )
  end

  test "a linked view opens as it was linked", %{conn: conn, base: base} do
    {:ok, lv, _html} = live(conn, base <> "/badges/outline/square/gg")

    assert has_element?(lv, "#badge-style-outline[aria-current=page]")
    assert has_element?(lv, "#badge-corners-square[aria-current=page]")
    assert has_element?(lv, "#badge-gg-on[aria-current=page]")
  end

  test "unknown options fall back to the defaults", %{conn: conn, base: base} do
    expected = base <> "/badges"
    assert {:error, {:live_redirect, %{to: ^expected}}} = live(conn, base <> "/badges/sparkly")
  end

  test "snippets follow the chosen badge", %{conn: conn, base: base} do
    {:ok, lv, _html} = live(conn, base <> "/badges/dot")

    lv
    |> element("#badge-snippet-form")
    |> render_change(%{snippet: %{kind: "coverage", theme: "forest", format: "png"}})

    assert has_element?(lv, "#badge-snippet-url pre", base <> "/badge/coverage/dot/forest.png")
    assert has_element?(lv, "#badge-snippet-html pre", "/badge/coverage/dot/dark.png")

    assert has_element?(
             lv,
             "#badge-snippet-preview img[src='#{base}/badge/coverage/dot/forest.png']"
           )
  end

  test "workflows that ran on the default branch get badges", %{
    conn: conn,
    repo: repo,
    base: base
  } do
    %GitGud.Workflows.WorkflowRun{repository_id: repo.id}
    |> GitGud.Workflows.WorkflowRun.create_changeset(%{
      "number" => 1,
      "workflow_path" => ".forgejo/workflows/audit.yml",
      "workflow_name" => "audit",
      "trigger" => "schedule",
      "head_ref" => "refs/heads/#{repo.default_branch}",
      "head_sha" => :crypto.strong_rand_bytes(20)
    })
    |> Ecto.Changeset.change(status: "success")
    |> GitGud.Repo.insert!()

    {:ok, lv, _html} = live(conn, base <> "/badges")

    assert has_element?(
             lv,
             ~s(#badges-current [data-badge="workflow:audit"] a[href="#{base}/badge/workflow/audit.svg"] svg.ggb)
           )

    lv
    |> element("#badge-snippet-form")
    |> render_change(%{snippet: %{kind: "workflow:audit", theme: "auto", format: "svg"}})

    assert has_element?(lv, "#badge-snippet-url pre", base <> "/badge/workflow/audit.svg")
    assert has_element?(lv, "#badge-snippet-markdown pre", "[![audit status]")
  end

  test "packages get install badges, and counts show", %{conn: conn, repo: repo, base: base} do
    {user, _} = repository_fixture()

    {:ok, _, _, _} =
      GitGud.Packages.publish_file(repo, "pypi", "Widget", "1.0.0", %{
        filename: "widget-1.0.0.tar.gz",
        body: "sdist",
        content_type: "application/x-tar",
        uploader: user
      })

    {:ok, lv, _html} = live(conn, base <> "/badges")

    assert has_element?(
             lv,
             ~s(#badges-current [data-badge="package:pypi:Widget"] a[href="#{base}/badge/package/pypi/Widget.svg"] svg.ggb)
           )

    for kind <- ~w(issues pulls commits contributors ci-duration release license language syms),
        do: assert(has_element?(lv, "#badges-current [data-badge=#{kind}] svg"))

    # Not a mirror, so no mirror badge.
    refute has_element?(lv, "#badges-current [data-badge=mirror]")

    lv
    |> element("#badge-snippet-form")
    |> render_change(%{snippet: %{kind: "package:pypi:Widget", theme: "dark", format: "png"}})

    assert has_element?(
             lv,
             "#badge-snippet-url pre",
             base <> "/badge/package/pypi/Widget/dark.png"
           )

    assert has_element?(lv, "#badge-snippet-markdown pre", "/packages)")
  end

  describe "the README block" do
    test "starts closed, and opens with the usual badges chosen", %{conn: conn, base: base} do
      {:ok, lv, _html} = live(conn, base <> "/badges")
      refute has_element?(lv, "#readme-card")

      lv |> element("#readme-toggle") |> render_click()

      assert has_element?(lv, "#readme-card")
      assert has_element?(lv, "#readme-toggle[aria-pressed=true]")

      for key <- ~w(ci coverage release license) do
        assert has_element?(lv, "[data-badge=#{key}] button[aria-pressed=true]")
      end

      assert has_element?(lv, "[data-badge=issues] button[aria-pressed=false]")

      md = lv |> element("#readme-markdown pre") |> render()
      assert md =~ "[![CI status](#{GitGudWeb.Endpoint.url()}#{base}/badge/ci.svg)]"
      assert md =~ "/badge/license.svg"
      refute md =~ "/badge/issues.svg"
    end

    test "choosing badges adds them, in the order shown", %{conn: conn, base: base} do
      {:ok, lv, _html} = live(conn, base <> "/badges/dot")
      lv |> element("#readme-toggle") |> render_click()
      lv |> element("#readme-none") |> render_click()
      assert has_element?(lv, "#readme-empty")

      lv |> element("[data-badge=license] button") |> render_click()
      lv |> element("[data-badge=ci] button") |> render_click()

      md = lv |> element("#readme-markdown pre") |> render()

      assert Regex.scan(~r{/badge/[^)]+}, md) |> List.flatten() ==
               ["/badge/ci/dot.svg", "/badge/license/dot.svg"]

      lv |> element("[data-badge=ci] button") |> render_click()
      md = lv |> element("#readme-markdown pre") |> render()
      assert Regex.scan(~r{/badge/[^)]+}, md) |> List.flatten() == ["/badge/license/dot.svg"]
    end

    test "theme, format and select all", %{conn: conn, base: base} do
      {:ok, lv, _html} = live(conn, base <> "/badges")
      lv |> element("#readme-toggle") |> render_click()
      lv |> element("#readme-all") |> render_click()

      lv
      |> element("#readme-form")
      |> render_change(%{readme: %{theme: "forest", format: "png"}})

      md = lv |> element("#readme-markdown pre") |> render()
      assert md =~ "#{base}/badge/issues/forest.png"
      assert md =~ "#{base}/badge/mark/forest.png"
      assert has_element?(lv, "#readme-html pre", "#{base}/badge/ci/dark.png")

      # The preview is the block's own images, on the theme's background.
      assert has_element?(lv, ~s(#readme-preview img[src="#{base}/badge/ci/forest.png"]))

      assert has_element?(
               lv,
               ~s(#readme-preview[style*="#{GitGud.Badges.Palette.token_hex("forest", "base-100")}"])
             )
    end

    test "closed, a tile opens its badge", %{conn: conn, base: base} do
      {:ok, lv, _html} = live(conn, base <> "/badges")
      assert has_element?(lv, ~s([data-badge=release] a[href="#{base}/badge/release.svg"]))
    end
  end

  test "the repository header links here", %{conn: conn, base: base} do
    {:ok, lv, _html} = live(conn, base <> "/actions")
    assert has_element?(lv, ~s(#repo-badges-link[href="#{base}/badges"]))
  end
end