hub/internal/handlers/helpers/helpers_test.go

262 lines
4.9 KiB
Go

package helpers
import (
"bytes"
"errors"
"fmt"
"io"
"net/http"
"net/http/httptest"
"net/url"
"strconv"
"testing"
"time"
"github.com/artifacthub/hub/internal/hub"
"github.com/artifacthub/hub/internal/tests"
"github.com/stretchr/testify/assert"
)
func TestBuildCacheControlHeader(t *testing.T) {
testCases := []struct {
cacheMaxAge time.Duration
expectedCacheControlHeader string
}{
{
0,
"max-age=0",
},
{
1 * time.Minute,
"max-age=60",
},
{
24 * time.Hour,
"max-age=86400",
},
}
for i, tc := range testCases {
t.Run(strconv.Itoa(i), func(t *testing.T) {
t.Parallel()
cacheControlHeader := BuildCacheControlHeader(tc.cacheMaxAge)
assert.Equal(t, tc.expectedCacheControlHeader, cacheControlHeader)
})
}
}
func TestGetPagination(t *testing.T) {
testCases := []struct {
qs url.Values
defaultLimit int
maxLimit int
expectedPagination *hub.Pagination
expectedError error
}{
{
map[string][]string{
"limit": {"aa"},
},
5,
10,
nil,
errors.New("invalid limit"),
},
{
map[string][]string{
"limit": {"20"},
},
5,
10,
nil,
errors.New("invalid limit"),
},
{
nil,
5,
10,
&hub.Pagination{
Limit: 5,
},
nil,
},
{
map[string][]string{
"limit": {"10"},
},
5,
10,
&hub.Pagination{
Limit: 10,
},
nil,
},
{
map[string][]string{
"offset": {"aa"},
},
5,
10,
nil,
errors.New("invalid offset"),
},
{
map[string][]string{
"offset": {"1"},
},
5,
10,
&hub.Pagination{
Limit: 5,
Offset: 1,
},
nil,
},
}
for i, tc := range testCases {
t.Run(strconv.Itoa(i), func(t *testing.T) {
t.Parallel()
p, err := GetPagination(tc.qs, tc.defaultLimit, tc.maxLimit)
assert.Equal(t, tc.expectedPagination, p)
if tc.expectedError != nil {
assert.Contains(t, err.Error(), tc.expectedError.Error())
}
})
}
}
func TestRenderJSON(t *testing.T) {
testCases := []struct {
data []byte
cacheMaxAge time.Duration
code int
}{
{
nil,
24 * time.Hour,
http.StatusOK,
},
{
[]byte("dataJSON"),
0,
http.StatusOK,
},
{
[]byte("dataJSON"),
24 * time.Hour,
http.StatusCreated,
},
}
for i, tc := range testCases {
t.Run(strconv.Itoa(i), func(t *testing.T) {
t.Parallel()
w := httptest.NewRecorder()
RenderJSON(w, tc.data, tc.cacheMaxAge, tc.code)
resp := w.Result()
defer resp.Body.Close()
h := resp.Header
data, _ := io.ReadAll(resp.Body)
assert.Equal(t, tc.code, resp.StatusCode)
assert.Equal(t, "application/json", h.Get("Content-Type"))
assert.Equal(t, BuildCacheControlHeader(tc.cacheMaxAge), h.Get("Cache-Control"))
if tc.data != nil {
assert.Equal(t, tc.data, data)
} else {
assert.Equal(t, []byte{}, data)
}
})
}
}
func TestRenderErrorJSON(t *testing.T) {
testCases := []struct {
err error
expectedStatusCode int
expectedErrorMsg string
}{
{
hub.ErrInvalidInput,
http.StatusBadRequest,
"invalid input",
},
{
fmt.Errorf("%w: test error", hub.ErrInvalidInput),
http.StatusBadRequest,
"invalid input: test error",
},
{
hub.ErrInsufficientPrivilege,
http.StatusForbidden,
"",
},
{
hub.ErrNotFound,
http.StatusNotFound,
"",
},
{
tests.ErrFakeDB,
http.StatusInternalServerError,
"",
},
}
for i, tc := range testCases {
t.Run(strconv.Itoa(i), func(t *testing.T) {
t.Parallel()
w := httptest.NewRecorder()
RenderErrorJSON(w, tc.err)
resp := w.Result()
defer resp.Body.Close()
h := resp.Header
data, _ := io.ReadAll(resp.Body)
assert.Equal(t, tc.expectedStatusCode, resp.StatusCode)
assert.Equal(t, "application/json", h.Get("Content-Type"))
var expectedBody bytes.Buffer
writeErrorJSON(&expectedBody, tc.expectedErrorMsg)
assert.Equal(t, expectedBody.Bytes(), data)
})
}
}
func TestRenderErrorWithCodeJSON(t *testing.T) {
testCases := []struct {
err error
code int
expectedErrorMsg string
}{
{
fmt.Errorf("%w: test error", hub.ErrInvalidInput),
http.StatusBadRequest,
"invalid input: test error",
},
{
fmt.Errorf("%w: test error", hub.ErrInvalidInput),
http.StatusBadGateway,
"invalid input: test error",
},
{
nil,
http.StatusUnauthorized,
"",
},
}
for i, tc := range testCases {
t.Run(strconv.Itoa(i), func(t *testing.T) {
t.Parallel()
w := httptest.NewRecorder()
RenderErrorWithCodeJSON(w, tc.err, tc.code)
resp := w.Result()
defer resp.Body.Close()
h := resp.Header
data, _ := io.ReadAll(resp.Body)
assert.Equal(t, tc.code, resp.StatusCode)
assert.Equal(t, "application/json", h.Get("Content-Type"))
var expectedBody bytes.Buffer
writeErrorJSON(&expectedBody, tc.expectedErrorMsg)
assert.Equal(t, expectedBody.Bytes(), data)
})
}
}