Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion ably/types/mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ def decode(data, encoding='', cipher=None, context=None):
log.error('Message cannot be decoded as no VCDiff decoder available')
raise AblyException('VCDiff decoder not available', 40019, 40019)

if not context.base_payload:
if context.base_payload is None:
log.error('VCDiff decoding requires base payload')
raise AblyException('VCDiff decode failure', 40018, 40018)

Expand Down
53 changes: 53 additions & 0 deletions test/uts/rest/unit/encoding/empty_delta_base_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import pytest

from ably import AblyVCDiffDecoder
from ably.types.message import Message
from ably.types.mixins import DecodingContext
from ably.util.exceptions import AblyException

# A VCDIFF window containing only an ADD instruction, independent of source bytes.
DELTA = bytes.fromhex('d6c3c40000000b0500050100') + b'hello' + bytes([6])


def delta_message():
return {
'id': 'next',
'data': DELTA,
'encoding': 'utf-8/vcdiff',
'extras': {'delta': {'from': 'initial'}},
}


@pytest.mark.parametrize('base', ['', b'', bytearray(), b'previous'])
def test_delta_decodes_from_present_base(base):
context = DecodingContext(base, 'initial', AblyVCDiffDecoder())

message = Message.from_encoded(delta_message(), context=context)

assert message.data == 'hello'
assert context.base_payload == b'hello'
assert context.last_message_id == 'next'


def test_delta_still_rejects_missing_base():
context = DecodingContext(None, 'initial', AblyVCDiffDecoder())

with pytest.raises(AblyException) as error:
Message.from_encoded(delta_message(), context=context)

assert error.value.code == 40018
assert context.base_payload is None
assert context.last_message_id == 'initial'


def test_batch_chains_delta_after_empty_full_message():
context = DecodingContext(vcdiff_decoder=AblyVCDiffDecoder())

messages = Message.from_encoded_array([
{'id': 'initial', 'data': '', 'encoding': 'utf-8'},
delta_message(),
], context=context)

assert [message.data for message in messages] == ['', 'hello']
assert context.base_payload == b'hello'
assert context.last_message_id == 'next'