Files
mesh-sdk/go/process/emit_integration_test.go
T
jschoubben 5fa64be894 Revert the revert of G's mesh-sdk merge (#191): G's sdk stands again over reader release 3
Main reverted G's half merge (#189, reverted by 8afc3eb in #191) and then took the reader release's S1-S5, which
copied G's code. G's form holds where they differ (process_bus.go, seats.go, state.go and their tests); the
release's kept names stay so main's callers keep building: SeatViewPrefix beside SeatReadPrefix, and QueueInvoke's
empty strings on not-ok (with its test TestQueueInvoke). The tree differs from G's head f30dee54 only by those and
the release's two tests (objects cap option, seat states and stream kinds).

Builds: design 47 G (the milestone's sdk part, as at f30dee54)

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
2026-11-13 12:49:56 +01:00

74 lines
2.8 KiB
Go

//go:build integration
package process
import (
"testing"
"time"
"github.com/nats-io/nats.go/jetstream"
stdio "git.novox.be/novox/mesh-sdk/go"
)
// 1188/AC3: given a stream accepting mail.send.sent, when the process emits it twice with the same
// message id inside the duplicate window, then the stream holds one message; with the headers stdio's
// Emit sets (stdio.go:498-509).
func TestEmitTwiceWithTheSameIDIsKeptToOneWithTheSDKsHeaders(t *testing.T) {
url, account := grantedSendProcess(t)
account.Node = "novox"
_, adminJetStream := adminJS(t, url)
stream, err := adminJetStream.CreateStream(ctxFor(t), jetstream.StreamConfig{
Name: "MAIL_EVENTS", Subjects: []string{"mesh.mod.mesh-mail.event.>", "mesh.seat.mail-sender.event.>", "mesh.seat.mail-sender.accept.>"}, Duplicates: time.Minute,
})
if err != nil {
t.Fatalf("the admin could not make the events stream: %v", err)
}
conn, err := Connect(account)
if err != nil {
t.Fatal(err)
}
defer conn.Close()
for i := 0; i < 2; i++ {
if err := conn.Emit("mail.send.sent", map[string]any{"send": "s1"}, stdio.EmitOptions{MessageID: "send-s1"}); err != nil {
t.Fatalf("emit %d: %v", i, err)
}
}
// A seat's event goes on mesh.seat.<seat>.event.<event> with the same headers (design 47 G A-10).
if err := conn.EmitSeat("mail-sender", "sent", map[string]any{"send": "s1"}, stdio.EmitOptions{MessageID: "seat-s1"}); err != nil {
t.Fatalf("EmitSeat: %v", err)
}
if m, err := stream.GetLastMsgForSubject(ctxFor(t), "mesh.seat.mail-sender.event.sent"); err != nil || m.Header.Get("x-event-id") != "seat-s1" || m.Header.Get("x-source") != "mesh-mail" {
t.Fatalf("the seat's event: %v, %v", m, err)
}
// An accepted kind goes on mesh.seat.<seat>.accept.<kind>.<caller>, the caller this process's module (A-273).
if err := conn.Accept("mail-sender", "send", map[string]any{"send": "s2"}, stdio.EmitOptions{MessageID: "accept-s2"}); err != nil {
t.Fatalf("Accept: %v", err)
}
if m, err := stream.GetLastMsgForSubject(ctxFor(t), "mesh.seat.mail-sender.accept.send.mesh-mail"); err != nil || m.Header.Get("x-event-id") != "accept-s2" || m.Header.Get("x-source") != "mesh-mail" {
t.Fatalf("the accepted kind: %v, %v", m, err)
}
info, err := stream.Info(ctxFor(t))
if err != nil {
t.Fatal(err)
}
if info.State.Msgs != 3 {
t.Fatalf("the stream holds %d messages, want 3: one of the doubled publish, one of the seat's event, one accepted", info.State.Msgs)
}
msg, err := stream.GetMsg(ctxFor(t), 1)
if err != nil {
t.Fatal(err)
}
if msg.Header.Get("x-event-id") != "send-s1" || msg.Header.Get("x-source") != "mesh-mail" ||
msg.Header.Get("x-node") != "novox" || msg.Header.Get("content-type") != "application/json" ||
msg.Header.Get("x-time") == "" {
t.Errorf("the stored message's headers are not the SDK's: %v", msg.Header)
}
}