Skip to content

Commit

Permalink
Upgrade to Microsoft.OpenApi v2
Browse files Browse the repository at this point in the history
Upgrade to preview 5 of Microsoft.OpenApi v2.
Lots of tests are broken.
Also applies some refactorings in files that needed to be touched, but those will be extracted out and merged ahead of time where possible in a future PR.
  • Loading branch information
martincostello committed Feb 6, 2025
1 parent fcfcdd6 commit 94aad3e
Show file tree
Hide file tree
Showing 81 changed files with 943 additions and 914 deletions.
6 changes: 3 additions & 3 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,14 @@
<PackageVersion Include="Microsoft.AspNetCore.TestHost" Version="6.0.32" />
<PackageVersion Include="Microsoft.CodeAnalysis.PublicApiAnalyzers" Version="3.3.4" />
<PackageVersion Include="Microsoft.Extensions.FileProviders.Embedded" Version="2.1.0" />
<PackageVersion Include="Microsoft.OpenApi" Version="1.6.22" />
<PackageVersion Include="Microsoft.OpenApi.Readers" Version="1.6.22" />
<PackageVersion Include="Microsoft.OpenApi" Version="2.0.0-preview5" />
<PackageVersion Include="Microsoft.OpenApi.Readers" Version="2.0.0-preview5" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3" />
<PackageVersion Include="NSubstitute" Version="5.3.0" />
<PackageVersion Include="NSwag.MSBuild" Version="14.2.0" />
<PackageVersion Include="ReportGenerator" Version="5.4.1" />
<PackageVersion Include="System.Text.Json" Version="4.6.0" />
<PackageVersion Include="System.Text.Json" Version="8.0.5" />
<PackageVersion Include="Verify.Xunit" Version="28.3.2" />
<PackageVersion Include="xunit" Version="2.9.2" />
<PackageVersion Include="xunit.core" Version="2.9.2" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ public void Setup()
{
Schema = new()
{
Type = "string",
Type = JsonSchemaType.String,
Description = "schema-level description",
},
};
Expand All @@ -120,7 +120,7 @@ public void Setup()
{
Schema = new()
{
Type = "string",
Type = JsonSchemaType.String,
},
},
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,13 @@ private static void ApplySwaggerOperationAttribute(
if (swaggerOperationAttribute.OperationId != null)
operation.OperationId = swaggerOperationAttribute.OperationId;

if (swaggerOperationAttribute.Tags != null)
{
operation.Tags = swaggerOperationAttribute.Tags
.Select(tagName => new OpenApiTag { Name = tagName })
.ToList();
}
// TODO Fix this
////if (swaggerOperationAttribute.Tags != null)
////{
//// operation.Tags = swaggerOperationAttribute.Tags
//// .Select(tagName => new OpenApiTag { Name = tagName })
//// .ToList();
////}
}

