1// Copyright 2015 The Prometheus Authors
2// Licensed under the Apache License, Version 2.0 (the "License");
3// you may not use this file except in compliance with the License.
4// You may obtain a copy of the License at
5//
6// http://www.apache.org/licenses/LICENSE-2.0
7//
8// Unless required by applicable law or agreed to in writing, software
9// distributed under the License is distributed on an "AS IS" BASIS,
10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11// See the License for the specific language governing permissions and
12// limitations under the License.
13
14package route
15
16import (
17	"net/http"
18	"net/http/httptest"
19	"testing"
20)
21
22func TestRedirect(t *testing.T) {
23	router := New().WithPrefix("/test/prefix")
24	w := httptest.NewRecorder()
25	r, err := http.NewRequest("GET", "http://localhost:9090/foo", nil)
26	if err != nil {
27		t.Fatalf("Error building test request: %s", err)
28	}
29
30	router.Redirect(w, r, "/some/endpoint", http.StatusFound)
31	if w.Code != http.StatusFound {
32		t.Fatalf("Unexpected redirect status code: got %d, want %d", w.Code, http.StatusFound)
33	}
34
35	want := "/test/prefix/some/endpoint"
36	got := w.Header()["Location"][0]
37	if want != got {
38		t.Fatalf("Unexpected redirect location: got %s, want %s", got, want)
39	}
40}
41
42func TestContext(t *testing.T) {
43	router := New()
44	router.Get("/test/:foo/", func(w http.ResponseWriter, r *http.Request) {
45		want := "bar"
46		got := Param(r.Context(), "foo")
47		if want != got {
48			t.Fatalf("Unexpected context value: want %q, got %q", want, got)
49		}
50	})
51
52	r, err := http.NewRequest("GET", "http://localhost:9090/test/bar/", nil)
53	if err != nil {
54		t.Fatalf("Error building test request: %s", err)
55	}
56	router.ServeHTTP(nil, r)
57}
58
59func TestContextWithValue(t *testing.T) {
60	router := New()
61	router.Get("/test/:foo/", func(w http.ResponseWriter, r *http.Request) {
62		want := "bar"
63		got := Param(r.Context(), "foo")
64		if want != got {
65			t.Fatalf("Unexpected context value: want %q, got %q", want, got)
66		}
67		want = "ipsum"
68		got = Param(r.Context(), "lorem")
69		if want != got {
70			t.Fatalf("Unexpected context value: want %q, got %q", want, got)
71		}
72		want = "sit"
73		got = Param(r.Context(), "dolor")
74		if want != got {
75			t.Fatalf("Unexpected context value: want %q, got %q", want, got)
76		}
77	})
78
79	r, err := http.NewRequest("GET", "http://localhost:9090/test/bar/", nil)
80	if err != nil {
81		t.Fatalf("Error building test request: %s", err)
82	}
83	params := map[string]string{
84		"lorem": "ipsum",
85		"dolor": "sit",
86	}
87
88	ctx := r.Context()
89	for p, v := range params {
90		ctx = WithParam(ctx, p, v)
91	}
92	r = r.WithContext(ctx)
93	router.ServeHTTP(nil, r)
94}
95
96func TestContextWithoutValue(t *testing.T) {
97	router := New()
98	router.Get("/test", func(w http.ResponseWriter, r *http.Request) {
99		want := ""
100		got := Param(r.Context(), "foo")
101		if want != got {
102			t.Fatalf("Unexpected context value: want %q, got %q", want, got)
103		}
104	})
105
106	r, err := http.NewRequest("GET", "http://localhost:9090/test", nil)
107	if err != nil {
108		t.Fatalf("Error building test request: %s", err)
109	}
110	router.ServeHTTP(nil, r)
111}
112
113func TestInstrumentation(t *testing.T) {
114	var got string
115	cases := []struct {
116		router *Router
117		want   string
118	}{
119		{
120			router: New(),
121			want:   "",
122		}, {
123			router: New().WithInstrumentation(func(handlerName string, handler http.HandlerFunc) http.HandlerFunc {
124				got = handlerName
125				return handler
126			}),
127			want: "/foo",
128		},
129	}
130
131	for _, c := range cases {
132		c.router.Get("/foo", func(w http.ResponseWriter, r *http.Request) {})
133
134		r, err := http.NewRequest("GET", "http://localhost:9090/foo", nil)
135		if err != nil {
136			t.Fatalf("Error building test request: %s", err)
137		}
138		c.router.ServeHTTP(nil, r)
139		if c.want != got {
140			t.Fatalf("Unexpected value: want %q, got %q", c.want, got)
141		}
142	}
143}
144
145func TestInstrumentations(t *testing.T) {
146	got := make([]string, 0)
147	cases := []struct {
148		router *Router
149		want   []string
150	}{
151		{
152			router: New(),
153			want:   []string{},
154		}, {
155			router: New().
156				WithInstrumentation(
157					func(handlerName string, handler http.HandlerFunc) http.HandlerFunc {
158						got = append(got, "1"+handlerName)
159						return handler
160					}).
161				WithInstrumentation(
162					func(handlerName string, handler http.HandlerFunc) http.HandlerFunc {
163						got = append(got, "2"+handlerName)
164						return handler
165					}).
166				WithInstrumentation(
167					func(handlerName string, handler http.HandlerFunc) http.HandlerFunc {
168						got = append(got, "3"+handlerName)
169						return handler
170					}),
171			want: []string{"1/foo", "2/foo", "3/foo"},
172		},
173	}
174
175	for _, c := range cases {
176		c.router.Get("/foo", func(w http.ResponseWriter, r *http.Request) {})
177
178		r, err := http.NewRequest("GET", "http://localhost:9090/foo", nil)
179		if err != nil {
180			t.Fatalf("Error building test request: %s", err)
181		}
182		c.router.ServeHTTP(nil, r)
183		if len(c.want) != len(got) {
184			t.Fatalf("Unexpected value: want %q, got %q", c.want, got)
185		}
186		for i, v := range c.want {
187			if v != got[i] {
188				t.Fatalf("Unexpected value: want %q, got %q", c.want, got)
189			}
190		}
191	}
192}
193