Skip to content
quarry Artifact [e74434cdb2]
Login

Artifact [e74434cdb2]

Artifact e74434cdb27d29a7862be1a5cae6907708280f7cc88a8ba847ad7d65c34551e0:


package events

import (
	"time"

	"testing"

	"craftdesign.group/quarry/internal/evt"
)

// A WatchNoun subscriber wakes when a matching event is raised for its
// own repo and noun — the change signal the CI run page waits on
// instead of polling dagnats on a timer.
func TestWatchNounTicksOnMatchingRaise(t *testing.T) {
	s := testServer(t)
	ticks, cancel := s.WatchNoun("alpha", "ci")
	defer cancel()
	if err := s.Raise(evt.CIStarted, "alpha", map[string]any{"runId": "r1"}); err != nil {
		t.Fatal(err)
	}
	select {
	case <-ticks:
	case <-time.After(3 * time.Second):
		t.Fatal("no tick for a matching raise")
	}
}

// A different noun in the same repo must not wake this watcher — the
// whole point of scoping the subscription is that a chat message does
// not push every open CI run page.
func TestWatchNounIgnoresAnotherNoun(t *testing.T) {
	s := testServer(t)
	ticks, cancel := s.WatchNoun("alpha", "ci")
	defer cancel()
	if err := s.Raise(evt.TicketOpened, "alpha", nil); err != nil {
		t.Fatal(err)
	}
	select {
	case <-ticks:
		t.Fatal("ticked for a different noun")
	case <-time.After(300 * time.Millisecond):
	}
}

// Nor may a matching noun in another repository wake it — one poller's
// event must reach only the readers watching that repo.
func TestWatchNounIgnoresAnotherRepo(t *testing.T) {
	s := testServer(t)
	ticks, cancel := s.WatchNoun("alpha", "ci")
	defer cancel()
	if err := s.Raise(evt.CIStarted, "beta", map[string]any{"runId": "r1"}); err != nil {
		t.Fatal(err)
	}
	select {
	case <-ticks:
		t.Fatal("ticked for another repo's event")
	case <-time.After(300 * time.Millisecond):
	}
}

// A subscribe failure — here forced by closing the connection first —
// must not leave the caller blocking on a channel that will never tick;
// the channel is closed instead.
func TestWatchNounClosesChannelOnSubscribeFailure(t *testing.T) {
	s := testServer(t)
	s.nc.Close() // the connection is gone; Subscribe must fail
	ticks, cancel := s.WatchNoun("alpha", "ci")
	defer cancel()
	select {
	case _, ok := <-ticks:
		if ok {
			t.Fatal("channel delivered a value instead of closing")
		}
	case <-time.After(2 * time.Second):
		t.Fatal("channel neither ticked nor closed")
	}
}