diff --git a/uts/rest/unit/encoding/message_encoding.md b/uts/rest/unit/encoding/message_encoding.md index 0a2ca2061..f44a2b2ee 100644 --- a/uts/rest/unit/encoding/message_encoding.md +++ b/uts/rest/unit/encoding/message_encoding.md @@ -402,7 +402,7 @@ mock_http = MockHttpClient( { "id": "msg1", "name": "event", - "data": "encrypted-data-here", + "data": "ZW5jcnlwdGVkLWRhdGEtaGVyZQ==", "encoding": "custom-encryption/base64", "timestamp": 1234567890000 } @@ -427,6 +427,56 @@ message = history.items[0] ASSERT message.encoding == "custom-encryption" # Data should be base64-decoded but not further processed ASSERT message.data IS bytes # Result of base64 decode +ASSERT message.data == bytes("encrypted-data-here") +``` + +--- + +## RSL6b - Invalid base64 delivered with last successful decoding + +**Test ID**: `rest/unit/RSL6b/invalid-base64-preserved-1` + +**Spec requirement:** If invalid Base64 is detected in the message payload, an error message must be sent to the logger, but the message must still be delivered with the last successful decoding and the `encoding` field retaining the component that could not be decoded. + +### Setup +```pseudo +channel_name = "test-RSL6b-invalid-${random_id()}" +captured_requests = [] + +# "@@@invalid@@@" is not valid RFC4648 base64 and cannot be decoded. +mock_http = MockHttpClient( + onConnectionAttempt: (conn) => conn.respond_with_success(), + onRequest: (req) => { + captured_requests.push(req) + req.respond_with(200, [ + { + "id": "msg1", + "name": "event", + "data": "@@@invalid@@@", + "encoding": "custom-encryption/base64", + "timestamp": 1234567890000 + } + ]) + } +) +install_mock(mock_http) + +client = Rest(options: ClientOptions(key: "appId.keyId:keySecret")) +channel = client.channels.get(channel_name) +``` + +### Test Steps +```pseudo +history = AWAIT channel.history() +message = history.items[0] +``` + +### Assertions +```pseudo +# Base64 decode fails, so the message is delivered with the last successful +# decoding: the data is unchanged and the encoding retains the base64 component. +ASSERT message.data == "@@@invalid@@@" +ASSERT message.encoding == "custom-encryption/base64" ``` --- diff --git a/uts/rest/unit/presence/rest_presence.md b/uts/rest/unit/presence/rest_presence.md index 979e07a50..cac2dfe01 100644 --- a/uts/rest/unit/presence/rest_presence.md +++ b/uts/rest/unit/presence/rest_presence.md @@ -1221,8 +1221,8 @@ channel_name = "test-RSP5g-${random_id()}" captured_requests = [] cipher_key = base64_decode("WUP6u0K7MXI5Zeo0VppPwg==") -# Encrypted data for {"secret":"data"} -encrypted_data = "HO4cYSP8LybPYBPZPHQOtuD53yrD3YV3NBoTEYBh4U0=" +# Encrypted data for {"example":{"json":"Object"}} +encrypted_data = "HO4cYSP8LybPYBPZPHQOtuD53yrD3YV3NBoTEYBh4U0N1QXHbtkfsDfTspKeLQFt" mock_http = MockHttpClient( onConnectionAttempt: (conn) => conn.respond_with_success(), @@ -1255,6 +1255,7 @@ result = AWAIT channel.presence.get() ```pseudo ASSERT result.items[0].data IS Object/Map # Decryption applied based on cipher+aes-128-cbc encoding +ASSERT result.items[0].data == { "example": { "json": "Object" } } ``` --- diff --git a/uts/rest/unit/stats.md b/uts/rest/unit/stats.md index cddeb2e97..3af2f46de 100644 --- a/uts/rest/unit/stats.md +++ b/uts/rest/unit/stats.md @@ -30,17 +30,17 @@ stats_data = [ { "intervalId": "2024-01-01:00:00", "unit": "hour", - "all": { - "messages": {"count": 100, "data": 5000}, - "all": {"count": 100, "data": 5000} + "entries": { + "messages.all.all.count": 100, + "messages.all.all.data": 5000 } }, { "intervalId": "2024-01-01:01:00", "unit": "hour", - "all": { - "messages": {"count": 150, "data": 7500}, - "all": {"count": 150, "data": 7500} + "entries": { + "messages.all.all.count": 150, + "messages.all.all.data": 7500 } } ] @@ -71,7 +71,10 @@ ASSERT result.items.length == 2 # Stats objects should have correct fields ASSERT result.items[0].intervalId == "2024-01-01:00:00" ASSERT result.items[0].unit == "hour" +ASSERT result.items[0].entries["messages.all.all.count"] == 100 +ASSERT result.items[0].entries["messages.all.all.data"] == 5000 ASSERT result.items[1].intervalId == "2024-01-01:01:00" +ASSERT result.items[1].entries["messages.all.all.count"] == 150 # Verify correct endpoint and method ASSERT captured_requests.length == 1 diff --git a/uts/rest/unit/types/options_types.md b/uts/rest/unit/types/options_types.md index a32917875..1d147b4d7 100644 --- a/uts/rest/unit/types/options_types.md +++ b/uts/rest/unit/types/options_types.md @@ -251,9 +251,9 @@ Tests that endpoint option affects default hosts. | ID | Endpoint | Expected Rest Host | |----|----------|--------------------| -| 1 | (none/production) | `rest.ably.io` | -| 2 | `"test"` | `test-rest.ably.io` | -| 3 | `"custom-env"` | `custom-env-rest.ably.io` | +| 1 | (none/production) | `main.realtime.ably.net` | +| 2 | `"test"` | `test.realtime.ably.net` | +| 3 | `"custom-env"` | `custom-env.realtime.ably.net` | ### Note The actual host resolution may be tested at the HTTP client level. This test verifies the option is stored correctly.