CountryCodeValidator { public static List<String> validate(List<String> countryCodes) { List<String> upperCaseCountries = Objects.requireNonNull(countryCodes).stream() .map(String::toUpperCase) .collect(toList()); List<String> invalidCodes = upperCaseCountries.stream() .filter(s -> CountryCode.getByAlpha2Code(s) == null) .collect(toList()); if (!invalidCodes.isEmpty()) { throw new IllegalArgumentException( "Following elements (" + invalidCodes + ") are not valid ISO 3166-1 alpha-2 country codes"); } List<String> uniqueCountries = upperCaseCountries.stream().distinct().collect(toList()); if (uniqueCountries.size() < countryCodes.size()) { logger.warn("Duplicate items were removed from {}", countryCodes); } return uniqueCountries; } private  CountryCodeValidator(); static List<String> validate(List<String> countryCodes);  }
@Test void should_fail_on_invalid_country_codes() { assertThatNullPointerException().isThrownBy(() -> validate(null)); assertThatNullPointerException().isThrownBy(() -> validate(Arrays.asList("US", null, "CA"))); assertThatIllegalArgumentException().isThrownBy(() -> validate(Arrays.asList("XX"))); assertThatIllegalArgumentException().isThrownBy(() -> validate(Arrays.asList("CZE"))); assertThatIllegalArgumentException().isThrownBy(() -> validate(Arrays.asList("D"))); assertThatIllegalArgumentException().isThrownBy(() -> validate(Arrays.asList(""))); assertThatIllegalArgumentException().isThrownBy(() -> validate(Arrays.asList("US", "XY", "CA"))); }
@Test void should_ignore_case_and_convert_to_upper_case() { assertThat(validate(Arrays.asList("us"))).containsExactly("US"); }
@Test void should_allow_multiple_values() { assertThat(validate(Arrays.asList("US", "ca"))).containsExactly("US", "CA"); }
@Test void should_allow_empty_list() { assertThat(validate(new ArrayList<>())).isEmpty(); }