Skip to content

Commit dda0fe4

Browse files
Change IOpenApiReferenceable.ResolveReference method to using the JsonPointer class rather than a string for the JSON pointer argument
1 parent e3ca80e commit dda0fe4

File tree

4 files changed

+25
-36
lines changed

4 files changed

+25
-36
lines changed

src/Microsoft.OpenApi/Extensions/OpenApiReferencableExtensions.cs

Lines changed: 17 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -16,51 +16,46 @@ namespace Microsoft.OpenApi.Extensions
1616
public static class OpenApiReferencableExtensions
1717
{
1818
/// <summary>
19-
/// TODO: tmpDbg comment
19+
/// Resolves a JSON Pointer with respect to an element, returning the referenced element.
2020
/// </summary>
2121
/// <param name="element">The referencable Open API element on which to apply the JSON pointer</param>
22-
/// <param name="jsonPointer">a JSON Pointer [RFC 6901](https://tools.ietf.org/html/rfc6901).</param>
22+
/// <param name="pointer">a JSON Pointer [RFC 6901](https://tools.ietf.org/html/rfc6901).</param>
2323
/// <returns>The element pointed to by the JSON pointer.</returns>
24-
public static IOpenApiReferenceable ResolveReference(this IOpenApiReferenceable element, string jsonPointer)
24+
public static IOpenApiReferenceable ResolveReference(this IOpenApiReferenceable element, JsonPointer pointer)
2525
{
26-
if (jsonPointer == "/")
26+
if (!pointer.Tokens.Any())
2727
{
2828
return element;
2929
}
30-
if (string.IsNullOrEmpty(jsonPointer))
31-
{
32-
throw new OpenApiException(string.Format(SRResource.InvalidReferenceId, jsonPointer));
33-
}
34-
var jsonPointerTokens = jsonPointer.Split('/');
35-
var propertyName = jsonPointerTokens.ElementAtOrDefault(1);
36-
var mapKey = jsonPointerTokens.ElementAtOrDefault(2);
30+
var propertyName = pointer.Tokens.FirstOrDefault();
31+
var mapKey = pointer.Tokens.ElementAtOrDefault(1);
3732
try
3833
{
3934
if (element.GetType() == typeof(OpenApiHeader))
4035
{
41-
return ResolveReferenceOnHeaderElement((OpenApiHeader)element, propertyName, mapKey, jsonPointer);
36+
return ResolveReferenceOnHeaderElement((OpenApiHeader)element, propertyName, mapKey, pointer);
4237
}
4338
if (element.GetType() == typeof(OpenApiParameter))
4439
{
45-
return ResolveReferenceOnParameterElement((OpenApiParameter)element, propertyName, mapKey, jsonPointer);
40+
return ResolveReferenceOnParameterElement((OpenApiParameter)element, propertyName, mapKey, pointer);
4641
}
4742
if (element.GetType() == typeof(OpenApiResponse))
4843
{
49-
return ResolveReferenceOnResponseElement((OpenApiResponse)element, propertyName, mapKey, jsonPointer);
44+
return ResolveReferenceOnResponseElement((OpenApiResponse)element, propertyName, mapKey, pointer);
5045
}
5146
}
5247
catch (KeyNotFoundException)
5348
{
54-
throw new OpenApiException(string.Format(SRResource.InvalidReferenceId, jsonPointer));
49+
throw new OpenApiException(string.Format(SRResource.InvalidReferenceId, pointer));
5550
}
56-
throw new OpenApiException(string.Format(SRResource.InvalidReferenceId, jsonPointer));
51+
throw new OpenApiException(string.Format(SRResource.InvalidReferenceId, pointer));
5752
}
5853

5954
private static IOpenApiReferenceable ResolveReferenceOnHeaderElement(
6055
OpenApiHeader headerElement,
6156
string propertyName,
6257
string mapKey,
63-
string jsonPointer)
58+
JsonPointer pointer)
6459
{
6560
switch (propertyName)
6661
{
@@ -69,15 +64,15 @@ private static IOpenApiReferenceable ResolveReferenceOnHeaderElement(
6964
case OpenApiConstants.Examples when mapKey != null:
7065
return headerElement.Examples[mapKey];
7166
default:
72-
throw new OpenApiException(string.Format(SRResource.InvalidReferenceId, jsonPointer));
67+
throw new OpenApiException(string.Format(SRResource.InvalidReferenceId, pointer));
7368
}
7469
}
7570

7671
private static IOpenApiReferenceable ResolveReferenceOnParameterElement(
7772
OpenApiParameter parameterElement,
7873
string propertyName,
7974
string mapKey,
80-
string jsonPointer)
75+
JsonPointer pointer)
8176
{
8277
switch (propertyName)
8378
{
@@ -86,15 +81,15 @@ private static IOpenApiReferenceable ResolveReferenceOnParameterElement(
8681
case OpenApiConstants.Examples when mapKey != null:
8782
return parameterElement.Examples[mapKey];
8883
default:
89-
throw new OpenApiException(string.Format(SRResource.InvalidReferenceId, jsonPointer));
84+
throw new OpenApiException(string.Format(SRResource.InvalidReferenceId, pointer));
9085
}
9186
}
9287

9388
private static IOpenApiReferenceable ResolveReferenceOnResponseElement(
9489
OpenApiResponse responseElement,
9590
string propertyName,
9691
string mapKey,
97-
string jsonPointer)
92+
JsonPointer pointer)
9893
{
9994
switch (propertyName)
10095
{
@@ -103,7 +98,7 @@ private static IOpenApiReferenceable ResolveReferenceOnResponseElement(
10398
case OpenApiConstants.Links when mapKey != null:
10499
return responseElement.Links[mapKey];
105100
default:
106-
throw new OpenApiException(string.Format(SRResource.InvalidReferenceId, jsonPointer));
101+
throw new OpenApiException(string.Format(SRResource.InvalidReferenceId, pointer));
107102
}
108103
}
109104
}

