spec/unit/models/message_spec.rb in ably-0.8.15 vs spec/unit/models/message_spec.rb in ably-1.0.0

- old
+ new

@@ -23,10 +23,42 @@ expect(model.timestamp).to be_a(Time) expect(model.timestamp.to_i).to be_within(1).of(Time.now.to_i) end end + context '#extras (#TM2i)' do + let(:model) { subject.new({ extras: extras }, protocol_message: protocol_message) } + + context 'when missing' do + let(:model) { subject.new({}, protocol_message: protocol_message) } + it 'is nil' do + expect(model.extras).to be_nil + end + end + + context 'when a string' do + let(:extras) { 'string' } + it 'raises an exception' do + expect { model.extras }.to raise_error ArgumentError, /extras contains an unsupported type/ + end + end + + context 'when a Hash' do + let(:extras) { { key: 'value' } } + it 'contains a Hash Json object' do + expect(model.extras).to eq(extras) + end + end + + context 'when a Json Array' do + let(:extras) { [{ 'key' => 'value' }] } + it 'contains a Json Array object' do + expect(model.extras).to eq(extras) + end + end + end + context '#connection_id attribute' do let(:protocol_connection_id) { random_str } let(:protocol_message) { Ably::Models::ProtocolMessage.new('connectionId' => protocol_connection_id, action: 1, timestamp: protocol_message_timestamp) } let(:model_connection_id) { random_str } @@ -374,9 +406,130 @@ end it 'has a ProtocolMessage' do expect(subject.assigned_to_protocol_message?).to eql(true) end + end + end + end + + context '#from_encoded (#TM3)' do + context 'with no encoding' do + let(:message_data) do + { name: 'name', data: 'data-string' } + end + let(:from_encoded) { subject.from_encoded(message_data) } + + it 'returns a message object' do + expect(from_encoded).to be_a(Ably::Models::Message) + expect(from_encoded.name).to eql('name') + expect(from_encoded.data).to eql('data-string') + expect(from_encoded.encoding).to be_nil + end + + context 'with a block' do + it 'does not call the block' do + block_called = false + subject.from_encoded(message_data) do |exception, message| + block_called = true + end + expect(block_called).to be_falsey + end + end + end + + context 'with an encoding' do + let(:hash_data) { { 'key' => 'value', 'key2' => 123 } } + let(:message_data) do + { name: 'name', data: JSON.dump(hash_data), encoding: 'json' } + end + let(:from_encoded) { subject.from_encoded(message_data) } + + it 'returns a message object' do + expect(from_encoded).to be_a(Ably::Models::Message) + expect(from_encoded.name).to eql('name') + expect(from_encoded.data).to eql(hash_data) + expect(from_encoded.encoding).to be_nil + end + end + + context 'with a custom encoding' do + let(:hash_data) { { 'key' => 'value', 'key2' => 123 } } + let(:message_data) do + { name: 'name', data: JSON.dump(hash_data), encoding: 'foo/json' } + end + let(:from_encoded) { subject.from_encoded(message_data) } + + it 'returns a message object with the residual incompatible transforms left in the encoding property' do + expect(from_encoded).to be_a(Ably::Models::Message) + expect(from_encoded.name).to eql('name') + expect(from_encoded.data).to eql(hash_data) + expect(from_encoded.encoding).to eql('foo') + end + end + + context 'with a Cipher encoding' do + let(:hash_data) { { 'key' => 'value', 'key2' => 123 } } + let(:cipher_params) { { key: Ably::Util::Crypto.generate_random_key(128), algorithm: 'aes', mode: 'cbc', key_length: 128 } } + let(:crypto) { Ably::Util::Crypto.new(cipher_params) } + let(:payload) { random_str } + let(:message_data) do + { name: 'name', data: crypto.encrypt(payload), encoding: 'utf-8/cipher+aes-128-cbc' } + end + let(:channel_options) { { cipher: cipher_params } } + let(:from_encoded) { subject.from_encoded(message_data, channel_options) } + + it 'returns a message object with the residual incompatible transforms left in the encoding property' do + expect(from_encoded).to be_a(Ably::Models::Message) + expect(from_encoded.name).to eql('name') + expect(from_encoded.data).to eql(payload) + expect(from_encoded.encoding).to be_nil + end + end + + context 'with invalid Cipher encoding' do + let(:hash_data) { { 'key' => 'value', 'key2' => 123 } } + let(:cipher_params) { { key: Ably::Util::Crypto.generate_random_key(128), algorithm: 'aes', mode: 'cbc', key_length: 128 } } + let(:unencryped_payload) { random_str } + let(:message_data) do + { name: 'name', data: unencryped_payload, encoding: 'utf-8/cipher+aes-128-cbc' } + end + let(:channel_options) { { cipher: cipher_params } } + + context 'without a block' do + it 'raises an exception' do + expect { subject.from_encoded(message_data, channel_options) }.to raise_exception(Ably::Exceptions::CipherError) + end + end + + context 'with a block' do + it 'calls the block with the exception' do + block_called = false + subject.from_encoded(message_data, channel_options) do |exception, message| + expect(exception).to be_a(Ably::Exceptions::CipherError) + block_called = true + end + expect(block_called).to be_truthy + end + end + end + end + + context '#from_encoded_array (#TM3)' do + context 'with no encoding' do + let(:message_data) do + [{ name: 'name1', data: 'data-string' }, { name: 'name2', data: 'data-string' }] + end + let(:from_encoded) { subject.from_encoded_array(message_data) } + + it 'returns an Array of message objects' do + first = from_encoded.first + expect(first).to be_a(Ably::Models::Message) + expect(first.name).to eql('name1') + expect(first.data).to eql('data-string') + expect(first.encoding).to be_nil + last = from_encoded.last + expect(last.name).to eql('name2') end end end end