Skip to content

Commit

Permalink
Merge pull request #1195 from dldl-cmd/openapioperation-copy-construc…
Browse files Browse the repository at this point in the history
…tor-preserve-null

OpenApiOperation constructor preserve null
  • Loading branch information
MaggieKimani1 authored Mar 29, 2023
2 parents db02b95 + d479ec3 commit 746fe68
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 7 deletions.
4 changes: 2 additions & 2 deletions src/Microsoft.OpenApi/Models/OpenApiOperation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -116,13 +116,13 @@ public OpenApiOperation() {}
/// </summary>
public OpenApiOperation(OpenApiOperation operation)
{
Tags = new List<OpenApiTag>(operation?.Tags);
Tags = operation?.Tags != null ? new List<OpenApiTag>(operation?.Tags) : null;
Summary = operation?.Summary ?? Summary;
Description = operation?.Description ?? Description;
ExternalDocs = operation?.ExternalDocs != null ? new(operation?.ExternalDocs) : null;
OperationId = operation?.OperationId ?? OperationId;
Parameters = operation?.Parameters != null ? new List<OpenApiParameter>(operation.Parameters) : null;
RequestBody = new(operation?.RequestBody);
RequestBody = operation?.RequestBody != null ? new(operation?.RequestBody) : null;
Responses = operation?.Responses != null ? new(operation?.Responses) : null;
Callbacks = operation?.Callbacks != null ? new Dictionary<string, OpenApiCallback>(operation.Callbacks) : null;
Deprecated = operation?.Deprecated ?? Deprecated;
Expand Down
4 changes: 2 additions & 2 deletions src/Microsoft.OpenApi/Models/OpenApiParameter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -243,11 +243,11 @@ public void SerializeAsV3WithoutReference(IOpenApiWriter writer)
// style
if (_style.HasValue)
{
writer.WriteProperty(OpenApiConstants.Style, Style.Value.GetDisplayName());
writer.WriteProperty(OpenApiConstants.Style, _style.Value.GetDisplayName());
}

// explode
writer.WriteProperty(OpenApiConstants.Explode, Explode, Style.HasValue && Style.Value == ParameterStyle.Form);
writer.WriteProperty(OpenApiConstants.Explode, _explode, _style.HasValue && _style.Value == ParameterStyle.Form);

// allowReserved
writer.WriteProperty(OpenApiConstants.AllowReserved, AllowReserved, false);
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"openapi":"3.0.1","info":{"title":"Swagger Petstore (Simple)","description":"A sample API that uses a petstore as an example to demonstrate features in the swagger-2.0 specification","termsOfService":"http://helloreverb.com/terms/","contact":{"name":"Swagger API team","url":"http://swagger.io","email":"[email protected]"},"license":{"name":"MIT","url":"http://opensource.org/licenses/MIT"},"version":"1.0.0"},"servers":[{"url":"http://petstore.swagger.io/api"}],"paths":{"/pets":{"get":{"description":"Returns all pets from the system that the user has access to","operationId":"findPets","parameters":[{"name":"tags","in":"query","description":"tags to filter by","style":"form","schema":{"type":"array","items":{"type":"string"}}},{"name":"limit","in":"query","description":"maximum number of results to return","style":"form","schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"pet response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/pet"}}},"application/xml":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/pet"}}}}},"4XX":{"description":"unexpected client error","content":{"text/html":{"schema":{"$ref":"#/components/schemas/errorModel"}}}},"5XX":{"description":"unexpected server error","content":{"text/html":{"schema":{"$ref":"#/components/schemas/errorModel"}}}}}},"post":{"description":"Creates a new pet in the store. Duplicates are allowed","operationId":"addPet","requestBody":{"description":"Pet to add to the store","content":{"application/json":{"schema":{"$ref":"#/components/schemas/newPet"}}},"required":true},"responses":{"200":{"description":"pet response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/pet"}}}},"4XX":{"description":"unexpected client error","content":{"text/html":{"schema":{"$ref":"#/components/schemas/errorModel"}}}},"5XX":{"description":"unexpected server error","content":{"text/html":{"schema":{"$ref":"#/components/schemas/errorModel"}}}}}}},"/pets/{id}":{"get":{"description":"Returns a user based on a single ID, if the user does not have access to the pet","operationId":"findPetById","parameters":[{"name":"id","in":"path","description":"ID of pet to fetch","required":true,"style":"simple","schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"pet response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/pet"}},"application/xml":{"schema":{"$ref":"#/components/schemas/pet"}}}},"4XX":{"description":"unexpected client error","content":{"text/html":{"schema":{"$ref":"#/components/schemas/errorModel"}}}},"5XX":{"description":"unexpected server error","content":{"text/html":{"schema":{"$ref":"#/components/schemas/errorModel"}}}}}},"delete":{"description":"deletes a single pet based on the ID supplied","operationId":"deletePet","parameters":[{"name":"id","in":"path","description":"ID of pet to delete","required":true,"style":"simple","schema":{"type":"integer","format":"int64"}}],"responses":{"204":{"description":"pet deleted"},"4XX":{"description":"unexpected client error","content":{"text/html":{"schema":{"$ref":"#/components/schemas/errorModel"}}}},"5XX":{"description":"unexpected server error","content":{"text/html":{"schema":{"$ref":"#/components/schemas/errorModel"}}}}}}}},"components":{"schemas":{"pet":{"required":["id","name"],"type":"object","properties":{"id":{"type":"integer","format":"int64"},"name":{"type":"string"},"tag":{"type":"string"}}},"newPet":{"required":["name"],"type":"object","properties":{"id":{"type":"integer","format":"int64"},"name":{"type":"string"},"tag":{"type":"string"}}},"errorModel":{"required":["code","message"],"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"}}}}}}
{"openapi":"3.0.1","info":{"title":"Swagger Petstore (Simple)","description":"A sample API that uses a petstore as an example to demonstrate features in the swagger-2.0 specification","termsOfService":"http://helloreverb.com/terms/","contact":{"name":"Swagger API team","url":"http://swagger.io","email":"[email protected]"},"license":{"name":"MIT","url":"http://opensource.org/licenses/MIT"},"version":"1.0.0"},"servers":[{"url":"http://petstore.swagger.io/api"}],"paths":{"/pets":{"get":{"description":"Returns all pets from the system that the user has access to","operationId":"findPets","parameters":[{"name":"tags","in":"query","description":"tags to filter by","schema":{"type":"array","items":{"type":"string"}}},{"name":"limit","in":"query","description":"maximum number of results to return","schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"pet response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/pet"}}},"application/xml":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/pet"}}}}},"4XX":{"description":"unexpected client error","content":{"text/html":{"schema":{"$ref":"#/components/schemas/errorModel"}}}},"5XX":{"description":"unexpected server error","content":{"text/html":{"schema":{"$ref":"#/components/schemas/errorModel"}}}}}},"post":{"description":"Creates a new pet in the store. Duplicates are allowed","operationId":"addPet","requestBody":{"description":"Pet to add to the store","content":{"application/json":{"schema":{"$ref":"#/components/schemas/newPet"}}},"required":true},"responses":{"200":{"description":"pet response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/pet"}}}},"4XX":{"description":"unexpected client error","content":{"text/html":{"schema":{"$ref":"#/components/schemas/errorModel"}}}},"5XX":{"description":"unexpected server error","content":{"text/html":{"schema":{"$ref":"#/components/schemas/errorModel"}}}}}}},"/pets/{id}":{"get":{"description":"Returns a user based on a single ID, if the user does not have access to the pet","operationId":"findPetById","parameters":[{"name":"id","in":"path","description":"ID of pet to fetch","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"pet response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/pet"}},"application/xml":{"schema":{"$ref":"#/components/schemas/pet"}}}},"4XX":{"description":"unexpected client error","content":{"text/html":{"schema":{"$ref":"#/components/schemas/errorModel"}}}},"5XX":{"description":"unexpected server error","content":{"text/html":{"schema":{"$ref":"#/components/schemas/errorModel"}}}}}},"delete":{"description":"deletes a single pet based on the ID supplied","operationId":"deletePet","parameters":[{"name":"id","in":"path","description":"ID of pet to delete","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"204":{"description":"pet deleted"},"4XX":{"description":"unexpected client error","content":{"text/html":{"schema":{"$ref":"#/components/schemas/errorModel"}}}},"5XX":{"description":"unexpected server error","content":{"text/html":{"schema":{"$ref":"#/components/schemas/errorModel"}}}}}}}},"components":{"schemas":{"pet":{"required":["id","name"],"type":"object","properties":{"id":{"type":"integer","format":"int64"},"name":{"type":"string"},"tag":{"type":"string"}}},"newPet":{"required":["name"],"type":"object","properties":{"id":{"type":"integer","format":"int64"},"name":{"type":"string"},"tag":{"type":"string"}}},"errorModel":{"required":["code","message"],"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"}}}}}}
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"openapi":"3.0.1","info":{"title":"Swagger Petstore (Simple)","description":"A sample API that uses a petstore as an example to demonstrate features in the swagger-2.0 specification","version":"1.0.0"},"servers":[{"url":"http://petstore.swagger.io/api"}],"paths":{"/add/{operand1}/{operand2}":{"get":{"operationId":"addByOperand1AndByOperand2","parameters":[{"name":"operand1","in":"path","description":"The first operand","required":true,"style":"simple","schema":{"type":"integer","my-extension":4},"my-extension":4},{"name":"operand2","in":"path","description":"The second operand","required":true,"style":"simple","schema":{"type":"integer","my-extension":4},"my-extension":4}],"responses":{"200":{"description":"pet response","content":{"application/json":{"schema":{"type":"array","items":{"required":["id","name"],"type":"object","properties":{"id":{"type":"integer","format":"int64"},"name":{"type":"string"},"tag":{"type":"string"}}}}}}}}}}}}
{"openapi":"3.0.1","info":{"title":"Swagger Petstore (Simple)","description":"A sample API that uses a petstore as an example to demonstrate features in the swagger-2.0 specification","version":"1.0.0"},"servers":[{"url":"http://petstore.swagger.io/api"}],"paths":{"/add/{operand1}/{operand2}":{"get":{"operationId":"addByOperand1AndByOperand2","parameters":[{"name":"operand1","in":"path","description":"The first operand","required":true,"schema":{"type":"integer","my-extension":4},"my-extension":4},{"name":"operand2","in":"path","description":"The second operand","required":true,"schema":{"type":"integer","my-extension":4},"my-extension":4}],"responses":{"200":{"description":"pet response","content":{"application/json":{"schema":{"type":"array","items":{"required":["id","name"],"type":"object","properties":{"id":{"type":"integer","format":"int64"},"name":{"type":"string"},"tag":{"type":"string"}}}}}}}}}}}}
54 changes: 54 additions & 0 deletions test/Microsoft.OpenApi.Tests/Models/OpenApiOperationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using FluentAssertions;
using Microsoft.OpenApi.Extensions;
using Microsoft.OpenApi.Models;
using NuGet.Frameworks;
using Xunit;
using Xunit.Abstractions;

Expand Down Expand Up @@ -793,5 +794,58 @@ public void EnsureOpenApiOperationCopyConstructorCopiesResponsesObject()
Assert.NotNull(operation.Responses);
Assert.Equal(2, operation.Responses.Count);
}

[Fact]
public void EnsureOpenApiOperationCopyConstructorCopiesNull()
{
// Arrange
_basicOperation.Parameters = null;
_basicOperation.Tags = null;
_basicOperation.Responses = null;
_basicOperation.Callbacks = null;
_basicOperation.Security = null;
_basicOperation.Servers = null;
_basicOperation.Extensions = null;

// Act
var operation = new OpenApiOperation(_basicOperation);

// Assert
Assert.Null(operation.Tags);
Assert.Null(operation.Summary);
Assert.Null(operation.Description);
Assert.Null(operation.ExternalDocs);
Assert.Null(operation.OperationId);
Assert.Null(operation.Parameters);
Assert.Null(operation.RequestBody);
Assert.Null(operation.Responses);
Assert.Null(operation.Callbacks);
Assert.Null(operation.Security);
Assert.Null(operation.Servers);
Assert.Null(operation.Extensions);
}

[Fact]
public void EnsureOpenApiOperationCopyConstructor_SerializationResultsInSame()
{
var operations = new[]
{
_basicOperation,
_operationWithBody,
_operationWithFormData,
_advancedOperationWithTagsAndSecurity
};

foreach (var operation in operations)
{
// Act
var expected = operation.SerializeAsJson(OpenApiSpecVersion.OpenApi3_0);
var openApiOperation = new OpenApiOperation(operation);
var actual = openApiOperation.SerializeAsJson(OpenApiSpecVersion.OpenApi3_0);

// Assert
actual.Should().Be(expected);
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"name":"name1","in":"path","style":"simple"}
{"name":"name1","in":"path"}

0 comments on commit 746fe68

Please sign in to comment.