spec/acceptance/realtime/presence_spec.rb in ably-0.8.8 vs spec/acceptance/realtime/presence_spec.rb in ably-0.8.9

- old
+ new

@@ -131,13 +131,13 @@ end context 'with supported data payload content type' do def register_presence_and_check_data(method_name, data) if method_name.to_s.match(/_client/) - presence_client_one.public_send(method_name, client_id, data: data) + presence_client_one.public_send(method_name, client_id, data) else - presence_client_one.public_send(method_name, data: data) + presence_client_one.public_send(method_name, data) end presence_client_one.subscribe do |presence_message| expect(presence_message.data).to eql(data) stop_reactor @@ -186,13 +186,13 @@ end context 'with unsupported data payload content type' do def presence_action(method_name, data) if method_name.to_s.match(/_client/) - presence_client_one.public_send(method_name, client_id, data: data) + presence_client_one.public_send(method_name, client_id, data) else - presence_client_one.public_send(method_name, data: data) + presence_client_one.public_send(method_name, data) end end context 'Integer' do let(:data) { 1 } @@ -675,11 +675,11 @@ end end context '#get' do context 'with :wait_for_sync option set to true' do - it 'waits until sync is complete', em_timeout: 15 do + it 'waits until sync is complete', em_timeout: 30 do # allow for slow connections and lots of messages enter_expected_count.times do |index| EventMachine.add_timer(index / 10) do presence_client_one.enter_client("client:#{index}") do |message| entered << message next unless entered.count == enter_expected_count @@ -694,11 +694,11 @@ end end end context 'by default' do - it 'it does not wait for sync', em_timeout: 15 do + it 'it does not wait for sync', em_timeout: 30 do # allow for slow connections and lots of messages enter_expected_count.times do |index| EventMachine.add_timer(index / 10) do presence_client_one.enter_client("client:#{index}") do |message| entered << message next unless entered.count == enter_expected_count @@ -743,33 +743,24 @@ end end end context '#enter' do - it 'allows client_id to be set on enter for anonymous clients' do - channel_anonymous_client.presence.enter client_id: "123" - - channel_anonymous_client.presence.subscribe do |presence| - expect(presence.client_id).to eq("123") - stop_reactor - end - end - context 'data attribute' do context 'when provided as argument option to #enter' do - it 'remains intact following #leave' do + it 'changes to value provided in #leave' do leave_callback_called = false - presence_client_one.enter(data: 'stored') do + presence_client_one.enter('stored') do expect(presence_client_one.data).to eql('stored') presence_client_one.leave do |presence| leave_callback_called = true end presence_client_one.on(:left) do - expect(presence_client_one.data).to eql('stored') + expect(presence_client_one.data).to eql(nil) EventMachine.next_tick do expect(leave_callback_called).to eql(true) stop_reactor end @@ -790,24 +781,19 @@ stop_reactor end end end - it 'raises an exception if client_id is not set' do - expect { channel_anonymous_client.presence.enter }.to raise_error(Ably::Exceptions::IncompatibleClientId, /without a client_id/) - stop_reactor - end - context 'without necessary capabilities to join presence' do let(:restricted_client) do auto_close Ably::Realtime::Client.new(default_options.merge(key: restricted_api_key, log_level: :fatal)) end let(:restricted_channel) { restricted_client.channel("cansubscribe:channel") } let(:restricted_presence) { restricted_channel.presence } it 'calls the Deferrable errback on capabilities failure' do - restricted_presence.enter(client_id: 'clientId').tap do |deferrable| + restricted_presence.enter_client('bob').tap do |deferrable| deferrable.callback { raise "Should not succeed" } deferrable.errback { stop_reactor } end end end @@ -815,11 +801,11 @@ it_should_behave_like 'a public presence method', :enter, :entered, {} end context '#update' do it 'without previous #enter automatically enters' do - presence_client_one.update(data: data_payload) do + presence_client_one.update(data_payload) do EventMachine.add_timer(1) do expect(presence_client_one.state).to eq(:entered) stop_reactor end end @@ -828,11 +814,11 @@ context 'when ENTERED' do it 'has no effect on the state' do presence_client_one.enter do presence_client_one.once_state_changed { fail 'State should not have changed ' } - presence_client_one.update(data: data_payload) do + presence_client_one.update(data_payload) do EventMachine.add_timer(1) do expect(presence_client_one.state).to eq(:entered) presence_client_one.off stop_reactor end @@ -840,21 +826,21 @@ end end end it 'updates the data if :data argument provided' do - presence_client_one.enter(data: 'prior') do - presence_client_one.update(data: data_payload) + presence_client_one.enter('prior') do + presence_client_one.update(data_payload) end presence_client_one.subscribe(:update) do |message| expect(message.data).to eql(data_payload) stop_reactor end end it 'updates the data to nil if :data argument is not provided (assumes nil value)' do - presence_client_one.enter(data: 'prior') do + presence_client_one.enter('prior') do presence_client_one.update end presence_client_one.subscribe(:update) do |message| expect(message.data).to be_nil stop_reactor @@ -869,37 +855,37 @@ let(:data) { random_str } let(:enter_data) { random_str } context 'when set to a string' do it 'emits the new data for the leave event' do - presence_client_one.enter data: enter_data do - presence_client_one.leave data: data + presence_client_one.enter enter_data do + presence_client_one.leave data end presence_client_one.subscribe(:leave) do |presence_message| expect(presence_message.data).to eql(data) stop_reactor end end end context 'when set to nil' do - it 'emits a nil value for the data attribute when leaving' do - presence_client_one.enter data: enter_data do - presence_client_one.leave data: nil + it 'emits the last value for the data attribute when leaving' do + presence_client_one.enter enter_data do + presence_client_one.leave nil end presence_client_one.subscribe(:leave) do |presence_message| expect(presence_message.data).to eql(enter_data) stop_reactor end end end - context 'when not passed as an argument' do - it 'emits the previously defined value as a convenience' do - presence_client_one.enter data: enter_data do + context 'when not passed as an argument (i.e. nil)' do + it 'emits the previous value for the data attribute when leaving' do + presence_client_one.enter enter_data do presence_client_one.leave end presence_client_one.subscribe(:leave) do |presence_message| expect(presence_message.data).to eql(enter_data) @@ -908,14 +894,14 @@ end end context 'and sync is complete' do it 'does not cache members that have left' do - presence_client_one.enter data: enter_data do + presence_client_one.enter enter_data do expect(presence_client_one.members).to be_in_sync expect(presence_client_one.members.send(:members).count).to eql(1) - presence_client_one.leave data: data + presence_client_one.leave data end presence_client_one.subscribe(:leave) do |presence_message| expect(presence_message.data).to eql(data) expect(presence_client_one.members.send(:members).count).to eql(0) @@ -933,23 +919,23 @@ it_should_behave_like 'a public presence method', :leave, :left, {}, enter_first: true end context ':left event' do it 'emits the data defined in enter' do - channel_client_one.presence.enter(data: 'data') do + channel_client_one.presence.enter('data') do channel_client_one.presence.leave end channel_client_two.presence.subscribe(:leave) do |message| expect(message.data).to eql('data') stop_reactor end end it 'emits the data defined in update' do - channel_client_one.presence.enter(data: 'something else') do - channel_client_one.presence.update(data: 'data') do + channel_client_one.presence.enter('something else') do + channel_client_one.presence.update('data') do channel_client_one.presence.leave end end channel_client_two.presence.subscribe(:leave) do |message| @@ -982,11 +968,11 @@ end end it 'enters a channel and sets the data based on the provided :data option' do client_count.times do |client_id| - presence_client_one.enter_client("client:#{client_id}", data: data) + presence_client_one.enter_client("client:#{client_id}", data) end presence_anonymous_client.subscribe(:enter) do |presence| expect(presence.data).to eql(data) clients << presence @@ -1038,11 +1024,11 @@ it 'updates the data attribute for the member when :data option provided' do updated_callback_count = 0 client_count.times do |client_id| presence_client_one.enter_client("client:#{client_id}") do - presence_client_one.update_client("client:#{client_id}", data: data) do + presence_client_one.update_client("client:#{client_id}", data) do updated_callback_count += 1 end end end @@ -1073,11 +1059,11 @@ it 'enters if not already entered' do updated_callback_count = 0 client_count.times do |client_id| - presence_client_one.update_client("client:#{client_id}", data: data) do + presence_client_one.update_client("client:#{client_id}", data) do updated_callback_count += 1 end end presence_anonymous_client.subscribe(:enter) do |presence| @@ -1103,12 +1089,12 @@ context 'multiple times on the same channel with different client_ids' do it 'emits the :leave event for each client_id' do left_callback_count = 0 client_count.times do |client_id| - presence_client_one.enter_client("client:#{client_id}", data: random_str) do - presence_client_one.leave_client("client:#{client_id}", data: data) do + presence_client_one.enter_client("client:#{client_id}", random_str) do + presence_client_one.leave_client("client:#{client_id}", data) do left_callback_count += 1 end end end @@ -1148,12 +1134,12 @@ end end context 'with a new value in :data option' do it 'emits the leave event with the new data value' do - presence_client_one.enter_client("client:unique", data: random_str) do - presence_client_one.leave_client("client:unique", data: data) + presence_client_one.enter_client("client:unique", random_str) do + presence_client_one.leave_client("client:unique", data) end presence_client_one.subscribe(:leave) do |presence_message| expect(presence_message.data).to eql(data) stop_reactor @@ -1161,12 +1147,12 @@ end end context 'with a nil value in :data option' do it 'emits the leave event with the previous value as a convenience' do - presence_client_one.enter_client("client:unique", data: data) do - presence_client_one.leave_client("client:unique", data: nil) + presence_client_one.enter_client("client:unique", data) do + presence_client_one.leave_client("client:unique", nil) end presence_client_one.subscribe(:leave) do |presence_message| expect(presence_message.data).to eql(data) stop_reactor @@ -1174,11 +1160,11 @@ end end context 'with no :data option' do it 'emits the leave event with the previous value as a convenience' do - presence_client_one.enter_client("client:unique", data: data) do + presence_client_one.enter_client("client:unique", data) do presence_client_one.leave_client("client:unique") end presence_client_one.subscribe(:leave) do |presence_message| expect(presence_message.data).to eql(data) @@ -1517,11 +1503,11 @@ end end context 'REST #get' do it 'returns current members' do - presence_client_one.enter(data: data_payload) do + presence_client_one.enter(data_payload) do members_page = channel_rest_client_one.presence.get this_member = members_page.items.first expect(this_member).to be_a(Ably::Models::PresenceMessage) expect(this_member.client_id).to eql(client_one.client_id) @@ -1530,11 +1516,11 @@ stop_reactor end end it 'returns no members once left' do - presence_client_one.enter(data: data_payload) do + presence_client_one.enter(data_payload) do presence_client_one.leave do members_page = channel_rest_client_one.presence.get expect(members_page.items.count).to eql(0) stop_reactor end @@ -1560,36 +1546,38 @@ context 'in channel options' do let(:client_one) { auto_close Ably::Realtime::Client.new(default_options) } it 'is converted into UTF_8' do - presence_client_one.enter(client_id: client_id) - presence_client_one.on(:entered) do |presence| - expect(presence.client_id.encoding).to eql(Encoding::UTF_8) - expect(presence.client_id.encode(Encoding::ASCII_8BIT)).to eql(client_id) - stop_reactor + channel_client_one.attach do + presence_client_one.subscribe(:enter) do |presence| + expect(presence.client_id.encoding).to eql(Encoding::UTF_8) + expect(presence.client_id.encode(Encoding::ASCII_8BIT)).to eql(client_id) + stop_reactor + end + presence_anonymous_client.enter_client(client_id) end end end end context 'encoding and decoding of presence message data' do - let(:secret_key) { random_str } + let(:secret_key) { Ably::Util::Crypto.generate_random_key(256) } let(:cipher_options) { { key: secret_key, algorithm: 'aes', mode: 'cbc', key_length: 256 } } let(:channel_name) { random_str } - let(:encrypted_channel) { client_one.channel(channel_name, encrypted: true, cipher_params: cipher_options) } - let(:channel_rest_client_one) { client_one.rest_client.channel(channel_name, encrypted: true, cipher_params: cipher_options) } + let(:encrypted_channel) { client_one.channel(channel_name, cipher: cipher_options) } + let(:channel_rest_client_one) { client_one.rest_client.channel(channel_name, cipher: cipher_options) } let(:crypto) { Ably::Util::Crypto.new(cipher_options) } - let(:data) { { 'key' => random_str } } + let(:data) { { 'hash_id' => random_str } } let(:data_as_json) { data.to_json } let(:data_as_cipher) { crypto.encrypt(data.to_json) } it 'encrypts presence message data' do encrypted_channel.attach do - encrypted_channel.presence.enter data: data + encrypted_channel.presence.enter data end encrypted_channel.presence.__incoming_msgbus__.unsubscribe(:presence) # remove all subscribe callbacks that could decrypt the message encrypted_channel.presence.__incoming_msgbus__.subscribe(:presence) do |presence| if protocol == :json @@ -1604,11 +1592,11 @@ end context '#subscribe' do it 'emits decrypted enter events' do encrypted_channel.attach do - encrypted_channel.presence.enter data: data + encrypted_channel.presence.enter data end encrypted_channel.presence.subscribe(:enter) do |presence_message| expect(presence_message.encoding).to be_nil expect(presence_message.data).to eql(data) @@ -1616,12 +1604,12 @@ end end it 'emits decrypted update events' do encrypted_channel.attach do - encrypted_channel.presence.enter(data: 'to be updated') do - encrypted_channel.presence.update data: data + encrypted_channel.presence.enter('to be updated') do + encrypted_channel.presence.update data end end encrypted_channel.presence.subscribe(:update) do |presence_message| expect(presence_message.encoding).to be_nil @@ -1630,11 +1618,11 @@ end end it 'emits previously set data for leave events' do encrypted_channel.attach do - encrypted_channel.presence.enter(data: data) do + encrypted_channel.presence.enter(data) do encrypted_channel.presence.leave end end encrypted_channel.presence.subscribe(:leave) do |presence_message| @@ -1645,11 +1633,11 @@ end end context '#get' do it 'returns a list of members with decrypted data' do - encrypted_channel.presence.enter(data: data) do + encrypted_channel.presence.enter(data) do encrypted_channel.presence.get do |members| member = members.first expect(member.encoding).to be_nil expect(member.data).to eql(data) stop_reactor @@ -1658,26 +1646,26 @@ end end context 'REST #get' do it 'returns a list of members with decrypted data' do - encrypted_channel.presence.enter(data: data) do + encrypted_channel.presence.enter(data) do member = channel_rest_client_one.presence.get.items.first expect(member.encoding).to be_nil expect(member.data).to eql(data) stop_reactor end end end context 'when cipher settings do not match publisher' do let(:client_options) { default_options.merge(log_level: :fatal) } - let(:incompatible_cipher_options) { { key: secret_key, algorithm: 'aes', mode: 'cbc', key_length: 128 } } - let(:incompatible_encrypted_channel) { client_two.channel(channel_name, encrypted: true, cipher_params: incompatible_cipher_options) } + let(:incompatible_cipher_options) { { key: Ably::Util::Crypto.generate_random_key(128), algorithm: 'aes', mode: 'cbc', key_length: 128 } } + let(:incompatible_encrypted_channel) { client_two.channel(channel_name, cipher: incompatible_cipher_options) } it 'delivers an unencoded presence message left with encoding value' do - encrypted_channel.presence.enter data: data + encrypted_channel.presence.enter data incompatible_encrypted_channel.presence.subscribe(:enter) do incompatible_encrypted_channel.presence.get do |members| member = members.first expect(member.encoding).to match(/cipher\+aes-256-cbc/) @@ -1694,11 +1682,11 @@ expect(error.message).to match(/Cipher algorithm AES-128-CBC does not match/) stop_reactor end encrypted_channel.attach do - encrypted_channel.presence.enter data: data + encrypted_channel.presence.enter data end end end end end @@ -1720,18 +1708,18 @@ expect(members.count).to eq(0) expect(message.data).to eql(data_payload) stop_reactor end end - presence_client_one.enter(data: data_payload) do + presence_client_one.enter(data_payload) do presence_client_one.leave end end end context 'connection failure mid-way through a large member sync' do - let(:members_count) { 400 } + let(:members_count) { 250 } let(:sync_pages_received) { [] } let(:client_options) { default_options.merge(log_level: :error) } it 'resumes the SYNC operation', em_timeout: 15 do when_all(*members_count.times.map do |index| @@ -1739,10 +1727,10 @@ end) do channel_client_two.attach do client_two.connection.transport.__incoming_protocol_msgbus__.subscribe(:protocol_message) do |protocol_message| if protocol_message.action == :sync sync_pages_received << protocol_message - force_connection_failure client_two if sync_pages_received.count == 2 + force_connection_failure client_two if sync_pages_received.count == 1 end end end presence_client_two.get(wait_for_sync: true) do |members|