Skip to content

Commit c5caa27

Browse files
committed
chore: add defensive programming
1 parent 7a9b01e commit c5caa27

File tree

5 files changed

+49
-46
lines changed

5 files changed

+49
-46
lines changed

src/Microsoft.OpenApi/Interfaces/IMetadataContainer.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) Microsoft Corporation. All rights reserved.
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
22
// Licensed under the MIT license.
33

44
using System.Collections.Generic;
@@ -14,6 +14,6 @@ public interface IMetadataContainer
1414
/// <summary>
1515
/// A collection of properties associated with the current OpenAPI element.
1616
/// </summary>
17-
IDictionary<string, object> Metadata { get; set; }
17+
IDictionary<string, object>? Metadata { get; set; }
1818
}
1919
}

src/Microsoft.OpenApi/Models/OpenApiReference.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) Microsoft Corporation. All rights reserved.
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
22
// Licensed under the MIT license.
33

44
using System;
@@ -92,8 +92,8 @@ public string? ReferenceV3
9292
{
9393
return Id;
9494
}
95-
if (Id.StartsWith("http://", StringComparison.OrdinalIgnoreCase) ||
96-
Id.StartsWith("https://", StringComparison.OrdinalIgnoreCase))
95+
if (!string.IsNullOrEmpty(Id) && Id is not null && Id.StartsWith("http://", StringComparison.OrdinalIgnoreCase) ||
96+
!string.IsNullOrEmpty(Id) && Id is not null && Id.StartsWith("https://", StringComparison.OrdinalIgnoreCase))
9797
{
9898
return Id;
9999
}

test/Microsoft.OpenApi.Hidi.Tests/Services/OpenApiFilterServiceTests.cs

Lines changed: 41 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) Microsoft Corporation. All rights reserved.
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
22
// Licensed under the MIT license.
33

