Skip to content
quarry Artifact [25632ec0e3]
Login

Artifact [25632ec0e3]

Artifact 25632ec0e37074d694be7f6ee689034e42e3a79a1a6959bf3c4001b5bab073cc:


package api

import (
	"context"
	"errors"
	"testing"

	"craftdesign.group/quarry/internal/ops"
)

// fakeRegistry is the minimal RepoRegistry a repo.add/repo.update test
// needs: it records what it was asked to do rather than touching a
// filesystem or a real store.
type fakeRegistry struct {
	added     []RepoSpec
	removed   []string
	updates   []repoUpdateIn
	addErr    error
	removeErr error
}

func (f *fakeRegistry) Add(spec RepoSpec) (string, error) {
	if f.addErr != nil {
		return "", f.addErr
	}
	f.added = append(f.added, spec)
	return "/repos/" + spec.Name, nil
}
func (f *fakeRegistry) Remove(name string) error {
	f.removed = append(f.removed, name)
	return f.removeErr
}
func (f *fakeRegistry) Delete(name, confirm string) error { return nil }
func (f *fakeRegistry) Update(name, description, visibility, homepage, topics string, mirrorable bool) error {
	f.updates = append(f.updates, repoUpdateIn{Name: name, Description: description,
		Private: visibility == "private", Homepage: homepage, Topics: topics, Mirrorable: mirrorable})
	return nil
}
func (f *fakeRegistry) SetChat(name string, on bool) error { return nil }
func (f *fakeRegistry) Imports() ([]RepoImport, error)     { return nil, nil }

// repo.add is open to any signed-in account now — Token, not Admin —
// and carries no site-admin capability requirement.
func TestRepoAddSurfaceIsOpenToAnySignedInAccount(t *testing.T) {
	r := ops.NewRegistry()
	if err := RegisterAll(r, Deps{Version: "v", Repos: NewRepos(nil)}); err != nil {
		t.Fatal(err)
	}
	op, ok := r.Lookup("repo.add")
	if !ok {
		t.Fatal("repo.add is not registered")
	}
	if op.Auth != ops.Token {
		t.Errorf("repo.add Auth = %v, want ops.Token (any signed-in account)", op.Auth)
	}
	if op.Caps != "" {
		t.Errorf("repo.add Caps = %q, want empty — no site-admin capability requirement", op.Caps)
	}
}

// Anyone who is admin of a mirror on THIS forge (which its creator is,
// by construction) may configure it without being a site admin —
// except mirror.writes, which stays the operator's call: flipping a
// tracking store to accept writes creates two write heads.
func TestMirrorOpsAreOpenExceptWrites(t *testing.T) {
	r := ops.NewRegistry()
	if err := RegisterAll(r, Deps{Version: "v", Repos: NewRepos(nil)}); err != nil {
		t.Fatal(err)
	}
	for _, name := range []string{"mirror.list", "mirror.set", "mirror.detach", "mirror.run"} {
		op, ok := r.Lookup(name)
		if !ok {
			t.Fatalf("%s is not registered", name)
		}
		if op.Auth != ops.Token {
			t.Errorf("%s Auth = %v, want ops.Token", name, op.Auth)
		}
		if op.Caps != "a" {
			t.Errorf("%s Caps = %q, want %q (admin of the mirror, not of the site)", name, op.Caps, "a")
		}
	}
	op, ok := r.Lookup("mirror.writes")
	if !ok {
		t.Fatal("mirror.writes is not registered")
	}
	if op.Auth != ops.Admin {
		t.Errorf("mirror.writes Auth = %v, want ops.Admin — this one stays the operator's call", op.Auth)
	}
}

// Creating a repository is the act of owning it: the creator is granted
// admin on it in the same operation, not merely served it.
func TestRepoAddGrantsTheCreatorAdmin(t *testing.T) {
	reg := &fakeRegistry{}
	accts := newFakeAccounts()
	r := ops.NewRegistry()
	if err := RegisterAll(r, Deps{Version: "v", Repos: NewRepos(nil), Registry: reg, Accounts: accts}); err != nil {
		t.Fatal(err)
	}
	ctx := ops.WithUser(context.Background(), "alice")
	if _, err := r.Invoke(ctx, "repo.add", repoAddIn{Name: "widgets", Create: true}); err != nil {
		t.Fatal(err)
	}
	if got := accts.grants["alice"]["widgets"]; got != "admin" {
		t.Fatalf("creator's grant = %q, want %q", got, "admin")
	}
}

// A repository must not be left ownerless: if the owner grant fails,
// the creation is rolled back (the registrar is asked to Remove what it
// just Added) and the caller is told, rather than serving a repository
// its own creator cannot administer.
func TestRepoAddRollsBackWhenTheOwnerGrantFails(t *testing.T) {
	reg := &fakeRegistry{}
	accts := newFakeAccounts()
	accts.grantErr = errors.New("boom")
	r := ops.NewRegistry()
	if err := RegisterAll(r, Deps{Version: "v", Repos: NewRepos(nil), Registry: reg, Accounts: accts}); err != nil {
		t.Fatal(err)
	}
	ctx := ops.WithUser(context.Background(), "alice")
	_, err := r.Invoke(ctx, "repo.add", repoAddIn{Name: "widgets", Create: true})
	if err == nil {
		t.Fatal("expected an error when the owner grant fails")
	}
	if len(reg.removed) != 1 || reg.removed[0] != "widgets" {
		t.Fatalf("rollback did not remove the repository: %+v", reg.removed)
	}
}

// repo.update applies mirrorable whole, like every other field here.
func TestRepoUpdateCarriesMirrorable(t *testing.T) {
	reg := &fakeRegistry{}
	r := ops.NewRegistry()
	if err := RegisterAll(r, Deps{Version: "v", Repos: NewRepos(map[string]*Repo{"widgets": {}}), Registry: reg}); err != nil {
		t.Fatal(err)
	}
	out, err := r.Invoke(context.Background(), "repo.update",
		repoUpdateIn{Name: "widgets", Mirrorable: true})
	if err != nil {
		t.Fatal(err)
	}
	if len(reg.updates) != 1 || !reg.updates[0].Mirrorable {
		t.Fatalf("Update was not asked to store mirrorable=true: %+v", reg.updates)
	}
	res := out.(repoUpdateOut)
	if !res.Mirrorable {
		t.Errorf("repo.update did not echo mirrorable back: %+v", res)
	}
}

// A private repository reports itself as not mirrorable through
// repo.get even when its own stored flag is on — Deps.Mirrorable is the
// EFFECTIVE answer, private trumps the flag, and a reader should not
// have to separately check Private to know whether mirroring works.
func TestRepoGetReportsPrivateRepositoriesAsNotMirrorable(t *testing.T) {
	r := ops.NewRegistry()
	d := Deps{Version: "v", Repos: NewRepos(map[string]*Repo{"secret": {}}),
		Private:    func() map[string]bool { return map[string]bool{"secret": true} },
		Mirrorable: func(repo string) bool { return false }, // the effective answer, flag notwithstanding
	}
	if err := RegisterAll(r, d); err != nil {
		t.Fatal(err)
	}
	out, err := r.Invoke(context.Background(), "repo.get", repoGetIn{Repo: "secret"})
	if err != nil {
		t.Fatal(err)
	}
	info := out.(repoInfo)
	if !info.Private {
		t.Fatal("test setup: repository did not report private")
	}
	if info.Mirrorable {
		t.Error("a private repository reported mirrorable=true")
	}
}