From daabfad05000972147d5c079084c95198973632a Mon Sep 17 00:00:00 2001 From: Jonathan Green Date: Fri, 8 Sep 2023 14:47:14 -0300 Subject: [PATCH] Fix language code validation (PP-422) (#1362) * Fix language code validation, and add some tests for it. --- core/configuration/library.py | 7 ++- tests/core/configuration/test_library.py | 55 ++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 tests/core/configuration/test_library.py diff --git a/core/configuration/library.py b/core/configuration/library.py index f5330e27de..410417885d 100644 --- a/core/configuration/library.py +++ b/core/configuration/library.py @@ -638,12 +638,17 @@ def validate_language_codes( ) -> Optional[List[str]]: """Verify that collection languages are valid.""" if value is not None: + languages = [] for language in value: - if not LanguageCodes.string_to_alpha_3(language): + validated_language = LanguageCodes.string_to_alpha_3(language) + if validated_language is None: field_label = cls.get_form_field_label(field.name) raise SettingsValidationError( problem_detail=UNKNOWN_LANGUAGE.detailed( f'"{field_label}": "{language}" is not a valid language code.' ) ) + if validated_language not in languages: + languages.append(validated_language) + return languages return value diff --git a/tests/core/configuration/test_library.py b/tests/core/configuration/test_library.py new file mode 100644 index 0000000000..ad00aa2860 --- /dev/null +++ b/tests/core/configuration/test_library.py @@ -0,0 +1,55 @@ +from functools import partial +from typing import Callable, List, Optional + +import pytest + +from core.configuration.library import LibrarySettings +from core.util.problem_detail import ProblemError + +LibrarySettingsFixture = Callable[..., LibrarySettings] + + +@pytest.fixture +def library_settings() -> LibrarySettingsFixture: + # Provide a default library settings object for tests, it just gives + # default values for required fields, so we can construct the settings + # without worrying about the defaults. + return partial( + LibrarySettings, + website="http://library.com", + help_web="http://library.com/help", + ) + + +@pytest.mark.parametrize( + "languages,expected", + [ + (None, None), + ([], []), + (["English"], ["eng"]), + (["English", "eng", "fr", "fre", "french"], ["eng", "fre"]), + ], +) +def test_validate_language_codes( + languages: Optional[List[str]], + expected: Optional[List[str]], + library_settings: LibrarySettingsFixture, +) -> None: + settings = library_settings(large_collection_languages=languages) + assert settings.large_collection_languages == expected + + settings = library_settings(small_collection_languages=languages) + assert settings.small_collection_languages == expected + + settings = library_settings(tiny_collection_languages=languages) + assert settings.tiny_collection_languages == expected + + +def test_validate_language_codes_error( + library_settings: LibrarySettingsFixture, +) -> None: + with pytest.raises(ProblemError) as excinfo: + library_settings(large_collection_languages=["eng", "xyz"]) + + assert excinfo.value.problem_detail.detail is not None + assert '"xyz" is not a valid language code' in excinfo.value.problem_detail.detail