From 9d29441a84858780f80ff1bc35ce9c0c5f43b0c9 Mon Sep 17 00:00:00 2001 From: JJ Liebig Date: Sun, 20 Sep 2026 00:21:32 +0200 Subject: test(windows): distinguish clipboard paste origin in input gauntlet (#4394) * test(windows): distinguish clipboard paste origin in input gauntlet refs #4314 * test(windows): correct gauntlet paste-origin evidence refs #4314 --- scripts/test_windows_input.py | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) (limited to 'scripts/test_windows_input.py') diff --git a/scripts/test_windows_input.py b/scripts/test_windows_input.py index 38868843..a844ea62 100644 --- a/scripts/test_windows_input.py +++ b/scripts/test_windows_input.py @@ -1,7 +1,7 @@ """Portable tests of the gauntlet's oracle, not Windows input qualification.""" import copy import unittest -from scripts.windows_input.report import catalogue, channel_identity_errors, herdr_protocol_label, known_host_gap, qualification_matrix, summarize, verdict +from scripts.windows_input.report import classification_of_client_events, catalogue, channel_identity_errors, herdr_protocol_label, known_host_gap, qualification_matrix, summarize, verdict class WindowsInputGauntletTests(unittest.TestCase): @@ -95,12 +95,49 @@ class WindowsInputGauntletTests(unittest.TestCase): staged = b"\x1b[200~C:\\Temp\\herdr-clipboard-images-user\\image.png\x1b[201~" self.assertEqual(verdict(case, "legacy", {**self.evidence, "path": "direct", "hex": empty_paste.hex()})[0], "pass") remote = {**self.evidence, "path": "herdr-remote", "hex": staged.hex(), + "paste_origin": "empty-paste", "staged_image_sha256": case["expected"]["legacy"]["sha256"]} self.assertEqual(verdict(case, "legacy", remote)[0], "pass") self.assertEqual(verdict(case, "legacy", {**remote, "staged_image_sha256": "0" * 64})[0], "fail") self.assertEqual(verdict(case, "legacy", {**self.evidence, "path": "herdr-remote", "hex": empty_paste.hex()})[0], "fail") self.assertEqual(verdict(case, "legacy", {**self.evidence, "path": "herdr", "hex": empty_paste.hex()})[0], "not_run") + def test_remote_clipboard_image_rejects_a_paste_the_terminal_issued(self): + # A staged PNG that came from a terminal-issued text paste proves nothing + # about the empty-paste bridge (#4314), and a staged PNG with no mapper + # evidence at all must not qualify the bridge either. + case = self.cases["clipboard-image"] + staged = b"\x1b[200~C:\\Temp\\herdr-clipboard-images-user\\image.png\x1b[201~" + remote = {**self.evidence, "path": "herdr-remote", "hex": staged.hex(), + "staged_image_sha256": case["expected"]["legacy"]["sha256"]} + self.assertEqual(verdict(case, "legacy", {**remote, "paste_origin": "terminal-paste"})[0], "fail") + for weak in ("none", "key-event", None): + self.assertEqual(verdict(case, "legacy", {**remote, "paste_origin": weak})[0], "inconclusive", weak) + self.assertEqual(verdict(case, "legacy", {**remote, "paste_origin": "empty-paste"})[0], "pass") + direct = {**self.evidence, "path": "direct", "hex": b"\x1b[200~\x1b[201~".hex()} + self.assertEqual(verdict(case, "legacy", {**direct, "paste_origin": "terminal-paste"})[0], "fail") + self.assertEqual(verdict(case, "legacy", {**direct, "paste_origin": "empty-paste"})[0], "pass") + + def test_client_event_trace_classifies_paste_origin(self): + self.assertEqual(classification_of_client_events(None), None) + self.assertEqual(classification_of_client_events([]), "none") + self.assertEqual( + classification_of_client_events(['mapped_event_groups=[Paste { text: "" }]']), + "empty-paste") + self.assertEqual( + classification_of_client_events(['mapped_event_groups=[Paste { text: "hello" }]']), + "terminal-paste") + self.assertEqual( + classification_of_client_events( + ["mapped_event_groups=[Key { code: Char('v'), modifiers: 0, kind: Press }]"]), + "key-event") + # A release alone is not a consumed press. + self.assertEqual( + classification_of_client_events( + ["mapped_event_groups=[Key { code: Char('v'), modifiers: 0, kind: Release }]"]), + "none") + self.assertEqual(classification_of_client_events(["not a trace line", 7]), None) + def test_mouse_interleave_requires_ordered_motion_and_paste(self): case = self.cases["mouse-interleave"] motion = b"\x1b[<35;10;5M" -- cgit v1.2.3