package api
import (
"context"
"path/filepath"
"slices"
"testing"
"craftdesign.group/quarry/internal/evt"
"craftdesign.group/quarry/internal/oltp"
"craftdesign.group/quarry/internal/ops"
)
// #389: a ticket kept on the forge tier raised no ticket.* event, so a
// webhook subscribed to "ticket" never fired on a default repository.
// Each write now raises the event ingest would raise for an artifact
// ticket making the same transition.
func TestForgeTierTicketsRaiseTicketEvents(t *testing.T) {
db, err := oltp.Open(filepath.Join(t.TempDir(), "o.db"))
if err != nil {
t.Fatal(err)
}
t.Cleanup(func() { db.Close() })
ev := &loudEvents{}
r := ops.NewRegistry()
if err := RegisterAll(r, Deps{Version: "v", Repos: testRepos(wikiIndex(t)), Local: db, Events: ev}); err != nil {
t.Fatal(err)
}
ctx := ops.WithUser(context.Background(), "dan")
got, err := r.Invoke(ctx, "ticket.intake", ticketIntakeIn{Repo: "test", Title: "crash on empty input"})
if err != nil {
t.Fatal(err)
}
id := got.(ticketIntakeOut).ID
for _, in := range []ticketSetIn{
{Repo: "test", ID: id[:12], Comment: "reproduced"},
{Repo: "test", ID: id[:12], Status: "Closed"},
{Repo: "test", ID: id[:12], Status: "Open"},
} {
if _, err := r.Invoke(ctx, "ticket.set", in); err != nil {
t.Fatal(err)
}
}
var tickets []evt.Kind
for _, k := range ev.seen() {
if k == evt.TicketOpened || k == evt.TicketChanged || k == evt.TicketClosed || k == evt.TicketReopened {
tickets = append(tickets, k)
}
}
want := []evt.Kind{evt.TicketOpened, evt.TicketChanged, evt.TicketClosed, evt.TicketReopened}
if !slices.Equal(tickets, want) {
t.Fatalf("FAIL: ticket events %v, want %v", tickets, want)
}
ev.mu.Lock()
last := ev.last
ev.mu.Unlock()
if last["ticket"] != id || last["status"] != "Open" || last["actor"] != "dan" {
t.Fatalf("FAIL: last payload %v", last)
}
t.Log("ok: opened, changed, closed, reopened, each once")
}