Remove enter binding, ; hide batched correction steps by default

This commit is contained in:
sebastien committed 2026-09-21 16:07:56 +02:00
1 parent 55f9a29677
commit c8ce04cf50
4 files changed
+139 -22

No files matched your search

+90 -2
View File
@@ -133,7 +133,8 @@ class GuiConvenienceTests(unittest.TestCase):
self.assertNotEqual(self.app.current_step.id, "giving_names")
def test_batch_status_waits_until_all_jobs_are_ready(self):
self.app.state_store.update_step("correction", variant="batch")
self.app.state_store.update_step("correction", variant="batch", last_run_variant="batch")
self.app._populate_tree()
self.app.state_store.update_step("batch_status", visited=True)
self.app.tree.selection_set("batch_status")
self.app.update()
@@ -150,7 +151,8 @@ class GuiConvenienceTests(unittest.TestCase):
self.assertEqual(self.app.current_step.id, "fetch_batches")
def test_batch_watch_buttons_use_loaded_evaluation_and_stop_on_reload(self):
self.app.state_store.update_step("correction", variant="batch")
self.app.state_store.update_step("correction", variant="batch", last_run_variant="batch")
self.app._populate_tree()
self.app.tree.selection_set("batch_status")
self.app.update()
with patch.object(self.app.batch_monitor, "start") as start:
@@ -175,6 +177,92 @@ class GuiConvenienceTests(unittest.TestCase):
self.assertEqual(self.app.current_step.id, "inputs")
self.assertEqual(self.app.state_store.step("batch_status")["status"], "success")
def test_batch_steps_hidden_until_a_correction_is_started(self):
batch_ids = ("submit_batches", "batch_status", "fetch_batches")
self.app.state_store.update_step("correction", variant="batch")
self.app._populate_tree()
for step_id in batch_ids:
self.assertFalse(self.app.tree.exists(step_id))
self.assertNotIn(step_id, self.app._progression_ids("correction"))
self.app.state_store.update_step("correction", last_run_variant="hybrid", status="running")
self.app._populate_tree()
for step_id in batch_ids:
self.assertTrue(self.app.tree.exists(step_id))
self.assertIn(step_id, self.app._progression_ids("correction"))
def test_existing_batch_artifacts_reveal_steps_even_in_live_mode(self):
for filename in ("batch_requests_flash.jsonl", "batch_requests_pro.jsonl",
"batch_jobs.json", "batched_correction_result.jsonl"):
with self.subTest(filename=filename):
path = self.evaluation / filename
path.write_text("")
self.app._populate_tree()
self.assertFalse(self.app.tree.exists("batch_status"))
path.write_text('{"jobs":{"flash":{"name":"batches/1"}}}\n')
self.app._populate_tree()
self.assertTrue(self.app.tree.exists("batch_status"))
self.app._handle_first_visit(self.app.step_by_id["batch_status"])
self.app.update()
self.assertNotEqual(self.app.state_store.step("batch_status").get("status"), "skipped")
path.unlink()
def test_started_batches_remain_visible_after_mode_change_and_reload(self):
self.app.state_store.update_step("correction", batch_started=True, last_run_variant="live")
self.app.state_store.load(self.evaluation)
self.app._populate_tree()
self.assertTrue(self.app.tree.exists("batch_status"))
fresh = self.repository / "Fresh"
fresh.mkdir()
self.app.state_store.load(fresh)
self.app._populate_tree()
self.assertFalse(self.app.tree.exists("batch_status"))
def test_navigation_skips_hidden_batch_steps(self):
with patch.object(self.app.tree, "selection_set") as select:
self.app._move_selection_from("correction", 1)
select.assert_called_once_with("manual_resolution")
def test_labels_and_correction_notify_once_on_success(self):
for step_id in ("labels", "correction"):
with self.subTest(step=step_id), patch("copienator_gui.app.notify_desktop") as notify:
self.app.active_step_id = step_id
self.app._finish_process(0, False)
self.app._finish_process(0, False)
notify.assert_called_once()
self.assertIn(self.evaluation.name, notify.call_args.args[1])
self.assertIn("labels" if step_id == "labels" else "correction",
notify.call_args.args[1])
def test_incomplete_failed_and_interrupted_steps_notify_the_outcome_once(self):
for step_id in ("labels", "correction"):
for code, interrupted, outcome in (
(4, False, "partielle"), (1, False, "échouée"),
(0, True, "interrompue"), (130, False, "interrompue"),
):
with self.subTest(step=step_id, code=code, interrupted=interrupted), \
patch("copienator_gui.app.notify_desktop") as notify:
self.app.active_step_id = step_id
self.app._finish_process(code, interrupted)
self.app._finish_process(code, interrupted)
notify.assert_called_once()
title, message = notify.call_args.args
self.assertIn(outcome, title)
self.assertIn(outcome, message)
self.assertIn(self.evaluation.name, message)
self.assertIn(f"code {code}", message)
self.assertNotIn("réussie", message)
def test_notification_failure_keeps_success_and_uses_existing_fallback(self):
self.app.active_step_id = "labels"
with patch("copienator_gui.app.notify_desktop", side_effect=RuntimeError("unavailable")), \
patch.object(self.app, "bell") as bell, \
patch.object(self.app, "_append_console") as console:
self.app._finish_process(0, False)
bell.assert_called_once()
self.assertTrue(any("Notification de bureau indisponible" in call.args[0]
for call in console.call_args_list))
self.assertEqual(self.app.state_store.step("labels")["status"], "success")
def test_optional_blank_crop_can_target_a_copy_or_be_skipped(self):
copies = self.evaluation/"Copies"
copies.mkdir()