Skip to content

Commit

Permalink
assured bindings and endpoints
Browse files Browse the repository at this point in the history
  • Loading branch information
Jesse Michael committed Aug 19, 2017
1 parent 2022320 commit 9b13b09
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 77 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
bin/go-rest-assured
bin/
coverage/
vendor/
.vscode/
debug
15 changes: 7 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
___ ___ ___ ___ ___ _____ ___ ___ ___ _ _ ___ ___ ___
/ __| / _ \ | _ \ | __| / __| |_ _| / \ / __| / __| | | | | | _ \ | __| | \
| (_ | | (_) | | / | _| \__ \ | | | - | \__ \ \__ \ | |_| | | / | _| | |) |
\___| \___/ TS__[O] |_|_\ |___| |___/ _|_|_ TS__[O] |_|_| |___/ |___/ \___/ |_|_\ |___| |___/
_|"""""|_|"""""| {======|_|"""""|_|"""""|_|"""""|_|"""""| {======|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|
"`-0-0-'"`-0-0-'./o--000'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'./o--000'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'

==========================================================================================================================
_________ ___ ______________ ___ __________ _____ _______
/ ___/ __ \ / _ \/ __/ __/_ __/ / _ | / __/ __/ / / / _ \/ __/ _ \
/ (_ / /_/ / / , _/ _/_\ \ / / / __ |_\ \_\ \/ /_/ / , _/ _// // /
\___/\____/ /_/|_/___/___/ /_/ /_/ |_/___/___/\____/_/|_/___/____/


=====================================================================


Running
Expand Down
77 changes: 40 additions & 37 deletions bindings/assured_bindings.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,81 +3,85 @@ package bindings
import (
"context"
"encoding/json"
"errors"
"net/http"
"strconv"

"github.com/go-kit/kit/endpoint"
kitlog "github.com/go-kit/kit/log"
kithttp "github.com/go-kit/kit/transport/http"
"github.com/gorilla/handlers"
"github.com/gorilla/mux"
"github.com/jesse0michael/go-rest-assured/endpoints"
)

var assuredMethods = []string{
http.MethodGet,
http.MethodHead,
http.MethodPost,
http.MethodPut,
http.MethodPatch,
http.MethodDelete,
http.MethodConnect,
http.MethodOptions,
}

// StartApplicationHTTPListener creates a Go-routine that has an HTTP listener for the application endpoints
func StartApplicationHTTPListener(logger kitlog.Logger, root context.Context, errc chan error) {
go func() {
ctx, cancel := context.WithCancel(root)
defer cancel()

router := createApplicationRouter(ctx, logger)

errc <- http.ListenAndServe(":9090", handlers.RecoveryHandler()(handlers.CombinedLoggingHandler(kitlog.NewStdlibAdapter(logger), router)))
logger.Log("message", "starting go rest assured on port 11011")
errc <- http.ListenAndServe(":11011", handlers.RecoveryHandler()(router))
}()
}

// createApplicationRouter sets up the router that will handle all of the application routes
func createApplicationRouter(ctx context.Context, logger kitlog.Logger) *mux.Router {
router := mux.NewRouter()
e := endpoints.NewAssuredEndpoints(logger)
assuredMethods := []string{
http.MethodGet,
http.MethodHead,
http.MethodPost,
http.MethodPut,
http.MethodPatch,
http.MethodDelete,
http.MethodConnect,
http.MethodOptions,
}

router.Handle(
"/given/{path:.*}",
kithttp.NewServer(
buildAssuredEndpoint(e.GivenEndpoint),
e.GivenEndpoint,
decodeAssuredCall,
encodeAssuredCall,
kithttp.ServerErrorLogger(logger),
)).Methods(assuredMethods...)
kithttp.ServerAfter(kithttp.SetResponseHeader("Access-Control-Allow-Origin", "*")),
kithttp.ServerErrorEncoder(errorEncoder)),
).Methods(assuredMethods...)

router.Handle(
"/when/{path:.*}",
kithttp.NewServer(
buildAssuredEndpoint(e.WhenEndpoint),
e.WhenEndpoint,
decodeAssuredCall,
encodeAssuredCall,
kithttp.ServerErrorLogger(logger),
)).Methods(assuredMethods...)
kithttp.ServerAfter(kithttp.SetResponseHeader("Access-Control-Allow-Origin", "*")),
kithttp.ServerErrorEncoder(errorEncoder)),
).Methods(assuredMethods...)

router.Handle(
"/then/{path:.*}",
kithttp.NewServer(
buildAssuredEndpoint(e.ThenEndpoint),
e.ThenEndpoint,
decodeAssuredCall,
encodeAssuredCall,
kithttp.ServerErrorLogger(logger),
)).Methods(assuredMethods...)
kithttp.ServerAfter(kithttp.SetResponseHeader("Access-Control-Allow-Origin", "*")),
kithttp.ServerErrorEncoder(errorEncoder)),
).Methods(assuredMethods...)

router.Handle(
"/clear/{path:.*}",
kithttp.NewServer(
buildAssuredEndpoint(e.ClearEndpoint),
e.ClearEndpoint,
decodeAssuredCall,
encodeAssuredCall,
kithttp.ServerErrorLogger(logger),
)).Methods(http.MethodDelete)
kithttp.ServerAfter(kithttp.SetResponseHeader("Access-Control-Allow-Origin", "*")),
kithttp.ServerErrorEncoder(errorEncoder)),
).Methods(http.MethodDelete)

router.Handle(
"/clear",
Expand All @@ -86,20 +90,13 @@ func createApplicationRouter(ctx context.Context, logger kitlog.Logger) *mux.Rou
decodeAssuredCall,
encodeAssuredCall,
kithttp.ServerErrorLogger(logger),
)).Methods(http.MethodDelete)
kithttp.ServerAfter(kithttp.SetResponseHeader("Access-Control-Allow-Origin", "*")),
kithttp.ServerErrorEncoder(errorEncoder)),
).Methods(http.MethodDelete)

return router
}

func buildAssuredEndpoint(f func(context.Context, *endpoints.AssuredCall) (*endpoints.AssuredCall, error)) endpoint.Endpoint {
return func(ctx context.Context, i interface{}) (interface{}, error) {
if call, ok := i.(*endpoints.AssuredCall); ok {
return f(ctx, call)
}
return nil, errors.New("Unable to decode Assured Call")
}
}

func decodeAssuredCall(ctx context.Context, req *http.Request) (interface{}, error) {
urlParams := mux.Vars(req)

Expand All @@ -116,14 +113,20 @@ func decodeAssuredCall(ctx context.Context, req *http.Request) (interface{}, err
json.NewDecoder(req.Body).Decode(ac.Response)
}

return ac, nil
return &ac, nil
}

func encodeAssuredCall(ctx context.Context, w http.ResponseWriter, i interface{}) error {
if call, ok := i.(*endpoints.AssuredCall); ok {
w.Header().Set("Content-Type", "application/json") // Content-Type needs to be set before WriteHeader https://golang.org/pkg/net/http/#ResponseWriter
w.WriteHeader(call.StatusCode)
return json.NewEncoder(w).Encode(call.Response)
if call.Response != nil {
w.Header().Set("Content-Type", "application/json") // Content-Type needs to be set before WriteHeader https://golang.org/pkg/net/http/#ResponseWriter
return json.NewEncoder(w).Encode(call.Response)
}
}
return nil
}

func errorEncoder(ctx context.Context, err error, w http.ResponseWriter) {

}
69 changes: 46 additions & 23 deletions endpoints/assured_endpoints.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,59 +13,82 @@ type AssuredCall struct {
StatusCode int
}

// AssuredEndpoints
type AssuredEndpoints struct {
logger kitlog.Logger
assuredCalls map[string]*AssuredCall
madeCalls map[string]*AssuredCall
assuredCalls map[string][]*AssuredCall
madeCalls map[string][]*AssuredCall
}

// NewAssuredEndpoints creates a new instance of assured endpoints
func NewAssuredEndpoints(l kitlog.Logger) *AssuredEndpoints {
return &AssuredEndpoints{
logger: l,
assuredCalls: map[string]*AssuredCall{},
madeCalls: map[string]*AssuredCall{},
assuredCalls: map[string][]*AssuredCall{},
madeCalls: map[string][]*AssuredCall{},
}
}

func (a AssuredEndpoints) GivenEndpoint(ctx context.Context, call *AssuredCall) (*AssuredCall, error) {
a.assuredCalls[call.Path] = call
a.logger.Log("assured call for path: %s", call.Path)
// GivenEndpoint is used to stub out a call for a given path
func (a AssuredEndpoints) GivenEndpoint(ctx context.Context, i interface{}) (interface{}, error) {
call, ok := i.(*AssuredCall)
if !ok {
return nil, errors.New("unable to convert request to AssuredCall")
}
a.assuredCalls[call.Path] = append(a.assuredCalls[call.Path], call)
a.logger.Log("message", "assured call set", "path", call.Path)

return call, nil
}

func (a AssuredEndpoints) WhenEndpoint(ctx context.Context, call *AssuredCall) (*AssuredCall, error) {
if a.assuredCalls[call.Path] == nil {
a.logger.Log("assured call not found for path: %s", call.Path)
// WhenEndpoint is used to test the assured calls
func (a AssuredEndpoints) WhenEndpoint(ctx context.Context, i interface{}) (interface{}, error) {
call, ok := i.(*AssuredCall)
if !ok {
return nil, errors.New("unable to convert request to AssuredCall")
}
if a.assuredCalls[call.Path] == nil || len(a.assuredCalls[call.Path]) == 0 {
a.logger.Log("message", "assured call not found", "path", call.Path)
return nil, errors.New("No assured calls")
}

a.madeCalls[call.Path] = call
a.madeCalls[call.Path] = append(a.madeCalls[call.Path], call)

assured := a.assuredCalls[call.Path][0]

return a.assuredCalls[call.Path], nil
a.assuredCalls[call.Path] = append(a.assuredCalls[call.Path][1:], assured)

return assured, nil
}

func (a AssuredEndpoints) ThenEndpoint(ctx context.Context, call *AssuredCall) (*AssuredCall, error) {
if a.madeCalls[call.Path] == nil {
a.logger.Log("made call not found for path: %s", call.Path)
return nil, errors.New("No made calls")
// ThenEndpoint is used to verify a particular call
func (a AssuredEndpoints) ThenEndpoint(ctx context.Context, i interface{}) (interface{}, error) {
call, ok := i.(*AssuredCall)
if !ok {
return nil, errors.New("unable to convert request to AssuredCall")
}

return a.madeCalls[call.Path], nil
}

func (a AssuredEndpoints) ClearEndpoint(ctx context.Context, call *AssuredCall) (*AssuredCall, error) {
a.assuredCalls[call.Path] = nil
a.madeCalls[call.Path] = nil
a.logger.Log("Cleared calls for path: %s", call.Path)
//ClearEndpoint is used to clear a specific assured call
func (a AssuredEndpoints) ClearEndpoint(ctx context.Context, i interface{}) (interface{}, error) {
call, ok := i.(*AssuredCall)
if !ok {
return nil, errors.New("unable to convert request to AssuredCall")
}
a.assuredCalls[call.Path] = []*AssuredCall{}
a.madeCalls[call.Path] = []*AssuredCall{}
a.logger.Log("message", "cleared calls for path", "path", call.Path)

return nil, nil
}

//ClearAllEndpoint is used to clear all assured calls
func (a AssuredEndpoints) ClearAllEndpoint(ctx context.Context, i interface{}) (interface{}, error) {
a.assuredCalls = map[string]*AssuredCall{}
a.madeCalls = map[string]*AssuredCall{}
a.logger.Log("Cleared all calls")
a.assuredCalls = map[string][]*AssuredCall{}
a.madeCalls = map[string][]*AssuredCall{}
a.logger.Log("message", "cleared all calls")

return nil, nil
}
14 changes: 8 additions & 6 deletions glide.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ import (

func main() {
logger := kitlog.NewLogfmtLogger(os.Stdout)
logger.Log("message", "go-rest-assured started")

rootCtx := context.Background()

errc := make(chan error)
Expand Down

0 comments on commit 9b13b09

Please sign in to comment.