112 lines
4.6 KiB
Python
112 lines
4.6 KiB
Python
"""Tests for the Voice Analysis settings — persistence + MCP config tools.
|
|
|
|
The config file (~/.fcp-mcp-server/config.json) is redirected to a tmp_path
|
|
so these never touch the developer's real settings.
|
|
"""
|
|
|
|
import json
|
|
|
|
import pytest
|
|
|
|
from fcpxml import model_manager
|
|
|
|
|
|
@pytest.fixture(autouse=True)
|
|
def isolated_config(tmp_path, monkeypatch):
|
|
"""Point model_manager's config file at a throwaway directory."""
|
|
monkeypatch.setattr(model_manager, "_CONFIG_DIR", tmp_path)
|
|
monkeypatch.setattr(model_manager, "_CONFIG_FILE", tmp_path / "config.json")
|
|
return tmp_path / "config.json"
|
|
|
|
|
|
class TestLoadVoiceAnalysisConfig:
|
|
def test_defaults_when_nothing_stored(self):
|
|
cfg = model_manager.load_voice_analysis_config()
|
|
assert cfg == model_manager.DEFAULT_VOICE_ANALYSIS_CONFIG
|
|
|
|
def test_defaults_are_not_shared_mutable_state(self):
|
|
cfg = model_manager.load_voice_analysis_config()
|
|
cfg["emphasis_weights"]["energy"] = 0.99
|
|
fresh = model_manager.load_voice_analysis_config()
|
|
assert fresh["emphasis_weights"]["energy"] == 0.30
|
|
|
|
def test_malformed_stored_values_fall_back_to_defaults(self, isolated_config):
|
|
isolated_config.write_text(json.dumps({"voice_analysis": {"energy_threshold": "loud"}}))
|
|
cfg = model_manager.load_voice_analysis_config()
|
|
assert cfg["energy_threshold"] == 0.5
|
|
|
|
def test_non_dict_stored_value_falls_back(self, isolated_config):
|
|
isolated_config.write_text(json.dumps({"voice_analysis": "nonsense"}))
|
|
assert model_manager.load_voice_analysis_config() == model_manager.DEFAULT_VOICE_ANALYSIS_CONFIG
|
|
|
|
def test_thresholds_are_clamped_to_unit_range(self, isolated_config):
|
|
isolated_config.write_text(
|
|
json.dumps({"voice_analysis": {"energy_threshold": 5.0, "emphasis_floor": -2.0}})
|
|
)
|
|
cfg = model_manager.load_voice_analysis_config()
|
|
assert cfg["energy_threshold"] == 1.0
|
|
assert cfg["emphasis_floor"] == 0.0
|
|
|
|
|
|
class TestSaveVoiceAnalysisConfig:
|
|
def test_saves_and_reloads(self):
|
|
model_manager.save_voice_analysis_config(energy_threshold=0.7, emotion_enabled=True)
|
|
cfg = model_manager.load_voice_analysis_config()
|
|
assert cfg["energy_threshold"] == 0.7
|
|
assert cfg["emotion_enabled"] is True
|
|
|
|
def test_omitted_fields_keep_current_value(self):
|
|
model_manager.save_voice_analysis_config(energy_threshold=0.7)
|
|
model_manager.save_voice_analysis_config(emphasis_floor=0.9)
|
|
cfg = model_manager.load_voice_analysis_config()
|
|
assert cfg["energy_threshold"] == 0.7
|
|
assert cfg["emphasis_floor"] == 0.9
|
|
|
|
def test_partial_weight_update_keeps_other_weights(self):
|
|
model_manager.save_voice_analysis_config(emphasis_weights={"energy": 0.55})
|
|
weights = model_manager.load_voice_analysis_config()["emphasis_weights"]
|
|
assert weights["energy"] == 0.55
|
|
assert weights["pitch_variation"] == 0.25
|
|
|
|
def test_unknown_weight_key_is_ignored(self):
|
|
model_manager.save_voice_analysis_config(emphasis_weights={"loudness": 9.0})
|
|
weights = model_manager.load_voice_analysis_config()["emphasis_weights"]
|
|
assert "loudness" not in weights
|
|
|
|
def test_does_not_clobber_unrelated_config_keys(self):
|
|
model_manager.save_hf_token("tok123")
|
|
model_manager.save_voice_analysis_config(energy_threshold=0.7)
|
|
assert model_manager.load_hf_token() == "tok123"
|
|
|
|
def test_returns_full_merged_config(self):
|
|
returned = model_manager.save_voice_analysis_config(energy_threshold=0.7)
|
|
assert returned == model_manager.load_voice_analysis_config()
|
|
|
|
|
|
class TestVoiceAnalysisConfigTools:
|
|
async def test_get_reports_current_settings(self):
|
|
from server import handle_get_voice_analysis_config
|
|
|
|
result = await handle_get_voice_analysis_config({})
|
|
text = result[0].text
|
|
assert "Voice Analysis Settings" in text
|
|
assert "Emphasis Weights" in text
|
|
|
|
async def test_save_persists_and_echoes_back(self):
|
|
from server import handle_save_voice_analysis_config
|
|
|
|
result = await handle_save_voice_analysis_config(
|
|
{"energy_threshold": 0.8, "emotion_enabled": True}
|
|
)
|
|
assert "0.80" in result[0].text
|
|
cfg = model_manager.load_voice_analysis_config()
|
|
assert cfg["energy_threshold"] == 0.8
|
|
assert cfg["emotion_enabled"] is True
|
|
|
|
async def test_save_with_no_arguments_is_a_noop(self):
|
|
from server import handle_save_voice_analysis_config
|
|
|
|
before = model_manager.load_voice_analysis_config()
|
|
await handle_save_voice_analysis_config({})
|
|
assert model_manager.load_voice_analysis_config() == before
|