This repository has phpunit in require-dev but no test infrastructure, so
every feature is currently verified from a consuming application. Two features
merged (or in review) as #12 and #13 made that gap concrete: their most fragile
parts are pure bundle logic, and the tests that cover them today live in another
repository.
What a bundle-local suite should cover first, in rough priority order:
External worker (#12)
ExternalWorkerRunner decisions — success reports complete, a throwing
handler reports fail with the exception message and no explicit retries
(the engine keeps its policy), an unhandled topic reports unacquire and is
not counted as processed, and held job ids are released on shutdown.
ExternalWorkerHandlerRegistry — topic-to-handler mapping, and a topic
claimed by two handlers failing loudly at resolution instead of first-match-wins.
ExternalWorkerJob::fromApi() — flattening {name,type,value} variables into
a name => value map, missing/empty variables, unknown fields.
ExternalWorkerOutcome factories and the payload each one produces
(especially: only what the caller decided is sent).
- The acquire payload shape:
lockDuration passed through as an ISO-8601
duration string, numberOfTasks honouring the batch size.
Event registry (#13)
createEventDeployment() builds the request the engine actually wants —
metadata on the query string as deploymentName/category/tenantId, not
as multipart parts, file part named file with its extension preserved. Most
fragile piece of that feature; regressing it back to the DMN shape is silent.
- The
.event/.channel extension gate rejecting .bpmn20.xml, .dmn and
especially .bar/.zip (the plausible-but-wrong case).
FlowEventInstance/create.input.json really requiring one event and one
channel reference, rejecting an array/scalar eventPayload, and the REST
operation and flowable:events:instances:create rejecting identically — one
schema, two consumers.
Cross-cutting
- Provider query mapping:
listQuery() whitelists, per-resource defaultSort,
and relationFilters() turning both an IRI and a bare id into the engine's id
field.
- Path prefixes staying
/service (process engine) vs. /dmn-api vs.
/external-job-api vs. /event-registry-api/… — the
base_url-without-/service gotcha applies per engine.
- Operation names resolving to their input schema. A concrete regression this
would have caught: flow_external_worker_job_bpmn_error resolved to
FlowExternalWorkerJobBpmn/error.input.json (the resolver splits at the last
underscore) and the operation shipped without a documented request body.
Most of this needs no engine: a MockHttpClient for the client, plain unit tests
for the worker core, and a Symfony kernel test for the DI wiring
(registerForAutoconfiguration of ExternalWorkerHandlerInterface, the tagged
registry, the input-schema resolver chain). Only an end-to-end event-correlation
test would want a real flowable-rest service.
🤖 Generated with Claude Code
This repository has
phpunitinrequire-devbut no test infrastructure, soevery feature is currently verified from a consuming application. Two features
merged (or in review) as #12 and #13 made that gap concrete: their most fragile
parts are pure bundle logic, and the tests that cover them today live in another
repository.
What a bundle-local suite should cover first, in rough priority order:
External worker (#12)
ExternalWorkerRunnerdecisions — success reportscomplete, a throwinghandler reports
failwith the exception message and no explicitretries(the engine keeps its policy), an unhandled topic reports
unacquireand isnot counted as processed, and held job ids are released on shutdown.
ExternalWorkerHandlerRegistry— topic-to-handler mapping, and a topicclaimed by two handlers failing loudly at resolution instead of first-match-wins.
ExternalWorkerJob::fromApi()— flattening{name,type,value}variables intoa
name => valuemap, missing/empty variables, unknown fields.ExternalWorkerOutcomefactories and the payload each one produces(especially: only what the caller decided is sent).
lockDurationpassed through as an ISO-8601duration string,
numberOfTaskshonouring the batch size.Event registry (#13)
createEventDeployment()builds the request the engine actually wants —metadata on the query string as
deploymentName/category/tenantId, notas multipart parts, file part named
filewith its extension preserved. Mostfragile piece of that feature; regressing it back to the DMN shape is silent.
.event/.channelextension gate rejecting.bpmn20.xml,.dmnandespecially
.bar/.zip(the plausible-but-wrong case).FlowEventInstance/create.input.jsonreally requiring one event and onechannel reference, rejecting an array/scalar
eventPayload, and the RESToperation and
flowable:events:instances:createrejecting identically — oneschema, two consumers.
Cross-cutting
listQuery()whitelists, per-resourcedefaultSort,and
relationFilters()turning both an IRI and a bare id into the engine's idfield.
/service(process engine) vs./dmn-apivs./external-job-apivs./event-registry-api/…— thebase_url-without-/servicegotcha applies per engine.would have caught:
flow_external_worker_job_bpmn_errorresolved toFlowExternalWorkerJobBpmn/error.input.json(the resolver splits at the lastunderscore) and the operation shipped without a documented request body.
Most of this needs no engine: a
MockHttpClientfor the client, plain unit testsfor the worker core, and a Symfony kernel test for the DI wiring
(
registerForAutoconfigurationofExternalWorkerHandlerInterface, the taggedregistry, the input-schema resolver chain). Only an end-to-end event-correlation
test would want a real
flowable-restservice.🤖 Generated with Claude Code