feat: add durable event contract

This commit is contained in:
Grendgi
2026-06-17 14:49:22 +03:00
parent 5b6a1c56ea
commit 5786958078
2 changed files with 248 additions and 0 deletions

View File

@@ -0,0 +1,98 @@
package durableevent
import (
"encoding/json"
"testing"
"time"
)
func TestNewEventBuildsValidEvent(t *testing.T) {
event, err := New("hh.response_received", "hh_response", "resume-1", map[string]any{"resume_id": "resume-1"})
if err != nil {
t.Fatalf("New returned error: %v", err)
}
if event.SchemaVersion != DefaultSchemaVersion {
t.Fatalf("schema version = %d, want %d", event.SchemaVersion, DefaultSchemaVersion)
}
if event.IdempotencyKey == "" {
t.Fatal("idempotency key was not generated")
}
if err := event.Validate(); err != nil {
t.Fatalf("generated event is invalid: %v", err)
}
}
func TestEventValidateRejectsInvalidShape(t *testing.T) {
validTime := time.Date(2026, 6, 17, 10, 0, 0, 0, time.UTC)
tests := []struct {
name string
event Event
}{
{
name: "bad event type",
event: Event{
EventType: "HH Response",
EntityType: "hh_response",
EntityID: "1",
IdempotencyKey: "key",
SchemaVersion: 1,
OccurredAt: validTime,
},
},
{
name: "missing entity id",
event: Event{
EventType: "hh.response_received",
EntityType: "hh_response",
IdempotencyKey: "key",
SchemaVersion: 1,
OccurredAt: validTime,
},
},
{
name: "invalid payload",
event: Event{
EventType: "hh.response_received",
EntityType: "hh_response",
EntityID: "1",
IdempotencyKey: "key",
SchemaVersion: 1,
OccurredAt: validTime,
Payload: json.RawMessage(`{`),
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if err := tt.event.Validate(); err == nil {
t.Fatal("invalid event was accepted")
}
})
}
}
func TestBuildIdempotencyKeyIsStable(t *testing.T) {
a := BuildIdempotencyKey("hh.response_received", "resume-1", "response-2")
b := BuildIdempotencyKey("hh.response_received", "resume-1", "response-2")
c := BuildIdempotencyKey("hh.response_received", "resume-1", "response-3")
if a == "" {
t.Fatal("empty idempotency key")
}
if a != b {
t.Fatal("same parts produced different keys")
}
if a == c {
t.Fatal("different parts produced same key")
}
}
func TestPayloadAcceptsRawMessage(t *testing.T) {
raw := json.RawMessage(`{"ok":true}`)
got, err := Payload(raw)
if err != nil {
t.Fatalf("Payload returned error: %v", err)
}
if string(got) != string(raw) {
t.Fatalf("payload = %s, want %s", got, raw)
}
}