Skip to content

Commit

Permalink
Add basic parsing of JSON into schema
Browse files Browse the repository at this point in the history
  • Loading branch information
caalberts committed Apr 21, 2018
1 parent 0204e91 commit 3259f5a
Show file tree
Hide file tree
Showing 8 changed files with 213 additions and 31 deletions.
37 changes: 37 additions & 0 deletions examples/stubs.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
[
{
"method": "GET",
"path": "/",
"status": 200,
"response": {
"success": true
}
},
{
"method": "GET",
"path": "/users",
"status": 200,
"response": {
"success": true,
"ids": [1, 2, 3]
}
},
{
"method": "POST",
"path": "/users",
"status": 201,
"response": {
"success": true,
"id": 4
}
},
{
"method": "GET",
"path": "/admin",
"status": 401,
"response": {
"success": false,
"message": "unauthorized"
}
}
]
2 changes: 1 addition & 1 deletion http/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func NewMux(schemas []localroast.Schema) Mux {
method: schema.Method,
path: schema.Path,
}
mux[route] = schema.StatusCode
mux[route] = schema.Status
}
return mux
}
Expand Down
20 changes: 10 additions & 10 deletions http/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,19 @@ func TestNewServer(t *testing.T) {
func TestNewMux(t *testing.T) {
schemas := []localroast.Schema{
localroast.Schema{
Method: "GET",
Path: "/",
StatusCode: 200,
Method: "GET",
Path: "/",
Status: 200,
},
localroast.Schema{
Method: "GET",
Path: "/users",
StatusCode: 200,
Method: "GET",
Path: "/users",
Status: 200,
},
localroast.Schema{
Method: "POST",
Path: "/users",
StatusCode: 201,
Method: "POST",
Path: "/users",
Status: 201,
},
}

Expand All @@ -52,7 +52,7 @@ func TestNewMux(t *testing.T) {
}

assert.Nil(t, err)
assert.Equal(t, schema.StatusCode, resp.StatusCode)
assert.Equal(t, schema.Status, resp.StatusCode)
}

resp, err = http.Get(server.URL + "/unknown")
Expand Down
6 changes: 3 additions & 3 deletions localroast.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package localroast

type Schema struct {
Method string
Path string
StatusCode int
Method string
Path string
Status int
}
61 changes: 61 additions & 0 deletions schema/json.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package schema

import (
"encoding/json"
"fmt"
"io/ioutil"
"strings"

"github.com/caalberts/localroast"
)

func FromJSON(filepath string) ([]localroast.Schema, error) {
f, err := ioutil.ReadFile(filepath)
if err != nil {
return []localroast.Schema{}, err
}
return BytesToSchema(f)
}

type stub struct {
Method *string `json:"method"`
Path *string `json:"path"`
Status *int `json:"status"`
Response json.RawMessage `json:"response"`
}

func BytesToSchema(bytes []byte) ([]localroast.Schema, error) {
var stubs []stub
err := json.Unmarshal(bytes, &stubs)
if err != nil {
return []localroast.Schema{}, err
}

schemas := make([]localroast.Schema, len(stubs))
for i, stub := range stubs {
if f := missingFields(stub); len(f) > 0 {
return []localroast.Schema{}, fmt.Errorf("Missing required fields: %s", strings.Join(f, ", "))
}
schemas[i] = localroast.Schema{
Method: *stub.Method,
Path: *stub.Path,
Status: *stub.Status,
}
}

return schemas, nil
}

func missingFields(s stub) []string {
var missingFields []string
if s.Method == nil {
missingFields = append(missingFields, "method")
}
if s.Path == nil {
missingFields = append(missingFields, "path")
}
if s.Status == nil {
missingFields = append(missingFields, "status")
}
return missingFields
}
84 changes: 84 additions & 0 deletions schema/json_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package schema

import (
"io/ioutil"
"net/http"
"testing"

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

var validJSON, _ = ioutil.ReadFile("../examples/stubs.json")

func TestBytesToSchema(t *testing.T) {
schemas, err := BytesToSchema(validJSON)

assert.Nil(t, err)
assert.Equal(t, 4, len(schemas))

assert.Equal(t, http.MethodGet, schemas[0].Method)
assert.Equal(t, http.MethodGet, schemas[1].Method)
assert.Equal(t, http.MethodPost, schemas[2].Method)
assert.Equal(t, http.MethodGet, schemas[3].Method)

assert.Equal(t, "/", schemas[0].Path)
assert.Equal(t, "/users", schemas[1].Path)
assert.Equal(t, "/users", schemas[2].Path)
assert.Equal(t, "/admin", schemas[3].Path)

assert.Equal(t, http.StatusOK, schemas[0].Status)
assert.Equal(t, http.StatusOK, schemas[1].Status)
assert.Equal(t, http.StatusCreated, schemas[2].Status)
assert.Equal(t, http.StatusUnauthorized, schemas[3].Status)
}

var missingKeys = `
[
{
"response": {
"success": true
}
}
]
`

func TestJSONWithMissingKeys(t *testing.T) {
_, err := BytesToSchema([]byte(missingKeys))
assert.NotNil(t, err)
assert.Equal(t, "Missing required fields: method, path, status", err.Error())
}

var invalidJSON = `
[
{
method: "GET",
path: "/",
status: 200,
response: {
"success": true
}
}
]
`

func TestInvalidJSON(t *testing.T) {
_, err := BytesToSchema([]byte(invalidJSON))
assert.NotNil(t, err)
}

var jsonObject = `
{
"method": "POST",
"path": "/users",
"status": 201,
"response": {
"success": true,
"id": 4
}
}
`

func TestJSONObject(t *testing.T) {
_, err := BytesToSchema([]byte(jsonObject))
assert.NotNil(t, err)
}
8 changes: 4 additions & 4 deletions schema/string.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,11 @@ func FromString(definition string) (localroast.Schema, error) {

method := matches[1]
path := matches[2]
code, _ := strconv.Atoi(matches[3])
status, _ := strconv.Atoi(matches[3])
schema := localroast.Schema{
Method: method,
Path: path,
StatusCode: code,
Method: method,
Path: path,
Status: status,
}
return schema, nil
}
Expand Down
26 changes: 13 additions & 13 deletions schema/string_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ func TestFromStrings(t *testing.T) {
assert.Equal(t, "/users", schemas[1].Path)
assert.Equal(t, "/user/1", schemas[2].Path)

assert.Equal(t, http.StatusOK, schemas[0].StatusCode)
assert.Equal(t, http.StatusCreated, schemas[1].StatusCode)
assert.Equal(t, http.StatusForbidden, schemas[2].StatusCode)
assert.Equal(t, http.StatusOK, schemas[0].Status)
assert.Equal(t, http.StatusCreated, schemas[1].Status)
assert.Equal(t, http.StatusForbidden, schemas[2].Status)

definitions = []string{
"GET / 200",
Expand All @@ -48,25 +48,25 @@ var schemaTests = []struct {
{
"GET / 200",
localroast.Schema{
Method: http.MethodGet,
Path: "/",
StatusCode: http.StatusOK,
Method: http.MethodGet,
Path: "/",
Status: http.StatusOK,
},
},
{
"POST / 201",
localroast.Schema{
Method: http.MethodPost,
Path: "/",
StatusCode: http.StatusCreated,
Method: http.MethodPost,
Path: "/",
Status: http.StatusCreated,
},
},
{
"PUT /user/1 403",
localroast.Schema{
Method: http.MethodPut,
Path: "/user/1",
StatusCode: http.StatusForbidden,
Method: http.MethodPut,
Path: "/user/1",
Status: http.StatusForbidden,
},
},
}
Expand All @@ -77,7 +77,7 @@ func TestFromString(t *testing.T) {
assert.Nil(t, err)
assert.Equal(t, test.expected.Method, schema.Method)
assert.Equal(t, test.expected.Path, schema.Path)
assert.Equal(t, test.expected.StatusCode, schema.StatusCode)
assert.Equal(t, test.expected.Status, schema.Status)
}
}

Expand Down

0 comments on commit 3259f5a

Please sign in to comment.