Skip to content

test: add a gateway-schema contract test for the zod resource schemas#3449

Open
lxbme wants to merge 1 commit into
apache:masterfrom
lxbme:test/gateway-contract
Open

test: add a gateway-schema contract test for the zod resource schemas#3449
lxbme wants to merge 1 commit into
apache:masterfrom
lxbme:test/gateway-contract

Conversation

@lxbme

@lxbme lxbme commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Please answer these questions before submitting a pull request, or your PR will get closed.

Why submit this pull request?

  • Bugfix

What changes will this PR take into?

This implements the "cheapest structural guard" proposed in the "hand-written zod transcription" item of the frontend review in #3417: a CI test asserting the dashboard's zod resource schemas are looser or equal to APISIX's own schema, so the recurring "form rejects a config the gateway accepts" class (#3146/#3147/#3362/#3376/#3395) can't silently reappear.

How it works

  • APISIX exposes its own per-resource JSON schema at GET /apisix/admin/schema/<resource>. scripts/refresh-gateway-schema.mjs (run via pnpm refresh:gateway-schema) snapshots the 11 resources that expose one — route, service, upstream, consumer, ssl, global_rule, plugin_config, consumer_group, stream_route, proto, credential — into src/types/schema/apisix/__fixtures__/gateway/. (secret is omitted: it is schema'd per-manager and the bare endpoint returns 400.) The snapshot is committed and refreshed on APISIX version bumps; _meta.json records the version (currently 3.17.0).
  • src/types/schema/apisix/gateway-contract.test.ts runs in the unit suite (no gateway needed). For each top-level property the gateway defines it asserts, against the merged dashboard schema: (a) the zod schema knows the field (else the form's resolver silently strips it on submit), and (b) the zod field accepts every value the gateway's enum allows.
  • Fields the dashboard does not model live in an ALLOWLIST with a reason — intentional non-support, or a KNOWN GAP flagged for follow-up; never a silent omission. A stale allowlist entry (a field zod now covers) also fails the test, forcing cleanup.

What it already caught

Populating the allowlist surfaced one genuine "form too strict" gap, plus several intentional differences:

  • KNOWN GAP — upstream.scheme omits "kafka": the gateway accepts a kafka-scheme upstream; the dashboard's zod enum does not, so it cannot be created via the form. Allowlisted with a note and flagged for a follow-up fix (which also needs UI support). This is exactly the class the test exists to surface.
  • Intentional differences (allowlisted with reasons): consumer.id / credential.name (keyed by username / id in the dashboard), proto.{name,labels,desc} (content-only form), consumer_group.name (no separate name field), upstream.{create_time,update_time} (server-managed, not modelled), and stream_route.name (the base read schema omits it, but it is accepted on the write path via StreamRoutePostSchema, per fix: unify stream-route submit pipelines, drop phantom plugin_config_id #3437).

Scope (kept to the "cheapest guard"): top-level properties only — nested objects and plugin configs (which the dashboard passes through, not transcribes) are out of scope, as is required-ness (the full read schema requires server-managed id/timestamps the write path omits, so comparing it produces only false positives). The longer-term JSON-Schema-driven form work (#3347/#3311/#2986) is unaffected.

Related issues

Part of #3417

Checklist:

  • Did you explain what problem does this PR solve? Or what new features have been added?
  • Have you added corresponding test cases?
  • Have you modified the corresponding document?
  • Is this PR backward compatible? If it is not backward compatible, please discuss on the mailing list first

This is a test + fixtures + a dev script only — no application/runtime code changes — so there is nothing for the e2e suite to exercise. Verified with tsc, ESLint, and the unit suite (pnpm test, which CI now runs). The test's sensitivity was confirmed by adding a fake property to a fixture (goes red naming the field) and by the stale-allowlist check.

@lxbme

lxbme commented Jul 27, 2026

Copy link
Copy Markdown
Contributor Author

Follow-up: the upstream scheme="kafka" gap this test flagged is fixed in #3450 (zod enum + scheme dropdown). Once both land, the temporary ENUM_ALLOWLIST entry here becomes obsolete and should be dropped on rebase.

@lxbme
lxbme marked this pull request as ready for review July 27, 2026 04:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants