Skip to content
quarry Artifact [6ac48d34a5]
Login

Artifact [6ac48d34a5]

Artifact 6ac48d34a571c31f6a2a47a7d7ee6da83364132cdb8a54542a89cdd49efc38e4:


package web

import (
	"reflect"
	"strings"
	"testing"

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

// The note is the order effective() builds access in, so its steps are
// asserted as that order, by their layer names rather than their words.
func TestPeopleSaysTheOrderAccessIsBuiltIn(t *testing.T) {
	plane := &memCaps{stored: map[string]string{"dan": "a"}}
	srv := peopleServer(t, plane)
	body := asDan(t, srv, "/r/alpha/settings")
	if !strings.Contains(body, `data-hook="access-order"`) {
		t.Fatal("People has no access-order note")
	}
	at := -1
	for _, layer := range []string{"nobody", "anonymous", "role", "category", "team"} {
		i := strings.Index(body, `data-layer="`+layer+`"`)
		if i < 0 || i < at {
			t.Fatalf("layer %s missing or out of order", layer)
		}
		at = i
	}
	// The site-admin flag adds nothing on a repository (#318), so it is
	// not a step in how access here is built.
	if strings.Contains(body, `data-layer="site"`) {
		t.Error("the access order still lists the site administrator as a layer")
	}
	if !strings.Contains(body, `data-hook="participation-is-anonymous"`) {
		t.Error("Anyone signed in may also does not say it is the anonymous category")
	}
	if !strings.Contains(body, `data-hook="category-held-by"`) {
		t.Error("Advanced does not name the roles that pull in a category")
	}
}

// Which roles pull in a category is read from the presets: the reader
// category is not the Reader role's, and must not be said to be.
func TestCategoriesNameTheRolesThatPullThemIn(t *testing.T) {
	var want []string
	for _, p := range oltp.Presets {
		if strings.ContainsRune(p.Caps, 'u') {
			want = append(want, p.Name)
		}
	}
	if len(want) == 0 {
		t.Fatal("no stock role holds u; the test proves nothing")
	}
	panel := capsPanelFor(&memCaps{stored: map[string]string{}}, "alpha")
	for _, row := range panel.Categories {
		if row.Name != "reader" {
			continue
		}
		if !reflect.DeepEqual(row.HeldBy, want) {
			t.Fatalf("reader held by %v, want %v", row.HeldBy, want)
		}
		for _, n := range row.HeldBy {
			if n == "Reader" {
				t.Fatal("the Reader role is named as holding the reader category")
			}
		}
		return
	}
	t.Fatal("no reader category row")
}

// siteCaps is a plane where one account's effective set holds s with
// no string of its own here: what the site-admin flag used to give on
// every repository.
type siteCaps struct {
	*memCaps
	site string
}

func (s siteCaps) CapsOf(acct, repo string) CapSet {
	if acct == s.site {
		return oltp.CapSet("s")
	}
	return s.memCaps.CapsOf(acct, repo)
}

// A site administrator is not a member of a repository they hold no
// role on (#318). The roster lists who holds a string or a team, and
// an effective set alone never puts somebody on it.
func TestASiteAdminIsNotOnTheRoster(t *testing.T) {
	plane := siteCaps{&memCaps{stored: map[string]string{"dan": "a", "root": ""}}, "root"}
	p := rosterFor(plane, nil, "alpha")
	var dan bool
	for _, row := range p.Rows {
		switch row.Name {
		case "root":
			t.Fatalf("a site administrator with no role is on the roster: %+v", row)
		case "dan":
			dan = true
		}
	}
	if !dan {
		t.Fatal("the repository's own admin is missing from the roster")
	}
	if p.Admins != 1 {
		t.Fatalf("roster counts %d admins, want 1", p.Admins)
	}
}