src/Microsoft.OpenApi/JsonPointer.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@ public class JsonPointer
1717
/// <param name="pointer">Pointer as string.</param>
1818
public JsonPointer(string pointer)
1919
{
20-
Tokens = pointer.Split('/').Skip(1).Select(Decode).ToArray();
20+
Tokens = string.IsNullOrEmpty(pointer) || pointer == "/"
21+
? new string[0]
22+
: pointer.Split('/').Skip(1).Select(Decode).ToArray();
2123
}
2224

2325
/// <summary>

src/Microsoft.OpenApi/Services/OpenApiWorkspace.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ public IOpenApiReferenceable ResolveReference(OpenApiReference reference)
121121
}
122122
else if (_fragments.TryGetValue(new Uri(BaseUrl, reference.ExternalResource), out var fragment))
123123
{
124-
var jsonPointer = $"/{reference.Id ?? string.Empty}";
124+
var jsonPointer = new JsonPointer($"/{reference.Id ?? string.Empty}");
125125
return fragment.ResolveReference(jsonPointer);
126126
}
127127
return null;

test/Microsoft.OpenApi.Tests/Workspaces/OpenApiReferencableTests.cs

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ public class OpenApiReferencableTests
6868
new object[] { _responseFragment, "/links/link1", _responseFragment.Links["link1"] },
6969
new object[] { _schemaFragment, "/", _schemaFragment},
7070
new object[] { _securitySchemeFragment, "/", _securitySchemeFragment},
71-
new object[] { _tagFragment, "/", _tagFragment},
71+
new object[] { _tagFragment, "/", _tagFragment}
7272
};
7373

7474
[Theory]
@@ -79,7 +79,7 @@ public void ResolveReferenceCanResolveValidJsonPointers(
7979
IOpenApiElement expectedResolvedElement)
8080
{
8181
// Act
82-
var actualResolvedElement = element.ResolveReference(jsonPointer);
82+
var actualResolvedElement = element.ResolveReference(new JsonPointer(jsonPointer));
8383

8484
// Assert
8585
Assert.Same(expectedResolvedElement, actualResolvedElement);
@@ -88,30 +88,22 @@ public void ResolveReferenceCanResolveValidJsonPointers(
8888
public static IEnumerable<object[]> ResolveReferenceShouldThrowOnInvalidReferenceIdTestData =>
8989
new List<object[]>
9090
{
91-
new object[] { _callbackFragment, null },
92-
new object[] { _callbackFragment, "" },
9391
new object[] { _callbackFragment, "/a" },
94-
new object[] { _headerFragment, null },
95-
new object[] { _headerFragment, "" },
9692
new object[] { _headerFragment, "/a" },
9793
new object[] { _headerFragment, "/examples" },
9894
new object[] { _headerFragment, "/examples/" },
9995
new object[] { _headerFragment, "/examples/a" },
100-
new object[] { _parameterFragment, null },
101-
new object[] { _parameterFragment, "" },
10296
new object[] { _parameterFragment, "/a" },
10397
new object[] { _parameterFragment, "/examples" },
10498
new object[] { _parameterFragment, "/examples/" },
10599
new object[] { _parameterFragment, "/examples/a" },
106-
new object[] { _responseFragment, null },
107-
new object[] { _responseFragment, "" },
108100
new object[] { _responseFragment, "/a" },
109101
new object[] { _responseFragment, "/headers" },
110102
new object[] { _responseFragment, "/headers/" },
111103
new object[] { _responseFragment, "/headers/a" },
112104
new object[] { _responseFragment, "/content" },
113105
new object[] { _responseFragment, "/content/" },
114-
new object[] { _responseFragment, "/content/a" },
106+
new object[] { _responseFragment, "/content/a" }
115107

116108
};
117109

@@ -120,7 +112,7 @@ public void ResolveReferenceCanResolveValidJsonPointers(
120112
public void ResolveReferenceShouldThrowOnInvalidReferenceId(IOpenApiReferenceable element, string jsonPointer)
121113
{
122114
// Act
123-
Action resolveReference = () => element.ResolveReference(jsonPointer);
115+
Action resolveReference = () => element.ResolveReference(new JsonPointer(jsonPointer));
124116

125117
// Assert
126118
var exception = Assert.Throws<OpenApiException>(resolveReference);

0 commit comments

Comments
 (0)