lct-55: ошибка адреса и сообщение в 112
This commit is contained in:
parent
29aca65e8c
commit
f0c9015f2b
14 changed files with 267 additions and 7 deletions
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
import asyncio
|
||||
import time
|
||||
from datetime import datetime, timedelta
|
||||
from datetime import UTC, datetime, timedelta
|
||||
from uuid import uuid4
|
||||
|
||||
import pytest
|
||||
|
|
@ -17,6 +17,7 @@ from app.domain.timers import TimerCode
|
|||
from app.main import app
|
||||
from app.scenarios import store
|
||||
from app.session.hub import hub
|
||||
from app.session.checkpoint import dump_state, load_state
|
||||
from app.session.store import MemorySessionStore
|
||||
|
||||
|
||||
|
|
@ -836,6 +837,76 @@ def send_status(station, service, status):
|
|||
read_until(station, "station.state")
|
||||
|
||||
|
||||
def test_crew_discovers_card_address_error_and_dispatcher_reports_it_to_112(client):
|
||||
session_id, control = start(client, scenario_id="dds-card-address-error")
|
||||
try:
|
||||
state = hub.get(session_id)
|
||||
card = state.desk.active
|
||||
assert card.dispatched_card.address == "улица Ленина, 16"
|
||||
assert card.scenario.ground_truth.address == "улица Ленина, 14"
|
||||
with client.websocket_connect(f"/ws/station/{session_id}") as station:
|
||||
service = accept_with_crew(station)
|
||||
station.send_json({
|
||||
"type": "card.error_report_112", "card_id": str(card.card_id),
|
||||
"text": "В карточке неверный адрес",
|
||||
})
|
||||
assert "Сначала получите доклад" in read_until(station, "error")["message"]
|
||||
complete_phone_call(station, state, "dispatched")
|
||||
read_until(station, "station.state")
|
||||
send_status(station, service, "responding")
|
||||
report = complete_phone_call(station, state, "arrived")
|
||||
snapshot = read_until(station, "station.state")["snapshot"]
|
||||
assert "улица Ленина, 14" in report["text"]
|
||||
assert "улица Ленина, 16" in report["text"]
|
||||
assert snapshot["card_error_discovered"] is True
|
||||
assert snapshot["report_112_text"] is None
|
||||
|
||||
message = "В карточке дом 16; бригада на месте установила дом 14."
|
||||
station.send_json({
|
||||
"type": "card.error_report_112", "card_id": str(card.card_id), "text": message,
|
||||
})
|
||||
snapshot = read_until(station, "station.state")["snapshot"]
|
||||
assert snapshot["report_112_text"] == message
|
||||
station.send_json({
|
||||
"type": "card.error_report_112", "card_id": str(card.card_id), "text": message,
|
||||
})
|
||||
assert sum(action == "card.error_report_112" for action, _, _ in card.dds_log) == 1
|
||||
|
||||
active = client.get("/api/sessions/active").json()
|
||||
teacher = next(row for row in active if row["session_id"] == str(session_id))
|
||||
assert teacher["dds_snapshot"]["report_112_text"] == message
|
||||
restored = load_state(dump_state(state), datetime.now(UTC))
|
||||
assert restored.station_snapshot().report_112_text == message
|
||||
station.send_json({"type": "station.finish"})
|
||||
read_until(station, "score.ready")
|
||||
|
||||
report = client.get(f"/api/sessions/{session_id}/report").json()
|
||||
actions = report["card_results"][0]["actions"]
|
||||
assert any(action["type"] == "card.error_report_112" and action["text"] == message
|
||||
for action in actions)
|
||||
assert message in client.get(f"/api/sessions/{session_id}/report.csv").text
|
||||
finally:
|
||||
control.__exit__(None, None, None)
|
||||
|
||||
|
||||
def test_report_to_112_is_unavailable_without_planted_card_error(client):
|
||||
session_id, control = start(client)
|
||||
try:
|
||||
state = hub.get(session_id)
|
||||
with client.websocket_connect(f"/ws/station/{session_id}") as station:
|
||||
read_until(station, "card.received")
|
||||
snapshot = read_until(station, "station.state")["snapshot"]
|
||||
assert snapshot["card_error_discovered"] is False
|
||||
station.send_json({
|
||||
"type": "card.error_report_112", "card_id": str(state.desk.active.card_id),
|
||||
"text": "Сообщаю об ошибке карточки в 112",
|
||||
})
|
||||
assert "Сначала получите доклад" in read_until(station, "error")["message"]
|
||||
assert not state.desk.active.dds_log
|
||||
finally:
|
||||
control.__exit__(None, None, None)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(("reaction", "passed"), [
|
||||
("fast", True), ("slow", False), ("missing", False), ("early", True),
|
||||
])
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ from fastapi.testclient import TestClient
|
|||
from app.api.auth import Principal
|
||||
from app.api.http import sessions
|
||||
from app.config import get_settings
|
||||
from app.domain.events import SessionReport
|
||||
from app.domain.events import DdsCardReport, SessionReport
|
||||
from app.domain.roles import Role
|
||||
from app.main import app
|
||||
from app.scoring.export import _cell, certificate_pdf, to_csv, to_pdf
|
||||
|
|
@ -83,6 +83,31 @@ def test_csv_shows_enabled_report_reaction_limit():
|
|||
assert ["Критерии", "", "Лимит реакции на доклад бригады, с", "20", ""] in rows
|
||||
|
||||
|
||||
def test_card_error_message_to_112_is_in_csv_and_pdf(tmp_path):
|
||||
report = sample_report()
|
||||
message = "В карточке дом 16; по докладу бригады фактически дом 14."
|
||||
report.card_results = [DdsCardReport(
|
||||
card_id=uuid4(), scenario_id="dds-card-address-error", score_auto=100,
|
||||
reply_text="", metrics=[], findings=[], actions=[{
|
||||
"type": "card.error_report_112", "text": message,
|
||||
"at": "2026-09-21T12:05:00+00:00",
|
||||
}],
|
||||
)]
|
||||
|
||||
rows = list(csv.reader(io.StringIO(to_csv(report).decode("utf-8-sig"))))
|
||||
assert any(row[0] == "Сообщение в 112" and row[3] == message for row in rows)
|
||||
|
||||
import shutil
|
||||
import subprocess
|
||||
|
||||
if shutil.which("pdftotext"):
|
||||
path = tmp_path / "dds-error.pdf"
|
||||
path.write_bytes(to_pdf(report))
|
||||
extracted = subprocess.check_output(["pdftotext", str(path), "-"], text=True)
|
||||
assert "Сообщения в 112 об ошибках карточек" in extracted
|
||||
assert message in extracted
|
||||
|
||||
|
||||
def test_pdf_supports_cyrillic_and_spans_pages(tmp_path):
|
||||
data = to_pdf(sample_report(long=True))
|
||||
assert data.startswith(b"%PDF-")
|
||||
|
|
|
|||
|
|
@ -236,8 +236,8 @@ def test_dispatcher_metric_dds_ack_excludes_pause_from_elapsed(clock):
|
|||
clock.advance(60)
|
||||
state.resume()
|
||||
clock.advance(15)
|
||||
card.set_service_status(service, ServiceStatus.ACCEPTED, "Принято")
|
||||
card.on_event("dds.open")
|
||||
card.set_service_status(service, ServiceStatus.ACCEPTED, "Принято")
|
||||
|
||||
metric = next(m for m in dispatcher_metrics(card, 30_000, services=services) if m.key == "dds_ack")
|
||||
assert metric.passed is True
|
||||
|
|
|
|||
Loading…
Reference in a new issue