1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package spec_test
16
17 import (
18 "path/filepath"
19 "strings"
20 "testing"
21
22 "github.com/go-openapi/spec"
23 "github.com/stretchr/testify/assert"
24 "github.com/stretchr/testify/require"
25 )
26
27
28
29 func TestSpec_Issue2743(t *testing.T) {
30 t.Run("should expand but produce unresolvable $ref", func(t *testing.T) {
31 path := filepath.Join("fixtures", "bugs", "2743", "working", "spec.yaml")
32 sp := loadOrFail(t, path)
33 require.NoError(t,
34 spec.ExpandSpec(sp, &spec.ExpandOptions{RelativeBase: path, SkipSchemas: true, PathLoader: testLoader}),
35 )
36
37 t.Run("all $ref do not resolve when expanding again", func(t *testing.T) {
38 err := spec.ExpandSpec(sp, &spec.ExpandOptions{RelativeBase: path, SkipSchemas: false, PathLoader: testLoader})
39 require.Error(t, err)
40 require.ErrorContains(t, err, filepath.FromSlash("swagger/paths/swagger/user/index.yml"))
41 })
42 })
43
44 t.Run("should expand and produce resolvable $ref", func(t *testing.T) {
45 path := filepath.Join("fixtures", "bugs", "2743", "not-working", "spec.yaml")
46 sp := loadOrFail(t, path)
47 require.NoError(t,
48 spec.ExpandSpec(sp, &spec.ExpandOptions{RelativeBase: path, SkipSchemas: true, PathLoader: testLoader}),
49 )
50
51 t.Run("all $ref properly reolve when expanding again", func(t *testing.T) {
52 require.NoError(t,
53 spec.ExpandSpec(sp, &spec.ExpandOptions{RelativeBase: path, SkipSchemas: false, PathLoader: testLoader}),
54 )
55 require.NotContainsf(t, asJSON(t, sp), "$ref", "all $ref's should have been expanded properly")
56 })
57 })
58 }
59
60 func TestSpec_Issue1429(t *testing.T) {
61 path := filepath.Join("fixtures", "bugs", "1429", "swagger.yaml")
62
63
64 sp := loadOrFail(t, path)
65 err := spec.ExpandSpec(sp, &spec.ExpandOptions{RelativeBase: path, SkipSchemas: false, PathLoader: testLoader})
66 require.NoError(t, err)
67
68
69 require.Truef(t, (sp.Paths != nil && sp.Paths.Paths != nil), "expected paths to be available in fixture")
70
71 assertPaths1429(t, sp)
72
73 for _, def := range sp.Definitions {
74 assert.Empty(t, def.Ref)
75 }
76
77
78 sp = loadOrFail(t, path)
79 err = spec.ExpandSpec(sp, &spec.ExpandOptions{RelativeBase: path, SkipSchemas: true, PathLoader: testLoader})
80 require.NoError(t, err)
81
82
83 require.Truef(t, (sp.Paths != nil && sp.Paths.Paths != nil), "expected paths to be available in fixture")
84
85 assertPaths1429SkipSchema(t, sp)
86
87 for _, def := range sp.Definitions {
88 assert.Contains(t, def.Ref.String(), "responses.yaml#/definitions/")
89 }
90 }
91
92 func assertPaths1429(t testing.TB, sp *spec.Swagger) {
93 for _, pi := range sp.Paths.Paths {
94 for _, param := range pi.Get.Parameters {
95 require.NotNilf(t, param.Schema, "expected param schema not to be nil")
96
97
98 assert.Equal(t, "", param.Schema.Ref.String())
99 }
100
101 for code, response := range pi.Get.Responses.StatusCodeResponses {
102
103 if code == 200 {
104 assert.Nilf(t, response.Schema, "expected response schema to be nil")
105 continue
106 }
107 require.NotNilf(t, response.Schema, "expected response schema not to be nil")
108 assert.Equal(t, "", response.Schema.Ref.String())
109 }
110 }
111 }
112
113 func assertPaths1429SkipSchema(t testing.TB, sp *spec.Swagger) {
114 for _, pi := range sp.Paths.Paths {
115 for _, param := range pi.Get.Parameters {
116 require.NotNilf(t, param.Schema, "expected param schema not to be nil")
117
118
119 switch param.Name {
120 case "plainRequest":
121
122 assert.Equal(t, "", param.Schema.Ref.String())
123 continue
124 case "nestedBody":
125
126 assert.Truef(t, strings.HasPrefix(param.Schema.Ref.String(), "#/definitions/"),
127 "expected rooted definitions $ref, got: %s", param.Schema.Ref.String())
128 continue
129 case "remoteRequest":
130 assert.Contains(t, param.Schema.Ref.String(), "remote/remote.yaml#/")
131 continue
132 }
133 assert.Contains(t, param.Schema.Ref.String(), "responses.yaml#/")
134
135 }
136
137 for code, response := range pi.Get.Responses.StatusCodeResponses {
138
139 switch code {
140 case 200:
141 assert.Nilf(t, response.Schema, "expected response schema to be nil")
142 continue
143 case 204:
144 assert.Contains(t, response.Schema.Ref.String(), "remote/remote.yaml#/")
145 continue
146 case 404:
147 assert.Equal(t, "", response.Schema.Ref.String())
148 continue
149 }
150 assert.Containsf(t, response.Schema.Ref.String(), "responses.yaml#/", "expected remote ref at resp. %d", code)
151 }
152 }
153 }
154
155 func TestSpec_MoreLocalExpansion(t *testing.T) {
156 path := filepath.Join("fixtures", "local_expansion", "spec2.yaml")
157
158
159 sp := loadOrFail(t, path)
160 require.NoError(t, spec.ExpandSpec(sp, &spec.ExpandOptions{RelativeBase: path, SkipSchemas: false, PathLoader: testLoader}))
161
162
163 assert.NotContains(t, asJSON(t, sp), `"$ref"`)
164 }
165
166 func TestSpec_Issue69(t *testing.T) {
167
168
169 path := filepath.Join("fixtures", "bugs", "69", "dapperbox.json")
170
171
172
173 sp := loadOrFail(t, path)
174 require.NoError(t, spec.ExpandSpec(sp, &spec.ExpandOptions{RelativeBase: path, SkipSchemas: false, PathLoader: testLoader}))
175
176
177 jazon := asJSON(t, sp)
178
179
180
181
182 assertRefInJSON(t, jazon, "#/definitions")
183
184
185 assertRefExpand(t, jazon, "", sp)
186 }
187
188 func TestSpec_Issue1621(t *testing.T) {
189 path := filepath.Join("fixtures", "bugs", "1621", "fixture-1621.yaml")
190
191
192
193 sp := loadOrFail(t, path)
194
195 err := spec.ExpandSpec(sp, &spec.ExpandOptions{RelativeBase: path, SkipSchemas: false, PathLoader: testLoader})
196 require.NoError(t, err)
197
198
199 jazon := asJSON(t, sp)
200
201 assertNoRef(t, jazon)
202 }
203
204 func TestSpec_Issue1614(t *testing.T) {
205 path := filepath.Join("fixtures", "bugs", "1614", "gitea.json")
206
207
208
209 sp := loadOrFail(t, path)
210 require.NoError(t, spec.ExpandSpec(sp, &spec.ExpandOptions{RelativeBase: path, SkipSchemas: false, PathLoader: testLoader}))
211
212
213 jazon := asJSON(t, sp)
214
215
216 assertRefInJSON(t, jazon, "#/definitions")
217
218
219 assertRefExpand(t, jazon, "", sp)
220
221
222
223 sp = loadOrFail(t, path)
224 require.NoError(t, spec.ExpandSpec(sp, &spec.ExpandOptions{
225 RelativeBase: path,
226 SkipSchemas: false,
227 AbsoluteCircularRef: true,
228 PathLoader: testLoader,
229 }))
230
231
232 jazon = asJSON(t, sp)
233
234
235 assertRefInJSONRegexp(t, jazon, `file://.*/gitea.json#/definitions/`)
236
237
238 assertRefExpand(t, jazon, "", sp, &spec.ExpandOptions{RelativeBase: path})
239 }
240
241 func TestSpec_Issue2113(t *testing.T) {
242
243 path := filepath.Join("fixtures", "bugs", "2113", "base.yaml")
244
245
246 sp := loadOrFail(t, path)
247 err := spec.ExpandSpec(sp, &spec.ExpandOptions{RelativeBase: path, SkipSchemas: false, PathLoader: testLoader})
248 require.NoError(t, err)
249
250
251 jazon := asJSON(t, sp)
252
253
254 assertNoRef(t, jazon)
255
256
257 sp = loadOrFail(t, path)
258 err = spec.ExpandSpec(sp, &spec.ExpandOptions{RelativeBase: path, SkipSchemas: true, PathLoader: testLoader})
259 require.NoError(t, err)
260
261 jazon = asJSON(t, sp)
262
263
264 assertRefInJSONRegexp(t, jazon, `^(schemas/dummy/dummy.yaml)|(schemas/example/example.yaml)`)
265
266
267 assertRefResolve(t, jazon, "", sp, &spec.ExpandOptions{RelativeBase: path, PathLoader: testLoader})
268
269
270 assertRefExpand(t, jazon, "", sp, &spec.ExpandOptions{RelativeBase: path, PathLoader: testLoader})
271 }
272
273 func TestSpec_Issue2113_External(t *testing.T) {
274
275
276
277
278 path := filepath.Join("fixtures", "skipschema", "external_definitions_valid.yml")
279
280
281 sp := loadOrFail(t, path)
282 require.NoError(t, spec.ExpandSpec(sp, &spec.ExpandOptions{RelativeBase: path, SkipSchemas: true, PathLoader: testLoader}))
283
284
285 jazon := asJSON(t, sp)
286
287 assertRefInJSONRegexp(t, jazon, `^(external/definitions.yml#/definitions)|(external/errors.yml#/error)|(external/nestedParams.yml#/bodyParam)`)
288
289
290 assertRefResolve(t, jazon, "", sp, &spec.ExpandOptions{RelativeBase: path, PathLoader: testLoader})
291
292
293 assertRefExpand(t, jazon, "", sp, &spec.ExpandOptions{RelativeBase: path, PathLoader: testLoader})
294
295
296 require.NoError(t, spec.ExpandSpec(sp, &spec.ExpandOptions{RelativeBase: path, SkipSchemas: false, PathLoader: testLoader}))
297
298 jazon = asJSON(t, sp)
299 assertNoRef(t, jazon)
300
301
302 sp = loadOrFail(t, path)
303 require.NoError(t, spec.ExpandSpec(sp, &spec.ExpandOptions{RelativeBase: path, SkipSchemas: false, PathLoader: testLoader}))
304
305 jazon = asJSON(t, sp)
306 assertNoRef(t, jazon)
307 }
308
309 func TestSpec_Issue2113_SkipSchema(t *testing.T) {
310
311
312
313
314 path := filepath.Join("fixtures", "flatten", "flatten.yml")
315
316
317 sp := loadOrFail(t, path)
318 require.NoError(t, spec.ExpandSpec(sp, &spec.ExpandOptions{RelativeBase: path, SkipSchemas: true, PathLoader: testLoader}))
319
320 jazon := asJSON(t, sp)
321
322
323 assertRefInJSONRegexp(t, jazon, `^(external/definitions.yml#/definitions)|(#/definitions/namedAgain)|(external/errors.yml#/error)`)
324
325
326 assertRefResolve(t, jazon, "", sp, &spec.ExpandOptions{RelativeBase: path, PathLoader: testLoader})
327
328 assertRefExpand(t, jazon, "", sp, &spec.ExpandOptions{RelativeBase: path, PathLoader: testLoader})
329
330
331 sp = loadOrFail(t, path)
332 require.NoError(t, spec.ExpandSpec(sp, &spec.ExpandOptions{RelativeBase: path, SkipSchemas: false, PathLoader: testLoader}))
333
334 jazon = asJSON(t, sp)
335 assertNoRef(t, jazon)
336 }
337
338 func TestSpec_PointersLoop(t *testing.T) {
339
340
341
342
343 path := filepath.Join("fixtures", "more_circulars", "pointers", "fixture-pointers-loop.yaml")
344
345
346 sp := loadOrFail(t, path)
347 require.NoError(t, spec.ExpandSpec(sp, &spec.ExpandOptions{RelativeBase: path, SkipSchemas: true, PathLoader: testLoader}))
348
349 jazon := asJSON(t, sp)
350 assertRefExpand(t, jazon, "", sp, &spec.ExpandOptions{RelativeBase: path, PathLoader: testLoader})
351
352 sp = loadOrFail(t, path)
353 require.NoError(t, spec.ExpandSpec(sp, &spec.ExpandOptions{RelativeBase: path, SkipSchemas: false, PathLoader: testLoader}))
354
355
356
357
358 jazon = asJSON(t, sp)
359
360 m := rex.FindAllStringSubmatch(jazon, -1)
361 require.NotEmpty(t, m)
362
363 refs := make(map[string]struct{}, 5)
364 for _, matched := range m {
365 subMatch := matched[1]
366 refs[subMatch] = struct{}{}
367 }
368 require.Len(t, refs, 1)
369
370 assertRefExpand(t, jazon, "", sp, &spec.ExpandOptions{RelativeBase: path, PathLoader: testLoader})
371 }
372
373 func TestSpec_Issue102(t *testing.T) {
374
375 path := filepath.Join("fixtures", "bugs", "102", "fixture-102.json")
376 sp := loadOrFail(t, path)
377
378 require.NoError(t, spec.ExpandSpec(sp, nil))
379
380 jazon := asJSON(t, sp)
381 assertRefInJSONRegexp(t, jazon, `^#/definitions/Error$`)
382
383 sp = loadOrFail(t, path)
384 sch := spec.RefSchema("#/definitions/Error")
385 require.NoError(t, spec.ExpandSchema(sch, sp, nil))
386
387 jazon = asJSON(t, sch)
388 assertRefInJSONRegexp(t, jazon, "^#/definitions/Error$")
389
390 sp = loadOrFail(t, path)
391 sch = spec.RefSchema("#/definitions/Error")
392 resp := spec.NewResponse().WithDescription("ok").WithSchema(sch)
393 require.NoError(t, spec.ExpandResponseWithRoot(resp, sp, nil))
394
395 jazon = asJSON(t, resp)
396 assertRefInJSONRegexp(t, jazon, "^#/definitions/Error$")
397
398 sp = loadOrFail(t, path)
399 sch = spec.RefSchema("#/definitions/Error")
400 param := spec.BodyParam("error", sch)
401 require.NoError(t, spec.ExpandParameterWithRoot(param, sp, nil))
402
403 jazon = asJSON(t, resp)
404 assertRefInJSONRegexp(t, jazon, "^#/definitions/Error$")
405 }
406
View as plain text