From da583f8d5dd416ef193e9107c472569614d0a12a Mon Sep 17 00:00:00 2001 From: Johan Brandhorst Date: Tue, 3 Apr 2018 21:31:31 +0100 Subject: [PATCH] Add test for marshalling of error details --- runtime/errors_test.go | 37 ++++++++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/runtime/errors_test.go b/runtime/errors_test.go index 2c7ecf18656..de51052893f 100644 --- a/runtime/errors_test.go +++ b/runtime/errors_test.go @@ -1,6 +1,7 @@ package runtime_test import ( + "context" "encoding/json" "fmt" "net/http" @@ -8,8 +9,8 @@ import ( "strings" "testing" - "context" "github.com/grpc-ecosystem/grpc-gateway/runtime" + "google.golang.org/genproto/googleapis/rpc/errdetails" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) @@ -17,10 +18,15 @@ import ( func TestDefaultHTTPError(t *testing.T) { ctx := context.Background() + statusWithDetails, _ := status.New(codes.FailedPrecondition, "failed precondition").WithDetails( + &errdetails.PreconditionFailure{}, + ) + for _, spec := range []struct { - err error - status int - msg string + err error + status int + msg string + details string }{ { err: fmt.Errorf("example error"), @@ -32,10 +38,16 @@ func TestDefaultHTTPError(t *testing.T) { status: http.StatusNotFound, msg: "no such resource", }, + { + err: statusWithDetails.Err(), + status: http.StatusPreconditionFailed, + msg: "failed precondition", + details: "type.googleapis.com/google.rpc.PreconditionFailure", + }, } { w := httptest.NewRecorder() req, _ := http.NewRequest("", "", nil) // Pass in an empty request to match the signature - runtime.DefaultHTTPError(ctx, &runtime.ServeMux{}, &runtime.JSONBuiltin{}, w, req, spec.err) + runtime.DefaultHTTPError(ctx, &runtime.ServeMux{}, &runtime.JSONPb{}, w, req, spec.err) if got, want := w.Header().Get("Content-Type"), "application/json"; got != want { t.Errorf(`w.Header().Get("Content-Type") = %q; want %q; on spec.err=%v`, got, want, spec.err) @@ -53,5 +65,20 @@ func TestDefaultHTTPError(t *testing.T) { if got, want := body["error"].(string), spec.msg; !strings.Contains(got, want) { t.Errorf(`body["error"] = %q; want %q; on spec.err=%v`, got, want, spec.err) } + + if spec.details != "" { + details, ok := body["details"].([]interface{}) + if !ok { + t.Errorf(`body["details"] = %T; want %T`, body["details"], []interface{}{}) + continue + } + if len(details) != 1 { + t.Errorf(`len(body["details"]) = %v; want 1`, len(details)) + continue + } + if details[0].(map[string]interface{})["@type"] != spec.details { + t.Errorf(`details.@type = %s; want %s`, details[0].(map[string]interface{})["@type"], spec.details) + } + } } }