package main
import (
"context"
"errors"
"testing"
"craftdesign.group/quarry/internal/oltp"
)
type fakePlane struct {
subs []string
topics map[string]string
added map[string][]string
removed map[string][]string
failSub string
}
func newFakePlane() *fakePlane {
return &fakePlane{topics: map[string]string{},
added: map[string][]string{}, removed: map[string][]string{}}
}
func (f *fakePlane) EnsureSubscriber(_ context.Context, account string) error {
if account == f.failSub {
return errors.New("notify is not holding this one")
}
f.subs = append(f.subs, account)
return nil
}
func (f *fakePlane) EnsureTopic(_ context.Context, key, name string) error {
f.topics[key] = name
return nil
}
func (f *fakePlane) AddTopicMember(_ context.Context, key, account string) error {
f.added[key] = append(f.added[key], account)
return nil
}
func (f *fakePlane) RemoveTopicMember(_ context.Context, key, account string) error {
f.removed[key] = append(f.removed[key], account)
return nil
}
type fakeBook struct {
accounts []oltp.Account
grants map[string]map[string]oltp.Role
}
func (b fakeBook) Accounts() ([]oltp.Account, error) { return b.accounts, nil }
func (b fakeBook) GrantsFor(account string) (map[string]oltp.Role, error) {
return b.grants[account], nil
}
func has(list []string, want string) bool {
for _, s := range list {
if s == want {
return true
}
}
return false
}
// The sweep makes notify match the forge: every account is a subscriber,
// the admin group holds today's admins and nobody else, and a grant is a
// membership of that repository's topic — whether or not the write that
// created it ever provisioned anything.
func TestReconcileMatchesAccountsAndGrants(t *testing.T) {
np := newFakePlane()
book := fakeBook{
accounts: []oltp.Account{
{Name: "dmestas", Admin: true},
{Name: "lou"},
{Name: "ghost", Admin: true, Disabled: "2026-09-01T00:00:00"},
},
grants: map[string]map[string]oltp.Role{
"dmestas": {"quarry": oltp.RepoAdmin},
"lou": {"quarry": oltp.Read, "Synthetic": oltp.Read},
"ghost": {"quarry": oltp.Read},
},
}
sync, err := reconcileNotify(context.Background(), np, book)
if err != nil {
t.Fatalf("FAIL: %v", err)
}
for _, name := range []string{"dmestas", "lou", "ghost"} {
if !has(np.subs, name) {
t.Errorf("FAIL: %s was not ensured as a subscriber", name)
}
}
if !has(np.added[adminsTopic], "dmestas") {
t.Error("FAIL: the admin did not join the admin group")
}
if !has(np.removed[adminsTopic], "lou") {
t.Error("FAIL: a non-admin was left in the admin group")
}
if !has(np.removed[adminsTopic], "ghost") || has(np.added[adminsTopic], "ghost") {
t.Error("FAIL: a disabled admin still receives fleet alerts")
}
if _, ok := np.topics[adminsTopic]; !ok {
t.Error("FAIL: the admin group topic was never created")
}
// A grant is a membership, and the key is the repository's, never
// the raw name: notify's keys are lowercase and punctuation-free,
// so "Synthetic" and "synthetic" must not become two topics.
if _, ok := np.topics[repoTopicKey("quarry")]; !ok {
t.Error("FAIL: the repository's activity topic was never created")
}
if !has(np.added[repoTopicKey("quarry")], "lou") {
t.Error("FAIL: a granted account did not join the repository topic")
}
if !has(np.added[repoTopicKey("Synthetic")], "lou") {
t.Error("FAIL: the second grant was skipped")
}
// A shut account keeps its rows in the forge; it must not keep its
// notifications.
if has(np.added[repoTopicKey("quarry")], "ghost") {
t.Error("FAIL: a disabled account was subscribed to repository activity")
}
if sync.Subscribers != 3 || sync.Members != 4 {
t.Errorf("FAIL: counted %d subscribers and %d memberships, want 3 and 4",
sync.Subscribers, sync.Members)
}
t.Log("ok: subscribers, the admin group and every grant's topic are current")
}
// One account notify cannot hold must not cost the others their alerts.
func TestReconcileKeepsGoingPastOneFailure(t *testing.T) {
np := newFakePlane()
np.failSub = "lou"
book := fakeBook{
accounts: []oltp.Account{{Name: "lou"}, {Name: "dmestas", Admin: true}},
grants: map[string]map[string]oltp.Role{"dmestas": {"quarry": oltp.RepoAdmin}},
}
sync, err := reconcileNotify(context.Background(), np, book)
if err == nil {
t.Error("FAIL: the failure was swallowed")
}
if !has(np.added[adminsTopic], "dmestas") || sync.Subscribers != 1 {
t.Error("FAIL: the sweep stopped at the first failure")
}
if has(np.added[adminsTopic], "lou") || has(np.removed[adminsTopic], "lou") {
t.Error("FAIL: an account notify does not hold was added to a topic anyway")
}
t.Log("ok: a failed account is reported and the rest are still provisioned")
}