Skip to content

Commit

Permalink
read json func
Browse files Browse the repository at this point in the history
  • Loading branch information
rozdolsky33 committed Sep 28, 2024
1 parent 6de5362 commit df3d2fa
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 6 deletions.
37 changes: 31 additions & 6 deletions tools.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ const randomStringSource = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXWYZ

// Tools is the type used to instantiate this module. Any variable of this type will have access to all the methods with the receiver *Tools.
type Tools struct {
MaxFileSize int
AllowedFileTypes []string
MaxJSONSize int
AllowUnknownFile bool
MaxFileSize int
AllowedFileTypes []string
MaxJSONSize int
AllowUnknownFields bool
}

// RandomString returns a string of random characters of length n, using randomStringSource as the source for the string
Expand Down Expand Up @@ -202,13 +202,38 @@ func (t *Tools) ReadJSON(w http.ResponseWriter, r *http.Request, data interface{

dec := json.NewDecoder(r.Body)

if !t.AllowUnknownFile {
if !t.AllowUnknownFields {
dec.DisallowUnknownFields()
}

err := dec.Decode(data)
if err != nil {
return err
var syntaxError *json.SyntaxError
var unmarshalTypeError *json.UnmarshalTypeError
var invalidUnmarshalError *json.InvalidUnmarshalError

switch {
case errors.As(err, &syntaxError):
return fmt.Errorf("body contains badly-formed JSON (at character %d)", syntaxError.Offset)
case errors.Is(err, io.ErrUnexpectedEOF):
return errors.New("body contains badly-formed JSON")
case errors.As(err, &unmarshalTypeError):
if unmarshalTypeError.Field != "" {
return fmt.Errorf("body contains icnorrect JSON type for field %q", unmarshalTypeError.Field)
}
return fmt.Errorf("body contains an invalid JSON (at character %d)", unmarshalTypeError.Offset)
case errors.Is(err, io.EOF):
return errors.New("body must not be empty")
case strings.HasPrefix(err.Error(), "json: unknown field"):
fieldName := strings.TrimPrefix(err.Error(), "json: unknown field")
return fmt.Errorf("body contains unknown key %s", fieldName)
case err.Error() == "http: request body too large":
return fmt.Errorf("body must not be larger than %d bytes", maxBytes)
case errors.As(err, &invalidUnmarshalError):
return fmt.Errorf("error unmarshalling JSON: %s", err.Error())
default:
return err
}
}

err = dec.Decode(&struct{}{})
Expand Down
59 changes: 59 additions & 0 deletions tools_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package toolkit

import (
"bytes"
"fmt"
"image"
"image/png"
Expand Down Expand Up @@ -213,3 +214,61 @@ func TestTools_DownloadStaticFile(t *testing.T) {
t.Error(err)
}
}

var jsonTests = []struct {
name string
json string
errorExpected bool
maxSize int
allowUnknown bool
}{
{name: "valid json", json: `{"foo": "bar"}`, errorExpected: false, maxSize: 1024, allowUnknown: false},
{name: "badly formatted json", json: `{"foo": }`, errorExpected: true, maxSize: 1024, allowUnknown: false},
{name: "incorrect type", json: `{"foo": 1}`, errorExpected: true, maxSize: 1024, allowUnknown: false},
{name: "two json files", json: `{"foo": "1""}{"alpha" : "beta"}`, errorExpected: true, maxSize: 1024, allowUnknown: false},
{name: "empty json", json: ``, errorExpected: true, maxSize: 1024, allowUnknown: false},
{name: "syntax error in json", json: `{"foo": 1""`, errorExpected: true, maxSize: 1024, allowUnknown: false},
{name: "unknown field in json", json: `{"fod": "1"}`, errorExpected: true, maxSize: 1024, allowUnknown: false},
{name: "allow unknown field in json", json: `{"fooo": "1"}`, errorExpected: false, maxSize: 1024, allowUnknown: true},
{name: "missing field name in json", json: `{jack: "1"}`, errorExpected: true, maxSize: 1024, allowUnknown: true},
{name: " file too large", json: `{"foo"": "bar"}`, errorExpected: true, maxSize: 4, allowUnknown: true},
{name: "not jason ", json: `Hello World!`, errorExpected: true, maxSize: 1024, allowUnknown: true},
}

func TestTools_ReadJSON(t *testing.T) {
var testTools Tools
for _, test := range jsonTests {
// set the max file size
testTools.MaxJSONSize = test.maxSize

// allow/disallow unknown fields
testTools.AllowUnknownFields = test.allowUnknown

var decodedJSON struct {
Foo string `json:"foo"`
}

// create a request with the body
req, err := http.NewRequest(http.MethodPost, "/", bytes.NewReader([]byte(test.json)))
if err != nil {
t.Log("Error:", err)
}

// create a recorder
rr := httptest.NewRecorder()

err = testTools.ReadJSON(rr, req, &decodedJSON)

if test.errorExpected && err == nil {
t.Errorf("%s: error expected, but none reived: %s", test.name, err.Error())
}

if !test.errorExpected && err != nil {
t.Errorf("%s: error not expected but one received", test.name)
}

req.Body.Close()

}

}

0 comments on commit df3d2fa

Please sign in to comment.