package httpserver import ( "encoding/json" "net/http" "net/http/httptest" "strings" "testing" "git.yuntuo.hk/k2safe/orbit/internal/fault" "git.yuntuo.hk/k2safe/orbit/pulse/service" ) func TestBodyAndErrorBoundary(t *testing.T) { for _, test := range []struct{ body, content, code string }{ {`{"payload":{"n":1,"n":2}}`, "application/json", "INVALID_ARGUMENT"}, {`{"retry":{"MaxAttempts":2}}`, "application/json", "INVALID_ARGUMENT"}, {`{"retry":{"max_attempts":1},"Retry":{"max_attempts":2}}`, "application/json", "INVALID_ARGUMENT"}, {`{}`, "text/plain", "UNSUPPORTED_MEDIA_TYPE"}, {`{"payload":{"arbitrary_key":9007199254740993}}`, "application/json", ""}, {`{"delay_ms":1000}`, "application/json", ""}, {`{"delay_ms":null}`, "application/json", "INVALID_ARGUMENT"}, {`{"delay_ms":-1}`, "application/json", "INVALID_ARGUMENT"}, {`{"delay_ms":1.5}`, "application/json", "INVALID_ARGUMENT"}, {`{"delay_ms":"1000"}`, "application/json", "INVALID_ARGUMENT"}, {`{"delay_ms":18446744073709551616}`, "application/json", "INVALID_ARGUMENT"}, {`{"delay_ms":1,"delay_ms":2}`, "application/json", "INVALID_ARGUMENT"}, } { r := httptest.NewRequest(http.MethodPost, "/v1/tasks", strings.NewReader(test.body)) r.Header.Set("Content-Type", test.content) var in service.SubmitInput err := decodeBody(r, &in) if test.code == "" { if err != nil { t.Fatal(err) } } else if fault.Code(err) != test.code { t.Fatalf("body %s: %v", test.body, err) } } w := httptest.NewRecorder() writeError(w, "request", fault.Forbidden) var envelope struct { Error struct { Code string `json:"code"` } `json:"error"` } if err := json.Unmarshal(w.Body.Bytes(), &envelope); err != nil || envelope.Error.Code != "PERMISSION_DENIED" || w.Code != 403 { t.Fatalf("bad error contract %s", w.Body.String()) } }