diff --git a/api/build.gradle b/api/build.gradle new file mode 100644 index 00000000..5ce9cbfb --- /dev/null +++ b/api/build.gradle @@ -0,0 +1,59 @@ +plugins { + id "com.diffplug.spotless" version "6.9.1" +} + +dependencies { + implementation 'org.eclipse.microprofile.openapi:microprofile-openapi-api:3.0' + testImplementation 'org.slf4j:slf4j-jdk14:2.0.0' + testImplementation 'org.openapitools.empoa:empoa-simple-models-impl:2.0.0' + testImplementation 'nl.jqno.equalsverifier:equalsverifier:3.10.1' + implementation group: 'org.apache.commons', name: 'commons-lang3', version: '3.12.0' + implementation group: 'org.reflections', name: 'reflections', version: '0.10.2' +} + +java { + withJavadocJar() + withSourcesJar() +} + +spotless { + java { + removeUnusedImports() + trimTrailingWhitespace() + palantirJavaFormat() + } +} + +publishing { + publications { + mavenJava(MavenPublication) { + artifactId = 'openapi-style-validator-api' + pom { + name = 'OpenAPI Style Validator - api' + description = 'module to expose API for writing custom rules to validate the style and standards of an OpenAPI specification' + packaging = 'jar' + url = 'https://openapitools.github.io/openapi-style-validator/' + inceptionYear = "2019" + licenses { + license { + name = 'Apache 2.0 License' + url = 'http://www.apache.org/licenses/LICENSE-2.0' + } + } + developers { + developer { + id = 'JFCote' + name = 'Jean-Francois Cote' + email = 'jcote@stingray.com' + } + } + scm { + connection = 'scm:git:https://github.com/openapitools/openapi-style-validator.git' + developerConnection = 'scm:git:https://github.com/openapitools/openapi-style-validator.git' + url = 'https://github.com/openapitools/openapi-style-validator/' + } + } + from components.java + } + } +} diff --git a/api/src/main/java/org/openapitools/openapistylevalidator/api/IRule.java b/api/src/main/java/org/openapitools/openapistylevalidator/api/IRule.java new file mode 100644 index 00000000..6aafd4b4 --- /dev/null +++ b/api/src/main/java/org/openapitools/openapistylevalidator/api/IRule.java @@ -0,0 +1,14 @@ +package org.openapitools.openapistylevalidator.api; + +import java.util.List; +import org.eclipse.microprofile.openapi.models.OpenAPI; +import org.openapitools.openapistylevalidator.error.StyleError; + +public interface IRule { + + String name(); + + String description(); + + List execute(OpenAPI api); +} diff --git a/api/src/main/java/org/openapitools/openapistylevalidator/api/IRuleManager.java b/api/src/main/java/org/openapitools/openapistylevalidator/api/IRuleManager.java new file mode 100644 index 00000000..16074f0b --- /dev/null +++ b/api/src/main/java/org/openapitools/openapistylevalidator/api/IRuleManager.java @@ -0,0 +1,8 @@ +package org.openapitools.openapistylevalidator.api; + +import java.util.List; + +public interface IRuleManager { + + List loadRules(); +} diff --git a/api/src/main/java/org/openapitools/openapistylevalidator/api/NamingConvention.java b/api/src/main/java/org/openapitools/openapistylevalidator/api/NamingConvention.java new file mode 100644 index 00000000..7a597b06 --- /dev/null +++ b/api/src/main/java/org/openapitools/openapistylevalidator/api/NamingConvention.java @@ -0,0 +1,24 @@ +package org.openapitools.openapistylevalidator.api; + +public enum NamingConvention { + UnderscoreCase("underscore_case"), + UnderscoreUpperCase("UNDERSCORE_UPPER_CASE"), + CamelCase("camelCase"), + HyphenCase("hyphen-case"), + AnyCase("AnyCase"), + HyphenUpperCase("Hyphen-Upper-Case"); + + private final String designation; + + NamingConvention(String appelation) { + this.designation = appelation; + } + + /** + * Method to get the name of the naming convention to be used in the reports + * @return the name of the naming convention + */ + public String getDesignation() { + return designation; + } +} diff --git a/api/src/main/java/org/openapitools/openapistylevalidator/api/RuleParameterProvider.java b/api/src/main/java/org/openapitools/openapistylevalidator/api/RuleParameterProvider.java new file mode 100644 index 00000000..e1e583fb --- /dev/null +++ b/api/src/main/java/org/openapitools/openapistylevalidator/api/RuleParameterProvider.java @@ -0,0 +1,12 @@ +package org.openapitools.openapistylevalidator.api; + +public interface RuleParameterProvider { + + NamingConvention pathNamingConvention(); + + NamingConvention parameterNamingConvention(); + + NamingConvention headerNamingConvention(); + + NamingConvention propertyNamingConvention(); +} diff --git a/lib/src/main/java/org/openapitools/openapistylevalidator/styleerror/GenericStyleError.java b/api/src/main/java/org/openapitools/openapistylevalidator/error/GenericStyleError.java similarity index 96% rename from lib/src/main/java/org/openapitools/openapistylevalidator/styleerror/GenericStyleError.java rename to api/src/main/java/org/openapitools/openapistylevalidator/error/GenericStyleError.java index 539971b1..ec8ed3dc 100644 --- a/lib/src/main/java/org/openapitools/openapistylevalidator/styleerror/GenericStyleError.java +++ b/api/src/main/java/org/openapitools/openapistylevalidator/error/GenericStyleError.java @@ -1,4 +1,4 @@ -package org.openapitools.openapistylevalidator.styleerror; +package org.openapitools.openapistylevalidator.error; import java.util.Objects; diff --git a/lib/src/main/java/org/openapitools/openapistylevalidator/styleerror/ModelNamingStyleError.java b/api/src/main/java/org/openapitools/openapistylevalidator/error/ModelNamingStyleError.java similarity index 94% rename from lib/src/main/java/org/openapitools/openapistylevalidator/styleerror/ModelNamingStyleError.java rename to api/src/main/java/org/openapitools/openapistylevalidator/error/ModelNamingStyleError.java index f7df4dfd..af70072b 100644 --- a/lib/src/main/java/org/openapitools/openapistylevalidator/styleerror/ModelNamingStyleError.java +++ b/api/src/main/java/org/openapitools/openapistylevalidator/error/ModelNamingStyleError.java @@ -1,4 +1,4 @@ -package org.openapitools.openapistylevalidator.styleerror; +package org.openapitools.openapistylevalidator.error; import java.util.Objects; diff --git a/lib/src/main/java/org/openapitools/openapistylevalidator/styleerror/ModelStyleError.java b/api/src/main/java/org/openapitools/openapistylevalidator/error/ModelStyleError.java similarity index 95% rename from lib/src/main/java/org/openapitools/openapistylevalidator/styleerror/ModelStyleError.java rename to api/src/main/java/org/openapitools/openapistylevalidator/error/ModelStyleError.java index d3ada4d5..787c6108 100644 --- a/lib/src/main/java/org/openapitools/openapistylevalidator/styleerror/ModelStyleError.java +++ b/api/src/main/java/org/openapitools/openapistylevalidator/error/ModelStyleError.java @@ -1,4 +1,4 @@ -package org.openapitools.openapistylevalidator.styleerror; +package org.openapitools.openapistylevalidator.error; import java.util.Objects; diff --git a/lib/src/main/java/org/openapitools/openapistylevalidator/styleerror/OperationNamingStyleError.java b/api/src/main/java/org/openapitools/openapistylevalidator/error/OperationNamingStyleError.java similarity index 96% rename from lib/src/main/java/org/openapitools/openapistylevalidator/styleerror/OperationNamingStyleError.java rename to api/src/main/java/org/openapitools/openapistylevalidator/error/OperationNamingStyleError.java index 2c87f956..24c65f44 100644 --- a/lib/src/main/java/org/openapitools/openapistylevalidator/styleerror/OperationNamingStyleError.java +++ b/api/src/main/java/org/openapitools/openapistylevalidator/error/OperationNamingStyleError.java @@ -1,4 +1,4 @@ -package org.openapitools.openapistylevalidator.styleerror; +package org.openapitools.openapistylevalidator.error; import java.util.Objects; import org.eclipse.microprofile.openapi.models.PathItem; diff --git a/lib/src/main/java/org/openapitools/openapistylevalidator/styleerror/OperationStyleError.java b/api/src/main/java/org/openapitools/openapistylevalidator/error/OperationStyleError.java similarity index 95% rename from lib/src/main/java/org/openapitools/openapistylevalidator/styleerror/OperationStyleError.java rename to api/src/main/java/org/openapitools/openapistylevalidator/error/OperationStyleError.java index 5fcd1e2f..0468c0ad 100644 --- a/lib/src/main/java/org/openapitools/openapistylevalidator/styleerror/OperationStyleError.java +++ b/api/src/main/java/org/openapitools/openapistylevalidator/error/OperationStyleError.java @@ -1,4 +1,4 @@ -package org.openapitools.openapistylevalidator.styleerror; +package org.openapitools.openapistylevalidator.error; import java.util.Objects; import org.eclipse.microprofile.openapi.models.PathItem; diff --git a/api/src/main/java/org/openapitools/openapistylevalidator/error/StyleCheckSection.java b/api/src/main/java/org/openapitools/openapistylevalidator/error/StyleCheckSection.java new file mode 100644 index 00000000..2cdc2317 --- /dev/null +++ b/api/src/main/java/org/openapitools/openapistylevalidator/error/StyleCheckSection.java @@ -0,0 +1,9 @@ +package org.openapitools.openapistylevalidator.error; + +public enum StyleCheckSection { + APIInfo, + Operations, + Models, + Naming, + OpenAPI, +} diff --git a/lib/src/main/java/org/openapitools/openapistylevalidator/styleerror/StyleError.java b/api/src/main/java/org/openapitools/openapistylevalidator/error/StyleError.java similarity index 74% rename from lib/src/main/java/org/openapitools/openapistylevalidator/styleerror/StyleError.java rename to api/src/main/java/org/openapitools/openapistylevalidator/error/StyleError.java index 29a8280a..c595dddb 100644 --- a/lib/src/main/java/org/openapitools/openapistylevalidator/styleerror/StyleError.java +++ b/api/src/main/java/org/openapitools/openapistylevalidator/error/StyleError.java @@ -1,15 +1,7 @@ -package org.openapitools.openapistylevalidator.styleerror; +package org.openapitools.openapistylevalidator.error; public class StyleError { - public enum StyleCheckSection { - APIInfo, - Operations, - Models, - Naming, - OpenAPI, - } - final StyleCheckSection styleCheckSection; final String fieldNames; final String description; diff --git a/lib/src/test/java/org/openapitools/openapistylevalidator/styleerror/GenericStyleErrorTest.java b/api/src/test/java/org/openapitools/openapistylevalidator/error/GenericStyleErrorTest.java similarity index 84% rename from lib/src/test/java/org/openapitools/openapistylevalidator/styleerror/GenericStyleErrorTest.java rename to api/src/test/java/org/openapitools/openapistylevalidator/error/GenericStyleErrorTest.java index b65703af..f3683663 100644 --- a/lib/src/test/java/org/openapitools/openapistylevalidator/styleerror/GenericStyleErrorTest.java +++ b/api/src/test/java/org/openapitools/openapistylevalidator/error/GenericStyleErrorTest.java @@ -1,4 +1,4 @@ -package org.openapitools.openapistylevalidator.styleerror; +package org.openapitools.openapistylevalidator.error; import nl.jqno.equalsverifier.EqualsVerifier; import org.junit.jupiter.api.Test; diff --git a/lib/src/test/java/org/openapitools/openapistylevalidator/styleerror/ModelNamingStyleErrorTest.java b/api/src/test/java/org/openapitools/openapistylevalidator/error/ModelNamingStyleErrorTest.java similarity index 85% rename from lib/src/test/java/org/openapitools/openapistylevalidator/styleerror/ModelNamingStyleErrorTest.java rename to api/src/test/java/org/openapitools/openapistylevalidator/error/ModelNamingStyleErrorTest.java index a2f4d2c2..df1a76cf 100644 --- a/lib/src/test/java/org/openapitools/openapistylevalidator/styleerror/ModelNamingStyleErrorTest.java +++ b/api/src/test/java/org/openapitools/openapistylevalidator/error/ModelNamingStyleErrorTest.java @@ -1,4 +1,4 @@ -package org.openapitools.openapistylevalidator.styleerror; +package org.openapitools.openapistylevalidator.error; import nl.jqno.equalsverifier.EqualsVerifier; import org.junit.jupiter.api.Test; diff --git a/lib/src/test/java/org/openapitools/openapistylevalidator/styleerror/ModelStyleErrorTest.java b/api/src/test/java/org/openapitools/openapistylevalidator/error/ModelStyleErrorTest.java similarity index 93% rename from lib/src/test/java/org/openapitools/openapistylevalidator/styleerror/ModelStyleErrorTest.java rename to api/src/test/java/org/openapitools/openapistylevalidator/error/ModelStyleErrorTest.java index 770f65ad..63f24b3b 100644 --- a/lib/src/test/java/org/openapitools/openapistylevalidator/styleerror/ModelStyleErrorTest.java +++ b/api/src/test/java/org/openapitools/openapistylevalidator/error/ModelStyleErrorTest.java @@ -1,4 +1,4 @@ -package org.openapitools.openapistylevalidator.styleerror; +package org.openapitools.openapistylevalidator.error; import static org.junit.jupiter.api.Assertions.assertEquals; diff --git a/lib/src/test/java/org/openapitools/openapistylevalidator/styleerror/OperationNamingStyleErrorTest.java b/api/src/test/java/org/openapitools/openapistylevalidator/error/OperationNamingStyleErrorTest.java similarity index 85% rename from lib/src/test/java/org/openapitools/openapistylevalidator/styleerror/OperationNamingStyleErrorTest.java rename to api/src/test/java/org/openapitools/openapistylevalidator/error/OperationNamingStyleErrorTest.java index 245ea870..54d29dac 100644 --- a/lib/src/test/java/org/openapitools/openapistylevalidator/styleerror/OperationNamingStyleErrorTest.java +++ b/api/src/test/java/org/openapitools/openapistylevalidator/error/OperationNamingStyleErrorTest.java @@ -1,4 +1,4 @@ -package org.openapitools.openapistylevalidator.styleerror; +package org.openapitools.openapistylevalidator.error; import nl.jqno.equalsverifier.EqualsVerifier; import org.junit.jupiter.api.Test; diff --git a/lib/src/test/java/org/openapitools/openapistylevalidator/styleerror/OperationStyleErrorTest.java b/api/src/test/java/org/openapitools/openapistylevalidator/error/OperationStyleErrorTest.java similarity index 85% rename from lib/src/test/java/org/openapitools/openapistylevalidator/styleerror/OperationStyleErrorTest.java rename to api/src/test/java/org/openapitools/openapistylevalidator/error/OperationStyleErrorTest.java index acfad389..52102d1d 100644 --- a/lib/src/test/java/org/openapitools/openapistylevalidator/styleerror/OperationStyleErrorTest.java +++ b/api/src/test/java/org/openapitools/openapistylevalidator/error/OperationStyleErrorTest.java @@ -1,4 +1,4 @@ -package org.openapitools.openapistylevalidator.styleerror; +package org.openapitools.openapistylevalidator.error; import nl.jqno.equalsverifier.EqualsVerifier; import org.junit.jupiter.api.Test; diff --git a/cli/build.gradle b/cli/build.gradle index 9335c367..b25c0d67 100644 --- a/cli/build.gradle +++ b/cli/build.gradle @@ -6,6 +6,7 @@ apply plugin: 'application' dependencies { implementation project(':openapi-style-validator-lib') + implementation project(':openapi-style-validator-api') implementation 'commons-cli:commons-cli:1.5.0' implementation 'org.slf4j:slf4j-jdk14:2.0.3' implementation 'io.swagger.parser.v3:swagger-parser:2.0.33' diff --git a/cli/src/main/java/org/openapitools/openapistylevalidator/cli/ObjectMapperProvider.java b/cli/src/main/java/org/openapitools/openapistylevalidator/cli/ObjectMapperProvider.java index 6b837d6a..f09a6baf 100644 --- a/cli/src/main/java/org/openapitools/openapistylevalidator/cli/ObjectMapperProvider.java +++ b/cli/src/main/java/org/openapitools/openapistylevalidator/cli/ObjectMapperProvider.java @@ -8,6 +8,7 @@ import com.fasterxml.jackson.databind.module.SimpleModule; import java.io.IOException; import org.openapitools.openapistylevalidator.ValidatorParameters; +import org.openapitools.openapistylevalidator.api.NamingConvention; class ObjectMapperProvider { @@ -22,17 +23,17 @@ ObjectMapper getOptionsObjectMapper() { optionsObjectMapper = new ObjectMapper() .registerModule(new SimpleModule("NamingConvention") - .addDeserializer(ValidatorParameters.NamingConvention.class, new NamingOptionsDeserializer())); + .addDeserializer(NamingConvention.class, new NamingOptionsDeserializer())); return optionsObjectMapper; } - private class NamingOptionsDeserializer extends JsonDeserializer { + private static class NamingOptionsDeserializer extends JsonDeserializer { @Override - public ValidatorParameters.NamingConvention deserialize(JsonParser parser, DeserializationContext ctxt) + public NamingConvention deserialize(JsonParser parser, DeserializationContext ctxt) throws IOException, JsonProcessingException { String name = parser.getText(); - ValidatorParameters.NamingConvention[] values = ValidatorParameters.NamingConvention.values(); - for (ValidatorParameters.NamingConvention value : values) { + NamingConvention[] values = NamingConvention.values(); + for (NamingConvention value : values) { if (value.name().equals(name)) { return value; } diff --git a/cli/src/main/java/org/openapitools/openapistylevalidator/cli/OptionManager.java b/cli/src/main/java/org/openapitools/openapistylevalidator/cli/OptionManager.java index 82f2db34..16efb5fd 100644 --- a/cli/src/main/java/org/openapitools/openapistylevalidator/cli/OptionManager.java +++ b/cli/src/main/java/org/openapitools/openapistylevalidator/cli/OptionManager.java @@ -11,6 +11,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.openapitools.openapistylevalidator.ValidatorParameters; +import org.openapitools.openapistylevalidator.api.NamingConvention; class OptionManager { private static final Logger logger = LogManager.getLogger(OptionManager.class); @@ -102,7 +103,7 @@ private void validateNamingConventions(ValidatorParameters parameters) { validateNamingConvention("property", parameters.getPropertyNamingConvention()); } - private void validateNamingConvention(String kind, ValidatorParameters.NamingConvention convention) { + private void validateNamingConvention(String kind, NamingConvention convention) { if (convention != null) return; throw new IllegalArgumentException("Invalid " + kind.toLowerCase() + "NamingConvention"); } diff --git a/cli/src/main/java/org/openapitools/openapistylevalidator/cli/OutputUtils.java b/cli/src/main/java/org/openapitools/openapistylevalidator/cli/OutputUtils.java index fe226e8c..0f3effcf 100644 --- a/cli/src/main/java/org/openapitools/openapistylevalidator/cli/OutputUtils.java +++ b/cli/src/main/java/org/openapitools/openapistylevalidator/cli/OutputUtils.java @@ -10,7 +10,7 @@ import org.apache.commons.cli.Options; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.openapitools.openapistylevalidator.styleerror.StyleError; +import org.openapitools.openapistylevalidator.error.StyleError; class OutputUtils { private static final Logger logger = LogManager.getLogger(OutputUtils.class); diff --git a/cli/src/main/java/org/openapitools/openapistylevalidator/cli/ValidationInitiator.java b/cli/src/main/java/org/openapitools/openapistylevalidator/cli/ValidationInitiator.java index e0602cc5..d9a79cc7 100644 --- a/cli/src/main/java/org/openapitools/openapistylevalidator/cli/ValidationInitiator.java +++ b/cli/src/main/java/org/openapitools/openapistylevalidator/cli/ValidationInitiator.java @@ -9,7 +9,7 @@ import org.openapitools.empoa.swagger.core.internal.SwAdapter; import org.openapitools.openapistylevalidator.OpenApiSpecStyleValidator; import org.openapitools.openapistylevalidator.ValidatorParameters; -import org.openapitools.openapistylevalidator.styleerror.StyleError; +import org.openapitools.openapistylevalidator.error.StyleError; public class ValidationInitiator { public List validate(OptionManager optionManager, CommandLine commandLine) { diff --git a/cli/src/test/java/org/openapitools/openapistylevalidator/cli/OptionManagerTest.java b/cli/src/test/java/org/openapitools/openapistylevalidator/cli/OptionManagerTest.java index 87a075dd..0d656e70 100644 --- a/cli/src/test/java/org/openapitools/openapistylevalidator/cli/OptionManagerTest.java +++ b/cli/src/test/java/org/openapitools/openapistylevalidator/cli/OptionManagerTest.java @@ -9,6 +9,7 @@ import org.junit.jupiter.api.Test; import org.mockito.Mockito; import org.openapitools.openapistylevalidator.ValidatorParameters; +import org.openapitools.openapistylevalidator.api.NamingConvention; class OptionManagerTest { @@ -62,7 +63,7 @@ void shouldFixPathNamingStrategy() throws Exception { ValidatorParameters parameters = subject.getOptionalValidatorParametersOrDefault(withOptions("alternativeLegacy")); - Assertions.assertEquals(ValidatorParameters.NamingConvention.CamelCase, parameters.getPathNamingConvention()); + Assertions.assertEquals(NamingConvention.CamelCase, parameters.getPathNamingConvention()); } @Test @@ -70,8 +71,7 @@ void shouldFixParameterNamingStrategy() throws Exception { ValidatorParameters parameters = subject.getOptionalValidatorParametersOrDefault(withOptions("alternativeLegacy")); - Assertions.assertEquals( - ValidatorParameters.NamingConvention.HyphenCase, parameters.getParameterNamingConvention()); + Assertions.assertEquals(NamingConvention.HyphenCase, parameters.getParameterNamingConvention()); } @Test @@ -79,8 +79,7 @@ void shouldFixPropertyNamingStrategy() throws Exception { ValidatorParameters parameters = subject.getOptionalValidatorParametersOrDefault(withOptions("alternativeLegacy")); - Assertions.assertEquals( - ValidatorParameters.NamingConvention.HyphenCase, parameters.getPropertyNamingConvention()); + Assertions.assertEquals(NamingConvention.HyphenCase, parameters.getPropertyNamingConvention()); } @Test @@ -88,7 +87,7 @@ void shouldIgnorePathNamingStrategyWhenPathNamingConventionIsSet() throws Except ValidatorParameters parameters = subject.getOptionalValidatorParametersOrDefault(withOptions("alternativeAndLegacy")); - Assertions.assertEquals(ValidatorParameters.NamingConvention.CamelCase, parameters.getPathNamingConvention()); + Assertions.assertEquals(NamingConvention.CamelCase, parameters.getPathNamingConvention()); } @Test @@ -96,8 +95,7 @@ void shouldIgnoreParameterNamingStrategyWhenParameterNamingConventionIsSet() thr ValidatorParameters parameters = subject.getOptionalValidatorParametersOrDefault(withOptions("alternativeAndLegacy")); - Assertions.assertEquals( - ValidatorParameters.NamingConvention.HyphenCase, parameters.getParameterNamingConvention()); + Assertions.assertEquals(NamingConvention.HyphenCase, parameters.getParameterNamingConvention()); } @Test @@ -105,8 +103,7 @@ void shouldIgnorePropertyNamingStrategyWhenPropertyNamingConventionIsSet() throw ValidatorParameters parameters = subject.getOptionalValidatorParametersOrDefault(withOptions("alternativeAndLegacy")); - Assertions.assertEquals( - ValidatorParameters.NamingConvention.HyphenCase, parameters.getPropertyNamingConvention()); + Assertions.assertEquals(NamingConvention.HyphenCase, parameters.getPropertyNamingConvention()); } @Test @@ -124,13 +121,10 @@ void shouldParseAllOptions() throws Exception { Assertions.assertEquals(true, parameters.isValidateModelPropertiesDescription()); Assertions.assertEquals(true, parameters.isValidateModelRequiredProperties()); Assertions.assertEquals(true, parameters.isValidateNaming()); - Assertions.assertEquals(ValidatorParameters.NamingConvention.HyphenCase, parameters.getPathNamingConvention()); - Assertions.assertEquals( - ValidatorParameters.NamingConvention.UnderscoreUpperCase, parameters.getHeaderNamingConvention()); - Assertions.assertEquals( - ValidatorParameters.NamingConvention.CamelCase, parameters.getParameterNamingConvention()); - Assertions.assertEquals( - ValidatorParameters.NamingConvention.CamelCase, parameters.getPropertyNamingConvention()); + Assertions.assertEquals(NamingConvention.HyphenCase, parameters.getPathNamingConvention()); + Assertions.assertEquals(NamingConvention.UnderscoreUpperCase, parameters.getHeaderNamingConvention()); + Assertions.assertEquals(NamingConvention.CamelCase, parameters.getParameterNamingConvention()); + Assertions.assertEquals(NamingConvention.CamelCase, parameters.getPropertyNamingConvention()); } /* begin - tests for issue #367 */ @@ -140,17 +134,12 @@ void shouldParseDetailedParameterNamingConventionOptions() throws Exception { subject.getOptionalValidatorParametersOrDefault(withOptions("detailedParameterNamingConvention")); Assertions.assertEquals(true, parameters.isValidateNaming()); - Assertions.assertEquals(ValidatorParameters.NamingConvention.HyphenCase, parameters.getPathNamingConvention()); - Assertions.assertEquals( - ValidatorParameters.NamingConvention.CamelCase, parameters.getParameterNamingConvention()); - Assertions.assertEquals( - ValidatorParameters.NamingConvention.CamelCase, parameters.getPropertyNamingConvention()); - Assertions.assertEquals( - ValidatorParameters.NamingConvention.HyphenCase, parameters.getPathParamNamingConvention()); - Assertions.assertEquals( - ValidatorParameters.NamingConvention.HyphenCase, parameters.getQueryParamNamingConvention()); - Assertions.assertEquals( - ValidatorParameters.NamingConvention.HyphenCase, parameters.getCookieParamNamingConvention()); + Assertions.assertEquals(NamingConvention.HyphenCase, parameters.getPathNamingConvention()); + Assertions.assertEquals(NamingConvention.CamelCase, parameters.getParameterNamingConvention()); + Assertions.assertEquals(NamingConvention.CamelCase, parameters.getPropertyNamingConvention()); + Assertions.assertEquals(NamingConvention.HyphenCase, parameters.getPathParamNamingConvention()); + Assertions.assertEquals(NamingConvention.HyphenCase, parameters.getQueryParamNamingConvention()); + Assertions.assertEquals(NamingConvention.HyphenCase, parameters.getCookieParamNamingConvention()); } @Test @@ -163,11 +152,9 @@ void shouldSetAllParametersNamingConventionUnderSameNameConvention() throws Exce ValidatorParameters parameters = subject.getOptionalValidatorParametersOrDefault(withOptions("alternative")); Assertions.assertEquals(true, parameters.isValidateNaming()); - Assertions.assertEquals(ValidatorParameters.NamingConvention.CamelCase, parameters.getPathNamingConvention()); - Assertions.assertEquals( - ValidatorParameters.NamingConvention.HyphenCase, parameters.getParameterNamingConvention()); - Assertions.assertEquals( - ValidatorParameters.NamingConvention.HyphenCase, parameters.getPropertyNamingConvention()); + Assertions.assertEquals(NamingConvention.CamelCase, parameters.getPathNamingConvention()); + Assertions.assertEquals(NamingConvention.HyphenCase, parameters.getParameterNamingConvention()); + Assertions.assertEquals(NamingConvention.HyphenCase, parameters.getPropertyNamingConvention()); Assertions.assertEquals(parameters.getParameterNamingConvention(), parameters.getPathParamNamingConvention()); Assertions.assertEquals(parameters.getParameterNamingConvention(), parameters.getQueryParamNamingConvention()); Assertions.assertEquals(parameters.getParameterNamingConvention(), parameters.getCookieParamNamingConvention()); @@ -185,14 +172,11 @@ void shouldParseCoexistingParameterNamingConventionOptions() throws Exception { subject.getOptionalValidatorParametersOrDefault(withOptions("parameterNamingConventionCoexistence")); Assertions.assertEquals(true, parameters.isValidateNaming()); - Assertions.assertEquals(ValidatorParameters.NamingConvention.HyphenCase, parameters.getPathNamingConvention()); - Assertions.assertEquals( - ValidatorParameters.NamingConvention.UnderscoreUpperCase, parameters.getParameterNamingConvention()); + Assertions.assertEquals(NamingConvention.HyphenCase, parameters.getPathNamingConvention()); + Assertions.assertEquals(NamingConvention.UnderscoreUpperCase, parameters.getParameterNamingConvention()); Assertions.assertEquals(parameters.getParameterNamingConvention(), parameters.getPathParamNamingConvention()); - Assertions.assertEquals( - ValidatorParameters.NamingConvention.HyphenCase, parameters.getQueryParamNamingConvention()); - Assertions.assertEquals( - ValidatorParameters.NamingConvention.HyphenCase, parameters.getCookieParamNamingConvention()); + Assertions.assertEquals(NamingConvention.HyphenCase, parameters.getQueryParamNamingConvention()); + Assertions.assertEquals(NamingConvention.HyphenCase, parameters.getCookieParamNamingConvention()); } /* end - tests for issue #367 */ diff --git a/cli/src/test/java/org/openapitools/openapistylevalidator/cli/ResourceTest.java b/cli/src/test/java/org/openapitools/openapistylevalidator/cli/ResourceTest.java index cd1ee185..480004c7 100644 --- a/cli/src/test/java/org/openapitools/openapistylevalidator/cli/ResourceTest.java +++ b/cli/src/test/java/org/openapitools/openapistylevalidator/cli/ResourceTest.java @@ -7,6 +7,7 @@ import org.apache.commons.io.IOUtils; import org.junit.jupiter.api.Test; import org.openapitools.openapistylevalidator.ValidatorParameters; +import org.openapitools.openapistylevalidator.api.NamingConvention; class ResourceTest { private static final String PREFIX = " \""; @@ -90,22 +91,22 @@ void defaultJsonFileContainsConstants() throws Exception { + PREFIX + ValidatorParameters.PATH_NAMING_CONVENTION + SEPARATOR_QUOTE - + ValidatorParameters.NamingConvention.HyphenCase + + NamingConvention.HyphenCase + NEXT_LINE_QUOTE + PREFIX + ValidatorParameters.HEADER_NAMING_CONVENTION + SEPARATOR_QUOTE - + ValidatorParameters.NamingConvention.UnderscoreUpperCase + + NamingConvention.UnderscoreUpperCase + NEXT_LINE_QUOTE + PREFIX + ValidatorParameters.PARAMETER_NAMING_CONVENTION + SEPARATOR_QUOTE - + ValidatorParameters.NamingConvention.CamelCase + + NamingConvention.CamelCase + NEXT_LINE_QUOTE + PREFIX + ValidatorParameters.PROPERTY_NAMING_CONVENTION + SEPARATOR_QUOTE - + ValidatorParameters.NamingConvention.CamelCase + + NamingConvention.CamelCase + "\"" + System.lineSeparator() + "}"; diff --git a/cli/src/test/java/org/openapitools/openapistylevalidator/cli/ValidationInitiatorTest.java b/cli/src/test/java/org/openapitools/openapistylevalidator/cli/ValidationInitiatorTest.java index 1408ef43..f5c43bb4 100644 --- a/cli/src/test/java/org/openapitools/openapistylevalidator/cli/ValidationInitiatorTest.java +++ b/cli/src/test/java/org/openapitools/openapistylevalidator/cli/ValidationInitiatorTest.java @@ -9,7 +9,7 @@ import org.apache.commons.cli.ParseException; import org.junit.jupiter.api.*; import org.mockito.Mockito; -import org.openapitools.openapistylevalidator.styleerror.StyleError; +import org.openapitools.openapistylevalidator.error.StyleError; import org.opentest4j.MultipleFailuresError; class ValidationInitiatorTest { diff --git a/gradle-plugin/build.gradle b/gradle-plugin/build.gradle index c84b3c5f..70169be0 100644 --- a/gradle-plugin/build.gradle +++ b/gradle-plugin/build.gradle @@ -4,6 +4,7 @@ plugins { dependencies { implementation project(':openapi-style-validator-lib') + implementation project(':openapi-style-validator-api') implementation 'io.swagger.parser.v3:swagger-parser:2.0.33' implementation 'org.openapitools.empoa:empoa-swagger-core:2.1.0' testImplementation 'junit:junit:4.13.2' diff --git a/gradle-plugin/src/main/java/org/openapitools/openapistylevalidator/gradle/OpenAPIStyleValidatorTask.java b/gradle-plugin/src/main/java/org/openapitools/openapistylevalidator/gradle/OpenAPIStyleValidatorTask.java index 40f17f84..f9a4fcfe 100644 --- a/gradle-plugin/src/main/java/org/openapitools/openapistylevalidator/gradle/OpenAPIStyleValidatorTask.java +++ b/gradle-plugin/src/main/java/org/openapitools/openapistylevalidator/gradle/OpenAPIStyleValidatorTask.java @@ -10,8 +10,8 @@ import org.openapitools.empoa.swagger.core.internal.SwAdapter; import org.openapitools.openapistylevalidator.OpenApiSpecStyleValidator; import org.openapitools.openapistylevalidator.ValidatorParameters; -import org.openapitools.openapistylevalidator.ValidatorParameters.NamingConvention; -import org.openapitools.openapistylevalidator.styleerror.StyleError; +import org.openapitools.openapistylevalidator.api.NamingConvention; +import org.openapitools.openapistylevalidator.error.StyleError; import java.util.List; diff --git a/lib/build.gradle b/lib/build.gradle index 5fb9909b..6b417df1 100644 --- a/lib/build.gradle +++ b/lib/build.gradle @@ -3,7 +3,10 @@ plugins { } dependencies { + implementation project(':openapi-style-validator-api') implementation 'org.eclipse.microprofile.openapi:microprofile-openapi-api:3.0' + implementation group: 'org.apache.commons', name: 'commons-lang3', version: '3.12.0' + implementation 'org.apache.commons:commons-collections4:4.4' testImplementation 'org.slf4j:slf4j-jdk14:2.0.3' testImplementation 'org.openapitools.empoa:empoa-simple-models-impl:2.1.0' testImplementation 'nl.jqno.equalsverifier:equalsverifier:3.10.1' @@ -40,9 +43,9 @@ publishing { } developers { developer { - id = 'JFCote' - name = 'Jean-Francois Cote' - email = 'jcote@stingray.com' + id = 'thiyagu' + name = 'Thiyagu GK' + email = 'thiyagu103@gmail.com' } } scm { diff --git a/lib/src/main/java/org/openapitools/openapistylevalidator/ErrorAggregator.java b/lib/src/main/java/org/openapitools/openapistylevalidator/ErrorAggregator.java index ee40b707..43ae7acc 100644 --- a/lib/src/main/java/org/openapitools/openapistylevalidator/ErrorAggregator.java +++ b/lib/src/main/java/org/openapitools/openapistylevalidator/ErrorAggregator.java @@ -3,19 +3,25 @@ import java.util.ArrayList; import java.util.List; import org.eclipse.microprofile.openapi.models.PathItem; -import org.openapitools.openapistylevalidator.styleerror.*; +import org.openapitools.openapistylevalidator.error.GenericStyleError; +import org.openapitools.openapistylevalidator.error.ModelNamingStyleError; +import org.openapitools.openapistylevalidator.error.ModelStyleError; +import org.openapitools.openapistylevalidator.error.OperationNamingStyleError; +import org.openapitools.openapistylevalidator.error.OperationStyleError; +import org.openapitools.openapistylevalidator.error.StyleCheckSection; +import org.openapitools.openapistylevalidator.error.StyleError; class ErrorAggregator { private final List errorList = new ArrayList<>(); - void logMissingOrEmptyAttribute(StyleError.StyleCheckSection styleCheckSection, String fieldNames) { + void logMissingOrEmptyAttribute(StyleCheckSection styleCheckSection, String fieldNames) { errorList.add(new StyleError(styleCheckSection, fieldNames, "Should be present and not empty")); } void validateMinimumInfo( List infoPresence, - StyleError.StyleCheckSection styleCheckSection, + StyleCheckSection styleCheckSection, String parentObjectName, String fieldNames) { boolean hasMinimumInfo = false; @@ -65,7 +71,7 @@ void logOperationBadNaming( String path, PathItem.HttpMethod httpMethod) { errorList.add(new OperationNamingStyleError( - StyleError.StyleCheckSection.Naming, + StyleCheckSection.Naming, variableName, String.format("%s should be in %s", variableType, neededNamingStrategy), path, @@ -74,7 +80,7 @@ void logOperationBadNaming( void logModelBadNaming(String variableName, String variableType, String neededNamingStrategy, String model) { errorList.add(new ModelNamingStyleError( - StyleError.StyleCheckSection.Naming, + StyleCheckSection.Naming, variableName, String.format("%s should be in %s", variableType, neededNamingStrategy), model)); @@ -82,8 +88,6 @@ void logModelBadNaming(String variableName, String variableType, String neededNa public void logMissingPathsAndComponents() { errorList.add(new StyleError( - StyleError.StyleCheckSection.OpenAPI, - "paths,components", - "Should have at least one of paths or components")); + StyleCheckSection.OpenAPI, "paths,components", "Should have at least one of paths or components")); } } diff --git a/lib/src/main/java/org/openapitools/openapistylevalidator/ErrorMessageHelper.java b/lib/src/main/java/org/openapitools/openapistylevalidator/ErrorMessageHelper.java new file mode 100644 index 00000000..1671f372 --- /dev/null +++ b/lib/src/main/java/org/openapitools/openapistylevalidator/ErrorMessageHelper.java @@ -0,0 +1,54 @@ +package org.openapitools.openapistylevalidator; + +import org.eclipse.microprofile.openapi.models.PathItem; +import org.openapitools.openapistylevalidator.error.GenericStyleError; +import org.openapitools.openapistylevalidator.error.OperationNamingStyleError; +import org.openapitools.openapistylevalidator.error.OperationStyleError; +import org.openapitools.openapistylevalidator.error.StyleCheckSection; +import org.openapitools.openapistylevalidator.error.StyleError; + +public class ErrorMessageHelper { + + private ErrorMessageHelper() {} + + public static StyleError logMissingOrEmptyAttribute(StyleCheckSection styleCheckSection, String fieldNames) { + return new StyleError(styleCheckSection, fieldNames, "Should be present and not empty"); + } + + public static StyleError logMissingPathsAndComponents() { + return new StyleError( + StyleCheckSection.OpenAPI, "paths,components", "Should have at least one of paths or components"); + } + + public static StyleError validateMinimumInfo( + StyleCheckSection styleCheckSection, String parentObjectName, String fieldNames) { + + return new GenericStyleError( + styleCheckSection, parentObjectName, fieldNames, "At least one field should be present and not empty"); + } + + public static StyleError logMissingOrEmptyOperationCollection( + String path, PathItem.HttpMethod method, String field) { + return new OperationStyleError( + field, "The collection should be present and there should be at least one item in it", path, method); + } + + public static StyleError logMissingOrEmptyOperationAttribute( + String path, PathItem.HttpMethod method, String field) { + return new OperationStyleError(field, "This field should be present and not empty", path, method); + } + + public static StyleError logOperationBadNaming( + String variableName, + String variableType, + String neededNamingStrategy, + String path, + PathItem.HttpMethod httpMethod) { + return new OperationNamingStyleError( + StyleCheckSection.Naming, + variableName, + String.format("%s should be in %s", variableType, neededNamingStrategy), + path, + httpMethod); + } +} diff --git a/lib/src/main/java/org/openapitools/openapistylevalidator/NamingValidator.java b/lib/src/main/java/org/openapitools/openapistylevalidator/NamingValidator.java index c044dc05..5ab9dbe2 100644 --- a/lib/src/main/java/org/openapitools/openapistylevalidator/NamingValidator.java +++ b/lib/src/main/java/org/openapitools/openapistylevalidator/NamingValidator.java @@ -2,6 +2,7 @@ import java.util.Arrays; import java.util.Optional; +import org.openapitools.openapistylevalidator.api.NamingConvention; class NamingValidator { @@ -76,7 +77,7 @@ private boolean isSeparatorCaseValid(String variableName, String separator, bool return variableName.length() == (totalLength + tokens.length - 1); } - boolean isNamingValid(String name, ValidatorParameters.NamingConvention namingStrategy) { + boolean isNamingValid(String name, NamingConvention namingStrategy) { switch (namingStrategy) { case UnderscoreCase: return isUnderscoreCase(name); diff --git a/lib/src/main/java/org/openapitools/openapistylevalidator/OpenApiSpecStyleValidator.java b/lib/src/main/java/org/openapitools/openapistylevalidator/OpenApiSpecStyleValidator.java index 1460e640..caf0de5a 100644 --- a/lib/src/main/java/org/openapitools/openapistylevalidator/OpenApiSpecStyleValidator.java +++ b/lib/src/main/java/org/openapitools/openapistylevalidator/OpenApiSpecStyleValidator.java @@ -1,6 +1,11 @@ package org.openapitools.openapistylevalidator; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; import org.eclipse.microprofile.openapi.models.OpenAPI; import org.eclipse.microprofile.openapi.models.Operation; import org.eclipse.microprofile.openapi.models.PathItem; @@ -9,8 +14,9 @@ import org.eclipse.microprofile.openapi.models.info.License; import org.eclipse.microprofile.openapi.models.media.Schema; import org.eclipse.microprofile.openapi.models.parameters.Parameter; -import org.openapitools.openapistylevalidator.ValidatorParameters.NamingConvention; -import org.openapitools.openapistylevalidator.styleerror.StyleError; +import org.openapitools.openapistylevalidator.api.NamingConvention; +import org.openapitools.openapistylevalidator.error.StyleCheckSection; +import org.openapitools.openapistylevalidator.error.StyleError; public class OpenApiSpecStyleValidator { public static final String INPUT_FILE = "inputFile"; @@ -54,17 +60,16 @@ private void validateInfo() { List infoPresence = new ArrayList<>(); infoPresence.add(license.getName() != null && !license.getName().isEmpty()); infoPresence.add(license.getUrl() != null && !license.getUrl().isEmpty()); - errorAggregator.validateMinimumInfo( - infoPresence, StyleError.StyleCheckSection.APIInfo, "license", "name|url"); + errorAggregator.validateMinimumInfo(infoPresence, StyleCheckSection.APIInfo, "license", "name|url"); } else { - errorAggregator.logMissingOrEmptyAttribute(StyleError.StyleCheckSection.APIInfo, "license"); + errorAggregator.logMissingOrEmptyAttribute(StyleCheckSection.APIInfo, "license"); } } if (parameters.isValidateInfoDescription()) { String description = info.getDescription(); if (description == null || description.isEmpty()) { - errorAggregator.logMissingOrEmptyAttribute(StyleError.StyleCheckSection.APIInfo, "description"); + errorAggregator.logMissingOrEmptyAttribute(StyleCheckSection.APIInfo, "description"); } } @@ -77,9 +82,9 @@ private void validateInfo() { infoPresence.add( contact.getEmail() != null && !contact.getEmail().isEmpty()); errorAggregator.validateMinimumInfo( - infoPresence, StyleError.StyleCheckSection.APIInfo, "contact", "name|url|email"); + infoPresence, StyleCheckSection.APIInfo, "contact", "name|url|email"); } else { - errorAggregator.logMissingOrEmptyAttribute(StyleError.StyleCheckSection.APIInfo, "contact"); + errorAggregator.logMissingOrEmptyAttribute(StyleCheckSection.APIInfo, "contact"); } } } diff --git a/lib/src/main/java/org/openapitools/openapistylevalidator/ValidatorParameters.java b/lib/src/main/java/org/openapitools/openapistylevalidator/ValidatorParameters.java index c978e94e..95b57424 100644 --- a/lib/src/main/java/org/openapitools/openapistylevalidator/ValidatorParameters.java +++ b/lib/src/main/java/org/openapitools/openapistylevalidator/ValidatorParameters.java @@ -1,5 +1,7 @@ package org.openapitools.openapistylevalidator; +import org.openapitools.openapistylevalidator.api.NamingConvention; + public class ValidatorParameters { public static final String VALIDATE_INFO_LICENSE = "validateInfoLicense"; public static final String VALIDATE_INFO_DESCRIPTION = "validateInfoDescription"; @@ -25,28 +27,6 @@ public class ValidatorParameters { public static final String PATH_PARAM_NAMING_CONVENTION = "pathParamNamingConvention"; public static final String COOKIE_PARAM_NAMING_CONVENTION = "cookieParamNamingConvention"; - public static enum NamingConvention { - UnderscoreCase("underscore_case"), - UnderscoreUpperCase("UNDERSCORE_UPPER_CASE"), - CamelCase("camelCase"), - HyphenCase("hyphen-case"), - AnyCase("AnyCase"), - HyphenUpperCase("Hyphen-Upper-Case"); - - private final String designation; - - NamingConvention(String appelation) { - this.designation = appelation; - } - - /** - * @return the name of the naming convention as it can be used in the reports - */ - public String getDesignation() { - return designation; - } - } - private boolean validateInfoLicense = true; private boolean validateInfoDescription = true; private boolean validateInfoContact = true; diff --git a/lib/src/main/java/org/openapitools/openapistylevalidator/commons/OpenAPIUtils.java b/lib/src/main/java/org/openapitools/openapistylevalidator/commons/OpenAPIUtils.java new file mode 100644 index 00000000..33d0cbe9 --- /dev/null +++ b/lib/src/main/java/org/openapitools/openapistylevalidator/commons/OpenAPIUtils.java @@ -0,0 +1,35 @@ +package org.openapitools.openapistylevalidator.commons; + +import java.util.List; +import java.util.Map; +import java.util.function.Predicate; +import java.util.stream.Collectors; +import org.eclipse.microprofile.openapi.models.OpenAPI; +import org.eclipse.microprofile.openapi.models.Operation; +import org.eclipse.microprofile.openapi.models.PathItem; + +public class OpenAPIUtils { + + private OpenAPIUtils() {} + + public static Map getPathItemsToValidate(OpenAPI openapi) { + return openapi.getPaths().getPathItems().entrySet().stream() + .filter(path -> !OpenAPIUtils.isPathIgnored(path.getValue())) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + } + + private static boolean isPathIgnored(PathItem path) { + if (path.getExtensions() != null && path.getExtensions().containsKey("x-style-validator-ignored")) { + Object o = path.getExtensions().getOrDefault("x-style-validator-ignored", "false"); + return Boolean.parseBoolean(o.toString()); + } + return false; + } + + public static List validateOperation(PathItem pathItem, Predicate predicate) { + return pathItem.getOperations().entrySet().stream() + .filter(entry -> predicate.test(entry.getValue())) + .map(Map.Entry::getKey) + .collect(Collectors.toList()); + } +} diff --git a/lib/src/main/java/org/openapitools/openapistylevalidator/rules/ContactInfoRule.java b/lib/src/main/java/org/openapitools/openapistylevalidator/rules/ContactInfoRule.java new file mode 100644 index 00000000..1de89830 --- /dev/null +++ b/lib/src/main/java/org/openapitools/openapistylevalidator/rules/ContactInfoRule.java @@ -0,0 +1,44 @@ +package org.openapitools.openapistylevalidator.rules; + +import static org.apache.commons.lang3.StringUtils.isEmpty; + +import java.util.Collections; +import java.util.List; +import org.eclipse.microprofile.openapi.models.OpenAPI; +import org.eclipse.microprofile.openapi.models.info.Contact; +import org.openapitools.openapistylevalidator.api.IRule; +import org.openapitools.openapistylevalidator.error.StyleCheckSection; +import org.openapitools.openapistylevalidator.error.StyleError; + +public class ContactInfoRule implements IRule { + + public static final String CONTACT_INFO = "contact info"; + + @Override + public String name() { + return CONTACT_INFO; + } + + @Override + public String description() { + return "At least one field should be present and not empty. name|url|email"; + } + + @Override + public List execute(OpenAPI api) { + Contact contact = api.getInfo().getContact(); + if (contact == null) { + StyleError styleError = + new StyleError(StyleCheckSection.APIInfo, "contact", "Should be present and not empty"); + return Collections.singletonList(styleError); + } + if (isEmpty(contact.getName()) && isEmpty(contact.getUrl()) && isEmpty(contact.getEmail())) { + StyleError styleError = new StyleError( + StyleCheckSection.APIInfo, + "contact", + "At least one field should be present and not empty. name|url|email"); + return Collections.singletonList(styleError); + } + return Collections.emptyList(); + } +} diff --git a/lib/src/main/java/org/openapitools/openapistylevalidator/rules/InfoDescriptionRule.java b/lib/src/main/java/org/openapitools/openapistylevalidator/rules/InfoDescriptionRule.java new file mode 100644 index 00000000..625e9494 --- /dev/null +++ b/lib/src/main/java/org/openapitools/openapistylevalidator/rules/InfoDescriptionRule.java @@ -0,0 +1,34 @@ +package org.openapitools.openapistylevalidator.rules; + +import static org.apache.commons.lang3.StringUtils.isEmpty; +import static org.openapitools.openapistylevalidator.ErrorMessageHelper.logMissingOrEmptyAttribute; +import static org.openapitools.openapistylevalidator.error.StyleCheckSection.APIInfo; + +import java.util.Collections; +import java.util.List; +import org.eclipse.microprofile.openapi.models.OpenAPI; +import org.openapitools.openapistylevalidator.api.IRule; +import org.openapitools.openapistylevalidator.error.StyleError; + +public class InfoDescriptionRule implements IRule { + + public static final String INFO_DESCRIPTION = "info description"; + + @Override + public String name() { + return INFO_DESCRIPTION; + } + + @Override + public String description() { + return "Description should be provided in the info section"; + } + + @Override + public List execute(OpenAPI api) { + if (isEmpty(api.getInfo().getDescription())) { + return Collections.singletonList(logMissingOrEmptyAttribute(APIInfo, "description")); + } + return Collections.emptyList(); + } +} diff --git a/lib/src/main/java/org/openapitools/openapistylevalidator/rules/LicenseRule.java b/lib/src/main/java/org/openapitools/openapistylevalidator/rules/LicenseRule.java new file mode 100644 index 00000000..1661b236 --- /dev/null +++ b/lib/src/main/java/org/openapitools/openapistylevalidator/rules/LicenseRule.java @@ -0,0 +1,43 @@ +package org.openapitools.openapistylevalidator.rules; + +import static org.apache.commons.lang3.StringUtils.isEmpty; +import static org.openapitools.openapistylevalidator.ErrorMessageHelper.logMissingOrEmptyAttribute; +import static org.openapitools.openapistylevalidator.ErrorMessageHelper.validateMinimumInfo; +import static org.openapitools.openapistylevalidator.error.StyleCheckSection.APIInfo; + +import java.util.Collections; +import java.util.List; +import org.eclipse.microprofile.openapi.models.OpenAPI; +import org.eclipse.microprofile.openapi.models.info.Info; +import org.eclipse.microprofile.openapi.models.info.License; +import org.openapitools.openapistylevalidator.api.IRule; +import org.openapitools.openapistylevalidator.error.StyleError; + +public class LicenseRule implements IRule { + + public static final String LICENCE_INFO = "licence info"; + + @Override + public String name() { + return LICENCE_INFO; + } + + @Override + public String description() { + return "at least name or url should be present in the license section"; + } + + @Override + public List execute(OpenAPI api) { + Info info = api.getInfo(); + License license = info.getLicense(); + if (license == null) { + return Collections.singletonList(logMissingOrEmptyAttribute(APIInfo, "license")); + } + + if (isEmpty(license.getName()) && isEmpty(license.getUrl())) { + return Collections.singletonList(validateMinimumInfo(APIInfo, "license", "name|url")); + } + return Collections.emptyList(); + } +} diff --git a/lib/src/main/java/org/openapitools/openapistylevalidator/rules/OpenAPIRule.java b/lib/src/main/java/org/openapitools/openapistylevalidator/rules/OpenAPIRule.java new file mode 100644 index 00000000..95fe312e --- /dev/null +++ b/lib/src/main/java/org/openapitools/openapistylevalidator/rules/OpenAPIRule.java @@ -0,0 +1,32 @@ +package org.openapitools.openapistylevalidator.rules; + +import static org.openapitools.openapistylevalidator.ErrorMessageHelper.logMissingPathsAndComponents; + +import java.util.Collections; +import java.util.List; +import org.eclipse.microprofile.openapi.models.OpenAPI; +import org.openapitools.openapistylevalidator.api.IRule; +import org.openapitools.openapistylevalidator.error.StyleError; + +public class OpenAPIRule implements IRule { + + public static final String OPENAPI = "openapi"; + + @Override + public String name() { + return OPENAPI; + } + + @Override + public String description() { + return "Rule for validating openAPI has at least one component and one path"; + } + + @Override + public List execute(OpenAPI api) { + if (api.getPaths() == null && api.getComponents() == null) { + return Collections.singletonList(logMissingPathsAndComponents()); + } + return Collections.emptyList(); + } +} diff --git a/lib/src/main/java/org/openapitools/openapistylevalidator/rules/OperationDescriptionRule.java b/lib/src/main/java/org/openapitools/openapistylevalidator/rules/OperationDescriptionRule.java new file mode 100644 index 00000000..718b5924 --- /dev/null +++ b/lib/src/main/java/org/openapitools/openapistylevalidator/rules/OperationDescriptionRule.java @@ -0,0 +1,41 @@ +package org.openapitools.openapistylevalidator.rules; + +import static org.apache.commons.lang3.StringUtils.*; +import static org.openapitools.openapistylevalidator.ErrorMessageHelper.logMissingOrEmptyOperationAttribute; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import org.eclipse.microprofile.openapi.models.OpenAPI; +import org.eclipse.microprofile.openapi.models.PathItem; +import org.openapitools.openapistylevalidator.api.IRule; +import org.openapitools.openapistylevalidator.commons.OpenAPIUtils; +import org.openapitools.openapistylevalidator.error.StyleError; + +public class OperationDescriptionRule implements IRule { + + @Override + public String name() { + return "Operation Description"; + } + + @Override + public String description() { + return "Operation Description should be present"; + } + + @Override + public List execute(OpenAPI api) { + Map pathItemsToValidate = OpenAPIUtils.getPathItemsToValidate(api); + return pathItemsToValidate.entrySet().stream() + .map(path -> validateTags(path.getKey(), path.getValue())) + .flatMap(List::stream) + .collect(Collectors.toList()); + } + + private List validateTags(String path, PathItem pathItem) { + return OpenAPIUtils.validateOperation(pathItem, op -> isEmpty(op.getDescription())).stream() + .map(method -> logMissingOrEmptyOperationAttribute(path, method, "description")) + .collect(Collectors.toList()); + } +} diff --git a/lib/src/main/java/org/openapitools/openapistylevalidator/rules/OperationIDRule.java b/lib/src/main/java/org/openapitools/openapistylevalidator/rules/OperationIDRule.java new file mode 100644 index 00000000..a2cad456 --- /dev/null +++ b/lib/src/main/java/org/openapitools/openapistylevalidator/rules/OperationIDRule.java @@ -0,0 +1,41 @@ +package org.openapitools.openapistylevalidator.rules; + +import static java.util.stream.Collectors.toList; +import static org.apache.commons.lang3.StringUtils.*; +import static org.openapitools.openapistylevalidator.ErrorMessageHelper.logMissingOrEmptyOperationAttribute; + +import java.util.List; +import java.util.Map; +import org.eclipse.microprofile.openapi.models.OpenAPI; +import org.eclipse.microprofile.openapi.models.PathItem; +import org.openapitools.openapistylevalidator.api.IRule; +import org.openapitools.openapistylevalidator.commons.OpenAPIUtils; +import org.openapitools.openapistylevalidator.error.StyleError; + +public class OperationIDRule implements IRule { + + @Override + public String name() { + return "Operation ID"; + } + + @Override + public String description() { + return "Operation ID should be present"; + } + + @Override + public List execute(OpenAPI api) { + Map pathItemsToValidate = OpenAPIUtils.getPathItemsToValidate(api); + return pathItemsToValidate.entrySet().stream() + .map(path -> validateTags(path.getKey(), path.getValue())) + .flatMap(List::stream) + .collect(toList()); + } + + private List validateTags(String path, PathItem pathItem) { + return OpenAPIUtils.validateOperation(pathItem, op -> isEmpty(op.getOperationId())).stream() + .map(method -> logMissingOrEmptyOperationAttribute(path, method, "operationId")) + .collect(toList()); + } +} diff --git a/lib/src/main/java/org/openapitools/openapistylevalidator/rules/OperationSummaryRule.java b/lib/src/main/java/org/openapitools/openapistylevalidator/rules/OperationSummaryRule.java new file mode 100644 index 00000000..7b83a1e7 --- /dev/null +++ b/lib/src/main/java/org/openapitools/openapistylevalidator/rules/OperationSummaryRule.java @@ -0,0 +1,41 @@ +package org.openapitools.openapistylevalidator.rules; + +import static org.apache.commons.lang3.StringUtils.*; +import static org.openapitools.openapistylevalidator.ErrorMessageHelper.logMissingOrEmptyOperationAttribute; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import org.eclipse.microprofile.openapi.models.OpenAPI; +import org.eclipse.microprofile.openapi.models.PathItem; +import org.openapitools.openapistylevalidator.api.IRule; +import org.openapitools.openapistylevalidator.commons.OpenAPIUtils; +import org.openapitools.openapistylevalidator.error.StyleError; + +public class OperationSummaryRule implements IRule { + + @Override + public String name() { + return "Operation Summary"; + } + + @Override + public String description() { + return "Operation Summary should be present"; + } + + @Override + public List execute(OpenAPI api) { + Map pathItemsToValidate = OpenAPIUtils.getPathItemsToValidate(api); + return pathItemsToValidate.entrySet().stream() + .map(path -> validateSummary(path.getKey(), path.getValue())) + .flatMap(List::stream) + .collect(Collectors.toList()); + } + + private List validateSummary(String path, PathItem pathItem) { + return OpenAPIUtils.validateOperation(pathItem, op -> isEmpty(op.getSummary())).stream() + .map(method -> logMissingOrEmptyOperationAttribute(path, method, "summary")) + .collect(Collectors.toList()); + } +} diff --git a/lib/src/main/java/org/openapitools/openapistylevalidator/rules/OperationTagRule.java b/lib/src/main/java/org/openapitools/openapistylevalidator/rules/OperationTagRule.java new file mode 100644 index 00000000..dd4e977e --- /dev/null +++ b/lib/src/main/java/org/openapitools/openapistylevalidator/rules/OperationTagRule.java @@ -0,0 +1,41 @@ +package org.openapitools.openapistylevalidator.rules; + +import static org.apache.commons.collections4.CollectionUtils.*; +import static org.openapitools.openapistylevalidator.ErrorMessageHelper.logMissingOrEmptyOperationCollection; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import org.eclipse.microprofile.openapi.models.OpenAPI; +import org.eclipse.microprofile.openapi.models.PathItem; +import org.openapitools.openapistylevalidator.api.IRule; +import org.openapitools.openapistylevalidator.commons.OpenAPIUtils; +import org.openapitools.openapistylevalidator.error.StyleError; + +public class OperationTagRule implements IRule { + + @Override + public String name() { + return "Operation ID"; + } + + @Override + public String description() { + return "Operation ID should be present"; + } + + @Override + public List execute(OpenAPI api) { + Map pathItemsToValidate = OpenAPIUtils.getPathItemsToValidate(api); + return pathItemsToValidate.entrySet().stream() + .map(path -> validateTags(path.getKey(), path.getValue())) + .flatMap(List::stream) + .collect(Collectors.toList()); + } + + private List validateTags(String path, PathItem pathItem) { + return OpenAPIUtils.validateOperation(pathItem, op -> isEmpty(op.getTags())).stream() + .map(method -> logMissingOrEmptyOperationCollection(path, method, "tags")) + .collect(Collectors.toList()); + } +} diff --git a/lib/src/test/java/org/openapitools/openapistylevalidator/ErrorAggregatorTest.java b/lib/src/test/java/org/openapitools/openapistylevalidator/ErrorAggregatorTest.java index fe0f2145..b26caf79 100644 --- a/lib/src/test/java/org/openapitools/openapistylevalidator/ErrorAggregatorTest.java +++ b/lib/src/test/java/org/openapitools/openapistylevalidator/ErrorAggregatorTest.java @@ -6,8 +6,8 @@ import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.openapitools.openapistylevalidator.styleerror.ModelStyleError; -import org.openapitools.openapistylevalidator.styleerror.StyleError; +import org.openapitools.openapistylevalidator.error.ModelStyleError; +import org.openapitools.openapistylevalidator.error.StyleCheckSection; class ErrorAggregatorTest { @@ -23,7 +23,7 @@ void logMissingOrEmptyAttributeShouldAddToErrorList() { // Arrange // Act - errorAggregator.logMissingOrEmptyAttribute(StyleError.StyleCheckSection.APIInfo, "contact"); + errorAggregator.logMissingOrEmptyAttribute(StyleCheckSection.APIInfo, "contact"); // Assert Assertions.assertAll( diff --git a/lib/src/test/java/org/openapitools/openapistylevalidator/NamingValidatorTest.java b/lib/src/test/java/org/openapitools/openapistylevalidator/NamingValidatorTest.java index c5f44514..a8602593 100644 --- a/lib/src/test/java/org/openapitools/openapistylevalidator/NamingValidatorTest.java +++ b/lib/src/test/java/org/openapitools/openapistylevalidator/NamingValidatorTest.java @@ -6,6 +6,7 @@ import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.openapitools.openapistylevalidator.api.NamingConvention; class NamingValidatorTest { @@ -24,9 +25,9 @@ void anyCaseShouldAlwaysReturnTrue() { String whateverCase3 = "variable"; // Act - boolean actual1 = validator.isNamingValid(whateverCase1, ValidatorParameters.NamingConvention.AnyCase); - boolean actual2 = validator.isNamingValid(whateverCase2, ValidatorParameters.NamingConvention.AnyCase); - boolean actual3 = validator.isNamingValid(whateverCase3, ValidatorParameters.NamingConvention.AnyCase); + boolean actual1 = validator.isNamingValid(whateverCase1, NamingConvention.AnyCase); + boolean actual2 = validator.isNamingValid(whateverCase2, NamingConvention.AnyCase); + boolean actual3 = validator.isNamingValid(whateverCase3, NamingConvention.AnyCase); // Assert Assertions.assertAll(() -> assertTrue(actual1), () -> assertTrue(actual2), () -> assertTrue(actual3)); @@ -40,12 +41,9 @@ void goodUnderscoreCaseShouldReturnTrue() { String goodUnderscoreCase3 = "my_super_variable"; // Act - boolean actual1 = - validator.isNamingValid(goodUnderscoreCase1, ValidatorParameters.NamingConvention.UnderscoreCase); - boolean actual2 = - validator.isNamingValid(goodUnderscoreCase2, ValidatorParameters.NamingConvention.UnderscoreCase); - boolean actual3 = - validator.isNamingValid(goodUnderscoreCase3, ValidatorParameters.NamingConvention.UnderscoreCase); + boolean actual1 = validator.isNamingValid(goodUnderscoreCase1, NamingConvention.UnderscoreCase); + boolean actual2 = validator.isNamingValid(goodUnderscoreCase2, NamingConvention.UnderscoreCase); + boolean actual3 = validator.isNamingValid(goodUnderscoreCase3, NamingConvention.UnderscoreCase); // Assert Assertions.assertAll(() -> assertTrue(actual1), () -> assertTrue(actual2), () -> assertTrue(actual3)); @@ -62,18 +60,12 @@ void badUnderscoreCaseShouldReturnFalse() { String badUnderscoreCase6 = "my_variable_"; // Act - boolean actual1 = - validator.isNamingValid(badUnderscoreCase1, ValidatorParameters.NamingConvention.UnderscoreCase); - boolean actual2 = - validator.isNamingValid(badUnderscoreCase2, ValidatorParameters.NamingConvention.UnderscoreCase); - boolean actual3 = - validator.isNamingValid(badUnderscoreCase3, ValidatorParameters.NamingConvention.UnderscoreCase); - boolean actual4 = - validator.isNamingValid(badUnderscoreCase4, ValidatorParameters.NamingConvention.UnderscoreCase); - boolean actual5 = - validator.isNamingValid(badUnderscoreCase5, ValidatorParameters.NamingConvention.UnderscoreCase); - boolean actual6 = - validator.isNamingValid(badUnderscoreCase6, ValidatorParameters.NamingConvention.UnderscoreCase); + boolean actual1 = validator.isNamingValid(badUnderscoreCase1, NamingConvention.UnderscoreCase); + boolean actual2 = validator.isNamingValid(badUnderscoreCase2, NamingConvention.UnderscoreCase); + boolean actual3 = validator.isNamingValid(badUnderscoreCase3, NamingConvention.UnderscoreCase); + boolean actual4 = validator.isNamingValid(badUnderscoreCase4, NamingConvention.UnderscoreCase); + boolean actual5 = validator.isNamingValid(badUnderscoreCase5, NamingConvention.UnderscoreCase); + boolean actual6 = validator.isNamingValid(badUnderscoreCase6, NamingConvention.UnderscoreCase); // Assert Assertions.assertAll( @@ -96,12 +88,12 @@ void goodCamelCaseShouldReturnTrue() { String goodCamelCase6 = "address1"; // Act - boolean actual1 = validator.isNamingValid(goodCamelCase1, ValidatorParameters.NamingConvention.CamelCase); - boolean actual2 = validator.isNamingValid(goodCamelCase2, ValidatorParameters.NamingConvention.CamelCase); - boolean actual3 = validator.isNamingValid(goodCamelCase3, ValidatorParameters.NamingConvention.CamelCase); - boolean actual4 = validator.isNamingValid(goodCamelCase4, ValidatorParameters.NamingConvention.CamelCase); - boolean actual5 = validator.isNamingValid(goodCamelCase5, ValidatorParameters.NamingConvention.CamelCase); - boolean actual6 = validator.isNamingValid(goodCamelCase6, ValidatorParameters.NamingConvention.CamelCase); + boolean actual1 = validator.isNamingValid(goodCamelCase1, NamingConvention.CamelCase); + boolean actual2 = validator.isNamingValid(goodCamelCase2, NamingConvention.CamelCase); + boolean actual3 = validator.isNamingValid(goodCamelCase3, NamingConvention.CamelCase); + boolean actual4 = validator.isNamingValid(goodCamelCase4, NamingConvention.CamelCase); + boolean actual5 = validator.isNamingValid(goodCamelCase5, NamingConvention.CamelCase); + boolean actual6 = validator.isNamingValid(goodCamelCase6, NamingConvention.CamelCase); // Assert Assertions.assertAll( @@ -123,11 +115,11 @@ void badCamelCaseShouldReturnFalse() { String badCamelCase5 = "my variable"; // Act - boolean actual1 = validator.isNamingValid(badCamelCase1, ValidatorParameters.NamingConvention.CamelCase); - boolean actual2 = validator.isNamingValid(badCamelCase2, ValidatorParameters.NamingConvention.CamelCase); - boolean actual3 = validator.isNamingValid(badCamelCase3, ValidatorParameters.NamingConvention.CamelCase); - boolean actual4 = validator.isNamingValid(badCamelCase4, ValidatorParameters.NamingConvention.CamelCase); - boolean actual5 = validator.isNamingValid(badCamelCase5, ValidatorParameters.NamingConvention.CamelCase); + boolean actual1 = validator.isNamingValid(badCamelCase1, NamingConvention.CamelCase); + boolean actual2 = validator.isNamingValid(badCamelCase2, NamingConvention.CamelCase); + boolean actual3 = validator.isNamingValid(badCamelCase3, NamingConvention.CamelCase); + boolean actual4 = validator.isNamingValid(badCamelCase4, NamingConvention.CamelCase); + boolean actual5 = validator.isNamingValid(badCamelCase5, NamingConvention.CamelCase); // Assert Assertions.assertAll( @@ -146,9 +138,9 @@ void goodHyphenCaseShouldReturnTrue() { String goodHyphenCase3 = "my-super-variable"; // Act - boolean actual1 = validator.isNamingValid(goodHyphenCase1, ValidatorParameters.NamingConvention.HyphenCase); - boolean actual2 = validator.isNamingValid(goodHyphenCase2, ValidatorParameters.NamingConvention.HyphenCase); - boolean actual3 = validator.isNamingValid(goodHyphenCase3, ValidatorParameters.NamingConvention.HyphenCase); + boolean actual1 = validator.isNamingValid(goodHyphenCase1, NamingConvention.HyphenCase); + boolean actual2 = validator.isNamingValid(goodHyphenCase2, NamingConvention.HyphenCase); + boolean actual3 = validator.isNamingValid(goodHyphenCase3, NamingConvention.HyphenCase); // Assert Assertions.assertAll(() -> assertTrue(actual1), () -> assertTrue(actual2), () -> assertTrue(actual3)); @@ -165,12 +157,12 @@ void badHyphenCaseShouldReturnFalse() { String badHyphenCase6 = "my_variable_"; // Act - boolean actual1 = validator.isNamingValid(badHyphenCase1, ValidatorParameters.NamingConvention.HyphenCase); - boolean actual2 = validator.isNamingValid(badHyphenCase2, ValidatorParameters.NamingConvention.HyphenCase); - boolean actual3 = validator.isNamingValid(badHyphenCase3, ValidatorParameters.NamingConvention.HyphenCase); - boolean actual4 = validator.isNamingValid(badHyphenCase4, ValidatorParameters.NamingConvention.HyphenCase); - boolean actual5 = validator.isNamingValid(badHyphenCase5, ValidatorParameters.NamingConvention.HyphenCase); - boolean actual6 = validator.isNamingValid(badHyphenCase6, ValidatorParameters.NamingConvention.HyphenCase); + boolean actual1 = validator.isNamingValid(badHyphenCase1, NamingConvention.HyphenCase); + boolean actual2 = validator.isNamingValid(badHyphenCase2, NamingConvention.HyphenCase); + boolean actual3 = validator.isNamingValid(badHyphenCase3, NamingConvention.HyphenCase); + boolean actual4 = validator.isNamingValid(badHyphenCase4, NamingConvention.HyphenCase); + boolean actual5 = validator.isNamingValid(badHyphenCase5, NamingConvention.HyphenCase); + boolean actual6 = validator.isNamingValid(badHyphenCase6, NamingConvention.HyphenCase); // Assert Assertions.assertAll( @@ -190,12 +182,9 @@ void goodHyphenUpperCaseShouldReturnTrue() { String goodHyphenUpperCase3 = "My-Super-Variable"; // Act - boolean actual1 = - validator.isNamingValid(goodHyphenUpperCase1, ValidatorParameters.NamingConvention.HyphenUpperCase); - boolean actual2 = - validator.isNamingValid(goodHyphenUpperCase2, ValidatorParameters.NamingConvention.HyphenUpperCase); - boolean actual3 = - validator.isNamingValid(goodHyphenUpperCase3, ValidatorParameters.NamingConvention.HyphenUpperCase); + boolean actual1 = validator.isNamingValid(goodHyphenUpperCase1, NamingConvention.HyphenUpperCase); + boolean actual2 = validator.isNamingValid(goodHyphenUpperCase2, NamingConvention.HyphenUpperCase); + boolean actual3 = validator.isNamingValid(goodHyphenUpperCase3, NamingConvention.HyphenUpperCase); // Assert Assertions.assertAll(() -> assertTrue(actual1), () -> assertTrue(actual2), () -> assertTrue(actual3)); @@ -211,16 +200,11 @@ void badHyphenUpperCaseShouldReturnFalse() { String badHyphenUpperCase5 = "MyVariable"; // Act - boolean actual1 = - validator.isNamingValid(badHyphenUpperCase1, ValidatorParameters.NamingConvention.HyphenUpperCase); - boolean actual2 = - validator.isNamingValid(badHyphenUpperCase2, ValidatorParameters.NamingConvention.HyphenUpperCase); - boolean actual3 = - validator.isNamingValid(badHyphenUpperCase3, ValidatorParameters.NamingConvention.HyphenUpperCase); - boolean actual4 = - validator.isNamingValid(badHyphenUpperCase4, ValidatorParameters.NamingConvention.HyphenUpperCase); - boolean actual5 = - validator.isNamingValid(badHyphenUpperCase5, ValidatorParameters.NamingConvention.HyphenUpperCase); + boolean actual1 = validator.isNamingValid(badHyphenUpperCase1, NamingConvention.HyphenUpperCase); + boolean actual2 = validator.isNamingValid(badHyphenUpperCase2, NamingConvention.HyphenUpperCase); + boolean actual3 = validator.isNamingValid(badHyphenUpperCase3, NamingConvention.HyphenUpperCase); + boolean actual4 = validator.isNamingValid(badHyphenUpperCase4, NamingConvention.HyphenUpperCase); + boolean actual5 = validator.isNamingValid(badHyphenUpperCase5, NamingConvention.HyphenUpperCase); // Assert Assertions.assertAll( diff --git a/lib/src/test/java/org/openapitools/openapistylevalidator/OpenApiSpecStyleValidatorTest.java b/lib/src/test/java/org/openapitools/openapistylevalidator/OpenApiSpecStyleValidatorTest.java index 3e7bfd08..a3353e7f 100644 --- a/lib/src/test/java/org/openapitools/openapistylevalidator/OpenApiSpecStyleValidatorTest.java +++ b/lib/src/test/java/org/openapitools/openapistylevalidator/OpenApiSpecStyleValidatorTest.java @@ -15,8 +15,8 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; -import org.openapitools.openapistylevalidator.ValidatorParameters.NamingConvention; -import org.openapitools.openapistylevalidator.styleerror.StyleError; +import org.openapitools.openapistylevalidator.api.NamingConvention; +import org.openapitools.openapistylevalidator.error.StyleError; class OpenApiSpecStyleValidatorTest { diff --git a/lib/src/test/java/org/openapitools/openapistylevalidator/TestDataProvider.java b/lib/src/test/java/org/openapitools/openapistylevalidator/TestDataProvider.java index 309ac611..be281705 100644 --- a/lib/src/test/java/org/openapitools/openapistylevalidator/TestDataProvider.java +++ b/lib/src/test/java/org/openapitools/openapistylevalidator/TestDataProvider.java @@ -1,6 +1,9 @@ package org.openapitools.openapistylevalidator; -class TestDataProvider { +import org.eclipse.microprofile.openapi.OASFactory; +import org.eclipse.microprofile.openapi.models.OpenAPI; + +public class TestDataProvider { /** * With these parameters the validator should skip all checks */ @@ -19,4 +22,34 @@ static ValidatorParameters createParametersDisablingAllValidations() { .setValidateModelNoLocalDef(false) .setValidateNaming(false); } + + public static OpenAPI createValidOpenApi() { + return OASFactory.createOpenAPI() + .openapi("3.0.1") + .info(OASFactory.createInfo() + .title("Ping Specification") + .version("1.0") + .description("Ping Specification") + .license(OASFactory.createLicense() + .name("Eclipse Public License - v2.0") + .url("https://www.eclipse.org/legal/epl-2.0/")) + .contact( + OASFactory.createContact().name("OpenAPI Tools").email("team@openapitools.org"))) + .addServer(OASFactory.createServer().url("http://localhost:8000/")) + .paths(OASFactory.createPaths() + .addPathItem( + "/ping", + OASFactory.createPathItem() + .GET(OASFactory.createOperation() + .operationId("pingGet") + .summary("A simple get call") + .description( + "When this method is called, the server answers with 200 OKs") + .addTag("demo") + .responses(OASFactory.createAPIResponses() + .addAPIResponse( + "200", + OASFactory.createAPIResponse() + .description("OK")))))); + } } diff --git a/lib/src/test/java/org/openapitools/openapistylevalidator/ValidatorParametersTest.java b/lib/src/test/java/org/openapitools/openapistylevalidator/ValidatorParametersTest.java index b7f25eb9..ada8f17b 100644 --- a/lib/src/test/java/org/openapitools/openapistylevalidator/ValidatorParametersTest.java +++ b/lib/src/test/java/org/openapitools/openapistylevalidator/ValidatorParametersTest.java @@ -1,10 +1,13 @@ package org.openapitools.openapistylevalidator; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.openapitools.openapistylevalidator.api.NamingConvention; class ValidatorParametersTest { @@ -31,34 +34,26 @@ void validateDefaultValues() { () -> assertTrue(parameters.isValidateModelNoLocalDef()), () -> assertTrue(parameters.isValidateNaming()), () -> assertTrue(parameters.isIgnoreHeaderXNaming()), - () -> assertEquals( - ValidatorParameters.NamingConvention.HyphenCase, parameters.getPathNamingConvention()), - () -> assertEquals( - ValidatorParameters.NamingConvention.CamelCase, parameters.getParameterNamingConvention()), - () -> assertEquals( - ValidatorParameters.NamingConvention.UnderscoreUpperCase, - parameters.getHeaderNamingConvention()), - () -> assertEquals( - ValidatorParameters.NamingConvention.CamelCase, parameters.getPropertyNamingConvention()), - () -> assertEquals( - ValidatorParameters.NamingConvention.CamelCase, parameters.getQueryParamNamingConvention()), - () -> assertEquals( - ValidatorParameters.NamingConvention.CamelCase, parameters.getPathParamNamingConvention()), - () -> assertEquals( - ValidatorParameters.NamingConvention.CamelCase, parameters.getCookieParamNamingConvention())); + () -> assertEquals(NamingConvention.HyphenCase, parameters.getPathNamingConvention()), + () -> assertEquals(NamingConvention.CamelCase, parameters.getParameterNamingConvention()), + () -> assertEquals(NamingConvention.UnderscoreUpperCase, parameters.getHeaderNamingConvention()), + () -> assertEquals(NamingConvention.CamelCase, parameters.getPropertyNamingConvention()), + () -> assertEquals(NamingConvention.CamelCase, parameters.getQueryParamNamingConvention()), + () -> assertEquals(NamingConvention.CamelCase, parameters.getPathParamNamingConvention()), + () -> assertEquals(NamingConvention.CamelCase, parameters.getCookieParamNamingConvention())); } @Test void testAllGetterSetters() { parameters = TestDataProvider.createParametersDisablingAllValidations() .setIgnoreHeaderXNaming(false) - .setPathNamingConvention(ValidatorParameters.NamingConvention.CamelCase) - .setParameterNamingConvention(ValidatorParameters.NamingConvention.CamelCase) - .setHeaderNamingConvention(ValidatorParameters.NamingConvention.UnderscoreUpperCase) - .setPropertyNamingConvention(ValidatorParameters.NamingConvention.CamelCase) - .setQueryParamNamingConvention(ValidatorParameters.NamingConvention.CamelCase) - .setPathParamNamingConvention(ValidatorParameters.NamingConvention.CamelCase) - .setCookieParamNamingConvention(ValidatorParameters.NamingConvention.CamelCase); + .setPathNamingConvention(NamingConvention.CamelCase) + .setParameterNamingConvention(NamingConvention.CamelCase) + .setHeaderNamingConvention(NamingConvention.UnderscoreUpperCase) + .setPropertyNamingConvention(NamingConvention.CamelCase) + .setQueryParamNamingConvention(NamingConvention.CamelCase) + .setPathParamNamingConvention(NamingConvention.CamelCase) + .setCookieParamNamingConvention(NamingConvention.CamelCase); Assertions.assertAll( () -> assertFalse(parameters.isValidateInfoLicense()), @@ -74,20 +69,12 @@ void testAllGetterSetters() { () -> assertFalse(parameters.isValidateModelNoLocalDef()), () -> assertFalse(parameters.isValidateNaming()), () -> assertFalse(parameters.isIgnoreHeaderXNaming()), - () -> assertEquals( - ValidatorParameters.NamingConvention.CamelCase, parameters.getPathNamingConvention()), - () -> assertEquals( - ValidatorParameters.NamingConvention.CamelCase, parameters.getParameterNamingConvention()), - () -> assertEquals( - ValidatorParameters.NamingConvention.UnderscoreUpperCase, - parameters.getHeaderNamingConvention()), - () -> assertEquals( - ValidatorParameters.NamingConvention.CamelCase, parameters.getPropertyNamingConvention()), - () -> assertEquals( - ValidatorParameters.NamingConvention.CamelCase, parameters.getQueryParamNamingConvention()), - () -> assertEquals( - ValidatorParameters.NamingConvention.CamelCase, parameters.getPathParamNamingConvention()), - () -> assertEquals( - ValidatorParameters.NamingConvention.CamelCase, parameters.getCookieParamNamingConvention())); + () -> assertEquals(NamingConvention.CamelCase, parameters.getPathNamingConvention()), + () -> assertEquals(NamingConvention.CamelCase, parameters.getParameterNamingConvention()), + () -> assertEquals(NamingConvention.UnderscoreUpperCase, parameters.getHeaderNamingConvention()), + () -> assertEquals(NamingConvention.CamelCase, parameters.getPropertyNamingConvention()), + () -> assertEquals(NamingConvention.CamelCase, parameters.getQueryParamNamingConvention()), + () -> assertEquals(NamingConvention.CamelCase, parameters.getPathParamNamingConvention()), + () -> assertEquals(NamingConvention.CamelCase, parameters.getCookieParamNamingConvention())); } } diff --git a/lib/src/test/java/org/openapitools/openapistylevalidator/rules/ContactInfoRuleTest.java b/lib/src/test/java/org/openapitools/openapistylevalidator/rules/ContactInfoRuleTest.java new file mode 100644 index 00000000..b9b16429 --- /dev/null +++ b/lib/src/test/java/org/openapitools/openapistylevalidator/rules/ContactInfoRuleTest.java @@ -0,0 +1,47 @@ +package org.openapitools.openapistylevalidator.rules; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.openapitools.openapistylevalidator.TestDataProvider.createValidOpenApi; + +import java.util.List; +import org.eclipse.microprofile.openapi.OASFactory; +import org.eclipse.microprofile.openapi.models.OpenAPI; +import org.junit.jupiter.api.Test; +import org.openapitools.openapistylevalidator.api.IRule; +import org.openapitools.openapistylevalidator.error.StyleError; + +public class ContactInfoRuleTest { + + private final IRule rule = new ContactInfoRule(); + + @Test + public void testWithValidOpenAPI() { + List violation = rule.execute(createValidOpenApi()); + assertTrue(violation.isEmpty()); + } + + @Test + public void testWithInValidOpenAPI() { + OpenAPI openapi = OASFactory.createOpenAPI().openapi("3.0.1").info(OASFactory.createInfo()); + List styleErrors = rule.execute(openapi); + assertEquals(1, styleErrors.size()); + assertEquals( + "*ERROR* Section: APIInfo: 'contact' -> Should be present and not empty", + styleErrors.get(0).toString()); + } + + @Test + public void shouldValidateMissingContactNameAndUrlAndEmailInfo() { + OpenAPI openapi = OASFactory.createOpenAPI() + .openapi("3.0.1") + .info(OASFactory.createInfo() + .license(OASFactory.createLicense()) + .contact(OASFactory.createContact())); + List styleErrors = rule.execute(openapi); + assertEquals(1, styleErrors.size()); + assertEquals( + "*ERROR* Section: APIInfo: 'contact' -> At least one field should be present and not empty. name|url|email", + styleErrors.get(0).toString()); + } +} diff --git a/lib/src/test/java/org/openapitools/openapistylevalidator/rules/InfoDescriptionRuleTest.java b/lib/src/test/java/org/openapitools/openapistylevalidator/rules/InfoDescriptionRuleTest.java new file mode 100644 index 00000000..39972d38 --- /dev/null +++ b/lib/src/test/java/org/openapitools/openapistylevalidator/rules/InfoDescriptionRuleTest.java @@ -0,0 +1,35 @@ +package org.openapitools.openapistylevalidator.rules; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.openapitools.openapistylevalidator.TestDataProvider.createValidOpenApi; + +import java.util.List; +import org.eclipse.microprofile.openapi.OASFactory; +import org.eclipse.microprofile.openapi.models.OpenAPI; +import org.junit.jupiter.api.Test; +import org.openapitools.openapistylevalidator.api.IRule; +import org.openapitools.openapistylevalidator.error.StyleError; + +public class InfoDescriptionRuleTest { + + private final IRule rule = new InfoDescriptionRule(); + + @Test + public void testWithValidOpenAPI() { + List violation = rule.execute(createValidOpenApi()); + assertTrue(violation.isEmpty()); + } + + @Test + public void testWithInValidOpenAPI() { + OpenAPI openapi = OASFactory.createOpenAPI() + .openapi("3.0.1") + .info(OASFactory.createInfo().description("")); + List styleErrors = rule.execute(openapi); + assertEquals(1, styleErrors.size()); + assertEquals( + "*ERROR* Section: APIInfo: 'description' -> Should be present and not empty", + styleErrors.get(0).toString()); + } +} diff --git a/lib/src/test/java/org/openapitools/openapistylevalidator/rules/LicenseRuleTest.java b/lib/src/test/java/org/openapitools/openapistylevalidator/rules/LicenseRuleTest.java new file mode 100644 index 00000000..de9d2dbb --- /dev/null +++ b/lib/src/test/java/org/openapitools/openapistylevalidator/rules/LicenseRuleTest.java @@ -0,0 +1,47 @@ +package org.openapitools.openapistylevalidator.rules; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.openapitools.openapistylevalidator.TestDataProvider.createValidOpenApi; + +import java.util.List; +import org.eclipse.microprofile.openapi.OASFactory; +import org.eclipse.microprofile.openapi.models.OpenAPI; +import org.junit.jupiter.api.Test; +import org.openapitools.openapistylevalidator.api.IRule; +import org.openapitools.openapistylevalidator.error.StyleError; + +public class LicenseRuleTest { + + private final IRule rule = new LicenseRule(); + + @Test + public void testWithValidOpenAPI() { + List violation = rule.execute(createValidOpenApi()); + assertTrue(violation.isEmpty()); + } + + @Test + public void testWithInValidOpenAPI() { + OpenAPI openapi = OASFactory.createOpenAPI() + .openapi("3.0.1") + .info(OASFactory.createInfo().description("")); + List styleErrors = rule.execute(openapi); + assertEquals(1, styleErrors.size()); + assertEquals( + "*ERROR* Section: APIInfo: 'license' -> Should be present and not empty", + styleErrors.get(0).toString()); + } + + @Test + public void shouldValidateLicenseUrlAndNameShouldNotBeEmpty() { + OpenAPI openapi = OASFactory.createOpenAPI() + .openapi("3.0.1") + .info(OASFactory.createInfo().license(OASFactory.createLicense())); + List styleErrors = rule.execute(openapi); + assertEquals(1, styleErrors.size()); + assertEquals( + "*ERROR* Section: APIInfo: 'name|url' in license -> At least one field should be present and not empty", + styleErrors.get(0).toString()); + } +} diff --git a/lib/src/test/java/org/openapitools/openapistylevalidator/rules/OpenAPIRuleTest.java b/lib/src/test/java/org/openapitools/openapistylevalidator/rules/OpenAPIRuleTest.java new file mode 100644 index 00000000..30d17309 --- /dev/null +++ b/lib/src/test/java/org/openapitools/openapistylevalidator/rules/OpenAPIRuleTest.java @@ -0,0 +1,32 @@ +package org.openapitools.openapistylevalidator.rules; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.openapitools.openapistylevalidator.TestDataProvider.*; + +import java.util.List; +import org.eclipse.microprofile.openapi.OASFactory; +import org.eclipse.microprofile.openapi.models.OpenAPI; +import org.junit.jupiter.api.Test; +import org.openapitools.openapistylevalidator.error.StyleError; + +public class OpenAPIRuleTest { + + private OpenAPIRule rule = new OpenAPIRule(); + + @Test + public void testWithValidOpenAPI() { + List violation = rule.execute(createValidOpenApi()); + assertTrue(violation.isEmpty()); + } + + @Test + public void testWithInValidOpenAPI() { + OpenAPI openapi = OASFactory.createOpenAPI().openapi("3.0.1"); + List styleErrors = rule.execute(openapi); + assertEquals(1, styleErrors.size()); + assertEquals( + "*ERROR* Section: OpenAPI: 'paths,components' -> Should have at least one of paths or components", + styleErrors.get(0).toString()); + } +} diff --git a/lib/src/test/java/org/openapitools/openapistylevalidator/rules/OperationDescriptionRuleTest.java b/lib/src/test/java/org/openapitools/openapistylevalidator/rules/OperationDescriptionRuleTest.java new file mode 100644 index 00000000..b57d4686 --- /dev/null +++ b/lib/src/test/java/org/openapitools/openapistylevalidator/rules/OperationDescriptionRuleTest.java @@ -0,0 +1,60 @@ +package org.openapitools.openapistylevalidator.rules; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.openapitools.openapistylevalidator.TestDataProvider.createValidOpenApi; + +import java.util.List; +import org.eclipse.microprofile.openapi.OASFactory; +import org.eclipse.microprofile.openapi.models.OpenAPI; +import org.junit.jupiter.api.Test; +import org.openapitools.openapistylevalidator.api.IRule; +import org.openapitools.openapistylevalidator.error.StyleError; + +public class OperationDescriptionRuleTest { + + private final IRule rule = new OperationDescriptionRule(); + + @Test + public void testWithValidOpenAPI() { + List violation = rule.execute(createValidOpenApi()); + assertTrue(violation.isEmpty()); + } + + @Test + public void testWithInValidOpenAPI() { + List styleErrors = rule.execute(createInValidOpenAPI()); + assertEquals(1, styleErrors.size()); + assertEquals( + "*ERROR* in Operation GET /ping 'description' -> This field should be present and not empty", + styleErrors.get(0).toString()); + } + + private OpenAPI createInValidOpenAPI() { + return OASFactory.createOpenAPI() + .openapi("3.0.1") + .info(OASFactory.createInfo() + .title("Ping Specification") + .version("1.0") + .license(OASFactory.createLicense() + .name("Eclipse Public License - v2.0") + .url("https://www.eclipse.org/legal/epl-2.0/")) + .description("This is a test spec") + .contact( + OASFactory.createContact().name("OpenAPI Tools").email("team@openapitools.org"))) + .addServer(OASFactory.createServer().url("http://localhost:8000/")) + .paths(OASFactory.createPaths() + .addPathItem( + "/ping", + OASFactory.createPathItem() + .GET(OASFactory.createOperation() + .operationId("pingGet") + .summary("A simple get call") + .addTag("demo") + .responses(OASFactory.createAPIResponses() + .addAPIResponse( + "200", + OASFactory.createAPIResponse() + .description("OK")))))); + } +} diff --git a/lib/src/test/java/org/openapitools/openapistylevalidator/rules/OperationIDRuleTest.java b/lib/src/test/java/org/openapitools/openapistylevalidator/rules/OperationIDRuleTest.java new file mode 100644 index 00000000..da4730c0 --- /dev/null +++ b/lib/src/test/java/org/openapitools/openapistylevalidator/rules/OperationIDRuleTest.java @@ -0,0 +1,62 @@ +package org.openapitools.openapistylevalidator.rules; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.openapitools.openapistylevalidator.TestDataProvider.createValidOpenApi; + +import java.util.List; +import org.eclipse.microprofile.openapi.OASFactory; +import org.eclipse.microprofile.openapi.models.OpenAPI; +import org.junit.jupiter.api.Test; +import org.openapitools.openapistylevalidator.api.IRule; +import org.openapitools.openapistylevalidator.error.StyleError; + +public class OperationIDRuleTest { + + private final IRule rule = new OperationIDRule(); + + @Test + public void testWithValidOpenAPI() { + List violation = rule.execute(createValidOpenApi()); + assertTrue(violation.isEmpty()); + } + + @Test + public void testWithInValidOpenAPI() { + OpenAPI openapi = createInValidOpenApi(); + List styleErrors = rule.execute(openapi); + assertEquals(1, styleErrors.size()); + assertEquals( + "*ERROR* in Operation GET /ping 'operationId' -> This field should be present and not empty", + styleErrors.get(0).toString()); + } + + private OpenAPI createInValidOpenApi() { + return OASFactory.createOpenAPI() + .openapi("3.0.1") + .info(OASFactory.createInfo() + .title("Ping Specification") + .version("1.0") + .license(OASFactory.createLicense() + .name("Eclipse Public License - v2.0") + .url("https://www.eclipse.org/legal/epl-2.0/")) + .description("This is a test spec") + .contact( + OASFactory.createContact().name("OpenAPI Tools").email("team@openapitools.org"))) + .addServer(OASFactory.createServer().url("http://localhost:8000/")) + .paths(OASFactory.createPaths() + .addPathItem( + "/ping", + OASFactory.createPathItem() + .GET(OASFactory.createOperation() + .summary("A simple get call") + .description( + "When this method is called, the server answers with 200 OKs") + .addTag("demo") + .responses(OASFactory.createAPIResponses() + .addAPIResponse( + "200", + OASFactory.createAPIResponse() + .description("OK")))))); + } +} diff --git a/lib/src/test/java/org/openapitools/openapistylevalidator/rules/OperationSummaryRuleTest.java b/lib/src/test/java/org/openapitools/openapistylevalidator/rules/OperationSummaryRuleTest.java new file mode 100644 index 00000000..dfb64411 --- /dev/null +++ b/lib/src/test/java/org/openapitools/openapistylevalidator/rules/OperationSummaryRuleTest.java @@ -0,0 +1,61 @@ +package org.openapitools.openapistylevalidator.rules; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.openapitools.openapistylevalidator.TestDataProvider.createValidOpenApi; + +import java.util.List; +import org.eclipse.microprofile.openapi.OASFactory; +import org.eclipse.microprofile.openapi.models.OpenAPI; +import org.junit.jupiter.api.Test; +import org.openapitools.openapistylevalidator.api.IRule; +import org.openapitools.openapistylevalidator.error.StyleError; + +public class OperationSummaryRuleTest { + + private final IRule rule = new OperationSummaryRule(); + + @Test + public void testWithValidOpenAPI() { + List violation = rule.execute(createValidOpenApi()); + assertTrue(violation.isEmpty()); + } + + @Test + public void testWithInValidOpenAPI() { + OpenAPI openapi = createInValidOpenApi(); + List styleErrors = rule.execute(openapi); + assertEquals(1, styleErrors.size()); + assertEquals( + "*ERROR* in Operation GET /ping 'summary' -> This field should be present and not empty", + styleErrors.get(0).toString()); + } + + private OpenAPI createInValidOpenApi() { + return OASFactory.createOpenAPI() + .openapi("3.0.1") + .info(OASFactory.createInfo() + .title("Ping Specification") + .version("1.0") + .license(OASFactory.createLicense() + .name("Eclipse Public License - v2.0") + .url("https://www.eclipse.org/legal/epl-2.0/")) + .description("This is a test spec") + .contact( + OASFactory.createContact().name("OpenAPI Tools").email("team@openapitools.org"))) + .addServer(OASFactory.createServer().url("http://localhost:8000/")) + .paths(OASFactory.createPaths() + .addPathItem( + "/ping", + OASFactory.createPathItem() + .GET(OASFactory.createOperation() + .operationId("pingGet") + .description( + "When this method is called, the server answers with 200 OKs") + .responses(OASFactory.createAPIResponses() + .addAPIResponse( + "200", + OASFactory.createAPIResponse() + .description("OK")))))); + } +} diff --git a/lib/src/test/java/org/openapitools/openapistylevalidator/rules/OperationTagRuleTest.java b/lib/src/test/java/org/openapitools/openapistylevalidator/rules/OperationTagRuleTest.java new file mode 100644 index 00000000..16c376e3 --- /dev/null +++ b/lib/src/test/java/org/openapitools/openapistylevalidator/rules/OperationTagRuleTest.java @@ -0,0 +1,62 @@ +package org.openapitools.openapistylevalidator.rules; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.openapitools.openapistylevalidator.TestDataProvider.createValidOpenApi; + +import java.util.List; +import org.eclipse.microprofile.openapi.OASFactory; +import org.eclipse.microprofile.openapi.models.OpenAPI; +import org.junit.jupiter.api.Test; +import org.openapitools.openapistylevalidator.api.IRule; +import org.openapitools.openapistylevalidator.error.StyleError; + +public class OperationTagRuleTest { + + private final IRule rule = new OperationTagRule(); + + @Test + public void testWithValidOpenAPI() { + List violation = rule.execute(createValidOpenApi()); + assertTrue(violation.isEmpty()); + } + + @Test + public void testWithInValidOpenAPI() { + OpenAPI openapi = createInValidOpenApi(); + List styleErrors = rule.execute(openapi); + assertEquals(1, styleErrors.size()); + assertEquals( + "*ERROR* in Operation GET /ping 'tags' -> The collection should be present and there should be at least one item in it", + styleErrors.get(0).toString()); + } + + private OpenAPI createInValidOpenApi() { + return OASFactory.createOpenAPI() + .openapi("3.0.1") + .info(OASFactory.createInfo() + .title("Ping Specification") + .version("1.0") + .license(OASFactory.createLicense() + .name("Eclipse Public License - v2.0") + .url("https://www.eclipse.org/legal/epl-2.0/")) + .description("This is a test spec") + .contact( + OASFactory.createContact().name("OpenAPI Tools").email("team@openapitools.org"))) + .addServer(OASFactory.createServer().url("http://localhost:8000/")) + .paths(OASFactory.createPaths() + .addPathItem( + "/ping", + OASFactory.createPathItem() + .GET(OASFactory.createOperation() + .operationId("pingGet") + .summary("A simple get call") + .description( + "When this method is called, the server answers with 200 OKs") + .responses(OASFactory.createAPIResponses() + .addAPIResponse( + "200", + OASFactory.createAPIResponse() + .description("OK")))))); + } +} diff --git a/maven-plugin/build.gradle b/maven-plugin/build.gradle index 717c5f65..1ceb18a1 100644 --- a/maven-plugin/build.gradle +++ b/maven-plugin/build.gradle @@ -11,7 +11,7 @@ dependencies { exclude group: 'javax.inject', module: 'javax.inject' exclude group: 'org.codehaus.plexus', module: 'plexus-component-annotations' } - + implementation project(':openapi-style-validator-api') implementation project(':openapi-style-validator-lib') implementation 'io.swagger.parser.v3:swagger-parser:2.0.33' implementation 'org.openapitools.empoa:empoa-swagger-core:2.1.0' diff --git a/maven-plugin/src/main/java/org/openapitools/openapistylevalidator/maven/OpenAPIStyleValidatorMojo.java b/maven-plugin/src/main/java/org/openapitools/openapistylevalidator/maven/OpenAPIStyleValidatorMojo.java index 85b20190..3ecbb76c 100644 --- a/maven-plugin/src/main/java/org/openapitools/openapistylevalidator/maven/OpenAPIStyleValidatorMojo.java +++ b/maven-plugin/src/main/java/org/openapitools/openapistylevalidator/maven/OpenAPIStyleValidatorMojo.java @@ -10,8 +10,8 @@ import org.openapitools.empoa.swagger.core.internal.SwAdapter; import org.openapitools.openapistylevalidator.OpenApiSpecStyleValidator; import org.openapitools.openapistylevalidator.ValidatorParameters; -import org.openapitools.openapistylevalidator.ValidatorParameters.NamingConvention; -import org.openapitools.openapistylevalidator.styleerror.StyleError; +import org.openapitools.openapistylevalidator.api.NamingConvention; +import org.openapitools.openapistylevalidator.error.StyleError; import io.swagger.parser.OpenAPIParser; import io.swagger.v3.parser.core.models.ParseOptions; diff --git a/settings.gradle b/settings.gradle index 02b3427c..942bd131 100644 --- a/settings.gradle +++ b/settings.gradle @@ -4,7 +4,10 @@ include(':openapi-style-validator-lib') include(':openapi-style-validator-cli') include(':openapi-style-validator-gradle-plugin') include(':openapi-style-validator-maven-plugin') +include(':openapi-style-validator-api') project(":openapi-style-validator-lib").projectDir = file('lib') project(":openapi-style-validator-cli").projectDir = file('cli') project(":openapi-style-validator-gradle-plugin").projectDir = file('gradle-plugin') project(":openapi-style-validator-maven-plugin").projectDir = file('maven-plugin') +project(":openapi-style-validator-api").projectDir = file('api') +