func TestRequestData(t *testing.T) { responseWriter := new(http_test.TestResponseWriter) testRequest, _ := http.NewRequest("GET", "http://goweb.org/people/123", strings.NewReader("{\"something\":true}")) codecService := codecsservices.NewWebCodecService() c := NewWebContext(responseWriter, testRequest, codecService) bod, _ := c.RequestBody() assert.Equal(t, "{\"something\":true}", string(bod)) dat, datErr := c.RequestData() if assert.NoError(t, datErr) { assert.Equal(t, true, dat.(map[string]interface{})["something"]) } responseWriter = new(http_test.TestResponseWriter) testRequest, _ = http.NewRequest("GET", "http://goweb.org/people/123?body={\"something\":true}", nil) codecService = codecsservices.NewWebCodecService() c = NewWebContext(responseWriter, testRequest, codecService) bod, _ = c.RequestBody() assert.Equal(t, "{\"something\":true}", string(bod)) dat, datErr = c.RequestData() if assert.NoError(t, datErr) { assert.Equal(t, true, dat.(map[string]interface{})["something"]) } }
func TestPrependPreHandler(t *testing.T) { handler1 := new(handlers_test.TestHandler) handler2 := new(handlers_test.TestHandler) codecService := codecsservices.NewWebCodecService() h := NewHttpHandler(codecService) handler1.TestData().Set("id", 1) handler2.TestData().Set("id", 2) handler1.On("WillHandle", mock.Anything).Return(true, nil) handler1.On("Handle", mock.Anything).Return(false, nil) handler2.On("WillHandle", mock.Anything).Return(true, nil) handler2.On("Handle", mock.Anything).Return(false, nil) h.PrependPreHandler(handler1) h.PrependPreHandler(handler2) h.Handlers.Handle(nil) assert.Equal(t, 2, len(h.PreHandlersPipe())) assert.Equal(t, 2, h.PreHandlersPipe()[0].(*handlers_test.TestHandler).TestData().Get("id").Data()) assert.Equal(t, 1, h.PreHandlersPipe()[1].(*handlers_test.TestHandler).TestData().Get("id").Data()) mock.AssertExpectationsForObjects(t, handler1.Mock) }
func TestFileExtension(t *testing.T) { responseWriter := new(http_test.TestResponseWriter) codecService := codecsservices.NewWebCodecService() testRequest, _ := http.NewRequest("get", "http://goweb.org/people/123.json", nil) c := NewWebContext(responseWriter, testRequest, codecService) assert.Equal(t, ".json", c.FileExtension()) testRequest, _ = http.NewRequest("get", "http://goweb.org/people/123.bson", nil) c = NewWebContext(responseWriter, testRequest, codecService) assert.Equal(t, ".bson", c.FileExtension()) testRequest, _ = http.NewRequest("get", "http://goweb.org/people/123.xml", nil) c = NewWebContext(responseWriter, testRequest, codecService) assert.Equal(t, ".xml", c.FileExtension()) testRequest, _ = http.NewRequest("get", "http://goweb.org/people.with.dots/123.xml", nil) c = NewWebContext(responseWriter, testRequest, codecService) assert.Equal(t, ".xml", c.FileExtension()) testRequest, _ = http.NewRequest("get", "http://goweb.org/people.with.dots/123.xml?a=b", nil) c = NewWebContext(responseWriter, testRequest, codecService) assert.Equal(t, ".xml", c.FileExtension()) }
func TestErrorHandlerGetsUsedOnError(t *testing.T) { responseWriter := new(http_test.TestResponseWriter) testRequest, _ := http.NewRequest("GET", "http://stretchr.org/goweb", nil) codecService := codecsservices.NewWebCodecService() handler := NewHttpHandler(codecService) errorHandler := new(handlers_test.TestHandler) handler.SetErrorHandler(errorHandler) errorHandler.On("Handle", mock.Anything).Return(false, nil) // make a handler throw an error var theError error = errors.New("Test error") handler.Map(func(c context.Context) error { return theError }) handler.ServeHTTP(responseWriter, testRequest) if mock.AssertExpectationsForObjects(t, errorHandler.Mock) { // get the first context ctx := errorHandler.Calls[0].Arguments[0].(context.Context) // make sure the error data field was set assert.Equal(t, theError.Error(), ctx.Data().Get("error").Data().(HandlerError).Error(), "the error should be set in the data with the 'error' key") assert.Equal(t, responseWriter, ctx.HttpResponseWriter()) assert.Equal(t, testRequest, ctx.HttpRequest()) } }
func TestBeforeHandler(t *testing.T) { cont := new(controllers_test.TestHandlerWithBeforeAndAfters) codecService := codecsservices.NewWebCodecService() h := NewHttpHandler(codecService) h.MapController(cont) log.Printf("%s", h) if assert.Equal(t, 2, len(h.PreHandlersPipe()), "2 pre handler's expected") { assertPathMatchHandler(t, h.PreHandlersPipe()[0].(*PathMatchHandler), "/test", "POST", "before POST /test") assertPathMatchHandler(t, h.PreHandlersPipe()[1].(*PathMatchHandler), "/test/123", "PUT", "before PUT /test/123") assertPathMatchHandler(t, h.PreHandlersPipe()[0].(*PathMatchHandler), "/test", "OPTIONS", "before OPTIONS /test") assertPathMatchHandler(t, h.PreHandlersPipe()[1].(*PathMatchHandler), "/test/123", "OPTIONS", "before OPTIONS /test/123") } if assert.Equal(t, 2, len(h.PostHandlersPipe()), "2 post handler's expected") { assertPathMatchHandler(t, h.PostHandlersPipe()[0].(*PathMatchHandler), "/test", "POST", "after POST /test") assertPathMatchHandler(t, h.PostHandlersPipe()[1].(*PathMatchHandler), "/test/123", "PUT", "after PUT /test/123") assertPathMatchHandler(t, h.PostHandlersPipe()[0].(*PathMatchHandler), "/test", "OPTIONS", "after OPTIONS /test") assertPathMatchHandler(t, h.PostHandlersPipe()[1].(*PathMatchHandler), "/test/123", "OPTIONS", "after OPTIONS /test/123") } }
func TestRespondEnvelopOptions(t *testing.T) { http := new(GowebHTTPResponder) codecService := codecsservices.NewWebCodecService() API := NewGowebAPIResponder(codecService, http) ctx := context_test.MakeTestContextWithPath("/?envelop=false") data := map[string]interface{}{"name": "Mat"} // When AlwaysEvenlopResponse = true but ?envelop=false API.Respond(ctx, 200, data, nil) assert.Equal(t, context_test.TestResponseWriter.Output, "{\"name\":\"Mat\"}") // When AlwaysEvenlopResponse = false ctx = context_test.MakeTestContext() API.AlwaysEnvelopResponse = false API.Respond(ctx, 200, data, nil) assert.Equal(t, context_test.TestResponseWriter.Output, "{\"name\":\"Mat\"}") // When AlwaysEvenlopResponse = false but ?envelop=true ctx = context_test.MakeTestContextWithPath("/?envelop=true") API.Respond(ctx, 200, data, nil) assert.Equal(t, context_test.TestResponseWriter.Output, "{\"d\":{\"name\":\"Mat\"},\"s\":200}") }
func TestMapStaticFile(t *testing.T) { codecService := codecsservices.NewWebCodecService() h := NewHttpHandler(codecService) h.MapStaticFile("/static-file", "/location/of/static-file") assert.Equal(t, 1, len(h.HandlersPipe())) staticHandler := h.HandlersPipe()[0].(*PathMatchHandler) if assert.Equal(t, 1, len(staticHandler.HttpMethods)) { assert.Equal(t, goweb_http.MethodGet, staticHandler.HttpMethods[0]) } var ctx context.Context var willHandle bool ctx = context_test.MakeTestContextWithPath("/static-file") willHandle, _ = staticHandler.WillHandle(ctx) assert.True(t, willHandle, "Static handler should handle") ctx = context_test.MakeTestContextWithPath("static-file") willHandle, _ = staticHandler.WillHandle(ctx) assert.True(t, willHandle, "Static handler should handle") ctx = context_test.MakeTestContextWithPath("static-file/") willHandle, _ = staticHandler.WillHandle(ctx) assert.True(t, willHandle, "Static handler should handle") ctx = context_test.MakeTestContextWithPath("static-file/something-else") willHandle, _ = staticHandler.WillHandle(ctx) assert.False(t, willHandle, "Static handler NOT should handle") }
func TestMethodString(t *testing.T) { responseWriter := new(http_test.TestResponseWriter) testRequest, _ := http.NewRequest("get", "http://goweb.org/people/123", nil) codecService := codecsservices.NewWebCodecService() c := NewWebContext(responseWriter, testRequest, codecService) assert.Equal(t, "GET", c.MethodString()) responseWriter = new(http_test.TestResponseWriter) testRequest, _ = http.NewRequest("put", "http://goweb.org/people/123", nil) c = NewWebContext(responseWriter, testRequest, codecService) assert.Equal(t, "PUT", c.MethodString()) responseWriter = new(http_test.TestResponseWriter) testRequest, _ = http.NewRequest("DELETE", "http://goweb.org/people/123", nil) c = NewWebContext(responseWriter, testRequest, codecService) assert.Equal(t, "DELETE", c.MethodString()) responseWriter = new(http_test.TestResponseWriter) testRequest, _ = http.NewRequest("anything", "http://goweb.org/people/123", nil) c = NewWebContext(responseWriter, testRequest, codecService) assert.Equal(t, "ANYTHING", c.MethodString()) }
// GetCodecService gets the codec service that will be used by this object. func (a *GowebAPIResponder) GetCodecService() codecsservices.CodecService { if a.codecService == nil { a.codecService = codecsservices.NewWebCodecService() } return a.codecService }
func TestNewHttpHandler(t *testing.T) { codecService := codecsservices.NewWebCodecService() h := NewHttpHandler(codecService) assert.Equal(t, 3, len(h.Handlers)) assert.Equal(t, codecService, h.CodecService()) }
func TestOptionsListForSingleResource(t *testing.T) { codecService := codecsservices.NewWebCodecService() h := NewHttpHandler(codecService) c := new(test.TestController) assert.Equal(t, "GET,DELETE,PATCH,PUT,HEAD,OPTIONS", strings.Join(optionsListForSingleResource(h, c), ",")) c2 := new(test.TestSemiRestfulController) assert.Equal(t, "GET,OPTIONS", strings.Join(optionsListForSingleResource(h, c2), ",")) }
func TestMapController_WithExplicitHTTPMethods(t *testing.T) { rest := new(controllers_test.TestController) codecService := codecsservices.NewWebCodecService() h := NewHttpHandler(codecService) h.HttpMethodForCreate = "CREATE" h.HttpMethodForReadOne = "READ_ONE" h.HttpMethodForReadMany = "READ_MANY" h.HttpMethodForDeleteOne = "DELETE_ONE" h.HttpMethodForDeleteMany = "DELETE_MANY" h.HttpMethodForUpdateOne = "UPDATE_ONE" h.HttpMethodForUpdateMany = "UPDATE_MANY" h.HttpMethodForReplace = "REPLACE" h.HttpMethodForHead = "HEAD_CUSTOM" h.HttpMethodForOptions = "OPTIONS_CUSTOM" h.MapController(rest) assert.Equal(t, 10, len(h.HandlersPipe())) // create assertPathMatchHandler(t, h.HandlersPipe()[0].(*PathMatchHandler), "/test", "CREATE", "create") // read one assertPathMatchHandler(t, h.HandlersPipe()[1].(*PathMatchHandler), "/test/123", "READ_ONE", "read one") // read many assertPathMatchHandler(t, h.HandlersPipe()[2].(*PathMatchHandler), "/test", "READ_MANY", "read many") // delete one assertPathMatchHandler(t, h.HandlersPipe()[3].(*PathMatchHandler), "/test/123", "DELETE_ONE", "delete one") // delete many assertPathMatchHandler(t, h.HandlersPipe()[4].(*PathMatchHandler), "/test", "DELETE_MANY", "delete many") // update one assertPathMatchHandler(t, h.HandlersPipe()[5].(*PathMatchHandler), "/test/123", "UPDATE_ONE", "update one") // update many assertPathMatchHandler(t, h.HandlersPipe()[6].(*PathMatchHandler), "/test", "UPDATE_MANY", "update many") // replace one assertPathMatchHandler(t, h.HandlersPipe()[7].(*PathMatchHandler), "/test/123", "REPLACE", "replace") // head assertPathMatchHandler(t, h.HandlersPipe()[8].(*PathMatchHandler), "/test/123", "HEAD_CUSTOM", "head") assertPathMatchHandler(t, h.HandlersPipe()[8].(*PathMatchHandler), "/test", "HEAD_CUSTOM", "head") // options assertPathMatchHandler(t, h.HandlersPipe()[9].(*PathMatchHandler), "/test/123", "OPTIONS_CUSTOM", "options") assertPathMatchHandler(t, h.HandlersPipe()[9].(*PathMatchHandler), "/test", "OPTIONS_CUSTOM", "options") }
func TestHandlerForOptions_PlainHandler(t *testing.T) { codecService := codecsservices.NewWebCodecService() httpHandler := NewHttpHandler(codecService) handler1 := new(handlers_test.TestHandler) itself, _ := httpHandler.handlerForOptions(handler1) assert.Equal(t, handler1, itself, "handlerForOptions with existing handler should just return the handler") }
func TestAPI_RespondWithError(t *testing.T) { http := new(GowebHTTPResponder) codecService := codecsservices.NewWebCodecService() API := NewGowebAPIResponder(codecService, http) ctx := context_test.MakeTestContext() errObject := "error message" API.RespondWithError(ctx, 500, errObject) assert.Equal(t, context_test.TestResponseWriter.Output, "{\"e\":[\"error message\"],\"s\":500}") }
func TestRespond(t *testing.T) { http := new(GowebHTTPResponder) codecService := codecsservices.NewWebCodecService() API := NewGowebAPIResponder(codecService, http) ctx := context_test.MakeTestContext() data := map[string]interface{}{"name": "Mat"} API.Respond(ctx, 200, data, nil) assert.Equal(t, context_test.TestResponseWriter.Output, "{\"d\":{\"name\":\"Mat\"},\"s\":200}") }
func TestRespondWithPublicDataFacade(t *testing.T) { http := new(GowebHTTPResponder) codecService := codecsservices.NewWebCodecService() API := NewGowebAPIResponder(codecService, http) ctx := context_test.MakeTestContext() data := new(dataObject) API.Respond(ctx, 200, data, nil) assert.Equal(t, context_test.TestResponseWriter.Output, "{\"d\":{\"used-public-data\":true},\"s\":200}") }
func MakeTestContextWithFullDetails(path, method, body string) *webcontext.WebContext { TestCodecService = codecsservices.NewWebCodecService() TestResponseWriter = new(http_test.TestResponseWriter) if len(body) == 0 { TestRequest, _ = http.NewRequest(method, path, nil) } else { TestRequest, _ = http.NewRequest(method, path, strings.NewReader(body)) } return webcontext.NewWebContext(TestResponseWriter, TestRequest, TestCodecService) }
func TestMapStatic(t *testing.T) { codecService := codecsservices.NewWebCodecService() h := NewHttpHandler(codecService) h.MapStatic("/static", "/location/of/static") assert.Equal(t, 1, len(h.HandlersPipe())) staticHandler := h.HandlersPipe()[0].(*PathMatchHandler) if assert.Equal(t, 1, len(staticHandler.HttpMethods)) { assert.Equal(t, goweb_http.MethodGet, staticHandler.HttpMethods[0]) } var ctx context.Context var willHandle bool ctx = context_test.MakeTestContextWithPath("/static/some/deep/file.dat") willHandle, _ = staticHandler.WillHandle(ctx) assert.True(t, willHandle, "Static handler should handle") ctx = context_test.MakeTestContextWithPath("/static/../static/some/deep/file.dat") willHandle, _ = staticHandler.WillHandle(ctx) assert.True(t, willHandle, "Static handler should handle") ctx = context_test.MakeTestContextWithPath("/static/some/../file.dat") willHandle, _ = staticHandler.WillHandle(ctx) assert.True(t, willHandle, "Static handler should handle") ctx = context_test.MakeTestContextWithPath("/static/../file.dat") willHandle, _ = staticHandler.WillHandle(ctx) assert.False(t, willHandle, "Static handler should not handle") ctx = context_test.MakeTestContextWithPath("/static") willHandle, _ = staticHandler.WillHandle(ctx) assert.True(t, willHandle, "Static handler should handle") ctx = context_test.MakeTestContextWithPath("/static/") willHandle, _ = staticHandler.WillHandle(ctx) assert.True(t, willHandle, "Static handler should handle") ctx = context_test.MakeTestContextWithPath("/static/doc.go") willHandle, _ = staticHandler.WillHandle(ctx) _, staticHandleErr := staticHandler.Handle(ctx) if assert.NoError(t, staticHandleErr) { } }
func TestQueryValue(t *testing.T) { responseWriter := new(http_test.TestResponseWriter) testRequest, _ := http.NewRequest("GET", "http://goweb.org/people/123?name=Mat&name=Laurie&age=30&something=true", strings.NewReader("[{\"something\":true},{\"something\":false}]")) codecService := codecsservices.NewWebCodecService() c := NewWebContext(responseWriter, testRequest, codecService) assert.Equal(t, "Mat", c.QueryValue("name"), "QueryValue should get first value") assert.Equal(t, "30", c.QueryValue("age")) assert.Equal(t, "", c.QueryValue("no-such-value")) }
func TestNewGowebAPIResponder(t *testing.T) { http := new(GowebHTTPResponder) codecService := codecsservices.NewWebCodecService() api := NewGowebAPIResponder(codecService, http) assert.Equal(t, http, api.httpResponder) assert.Equal(t, codecService, api.GetCodecService()) assert.Equal(t, api.StandardFieldStatusKey, "s") assert.Equal(t, api.StandardFieldDataKey, "d") assert.Equal(t, api.StandardFieldErrorsKey, "e") }
func TestPathParams(t *testing.T) { responseWriter := new(http_test.TestResponseWriter) testRequest, _ := http.NewRequest("GET", "http://goweb.org/people/123", nil) codecService := codecsservices.NewWebCodecService() c := NewWebContext(responseWriter, testRequest, codecService) c.Data().Set(context.DataKeyPathParameters, objects.Map{"animal": "monkey"}) assert.Equal(t, "monkey", c.PathParams().Get("animal")) assert.Equal(t, "monkey", c.PathValue("animal")) assert.Equal(t, "", c.PathValue("doesn't exist")) }
func TestMapStaticFile_WithMatcherFuncs(t *testing.T) { codecService := codecsservices.NewWebCodecService() h := NewHttpHandler(codecService) matcherFunc := MatcherFunc(func(c context.Context) (MatcherFuncDecision, error) { return Match, nil }) h.MapStaticFile("/static-file", "/location/of/static-file", matcherFunc) assert.Equal(t, 1, len(h.HandlersPipe())) staticHandler := h.HandlersPipe()[0].(*PathMatchHandler) assert.Equal(t, 1, len(staticHandler.MatcherFuncs)) assert.Equal(t, matcherFunc, staticHandler.MatcherFuncs[0], "Matcher func (first)") }
func TestFormValue(t *testing.T) { responseWriter := new(http_test.TestResponseWriter) testRequest, _ := http.NewRequest("POST", "http://goweb.org/people/123?query=yes", strings.NewReader("name=Mat&name=Laurie&age=30&something=true")) testRequest.Header.Set("Content-Type", "application/x-www-form-urlencoded") codecService := codecsservices.NewWebCodecService() c := NewWebContext(responseWriter, testRequest, codecService) assert.Equal(t, "Mat", c.FormValue("name"), "QueryValue should get first value") assert.Equal(t, "30", c.FormValue("age")) assert.Equal(t, "", c.FormValue("no-such-value")) assert.Equal(t, "yes", c.FormValue("query")) }
func TestRespondWithCustomFieldnames(t *testing.T) { http := new(GowebHTTPResponder) codecService := codecsservices.NewWebCodecService() API := NewGowebAPIResponder(codecService, http) ctx := context_test.MakeTestContext() data := map[string]interface{}{"name": "Mat"} API.StandardFieldDataKey = "data" API.StandardFieldStatusKey = "status" API.Respond(ctx, 200, data, nil) assert.Equal(t, context_test.TestResponseWriter.Output, "{\"data\":{\"name\":\"Mat\"},\"status\":200}") }
func TestAppendPostHandler(t *testing.T) { handler1 := new(handlers_test.TestHandler) codecService := codecsservices.NewWebCodecService() h := NewHttpHandler(codecService) handler1.On("WillHandle", mock.Anything).Return(true, nil) handler1.On("Handle", mock.Anything).Return(false, nil) h.AppendPostHandler(handler1) h.Handlers.Handle(nil) assert.Equal(t, 1, len(h.PostHandlersPipe())) mock.AssertExpectationsForObjects(t, handler1.Mock) }
func TestGetAndSetErrorHandler(t *testing.T) { codecService := codecsservices.NewWebCodecService() handler := NewHttpHandler(codecService) errorHandler := new(handlers_test.TestHandler) // default one should be made assert.NotNil(t, handler.ErrorHandler()) //... but if we set one explicitally handler.SetErrorHandler(errorHandler) //... it should be set! assert.Equal(t, errorHandler, handler.ErrorHandler()) }
func TestMapController_DefaultOptions(t *testing.T) { semi := new(controllers_test.TestSemiRestfulController) codecService := codecsservices.NewWebCodecService() h := NewHttpHandler(codecService) h.MapController(semi) assert.Equal(t, 5, len(h.HandlersPipe())) // get the last two handler1 := h.HandlersPipe()[len(h.HandlersPipe())-2] handler2 := h.HandlersPipe()[len(h.HandlersPipe())-1] assertPathMatchHandler(t, handler1.(*PathMatchHandler), "/test-semi-restful", "OPTIONS", "options") assertPathMatchHandler(t, handler2.(*PathMatchHandler), "/test-semi-restful/{id}", "OPTIONS", "options") }
func TestMap(t *testing.T) { codecService := codecsservices.NewWebCodecService() handler := NewHttpHandler(codecService) called := false handler.Map("/people/{id}", func(c context.Context) error { called = true return nil }) assert.Equal(t, 1, len(handler.HandlersPipe())) ctx := context_test.MakeTestContextWithPath("people/123") handler.Handlers.Handle(ctx) assert.True(t, called) }
func TestNewContext(t *testing.T) { responseWriter := new(http_test.TestResponseWriter) testRequest, _ := http.NewRequest("GET", "http://goweb.org/people/123", nil) codecService := codecsservices.NewWebCodecService() c := NewWebContext(responseWriter, testRequest, codecService) if assert.NotNil(t, c) { assert.Equal(t, "people/123", c.Path().RawPath) assert.Equal(t, testRequest, c.httpRequest) assert.Equal(t, responseWriter, c.httpResponseWriter) assert.Equal(t, codecService, c.codecService) assert.Equal(t, codecService, c.CodecService()) } }
func TestQueryValues(t *testing.T) { responseWriter := new(http_test.TestResponseWriter) testRequest, _ := http.NewRequest("GET", "http://goweb.org/people/123?name=Mat&name=Laurie&age=30&something=true", strings.NewReader("[{\"something\":true},{\"something\":false}]")) codecService := codecsservices.NewWebCodecService() c := NewWebContext(responseWriter, testRequest, codecService) names := c.QueryValues("name") if assert.Equal(t, 2, len(names)) { assert.Equal(t, "Mat", names[0]) assert.Equal(t, "Laurie", names[1]) } assert.Nil(t, c.QueryValues("no-such-value")) }