ably 1.1.7 → 1.1.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +59 -0
  3. data/COPYRIGHT +1 -1
  4. data/SPEC.md +0 -7
  5. data/ably.gemspec +1 -1
  6. data/lib/ably/models/connection_details.rb +8 -2
  7. data/lib/ably/models/delta_extras.rb +29 -0
  8. data/lib/ably/models/error_info.rb +6 -2
  9. data/lib/ably/models/message.rb +11 -0
  10. data/lib/ably/models/protocol_message.rb +5 -8
  11. data/lib/ably/realtime/channel/channel_state_machine.rb +5 -1
  12. data/lib/ably/realtime/channel/publisher.rb +3 -2
  13. data/lib/ably/realtime/channel.rb +2 -0
  14. data/lib/ably/realtime/connection/connection_manager.rb +13 -4
  15. data/lib/ably/realtime/connection/connection_state_machine.rb +4 -0
  16. data/lib/ably/realtime/connection.rb +0 -3
  17. data/lib/ably/rest/channel.rb +4 -3
  18. data/lib/ably/rest/client.rb +16 -4
  19. data/lib/ably/version.rb +1 -1
  20. data/spec/acceptance/realtime/channel_spec.rb +212 -7
  21. data/spec/acceptance/realtime/connection_failures_spec.rb +56 -1
  22. data/spec/acceptance/realtime/connection_spec.rb +249 -0
  23. data/spec/acceptance/realtime/presence_spec.rb +18 -1
  24. data/spec/acceptance/rest/channel_spec.rb +73 -11
  25. data/spec/acceptance/rest/channels_spec.rb +1 -1
  26. data/spec/support/test_app.rb +1 -1
  27. data/spec/unit/models/delta_extras_spec.rb +14 -0
  28. data/spec/unit/models/error_info_spec.rb +17 -1
  29. data/spec/unit/models/message_spec.rb +24 -0
  30. data/spec/unit/models/protocol_message_spec.rb +24 -20
  31. data/spec/unit/realtime/channel_spec.rb +2 -1
  32. data/spec/unit/realtime/channels_spec.rb +3 -3
  33. data/spec/unit/rest/channel_spec.rb +40 -7
  34. data/spec/unit/rest/client_spec.rb +27 -0
  35. metadata +7 -4
@@ -5,11 +5,13 @@ describe Ably::Rest::Channel do
5
5
  include Ably::Modules::Conversions
6
6
 
7
7
  vary_by_protocol do
8
- let(:default_options) { { key: api_key, environment: environment, protocol: protocol} }
8
+ let(:default_options) { { key: api_key, environment: environment, protocol: protocol, max_frame_size: max_frame_size, max_message_size: max_message_size } }
9
9
  let(:client_options) { default_options }
10
10
  let(:client) do
11
11
  Ably::Rest::Client.new(client_options)
12
12
  end
13
+ let(:max_message_size) { nil }
14
+ let(:max_frame_size) { nil }
13
15
 
14
16
  describe '#publish' do
15
17
  let(:channel_name) { random_str }
@@ -60,7 +62,8 @@ describe Ably::Rest::Channel do
60
62
  end
61
63
 
62
64
  it 'publishes an array of messages in one HTTP request' do
63
- expect(messages.sum(&:size) < Ably::Rest::Channel::MAX_MESSAGE_SIZE).to eq(true)
65
+ expect(client.max_message_size).to eq(Ably::Rest::Client::MAX_MESSAGE_SIZE)
66
+ expect(messages.sum(&:size) < Ably::Rest::Client::MAX_MESSAGE_SIZE).to eq(true)
64
67
 
65
68
  expect(client).to receive(:post).once.and_call_original
66
69
  expect(channel.publish(messages)).to eql(true)
@@ -70,19 +73,78 @@ describe Ably::Rest::Channel do
70
73
  end
71
74
 
72
75
  context 'with an array of Message objects' do
