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.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +11 -8
  3. data/lib/submodules/ably-ruby/.github/workflows/check.yml +2 -1
  4. data/lib/submodules/ably-ruby/CHANGELOG.md +25 -0
  5. data/lib/submodules/ably-ruby/README.md +24 -7
  6. data/lib/submodules/ably-ruby/SPEC.md +1738 -869
  7. data/lib/submodules/ably-ruby/ably.gemspec +1 -1
  8. data/lib/submodules/ably-ruby/lib/ably/auth.rb +19 -11
  9. data/lib/submodules/ably-ruby/lib/ably/models/protocol_message.rb +4 -26
  10. data/lib/submodules/ably-ruby/lib/ably/modules/safe_deferrable.rb +2 -2
  11. data/lib/submodules/ably-ruby/lib/ably/modules/state_emitter.rb +1 -1
  12. data/lib/submodules/ably-ruby/lib/ably/realtime/auth.rb +4 -0
  13. data/lib/submodules/ably-ruby/lib/ably/realtime/channel/channel_manager.rb +51 -48
  14. data/lib/submodules/ably-ruby/lib/ably/realtime/channel/channel_properties.rb +9 -0
  15. data/lib/submodules/ably-ruby/lib/ably/realtime/channel/channel_state_machine.rb +2 -0
  16. data/lib/submodules/ably-ruby/lib/ably/realtime/channel.rb +4 -3
  17. data/lib/submodules/ably-ruby/lib/ably/realtime/channels.rb +20 -0
  18. data/lib/submodules/ably-ruby/lib/ably/realtime/client/incoming_message_dispatcher.rb +14 -13
  19. data/lib/submodules/ably-ruby/lib/ably/realtime/client.rb +14 -6
  20. data/lib/submodules/ably-ruby/lib/ably/realtime/connection/connection_manager.rb +21 -22
  21. data/lib/submodules/ably-ruby/lib/ably/realtime/connection.rb +77 -109
  22. data/lib/submodules/ably-ruby/lib/ably/realtime/presence/members_map.rb +41 -92
  23. data/lib/submodules/ably-ruby/lib/ably/realtime/presence/presence_manager.rb +12 -17
  24. data/lib/submodules/ably-ruby/lib/ably/realtime/presence.rb +15 -6
  25. data/lib/submodules/ably-ruby/lib/ably/realtime/push.rb +0 -27
  26. data/lib/submodules/ably-ruby/lib/ably/realtime/recovery_key_context.rb +36 -0
  27. data/lib/submodules/ably-ruby/lib/ably/rest/client.rb +4 -6
  28. data/lib/submodules/ably-ruby/lib/ably/rest/push/admin.rb +1 -1
  29. data/lib/submodules/ably-ruby/lib/ably/rest/push.rb +0 -19
  30. data/lib/submodules/ably-ruby/lib/ably/util/ably_extensions.rb +29 -0
  31. data/lib/submodules/ably-ruby/lib/ably/util/crypto.rb +2 -2
  32. data/lib/submodules/ably-ruby/lib/ably/util/safe_deferrable.rb +1 -1
  33. data/lib/submodules/ably-ruby/lib/ably/version.rb +5 -7
  34. data/lib/submodules/ably-ruby/spec/acceptance/realtime/auth_spec.rb +0 -7
  35. data/lib/submodules/ably-ruby/spec/acceptance/realtime/channel_history_spec.rb +8 -12
  36. data/lib/submodules/ably-ruby/spec/acceptance/realtime/channel_spec.rb +474 -300
  37. data/lib/submodules/ably-ruby/spec/acceptance/realtime/client_spec.rb +1 -1
  38. data/lib/submodules/ably-ruby/spec/acceptance/realtime/connection_failures_spec.rb +8 -25
  39. data/lib/submodules/ably-ruby/spec/acceptance/realtime/connection_spec.rb +28 -120
  40. data/lib/submodules/ably-ruby/spec/acceptance/realtime/message_spec.rb +24 -53
  41. data/lib/submodules/ably-ruby/spec/acceptance/realtime/presence_spec.rb +123 -92
  42. data/lib/submodules/ably-ruby/spec/acceptance/rest/channel_spec.rb +2 -2
  43. data/lib/submodules/ably-ruby/spec/acceptance/rest/client_spec.rb +9 -2
  44. data/lib/submodules/ably-ruby/spec/acceptance/rest/message_spec.rb +8 -11
  45. data/lib/submodules/ably-ruby/spec/acceptance/rest/push_admin_spec.rb +20 -15
  46. data/lib/submodules/ably-ruby/spec/shared/client_initializer_behaviour.rb +1 -1
  47. data/lib/submodules/ably-ruby/spec/support/markdown_spec_formatter.rb +1 -1
  48. data/lib/submodules/ably-ruby/spec/unit/models/protocol_message_spec.rb +0 -86
  49. data/lib/submodules/ably-ruby/spec/unit/models/token_details_spec.rb +4 -2
  50. data/lib/submodules/ably-ruby/spec/unit/realtime/channels_spec.rb +1 -1
  51. data/lib/submodules/ably-ruby/spec/unit/realtime/connection_spec.rb +0 -30
  52. data/lib/submodules/ably-ruby/spec/unit/realtime/recovery_key_context_spec.rb +36 -0
  53. data/lib/submodules/ably-ruby/spec/unit/util/crypto_spec.rb +15 -15
  54. metadata +5 -4
  55. data/lib/submodules/ably-ruby/spec/acceptance/realtime/push_spec.rb +0 -27
  56. data/lib/submodules/ably-ruby/spec/acceptance/rest/push_spec.rb +0 -25
