feat: publish immutable workflow definitions with typed SDK
This commit is contained in:
58
internal/transport/httpserver/workflow_definitions_test.go
Normal file
58
internal/transport/httpserver/workflow_definitions_test.go
Normal file
@@ -0,0 +1,58 @@
|
||||
package httpserver
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"git.yuntuo.hk/k2safe/orbit/weave/definition"
|
||||
)
|
||||
|
||||
func TestWorkflowStrictJSONAndNullableLiteral(t *testing.T) {
|
||||
valid := `{"version":"v1","reason":"release","specification":{"schema_version":1,"input_type":{"kind":"OBJECT","fields":{"number":{"kind":"NUMBER"}}},"timeout_ms":1000,"failure_policy":"REVIEW","body":{"output_type":{"kind":"NULL"},"output":{"kind":"LITERAL","literal":null}}}}`
|
||||
for _, tc := range []struct {
|
||||
name, raw string
|
||||
ok bool
|
||||
}{
|
||||
{"explicit null literal", valid, true},
|
||||
{"map type case alias", strings.Replace(valid, `"number":{"kind"`, `"number":{"Kind"`, 1), false},
|
||||
{"map unknown property", strings.Replace(valid, `"number":{"kind":"NUMBER"}`, `"number":{"kind":"NUMBER","code":"script"}`, 1), false},
|
||||
{"null type map", strings.Replace(valid, `"number":{"kind":"NUMBER"}`, `"number":null`, 1), false},
|
||||
{"null collection", strings.Replace(valid, `"body":{`, `"body":{"steps":null,`, 1), false},
|
||||
{"duplicate field", strings.Replace(valid, `"schema_version":1`, `"schema_version":1,"schema_version":2`, 1), false},
|
||||
{"extra top property", strings.Replace(valid, `"reason":"release"`, `"reason":"release","Code":"arbitrary"`, 1), false},
|
||||
} {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
r := httptest.NewRequest("POST", "/", strings.NewReader(tc.raw))
|
||||
r.Header.Set("Content-Type", "application/json")
|
||||
var in definition.PublishInput
|
||||
err := decodeBody(r, &in)
|
||||
if (err == nil) != tc.ok {
|
||||
t.Fatalf("decode: %v", err)
|
||||
}
|
||||
if tc.ok {
|
||||
if _, err := definition.Check(in.Specification); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
// Value.fields 同样递归检查精确字段名;普通任务payload仍不得显式null。
|
||||
for _, raw := range []string{`{"kind":"OBJECT","fields":{"x":{"Kind":"LITERAL","literal":1}}}`, `{"kind":"OBJECT","fields":{"x":null}}`} {
|
||||
r := httptest.NewRequest("POST", "/", strings.NewReader(raw))
|
||||
r.Header.Set("Content-Type", "application/json")
|
||||
var value definition.Value
|
||||
if decodeBody(r, &value) == nil {
|
||||
t.Fatal("invalid value map accepted")
|
||||
}
|
||||
}
|
||||
var ordinary struct {
|
||||
Payload json.RawMessage `json:"payload"`
|
||||
}
|
||||
r := httptest.NewRequest("POST", "/", strings.NewReader(`{"payload":null}`))
|
||||
r.Header.Set("Content-Type", "application/json")
|
||||
if decodeBody(r, &ordinary) == nil {
|
||||
t.Fatal("nullable exception leaked to task payload")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user