package api import ( "context" "git.ipao.vip/rogee/creator-hub/internal/creator" "testing" "time" ) type gatedListenerWriter struct { listenerWriterStub entered, release chan struct{} } func (s *gatedListenerWriter) RecordListenerDeliveries(ctx context.Context, id, generation string, items []creator.ListenerDelivery) error { close(s.entered) select { case <-ctx.Done(): return ctx.Err() case <-s.release: } return s.listenerWriterStub.RecordListenerDeliveries(ctx, id, generation, items) } func TestListenerPushIsPublishedOnlyAfterSuccessfulCommit(t *testing.T) { updates, remove := creatorUpdates.subscribe() defer remove() writer := &gatedListenerWriter{entered: make(chan struct{}), release: make(chan struct{})} session := &listenerSessionStub{initial: []creator.ListenerDelivery{{Kind: "open", DeliveryID: "saved"}}, pollErr: creator.ErrConflict} result := make(chan error, 1) go func() { result <- runListenerSession(context.Background(), writer, "account", "generation", session) }() select { case <-writer.entered: case <-time.After(time.Second): t.Fatal("persistence not started") } select { case <-updates: t.Fatal("published before commit") default: } close(writer.release) select { case <-result: case <-time.After(time.Second): t.Fatal("worker did not finish") } select { case <-updates: case <-time.After(100 * time.Millisecond): t.Fatal("successful commit did not notify page") } if len(session.ack) != 1 || session.ack[0] != "saved" { t.Fatal("saved delivery not acknowledged") } }