b/162837037 Handle traversal null collections Change-Id: Ib14c3965a9646786ca4184852bdd98bf2a76d0f4
diff --git a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/BaseTraversalHelper.java b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/BaseTraversalHelper.java index 5319099..a10f139 100644 --- a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/BaseTraversalHelper.java +++ b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/BaseTraversalHelper.java
@@ -88,7 +88,8 @@ } @Override - public void sendServerVariableTraversals(ImmutableMap<String, ServerVariable> serverVariablesMap) { + public void sendServerVariableTraversals( + ImmutableMap<String, ServerVariable> serverVariablesMap) { Optional.ofNullable(serverVariablesMap) .ifPresent( serverVariables -> {
diff --git a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/Immutables.java b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/Immutables.java new file mode 100644 index 0000000..e39b609 --- /dev/null +++ b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/Immutables.java
@@ -0,0 +1,24 @@ +package com.apigee.security.oas.extendedvalidator; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import org.checkerframework.checker.nullness.qual.Nullable; + +/** Set of utility methods for safely transforming a collection into an immutable collection. */ +public final class Immutables { + + /** Safely converts {@link List} to {@link ImmutableList}. */ + public static final <T> ImmutableList<T> toImmutableList(@Nullable List<T> list) { + return Optional.ofNullable(list).map(ImmutableList::copyOf).orElse(ImmutableList.of()); + } + + /** Safely converts {@link Map} to {@link ImmutableMap}. */ + public static final <K, V> ImmutableMap<K, V> toImmutableMap(@Nullable Map<K, V> map) { + return Optional.ofNullable(map).map(ImmutableMap::copyOf).orElse(ImmutableMap.of()); + } + + private Immutables() {} +}
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 3096ba5..1709d93 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
@@ -1,5 +1,7 @@ package com.apigee.security.oas.extendedvalidator; +import static com.apigee.security.oas.extendedvalidator.Immutables.toImmutableList; + import com.google.common.collect.ImmutableList; import com.google.inject.assistedinject.Assisted; import javax.inject.Inject; @@ -25,8 +27,8 @@ traversalHelper.sendExternalDocsTraversal(openApiSchemaObj.getExternalDocs()); traversalHelper.sendInfoTraversal(openApiSchemaObj.getInfo()); - traversalHelper.sendServerTraversals(ImmutableList.copyOf(openApiSchemaObj.getServers())); - traversalHelper.sendTagTraversals(ImmutableList.copyOf(openApiSchemaObj.getTags())); + traversalHelper.sendServerTraversals(toImmutableList(openApiSchemaObj.getServers())); + traversalHelper.sendTagTraversals(toImmutableList(openApiSchemaObj.getTags())); // TODO(b/162508047): Add path object traversal and callback object traversal logic. } }
diff --git a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/ServerTraversal.java b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/ServerTraversal.java index c7c3967..c464d7a 100644 --- a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/ServerTraversal.java +++ b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/ServerTraversal.java
@@ -1,7 +1,8 @@ package com.apigee.security.oas.extendedvalidator; +import static com.apigee.security.oas.extendedvalidator.Immutables.toImmutableMap; + import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; import com.google.inject.assistedinject.Assisted; import java.util.Map; import java.util.Optional; @@ -28,7 +29,6 @@ TraversalHelper traversalHelper = traversalHelperFactory.create(getUpdatedTraversalPath()); - traversalHelper.sendServerVariableTraversals( - ImmutableMap.copyOf(openApiSchemaObj.getVariables())); + traversalHelper.sendServerVariableTraversals(toImmutableMap(openApiSchemaObj.getVariables())); } }
diff --git a/oas-core/src/test/java/com/apigee/security/oas/extendedvalidator/ImmutablesTest.java b/oas-core/src/test/java/com/apigee/security/oas/extendedvalidator/ImmutablesTest.java new file mode 100644 index 0000000..db39a19 --- /dev/null +++ b/oas-core/src/test/java/com/apigee/security/oas/extendedvalidator/ImmutablesTest.java
@@ -0,0 +1,50 @@ +package com.apigee.security.oas.extendedvalidator; + +import static org.assertj.core.api.Assertions.assertThat; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSortedMap; +import java.util.ArrayList; +import java.util.List; +import java.util.NavigableMap; +import java.util.TreeMap; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +@RunWith(JUnit4.class) +public class ImmutablesTest { + + @Test + public void toImmutableList_validMutableList_returnsReplicaImmutableList() { + List<Integer> list = new ArrayList<>(3); + list.add(3); + list.add(2); + list.add(1); + + assertThat(Immutables.toImmutableList(list)).isEqualTo(list); + } + + @Test + public void toImmutableList_null_returnsEmptyImmutableList() { + assertThat(Immutables.toImmutableList(null)).isEqualTo(ImmutableList.of()); + } + + @Test + public void toImmutableMap_validMutableMap_returnsReplicaImmutableMap() { + NavigableMap<String, Integer> map = new TreeMap<>(); + map.put("one", 1); + map.put("two", 2); + map.put("three", 3); + ImmutableSortedMap<String, Integer> immutableMap = + ImmutableSortedMap.of("one", 1, "two", 2, "three", 3); + + assertThat(map).isEqualTo(immutableMap); + } + + @Test + public void toImmutableMap_null_returnsEmptyImmutableMap() { + assertThat(Immutables.toImmutableMap(null)).isEqualTo(ImmutableMap.of()); + } +}
diff --git a/oas-core/src/test/java/com/apigee/security/oas/extendedvalidator/InfoTraversalTest.java b/oas-core/src/test/java/com/apigee/security/oas/extendedvalidator/InfoTraversalTest.java index bb23e34..462db49 100644 --- a/oas-core/src/test/java/com/apigee/security/oas/extendedvalidator/InfoTraversalTest.java +++ b/oas-core/src/test/java/com/apigee/security/oas/extendedvalidator/InfoTraversalTest.java
@@ -1,7 +1,6 @@ package com.apigee.security.oas.extendedvalidator; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -51,7 +50,6 @@ public void traverse_sendsContactToTraversalHelper() { infoTraversal.traverse(); - verify(traversalHelperFactory, atLeastOnce()).create(any(ImmutableList.class)); verify(traversalHelper).sendContactTraversal(contact); } @@ -59,7 +57,6 @@ public void traverse_sendsLicenseToTraversalHelper() { infoTraversal.traverse(); - verify(traversalHelperFactory, atLeastOnce()).create(any(ImmutableList.class)); verify(traversalHelper).sendLicenseTraversal(license); } }
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 7451a2f..4df4f5d 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
@@ -78,15 +78,31 @@ public void traverse_sendsServersToTraversalHelper() { openApiSpecificationTraversal.traverse(); - verify(traversalHelperFactory, atLeastOnce()).create(any(ImmutableList.class)); verify(traversalHelper).sendServerTraversals(servers); } @Test + public void traverse_nullServersMember_doesNotFail() { + when(openApiSpec.getServers()).thenReturn(null); + + openApiSpecificationTraversal.traverse(); + + verify(traversalHelper, atLeastOnce()).sendServerTraversals(any()); + } + + @Test public void traverse_sendsTagsToTraversalHelper() { openApiSpecificationTraversal.traverse(); - verify(traversalHelperFactory, atLeastOnce()).create(any(ImmutableList.class)); verify(traversalHelper).sendTagTraversals(tags); } + + @Test + public void traverse_nullTagsMember_doesNotFail() { + when(openApiSpec.getTags()).thenReturn(null); + + openApiSpecificationTraversal.traverse(); + + verify(traversalHelper, atLeastOnce()).sendTagTraversals(any()); + } }
diff --git a/oas-core/src/test/java/com/apigee/security/oas/extendedvalidator/ServerTraversalTest.java b/oas-core/src/test/java/com/apigee/security/oas/extendedvalidator/ServerTraversalTest.java index 24294a8..5887005 100644 --- a/oas-core/src/test/java/com/apigee/security/oas/extendedvalidator/ServerTraversalTest.java +++ b/oas-core/src/test/java/com/apigee/security/oas/extendedvalidator/ServerTraversalTest.java
@@ -52,10 +52,18 @@ } @Test - public void traverse_sendsServerVariableChildrenTraversalsToTraversalCommander() { + public void traverse_sendsServerVariablesToTraversalHelper() { serverTraversal.traverse(); - verify(traversalHelperFactory, atLeastOnce()).create(any(ImmutableList.class)); verify(traversalHelper).sendServerVariableTraversals(ImmutableMap.copyOf(serverVariables)); } + + @Test + public void traverse_nullServerVariablesMember_doesNotFail() { + when(server.getVariables()).thenReturn(null); + + serverTraversal.traverse(); + + verify(traversalHelper, atLeastOnce()).sendServerVariableTraversals(any()); + } }
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 index 3e57ee7..ab86592 100644 --- 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
@@ -1,7 +1,6 @@ package com.apigee.security.oas.extendedvalidator; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -44,10 +43,9 @@ } @Test - public void traverse_sendsTraversalCommanderExternalDocsTraversalCommand() { + public void traverse_sendsExternalDocsToTraversalHelper() { tagTraversal.traverse(); - verify(traversalHelperFactory, atLeastOnce()).create(any(ImmutableList.class)); verify(traversalHelper).sendExternalDocsTraversal(externalDocs); } }