"""BGM配置合并逻辑单元测试。""" import pytest from packages.domain.bgm_utils import merge_bgm_config class TestMergeBgmConfig: """merge_bgm_config 单元测试。""" def test_template_empty_user_has_config(self): """模板为空,用户有配置 → 返回用户配置副本。""" template = {} user = {"audio_url": "http://example.com/bgm.mp3", "volume": 0.8} result = merge_bgm_config(template, user) assert result == {"audio_url": "http://example.com/bgm.mp3", "volume": 0.8} # 确保返回的是新对象,不是同一引用 assert result is not user def test_user_empty_template_has_config(self): """用户为空,模板有配置 → 返回模板配置副本。""" template = {"audio_url": "http://example.com/default.mp3", "enabled": True} user = {} result = merge_bgm_config(template, user) assert result == {"audio_url": "http://example.com/default.mp3", "enabled": True} assert result is not template def test_both_empty(self): """都为空 → 返回空dict。""" result = merge_bgm_config({}, {}) assert result == {} def test_user_overrides_single_field(self): """用户覆盖单个普通字段。""" template = {"audio_url": "http://template.com/default.mp3", "volume": 0.5} user = {"audio_url": "http://user.com/custom.mp3"} result = merge_bgm_config(template, user) assert result["audio_url"] == "http://user.com/custom.mp3" assert result["volume"] == 0.5 # 模板值保留 def test_user_overrides_multiple_fields(self): """用户覆盖多个字段。""" template = { "audio_url": "http://template.com/default.mp3", "volume": 0.5, "fade_in": 1.0, "fade_out": 1.0, } user = { "audio_url": "http://user.com/custom.mp3", "volume": 0.9, } result = merge_bgm_config(template, user) assert result["audio_url"] == "http://user.com/custom.mp3" assert result["volume"] == 0.9 assert result["fade_in"] == 1.0 assert result["fade_out"] == 1.0 def test_enabled_not_in_user_keep_template_true(self): """enabled特殊处理:用户没传,模板enabled=True → 保留True。""" template = {"audio_url": "http://template.com/default.mp3", "enabled": True} user = {"audio_url": "http://user.com/custom.mp3"} result = merge_bgm_config(template, user) assert result["enabled"] is True assert result["audio_url"] == "http://user.com/custom.mp3" def test_enabled_not_in_user_keep_template_false(self): """enabled特殊处理:用户没传,模板enabled=False → 保留False。""" template = {"audio_url": "http://template.com/default.mp3", "enabled": False} user = {"audio_url": "http://user.com/custom.mp3"} result = merge_bgm_config(template, user) assert result["enabled"] is False def test_enabled_explicit_true_overrides_template_false(self): """enabled特殊处理:用户显式传True,覆盖模板False。""" template = {"audio_url": "http://template.com/default.mp3", "enabled": False} user = {"enabled": True} result = merge_bgm_config(template, user) assert result["enabled"] is True def test_enabled_explicit_false_overrides_template_true(self): """enabled特殊处理:用户显式传False,覆盖模板True。""" template = {"audio_url": "http://template.com/default.mp3", "enabled": True} user = {"enabled": False} result = merge_bgm_config(template, user) assert result["enabled"] is False def test_nested_fields_shallow_merge(self): """普通字段(包括嵌套dict)按浅层合并处理。""" template = { "audio_url": "http://template.com/default.mp3", "effects": {"fade_in": 1.0, "fade_out": 1.0}, } user = { "effects": {"fade_in": 3.0}, # 整个覆盖,不是深合并 } result = merge_bgm_config(template, user) # 浅层合并:用户的effects完全替换模板的effects assert result["effects"] == {"fade_in": 3.0} def test_user_none_value_fields(self): """用户传None值的字段,会覆盖模板值为None。""" template = {"audio_url": "http://template.com/default.mp3", "volume": 0.5} user = {"audio_url": None} result = merge_bgm_config(template, user) assert result["audio_url"] is None assert result["volume"] == 0.5 def test_does_not_mutate_inputs(self): """合并操作不修改原始输入对象。""" template = {"audio_url": "http://template.com/default.mp3", "enabled": True, "volume": 0.5} user = {"volume": 0.9} template_copy = dict(template) user_copy = dict(user) merge_bgm_config(template, user) assert template == template_copy assert user == user_copy def test_user_adds_new_field(self): """用户新增模板中没有的字段。""" template = {"audio_url": "http://template.com/default.mp3"} user = {"loop": True, "start_time": 5.0} result = merge_bgm_config(template, user) assert result["audio_url"] == "http://template.com/default.mp3" assert result["loop"] is True assert result["start_time"] == 5.0 def test_asset_id_and_preset_id_fields(self): """asset_id和preset_id字段正常合并。""" template = {"preset_id": "preset_default", "volume": 0.5} user = {"asset_id": "asset_user_123"} result = merge_bgm_config(template, user) assert result["preset_id"] == "preset_default" assert result["asset_id"] == "asset_user_123" assert result["volume"] == 0.5