@@ -127,14 +127,6 @@ describe Ably::Models::ProtocolMessage do
127
127
  end
128
128
  end
129
129
 
130
- context '#connection_serial' do
131
- let(:protocol_message) { new_protocol_message(connection_serial: "55") }
132
- it 'converts :connection_serial to an Integer' do
133
- expect(protocol_message.connection_serial).to be_a(Integer)
134
- expect(protocol_message.connection_serial).to eql(55)
135
- end
136
- end
137
-
138
130
  context '#flags (#TR4i)' do
139
131
  context 'when nil' do
140
132
  let(:protocol_message) { new_protocol_message({}) }
@@ -241,76 +233,6 @@ describe Ably::Models::ProtocolMessage do
241
233
  end
242
234
  end
243
235
 
244
- context '#has_connection_serial?' do
245
- context 'without connection_serial' do
246
- let(:protocol_message) { new_protocol_message({}) }
247
-
248
- it 'returns false' do
249
- expect(protocol_message.has_connection_serial?).to eql(false)
250
- end
251
- end
252
-
253
- context 'with connection_serial' do
254
- let(:protocol_message) { new_protocol_message(connection_serial: "55") }
255
-
256
- it 'returns true' do
257
- expect(protocol_message.has_connection_serial?).to eql(true)
258
- end
259
- end
260
- end
261
-
262
- context '#serial' do
263
- context 'with underlying msg_serial' do
264
- let(:protocol_message) { new_protocol_message(msg_serial: "55") }
265
- it 'converts :msg_serial to an Integer' do
266
- expect(protocol_message.serial).to be_a(Integer)
267
- expect(protocol_message.serial).to eql(55)
268
- end
269
- end
270
-
271
- context 'with underlying connection_serial' do
272
- let(:protocol_message) { new_protocol_message(connection_serial: "55") }
273
- it 'converts :connection_serial to an Integer' do
274
- expect(protocol_message.serial).to be_a(Integer)
275
- expect(protocol_message.serial).to eql(55)
276
- end
277
- end
278
-
279
- context 'with underlying connection_serial and msg_serial' do
280
- let(:protocol_message) { new_protocol_message(connection_serial: "99", msg_serial: "11") }
281
- it 'prefers connection_serial and converts :connection_serial to an Integer' do
282
- expect(protocol_message.serial).to be_a(Integer)
283
- expect(protocol_message.serial).to eql(99)
284
- end
285
- end
286
- end
287
-
288
- context '#has_serial?' do
289
- context 'without msg_serial or connection_serial' do
290
- let(:protocol_message) { new_protocol_message({}) }
291
-
292
- it 'returns false' do
293
- expect(protocol_message.has_serial?).to eql(false)
294
- end
295
- end
296
-
297
- context 'with msg_serial' do
298
- let(:protocol_message) { new_protocol_message(msg_serial: "55") }
299
-
300
- it 'returns true' do
301
- expect(protocol_message.has_serial?).to eql(true)
302
- end
303
- end
304
-
305
- context 'with connection_serial' do
306
- let(:protocol_message) { new_protocol_message(connection_serial: "55") }
307
-
308
- it 'returns true' do
309
- expect(protocol_message.has_serial?).to eql(true)
310
- end
311
- end
312
- end
313
-
314
236
  context '#error' do
315
237
  context 'with no error attribute' do
316
238
  let(:protocol_message) { new_protocol_message(action: 1) }
