package events
import (
"testing"
"time"
"craftdesign.group/quarry/internal/evt"
)
// Repository names may contain dots, so a.b's subjects begin with a's.
// Nothing read or watched for a may carry a.b's: a.b may be private
// where a is public, and its actors, summaries, readers and even the
// timing of its pushes are its own.
func TestTheEventLogShowsOnlyThatRepository(t *testing.T) {
s := testServer(t)
for _, repo := range []string{"a", "a.b"} {
if err := s.Raise(evt.TicketClosed, repo, map[string]any{"actor": "in-" + repo}); err != nil {
t.Fatal(err)
}
}
got, err := s.Recent("a", 10)
if err != nil {
t.Fatal(err)
}
if len(got) != 1 || got[0].Repo != "a" || got[0].Actor != "in-a" {
t.Errorf("a's event log is %+v, want only a's one event", got)
}
}
func TestATallyFamilyCountsOnlyThatRepository(t *testing.T) {
s := testServer(t)
for _, c := range [][2]string{
{"a", "clone.auth.ann"},
{"a", "clone.client.zit.v1"},
// a.clone.auth's clone total, and a.clone.client's reader bob:
// each continues one of a's families by a token or two.
{"a.clone.auth", "clone"},
{"a.clone.client", "clone.auth.bob"},
{"a.x", "clone.auth.eve"},
} {
if err := s.Count(c[0], c[1], 1); err != nil {
t.Fatal(err)
}
}
auth, err := s.Totals("a", "clone.auth")
if err != nil {
t.Fatal(err)
}
if len(auth) != 1 || auth["ann"] != 1 {
t.Errorf("a's readers are %v, want only ann", auth)
}
clients, err := s.Totals("a", "clone.client")
if err != nil {
t.Fatal(err)
}
if len(clients) != 1 || clients["zit.v1"] != 1 {
t.Errorf("a's clients are %v, want only zit.v1", clients)
}
}
// ticked reports whether ch ticks within a short wait.
func ticked(ch <-chan struct{}) bool {
select {
case <-ch:
return true
case <-time.After(300 * time.Millisecond):
return false
}
}
func TestALiveWatchWakesOnlyForThatRepository(t *testing.T) {
s := testServer(t)
ticks, cancel := s.Watch("a")
defer cancel()
if err := s.nc.Publish("zit.evt.a.b.artifact", nil); err != nil {
t.Fatal(err)
}
if ticked(ticks) {
t.Error("a's watch ticked for a push to a.b")
}
if err := s.nc.Publish("zit.evt.a.artifact", nil); err != nil {
t.Fatal(err)
}
if !ticked(ticks) {
t.Error("a's watch never ticked for a's own push")
}
every, stop := s.Watch("*")
defer stop()
if err := s.nc.Publish("zit.evt.a.b.artifact", nil); err != nil {
t.Fatal(err)
}
if !ticked(every) {
t.Error("the watch on every repository missed a dotted one")
}
}
func TestANounWatchWakesOnlyForThatRepository(t *testing.T) {
s := testServer(t)
ticks, cancel := s.WatchNoun("a", "ci")
defer cancel()
// a.ci's ci.started is quarry.evt.a.ci.ci.started.
if err := s.Raise(evt.CIStarted, "a.ci", nil); err != nil {
t.Fatal(err)
}
if ticked(ticks) {
t.Error("a's ci watch ticked for a.ci's run")
}
}