ably 1.1.6 → 1.2.0

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 (67) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/check.yml +15 -1
  3. data/CHANGELOG.md +131 -0
  4. data/COPYRIGHT +1 -1
  5. data/README.md +14 -2
  6. data/SPEC.md +0 -7
  7. data/UPDATING.md +30 -0
  8. data/ably.gemspec +12 -7
  9. data/lib/ably/agent.rb +3 -0
  10. data/lib/ably/auth.rb +3 -3
  11. data/lib/ably/exceptions.rb +6 -0
  12. data/lib/ably/models/channel_options.rb +97 -0
  13. data/lib/ably/models/connection_details.rb +8 -0
  14. data/lib/ably/models/delta_extras.rb +29 -0
  15. data/lib/ably/models/error_info.rb +6 -2
  16. data/lib/ably/models/idiomatic_ruby_wrapper.rb +4 -0
  17. data/lib/ably/models/message.rb +28 -3
  18. data/lib/ably/models/presence_message.rb +14 -0
  19. data/lib/ably/models/protocol_message.rb +29 -12
  20. data/lib/ably/models/token_details.rb +7 -2
  21. data/lib/ably/modules/channels_collection.rb +22 -2
  22. data/lib/ably/modules/conversions.rb +34 -0
  23. data/lib/ably/realtime/channel/channel_manager.rb +18 -6
  24. data/lib/ably/realtime/channel/channel_state_machine.rb +10 -1
  25. data/lib/ably/realtime/channel/publisher.rb +6 -0
  26. data/lib/ably/realtime/channel.rb +54 -22
  27. data/lib/ably/realtime/channels.rb +1 -1
  28. data/lib/ably/realtime/client/incoming_message_dispatcher.rb +14 -6
  29. data/lib/ably/realtime/connection/connection_manager.rb +13 -4
  30. data/lib/ably/realtime/connection/connection_state_machine.rb +4 -0
  31. data/lib/ably/realtime/connection.rb +2 -2
  32. data/lib/ably/rest/channel.rb +31 -31
  33. data/lib/ably/rest/client.rb +27 -12
  34. data/lib/ably/util/crypto.rb +1 -1
  35. data/lib/ably/version.rb +2 -14
  36. data/lib/ably.rb +1 -0
  37. data/spec/acceptance/realtime/auth_spec.rb +1 -1
  38. data/spec/acceptance/realtime/channel_history_spec.rb +25 -0
  39. data/spec/acceptance/realtime/channel_spec.rb +466 -21
  40. data/spec/acceptance/realtime/channels_spec.rb +59 -7
  41. data/spec/acceptance/realtime/connection_failures_spec.rb +59 -2
  42. data/spec/acceptance/realtime/connection_spec.rb +256 -28
  43. data/spec/acceptance/realtime/message_spec.rb +77 -0
  44. data/spec/acceptance/realtime/presence_history_spec.rb +3 -1
  45. data/spec/acceptance/realtime/presence_spec.rb +31 -159
  46. data/spec/acceptance/rest/auth_spec.rb +18 -0
  47. data/spec/acceptance/rest/channel_spec.rb +84 -9
  48. data/spec/acceptance/rest/channels_spec.rb +23 -6
  49. data/spec/acceptance/rest/client_spec.rb +25 -21
  50. data/spec/acceptance/rest/message_spec.rb +61 -3
  51. data/spec/lib/unit/models/channel_options_spec.rb +52 -0
  52. data/spec/shared/model_behaviour.rb +1 -1
  53. data/spec/spec_helper.rb +11 -2
  54. data/spec/support/test_app.rb +1 -1
  55. data/spec/unit/models/delta_extras_spec.rb +14 -0
  56. data/spec/unit/models/error_info_spec.rb +17 -1
  57. data/spec/unit/models/message_spec.rb +97 -0
  58. data/spec/unit/models/presence_message_spec.rb +49 -0
  59. data/spec/unit/models/protocol_message_spec.rb +125 -27
  60. data/spec/unit/models/token_details_spec.rb +14 -0
  61. data/spec/unit/realtime/channel_spec.rb +3 -2
  62. data/spec/unit/realtime/channels_spec.rb +53 -15
  63. data/spec/unit/realtime/incoming_message_dispatcher_spec.rb +38 -0
  64. data/spec/unit/rest/channel_spec.rb +44 -1
  65. data/spec/unit/rest/channels_spec.rb +81 -14
  66. data/spec/unit/rest/client_spec.rb +47 -0
  67. metadata +60 -24
