"""The AI web page's review cases, run unchanged against the desktop page. They use this folder's `page` and `stub` fixtures: the page talks to the review backend over the fake Qt bridge instead of HTTP. """ import sys from pathlib import Path sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "page_check_ai")) from test_ai_review import ( # noqa: E402,F401 test_approve_stays_blocked_while_rows_are_unverified, test_band_counts_and_legend_match, test_band_filters_show_the_right_rows, test_draft_edit_is_not_saved_until_save, test_page_x_of_y_updates_while_running, ) from test_ai_review import FIELDS, FLAGGED, open_review # noqa: E402 from test_ai_cost import ( # noqa: E402,F401 cost_page, test_by_hand_panel_is_labelled_assumptions_and_recomputes, test_coverage_pill_counts_priced_of_all_documents, test_month_breakdown_groups_runs_by_month, test_runs_show_tokens_and_cost_and_unpriced_is_not_zero, test_spend_tiles_sum_the_priced_runs, ) from page_check_common import no_ai_cases # noqa: E402 globals().update(no_ai_cases()) TAMPER = """async (path) => { const reply = new Promise(done => { const base = window.__pyMsg; window.__pyMsg = m => { base(m); if (JSON.parse(m).event === 'ai_response') done(JSON.parse(m).data); }; }); bridge.ai_request(999, 'POST', path, '{}'); return await reply; }""" def test_a_changed_page_cannot_approve_over_the_bridge(page, stub): """The gate is Python's: a page that skips its own buttons and calls the slot is still refused.""" stub.put_run("job-t", "bands.pdf", FIELDS) open_review(page, "job-t") reply = page.evaluate(TAMPER, "/runs/job-t/approve") assert reply["id"] == 999 and reply["status"] == 409 and str(FLAGGED) in reply["body"]["detail"] assert stub.RUNS["job-t"]["approved"] is False