73
- let(:messages) do
74
- 10.times.map do |index|
75
- Ably::Models::Message(name: index.to_s, data: { "index" => index + 10 })
76
+ context 'when max_message_size and max_frame_size is not set' do
77
+ before do
78
+ expect(client.max_message_size).to eq(Ably::Rest::Client::MAX_MESSAGE_SIZE)
79
+ expect(client.max_frame_size).to eq(Ably::Rest::Client::MAX_FRAME_SIZE)
80
+ end
81
+
82
+ context 'and messages size (130 bytes) is smaller than the max_message_size' do
83
+ let(:messages) do
84
+ 10.times.map do |index|
85
+ Ably::Models::Message(name: index.to_s, data: { "index" => index + 10 })
86
+ end
87
+ end
88
+
89
+ it 'publishes an array of messages in one HTTP request' do
90
+ expect(messages.sum &:size).to eq(130)
91
+ expect(client).to receive(:post).once.and_call_original
92
+ expect(channel.publish(messages)).to eql(true)
93
+ expect(channel.history.items.map(&:name)).to match_array(messages.map(&:name))
94
+ expect(channel.history.items.map(&:data)).to match_array(messages.map(&:data))
95
+ end
96
+ end
97
+
98
+ context 'and messages size (177784 bytes) is bigger than the max_message_size' do
99
+ let(:messages) do
100
+ 10000.times.map do |index|
101
+ Ably::Models::Message(name: index.to_s, data: { "index" => index + 1 })
102
+ end
103
+ end
104
+
105
+ it 'should not publish and raise Ably::Exceptions::MaxMessageSizeExceeded' do
106
+ expect(messages.sum &:size).to eq(177784)
107
+ expect { channel.publish(messages) }.to raise_error(Ably::Exceptions::MaxMessageSizeExceeded)
108
+ end
76
109
  end
77
110
  end
78
111
 
79
- it 'publishes an array of messages in one HTTP request' do
80
- expect(messages.sum(&:size) < Ably::Rest::Channel::MAX_MESSAGE_SIZE).to eq(true)
112
+ context 'when max_message_size is 655 bytes' do
113
+ let(:max_message_size) { 655 }
81
114
 
82
- expect(client).to receive(:post).once.and_call_original
83
- expect(channel.publish(messages)).to eql(true)
84
- expect(channel.history.items.map(&:name)).to match_array(messages.map(&:name))
85
- expect(channel.history.items.map(&:data)).to match_array(messages.map(&:data))
115
+ before do
116
+ expect(client.max_message_size).to eq(max_message_size)
117
+ expect(client.max_frame_size).to eq(Ably::Rest::Client::MAX_FRAME_SIZE)
118
+ end
119
+
120
+ context 'and messages size (130 bytes) is smaller than the max_message_size' do
121
+ let(:messages) do
122
+ 10.times.map do |index|
123
+ Ably::Models::Message(name: index.to_s, data: { "index" => index + 10 })
124
+ end
125
+ end
126
+
127
+ it 'publishes an array of messages in one HTTP request' do
128
+ expect(messages.sum &:size).to eq(130)
129
+ expect(client).to receive(:post).once.and_call_original
130
+ expect(channel.publish(messages)).to eql(true)
131
+ expect(channel.history.items.map(&:name)).to match_array(messages.map(&:name))
132
+ expect(channel.history.items.map(&:data)).to match_array(messages.map(&:data))
133
+ end
134
+ end
135
+
136
+ context 'and messages size (177784 bytes) is bigger than the max_message_size' do
137
+ let(:messages) do
138
+ 10000.times.map do |index|
139
+ Ably::Models::Message(name: index.to_s, data: { "index" => index + 1 })
140
+ end
141
+ end
142
+
143
+ it 'should not publish and raise Ably::Exceptions::MaxMessageSizeExceeded' do
144
+ expect(messages.sum &:size).to eq(177784)
145
+ expect { channel.publish(messages) }.to raise_error(Ably::Exceptions::MaxMessageSizeExceeded)
146
+ end
147
+ end
86
148
  end