@@ -7,10 +7,11 @@ describe Ably::Rest::Channel do
7
7
  'Ably::Rest::Client',
8
8
  encoders: [],
9
9
  post: instance_double('Faraday::Response', status: 201),
10
- idempotent_rest_publishing: false,
10
+ idempotent_rest_publishing: false, max_message_size: max_message_size
11
11
  )
12
12
  end
13
13
  let(:channel_name) { 'unique' }
14
+ let(:max_message_size) { nil }
14
15
 
15
16
  subject { Ably::Rest::Channel.new(client, channel_name) }
16
17
 
@@ -126,5 +127,47 @@ describe Ably::Rest::Channel do
126
127
  expect { subject.publish(encoded_value, 'data') }.to raise_error ArgumentError, /must be a String/
127
128
  end
128
129
  end
130
+
131
+ context 'max message size exceeded' do
132
+ context 'when max_message_size is nil' do
133
+ context 'and a message size is 65537 bytes' do
134
+ it 'should raise Ably::Exceptions::MaxMessageSizeExceeded' do
135
+ expect { subject.publish('x' * 65537, 'data') }.to raise_error Ably::Exceptions::MaxMessageSizeExceeded
136
+ end
137
+ end
138
+ end
139
+
140
+ context 'when max_message_size is 65536 bytes' do
141
+ let(:max_message_size) { 65536 }
142
+
143
+ context 'and a message size is 65537 bytes' do
144
+ it 'should raise Ably::Exceptions::MaxMessageSizeExceeded' do
145
+ expect { subject.publish('x' * 65537, 'data') }.to raise_error Ably::Exceptions::MaxMessageSizeExceeded
146
+ end
147
+ end
148
+
149
+ context 'and a message size is 10 bytes' do
150
+ it 'should send a message' do
151
+ expect(subject.publish('x' * 10, 'data')).to eq(true)
152
+ end
153
+ end
154
+ end
155
+
156
+ context 'when max_message_size is 10 bytes' do
157
+ let(:max_message_size) { 10 }
158
+
159
+ context 'and a message size is 11 bytes' do
160
+ it 'should raise Ably::Exceptions::MaxMessageSizeExceeded' do
161
+ expect { subject.publish('x' * 11, 'data') }.to raise_error Ably::Exceptions::MaxMessageSizeExceeded
162
+ end
163
+ end
164
+
165
+ context 'and a message size is 2 bytes' do
166
+ it 'should send a message' do
167
+ expect(subject.publish('x' * 2, 'data')).to eq(true)
168
+ end
169
+ end
170
+ end
171
+ end
129
172
  end
130
173
  end
@@ -2,30 +2,97 @@
2
2
  require 'spec_helper'
3
3
 
4
4
  describe Ably::Rest::Channels do
5
- let(:client) { instance_double('Ably::Rest::Client') }
5
+ let(:client) { instance_double('Ably::Rest::Client', logger: double('logger').as_null_object) }
6
6
  let(:channel_name) { 'unique'.encode(Encoding::UTF_8) }
7
- let(:options) { { 'bizarre' => 'value' } }
7
+ let(:options) do
8
+ { params: { 'bizarre' => 'value' } }
9
+ end
8
10
 
9
11
  subject { Ably::Rest::Channels.new(client) }
10
12
 
