59 lines
2.4 KiB
Go
59 lines
2.4 KiB
Go
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")
|
||
}
|
||
}
|