diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
index c5b4cab90..a7d83e3dc 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.md
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -10,8 +10,8 @@ assignees: ''
**Describe the bug**
A clear and concise description of what the bug is.
-**To Reproduce**
-Steps to reproduce the current behavior:
+**OpenApi File To Reproduce**
+Add the OpenApi file you're using or a link to it as well as the steps to reproduce the current behavior.
**Expected behavior**
A clear and concise description of what you expected to happen.
diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml
index 77dc8fd7b..95f001e1f 100644
--- a/.github/workflows/ci-cd.yml
+++ b/.github/workflows/ci-cd.yml
@@ -14,7 +14,7 @@ jobs:
GITHUB_RUN_NUMBER: ${{ github.run_number }}
steps:
- name: Setup .NET
- uses: actions/setup-dotnet@v3
+ uses: actions/setup-dotnet@v4
with:
dotnet-version: 7.0.x
diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
index f58bfa0c9..11c90f95b 100644
--- a/.github/workflows/codeql-analysis.yml
+++ b/.github/workflows/codeql-analysis.yml
@@ -17,7 +17,7 @@ jobs:
uses: actions/checkout@v4
- name: Setup .NET
- uses: actions/setup-dotnet@v3
+ uses: actions/setup-dotnet@v4
with:
dotnet-version: 7.0.x
diff --git a/.github/workflows/sonarcloud.yml b/.github/workflows/sonarcloud.yml
index c6b975ae5..5f12a604b 100644
--- a/.github/workflows/sonarcloud.yml
+++ b/.github/workflows/sonarcloud.yml
@@ -30,16 +30,16 @@ jobs:
runs-on: windows-latest
steps:
- name: Set up JDK 17
- uses: actions/setup-java@v3
+ uses: actions/setup-java@v4
with:
distribution: 'adopt'
java-version: 17
- name: Setup .NET 5 # At the moment the scanner requires dotnet 5 https://www.nuget.org/packages/dotnet-sonarscanner
- uses: actions/setup-dotnet@v3
+ uses: actions/setup-dotnet@v4
with:
dotnet-version: 5.0.x
- name: Setup .NET
- uses: actions/setup-dotnet@v3
+ uses: actions/setup-dotnet@v4
with:
dotnet-version: 7.0.x
- uses: actions/checkout@v4
diff --git a/docs/CI-CD_DOCUMENTATION.md b/docs/CI-CD_DOCUMENTATION.md
deleted file mode 100644
index 40053cf82..000000000
--- a/docs/CI-CD_DOCUMENTATION.md
+++ /dev/null
@@ -1,81 +0,0 @@
-# CI/CD documentation
-
-## 1. Run workflow manually
-
-1. Go to the project's GitHub repository and click on the **Actions** tab
-
-2. From the "Workflows" list on the left, click on "CI/CD Pipeline"
-
-3. On the right, next to the "This workflow has a workflow_dispatch event trigger" label, click on the "Run workflow" dropdown, make sure the default branch is selected (if not manually changed, should be main or master) in the "Use workflow from" dropdown and click the "Run workflow" button
-
-![Actions_workflow_dispatch](images/Actions_workflow_dispatch.png)
-
-NOTE: **screenshots are only exemplary**
-
-
-
-## 2. Automated NuGet publishing
-
-To setup the automated publishing to NuGet:
-
-1. Go to the repo **Settings** tab -> **Secrets**
-
-2. Add a secret with the name `NUGET_API_KEY` and as value use an API key from NuGet.org that is assigned to the packages for this project
-
-NOTE: the automated NuGet publishing is execute **only** when a release is triggered by the ["Automated versioning" feature](#3-automated-versioning)
-
-
-
-## 3. Automated versioning
-
-Automatically bumps up the GitHub tag in the repo and executes the CD job
-
-Note: **not every commit to your default branch creates a release**
-
-Follow these instructions for any commit (push or PR merge) to your default branch, you would like to execute the automated versioning.
-
-You would need one of three keywords at the start of your commit title. Each of the three keywords corresponds to a number in your release version i.e. v1.2.3. The release versioning uses the ["Conventional Commits" specification](https://www.conventionalcommits.org/en/v1.0.0/):
-
-- "fix: ..." - this keyword corresponds to the last number v1.2.**3**, also known as PATCH;
-- "feat: ..." - this keyword corresponds to the middle number v1.**2**.3, also known as MINOR;
-- "perf: ..." - this keyword corresponds to the first number v**1**.2.3, also known as MAJOR. In addition, to trigger a MAJOR release, you would need to write "BREAKING CHANGE: ..." in the description of the commit, with an empty line above it to indicate it is in the portion of the description;
-
-Note: when making a MAJOR release by committing through a terminal, use the multiple line syntax to add the commit title on one line and then adding an empty line, and then adding the "BREAKING CHANGE: " label
-
-
-#### Examples
-
-Example(fix/PATCH):
-`git commit -a -m "fix: this is a PATCH release triggering commit"`
-
-`git push origin vnext`
-
-Result: v1.2.3 -> **v1.2.4**
-
-
-
-Example(feat/MINOR):
-`git commit -a -m "feat: this is a MINOR release triggering commit"`
-
-`git push origin vnext`
-
-Result: v1.2.3 -> **v1.3.0**
-
-
-
-Example(perf/MAJOR):
-`` git commit -a -m "perf: this is a MAJOR release triggering commit ` ``
-
->>
->> `BREAKING CHANGE: this is the breaking change"`
-
-`git push origin vnext`
-
-Result: v1.2.3 -> **v2.0.0**
-
-
-Note: in the MAJOR release example, the PowerShell multiline syntax ` (backtick) is used. After writing a backtick, a press of the Enter key should open a new line.
-
-#
-
-Built with ❤ by [Pipeline Foundation](https://pipeline.foundation)
diff --git a/docs/images/Actions_workflow_dispatch.png b/docs/images/Actions_workflow_dispatch.png
deleted file mode 100644
index 279e39e0c..000000000
Binary files a/docs/images/Actions_workflow_dispatch.png and /dev/null differ
diff --git a/src/Microsoft.OpenApi.Hidi/Formatters/PowerShellFormatter.cs b/src/Microsoft.OpenApi.Hidi/Formatters/PowerShellFormatter.cs
index b7fe664c1..aab3fb829 100644
--- a/src/Microsoft.OpenApi.Hidi/Formatters/PowerShellFormatter.cs
+++ b/src/Microsoft.OpenApi.Hidi/Formatters/PowerShellFormatter.cs
@@ -44,8 +44,8 @@ static PowerShellFormatter()
// 6. Add AdditionalProperties to object schemas.
public override void Visit(ref JsonSchema schema)
- {
- AddAdditionalPropertiesToSchema(schema);
+ {
+ AddAdditionalPropertiesToSchema(ref schema);
schema = ResolveAnyOfSchema(ref schema);
schema = ResolveOneOfSchema(ref schema);
@@ -174,7 +174,7 @@ private static IList ResolveFunctionParameters(IListenable
hidi
./../../artifacts
- 1.3.5
+ 1.3.6
OpenAPI.NET CLI tool for slicing OpenAPI documents
true
@@ -34,8 +34,8 @@
-
-
+
+
diff --git a/src/Microsoft.OpenApi.Hidi/Utilities/SettingsUtilities.cs b/src/Microsoft.OpenApi.Hidi/Utilities/SettingsUtilities.cs
index 6ec32f488..f6798287a 100644
--- a/src/Microsoft.OpenApi.Hidi/Utilities/SettingsUtilities.cs
+++ b/src/Microsoft.OpenApi.Hidi/Utilities/SettingsUtilities.cs
@@ -1,6 +1,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
+using System.IO;
using Microsoft.Extensions.Configuration;
using Microsoft.OpenApi.OData;
@@ -11,15 +12,19 @@ internal static class SettingsUtilities
internal static IConfiguration GetConfiguration(string? settingsFile = null)
{
if (string.IsNullOrEmpty(settingsFile))
+ {
settingsFile = "appsettings.json";
+ }
+
+ var settingsFilePath = Path.Combine(Directory.GetCurrentDirectory(), settingsFile);
IConfiguration config = new ConfigurationBuilder()
- .AddJsonFile(settingsFile, true)
- .Build();
+ .AddJsonFile(settingsFilePath, true)
+ .Build();
return config;
}
-
+
internal static OpenApiConvertSettings GetOpenApiConvertSettings(IConfiguration config, string? metadataVersion)
{
if (config == null) { throw new System.ArgumentNullException(nameof(config)); }
diff --git a/src/Microsoft.OpenApi.Readers/Microsoft.OpenApi.Readers.csproj b/src/Microsoft.OpenApi.Readers/Microsoft.OpenApi.Readers.csproj
index 632cbf599..a18222a87 100644
--- a/src/Microsoft.OpenApi.Readers/Microsoft.OpenApi.Readers.csproj
+++ b/src/Microsoft.OpenApi.Readers/Microsoft.OpenApi.Readers.csproj
@@ -1,9 +1,9 @@
-
+
netstandard2.0
latest
true
- 1.6.10
+ 1.6.11
OpenAPI.NET Readers for JSON and YAML documents
true
@@ -21,7 +21,6 @@
-
diff --git a/src/Microsoft.OpenApi.Readers/ParseNodes/MapNode.cs b/src/Microsoft.OpenApi.Readers/ParseNodes/MapNode.cs
index f0cdea3fa..a26b35140 100644
--- a/src/Microsoft.OpenApi.Readers/ParseNodes/MapNode.cs
+++ b/src/Microsoft.OpenApi.Readers/ParseNodes/MapNode.cs
@@ -8,6 +8,7 @@
using System.Linq;
using System.Text.Json;
using System.Text.Json.Nodes;
+using Json.Schema;
using Microsoft.OpenApi.Any;
using Microsoft.OpenApi.Interfaces;
using Microsoft.OpenApi.Models;
@@ -123,6 +124,57 @@ public override Dictionary CreateMapWithReference(
return nodes.Where(n => n != default).ToDictionary(k => k.key, v => v.value);
}
+ public override Dictionary CreateJsonSchemaMapWithReference(
+ ReferenceType referenceType,
+ Func map,
+ OpenApiSpecVersion version)
+ {
+ var jsonMap = _node ?? throw new OpenApiReaderException($"Expected map while parsing {typeof(JsonSchema).Name}", Context);
+
+ var nodes = jsonMap.Select(
+ n =>
+ {
+ var key = n.Key;
+ (string key, JsonSchema value) entry;
+ try
+ {
+ Context.StartObject(key);
+ entry = (key,
+ value: map(new MapNode(Context, (JsonObject)n.Value))
+ );
+ if (entry.value == null)
+ {
+ return default; // Body Parameters shouldn't be converted to Parameters
+ }
+ // If the component isn't a reference to another component, then point it to itself.
+ if (entry.value.GetRef() == null)
+ {
+ var builder = new JsonSchemaBuilder();
+
+ // construct the Ref and append it to the builder
+ var reference = version == OpenApiSpecVersion.OpenApi2_0 ? string.Concat("#/definitions/", entry.key) :
+ string.Concat("#/components/schemas/", entry.key);
+
+ builder.Ref(reference);
+
+ // Append all the keywords in original schema to our new schema using a builder instance
+ foreach (var keyword in entry.value.Keywords)
+ {
+ builder.Add(keyword);
+ }
+ entry.value = builder.Build();
+ }
+ }
+ finally
+ {
+ Context.EndObject();
+ }
+ return entry;
+ }
+ );
+ return nodes.Where(n => n != default).ToDictionary(k => k.key, v => v.value);
+ }
+
public override Dictionary CreateSimpleMap(Func map)
{
var jsonMap = _node ?? throw new OpenApiReaderException($"Expected map while parsing {typeof(T).Name}", Context);
diff --git a/src/Microsoft.OpenApi.Readers/ParseNodes/ParseNode.cs b/src/Microsoft.OpenApi.Readers/ParseNodes/ParseNode.cs
index 8c9f992f3..bfdc7f3f0 100644
--- a/src/Microsoft.OpenApi.Readers/ParseNodes/ParseNode.cs
+++ b/src/Microsoft.OpenApi.Readers/ParseNodes/ParseNode.cs
@@ -1,9 +1,10 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
+// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
using System;
using System.Collections.Generic;
using System.Text.Json.Nodes;
+using Json.Schema;
using Microsoft.OpenApi.Any;
using Microsoft.OpenApi.Interfaces;
using Microsoft.OpenApi.Models;
@@ -66,6 +67,14 @@ public virtual Dictionary CreateMapWithReference(
throw new OpenApiReaderException("Cannot create map from this reference.", Context);
}
+ public virtual Dictionary CreateJsonSchemaMapWithReference(
+ ReferenceType referenceType,
+ Func map,
+ OpenApiSpecVersion version)
+ {
+ throw new OpenApiReaderException("Cannot create map from this reference.", Context);
+ }
+
public virtual List CreateSimpleList(Func map)
{
throw new OpenApiReaderException("Cannot create simple list from this type of node.", Context);
diff --git a/src/Microsoft.OpenApi.Readers/ParseNodes/ParserHelper.cs b/src/Microsoft.OpenApi.Readers/ParseNodes/ParserHelper.cs
new file mode 100644
index 000000000..9dd05ebdd
--- /dev/null
+++ b/src/Microsoft.OpenApi.Readers/ParseNodes/ParserHelper.cs
@@ -0,0 +1,35 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT license.
+
+using System;
+using System.Globalization;
+
+namespace Microsoft.OpenApi.Readers.ParseNodes
+{
+ ///
+ /// Useful tools to parse data
+ ///
+ internal class ParserHelper
+ {
+ ///
+ /// Parses decimal in invariant culture.
+ /// If the decimal is too big or small, it returns the default value
+ ///
+ /// Note: sometimes developers put Double.MaxValue or Long.MaxValue as min/max values for numbers in json schema even if their numbers are not expected to be that big/small.
+ /// As we have already released the library with Decimal type for Max/Min, let's not introduce the breaking change and just fallback to Decimal.Max / Min. This should satisfy almost every scenario.
+ /// We can revisit this if somebody really needs to have double or long here.
+ ///
+ ///
+ public static decimal ParseDecimalWithFallbackOnOverflow(string value, decimal defaultValue)
+ {
+ try
+ {
+ return decimal.Parse(value, NumberStyles.Float, CultureInfo.InvariantCulture);
+ }
+ catch (OverflowException)
+ {
+ return defaultValue;
+ }
+ }
+ }
+}
diff --git a/src/Microsoft.OpenApi.Readers/V2/OpenApiDocumentDeserializer.cs b/src/Microsoft.OpenApi.Readers/V2/OpenApiDocumentDeserializer.cs
index 9430e5d84..97c194098 100644
--- a/src/Microsoft.OpenApi.Readers/V2/OpenApiDocumentDeserializer.cs
+++ b/src/Microsoft.OpenApi.Readers/V2/OpenApiDocumentDeserializer.cs
@@ -59,12 +59,8 @@ internal static partial class OpenApiV2Deserializer
"definitions",
(o, n) =>
{
- if (o.Components == null)
- {
- o.Components = new();
- }
-
- o.Components.Schemas = n.CreateMap(LoadSchema);
+ o.Components ??= new();
+ o.Components.Schemas = n.CreateJsonSchemaMapWithReference(ReferenceType.Schema, LoadSchema, OpenApiSpecVersion.OpenApi2_0);
}
},
{
diff --git a/src/Microsoft.OpenApi.Readers/V2/OpenApiHeaderDeserializer.cs b/src/Microsoft.OpenApi.Readers/V2/OpenApiHeaderDeserializer.cs
index e4c177a0b..4d73cf4ef 100644
--- a/src/Microsoft.OpenApi.Readers/V2/OpenApiHeaderDeserializer.cs
+++ b/src/Microsoft.OpenApi.Readers/V2/OpenApiHeaderDeserializer.cs
@@ -1,4 +1,4 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
+// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
using System;
diff --git a/src/Microsoft.OpenApi.Readers/V3/JsonSchemaDeserializer.cs b/src/Microsoft.OpenApi.Readers/V3/JsonSchemaDeserializer.cs
index 4f5796155..2621d3729 100644
--- a/src/Microsoft.OpenApi.Readers/V3/JsonSchemaDeserializer.cs
+++ b/src/Microsoft.OpenApi.Readers/V3/JsonSchemaDeserializer.cs
@@ -1,13 +1,11 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
-using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text.Json.Nodes;
using Json.Schema;
using Json.Schema.OpenApi;
-using Microsoft.OpenApi.Any;
using Microsoft.OpenApi.Interfaces;
using Microsoft.OpenApi.Models;
using Microsoft.OpenApi.Extensions;
diff --git a/src/Microsoft.OpenApi.Readers/V3/OpenApiComponentsDeserializer.cs b/src/Microsoft.OpenApi.Readers/V3/OpenApiComponentsDeserializer.cs
index b6296064d..53790ac5f 100644
--- a/src/Microsoft.OpenApi.Readers/V3/OpenApiComponentsDeserializer.cs
+++ b/src/Microsoft.OpenApi.Readers/V3/OpenApiComponentsDeserializer.cs
@@ -20,7 +20,7 @@ internal static partial class OpenApiV3Deserializer
{
private static readonly FixedFieldMap _componentsFixedFields = new()
{
- {"schemas", (o, n) => o.Schemas = n.CreateMap(LoadSchema)},
+ {"schemas", (o, n) => o.Schemas = n.CreateJsonSchemaMapWithReference(ReferenceType.Schema, LoadSchema, OpenApiSpecVersion.OpenApi3_0)},
{"responses", (o, n) => o.Responses = n.CreateMapWithReference(ReferenceType.Response, LoadResponse)},
{"parameters", (o, n) => o.Parameters = n.CreateMapWithReference(ReferenceType.Parameter, LoadParameter)},
{"examples", (o, n) => o.Examples = n.CreateMapWithReference(ReferenceType.Example, LoadExample)},
diff --git a/src/Microsoft.OpenApi.Readers/V31/JsonSchemaDeserializer.cs b/src/Microsoft.OpenApi.Readers/V31/JsonSchemaDeserializer.cs
index b389860af..2b1972824 100644
--- a/src/Microsoft.OpenApi.Readers/V31/JsonSchemaDeserializer.cs
+++ b/src/Microsoft.OpenApi.Readers/V31/JsonSchemaDeserializer.cs
@@ -1,9 +1,13 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
-using System.Text.Json;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Text.Json.Nodes;
using Json.Schema;
+using Json.Schema.OpenApi;
using Microsoft.OpenApi.Extensions;
+using Microsoft.OpenApi.Interfaces;
using Microsoft.OpenApi.Models;
using Microsoft.OpenApi.Readers.ParseNodes;
using JsonSchema = Json.Schema.JsonSchema;
@@ -15,20 +19,259 @@ namespace Microsoft.OpenApi.Readers.V31
/// runtime Open API object model.
///
internal static partial class OpenApiV31Deserializer
- {
+ {
+ private static readonly FixedFieldMap _schemaFixedFields = new()
+ {
+ {
+ "title", (o, n) =>
+ {
+ o.Title(n.GetScalarValue());
+ }
+ },
+ {
+ "multipleOf", (o, n) =>
+ {
+ o.MultipleOf(decimal.Parse(n.GetScalarValue(), NumberStyles.Float, CultureInfo.InvariantCulture));
+ }
+ },
+ {
+ "maximum", (o, n) =>
+ {
+ o.Maximum(decimal.Parse(n.GetScalarValue(), NumberStyles.Float, CultureInfo.InvariantCulture));
+ }
+ },
+ {
+ "exclusiveMaximum", (o, n) =>
+ {
+ o.ExclusiveMaximum(decimal.Parse(n.GetScalarValue(), NumberStyles.Float, CultureInfo.InvariantCulture));
+ }
+ },
+ {
+ "minimum", (o, n) =>
+ {
+ o.Minimum(decimal.Parse(n.GetScalarValue(), NumberStyles.Float, CultureInfo.InvariantCulture));
+ }
+ },
+ {
+ "exclusiveMinimum", (o, n) =>
+ {
+ o.ExclusiveMinimum(decimal.Parse(n.GetScalarValue(), NumberStyles.Float, CultureInfo.InvariantCulture));
+ }
+ },
+ {
+ "maxLength", (o, n) =>
+ {
+ o.MaxLength(uint.Parse(n.GetScalarValue(), CultureInfo.InvariantCulture));
+ }
+ },
+ {
+ "minLength", (o, n) =>
+ {
+ o.MinLength(uint.Parse(n.GetScalarValue(), CultureInfo.InvariantCulture));
+ }
+ },
+ {
+ "pattern", (o, n) =>
+ {
+ o.Pattern(n.GetScalarValue());
+ }
+ },
+ {
+ "maxItems", (o, n) =>
+ {
+ o.MaxItems(uint.Parse(n.GetScalarValue(), CultureInfo.InvariantCulture));
+ }
+ },
+ {
+ "minItems", (o, n) =>
+ {
+ o.MinItems(uint.Parse(n.GetScalarValue(), CultureInfo.InvariantCulture));
+ }
+ },
+ {
+ "uniqueItems", (o, n) =>
+ {
+ o.UniqueItems(bool.Parse(n.GetScalarValue()));
+ }
+ },
+ {
+ "maxProperties", (o, n) =>
+ {
+ o.MaxProperties(uint.Parse(n.GetScalarValue(), CultureInfo.InvariantCulture));
+ }
+ },
+ {
+ "minProperties", (o, n) =>
+ {
+ o.MinProperties(uint.Parse(n.GetScalarValue(), CultureInfo.InvariantCulture));
+ }
+ },
+ {
+ "required", (o, n) =>
+ {
+ o.Required(new HashSet(n.CreateSimpleList(n2 => n2.GetScalarValue())));
+ }
+ },
+ {
+ "enum", (o, n) =>
+ {
+ o.Enum(n.CreateListOfAny());
+ }
+ },
+ {
+ "type", (o, n) =>
+ {
+ if(n is ListNode)
+ {
+ o.Type(n.CreateSimpleList(s => SchemaTypeConverter.ConvertToSchemaValueType(s.GetScalarValue())));
+ }
+ else
+ {
+ o.Type(SchemaTypeConverter.ConvertToSchemaValueType(n.GetScalarValue()));
+ }
+ }
+ },
+ {
+ "allOf", (o, n) =>
+ {
+ o.AllOf(n.CreateList(LoadSchema));
+ }
+ },
+ {
+ "oneOf", (o, n) =>
+ {
+ o.OneOf(n.CreateList(LoadSchema));
+ }
+ },
+ {
+ "anyOf", (o, n) =>
+ {
+ o.AnyOf(n.CreateList(LoadSchema));
+ }
+ },
+ {
+ "not", (o, n) =>
+ {
+ o.Not(LoadSchema(n));
+ }
+ },
+ {
+ "items", (o, n) =>
+ {
+ o.Items(LoadSchema(n));
+ }
+ },
+ {
+ "properties", (o, n) =>
+ {
+ o.Properties(n.CreateMap(LoadSchema));
+ }
+ },
+ {
+ "additionalProperties", (o, n) =>
+ {
+ if (n is ValueNode)
+ {
+ o.AdditionalPropertiesAllowed(bool.Parse(n.GetScalarValue()));
+ }
+ else
+ {
+ o.AdditionalProperties(LoadSchema(n));
+ }
+ }
+ },
+ {
+ "description", (o, n) =>
+ {
+ o.Description(n.GetScalarValue());
+ }
+ },
+ {
+ "format", (o, n) =>
+ {
+ o.Format(n.GetScalarValue());
+ }
+ },
+ {
+ "default", (o, n) =>
+ {
+ o.Default(n.CreateAny().Node);
+ }
+ },
+ {
+ "discriminator", (o, n) =>
+ {
+ var discriminator = LoadDiscriminator(n);
+ o.Discriminator(discriminator);
+ }
+ },
+ {
+ "readOnly", (o, n) =>
+ {
+ o.ReadOnly(bool.Parse(n.GetScalarValue()));
+ }
+ },
+ {
+ "writeOnly", (o, n) =>
+ {
+ o.WriteOnly(bool.Parse(n.GetScalarValue()));
+ }
+ },
+ {
+ "xml", (o, n) =>
+ {
+ var xml = LoadXml(n);
+ o.Xml(xml.Namespace, xml.Name, xml.Prefix, xml.Attribute, xml.Wrapped,
+ (IReadOnlyDictionary)xml.Extensions);
+ }
+ },
+ {
+ "externalDocs", (o, n) =>
+ {
+ var externalDocs = LoadExternalDocs(n);
+ o.ExternalDocs(externalDocs.Url, externalDocs.Description,
+ (IReadOnlyDictionary)externalDocs.Extensions);
+ }
+ },
+ {
+ "example", (o, n) =>
+ {
+ o.Example(n.CreateAny().Node);
+ }
+ },
+ {
+ "examples", (o, n) =>
+ {
+ o.Examples(n.CreateSimpleList(s => (JsonNode)s.GetScalarValue()));
+ }
+ },
+ {
+ "deprecated", (o, n) =>
+ {
+ o.Deprecated(bool.Parse(n.GetScalarValue()));
+ }
+ },
+ };
+
+ private static readonly PatternFieldMap _schemaPatternFields = new PatternFieldMap
+ {
+ {s => s.StartsWith("x-"), (o, p, n) => o.Extensions(LoadExtensions(p, LoadExtension(p, n)))}
+ };
+
public static JsonSchema LoadSchema(ParseNode node)
{
var mapNode = node.CheckMapNode(OpenApiConstants.Schema);
var builder = new JsonSchemaBuilder();
// check for a $ref and if present, add it to the builder as a Ref keyword
- if (mapNode.GetReferencePointer() is {} pointer)
+ var pointer = mapNode.GetReferencePointer();
+ if (pointer != null)
{
builder = builder.Ref(pointer);
// Check for summary and description and append to builder
var summary = mapNode.GetSummaryValue();
- var description = mapNode.GetDescriptionValue();
+ var description = mapNode.GetDescriptionValue();
if (!string.IsNullOrEmpty(summary))
{
builder.Summary(summary);
@@ -40,10 +283,23 @@ public static JsonSchema LoadSchema(ParseNode node)
return builder.Build();
}
- else
+
+ foreach (var propertyNode in mapNode)
{
- return node.JsonNode.Deserialize();
+ propertyNode.ParseField(builder, _schemaFixedFields, _schemaPatternFields);
}
+
+ var schema = builder.Build();
+ return schema;
+ }
+
+ private static Dictionary LoadExtensions(string value, IOpenApiExtension extension)
+ {
+ var extensions = new Dictionary
+ {
+ { value, extension }
+ };
+ return extensions;
}
}
diff --git a/src/Microsoft.OpenApi/Extensions/JsonSchemaBuilderExtensions.cs b/src/Microsoft.OpenApi/Extensions/JsonSchemaBuilderExtensions.cs
index 92738f66c..65d7409c3 100644
--- a/src/Microsoft.OpenApi/Extensions/JsonSchemaBuilderExtensions.cs
+++ b/src/Microsoft.OpenApi/Extensions/JsonSchemaBuilderExtensions.cs
@@ -1,4 +1,4 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
+// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
using System;
@@ -15,8 +15,6 @@ namespace Microsoft.OpenApi.Extensions
///
public static class JsonSchemaBuilderExtensions
{
- private static readonly Dictionary _keywords = new Dictionary();
-
///
/// Custom extensions in the schema
///
@@ -114,25 +112,6 @@ public static JsonSchemaBuilder OpenApiExternalDocs(this JsonSchemaBuilder build
return builder;
}
- ///
- /// Removes a keyword from the builder instance
- ///
- ///
- ///
- ///
- public static JsonSchemaBuilder RemoveKeyWord(this JsonSchemaBuilder builder, IJsonSchemaKeyword keyWord)
- {
- var schema = builder.Build();
- var newKeyWords = new List();
- newKeyWords = schema.Keywords.Where(x => !x.Equals(keyWord)).ToList();
- foreach (var item in newKeyWords)
- {
- builder.Add(item);
- }
-
- return builder;
- }
-
///
/// Removes a keyword
///
@@ -155,7 +134,6 @@ public static JsonSchemaBuilder Remove(this JsonSchemaBuilder builder, string ke
}
}
- //_keywords.Remove(keyword);
return schemaBuilder;
}
}
diff --git a/src/Microsoft.OpenApi/Extensions/JsonSchemaExtensions.cs b/src/Microsoft.OpenApi/Extensions/JsonSchemaExtensions.cs
index 1e70021de..6c0545fc3 100644
--- a/src/Microsoft.OpenApi/Extensions/JsonSchemaExtensions.cs
+++ b/src/Microsoft.OpenApi/Extensions/JsonSchemaExtensions.cs
@@ -84,6 +84,6 @@ public static string GetSummary(this JsonSchema schema)
public static IDictionary GetExtensions(this JsonSchema schema)
{
return schema.TryGetKeyword(ExtensionsKeyword.Name, out var k) ? k.Extensions! : null;
- }
+ }
}
}
diff --git a/src/Microsoft.OpenApi/Helpers/SchemaSerializerHelper.cs b/src/Microsoft.OpenApi/Helpers/SchemaSerializerHelper.cs
index ae0ffd52b..62a677432 100644
--- a/src/Microsoft.OpenApi/Helpers/SchemaSerializerHelper.cs
+++ b/src/Microsoft.OpenApi/Helpers/SchemaSerializerHelper.cs
@@ -13,13 +13,12 @@ namespace Microsoft.OpenApi.Helpers
{
internal static class SchemaSerializerHelper
{
- internal static void WriteAsItemsProperties(JsonSchema schema, IOpenApiWriter writer, IDictionary extensions)
+ internal static void WriteAsItemsProperties(JsonSchema schema,
+ IOpenApiWriter writer,
+ IDictionary extensions,
+ OpenApiSpecVersion version)
{
- if (writer == null)
- {
- Utils.CheckArgumentNull(writer);
- }
-
+ Utils.CheckArgumentNull(writer);
// type
if (schema.GetJsonType() != null)
{
@@ -39,7 +38,7 @@ internal static void WriteAsItemsProperties(JsonSchema schema, IOpenApiWriter wr
// items
writer.WriteOptionalObject(OpenApiConstants.Items, schema.GetItems(),
- (w, s) => w.WriteJsonSchema(s));
+ (w, s) => w.WriteJsonSchema(s, version));
// collectionFormat
// We need information from style in parameter to populate this.
@@ -96,7 +95,7 @@ internal static void WriteAsItemsProperties(JsonSchema schema, IOpenApiWriter wr
// extensions
writer.WriteExtensions(extensions, OpenApiSpecVersion.OpenApi2_0);
}
-
+
private static string RetrieveFormatFromNestedSchema(IReadOnlyCollection schema)
{
if (schema != null)
diff --git a/src/Microsoft.OpenApi/Microsoft.OpenApi.csproj b/src/Microsoft.OpenApi/Microsoft.OpenApi.csproj
index c81ff50b3..b5db340ba 100644
--- a/src/Microsoft.OpenApi/Microsoft.OpenApi.csproj
+++ b/src/Microsoft.OpenApi/Microsoft.OpenApi.csproj
@@ -3,7 +3,7 @@
netstandard2.0
Latest
true
- 1.6.10
+ 1.6.11
.NET models with JSON and YAML writers for OpenAPI specification
true
diff --git a/src/Microsoft.OpenApi/Models/OpenApiComponents.cs b/src/Microsoft.OpenApi/Models/OpenApiComponents.cs
index 2d96e3327..4af4248ab 100644
--- a/src/Microsoft.OpenApi/Models/OpenApiComponents.cs
+++ b/src/Microsoft.OpenApi/Models/OpenApiComponents.cs
@@ -109,7 +109,7 @@ public void SerializeAsV31(IOpenApiWriter writer)
// however if they have cycles, then we will need a component rendered
if (writer.GetSettings().InlineLocalReferences)
{
- RenderComponents(writer);
+ RenderComponents(writer, OpenApiSpecVersion.OpenApi3_1);
return;
}
@@ -149,7 +149,7 @@ public void SerializeAsV3(IOpenApiWriter writer)
// however if they have cycles, then we will need a component rendered
if (writer.GetSettings().InlineLocalReferences)
{
- RenderComponents(writer);
+ RenderComponents(writer, OpenApiSpecVersion.OpenApi3_0);
return;
}
@@ -177,11 +177,11 @@ private void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version
if (reference != null &&
reference.OriginalString.Split('/').Last().Equals(key))
{
- w.WriteJsonSchemaWithoutReference(w, s);
+ w.WriteJsonSchemaWithoutReference(w, s, version);
}
else
{
- w.WriteJsonSchema(s);
+ w.WriteJsonSchema(s, version);
}
});
@@ -335,7 +335,7 @@ private void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version
writer.WriteEndObject();
}
- private void RenderComponents(IOpenApiWriter writer)
+ private void RenderComponents(IOpenApiWriter writer, OpenApiSpecVersion version)
{
var loops = writer.GetSettings().LoopDetector.Loops;
writer.WriteStartObject();
@@ -344,7 +344,7 @@ private void RenderComponents(IOpenApiWriter writer)
writer.WriteOptionalMap(
OpenApiConstants.Schemas,
Schemas,
- static (w, key, s) => { w.WriteJsonSchema(s); });
+ (w, key, s) => { w.WriteJsonSchema(s, version); });
}
writer.WriteEndObject();
}
diff --git a/src/Microsoft.OpenApi/Models/OpenApiDocument.cs b/src/Microsoft.OpenApi/Models/OpenApiDocument.cs
index c6e047ce0..f0c341f48 100644
--- a/src/Microsoft.OpenApi/Models/OpenApiDocument.cs
+++ b/src/Microsoft.OpenApi/Models/OpenApiDocument.cs
@@ -246,7 +246,7 @@ public void SerializeAsV2(IOpenApiWriter writer)
writer.WriteOptionalMap(
OpenApiConstants.Definitions,
openApiSchemas,
- (w, key, s) => w.WriteJsonSchema(s));
+ (w, key, s) => w.WriteJsonSchema(s, OpenApiSpecVersion.OpenApi2_0));
}
}
else
@@ -265,11 +265,11 @@ public void SerializeAsV2(IOpenApiWriter writer)
if (reference != null &&
reference.OriginalString.Split('/').Last().Equals(key))
{
- w.WriteJsonSchemaWithoutReference(w, s);
+ w.WriteJsonSchemaWithoutReference(w, s, OpenApiSpecVersion.OpenApi2_0);
}
else
{
- w.WriteJsonSchema(s);
+ w.WriteJsonSchema(s, OpenApiSpecVersion.OpenApi2_0);
}
});
}
diff --git a/src/Microsoft.OpenApi/Models/OpenApiHeader.cs b/src/Microsoft.OpenApi/Models/OpenApiHeader.cs
index c73d9433d..0b5c8dd92 100644
--- a/src/Microsoft.OpenApi/Models/OpenApiHeader.cs
+++ b/src/Microsoft.OpenApi/Models/OpenApiHeader.cs
@@ -1,4 +1,4 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
+// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
using System;
@@ -225,7 +225,7 @@ internal virtual void SerializeInternalWithoutReference(IOpenApiWriter writer, O
writer.WriteProperty(OpenApiConstants.AllowReserved, AllowReserved, false);
// schema
- writer.WriteOptionalObject(OpenApiConstants.Schema, Schema, (w, s) => writer.WriteJsonSchema(s));
+ writer.WriteOptionalObject(OpenApiConstants.Schema, Schema, (w, s) => writer.WriteJsonSchema(s, version));
// example
writer.WriteOptionalObject(OpenApiConstants.Example, Example, (w, s) => w.WriteAny(s));
@@ -295,7 +295,7 @@ public void SerializeAsV2WithoutReference(IOpenApiWriter writer)
writer.WriteProperty(OpenApiConstants.AllowReserved, AllowReserved, false);
// schema
- SchemaSerializerHelper.WriteAsItemsProperties(Schema, writer, Extensions);
+ SchemaSerializerHelper.WriteAsItemsProperties(Schema, writer, Extensions, OpenApiSpecVersion.OpenApi2_0);
// example
writer.WriteOptionalObject(OpenApiConstants.Example, Example, (w, s) => w.WriteAny(s));
diff --git a/src/Microsoft.OpenApi/Models/OpenApiMediaType.cs b/src/Microsoft.OpenApi/Models/OpenApiMediaType.cs
index e8aa58986..5d195e264 100644
--- a/src/Microsoft.OpenApi/Models/OpenApiMediaType.cs
+++ b/src/Microsoft.OpenApi/Models/OpenApiMediaType.cs
@@ -1,4 +1,4 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
+// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
using System;
@@ -97,7 +97,7 @@ private void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version
writer.WriteStartObject();
// schema
- writer.WriteOptionalObject(OpenApiConstants.Schema, Schema, (w, s) => writer.WriteJsonSchema(s));
+ writer.WriteOptionalObject(OpenApiConstants.Schema, Schema, (w, s) => writer.WriteJsonSchema(s, version));
// example
writer.WriteOptionalObject(OpenApiConstants.Example, Example, (w, e) => w.WriteAny(e));
diff --git a/src/Microsoft.OpenApi/Models/OpenApiParameter.cs b/src/Microsoft.OpenApi/Models/OpenApiParameter.cs
index 4fe85f1c0..3afae77e1 100644
--- a/src/Microsoft.OpenApi/Models/OpenApiParameter.cs
+++ b/src/Microsoft.OpenApi/Models/OpenApiParameter.cs
@@ -1,4 +1,4 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
+// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
using System;
@@ -291,7 +291,7 @@ internal virtual void SerializeInternalWithoutReference(IOpenApiWriter writer, O
if (Schema != null)
{
writer.WritePropertyName(OpenApiConstants.Schema);
- writer.WriteJsonSchema(Schema);
+ writer.WriteJsonSchema(Schema, version);
}
// example
@@ -371,7 +371,7 @@ public void SerializeAsV2WithoutReference(IOpenApiWriter writer)
// schema
if (this is OpenApiBodyParameter)
{
- writer.WriteOptionalObject(OpenApiConstants.Schema, Schema, (w, s) => writer.WriteJsonSchema(s));
+ writer.WriteOptionalObject(OpenApiConstants.Schema, Schema, (w, s) => writer.WriteJsonSchema(s, OpenApiSpecVersion.OpenApi2_0));
}
// In V2 parameter's type can't be a reference to a custom object schema or can't be of type object
// So in that case map the type as string.
@@ -400,7 +400,7 @@ public void SerializeAsV2WithoutReference(IOpenApiWriter writer)
// multipleOf
if (Schema != null)
{
- SchemaSerializerHelper.WriteAsItemsProperties(Schema, writer, Extensions);
+ SchemaSerializerHelper.WriteAsItemsProperties(Schema, writer, Extensions, OpenApiSpecVersion.OpenApi2_0);
var extensions = Schema.GetExtensions();
if (extensions != null)
{
diff --git a/src/Microsoft.OpenApi/Models/OpenApiResponse.cs b/src/Microsoft.OpenApi/Models/OpenApiResponse.cs
index 447b2fb1d..9aa136a77 100644
--- a/src/Microsoft.OpenApi/Models/OpenApiResponse.cs
+++ b/src/Microsoft.OpenApi/Models/OpenApiResponse.cs
@@ -1,13 +1,9 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
+// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
using System;
using System.Collections.Generic;
using System.Linq;
-using System.Text.Json;
-using System.Text.Json.Nodes;
-using Json.More;
-using Microsoft.OpenApi.Helpers;
using Microsoft.OpenApi.Interfaces;
using Microsoft.OpenApi.Writers;
@@ -215,7 +211,7 @@ public void SerializeAsV2WithoutReference(IOpenApiWriter writer)
if (mediatype.Value != null)
{
// schema
- writer.WriteOptionalObject(OpenApiConstants.Schema, mediatype.Value.Schema, (w, s) => writer.WriteJsonSchema(s));
+ writer.WriteOptionalObject(OpenApiConstants.Schema, mediatype.Value.Schema, (w, s) => writer.WriteJsonSchema(s, OpenApiSpecVersion.OpenApi2_0));
// examples
if (Content.Values.Any(m => m.Example != null))
diff --git a/src/Microsoft.OpenApi/Services/OpenApiReferenceResolver.cs b/src/Microsoft.OpenApi/Services/OpenApiReferenceResolver.cs
index d9849dd44..43f1b7877 100644
--- a/src/Microsoft.OpenApi/Services/OpenApiReferenceResolver.cs
+++ b/src/Microsoft.OpenApi/Services/OpenApiReferenceResolver.cs
@@ -1,4 +1,4 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
+// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
using System;
@@ -189,7 +189,7 @@ public override void Visit(IDictionary links)
{
ResolveMap(links);
}
-
+
///
/// Resolve all references used in a schem
///
@@ -200,17 +200,20 @@ public override void Visit(ref JsonSchema schema)
var description = schema.GetDescription();
var summary = schema.GetSummary();
- if (reference != null)
+ if (schema.Keywords.Count.Equals(1) && reference != null)
{
schema = ResolveJsonSchemaReference(reference, description, summary);
}
-
+
var builder = new JsonSchemaBuilder();
- foreach (var keyword in schema.Keywords)
+ if (schema?.Keywords is { } keywords)
{
- builder.Add(keyword);
+ foreach (var keyword in keywords)
+ {
+ builder.Add(keyword);
+ }
}
-
+
ResolveJsonSchema(schema.GetItems(), r => builder.Items(r));
ResolveJsonSchemaList((IList)schema.GetOneOf(), r => builder.OneOf(r));
ResolveJsonSchemaList((IList)schema.GetAllOf(), r => builder.AllOf(r));
@@ -277,7 +280,8 @@ public JsonSchema ResolveJsonSchemaReference(Uri reference, string description =
}
else
{
- return null;
+ var referenceId = reference.OriginalString.Split('/').LastOrDefault();
+ throw new OpenApiException(string.Format(Properties.SRResource.InvalidReferenceId, referenceId));
}
}
@@ -349,7 +353,7 @@ private void ResolveJsonSchemaList(IList list, Action Walk(item.Value, isComponent: true));
+ Walk(item.Key, () => components.Schemas[item.Key] = Walk(item.Value, isComponent: true));
}
}
});
@@ -498,8 +498,7 @@ internal void Walk(OpenApiPathItem pathItem, bool isComponent = false)
_visitor.Visit(pathItem);
- // The path may be a reference
- if (pathItem != null && !ProcessAsReference(pathItem))
+ if (pathItem != null)
{
Walk(OpenApiConstants.Parameters, () => Walk(pathItem.Parameters));
Walk(pathItem.Operations);
@@ -850,9 +849,20 @@ internal JsonSchema Walk(JsonSchema schema, bool isComponent = false)
{
Walk("properties", () =>
{
+ var props = new Dictionary();
+ var builder = new JsonSchemaBuilder();
+ foreach(var keyword in schema.Keywords)
+ {
+ builder.Add(keyword);
+ }
+
foreach (var item in schema.GetProperties())
{
- Walk(item.Key, () => Walk(item.Value));
+ var key = item.Key;
+ JsonSchema newSchema = null;
+ Walk(key, () => newSchema = Walk(item.Value));
+ props.Add(key, newSchema);
+ schema = builder.Properties(props);
}
});
}
@@ -1158,7 +1168,8 @@ private void Walk(string context, Action walk)
///
private bool ProcessAsReference(IOpenApiReferenceable referenceable, bool isComponent = false)
{
- var isReference = referenceable.Reference != null && !isComponent;
+ var isReference = referenceable.Reference != null &&
+ (!isComponent || referenceable.UnresolvedReference);
if (isReference)
{
Walk(referenceable);
diff --git a/src/Microsoft.OpenApi/Services/OpenApiWorkspace.cs b/src/Microsoft.OpenApi/Services/OpenApiWorkspace.cs
index 1abde0f89..63c1defaf 100644
--- a/src/Microsoft.OpenApi/Services/OpenApiWorkspace.cs
+++ b/src/Microsoft.OpenApi/Services/OpenApiWorkspace.cs
@@ -1,11 +1,10 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
+// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
-using Json.More;
using Json.Schema;
using Microsoft.OpenApi.Extensions;
using Microsoft.OpenApi.Interfaces;
diff --git a/src/Microsoft.OpenApi/Validations/Rules/JsonSchemaRules.cs b/src/Microsoft.OpenApi/Validations/Rules/JsonSchemaRules.cs
index a8efc0289..aa9f62ac1 100644
--- a/src/Microsoft.OpenApi/Validations/Rules/JsonSchemaRules.cs
+++ b/src/Microsoft.OpenApi/Validations/Rules/JsonSchemaRules.cs
@@ -34,6 +34,21 @@ public static class JsonSchemaRules
context.Exit();
+ // examples
+ context.Enter("examples");
+
+ if (jsonSchema.GetExamples() is { } examples)
+ {
+ for (int i = 0; i < examples.Count; i++)
+ {
+ context.Enter(i.ToString());
+ RuleHelpers.ValidateDataTypeMismatch(context, nameof(SchemaMismatchedDataType), examples.ElementAt(i), jsonSchema);
+ context.Exit();
+ }
+ }
+
+ context.Exit();
+
// example
context.Enter("example");
diff --git a/src/Microsoft.OpenApi/Validations/ValidationRule.cs b/src/Microsoft.OpenApi/Validations/ValidationRule.cs
index c59e0fc74..aa866734a 100644
--- a/src/Microsoft.OpenApi/Validations/ValidationRule.cs
+++ b/src/Microsoft.OpenApi/Validations/ValidationRule.cs
@@ -1,8 +1,7 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
+// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
using System;
-using System.Globalization;
using Microsoft.OpenApi.Interfaces;
using Microsoft.OpenApi.Properties;
diff --git a/src/Microsoft.OpenApi/Writers/IOpenApiWriter.cs b/src/Microsoft.OpenApi/Writers/IOpenApiWriter.cs
index 0c97f580b..88d4ae686 100644
--- a/src/Microsoft.OpenApi/Writers/IOpenApiWriter.cs
+++ b/src/Microsoft.OpenApi/Writers/IOpenApiWriter.cs
@@ -76,14 +76,16 @@ public interface IOpenApiWriter
/// Write the JsonSchema object
///
///
- void WriteJsonSchema(JsonSchema schema);
+ ///
+ void WriteJsonSchema(JsonSchema schema, OpenApiSpecVersion version);
///
/// Write the JsonSchema object
///
/// The IOpenApiWriter object
/// The JsonSchema object
- void WriteJsonSchemaWithoutReference(IOpenApiWriter writer, JsonSchema schema);
+ ///
+ void WriteJsonSchemaWithoutReference(IOpenApiWriter writer, JsonSchema schema, OpenApiSpecVersion version);
///
/// Flush the writer.
@@ -95,6 +97,7 @@ public interface IOpenApiWriter
///
///
///
- void WriteJsonSchemaReference(IOpenApiWriter writer, Uri reference);
+ ///
+ void WriteJsonSchemaReference(IOpenApiWriter writer, Uri reference, OpenApiSpecVersion version);
}
}
diff --git a/src/Microsoft.OpenApi/Writers/OpenApiWriterBase.cs b/src/Microsoft.OpenApi/Writers/OpenApiWriterBase.cs
index 335cba7af..ef5883711 100644
--- a/src/Microsoft.OpenApi/Writers/OpenApiWriterBase.cs
+++ b/src/Microsoft.OpenApi/Writers/OpenApiWriterBase.cs
@@ -1,4 +1,4 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
+// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
using System;
@@ -422,19 +422,20 @@ protected void VerifyCanWritePropertyName(string name)
/// Writes out a JsonSchema object
///
///
- public void WriteJsonSchema(JsonSchema schema)
+ ///
+ public void WriteJsonSchema(JsonSchema schema, OpenApiSpecVersion version)
{
if (schema == null)
{
return;
}
-
+
var reference = schema.GetRef();
if (reference != null)
{
if (!Settings.ShouldInlineReference())
{
- WriteJsonSchemaReference(this, reference);
+ WriteJsonSchemaReference(this, reference, version);
return;
}
else
@@ -446,13 +447,13 @@ public void WriteJsonSchema(JsonSchema schema)
if (!Settings.LoopDetector.PushLoop(schema))
{
Settings.LoopDetector.SaveLoop(schema);
- WriteJsonSchemaReference(this, reference);
+ WriteJsonSchemaReference(this, reference, version);
return;
}
}
}
- WriteJsonSchemaWithoutReference(this, schema);
+ WriteJsonSchemaWithoutReference(this, schema, version);
if (reference != null)
{
@@ -461,7 +462,7 @@ public void WriteJsonSchema(JsonSchema schema)
}
///
- public void WriteJsonSchemaWithoutReference(IOpenApiWriter writer, JsonSchema schema)
+ public void WriteJsonSchemaWithoutReference(IOpenApiWriter writer, JsonSchema schema, OpenApiSpecVersion version)
{
writer.WriteStartObject();
@@ -517,23 +518,23 @@ public void WriteJsonSchemaWithoutReference(IOpenApiWriter writer, JsonSchema sc
writer.WriteProperty(OpenApiConstants.Type, schema.GetJsonType()?.ToString().ToLowerInvariant());
// allOf
- writer.WriteOptionalCollection(OpenApiConstants.AllOf, schema.GetAllOf(), (w, s) => w.WriteJsonSchema(s));
+ writer.WriteOptionalCollection(OpenApiConstants.AllOf, schema.GetAllOf(), (w, s) => w.WriteJsonSchema(s, version));
// anyOf
- writer.WriteOptionalCollection(OpenApiConstants.AnyOf, schema.GetAnyOf(), (w, s) => w.WriteJsonSchema(s));
+ writer.WriteOptionalCollection(OpenApiConstants.AnyOf, schema.GetAnyOf(), (w, s) => w.WriteJsonSchema(s, version));
// oneOf
- writer.WriteOptionalCollection(OpenApiConstants.OneOf, schema.GetOneOf(), (w, s) => w.WriteJsonSchema(s));
+ writer.WriteOptionalCollection(OpenApiConstants.OneOf, schema.GetOneOf(), (w, s) => w.WriteJsonSchema(s, version));
// not
- writer.WriteOptionalObject(OpenApiConstants.Not, schema.GetNot(), (w, s) => w.WriteJsonSchema(s));
+ writer.WriteOptionalObject(OpenApiConstants.Not, schema.GetNot(), (w, s) => w.WriteJsonSchema(s, version));
// items
- writer.WriteOptionalObject(OpenApiConstants.Items, schema.GetItems(), (w, s) => w.WriteJsonSchema(s));
+ writer.WriteOptionalObject(OpenApiConstants.Items, schema.GetItems(), (w, s) => w.WriteJsonSchema(s, version));
// properties
writer.WriteOptionalMap(OpenApiConstants.Properties, (IDictionary)schema.GetProperties(),
- (w, key, s) => w.WriteJsonSchema(s));
+ (w, key, s) => w.WriteJsonSchema(s, version));
// additionalProperties
if (schema.GetAdditionalPropertiesAllowed() ?? false)
@@ -541,7 +542,7 @@ public void WriteJsonSchemaWithoutReference(IOpenApiWriter writer, JsonSchema sc
writer.WriteOptionalObject(
OpenApiConstants.AdditionalProperties,
schema.GetAdditionalProperties(),
- (w, s) => w.WriteJsonSchema(s));
+ (w, s) => w.WriteJsonSchema(s, version));
}
else
{
@@ -576,7 +577,10 @@ public void WriteJsonSchemaWithoutReference(IOpenApiWriter writer, JsonSchema sc
writer.WriteOptionalObject(OpenApiConstants.ExternalDocs, schema.GetExternalDocs(), (w, s) => JsonSerializer.Serialize(s));
// example
- writer.WriteOptionalObject(OpenApiConstants.Example, schema.GetExample(), (w, e) => w.WriteAny(new OpenApiAny(e)));
+ writer.WriteOptionalObject(OpenApiConstants.Example, schema.GetExample(), (w, s) => w.WriteAny(new OpenApiAny(s)));
+
+ // examples
+ writer.WriteOptionalCollection(OpenApiConstants.Examples, schema.GetExamples(), (n, e) => n.WriteAny(new OpenApiAny(e)));
// deprecated
writer.WriteProperty(OpenApiConstants.Deprecated, schema.GetDeprecated(), false);
@@ -588,10 +592,14 @@ public void WriteJsonSchemaWithoutReference(IOpenApiWriter writer, JsonSchema sc
}
///
- public void WriteJsonSchemaReference(IOpenApiWriter writer, Uri reference)
+ public void WriteJsonSchemaReference(IOpenApiWriter writer, Uri reference, OpenApiSpecVersion version)
{
- this.WriteStartObject();
- this.WriteProperty(OpenApiConstants.DollarRef, reference.OriginalString);
+ var referenceItem = version.Equals(OpenApiSpecVersion.OpenApi2_0)
+ ? reference.OriginalString.Replace("components/schemas", "definitions")
+ : reference.OriginalString;
+
+ WriteStartObject();
+ this.WriteProperty(OpenApiConstants.DollarRef, referenceItem);
WriteEndObject();
}
}
diff --git a/test/Microsoft.OpenApi.Hidi.Tests/Microsoft.OpenApi.Hidi.Tests.csproj b/test/Microsoft.OpenApi.Hidi.Tests/Microsoft.OpenApi.Hidi.Tests.csproj
index 8ea740315..6e0ca4ac2 100644
--- a/test/Microsoft.OpenApi.Hidi.Tests/Microsoft.OpenApi.Hidi.Tests.csproj
+++ b/test/Microsoft.OpenApi.Hidi.Tests/Microsoft.OpenApi.Hidi.Tests.csproj
@@ -13,9 +13,9 @@
-
-
-
+
+
+
diff --git a/test/Microsoft.OpenApi.Hidi.Tests/Services/OpenApiServiceTests.cs b/test/Microsoft.OpenApi.Hidi.Tests/Services/OpenApiServiceTests.cs
index 56063130f..b06e38d3f 100644
--- a/test/Microsoft.OpenApi.Hidi.Tests/Services/OpenApiServiceTests.cs
+++ b/test/Microsoft.OpenApi.Hidi.Tests/Services/OpenApiServiceTests.cs
@@ -186,24 +186,6 @@ public async Task TransformCommandConvertsOpenApiWithDefaultOutputName()
Assert.NotEmpty(output);
}
- [Fact]
- public async Task TransformCommandConvertsCsdlWithDefaultOutputName()
- {
- var options = new HidiOptions
- {
- Csdl = Path.Combine("UtilityFiles", "Todo.xml"),
- CleanOutput = true,
- TerseOutput = false,
- InlineLocal = false,
- InlineExternal = false,
- };
- // create a dummy ILogger instance for testing
- await OpenApiService.TransformOpenApiDocument(options, _logger);
-
- var output = await File.ReadAllTextAsync("output.yml");
- Assert.NotEmpty(output);
- }
-
[Fact]
public async Task TransformCommandConvertsOpenApiWithDefaultOutputNameAndSwitchFormat()
{
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 3fefc302d..4cdae8853 100644
--- a/test/Microsoft.OpenApi.Readers.Tests/Microsoft.OpenApi.Readers.Tests.csproj
+++ b/test/Microsoft.OpenApi.Readers.Tests/Microsoft.OpenApi.Readers.Tests.csproj
@@ -23,9 +23,8 @@
-
-
-
+
+
diff --git a/test/Microsoft.OpenApi.Readers.Tests/OpenApiReaderTests/OpenApiDiagnosticTests.cs b/test/Microsoft.OpenApi.Readers.Tests/OpenApiReaderTests/OpenApiDiagnosticTests.cs
index 7f7c34b26..be476652e 100644
--- a/test/Microsoft.OpenApi.Readers.Tests/OpenApiReaderTests/OpenApiDiagnosticTests.cs
+++ b/test/Microsoft.OpenApi.Readers.Tests/OpenApiReaderTests/OpenApiDiagnosticTests.cs
@@ -56,8 +56,11 @@ public async Task DiagnosticReportMergedForExternalReference()
Assert.NotNull(result);
Assert.NotNull(result.OpenApiDocument.Workspace);
Assert.True(result.OpenApiDocument.Workspace.Contains("TodoReference.yaml"));
- result.OpenApiDiagnostic.Errors.Should().BeEquivalentTo(new List {
- new( new OpenApiException("[File: ./TodoReference.yaml] Invalid Reference identifier 'object-not-existing'.")) });
+ result.OpenApiDiagnostic.Errors.Should().BeEquivalentTo(new List
+ {
+ new OpenApiError("", "[File: ./TodoReference.yaml] Paths is a REQUIRED field at #/"),
+ new(new OpenApiException("[File: ./TodoReference.yaml] Invalid Reference identifier 'object-not-existing'."))
+ });
}
}
diff --git a/test/Microsoft.OpenApi.Readers.Tests/OpenApiReaderTests/Samples/OpenApiDiagnosticReportMerged/TodoReference.yaml b/test/Microsoft.OpenApi.Readers.Tests/OpenApiReaderTests/Samples/OpenApiDiagnosticReportMerged/TodoReference.yaml
index db3958149..98cd3d40a 100644
--- a/test/Microsoft.OpenApi.Readers.Tests/OpenApiReaderTests/Samples/OpenApiDiagnosticReportMerged/TodoReference.yaml
+++ b/test/Microsoft.OpenApi.Readers.Tests/OpenApiReaderTests/Samples/OpenApiDiagnosticReportMerged/TodoReference.yaml
@@ -23,4 +23,4 @@ components:
type: object
properties:
id:
- type:string
\ No newline at end of file
+ type: string
\ No newline at end of file
diff --git a/test/Microsoft.OpenApi.Readers.Tests/ParseNodes/ParserHelperTests.cs b/test/Microsoft.OpenApi.Readers.Tests/ParseNodes/ParserHelperTests.cs
new file mode 100644
index 000000000..1368e103d
--- /dev/null
+++ b/test/Microsoft.OpenApi.Readers.Tests/ParseNodes/ParserHelperTests.cs
@@ -0,0 +1,25 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT license.
+
+using System.Globalization;
+using Microsoft.OpenApi.Readers.ParseNodes;
+using Xunit;
+
+namespace Microsoft.OpenApi.Readers.Tests.ParseNodes
+{
+ [Collection("DefaultSettings")]
+ public class ParserHelperTests
+ {
+ [Fact]
+ public void ParseDecimalWithFallbackOnOverflow_ReturnsParsedValue()
+ {
+ Assert.Equal(23434, ParserHelper.ParseDecimalWithFallbackOnOverflow("23434", 10));
+ }
+
+ [Fact]
+ public void ParseDecimalWithFallbackOnOverflow_Overflows_ReturnsFallback()
+ {
+ Assert.Equal(10, ParserHelper.ParseDecimalWithFallbackOnOverflow(double.MaxValue.ToString(CultureInfo.InvariantCulture), 10));
+ }
+ }
+}
diff --git a/test/Microsoft.OpenApi.Readers.Tests/ReferenceService/TryLoadReferenceV2Tests.cs b/test/Microsoft.OpenApi.Readers.Tests/ReferenceService/TryLoadReferenceV2Tests.cs
index dcf9c5d43..d9d4e0eb3 100644
--- a/test/Microsoft.OpenApi.Readers.Tests/ReferenceService/TryLoadReferenceV2Tests.cs
+++ b/test/Microsoft.OpenApi.Readers.Tests/ReferenceService/TryLoadReferenceV2Tests.cs
@@ -1,4 +1,4 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
+// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
using System.Collections.Generic;
@@ -159,6 +159,7 @@ public void LoadResponseAndSchemaReference()
["application/json"] = new()
{
Schema = new JsonSchemaBuilder()
+ .Ref("#/definitions/SampleObject2")
.Description("Sample description")
.Required("name")
.Properties(
diff --git a/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiDocumentTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiDocumentTests.cs
index 2abac53ff..692cd31fa 100644
--- a/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiDocumentTests.cs
+++ b/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiDocumentTests.cs
@@ -22,15 +22,12 @@ public void ShouldParseProducesInAnyOrder()
var reader = new OpenApiStreamReader();
var doc = reader.Read(stream, out var diagnostic);
- var successSchema = new JsonSchemaBuilder()
- .Type(SchemaValueType.Array)
- .Items(new JsonSchemaBuilder()
- .Ref("#/definitions/Item"));
-
var okSchema = new JsonSchemaBuilder()
+ .Ref("#/definitions/Item")
.Properties(("id", new JsonSchemaBuilder().Type(SchemaValueType.String).Description("Item identifier.")));
var errorSchema = new JsonSchemaBuilder()
+ .Ref("#/definitions/Error")
.Properties(("code", new JsonSchemaBuilder().Type(SchemaValueType.Integer).Format("int32")),
("message", new JsonSchemaBuilder().Type(SchemaValueType.String)),
("fields", new JsonSchemaBuilder().Type(SchemaValueType.String)));
@@ -165,10 +162,12 @@ public void ShouldAssignSchemaToAllResponses()
var successSchema = new JsonSchemaBuilder()
.Type(SchemaValueType.Array)
.Items(new JsonSchemaBuilder()
+ .Ref("#/definitions/Item")
.Properties(("id", new JsonSchemaBuilder().Type(SchemaValueType.String).Description("Item identifier."))))
.Build();
var errorSchema = new JsonSchemaBuilder()
+ .Ref("#/definitions/Error")
.Properties(("code", new JsonSchemaBuilder().Type(SchemaValueType.Integer).Format("int32")),
("message", new JsonSchemaBuilder().Type(SchemaValueType.String)),
("fields", new JsonSchemaBuilder().Type(SchemaValueType.String)))
@@ -201,7 +200,7 @@ public void ShouldAllowComponentsThatJustContainAReference()
JsonSchema schema = doc.Components.Schemas["AllPets"];
// Assert
- if (schema.GetRef() != null)
+ if (schema.Keywords.Count.Equals(1) && schema.GetRef() != null)
{
// detected a cycle - this code gets triggered
Assert.Fail("A cycle should not be detected");
diff --git a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiDocumentTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiDocumentTests.cs
index 89100c4aa..c257a558e 100644
--- a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiDocumentTests.cs
+++ b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiDocumentTests.cs
@@ -7,7 +7,6 @@
using Microsoft.OpenApi.Models;
using Microsoft.OpenApi.Writers;
using Xunit;
-using static System.Net.Mime.MediaTypeNames;
namespace Microsoft.OpenApi.Readers.Tests.V31Tests
{
@@ -70,8 +69,8 @@ public void ParseDocumentWithWebhooksShouldSucceed()
{
Schemas =
{
- ["pet1"] = petSchema,
- ["newPet"] = newPetSchema
+ ["petSchema"] = petSchema,
+ ["newPetSchema"] = newPetSchema
}
};
@@ -199,7 +198,7 @@ public void ParseDocumentsWithReusablePathItemInWebhooksSucceeds()
("id", new JsonSchemaBuilder().Type(SchemaValueType.Integer).Format("int64")),
("name", new JsonSchemaBuilder().Type(SchemaValueType.String)),
("tag", new JsonSchemaBuilder().Type(SchemaValueType.String))),
- ["newPet"] = new JsonSchemaBuilder()
+ ["newPetSchema"] = new JsonSchemaBuilder()
.Type(SchemaValueType.Object)
.Required("name")
.Properties(
@@ -211,7 +210,7 @@ public void ParseDocumentsWithReusablePathItemInWebhooksSucceeds()
// Create a clone of the schema to avoid modifying things in components.
var petSchema = components.Schemas["petSchema"];
- var newPetSchema = components.Schemas["newPet"];
+ var newPetSchema = components.Schemas["newPetSchema"];
components.PathItems = new Dictionary
{
@@ -333,14 +332,10 @@ public void ParseDocumentWithDescriptionInDollarRefsShouldSucceed()
// Act
var actual = new OpenApiStreamReader().Read(stream, out var diagnostic);
- var schema = actual.Paths["/pets"].Operations[OperationType.Get].Responses["200"].Content["application/json"].Schema;
var header = actual.Components.Responses["Test"].Headers["X-Test"];
// Assert
Assert.True(header.Description == "A referenced X-Test header"); /*response header #ref's description overrides the header's description*/
- Assert.Null(schema.GetRef());
- Assert.Equal(SchemaValueType.Object, schema.GetJsonType());
- Assert.Equal("A pet in a petstore", schema.GetDescription()); /*The reference object's description overrides that of the referenced component*/
}
[Fact]
diff --git a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/Samples/OpenApiDocument/docWithExample.yaml b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/Samples/OpenApiDocument/docWithExample.yaml
index 51ffd38b3..44ede6301 100644
--- a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/Samples/OpenApiDocument/docWithExample.yaml
+++ b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/Samples/OpenApiDocument/docWithExample.yaml
@@ -61,21 +61,10 @@ paths: # The available paths and operations for the API
properties:
message: # A property for the confirmation message
type: string
- example: File uploaded successfully
+ examples:
+ - The file was uploaded successfully
components: # Reusable components for the API
schemas: # JSON Schema definitions for the API
- User: # A schema for a user object
- $id: http://example.com/schemas/user # The identifier for the schema
- type: object
- properties:
- name: # A property for the user name
- type: string
- default: "John Doe" # The default value for the user name
- age: # A property for the user age
- type: integer
- minimum: 0
- default: 18 # The default value for the user age
- unevaluatedProperties: false # No additional properties are allowed
Pet: # A schema for a pet object
type: object
required:
diff --git a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/Samples/OpenApiDocument/documentWithReusablePaths.yaml b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/Samples/OpenApiDocument/documentWithReusablePaths.yaml
index f9327910b..33cf7301e 100644
--- a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/Samples/OpenApiDocument/documentWithReusablePaths.yaml
+++ b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/Samples/OpenApiDocument/documentWithReusablePaths.yaml
@@ -21,7 +21,7 @@ components:
type: string
tag:
type: string
- newPet:
+ newPetSchema:
type: object
required:
- name
@@ -75,7 +75,7 @@ components:
content:
'application/json':
schema:
- "$ref": '#/components/schemas/newPet'
+ "$ref": '#/components/schemas/newPetSchema'
responses:
"200":
description: Return a 200 status to indicate that the data was received successfully
diff --git a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/Samples/OpenApiDocument/documentWithSummaryAndDescriptionInReference.yaml b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/Samples/OpenApiDocument/documentWithSummaryAndDescriptionInReference.yaml
index 0d061203d..37a05f101 100644
--- a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/Samples/OpenApiDocument/documentWithSummaryAndDescriptionInReference.yaml
+++ b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/Samples/OpenApiDocument/documentWithSummaryAndDescriptionInReference.yaml
@@ -13,17 +13,16 @@ paths:
application/json:
schema:
"$ref": '#/components/schemas/pet'
- summary: A pet
- description: A pet in a petstore
components:
headers:
X-Test:
description: Test
+ summary: An X-Test header
schema:
type: string
responses:
Test:
- description: Test Repsonse
+ description: Test Response
headers:
X-Test:
$ref: '#/components/headers/X-Test'
diff --git a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/Samples/OpenApiDocument/documentWithWebhooks.yaml b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/Samples/OpenApiDocument/documentWithWebhooks.yaml
index 11c389157..74dd1b473 100644
--- a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/Samples/OpenApiDocument/documentWithWebhooks.yaml
+++ b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/Samples/OpenApiDocument/documentWithWebhooks.yaml
@@ -31,12 +31,12 @@ webhooks:
schema:
type: array
items:
- "$ref": '#/components/schemas/pet1'
+ "$ref": '#/components/schemas/petSchema'
application/xml:
schema:
type: array
items:
- "$ref": '#/components/schemas/pet1'
+ "$ref": '#/components/schemas/petSchema'
post:
requestBody:
description: Information about a new pet in the system
@@ -44,17 +44,17 @@ webhooks:
content:
'application/json':
schema:
- "$ref": '#/components/schemas/newPet'
+ "$ref": '#/components/schemas/newPetSchema'
responses:
"200":
description: Return a 200 status to indicate that the data was received successfully
content:
application/json:
schema:
- $ref: '#/components/schemas/pet1'
+ $ref: '#/components/schemas/petSchema'
components:
schemas:
- pet1:
+ petSchema:
type: object
required:
- id
@@ -67,7 +67,7 @@ components:
type: string
tag:
type: string
- newPet:
+ newPetSchema:
type: object
required:
- name
diff --git a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/JsonSchemaTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/JsonSchemaTests.cs
index 7d81a8601..b37067e09 100644
--- a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/JsonSchemaTests.cs
+++ b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/JsonSchemaTests.cs
@@ -224,20 +224,22 @@ public void ParseBasicSchemaWithReferenceShouldSucceed()
}
});
- components.Should().BeEquivalentTo(
- new OpenApiComponents
- {
- Schemas =
+ var expectedComponents = new OpenApiComponents
+ {
+ Schemas =
{
["ErrorModel"] = new JsonSchemaBuilder()
+ .Ref("#/components/schemas/ErrorModel")
.Type(SchemaValueType.Object)
.Required("message", "code")
.Properties(
("message", new JsonSchemaBuilder().Type(SchemaValueType.String)),
("code", new JsonSchemaBuilder().Type(SchemaValueType.Integer).Minimum(100).Maximum(600))),
["ExtendedErrorModel"] = new JsonSchemaBuilder()
+ .Ref("#/components/schemas/ExtendedErrorModel")
.AllOf(
new JsonSchemaBuilder()
+ .Ref("#/components/schemas/ErrorModel")
.Type(SchemaValueType.Object)
.Properties(
("code", new JsonSchemaBuilder().Type(SchemaValueType.Integer).Minimum(100).Maximum(600)),
@@ -246,11 +248,11 @@ public void ParseBasicSchemaWithReferenceShouldSucceed()
new JsonSchemaBuilder()
.Type(SchemaValueType.Object)
.Required("rootCause")
- .Properties(("rootCause", new JsonSchemaBuilder().Type(SchemaValueType.String))))
+ .Properties(("rootCause", new JsonSchemaBuilder().Type(SchemaValueType.String))))
}
- },
- options => options.Excluding(m => m.Name == "HostDocument")
- .IgnoringCyclicReferences());
+ };
+
+ components.Should().BeEquivalentTo(expectedComponents);
}
[Fact]
@@ -280,6 +282,7 @@ public void ParseAdvancedSchemaWithReferenceShouldSucceed()
.Description("A representation of a cat")
.AllOf(
new JsonSchemaBuilder()
+ .Ref("#/components/schemas/Pet1")
.Type(SchemaValueType.Object)
.Discriminator(new OpenApiDiscriminator { PropertyName = "petType" })
.Properties(
@@ -306,6 +309,7 @@ public void ParseAdvancedSchemaWithReferenceShouldSucceed()
.Description("A representation of a dog")
.AllOf(
new JsonSchemaBuilder()
+ .Ref("#/components/schemas/Pet1")
.Type(SchemaValueType.Object)
.Discriminator(new OpenApiDiscriminator { PropertyName = "petType" })
.Properties(
diff --git a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiDocumentTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiDocumentTests.cs
index 71b7a7d74..46ac9f815 100644
--- a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiDocumentTests.cs
+++ b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiDocumentTests.cs
@@ -217,13 +217,14 @@ public void ParseStandardPetStoreDocumentShouldSucceed()
OpenApiDiagnostic context;
using (var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "petStore.yaml")))
{
- var actual = new OpenApiStreamReader().Read(stream, out context);
+ var doc = new OpenApiStreamReader().Read(stream, out context);
var components = new OpenApiComponents
{
Schemas = new Dictionary
{
- ["pet"] = new JsonSchemaBuilder()
+ ["pet1"] = new JsonSchemaBuilder()
+ .Ref("#/components/schemas/pet1")
.Type(SchemaValueType.Object)
.Required("id", "name")
.Properties(
@@ -231,6 +232,7 @@ public void ParseStandardPetStoreDocumentShouldSucceed()
("name", new JsonSchemaBuilder().Type(SchemaValueType.String)),
("tag", new JsonSchemaBuilder().Type(SchemaValueType.String))),
["newPet"] = new JsonSchemaBuilder()
+ .Ref("#/components/schemas/newPet")
.Type(SchemaValueType.Object)
.Required("name")
.Properties(
@@ -238,6 +240,7 @@ public void ParseStandardPetStoreDocumentShouldSucceed()
("name", new JsonSchemaBuilder().Type(SchemaValueType.String)),
("tag", new JsonSchemaBuilder().Type(SchemaValueType.String))),
["errorModel"] = new JsonSchemaBuilder()
+ .Ref("#/components/schemas/errorModel")
.Type(SchemaValueType.Object)
.Required("code", "message")
.Properties(
@@ -246,13 +249,13 @@ public void ParseStandardPetStoreDocumentShouldSucceed()
}
};
- var petSchema = components.Schemas["pet"];
+ var petSchema = components.Schemas["pet1"];
var newPetSchema = components.Schemas["newPet"];
var errorModelSchema = components.Schemas["errorModel"];
- var expected = new OpenApiDocument
+ var expectedDoc = new OpenApiDocument
{
Info = new OpenApiInfo
{
@@ -519,7 +522,7 @@ public void ParseStandardPetStoreDocumentShouldSucceed()
Components = components
};
- actual.Should().BeEquivalentTo(expected);
+ doc.Should().BeEquivalentTo(expectedDoc);
}
context.Should().BeEquivalentTo(
@@ -539,6 +542,7 @@ public void ParseModifiedPetStoreDocumentWithTagAndSecurityShouldSucceed()
Schemas = new Dictionary
{
["pet1"] = new JsonSchemaBuilder()
+ .Ref("#/components/schemas/pet1")
.Type(SchemaValueType.Object)
.Required("id", "name")
.Properties(
@@ -546,6 +550,7 @@ public void ParseModifiedPetStoreDocumentWithTagAndSecurityShouldSucceed()
("name", new JsonSchemaBuilder().Type(SchemaValueType.String)),
("tag", new JsonSchemaBuilder().Type(SchemaValueType.String))),
["newPet"] = new JsonSchemaBuilder()
+ .Ref("#/components/schemas/newPet")
.Type(SchemaValueType.Object)
.Required("name")
.Properties(
@@ -553,6 +558,7 @@ public void ParseModifiedPetStoreDocumentWithTagAndSecurityShouldSucceed()
("name", new JsonSchemaBuilder().Type(SchemaValueType.String)),
("tag", new JsonSchemaBuilder().Type(SchemaValueType.String))),
["errorModel"] = new JsonSchemaBuilder()
+ .Ref("#/components/schemas/errorModel")
.Type(SchemaValueType.Object)
.Required("code", "message")
.Properties(
@@ -1090,6 +1096,7 @@ public void ParseDocumentWithJsonSchemaReferencesWorks()
var actualSchema = doc.Paths["/users/{userId}"].Operations[OperationType.Get].Responses["200"].Content["application/json"].Schema;
var expectedSchema = new JsonSchemaBuilder()
+ .Ref("#/components/schemas/User")
.Type(SchemaValueType.Object)
.Properties(
("id", new JsonSchemaBuilder().Type(SchemaValueType.Integer)),
diff --git a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/Samples/OpenApiDocument/docWithJsonSchema.yaml b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/Samples/OpenApiDocument/docWithJsonSchema.yaml
index b26947dc4..984e5ce2b 100644
--- a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/Samples/OpenApiDocument/docWithJsonSchema.yaml
+++ b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/Samples/OpenApiDocument/docWithJsonSchema.yaml
@@ -1,4 +1,4 @@
-openapi: 3.1.0
+openapi: '3.0.1'
info:
title: Sample API with Schema Reference
version: 1.0.0
diff --git a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/Samples/OpenApiDocument/petStore.yaml b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/Samples/OpenApiDocument/petStore.yaml
index d0696cde5..6a9df318b 100644
--- a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/Samples/OpenApiDocument/petStore.yaml
+++ b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/Samples/OpenApiDocument/petStore.yaml
@@ -42,12 +42,12 @@ paths:
schema:
type: array
items:
- "$ref": '#/components/schemas/pet'
+ "$ref": '#/components/schemas/pet1'
application/xml:
schema:
type: array
items:
- "$ref": '#/components/schemas/pet'
+ "$ref": '#/components/schemas/pet1'
'4XX':
description: unexpected client error
@@ -77,7 +77,7 @@ paths:
content:
application/json:
schema:
- "$ref": '#/components/schemas/pet'
+ "$ref": '#/components/schemas/pet1'
'4XX':
description: unexpected client error
content:
@@ -108,10 +108,10 @@ paths:
content:
application/json:
schema:
- "$ref": '#/components/schemas/pet'
+ "$ref": '#/components/schemas/pet1'
application/xml:
schema:
- "$ref": '#/components/schemas/pet'
+ "$ref": '#/components/schemas/pet1'
'4XX':
description: unexpected client error
content:
@@ -152,7 +152,7 @@ paths:
"$ref": '#/components/schemas/errorModel'
components:
schemas:
- pet:
+ pet1:
type: object
required:
- id
diff --git a/test/Microsoft.OpenApi.SmokeTests/Microsoft.OpenApi.SmokeTests.csproj b/test/Microsoft.OpenApi.SmokeTests/Microsoft.OpenApi.SmokeTests.csproj
index 1f6d93401..a33119ef3 100644
--- a/test/Microsoft.OpenApi.SmokeTests/Microsoft.OpenApi.SmokeTests.csproj
+++ b/test/Microsoft.OpenApi.SmokeTests/Microsoft.OpenApi.SmokeTests.csproj
@@ -12,8 +12,8 @@
-
-
+
+
diff --git a/test/Microsoft.OpenApi.Tests/Microsoft.OpenApi.Tests.csproj b/test/Microsoft.OpenApi.Tests/Microsoft.OpenApi.Tests.csproj
index 56bb62fa3..18cce9bd6 100644
--- a/test/Microsoft.OpenApi.Tests/Microsoft.OpenApi.Tests.csproj
+++ b/test/Microsoft.OpenApi.Tests/Microsoft.OpenApi.Tests.csproj
@@ -12,14 +12,14 @@
-
+
-
-
-
+
+
+
-
+
diff --git a/test/Microsoft.OpenApi.Tests/Models/OpenApiDocumentTests.SerializeAdvancedDocumentWithReferenceAsV2JsonWorks_produceTerseOutput=False.verified.txt b/test/Microsoft.OpenApi.Tests/Models/OpenApiDocumentTests.SerializeAdvancedDocumentWithReferenceAsV2JsonWorks_produceTerseOutput=False.verified.txt
index 6f4d12e71..06e0f2ca9 100644
--- a/test/Microsoft.OpenApi.Tests/Models/OpenApiDocumentTests.SerializeAdvancedDocumentWithReferenceAsV2JsonWorks_produceTerseOutput=False.verified.txt
+++ b/test/Microsoft.OpenApi.Tests/Models/OpenApiDocumentTests.SerializeAdvancedDocumentWithReferenceAsV2JsonWorks_produceTerseOutput=False.verified.txt
@@ -55,20 +55,20 @@
"schema": {
"type": "array",
"items": {
- "$ref": "#/components/schemas/pet"
+ "$ref": "#/definitions/pet"
}
}
},
"4XX": {
"description": "unexpected client error",
"schema": {
- "$ref": "#/components/schemas/errorModel"
+ "$ref": "#/definitions/errorModel"
}
},
"5XX": {
"description": "unexpected server error",
"schema": {
- "$ref": "#/components/schemas/errorModel"
+ "$ref": "#/definitions/errorModel"
}
}
}
@@ -90,7 +90,7 @@
"description": "Pet to add to the store",
"required": true,
"schema": {
- "$ref": "#/components/schemas/newPet"
+ "$ref": "#/definitions/newPet"
}
}
],
@@ -98,19 +98,19 @@
"200": {
"description": "pet response",
"schema": {
- "$ref": "#/components/schemas/pet"
+ "$ref": "#/definitions/pet"
}
},
"4XX": {
"description": "unexpected client error",
"schema": {
- "$ref": "#/components/schemas/errorModel"
+ "$ref": "#/definitions/errorModel"
}
},
"5XX": {
"description": "unexpected server error",
"schema": {
- "$ref": "#/components/schemas/errorModel"
+ "$ref": "#/definitions/errorModel"
}
}
}
@@ -139,19 +139,19 @@
"200": {
"description": "pet response",
"schema": {
- "$ref": "#/components/schemas/pet"
+ "$ref": "#/definitions/pet"
}
},
"4XX": {
"description": "unexpected client error",
"schema": {
- "$ref": "#/components/schemas/errorModel"
+ "$ref": "#/definitions/errorModel"
}
},
"5XX": {
"description": "unexpected server error",
"schema": {
- "$ref": "#/components/schemas/errorModel"
+ "$ref": "#/definitions/errorModel"
}
}
}
@@ -179,13 +179,13 @@
"4XX": {
"description": "unexpected client error",
"schema": {
- "$ref": "#/components/schemas/errorModel"
+ "$ref": "#/definitions/errorModel"
}
},
"5XX": {
"description": "unexpected server error",
"schema": {
- "$ref": "#/components/schemas/errorModel"
+ "$ref": "#/definitions/errorModel"
}
}
}
diff --git a/test/Microsoft.OpenApi.Tests/Models/OpenApiDocumentTests.SerializeAdvancedDocumentWithReferenceAsV2JsonWorks_produceTerseOutput=True.verified.txt b/test/Microsoft.OpenApi.Tests/Models/OpenApiDocumentTests.SerializeAdvancedDocumentWithReferenceAsV2JsonWorks_produceTerseOutput=True.verified.txt
index ce5390739..ae1db5447 100644
--- a/test/Microsoft.OpenApi.Tests/Models/OpenApiDocumentTests.SerializeAdvancedDocumentWithReferenceAsV2JsonWorks_produceTerseOutput=True.verified.txt
+++ b/test/Microsoft.OpenApi.Tests/Models/OpenApiDocumentTests.SerializeAdvancedDocumentWithReferenceAsV2JsonWorks_produceTerseOutput=True.verified.txt
@@ -1 +1 @@
-{"swagger":"2.0","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":"foo@example.com"},"license":{"name":"MIT","url":"http://opensource.org/licenses/MIT"},"version":"1.0.0"},"host":"petstore.swagger.io","basePath":"/api","schemes":["http"],"paths":{"/pets":{"get":{"description":"Returns all pets from the system that the user has access to","operationId":"findPets","produces":["application/json","application/xml","text/html"],"parameters":[{"in":"query","name":"tags","description":"tags to filter by","type":"array","items":{"type":"string"},"collectionFormat":"multi"},{"in":"query","name":"limit","description":"maximum number of results to return","type":"integer","format":"int32"}],"responses":{"200":{"description":"pet response","schema":{"type":"array","items":{"$ref":"#/components/schemas/pet"}}},"4XX":{"description":"unexpected client error","schema":{"$ref":"#/components/schemas/errorModel"}},"5XX":{"description":"unexpected server error","schema":{"$ref":"#/components/schemas/errorModel"}}}},"post":{"description":"Creates a new pet in the store. Duplicates are allowed","operationId":"addPet","consumes":["application/json"],"produces":["application/json","text/html"],"parameters":[{"in":"body","name":"body","description":"Pet to add to the store","required":true,"schema":{"$ref":"#/components/schemas/newPet"}}],"responses":{"200":{"description":"pet response","schema":{"$ref":"#/components/schemas/pet"}},"4XX":{"description":"unexpected client error","schema":{"$ref":"#/components/schemas/errorModel"}},"5XX":{"description":"unexpected server error","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","produces":["application/json","application/xml","text/html"],"parameters":[{"in":"path","name":"id","description":"ID of pet to fetch","required":true,"type":"integer","format":"int64"}],"responses":{"200":{"description":"pet response","schema":{"$ref":"#/components/schemas/pet"}},"4XX":{"description":"unexpected client error","schema":{"$ref":"#/components/schemas/errorModel"}},"5XX":{"description":"unexpected server error","schema":{"$ref":"#/components/schemas/errorModel"}}}},"delete":{"description":"deletes a single pet based on the ID supplied","operationId":"deletePet","produces":["text/html"],"parameters":[{"in":"path","name":"id","description":"ID of pet to delete","required":true,"type":"integer","format":"int64"}],"responses":{"204":{"description":"pet deleted"},"4XX":{"description":"unexpected client error","schema":{"$ref":"#/components/schemas/errorModel"}},"5XX":{"description":"unexpected server error","schema":{"$ref":"#/components/schemas/errorModel"}}}}}},"definitions":{"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"}}}}}
\ No newline at end of file
+{"swagger":"2.0","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":"foo@example.com"},"license":{"name":"MIT","url":"http://opensource.org/licenses/MIT"},"version":"1.0.0"},"host":"petstore.swagger.io","basePath":"/api","schemes":["http"],"paths":{"/pets":{"get":{"description":"Returns all pets from the system that the user has access to","operationId":"findPets","produces":["application/json","application/xml","text/html"],"parameters":[{"in":"query","name":"tags","description":"tags to filter by","type":"array","items":{"type":"string"},"collectionFormat":"multi"},{"in":"query","name":"limit","description":"maximum number of results to return","type":"integer","format":"int32"}],"responses":{"200":{"description":"pet response","schema":{"type":"array","items":{"$ref":"#/definitions/pet"}}},"4XX":{"description":"unexpected client error","schema":{"$ref":"#/definitions/errorModel"}},"5XX":{"description":"unexpected server error","schema":{"$ref":"#/definitions/errorModel"}}}},"post":{"description":"Creates a new pet in the store. Duplicates are allowed","operationId":"addPet","consumes":["application/json"],"produces":["application/json","text/html"],"parameters":[{"in":"body","name":"body","description":"Pet to add to the store","required":true,"schema":{"$ref":"#/definitions/newPet"}}],"responses":{"200":{"description":"pet response","schema":{"$ref":"#/definitions/pet"}},"4XX":{"description":"unexpected client error","schema":{"$ref":"#/definitions/errorModel"}},"5XX":{"description":"unexpected server error","schema":{"$ref":"#/definitions/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","produces":["application/json","application/xml","text/html"],"parameters":[{"in":"path","name":"id","description":"ID of pet to fetch","required":true,"type":"integer","format":"int64"}],"responses":{"200":{"description":"pet response","schema":{"$ref":"#/definitions/pet"}},"4XX":{"description":"unexpected client error","schema":{"$ref":"#/definitions/errorModel"}},"5XX":{"description":"unexpected server error","schema":{"$ref":"#/definitions/errorModel"}}}},"delete":{"description":"deletes a single pet based on the ID supplied","operationId":"deletePet","produces":["text/html"],"parameters":[{"in":"path","name":"id","description":"ID of pet to delete","required":true,"type":"integer","format":"int64"}],"responses":{"204":{"description":"pet deleted"},"4XX":{"description":"unexpected client error","schema":{"$ref":"#/definitions/errorModel"}},"5XX":{"description":"unexpected server error","schema":{"$ref":"#/definitions/errorModel"}}}}}},"definitions":{"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"}}}}}
\ No newline at end of file
diff --git a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiRequestBodyReferenceTests.SerializeRequestBodyReferenceAsV31JsonWorks_produceTerseOutput=False.verified.txt b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiRequestBodyReferenceTests.SerializeRequestBodyReferenceAsV31JsonWorks_produceTerseOutput=False.verified.txt
index c4d9bef00..cdbbe00d1 100644
--- a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiRequestBodyReferenceTests.SerializeRequestBodyReferenceAsV31JsonWorks_produceTerseOutput=False.verified.txt
+++ b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiRequestBodyReferenceTests.SerializeRequestBodyReferenceAsV31JsonWorks_produceTerseOutput=False.verified.txt
@@ -3,15 +3,7 @@
"content": {
"application/json": {
"schema": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string"
- },
- "email": {
- "type": "string"
- }
- }
+ "$ref": "#/components/schemas/UserSchema"
}
}
}
diff --git a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiRequestBodyReferenceTests.SerializeRequestBodyReferenceAsV31JsonWorks_produceTerseOutput=True.verified.txt b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiRequestBodyReferenceTests.SerializeRequestBodyReferenceAsV31JsonWorks_produceTerseOutput=True.verified.txt
index 3d91acf86..e82312f67 100644
--- a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiRequestBodyReferenceTests.SerializeRequestBodyReferenceAsV31JsonWorks_produceTerseOutput=True.verified.txt
+++ b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiRequestBodyReferenceTests.SerializeRequestBodyReferenceAsV31JsonWorks_produceTerseOutput=True.verified.txt
@@ -1 +1 @@
-{"description":"User creation request body","content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"email":{"type":"string"}}}}}}
\ No newline at end of file
+{"description":"User creation request body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserSchema"}}}}
\ No newline at end of file
diff --git a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiRequestBodyReferenceTests.SerializeRequestBodyReferenceAsV3JsonWorks_produceTerseOutput=False.verified.txt b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiRequestBodyReferenceTests.SerializeRequestBodyReferenceAsV3JsonWorks_produceTerseOutput=False.verified.txt
index c4d9bef00..cdbbe00d1 100644
--- a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiRequestBodyReferenceTests.SerializeRequestBodyReferenceAsV3JsonWorks_produceTerseOutput=False.verified.txt
+++ b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiRequestBodyReferenceTests.SerializeRequestBodyReferenceAsV3JsonWorks_produceTerseOutput=False.verified.txt
@@ -3,15 +3,7 @@
"content": {
"application/json": {
"schema": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string"
- },
- "email": {
- "type": "string"
- }
- }
+ "$ref": "#/components/schemas/UserSchema"
}
}
}
diff --git a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiRequestBodyReferenceTests.SerializeRequestBodyReferenceAsV3JsonWorks_produceTerseOutput=True.verified.txt b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiRequestBodyReferenceTests.SerializeRequestBodyReferenceAsV3JsonWorks_produceTerseOutput=True.verified.txt
index 3d91acf86..e82312f67 100644
--- a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiRequestBodyReferenceTests.SerializeRequestBodyReferenceAsV3JsonWorks_produceTerseOutput=True.verified.txt
+++ b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiRequestBodyReferenceTests.SerializeRequestBodyReferenceAsV3JsonWorks_produceTerseOutput=True.verified.txt
@@ -1 +1 @@
-{"description":"User creation request body","content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"email":{"type":"string"}}}}}}
\ No newline at end of file
+{"description":"User creation request body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserSchema"}}}}
\ No newline at end of file
diff --git a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiRequestBodyReferenceTests.cs b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiRequestBodyReferenceTests.cs
index 53fa179ea..edfb81e09 100644
--- a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiRequestBodyReferenceTests.cs
+++ b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiRequestBodyReferenceTests.cs
@@ -101,6 +101,7 @@ public void RequestBodyReferenceResolutionWorks()
{
// Assert
var expectedSchema = new JsonSchemaBuilder()
+ .Ref("#/components/schemas/UserSchema")
.Type(SchemaValueType.Object)
.Properties(
("name", new JsonSchemaBuilder().Type(SchemaValueType.String)),
diff --git a/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt b/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt
index 70695eaa5..621724d63 100755
--- a/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt
+++ b/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt
@@ -166,6 +166,14 @@ namespace Microsoft.OpenApi.Extensions
public const string Name = "extensions";
public void Evaluate(Json.Schema.EvaluationContext context) { }
}
+ [Json.Schema.SchemaKeyword("externalDocs")]
+ public class ExternalDocsKeyword : Json.Schema.IJsonSchemaKeyword
+ {
+ public const string Name = "externalDocs";
+ public ExternalDocsKeyword(Microsoft.OpenApi.Models.OpenApiExternalDocs value) { }
+ public Microsoft.OpenApi.Models.OpenApiExternalDocs Value { get; }
+ public void Evaluate(Json.Schema.EvaluationContext context) { }
+ }
public static class JsonSchemaBuilderExtensions
{
public static Json.Schema.JsonSchemaBuilder AdditionalPropertiesAllowed(this Json.Schema.JsonSchemaBuilder builder, bool additionalPropertiesAllowed) { }
@@ -174,6 +182,8 @@ namespace Microsoft.OpenApi.Extensions
public static Json.Schema.JsonSchemaBuilder ExclusiveMinimum(this Json.Schema.JsonSchemaBuilder builder, bool value) { }
public static Json.Schema.JsonSchemaBuilder Extensions(this Json.Schema.JsonSchemaBuilder builder, System.Collections.Generic.IDictionary extensions) { }
public static Json.Schema.JsonSchemaBuilder Nullable(this Json.Schema.JsonSchemaBuilder builder, bool value) { }
+ public static Json.Schema.JsonSchemaBuilder OpenApiExternalDocs(this Json.Schema.JsonSchemaBuilder builder, Microsoft.OpenApi.Models.OpenApiExternalDocs externalDocs) { }
+ public static Json.Schema.JsonSchemaBuilder Remove(this Json.Schema.JsonSchemaBuilder builder, string keyword) { }
public static Json.Schema.JsonSchemaBuilder Summary(this Json.Schema.JsonSchemaBuilder builder, string summary) { }
}
public static class JsonSchemaExtensions
@@ -184,6 +194,7 @@ namespace Microsoft.OpenApi.Extensions
public static Microsoft.OpenApi.Extensions.DiscriminatorKeyword GetOpenApiDiscriminator(this Json.Schema.JsonSchema schema) { }
public static bool? GetOpenApiExclusiveMaximum(this Json.Schema.JsonSchema schema) { }
public static bool? GetOpenApiExclusiveMinimum(this Json.Schema.JsonSchema schema) { }
+ public static Microsoft.OpenApi.Models.OpenApiExternalDocs GetOpenApiExternalDocs(this Json.Schema.JsonSchema schema) { }
public static string GetSummary(this Json.Schema.JsonSchema schema) { }
}
[Json.Schema.SchemaKeyword("nullable")]
@@ -299,7 +310,7 @@ namespace Microsoft.OpenApi.MicrosoftExtensions
public class EnumDescription : Microsoft.OpenApi.Interfaces.IOpenApiElement
{
public EnumDescription() { }
- public EnumDescription(Microsoft.OpenApi.Any.OpenApiObject source) { }
+ public EnumDescription(System.Text.Json.Nodes.JsonObject source) { }
public string Description { get; set; }
public string Name { get; set; }
public string Value { get; set; }
@@ -313,7 +324,7 @@ namespace Microsoft.OpenApi.MicrosoftExtensions
public string Version { get; set; }
public static string Name { get; }
public void Write(Microsoft.OpenApi.Writers.IOpenApiWriter writer, Microsoft.OpenApi.OpenApiSpecVersion specVersion) { }
- public static Microsoft.OpenApi.MicrosoftExtensions.OpenApiDeprecationExtension Parse(Microsoft.OpenApi.Any.IOpenApiAny source) { }
+ public static Microsoft.OpenApi.MicrosoftExtensions.OpenApiDeprecationExtension Parse(Microsoft.OpenApi.Any.OpenApiAny source) { }
}
public class OpenApiEnumFlagsExtension : Microsoft.OpenApi.Interfaces.IOpenApiExtension
{
@@ -321,7 +332,7 @@ namespace Microsoft.OpenApi.MicrosoftExtensions
public bool IsFlags { get; set; }
public static string Name { get; }
public void Write(Microsoft.OpenApi.Writers.IOpenApiWriter writer, Microsoft.OpenApi.OpenApiSpecVersion specVersion) { }
- public static Microsoft.OpenApi.MicrosoftExtensions.OpenApiEnumFlagsExtension Parse(Microsoft.OpenApi.Any.IOpenApiAny source) { }
+ public static Microsoft.OpenApi.MicrosoftExtensions.OpenApiEnumFlagsExtension Parse(Microsoft.OpenApi.Any.OpenApiAny source) { }
}
public class OpenApiEnumValuesDescriptionExtension : Microsoft.OpenApi.Interfaces.IOpenApiExtension
{
@@ -330,7 +341,7 @@ namespace Microsoft.OpenApi.MicrosoftExtensions
public System.Collections.Generic.List ValuesDescriptions { get; set; }
public static string Name { get; }
public void Write(Microsoft.OpenApi.Writers.IOpenApiWriter writer, Microsoft.OpenApi.OpenApiSpecVersion specVersion) { }
- public static Microsoft.OpenApi.MicrosoftExtensions.OpenApiEnumValuesDescriptionExtension Parse(Microsoft.OpenApi.Any.IOpenApiAny source) { }
+ public static Microsoft.OpenApi.MicrosoftExtensions.OpenApiEnumValuesDescriptionExtension Parse(Microsoft.OpenApi.Any.OpenApiAny source) { }
}
public class OpenApiPagingExtension : Microsoft.OpenApi.Interfaces.IOpenApiExtension
{
@@ -340,7 +351,7 @@ namespace Microsoft.OpenApi.MicrosoftExtensions
public string OperationName { get; set; }
public static string Name { get; }
public void Write(Microsoft.OpenApi.Writers.IOpenApiWriter writer, Microsoft.OpenApi.OpenApiSpecVersion specVersion) { }
- public static Microsoft.OpenApi.MicrosoftExtensions.OpenApiPagingExtension Parse(Microsoft.OpenApi.Any.IOpenApiAny source) { }
+ public static Microsoft.OpenApi.MicrosoftExtensions.OpenApiPagingExtension Parse(Microsoft.OpenApi.Any.OpenApiAny source) { }
}
public class OpenApiPrimaryErrorMessageExtension : Microsoft.OpenApi.Interfaces.IOpenApiExtension
{
@@ -348,7 +359,7 @@ namespace Microsoft.OpenApi.MicrosoftExtensions
public bool IsPrimaryErrorMessage { get; set; }
public static string Name { get; }
public void Write(Microsoft.OpenApi.Writers.IOpenApiWriter writer, Microsoft.OpenApi.OpenApiSpecVersion specVersion) { }
- public static Microsoft.OpenApi.MicrosoftExtensions.OpenApiPrimaryErrorMessageExtension Parse(Microsoft.OpenApi.Any.IOpenApiAny source) { }
+ public static Microsoft.OpenApi.MicrosoftExtensions.OpenApiPrimaryErrorMessageExtension Parse(Microsoft.OpenApi.Any.OpenApiAny source) { }
}
public class OpenApiReservedParameterExtension : Microsoft.OpenApi.Interfaces.IOpenApiExtension
{
@@ -356,7 +367,7 @@ namespace Microsoft.OpenApi.MicrosoftExtensions
public bool? IsReserved { get; set; }
public static string Name { get; }
public void Write(Microsoft.OpenApi.Writers.IOpenApiWriter writer, Microsoft.OpenApi.OpenApiSpecVersion specVersion) { }
- public static Microsoft.OpenApi.MicrosoftExtensions.OpenApiReservedParameterExtension Parse(Microsoft.OpenApi.Any.IOpenApiAny source) { }
+ public static Microsoft.OpenApi.MicrosoftExtensions.OpenApiReservedParameterExtension Parse(Microsoft.OpenApi.Any.OpenApiAny source) { }
}
}
namespace Microsoft.OpenApi.Models
@@ -1471,9 +1482,9 @@ namespace Microsoft.OpenApi.Writers
void Flush();
void WriteEndArray();
void WriteEndObject();
- void WriteJsonSchema(Json.Schema.JsonSchema schema);
- void WriteJsonSchemaReference(Microsoft.OpenApi.Writers.IOpenApiWriter writer, System.Uri reference);
- void WriteJsonSchemaWithoutReference(Microsoft.OpenApi.Writers.IOpenApiWriter writer, Json.Schema.JsonSchema schema);
+ void WriteJsonSchema(Json.Schema.JsonSchema schema, Microsoft.OpenApi.OpenApiSpecVersion version);
+ void WriteJsonSchemaReference(Microsoft.OpenApi.Writers.IOpenApiWriter writer, System.Uri reference, Microsoft.OpenApi.OpenApiSpecVersion version);
+ void WriteJsonSchemaWithoutReference(Microsoft.OpenApi.Writers.IOpenApiWriter writer, Json.Schema.JsonSchema schema, Microsoft.OpenApi.OpenApiSpecVersion version);
void WriteNull();
void WritePropertyName(string name);
void WriteRaw(string value);
@@ -1534,9 +1545,9 @@ namespace Microsoft.OpenApi.Writers
public abstract void WriteEndArray();
public abstract void WriteEndObject();
public virtual void WriteIndentation() { }
- public void WriteJsonSchema(Json.Schema.JsonSchema schema) { }
- public void WriteJsonSchemaReference(Microsoft.OpenApi.Writers.IOpenApiWriter writer, System.Uri reference) { }
- public void WriteJsonSchemaWithoutReference(Microsoft.OpenApi.Writers.IOpenApiWriter writer, Json.Schema.JsonSchema schema) { }
+ public void WriteJsonSchema(Json.Schema.JsonSchema schema, Microsoft.OpenApi.OpenApiSpecVersion version) { }
+ public void WriteJsonSchemaReference(Microsoft.OpenApi.Writers.IOpenApiWriter writer, System.Uri reference, Microsoft.OpenApi.OpenApiSpecVersion version) { }
+ public void WriteJsonSchemaWithoutReference(Microsoft.OpenApi.Writers.IOpenApiWriter writer, Json.Schema.JsonSchema schema, Microsoft.OpenApi.OpenApiSpecVersion version) { }
public abstract void WriteNull();
public abstract void WritePropertyName(string name);
public abstract void WriteRaw(string value);
@@ -1572,6 +1583,8 @@ namespace Microsoft.OpenApi.Writers
where T : struct { }
public static void WriteProperty(this Microsoft.OpenApi.Writers.IOpenApiWriter writer, string name, T? value)
where T : struct { }
+ public static void WriteRequiredCollection(this Microsoft.OpenApi.Writers.IOpenApiWriter writer, string name, System.Collections.Generic.IEnumerable elements, System.Action action)
+ where T : Microsoft.OpenApi.Interfaces.IOpenApiElement { }
public static void WriteRequiredMap(this Microsoft.OpenApi.Writers.IOpenApiWriter writer, string name, System.Collections.Generic.IDictionary elements, System.Action action) { }
public static void WriteRequiredMap(this Microsoft.OpenApi.Writers.IOpenApiWriter writer, string name, System.Collections.Generic.IDictionary elements, System.Action action)
where T : Microsoft.OpenApi.Interfaces.IOpenApiElement { }
diff --git a/test/Microsoft.OpenApi.Tests/Validations/ValidationRuleSetTests.cs b/test/Microsoft.OpenApi.Tests/Validations/ValidationRuleSetTests.cs
index 14af8e042..55ae552d1 100644
--- a/test/Microsoft.OpenApi.Tests/Validations/ValidationRuleSetTests.cs
+++ b/test/Microsoft.OpenApi.Tests/Validations/ValidationRuleSetTests.cs
@@ -1,4 +1,4 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
+// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
using System.Collections.Generic;
@@ -52,8 +52,8 @@ public void RuleSetConstructorsReturnsTheCorrectRules()
Assert.Empty(ruleSet_4.Rules);
// Update the number if you add new default rule(s).
- Assert.Equal(22, ruleSet_1.Rules.Count);
- Assert.Equal(22, ruleSet_2.Rules.Count);
+ Assert.Equal(23, ruleSet_1.Rules.Count);
+ Assert.Equal(23, ruleSet_2.Rules.Count);
Assert.Equal(3, ruleSet_3.Rules.Count);
}
diff --git a/test/Microsoft.OpenApi.Tests/Walkers/WalkerLocationTests.cs b/test/Microsoft.OpenApi.Tests/Walkers/WalkerLocationTests.cs
index 57862b67a..8631ac6a4 100644
--- a/test/Microsoft.OpenApi.Tests/Walkers/WalkerLocationTests.cs
+++ b/test/Microsoft.OpenApi.Tests/Walkers/WalkerLocationTests.cs
@@ -210,6 +210,18 @@ public void LocateReferences()
Headers = new Dictionary
{
["test-header"] = testHeader
+ },
+ SecuritySchemes = new Dictionary
+ {
+ ["test-secScheme"] = new OpenApiSecurityScheme
+ {
+ Reference = new OpenApiReference
+ {
+ Id = "reference-to-scheme",
+ Type = ReferenceType.SecurityScheme
+ },
+ UnresolvedReference = true
+ }
}
}
};
@@ -224,6 +236,7 @@ public void LocateReferences()
"referenceAt: #/components/schemas/derived",
"referenceAt: #/components/schemas/derived/anyOf",
"referenceAt: #/components/schemas/base",
+ "referenceAt: #/components/securitySchemes/test-secScheme",
"referenceAt: #/components/headers/test-header/schema"
});
}
diff --git a/test/Microsoft.OpenApi.Tests/Workspaces/OpenApiWorkspaceTests.cs b/test/Microsoft.OpenApi.Tests/Workspaces/OpenApiWorkspaceTests.cs
index a67df9e92..57faaf72f 100644
--- a/test/Microsoft.OpenApi.Tests/Workspaces/OpenApiWorkspaceTests.cs
+++ b/test/Microsoft.OpenApi.Tests/Workspaces/OpenApiWorkspaceTests.cs
@@ -1,4 +1,4 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
+// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
using System;
@@ -72,13 +72,14 @@ public void OpenApiWorkspacesAllowDocumentsToReferenceEachOther()
[Fact]
public void OpenApiWorkspacesCanResolveExternalReferences()
{
+ var refUri = new Uri("https://everything.json/common#/components/schemas/test");
var workspace = new OpenApiWorkspace();
- var doc = CreateCommonDocument();
+ var doc = CreateCommonDocument(refUri);
var location = "common";
workspace.AddDocument(location, doc);
- var schema = workspace.ResolveJsonSchemaReference(new Uri("https://everything.json/common#/components/schemas/test"));
+ var schema = workspace.ResolveJsonSchemaReference(refUri);
Assert.NotNull(schema);
Assert.Equal("The referenced one", schema.GetDescription());
@@ -90,6 +91,7 @@ public void OpenApiWorkspacesAllowDocumentsToReferenceEachOther_short()
var workspace = new OpenApiWorkspace();
var doc = new OpenApiDocument();
+ var reference = "#/components/schemas/test";
doc.CreatePathItem("/", p =>
{
p.Description = "Consumer";
@@ -98,14 +100,15 @@ public void OpenApiWorkspacesAllowDocumentsToReferenceEachOther_short()
{
re.Description = "Success";
re.CreateContent("application/json", co =>
- co.Schema = new JsonSchemaBuilder().Ref("test").Build()
+ co.Schema = new JsonSchemaBuilder().Ref(reference).Build()
);
})
);
});
+ var refUri = new Uri("https://registry" + reference.Split('#').LastOrDefault());
workspace.AddDocument("root", doc);
- workspace.AddDocument("common", CreateCommonDocument());
+ workspace.AddDocument("common", CreateCommonDocument(refUri));
var errors = doc.ResolveReferences();
Assert.Empty(errors);
@@ -178,9 +181,9 @@ public void OpenApiWorkspacesCanResolveReferencesToDocumentFragmentsWithJsonPoin
}
// Test artifacts
- private static OpenApiDocument CreateCommonDocument()
+ private static OpenApiDocument CreateCommonDocument(Uri refUri)
{
- return new()
+ var doc = new OpenApiDocument()
{
Components = new()
{
@@ -189,6 +192,13 @@ private static OpenApiDocument CreateCommonDocument()
}
}
};
+
+ foreach(var schema in doc.Components.Schemas)
+ {
+ SchemaRegistry.Global.Register(refUri, schema.Value);
+ }
+
+ return doc;
}
}