@@ -475,14 +397,6 @@ describe Ably::Models::ProtocolMessage do
475
397
  end
476
398
  end
477
399
 
478
- context 'with missing msg_serial for ack message' do
479
- let(:model) { new_protocol_message({ :action => message_action }) }
480
-
481
- it 'it raises an exception' do
482
- expect { model.to_json }.to raise_error TypeError, /msg_serial.*missing/
483
- end
484
- end
485
-
486
400
  context 'is aliased by #to_s' do
487
401
  let(:model) { new_protocol_message({ :action => attached_action, :channelSerial => 'unique', messages: [message1, message2, message3], :timestamp => as_since_epoch(Time.now) }) }
488
402
 
@@ -56,6 +56,7 @@ describe Ably::Models::TokenDetails do
56
56
 
57
57
  context '#expired?' do
58
58
  let(:expire_time) { Time.now + Ably::Models::TokenDetails::TOKEN_EXPIRY_BUFFER }
59
+ let(:clock_skew) { 1 } # clock skew of 1 second
59
60
 
60
61
  context 'once grace period buffer has passed' do
61
62
  subject { Ably::Models::TokenDetails.new(expires: expire_time - 1) }
@@ -74,7 +75,7 @@ describe Ably::Models::TokenDetails do
74
75
  end
75
76
 
76
77
  context 'when expires is not available (i.e. string tokens)' do
77
- subject { Ably::Models::TokenDetails.new() }
78
+ subject { Ably::Models::TokenDetails.new }
78
79
 
79
80
  it 'is always false' do
80
81
  expect(subject.expired?).to eql(false)
@@ -90,8 +91,9 @@ describe Ably::Models::TokenDetails do
90
91
  expect(subject.expired?(from: (Time.now - server_offset_time))).to eql(false)
91
92
  end
92
93
 
94
+ # Test is flaky and fails on CI, so adding a bit of extra tolerance (clock_skew) to make it work
93
95
  it 'is true' do
94
- expect(subject.expired?(from: Time.now)).to eql(true)
96
+ expect(subject.expired?(from: Time.now + clock_skew)).to eql(true)
95
97
  end
96
98
  end
97
99
  end
@@ -2,7 +2,7 @@
2
2
  require 'spec_helper'
3
3
 
4
4
  describe Ably::Realtime::Channels do
5
- let(:connection) { instance_double('Ably::Realtime::Connection', unsafe_on: true, on_resume: true) }
5
+ let(:connection) { instance_double('Ably::Realtime::Connection', unsafe_on: true) }
6
6
  let(:client) do
7
7
  instance_double('Ably::Realtime::Client', connection: connection, client_id: 'clientId', logger: double('logger').as_null_object)
8
8
  end
@@ -34,36 +34,6 @@ describe Ably::Realtime::Connection do
34
34
  it_behaves_like 'an incoming protocol message bus'
35
35
  it_behaves_like 'an outgoing protocol message bus'
36
36
 
37
- describe 'connection resume callbacks', api_private: true do
38
- let(:callbacks) { [] }
39
-
40
- describe '#trigger_resumed' do
41
- it 'executes the callbacks' do
42
- subject.on_resume { callbacks << true }
43
- subject.trigger_resumed
44
- expect(callbacks.count).to eql(1)
45
- end
46
- end
47
-
48
- describe '#on_resume' do
49
- it 'registers a callback' do
50
- subject.on_resume { callbacks << true }
51
- subject.trigger_resumed
52
- expect(callbacks.count).to eql(1)
53
- end
54
- end
55
-
56
- describe '#off_resume' do
57
- it 'registers a callback' do
58
- subject.on_resume { callbacks << true }
59
- additional_proc = lambda { raise 'This should not be called' }
60
- subject.off_resume(&additional_proc)
61
- subject.trigger_resumed
62
- expect(callbacks.count).to eql(1)
63
- end
64
- end
65
- end
66
-
67
37
  after(:all) do
68
38
  sleep 1 # let realtime library shut down any open clients
69
39
  end
