2.4 KiB · text History b868907
defmodule GitGud.Workflows.PermissionsTest do
  use ExUnit.Case, async: true

  alias GitGud.Workflows.Permissions

  @default %{"contents" => :read, "packages" => :write, "actions" => :write}

  # Every scope that means something, at one level.
  defp all(level),
    do: Map.new(~w(contents packages actions issues pull-requests), &{&1, level})

  test "no permissions: anywhere keeps what job tokens always could" do
    assert Permissions.effective(%{"on" => "push"}, %{"runs-on" => "x"}) == @default
    assert Permissions.effective(nil, nil) == @default
  end

  test "…which is nothing on issues or pull requests" do
    refute Permissions.permits?(Permissions.to_claim(@default), "issues", :read)
    refute Permissions.permits?(Permissions.to_claim(@default), "pull-requests", :read)
    # A token minted before tokens carried permissions.
    refute Permissions.permits?(nil, "issues", :read)
  end

  test "read-all and write-all" do
    assert Permissions.effective(%{"permissions" => "read-all"}, %{}) == all(:read)
    assert Permissions.effective(%{"permissions" => "write-all"}, %{}) == all(:write)
  end

  test "{} is nothing" do
    assert Permissions.effective(%{"permissions" => %{}}, %{}) == all(:none)
  end

  test "a map leaves every scope it doesn't name at none" do
    assert Permissions.effective(%{"permissions" => %{"contents" => "write"}}, %{}) ==
             %{all(:none) | "contents" => :write}
  end

  test "issues and pull-requests are honoured; scopes gitgud doesn't use are ignored" do
    doc = %{
      "permissions" => %{
        "issues" => "write",
        "pull-requests" => "read",
        "id-token" => "write",
        "packages" => "read"
      }
    }

    assert Permissions.effective(doc, %{}) ==
             %{all(:none) | "packages" => :read, "issues" => :write, "pull-requests" => :read}
  end

  test "the job's permissions replace the workflow's, with no merge" do
    doc = %{"permissions" => %{"contents" => "write", "packages" => "write"}}
    job = %{"permissions" => %{"packages" => "read"}}

    assert Permissions.effective(doc, job) == %{all(:none) | "packages" => :read}
    assert Permissions.effective(doc, %{"permissions" => %{}}) == all(:none)
  end

  test "values it doesn't understand grant nothing" do
    assert Permissions.effective(%{"permissions" => %{"contents" => "admin"}}, %{}) ==
             all(:none)

    assert Permissions.effective(%{"permissions" => "everything"}, %{}) == all(:none)
  end
end