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)
}
}