Skip to content

Commit 7fc05ee

Browse files
committed
add tests
1 parent 239c10f commit 7fc05ee

File tree

4 files changed

+165
-2
lines changed

4 files changed

+165
-2
lines changed

go.mod

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ require (
1616
github.com/go-playground/universal-translator v0.18.0 // indirect
1717
github.com/go-playground/validator/v10 v10.10.0 // indirect
1818
github.com/goccy/go-json v0.9.7 // indirect
19+
github.com/gorilla/websocket v1.5.0 // indirect
1920
github.com/json-iterator/go v1.1.12 // indirect
2021
github.com/labstack/gommon v0.3.1 // indirect
2122
github.com/leodido/go-urn v1.2.1 // indirect
@@ -26,6 +27,7 @@ require (
2627
github.com/pelletier/go-toml/v2 v2.0.1 // indirect
2728
github.com/pmezard/go-difflib v1.0.0 // indirect
2829
github.com/ugorji/go/codec v1.2.7 // indirect
30+
github.com/urfave/negroni v1.0.0 // indirect
2931
github.com/valyala/bytebufferpool v1.0.0 // indirect
3032
github.com/valyala/fasttemplate v1.2.1 // indirect
3133
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 // indirect

go.sum

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGF
1818
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
1919
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
2020
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
21+
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
22+
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
2123
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
2224
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
2325
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
@@ -60,6 +62,8 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO
6062
github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M=
6163
github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0=
6264
github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY=
65+
github.com/urfave/negroni v1.0.0 h1:kIimOitoypq34K7TG7DUaJ9kq/N4Ofuwi1sjz0KipXc=
66+
github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4=
6367
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
6468
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
6569
github.com/valyala/fasttemplate v1.2.1 h1:TVEnxayobAdVkhQfrfes2IzOB6o+z4roRkPF52WA1u4=

problem_details.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"github.com/labstack/echo/v4"
88
"github.com/pkg/errors"
99
"net/http"
10+
"net/http/httptest"
1011
"reflect"
1112
)
1213

@@ -143,10 +144,14 @@ func ResolveProblemDetails(w http.ResponseWriter, r *http.Request, err error) er
143144
statusCode = err.(*echo.HTTPError).Code
144145
err = err.(*echo.HTTPError).Message.(error)
145146
} else if errors.As(err, &ginError) {
146-
var rw = w.(gin.ResponseWriter)
147-
if rw.Written() {
147+
var rw, ok = w.(gin.ResponseWriter)
148+
if ok && rw.Written() {
148149
statusCode = rw.Status()
149150
}
151+
if gin.Mode() == gin.TestMode {
152+
var rw = w.(*httptest.ResponseRecorder)
153+
statusCode = rw.Code
154+
}
150155
err = err.(*gin.Error).Err.(error)
151156
}
152157

problem_details_test.go

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
package problem
2+
3+
import (
4+
"errors"
5+
"github.com/gin-gonic/gin"
6+
"github.com/labstack/echo/v4"
7+
custom_errors "github.com/meysamhadeli/problem-details/samples/custom-errors"
8+
"github.com/stretchr/testify/assert"
9+
"net/http"
10+
"net/http/httptest"
11+
"testing"
12+
)
13+
14+
func Test_BadRequest_Err(t *testing.T) {
15+
badRequestErr := New(http.StatusBadRequest, "bad-request", "We have a bad request error")
16+
17+
assert.Equal(t, "We have a bad request error", badRequestErr.GetDetails())
18+
assert.Equal(t, "bad-request", badRequestErr.GetTitle())
19+
assert.Equal(t, "https://httpstatuses.io/400", badRequestErr.GetType())
20+
assert.Equal(t, http.StatusBadRequest, badRequestErr.GetStatus())
21+
}
22+
23+
func TestMap_CustomType_Echo(t *testing.T) {
24+
25+
e := echo.New()
26+
req := httptest.NewRequest(http.MethodGet, "http://echo_endpoint1", nil)
27+
rec := httptest.NewRecorder()
28+
c := e.NewContext(req, rec)
29+
30+
err := echo_endpoint1(c)
31+
32+
var problemErr ProblemDetailErr
33+
34+
Map[custom_errors.BadRequestError](func() ProblemDetailErr {
35+
problemErr = New(http.StatusBadRequest, "bad-request", err.Error())
36+
return problemErr
37+
})
38+
39+
_ = ResolveProblemDetails(c.Response(), c.Request(), err)
40+
41+
assert.Equal(t, c.Response().Status, http.StatusBadRequest)
42+
assert.Equal(t, err.Error(), problemErr.GetDetails())
43+
assert.Equal(t, "bad-request", problemErr.GetTitle())
44+
assert.Equal(t, "https://httpstatuses.io/400", problemErr.GetType())
45+
assert.Equal(t, http.StatusBadRequest, problemErr.GetStatus())
46+
}
47+
48+
func TestMap_Status_Echo(t *testing.T) {
49+
50+
e := echo.New()
51+
req := httptest.NewRequest(http.MethodGet, "http://echo_endpoint2", nil)
52+
rec := httptest.NewRecorder()
53+
c := e.NewContext(req, rec)
54+
55+
err := echo_endpoint2(c)
56+
57+
var problemErr ProblemDetailErr
58+
59+
// map status code to problem details error
60+
MapStatus(http.StatusBadGateway, func() ProblemDetailErr {
61+
problemErr = New(http.StatusUnauthorized, "unauthorized", err.Error())
62+
return problemErr
63+
})
64+
65+
_ = ResolveProblemDetails(c.Response(), c.Request(), err)
66+
67+
assert.Equal(t, c.Response().Status, http.StatusUnauthorized)
68+
assert.Equal(t, err.(*echo.HTTPError).Message.(error).Error(), problemErr.GetDetails())
69+
assert.Equal(t, "unauthorized", problemErr.GetTitle())
70+
assert.Equal(t, "https://httpstatuses.io/401", problemErr.GetType())
71+
assert.Equal(t, http.StatusUnauthorized, problemErr.GetStatus())
72+
}
73+
74+
func TestMap_CustomType_Gin(t *testing.T) {
75+
76+
gin.SetMode(gin.TestMode)
77+
w := httptest.NewRecorder()
78+
c, _ := gin.CreateTestContext(w)
79+
r := gin.Default()
80+
81+
r.GET("/gin_endpoint1", func(ctx *gin.Context) {
82+
err := errors.New("We have a custom type error in our endpoint")
83+
customBadRequestError := custom_errors.BadRequestError{InternalError: err}
84+
_ = c.Error(customBadRequestError)
85+
})
86+
87+
req, _ := http.NewRequest(http.MethodGet, "/gin_endpoint1", nil)
88+
r.ServeHTTP(w, req)
89+
90+
for _, err := range c.Errors {
91+
92+
var problemErr ProblemDetailErr
93+
94+
Map[custom_errors.BadRequestError](func() ProblemDetailErr {
95+
problemErr = New(http.StatusBadRequest, "bad-request", err.Error())
96+
return problemErr
97+
})
98+
99+
_ = ResolveProblemDetails(w, req, err)
100+
101+
assert.Equal(t, http.StatusBadRequest, problemErr.GetStatus())
102+
assert.Equal(t, err.Error(), problemErr.GetDetails())
103+
assert.Equal(t, "bad-request", problemErr.GetTitle())
104+
assert.Equal(t, "https://httpstatuses.io/400", problemErr.GetType())
105+
}
106+
}
107+
108+
func TestMap_Status_Gin(t *testing.T) {
109+
110+
gin.SetMode(gin.TestMode)
111+
w := httptest.NewRecorder()
112+
c, _ := gin.CreateTestContext(w)
113+
r := gin.Default()
114+
115+
r.GET("/gin_endpoint2", func(ctx *gin.Context) {
116+
err := errors.New("We have a specific status code error in our endpoint")
117+
// change status code 'StatusBadGateway' to 'StatusUnauthorized' base on handler config
118+
_ = c.AbortWithError(http.StatusBadGateway, err)
119+
})
120+
121+
req, _ := http.NewRequest(http.MethodGet, "/gin_endpoint2", nil)
122+
r.ServeHTTP(w, req)
123+
124+
for _, err := range c.Errors {
125+
126+
var problemErr ProblemDetailErr
127+
128+
// map status code to problem details error
129+
MapStatus(http.StatusBadGateway, func() ProblemDetailErr {
130+
problemErr = New(http.StatusUnauthorized, "unauthorized", err.Error())
131+
return problemErr
132+
})
133+
134+
_ = ResolveProblemDetails(w, req, err)
135+
136+
assert.Equal(t, http.StatusUnauthorized, problemErr.GetStatus())
137+
assert.Equal(t, err.Error(), problemErr.GetDetails())
138+
assert.Equal(t, "unauthorized", problemErr.GetTitle())
139+
assert.Equal(t, "https://httpstatuses.io/401", problemErr.GetType())
140+
}
141+
}
142+
143+
func echo_endpoint1(c echo.Context) error {
144+
err := errors.New("We have a custom type error in our endpoint")
145+
return custom_errors.BadRequestError{InternalError: err}
146+
}
147+
148+
func echo_endpoint2(c echo.Context) error {
149+
err := errors.New("We have a specific status code error in our endpoint")
150+
// change status code 'StatusBadGateway' to 'StatusUnauthorized' base on handler config
151+
return echo.NewHTTPError(http.StatusBadGateway, err)
152+
}

0 commit comments

Comments
 (0)