Skip to content

Commit 79d53a3

Browse files
authored
AYS-688 | AysUserFilter.lineNumber Field Validations Have Been Fixed (#477)
1 parent a832fdd commit 79d53a3

File tree

5 files changed

+98
-2
lines changed

5 files changed

+98
-2
lines changed

src/main/java/org/ays/auth/model/AysUserFilter.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import org.ays.auth.model.enums.AysUserStatus;
1111
import org.ays.common.model.AysFilter;
1212
import org.ays.common.util.validation.Name;
13+
import org.ays.common.util.validation.OnlyPositiveNumber;
1314
import org.springframework.data.jpa.domain.Specification;
1415
import org.springframework.util.StringUtils;
1516

@@ -65,6 +66,7 @@ public class AysUserFilter implements AysFilter {
6566
@Setter
6667
public static class PhoneNumber {
6768

69+
@OnlyPositiveNumber
6870
@Size(min = 1, max = 10)
6971
private String lineNumber;
7072

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package org.ays.common.util.validation;
2+
3+
import jakarta.validation.Constraint;
4+
import jakarta.validation.Payload;
5+
6+
import java.lang.annotation.ElementType;
7+
import java.lang.annotation.Retention;
8+
import java.lang.annotation.RetentionPolicy;
9+
import java.lang.annotation.Target;
10+
11+
/**
12+
* Annotation to validate that a numeric field contains only positive values.
13+
* <p>
14+
* This constraint is validated using the {@link OnlyPositiveNumberValidator} class.
15+
* It can be applied to fields of numeric types (e.g., {@link Integer}, {@link Long}) to enforce positivity.
16+
* </p>
17+
*/
18+
@Target(ElementType.FIELD)
19+
@Retention(RetentionPolicy.RUNTIME)
20+
@Constraint(validatedBy = OnlyPositiveNumberValidator.class)
21+
public @interface OnlyPositiveNumber {
22+
23+
24+
/**
25+
* Returns the error message when the number is not positive.
26+
*
27+
* @return the validation error message
28+
*/
29+
String message() default "must be positive number";
30+
31+
/**
32+
* Returns the validation groups this constraint belongs to.
33+
*
34+
* @return the validation groups
35+
*/
36+
Class<?>[] groups() default {};
37+
38+
/**
39+
* Returns the custom payload objects associated with this constraint.
40+
*
41+
* @return the payload
42+
*/
43+
Class<? extends Payload>[] payload() default {};
44+
45+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package org.ays.common.util.validation;
2+
3+
import jakarta.validation.ConstraintValidator;
4+
import jakarta.validation.ConstraintValidatorContext;
5+
import org.apache.commons.lang3.StringUtils;
6+
import org.apache.commons.lang3.math.NumberUtils;
7+
8+
/**
9+
* A custom validator implementation for the {@link OnlyPositiveNumber} annotation.
10+
* <p>
11+
* Validates whether the given {@link String} represents a positive numeric value.
12+
* The input is considered valid if it is non-blank, contains only digits, and represents a number greater than zero.
13+
* </p>
14+
*/
15+
class OnlyPositiveNumberValidator implements ConstraintValidator<OnlyPositiveNumber, String> {
16+
17+
/**
18+
* Validates whether the provided {@code String} value is a positive number.
19+
*
20+
* @param number the string value to validate
21+
* @param context the context in which the constraint is evaluated
22+
* @return {@code true} if the value is blank or a positive number; {@code false} otherwise
23+
*/
24+
@Override
25+
public boolean isValid(String number, ConstraintValidatorContext context) {
26+
27+
if (StringUtils.isEmpty(number)) {
28+
return true;
29+
}
30+
31+
return NumberUtils.isDigits(number) && Long.parseLong(number) > 0;
32+
}
33+
34+
}

src/test/java/org/ays/auth/controller/AysUserControllerTest.java

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,14 @@ void givenUserListRequest_whenLastNameDoesNotValid_thenReturnValidationError(Str
185185
@ValueSource(strings = {
186186
"",
187187
"12345678912",
188-
"12345678912367"
188+
"12345678912367",
189+
"-321",
190+
"321.",
191+
"12.34",
192+
"1 234",
193+
"-45",
194+
"12a34",
195+
" "
189196
})
190197
@ParameterizedTest
191198
void givenUserListRequest_whenLineNumberIsNotValid_thenReturnValidationError(String mockLineNumber) throws Exception {
@@ -210,7 +217,11 @@ void givenUserListRequest_whenLineNumberIsNotValid_thenReturnValidationError(Str
210217
.andExpect(AysMockResultMatchersBuilders.status()
211218
.isBadRequest())
212219
.andExpect(AysMockResultMatchersBuilders.subErrors()
213-
.isNotEmpty());
220+
.isArray())
221+
.andExpect(AysMockResultMatchersBuilders.subErrorsSize()
222+
.value(1))
223+
.andExpect(AysMockResultMatchersBuilders.subErrors("[*].field")
224+
.value("lineNumber"));
214225

215226
// Verify
216227
Mockito.verify(userReadService, Mockito.never())

src/test/java/org/ays/util/AysMockResultMatchersBuilders.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,10 @@ public static JsonPathResultMatchers subErrors() {
7272
return MockMvcResultMatchers.jsonPath("$.subErrors");
7373
}
7474

75+
public static JsonPathResultMatchers subErrorsSize() {
76+
return MockMvcResultMatchers.jsonPath("$.subErrors.size()");
77+
}
78+
7579
public static JsonPathResultMatchers subErrors(String path) {
7680
return MockMvcResultMatchers.jsonPath("$.subErrors".concat(path));
7781
}

0 commit comments

Comments
 (0)