Loading
Pre-release audit since alpha12: a checkout left open by a throw, an outcome named wrong, a query on every node left, an inert control with no role, dead code, stale docs and misfiled translations
Fixes for the pre-release audit of 1.x since 1.0.0-alpha12. See [#3615875] for the findings.
Correctness
PaymentInteraction::pay()closes the checkout on a throw. Every deliberate exit after the opening event already announced the closing; a raise fromresolve(),preview()or the payment creation did not, leaving a subscriber holding its subject for a checkout that will never charge. The closing is idempotent, so an exit that already closed does not announce a second one.- The payment timeout description named the
timeoutoutcome. It isexpired. Fixed in the setting and infr.po.
Performance
RelativeDeadline::forget()returns early unless the anchor isnode. The executor forgets deadline state on every token leaving a node that carries any timeout, and only that anchor ever records any, so the ordinary wait was paying a variable lookup on the way out that could only find nothing.- The click to pay looks the reusable pending payment up once instead of three times:
pendingAsking()returns what survived rather than nothing.PinnedPayment::existsInAnyState()answers "already paid" in one query instead of two.
Accessibility
- The inert payment control takes
role="link", without whicharia-disabledis dropped and a screen-reader user is told nothing about why it will not act. - The refusal id moved from the list to a wrapper, so the sentence framing the reasons is read out with the control that points at them.
- orchestra_payment ships a component stylesheet, so the inert control no longer looks identical to the live one under a theme that says nothing about
is-disabled. The disabled state is never carried by color alone: the reasons are listed above it in words.
Dead code
DeadlineCalculator::resolveDuration()and itsWorkflowEnginedelegate are gone (no callers anywhere; the provider refactor had copied the body intoRelativeDeadline).DeadlineCalculatorno longer takesVariableResolver.TimeoutSweeperno longer takes the config factory it stopped reading.isVariableName()moved toDeadlineProviderBaseinstead of living twice.
Documentation and translations
PaymentOrchestraHooksdescribed a two-pin design that does not exist; rewritten to matchdocs/payment.mdand the code.docs/concepts.mdanddocs/roadmap.mddescribe the deadline provider and the checkout events;docs/metrics.mdregenerated.- The two
payment_lapsedstrings moved to orchestra_payment's ownfr.po; 80 orphaned msgids removed across 17 files; 36 previously untranslated strings added. drupal/kessaiis pinned to^1.0@alpharather than1.x-dev.
Tests
CheckoutOrderingTest::testThrowOnTheWayToTheGatewayClosesTheCheckoutandInstanceTimeoutAnchorTest::testLeavingParkAnchoredNodeReadsNoAnchorare new; both were run against the unfixed code and seen to fail first. The anchor one compares the query argument with the LIKE escaping stripped, because an entity query escapes every underscore in a variable name and a plain comparison passes for the wrong reason.CheckoutRefusalTestasserts the control's role and the new refusal structure.
Ran locally against MySQL: the payment kernel suite (10 classes) and the engine timeout classes. phpcs (drupal.org CI ruleset, severity 1), phpstan (phpstan-drupal level 1, only the new.static findings CI ignores), stylelint and cspell are clean.