@@ -0,0 +1,36 @@
1
+ require 'spec_helper'
2
+ require 'ably/realtime/recovery_key_context'
3
+
4
+ describe Ably::Realtime::RecoveryKeyContext do
5
+
6
+ context 'connection recovery key' do
7
+
8
+ it 'should encode recovery key - RTN16i, RTN16f, RTN16j' do
9
+ connection_key = 'key'
10
+ msg_serial = 123
11
+ channel_serials = {
12
+ 'channel1' => 'serial1',
13
+ 'channel2' => 'serial2'
14
+ }
15
+ recovery_context = Ably::Realtime::RecoveryKeyContext.new(connection_key, msg_serial, channel_serials)
16
+ encoded_recovery_key = recovery_context.to_json
17
+ expect(encoded_recovery_key).to eq "{\"connection_key\":\"key\",\"msg_serial\":123," <<
18
+ "\"channel_serials\":{\"channel1\":\"serial1\",\"channel2\":\"serial2\"}}"
19
+ end
20
+
21
+ it 'should decode recovery key - RTN16i, RTN16f, RTN16j' do
22
+ encoded_recovery_key = "{\"connection_key\":\"key\",\"msg_serial\":123," <<
23
+ "\"channel_serials\":{\"channel1\":\"serial1\",\"channel2\":\"serial2\"}}"
24
+ decoded_recovery_key = Ably::Realtime::RecoveryKeyContext.from_json(encoded_recovery_key)
25
+ expect(decoded_recovery_key.connection_key).to eq("key")
26
+ expect(decoded_recovery_key.msg_serial).to eq(123)
27
+ end
28
+
29
+ it 'should return nil for invalid recovery key - RTN16i, RTN16f, RTN16j' do
30
+ encoded_recovery_key = "{\"invalid key\"}"
31
+ decoded_recovery_key = Ably::Realtime::RecoveryKeyContext.from_json(encoded_recovery_key)
32
+ expect(decoded_recovery_key).to be_nil
33
+ end
34
+
35
+ end
36
+ end
@@ -72,26 +72,26 @@ describe Ably::Util::Crypto do
72
72
  end
73
73
  end
74
74
 
75
- context 'encrypts & decrypt' do
75
+ context '#encrypt & #decrypt' do
76
76
  let(:string) { random_str }
77
- let(:byte_array) { random_str.to_msgpack.unpack('C*') }
78
-
79
- specify '#encrypt encrypts a string' do
80
- encrypted = subject.encrypt(string)
81
- expect(subject.decrypt(encrypted)).to eql(string)
82
- end
77
+ let(:empty_string) { '' }
83
78
 
84
- specify '#decrypt decrypts a string' do
79
+ specify 'encrypts and decrypts a non-empty string' do
80
+ expect(string).to be_ascii_only
85
81
  encrypted = subject.encrypt(string)
86
- expect(subject.decrypt(encrypted)).to eql(string)
82
+ expect(encrypted).to be_truthy
83
+ decrypted = subject.decrypt(encrypted)
84
+ expect(decrypted).to eql(string)
85
+ expect(decrypted).to be_ascii_only
87
86
  end
88
- end
89
-
90
- context 'encrypting an empty string' do
91
- let(:empty_string) { '' }
92
87
 
93
- it 'raises an ArgumentError' do
94
- expect { subject.encrypt(empty_string) }.to raise_error ArgumentError, /data must not be empty/
88
+ specify 'encrypts and decrypts an empty string' do
89
+ expect(empty_string).to be_ascii_only
90
+ encrypted = subject.encrypt(empty_string)
91
+ expect(encrypted).to be_truthy
92
+ decrypted = subject.decrypt(encrypted)
93
+ expect(decrypted).to eql(empty_string)
94
+ expect(decrypted).to be_ascii_only
95
95
  end
96
96
  end
97
97
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ably-rest
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.5
4
+ version: 1.2.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matthew O'Riordan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-05-17 00:00:00.000000000 Z
11
+ date: 2024-09-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -390,6 +390,7 @@ files:
390
390
  - lib/submodules/ably-ruby/lib/ably/realtime/push/admin.rb
391
391
  - lib/submodules/ably-ruby/lib/ably/realtime/push/channel_subscriptions.rb
392
392
  - lib/submodules/ably-ruby/lib/ably/realtime/push/device_registrations.rb
393
+ - lib/submodules/ably-ruby/lib/ably/realtime/recovery_key_context.rb
393
394
  - lib/submodules/ably-ruby/lib/ably/rest.rb
394
395
  - lib/submodules/ably-ruby/lib/ably/rest/channel.rb
395
396
  - lib/submodules/ably-ruby/lib/ably/rest/channel/push_channel.rb
@@ -407,6 +408,7 @@ files:
407
408
  - lib/submodules/ably-ruby/lib/ably/rest/push/admin.rb
408
409
  - lib/submodules/ably-ruby/lib/ably/rest/push/channel_subscriptions.rb
409
410
  - lib/submodules/ably-ruby/lib/ably/rest/push/device_registrations.rb
411
+ - lib/submodules/ably-ruby/lib/ably/util/ably_extensions.rb
410
412
  - lib/submodules/ably-ruby/lib/ably/util/crypto.rb
411
413
  - lib/submodules/ably-ruby/lib/ably/util/pub_sub.rb
412
414
  - lib/submodules/ably-ruby/lib/ably/util/safe_deferrable.rb
@@ -422,7 +424,6 @@ files:
422
424
  - lib/submodules/ably-ruby/spec/acceptance/realtime/presence_history_spec.rb
423
425
  - lib/submodules/ably-ruby/spec/acceptance/realtime/presence_spec.rb
424
426
  - lib/submodules/ably-ruby/spec/acceptance/realtime/push_admin_spec.rb
425
- - lib/submodules/ably-ruby/spec/acceptance/realtime/push_spec.rb
426
427
  - lib/submodules/ably-ruby/spec/acceptance/realtime/stats_spec.rb
427
428
  - lib/submodules/ably-ruby/spec/acceptance/realtime/time_spec.rb
428
429
  - lib/submodules/ably-ruby/spec/acceptance/rest/auth_spec.rb
@@ -434,7 +435,6 @@ files:
434
435
  - lib/submodules/ably-ruby/spec/acceptance/rest/message_spec.rb
435
436
  - lib/submodules/ably-ruby/spec/acceptance/rest/presence_spec.rb
436
437
  - lib/submodules/ably-ruby/spec/acceptance/rest/push_admin_spec.rb
437
- - lib/submodules/ably-ruby/spec/acceptance/rest/push_spec.rb
438
438
  - lib/submodules/ably-ruby/spec/acceptance/rest/stats_spec.rb
439
439
  - lib/submodules/ably-ruby/spec/acceptance/rest/time_spec.rb
440
440
  - lib/submodules/ably-ruby/spec/lib/unit/models/channel_options_spec.rb
@@ -499,6 +499,7 @@ files:
499
499
  - lib/submodules/ably-ruby/spec/unit/realtime/presence_spec.rb
500
500
  - lib/submodules/ably-ruby/spec/unit/realtime/push_channel_spec.rb
501
501
  - lib/submodules/ably-ruby/spec/unit/realtime/realtime_spec.rb
502
+ - lib/submodules/ably-ruby/spec/unit/realtime/recovery_key_context_spec.rb
502
503
  - lib/submodules/ably-ruby/spec/unit/realtime/safe_deferrable_spec.rb
503
504
  - lib/submodules/ably-ruby/spec/unit/realtime/websocket_transport_spec.rb
504
505
  - lib/submodules/ably-ruby/spec/unit/rest/channel_spec.rb
@@ -1,27 +0,0 @@
1
- # encoding: utf-8
2
- require 'spec_helper'
3
-
4
- describe Ably::Realtime::Push, :event_machine do
5
- vary_by_protocol do
6
- let(:default_options) { { key: api_key, environment: environment, protocol: protocol} }
7
- let(:client_options) { default_options }
8
- let(:client) do
9
- Ably::Realtime::Client.new(client_options)
10
- end
11
- subject { client.push }
12
-
13
- describe '#activate' do
14
- it 'raises an unsupported exception' do
15
- expect { subject.activate('foo') }.to raise_error(Ably::Exceptions::PushNotificationsNotSupported)
16
- stop_reactor
17
- end
18
- end
19
-
20
- describe '#deactivate' do
21
- it 'raises an unsupported exception' do
22
- expect { subject.deactivate('foo') }.to raise_error(Ably::Exceptions::PushNotificationsNotSupported)
23
- stop_reactor
24
- end
25
- end
26
- end
27
- end
@@ -1,25 +0,0 @@
1
- # encoding: utf-8
2
- require 'spec_helper'
3
-
4
- describe Ably::Rest::Push do
5
- vary_by_protocol do
6
- let(:default_options) { { key: api_key, environment: environment, protocol: protocol} }
7
- let(:client_options) { default_options }
8
- let(:client) do
9
- Ably::Rest::Client.new(client_options)
10
- end
11
- subject { client.push }
12
-
13
- describe '#activate' do
14
- it 'raises an unsupported exception' do
15
- expect { subject.activate('foo') }.to raise_error(Ably::Exceptions::PushNotificationsNotSupported)
16
- end
17
- end
18
-
19
- describe '#deactivate' do
20
- it 'raises an unsupported exception' do
21
- expect { subject.deactivate('foo') }.to raise_error(Ably::Exceptions::PushNotificationsNotSupported)
22
- end
23
- end
24
- end
25
- end