camunda / camunda/api-test-generator

Positive suite doesn't enumerate enum values on optional sort/filter fields — server-side bugs at valid enum values invisible

Open
#108 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug enhancement OCA
Dominant language
TypeScript
Stars
0
Forks
3
Avg merge
13h 41m
Merged PRs (30d)
23

Description

Summary

Positive-path tests don't enumerate enum values for optional sort/filter body fields (and similar enum-typed query/body parameters). Server-side semantic bugs that fire on a valid enum value but not others slip through both suites today.

Canonical example: camunda/camunda#50945POST /process-definitions/statistics/process-instances returns 500 when the request body contains:

{ "sort": [{ "field": "processDefinitionId", "order": "DESC" }] }

processDefinitionId is one of three documented valid enum values for ProcessDefinitionInstanceStatisticsQuerySortRequest.field:

{
  "field": {
    "type": "string",
    "enum": [
      "processDefinitionId",
      "activeInstancesWithIncidentCount",
      "activeInstancesWithoutIncidentCount"
    ]
  }
}

The other two values return 200; only processDefinitionId 500s. Per-enum-value semantic bugs of this shape are exactly what a generated suite should catch.

Why neither current suite catches this

Positive suite (path-analyser/dist/generated-tests/getProcessDefinitionInstanceStatistics.feature.spec.ts)

One test, feature-1 - base (1), sends an empty body {} and expects 200. Optional fields are never populated; enum values are never explored.

Negative suite (request-validation/generated/processdefinitions-validation-api-tests.spec.ts)

Has an Enum violation sort.0.field (#1) test that sends 'processDefinitionId_INVALID' to confirm the server returns 400. By design the negative suite covers invalid requests — a request with a valid enum value that triggers a 500 is out of scope.

So there's a coverage gap between "empty body → 200" (positive) and "malformed body → 400" (negative): valid bodies that exercise specific enum values.

Proposed fix: enum-value variant generation

Extend the variant generator to enumerate enum values on optional body/query/path fields, producing one test per enum value per ordering-relevant axis. Concretely, for the canonical example:

test.each([
  'processDefinitionId',
  'activeInstancesWithIncidentCount',
  'activeInstancesWithoutIncidentCount',
])('getProcessDefinitionInstanceStatistics - sort by %s returns 200', async (field) => {
  // POST with { sort: [{ field, order: 'ASC' }] }, assert 200, validate response shape
});

The path-analyser already emits .variant.spec.ts files for oneOf discriminator variants (see e.g. getProcessDefinitionInstanceVersionStatistics.variant.spec.ts). This is structurally identical: enumerate finite alternatives at one axis, hold the rest minimal.

Scope and budget
  • Axes to vary: sort[].field, filter.* enum fields, top-level enum body/query parameters, and order (ASC/DESC) when paired with sort.
  • Combinations: vary one axis at a time (the natural extension of "base" — not a cartesian product). For sort, that's N enum values × 2 orders, scoped per endpoint.
  • Budget: cap variants per endpoint (suggest 12) with deterministic enumeration ordered by the spec's enum declaration. Fallback to "base only" if the budget would be exceeded.
  • Determinism: enumeration follows OpenAPI declaration order so output is byte-stable under the existing TEST_SEED=snapshot-baseline discipline.
Files likely touched
  • path-analyser/src/scenarioGenerator.ts — add an enum-axis variant strategy alongside the existing oneOf-variant strategy.
  • path-analyser/src/codegen/emitter.ts — emit .variant.spec.ts with test.each shape.
  • tests/fixtures/planner/ — Layer-2 fixture: hand-built minimal OperationGraph with an enum-typed sort field; assert the planner emits one variant per enum value.
  • tests/regression/bundled-spec-invariants.test.ts — Layer-3 invariant: every endpoint with an optional sort field has at least one variant per enum value (or is in a documented exclusion list).

Acceptance criteria

  1. Layer-1 fixturepath-analyser/src/scenarioGenerator.ts emits one variant per enum value when an optional body field has type: string + enum: [...].
  2. Layer-2 fixture — minimal OperationGraph with sort-enum and filter-enum fields produces the expected variant fan-out.
  3. Layer-3 invariantgetProcessDefinitionInstanceStatistics (and structurally similar endpoints — searchProcessInstances, searchUserTasks, etc.) emit a .variant.spec.ts file with one test.each row per declared sort field.
  4. Regression artefact — a manually-run variant suite on a snapshot build (or local Camunda) reproduces the 500 for processDefinitionId from #50945, demonstrating the test class would have caught the bug.
  5. Budget honoured — no endpoint emits more than the configured cap; overflow falls back to feature-N base test plus a documented partial-variant exclusion noted in path-analyser/domain-semantics.json or equivalent.
  6. Determinism preservedTEST_SEED=snapshot-baseline npm run testsuite:generate is byte-stable across runs (existing CI guard).

Out of scope

  • Cartesian-product exploration across multiple enum axes. Single-axis variants only; multi-axis combinations are a separate (much larger) issue.
  • Numeric-range or string-pattern variant exploration (separate test class — boundary/property-based testing).
  • Negative-suite changes — request-validation already covers enum violations.

References

  • Bug surfaced this gap: camunda/camunda#50945
  • Existing variant generation pattern: path-analyser/dist/generated-tests/*.variant.spec.ts
  • Layered test strategy this would extend: CONTRIBUTING.md

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with path-analyser/src/scenarioGenerator.ts and the existing oneOf variant strategy, then inspect path-analyser/src/codegen/emitter.ts and the generated .variant.spec.ts examples. Use the planner fixtures and bundled-spec invariants tests to define enum-axis fan-out, budget, and determinism. Done means the listed acceptance layers pass, including TEST_SEED=snapshot-baseline npm run testsuite:generate and the regression variant for getProcessDefinitionInstanceStatistics.

Written by the indexing model from the issue text.

Assessment

Tech stack
openapi, typescript
Domain
testing-qa, tooling
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.