11
- context 'creating channels' do
12
- it '#get creates a channel' do
13
- expect(Ably::Rest::Channel).to receive(:new).with(client, channel_name, options)
14
- subject.get(channel_name, options)
15
- end
13
+ describe '#get' do
14
+ context "when channel doesn't exist" do
15
+ shared_examples 'creates a channel' do
16
+ it 'creates a channel (RSN3a)' do
17
+ expect(Ably::Rest::Channel).to receive(:new).with(client, channel_name, options)
18
+ subject.get(channel_name, options)
19
+ end
20
+ end
16
21
 
17
- it '#get will reuse the channel object' do
18
- channel = subject.get(channel_name, options)
19
- expect(channel).to be_a(Ably::Rest::Channel)
20
- expect(subject.get(channel_name, options).object_id).to eql(channel.object_id)
22
+ describe 'hash' do
23
+ let(:channel_options) { options }
24
+ it { expect(channel_options).to be_a(Hash) }
25
+
26
+ include_examples 'creates a channel'
27
+ end
28
+
29
+ describe 'ChannelOptions object' do
30
+ let(:channel_options) { Ably::Models::ChannelOptions.new(options) }
31
+ it { expect(channel_options).to be_a(Ably::Models::ChannelOptions) }
32
+
33
+ include_examples 'creates a channel'
34
+ end
21
35
  end
22
36
 
23
- it '[] creates a channel' do
24
- expect(Ably::Rest::Channel).to receive(:new).with(client, channel_name, options)
25
- subject.get(channel_name, options)
37
+ context 'when an existing channel exists' do
38
+ shared_examples 'reuse a channel object if it exists' do
39
+ it 'will reuse a channel object if it exists (RSN3a)' do
40
+ channel = subject.get(channel_name, channel_options)
41
+ expect(channel).to be_a(Ably::Rest::Channel)
42
+ expect(subject.get(channel_name, channel_options).object_id).to eql(channel.object_id)
43
+ end
44
+ end
45
+
46
+ describe 'hash' do
47
+ let(:channel_options) { options }
48
+ it { expect(channel_options).to be_a(Hash) }
49
+
50
+ include_examples 'reuse a channel object if it exists'
51
+ end
52
+
53
+ describe 'ChannelOptions object' do
54
+ let(:channel_options) { Ably::Models::ChannelOptions.new(options) }
55
+ it { expect(channel_options).to be_a(Ably::Models::ChannelOptions) }
56
+
57
+ include_examples 'reuse a channel object if it exists'
58
+ end
59
+
60
+ context 'with new channel_options modes' do
61
+ shared_examples 'update channel with provided options :modes' do
62
+ it 'will update channel with provided options modes (RSN3c)' do
63
+ channel = subject.get(channel_name, channel_options)
64
+ expect(channel.options.modes).to eq(modes)
65
+
66
+ subject.get(channel_name, channel_options)
67
+ expect(channel.options.modes).to eq(modes)
68
+ end
69
+ end
70
+
71
+ let(:modes) { %i[subscribe] }
72
+ let(:new_options) { { modes: modes } }
73
+
74
+ describe 'hash' do
75
+ let(:channel_options) { new_options }
76
+ it { expect(channel_options).to be_a(Hash) }
77
+
78
+ include_examples 'update channel with provided options :modes'
79
+ end
80
+
81
+ describe 'ChannelOptions object' do
82
+ let(:channel_options) { Ably::Models::ChannelOptions.new(new_options) }
83
+ it { expect(channel_options).to be_a(Ably::Models::ChannelOptions) }
84
+
85
+ include_examples 'update channel with provided options :modes'
86
+ end
87
+ end
26
88
  end
27
89
  end
28
90
 
91
+ it '[] creates a channel' do
92
+ expect(Ably::Rest::Channel).to receive(:new).with(client, channel_name, options)
93
+ subject.get(channel_name, options)
94
+ end
95
+
29
96
  context '#fetch' do
30
97
  it 'retrieves a channel if it exists' do
