diff options
Diffstat (limited to 'common-parameters/src/test/java/org/onap/policy/common/parameters/TestBeanValidator.java')
-rw-r--r-- | common-parameters/src/test/java/org/onap/policy/common/parameters/TestBeanValidator.java | 519 |
1 files changed, 266 insertions, 253 deletions
diff --git a/common-parameters/src/test/java/org/onap/policy/common/parameters/TestBeanValidator.java b/common-parameters/src/test/java/org/onap/policy/common/parameters/TestBeanValidator.java index f1e468b0..83d0a7f9 100644 --- a/common-parameters/src/test/java/org/onap/policy/common/parameters/TestBeanValidator.java +++ b/common-parameters/src/test/java/org/onap/policy/common/parameters/TestBeanValidator.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * ONAP * ================================================================================ - * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2020-2021 AT&T Intellectual Property. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,30 +20,33 @@ package org.onap.policy.common.parameters; -import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.assertTrue; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Consumer; -import lombok.AccessLevel; import lombok.Getter; import org.junit.Before; import org.junit.Test; +import org.onap.policy.common.parameters.annotations.ClassName; import org.onap.policy.common.parameters.annotations.Max; import org.onap.policy.common.parameters.annotations.Min; import org.onap.policy.common.parameters.annotations.NotBlank; import org.onap.policy.common.parameters.annotations.NotNull; +import org.onap.policy.common.parameters.annotations.Pattern; +import org.onap.policy.common.parameters.annotations.Size; +import org.onap.policy.common.parameters.annotations.Valid; public class TestBeanValidator { - private static final String GET_MSG = "\"get\""; - private static final IllegalStateException EXPECTED_EXCEPTION = new IllegalStateException("expected exception"); private static final String TOP = "top"; private static final String STR_FIELD = "strValue"; private static final String INT_FIELD = "intValue"; private static final String NUM_FIELD = "numValue"; - private static final String BOOL_FIELD = "boolValue"; + private static final String ITEMS_FIELD = "items"; private static final String STRING_VALUE = "string value"; private static final int INT_VALUE = 20; @@ -114,115 +117,6 @@ public class TestBeanValidator { } @Test - public void testValidateField() { - /* - * Note: nested classes contain fields like "$this", thus the check for "$" in the - * variable name is already covered by the other tests. - */ - - /* - * Class with no annotations. - */ - class NoAnnotations { - @SuppressWarnings("unused") - String strValue; - } - - NoAnnotations noAnnot = new NoAnnotations(); - noAnnot.strValue = null; - assertTrue(validator.validateTop(TOP, noAnnot).isValid()); - - /* - * Class containing a static field with an annotation. - */ - AnnotFieldStatic annotFieldStatic = new AnnotFieldStatic(); - assertThatIllegalArgumentException().isThrownBy(() -> validator.validateTop(TOP, annotFieldStatic)) - .withMessageContaining(STR_FIELD).withMessageContaining("static"); - - /* - * Class containing a static field, with an annotation at the class level. - */ - AnnotClassStatic annotClassStatic = new AnnotClassStatic(); - assertTrue(validator.validateTop(TOP, annotClassStatic).isValid()); - - /* - * Class with no getter method, with field-level annotation. - */ - class NoGetter { - @NotNull - String strValue; - } - - NoGetter noGetter = new NoGetter(); - assertThatIllegalArgumentException().isThrownBy(() -> validator.validateTop(TOP, noGetter)) - .withMessageContaining(STR_FIELD).withMessageContaining(GET_MSG); - - /* - * Class with no getter method, with class-level annotation. - */ - @NotNull - class ClassNoGetter { - @SuppressWarnings("unused") - String strValue; - } - - ClassNoGetter classNoGetter = new ClassNoGetter(); - assertTrue(validator.validateTop(TOP, classNoGetter).isValid()); - - /* - * Class with "blank", but no "null" check. Value is null. - */ - class NoNullCheck { - @NotBlank - @Getter - String strValue; - } - - NoNullCheck noNullCheck = new NoNullCheck(); - assertTrue(validator.validateTop(TOP, noNullCheck).isValid()); - - /* - * Class with conflicting minimum and maximum, where the value doesn't satisfy - * either of them. This should only generate one result, rather than one for each - * check. Note: the "max" check occurs before the "min" check, so that's the one - * we expect in the result. - */ - class MinAndMax { - @Getter - @Min(200) - @Max(100) - Integer intValue; - } - - MinAndMax minAndMax = new MinAndMax(); - minAndMax.intValue = 150; - BeanValidationResult result = validator.validateTop(INT_FIELD, minAndMax); - assertFalse(result.isValid()); - assertInvalid("testValidateField", result, INT_FIELD, "maximum"); - assertFalse(result.getResult().contains("minimum")); - } - - @Test - public void testGetValue() { - /* - * Class where the getter throws an exception. - */ - class GetExcept { - @NotNull - String strValue; - - @SuppressWarnings("unused") - public String getStrValue() { - throw EXPECTED_EXCEPTION; - } - } - - GetExcept getExcept = new GetExcept(); - assertThatIllegalArgumentException().isThrownBy(() -> validator.validateTop(TOP, getExcept)) - .withMessageContaining(STR_FIELD).withMessageContaining("accessor threw"); - } - - @Test public void testVerNotNull() { class NotNullCheck { @Getter @@ -280,6 +174,135 @@ public class TestBeanValidator { assertTrue(validator.validateTop(TOP, notBlankInt).isValid()); } + /** + * Tests verSize with a collection. + */ + @Test + public void testVerSizeCollection() { + class CollectionSizeCheck { + @Getter + @Size(min = 3) + Collection<Integer> items; + } + + CollectionSizeCheck collCheck = new CollectionSizeCheck(); + + // valid length - exact + collCheck.items = List.of(1, 2, 3); + assertThat(validator.validateTop(TOP, collCheck).isValid()).isTrue(); + + // valid length - extra + collCheck.items = List.of(1, 2, 3, 4); + assertThat(validator.validateTop(TOP, collCheck).isValid()).isTrue(); + + // too few + collCheck.items = List.of(1, 2); + assertInvalid("testVerSize", validator.validateTop(TOP, collCheck), ITEMS_FIELD, "minimum", "3"); + + // null + collCheck.items = null; + assertThat(validator.validateTop(TOP, collCheck).isValid()).isTrue(); + } + + /** + * Tests verSize with a map. + */ + @Test + public void testVerSizeMap() { + class MapSizeCheck { + @Getter + @Size(min = 3) + Map<Integer, Integer> items; + } + + MapSizeCheck mapCheck = new MapSizeCheck(); + + // valid length - exact + mapCheck.items = Map.of(1, 10, 2, 20, 3, 30); + assertThat(validator.validateTop(TOP, mapCheck).isValid()).isTrue(); + + // valid length - extra + mapCheck.items = Map.of(1, 10, 2, 20, 3, 30, 4, 40); + assertThat(validator.validateTop(TOP, mapCheck).isValid()).isTrue(); + + // too few + mapCheck.items = Map.of(1, 10, 2, 20); + assertInvalid("testVerSize", validator.validateTop(TOP, mapCheck), ITEMS_FIELD, "minimum", "3"); + + // null + mapCheck.items = null; + assertThat(validator.validateTop(TOP, mapCheck).isValid()).isTrue(); + } + + /** + * Tests verSize with an object for which it doesn't apply. + */ + @Test + public void testVerSizeOther() { + class OtherSizeCheck { + @Getter + @Size(min = 3) + Integer items; + } + + OtherSizeCheck otherCheck = new OtherSizeCheck(); + + otherCheck.items = 10; + assertThat(validator.validateTop(TOP, otherCheck).isValid()).isTrue(); + } + + @Test + public void testVerRegex() { + class RegexCheck { + @Getter + @Pattern(regexp = "[a-f]*") + String strValue; + } + + RegexCheck regexCheck = new RegexCheck(); + + // does not match + regexCheck.strValue = "xyz"; + assertInvalid("testVerRegex", validator.validateTop(TOP, regexCheck), STR_FIELD, + "does not match regular expression [a-f]"); + + // matches + regexCheck.strValue = "abcabc"; + assertTrue(validator.validateTop(TOP, regexCheck).isValid()); + + // invalid regex + class InvalidRegexCheck { + @Getter + @Pattern(regexp = "[a-f") + String strValue; + } + + InvalidRegexCheck invalidRegexCheck = new InvalidRegexCheck(); + + // does not match + invalidRegexCheck.strValue = "abc"; + assertInvalid("testVerRegex", validator.validateTop(TOP, invalidRegexCheck), STR_FIELD, + "does not match regular expression [a-f"); + + // matches + regexCheck.strValue = "abcabc"; + assertTrue(validator.validateTop(TOP, regexCheck).isValid()); + + /* + * Class with "regex" annotation on an integer. + */ + class RegexInt { + @Getter + @Pattern(regexp = "[a-f]*") + int intValue; + } + + RegexInt regexInt = new RegexInt(); + regexInt.intValue = 0; + assertInvalid("testVerRegex", validator.validateTop(TOP, regexInt), INT_FIELD, + "does not match regular expression [a-f]"); + } + @Test public void testVerMax() { /* @@ -468,184 +491,174 @@ public class TestBeanValidator { assertTrue(validator.validateTop(TOP, atomIntField).isValid()); } - private <T> void assertNumeric(String testName, T object, Consumer<Integer> setter, String fieldName, - String expectedText, int inside, int edge, int outside) { - setter.accept(inside); - assertTrue(validator.validateTop(TOP, object).isValid()); + @Test + public void testVerClassName() { + class ClassNameCheck { + @Getter + @ClassName + String strValue; + } - // on the edge - setter.accept(edge); - assertTrue(validator.validateTop(TOP, object).isValid()); + ClassNameCheck classCheck = new ClassNameCheck(); - // invalid - setter.accept(outside); - assertInvalid("testVerNotNull", validator.validateTop(TOP, object), fieldName, expectedText); + // null should be OK + classCheck.strValue = null; + assertTrue(validator.validateTop(TOP, classCheck).isValid()); + + // valid class name + classCheck.strValue = getClass().getName(); + assertTrue(validator.validateTop(TOP, classCheck).isValid()); + + // invalid class name + classCheck.strValue = "<unknown class>"; + assertInvalid("testVerClassName", validator.validateTop(TOP, classCheck), + STR_FIELD, "class is not in the classpath"); } @Test - public void testGetAccessor() { - /* - * Class with "get" method has been tested through-out this junit, so no need to - * do more. - */ - - /* - * Class with "is" method. - */ - class IsField { + public void testVerCascade() { + class Item { + @Getter @NotNull - Boolean boolValue; - - @SuppressWarnings("unused") - public Boolean isBoolValue() { - return boolValue; - } + Integer intValue; } - // ok value - IsField isField = new IsField(); - isField.boolValue = true; - assertTrue(validator.validateTop(TOP, isField).isValid()); + @Getter + class Container { + @Valid + Item checked; - // invalid value - isField.boolValue = null; - assertInvalid("testGetAccessor", validator.validateTop(TOP, isField), BOOL_FIELD, "null"); - } + Item unchecked; - @Test - public void testGetMethod() { - /* - * Class with some fields annotated and some not. - */ - @Getter - class Mixed { - Integer intValue; + @Valid + List<Item> items; - @NotNull - String strValue; + @Valid + Map<String, Item> itemMap; } - // invalid - Mixed mixed = new Mixed(); - BeanValidationResult result = validator.validateTop(TOP, mixed); - assertInvalid("testGetMethod", result, STR_FIELD, "null"); - assertFalse(result.getResult().contains(INT_FIELD)); - - // intValue is null, but it isn't annotated so this should be valid - mixed.strValue = STRING_VALUE; - assertTrue(validator.validateTop(TOP, mixed).isValid()); + Container cont = new Container(); + cont.unchecked = new Item(); + cont.items = List.of(new Item()); + cont.itemMap = Map.of(STRING_VALUE, new Item()); + + cont.checked = null; + assertTrue(validator.validateTop(TOP, cont).isValid()); + + cont.checked = new Item(); + + assertInvalid("testVerCascade", validator.validateTop(TOP, cont), INT_FIELD, "null"); + + cont.checked.intValue = INT_VALUE; + assertTrue(validator.validateTop(TOP, cont).isValid()); } @Test - public void testValidMethod() { + public void testVerCollection() { + @Getter + class Container { + List<@Min(5) Integer> items; - /* - * Plain getter. - */ - class PlainGetter { - @NotNull - @Getter + // not a collection - should not be checked + @Valid String strValue; + + String noAnnotations; } - // invalid - PlainGetter plainGetter = new PlainGetter(); - assertInvalid("testValidMethod", validator.validateTop(TOP, plainGetter), STR_FIELD, "null"); + Container cont = new Container(); + cont.strValue = STRING_VALUE; + cont.noAnnotations = STRING_VALUE; - // valid - plainGetter.strValue = STRING_VALUE; - assertTrue(validator.validateTop(TOP, plainGetter).isValid()); + // null collection - always valid + assertTrue(validator.validateTop(TOP, cont).isValid()); - /* - * Static getter - should throw an exception. - */ - StaticGetter staticGetter = new StaticGetter(); - assertThatIllegalArgumentException().isThrownBy(() -> validator.validateTop(TOP, staticGetter)) - .withMessageContaining(STR_FIELD).withMessageContaining(GET_MSG); + // empty collection - always valid + cont.items = List.of(); + assertTrue(validator.validateTop(TOP, cont).isValid()); - /* - * Protected getter - should throw an exception. - */ - class ProtectedGetter { - @NotNull - @Getter(AccessLevel.PROTECTED) - String strValue; - } + cont.items = List.of(-10, -20); + assertThat(validator.validateTop(TOP, cont).getResult()).contains("\"0\"", "-10", "\"1\"", "-20", "minimum"); - ProtectedGetter protectedGetter = new ProtectedGetter(); - assertThatIllegalArgumentException().isThrownBy(() -> validator.validateTop(TOP, protectedGetter)) - .withMessageContaining(STR_FIELD).withMessageContaining(GET_MSG); + cont.items = List.of(10, -30); + assertThat(validator.validateTop(TOP, cont).getResult()).contains("\"1\"", "-30", "minimum") + .doesNotContain("\"0\""); - /* - * getter is a "void" function - should throw an exception. - */ - class VoidGetter { - @NotNull + cont.items = List.of(10, 20); + assertTrue(validator.validateTop(TOP, cont).isValid()); + } + + @Test + public void testVerMap() { + @Getter + class Container { + Map<String, @Min(5) Integer> items; + + // not a map + @NotBlank String strValue; - @SuppressWarnings("unused") - public void getStrValue() { - // do nothing - } + String noAnnotations; } - VoidGetter voidGetter = new VoidGetter(); - assertThatIllegalArgumentException().isThrownBy(() -> validator.validateTop(TOP, voidGetter)) - .withMessageContaining(STR_FIELD).withMessageContaining(GET_MSG); + Container cont = new Container(); + cont.strValue = STRING_VALUE; + cont.noAnnotations = STRING_VALUE; - /* - * getter takes an argument - should throw an exception. - */ - class ArgGetter { - @NotNull - String strValue; + // null map - always valid + assertTrue(validator.validateTop(TOP, cont).isValid()); - @SuppressWarnings("unused") - public String getStrValue(String echo) { - return echo; - } - } + // empty map - always valid + cont.items = Map.of(); + assertTrue(validator.validateTop(TOP, cont).isValid()); - ArgGetter argGetter = new ArgGetter(); - assertThatIllegalArgumentException().isThrownBy(() -> validator.validateTop(TOP, argGetter)) - .withMessageContaining(STR_FIELD).withMessageContaining(GET_MSG); - } + cont.items = Map.of("abc", -10, "def", -20); + assertThat(validator.validateTop(TOP, cont).getResult()).contains("abc", "-10", "def", "-20", "minimum"); + cont.items = Map.of("abc", 10, "def", -30); + assertThat(validator.validateTop(TOP, cont).getResult()).contains("def", "-30", "minimum") + .doesNotContain("abc"); - private void assertInvalid(String testName, BeanValidationResult result, String fieldName, String message) { - String text = result.getResult(); - assertNotNull(testName, text); - assertTrue(testName, text.contains(fieldName)); - assertTrue(testName, text.contains(message)); + cont.items = Map.of("abc", 10, "def", 20); + assertTrue(validator.validateTop(TOP, cont).isValid()); } - /** - * Annotated static field. - */ - private static class AnnotFieldStatic { - @NotNull - static String strValue; + @Test + public void testGetEntryName() { + assertThat(validator.getEntryName(makeEntry(null, 0))).isEmpty(); + assertThat(validator.getEntryName(makeEntry("", 0))).isEmpty(); + assertThat(validator.getEntryName(makeEntry(STRING_VALUE, 0))).isEqualTo(STRING_VALUE); } /** - * Annotated class with a static field. + * Makes a Map entry with the given key and value. + * + * @param key desired key + * @param value desired value + * @return a new Map entry */ - @NotNull - private static class AnnotClassStatic { - @SuppressWarnings("unused") - static String strValue; + private Map.Entry<String, Integer> makeEntry(String key, int value) { + HashMap<String, Integer> map = new HashMap<>(); + map.put(key, value); + return map.entrySet().iterator().next(); } - /** - * Class with an annotated field, but a static "getter". - */ - private static class StaticGetter { - @NotNull - String strValue; + private <T> void assertNumeric(String testName, T object, Consumer<Integer> setter, String fieldName, + String expectedText, int inside, int edge, int outside) { + setter.accept(inside); + assertTrue(validator.validateTop(TOP, object).isValid()); - @SuppressWarnings("unused") - public static String getStrValue() { - return STRING_VALUE; - } + // on the edge + setter.accept(edge); + assertTrue(validator.validateTop(TOP, object).isValid()); + + // invalid + setter.accept(outside); + assertInvalid("testVerNotNull", validator.validateTop(TOP, object), fieldName, expectedText); + } + + + private void assertInvalid(String testName, BeanValidationResult result, String... text) { + assertThat(result.getResult()).describedAs(testName).contains(text); } } |