87
149
  end
88
150
 
@@ -36,7 +36,7 @@ describe Ably::Rest::Channels do
36
36
  let(:new_channel_options) { { encrypted: true } }
37
37
  let(:original_channel) { client.channels.get(channel_name, options) }
38
38
 
39
- it 'overrides the existing channel options and returns the channel object' do
39
+ it 'overrides the existing channel options and returns the channel object (RSN3c)' do
40
40
  expect(original_channel.options).to_not include(:encrypted)
41
41
  new_channel = client.channels.get(channel_name, new_channel_options)
42
42
  expect(new_channel).to be_a(Ably::Rest::Channel)
@@ -59,7 +59,7 @@ class TestApp
59
59
 
60
60
  url = "#{sandbox_client.endpoint}/apps/#{app_id}"
61
61
 
62
- basic_auth = Base64.encode64(api_key).chomp
62
+ basic_auth = Base64.urlsafe_encode64(api_key).chomp
63
63
  headers = { "Authorization" => "Basic #{basic_auth}" }
64
64
 
65
65
  Faraday.delete(url, nil, headers)
@@ -0,0 +1,14 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+
4
+ describe Ably::Models::DeltaExtras do
5
+ subject { described_class.new({ format: 'vcdiff', from: '1234-4567-8910-1001-1111'}) }
6
+
7
+ it 'should have `from` attribute' do
8
+ expect(subject.from).to eq('1234-4567-8910-1001-1111')
9
+ end
10
+
11
+ it 'should have `format` attribute' do
12
+ expect(subject.format).to eq('vcdiff')
13
+ end
14
+ end
@@ -5,7 +5,7 @@ describe Ably::Models::ErrorInfo do
5
5
  subject { Ably::Models::ErrorInfo }
6
6
 
7
7
  context '#TI1, #TI4' do
8
- it_behaves_like 'a model', with_simple_attributes: %w(code status_code href message) do
8
+ it_behaves_like 'a model', with_simple_attributes: %w(code status_code href message request_id cause) do
9
9
  let(:model_args) { [] }
10
10
  end
11
11
  end
@@ -18,6 +18,22 @@ describe Ably::Models::ErrorInfo do
18
18
  end
19
19
  end
20
20
 
21
+ context '#request_id #RSC7c' do
22
+ subject { Ably::Models::ErrorInfo.new('request_id' => '123-456-789-001') }
23
+
24
+ it 'should return request ID' do
25
+ expect(subject.request_id).to eql('123-456-789-001')
26
+ end
27
+ end
28
+
29
+ context '#cause #TI1' do
30
+ subject { Ably::Models::ErrorInfo.new('cause' => Ably::Models::ErrorInfo.new({})) }
31
+
32
+ it 'should return cause attribute' do
33
+ expect(subject.cause).to be_kind_of(Ably::Models::ErrorInfo)
34
+ end
35
+ end
36
+
21
37
  context 'log entries container help link #TI5' do
22
38
  context 'without an error code' do
23
39
  subject { Ably::Models::ErrorInfo.new('statusCode' => 401) }
@@ -606,4 +606,28 @@ describe Ably::Models::Message do
606
606
  end
607
607
  end
608
608
  end
609
+
610
+ context '#delta_extras (TM2i)' do
611
+ let(:delta_extras) { message.delta_extras }
612
+
613
+ context 'when delta' do
614
+ let(:message) { subject.new({ extras: { delta: { from: '1234-1234-5678-9009', format: 'vcdiff' } } }) }
615
+
616
+ it 'should return vcdiff format' do
617
+ expect(delta_extras.format).to eq('vcdiff')
618
+ end
619
+
620
+ it 'should return 1234-1234-5678-9009 message id' do
621
+ expect(delta_extras.from).to eq('1234-1234-5678-9009')
622
+ end
623
+ end
624
+
625
+ context 'when no delta' do
626
+ let(:message) { subject.new({ extras: {} }) }
627
+
628
+ it 'should return nil' do
629
+ expect(delta_extras).to eq(nil)
630
+ end
631
+ end
632
+ end
609
633
  end
