package response_test import ( "encoding/json" "strings" "testing" apierrors "git.yuntuo.hk/k2safe/go-omni/errors" "git.yuntuo.hk/k2safe/go-omni/response" ) func TestCatalogHTTP200AndRawJSON(t *testing.T) { c := apierrors.Catalog{DefaultStatus: 200, Definitions: map[string]apierrors.Definition{"INVALID": {Code: 400002, Message: "invalid"}}} cfg := response.Config{CodeType: "int32", SuccessCode: 0, ErrorCode: 9999, ErrorMessage: "fallback", Body: map[string]any{"ok": "${ok}", "code": "${code}", "data": "${data}"}, ErrorBody: map[string]any{"failed": "${ok}", "code": "${code}", "msg": "${message}"}} enc, err := response.WithErrors(c, response.MustNew(cfg)) if err != nil { t.Fatal(err) } for _, encoder := range []response.Encoder{enc, response.RawJSON(enc)} { p, err := encoder.Encode(response.Result{Status: 500, Err: apierrors.ByCode("INVALID")}) if err != nil { t.Fatal(err) } var body map[string]any if err = json.Unmarshal(p.Body, &body); err != nil { t.Fatal(err) } if p.Status != 200 || body["failed"] != false || body["code"] != float64(400002) || body["msg"] != "invalid" || body["data"] != nil { t.Fatal(string(p.Body)) } } p, err := response.RawJSON(enc).Encode(response.Result{Status: 200, Data: map[string]bool{"value": true}}) if err != nil || strings.Contains(string(p.Body), "code") { t.Fatal(string(p.Body), err) } for _, change := range []response.Config{ {CodeType: "string"}, {CodeType: "int32", SuccessCode: 0, ErrorCode: 9, Codes: map[string]any{"INVALID": 1}}, {CodeType: "int32", SuccessCode: 0, ErrorCode: 9, Messages: map[string]string{"INVALID": "different"}}, } { if _, err := response.WithErrors(c, response.MustNew(change)); err == nil { t.Fatal("accepted conflicting catalog mapping") } } enc, err = response.WithErrors(c, response.EncoderFunc(func(r response.Result) (response.Payload, error) { if !r.IsError() || r.Status != 200 || r.BusinessCode != int64(400002) { t.Fatal(r) } return response.Text(202, "ACK"), nil })) if err != nil { t.Fatal(err) } p, err = enc.Encode(response.Result{Err: apierrors.ByCode("INVALID")}) if err != nil || p.Status != 202 || string(p.Body) != "ACK" { t.Fatal(p, err) } } func TestCatalogWrapperPreservesScope(t *testing.T) { catalog := apierrors.Catalog{DefaultStatus: 200, Definitions: map[string]apierrors.Definition{ "invalid": {Code: "invalid", Message: "project message"}, }} inner := response.MustWithErrors(catalog, response.Default()) for _, encoder := range []response.Encoder{inner, response.RawJSON(inner)} { for _, outer := range []apierrors.Catalog{{}, catalog} { bound, err := response.WithErrors(outer, encoder) if err != nil { t.Fatal(err) } payload, err := bound.Encode(response.Result{Err: apierrors.ByCode("invalid")}) if err != nil || payload.Status != 200 || !strings.Contains(string(payload.Body), "project message") { t.Fatal(payload, err) } } other := catalog.Clone() other.Definitions["invalid"] = apierrors.Definition{Status: 409, Code: "other", Message: "other"} if _, err := response.WithErrors(other, encoder); err == nil { t.Fatal("stacked conflicting policies") } } }