github.com/System-Glitch/goyave/v2@v2.10.3-0.20200819142921-51011e75d504/route_test.go (about) 1 package goyave 2 3 import ( 4 "net/http" 5 "net/http/httptest" 6 "regexp" 7 "testing" 8 9 "github.com/System-Glitch/goyave/v2/validation" 10 ) 11 12 type RouteTestSuite struct { 13 TestSuite 14 } 15 16 func (suite *RouteTestSuite) SetupTest() { 17 regexCache = make(map[string]*regexp.Regexp, 5) 18 } 19 20 func (suite *RouteTestSuite) TearDownTest() { 21 regexCache = nil 22 } 23 24 func (suite *RouteTestSuite) TestNewRoute() { 25 route := newRoute(func(resp *Response, r *Request) {}) 26 suite.NotNil(route) 27 suite.NotNil(route.handler) 28 } 29 30 func (suite *RouteTestSuite) TestMakeParameters() { 31 route := newRoute(func(resp *Response, r *Request) {}) 32 route.compileParameters("/product/{id:[0-9]+}", true) 33 suite.Equal([]string{"id"}, route.parameters) 34 suite.NotNil(route.regex) 35 suite.True(route.regex.MatchString("/product/666")) 36 suite.False(route.regex.MatchString("/product/")) 37 suite.False(route.regex.MatchString("/product/qwerty")) 38 } 39 40 func (suite *RouteTestSuite) TestMatch() { 41 handler := func(resp *Response, r *Request) { 42 resp.String(http.StatusOK, "Success") 43 } 44 route := &Route{ 45 name: "test-route", 46 uri: "/product/{id:[0-9]+}", 47 methods: []string{"GET", "POST"}, 48 parent: nil, 49 handler: handler, 50 validationRules: nil, 51 } 52 route.compileParameters(route.uri, true) 53 54 rawRequest := httptest.NewRequest("GET", "/product/33", nil) 55 match := routeMatch{currentPath: rawRequest.URL.Path} 56 suite.True(route.match(rawRequest, &match)) 57 suite.Equal("33", match.parameters["id"]) 58 59 rawRequest = httptest.NewRequest("POST", "/product/33", nil) 60 match = routeMatch{currentPath: rawRequest.URL.Path} 61 suite.True(route.match(rawRequest, &match)) 62 suite.Equal("33", match.parameters["id"]) 63 64 rawRequest = httptest.NewRequest("PUT", "/product/33", nil) 65 match = routeMatch{currentPath: rawRequest.URL.Path} 66 suite.False(route.match(rawRequest, &match)) 67 suite.Equal(errMatchMethodNotAllowed, match.err) 68 69 // Test error has not been overridden 70 rawRequest = httptest.NewRequest("PUT", "/product/test", nil) 71 suite.False(route.match(rawRequest, &match)) 72 suite.Equal(errMatchMethodNotAllowed, match.err) 73 74 match = routeMatch{currentPath: rawRequest.URL.Path} 75 suite.False(route.match(rawRequest, &match)) 76 suite.Equal(errMatchNotFound, match.err) 77 78 route = &Route{ 79 name: "test-route", 80 uri: "/product/{id:[0-9]+}/{name}", 81 methods: []string{"GET"}, 82 parent: nil, 83 handler: handler, 84 validationRules: nil, 85 } 86 route.compileParameters(route.uri, true) 87 rawRequest = httptest.NewRequest("GET", "/product/666/test", nil) 88 match = routeMatch{currentPath: rawRequest.URL.Path} 89 suite.True(route.match(rawRequest, &match)) 90 suite.Equal("666", match.parameters["id"]) 91 suite.Equal("test", match.parameters["name"]) 92 93 route = &Route{ 94 name: "test-route", 95 uri: "/categories/{category}/{sort:(?:asc|desc|new)}", 96 methods: []string{"GET"}, 97 parent: nil, 98 handler: handler, 99 validationRules: nil, 100 } 101 route.compileParameters(route.uri, true) 102 rawRequest = httptest.NewRequest("GET", "/categories/lawn-mower/asc", nil) 103 match = routeMatch{currentPath: rawRequest.URL.Path} 104 suite.True(route.match(rawRequest, &match)) 105 suite.Equal("lawn-mower", match.parameters["category"]) 106 suite.Equal("asc", match.parameters["sort"]) 107 108 rawRequest = httptest.NewRequest("GET", "/categories/lawn-mower/notsort", nil) 109 match = routeMatch{currentPath: rawRequest.URL.Path} 110 suite.False(route.match(rawRequest, &match)) 111 } 112 113 func (suite *RouteTestSuite) TestAccessors() { 114 route := &Route{ 115 name: "route-name", 116 uri: "/product/{id:[0-9+]}", 117 parent: newRouter(), 118 methods: []string{"GET", "POST"}, 119 } 120 121 suite.Equal("route-name", route.GetName()) 122 123 suite.Panics(func() { 124 route.Name("new-name") // Cannot re-set name 125 }) 126 127 route = &Route{ 128 name: "", 129 uri: "/product/{id:[0-9+]}", 130 parent: newRouter(), 131 methods: []string{"GET", "POST"}, 132 } 133 route.Name("new-name") 134 suite.Equal("new-name", route.GetName()) 135 136 suite.Equal("/product/{id:[0-9+]}", route.GetURI()) 137 suite.Equal([]string{"GET", "POST"}, route.GetMethods()) 138 } 139 140 func (suite *RouteTestSuite) TestGetFullURI() { 141 router := newRouter().Subrouter("/product").Subrouter("/{id:[0-9+]}") 142 route := router.Route("GET|POST", "/{name}/accessories", func(resp *Response, r *Request) {}).Name("route-name") 143 144 suite.Equal("/product/{id:[0-9+]}/{name}/accessories", route.GetFullURI()) 145 } 146 147 func (suite *RouteTestSuite) TestBuildURL() { 148 route := &Route{ 149 name: "route-name", 150 uri: "/product/{id:[0-9+]}", 151 methods: []string{"GET", "POST"}, 152 } 153 route.compileParameters(route.uri, true) 154 suite.Equal("http://127.0.0.1:1235/product/42", route.BuildURL("42")) 155 156 suite.Panics(func() { 157 route.BuildURL() 158 }) 159 suite.Panics(func() { 160 route.BuildURL("42", "more") 161 }) 162 163 route = &Route{ 164 name: "route-name", 165 uri: "/product/{id:[0-9+]}/{name}/accessories", 166 methods: []string{"GET", "POST"}, 167 } 168 route.compileParameters(route.uri, true) 169 suite.Equal("http://127.0.0.1:1235/product/42/screwdriver/accessories", route.BuildURL("42", "screwdriver")) 170 171 router := newRouter().Subrouter("/product").Subrouter("/{id:[0-9+]}") 172 route = router.Route("GET|POST", "/{name}/accessories", func(resp *Response, r *Request) {}).Name("route-name") 173 174 suite.Equal("http://127.0.0.1:1235/product/42/screwdriver/accessories", route.BuildURL("42", "screwdriver")) 175 } 176 177 func (suite *RouteTestSuite) TestValidate() { 178 route := &Route{ 179 name: "route-name", 180 uri: "/product/{id:[0-9+]}", 181 methods: []string{"GET", "POST"}, 182 } 183 rules := &validation.Rules{ 184 Fields: map[string]*validation.Field{ 185 "field": { 186 Rules: []*validation.Rule{ 187 {Name: "required"}, 188 {Name: "string"}, 189 }, 190 }, 191 }, 192 } 193 route.Validate(rules) 194 suite.Equal(rules, route.validationRules) 195 } 196 197 func (suite *RouteTestSuite) TestMiddleware() { 198 route := &Route{ 199 name: "route-name", 200 uri: "/product/{id:[0-9+]}", 201 methods: []string{"GET", "POST"}, 202 } 203 middelware := func(next Handler) Handler { 204 return func(response *Response, r *Request) {} 205 } 206 middelware2 := func(next Handler) Handler { 207 return func(response *Response, r *Request) {} 208 } 209 route.Middleware(middelware, middelware2) 210 suite.Len(route.middleware, 2) 211 } 212 213 func TestRouteTestSuite(t *testing.T) { 214 RunTest(t, new(RouteTestSuite)) 215 }