1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package untyped
16
17 import (
18 "io"
19 "net/http"
20 "sort"
21 "testing"
22
23 "github.com/go-openapi/analysis"
24 "github.com/go-openapi/errors"
25 "github.com/go-openapi/loads"
26 "github.com/go-openapi/runtime"
27 swaggerspec "github.com/go-openapi/spec"
28 "github.com/stretchr/testify/assert"
29 "github.com/stretchr/testify/require"
30 )
31
32 func stubAutenticator() runtime.Authenticator {
33 return runtime.AuthenticatorFunc(func(_ interface{}) (bool, interface{}, error) { return false, nil, nil })
34 }
35
36 func stubAuthorizer() runtime.Authorizer {
37 return runtime.AuthorizerFunc(func(_ *http.Request, _ interface{}) error { return nil })
38 }
39
40 type stubConsumer struct {
41 }
42
43 func (s *stubConsumer) Consume(_ io.Reader, _ interface{}) error {
44 return nil
45 }
46
47 type stubProducer struct {
48 }
49
50 func (s *stubProducer) Produce(_ io.Writer, _ interface{}) error {
51 return nil
52 }
53
54 type stubOperationHandler struct {
55 }
56
57 func (s *stubOperationHandler) ParameterModel() interface{} {
58 return nil
59 }
60
61 func (s *stubOperationHandler) Handle(_ interface{}) (interface{}, error) {
62 return map[string]interface{}{}, nil
63 }
64
65 func TestUntypedAPIRegistrations(t *testing.T) {
66 api := NewAPI(new(loads.Document)).WithJSONDefaults()
67
68 api.RegisterConsumer("application/yada", new(stubConsumer))
69 api.RegisterProducer("application/yada-2", new(stubProducer))
70 api.RegisterOperation("get", "/{someId}", new(stubOperationHandler))
71 api.RegisterAuth("basic", stubAutenticator())
72 api.RegisterAuthorizer(stubAuthorizer())
73
74 assert.NotNil(t, api.authorizer)
75 assert.NotEmpty(t, api.authenticators)
76
77 _, ok := api.authenticators["basic"]
78 assert.True(t, ok)
79 _, ok = api.consumers["application/yada"]
80 assert.True(t, ok)
81 _, ok = api.producers["application/yada-2"]
82 assert.True(t, ok)
83 _, ok = api.consumers["application/json"]
84 assert.True(t, ok)
85 _, ok = api.producers["application/json"]
86 assert.True(t, ok)
87 _, ok = api.operations["GET"]["/{someId}"]
88 assert.True(t, ok)
89
90 authorizer := api.Authorizer()
91 assert.NotNil(t, authorizer)
92
93 h, ok := api.OperationHandlerFor("get", "/{someId}")
94 assert.True(t, ok)
95 assert.NotNil(t, h)
96
97 _, ok = api.OperationHandlerFor("doesntExist", "/{someId}")
98 assert.False(t, ok)
99 }
100
101 func TestUntypedAppValidation(t *testing.T) {
102 invalidSpecStr := `{
103 "consumes": ["application/json"],
104 "produces": ["application/json"],
105 "security": [
106 {"apiKey":[]}
107 ],
108 "parameters": {
109 "format": {
110 "in": "query",
111 "name": "format",
112 "type": "string"
113 }
114 },
115 "paths": {
116 "/": {
117 "parameters": [
118 {
119 "name": "limit",
120 "type": "integer",
121 "format": "int32",
122 "x-go-name": "Limit"
123 }
124 ],
125 "get": {
126 "consumes": ["application/x-yaml"],
127 "produces": ["application/x-yaml"],
128 "security": [
129 {"basic":[]}
130 ],
131 "parameters": [
132 {
133 "name": "skip",
134 "type": "integer",
135 "format": "int32"
136 }
137 ]
138 }
139 }
140 }
141 }`
142 specStr := `{
143 "consumes": ["application/json"],
144 "produces": ["application/json"],
145 "security": [
146 {"apiKey":[]}
147 ],
148 "securityDefinitions": {
149 "basic": { "type": "basic" },
150 "apiKey": { "type": "apiKey", "in":"header", "name":"X-API-KEY" }
151 },
152 "parameters": {
153 "format": {
154 "in": "query",
155 "name": "format",
156 "type": "string"
157 }
158 },
159 "paths": {
160 "/": {
161 "parameters": [
162 {
163 "name": "limit",
164 "type": "integer",
165 "format": "int32",
166 "x-go-name": "Limit"
167 }
168 ],
169 "get": {
170 "consumes": ["application/x-yaml"],
171 "produces": ["application/x-yaml"],
172 "security": [
173 {"basic":[]}
174 ],
175 "parameters": [
176 {
177 "name": "skip",
178 "type": "integer",
179 "format": "int32"
180 }
181 ]
182 }
183 }
184 }
185 }`
186 validSpec, err := loads.Analyzed([]byte(specStr), "")
187 require.NoError(t, err)
188 assert.NotNil(t, validSpec)
189
190 spec, err := loads.Analyzed([]byte(invalidSpecStr), "")
191 require.NoError(t, err)
192 assert.NotNil(t, spec)
193
194 analyzed := analysis.New(spec.Spec())
195 analyzedValid := analysis.New(validSpec.Spec())
196 cons := analyzed.ConsumesFor(analyzed.AllPaths()["/"].Get)
197 assert.Len(t, cons, 1)
198 prods := analyzed.RequiredProduces()
199 assert.Len(t, prods, 2)
200
201 api1 := NewAPI(spec)
202 err = api1.Validate()
203 require.Error(t, err)
204 assert.Equal(t, "missing [application/x-yaml] consumes registrations", err.Error())
205
206 api1.RegisterConsumer("application/x-yaml", new(stubConsumer))
207 err = api1.validate()
208 require.Error(t, err)
209 assert.Equal(t, "missing [application/x-yaml] produces registrations", err.Error())
210
211 api1.RegisterProducer("application/x-yaml", new(stubProducer))
212 err = api1.validate()
213 require.Error(t, err)
214 assert.Equal(t, "missing [GET /] operation registrations", err.Error())
215
216 api1.RegisterOperation("get", "/", new(stubOperationHandler))
217 err = api1.validate()
218 require.Error(t, err)
219 assert.Equal(t, "missing [apiKey, basic] auth scheme registrations", err.Error())
220
221 api1.RegisterAuth("basic", stubAutenticator())
222 api1.RegisterAuth("apiKey", stubAutenticator())
223 err = api1.validate()
224 require.Error(t, err)
225 assert.Equal(t, "missing [apiKey, basic] security definitions registrations", err.Error())
226
227 api3 := NewAPI(validSpec)
228 api3.RegisterConsumer("application/x-yaml", new(stubConsumer))
229 api3.RegisterProducer("application/x-yaml", new(stubProducer))
230 api3.RegisterOperation("get", "/", new(stubOperationHandler))
231 api3.RegisterAuth("basic", stubAutenticator())
232 api3.RegisterAuth("apiKey", stubAutenticator())
233 err = api3.validate()
234 require.NoError(t, err)
235 api3.RegisterConsumer("application/something", new(stubConsumer))
236 err = api3.validate()
237 require.Error(t, err)
238 assert.Equal(t, "missing from spec file [application/something] consumes", err.Error())
239
240 api2 := NewAPI(spec)
241 api2.RegisterConsumer("application/something", new(stubConsumer))
242 err = api2.validate()
243 require.Error(t, err)
244 assert.Equal(t, "missing [application/x-yaml] consumes registrations\nmissing from spec file [application/something] consumes", err.Error())
245 api2.RegisterConsumer("application/x-yaml", new(stubConsumer))
246 delete(api2.consumers, "application/something")
247 api2.RegisterProducer("application/something", new(stubProducer))
248 err = api2.validate()
249 require.Error(t, err)
250 assert.Equal(t, "missing [application/x-yaml] produces registrations\nmissing from spec file [application/something] produces", err.Error())
251 delete(api2.producers, "application/something")
252 api2.RegisterProducer("application/x-yaml", new(stubProducer))
253
254 expected := []string{"application/x-yaml"}
255 sort.Strings(expected)
256 consumes := analyzed.ConsumesFor(analyzed.AllPaths()["/"].Get)
257 sort.Strings(consumes)
258 assert.Equal(t, expected, consumes)
259 consumers := api1.ConsumersFor(consumes)
260 assert.Len(t, consumers, 1)
261
262 produces := analyzed.ProducesFor(analyzed.AllPaths()["/"].Get)
263 sort.Strings(produces)
264 assert.Equal(t, expected, produces)
265 producers := api1.ProducersFor(produces)
266 assert.Len(t, producers, 1)
267
268 definitions := analyzedValid.SecurityDefinitionsFor(analyzedValid.AllPaths()["/"].Get)
269 expectedSchemes := map[string]swaggerspec.SecurityScheme{"basic": *swaggerspec.BasicAuth()}
270 assert.Equal(t, expectedSchemes, definitions)
271 authenticators := api3.AuthenticatorsFor(definitions)
272 assert.Len(t, authenticators, 1)
273
274 opHandler := runtime.OperationHandlerFunc(func(data interface{}) (interface{}, error) {
275 return data, nil
276 })
277 d, err := opHandler.Handle(1)
278 require.NoError(t, err)
279 assert.Equal(t, 1, d)
280
281 authenticator := runtime.AuthenticatorFunc(func(params interface{}) (bool, interface{}, error) {
282 if str, ok := params.(string); ok {
283 return ok, str, nil
284 }
285 return true, nil, errors.Unauthenticated("authenticator")
286 })
287 ok, p, err := authenticator.Authenticate("hello")
288 assert.True(t, ok)
289 require.NoError(t, err)
290 assert.Equal(t, "hello", p)
291 }
292
View as plain text