summaryrefslogtreecommitdiffstats
path: root/docs/superpowers
diff options
context:
space:
mode:
Diffstat (limited to 'docs/superpowers')
-rw-r--r--docs/superpowers/plans/2026-08-03-post-0.1.0-usability.md49
1 files changed, 47 insertions, 2 deletions
diff --git a/docs/superpowers/plans/2026-08-03-post-0.1.0-usability.md b/docs/superpowers/plans/2026-08-03-post-0.1.0-usability.md
index 1edcf59..7f79100 100644
--- a/docs/superpowers/plans/2026-08-03-post-0.1.0-usability.md
+++ b/docs/superpowers/plans/2026-08-03-post-0.1.0-usability.md
@@ -68,8 +68,8 @@ taking that too literally.
| 21 | Default shortcuts are not sensible enough | discoverability | S | open |
| 22 | Translatability audit and i18n wiring | correctness | M | open |
| 23 | No way to save a search query from the UI | workflow | M | open |
-| 24 | No right-click actions on the thread list | discoverability | S | open |
-| 25 | No select-all, and bulk actions are undiscoverable | workflow | S | open |
+| 24 | No right-click actions on the thread list | discoverability | S | **done** |
+| 25 | No select-all, and bulk actions are undiscoverable | workflow | S | **done** |
| 26 | No way to add or remove an arbitrary tag from the UI | workflow | S | **done** |
| 27 | The UI cannot see a sync it did not start | feedback | S | **done** |
| 28 | Re-adding `unread` counts 2 unsynced changes, not 0 | correctness | S | open |
@@ -80,6 +80,7 @@ taking that too literally.
| 33 | Status bar messages never expire | feedback | S | open |
| 34 | No overview of the Maildir itself | information | M | open |
| 35 | No refresh of the thread list after a sync | workflow | M | open |
+| 36 | `test_mainwindow` cannot reach the worker | testing | S | open, on demand |
Sizes are rough: XS under an hour, S a sitting, M a session.
@@ -1640,6 +1641,50 @@ from a current one, so the plumbing for a second concurrent query exists.
- Scroll position likewise.
- A refresh must not re-trigger mark-read for the thread already on screen.
+## 36. `test_mainwindow` cannot reach the worker
+
+**Observed:** twice in one session (0.8.0), a defect could not be given a
+regression test because `MainWindow` in tests has no notmuch database, so its
+`NotmuchWorker` never emits `threadLoaded`. Both were verified by hand and by a
+standalone model instead:
+
+- A queued `threadLoaded` repainting a pane that a multi-row selection had just
+ blanked. The fix guards `onThreadLoaded()`, and that guard is untested: the
+ test passes with it reverted.
+- A local sync reporting itself as a background one. Staging it needs
+ `MailSync::isRunning()` true at one transition and false at the next, which
+ needs a configured sync command and a live child process. That was tried and
+ abandoned: it left a process running for the length of the suite and popped a
+ dialog on the user's screen.
+
+**The machinery already exists and is not the gap.** `tests/notmuchfixture.h`
+builds a throwaway Maildir in a `QTemporaryDir`, runs `notmuch new` with
+`NOTMUCH_CONFIG` scoped to the test process, and `addMessage()` takes
+message-id, subject, from, date, body, unread and in-reply-to, so threads come
+from real `In-Reply-To` chains. `test_notmuchworker` uses it. `test_mainwindow`
+does not.
+
+**Explicitly rejected: a corpus built from the user's real mail.** Considered
+and declined 2026-08-04. The global rule against personal data in fixtures
+forbids it, git hooks enforce it, and this repository is public. Scrubbing is
+also the fragile path: one surviving `In-Reply-To` or `References` header names a
+real correspondent, and a scrubbed message no longer demonstrates what the real
+one did. Where a real message exposes a parser bug, hand-write a minimal `.eml`
+reproducing its **shape**, as `truncated.eml` and `hostile_filename.eml` already
+do.
+
+**Approach.** Give `test_mainwindow` the fixture and point the window's worker at
+it, so a test can select a thread and let a real `threadLoaded` arrive.
+
+**Do this when a defect needs it, not before** (user, 2026-08-04). Wiring it
+with nothing to test proves nothing. The two defects above are already fixed;
+this item is the note that the next one of its kind should be tested properly
+rather than modelled.
+
+**Constraint:** every existing `test_mainwindow` case constructs a bare
+`MainWindow` and must keep working. The fixture is per-test, not a suite-wide
+`initTestCase`, or every case pays for a `notmuch new`.
+
## Deferred, unsized, or split out
Items noted while triaging but not part of the original list. Same numbering