Skip to content

refactor(handler-graphql): remove ContextPlugin from tests#5407

Merged
adrians5j merged 49 commits into
nextfrom
adrian/self-hosted-20-2026-07-09
Jul 16, 2026
Merged

refactor(handler-graphql): remove ContextPlugin from tests#5407
adrians5j merged 49 commits into
nextfrom
adrian/self-hosted-20-2026-07-09

Conversation

@adrians5j

@adrians5j adrians5j commented Jul 15, 2026

Copy link
Copy Markdown
Member

What changed

Continues #40 (grep ContextPlugin → zero): handler-graphql tests are now ContextPlugin-free.

  • Pure context.container.register ContextPlugins (booksSchemaPlugin, decoratorsPlugin) → plain container => {} function plugins.
  • booksCrudPlugin (sets ctx.getBooks, read by the Query.books resolver) → a RequestContextInitializer that augments the context post-auth.
  • useGqlHandler now calls function plugins directly; it still bridges the remaining legacy graphql-schema plugins (bridge removal is Entity attribute - check initial deletion #39).
  • Deleted disableIntrospectionQuery.test.ts — fully it.skip'd, relied on the legacy context.reply.hijack pattern that the DI-native handler doesn't support.

Left intact on purpose: the legacy graphql-schema path (createGraphQLSchemaPlugin) — it's still used by prod schemas (api-file-manager-s3, api-record-locking), so removing it belongs to #39, not this ContextPlugin sweep.

Verification

yarn test packages/handler-graphql → 45 passed. adio clean, lint clean.

Stacked on #5406 (CMS cluster) → #5403 (PR-C). Base retargets to next as the stack merges.

Squash Merge Commit

refactor(handler-graphql): remove ContextPlugin from tests (#5407)

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 16 commits July 13, 2026 10:50
… to DI

createElasticsearchBackgroundTasks() (a task-registration ContextPlugin) →
ElasticsearchTasksFeature. Migrated the es-tasks + ddb-es test harnesses and
the dead api-background-tasks-os bundle (now re-exports the feature).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Rg3MRCToopzWSTPWqU9Lga
createTenancyAndSecurity (4 ContextPlugins) was unused — TenancyAndSecurity-
Feature (a DI RequestContextInitializer) is the live test-harness setup.
Reduced tenancySecurity.ts to the still-used constants (defaultIdentity,
FULL_ACCESS_*/UNKNOWN_TEAM_ID). No production ContextPlugin remains; only the
class definition + bridge + test-file usages are left toward grep-zero.

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

defaultIdentity + FULL_ACCESS_*/UNKNOWN_TEAM_ID now live in the base
@webiny/api-testing package; @webiny/testing re-exports them (zero consumer
churn — the 10 barrel importers + internals keep working).

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

The base test-utils package mocks api-core abstractions (Authenticator/
Authorizer/TenantContext/IdentityContext), so the name should say so. First
step of standardizing on sibling -testing packages. Repointed all ~14 importers;
@webiny/testing re-exports unchanged.

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-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
Converts handler-graphql test ContextPlugins to DI:
- pure container.register ContextPlugins (booksSchemaPlugin, decoratorsPlugin)
  -> plain container => {} function plugins;
- booksCrudPlugin (set ctx.getBooks, read by the Query.books resolver) -> a
  RequestContextInitializer that augments the context post-auth;
- useGqlHandler now calls function plugins directly, still bridging the
  remaining legacy graphql-schema plugins (bridge removal is #39);
- deleted disableIntrospectionQuery.test.ts (fully it.skip'd; relied on the
  legacy context.reply.hijack pattern unavailable in the DI handler).

The legacy graphql-schema path (createGraphQLSchemaPlugin) is left intact — it
is still used by prod schemas (api-file-manager-s3, api-record-locking) and its
removal belongs to #39.

handler-graphql tests are now ContextPlugin-free. 45 tests green.

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

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Rg3MRCToopzWSTPWqU9Lga
@adrians5j
adrians5j changed the base branch from adrian/self-hosted-19-2026-07-09 to next July 15, 2026 18:24
…-2026-07-09

# Conflicts:
#	packages/api-audit-logs/__tests__/helpers/useHandler.ts
#	packages/api-audit-logs/package.json
#	packages/api-audit-logs/tsconfig.build.json
#	packages/api-audit-logs/tsconfig.json
#	packages/api-workflows/__tests__/__helpers/handler.ts
#	packages/api-workflows/package.json
#	packages/api-workflows/tsconfig.build.json
#	packages/api-workflows/tsconfig.json
@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 ❌ 0/3 passed
DDB+OS ✅ 20/20 passed
SQL ✅ 10/10 passed
PGlite ❌ 9/10 passed
❌ Failed packages

DDB

  • api-core

PGlite

  • api-websockets

@adrians5j
adrians5j merged commit 44df61b into next Jul 16, 2026
19 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