Skip to content

Commit

Permalink
Route handler to use UseNumber decoding
Browse files Browse the repository at this point in the history
Signed-off-by: Matthew Whitehead <[email protected]>
  • Loading branch information
matthew1001 committed Sep 13, 2024
1 parent 5fb3c9e commit c73cd77
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 3 deletions.
4 changes: 3 additions & 1 deletion pkg/ffapi/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,9 @@ func (hs *HandlerFactory) RouteHandler(route *Route) http.HandlerFunc {
fallthrough
case strings.HasPrefix(strings.ToLower(contentType), "application/json"):
if jsonInput != nil {
err = json.NewDecoder(req.Body).Decode(&jsonInput)
d := json.NewDecoder(req.Body)
d.UseNumber()
err = d.Decode(&jsonInput)
}
case strings.HasPrefix(strings.ToLower(contentType), "text/plain"):
default:
Expand Down
69 changes: 67 additions & 2 deletions pkg/ffapi/handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@ import (
"context"
"encoding/json"
"fmt"
"github.com/getkin/kin-openapi/openapi3"
"github.com/stretchr/testify/require"
"io"
"mime/multipart"
"net/http"
Expand All @@ -31,13 +29,24 @@ import (
"testing"
"time"

"github.com/getkin/kin-openapi/openapi3"
"github.com/stretchr/testify/require"

"github.com/gorilla/mux"
"github.com/hyperledger/firefly-common/pkg/config"
"github.com/hyperledger/firefly-common/pkg/httpserver"
"github.com/sirupsen/logrus"
"github.com/stretchr/testify/assert"
)

const largeParamLiteral = `{
"largeNumberParam": 10000000000000000000000000001
}`

const scientificParamLiteral = `{
"scientificNumberParam": 1e+24
}`

const configDir = "../../test/data/config"

func newTestHandlerFactory(basePath string, basePathParams []*PathParam) *HandlerFactory {
Expand Down Expand Up @@ -112,6 +121,62 @@ func TestRouteServePOST201WithParams(t *testing.T) {
assert.Equal(t, "value2", resJSON["output1"])
}

func TestRouteServePOST201WithParamsLargeNumber(t *testing.T) {
s, _, done := newTestServer(t, []*Route{{
Name: "testRoute",
Path: "/test/{something}",
Method: "POST",
PathParams: []*PathParam{},
QueryParams: []*QueryParam{},
JSONInputValue: func() interface{} { return make(map[string]interface{}) },
JSONOutputValue: func() interface{} { return make(map[string]interface{}) },
JSONOutputCodes: []int{201},
JSONHandler: func(r *APIRequest) (output interface{}, err error) {
assert.Equal(t, r.Input, map[string]interface{}{"largeNumberParam": json.Number("10000000000000000000000000001")})
// Echo the input back as the response
return r.Input, nil
},
}}, "", nil)
defer done()

res, err := http.Post(fmt.Sprintf("http://%s/test/stuff", s.Addr()), "application/json", bytes.NewReader([]byte(largeParamLiteral)))
assert.NoError(t, err)
assert.Equal(t, 201, res.StatusCode)
var resJSON map[string]interface{}
d := json.NewDecoder(res.Body)
d.UseNumber()
d.Decode(&resJSON)
assert.Equal(t, json.Number("10000000000000000000000000001"), resJSON["largeNumberParam"])
}

func TestRouteServePOST201WithParamsScientificNumber(t *testing.T) {
s, _, done := newTestServer(t, []*Route{{
Name: "testRoute",
Path: "/test/{something}",
Method: "POST",
PathParams: []*PathParam{},
QueryParams: []*QueryParam{},
JSONInputValue: func() interface{} { return make(map[string]interface{}) },
JSONOutputValue: func() interface{} { return make(map[string]interface{}) },
JSONOutputCodes: []int{201},
JSONHandler: func(r *APIRequest) (output interface{}, err error) {
assert.Equal(t, r.Input, map[string]interface{}{"scientificNumberParam": json.Number("1e+24")})
// Echo the input back as the response
return r.Input, nil
},
}}, "", nil)
defer done()

res, err := http.Post(fmt.Sprintf("http://%s/test/stuff", s.Addr()), "application/json", bytes.NewReader([]byte(scientificParamLiteral)))
assert.NoError(t, err)
assert.Equal(t, 201, res.StatusCode)
var resJSON map[string]interface{}
d := json.NewDecoder(res.Body)
d.UseNumber()
d.Decode(&resJSON)
assert.Equal(t, json.Number("1e+24"), resJSON["scientificNumberParam"])
}

func TestJSONHTTPResponseEncodeFail(t *testing.T) {
s, _, done := newTestServer(t, []*Route{{
Name: "testRoute",
Expand Down

0 comments on commit c73cd77

Please sign in to comment.