package api
import (
"context"
"testing"
"craftdesign.group/quarry/internal/oltp"
"craftdesign.group/quarry/internal/ops"
)
type recordedActs struct{ acts []oltp.ForgeAct }
func (r *recordedActs) RecordForgeAct(actor, op, repo, owner string) error {
r.acts = append(r.acts, oltp.ForgeAct{Actor: actor, Op: op, Repo: repo, Owner: owner})
return nil
}
func (r *recordedActs) ForgeActs(repo string, limit int) ([]oltp.ForgeAct, error) {
var out []oltp.ForgeAct
for _, a := range r.acts {
if a.Repo == repo {
out = append(out, a)
}
}
return out, nil
}
// The operator's power over a repository they do not hold stays, and
// stops being invisible to the person whose repository it is.
func TestTheOperatorLeavesAReceipt(t *testing.T) {
for _, tc := range []struct {
name, actor, repo string
want bool
why string
}{
{"an operator reaching into somebody's repository", "root", "held", true,
"this is the case the journal exists for"},
{"the owner acting on their own", "ada", "held", false,
"nobody needs a receipt for what they did to their own repository"},
{"an ordinary member within their letters", "grace", "held", false,
"a member acting is not the operator reaching in"},
{"an operator on a store nobody holds", "root", "unclaimed", false,
"administering the forge is the job, not an intrusion"},
} {
acts := &recordedActs{}
d := Deps{
Acts: acts,
Owners: deedOwners{owner: map[string]string{"held": "ada", "unclaimed": ""}},
Accounts: deedAccounts{admin: "root"},
}
d.WitnessOperator()(ops.WithUser(context.Background(), tc.actor),
"repo.update", repoUpdateIn{Name: tc.repo})
got := len(acts.acts) == 1
if got != tc.want {
t.Errorf("FAIL: %s: recorded=%v, want %v — %s", tc.name, got, tc.want, tc.why)
continue
}
if tc.want {
a := acts.acts[0]
if a.Actor != tc.actor || a.Repo != tc.repo || a.Owner != "ada" || a.Op != "repo.update" {
t.Errorf("FAIL: %s: receipt = %+v", tc.name, a)
continue
}
}
t.Logf("ok: %s", tc.name)
}
}
// The owner AT THE TIME is recorded, not looked up later: a repository
// changes hands, and a receipt that re-resolved the owner would quietly
// re-attribute what was done to somebody who was not there.
func TestTheReceiptNamesTheOwnerAtTheTime(t *testing.T) {
acts := &recordedActs{}
owners := deedOwners{owner: map[string]string{"held": "ada"}}
d := Deps{Acts: acts, Owners: owners, Accounts: deedAccounts{admin: "root"}}
d.WitnessOperator()(ops.WithUser(context.Background(), "root"), "repo.update", repoUpdateIn{Name: "held"})
owners.owner["held"] = "heir"
got, err := acts.ForgeActs("held", 10)
if err != nil {
t.Fatal(err)
}
if len(got) != 1 || got[0].Owner != "ada" {
t.Fatalf("receipt = %+v, want the owner at the time (ada)", got)
}
t.Log("ok: the receipt names who held it then")
}
// A journal that cannot be written must not fail the act it describes.
func TestAFailedReceiptDoesNotFailTheAct(t *testing.T) {
d := Deps{Acts: nil, Owners: deedOwners{owner: map[string]string{"held": "ada"}},
Accounts: deedAccounts{admin: "root"}}
d.WitnessOperator()(ops.WithUser(context.Background(), "root"), "repo.update", repoUpdateIn{Name: "held"})
t.Log("ok: no journal, no panic, no refusal")
}