@@ -10,9 +10,9 @@ describe Ably::Models::ProtocolMessage do
10
10
  subject.new({ action: 1 }.merge(options))
11
11
  end
12
12
 
13
- # TR4n, TR4b, TR4c, TR4d, TR4e
13
+ # TR4n, TR4b, TR4c, TR4d
14
14
  it_behaves_like 'a model',
15
- with_simple_attributes: %w(id channel channel_serial connection_id connection_key),
15
+ with_simple_attributes: %w(id channel channel_serial connection_id),
16
16
  base_model_options: { action: 1 } do
17
17
 
18
18
  let(:model_args) { [] }
@@ -176,6 +176,28 @@ describe Ably::Models::ProtocolMessage do
176
176
  end
177
177
  end
178
178
 
179
+ context 'when attach resumed flag' do
180
+ context 'flags is 34' do
181
+ let(:protocol_message) { new_protocol_message(flags: 34) }
182
+
183
+ it '#has_attach_resume_flag? is true' do
184
+ expect(protocol_message.has_attach_resume_flag?).to be_truthy
185
+ end
186
+
187
+ it '#has_attach_presence_flag? is false' do
188
+ expect(protocol_message.has_attach_presence_flag?).to be_falsey
189
+ end
190
+ end
191
+
192
+ context 'flags is 0' do
193
+ let(:protocol_message) { new_protocol_message(flags: 0) }
194
+
195
+ it 'should raise an exception if flags is a float number' do
196
+ expect(protocol_message.has_attach_resume_flag?).to be_falsy
197
+ end
198
+ end
199
+ end
200
+
179
201
  context 'when channel resumed and presence flags present' do
180
202
  let(:protocol_message) { new_protocol_message(flags: 5) }
181
203
 
@@ -417,24 +439,6 @@ describe Ably::Models::ProtocolMessage do
417
439
  end
418
440
  end
419
441
  end
420
-
421
- context '#connection_key (#TR4e)' do
422
- context 'existing only in #connection_details.connection_key' do
423
- let(:protocol_message) { new_protocol_message(connectionDetails: { connectionKey: 'key' }) }
424
-
425
- it 'is returned' do
426
- expect(protocol_message.connection_key).to eql('key')
427
- end
428
- end
429
-
430
- context 'existing in both #connection_key and #connection_details.connection_key' do
431
- let(:protocol_message) { new_protocol_message(connectionKey: 'deprecated', connectionDetails: { connectionKey: 'key' }) }
432
-
433
- it 'returns #connection_details.connection_key as #connection_key will be deprecated > 0.8' do
434
- expect(protocol_message.connection_key).to eql('key')
435
- end
436
- end
437
- end
438
442
  end
439
443
 
440
444
  context '#to_json', :api_private do
@@ -3,7 +3,7 @@ require 'spec_helper'
3
3
  require 'shared/protocol_msgbus_behaviour'
4
4
 
5
5
  describe Ably::Realtime::Channel do
6
- let(:client) { double('client').as_null_object }
6
+ let(:client) { Ably::Realtime::Client.new(token: 'valid') }
7
7
  let(:channel_name) { 'test' }
8
8
 
9
9
  subject do
@@ -71,6 +71,7 @@ describe Ably::Realtime::Channel do
71
71
  let(:message) { instance_double('Ably::Models::Message', client_id: nil, size: 0) }
72
72
 
73
73
  before do
74
+ allow(subject).to receive(:enqueue_messages_on_connection).and_return(message)
74
75
  allow(subject).to receive(:create_message).and_return(message)
