Files
creator-hub/internal/controlplane/api/event_cover_worker_test.go
T
rogee 360bf96bab
douyin-release-gate / verify (push) Failing after 18m0s
feat: push Douyin events through shared WebSocket and SSE
2026-10-07 23:45:32 +08:00

108 lines
3.1 KiB
Go

package api
import (
"context"
"errors"
"git.ipao.vip/rogee/creator-hub/internal/creator"
"testing"
"time"
)
type coverWriterStub struct {
listenerWriterStub
saved chan []creator.ListenerDelivery
err error
}
func (s *coverWriterStub) UpdateListenerEventCovers(_ context.Context, _, _ string, items []creator.ListenerDelivery) error {
s.saved <- items
return s.err
}
type coverEnricherStub struct {
listenerSessionStub
entered chan struct{}
release chan struct{}
err error
}
func (s *coverEnricherStub) enrich(ctx context.Context, items []creator.ListenerDelivery) ([]creator.ListenerDelivery, error) {
select {
case s.entered <- struct{}{}:
default:
}
select {
case <-ctx.Done():
return nil, ctx.Err()
case <-s.release:
}
for i := range items {
items[i].Notice.WorkCoverError = "cached result"
}
return items, s.err
}
func coverDelivery() []creator.ListenerDelivery {
return []creator.ListenerDelivery{{Kind: "notice", DeliveryID: "cover", Notice: &creator.ListenerNotice{EventKey: "cover", EventType: "like", WorkID: "9", WorkAuthorUID: "1", WorkCoverURL: "https://example.com/cover"}}}
}
func TestEventCoverWorkerDoesNotBlockReceptionAndReportsOverload(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
writer := &coverWriterStub{saved: make(chan []creator.ListenerDelivery, 64)}
session := &coverEnricherStub{entered: make(chan struct{}, 1), release: make(chan struct{})}
queue := startListenerCoverWorker(ctx, writer, "account", "generation", session)
original := coverDelivery()
queue(original)()
select {
case <-session.entered:
case <-time.After(time.Second):
t.Fatal("cover worker did not start")
}
for i := 0; i < 32; i++ {
queue(coverDelivery())()
}
overloaded := coverDelivery()
queue(overloaded)()
if overloaded[0].Notice.WorkCoverError != coverQueueFullReason {
t.Fatal("overload must be included in notification persistence")
}
select {
case <-writer.saved:
t.Fatal("overload performed a synchronous cover-result write")
default:
}
if original[0].Notice.WorkCoverError != "" {
t.Fatal("delivery was mutated before persistence")
}
close(session.release)
select {
case saved := <-writer.saved:
if saved[0].Notice.WorkCoverError != "cached result" {
t.Fatal("result missing")
}
case <-time.After(time.Second):
t.Fatal("cover not saved")
}
}
func TestEventCoverFailureIsRecordedAndDoesNotChangeListenerStatus(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
release := make(chan struct{})
close(release)
writer := &coverWriterStub{saved: make(chan []creator.ListenerDelivery, 4), err: creator.ErrConflict}
session := &coverEnricherStub{entered: make(chan struct{}, 1), release: release, err: errors.New("cover unavailable")}
queue := startListenerCoverWorker(ctx, writer, "account", "generation", session)
queue(nil)()
queue(coverDelivery())()
select {
case saved := <-writer.saved:
if saved[0].Notice.WorkCoverError != "cover unavailable" {
t.Fatal("error hidden")
}
case <-time.After(time.Second):
t.Fatal("error not saved")
}
if writer.batches != 0 {
t.Fatal("cover failure changed listener health")
}
}