Skip to content

test/uts: push activation UTS suite (75 derived tests) + push deviations - #2283

Draft
paddybyers wants to merge 1 commit into
mainfrom
feat/uts-push
Draft

test/uts: push activation UTS suite (75 derived tests) + push deviations#2283
paddybyers wants to merge 1 commit into
mainfrom
feat/uts-push

Conversation

@paddybyers

Copy link
Copy Markdown
Member

Derives the full push activation UTS suite from the spec PR ably/specification#513 (which adds both the push spec enhancements — Push#updateToken, APNs token-variant slots, the unified PATCH registration sync, the RSH6a raw-value clarification — and the portable test specs for the previously-untested activation half of RSH: RSH2, RSH3, RSH4–5, RSH6, RSH8, and the push types).

What's here

  • test/uts/rest/unit/push/push_helpers.ts — shared harness mapping the UTS push-platform constructs onto ably-js's seam: MockPushStorage (AsyncStorage-shaped, with dump/seed/fault flags/onOperation), deferred(), mockRegistrationServer(), and pushClient()/activateInto() building per-client ReactNativePush plugins (with the react-native module fake).
  • Unit — 62 tests, 7 files: the full RSH3 state-machine transition matrix (both registrar branches, RSH3d2c1 classification, rollbacks), LocalDevice attributes + clientId lifecycle, persistence/rehydration incl. the RSH8a1 corruption discard, RSH4/RSH5 queue semantics (incl. the spec's own worked example), updateToken (existing file rewritten onto the shared harness, aligned to the updated UTS test ids, extended with the RSH8l2 token-variant tests), device auth incl. the RSH1b/RSH1c own-device clauses, and the PCD/PCP/PCS types.
  • Integration — 7 tests: real-sandbox round-trips using ablyChannel-seeded storage (riding RSH3a2c, so no FCM/APNs credentials needed), incl. end-to-end delivery of an admin publish and the RSH6a device-auth server-acceptance check.
  • Proxy — 6 tests: fault injection on the registration endpoints via uts-proxy — the RSH3d2c1 classifications (proven client-side by a direct admin client observing the registration survive an intercepted DELETE), rollback/retry flows, and RSH4 queueing against a delayed registration.

Every test carries its // UTS: <test-id> tag.

Deviations

Tests assert spec behaviour; where ably-js is non-conformant they are skipped or assertion-guarded via the established RUN_DEVIATIONS convention, with 13 new entries in test/uts/deviations.md documenting the observed behaviour and pointing at the exact code. Highlights (each a candidate fix PR):

  • No re-activation registration sync (RSH3a2a/RSH3f1) — activate() over registered storage resolves without contacting the server; the RSH3a2a1 61002 clientId check is dead code.
  • Device auth — a bearer Authorization header that replaces client auth (no X-Ably-DeviceToken; no RSH6b X-Ably-DeviceSecret path; and a registerCallback result without an identity token crashes the machine, leaving activate() unsettled). Live probing showed the bearer is not accepted as device auth on /push/channelSubscriptions — it only works on the registration endpoints because the identity token is itself an Ably token.
  • Concurrent activate()/deactivate() rejected ("already in progress") instead of coalesced; no deregistration from NotActivated (RSH3a1c); RSH3d2c1 classification unimplemented; deviceSecret entropy below RSH3a2b's requirement; the RSH8d/e/f clientId lifecycle unwired (shares a root cause with REST auth.clientId not derived from token details (RSA7b, RSA12) #2192); corrupt persisted state neither discarded nor survivable (RSH3h/RSH8a1) and partial persisted state not loaded (RSH8a); AfterRegistrationSyncFailed not persisted; APNs token variants unimplemented (pending the spec extension); updatedCallback missing (only the deprecated updateFailedCallback); and push type-surface differences (PCP2/PCP4/PCS5).

Also corrected: the msgpack section of deviations.md (the limitation is this repo's JSON-level mock port, not the UTS contract — the UTS has msgpack unit specs), and a new server-issue entry for the ablyChannel-recipient PATCH bug fixed by ably/realtime#8591 (two tests skipped unconditionally pending its sandbox deploy, then to be unskipped).

Results

  • Unit: push tier 118 passing / 18 pending; full UTS unit suite 1428 passing / 73 pending (npm run test:uts:unit).
  • Integration: 6 passing / 1 pending; proxy: 3 passing / 3 pending (network + uts-proxy required).
  • With RUN_DEVIATIONS=1, every skipped/guarded test fails exactly at its documented deviation point; none unexpectedly passes.

No SDK source changes in this PR — tests and deviation records only.

🤖 Generated with Claude Code

…push deviations

Derive the full push activation UTS suite from ably/specification#513
(uts/rest/unit/push, uts/rest/unit/types, uts/rest/integration,
uts/rest/integration/proxy), which specifies the previously-untested
activation half of the RSH spec (RSH2, RSH3, RSH4-5, RSH6, RSH8) and the
push types, plus the token-variants/updateToken spec extension.

- push_helpers.ts: shared harness mapping the UTS push platform constructs
  onto ably-js's seam — MockPushStorage (the AsyncStorage-shaped mock with
  dump/seed/fault flags/onOperation), deferred(), mockRegistrationServer(),
  pushClient()/activateInto() building per-client ReactNativePush plugins,
  and the react-native module fake.
- Unit (62 tests, 7 files): the full RSH3 state-machine transition matrix
  including both registrar branches and RSH3d2c1 classification; LocalDevice
  attributes and clientId lifecycle; persistence/rehydration including the
  RSH8a1 corruption discard; RSH4/RSH5 queue semantics; updateToken
  (push_update_token.test.ts rewritten onto the shared harness, aligned to
  the updated UTS test ids, extended with the RSH8l2 token-variant tests);
  device auth including the RSH1b/RSH1c own-device clauses; PCD/PCP/PCS
  types.
- Integration (7 tests): real-sandbox round-trips using ablyChannel-seeded
  storage, including end-to-end delivery of an admin publish and the RSH6a
  device-auth server-acceptance check.
- Proxy (6 tests): fault injection on the registration endpoints — the
  RSH3d2c1 classifications, rollback/retry, and RSH4 queueing against a
  delayed registration.

Tests assert spec behaviour; where ably-js is non-conformant they are
skipped (or assertion-guarded) via the established RUN_DEVIATIONS
convention, with 13 new entries in deviations.md documenting the observed
behaviour: no re-activation registration sync (RSH3a2a/RSH3f1, with the
61002 check confirmed dead code); concurrent activate/deactivate rejected
instead of coalesced; device auth via a bearer Authorization header that
replaces client auth (no X-Ably-DeviceToken, no RSH6b deviceSecret path,
and a registerCallback result without an identity token crashes the
machine); no deregistration from NotActivated (RSH3a1c); RSH3d2c1
classification unimplemented; deviceSecret entropy below RSH3a2b's
requirement; the clientId lifecycle (RSH8d/e/f) unwired; corrupt persisted
state neither discarded nor survivable (RSH3h/RSH8a1) and partial persisted
state not loaded (RSH8a); AfterRegistrationSyncFailed not persisted; APNs
token variants unimplemented (pending the spec extension); the
updatedCallback missing; and push type surface differences. Also corrects
the msgpack section: the limitation is this repo's mock (JSON-level), not
the UTS contract, and records the ablyChannel-PATCH server issue (fixed by
ably/realtime#8591; two tests skipped pending its sandbox deploy).

Unit results: 118 passing / 18 pending in the push tier; full UTS unit
suite 1428 passing / 73 pending. Integration: 6 passing / 1 pending;
proxy: 3 passing / 3 pending (network + uts-proxy required).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Aug 8, 2026

Copy link
Copy Markdown

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: b22ad739-eeb8-4b35-bd79-53fc31cb1e4e

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant