nginx-proxy-manager-zh/backend/internal/api/http/responses_test.go

197 lines
5.9 KiB
Go
Raw Normal View History

2023-07-24 21:59:02 -04:00
package http
import (
"io"
"net/http"
"net/http/httptest"
"npm/internal/entity/user"
"npm/internal/model"
"testing"
"github.com/qri-io/jsonschema"
"github.com/stretchr/testify/assert"
2023-11-07 18:57:15 -05:00
"go.uber.org/goleak"
2023-07-24 21:59:02 -04:00
)
func TestResultResponseJSON(t *testing.T) {
2023-11-07 18:57:15 -05:00
// goleak is used to detect goroutine leaks
defer goleak.VerifyNone(t, goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener"))
2023-07-24 21:59:02 -04:00
tests := []struct {
name string
status int
given interface{}
want string
}{
{
name: "simple response",
status: http.StatusOK,
given: true,
want: "{\"result\":true}",
},
{
name: "detailed response",
status: http.StatusBadRequest,
given: user.Model{
ModelBase: model.ModelBase{ID: 10},
Email: "me@example.com",
Name: "John Doe",
Nickname: "Jonny",
},
want: "{\"result\":{\"id\":10,\"created_at\":0,\"updated_at\":0,\"name\":\"John Doe\",\"nickname\":\"Jonny\",\"email\":\"me@example.com\",\"is_disabled\":false,\"gravatar_url\":\"\"}}",
},
{
name: "error response",
status: http.StatusNotFound,
given: ErrorResponse{
Code: 404,
Message: "Not found",
Invalid: []string{"your", "page", "was", "not", "found"},
},
want: "{\"result\":null,\"error\":{\"code\":404,\"message\":\"Not found\",\"invalid\":[\"your\",\"page\",\"was\",\"not\",\"found\"]}}",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
r := httptest.NewRequest(http.MethodGet, "/anything", nil)
w := httptest.NewRecorder()
ResultResponseJSON(w, r, tt.status, tt.given)
res := w.Result()
defer res.Body.Close()
body, err := io.ReadAll(res.Body)
if err != nil {
t.Errorf("expected error to be nil got %v", err)
}
assert.Equal(t, tt.want, string(body))
assert.Equal(t, tt.status, res.StatusCode)
assert.Equal(t, "application/json; charset=utf-8", res.Header.Get("Content-Type"))
})
}
}
func TestResultSchemaErrorJSON(t *testing.T) {
2023-11-07 18:57:15 -05:00
// goleak is used to detect goroutine leaks
defer goleak.VerifyNone(t, goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener"))
2023-07-24 21:59:02 -04:00
tests := []struct {
name string
given []jsonschema.KeyError
want string
}{
{
name: "case a",
given: []jsonschema.KeyError{
{
PropertyPath: "/something",
InvalidValue: "name",
Message: "Name cannot be empty",
},
},
want: "{\"result\":null,\"error\":{\"code\":400,\"message\":{},\"invalid\":[{\"propertyPath\":\"/something\",\"invalidValue\":\"name\",\"message\":\"Name cannot be empty\"}]}}",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
r := httptest.NewRequest(http.MethodGet, "/anything", nil)
w := httptest.NewRecorder()
ResultSchemaErrorJSON(w, r, tt.given)
res := w.Result()
defer res.Body.Close()
body, err := io.ReadAll(res.Body)
if err != nil {
t.Errorf("expected error to be nil got %v", err)
}
assert.Equal(t, tt.want, string(body))
assert.Equal(t, 400, res.StatusCode)
assert.Equal(t, "application/json; charset=utf-8", res.Header.Get("Content-Type"))
})
}
}
func TestResultErrorJSON(t *testing.T) {
2023-11-07 18:57:15 -05:00
// goleak is used to detect goroutine leaks
defer goleak.VerifyNone(t, goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener"))
2023-07-24 21:59:02 -04:00
tests := []struct {
name string
status int
message string
extended interface{}
want string
}{
{
name: "case a",
status: http.StatusBadGateway,
message: "Oh not something is not acceptable",
extended: nil,
want: "{\"result\":null,\"error\":{\"code\":502,\"message\":\"Oh not something is not acceptable\"}}",
},
{
name: "case b",
status: http.StatusNotAcceptable,
message: "Oh not something is not acceptable again",
extended: []string{"name is not allowed", "dob is wrong or something"},
want: "{\"result\":null,\"error\":{\"code\":406,\"message\":\"Oh not something is not acceptable again\",\"invalid\":[\"name is not allowed\",\"dob is wrong or something\"]}}",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
r := httptest.NewRequest(http.MethodGet, "/anything", nil)
w := httptest.NewRecorder()
ResultErrorJSON(w, r, tt.status, tt.message, tt.extended)
res := w.Result()
defer res.Body.Close()
body, err := io.ReadAll(res.Body)
if err != nil {
t.Errorf("expected error to be nil got %v", err)
}
assert.Equal(t, tt.want, string(body))
assert.Equal(t, tt.status, res.StatusCode)
assert.Equal(t, "application/json; charset=utf-8", res.Header.Get("Content-Type"))
})
}
}
func TestNotFound(t *testing.T) {
2023-11-07 18:57:15 -05:00
// goleak is used to detect goroutine leaks
defer goleak.VerifyNone(t, goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener"))
2023-07-24 21:59:02 -04:00
t.Run("basic test", func(t *testing.T) {
r := httptest.NewRequest(http.MethodGet, "/anything", nil)
w := httptest.NewRecorder()
NotFound(w, r)
res := w.Result()
defer res.Body.Close()
body, err := io.ReadAll(res.Body)
if err != nil {
t.Errorf("expected error to be nil got %v", err)
}
assert.Equal(t, "{\"result\":null,\"error\":{\"code\":404,\"message\":\"Not found\"}}", string(body))
assert.Equal(t, http.StatusNotFound, res.StatusCode)
assert.Equal(t, "application/json; charset=utf-8", res.Header.Get("Content-Type"))
})
}
func TestResultResponseText(t *testing.T) {
2023-11-07 18:57:15 -05:00
// goleak is used to detect goroutine leaks
defer goleak.VerifyNone(t, goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener"))
2023-07-24 21:59:02 -04:00
t.Run("basic test", func(t *testing.T) {
r := httptest.NewRequest(http.MethodGet, "/anything", nil)
w := httptest.NewRecorder()
ResultResponseText(w, r, http.StatusOK, "omg this works")
res := w.Result()
defer res.Body.Close()
body, err := io.ReadAll(res.Body)
if err != nil {
t.Errorf("expected error to be nil got %v", err)
}
assert.Equal(t, "omg this works", string(body))
assert.Equal(t, http.StatusOK, res.StatusCode)
assert.Equal(t, "text/plain; charset=utf-8", res.Header.Get("Content-Type"))
})
}