31
98
  channel = subject.get(channel_name, options)
@@ -38,6 +38,26 @@ describe Ably::Rest::Client do
38
38
  end
39
39
  end
40
40
 
41
+ context 'use agent' do
42
+ context 'set agent to non-default value' do
43
+ context 'default agent' do
44
+ let(:client_options) { { key: 'appid.keyuid:keysecret' } }
45
+
46
+ it 'should return default ably agent' do
47
+ expect(subject.agent).to eq(Ably::AGENT)
48
+ end
49
+ end
50
+
51
+ context 'custom agent' do
52
+ let(:client_options) { { key: 'appid.keyuid:keysecret', agent: 'example-gem/1.1.4 ably-ruby/1.1.5 ruby/3.0.0' } }
53
+
54
+ it 'should overwrite client.agent' do
55
+ expect(subject.agent).to eq('example-gem/1.1.4 ably-ruby/1.1.5 ruby/3.0.0')
56
+ end
57
+ end
58
+ end
59
+ end
60
+
41
61
  context ':use_token_auth' do
42
62
  context 'set to false' do
43
63
  context 'with a key and :tls => false' do
@@ -67,6 +87,33 @@ describe Ably::Rest::Client do
67
87
  end
68
88
  end
69
89
  end
90
+
91
+ context 'max_message_size' do
92
+ context 'is not present' do
93
+ let(:client_options) { { key: 'appid.keyuid:keysecret' } }
94
+
95
+ it 'should return default 65536 (#TO3l8)' do
96
+ expect(subject.max_message_size).to eq(Ably::Rest::Client::MAX_MESSAGE_SIZE)
97
+ end
98
+ end
99
+
100
+ context 'is nil' do
101
+ let(:client_options) { { key: 'appid.keyuid:keysecret', max_message_size: nil } }
102
+
103
+ it 'should return default 65536 (#TO3l8)' do
104
+ expect(Ably::Rest::Client::MAX_MESSAGE_SIZE).to eq(65536)
105
+ expect(subject.max_message_size).to eq(Ably::Rest::Client::MAX_MESSAGE_SIZE)
106
+ end
107
+ end
108
+
109
+ context 'is customized 131072 bytes' do
110
+ let(:client_options) { { key: 'appid.keyuid:keysecret', max_message_size: 131072 } }
111
+
112
+ it 'should return 131072' do
113
+ expect(subject.max_message_size).to eq(131072)
114
+ end
115
+ end
116
+ end
70
117
  end
71
118
 
72
119
  context 'request_id generation' do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ably
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.6
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lewis Marshall
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2021-05-25 00:00:00.000000000 Z
12
+ date: 2022-04-05 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: eventmachine
@@ -45,14 +45,14 @@ dependencies:
45
45
  requirements:
46
46
  - - "~>"
47
47
  - !ruby/object:Gem::Version
48
- version: '7.4'
48
+ version: '8.0'
49
49
  type: :runtime
50
50
  prerelease: false
51
51
  version_requirements: !ruby/object:Gem::Requirement
52
52
  requirements:
53
53
  - - "~>"
54
54
  - !ruby/object:Gem::Version
55
- version: '7.4'
55
+ version: '8.0'
56
56
  - !ruby/object:Gem::Dependency
57
57
  name: faraday
58
58
  requirement: !ruby/object:Gem::Requirement
@@ -143,14 +143,14 @@ dependencies:
143
143
  requirements:
144
144
  - - "~>"
145
145
  - !ruby/object:Gem::Version
146
- version: '11.3'
146
+ version: '13.0'
147
147
  type: :development
148
148
  prerelease: false
149
149
  version_requirements: !ruby/object:Gem::Requirement
150
150
  requirements:
151
151
  - - "~>"
152
152
  - !ruby/object:Gem::Version
153
- version: '11.3'
153
+ version: '13.0'
154
154
  - !ruby/object:Gem::Dependency
155
155
  name: redcarpet
