From 49fc9a116f5746c7d469ede09634ad7c7956e069 Mon Sep 17 00:00:00 2001 From: qzl Date: Tue, 7 Apr 2026 18:44:21 +0800 Subject: [PATCH] =?UTF-8?q?test:=20=E6=B7=BB=E5=8A=A0=20profile=20settings?= =?UTF-8?q?=20=E5=92=8C=20runtime=20models=20=E5=8D=95=E5=85=83=E6=B5=8B?= =?UTF-8?q?=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tests/unit/test_parse_profile_settings.py | 137 ++++++++++++++++++ .../unit/test_runtime_models_worker_output.py | 22 +++ 2 files changed, 159 insertions(+) create mode 100644 backend/tests/unit/test_parse_profile_settings.py create mode 100644 backend/tests/unit/test_runtime_models_worker_output.py diff --git a/backend/tests/unit/test_parse_profile_settings.py b/backend/tests/unit/test_parse_profile_settings.py new file mode 100644 index 0000000..c77e0b8 --- /dev/null +++ b/backend/tests/unit/test_parse_profile_settings.py @@ -0,0 +1,137 @@ +from __future__ import annotations + +import pytest + +from schemas.shared.user import ( + NotificationSettings, + PreferenceSettings, + ProfileSettingsV1, + parse_profile_settings, +) + + +class TestParseProfileSettings: + def test_parse_profile_settings_with_full_settings(self) -> None: + raw = { + "version": 1, + "preferences": { + "interface_language": "en-US", + "ai_language": "en-US", + "timezone": "America/New_York", + "country": "US", + }, + "privacy": {"profile_visibility": "private"}, + "notification": { + "allow_notifications": True, + "allow_vibration": False, + }, + } + result = parse_profile_settings(raw) + + assert isinstance(result, ProfileSettingsV1) + assert result.version == 1 + assert isinstance(result.preferences, PreferenceSettings) + assert result.preferences.interface_language == "en-US" + assert result.preferences.ai_language == "en-US" + assert result.preferences.timezone == "America/New_York" + assert result.preferences.country == "US" + assert isinstance(result.notification, NotificationSettings) + assert result.notification.allow_notifications is True + assert result.notification.allow_vibration is False + + def test_parse_profile_settings_with_empty_settings(self) -> None: + result = parse_profile_settings(None) + + assert isinstance(result, ProfileSettingsV1) + assert result.version == 1 + assert isinstance(result.preferences, PreferenceSettings) + assert result.preferences.interface_language == "zh-CN" + assert result.preferences.ai_language == "zh-CN" + assert result.preferences.timezone == "Asia/Shanghai" + assert result.preferences.country == "CN" + assert isinstance(result.notification, NotificationSettings) + assert result.notification.allow_notifications is True + assert result.notification.allow_vibration is True + + def test_parse_profile_settings_with_partial_preferences(self) -> None: + raw = { + "preferences": { + "interface_language": "en-US", + }, + } + result = parse_profile_settings(raw) + + assert result.preferences.interface_language == "en-US" + assert result.preferences.ai_language == "zh-CN" + assert result.preferences.timezone == "Asia/Shanghai" + assert result.preferences.country == "CN" + + def test_parse_profile_settings_with_partial_notification(self) -> None: + raw = { + "notification": { + "allow_notifications": False, + }, + } + result = parse_profile_settings(raw) + + assert isinstance(result.notification, NotificationSettings) + assert result.notification.allow_notifications is False + assert result.notification.allow_vibration is True + + def test_parse_profile_settings_with_legacy_notification_format(self) -> None: + raw = { + "notification": { + "push_enabled": True, + }, + } + result = parse_profile_settings(raw) + + assert isinstance(result.notification, NotificationSettings) + assert result.notification.allow_notifications is True + assert result.notification.allow_vibration is True + + def test_parse_profile_settings_invalid_language_uses_default(self) -> None: + raw = { + "preferences": { + "interface_language": "invalid-language", + }, + } + with pytest.raises(ValueError, match="language must be a valid BCP-47 tag"): + parse_profile_settings(raw) + + def test_parse_profile_settings_invalid_timezone_uses_default(self) -> None: + raw = { + "preferences": { + "timezone": "Invalid/Timezone", + }, + } + with pytest.raises(ValueError, match="timezone must be a valid IANA timezone"): + parse_profile_settings(raw) + + def test_parse_profile_settings_country_normalized_to_uppercase(self) -> None: + raw = { + "preferences": { + "country": "us", + }, + } + result = parse_profile_settings(raw) + assert result.preferences.country == "US" + + def test_profile_settings_v1_model_dump(self) -> None: + settings = ProfileSettingsV1( + preferences=PreferenceSettings( + interface_language="en-US", + ai_language="en-US", + timezone="UTC", + country="US", + ), + notification=NotificationSettings( + allow_notifications=True, + allow_vibration=False, + ), + ) + dumped = settings.model_dump(mode="json") + + assert dumped["preferences"]["interface_language"] == "en-US" + assert dumped["notification"]["allow_notifications"] is True + assert dumped["notification"]["allow_vibration"] is False diff --git a/backend/tests/unit/test_runtime_models_worker_output.py b/backend/tests/unit/test_runtime_models_worker_output.py new file mode 100644 index 0000000..7015a0f --- /dev/null +++ b/backend/tests/unit/test_runtime_models_worker_output.py @@ -0,0 +1,22 @@ +from __future__ import annotations + +import pytest +from pydantic import ValidationError + +from schemas.agent.runtime_models import WorkerAgentOutputLite + + +def test_worker_output_lite_rejects_divination_derived_from_llm() -> None: + payload = { + "status": "success", + "sign_level": "中上签", + "conclusion": ["结论"], + "focus_points": ["重点"], + "advice": ["建议"], + "keywords": ["关键词一", "关键词二", "关键词三"], + "answer": "最终答案", + "divination_derived": {}, + } + + with pytest.raises(ValidationError): + WorkerAgentOutputLite.model_validate(payload)