@@ -12,6 +12,7 @@ import (
1212 "testing"
1313 "testing/fstest"
1414
15+ "github.com/pb33f/libopenapi"
1516 "github.com/pb33f/libopenapi/datamodel"
1617 "github.com/pb33f/libopenapi/index"
1718 "github.com/stretchr/testify/assert"
@@ -306,6 +307,117 @@ paths:
306307 assertNoFilePathRefs (t , result .Bytes )
307308}
308309
310+ func TestBundleDocumentComposedWithOrigins_SchemaProxyGetReferenceUsesBundledRef (t * testing.T ) {
311+ tmpDir := t .TempDir ()
312+
313+ topSpec := `openapi: 3.1.0
314+ info:
315+ title: Bundle Ref Getter Test
316+ version: 1.0.0
317+ paths:
318+ /:
319+ get:
320+ operationId: getRoot
321+ responses:
322+ '400':
323+ $ref: "#/components/responses/BadRequest"
324+ '500':
325+ $ref: "./shared.yaml#/components/responses/InternalServerError"
326+ components:
327+ responses:
328+ BadRequest:
329+ $ref: "./shared.yaml#/components/responses/BadRequest"
330+ schemas:
331+ Error:
332+ type: object
333+ properties:
334+ wrong:
335+ type: string
336+ `
337+
338+ sharedSpec := `openapi: 3.1.0
339+ components:
340+ responses:
341+ BadRequest:
342+ description: Bad Request
343+ content:
344+ application/json:
345+ schema:
346+ $ref: "#/components/schemas/Error"
347+ InternalServerError:
348+ description: Internal Server Error
349+ content:
350+ application/json:
351+ schema:
352+ $ref: "#/components/schemas/InternalServerError"
353+ schemas:
354+ Error:
355+ type: object
356+ properties:
357+ message:
358+ type: string
359+ InternalServerError:
360+ type: object
361+ properties:
362+ message:
363+ type: string
364+ `
365+
366+ topFile := filepath .Join (tmpDir , "top.yaml" )
367+ sharedFile := filepath .Join (tmpDir , "shared.yaml" )
368+ require .NoError (t , os .WriteFile (topFile , []byte (topSpec ), 0644 ))
369+ require .NoError (t , os .WriteFile (sharedFile , []byte (sharedSpec ), 0644 ))
370+
371+ config := datamodel .NewDocumentConfiguration ()
372+ config .BasePath = tmpDir
373+ config .SpecFilePath = topFile
374+ config .ExtractRefsSequentially = true
375+
376+ spec , err := os .ReadFile (topFile )
377+ require .NoError (t , err )
378+
379+ doc , err := libopenapi .NewDocumentWithConfiguration (spec , config )
380+ require .NoError (t , err )
381+
382+ model , err := doc .BuildV3Model ()
383+ require .NoError (t , err )
384+
385+ result , err := BundleDocumentComposedWithOrigins (& model .Model , nil )
386+ require .NoError (t , err )
387+ require .NotNil (t , result )
388+
389+ bundledStr := string (result .Bytes )
390+ assert .Contains (t , bundledStr , "#/components/schemas/Error__shared" )
391+ assert .Contains (t , bundledStr , "#/components/schemas/InternalServerError" )
392+
393+ op := model .Model .Paths .PathItems .GetOrZero ("/" ).Get
394+ require .NotNil (t , op )
395+ require .NotNil (t , op .Responses )
396+
397+ badRequest := op .Responses .Codes .GetOrZero ("400" )
398+ require .NotNil (t , badRequest )
399+ badRequestSchema := badRequest .Content .GetOrZero ("application/json" ).Schema
400+ require .NotNil (t , badRequestSchema )
401+
402+ internalError := op .Responses .Codes .GetOrZero ("500" )
403+ require .NotNil (t , internalError )
404+ internalErrorSchema := internalError .Content .GetOrZero ("application/json" ).Schema
405+ require .NotNil (t , internalErrorSchema )
406+
407+ assert .Equal (t , "#/components/schemas/Error__shared" , badRequestSchema .GetReference ())
408+ assert .Equal (t , "#/components/schemas/InternalServerError" , internalErrorSchema .GetReference ())
409+
410+ badRequestOrigin := result .Origins [badRequestSchema .GetReference ()]
411+ require .NotNil (t , badRequestOrigin )
412+ assert .Equal (t , sharedFile , badRequestOrigin .OriginalFile )
413+ assert .Equal (t , "#/components/schemas/Error" , badRequestOrigin .OriginalRef )
414+
415+ internalErrorOrigin := result .Origins [internalErrorSchema .GetReference ()]
416+ require .NotNil (t , internalErrorOrigin )
417+ assert .Equal (t , sharedFile , internalErrorOrigin .OriginalFile )
418+ assert .Equal (t , "#/components/schemas/InternalServerError" , internalErrorOrigin .OriginalRef )
419+ }
420+
309421// TestBundlerComposedWithOrigins_AbsolutePathRefReuse ensures absolute-path refs
310422// that point at inline-required content are replaced with the inlined node content.
311423func TestBundlerComposedWithOrigins_AbsolutePathRefReuse (t * testing.T ) {
0 commit comments