156
156
  requirement: !ruby/object:Gem::Requirement
@@ -171,14 +171,14 @@ dependencies:
171
171
  requirements:
172
172
  - - "~>"
173
173
  - !ruby/object:Gem::Version
174
- version: 3.3.0
174
+ version: 3.10.0
175
175
  type: :development
176
176
  prerelease: false
177
177
  version_requirements: !ruby/object:Gem::Requirement
178
178
  requirements:
179
179
  - - "~>"
180
180
  - !ruby/object:Gem::Version
181
- version: 3.3.0
181
+ version: 3.10.0
182
182
  - !ruby/object:Gem::Dependency
183
183
  name: rspec-retry
184
184
  requirement: !ruby/object:Gem::Requirement
@@ -250,61 +250,89 @@ dependencies:
250
250
  - !ruby/object:Gem::Version
251
251
  version: '3.11'
252
252
  - !ruby/object:Gem::Dependency
253
- name: coveralls
253
+ name: simplecov
254
254
  requirement: !ruby/object:Gem::Requirement
255
255
  requirements:
256
- - - ">="
256
+ - - "~>"
257
257
  - !ruby/object:Gem::Version
258
- version: '0'
258
+ version: 0.21.2
259
259
  type: :development
260
260
  prerelease: false
261
261
  version_requirements: !ruby/object:Gem::Requirement
262
262
  requirements:
263
- - - ">="
263
+ - - "~>"
264
264
  - !ruby/object:Gem::Version
265
- version: '0'
265
+ version: 0.21.2
266
+ - !ruby/object:Gem::Dependency
267
+ name: simplecov-lcov
268
+ requirement: !ruby/object:Gem::Requirement
269
+ requirements:
270
+ - - "~>"
271
+ - !ruby/object:Gem::Version
272
+ version: 0.8.0
273
+ type: :development
274
+ prerelease: false
275
+ version_requirements: !ruby/object:Gem::Requirement
276
+ requirements:
277
+ - - "~>"
278
+ - !ruby/object:Gem::Version
279
+ version: 0.8.0
266
280
  - !ruby/object:Gem::Dependency
267
281
  name: parallel_tests
268
282
  requirement: !ruby/object:Gem::Requirement
269
283
  requirements:
270
284
  - - "~>"
271
285
  - !ruby/object:Gem::Version
272
- version: '2.22'
286
+ version: '3.7'
273
287
  type: :development
274
288
  prerelease: false
275
289
  version_requirements: !ruby/object:Gem::Requirement
276
290
  requirements:
277
291
  - - "~>"
278
292
  - !ruby/object:Gem::Version
279
- version: '2.22'
293
+ version: '3.7'
280
294
  - !ruby/object:Gem::Dependency
281
295
  name: pry
282
296
  requirement: !ruby/object:Gem::Requirement
283
297
  requirements:
284
- - - ">="
298
+ - - "~>"
285
299
  - !ruby/object:Gem::Version
286
- version: '0'
300
+ version: 0.14.1
287
301
  type: :development
288
302
  prerelease: false
289
303
  version_requirements: !ruby/object:Gem::Requirement
290
304
  requirements:
291
- - - ">="
305
+ - - "~>"
292
306
  - !ruby/object:Gem::Version
293
- version: '0'
307
+ version: 0.14.1
294
308
  - !ruby/object:Gem::Dependency
295
309
  name: pry-byebug
296
310
  requirement: !ruby/object:Gem::Requirement
297
311
  requirements:
298
- - - ">="
312
+ - - "~>"
299
313
  - !ruby/object:Gem::Version
300
- version: '0'
314
+ version: 3.8.0
301
315
  type: :development
302
316
  prerelease: false
303
317
  version_requirements: !ruby/object:Gem::Requirement
304
318
  requirements:
305
- - - ">="
319
+ - - "~>"
306
320
  - !ruby/object:Gem::Version
