Miscs personal GUI improvement

This commit is contained in:
2026-09-14 09:42:13 +02:00
parent e8b8a11c5b
commit d60d5479d6
5 changed files with 207 additions and 33 deletions
+5 -1
View File
@@ -52,7 +52,11 @@ class GuiConvenienceTests(unittest.TestCase):
(self.evaluation / "enonce.pdf").unlink()
self.app._reload_inputs()
self.assertEqual(self.app.state_store.step("inputs")["status"], "ready")
self.assertIn("enonce.pdf", self.app.description_label.cget("text"))
self.assertIn("enonce.pdf", self.app.missing_requirements_label.cget("text"))
style = ttk.Style(self.app)
self.assertEqual(
style.lookup("MissingPrerequisite.TLabel", "foreground"), "#c62828"
)
def test_compact_evaluation_input_and_open_folder_button(self):
self.assertEqual(int(self.app.evaluation_entry.cget("width")), 42)
+48
View File
@@ -38,6 +38,7 @@ from copienator_gui.app import (
build_runner_environment,
copy_pdf_paths,
detected_annotation_directories,
get_personal_interro_files,
has_manual_conflicts,
plotting_shortcut_lines,
process_status,
@@ -1660,6 +1661,53 @@ class WorkflowTests(unittest.TestCase):
self.assertNotIn("update_ods", standard_ids)
self.assertIn("update_ods", personal_ids)
def test_get_personal_interro_files_copies_the_three_expected_sources(self) -> None:
with tempfile.TemporaryDirectory() as directory:
root = Path(directory)
source = root / "source"
evaluation = root / "Interro07"
source.mkdir()
evaluation.mkdir()
contents = {
"Interro07.pdf": b"pdf",
"Interro07.tex": b"statement",
"Interro07c.tex": b"correction",
}
for name, content in contents.items():
(source / name).write_bytes(content)
copied = get_personal_interro_files(evaluation, source)
self.assertEqual(
copied,
(
evaluation / "enonce.pdf",
evaluation / "enonce.tex",
evaluation / "correction.tex",
),
)
self.assertEqual((evaluation / "enonce.pdf").read_bytes(), b"pdf")
self.assertEqual((evaluation / "enonce.tex").read_bytes(), b"statement")
self.assertEqual((evaluation / "correction.tex").read_bytes(), b"correction")
def test_get_personal_interro_files_validates_name_and_all_sources_first(self) -> None:
with tempfile.TemporaryDirectory() as directory:
root = Path(directory)
source = root / "source"
source.mkdir()
invalid = root / "DS07"
invalid.mkdir()
with self.assertRaisesRegex(ValueError, "Interro"):
get_personal_interro_files(invalid, source)
evaluation = root / "Interro07"
evaluation.mkdir()
(evaluation / "enonce.pdf").write_bytes(b"existing")
(source / "Interro07.pdf").write_bytes(b"new")
with self.assertRaisesRegex(FileNotFoundError, "Interro07.tex"):
get_personal_interro_files(evaluation, source)
self.assertEqual((evaluation / "enonce.pdf").read_bytes(), b"existing")
def test_first_visit_automation_is_declared_on_expected_steps(self) -> None:
auto_start = {
step.id for step in self.steps.values() if step.auto_start_first_visit
+54 -4
View File
@@ -4,13 +4,14 @@ import os
import tempfile
import unittest
from pathlib import Path
from tkinter import ttk
from types import SimpleNamespace
from unittest.mock import Mock, patch
from copienator import CliError, EvaluationWorkspace, ExitCode
from copienator.commands import enonce_info as personal
from copienator.commands import gemini_for_enonce as gemini
from copienator_gui.app import CopienatorApp
from copienator_gui.app import CopienatorApp, get_personal_interro_files
from copienator_gui.workflow import build_workflow
@@ -53,7 +54,7 @@ class PersonalStatementTests(unittest.TestCase):
enabled = {step.id: step for step in build_workflow(True)}
self.assertEqual([variant.id for variant in standard["statement"].variants], ["gemini"])
self.assertEqual([variant.program for variant in enabled["statement"].variants],
["statement", "statement-personal"])
["statement-personal", "statement"])
for ident in ("statement_groups", "statement_persp"):
self.assertNotIn(ident, standard)
self.assertTrue(enabled[ident].optional)
@@ -140,6 +141,48 @@ class SelectiveGeminiTests(unittest.TestCase):
@unittest.skipUnless(os.environ.get("DISPLAY"), "Tk requires a display")
class PersonalStatementGuiTests(unittest.TestCase):
def test_get_file_button_completes_inputs_and_advances(self):
with tempfile.TemporaryDirectory() as temporary:
repository = Path(temporary)
evaluation = repository / "Interro12"
source = repository / "source"
evaluation.mkdir()
source.mkdir()
(repository / "names").touch()
for name, content in (
("Interro12.pdf", b"pdf"),
("Interro12.tex", b"statement"),
("Interro12c.tex", b"correction"),
):
(source / name).write_bytes(content)
app = CopienatorApp(repository, True, evaluation)
try:
app.update()
buttons = [
child
for child in app.form.winfo_children()
if isinstance(child, ttk.Button)
]
get_button = next(
button for button in buttons if button.cget("text") == "Get the files"
)
with patch(
"copienator_gui.app.get_personal_interro_files",
side_effect=lambda target: get_personal_interro_files(target, source),
):
get_button.invoke()
app.update()
self.assertEqual(app.state_store.step("inputs")["status"], "success")
self.assertEqual(app.current_step.id, "statement")
self.assertEqual((evaluation / "enonce.pdf").read_bytes(), b"pdf")
self.assertEqual((evaluation / "enonce.tex").read_bytes(), b"statement")
self.assertEqual((evaluation / "correction.tex").read_bytes(), b"correction")
finally:
for callback in app.tk.splitlist(app.tk.call("after", "info")):
app.after_cancel(callback)
app.destroy()
def test_personal_requirements_and_optional_button_command_previews(self):
with tempfile.TemporaryDirectory() as temporary:
evaluation = Path(temporary)
@@ -149,12 +192,19 @@ class PersonalStatementGuiTests(unittest.TestCase):
app.update()
app.tree.selection_set("statement")
app.update()
app._select_variant(1)
self.assertEqual(app.variant_var.get(), "personal")
self.assertIn("statement-personal", app.command_var.get())
self.assertEqual(app._missing_requirements(app.current_step), [])
self.assertIn("SHEETINFO", app.description_label.cget("text"))
self.assertFalse(
any(
isinstance(child, ttk.LabelFrame)
and child.cget("text") == "Après génération — facultatif"
for child in app.form.winfo_children()
)
)
for ident, flag in (("statement_groups", "--groups-only"), ("statement_persp", "--persp-only")):
app._select_statement_action(ident)
app.tree.selection_set(ident)
app.update()
self.assertEqual(app.current_step.id, ident)
self.assertIn(flag, app.command_var.get())