package api
import (
"strings"
"testing"
"craftdesign.group/quarry/internal/oltp"
)
// account.explain's two halves must not contradict each other.
//
// The `can` sentence came from oltp.Explain, which asks HasAny and so
// reads `a` as a wildcard. The letter list came from oltp.Decode via
// Closure, which has no entry for `a`. Both were internally consistent
// and the ANSWER contradicted itself: a repository admin was told they
// could check in and edit tickets, above a list showing no i, k, w or
// f (8ea1e46d, G-84).
//
// Asserted at the op's own composition rather than only in oltp,
// because the defect was not in either function — it was in feeding
// them different inputs.
func TestExplainsSentenceAndLettersAgreeForAnAdmin(t *testing.T) {
const caps = "a"
sentence := oltp.Explain("jan", oltp.CapSet(caps))
// The composition the op performs. If this drifts from register.go
// the assertion below is worthless, so it is spelled the same way.
grants := oltp.Decode(oltp.AsGated(caps))
joined := strings.Join(grants, " | ")
for _, claim := range []string{"check in", "edit tickets", "edit wiki pages"} {
if !strings.Contains(sentence, claim) {
continue // the sentence does not make this claim; nothing to match
}
// The sentence claims it, so the letters must carry it.
var found bool
for _, g := range grants {
if strings.Contains(g, strings.TrimSuffix(claim, "s")) {
found = true
break
}
}
if !found {
t.Errorf("FAIL: the sentence says an admin can %q and the letter list does not "+
"carry it.\n sentence: %s\n letters: %s", claim, sentence, joined)
}
}
if len(grants) < 10 {
t.Errorf("FAIL: an admin's letter list has %d entries; `a` is not expanding, so the "+
"page will contradict its own sentence again", len(grants))
}
}