44
using System.Globalization;
@@ -241,50 +241,53 @@ public async Task CopiesOverAllReferencedComponentsToTheSubsetDocumentCorrectly(
241241
var doc = (await OpenApiDocument.LoadAsync(stream, "yaml", settings)).Document;
242242

243243
// validated the tags are read as references
244-
var openApiOperationTags = doc.Paths["/items"].Operations[OperationType.Get].Tags?.ToArray();
244+
var openApiOperationTags = doc?.Paths["/items"].Operations?[OperationType.Get].Tags?.ToArray();
245245
Assert.NotNull(openApiOperationTags);
246246
Assert.Single(openApiOperationTags);
247247
Assert.True(openApiOperationTags[0].UnresolvedReference);
248248

249249
var predicate = OpenApiFilterService.CreatePredicate(operationIds: operationIds);
250-
var subsetOpenApiDocument = OpenApiFilterService.CreateFilteredDocument(doc, predicate);
251-
252-
var response = subsetOpenApiDocument.Paths["/items"].Operations?[OperationType.Get]?.Responses?["200"];
253-
var responseHeader = response?.Headers?["x-custom-header"];
254-
var mediaTypeExample = response?.Content?["application/json"]?.Examples?.First().Value;
255-
var targetHeaders = subsetOpenApiDocument.Components?.Headers;
256-
var targetExamples = subsetOpenApiDocument.Components?.Examples;
257-
258-
// Assert
259-
Assert.Same(doc.Servers, subsetOpenApiDocument.Servers);
260-
var headerReference = Assert.IsType<OpenApiHeaderReference>(responseHeader);
261-
Assert.False(headerReference.UnresolvedReference);
262-
var exampleReference = Assert.IsType<OpenApiExampleReference>(mediaTypeExample);
263-
Assert.False(exampleReference?.UnresolvedReference);
264-
Assert.NotNull(targetHeaders);
265-
Assert.Single(targetHeaders);
266-
Assert.NotNull(targetExamples);
267-
Assert.Single(targetExamples);
268-
// validated the tags of the trimmed document are read as references
269-
var trimmedOpenApiOperationTags = subsetOpenApiDocument.Paths["/items"].Operations[OperationType.Get].Tags?.ToArray();
270-
Assert.NotNull(trimmedOpenApiOperationTags);
271-
Assert.Single(trimmedOpenApiOperationTags);
272-
Assert.True(trimmedOpenApiOperationTags[0].UnresolvedReference);
273-
274-
// Finally try to write the trimmed document as v3 document
275-
var outputStringWriter = new StringWriter(CultureInfo.InvariantCulture);
276-
var writer = new OpenApiJsonWriter(outputStringWriter)
250+
if (doc is not null)
277251
{
278-
Settings = new OpenApiWriterSettings()
252+
var subsetOpenApiDocument = OpenApiFilterService.CreateFilteredDocument(doc, predicate);
253+
254+
var response = subsetOpenApiDocument.Paths["/items"].Operations?[OperationType.Get]?.Responses?["200"];
255+
var responseHeader = response?.Headers?["x-custom-header"];
256+
var mediaTypeExample = response?.Content?["application/json"]?.Examples?.First().Value;
257+
var targetHeaders = subsetOpenApiDocument.Components?.Headers;
258+
var targetExamples = subsetOpenApiDocument.Components?.Examples;
259+
260+
// Assert
261+
Assert.Same(doc.Servers, subsetOpenApiDocument.Servers);
262+
var headerReference = Assert.IsType<OpenApiHeaderReference>(responseHeader);
263+
Assert.False(headerReference.UnresolvedReference);
264+
var exampleReference = Assert.IsType<OpenApiExampleReference>(mediaTypeExample);
265+
Assert.False(exampleReference?.UnresolvedReference);
266+
Assert.NotNull(targetHeaders);
267+
Assert.Single(targetHeaders);
268+
Assert.NotNull(targetExamples);
269+
Assert.Single(targetExamples);
270+
// validated the tags of the trimmed document are read as references
271+
var trimmedOpenApiOperationTags = subsetOpenApiDocument.Paths["/items"].Operations?[OperationType.Get].Tags?.ToArray();
272+
Assert.NotNull(trimmedOpenApiOperationTags);
273+
Assert.Single(trimmedOpenApiOperationTags);
274+
Assert.True(trimmedOpenApiOperationTags[0].UnresolvedReference);
275+
276+
// Finally try to write the trimmed document as v3 document
277+
var outputStringWriter = new StringWriter(CultureInfo.InvariantCulture);
278+
var writer = new OpenApiJsonWriter(outputStringWriter)
279279
{
280-
InlineExternalReferences = true,
281-
InlineLocalReferences = true
282-
}
283-
};
284-
subsetOpenApiDocument.SerializeAsV3(writer);
285-
await writer.FlushAsync();
286-
var result = outputStringWriter.ToString();
287-
Assert.NotEmpty(result);
280+
Settings = new OpenApiWriterSettings()
281+
{
282+
InlineExternalReferences = true,
283+
InlineLocalReferences = true
284+
}
285+
};
286+
subsetOpenApiDocument.SerializeAsV3(writer);
287+
await writer.FlushAsync();
288+
var result = outputStringWriter.ToString();
289+
Assert.NotEmpty(result);
290+
}
288291
}
289292

290293
[Theory]

test/Microsoft.OpenApi.Tests/Models/OpenApiReferenceTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) Microsoft Corporation. All rights reserved.
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
22
// Licensed under the MIT license.
33

44
using System.Threading.Tasks;
@@ -45,7 +45,7 @@ public void SettingInternalReferenceForComponentsStyleReferenceShouldSucceed(
4545
[InlineData("Pet.yaml#/components/schemas/Pet", "Pet.yaml", "Pet", ReferenceType.Schema)]
4646
[InlineData("abc#/components/schemas/Pet", "abc", "Pet", ReferenceType.Schema)]
4747
[InlineData("abc#/components/schemas/HttpsValidationProblem", "abc", "HttpsValidationProblem", ReferenceType.Schema)]
48-
public void SettingExternalReferenceV3ShouldSucceed(string expected, string externalResource, string id, ReferenceType? type)
48+
public void SettingExternalReferenceV3ShouldSucceed(string expected, string externalResource, string id, ReferenceType type)
4949
{
5050
// Arrange & Act
5151
var reference = new OpenApiReference

test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ namespace Microsoft.OpenApi.Interfaces
200200
public interface IDiagnostic { }
201201
public interface IMetadataContainer
202202
{
203-
System.Collections.Generic.IDictionary<string, object> Metadata { get; set; }
203+
System.Collections.Generic.IDictionary<string, object>? Metadata { get; set; }
204204
}
205205
public interface IOpenApiElement { }
206206
public interface IOpenApiExtensible : Microsoft.OpenApi.Interfaces.IOpenApiElement

0 commit comments

Comments
 (0)