package api
import (
"sync"
"testing"
"craftdesign.group/quarry/internal/evt"
)
type fakeEvents struct {
mu sync.Mutex
seen []string
}
func (f *fakeEvents) Raise(kind evt.Kind, repo string, _ map[string]any) error {
f.mu.Lock()
defer f.mu.Unlock()
f.seen = append(f.seen, kind.Subject(repo))
return nil
}
func (f *fakeEvents) subjects() []string {
f.mu.Lock()
defer f.mu.Unlock()
return append([]string(nil), f.seen...)
}
func TestActivityRaisesOnItsSubject(t *testing.T) {
fe := &fakeEvents{}
d := Deps{Events: fe}
d.fireNotify(NotifyEvent{
Kind: evt.TicketOpened, Workflow: "quarry-activity", To: "repo:test",
Payload: map[string]any{"repo": "test", "actor": "dan"},
TxnID: "activity:ticket:1",
})
got := fe.subjects()
if len(got) != 1 || got[0] != "quarry.evt.test.ticket.opened" {
t.Fatalf("raised %v, want [quarry.evt.test.ticket.opened]", got)
}
}
// A mention is addressed to one person, not to the repository, so it is
// not part of the repository's event vocabulary — the same line the
// webhook surface already draws.
func TestMentionsRaiseNothing(t *testing.T) {
fe := &fakeEvents{}
d := Deps{Events: fe}
d.fireNotify(NotifyEvent{
Kind: evt.ForumPosted, Workflow: "quarry-mention", To: "dan",
Payload: map[string]any{"repo": "test"},
TxnID: "mention:1",
})
if got := fe.subjects(); len(got) != 0 {
t.Errorf("a mention raised %v", got)
}
}
// kindOf's guess off a TxnID is good enough to label a webhook payload,
// but a workflow matches on the SUBJECT — so an unnamed site must raise
// nothing rather than something a subscriber would come to depend on.
func TestUnnamedSiteRaisesNothing(t *testing.T) {
fe := &fakeEvents{}
d := Deps{Events: fe}
d.fireNotify(NotifyEvent{
Workflow: "quarry-activity", To: "repo:test",
Payload: map[string]any{"repo": "test"},
TxnID: "activity:wiki:abc",
})
if got := fe.subjects(); len(got) != 0 {
t.Errorf("an unnamed site raised %v", got)
}
}