fix: норматив доклада только по выбору
This commit is contained in:
parent
6e7c4f4596
commit
5e459c449b
14 changed files with 100 additions and 21 deletions
|
|
@ -455,6 +455,7 @@ def test_instructor_criteria_change_timer_and_success_threshold(client, monkeypa
|
|||
"decision_time_limit_seconds": 45,
|
||||
"card_fill_time_limit_seconds": 180,
|
||||
"dds_card_work_time_limit_seconds": 180,
|
||||
"dds_report_reaction_enabled": False,
|
||||
"dds_report_reaction_limit_seconds": 20,
|
||||
"allowed_errors": 50,
|
||||
"require_correct_grammar": False,
|
||||
|
|
@ -749,7 +750,7 @@ def test_dds_card_over_three_minutes_has_e3_finding_and_actual_deviation(client)
|
|||
|
||||
|
||||
def test_complete_dds_workflow_with_training_calls_and_status_updates(client):
|
||||
session_id, control = start(client)
|
||||
session_id, control = start(client, criteria={"dds_report_reaction_enabled": True})
|
||||
try:
|
||||
state = hub.get(session_id)
|
||||
with client.websocket_connect(f"/ws/station/{session_id}") as station:
|
||||
|
|
@ -835,6 +836,7 @@ def send_status(station, service, status):
|
|||
def test_dds_report_reaction_goes_from_criteria_to_report(client, reaction, passed):
|
||||
"""Лимит из `scenario.start` доходит до метрики, отметки D6 и отчёта."""
|
||||
session_id, control = start(client, criteria={
|
||||
"dds_report_reaction_enabled": True,
|
||||
"dds_report_reaction_limit_seconds": 20,
|
||||
"score_weights": {"dds_report_reaction": 3.5},
|
||||
})
|
||||
|
|
@ -876,6 +878,7 @@ def test_dds_report_reaction_goes_from_criteria_to_report(client, reaction, pass
|
|||
|
||||
report = client.get(f"/api/sessions/{session_id}/report").json()
|
||||
assert report["criteria"]["dds_report_reaction_limit_seconds"] == 20
|
||||
assert report["criteria"]["dds_report_reaction_enabled"] is True
|
||||
assert [item for item in report["metrics"]
|
||||
if item["key"] == "dds_report_reaction"] == metrics
|
||||
if reaction == "slow":
|
||||
|
|
@ -889,7 +892,7 @@ def test_dds_report_reaction_goes_from_criteria_to_report(client, reaction, pass
|
|||
def test_refusal_after_crew_report_does_not_lower_score_without_finding(client):
|
||||
"""Бригада доложила о прибытии, но работы не проводились: отказ с причиной
|
||||
— терминальный исход, неотмеченное «Прибытие» не штрафуется."""
|
||||
session_id, control = start(client)
|
||||
session_id, control = start(client, criteria={"dds_report_reaction_enabled": True})
|
||||
try:
|
||||
state = hub.get(session_id)
|
||||
with client.websocket_connect(f"/ws/station/{session_id}") as station:
|
||||
|
|
|
|||
|
|
@ -324,10 +324,12 @@ def reaction(status_log, reports, limit_ms=45_000, pause_intervals=None):
|
|||
entries=status_log, services=SERVICES, crew_assignments=card.crew_assignments,
|
||||
deadline_ms=30_000, elapsed_ms=5_000, phone_reports=reports,
|
||||
report_reaction_ms=limit_ms,
|
||||
report_reaction_enabled=True,
|
||||
pause_intervals=pause_intervals,
|
||||
)
|
||||
metric = next((m for m in dispatcher_metrics(card, 30_000, services=SERVICES,
|
||||
report_reaction_ms=limit_ms,
|
||||
report_reaction_enabled=True,
|
||||
pause_intervals=pause_intervals)
|
||||
if m.key == "dds_report_reaction"), None)
|
||||
return [f for f in findings if f.metric_key == "dds_report_reaction"], metric
|
||||
|
|
|
|||
|
|
@ -68,11 +68,21 @@ def test_csv_contains_sections_and_blocks_formula_injection():
|
|||
assert any(row[0] == "Занятие" and row[3] == "'=1+1" for row in rows)
|
||||
assert any(row[0] == "Ошибки" and row[3] == "'+HYPERLINK(\"x\")" for row in rows)
|
||||
assert any(row[0] == "Самооценка" and row[3] == "'@SUM(1,2)" for row in rows)
|
||||
assert ["Критерии", "", "Лимит реакции на доклад бригады, с", "45", ""] in rows
|
||||
assert ["Критерии", "", "Лимит реакции на доклад бригады, с", "не применяется", ""] in rows
|
||||
assert _cell(" =cmd") == "' =cmd"
|
||||
assert _cell("\tОбычный текст") == "'\tОбычный текст"
|
||||
|
||||
|
||||
def test_csv_shows_enabled_report_reaction_limit():
|
||||
report = sample_report()
|
||||
report.criteria.dds_report_reaction_enabled = True
|
||||
report.criteria.dds_report_reaction_limit_seconds = 20
|
||||
|
||||
rows = list(csv.reader(io.StringIO(to_csv(report).decode("utf-8-sig"))))
|
||||
|
||||
assert ["Критерии", "", "Лимит реакции на доклад бригады, с", "20", ""] in rows
|
||||
|
||||
|
||||
def test_pdf_supports_cyrillic_and_spans_pages(tmp_path):
|
||||
data = to_pdf(sample_report(long=True))
|
||||
assert data.startswith(b"%PDF-")
|
||||
|
|
@ -91,6 +101,7 @@ def test_pdf_supports_cyrillic_and_spans_pages(tmp_path):
|
|||
assert "Адрес должен быть уточнён" in extracted
|
||||
assert "Заявитель сообщает о дыме" in extracted
|
||||
assert "Лимит реакции на доклад бригады" in extracted
|
||||
assert "не применяется" in extracted
|
||||
|
||||
|
||||
def test_certificate_pdf_contains_saved_result(tmp_path):
|
||||
|
|
|
|||
|
|
@ -88,6 +88,7 @@ def test_active_dds_session_round_trips_without_losing_work():
|
|||
|
||||
def test_report_reaction_keeps_times_and_limit_after_restore():
|
||||
before = dds_state()
|
||||
before.criteria.dds_report_reaction_enabled = True
|
||||
before.criteria.dds_report_reaction_limit_seconds = 20
|
||||
card = before.desk.active
|
||||
service = before.card_services(card)[0]
|
||||
|
|
@ -102,6 +103,7 @@ def test_report_reaction_keeps_times_and_limit_after_restore():
|
|||
restored = load_state(dump_state(before), now_utc())
|
||||
|
||||
assert restored.criteria.dds_report_reaction_limit_seconds == 20
|
||||
assert restored.criteria.dds_report_reaction_enabled
|
||||
assert restored.desk.active.phone_reports == card.phone_reports
|
||||
|
||||
def reaction(state):
|
||||
|
|
@ -118,6 +120,31 @@ def test_report_reaction_keeps_times_and_limit_after_restore():
|
|||
assert reaction(restored) == reaction(before), "оценка после восстановления та же"
|
||||
|
||||
|
||||
def test_report_reaction_default_off_keeps_status_completeness_d6():
|
||||
state = dds_state()
|
||||
card = state.desk.active
|
||||
service = state.card_services(card)[0]
|
||||
card.set_service_status(service, ServiceStatus.RESPONDING,
|
||||
"Основание: доклад.\nСведения: бригада выехала.")
|
||||
without_report = state.model_copy(deep=True)
|
||||
card.phone_reports.append(PhoneReportRecord(
|
||||
service=service, crew=card.crew_selected, phase="dispatched",
|
||||
text="Бригада выехала", at=card.status_log[-1].at - timedelta(seconds=70),
|
||||
))
|
||||
|
||||
result = score_dds_card(state, card)
|
||||
baseline = score_dds_card(without_report, without_report.desk.active)
|
||||
|
||||
assert state.criteria.dds_report_reaction_enabled is False
|
||||
assert result.score_auto == baseline.score_auto
|
||||
assert [(item.code, item.metric_key, item.fact) for item in result.findings] == [
|
||||
(item.code, item.metric_key, item.fact) for item in baseline.findings
|
||||
]
|
||||
assert not any(item.key == "dds_report_reaction" for item in result.metrics)
|
||||
assert not any(item.metric_key == "dds_report_reaction" for item in result.findings)
|
||||
assert any(item.code is ErrorCode.D6 for item in result.findings)
|
||||
|
||||
|
||||
def completed_card() -> DdsCardRecord:
|
||||
return DdsCardRecord(
|
||||
card_id=uuid4(),
|
||||
|
|
|
|||
|
|
@ -628,6 +628,7 @@ def test_repeated_pause_and_resume_are_idempotent(clock, monkeypatch):
|
|||
def test_report_reaction_excludes_pause_after_control_and_checkpoint(clock, monkeypatch):
|
||||
base = datetime(2026, 9, 27, 10, tzinfo=UTC)
|
||||
state, card = _dds_state_with_active_card(clock)
|
||||
state.criteria.dds_report_reaction_enabled = True
|
||||
service = state.card_services(card)[0]
|
||||
monkeypatch.setattr("app.session.dds.now_utc", lambda: base)
|
||||
card.set_service_status(service, ServiceStatus.ACCEPTED, "Карточка принята")
|
||||
|
|
|
|||
Loading…
Reference in a new issue