1 package middleware
2
3 import (
4 "context"
5 "fmt"
6 "net/http"
7 "net/http/httptest"
8 "testing"
9
10 "github.com/stretchr/testify/assert"
11 "github.com/stretchr/testify/require"
12 )
13
14 func TestRedocMiddleware(t *testing.T) {
15 t.Run("with defaults", func(t *testing.T) {
16 redoc := Redoc(RedocOpts{}, nil)
17
18 req, err := http.NewRequestWithContext(context.Background(), http.MethodGet, "/docs", nil)
19 require.NoError(t, err)
20 recorder := httptest.NewRecorder()
21 redoc.ServeHTTP(recorder, req)
22 assert.Equal(t, http.StatusOK, recorder.Code)
23 assert.Equal(t, "text/html; charset=utf-8", recorder.Header().Get(contentTypeHeader))
24 var o RedocOpts
25 o.EnsureDefaults()
26 assert.Contains(t, recorder.Body.String(), fmt.Sprintf("<title>%s</title>", o.Title))
27 assert.Contains(t, recorder.Body.String(), fmt.Sprintf("<redoc spec-url='%s'></redoc>", o.SpecURL))
28 assert.Contains(t, recorder.Body.String(), redocLatest)
29 })
30
31 t.Run("with alternate path and spec URL", func(t *testing.T) {
32 redoc := Redoc(RedocOpts{
33 BasePath: "/base",
34 Path: "ui",
35 SpecURL: "/ui/swagger.json",
36 }, nil)
37
38 req, err := http.NewRequestWithContext(context.Background(), http.MethodGet, "/base/ui", nil)
39 require.NoError(t, err)
40 recorder := httptest.NewRecorder()
41 redoc.ServeHTTP(recorder, req)
42 assert.Equal(t, http.StatusOK, recorder.Code)
43 assert.Contains(t, recorder.Body.String(), "<redoc spec-url='/ui/swagger.json'></redoc>")
44 })
45
46 t.Run("with custom template", func(t *testing.T) {
47 redoc := Redoc(RedocOpts{
48 Template: `<!DOCTYPE html>
49 <html>
50 <head>
51 <title>{{ .Title }}</title>
52 <meta charset="utf-8"/>
53 <meta name="viewport" content="width=device-width, initial-scale=1">
54 <link href="https://fonts.googleapis.com/css?family=Montserrat:300,400,700|Roboto:300,400,700" rel="stylesheet">
55
56 <!--
57 ReDoc doesn't change outer page styles
58 -->
59 <style>
60 body {
61 margin: 0;
62 padding: 0;
63 }
64 </style>
65 </head>
66 <body>
67 <redoc
68 spec-url='{{ .SpecURL }}'
69 required-props-first=true
70 theme='{
71 "sidebar": {
72 "backgroundColor": "lightblue"
73 }
74 }'
75 ></redoc>
76 <script src="{{ .RedocURL }}"> </script>
77 </body>
78 </html>
79 `,
80 }, nil)
81
82 req, err := http.NewRequestWithContext(context.Background(), http.MethodGet, "/docs", nil)
83 require.NoError(t, err)
84 recorder := httptest.NewRecorder()
85 redoc.ServeHTTP(recorder, req)
86 assert.Equal(t, http.StatusOK, recorder.Code)
87 assert.Contains(t, recorder.Body.String(), "required-props-first=true")
88 })
89
90 t.Run("edge cases", func(t *testing.T) {
91 t.Run("with invalid custom template", func(t *testing.T) {
92 assert.Panics(t, func() {
93 Redoc(RedocOpts{
94 Template: `<!DOCTYPE html>
95 <html>
96 <head>
97 spec-url='{{ .Spec
98 </html>
99 `,
100 }, nil)
101 })
102 })
103
104 t.Run("with custom template that fails to execute", func(t *testing.T) {
105 assert.Panics(t, func() {
106 Redoc(RedocOpts{
107 Template: `<!DOCTYPE html>
108 <html>
109 spec-url='{{ .Unknown }}'
110 </html>
111 `,
112 }, nil)
113 })
114 })
115 })
116 }
117
View as plain text