Commit 7777ebc
authored
* test: end-to-end coverage of scripts/export.py + manual QA checklist (closes #27)
Adds tests/test_cli_export_e2e.py — five unittest cases that drive
scripts/export.py main() against a self-contained SQLite fixture
(workspaceStorage + globalStorage cursorDiskKV) under tempfile, with
WORKSPACE_PATH / CLI_CHATS_PATH / XDG_STATE_HOME overrides. Coverage:
- no-zip mode writes .md files under <out>/<date>/...
- YAML frontmatter contains log_id, title, workspace, created_at, updated_at
- default zip mode writes cursor-export-<date>.zip containing .md entries
- manifest.jsonl entries carry log_id / path / updated_at
- --since last is idempotent — second run does not rewrite unchanged files
Adds tests/cli-export-qa-checklist.md as the manual companion: --help,
zip + no-zip + --since last exports, app.py launch + curl smoke,
markdown/PDF download from the web UI.
Adds exports/ to .gitignore alongside the existing export/ entry so
either pluralisation of the example output directory stays untracked.
The fixture is self-contained (does not depend on the conftest.py from
PR #32) so the suite runs on master CI as-is under `unittest discover`.
* docs: tag CLI checklist code fences as bash + use default app port 3000
CodeRabbit MD040 — fenced blocks need a language identifier. Tagged
the four command snippets as `bash`.
Dropped the `--port 3001` override from §5 / §6 in favour of the
script's default port 3000; the explicit flag was a holdover from
issue #27's wording with no actual reason to deviate from the default.
* review: Brad's PR #33 pass — XDG isolation, --no-composer fix, flag coverage
Six follow-ups across two threads of Brad's review.
Production fixes:
* scripts/export.py get_global_state_dir() now honors XDG_STATE_HOME
(returns $XDG_STATE_HOME/cursor-chat-browser), falling back to the
historical ~/.cursor-chat-browser only when the env var is unset.
Without this, the --since last test leaked state into the developer's
real home directory; the test still passed but only by timestamp
coincidence and corrupted ~/.cursor-chat-browser/export_state.json
on every CI run.
* scripts/export.py --no-composer was a parsed-but-unused flag —
opts["include_composer"] was set but never consulted. Added the
missing guard at the IDE-composer iteration site so the flag now
actually skips composer rows.
Test additions to tests/test_cli_export_e2e.py:
* Both DB-seeding helpers (_make_global_state_db, _make_workspace_storage)
now use contextlib.closing(sqlite3.connect(...)). A mid-setup
exception used to leak the handle and on Windows that blocks
TemporaryDirectory.cleanup().
* New TestGetGlobalStateDir regression class — two tests pinning
both branches of the XDG behavior so this can't silently regress.
* test_no_composer_skips_ide_composer_data — fixture seeds composer
data exclusively, so --no-composer must produce zero markdown.
* test_exclude_rules_filters_matching_composer — writes a rules file
containing "E2E" (substring of the seeded composer's title) and
asserts the seeded composer is filtered out before any markdown is
written.
Doc fix in tests/cli-export-qa-checklist.md:
* `curl -sI` sends HTTP/1.1 by default and the dev server replies in
kind. Listing HTTP/1.0 first would have triggered false-fail reports
from testers seeing HTTP/1.1.
Verified locally:
- python3 -m unittest tests.test_cli_export_e2e: 9 passed
- python3 -m unittest discover tests: 187 passed, OK
- ~/.cursor-chat-browser never created during the run
- python3 app.py boots clean; curl -sI returns HTTP/1.1 200 OK
* test: derive XDG temp path via tempfile.gettempdir() (Ruff S108)
CodeRabbit flagged the hardcoded `/tmp/some-xdg-root` literal in
test_uses_xdg_state_home_when_set: it's Linux-specific and trips
Ruff's S108 (hardcoded-tmp-directory) lint. Derive the path from
tempfile.gettempdir() and join with os.path.join so the test runs
on Windows / macOS too and stays lint-clean.
1 parent 81a4010 commit 7777ebc
4 files changed
Lines changed: 421 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
29 | 29 | | |
30 | 30 | | |
31 | 31 | | |
| 32 | + | |
32 | 33 | | |
33 | 34 | | |
34 | 35 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
131 | 131 | | |
132 | 132 | | |
133 | 133 | | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
134 | 141 | | |
135 | 142 | | |
136 | 143 | | |
| |||
488 | 495 | | |
489 | 496 | | |
490 | 497 | | |
491 | | - | |
492 | | - | |
| 498 | + | |
| 499 | + | |
| 500 | + | |
493 | 501 | | |
494 | 502 | | |
495 | 503 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
0 commit comments