Files
wehub-resource-sync 7a0da7932b
OSV-Scanner (Scheduled) / scan-scheduled (push) Failing after 0s
Create Release / test-gate (push) Has been cancelled
Create Release / release-gate (push) Has been cancelled
Create Release / ci-gate (push) Has been cancelled
Create Release / version-check (push) Has been cancelled
Create Release / e2e-test-gate (push) Has been cancelled
Create Release / responsive-test-gate (push) Has been cancelled
Create Release / compat-test-gate (push) Has been cancelled
Create Release / compose-integration-gate (push) Has been cancelled
Create Release / vulture-gate (push) Has been cancelled
Create Release / build (push) Has been cancelled
Create Release / provenance (push) Has been cancelled
Create Release / prerelease-docker (push) Has been cancelled
Create Release / publish-docker (push) Has been cancelled
Create Release / create-release (push) Has been cancelled
Create Release / cleanup-changelog (push) Has been cancelled
Create Release / trigger-pypi (push) Has been cancelled
Create Release / monitor-pypi (push) Has been cancelled
Create Release / Clean up orphan prerelease tags and signatures (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-form] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-metrics] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-workflow] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-core] (push) Has been cancelled
CodeQL Advanced / Analyze (javascript-typescript) (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [history-news] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [library] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [link-analytics] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-core] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-lifecycle] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [error-benchmark] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-pages] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) (push) Has been cancelled
Docker Tests (Consolidated) / Accessibility Tests (push) Has been cancelled
Docker Tests (Consolidated) / LLM Unit Tests (push) Has been cancelled
Docker Tests (Consolidated) / LLM Example Tests (push) Has been cancelled
Docker Tests (Consolidated) / Production Image Smoke Test (push) Has been cancelled
Docker Tests (Consolidated) / Infrastructure Tests (push) Has been cancelled
OSSF Scorecard / OSSF Security Scorecard Analysis (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [mobile] (push) Has been cancelled
Backwards Compatibility / Verify Encryption Constants (push) Has been cancelled
Backwards Compatibility / PyPI Version Compatibility (push) Has been cancelled
Backwards Compatibility / Database Migration Tests (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Docker Tests (Consolidated) / detect-changes (push) Has been cancelled
Docker Tests (Consolidated) / Build Test Image (push) Has been cancelled
Docker Tests (Consolidated) / All Pytest Tests + Coverage (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [accessibility] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [api-crud] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-login] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-pages] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-register] (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:08:55 +08:00

309 lines
10 KiB
Python

"""
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."""
# <input type="checkbox" value="custom">
assert parse_boolean("custom") is True
def test_hidden_fallback_false(self):
"""Test hidden input fallback value for unchecked checkbox."""
# Common pattern: <input type="hidden" value="false">
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: <input type="hidden" name="setting" value="false">
# <input type="checkbox" name="setting">
# 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: <input type="checkbox" name="setting" value="true">
assert parse_boolean("true") is True
def test_checked_checkbox_value_one(self):
"""Test checked checkbox with value="1"."""
# Pattern: <input type="checkbox" name="setting" value="1">
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)