307
- version: '0'
321
+ version: 3.8.0
322
+ - !ruby/object:Gem::Dependency
323
+ name: webrick
324
+ requirement: !ruby/object:Gem::Requirement
325
+ requirements:
326
+ - - "~>"
327
+ - !ruby/object:Gem::Version
328
+ version: 1.7.0
329
+ type: :development
330
+ prerelease: false
331
+ version_requirements: !ruby/object:Gem::Requirement
332
+ requirements:
333
+ - - "~>"
334
+ - !ruby/object:Gem::Version
335
+ version: 1.7.0
308
336
  description: A Ruby client library for ably.io realtime messaging
309
337
  email:
310
338
  - lewis@lmars.net
@@ -326,16 +354,20 @@ files:
326
354
  - README.md
327
355
  - Rakefile
328
356
  - SPEC.md
357
+ - UPDATING.md
329
358
  - ably.gemspec
330
359
  - lib/ably.rb
360
+ - lib/ably/agent.rb
331
361
  - lib/ably/auth.rb
332
362
  - lib/ably/exceptions.rb
333
363
  - lib/ably/logger.rb
334
364
  - lib/ably/models/auth_details.rb
365
+ - lib/ably/models/channel_options.rb
335
366
  - lib/ably/models/channel_state_change.rb
336
367
  - lib/ably/models/cipher_params.rb
337
368
  - lib/ably/models/connection_details.rb
338
369
  - lib/ably/models/connection_state_change.rb
370
+ - lib/ably/models/delta_extras.rb
339
371
  - lib/ably/models/device_details.rb
340
372
  - lib/ably/models/device_push_details.rb
341
373
  - lib/ably/models/error_info.rb
@@ -447,6 +479,7 @@ files:
447
479
  - spec/acceptance/rest/push_spec.rb
448
480
  - spec/acceptance/rest/stats_spec.rb
449
481
  - spec/acceptance/rest/time_spec.rb
482
+ - spec/lib/unit/models/channel_options_spec.rb
450
483
  - spec/rspec_config.rb
451
484
  - spec/run_parallel_tests
452
485
  - spec/shared/client_initializer_behaviour.rb
@@ -473,6 +506,7 @@ files:
473
506
  - spec/unit/models/cipher_params_spec.rb
474
507
  - spec/unit/models/connection_details_spec.rb
475
508
  - spec/unit/models/connection_state_change_spec.rb
509
+ - spec/unit/models/delta_extras_spec.rb
476
510
  - spec/unit/models/device_details_spec.rb
477
511
  - spec/unit/models/device_push_details_spec.rb
478
512
  - spec/unit/models/error_info_spec.rb
@@ -531,7 +565,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
531
565
  - !ruby/object:Gem::Version
532
566
  version: '0'
533
567
  requirements: []
534
- rubygems_version: 3.0.3
568
+ rubygems_version: 3.3.7
535
569
  signing_key:
536
570
  specification_version: 4
537
571
  summary: A Ruby client library for ably.io realtime messaging implemented using EventMachine
@@ -562,6 +596,7 @@ test_files:
562
596
  - spec/acceptance/rest/push_spec.rb
563
597
  - spec/acceptance/rest/stats_spec.rb
564
598
  - spec/acceptance/rest/time_spec.rb
599
+ - spec/lib/unit/models/channel_options_spec.rb
565
600
  - spec/rspec_config.rb
566
601
  - spec/run_parallel_tests
567
602
  - spec/shared/client_initializer_behaviour.rb
@@ -588,6 +623,7 @@ test_files:
588
623
  - spec/unit/models/cipher_params_spec.rb
589
624
  - spec/unit/models/connection_details_spec.rb
590
625
  - spec/unit/models/connection_state_change_spec.rb
626
+ - spec/unit/models/delta_extras_spec.rb
591
627
  - spec/unit/models/device_details_spec.rb
592
628
  - spec/unit/models/device_push_details_spec.rb
593
629
  - spec/unit/models/error_info_spec.rb