Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Resolve #606: add schema naming convention validation #607

Merged
merged 1 commit into from
Sep 28, 2023
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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ The options file is described in json (example in `specs/options.json`), and has
|queryParamNamingConvention|string| `CamelCase`, `PascalCase`, `HyphenUpperCase`, `HyphenCase`, `UnderscoreCase`, `UnderscoreUpperCase`, `AnyCase` |(same as `parameterNamingConvention`)|Specific naming convention for query parameters [(note)](#parameter-naming-convention-hierarchy)|
|cookieParamNamingConvention|string| `CamelCase`, `PascalCase`, `HyphenUpperCase`, `HyphenCase`, `UnderscoreCase`, `UnderscoreUpperCase`, `AnyCase` |(same as `parameterNamingConvention`)|Specific naming convention for cookie parameters [(note)](#parameter-naming-convention-hierarchy)|
|headerNamingConvention|string| `CamelCase`, `PascalCase`, `HyphenUpperCase`, `HyphenCase`, `UnderscoreCase`, `UnderscoreUpperCase`, `AnyCase` |`UnderscoreUpperCase`|Naming convention for headers|
|schemaNamingConvention|string| `CamelCase`, `PascalCase`, `HyphenUpperCase`, `HyphenCase`, `UnderscoreCase`, `UnderscoreUpperCase`, `AnyCase` |`PascalCase`|Naming convention for schemas|
|propertyNamingConvention|string| `CamelCase`, `PascalCase`, `HyphenUpperCase`, `HyphenCase`, `UnderscoreCase`, `UnderscoreUpperCase`, `AnyCase` |`CamelCase`|Naming convention for properties|
|allowedModelProperties|array| `["_links", "_embedded"]`|`[]`|An array of property names that are authorised even if they do not match to the "propertyNamingConvention"|

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ private void validateNamingConventions(ValidatorParameters parameters) {
validateNamingConvention("header", parameters.getHeaderNamingConvention());
validateNamingConvention("parameter", parameters.getParameterNamingConvention());
validateNamingConvention("path", parameters.getPathNamingConvention());
validateNamingConvention("schema", parameters.getSchemaNamingConvention());
validateNamingConvention("property", parameters.getPropertyNamingConvention());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,8 @@ void shouldParseAllOptions() throws Exception {
ValidatorParameters.NamingConvention.UnderscoreUpperCase, parameters.getHeaderNamingConvention());
Assertions.assertEquals(
ValidatorParameters.NamingConvention.CamelCase, parameters.getParameterNamingConvention());
Assertions.assertEquals(
ValidatorParameters.NamingConvention.PascalCase, parameters.getSchemaNamingConvention());
Assertions.assertEquals(
ValidatorParameters.NamingConvention.CamelCase, parameters.getPropertyNamingConvention());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,11 @@ void defaultJsonFileContainsConstants() throws Exception {
+ ValidatorParameters.NamingConvention.CamelCase
+ NEXT_LINE_QUOTE
+ PREFIX
+ ValidatorParameters.SCHEMA_NAMING_CONVENTION
+ SEPARATOR_QUOTE
+ ValidatorParameters.NamingConvention.PascalCase
+ NEXT_LINE_QUOTE
+ PREFIX
+ ValidatorParameters.PROPERTY_NAMING_CONVENTION
+ SEPARATOR_QUOTE
+ ValidatorParameters.NamingConvention.CamelCase
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,21 @@ void throwsIllegalArgumentException() {
}
}

@Nested
class GivenInvalidSchemaNamingConvention {
@BeforeEach
void init() throws ParseException {
commandLine = parser.parse(options, new String[] {
"-s", SRC_TEST_RESOURCES_SOME_YAML, "-o", "src/test/resources/invalidSchemaNamingConvention.json"
});
}

@Test
void throwsIllegalArgumentException() {
assertThrowsIllegalArgumentExceptionWithExceptedMessage("Invalid schemaNamingConvention", commandLine);
}
}

@Nested
class GivenInvalidPropertyNamingConvention {
@BeforeEach
Expand Down
1 change: 1 addition & 0 deletions cli/src/test/resources/default.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,6 @@
"pathNamingConvention": "HyphenCase",
"headerNamingConvention": "UnderscoreUpperCase",
"parameterNamingConvention": "CamelCase",
"schemaNamingConvention": "PascalCase",
"propertyNamingConvention": "CamelCase"
}
3 changes: 3 additions & 0 deletions cli/src/test/resources/invalidSchemaNamingConvention.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"schemaNamingConvention": "Wrong naming convention"
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ public class OpenAPIStyleValidatorTask extends DefaultTask {
private NamingConvention pathNamingConvention = NamingConvention.HyphenCase;
private NamingConvention parameterNamingConvention = NamingConvention.CamelCase;
private NamingConvention headerNamingConvention = NamingConvention.UnderscoreUpperCase;
private NamingConvention schemaNamingConvention = NamingConvention.PascalCase;
private NamingConvention propertyNamingConvention = NamingConvention.CamelCase;
private NamingConvention queryParamNamingConvention = NamingConvention.CamelCase;
private NamingConvention pathParamNamingConvention = NamingConvention.CamelCase;
Expand Down Expand Up @@ -160,22 +161,27 @@ public void setHeaderNamingConvention(NamingConvention headerNamingConvention) {
this.headerNamingConvention = headerNamingConvention;
}

@Option(option = ValidatorParameters.SCHEMA_NAMING_CONVENTION, description = "Naming convention for schemas")
public void setSchemaNamingConvention(NamingConvention schemaNamingConvention) {
this.schemaNamingConvention = schemaNamingConvention;
}

@Option(option = ValidatorParameters.PROPERTY_NAMING_CONVENTION, description = "Naming convention for properties")
public void setPropertyNamingConvention(NamingConvention propertyNamingConvention) {
this.propertyNamingConvention = propertyNamingConvention;
}

@Option(option = ValidatorParameters.PROPERTY_NAMING_CONVENTION, description = "Naming convention for path parameters")
@Option(option = ValidatorParameters.PATH_PARAM_NAMING_CONVENTION, description = "Naming convention for path parameters")
public void setPathParamNamingConvention(NamingConvention pathParamNamingConvention) {
this.pathParamNamingConvention = pathParamNamingConvention;
}

@Option(option = ValidatorParameters.PROPERTY_NAMING_CONVENTION, description = "Naming convention for query parameters")
@Option(option = ValidatorParameters.QUERY_PARAM_NAMING_CONVENTION, description = "Naming convention for query parameters")
public void setQueryParamNamingConvention(NamingConvention queryParamNamingConvention) {
this.queryParamNamingConvention = queryParamNamingConvention;
}

@Option(option = ValidatorParameters.PROPERTY_NAMING_CONVENTION, description = "Naming convention for cookie parameters")
@Option(option = ValidatorParameters.COOKIE_PARAM_NAMING_CONVENTION, description = "Naming convention for cookie parameters")
public void setCookieParamNamingConvention(NamingConvention cookieParamNamingConvention) {
this.cookieParamNamingConvention = cookieParamNamingConvention;
}
Expand All @@ -198,6 +204,7 @@ public ValidatorParameters createValidatorParameters() {
parameters.setPathNamingConvention(pathNamingConvention);
parameters.setParameterNamingConvention(parameterNamingConvention);
parameters.setHeaderNamingConvention(headerNamingConvention);
parameters.setSchemaNamingConvention(schemaNamingConvention);
parameters.setPropertyNamingConvention(propertyNamingConvention);
parameters.setPathParamNamingConvention(pathParamNamingConvention);
parameters.setQueryParamNamingConvention(queryParamNamingConvention);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,15 @@ private void validateNaming() {
if (openAPI.getComponents() != null && openAPI.getComponents().getSchemas() != null) {
for (String definition : openAPI.getComponents().getSchemas().keySet()) {
Schema model = openAPI.getComponents().getSchemas().get(definition);
boolean isSchemaNameValid =
namingValidator.isNamingValid(definition, parameters.getSchemaNamingConvention());
if (!isSchemaNameValid) {
errorAggregator.logModelBadNaming(
definition,
"schema",
parameters.getSchemaNamingConvention().getDesignation(),
definition);
}

if (model.getProperties() != null) {
for (Map.Entry<String, Schema> entry :
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ public class ValidatorParameters {
public static final String PATH_NAMING_CONVENTION = "pathNamingConvention";
public static final String PARAMETER_NAMING_CONVENTION = "parameterNamingConvention";
public static final String HEADER_NAMING_CONVENTION = "headerNamingConvention";
public static final String SCHEMA_NAMING_CONVENTION = "schemaNamingConvention";
public static final String PROPERTY_NAMING_CONVENTION = "propertyNamingConvention";
public static final String QUERY_PARAM_NAMING_CONVENTION = "queryParamNamingConvention";
public static final String PATH_PARAM_NAMING_CONVENTION = "pathParamNamingConvention";
Expand Down Expand Up @@ -72,6 +73,7 @@ public String getDesignation() {
private NamingConvention pathNamingConvention = NamingConvention.HyphenCase;
private NamingConvention parameterNamingConvention = NamingConvention.CamelCase;
private NamingConvention headerNamingConvention = NamingConvention.UnderscoreUpperCase;
private NamingConvention schemaNamingConvention = NamingConvention.PascalCase;
private NamingConvention propertyNamingConvention = NamingConvention.CamelCase;
private NamingConvention queryParamNamingConvention = NamingConvention.CamelCase;
private NamingConvention pathParamNamingConvention = NamingConvention.CamelCase;
Expand Down Expand Up @@ -143,6 +145,10 @@ public NamingConvention getHeaderNamingConvention() {
return headerNamingConvention;
}

public NamingConvention getSchemaNamingConvention() {
return schemaNamingConvention;
}

public NamingConvention getPropertyNamingConvention() {
return propertyNamingConvention;
}
Expand Down Expand Up @@ -243,6 +249,11 @@ public ValidatorParameters setHeaderNamingConvention(NamingConvention headerNami
return this;
}

public ValidatorParameters setSchemaNamingConvention(NamingConvention schemaNamingConvention) {
this.schemaNamingConvention = schemaNamingConvention;
return this;
}

public ValidatorParameters setPropertyNamingConvention(NamingConvention propertyNamingConvention) {
this.propertyNamingConvention = propertyNamingConvention;
return this;
Expand Down Expand Up @@ -311,6 +322,7 @@ public String toString() {
+ "pathNamingConvention=%s, "
+ "headerNamingConvention=%s, "
+ "parameterNamingConvention=%s, "
+ "schemaNamingConvention=%s, "
+ "propertyNamingConvention=%s, "
+ "queryParamNamingConvention=%s, "
+ "pathParamNamingConvention=%s, "
Expand All @@ -332,6 +344,7 @@ public String toString() {
pathNamingConvention,
headerNamingConvention,
parameterNamingConvention,
schemaNamingConvention,
propertyNamingConvention,
queryParamNamingConvention,
pathParamNamingConvention,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,25 @@ void shouldReportHeaderNamingConventionError() {
errors.get(0).toString()));
}

@Test
void shouldReportSchemaNamingConventionError() {
OpenAPI openAPI = createValidOpenAPI();

OpenApiSpecStyleValidator validator = new OpenApiSpecStyleValidator(openAPI);

ValidatorParameters validatorParams = new ValidatorParameters();
validatorParams.setSchemaNamingConvention(NamingConvention.HyphenUpperCase);
List<StyleError> errors = validator.validate(validatorParams);
Assertions.assertAll(
() -> assertEquals(2, errors.size()),
() -> assertEquals(
"*ERROR* in model FooSchema 'FooSchema' -> schema should be in Hyphen-Upper-Case",
errors.get(0).toString()),
() -> assertEquals(
"*ERROR* in model BazSchema 'BazSchema' -> schema should be in Hyphen-Upper-Case",
errors.get(1).toString()));
}

@Test
void shouldReportPropertyNamingConventionError() {
OpenAPI openAPI = createValidOpenAPI();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ void validateDefaultValues() {
() -> assertEquals(
ValidatorParameters.NamingConvention.UnderscoreUpperCase,
parameters.getHeaderNamingConvention()),
() -> assertEquals(
ValidatorParameters.NamingConvention.PascalCase, parameters.getSchemaNamingConvention()),
() -> assertEquals(
ValidatorParameters.NamingConvention.CamelCase, parameters.getPropertyNamingConvention()),
() -> assertEquals(
Expand All @@ -55,6 +57,7 @@ void testAllGetterSetters() {
.setPathNamingConvention(ValidatorParameters.NamingConvention.CamelCase)
.setParameterNamingConvention(ValidatorParameters.NamingConvention.CamelCase)
.setHeaderNamingConvention(ValidatorParameters.NamingConvention.UnderscoreUpperCase)
.setSchemaNamingConvention(ValidatorParameters.NamingConvention.PascalCase)
.setPropertyNamingConvention(ValidatorParameters.NamingConvention.CamelCase)
.setQueryParamNamingConvention(ValidatorParameters.NamingConvention.CamelCase)
.setPathParamNamingConvention(ValidatorParameters.NamingConvention.CamelCase)
Expand All @@ -81,6 +84,8 @@ void testAllGetterSetters() {
() -> assertEquals(
ValidatorParameters.NamingConvention.UnderscoreUpperCase,
parameters.getHeaderNamingConvention()),
() -> assertEquals(
ValidatorParameters.NamingConvention.PascalCase, parameters.getSchemaNamingConvention()),
() -> assertEquals(
ValidatorParameters.NamingConvention.CamelCase, parameters.getPropertyNamingConvention()),
() -> assertEquals(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ public class OpenAPIStyleValidatorMojo extends AbstractMojo {
@Parameter(property = ValidatorParameters.HEADER_NAMING_CONVENTION, defaultValue = "UnderscoreUpperCase")
private NamingConvention headerNamingConvention = NamingConvention.UnderscoreUpperCase;

@Parameter(property = ValidatorParameters.SCHEMA_NAMING_CONVENTION, defaultValue = "PascalCase")
private NamingConvention schemaNamingConvention = NamingConvention.PascalCase;

@Parameter(property = ValidatorParameters.PROPERTY_NAMING_CONVENTION, defaultValue = "CamelCase")
private NamingConvention propertyNamingConvention = NamingConvention.CamelCase;

Expand Down Expand Up @@ -128,6 +131,7 @@ public ValidatorParameters createValidatorParameters() {
parameters.setPathNamingConvention(pathNamingConvention);
parameters.setHeaderNamingConvention(headerNamingConvention);
parameters.setParameterNamingConvention(parameterNamingConvention);
parameters.setSchemaNamingConvention(schemaNamingConvention);
parameters.setPropertyNamingConvention(propertyNamingConvention);
parameters.setPathParamNamingConvention(pathParamNamingConvention);
parameters.setQueryParamNamingConvention(queryParamNamingConvention);
Expand Down
3 changes: 2 additions & 1 deletion maven-plugin/src/test/resources/projects/testDefault/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
<pathNamingConvention>HyphenCase</pathNamingConvention>
<headerNamingConvention>UnderscoreUpperCase</headerNamingConvention>
<parameterNamingConvention>CamelCase</parameterNamingConvention>
<schemaNamingConvention>PascalCase</schemaNamingConvention>
<propertyNamingConvention>CamelCase</propertyNamingConvention>
</configuration>
<executions>
Expand All @@ -43,4 +44,4 @@
</plugin>
</plugins>
</build>
</project>
</project>
5 changes: 3 additions & 2 deletions specs/options.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@
"ignoreHeaderXNaming": true,
"pathNamingConvention": "HyphenCase",
"parameterNamingConvention": "CamelCase",
"schemaNamingConvention": "PascalCase",
"propertyNamingConvention": "CamelCase",
"queryParamNamingConvention": "CamelCase",
"pathParamNamingConvention": "HyphenCase",
"cookieParamNamingConvention": "CamelCase"
"pathParamNamingConvention": "HyphenCase",
"cookieParamNamingConvention": "CamelCase"
}