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") } }