package events import ( "context" "strings" "testing" core "git.yuntuo.hk/k2safe/orbit/model" "git.yuntuo.hk/k2safe/orbit/platform/auth" ) type recordingStore struct { Store input CreateInput calls int } func (s *recordingStore) CreateSubscription(_ context.Context, _ auth.Token, _ string, in CreateInput) (SubscriptionResult, error) { s.input = in s.calls++ return SubscriptionResult{}, nil } func TestSubscriptionNormalizationAndValidation(t *testing.T) { store := &recordingStore{} svc := New(store) good := CreateInput{Name: "object-results", QueueID: core.ID(strings.Repeat("1", 32))} if _, err := svc.Create(context.Background(), auth.Token{}, "create", good); err != nil { t.Fatal(err) } if store.input.MaxPending != 100 || store.input.MaxAttempts != 20 || len(store.input.Types) != 4 || store.input.FromSequence != nil { t.Fatal("invalid defaults") } // 排序仅作用于内部副本,不修改调用方重报保存的原输入。 types := []string{"task.succeeded", "task.cancelled"} good.Types = types if _, err := svc.Create(context.Background(), auth.Token{}, "create", good); err != nil { t.Fatal(err) } if types[0] != "task.succeeded" || store.input.Types[0] != "task.cancelled" { t.Fatal("normalization modified caller") } cases := []func(*CreateInput){ func(in *CreateInput) { in.Name = " spaced " }, func(in *CreateInput) { in.QueueID = "missing" }, func(in *CreateInput) { in.MaxPending = 1001 }, func(in *CreateInput) { in.MaxAttempts = 101 }, func(in *CreateInput) { in.Types = []string{"task.accepted"} }, func(in *CreateInput) { in.Types = []string{"task.failed", "task.failed"} }, } for i, mutate := range cases { in := good mutate(&in) if _, err := svc.Create(context.Background(), auth.Token{}, "create", in); err == nil { t.Fatalf("accepted invalid case %d", i) } } for _, key := range []string{"", "with space", strings.Repeat("a", 129)} { if _, err := svc.Create(context.Background(), auth.Token{}, key, good); err == nil { t.Fatal("accepted invalid identity") } } if store.calls != 2 { t.Fatal("invalid input reached storage") } } func TestDeliveryProofStrictness(t *testing.T) { secret, digest, err := NewSecret() if err != nil { t.Fatal(err) } actual, err := SecretDigest(secret) if err != nil || actual != digest { t.Fatal("proof roundtrip", err) } for _, s := range []string{"", secret + "=", secret + "\n", secret[:42], strings.Repeat("!", 43)} { if _, err := SecretDigest(s); err == nil { t.Fatal("accepted noncanonical proof") } } if ResultType("task.requeued") || ResultType("task.accepted") || !ResultType("task.needs_review") { t.Fatal("invalid result event scope") } }