Skip to content

Commit

Permalink
fix: advanced query validate endtime > starttime
Browse files Browse the repository at this point in the history
  • Loading branch information
GalvinGao committed Apr 6, 2023
1 parent 8dc9959 commit a2d7aa9
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 32 deletions.
2 changes: 1 addition & 1 deletion internal/controller/v2/result.go
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ func (c *Result) GetTrends(ctx *fiber.Ctx) error {
// @Success 200 {object} modelv2.AdvancedQueryResult{advanced_results=[]modelv2.DropMatrixQueryResult} "Drop Matrix Response: when `interval` has been left undefined."
// @Success 202 {object} modelv2.AdvancedQueryResult{advanced_results=[]modelv2.TrendQueryResult} "Trend Response: when `interval` has been defined a value greater than `0`. Notice that this response still responds with a status code of `200`, but due to swagger limitations, to denote a different response with the same status code is not possible. Therefore, a status code of `202` is used, only for the purpose of workaround."
// @Failure 500 {object} pgerr.PenguinError "An unexpected error occurred"
// @Router /PenguinStats/api/v2/advanced [POST]
// @Router /PenguinStats/api/v2/result/advanced [POST]
func (c *Result) AdvancedQuery(ctx *fiber.Ctx) error {
var request types.AdvancedQueryRequest
if err := rekuest.ValidBody(ctx, &request); err != nil {
Expand Down
2 changes: 1 addition & 1 deletion internal/model/types/advanced_query.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@ type AdvancedQuery struct {
IsPersonal null.Bool `json:"isPersonal" swaggertype:"boolean"`
SourceCategory string `json:"sourceCategory" validate:"sourcecategory"`
StartTime null.Int `json:"start" swaggertype:"integer"`
EndTime null.Int `json:"end" swaggertype:"integer"`
EndTime null.Int `json:"end" validate:"gtfield=StartTime" swaggertype:"integer"`
Interval null.Int `json:"interval" swaggertype:"integer"`
}
9 changes: 9 additions & 0 deletions internal/util/validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ func NewValidator() *validator.Validate {
validate.RegisterValidation("semverprefixed", semverPrefixed)
validate.RegisterValidation("arkserver", arkServer)
validate.RegisterValidation("sourcecategory", sourceCategory)
validate.RegisterCustomTypeFunc(nullIntValuer, null.Int{})
validate.RegisterCustomTypeFunc(nullStringValuer, null.String{})

return validate
Expand Down Expand Up @@ -55,6 +56,14 @@ func sourceCategory(fl validator.FieldLevel) bool {
return val == "" || val == constant.SourceCategoryAll || val == constant.SourceCategoryAutomated || val == constant.SourceCategoryManual
}

func nullIntValuer(field reflect.Value) interface{} {
if valuer, ok := field.Interface().(null.Int); ok {
return valuer.Int64
}

return nil
}

func nullStringValuer(field reflect.Value) interface{} {
if valuer, ok := field.Interface().(null.String); ok {
return valuer.String
Expand Down
27 changes: 27 additions & 0 deletions test/api_test.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
package test

import (
"bytes"
"io"
"net/http"
"net/http/httptest"
"sync"
"testing"

"github.com/gofiber/fiber/v2"
"github.com/stretchr/testify/assert"
"github.com/tidwall/gjson"
"go.uber.org/fx"
"go.uber.org/fx/fxtest"

Expand Down Expand Up @@ -52,6 +55,30 @@ func request(t *testing.T, req *http.Request, msTimeout ...int) *http.Response {
return resp
}

func JsonRequestCustom(t *testing.T, req *http.Request) (*http.Response, *gjson.Result) {
t.Helper()

resp := request(t, req)

bodyBytes, err := io.ReadAll(resp.Body)
assert.NoError(t, err, "failed to read response body")

body := gjson.ParseBytes(bodyBytes)

return resp, &body
}

func JsonRequest(t *testing.T, path, body string, headers *http.Header) (*http.Response, *gjson.Result) {
t.Helper()

req := httptest.NewRequest(http.MethodPost, path, bytes.NewBufferString(body))
if headers != nil {
req.Header = *headers
}
req.Header.Set("Content-Type", "application/json")
return JsonRequestCustom(t, req)
}

func TestAPIMeta(t *testing.T) {
startup(t)
t.Parallel()
Expand Down
31 changes: 31 additions & 0 deletions test/v2_advanced_query_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package test

import (
"net/http"
"testing"

"github.com/stretchr/testify/assert"
"github.com/tidwall/gjson"
)

func TestAPIV2AdvancedQuery(t *testing.T) {
startup(t)
t.Parallel()

query := func(body string, headers *http.Header) (*http.Response, *gjson.Result) {
t.Helper()
return JsonRequest(t, "/PenguinStats/api/v2/result/advanced", body, headers)
}

t.Run("valid body", func(t *testing.T) {
h, j := query(`{"queries":[{"stageId":"main_01-07","itemIds":[],"server":"CN","isPersonal":false,"sourceCategory":"all","start":1556668800000,"end":1562630400000}]}`, nil)
assert.Equal(t, http.StatusOK, h.StatusCode)
assert.NotEmpty(t, len(j.Get("advanced_results").String()))
})

t.Run("invalid body", func(t *testing.T) {
h, j := query(`{"queries":[{"stageId":"main_01-07","itemIds":[],"server":"CN","isPersonal":false,"sourceCategory":"all","start":1556668800000,"end":1556668800000}]}`, nil)
assert.Equal(t, http.StatusBadRequest, h.StatusCode)
assert.Equal(t, "invalid time range", j.Get("error").String())
})
}
32 changes: 2 additions & 30 deletions test/v2_report_test.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
package test

import (
"bytes"
"io"
"net/http"
"net/http/httptest"
"testing"
"time"

Expand All @@ -17,39 +14,14 @@ func TestAPIV2Reports(t *testing.T) {
startup(t)
t.Parallel()

// helpers
jsonReqCustom := func(req *http.Request) (*http.Response, *gjson.Result) {
t.Helper()

resp := request(t, req)

bodyBytes, err := io.ReadAll(resp.Body)
assert.NoError(t, err, "failed to read response body")

body := gjson.ParseBytes(bodyBytes)

return resp, &body
}

jsonReq := func(path, body string, headers *http.Header) (*http.Response, *gjson.Result) {
t.Helper()

req := httptest.NewRequest(http.MethodPost, path, bytes.NewBufferString(body))
if headers != nil {
req.Header = *headers
}
req.Header.Set("Content-Type", "application/json")
return jsonReqCustom(req)
}

report := func(body string, headers *http.Header) (*http.Response, *gjson.Result) {
t.Helper()
return jsonReq("/PenguinStats/api/v2/report", body, headers)
return JsonRequest(t, "/PenguinStats/api/v2/report", body, headers)
}

recall := func(body string, headers *http.Header) (*http.Response, *gjson.Result) {
t.Helper()
return jsonReq("/PenguinStats/api/v2/report/recall", body, headers)
return JsonRequest(t, "/PenguinStats/api/v2/report/recall", body, headers)
}

// tests
Expand Down

0 comments on commit a2d7aa9

Please sign in to comment.