1// Copyright 2014 Manu Martinez-Almeida.  All rights reserved.
2// Use of this source code is governed by a MIT style
3// license that can be found in the LICENSE file.
4
5package gin
6
7import (
8	"testing"
9
10	"github.com/stretchr/testify/assert"
11)
12
13func init() {
14	SetMode(TestMode)
15}
16
17func TestRouterGroupBasic(t *testing.T) {
18	router := New()
19	group := router.Group("/hola", func(c *Context) {})
20	group.Use(func(c *Context) {})
21
22	assert.Len(t, group.Handlers, 2)
23	assert.Equal(t, group.BasePath(), "/hola")
24	assert.Equal(t, group.engine, router)
25
26	group2 := group.Group("manu")
27	group2.Use(func(c *Context) {}, func(c *Context) {})
28
29	assert.Len(t, group2.Handlers, 4)
30	assert.Equal(t, group2.BasePath(), "/hola/manu")
31	assert.Equal(t, group2.engine, router)
32}
33
34func TestRouterGroupBasicHandle(t *testing.T) {
35	performRequestInGroup(t, "GET")
36	performRequestInGroup(t, "POST")
37	performRequestInGroup(t, "PUT")
38	performRequestInGroup(t, "PATCH")
39	performRequestInGroup(t, "DELETE")
40	performRequestInGroup(t, "HEAD")
41	performRequestInGroup(t, "OPTIONS")
42}
43
44func performRequestInGroup(t *testing.T, method string) {
45	router := New()
46	v1 := router.Group("v1", func(c *Context) {})
47	assert.Equal(t, v1.BasePath(), "/v1")
48
49	login := v1.Group("/login/", func(c *Context) {}, func(c *Context) {})
50	assert.Equal(t, login.BasePath(), "/v1/login/")
51
52	handler := func(c *Context) {
53		c.String(400, "the method was %s and index %d", c.Request.Method, c.index)
54	}
55
56	switch method {
57	case "GET":
58		v1.GET("/test", handler)
59		login.GET("/test", handler)
60	case "POST":
61		v1.POST("/test", handler)
62		login.POST("/test", handler)
63	case "PUT":
64		v1.PUT("/test", handler)
65		login.PUT("/test", handler)
66	case "PATCH":
67		v1.PATCH("/test", handler)
68		login.PATCH("/test", handler)
69	case "DELETE":
70		v1.DELETE("/test", handler)
71		login.DELETE("/test", handler)
72	case "HEAD":
73		v1.HEAD("/test", handler)
74		login.HEAD("/test", handler)
75	case "OPTIONS":
76		v1.OPTIONS("/test", handler)
77		login.OPTIONS("/test", handler)
78	default:
79		panic("unknown method")
80	}
81
82	w := performRequest(router, method, "/v1/login/test")
83	assert.Equal(t, w.Code, 400)
84	assert.Equal(t, w.Body.String(), "the method was "+method+" and index 3")
85
86	w = performRequest(router, method, "/v1/test")
87	assert.Equal(t, w.Code, 400)
88	assert.Equal(t, w.Body.String(), "the method was "+method+" and index 1")
89}
90
91func TestRouterGroupInvalidStatic(t *testing.T) {
92	router := New()
93	assert.Panics(t, func() {
94		router.Static("/path/:param", "/")
95	})
96
97	assert.Panics(t, func() {
98		router.Static("/path/*param", "/")
99	})
100}
101
102func TestRouterGroupInvalidStaticFile(t *testing.T) {
103	router := New()
104	assert.Panics(t, func() {
105		router.StaticFile("/path/:param", "favicon.ico")
106	})
107
108	assert.Panics(t, func() {
109		router.StaticFile("/path/*param", "favicon.ico")
110	})
111}
112
113func TestRouterGroupTooManyHandlers(t *testing.T) {
114	router := New()
115	handlers1 := make([]HandlerFunc, 40)
116	router.Use(handlers1...)
117
118	handlers2 := make([]HandlerFunc, 26)
119	assert.Panics(t, func() {
120		router.Use(handlers2...)
121	})
122	assert.Panics(t, func() {
123		router.GET("/", handlers2...)
124	})
125}
126
127func TestRouterGroupBadMethod(t *testing.T) {
128	router := New()
129	assert.Panics(t, func() {
130		router.Handle("get", "/")
131	})
132	assert.Panics(t, func() {
133		router.Handle(" GET", "/")
134	})
135	assert.Panics(t, func() {
136		router.Handle("GET ", "/")
137	})
138	assert.Panics(t, func() {
139		router.Handle("", "/")
140	})
141	assert.Panics(t, func() {
142		router.Handle("PO ST", "/")
143	})
144	assert.Panics(t, func() {
145		router.Handle("1GET", "/")
146	})
147	assert.Panics(t, func() {
148		router.Handle("PATCh", "/")
149	})
150}
151
152func TestRouterGroupPipeline(t *testing.T) {
153	router := New()
154	testRoutesInterface(t, router)
155
156	v1 := router.Group("/v1")
157	testRoutesInterface(t, v1)
158}
159
160func testRoutesInterface(t *testing.T, r IRoutes) {
161	handler := func(c *Context) {}
162	assert.Equal(t, r, r.Use(handler))
163
164	assert.Equal(t, r, r.Handle("GET", "/handler", handler))
165	assert.Equal(t, r, r.Any("/any", handler))
166	assert.Equal(t, r, r.GET("/", handler))
167	assert.Equal(t, r, r.POST("/", handler))
168	assert.Equal(t, r, r.DELETE("/", handler))
169	assert.Equal(t, r, r.PATCH("/", handler))
170	assert.Equal(t, r, r.PUT("/", handler))
171	assert.Equal(t, r, r.OPTIONS("/", handler))
172	assert.Equal(t, r, r.HEAD("/", handler))
173
174	assert.Equal(t, r, r.StaticFile("/file", "."))
175	assert.Equal(t, r, r.Static("/static", "."))
176	assert.Equal(t, r, r.StaticFS("/static2", Dir(".", false)))
177}
178