package link import ( "strings" "testing" "github.com/novox/mesh-controller/internal/broker" ) // A message given up on a module's own stream is delivered again on EVENTS to the consumer that gave it up, // and only while that consumer is still granted it (novox/hq ADR 0363 ยง7). func TestAModuleStreamsDeadLetterGoesBackOnlyWhileGranted(t *testing.T) { js := aBus(t) mail := broker.ModuleStream{Module: "mesh-mail", Name: "MAIL", Events: []string{"mail.*.message.added"}, MaxAgeDays: 7, MaxMiB: 16, Restricted: true} if err := js.EnsureStream(mail.Stream()); err != nil { t.Fatal(err) } t.Cleanup(func() { _ = js.Context().DeleteStream("MAIL") }) subject := broker.ModuleStreamSubject("mesh-mail", "mail.mesh.message.added") heard := broker.Heard{Stream: "MAIL", Emitter: "mesh-mail", Filters: []string{subject}} reader := broker.Principal{Kind: broker.KindModule, Node: "ace", Module: "reader", Hears: []broker.Heard{heard}, PasswordHash: "x"} users := broker.ConsumersOf([]broker.Principal{reader}) if len(users) != 2 { t.Fatalf("the reader's consumers: %+v", users) } for _, c := range users { if err := js.EnsureConsumer(c.Consumer); err != nil { t.Fatal(err) } } d := DeadLetter{ID: 9, Stream: "MAIL", Consumer: "ace_reader", Subject: subject} got, err := AgainTo(js.Context(), d) if err != nil { t.Fatal(err) } if got != broker.AgainSubject("ace_reader", subject) { t.Fatalf("delivered again on %s", got) } if err := js.RemoveConsumer("MAIL", "ace_reader"); err != nil { t.Fatal(err) } if _, err := AgainTo(js.Context(), d); err == nil || !strings.Contains(err.Error(), "no longer hears MAIL") { t.Fatalf("delivered again to a consumer no longer granted: %v", err) } }