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  }