From b39d037b3cf0c49853f04a24bb1bf0894def4d3f Mon Sep 17 00:00:00 2001 From: Darrel Miller Date: Sun, 15 Sep 2019 14:06:13 -0400 Subject: [PATCH] Collapsed components that are references --- .../ParseNodes/MapNode.cs | 12 +- .../Microsoft.OpenApi.Readers.Tests.csproj | 6 + .../V2Tests/OpenApiDocumentTests.cs | 19 ++ .../Samples/ComponentRootReference.json | 178 ++++++++++++++++++ 4 files changed, 211 insertions(+), 4 deletions(-) create mode 100644 test/Microsoft.OpenApi.Readers.Tests/V2Tests/Samples/ComponentRootReference.json diff --git a/src/Microsoft.OpenApi.Readers/ParseNodes/MapNode.cs b/src/Microsoft.OpenApi.Readers/ParseNodes/MapNode.cs index 95aa4ff62..8ea49ab6d 100644 --- a/src/Microsoft.OpenApi.Readers/ParseNodes/MapNode.cs +++ b/src/Microsoft.OpenApi.Readers/ParseNodes/MapNode.cs @@ -100,11 +100,15 @@ public override Dictionary CreateMapWithReference( { return null; // Body Parameters shouldn't be converted to Parameters } - entry.value.Reference = new OpenApiReference() + // If the component isn't a reference to another component, then point it to itself. + if (entry.value.Reference == null) { - Type = referenceType, - Id = entry.key - }; + entry.value.Reference = new OpenApiReference() + { + Type = referenceType, + Id = entry.key + }; + } return entry; } ); diff --git a/test/Microsoft.OpenApi.Readers.Tests/Microsoft.OpenApi.Readers.Tests.csproj b/test/Microsoft.OpenApi.Readers.Tests/Microsoft.OpenApi.Readers.Tests.csproj index e24afc871..211e268de 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/Microsoft.OpenApi.Readers.Tests.csproj +++ b/test/Microsoft.OpenApi.Readers.Tests/Microsoft.OpenApi.Readers.Tests.csproj @@ -12,6 +12,9 @@ true ..\..\src\Microsoft.OpenApi.snk + + + Never @@ -25,6 +28,9 @@ Never + + PreserveNewest + Never diff --git a/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiDocumentTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiDocumentTests.cs index fbf3da7de..35522f510 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiDocumentTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiDocumentTests.cs @@ -316,5 +316,24 @@ public void ShouldAssignSchemaToAllResponses() xml.Schema.ShouldBeEquivalentTo(targetSchema); } } + + + [Fact] + public void ShouldAllowComponentsThatJustContainAReference() + { + using (var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "ComponentRootReference.json"))) + { + OpenApiStreamReader reader = new OpenApiStreamReader(); + OpenApiDocument doc = reader.Read(stream, out OpenApiDiagnostic diags); + OpenApiSchema schema1 = doc.Components.Schemas["AllPets"]; + Assert.False(schema1.UnresolvedReference); + OpenApiSchema schema2 = (OpenApiSchema)doc.ResolveReference(schema1.Reference); + if (schema2.UnresolvedReference && schema1.Reference.Id == schema2.Reference.Id) + { + // detected a cycle - this code gets triggered + Assert.True(false, "A cycle should not be detected"); + } + } + } } } \ No newline at end of file diff --git a/test/Microsoft.OpenApi.Readers.Tests/V2Tests/Samples/ComponentRootReference.json b/test/Microsoft.OpenApi.Readers.Tests/V2Tests/Samples/ComponentRootReference.json new file mode 100644 index 000000000..c5c055e0d --- /dev/null +++ b/test/Microsoft.OpenApi.Readers.Tests/V2Tests/Samples/ComponentRootReference.json @@ -0,0 +1,178 @@ +{ + "openapi": "3.0.0", + "info": { + "version": "1.0.0", + "title": "Swagger Petstore", + "license": { + "name": "MIT" + } + }, + "servers": [ + { + "url": "http://petstore.swagger.io/v1" + } + ], + "paths": { + "/pets": { + "get": { + "summary": "List all pets", + "operationId": "listPets", + "tags": [ + "pets" + ], + "parameters": [ + { + "name": "limit", + "in": "query", + "description": "How many items to return at one time (max 100)", + "required": false, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "responses": { + "200": { + "description": "A paged array of pets", + "headers": { + "x-next": { + "description": "A link to the next page of responses", + "schema": { + "type": "string" + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AllPets" + } + } + } + }, + "default": { + "description": "unexpected error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + }, + "post": { + "summary": "Create a pet", + "operationId": "createPets", + "tags": [ + "pets" + ], + "responses": { + "201": { + "description": "Null response" + }, + "default": { + "description": "unexpected error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/pets/{petId}": { + "get": { + "summary": "Info for a specific pet", + "operationId": "showPetById", + "tags": [ + "pets" + ], + "parameters": [ + { + "name": "petId", + "in": "path", + "required": true, + "description": "The id of the pet to retrieve", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Expected response to a valid request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Pets" + } + } + } + }, + "default": { + "description": "unexpected error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + } + }, + "components": { + "schemas": { + "Pet": { + "required": [ + "id", + "name" + ], + "properties": { + "id": { + "type": "integer", + "format": "int64" + }, + "name": { + "type": "string" + }, + "tag": { + "type": "string" + } + } + }, + "Pets": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Pet" + } + }, + "AllPets": { + "$ref": "#/components/schemas/Pets" + }, + "Error": { + "required": [ + "code", + "message" + ], + "properties": { + "code": { + "type": "integer", + "format": "int32" + }, + "message": { + "type": "string" + } + } + } + } + } +} \ No newline at end of file