""" Tests for boolean parsing in settings manager. This module tests the parse_boolean() function which handles HTML checkbox semantics and various boolean representations from forms, JSON, and environment variables. Note: parse_boolean is used internally for HTML form handling but is not exported from the settings package. For API/config/database boolean conversion, use to_bool from utilities.type_utils instead. """ import pytest from local_deep_research.settings.manager import parse_boolean class TestParseBooleanBasicTypes: """Test parse_boolean with basic Python types.""" def test_boolean_true(self): """Test that True remains True.""" assert parse_boolean(True) is True def test_boolean_false(self): """Test that False remains False.""" assert parse_boolean(False) is False def test_none_is_false(self): """Test that None converts to False.""" assert parse_boolean(None) is False class TestParseBooleanStringValues: """Test parse_boolean with string representations.""" @pytest.mark.parametrize( "value", [ "true", "True", "TRUE", "yes", "Yes", "YES", "on", "On", "ON", "1", "enabled", "ENABLED", "checked", "CHECKED", "any_random_string", " true ", # With whitespace " yes ", " on ", ], ) def test_truthy_strings(self, value): """Test that various truthy string values convert to True.""" assert parse_boolean(value) is True @pytest.mark.parametrize( "value", [ "false", "False", "FALSE", "no", "No", "NO", "off", "Off", "OFF", "0", "", " ", # Whitespace only " false ", # With whitespace " no ", " off ", " 0 ", ], ) def test_falsy_strings(self, value): """Test that various falsy string values convert to False.""" assert parse_boolean(value) is False class TestParseBooleanHTMLFormValues: """Test parse_boolean with HTML form submission values.""" def test_checkbox_checked_standard(self): """Test standard HTML checkbox checked value.""" # Most browsers send "on" for checked checkboxes # "on" is NOT in FALSY_VALUES, so it's treated as True assert parse_boolean("on") is True def test_checkbox_unchecked(self): """Test HTML checkbox unchecked (empty string from hidden input).""" assert parse_boolean("") is False def test_checkbox_with_custom_value(self): """Test HTML checkbox with custom value attribute.""" # assert parse_boolean("custom") is True def test_hidden_fallback_false(self): """Test hidden input fallback value for unchecked checkbox.""" # Common pattern: assert parse_boolean("false") is False class TestParseBooleanJSONValues: """Test parse_boolean with values from JSON parsing.""" def test_json_true(self): """Test JSON boolean true.""" assert parse_boolean(True) is True def test_json_false(self): """Test JSON boolean false.""" assert parse_boolean(False) is False def test_json_string_true(self): """Test JSON string "true".""" assert parse_boolean("true") is True def test_json_string_false(self): """Test JSON string "false".""" assert parse_boolean("false") is False class TestParseBooleanEnvironmentVariables: """Test parse_boolean with environment variable values.""" @pytest.mark.parametrize( "env_value", ["1", "true", "True", "TRUE", "yes", "YES", "on", "ON", "enabled"], ) def test_common_env_true_values(self, env_value): """Test common environment variable values for true.""" assert parse_boolean(env_value) is True @pytest.mark.parametrize( "env_value", ["0", "false", "False", "FALSE", "no", "NO", "off", "OFF", ""], ) def test_common_env_false_values(self, env_value): """Test common environment variable values for false.""" assert parse_boolean(env_value) is False class TestParseBooleanEdgeCases: """Test parse_boolean with edge cases and unusual inputs.""" def test_whitespace_only_is_false(self): """Test that whitespace-only strings are false.""" assert parse_boolean(" ") is False assert parse_boolean("\t") is False assert parse_boolean("\n") is False def test_numeric_zero_is_false(self): """Test that numeric 0 converts to False.""" assert parse_boolean(0) is False def test_numeric_nonzero_is_true(self): """Test that non-zero numbers convert to True.""" assert parse_boolean(1) is True assert parse_boolean(42) is True assert parse_boolean(-1) is True assert parse_boolean(3.14) is True def test_empty_list_is_false(self): """Test that empty list converts to False.""" assert parse_boolean([]) is False def test_nonempty_list_is_true(self): """Test that non-empty list converts to True.""" assert parse_boolean([1, 2, 3]) is True assert parse_boolean(["false"]) is True # Non-empty list def test_empty_dict_is_false(self): """Test that empty dict converts to False.""" assert parse_boolean({}) is False def test_nonempty_dict_is_true(self): """Test that non-empty dict converts to True.""" assert parse_boolean({"key": "value"}) is True def test_case_insensitive_handling(self): """Test that string comparison is case-insensitive.""" assert parse_boolean("TrUe") is True assert parse_boolean("FaLsE") is False assert parse_boolean("YeS") is True assert parse_boolean("nO") is False def test_string_with_leading_trailing_spaces(self): """Test strings with leading/trailing whitespace are trimmed.""" assert parse_boolean(" true ") is True assert parse_boolean(" false ") is False assert parse_boolean(" 0 ") is False assert parse_boolean(" 1 ") is True class TestParseBooleanConsistency: """Test parse_boolean for consistency across different input sources.""" def test_form_json_env_consistency_true(self): """Test that true values are consistent across input sources.""" # Form data assert parse_boolean("true") is True # JSON assert parse_boolean(True) is True # Environment assert parse_boolean("1") is True def test_form_json_env_consistency_false(self): """Test that false values are consistent across input sources.""" # Form data assert parse_boolean("false") is False assert parse_boolean("") is False # JSON assert parse_boolean(False) is False # Environment assert parse_boolean("0") is False def test_roundtrip_bool_to_string_to_bool(self): """Test roundtrip conversion: bool -> str -> bool.""" # True roundtrip assert parse_boolean(str(True).lower()) is True # False roundtrip assert parse_boolean(str(False).lower()) is False class TestParseBooleanHTMLSemantics: """ Test parse_boolean for HTML checkbox semantics. HTML checkbox semantics: Any value present (except explicit false) = checked = True. This is documented behavior in the parse_boolean docstring. """ def test_unchecked_checkbox_not_submitted(self): """Test unchecked checkbox (not in form data) = None = False.""" assert parse_boolean(None) is False def test_unchecked_checkbox_hidden_fallback(self): """Test unchecked checkbox with hidden fallback value.""" # Pattern: # # When unchecked, form submits hidden input value assert parse_boolean("false") is False def test_checked_checkbox_standard(self): """Test checked checkbox with standard value.""" # Most browsers send "on" for checked checkboxes # "on" is NOT in FALSY_VALUES, so it's treated as True assert parse_boolean("on") is True def test_checked_checkbox_explicit_true(self): """Test checked checkbox with explicit "true" value.""" # Pattern: assert parse_boolean("true") is True def test_checked_checkbox_value_one(self): """Test checked checkbox with value="1".""" # Pattern: assert parse_boolean("1") is True class TestParseBooleanRegressions: """Test parse_boolean for known issues and regressions.""" def test_issue_corrupted_value_detection(self): """ Test that checkbox values are parsed before corrupted value detection. This prevents incorrect triggering of corrupted value detection when checkbox values come in as strings (e.g., "true") instead of booleans. Related to settings_routes.py:292-299 """ # String "true" from form should not be considered corrupted assert parse_boolean("true") is True assert isinstance(parse_boolean("true"), bool) # String "false" from form should not be considered corrupted assert parse_boolean("false") is False assert isinstance(parse_boolean("false"), bool) def test_ajax_vs_post_consistency(self): """ Test consistency between AJAX (JSON) and traditional POST submissions. Related to settings_routes.py:1-38 dual-mode submission pattern. """ # AJAX mode: JavaScript sends boolean ajax_checked = True ajax_unchecked = False # Traditional POST: Browser sends string post_checked = "true" post_unchecked = "false" # Both modes should produce same results assert parse_boolean(ajax_checked) == parse_boolean(post_checked) assert parse_boolean(ajax_unchecked) == parse_boolean(post_unchecked)