Skip to content

refactor(headless-cms): remove ContextPlugin from tests#5406

Merged
adrians5j merged 54 commits into
nextfrom
adrian/self-hosted-19-2026-07-09
Jul 15, 2026
Merged

refactor(headless-cms): remove ContextPlugin from tests#5406
adrians5j merged 54 commits into
nextfrom
adrian/self-hosted-19-2026-07-09

Conversation

@adrians5j

@adrians5j adrians5j commented Jul 15, 2026

Copy link
Copy Markdown
Member

What changed

First slice of #40 (grep ContextPlugin → zero): api-headless-cms tests are now ContextPlugin-free. This is a prerequisite for deleting the legacy bridge (#39) — the bridge's only real remaining job is dispatching test ContextPlugins.

Recipe (test helpers already call function-plugins directly, pre-auth):

  • Pure DI ContextPlugins (context.container.register*) → plain container => {…} function plugins — lifecycle-hook mocks, model/group providers, entry event handlers.
  • Post-auth-timing cases → a RequestContextInitializer:
    • benchmark.test resolves BenchmarkAbstraction, which HeadlessCmsFeature registers after the plugins loop.
    • httpOptions must not run on an OPTIONS preflight (which short-circuits before context init).
  • Dead code → deleted two unused benchmark test helpers.

No production code touched — test infra only. ctx.db / ctx.benchmark / ctx.plugins bags are already dead (no real reads).

Verification

All affected suites green: onBeforeEntryPublish, contentModelGroup.extension, dynamicZoneField, benchmark, httpOptions, lifecycleHooks, and the 3 lifecycle-mock consumers (contentEntryHooks, contentModel.crud, contentModel.crud.reservedModelIds).

Stacked on #5403 (PR-C). Base will retarget to next once #5403 merges.

Squash Merge Commit

