2018-07-14 21:58:30 +00:00
|
|
|
package lambdarouter
|
|
|
|
|
|
|
|
import (
|
|
|
|
"errors"
|
|
|
|
"net/http"
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/aws/aws-lambda-go/events"
|
|
|
|
. "github.com/smartystreets/goconvey/convey"
|
|
|
|
)
|
|
|
|
|
|
|
|
func TestRouterSpec(t *testing.T) {
|
|
|
|
|
|
|
|
Convey("Given an instantiated router", t, func() {
|
|
|
|
request := events.APIGatewayProxyRequest{}
|
2018-07-19 02:52:14 +00:00
|
|
|
rtr := NewAPIGRouter(&APIGRouterConfig{
|
|
|
|
Request: &request,
|
|
|
|
Prefix: "/shipping",
|
|
|
|
Headers: map[string]string{
|
|
|
|
"Access-Control-Allow-Origin": "*",
|
|
|
|
"Access-Control-Allow-Credentials": "true",
|
|
|
|
},
|
|
|
|
})
|
2018-07-14 21:58:30 +00:00
|
|
|
|
|
|
|
Convey("When the handler func does NOT return an error", func() {
|
2018-07-17 21:01:18 +00:00
|
|
|
hdlrfunc := func(ctx *APIGContext) {
|
|
|
|
ctx.Status = http.StatusOK
|
|
|
|
ctx.Body = []byte("hello")
|
|
|
|
ctx.Err = nil
|
2018-07-14 21:58:30 +00:00
|
|
|
}
|
|
|
|
|
2018-07-18 23:15:07 +00:00
|
|
|
Convey("And a Get handler expecting the pattern /listings/{id}/state/{event} is defined", func() {
|
|
|
|
rtr.Get("/listings/{id}/state/{event}", hdlrfunc)
|
2018-07-17 21:01:18 +00:00
|
|
|
rtr.Post("/orders", func(ctx *APIGContext) {})
|
|
|
|
rtr.Put("/orders", func(ctx *APIGContext) {})
|
|
|
|
rtr.Patch("/orders", func(ctx *APIGContext) {})
|
|
|
|
rtr.Delete("/orders/{id}", func(ctx *APIGContext) {})
|
2018-07-14 21:58:30 +00:00
|
|
|
|
|
|
|
Convey("And the request matches the pattern and the path params are filled", func() {
|
|
|
|
request.HTTPMethod = http.MethodGet
|
2018-07-18 23:15:07 +00:00
|
|
|
request.Path = "/shipping/listings/57/state/list"
|
2018-07-14 21:58:30 +00:00
|
|
|
request.PathParameters = map[string]string{
|
2018-07-18 23:15:07 +00:00
|
|
|
"id": "57",
|
|
|
|
"event": "list",
|
2018-07-14 21:58:30 +00:00
|
|
|
}
|
|
|
|
request.RequestContext.Authorizer = map[string]interface{}{
|
|
|
|
"claims": map[string]interface{}{
|
|
|
|
"cognito:username": "mitchell",
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2018-07-19 02:52:14 +00:00
|
|
|
Convey("The router will return the expected status, body, and headers", func() {
|
2018-07-14 21:58:30 +00:00
|
|
|
response := rtr.Respond()
|
|
|
|
|
|
|
|
So(response.StatusCode, ShouldEqual, http.StatusOK)
|
|
|
|
So(response.Body, ShouldEqual, "hello")
|
2018-07-19 02:52:14 +00:00
|
|
|
So(response.Headers, ShouldResemble, map[string]string{
|
|
|
|
"Access-Control-Allow-Origin": "*",
|
|
|
|
"Access-Control-Allow-Credentials": "true",
|
|
|
|
})
|
2018-07-14 21:58:30 +00:00
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
Convey("And the request does NOT match the pattern", func() {
|
|
|
|
request.HTTPMethod = http.MethodGet
|
|
|
|
request.Path = "/orders/filter"
|
|
|
|
|
2018-07-15 18:41:02 +00:00
|
|
|
Convey("The router will return an error body and a status not found", func() {
|
2018-07-14 21:58:30 +00:00
|
|
|
response := rtr.Respond()
|
|
|
|
|
|
|
|
So(response.StatusCode, ShouldEqual, http.StatusNotFound)
|
|
|
|
So(response.Body, ShouldEqual, "{\"error\":\"no route matching path found\"}")
|
2018-08-30 20:07:44 +00:00
|
|
|
So(response.Headers, ShouldResemble, map[string]string{
|
|
|
|
"Access-Control-Allow-Origin": "*",
|
|
|
|
"Access-Control-Allow-Credentials": "true",
|
|
|
|
})
|
2018-07-14 21:58:30 +00:00
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2018-07-18 23:15:07 +00:00
|
|
|
Convey("And a Get handler expecting the pattern /listings/{id}/state/{event} is defined AGAIN", func() {
|
2018-07-14 21:58:30 +00:00
|
|
|
So(func() {
|
2018-07-18 23:15:07 +00:00
|
|
|
rtr.Get("/listings/{id}/state/{event}", hdlrfunc)
|
2018-07-14 21:58:30 +00:00
|
|
|
}, ShouldPanicWith, "endpoint already existent")
|
|
|
|
})
|
2018-07-15 18:41:02 +00:00
|
|
|
|
|
|
|
Convey("And a Get handler expecting the pattern /orders/filter", func() {
|
|
|
|
rtr.Get("/orders/filter", hdlrfunc)
|
|
|
|
|
|
|
|
Convey("And the request matches the pattern and the path params are filled", func() {
|
|
|
|
request.HTTPMethod = http.MethodGet
|
|
|
|
request.Path = "/shipping/orders/filter"
|
|
|
|
|
|
|
|
Convey("The router will return the expected status and body", func() {
|
|
|
|
response := rtr.Respond()
|
|
|
|
|
|
|
|
So(response.StatusCode, ShouldEqual, http.StatusOK)
|
|
|
|
So(response.Body, ShouldEqual, "hello")
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
Convey("And the request does NOT match either of the patterns", func() {
|
|
|
|
request.HTTPMethod = http.MethodGet
|
|
|
|
request.Path = "/shipping/orders/filter/by_user"
|
|
|
|
|
|
|
|
Convey("The router will return an error body and a status not found", func() {
|
|
|
|
response := rtr.Respond()
|
|
|
|
|
|
|
|
So(response.StatusCode, ShouldEqual, http.StatusNotFound)
|
|
|
|
So(response.Body, ShouldEqual, "{\"error\":\"no route matching path found\"}")
|
|
|
|
})
|
|
|
|
})
|
|
|
|
})
|
2018-07-14 21:58:30 +00:00
|
|
|
})
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
Convey("When the handler func does return a record not found", func() {
|
2018-07-17 21:01:18 +00:00
|
|
|
hdlrfunc := func(ctx *APIGContext) {
|
2018-08-30 20:07:44 +00:00
|
|
|
ctx.Status = http.StatusNoContent
|
2018-07-17 21:01:18 +00:00
|
|
|
ctx.Body = []byte("hello")
|
|
|
|
ctx.Err = errors.New("record not found")
|
2018-07-14 21:58:30 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2018-07-18 23:15:07 +00:00
|
|
|
Convey("And a Get handler expecting the pattern /listings/{id}/state/{event} is defined", func() {
|
|
|
|
rtr.Get("/listings/{id}/state/{event}", hdlrfunc)
|
2018-07-14 21:58:30 +00:00
|
|
|
|
|
|
|
Convey("And the request matches the pattern and the path params are filled", func() {
|
|
|
|
request.HTTPMethod = http.MethodGet
|
2018-07-18 23:15:07 +00:00
|
|
|
request.Path = "/shipping/listings/57/state/list"
|
2018-07-14 21:58:30 +00:00
|
|
|
request.PathParameters = map[string]string{
|
2018-07-18 23:15:07 +00:00
|
|
|
"id": "57",
|
|
|
|
"event": "list",
|
2018-07-14 21:58:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Convey("The router will return the expected status and body", func() {
|
|
|
|
response := rtr.Respond()
|
|
|
|
|
|
|
|
So(response.StatusCode, ShouldEqual, http.StatusNoContent)
|
|
|
|
So(response.Body, ShouldEqual, "{\"error\":\"record not found\"}")
|
|
|
|
})
|
|
|
|
})
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
Convey("When the handler func does return a status < 400", func() {
|
2018-07-17 21:01:18 +00:00
|
|
|
middlefunc1 := func(ctx *APIGContext) {
|
|
|
|
ctx.Status = http.StatusOK
|
|
|
|
ctx.Body = []byte("hello")
|
|
|
|
ctx.Err = nil
|
2018-07-16 23:44:38 +00:00
|
|
|
}
|
2018-07-17 21:01:18 +00:00
|
|
|
middlefunc2 := func(ctx *APIGContext) {
|
|
|
|
ctx.Status = http.StatusOK
|
|
|
|
ctx.Body = []byte("hello")
|
|
|
|
ctx.Err = errors.New("bad request")
|
2018-07-16 23:44:38 +00:00
|
|
|
}
|
2018-07-17 21:01:18 +00:00
|
|
|
hdlrfunc := func(ctx *APIGContext) {
|
|
|
|
ctx.Status = http.StatusOK
|
|
|
|
ctx.Body = []byte("hello")
|
|
|
|
ctx.Err = nil
|
2018-07-14 21:58:30 +00:00
|
|
|
}
|
|
|
|
|
2018-07-18 23:15:07 +00:00
|
|
|
Convey("And a Get handler expecting the pattern /listings/{id}/state/{event} is defined", func() {
|
|
|
|
rtr.Get("/listings/{id}/state/{event}", middlefunc1, middlefunc2, hdlrfunc)
|
2018-07-14 21:58:30 +00:00
|
|
|
|
|
|
|
Convey("And the request matches the pattern and the path params are filled", func() {
|
|
|
|
request.HTTPMethod = http.MethodGet
|
2018-07-18 23:15:07 +00:00
|
|
|
request.Path = "/shipping/listings/57/state/list"
|
2018-07-14 21:58:30 +00:00
|
|
|
request.PathParameters = map[string]string{
|
2018-07-18 23:15:07 +00:00
|
|
|
"id": "57",
|
|
|
|
"event": "list",
|
2018-07-14 21:58:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Convey("The router will return the expected status and body", func() {
|
|
|
|
response := rtr.Respond()
|
|
|
|
|
|
|
|
So(response.StatusCode, ShouldEqual, http.StatusBadRequest)
|
|
|
|
So(response.Body, ShouldEqual, "{\"error\":\"bad request\"}")
|
|
|
|
})
|
|
|
|
})
|
|
|
|
})
|
|
|
|
})
|
|
|
|
})
|
|
|
|
}
|