5 Commits
Author SHA1 Message Date
Juan DenisandClaude Opus 5 39c623c4e9 fix(tests): the "absent extension" seam test named a real extension
test_ext_to_ext_seam_absent_side_returns_default asserted that
get_installed_extension_attr returns its default for serverkit-analytics, on
the stated assumption that analytics "is not installed in this test panel".

That assumption is a property of the machine, not of the code. On a checkout
that HAS analytics under backend/app/plugins/, the seam correctly resolved
`inject` and the test failed with:

    assert <function inject at 0x...> is None

which reads as "the seam is broken" and means precisely the opposite -- the
seam did its job.

It now names a slug that cannot exist, so it tests the contract ("callee absent
-> default, never raises") instead of which extensions happen to be installed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-12 21:48:21 -04:00
Juan DenisandClaude Opus 5 9d570834aa perf(tests): build the Flask app once per session, not once per test
The `app` fixture called create_app('testing') for every one of 3173 tests,
registering 90+ blueprints each time. Measured on a fixed 199-test sample
(pytest --splits 16 --group 5 --durations=0):

    setup     144.9s   89.5%
    call        8.8s    5.4%
    teardown    8.2s    5.0%

95% of the suite's time was preparing to test; 5% was testing. The app is now
built once per process and shared.

Same 794-test slice, before and after — identical results, 2.66x faster:

    before   4 failed, 773 passed, 17 skipped   593.30s
    after    4 failed, 773 passed, 17 skipped   223.11s

(the 4 are pre-existing locally: serverkit-wordpress isn't checked out here.)

Sharing one app surfaces three things a per-test app hid, all handled in the
fixture rather than patched test by test:

1. create_app() is not a pure constructor — it SEEDS the bundled flagship
   extension rows as a boot side effect (test_cloudflare_extraction asserts
   they are "seeded on boot"). The per-test drop_all wipes them, and a shared
   app never re-boots, so every test after the first saw no flagship and the
   extension routes answered 503. seed_flagship_extensions() is now re-run
   after each create_all. The session fixture also boots twice on purpose:
   once to create the schema, once to seed into a schema that exists.

2. Config mutation now leaks where it used to die with the app (e.g.
   test_demo_deploys sets DEMO_DEPLOYS_ENABLED=False and never restores it),
   so config is snapshotted and restored around every test.

3. Structure mutation cannot be undone at all — Flask has no
   unregister_blueprint, and refuses setup methods once an app has served a
   request. Those tests opt out via `pytestmark = pytest.mark.fresh_app` and
   get a private app. Three groups needed it: 13 modules calling
   register_blueprint/add_url_rule directly, 11 that install plugins (
   plugin_service hot-loads their blueprints onto the live app), and
   test_audit_log which adds routes with @app.route.

Tests using the `wp_extension` fixture are detected from the fixture graph
instead of being marked, since that fixture mounts blueprints on whatever app
it is handed — miss one marker and the failure lands in an unrelated test much
later in the run.

Plan 64 Phase 1. Phase 2 (savepoint rollback instead of create_all/drop_all)
is NOT included: it currently takes the slice from 4 failures to 100 failures
and 201 errors, and needs its own round.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-06 02:59:14 -04:00
Juan Denis 7c6b0f3958 security: hook seam lifecycle + registrant binding
Audit remediation (extension seams):
- disable/uninstall tear down the extension's backup kinds, event
  types, and template providers (unregister_capabilities by slug);
  enable re-registers (idempotent)
- wordpress_bridge fails closed unless the extension row is ACTIVE;
  orphaned-site db snapshot route returns clean 503
- provider registrations bound to their registrant: cross-slug
  replace/hijack rejected for backup kinds, event types, template
  providers
2026-08-05 13:36:33 -04:00
Juan Denis ba3bc685fe test: split WP suites — extension-owned move to serverkit-wordpress
10 extension-owned suites (surface, extraction, import-zip, php errors/
limits, pipelines alias, plugin library, promote, reports, ssh import)
move to the extension repo via the SERVERKIT_WORDPRESS_DIR loader.
Panel-core suites (bridge, hooks-absent, seeding, authz sweeps) updated
for WP-absent behavior; conftest seeds the manifest onto test plugin rows.
2026-08-05 02:38:41 -04:00
Juan Denis d61985e73b test: WP hook inversion matrix (present x absent)
16 tests covering boot registration, idempotency, backup provider
resolve/validate/missing-state, event catalog present/absent, template
provider dispatch, monitor binding gate, health-sweep no-op, analytics
ext-to-ext guards. Existing suites minimally updated for the provider
interfaces (171 WP/monitor + 316 backup/events/templates green).
2026-08-05 01:18:32 -04:00