75
76
  allow(subject).to receive(:attach).and_return(:true)
76
77
  end
@@ -11,19 +11,19 @@ describe Ably::Realtime::Channels do
11
11
 
12
12
  context 'creating channels' do
13
13
  context '#get' do
14
- it 'creates a channel if it does not exist' do
14
+ it 'creates a channel if it does not exist (RSN3a)' do
15
15
  expect(Ably::Realtime::Channel).to receive(:new).with(client, channel_name, options)
16
16
  subject.get(channel_name, options)
17
17
  end
18
18
 
19
19
  context 'when an existing channel exists' do
20
- it 'will reuse a channel object if it exists' do
20
+ it 'will reuse a channel object if it exists (RSN3a)' do
21
21
  channel = subject.get(channel_name, options)
22
22
  expect(channel).to be_a(Ably::Realtime::Channel)
23
23
  expect(subject.get(channel_name, options).object_id).to eql(channel.object_id)
24
24
  end
25
25
 
26
- it 'will update the options on the channel if provided' do
26
+ it 'will update the options on the channel if provided (RSN3c)' do
27
27
  channel = subject.get(channel_name, options)
28
28
  expect(channel.options).to eql(options)
29
29
  expect(channel.options).to_not include(:encrypted)
@@ -7,17 +7,14 @@ 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
 
17
- it 'should return Ably::Rest::Channel::MAX_MESSAGE_SIZE equal 65536 (TO3l8)' do
18
- expect(Ably::Rest::Channel::MAX_MESSAGE_SIZE).to eq(65536)
19
- end
20
-
21
18
  describe '#initializer' do
22
19
  let(:channel_name) { random_str.encode(encoding) }
23
20
 
@@ -132,8 +129,44 @@ describe Ably::Rest::Channel do
132
129
  end
133
130
 
134
131
  context 'max message size exceeded' do
135
- it 'should raise Ably::Exceptions::MaxMessageSizeExceeded' do
136
- expect { subject.publish('x' * 65537, 'data') }.to raise_error Ably::Exceptions::MaxMessageSizeExceeded
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
137
170
  end
138
171
  end
139
172
  end
@@ -87,6 +87,33 @@ describe Ably::Rest::Client do
87
87
  end
88
88
  end
89
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
90
117
  end
91
118
 
92
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.7
4
+ version: 1.1.8
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-08-03 00:00:00.000000000 Z
12
+ date: 2022-02-15 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: eventmachine
@@ -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
@@ -351,6 +351,7 @@ files:
351
351
  - lib/ably/models/cipher_params.rb
352
352
  - lib/ably/models/connection_details.rb
353
353
  - lib/ably/models/connection_state_change.rb
354
+ - lib/ably/models/delta_extras.rb
354
355
  - lib/ably/models/device_details.rb
355
356
  - lib/ably/models/device_push_details.rb
356
357
  - lib/ably/models/error_info.rb
@@ -488,6 +489,7 @@ files:
488
489
  - spec/unit/models/cipher_params_spec.rb
489
490
  - spec/unit/models/connection_details_spec.rb
490
491
  - spec/unit/models/connection_state_change_spec.rb
492
+ - spec/unit/models/delta_extras_spec.rb
491
493
  - spec/unit/models/device_details_spec.rb
492
494
  - spec/unit/models/device_push_details_spec.rb
493
495
  - spec/unit/models/error_info_spec.rb
@@ -603,6 +605,7 @@ test_files:
603
605
  - spec/unit/models/cipher_params_spec.rb
604
606
  - spec/unit/models/connection_details_spec.rb
605
607
  - spec/unit/models/connection_state_change_spec.rb
608
+ - spec/unit/models/delta_extras_spec.rb
606
609
  - spec/unit/models/device_details_spec.rb
607
610
  - spec/unit/models/device_push_details_spec.rb
608
611
  - spec/unit/models/error_info_spec.rb