b/161470092 Implement traversal for OpenApi4j Tag object Change-Id: Ib038193c03e25bf7365aae90a34292647eecd8ea
diff --git a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/ExternalDocsTraversal.java b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/ExternalDocsTraversal.java new file mode 100644 index 0000000..59a9440 --- /dev/null +++ b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/ExternalDocsTraversal.java
@@ -0,0 +1,28 @@ +package com.apigee.security.oas.extendedvalidator; + +import com.google.inject.assistedinject.Assisted; +import javax.inject.Inject; +import org.openapi4j.parser.model.v3.ExternalDocs; + +/** A {@link Traversal} that traverses a {@link ExternalDocs} object. */ +final class ExternalDocsTraversal extends Traversal<ExternalDocs> + implements ExternalDocsTraversalCommand { + + @Inject + ExternalDocsTraversal( + TraversalCoordinator traversalCoordinator, + ExtensionValidationIntegrator extensionValidationIntegrator, + TraversalCommandFactory traversalCommandFactory, + @Assisted ExternalDocs openApiSchemaObj) { + super( + traversalCoordinator, + extensionValidationIntegrator, + traversalCommandFactory, + openApiSchemaObj); + } + + @Override + public void traverse() { + // TODO(b/161441872): Add call to process extensions. + } +}
diff --git a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/ExternalDocsTraversalCommand.java b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/ExternalDocsTraversalCommand.java new file mode 100644 index 0000000..b2c79b9 --- /dev/null +++ b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/ExternalDocsTraversalCommand.java
@@ -0,0 +1,4 @@ +package com.apigee.security.oas.extendedvalidator; + +/** A {@link TraversalCommand} interface for {@link ExternalDocsTraversal}. */ +public interface ExternalDocsTraversalCommand extends TraversalCommand {}
diff --git a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/InfoTraversal.java b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/InfoTraversal.java index 2f1781c..046b274 100644 --- a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/InfoTraversal.java +++ b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/InfoTraversal.java
@@ -24,11 +24,9 @@ public void traverse() { // TODO(b/161441872): Process extensions. - // TODO(b/161811574): Add check for Contacts' existence. + // TODO(b/161811574): Add checks for field unpacking. traversalCoordinator.handleTraversalCommand( traversalCommandFactory.create(openApiSchemaObj.getContact())); - - // TODO(b/161811574): Add check for License's existence. traversalCoordinator.handleTraversalCommand( traversalCommandFactory.create(openApiSchemaObj.getLicense())); }
diff --git a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/OpenApiSpecificationTraversal.java b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/OpenApiSpecificationTraversal.java index 0138fee..109132d 100644 --- a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/OpenApiSpecificationTraversal.java +++ b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/OpenApiSpecificationTraversal.java
@@ -28,10 +28,11 @@ traverseInfo(); traverseServers(); + traverseTags(); } private void traverseInfo() { - // TODO(b/161811574): Add check for Info's existence. + // TODO(b/161811574): Safely unpack Info. traversalCoordinator.handleTraversalCommand( traversalCommandFactory.create(openApiSchemaObj.getInfo())); @@ -46,4 +47,14 @@ traversalCoordinator.handleTraversalCommand( traversalCommandFactory.create(server)))); } + + private void traverseTags() { + Optional.ofNullable(openApiSchemaObj.getTags()) + .ifPresent( + tags -> + tags.forEach( + tag -> + traversalCoordinator.handleTraversalCommand( + traversalCommandFactory.create(tag)))); + } }
diff --git a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/OpenApiSpecificationTraversalCommand.java b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/OpenApiSpecificationTraversalCommand.java index 2f65ded..c7e4cdc 100644 --- a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/OpenApiSpecificationTraversalCommand.java +++ b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/OpenApiSpecificationTraversalCommand.java
@@ -1,4 +1,4 @@ package com.apigee.security.oas.extendedvalidator; -/** A {@link TraversalCommand} marker interface for {@link OpenApiSpecificationTraversal}. */ +/** A {@link TraversalCommand} interface for {@link OpenApiSpecificationTraversal}. */ public interface OpenApiSpecificationTraversalCommand extends TraversalCommand {}
diff --git a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/TagTraversal.java b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/TagTraversal.java new file mode 100644 index 0000000..52ecd34 --- /dev/null +++ b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/TagTraversal.java
@@ -0,0 +1,34 @@ +package com.apigee.security.oas.extendedvalidator; + +import com.google.inject.assistedinject.Assisted; +import java.util.Optional; +import javax.inject.Inject; +import org.openapi4j.parser.model.v3.Tag; + +/** A {@link Traversal} that traverses a {@link Tag} object. */ +final class TagTraversal extends Traversal<Tag> implements TagTraversalCommand { + + @Inject + TagTraversal( + TraversalCoordinator traversalCoordinator, + ExtensionValidationIntegrator extensionValidationIntegrator, + TraversalCommandFactory traversalCommandFactory, + @Assisted Tag openApiSchemaObj) { + super( + traversalCoordinator, + extensionValidationIntegrator, + traversalCommandFactory, + openApiSchemaObj); + } + + @Override + public void traverse() { + // TODO(b/161441872): Add call to process extensions. + + Optional.ofNullable(openApiSchemaObj.getExternalDocs()) + .ifPresent( + externalDocs -> + traversalCoordinator.handleTraversalCommand( + traversalCommandFactory.create(externalDocs))); + } +}
diff --git a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/TagTraversalCommand.java b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/TagTraversalCommand.java new file mode 100644 index 0000000..23bd91b --- /dev/null +++ b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/TagTraversalCommand.java
@@ -0,0 +1,4 @@ +package com.apigee.security.oas.extendedvalidator; + +/** A {@link TraversalCommand} interface for {@link TagTraversal}. */ +public interface TagTraversalCommand extends TraversalCommand {}
diff --git a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/Traversal.java b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/Traversal.java index cc1ad65..7211dfb 100644 --- a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/Traversal.java +++ b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/Traversal.java
@@ -5,10 +5,10 @@ /** Superclass field skeleton for traversing an {@link OpenApiSchema} object. */ abstract class Traversal<T extends OpenApiSchema> { - protected T openApiSchemaObj; - protected TraversalCoordinator traversalCoordinator; - protected ExtensionValidationIntegrator extensionValidationIntegrator; - protected TraversalCommandFactory traversalCommandFactory; + protected final T openApiSchemaObj; + protected final TraversalCoordinator traversalCoordinator; + protected final ExtensionValidationIntegrator extensionValidationIntegrator; + protected final TraversalCommandFactory traversalCommandFactory; Traversal( TraversalCoordinator traversalCoordinator,
diff --git a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/TraversalCommandFactory.java b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/TraversalCommandFactory.java index b742780..e7d0ad4 100644 --- a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/TraversalCommandFactory.java +++ b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/TraversalCommandFactory.java
@@ -1,11 +1,13 @@ package com.apigee.security.oas.extendedvalidator; import org.openapi4j.parser.model.v3.Contact; +import org.openapi4j.parser.model.v3.ExternalDocs; import org.openapi4j.parser.model.v3.Info; import org.openapi4j.parser.model.v3.License; import org.openapi4j.parser.model.v3.OpenApi3; import org.openapi4j.parser.model.v3.Server; import org.openapi4j.parser.model.v3.ServerVariable; +import org.openapi4j.parser.model.v3.Tag; /** * Generates {@link TraversalCommand} implementations via Guice's {@link @@ -13,15 +15,19 @@ */ interface TraversalCommandFactory { - OpenApiSpecificationTraversalCommand create(OpenApi3 openApiSpec); + ContactTraversalCommand create(Contact contact); + + ExternalDocsTraversalCommand create(ExternalDocs externalDocs); InfoTraversalCommand create(Info info); - ContactTraversalCommand create(Contact contact); - LicenseTraversalCommand create(License license); + OpenApiSpecificationTraversalCommand create(OpenApi3 openApiSpec); + ServerTraversalCommand create(Server server); ServerVariableTraversalCommand create(ServerVariable serverVariable, String name); + + TagTraversalCommand create(Tag tag); }
diff --git a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/TraversalCommandFactoryModule.java b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/TraversalCommandFactoryModule.java index 8384642..bcaba34 100644 --- a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/TraversalCommandFactoryModule.java +++ b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/TraversalCommandFactoryModule.java
@@ -9,13 +9,15 @@ protected void configure() { install( new FactoryModuleBuilder() + .implement(ContactTraversalCommand.class, ContactTraversal.class) + .implement(ExternalDocsTraversalCommand.class, ExternalDocsTraversal.class) + .implement(InfoTraversalCommand.class, InfoTraversal.class) + .implement(LicenseTraversalCommand.class, LicenseTraversal.class) .implement( OpenApiSpecificationTraversalCommand.class, OpenApiSpecificationTraversal.class) - .implement(InfoTraversalCommand.class, InfoTraversal.class) - .implement(ContactTraversalCommand.class, ContactTraversal.class) - .implement(LicenseTraversalCommand.class, LicenseTraversal.class) .implement(ServerTraversalCommand.class, ServerTraversal.class) .implement(ServerVariableTraversalCommand.class, ServerVariableTraversal.class) + .implement(TagTraversalCommand.class, TagTraversal.class) .build(TraversalCommandFactory.class)); } }
diff --git a/oas-core/src/test/java/com/apigee/security/oas/extendedvalidator/OpenApiSpecificationTraversalTest.java b/oas-core/src/test/java/com/apigee/security/oas/extendedvalidator/OpenApiSpecificationTraversalTest.java index 348e2d4..0887e9d 100644 --- a/oas-core/src/test/java/com/apigee/security/oas/extendedvalidator/OpenApiSpecificationTraversalTest.java +++ b/oas-core/src/test/java/com/apigee/security/oas/extendedvalidator/OpenApiSpecificationTraversalTest.java
@@ -19,6 +19,7 @@ import org.openapi4j.parser.model.v3.Info; import org.openapi4j.parser.model.v3.OpenApi3; import org.openapi4j.parser.model.v3.Server; +import org.openapi4j.parser.model.v3.Tag; @RunWith(JUnit4.class) public class OpenApiSpecificationTraversalTest { @@ -31,6 +32,7 @@ private OpenApiSpecificationTraversal openApiSpecificationTraversal; private ImmutableList<Server> servers; + private ImmutableList<Tag> tags; /** Sets up live and mocked instances for testing. */ @Before @@ -49,6 +51,9 @@ servers = ImmutableList.of(new Server(), new Server(), new Server()); when(openApiSpec.getServers()).thenReturn(servers); + tags = ImmutableList.of(new Tag(), new Tag(), new Tag()); + when(openApiSpec.getTags()).thenReturn(tags); + when(openApiSpec.getInfo()).thenReturn(new Info()); } @@ -59,7 +64,7 @@ verify(traversalCoordinator).handleTraversalCommand(any(InfoTraversal.class)); } - // TODO(b/161811574): Add tests for additional nullable children. + // TODO(b/161811574): Add tests to check other nullable children. @Test public void traverse_sendsServerChildrenTraversalsToTraversalCommander() { @@ -75,4 +80,19 @@ openApiSpecificationTraversal.traverse(); } + + @Test + public void traverse_sendsTagChildrenTraversalsToTraversalCommander() { + openApiSpecificationTraversal.traverse(); + + verify(traversalCoordinator, times(tags.size())) + .handleTraversalCommand(any(TagTraversalCommand.class)); + } + + @Test + public void traverse_nullTagChildren_doesNotThrowException() { + when(openApiSpec.getTags()).thenReturn(null); + + openApiSpecificationTraversal.traverse(); + } }
diff --git a/oas-core/src/test/java/com/apigee/security/oas/extendedvalidator/TagTraversalTest.java b/oas-core/src/test/java/com/apigee/security/oas/extendedvalidator/TagTraversalTest.java new file mode 100644 index 0000000..bf3db6f --- /dev/null +++ b/oas-core/src/test/java/com/apigee/security/oas/extendedvalidator/TagTraversalTest.java
@@ -0,0 +1,58 @@ +package com.apigee.security.oas.extendedvalidator; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import com.google.inject.Guice; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; +import org.mockito.quality.Strictness; +import org.openapi4j.parser.model.v3.ExternalDocs; +import org.openapi4j.parser.model.v3.Tag; + +@RunWith(JUnit4.class) +public class TagTraversalTest { + + @Rule public final MockitoRule rule = MockitoJUnit.rule().strictness(Strictness.STRICT_STUBS); + + @Mock private TraversalCoordinator traversalCoordinator; + @Mock private ExtensionValidationIntegrator extensionValidationIntegrator; + @Mock private Tag tag; + + private TagTraversal tagTraversal; + + /** Sets up live and mocked instances for testing. */ + @Before + public void setup() { + TraversalCommandFactory traversalCommandFactory = + Guice.createInjector(new ExtendedValidatorMainModule()) + .getInstance(TraversalCommandFactory.class); + + tagTraversal = + new TagTraversal( + traversalCoordinator, extensionValidationIntegrator, traversalCommandFactory, tag); + } + + @Test + public void traverse_sendsTraversalCommanderExternalDocsTraversalCommand() { + when(tag.getExternalDocs()).thenReturn(new ExternalDocs()); + + tagTraversal.traverse(); + + verify(traversalCoordinator).handleTraversalCommand(any(ExternalDocsTraversal.class)); + } + + @Test + public void traverse_nullExternalDocChild_doesNotFail() { + when(tag.getExternalDocs()).thenReturn(null); + + tagTraversal.traverse(); + } +}
diff --git a/oas-core/src/test/java/com/apigee/security/oas/extendedvalidator/TraversalCommandFactoryTest.java b/oas-core/src/test/java/com/apigee/security/oas/extendedvalidator/TraversalCommandFactoryTest.java index 9f580b4..25920ac 100644 --- a/oas-core/src/test/java/com/apigee/security/oas/extendedvalidator/TraversalCommandFactoryTest.java +++ b/oas-core/src/test/java/com/apigee/security/oas/extendedvalidator/TraversalCommandFactoryTest.java
@@ -8,11 +8,13 @@ import org.junit.runner.RunWith; import org.junit.runners.JUnit4; import org.openapi4j.parser.model.v3.Contact; +import org.openapi4j.parser.model.v3.ExternalDocs; import org.openapi4j.parser.model.v3.Info; import org.openapi4j.parser.model.v3.License; import org.openapi4j.parser.model.v3.OpenApi3; import org.openapi4j.parser.model.v3.Server; import org.openapi4j.parser.model.v3.ServerVariable; +import org.openapi4j.parser.model.v3.Tag; @RunWith(JUnit4.class) public class TraversalCommandFactoryTest { @@ -64,4 +66,15 @@ assertThat(traversal).isInstanceOf(ServerVariableTraversalCommand.class); } + + @Test + public void create_tagObjectPassed_returnsTagTraversalCommand() { + assertThat(traversalCommandFactory.create(new Tag())).isInstanceOf(TagTraversalCommand.class); + } + + @Test + public void create_externalDocsObjectPassed_returnsExternalDocsTraversalCommand() { + assertThat(traversalCommandFactory.create(new ExternalDocs())) + .isInstanceOf(ExternalDocsTraversalCommand.class); + } }