Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion src/Microsoft.OpenApi/Services/OpenApiWorkspace.cs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@
/// Registers a document's components into the workspace
/// </summary>
/// <param name="document"></param>
public void RegisterComponents(OpenApiDocument document)

Check warning on line 84 in src/Microsoft.OpenApi/Services/OpenApiWorkspace.cs

View workflow job for this annotation

GitHub Actions / Build

Refactor this method to reduce its Cognitive Complexity from 71 to the 15 allowed.

Check warning on line 84 in src/Microsoft.OpenApi/Services/OpenApiWorkspace.cs

View workflow job for this annotation

GitHub Actions / Build

Refactor this method to reduce its Cognitive Complexity from 71 to the 15 allowed.

Check warning on line 84 in src/Microsoft.OpenApi/Services/OpenApiWorkspace.cs

View workflow job for this annotation

GitHub Actions / Build

Refactor this method to reduce its Cognitive Complexity from 71 to the 15 allowed.
{
if (document?.Components == null) return;

Expand All @@ -94,8 +94,13 @@
foreach (var item in document.Components.Schemas)
{
if (item.Value == null) continue;
location = item.Value.Id ?? baseUri + ReferenceType.Schema.GetDisplayName() + ComponentSegmentSeparator + item.Key;
location = baseUri + ReferenceType.Schema.GetDisplayName() + ComponentSegmentSeparator + item.Key;
RegisterComponent(location, item.Value);

if (item.Value is not OpenApiSchemaReference && item.Value.Id is string schemaId && schemaId.Length > 0)
{
RegisterComponent(schemaId, item.Value);
}
}
}

Expand Down Expand Up @@ -290,7 +295,7 @@
/// <param name="value"></param>
public void AddDocumentId(string? key, Uri? value)
{
if (!string.IsNullOrEmpty(key) && key is not null && value is not null && !_documentsIdRegistry.ContainsKey(key))

Check warning on line 298 in src/Microsoft.OpenApi/Services/OpenApiWorkspace.cs

View workflow job for this annotation

GitHub Actions / Build

Change this condition so that it does not always evaluate to 'True'.

Check warning on line 298 in src/Microsoft.OpenApi/Services/OpenApiWorkspace.cs

View workflow job for this annotation

GitHub Actions / Build

Change this condition so that it does not always evaluate to 'True'.

Check warning on line 298 in src/Microsoft.OpenApi/Services/OpenApiWorkspace.cs

View workflow job for this annotation

GitHub Actions / Build

Change this condition so that it does not always evaluate to 'True'.
{
_documentsIdRegistry[key] = value;
}
Expand Down Expand Up @@ -393,7 +398,7 @@
return default;
}

internal static IOpenApiSchema? ResolveSubSchema(IOpenApiSchema schema, string[] pathSegments, Stack<IOpenApiSchema> visitedSchemas)

Check warning on line 401 in src/Microsoft.OpenApi/Services/OpenApiWorkspace.cs

View workflow job for this annotation

GitHub Actions / Build

Refactor this method to reduce its Cognitive Complexity from 21 to the 15 allowed.

Check warning on line 401 in src/Microsoft.OpenApi/Services/OpenApiWorkspace.cs

View workflow job for this annotation

GitHub Actions / Build

Refactor this method to reduce its Cognitive Complexity from 21 to the 15 allowed.
{
// Prevent infinite recursion in case of circular references
if (visitedSchemas.Contains(schema))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,75 @@ public async Task ParseLocalReferenceToJsonSchemaResourceWorks()
Assert.Equal(JsonSchemaType.Object | JsonSchemaType.Null, schema.Type);
}

[Fact]
public async Task ParseExternalSchemaReferencedDirectlyAndReExportedAtRootWorks()
{
var tempDirectory = Path.Join(Path.GetTempPath(), Guid.NewGuid().ToString("N"));
Directory.CreateDirectory(tempDirectory);

var rootPath = Path.Join(tempDirectory, "root.yaml");
var sharedPath = Path.Join(tempDirectory, "shared.yaml");

await File.WriteAllTextAsync(rootPath,
@"openapi: 3.1.0
info:
title: T
version: 1.0.0
paths:
/a:
get:
responses:
'200':
description: ok
content:
application/json:
schema:
type: object
properties:
meta:
$ref: './shared.yaml#/Leaf'
components:
schemas:
Leaf:
$ref: './shared.yaml#/Leaf'
");

await File.WriteAllTextAsync(sharedPath,
@"Leaf:
type: object
properties:
x:
type: string
y:
type: integer
");

try
{
var settings = new OpenApiReaderSettings
{
LoadExternalRefs = true,
BaseUrl = new Uri(rootPath),
};
settings.AddYamlReader();

var result = await OpenApiDocument.LoadAsync(rootPath, settings);
var responseSchema = result.Document.Paths["/a"].Operations[HttpMethod.Get].Responses["200"].Content["application/json"].Schema;
var metaSchema = responseSchema.Properties["meta"];
var leafSchema = result.Document.Components.Schemas["Leaf"];

Assert.NotNull(result.Document);
Assert.DoesNotContain(result.Diagnostic.Errors, error => error.Message.Contains("Circular reference detected while resolving schema", StringComparison.Ordinal));
Assert.DoesNotContain(result.Diagnostic.Warnings, warning => warning.Message.Contains("Circular reference detected while resolving schema", StringComparison.Ordinal));
Assert.IsType<OpenApiSchemaReference>(metaSchema);
Assert.IsType<OpenApiSchemaReference>(leafSchema);
}
finally
{
Directory.Delete(tempDirectory, true);
}
}

[Fact]
public void ResolveSubSchema_ShouldTraverseKnownKeywords()
{
Expand Down
Loading