112 lines
2.8 KiB
Go
112 lines
2.8 KiB
Go
package docnotify
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
|
|
"chat-agent-system/internal/docgov"
|
|
"chat-agent-system/internal/docrevision"
|
|
"chat-agent-system/internal/notification"
|
|
)
|
|
|
|
type stubNotify struct {
|
|
available bool
|
|
calls int
|
|
lastType string
|
|
}
|
|
|
|
func (s *stubNotify) Available() bool { return s != nil && s.available }
|
|
|
|
func (s *stubNotify) EmitDocumentEvent(_ context.Context, eventType, _, _, _, _ string, _ int64, _ notification.DocumentEventPayload) (bool, error) {
|
|
s.calls++
|
|
s.lastType = eventType
|
|
return true, nil
|
|
}
|
|
|
|
type stubDocs struct {
|
|
doc *docgov.DocumentRecord
|
|
}
|
|
|
|
func (s stubDocs) GetDocument(_ context.Context, _ string) (*docgov.DocumentRecord, error) {
|
|
return s.doc, nil
|
|
}
|
|
|
|
func TestBindOnce(t *testing.T) {
|
|
rev := &docrevision.Service{}
|
|
sub := &Subscriber{Notify: &stubNotify{available: true}}
|
|
if !Bind(rev, sub) {
|
|
t.Fatal("first bind")
|
|
}
|
|
if Bind(rev, sub) {
|
|
t.Fatal("second bind must be a no-op")
|
|
}
|
|
if rev.OnOutbox == nil {
|
|
t.Fatal("hook missing")
|
|
}
|
|
}
|
|
|
|
func TestHandleCandidateReady(t *testing.T) {
|
|
n := &stubNotify{available: true}
|
|
sub := &Subscriber{
|
|
Notify: n,
|
|
Docs: stubDocs{doc: &docgov.DocumentRecord{AuthorID: 9, ProjectID: 4}},
|
|
}
|
|
if err := sub.Handle(context.Background(), notification.EventDocAgentCandidateReady, map[string]any{
|
|
"doc_id": "d1", "candidate_id": int64(3),
|
|
}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if n.calls != 1 || n.lastType != notification.EventDocAgentCandidateReady {
|
|
t.Fatalf("calls=%d type=%s", n.calls, n.lastType)
|
|
}
|
|
}
|
|
|
|
func TestHandleSkipsWhenConsumerLive(t *testing.T) {
|
|
n := &stubNotify{available: true}
|
|
sub := &Subscriber{
|
|
Notify: n,
|
|
Docs: stubDocs{doc: &docgov.DocumentRecord{AuthorID: 9, ProjectID: 4}},
|
|
SkipWrite: func(context.Context) bool {
|
|
return true
|
|
},
|
|
}
|
|
if err := sub.Handle(context.Background(), notification.EventDocAgentCandidateReady, map[string]any{
|
|
"doc_id": "d1", "candidate_id": int64(3),
|
|
}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if n.calls != 0 {
|
|
t.Fatalf("live consumer must skip hook write, calls=%d", n.calls)
|
|
}
|
|
}
|
|
|
|
func TestHandleWritesWhenNotLive(t *testing.T) {
|
|
n := &stubNotify{available: true}
|
|
sub := &Subscriber{
|
|
Notify: n,
|
|
Docs: stubDocs{doc: &docgov.DocumentRecord{AuthorID: 9, ProjectID: 4}},
|
|
SkipWrite: func(context.Context) bool {
|
|
return false
|
|
},
|
|
}
|
|
if err := sub.Handle(context.Background(), notification.EventDocAgentCandidateReady, map[string]any{
|
|
"doc_id": "d1", "candidate_id": int64(3),
|
|
}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if n.calls != 1 {
|
|
t.Fatalf("off/shadow must keep hook write, calls=%d", n.calls)
|
|
}
|
|
}
|
|
|
|
func TestHandleSkipsUnknownAndNoRecipient(t *testing.T) {
|
|
n := &stubNotify{available: true}
|
|
sub := &Subscriber{Notify: n}
|
|
if err := sub.Handle(context.Background(), "document.unknown", map[string]any{"doc_id": "d1"}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if n.calls != 0 {
|
|
t.Fatalf("unknown event must not emit, calls=%d", n.calls)
|
|
}
|
|
}
|