Add test suite (63 tests) and CI workflow, fix Settings API bugs
Some checks failed
Release / Bump version and tag (push) Successful in 4s
Sidecar Release / Bump sidecar version and tag (push) Failing after 3s
Tests / Python Backend Tests (push) Failing after 3s
Tests / Frontend Tests (push) Successful in 8s
Tests / Rust Sidecar Tests (push) Successful in 3m10s
Some checks failed
Release / Bump version and tag (push) Successful in 4s
Sidecar Release / Bump sidecar version and tag (push) Failing after 3s
Tests / Python Backend Tests (push) Failing after 3s
Tests / Frontend Tests (push) Successful in 8s
Tests / Rust Sidecar Tests (push) Successful in 3m10s
Test suite covering all three layers: Python backend (25 tests): - AppController: state machine, start/stop, callbacks, settings reload - API server: REST endpoints, config CRUD, status, devices - Config: dot-notation get/set, persistence, nested paths - Main headless: ready event port format validation Svelte frontend (14 tests via Vitest): - Backend store: exported properties/methods, port derivation, URLs - Config store: method names (fetchConfig not loadConfig), defaults - Transcriptions store: add/clear/plaintext - File extension regression: ensures $state runes only in .svelte.ts Rust sidecar (24 tests via cargo test): - Platform/arch detection, asset name construction - Ready event deserialization (with extra fields tolerance) - Path construction, version read/write, old version cleanup - Zip extraction, SidecarManager lifecycle CI workflow (.gitea/workflows/test.yml): - Runs on push to main and PRs - Three parallel jobs: Python, Frontend, Rust Also fixes three bugs found during test planning: - Settings: /api/check-updates -> GET /api/check-update - Settings: /api/remote/login -> /api/login - Settings: /api/remote/register -> /api/register Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
0
client/tests/__init__.py
Normal file
0
client/tests/__init__.py
Normal file
78
client/tests/test_config.py
Normal file
78
client/tests/test_config.py
Normal file
@@ -0,0 +1,78 @@
|
||||
"""Tests for client.config.Config."""
|
||||
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
# Ensure project root is on path
|
||||
project_root = Path(__file__).resolve().parent.parent.parent
|
||||
sys.path.insert(0, str(project_root))
|
||||
|
||||
from client.config import Config
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def cfg(tmp_path):
|
||||
"""A Config backed by a temp file so we never touch the real user config."""
|
||||
return Config(config_path=str(tmp_path / "test_config.yaml"))
|
||||
|
||||
|
||||
# ── dot-notation get ────────────────────────────────────────────────
|
||||
|
||||
|
||||
def test_dot_notation_get(cfg):
|
||||
"""Config.get should traverse nested dicts using dot-separated keys."""
|
||||
cfg.config = {"audio": {"sample_rate": 16000}}
|
||||
assert cfg.get("audio.sample_rate") == 16000
|
||||
|
||||
|
||||
# ── dot-notation set ────────────────────────────────────────────────
|
||||
|
||||
|
||||
def test_dot_notation_set(cfg):
|
||||
"""Config.set should create/update nested values via dot-separated keys."""
|
||||
cfg.set("audio.sample_rate", 44100)
|
||||
assert cfg.config["audio"]["sample_rate"] == 44100
|
||||
|
||||
# Also readable via .get
|
||||
assert cfg.get("audio.sample_rate") == 44100
|
||||
|
||||
|
||||
# ── missing key returns default ─────────────────────────────────────
|
||||
|
||||
|
||||
def test_missing_key_returns_default(cfg):
|
||||
"""Accessing a nonexistent key should return the supplied default."""
|
||||
assert cfg.get("nonexistent.path", "fallback") == "fallback"
|
||||
assert cfg.get("also.missing") is None # default default is None
|
||||
|
||||
|
||||
# ── nested set creates intermediate dicts ───────────────────────────
|
||||
|
||||
|
||||
def test_nested_set_creates_path(cfg):
|
||||
"""Setting a deeply nested key should create all intermediate dicts."""
|
||||
cfg.config = {}
|
||||
cfg.set("a.b.c.d", 42)
|
||||
|
||||
assert cfg.config["a"]["b"]["c"]["d"] == 42
|
||||
assert cfg.get("a.b.c.d") == 42
|
||||
|
||||
|
||||
# ── save and reload round-trip ──────────────────────────────────────
|
||||
|
||||
|
||||
def test_save_and_reload(tmp_path):
|
||||
"""Values persisted via save() should survive a fresh Config load."""
|
||||
config_file = str(tmp_path / "roundtrip.yaml")
|
||||
|
||||
# Create and populate
|
||||
cfg1 = Config(config_path=config_file)
|
||||
cfg1.set("user.name", "TestUser")
|
||||
cfg1.set("transcription.model", "tiny.en")
|
||||
|
||||
# Load a fresh instance from the same file
|
||||
cfg2 = Config(config_path=config_file)
|
||||
assert cfg2.get("user.name") == "TestUser"
|
||||
assert cfg2.get("transcription.model") == "tiny.en"
|
||||
Reference in New Issue
Block a user