FINERACT-2326: Locale Validator shall accept all valid language codes
This commit is contained in:
+1
-1
@@ -55,7 +55,7 @@ class BusinessDateValidationTest {
|
|||||||
@Test
|
@Test
|
||||||
void invalidLocale() {
|
void invalidLocale() {
|
||||||
var request = BusinessDateUpdateRequest.builder().dateFormat("dd-MM-yyyy").type(BusinessDateType.BUSINESS_DATE).date("12-05-2025")
|
var request = BusinessDateUpdateRequest.builder().dateFormat("dd-MM-yyyy").type(BusinessDateType.BUSINESS_DATE).date("12-05-2025")
|
||||||
.locale("EN").build();
|
.locale("INVALID").build();
|
||||||
|
|
||||||
var errors = validator.validateObject(request);
|
var errors = validator.validateObject(request);
|
||||||
|
|
||||||
|
|||||||
+17
-1
@@ -27,6 +27,22 @@ class LocaleValidator implements ConstraintValidator<Locale, String> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isValid(String value, ConstraintValidatorContext context) {
|
public boolean isValid(String value, ConstraintValidatorContext context) {
|
||||||
return StringUtils.isNotBlank(value) && Arrays.asList(java.util.Locale.getISOLanguages()).contains(value);
|
if (StringUtils.isBlank(value)) {
|
||||||
|
return false; // empty string is invalid
|
||||||
|
}
|
||||||
|
|
||||||
|
// Normalize input to use BCP 47 format (e.g., "en-US")
|
||||||
|
String languageTag = value.replace('_', '-');
|
||||||
|
|
||||||
|
java.util.Locale inputLocale = java.util.Locale.forLanguageTag(languageTag);
|
||||||
|
|
||||||
|
// If language is empty, it's not a valid locale
|
||||||
|
if (inputLocale.getLanguage().isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if it matches any available locale
|
||||||
|
return Arrays.stream(java.util.Locale.getAvailableLocales())
|
||||||
|
.anyMatch(available -> available.toLanguageTag().equalsIgnoreCase(inputLocale.toLanguageTag()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+21
-14
@@ -27,6 +27,8 @@ import lombok.NoArgsConstructor;
|
|||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.fineract.validation.config.ValidationConfig;
|
import org.apache.fineract.validation.config.ValidationConfig;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
|
import org.junit.jupiter.params.provider.ValueSource;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
import org.springframework.test.context.ContextConfiguration;
|
import org.springframework.test.context.ContextConfiguration;
|
||||||
@@ -51,24 +53,29 @@ class LocaleValidationTest {
|
|||||||
assertThat(errors.getFieldErrors()).anyMatch(e -> e.getField().equals("locale"));
|
assertThat(errors.getFieldErrors()).anyMatch(e -> e.getField().equals("locale"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@ParameterizedTest
|
||||||
void invalidFormat() {
|
@ValueSource(strings = { "invalid-locale", // invalid format
|
||||||
var request = LocaleModel.builder().locale("EN").build();
|
"xx-YY", // non-existent locale
|
||||||
|
"random text", // random text
|
||||||
|
"123", // numbers
|
||||||
|
"en-US-extra" // extra segment
|
||||||
|
})
|
||||||
|
void invalidFormats(String locale) {
|
||||||
|
var request = LocaleModel.builder().locale(locale).build();
|
||||||
var errors = validator.validateObject(request);
|
var errors = validator.validateObject(request);
|
||||||
|
assertThat(errors.getFieldErrorCount()).as("Expected locale '%s' to be invalid but it was valid", locale).isGreaterThan(0);
|
||||||
assertThat(errors.getFieldErrorCount()).isEqualTo(1);
|
|
||||||
|
|
||||||
assertThat(errors.getFieldErrors()).anyMatch(e -> e.getField().equals("locale"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@ParameterizedTest
|
||||||
void valid() {
|
@ValueSource(strings = { "en", // language only
|
||||||
var request = LocaleModel.builder().locale("en").build();
|
"EN", // uppercase language only
|
||||||
|
"en-US", // language with country (hyphen)
|
||||||
|
"en_US", // language with country (underscore)
|
||||||
|
})
|
||||||
|
void validLocales(String locale) {
|
||||||
|
var request = LocaleModel.builder().locale(locale).build();
|
||||||
var errors = validator.validateObject(request);
|
var errors = validator.validateObject(request);
|
||||||
|
assertThat(errors.getFieldErrorCount()).as("Expected locale '%s' to be valid but it was invalid", locale).isZero();
|
||||||
assertThat(errors.getFieldErrorCount()).isEqualTo(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Builder
|
@Builder
|
||||||
|
|||||||
Reference in New Issue
Block a user