1.7 KiB · text History a6f4469
defmodule GitGudWeb.RepoAuthHelpers do
  @moduledoc """
  Shared setup for the tests that check who may use a repository's
  settings pages: a public repository (so any signed-in user can read
  it), a path into it, and a way to take an owner's rights away from
  under a socket they already have open.
  """

  import Ecto.Query
  import GitGud.AccountsFixtures

  alias GitGud.Repo
  alias GitGud.Repositories
  alias GitGud.Repositories.Repository
  alias GitGud.Repositories.Storage

  @doc "A public repository owned by `owner`, with the associations the pages read."
  def public_repo(owner) do
    {:ok, repo} =
      Repositories.create_repository(owner, %{
        "name" => "authz#{System.unique_integer([:positive])}",
        "visibility" => "public"
      })

    Repo.preload(repo, [:owner, :organization])
  end

  @doc "`/r/:owner/:name<suffix>`."
  def repo_path(repo, suffix \\ ""), do: "/r/#{Storage.repo_handle(repo)}/#{repo.name}#{suffix}"

  @doc """
  Hands a personal repository to someone else, so the user who opened
  a page on it as its owner no longer administers it.
  """
  def transfer_away(%Repository{id: id}) do
    {1, _} =
      Repo.update_all(from(r in Repository, where: r.id == ^id),
        set: [owner_id: user_fixture().id]
      )

    :ok
  end

  @doc """
  Makes `user` a plain member of `org`, adding another admin first so
  the org isn't left without one.
  """
  def demote(org, user) do
    {:ok, _} = GitGud.Organizations.add_member(org, user_fixture(), "admin")

    {1, _} =
      Repo.update_all(
        from(m in GitGud.Organizations.Membership,
          where: m.organization_id == ^org.id and m.user_id == ^user.id
        ),
        set: [role: "member"]
      )

    :ok
  end
end