refactor(headless-cms): remove ContextPlugin from tests (#5406)

adrians5j and others added 30 commits July 8, 2026 06:36
…r-core

The WCP license refresh is a per-request RequestInitializer — a transport request-lifecycle
concern — but it lived in api-core (domain), forcing api-core to depend on @webiny/event-handler-core.

Move WcpLicenseInitializer into @webiny/api-event-handler-core (the shared API request stack) and
register it in registerApiRequestStack, so it runs for every flavour (aws + server). api-core keeps
the WCP domain (WcpLicenseProvider, WcpContext, loadWcpLicense) and now exports WcpLicenseProvider;
its @webiny/event-handler-core dependency drops to devDependencies (tests only).

Result: api-core's production layer no longer imports the transport package.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Rg3MRCToopzWSTPWqU9Lga
…o it

Every api package's tests copy the same TestAuthenticator/TestAuthorizer mocks, AuthTrigger/
RootTenant decorators, and createIdentity helper (~15 drifting copies). Introduce
@webiny/api-testing (deps api-core + event-handler-core) as the single home for these primitives,
using the more-evolved parameterized versions (TestIdentity/TestPermissions abstractions).

Migrate api-aco as the first consumer: delete its 5 local copies, import from @webiny/api-testing.
api-aco tests pass.

Note: the base package can't share handler *composition* (feature set differs per package) — only
the auth/tenant scaffold primitives. api-core stays on its local copies for now (it sits below this
package; consuming it would be a dev-cycle — revisit with the test-tiers split).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Rg3MRCToopzWSTPWqU9Lga
…-cms/testing onto it

Standardize TestPermissions on the `{ list }` holder (from the CMS harness) instead of a bare array
+ cast — DI then treats it as a single value cleanly, no `as never`. Update api-aco to register
`{ list: permissions }`.

Migrate @webiny/api-headless-cms/testing (createCmsTestHandler + re-exports) onto @webiny/api-testing;
delete its 4 local mock/decorator copies. High-leverage: every package using createCmsTestHandler
now gets the shared primitives transitively. Verified via api-aco graphql + context handlers.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Rg3MRCToopzWSTPWqU9Lga
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Rg3MRCToopzWSTPWqU9Lga
…2026-07-08

# Conflicts:
#	packages/api-core/src/index.ts
#	packages/api-event-handler-core/src/WcpLicenseInitializer.ts
api-scheduler: delete dead registerSchedulerExtension + createScheduler
(superseded by SchedulerFeature + SchedulerModelContextualSchema).
api-scheduler-aws/-server: convert the SchedulerService transport
ContextPlugins to RequestContextInitializer; wire aws consumer directly.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Rg3MRCToopzWSTPWqU9Lga
api-file-manager-server: aggregate ContextPlugin -> FileManagerServerFeature.
api-headless-cms-es-tasks: task-registration ContextPlugin ->
HeadlessCmsEsTasksFeature; migrate test harness; drop from dead api-
background-tasks-os bundle.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Rg3MRCToopzWSTPWqU9Lga
…2026-07-09

# Conflicts:
#	packages/api-background-tasks-os/package.json
#	packages/api-background-tasks-os/src/index.ts
#	packages/api-background-tasks-os/tsconfig.build.json
#	packages/api-background-tasks-os/tsconfig.json
#	packages/api-headless-cms-es-tasks/__tests__/context/useHandler.ts
#	yarn.lock
DbFeature no longer writes ctx.db (drops the EMPTY_SCHEMA contextual schema
that existed only for that). Readers migrated to DI: db.driver.getClient()
-> resolve(DynamoDBClient).client; db.store -> resolve(DbInstance).store.
Dropped the .db type from api-websockets + api-audit-logs contexts. The
legacy dbPlugins default (test storage-preset glue) stays, documented
@deprecated, until the setupFile presets move to their own drivers.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Rg3MRCToopzWSTPWqU9Lga
The legacy dbPlugins (test storage-preset glue) is now a named export from
@webiny/handler-db/testing instead of the shipped default export; the two
DDB/DDB-ES setupFile.js presets import it from there. Keeps test scaffolding
out of the package's production entry. DbContext inlined into testing.ts;
types.ts removed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Rg3MRCToopzWSTPWqU9Lga
…to DI

New HcmsBulkActionsFeature (config + 6 actions + tasks + a per-request
RequestContextInitializer for the model-derived CmsGraphQLSchemaFactory).
Eliminated the BulkActionContext service-locator bag: bulk-action tasks now
inject concrete use-cases (TasksCrud/ListTasksUseCase/TriggerTaskUseCase/
GetModelUseCase) instead of the request context.

HcmsTasksFeature now registers bulk-actions + delete-model directly (delete-
model crud/graphql ContextPlugins -> RequestContextInitializers, order
preserved for DeleteModelOperations/DisableModelFeature); deleted the
HcmsTasksInitializer bridge. ddb-es orphan re-exports the feature.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Rg3MRCToopzWSTPWqU9Lga
FileManagerS3Feature now registers the S3 file-operation features + the static
S3 GraphQL schema (CoreGraphQLSchemaFactory) natively, dropping the legacy
ContextPlugin + createFileManagerS3 array. WCP-gated threat scanning moved to a
RequestContextInitializer so the canUseFileManagerThreatDetection() gate runs
after the per-request license refresh (register-time reads NullLicense and
would silently skip it).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Rg3MRCToopzWSTPWqU9Lga
…-2026-07-09

# Conflicts:
#	packages/cli-core/files/references.json
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Rg3MRCToopzWSTPWqU9Lga
WebsiteBuilderFeature now registers all page/redirect/nextjs/nuxt features, the
static WB GraphQL (CoreGraphQLSchemaFactory), and a RequestContextInitializer
for per-request Page/Redirect model resolution — dropping the legacy
createWebsiteBuilder/createContext ContextPlugins + the bridge. setupWebsite-
BuilderModels kept for the REST route (all-transport, pre-routing) path.
Migrated the wb / wb-scheduler / wb-workflows test harnesses.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Rg3MRCToopzWSTPWqU9Lga
createAuditLogs() + createAuditLogsContext() (the two legacy ContextPlugins)
were never called — the live wiring is AuditLogsFeature (registerApiRequestStack).
Deleted both, completing the #40 ContextPlugin removal for production packages.
The AuditLogsContext service-locator bag + handler DI cleanup is a separate
follow-up (facade dissection), not a ContextPlugin.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Rg3MRCToopzWSTPWqU9Lga
adrians5j and others added 9 commits July 13, 2026 14:49
…-2026-07-09

# Conflicts:
#	packages/api-core-testing/src/tenancySecurity.ts
#	packages/testing/src/context/tenancySecurity.ts
…less-cms-testing

Moves the CMS integration test handler off the @webiny/api-headless-cms/testing
subpath into a dedicated sibling package (keeps test scaffolding out of the
shipped api-headless-cms bundle). Repointed all 9 consumer packages + added the
devDep; dropped the subpath. Deps api-headless-cms + api-core-testing.

Note: references.json not regenerated (webiny CLI generator needs a full local
build; it's a non-CI-checked cache that self-corrects on a clean sync-dependencies).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Rg3MRCToopzWSTPWqU9Lga
…-2026-07-09

# Conflicts:
#	packages/api-headless-cms-es-tasks/tsconfig.build.json
#	packages/api-headless-cms-es-tasks/tsconfig.json
#	packages/cli-core/files/references.json
Merge left conflict markers in api-headless-cms-es-tasks tsconfig.json +
tsconfig.build.json (HEAD side carried phantom ../api-headless-cms-testing +
../handler-db refs from a stale on-disk dir; next side added ../db-dynamodb).
Kept the two real deps (db-dynamodb + api-headless-cms-testing), dropped the
phantom handler-db, and regenerated via generateTsConfigsInPackages.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Rg3MRCToopzWSTPWqU9Lga
…TestHandler

Deletes the legacy @webiny/testing harness (useContextHandler/useGraphQLHandler
+ TenancyAndSecurityFeature + the createHandlerCore bridge machinery), the last
duplicate CMS test harness. Its 3 real consumers are migrated onto the
DI-native createCmsTestHandler (from @webiny/api-headless-cms-testing):

- api-audit-logs, api-elasticsearch-tasks, api-workflows: useHandler/handler.ts
  now build on createCmsTestHandler.getContext / createQuery / createMutation.
  Auth is via TestAuthenticator (identity.teams flows through); BackgroundTasks +
  mock TaskService are registered per-consumer in the features hook (createCmsTest-
  Handler doesn't register them globally, matching the existing PR-B consumers).
- Constant-only importers (FULL_ACCESS_TEAM_ID/UNKNOWN_TEAM_ID) repointed to
  @webiny/api-core-testing.

createCmsTestHandler gains useGraphQLHandler's conveniences: createQuery /
createMutation / introspect + identity/tenant in the return.

api-workflows team-review fix: the DI-native auth layer normalizes a team-less
identity to  (was undefined under TenancyAndSecurityFeature), so the
GetUserTeams test mock now guards on length; the mock decorator is applied via a
RequestContextInitializer ordered after WorkflowsInitializer (which registers
GetUserTeamsUseCase post-auth). Also drops a ContextPlugin usage (toward #40).

BUILD_EXCLUDED_PACKAGES emptied (the excluded @webiny/testing is gone; the new
-testing packages are normal buildable refs, per PR-B).

Verified: api-workflows 53, api-headless-cms-workflows 5, api-audit-logs 11,
api-headless-cms-tasks 2 (no regression). es-tasks needs OpenSearch (env down
locally; the same 'No registration for OpenSearch/Client' appears on the
untouched PR-B ddb-es package) — defers to CI.

Note: references.json not regenerated (webiny CLI generator needs a full local
build; non-CI-checked cache, self-corrects on a clean sync-dependencies).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Rg3MRCToopzWSTPWqU9Lga
…-2026-07-09

# Conflicts:
#	packages/api-aco/package.json
#	packages/api-aco/tsconfig.build.json
#	packages/api-aco/tsconfig.json
#	packages/api-headless-cms-testing/src/createCmsTestHandler.ts
#	packages/api-headless-cms/src/testing/index.ts
#	packages/cli-core/files/references.json
#	packages/testing/package.json
#	packages/testing/src/context/tenancySecurity.ts
#	packages/testing/tsconfig.build.json
#	packages/testing/tsconfig.json
#	yarn.lock
…-2026-07-09

# Conflicts:
#	packages/api-headless-cms-scheduler/tsconfig.json
#	packages/api-headless-cms-workflows/package.json
#	packages/api-headless-cms-workflows/tsconfig.build.json
#	packages/api-headless-cms-workflows/tsconfig.json
#	packages/api-website-builder-workflows/tsconfig.json
Converts api-headless-cms test ContextPlugins to DI:
- pure container.register/registerFactory ContextPlugins -> plain
  container => {} function plugins (the test helpers call function plugins
  directly, pre-auth); lifecycle-hook mocks, model/group providers.
- benchmark.test + httpOptions -> a RequestContextInitializer (post-auth
  timing: benchmark resolves BenchmarkAbstraction which HeadlessCmsFeature
  registers after the plugins loop; httpOptions must not run on OPTIONS).
- Deleted two dead, unused benchmark test helpers.

api-headless-cms tests are now ContextPlugin-free (only comments remain).
Part of #40 (toward deleting the legacy bridge, #39).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Rg3MRCToopzWSTPWqU9Lga
@adrians5j

Copy link
Copy Markdown
Member Author

/vitest

@github-actions

github-actions Bot commented Jul 15, 2026

Copy link
Copy Markdown

Vitest tests have been initiated (for more information, click here). ✨

Group Status
No storage ✅ 53/53 passed
DDB ✅ 17/17 passed
DDB+OS ✅ 20/20 passed
SQL ✅ 10/10 passed
PGlite ✅ 10/10 passed

adrians5j and others added 5 commits July 15, 2026 11:56
…workflows harnesses

The retired useContextHandler/createHandlerCore registered BackgroundTasksFeature
+ a mock TaskService globally, so the PR-C migration mirrored that defensively.
It is not needed:
- AcoFeature's FLP handlers inject TaskService as OPTIONAL ([TaskService, { optional
  true }], guarded by `if (this.tasks)`) — absent = task triggering is skipped;
- AuditLogsFeature and WorkflowsFeature never resolve tasks at all.

Removed the BackgroundTasksFeature + mock registrations and the now-orphaned
@webiny/background-tasks devDep from both. (es-tasks keeps it — its rawHandle
resolves TasksCrud directly.) audit-logs 11 + api-workflows 53 green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Rg3MRCToopzWSTPWqU9Lga
@adrians5j

Copy link
Copy Markdown
Member Author

/vitest

@github-actions

github-actions Bot commented Jul 15, 2026

Copy link
Copy Markdown

Vitest tests have been initiated (for more information, click here). ✨

Group Status
No storage ✅ 53/53 passed
DDB ✅ 17/17 passed
DDB+OS ✅ 20/20 passed
SQL ✅ 10/10 passed
PGlite ❌ 9/10 passed
❌ Failed packages

PGlite

  • api-websockets

@adrians5j
adrians5j changed the base branch from adrian/self-hosted-18-2026-07-09 to next July 15, 2026 13:47
@adrians5j
adrians5j merged commit 158fae9 into next Jul 15, 2026
32 checks passed
@adrians5j adrians5j added the context-plugin-removal #40: remove legacy ContextPlugin usage (→ DI) label Jul 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

context-plugin-removal #40: remove legacy ContextPlugin usage (→ DI)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant