Skip to content

fix(uts/objects): align REST fixture provisioning with V2 objects API#497

Open
sacOO7 wants to merge 5 commits into
uts-liveobjectsfrom
fix/uts-liveobjects-rest-provisioning
Open

fix(uts/objects): align REST fixture provisioning with V2 objects API#497
sacOO7 wants to merge 5 commits into
uts-liveobjectsfrom
fix/uts-liveobjects-rest-provisioning

Conversation

@sacOO7

@sacOO7 sacOO7 commented Jun 26, 2026

Copy link
Copy Markdown
Collaborator

Summary

The provision_objects_via_rest REST fixture helper in uts/objects/helpers/standard_test_pool.md
described the legacy / pre-V2 objects REST shape and posted to the legacy prod-sandbox host. This
aligns it (and its only call site) with the V2 contract (per the LiveObjects OpenAPI specification,
ably-docs/static/open-specs/liveobjects.yaml, "Update LiveObjects REST API docs for V2 format",
2026-01-22) and with the canonical nonprod sandbox host every other UTS integration spec uses.

What changed

1. V2 request shape

uts/objects/helpers/standard_test_pool.md — the provision_objects_via_rest helper:

Before (pre-V2) After (V2)
Endpoint POST …/channels/{ch}/objects (plural) POST …/channels/{ch}/object (singular)
Body envelope { "messages": [ … ] } a single operation or a bare JSON array (batch) — no envelope
Operation encoding nested operation: { action: "MAP_SET", objectId, mapSet:{…} } payload-key discriminator mapSet:{…} + sibling objectId/path
Target objectId only objectId or path
Extras optional idempotency id; string/bytes may carry encoding

It now documents each operation shape (mapSet, mapRemove, mapCreate, counterInc, counterCreate),
the { string | number | boolean | bytes | objectId } primitive values, and mapCreate.semantics as the
integer 0 (LWW) with { data: … }-wrapped entries.

uts/objects/integration/objects_lifecycle_test.md — the only caller (RTPO15,
rest-provisioned-data-sync-0) updated to the V2 operation shape, so the spec stays internally consistent:

-  {
-    operation: {
-      action: "MAP_SET",
-      objectId: "root",
-      mapSet: { key: "provisioned", value: { string: "from_rest" } }
-    }
-  }
+  {
+    mapSet: { key: "provisioned", value: { string: "from_rest" } },
+    objectId: "root"
+  }

2. Sandbox host

uts/objects/helpers/standard_test_pool.md — the provision_objects_via_rest POST URL:

-  POST https://sandbox-rest.ably.io/channels/{encode_uri_component(channel_name)}/object
+  POST https://sandbox.realtime.ably-nonprod.net/channels/{encode_uri_component(channel_name)}/object

sandbox-rest.ably.io was a stale leftover: the objects integration specs were migrated to the nonprod
host in e57d340e, but the pooled helper was missed — leaving it provisioning fixtures on a different
backend
than the app/key are created on, so RTPO15 could never resolve. sandbox.realtime.ably-nonprod.net
is the host the entire UTS integration corpus uses — raw HTTP (app provisioning) uses the explicit URL, and
SDK clients use endpoint: "nonprod:sandbox", which resolves to the same host. sandbox-rest.ably.io now
appears nowhere in the objects module.

Validation

Every element was checked field-by-field against the V2 OpenAPI: singular /object path, OperationRequest
= single-or-array (no messages), mapSet = {key, value: PrimitiveValue}, mapCreate.semantics integer
0, objectId/path targets, idempotency id, and the PrimitiveValue set (incl. optional encoding).
The host was cross-checked against every realtime/integration and rest/integration spec: 82 raw-HTTP
references to https://sandbox.realtime.ably-nonprod.net and 196 endpoint: "nonprod:sandbox" client
configs; sandbox-rest.ably.io is used by no other spec file.

Context

Surfaced while deriving the ably-java integration helper
(uts/.../integration/standard/liveobjects/helpers.kt in ably-java), which is built to this same V2 shape
and the same nonprod host (via restHost = ProxyManager.sandboxRealtimeHost).

3. Sandbox host on the integration clients

uts/objects/integration/objects_lifecycle_test.md (10 client blocks) and objects_sync_test.md (5) set
no host on their Realtime(...) options:

- Realtime(options: { key: api_key, useBinaryProtocol: PROTOCOL == "msgpack" })
+ Realtime(options: { key: api_key, endpoint: "nonprod:sandbox", useBinaryProtocol: PROTOCOL == "msgpack" })

Without an endpoint the SDK falls back to the production host (realtime.ably.io, REC1a), so the clients
would never reach the nonprod sandbox the "Sandbox Setup" provisions the app on — the header was
aspirational. Every other UTS integration spec configures clients with endpoint: "nonprod:sandbox"; this
adds it to match. (The proxy spec objects_faults.md already routes correctly — nonprod:sandbox target +
localhost proxy hop.)

The `provision_objects_via_rest` helper described the legacy pre-V2 REST shape
(`POST .../objects` with a `{ "messages": [ { operation: { action, ... } } ] }`
envelope), which no longer matches the LiveObjects objects REST API.

Update it to the V2 contract (per the LiveObjects OpenAPI specification):
- endpoint is singular `POST .../object`;
- the body is a single operation object, or a bare JSON array (batch) — no
  `messages` envelope;
- an operation is identified by its payload key (`mapSet`/`mapRemove`/`mapCreate`/
  `counterInc`/`counterCreate`) with an `objectId` or `path` target (and optional
  idempotency `id`); values are `{string|number|boolean|bytes|objectId}`;
- `mapCreate.semantics` is the integer 0 (LWW) with `{data:}`-wrapped entries.

Also update the only call site (RTPO15 in objects_lifecycle_test.md) to the V2
operation shape so the spec stays internally consistent.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot temporarily deployed to staging/pull/497 June 26, 2026 10:33 Inactive
The REST fixture-provisioning helper still POSTed to https://sandbox-rest.ably.io,
the legacy prod-sandbox host. Every other objects integration spec — and the whole
UTS integration corpus (realtime + rest) — provisions apps and routes clients via
https://sandbox.realtime.ably-nonprod.net (raw HTTP) / endpoint: "nonprod:sandbox"
(SDK clients). The objects integration specs were migrated to the nonprod host in
e57d340, but standard_test_pool.md was missed, leaving provision_objects_via_rest
posting fixtures to a different backend than the app/key were provisioned on — so
RTPO15 (rest-provisioned-data-sync) could never resolve.

Point the helper at the canonical nonprod host to match.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot temporarily deployed to staging/pull/497 June 26, 2026 11:26 Inactive
@github-actions github-actions Bot temporarily deployed to staging/pull/497 June 26, 2026 11:31 Inactive
The Realtime client option blocks in objects_lifecycle_test.md (10) and
objects_sync_test.md (5) set no host, so the SDK falls back to the production
endpoint (realtime.ably.io, REC1a) — meaning the clients never reach the nonprod
sandbox the "Sandbox Setup" provisions the app on. Every other UTS integration
spec (realtime + rest) configures clients with endpoint: "nonprod:sandbox"; add
it here to match so the tests actually exercise the sandbox.

Added missing auto-connect false to clientOptions
@sacOO7 sacOO7 force-pushed the fix/uts-liveobjects-rest-provisioning branch from c3435fd to 356b57f Compare June 26, 2026 11:46
@github-actions github-actions Bot temporarily deployed to staging/pull/497 June 26, 2026 11:46 Inactive
@github-actions github-actions Bot temporarily deployed to staging/pull/497 June 26, 2026 11:48 Inactive
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