ably-rest 1.2.5 → 1.2.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +11 -8
- data/lib/submodules/ably-ruby/.github/workflows/check.yml +2 -1
- data/lib/submodules/ably-ruby/CHANGELOG.md +25 -0
- data/lib/submodules/ably-ruby/README.md +24 -7
- data/lib/submodules/ably-ruby/SPEC.md +1738 -869
- data/lib/submodules/ably-ruby/ably.gemspec +1 -1
- data/lib/submodules/ably-ruby/lib/ably/auth.rb +19 -11
- data/lib/submodules/ably-ruby/lib/ably/models/protocol_message.rb +4 -26
- data/lib/submodules/ably-ruby/lib/ably/modules/safe_deferrable.rb +2 -2
- data/lib/submodules/ably-ruby/lib/ably/modules/state_emitter.rb +1 -1
- data/lib/submodules/ably-ruby/lib/ably/realtime/auth.rb +4 -0
- data/lib/submodules/ably-ruby/lib/ably/realtime/channel/channel_manager.rb +51 -48
- data/lib/submodules/ably-ruby/lib/ably/realtime/channel/channel_properties.rb +9 -0
- data/lib/submodules/ably-ruby/lib/ably/realtime/channel/channel_state_machine.rb +2 -0
- data/lib/submodules/ably-ruby/lib/ably/realtime/channel.rb +4 -3
- data/lib/submodules/ably-ruby/lib/ably/realtime/channels.rb +20 -0
- data/lib/submodules/ably-ruby/lib/ably/realtime/client/incoming_message_dispatcher.rb +14 -13
- data/lib/submodules/ably-ruby/lib/ably/realtime/client.rb +14 -6
- data/lib/submodules/ably-ruby/lib/ably/realtime/connection/connection_manager.rb +21 -22
- data/lib/submodules/ably-ruby/lib/ably/realtime/connection.rb +77 -109
- data/lib/submodules/ably-ruby/lib/ably/realtime/presence/members_map.rb +41 -92
- data/lib/submodules/ably-ruby/lib/ably/realtime/presence/presence_manager.rb +12 -17
- data/lib/submodules/ably-ruby/lib/ably/realtime/presence.rb +15 -6
- data/lib/submodules/ably-ruby/lib/ably/realtime/push.rb +0 -27
- data/lib/submodules/ably-ruby/lib/ably/realtime/recovery_key_context.rb +36 -0
- data/lib/submodules/ably-ruby/lib/ably/rest/client.rb +4 -6
- data/lib/submodules/ably-ruby/lib/ably/rest/push/admin.rb +1 -1
- data/lib/submodules/ably-ruby/lib/ably/rest/push.rb +0 -19
- data/lib/submodules/ably-ruby/lib/ably/util/ably_extensions.rb +29 -0
- data/lib/submodules/ably-ruby/lib/ably/util/crypto.rb +2 -2
- data/lib/submodules/ably-ruby/lib/ably/util/safe_deferrable.rb +1 -1
- data/lib/submodules/ably-ruby/lib/ably/version.rb +5 -7
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/auth_spec.rb +0 -7
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/channel_history_spec.rb +8 -12
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/channel_spec.rb +474 -300
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/client_spec.rb +1 -1
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/connection_failures_spec.rb +8 -25
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/connection_spec.rb +28 -120
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/message_spec.rb +24 -53
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/presence_spec.rb +123 -92
- data/lib/submodules/ably-ruby/spec/acceptance/rest/channel_spec.rb +2 -2
- data/lib/submodules/ably-ruby/spec/acceptance/rest/client_spec.rb +9 -2
- data/lib/submodules/ably-ruby/spec/acceptance/rest/message_spec.rb +8 -11
- data/lib/submodules/ably-ruby/spec/acceptance/rest/push_admin_spec.rb +20 -15
- data/lib/submodules/ably-ruby/spec/shared/client_initializer_behaviour.rb +1 -1
- data/lib/submodules/ably-ruby/spec/support/markdown_spec_formatter.rb +1 -1
- data/lib/submodules/ably-ruby/spec/unit/models/protocol_message_spec.rb +0 -86
- data/lib/submodules/ably-ruby/spec/unit/models/token_details_spec.rb +4 -2
- data/lib/submodules/ably-ruby/spec/unit/realtime/channels_spec.rb +1 -1
- data/lib/submodules/ably-ruby/spec/unit/realtime/connection_spec.rb +0 -30
- data/lib/submodules/ably-ruby/spec/unit/realtime/recovery_key_context_spec.rb +36 -0
- data/lib/submodules/ably-ruby/spec/unit/util/crypto_spec.rb +15 -15
- metadata +5 -4
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/push_spec.rb +0 -27
- data/lib/submodules/ably-ruby/spec/acceptance/rest/push_spec.rb +0 -25
@@ -60,13 +60,13 @@ describe Ably::Realtime::Presence, :event_machine do
|
|
60
60
|
end
|
61
61
|
|
62
62
|
unless expected_state == :left
|
63
|
-
it
|
63
|
+
it "presence #{method_name} : raise an exception if the channel is detached" do
|
64
64
|
setup_test(method_name, args, options) do
|
65
65
|
channel_client_one.attach do
|
66
66
|
channel_client_one.transition_state_machine :detaching
|
67
67
|
channel_client_one.once(:detached) do
|
68
68
|
presence_client_one.public_send(method_name, args).tap do |deferrable|
|
69
|
-
deferrable.callback { raise
|
69
|
+
deferrable.callback { raise "presence #{method_name} should not succeed" }
|
70
70
|
deferrable.errback do |error|
|
71
71
|
expect(error).to be_a(Ably::Exceptions::InvalidState)
|
72
72
|
expect(error.message).to match(/Operation is not allowed when channel is in STATE.Detached/)
|
@@ -78,12 +78,12 @@ describe Ably::Realtime::Presence, :event_machine do
|
|
78
78
|
end
|
79
79
|
end
|
80
80
|
|
81
|
-
it
|
81
|
+
it "presence #{method_name} : raise an exception if the channel becomes detached" do
|
82
82
|
setup_test(method_name, args, options) do
|
83
83
|
channel_client_one.attach do
|
84
84
|
channel_client_one.transition_state_machine :detaching
|
85
85
|
presence_client_one.public_send(method_name, args).tap do |deferrable|
|
86
|
-
deferrable.callback { raise
|
86
|
+
deferrable.callback { raise "presence #{method_name} should not succeed" }
|
87
87
|
deferrable.errback do |error|
|
88
88
|
expect(error).to be_a(Ably::Exceptions::InvalidState)
|
89
89
|
expect(error.message).to match(/Operation failed as channel transitioned to STATE.Detached/)
|
@@ -94,13 +94,13 @@ describe Ably::Realtime::Presence, :event_machine do
|
|
94
94
|
end
|
95
95
|
end
|
96
96
|
|
97
|
-
it
|
97
|
+
it "presence #{method_name} : raise an exception if the channel is failed" do
|
98
98
|
setup_test(method_name, args, options) do
|
99
99
|
channel_client_one.attach do
|
100
100
|
channel_client_one.transition_state_machine :failed
|
101
101
|
expect(channel_client_one.state).to eq(:failed)
|
102
102
|
presence_client_one.public_send(method_name, args).tap do |deferrable|
|
103
|
-
deferrable.callback { raise
|
103
|
+
deferrable.callback { raise "presence #{method_name} : Get should not succeed" }
|
104
104
|
deferrable.errback do |error|
|
105
105
|
expect(error).to be_a(Ably::Exceptions::InvalidState)
|
106
106
|
expect(error.message).to match(/Operation is not allowed when channel is in STATE.Failed/)
|
@@ -111,11 +111,11 @@ describe Ably::Realtime::Presence, :event_machine do
|
|
111
111
|
end
|
112
112
|
end
|
113
113
|
|
114
|
-
it
|
114
|
+
it "presence #{method_name} : raise an exception if the channel becomes failed" do
|
115
115
|
setup_test(method_name, args, options) do
|
116
116
|
channel_client_one.attach do
|
117
117
|
presence_client_one.public_send(method_name, args).tap do |deferrable|
|
118
|
-
deferrable.callback { raise
|
118
|
+
deferrable.callback { raise "presence #{method_name} : Get should not succeed" }
|
119
119
|
deferrable.errback do |error|
|
120
120
|
expect(error).to be_a(Ably::Exceptions::MessageDeliveryFailed)
|
121
121
|
stop_reactor
|
@@ -516,11 +516,11 @@ describe Ably::Realtime::Presence, :event_machine do
|
|
516
516
|
stop_reactor
|
517
517
|
end
|
518
518
|
|
519
|
-
it 'will emit an :
|
519
|
+
it 'will emit an :sync_complete event when synchronisation is complete' do
|
520
520
|
presence_client_one.enter
|
521
521
|
presence_client_two.enter
|
522
522
|
|
523
|
-
presence_anonymous_client.members.once(:
|
523
|
+
presence_anonymous_client.members.once(:sync_complete) do
|
524
524
|
stop_reactor
|
525
525
|
end
|
526
526
|
|
@@ -545,7 +545,7 @@ describe Ably::Realtime::Presence, :event_machine do
|
|
545
545
|
entered += 1
|
546
546
|
next unless entered == 2
|
547
547
|
|
548
|
-
presence_anonymous_client.members.once(:
|
548
|
+
presence_anonymous_client.members.once(:sync_complete) do
|
549
549
|
expect(presence_anonymous_client.members.count).to eql(2)
|
550
550
|
member_ids = presence_anonymous_client.members.map(&:member_key)
|
551
551
|
expect(member_ids.count).to eql(2)
|
@@ -580,7 +580,6 @@ describe Ably::Realtime::Presence, :event_machine do
|
|
580
580
|
action = Ably::Models::ProtocolMessage::ACTION.Presence
|
581
581
|
presence_msg = Ably::Models::ProtocolMessage.new(
|
582
582
|
action: action,
|
583
|
-
connection_serial: 20,
|
584
583
|
channel: channel_name,
|
585
584
|
presence: presence_data,
|
586
585
|
timestamp: Time.now.to_i * 1000
|
@@ -633,7 +632,6 @@ describe Ably::Realtime::Presence, :event_machine do
|
|
633
632
|
action = Ably::Models::ProtocolMessage::ACTION.Presence
|
634
633
|
presence_msg = Ably::Models::ProtocolMessage.new(
|
635
634
|
action: action,
|
636
|
-
connection_serial: anonymous_client.connection.serial + 1,
|
637
635
|
channel: channel_name,
|
638
636
|
presence: presence_data,
|
639
637
|
timestamp: Time.now.to_i * 1000
|
@@ -644,7 +642,6 @@ describe Ably::Realtime::Presence, :event_machine do
|
|
644
642
|
action = Ably::Models::ProtocolMessage::ACTION.Sync
|
645
643
|
sync_msg = Ably::Models::ProtocolMessage.new(
|
646
644
|
action: action,
|
647
|
-
connection_serial: anonymous_client.connection.serial + 2,
|
648
645
|
channel: channel_name,
|
649
646
|
channel_serial: 'validserialprefix:', # with no part after the `:` this indicates the end to the SYNC
|
650
647
|
presence: [],
|
@@ -707,21 +704,29 @@ describe Ably::Realtime::Presence, :event_machine do
|
|
707
704
|
|
708
705
|
context '#sync_complete? and SYNC flags (#RTP1)' do
|
709
706
|
context 'when attaching to a channel without any members present' do
|
710
|
-
|
711
|
-
|
707
|
+
it 'sync_complete? is true, no members are received and the presence channel is synced (#RTP1)' do
|
708
|
+
sync_info_received = false
|
712
709
|
|
713
710
|
anonymous_client.connection.__incoming_protocol_msgbus__.subscribe(:protocol_message) do |protocol_message|
|
714
711
|
if protocol_message.action == :attached
|
715
|
-
|
716
|
-
|
712
|
+
if protocol_message.has_presence_flag?
|
713
|
+
sync_info_received = false
|
714
|
+
else
|
715
|
+
sync_info_received = true
|
716
|
+
end
|
717
|
+
end
|
718
|
+
if protocol_message.action == Ably::Models::ProtocolMessage::ACTION.Sync
|
719
|
+
expect(protocol_message.presence).to be_empty
|
720
|
+
sync_info_received = true
|
717
721
|
end
|
718
722
|
end
|
719
723
|
|
720
724
|
channel_anonymous_client.attach do
|
721
|
-
|
722
|
-
|
723
|
-
|
724
|
-
|
725
|
+
wait_until(lambda { channel_anonymous_client.presence.sync_complete? and sync_info_received}) do
|
726
|
+
channel_anonymous_client.presence.get do |members|
|
727
|
+
expect(members).to be_empty
|
728
|
+
stop_reactor
|
729
|
+
end
|
725
730
|
end
|
726
731
|
end
|
727
732
|
end
|
@@ -851,7 +856,7 @@ describe Ably::Realtime::Presence, :event_machine do
|
|
851
856
|
# Hacky accessing a private method, but absent members are intentionally not exposed to any public APIs
|
852
857
|
expect(presence_anonymous_client.members.send(:absent_members).length).to eql(1)
|
853
858
|
|
854
|
-
presence_anonymous_client.members.once(:
|
859
|
+
presence_anonymous_client.members.once(:sync_complete) do
|
855
860
|
# Check that members count is exact indicating the members with LEAVE action after sync are removed
|
856
861
|
expect(presence_anonymous_client).to be_sync_complete
|
857
862
|
expect(presence_anonymous_client.members.length).to eql(enter_expected_count - 1)
|
@@ -1007,7 +1012,7 @@ describe Ably::Realtime::Presence, :event_machine do
|
|
1007
1012
|
|
1008
1013
|
channel_anonymous_client.attach do
|
1009
1014
|
presence_anonymous_client.get(wait_for_sync: false) do |members|
|
1010
|
-
expect(presence_anonymous_client.members).to_not
|
1015
|
+
expect(presence_anonymous_client.members).to_not be_sync_complete
|
1011
1016
|
expect(members.count).to eql(0)
|
1012
1017
|
stop_reactor
|
1013
1018
|
end
|
@@ -1214,7 +1219,7 @@ describe Ably::Realtime::Presence, :event_machine do
|
|
1214
1219
|
presence_client_one.subscribe(:enter) do
|
1215
1220
|
presence_client_one.unsubscribe :enter
|
1216
1221
|
EventMachine.add_timer(0.5) do
|
1217
|
-
expect(presence_client_one.members).to
|
1222
|
+
expect(presence_client_one.members).to be_sync_complete
|
1218
1223
|
expect(presence_client_one.members.send(:members).count).to eql(1)
|
1219
1224
|
presence_client_one.leave data
|
1220
1225
|
end
|
@@ -1592,14 +1597,16 @@ describe Ably::Realtime::Presence, :event_machine do
|
|
1592
1597
|
end
|
1593
1598
|
|
1594
1599
|
it 'fails if the connection is DETACHED (#RTP11b)' do
|
1595
|
-
|
1596
|
-
channel_client_one.
|
1597
|
-
|
1598
|
-
|
1599
|
-
|
1600
|
-
|
1601
|
-
|
1602
|
-
|
1600
|
+
client_one.connection.once :connected do
|
1601
|
+
channel_client_one.attach do
|
1602
|
+
channel_client_one.detach do
|
1603
|
+
presence_client_one.get.tap do |deferrable|
|
1604
|
+
deferrable.callback { raise 'Get should not succeed' }
|
1605
|
+
deferrable.errback do |error|
|
1606
|
+
expect(error).to be_a(Ably::Exceptions::InvalidState)
|
1607
|
+
expect(error.message).to match(/Operation is not allowed when channel is in STATE.Detached/)
|
1608
|
+
stop_reactor
|
1609
|
+
end
|
1603
1610
|
end
|
1604
1611
|
end
|
1605
1612
|
end
|
@@ -1815,29 +1822,31 @@ describe Ably::Realtime::Presence, :event_machine do
|
|
1815
1822
|
let(:total_members) { members_per_client * 2 }
|
1816
1823
|
|
1817
1824
|
it 'returns a complete list of members on all clients' do
|
1818
|
-
|
1819
|
-
presence_client_one.
|
1820
|
-
|
1821
|
-
|
1825
|
+
wait_until(lambda { client_one.connection.state == :connected and client_two.connection.state == :connected }) do
|
1826
|
+
presence_client_one.subscribe(:enter) do
|
1827
|
+
clients_entered[:client_one] += 1
|
1828
|
+
end
|
1822
1829
|
|
1823
|
-
|
1824
|
-
|
1825
|
-
|
1830
|
+
presence_client_two.subscribe(:enter) do
|
1831
|
+
clients_entered[:client_two] += 1
|
1832
|
+
end
|
1826
1833
|
|
1827
|
-
|
1828
|
-
|
1829
|
-
|
1834
|
+
members_per_client.times do |indx|
|
1835
|
+
presence_client_one.enter_client("client_1:#{indx}")
|
1836
|
+
presence_client_two.enter_client("client_2:#{indx}")
|
1837
|
+
end
|
1830
1838
|
|
1831
|
-
|
1832
|
-
|
1833
|
-
|
1834
|
-
|
1839
|
+
wait_until(lambda { clients_entered[:client_one] + clients_entered[:client_two] == total_members * 2 }) do
|
1840
|
+
presence_anonymous_client.get(wait_for_sync: true) do |anonymous_members|
|
1841
|
+
expect(anonymous_members.count).to eq(total_members)
|
1842
|
+
expect(anonymous_members.map(&:client_id).uniq.count).to eq(total_members)
|
1835
1843
|
|
1836
|
-
|
1837
|
-
|
1838
|
-
|
1839
|
-
|
1840
|
-
|
1844
|
+
presence_client_one.get(wait_for_sync: true) do |client_one_members|
|
1845
|
+
presence_client_two.get(wait_for_sync: true) do |client_two_members|
|
1846
|
+
expect(client_one_members.count).to eq(total_members)
|
1847
|
+
expect(client_one_members.count).to eq(client_two_members.count)
|
1848
|
+
stop_reactor
|
1849
|
+
end
|
1841
1850
|
end
|
1842
1851
|
end
|
1843
1852
|
end
|
@@ -2243,7 +2252,6 @@ describe Ably::Realtime::Presence, :event_machine do
|
|
2243
2252
|
action = Ably::Models::ProtocolMessage::ACTION.Sync
|
2244
2253
|
sync_message = Ably::Models::ProtocolMessage.new(
|
2245
2254
|
action: action,
|
2246
|
-
connection_serial: 10,
|
2247
2255
|
channel_serial: 'sequenceid:cursor',
|
2248
2256
|
channel: channel_name,
|
2249
2257
|
presence: presence_sync_1,
|
@@ -2253,7 +2261,6 @@ describe Ably::Realtime::Presence, :event_machine do
|
|
2253
2261
|
|
2254
2262
|
sync_message = Ably::Models::ProtocolMessage.new(
|
2255
2263
|
action: action,
|
2256
|
-
connection_serial: 11,
|
2257
2264
|
channel_serial: 'sequenceid:', # indicates SYNC is complete
|
2258
2265
|
channel: channel_name,
|
2259
2266
|
presence: presence_sync_2,
|
@@ -2294,7 +2301,6 @@ describe Ably::Realtime::Presence, :event_machine do
|
|
2294
2301
|
action = Ably::Models::ProtocolMessage::ACTION.Sync
|
2295
2302
|
sync_message = Ably::Models::ProtocolMessage.new(
|
2296
2303
|
action: action,
|
2297
|
-
connection_serial: 10,
|
2298
2304
|
channel: channel_name,
|
2299
2305
|
presence: presence_sync,
|
2300
2306
|
timestamp: Time.now.to_i * 1000
|
@@ -2348,7 +2354,6 @@ describe Ably::Realtime::Presence, :event_machine do
|
|
2348
2354
|
action = Ably::Models::ProtocolMessage::ACTION.Sync
|
2349
2355
|
sync_message = Ably::Models::ProtocolMessage.new(
|
2350
2356
|
action: action,
|
2351
|
-
connection_serial: 10,
|
2352
2357
|
channel: channel_name,
|
2353
2358
|
presence: presence_sync_protocol_message,
|
2354
2359
|
timestamp: Time.now.to_i * 1000
|
@@ -2467,7 +2472,7 @@ describe Ably::Realtime::Presence, :event_machine do
|
|
2467
2472
|
end
|
2468
2473
|
|
2469
2474
|
leave_message = Ably::Models::PresenceMessage.new(
|
2470
|
-
'id' => "#{client_two.connection.id}:#{
|
2475
|
+
'id' => "#{client_two.connection.id}:#{client_two.connection.send(:client_msg_serial)}:1",
|
2471
2476
|
'clientId' => presence_client_two.client_id,
|
2472
2477
|
'connectionId' => client_two.connection.id,
|
2473
2478
|
'timestamp' => as_since_epoch(Time.now),
|
@@ -2532,37 +2537,59 @@ describe Ably::Realtime::Presence, :event_machine do
|
|
2532
2537
|
let(:member_data) { random_str }
|
2533
2538
|
|
2534
2539
|
it 'immediately resends all local presence members (#RTP5c2, #RTP19a)' do
|
2535
|
-
|
2536
|
-
|
2540
|
+
member_leave_event_fired = false
|
2541
|
+
local_members_sent = false
|
2542
|
+
|
2543
|
+
presence_client_one.subscribe(:enter) do |entered_member|
|
2544
|
+
expect(entered_member.action).to eq(Ably::Models::PresenceMessage::ACTION.Enter)
|
2545
|
+
expect(entered_member.data).to eq(member_data)
|
2546
|
+
expect(entered_member.client_id).to eq(client_one.auth.client_id)
|
2547
|
+
expect(entered_member.id).to be_truthy
|
2548
|
+
entered_member_id = entered_member.id
|
2537
2549
|
|
2538
|
-
presence_client_one.enter(member_data)
|
2539
|
-
presence_client_one.subscribe(:enter) do
|
2540
2550
|
presence_client_one.unsubscribe :enter
|
2541
2551
|
|
2542
|
-
presence_client_one.
|
2543
|
-
|
2544
|
-
|
2552
|
+
expect(presence_client_one.members.length).to eql(1)
|
2553
|
+
expect(presence_client_one.members.local_members.length).to eql(1)
|
2554
|
+
|
2555
|
+
# subscribe to outgoing messages to check for entered local members with id
|
2556
|
+
client_one.connection.__outgoing_protocol_msgbus__.subscribe(:protocol_message) do |protocol_message|
|
2557
|
+
if protocol_message.action == :presence
|
2558
|
+
protocol_message.presence.each do |local_member|
|
2559
|
+
expect(local_member.id).to eq(entered_member_id)
|
2560
|
+
expect(local_member.action).to eq(Ably::Models::PresenceMessage::ACTION.Enter)
|
2561
|
+
expect(local_member.data).to eq(member_data)
|
2562
|
+
expect(local_member.client_id).to eq(client_one.auth.client_id)
|
2563
|
+
local_members_sent = true
|
2564
|
+
end
|
2565
|
+
end
|
2545
2566
|
end
|
2546
2567
|
|
2547
|
-
|
2548
|
-
|
2549
|
-
presence_client_one.subscribe(:update) do |message|
|
2550
|
-
expect(local_member_leave_event_fired).to be_truthy
|
2568
|
+
presence_client_one.subscribe(:leave) do |message|
|
2569
|
+
# Member will leave the PresenceMap due to the ATTACHED without Presence
|
2551
2570
|
expect(message.data).to eq(member_data)
|
2552
2571
|
expect(message.client_id).to eq(client_one.auth.client_id)
|
2553
|
-
|
2554
|
-
|
2555
|
-
|
2556
|
-
|
2557
|
-
|
2558
|
-
|
2572
|
+
member_leave_event_fired = true
|
2573
|
+
end
|
2574
|
+
|
2575
|
+
# Shouldn't receive enter/update message when local_members are entered
|
2576
|
+
# This is due to the fact that, when we enter local member we also send
|
2577
|
+
# member id, and server automatically checks for duplicate id and doesn't
|
2578
|
+
# send presenceEnter or presenceUpdate if id is found.
|
2579
|
+
presence_client_one.subscribe(:enter, :update) do |message|
|
2580
|
+
raise { "client shouldn't receive update event for entered local members" }
|
2559
2581
|
end
|
2560
2582
|
|
2561
|
-
presence_client_one.members.once(:
|
2562
|
-
# Immediately after SYNC (no sync actually occurred, but this event fires immediately after a channel SYNCs or is not expecting to SYNC)
|
2583
|
+
presence_client_one.members.once(:sync_complete) do
|
2563
2584
|
expect(presence_client_one.members.length).to eql(0)
|
2564
|
-
|
2565
|
-
|
2585
|
+
|
2586
|
+
# Since, this is a client sent event, local_members are not cleared
|
2587
|
+
# local_members acts a source of truth for server and not vice versa
|
2588
|
+
expect(presence_client_one.members.local_members.length).to eql(1)
|
2589
|
+
|
2590
|
+
wait_until(lambda { member_leave_event_fired and local_members_sent}) do
|
2591
|
+
stop_reactor
|
2592
|
+
end
|
2566
2593
|
end
|
2567
2594
|
|
2568
2595
|
# ATTACHED ProtocolMessage with no presence flag will clear the presence set immediately, #RTP19a
|
@@ -2572,6 +2599,8 @@ describe Ably::Realtime::Presence, :event_machine do
|
|
2572
2599
|
flags: 0 # no resume or presence flag
|
2573
2600
|
)
|
2574
2601
|
end
|
2602
|
+
|
2603
|
+
presence_client_one.enter(member_data)
|
2575
2604
|
end
|
2576
2605
|
end
|
2577
2606
|
end
|
@@ -2684,23 +2713,25 @@ describe Ably::Realtime::Presence, :event_machine do
|
|
2684
2713
|
|
2685
2714
|
context 'channel transitions to the DETACHED state' do
|
2686
2715
|
it 'clears the PresenceMap and local member map copy and does not emit any presence events (#RTP5a)' do
|
2687
|
-
|
2688
|
-
|
2689
|
-
presence_client_one.
|
2716
|
+
wait_until(lambda { client_one.connection.state == :connected and anonymous_client.connection.state == :connected }) do
|
2717
|
+
presence_client_one.enter
|
2718
|
+
presence_client_one.subscribe(:enter) do
|
2719
|
+
presence_client_one.unsubscribe :enter
|
2690
2720
|
|
2691
|
-
|
2692
|
-
|
2693
|
-
|
2721
|
+
channel_anonymous_client.attach do
|
2722
|
+
presence_anonymous_client.get do |members|
|
2723
|
+
expect(members.count).to eq(1)
|
2694
2724
|
|
2695
|
-
|
2696
|
-
|
2697
|
-
|
2698
|
-
|
2725
|
+
presence_anonymous_client.subscribe { raise 'No presence events should be emitted' }
|
2726
|
+
channel_anonymous_client.detach do
|
2727
|
+
expect(presence_anonymous_client.members.length).to eq(0)
|
2728
|
+
expect(channel_anonymous_client).to be_detached
|
2699
2729
|
|
2700
|
-
|
2701
|
-
|
2702
|
-
|
2703
|
-
|
2730
|
+
expect(presence_client_one.members.local_members.count).to eq(1)
|
2731
|
+
channel_client_one.detach do
|
2732
|
+
expect(presence_client_one.members.local_members.count).to eq(0)
|
2733
|
+
stop_reactor
|
2734
|
+
end
|
2704
2735
|
end
|
2705
2736
|
end
|
2706
2737
|
end
|
@@ -191,7 +191,7 @@ describe Ably::Rest::Channel do
|
|
191
191
|
let(:client_options) { default_options.merge(use_token_auth: true, default_token_params: { capability: capability }) }
|
192
192
|
|
193
193
|
it 'raises a permission error when publishing' do
|
194
|
-
expect { channel.publish(name, data) }.to raise_error(Ably::Exceptions::UnauthorizedRequest, /
|
194
|
+
expect { channel.publish(name, data) }.to raise_error(Ably::Exceptions::UnauthorizedRequest, /40160/)
|
195
195
|
end
|
196
196
|
end
|
197
197
|
|
@@ -280,7 +280,7 @@ describe Ably::Rest::Channel do
|
|
280
280
|
|
281
281
|
context 'with an invalid client_id in the message' do
|
282
282
|
it 'succeeds in the client library but then fails when published to Ably' do
|
283
|
-
expect { channel.publish([name: 'event', client_id: 'invalid']) }.to raise_error
|
283
|
+
expect { channel.publish([name: 'event', client_id: 'invalid']) }.to raise_error(Ably::Exceptions::InvalidRequest, /40012/)
|
284
284
|
end
|
285
285
|
end
|
286
286
|
|
@@ -1095,9 +1095,16 @@ describe Ably::Rest::Client do
|
|
1095
1095
|
end
|
1096
1096
|
|
1097
1097
|
it 'sends a protocol version and lib version header (#G4, #RSC7a, #RSC7b)' do
|
1098
|
-
client.channels.get('foo').publish("event")
|
1098
|
+
response = client.channels.get('foo').publish("event")
|
1099
|
+
expect(response).to eql true
|
1099
1100
|
expect(publish_message_stub).to have_been_requested
|
1100
|
-
|
1101
|
+
if agent.nil?
|
1102
|
+
expect(publish_message_stub.to_s).to include("'Ably-Agent'=>'#{Ably::AGENT}'")
|
1103
|
+
expect(publish_message_stub.to_s).to include("'X-Ably-Version'=>'2'")
|
1104
|
+
else
|
1105
|
+
expect(publish_message_stub.to_s).to include("'Ably-Agent'=>'ably-ruby/1.1.1 ruby/3.1.1'")
|
1106
|
+
expect(publish_message_stub.to_s).to include("'X-Ably-Version'=>'2'")
|
1107
|
+
end
|
1101
1108
|
end
|
1102
1109
|
end
|
1103
1110
|
end
|
@@ -204,20 +204,17 @@ describe Ably::Rest::Channel, 'messages' do
|
|
204
204
|
end
|
205
205
|
end
|
206
206
|
|
207
|
-
specify 'idempotent publishing is
|
208
|
-
|
209
|
-
client = Ably::Rest::Client.new(key: api_key, protocol: protocol)
|
210
|
-
expect(client.idempotent_rest_publishing).to be_falsey
|
211
|
-
stub_const 'Ably::PROTOCOL_VERSION', '1.1'
|
212
|
-
client = Ably::Rest::Client.new(key: api_key, protocol: protocol)
|
207
|
+
specify 'idempotent publishing is set as per clientOptions' do
|
208
|
+
# set idempotent_rest_publishing to false
|
209
|
+
client = Ably::Rest::Client.new(key: api_key, protocol: protocol, idempotent_rest_publishing: false)
|
213
210
|
expect(client.idempotent_rest_publishing).to be_falsey
|
214
|
-
end
|
215
211
|
|
216
|
-
|
217
|
-
|
218
|
-
client = Ably::Rest::Client.new(key: api_key, protocol: protocol)
|
212
|
+
# set idempotent_rest_publishing to true
|
213
|
+
client = Ably::Rest::Client.new(key: api_key, protocol: protocol, idempotent_rest_publishing: true)
|
219
214
|
expect(client.idempotent_rest_publishing).to be_truthy
|
220
|
-
|
215
|
+
end
|
216
|
+
|
217
|
+
specify 'idempotent publishing is enabled by default (#TO3n)' do
|
221
218
|
client = Ably::Rest::Client.new(key: api_key, protocol: protocol)
|
222
219
|
expect(client.idempotent_rest_publishing).to be_truthy
|
223
220
|
end
|
@@ -181,7 +181,7 @@ describe Ably::Rest::Push::Admin do
|
|
181
181
|
client_id: client_id,
|
182
182
|
push: {
|
183
183
|
recipient: {
|
184
|
-
transport_type: '
|
184
|
+
transport_type: 'fcm',
|
185
185
|
registration_token: 'secret_token',
|
186
186
|
}
|
187
187
|
}
|
@@ -250,7 +250,7 @@ describe Ably::Rest::Push::Admin do
|
|
250
250
|
client_id: client_id,
|
251
251
|
push: {
|
252
252
|
recipient: {
|
253
|
-
transport_type: '
|
253
|
+
transport_type: 'fcm',
|
254
254
|
registration_token: 'secret_token',
|
255
255
|
}
|
256
256
|
}
|
@@ -268,7 +268,7 @@ describe Ably::Rest::Push::Admin do
|
|
268
268
|
expect(device).to be_a(Ably::Models::DeviceDetails)
|
269
269
|
expect(device.platform).to eql('ios')
|
270
270
|
expect(device.client_id).to eql(client_id)
|
271
|
-
expect(device.push.recipient.fetch(:transport_type)).to eql('
|
271
|
+
expect(device.push.recipient.fetch(:transport_type)).to eql('fcm')
|
272
272
|
end
|
273
273
|
|
274
274
|
it 'returns a DeviceDetails object if a DeviceDetails object is provided' do
|
@@ -276,7 +276,7 @@ describe Ably::Rest::Push::Admin do
|
|
276
276
|
expect(device).to be_a(Ably::Models::DeviceDetails)
|
277
277
|
expect(device.platform).to eql('ios')
|
278
278
|
expect(device.client_id).to eql(client_id)
|
279
|
-
expect(device.push.recipient.fetch(:transport_type)).to eql('
|
279
|
+
expect(device.push.recipient.fetch(:transport_type)).to eql('fcm')
|
280
280
|
end
|
281
281
|
|
282
282
|
it 'raises a ResourceMissing exception if device ID does not exist' do
|
@@ -350,14 +350,14 @@ describe Ably::Rest::Push::Admin do
|
|
350
350
|
expect(device_retrieved.push.recipient['foo_bar']).to eql('string')
|
351
351
|
end
|
352
352
|
|
353
|
-
context 'with
|
353
|
+
context 'with FCM target' do
|
354
354
|
let(:device_token) { random_str }
|
355
355
|
|
356
356
|
it 'saves the associated DevicePushDetails' do
|
357
357
|
subject.save(device_details.merge(
|
358
358
|
push: {
|
359
359
|
recipient: {
|
360
|
-
transport_type: '
|
360
|
+
transport_type: 'fcm',
|
361
361
|
registrationToken: device_token
|
362
362
|
}
|
363
363
|
}
|
@@ -365,14 +365,15 @@ describe Ably::Rest::Push::Admin do
|
|
365
365
|
|
366
366
|
device_retrieved = subject.get(device_details.fetch(:id))
|
367
367
|
|
368
|
-
expect(device_retrieved.push.recipient.fetch('transportType')).to eql('
|
368
|
+
expect(device_retrieved.push.recipient.fetch('transportType')).to eql('fcm')
|
369
369
|
expect(device_retrieved.push.recipient[:registration_token]).to eql(device_token)
|
370
370
|
end
|
371
371
|
end
|
372
372
|
|
373
373
|
context 'with web target' do
|
374
374
|
let(:target_url) { 'http://foo.com/bar' }
|
375
|
-
let(:
|
375
|
+
let(:p256dh) { random_str }
|
376
|
+
let(:auth) { random_str }
|
376
377
|
|
377
378
|
it 'saves the associated DevicePushDetails' do
|
378
379
|
subject.save(device_details.merge(
|
@@ -380,7 +381,10 @@ describe Ably::Rest::Push::Admin do
|
|
380
381
|
recipient: {
|
381
382
|
transport_type: 'web',
|
382
383
|
targetUrl: target_url,
|
383
|
-
encryptionKey:
|
384
|
+
encryptionKey: {
|
385
|
+
p256dh: p256dh,
|
386
|
+
auth: auth
|
387
|
+
}
|
384
388
|
}
|
385
389
|
}
|
386
390
|
))
|
@@ -389,7 +393,8 @@ describe Ably::Rest::Push::Admin do
|
|
389
393
|
|
390
394
|
expect(device_retrieved.push.recipient[:transport_type]).to eql('web')
|
391
395
|
expect(device_retrieved.push.recipient['targetUrl']).to eql(target_url)
|
392
|
-
expect(device_retrieved.push.recipient['encryptionKey']).to eql(
|
396
|
+
expect(device_retrieved.push.recipient['encryptionKey']['p256dh']).to eql(p256dh)
|
397
|
+
expect(device_retrieved.push.recipient['encryptionKey']['auth']).to eql(auth)
|
393
398
|
end
|
394
399
|
end
|
395
400
|
|
@@ -462,7 +467,7 @@ describe Ably::Rest::Push::Admin do
|
|
462
467
|
client_id: client_id,
|
463
468
|
push: {
|
464
469
|
recipient: {
|
465
|
-
transport_type: '
|
470
|
+
transport_type: 'fcm',
|
466
471
|
registrationToken: 'secret_token',
|
467
472
|
}
|
468
473
|
}
|
@@ -476,7 +481,7 @@ describe Ably::Rest::Push::Admin do
|
|
476
481
|
client_id: client_id,
|
477
482
|
push: {
|
478
483
|
recipient: {
|
479
|
-
transport_type: '
|
484
|
+
transport_type: 'fcm',
|
480
485
|
registration_token: 'secret_token',
|
481
486
|
}
|
482
487
|
}
|
@@ -525,7 +530,7 @@ describe Ably::Rest::Push::Admin do
|
|
525
530
|
client_id: client_id,
|
526
531
|
push: {
|
527
532
|
recipient: {
|
528
|
-
transport_type: '
|
533
|
+
transport_type: 'fcm',
|
529
534
|
registration_token: 'secret_token',
|
530
535
|
}
|
531
536
|
}
|
@@ -539,7 +544,7 @@ describe Ably::Rest::Push::Admin do
|
|
539
544
|
client_id: client_id,
|
540
545
|
push: {
|
541
546
|
recipient: {
|
542
|
-
transport_type: '
|
547
|
+
transport_type: 'fcm',
|
543
548
|
registration_token: 'secret_token',
|
544
549
|
}
|
545
550
|
}
|
@@ -580,7 +585,7 @@ describe Ably::Rest::Push::Admin do
|
|
580
585
|
client_id: client_id,
|
581
586
|
push: {
|
582
587
|
recipient: {
|
583
|
-
transport_type: '
|
588
|
+
transport_type: 'fcm',
|
584
589
|
registration_token: 'secret_token',
|
585
590
|
}
|
586
591
|
}
|
@@ -130,7 +130,7 @@ shared_examples 'a client initializer' do
|
|
130
130
|
end
|
131
131
|
|
132
132
|
context 'with token' do
|
133
|
-
let(:client_options) { { token: 'token',
|
133
|
+
let(:client_options) { { token: 'token', auto_connect: false } }
|
134
134
|
|
135
135
|
it 'sets the token' do
|
136
136
|
expect(subject.auth.current_token_details.token).to eql('token')
|
@@ -83,7 +83,7 @@ module Ably
|
|
83
83
|
attr_reader :output, :indent
|
84
84
|
|
85
85
|
def documenting_rest_only?
|
86
|
-
File.
|
86
|
+
File.exist?(File.expand_path('../../../../../../ably-rest.gemspec', __FILE__))
|
87
87
|
end
|
88
88
|
|
89
89
|
def example_name_and_link(notification)
|