feat: add speaker mapping and workflow improvements
This commit is contained in:
@@ -0,0 +1,136 @@
|
||||
import json
|
||||
from datetime import date
|
||||
|
||||
import pytest
|
||||
|
||||
from mka.application.meeting_service import ParticipantInput
|
||||
from mka.application.run_inputs import (
|
||||
RunInputJsonError,
|
||||
RunInputState,
|
||||
export_run_inputs,
|
||||
import_run_inputs,
|
||||
run_input_filename,
|
||||
)
|
||||
|
||||
|
||||
def populated_state() -> RunInputState:
|
||||
return RunInputState(
|
||||
title="F&E Technik Abteilungs Jour Fixe",
|
||||
description="Review the production trial.",
|
||||
language="de",
|
||||
meeting_date=date(2026, 8, 25),
|
||||
participants=(
|
||||
ParticipantInput(
|
||||
participant_id="martin",
|
||||
display_name="Martin Tazl",
|
||||
role="Project lead",
|
||||
organization="Engineering",
|
||||
),
|
||||
ParticipantInput(
|
||||
participant_id="alex",
|
||||
display_name="Alexander Funk",
|
||||
attendance_status="mentioned_only",
|
||||
),
|
||||
),
|
||||
audio_normalization=False,
|
||||
diarization_enabled=True,
|
||||
source_file_name="2026-08-25_jour_fixe.wav",
|
||||
)
|
||||
|
||||
|
||||
def test_current_form_state_serializes_with_schema_and_all_supported_values() -> None:
|
||||
document = json.loads(export_run_inputs(populated_state()))
|
||||
|
||||
assert document["schema_version"] == 1
|
||||
assert document["meeting"]["title"] == "F&E Technik Abteilungs Jour Fixe"
|
||||
assert document["meeting"]["description"] == "Review the production trial."
|
||||
assert document["meeting"]["language"] == "de"
|
||||
assert document["meeting"]["date"] == "2026-08-25"
|
||||
assert document["meeting"]["participants"][1] == {
|
||||
"participant_id": "alex",
|
||||
"display_name": "Alexander Funk",
|
||||
"role": "",
|
||||
"organization": "",
|
||||
"attendance_status": "mentioned_only",
|
||||
}
|
||||
assert document["processing"] == {
|
||||
"audio_normalization": False,
|
||||
"diarization_enabled": True,
|
||||
}
|
||||
|
||||
|
||||
def test_export_import_round_trip_restores_form_and_participants() -> None:
|
||||
original = populated_state()
|
||||
|
||||
restored = import_run_inputs(export_run_inputs(original))
|
||||
|
||||
assert restored == original
|
||||
assert restored.participants[0].participant_id == "martin"
|
||||
assert restored.participants[0].display_name == "Martin Tazl"
|
||||
|
||||
|
||||
def test_missing_optional_fields_use_current_defaults() -> None:
|
||||
restored = import_run_inputs('{"schema_version": 1}')
|
||||
|
||||
defaults = RunInputState.defaults()
|
||||
assert restored == defaults
|
||||
|
||||
|
||||
def test_unknown_safe_fields_are_ignored() -> None:
|
||||
restored = import_run_inputs(
|
||||
json.dumps(
|
||||
{
|
||||
"schema_version": 1,
|
||||
"meeting": {"title": "Known", "future_field": {"value": 1}},
|
||||
"processing": {"future_toggle": True},
|
||||
"future_section": [1, 2, 3],
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
assert restored.title == "Known"
|
||||
|
||||
|
||||
@pytest.mark.parametrize("content", ["not-json", "[]", b"\xff"])
|
||||
def test_malformed_json_is_rejected(content: str | bytes) -> None:
|
||||
with pytest.raises(RunInputJsonError, match="Malformed|top-level"):
|
||||
import_run_inputs(content)
|
||||
|
||||
|
||||
def test_unsupported_future_schema_is_rejected() -> None:
|
||||
with pytest.raises(RunInputJsonError, match="Unsupported.*schema_version"):
|
||||
import_run_inputs('{"schema_version": 2}')
|
||||
|
||||
|
||||
def test_media_contents_are_never_serialized() -> None:
|
||||
exported = export_run_inputs(populated_state())
|
||||
|
||||
assert "2026-08-25_jour_fixe.wav" in exported
|
||||
assert "audio_bytes" not in exported
|
||||
assert "base64" not in exported
|
||||
|
||||
|
||||
def test_source_filename_must_not_be_a_machine_specific_path() -> None:
|
||||
with pytest.raises(RunInputJsonError, match="filename, not a path"):
|
||||
import_run_inputs('{"schema_version": 1, "source_file_name": "/tmp/meeting.wav"}')
|
||||
|
||||
|
||||
def test_invalid_or_duplicate_participants_are_not_silently_reinterpreted() -> None:
|
||||
document = {
|
||||
"schema_version": 1,
|
||||
"meeting": {
|
||||
"participants": [
|
||||
{"participant_id": "martin", "display_name": "Martin"},
|
||||
{"participant_id": "martin", "display_name": "Someone else"},
|
||||
]
|
||||
},
|
||||
}
|
||||
|
||||
with pytest.raises(RunInputJsonError, match="Duplicate participant_id"):
|
||||
import_run_inputs(json.dumps(document))
|
||||
|
||||
|
||||
def test_export_filename_is_readable_and_machine_independent() -> None:
|
||||
assert run_input_filename("F&E Technik Jour Fixe") == (
|
||||
"meeting-inputs-f-e-technik-jour-fixe.json"
|
||||
)
|
||||
Reference in New Issue
Block a user