Repository navigation
Test layout, accessibility job, registry-race fix, ragged/XLSX test deltas (#167, #168, #191, #192, #193) - #214
Draft
amar-python wants to merge 9 commits into
Draft
amar-python wants to merge 9 commits into
amar-python wants to merge 9 commits into
Conversation
Flat tests/*.py made it impossible to run one category, and the M2/M3 tests landed uncategorised. Six folders, each a package, with the renames PR #41 proposed plus the 17 test files that landed after it was drafted. - tests/{unit,system,system_integration,performance,accessibility,uat}/ - tests/conftest.py: folder-derived markers, plus the shared live_api, registry_cleanup, te_org_cleanup, destructive_enabled and unique_tag fixtures - pytest.ini: system, sit, performance, accessibility, uat markers - Makefile: test-unit / test-system / test-sit / test-performance / test-accessibility / test-uat - scripts/lint.sh: every Python test file is now collected by find, so the list cannot drift again; tests get E702/E401/E128 relaxed, source does not - requirements-dev.txt: playwright, axe-playwright-python (for #168) - health_check.py rglob, select_tests.py / run_qa.ps1 / .gitignore path updates 365 tests collected before and after; the no-database tiers pass unchanged. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011T6Wqj8HS5EUEcvTUM24SL
tests/test_header_mapping.py, test_original_bytes.py and test_registry_race.py landed flat on main; all three need PostgreSQL, so they go to system_integration/. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011T6Wqj8HS5EUEcvTUM24SL
- tests/accessibility/: Playwright fixtures and scans of /auth, / and /audit. Signed-out, / and /audit redirect to /auth, so they would have been scanned as the sign-in page and reported a false green. The signed_in_page fixture seeds the te.session sessionStorage entry and stubs /api/**, and every scan asserts it landed on the route it asked for. - quality-gate.yml: new `accessibility` job on pull_request. The scan step is continue-on-error because the frontend has known unfixed defects; results are uploaded as an artifact. The integration job now runs with --markers "not accessibility". - The job installs with `npm ci`, not bun: bun.lock is stale (zod ^3 vs ^4) and `bun install --frozen-lockfile` fails against package.json. First local run against the Vite dev server: 4 pass, 3 fail. The failures are real frontend defects (unlabelled select on /audit; no <main> on /auth and /audit), which is what the issue says to expect. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011T6Wqj8HS5EUEcvTUM24SL
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011T6Wqj8HS5EUEcvTUM24SL
…191, F1) Adds tests/system_integration/test_registry_race.py: several uploads released together by a barrier, 40 rounds each, for (a) the identical file, (b) identical content under different names, (c) the same name with different content. Asserts exactly one winner, one registry row, an attributable duplicate_file for every loser, and no orphan csv_<hash> tables or duplicated rows. The test found a defect. When identical uploads overlap, the losing request could get a generic status "error" ("relation ... already exists" / "type ... already exists") instead of duplicate_file: the #81 handler caught only UniqueViolation, and these arrive as DuplicateTable / DuplicateObject. The registry stayed consistent; the loser just was not told why. The handler also named the loser's own file, not the winner's. upload_dynamic now catches all three and a small _lost_race() looks up the winner in the registry. Evidence, PostgreSQL 16: - fix reverted: 5 of 5 runs fail - fix in place: 12 of 12 (at 8 rounds) and 6 of 6 (at 40 rounds) pass - mutation, file_hash UNIQUE dropped: the different-names test fails 10 of 10. The same-name test does not detect it, because UNIQUE (file_name) and the csv_<hash> table name also stop that case; documented in the test. - full suite, all four environments deployed: 370 passed. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011T6Wqj8HS5EUEcvTUM24SL
…ounting (#192) Upstream's tests already check the accounting identity and that each ragged row gets a reason in the response. Adds what they do not: that every reason is also stored (GET /api/csv/uploads/{id}), and the same checks for T&E mode, with a file mixing good rows, an in-file duplicate and several ragged rows. Mutation, extra_cells() forced to return []: 6 of 9 tests in the file fail, including all the new ones. Passing run against PostgreSQL 16: 9 passed. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011T6Wqj8HS5EUEcvTUM24SL
…back (#193) Upstream's guard and tests already cover the payloads and plain numbers by reading values back through sheet_to_json. The issue asks for the cell to be asserted as stored as text, which is the property that stops a spreadsheet from evaluating it: adds that for =cmd, +cmd, -cmd, @cmd and a tab-prefixed value in the error report, and for the audit report. Mutation, upstream's guard disabled: 11 of 38 tests in export.test.ts fail. Spreadsheet-application check, as the issue asks: the XLSX produced by downloadErrorReport, opened in LibreOffice 24.2.7.2, shows '=1+1, '=cmd, '+cmd, '-cmd, '@cmd literally (not evaluated); -5 and plain are untouched. Microsoft Excel was not available, so it is not covered. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011T6Wqj8HS5EUEcvTUM24SL
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011T6Wqj8HS5EUEcvTUM24SL
Only conflict was the generated docs/TEST_CASES.md, regenerated with scripts/test_catalogue.py. tests/test_te_reupload_registry.py (#215) landed flat on main and is moved to tests/system_integration/ to match the #167 layout. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011T6Wqj8HS5EUEcvTUM24SL
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Work on the "04 Enhancements" batch (#167, #168, #169, #191, #192, #193, #194, #195).
While I was building this,
mainmoved. Merged #202 already delivered #169, #193 and #194, and open draft #213 implements #195. So this PR is rebased onto currentmainand contains only whatmainlacks, plus one defect the new tests found. Nothing here overrides upstream's #169, #193 or #194 implementations.mainand equivalent to what I built; I dropped mine. Catalogue regenerated for the new layoutChanges
#167. Six folders (
unit,system,system_integration,performance,accessibility,uat), each a package.tests/conftest.pygives every test its folder's marker, sopytest -m sitandpytest tests/system_integrationselect the same set, and adds the shared fixtures (live_api,registry_cleanup,te_org_cleanup,destructive_enabled,unique_tag). New markers,make test-*targets,tests/README.md.scripts/lint.shnow collects every test file withfind, so the list can't drift again. The three test files that landed flat onmainafter I branched are moved too.#168.
tests/accessibility/(Playwright + axe-core, WCAG 2.1 AA) and a newaccessibilityjob./and/auditredirect to/authwhen signed out, so a plain scan would check the sign-in page three times and report a false green. The tests seed thete.sessionsessionStorage entry, stub/api/**, and assert they landed on the route they asked for. The integration job and the coverage gate step now exclude the marker.#191. Concurrency test: uploads released together by a barrier, 40 rounds, for identical file, identical content under different names, and same name with different content. It asserts one winner, one registry row, an attributable rejection for every loser, and no orphan tables. Upstream's test tolerated
"error"as a valid loser outcome, so it could not catch this: the losing request can get a genericstatus: "error"("relation … already exists" / "type … already exists") instead ofduplicate_file, because the loader catches onlyUniqueViolation. It now also catchesDuplicateTableandDuplicateObject, and names the winner rather than echoing the loser's own file. This replaces upstream'stest_registry_race.py.#192. Upstream's tests check the accounting identity and a reason per ragged row. Adds what they don't: the reason is also stored (
GET /api/csv/uploads/{id}), and the same for T&E mode.#193. Asserts the XLSX cell is a text cell with no formula, for
=cmd,+cmd,-cmd,@cmdand a tab-prefixed value, in the error and audit reports.Evidence
All run against PostgreSQL 16 with all four environments deployed, on this branch rebased onto
main(ad39ddf).test_report.py --markers "not accessibility" --strict): 391 passed, 0 failed, 0 skippedmain388; this branch 391 non-accessibility + 7 accessibility. Reconciles exactly (388 − 2 upstream race tests + 3 mine + 2 ragged), so the reorg lost nothingmake lint, bandit,make health(89),test_catalogue.py --check: pass. Frontend: vitest 165 passed,tsccleanmain: with the loader fix, 5/5 runs pass. With the fix reverted (upstream behaviour), 3/3 failUNIQUE(file_hash)fails the different-names race test 10/10 (the same-name test does not catch it, sinceUNIQUE(file_name)also guards that case; documented in the test);extra_cells()returning[]fails 6 of 9 ragged tests; disabling upstream's XLSX guard fails 11 of 38 export testsdownloadErrorReport, opened in LibreOffice 24.2.7.2, shows'=1+1,'=cmd,'+cmd,'-cmd,'@cmdliterally, not evaluated;-5andplainuntouchedFirst local run of the accessibility scans against the Vite dev server: 4 pass, 3 fail. The failures are real frontend defects, as #168 expects: an unlabelled select on
/audit, and no<main>landmark on/authand/audit.Not verified, and decisions needed
continue-on-erroron purpose, because of the known frontend defects.inferred_unconfirmedand flags strictness as "Decision for the owner"). The issue text says "require". I built the strict version: dynamic upload withouttypesConfirmedcreates nothing and returns the inferred types; migration0009, provenance returned and shown in the files list; a retry reuses confirmed types rather than re-inferring; plus the T&E-rejects-dynamic-table test. It breaks every API caller that omits the flag (~40 test call sites andsmoke_test.shwere updated). It is preserved, not proposed, as commit0fcedafon branchenh/04-all-eight-original, which also holds my dropped Add test catalogue generator (scripts/test_catalogue.py + docs/TEST_CASES.md) #169/Gate: measure api/services coverage with floors for the three loaders #194 versions for comparison. Both designs claim migration0009, so whichever merges second will need renumbering.dynamic_loadernow measures about 87.6%.csv-table-hub-main/bun.lockis stale (zod^3 vs ^4), sobun install --frozen-lockfilefails. The new job usesnpm cifor that reason.Closes #167, #191, #192. Refs #168, #193 (CI run and Excel outstanding).
Generated by Claude Code