public static void ApplySwaggerOperationFilterAttributes(
Expand Down
10 changes: 9 additions & 1 deletion src/Swashbuckle.AspNetCore.ApiTesting/ApiTestRunnerBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,20 @@
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.OpenApi.Models;
using Microsoft.OpenApi.Reader;
using Microsoft.OpenApi.Readers;
using Microsoft.OpenApi.Writers;

namespace Swashbuckle.AspNetCore.ApiTesting
{
public abstract class ApiTestRunnerBase : IDisposable
{
static ApiTestRunnerBase()
{
// TODO Make an assembly fixture
OpenApiReaderRegistry.RegisterReader(OpenApiConstants.Yaml, new OpenApiYamlReader());
}

private readonly ApiTestRunnerOptions _options;
private readonly RequestValidator _requestValidator;
private readonly ResponseValidator _responseValidator;
Expand Down Expand Up @@ -85,4 +93,4 @@ public void Dispose()
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using System;
using System.IO;
using Microsoft.OpenApi.Models;
using Microsoft.OpenApi.Readers;

namespace Swashbuckle.AspNetCore.ApiTesting
{
Expand All @@ -10,9 +9,12 @@ public static class ApiTestRunnerOptionsExtensions
public static void AddOpenApiFile(this ApiTestRunnerOptions options, string documentName, string filePath)
{
using var fileStream = File.OpenRead(filePath);
using var memoryStream = new MemoryStream();

var openApiDocument = new OpenApiStreamReader().Read(fileStream, out var diagnostic);
options.OpenApiDocs.Add(documentName, openApiDocument);
fileStream.CopyTo(memoryStream);

var result = OpenApiDocument.Load(memoryStream);
options.OpenApiDocs.Add(documentName, result.Document);
}

public static OpenApiDocument GetOpenApiDocument(this ApiTestRunnerOptions options, string documentName)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

namespace Swashbuckle.AspNetCore.ApiTesting
{
public class JsonContentValidator : IContentValidator
public sealed class JsonContentValidator : IContentValidator
{
private readonly JsonValidator _jsonValidator = new();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@

namespace Swashbuckle.AspNetCore.ApiTesting
{
public class JsonAllOfValidator(JsonValidator jsonValidator) : IJsonValidator
public sealed class JsonAllOfValidator(JsonValidator jsonValidator) : IJsonValidator
{
private JsonValidator _jsonValidator = jsonValidator;
private readonly JsonValidator _jsonValidator = jsonValidator;

public bool CanValidate(OpenApiSchema schema) => schema.AllOf != null && schema.AllOf.Any();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@

namespace Swashbuckle.AspNetCore.ApiTesting
{
public class JsonAnyOfValidator(JsonValidator jsonValidator) : IJsonValidator
public sealed class JsonAnyOfValidator(JsonValidator jsonValidator) : IJsonValidator
{
private JsonValidator _jsonValidator = jsonValidator;
private readonly JsonValidator _jsonValidator = jsonValidator;

public bool CanValidate(OpenApiSchema schema) => schema.AnyOf != null && schema.AnyOf.Any();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ public class JsonArrayValidator(IJsonValidator jsonValidator) : IJsonValidator
{
private readonly IJsonValidator _jsonValidator = jsonValidator;

public bool CanValidate(OpenApiSchema schema) => schema.Type == "array";
public bool CanValidate(OpenApiSchema schema) => schema.Type is JsonSchemaType.Array;

public bool Validate(
OpenApiSchema schema,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@

namespace Swashbuckle.AspNetCore.ApiTesting
{
public class JsonBooleanValidator : IJsonValidator
public sealed class JsonBooleanValidator : IJsonValidator
{
public bool CanValidate(OpenApiSchema schema) => schema.Type == "boolean";
public bool CanValidate(OpenApiSchema schema) => schema.Type is JsonSchemaType.Boolean;

public bool Validate(
OpenApiSchema schema,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@

namespace Swashbuckle.AspNetCore.ApiTesting
{
public class JsonNullValidator : IJsonValidator
public sealed class JsonNullValidator : IJsonValidator
{
public bool CanValidate(OpenApiSchema schema) => schema.Type == "null";
public bool CanValidate(OpenApiSchema schema) => schema.Type is JsonSchemaType.Null;

public bool Validate(
OpenApiSchema schema,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@

namespace Swashbuckle.AspNetCore.ApiTesting
{
public class JsonNumberValidator : IJsonValidator
public sealed class JsonNumberValidator : IJsonValidator
{
public bool CanValidate(OpenApiSchema schema) => schema.Type == "number";
public bool CanValidate(OpenApiSchema schema) => schema.Type is JsonSchemaType.Number;

public bool Validate(
OpenApiSchema schema,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@

namespace Swashbuckle.AspNetCore.ApiTesting
{
public class JsonObjectValidator(IJsonValidator jsonValidator) : IJsonValidator
public sealed class JsonObjectValidator(IJsonValidator jsonValidator) : IJsonValidator
{
private readonly IJsonValidator _jsonValidator = jsonValidator;

public bool CanValidate(OpenApiSchema schema) => schema.Type == "object";
public bool CanValidate(OpenApiSchema schema) => schema.Type is JsonSchemaType.Object;

public bool Validate(
OpenApiSchema schema,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

namespace Swashbuckle.AspNetCore.ApiTesting
{
public class JsonOneOfValidator(JsonValidator jsonValidator) : IJsonValidator
public sealed class JsonOneOfValidator(JsonValidator jsonValidator) : IJsonValidator
{
private readonly JsonValidator _jsonValidator = jsonValidator;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@

namespace Swashbuckle.AspNetCore.ApiTesting
{
public class JsonStringValidator : IJsonValidator
public sealed class JsonStringValidator : IJsonValidator
{
public bool CanValidate(OpenApiSchema schema) => schema.Type == "string";
public bool CanValidate(OpenApiSchema schema) => schema.Type is JsonSchemaType.String;

public bool Validate(
OpenApiSchema schema,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
using System.Collections.Generic;
using System.Linq;
using Microsoft.OpenApi.Models;
using Microsoft.OpenApi.Models.References;
using Newtonsoft.Json.Linq;

namespace Swashbuckle.AspNetCore.ApiTesting
{
public class JsonValidator : IJsonValidator
public sealed class JsonValidator : IJsonValidator
{
private readonly IEnumerable<IJsonValidator> _subValidators;

Expand Down Expand Up @@ -33,11 +34,17 @@ public bool Validate(
JToken instance,
out IEnumerable<string> errorMessages)
{
var errorMessagesList = new List<string>();

schema = schema.Reference != null
? (OpenApiSchema)openApiDocument.ResolveReference(schema.Reference)
? new OpenApiSchemaReference(schema.Reference.Id, openApiDocument)
: schema;

var errorMessagesList = new List<string>();
// TODO Why don't invalid references throw anymore?
if (schema.Reference != null && !openApiDocument.Components.Schemas.Any((p) => p.Key == schema.Reference.Id))
{
throw new System.InvalidOperationException($"Invalid Reference identifier '{schema.Reference.Id}'.");
}

foreach (var subValidator in _subValidators)
{
Expand Down
60 changes: 35 additions & 25 deletions src/Swashbuckle.AspNetCore.ApiTesting/OpenApiSchemaExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,45 +5,55 @@

namespace Swashbuckle.AspNetCore.ApiTesting
{
public static class OpenApiSchemaExtensions
internal static class OpenApiSchemaExtensions
{
internal static bool TryParse(this OpenApiSchema schema, string stringValue, out object typedValue)
{
typedValue = null;

if (schema.Type == "integer" && schema.Format == "int64" && long.TryParse(stringValue, out long longValue))
if (schema.Type is JsonSchemaType.Integer && schema.Format == "int64" && long.TryParse(stringValue, out long longValue))
{
typedValue = longValue;

else if (schema.Type == "integer" && int.TryParse(stringValue, out int intValue))
}
else if (schema.Type is JsonSchemaType.Integer && int.TryParse(stringValue, out int intValue))
{
typedValue = intValue;

else if (schema.Type == "number" && schema.Format == "double" && double.TryParse(stringValue, out double doubleValue))
}
else if (schema.Type is JsonSchemaType.Number && schema.Format == "double" && double.TryParse(stringValue, out double doubleValue))
{
typedValue = doubleValue;

else if (schema.Type == "number" && float.TryParse(stringValue, out float floatValue))
}
else if (schema.Type is JsonSchemaType.Number && float.TryParse(stringValue, out float floatValue))
{
typedValue = floatValue;

else if (schema.Type == "string" && schema.Format == "byte" && byte.TryParse(stringValue, out byte byteValue))
}
else if (schema.Type is JsonSchemaType.String && schema.Format == "byte" && byte.TryParse(stringValue, out byte byteValue))
{
typedValue = byteValue;

else if (schema.Type == "boolean" && bool.TryParse(stringValue, out bool boolValue))
}
else if (schema.Type is JsonSchemaType.Boolean && bool.TryParse(stringValue, out bool boolValue))
{
typedValue = boolValue;

else if (schema.Type == "string" && schema.Format == "date" && DateTime.TryParse(stringValue, out DateTime dateValue))
}
else if (schema.Type is JsonSchemaType.String && schema.Format == "date" && DateTime.TryParse(stringValue, out DateTime dateValue))
{
typedValue = dateValue;

else if (schema.Type == "string" && schema.Format == "date-time" && DateTime.TryParse(stringValue, out DateTime dateTimeValue))
}
else if (schema.Type is JsonSchemaType.String && schema.Format == "date-time" && DateTime.TryParse(stringValue, out DateTime dateTimeValue))
{
typedValue = dateTimeValue;

else if (schema.Type == "string" && schema.Format == "uuid" && Guid.TryParse(stringValue, out Guid uuidValue))
}
else if (schema.Type is JsonSchemaType.String && schema.Format == "uuid" && Guid.TryParse(stringValue, out Guid uuidValue))
{
typedValue = uuidValue;

else if (schema.Type == "string")
}
else if (schema.Type is JsonSchemaType.String)
{
typedValue = stringValue;

else if (schema.Type == "array")
}
else if (schema.Type is JsonSchemaType.Array)
{
var arrayValue = (schema.Items == null)
var arrayValue = schema.Items == null
? stringValue.Split(',')
: stringValue.Split(',').Select(itemStringValue =>
{
Expand All @@ -59,9 +69,9 @@ internal static bool TryParse(this OpenApiSchema schema, string stringValue, out

internal static string TypeIdentifier(this OpenApiSchema schema)
{
var idBuilder = new StringBuilder(schema.Type);
var idBuilder = new StringBuilder(schema.Type.ToString().ToLowerInvariant());

if (schema.Type == "array" && schema.Items != null)
if (schema.Type is JsonSchemaType.Array && schema.Items != null)
idBuilder.Append($"[{schema.Items.Type}]");

return idBuilder.ToString();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@ Swashbuckle.AspNetCore.ApiTesting.JsonValidator.CanValidate(Microsoft.OpenApi.Mo
Swashbuckle.AspNetCore.ApiTesting.JsonValidator.JsonValidator() -> void
Swashbuckle.AspNetCore.ApiTesting.JsonValidator.Validate(Microsoft.OpenApi.Models.OpenApiSchema schema, Microsoft.OpenApi.Models.OpenApiDocument openApiDocument, Newtonsoft.Json.Linq.JToken instance, out System.Collections.Generic.IEnumerable<string> errorMessages) -> bool
Swashbuckle.AspNetCore.ApiTesting.OpenApiDocumentExtensions
Swashbuckle.AspNetCore.ApiTesting.OpenApiSchemaExtensions
Swashbuckle.AspNetCore.ApiTesting.RequestDoesNotMatchSpecException
Swashbuckle.AspNetCore.ApiTesting.RequestDoesNotMatchSpecException.RequestDoesNotMatchSpecException(string message) -> void
Swashbuckle.AspNetCore.ApiTesting.RequestValidator
Expand Down
9 changes: 5 additions & 4 deletions src/Swashbuckle.AspNetCore.ApiTesting/RequestValidator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@
using Microsoft.AspNetCore.Routing;
using Microsoft.AspNetCore.Routing.Template;
using Microsoft.OpenApi.Models;
using Microsoft.OpenApi.Models.References;

namespace Swashbuckle.AspNetCore.ApiTesting
{
public class RequestValidator(IEnumerable<IContentValidator> contentValidators)
public sealed class RequestValidator(IEnumerable<IContentValidator> contentValidators)
{
private readonly IEnumerable<IContentValidator> _contentValidators = contentValidators;

Expand Down Expand Up @@ -60,7 +61,7 @@ private static IEnumerable<OpenApiParameter> ExpandParameterSpecs(
.Select(p =>
{
return p.Reference != null
? (OpenApiParameter)openApiDocument.ResolveReference(p.Reference)
? new OpenApiParameterReference(p.Reference.Id, openApiDocument)
: p;
});
}
Expand Down Expand Up @@ -113,7 +114,7 @@ private static void ValidateParameters(
}

var schema = (parameterSpec.Schema.Reference != null)
? (OpenApiSchema)openApiDocument.ResolveReference(parameterSpec.Schema.Reference)
? new OpenApiSchemaReference(parameterSpec.Schema.Reference.Id, openApiDocument)
: parameterSpec.Schema;

if (!schema.TryParse(value, out object typedValue))
Expand All @@ -126,7 +127,7 @@ private static void ValidateParameters(
private void ValidateContent(OpenApiRequestBody requestBodySpec, OpenApiDocument openApiDocument, HttpContent content)
{
requestBodySpec = requestBodySpec.Reference != null
? (OpenApiRequestBody)openApiDocument.ResolveReference(requestBodySpec.Reference)
? new OpenApiRequestBodyReference(requestBodySpec.Reference.Id, openApiDocument)
: requestBodySpec;

if (requestBodySpec.Required && content == null)
Expand Down
Loading

0 comments on commit 94aad3e

Please sign in to comment.