You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
88 lines
2.9 KiB
88 lines
2.9 KiB
import json |
|
from pathlib import Path |
|
|
|
import pytest |
|
|
|
from voice_transcriptor.models import AppSettings |
|
from voice_transcriptor.services.settings import SettingsRepository |
|
|
|
|
|
def test_load_missing_file_returns_documented_defaults(monkeypatch, tmp_path: Path) -> None: |
|
documents = tmp_path / "Documents" |
|
documents.mkdir() |
|
monkeypatch.setattr(Path, "home", classmethod(lambda cls: tmp_path)) |
|
|
|
settings, warning = SettingsRepository(tmp_path / "settings.json").load() |
|
|
|
assert settings == AppSettings("gpt-4o-transcribe", "pt-BR", documents) |
|
assert warning is None |
|
|
|
|
|
def test_load_missing_file_uses_home_when_documents_is_unavailable( |
|
monkeypatch, tmp_path: Path |
|
) -> None: |
|
monkeypatch.setattr(Path, "home", classmethod(lambda cls: tmp_path)) |
|
|
|
settings, warning = SettingsRepository(tmp_path / "settings.json").load() |
|
|
|
assert settings.output_directory == tmp_path |
|
assert warning is None |
|
|
|
|
|
def test_save_and_load_round_trip_utf8_settings(tmp_path: Path) -> None: |
|
path = tmp_path / "settings.json" |
|
expected = AppSettings("gpt-4o-transcribe", "pt-BR", tmp_path / "Transcrições") |
|
repository = SettingsRepository(path) |
|
|
|
repository.save(expected) |
|
actual, warning = repository.load() |
|
|
|
assert actual == expected |
|
assert warning is None |
|
assert json.loads(path.read_text(encoding="utf-8")) == { |
|
"model": "gpt-4o-transcribe", |
|
"language": "pt-BR", |
|
"output_directory": str(tmp_path / "Transcrições"), |
|
} |
|
|
|
|
|
def test_load_malformed_file_recovers_defaults_with_nonfatal_warning(tmp_path: Path) -> None: |
|
path = tmp_path / "settings.json" |
|
path.write_text("not json", encoding="utf-8") |
|
|
|
settings, warning = SettingsRepository(path).load() |
|
|
|
assert settings.model == "gpt-4o-transcribe" |
|
assert warning is not None |
|
assert "settings" in warning.lower() |
|
|
|
|
|
def test_save_replaces_existing_file_atomically(monkeypatch, tmp_path: Path) -> None: |
|
path = tmp_path / "settings.json" |
|
path.write_text("old", encoding="utf-8") |
|
calls: list[tuple[Path, Path]] = [] |
|
original_replace = Path.replace |
|
|
|
def recording_replace(source: Path, destination: Path) -> Path: |
|
calls.append((source, destination)) |
|
return original_replace(source, destination) |
|
|
|
monkeypatch.setattr(Path, "replace", recording_replace) |
|
|
|
SettingsRepository(path).save(AppSettings("model", "pt-BR", tmp_path / "out")) |
|
|
|
assert calls |
|
source, destination = calls[0] |
|
assert source.parent == path.parent |
|
assert destination == path |
|
assert json.loads(path.read_text(encoding="utf-8"))["model"] == "model" |
|
|
|
|
|
def test_saved_settings_never_include_api_key_fields(tmp_path: Path) -> None: |
|
path = tmp_path / "settings.json" |
|
|
|
SettingsRepository(path).save(AppSettings("model", "pt-BR", tmp_path / "out")) |
|
|
|
serialized = path.read_text(encoding="utf-8").lower() |
|
assert "api" not in serialized |
|
assert "key" not in serialized
|
|
|