Skip to content

Commit 78bcdd4

Browse files
committed
Add validation rule (+ test) to create an error when a path parameter does not appear in the path.
1 parent 553061a commit 78bcdd4

File tree

2 files changed

+90
-0
lines changed

2 files changed

+90
-0
lines changed

src/Microsoft.OpenApi/Validations/Rules/OpenApiParameterRules.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,22 @@ public static class OpenApiParameterRules
9696
context.Exit();
9797
});
9898

99+
/// <summary>
100+
/// Validate that a path parameter should always appear in the path
101+
/// </summary>
102+
public static ValidationRule<OpenApiParameter> PathParameterShouldBeInThePath =>
103+
new ValidationRule<OpenApiParameter>(
104+
(context, parameter) =>
105+
{
106+
if (parameter.In == ParameterLocation.Path && !context.PathString.Contains("{" + parameter.Name + "}"))
107+
{
108+
context.Enter("in");
109+
context.CreateError(
110+
nameof(PathParameterShouldBeInThePath),
111+
$"Declared path parameter \"{parameter.Name}\" needs to be defined as a path parameter at either the path or operation level");
112+
context.Exit();
113+
}
114+
});
99115
// add more rule.
100116
}
101117
}

test/Microsoft.OpenApi.Tests/Validations/OpenApiParameterValidationTests.cs

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,5 +173,79 @@ public void ValidateExamplesShouldNotHaveDataTypeMismatchForSimpleSchema()
173173
"#/examples/example2/value"
174174
});
175175
}
176+
177+
[Fact]
178+
public void PathParameterNotInThePathShouldReturnAnError()
179+
{
180+
// Arrange
181+
IEnumerable<OpenApiError> errors;
182+
183+
var parameter = new OpenApiParameter()
184+
{
185+
Name = "parameter1",
186+
In = ParameterLocation.Path,
187+
Required = true,
188+
Schema = new OpenApiSchema()
189+
{
190+
Type = "string",
191+
}
192+
};
193+
194+
// Act
195+
var validator = new OpenApiValidator(ValidationRuleSet.GetDefaultRuleSet());
196+
validator.Enter("1");
197+
198+
var walker = new OpenApiWalker(validator);
199+
walker.Walk(parameter);
200+
201+
errors = validator.Errors;
202+
bool result = errors.Any();
203+
204+
// Assert
205+
result.Should().BeTrue();
206+
errors.OfType<OpenApiValidatorError>().Select(e => e.RuleName).Should().BeEquivalentTo(new[]
207+
{
208+
"PathParameterShouldBeInThePath"
209+
});
210+
errors.Select(e => e.Pointer).Should().BeEquivalentTo(new[]
211+
{
212+
"#/1/in"
213+
});
214+
}
215+
216+
[Fact]
217+
public void PathParameterInThePastShouldBeOk()
218+
{
219+
// Arrange
220+
IEnumerable<OpenApiError> errors;
221+
222+
var parameter = new OpenApiParameter()
223+
{
224+
Name = "parameter1",
225+
In = ParameterLocation.Path,
226+
Required = true,
227+
Schema = new OpenApiSchema()
228+
{
229+
Type = "string",
230+
}
231+
};
232+
233+
// Act
234+
var validator = new OpenApiValidator(ValidationRuleSet.GetDefaultRuleSet());
235+
validator.Enter("paths");
236+
validator.Enter("/{parameter1}");
237+
validator.Enter("get");
238+
validator.Enter("parameters");
239+
validator.Enter("1");
240+
241+
var walker = new OpenApiWalker(validator);
242+
walker.Walk(parameter);
243+
244+
errors = validator.Errors;
245+
bool result = errors.Any();
246+
247+
// Assert
248+
result.Should().BeFalse();
249+
}
176250
}
177251
}

0 commit comments

Comments
 (0)