ably-rest 1.1.2 → 1.2.2
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/.travis.yml +3 -0
- data/CHANGELOG.md +1 -1
- data/MAINTAINERS.md +1 -0
- data/README.md +4 -2
- data/ably-rest.gemspec +15 -18
- data/lib/ably-rest.rb +2 -0
- data/lib/submodules/ably-ruby/.github/workflows/check.yml +50 -0
- data/lib/submodules/ably-ruby/CHANGELOG.md +200 -0
- data/lib/submodules/ably-ruby/COPYRIGHT +1 -0
- data/lib/submodules/ably-ruby/LICENSE +172 -11
- data/lib/submodules/ably-ruby/MAINTAINERS.md +1 -0
- data/lib/submodules/ably-ruby/README.md +24 -22
- data/lib/submodules/ably-ruby/SPEC.md +1020 -929
- data/lib/submodules/ably-ruby/UPDATING.md +30 -0
- data/lib/submodules/ably-ruby/ably.gemspec +16 -23
- data/lib/submodules/ably-ruby/lib/ably/agent.rb +3 -0
- data/lib/submodules/ably-ruby/lib/ably/auth.rb +20 -10
- data/lib/submodules/ably-ruby/lib/ably/exceptions.rb +8 -2
- data/lib/submodules/ably-ruby/lib/ably/logger.rb +4 -4
- data/lib/submodules/ably-ruby/lib/ably/models/channel_details.rb +59 -0
- data/lib/submodules/ably-ruby/lib/ably/models/channel_metrics.rb +84 -0
- data/lib/submodules/ably-ruby/lib/ably/models/channel_occupancy.rb +43 -0
- data/lib/submodules/ably-ruby/lib/ably/models/channel_options.rb +97 -0
- data/lib/submodules/ably-ruby/lib/ably/models/channel_status.rb +53 -0
- data/lib/submodules/ably-ruby/lib/ably/models/connection_details.rb +8 -0
- data/lib/submodules/ably-ruby/lib/ably/models/delta_extras.rb +29 -0
- data/lib/submodules/ably-ruby/lib/ably/models/device_details.rb +1 -1
- data/lib/submodules/ably-ruby/lib/ably/models/error_info.rb +6 -2
- data/lib/submodules/ably-ruby/lib/ably/models/idiomatic_ruby_wrapper.rb +4 -0
- data/lib/submodules/ably-ruby/lib/ably/models/message.rb +28 -3
- data/lib/submodules/ably-ruby/lib/ably/models/presence_message.rb +14 -0
- data/lib/submodules/ably-ruby/lib/ably/models/protocol_message.rb +31 -14
- data/lib/submodules/ably-ruby/lib/ably/models/token_details.rb +7 -2
- data/lib/submodules/ably-ruby/lib/ably/models/token_request.rb +1 -1
- data/lib/submodules/ably-ruby/lib/ably/modules/ably.rb +11 -1
- data/lib/submodules/ably-ruby/lib/ably/modules/channels_collection.rb +22 -2
- data/lib/submodules/ably-ruby/lib/ably/modules/conversions.rb +34 -0
- data/lib/submodules/ably-ruby/lib/ably/realtime/auth.rb +2 -2
- data/lib/submodules/ably-ruby/lib/ably/realtime/channel/channel_manager.rb +19 -7
- data/lib/submodules/ably-ruby/lib/ably/realtime/channel/channel_properties.rb +24 -0
- data/lib/submodules/ably-ruby/lib/ably/realtime/channel/channel_state_machine.rb +10 -1
- data/lib/submodules/ably-ruby/lib/ably/realtime/channel/publisher.rb +6 -0
- data/lib/submodules/ably-ruby/lib/ably/realtime/channel.rb +56 -28
- data/lib/submodules/ably-ruby/lib/ably/realtime/channels.rb +1 -1
- data/lib/submodules/ably-ruby/lib/ably/realtime/client/incoming_message_dispatcher.rb +14 -6
- data/lib/submodules/ably-ruby/lib/ably/realtime/client.rb +9 -0
- data/lib/submodules/ably-ruby/lib/ably/realtime/connection/connection_manager.rb +13 -4
- data/lib/submodules/ably-ruby/lib/ably/realtime/connection/connection_state_machine.rb +4 -0
- data/lib/submodules/ably-ruby/lib/ably/realtime/connection/websocket_transport.rb +67 -1
- data/lib/submodules/ably-ruby/lib/ably/realtime/connection.rb +6 -5
- data/lib/submodules/ably-ruby/lib/ably/realtime/presence.rb +0 -14
- data/lib/submodules/ably-ruby/lib/ably/rest/channel.rb +44 -29
- data/lib/submodules/ably-ruby/lib/ably/rest/client.rb +60 -29
- data/lib/submodules/ably-ruby/lib/ably/rest/middleware/encoder.rb +1 -1
- data/lib/submodules/ably-ruby/lib/ably/rest/middleware/exceptions.rb +1 -1
- data/lib/submodules/ably-ruby/lib/ably/rest/middleware/external_exceptions.rb +1 -1
- data/lib/submodules/ably-ruby/lib/ably/rest/middleware/fail_if_unsupported_mime_type.rb +5 -2
- data/lib/submodules/ably-ruby/lib/ably/rest/middleware/logger.rb +1 -1
- data/lib/submodules/ably-ruby/lib/ably/rest/middleware/parse_json.rb +1 -1
- data/lib/submodules/ably-ruby/lib/ably/rest/middleware/parse_message_pack.rb +1 -1
- data/lib/submodules/ably-ruby/lib/ably/util/crypto.rb +1 -1
- data/lib/submodules/ably-ruby/lib/ably/version.rb +2 -14
- data/lib/submodules/ably-ruby/lib/ably.rb +1 -0
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/auth_spec.rb +4 -4
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/channel_history_spec.rb +25 -0
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/channel_spec.rb +476 -21
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/channels_spec.rb +59 -7
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/client_spec.rb +72 -16
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/connection_failures_spec.rb +85 -13
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/connection_spec.rb +301 -34
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/message_spec.rb +77 -0
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/presence_history_spec.rb +3 -59
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/presence_spec.rb +84 -158
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/push_admin_spec.rb +3 -19
- data/lib/submodules/ably-ruby/spec/acceptance/rest/auth_spec.rb +24 -75
- data/lib/submodules/ably-ruby/spec/acceptance/rest/base_spec.rb +8 -4
- data/lib/submodules/ably-ruby/spec/acceptance/rest/channel_spec.rb +141 -10
- data/lib/submodules/ably-ruby/spec/acceptance/rest/channels_spec.rb +23 -6
- data/lib/submodules/ably-ruby/spec/acceptance/rest/client_spec.rb +146 -47
- data/lib/submodules/ably-ruby/spec/acceptance/rest/message_spec.rb +61 -3
- data/lib/submodules/ably-ruby/spec/acceptance/rest/push_admin_spec.rb +3 -19
- data/lib/submodules/ably-ruby/spec/lib/unit/models/channel_options_spec.rb +52 -0
- data/lib/submodules/ably-ruby/spec/run_parallel_tests +2 -7
- data/lib/submodules/ably-ruby/spec/shared/client_initializer_behaviour.rb +131 -8
- data/lib/submodules/ably-ruby/spec/shared/model_behaviour.rb +1 -1
- data/lib/submodules/ably-ruby/spec/spec_helper.rb +12 -2
- data/lib/submodules/ably-ruby/spec/support/serialization_helper.rb +21 -0
- data/lib/submodules/ably-ruby/spec/support/test_app.rb +3 -3
- data/lib/submodules/ably-ruby/spec/unit/logger_spec.rb +6 -14
- data/lib/submodules/ably-ruby/spec/unit/models/channel_details_spec.rb +30 -0
- data/lib/submodules/ably-ruby/spec/unit/models/channel_metrics_spec.rb +42 -0
- data/lib/submodules/ably-ruby/spec/unit/models/channel_occupancy_spec.rb +17 -0
- data/lib/submodules/ably-ruby/spec/unit/models/channel_status_spec.rb +36 -0
- data/lib/submodules/ably-ruby/spec/unit/models/delta_extras_spec.rb +14 -0
- data/lib/submodules/ably-ruby/spec/unit/models/error_info_spec.rb +17 -1
- data/lib/submodules/ably-ruby/spec/unit/models/message_spec.rb +97 -0
- data/lib/submodules/ably-ruby/spec/unit/models/presence_message_spec.rb +49 -0
- data/lib/submodules/ably-ruby/spec/unit/models/protocol_message_spec.rb +125 -27
- data/lib/submodules/ably-ruby/spec/unit/models/token_details_spec.rb +14 -0
- data/lib/submodules/ably-ruby/spec/unit/realtime/channel_spec.rb +3 -2
- data/lib/submodules/ably-ruby/spec/unit/realtime/channels_spec.rb +53 -15
- data/lib/submodules/ably-ruby/spec/unit/realtime/client_spec.rb +19 -6
- data/lib/submodules/ably-ruby/spec/unit/realtime/incoming_message_dispatcher_spec.rb +38 -0
- data/lib/submodules/ably-ruby/spec/unit/rest/channel_spec.rb +44 -1
- data/lib/submodules/ably-ruby/spec/unit/rest/channels_spec.rb +81 -14
- data/lib/submodules/ably-ruby/spec/unit/rest/client_spec.rb +47 -0
- data/spec/spec_helper.rb +5 -0
- data/spec/unit/client_spec.rb +30 -0
- metadata +88 -25
- data/lib/submodules/ably-ruby/.travis.yml +0 -19
|
@@ -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, idempotent_rest_publishing: false } }
|
|
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 }
|
|
@@ -40,7 +42,7 @@ describe Ably::Rest::Channel do
|
|
|
40
42
|
|
|
41
43
|
it 'publishes the message without a client_id' do
|
|
42
44
|
expect(client).to receive(:post).
|
|
43
|
-
with("/channels/#{channel_name}/publish", hash_excluding(client_id: client_id)).
|
|
45
|
+
with("/channels/#{channel_name}/publish", hash_excluding(client_id: client_id), {}).
|
|
44
46
|
and_return(double('response', status: 201))
|
|
45
47
|
|
|
46
48
|
expect(channel.publish(name, data)).to eql(true)
|
|
@@ -60,6 +62,9 @@ describe Ably::Rest::Channel do
|
|
|
60
62
|
end
|
|
61
63
|
|
|
62
64
|
it 'publishes an array of messages in one HTTP request' do
|
|
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)
|
|
67
|
+
|
|
63
68
|
expect(client).to receive(:post).once.and_call_original
|
|
64
69
|
expect(channel.publish(messages)).to eql(true)
|
|
65
70
|
expect(channel.history.items.map(&:name)).to match_array(messages.map { |message| message[:name] })
|
|
@@ -68,17 +73,116 @@ describe Ably::Rest::Channel do
|
|
|
68
73
|
end
|
|
69
74
|
|
|
70
75
|
context 'with an array of Message objects' do
|
|
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
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
context 'when max_message_size is 655 bytes' do
|
|
113
|
+
let(:max_message_size) { 655 }
|
|
114
|
+
|
|
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
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
context 'with a Message object' do
|
|
152
|
+
let(:name) { random_str }
|
|
153
|
+
|
|
154
|
+
let(:message) do
|
|
155
|
+
Ably::Models::Message(name: name, data: data)
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
it 'publishes the message' do
|
|
159
|
+
expect(client).to receive(:post).once.and_call_original
|
|
160
|
+
expect(channel.publish(message)).to eql(true)
|
|
161
|
+
expect(channel.history.items.first.name).to eql(name)
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
context 'with a Message object and query params' do
|
|
166
|
+
let(:message) do
|
|
167
|
+
Ably::Models::Message(name: name, data: data)
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
it 'should fail to publish the message (RSL1l1)' do
|
|
171
|
+
expect(client).to receive(:post).once.and_call_original
|
|
172
|
+
expect { channel.publish(message, { _forceNack: 'true' }) }.to raise_error(Ably::Exceptions::InvalidRequest, /40099/)
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
context 'with Messages and query params' do
|
|
71
177
|
let(:messages) do
|
|
72
178
|
10.times.map do |index|
|
|
73
|
-
|
|
179
|
+
{ name: index.to_s, data: { "index" => index + 10 } }
|
|
74
180
|
end
|
|
75
181
|
end
|
|
76
182
|
|
|
77
|
-
it '
|
|
183
|
+
it 'should fail to publish the message (RSL1l1)' do
|
|
78
184
|
expect(client).to receive(:post).once.and_call_original
|
|
79
|
-
expect
|
|
80
|
-
expect(channel.history.items.map(&:name)).to match_array(messages.map(&:name))
|
|
81
|
-
expect(channel.history.items.map(&:data)).to match_array(messages.map(&:data))
|
|
185
|
+
expect { channel.publish(messages, { _forceNack: 'true' }) }.to raise_error(Ably::Exceptions::InvalidRequest, /40099/)
|
|
82
186
|
end
|
|
83
187
|
end
|
|
84
188
|
|
|
@@ -96,7 +200,7 @@ describe Ably::Rest::Channel do
|
|
|
96
200
|
let(:data) { random_str }
|
|
97
201
|
|
|
98
202
|
it 'publishes the message without a name attribute in the payload' do
|
|
99
|
-
expect(client).to receive(:post).with(anything, { "data" => data }).once.and_call_original
|
|
203
|
+
expect(client).to receive(:post).with(anything, { "data" => data }, {}).once.and_call_original
|
|
100
204
|
expect(channel.publish(nil, data)).to eql(true)
|
|
101
205
|
expect(channel.history.items.first.name).to be_nil
|
|
102
206
|
expect(channel.history.items.first.data).to eql(data)
|
|
@@ -107,7 +211,7 @@ describe Ably::Rest::Channel do
|
|
|
107
211
|
let(:name) { random_str }
|
|
108
212
|
|
|
109
213
|
it 'publishes the message without a data attribute in the payload' do
|
|
110
|
-
expect(client).to receive(:post).with(anything, { "name" => name }).once.and_call_original
|
|
214
|
+
expect(client).to receive(:post).with(anything, { "name" => name }, {}).once.and_call_original
|
|
111
215
|
expect(channel.publish(name)).to eql(true)
|
|
112
216
|
expect(channel.history.items.first.name).to eql(name)
|
|
113
217
|
expect(channel.history.items.first.data).to be_nil
|
|
@@ -118,7 +222,7 @@ describe Ably::Rest::Channel do
|
|
|
118
222
|
let(:name) { random_str }
|
|
119
223
|
|
|
120
224
|
it 'publishes the message without any attributes in the payload' do
|
|
121
|
-
expect(client).to receive(:post).with(anything, {}).once.and_call_original
|
|
225
|
+
expect(client).to receive(:post).with(anything, {}, {}).once.and_call_original
|
|
122
226
|
expect(channel.publish(nil)).to eql(true)
|
|
123
227
|
expect(channel.history.items.first.name).to be_nil
|
|
124
228
|
expect(channel.history.items.first.data).to be_nil
|
|
@@ -312,6 +416,15 @@ describe Ably::Rest::Channel do
|
|
|
312
416
|
end
|
|
313
417
|
end
|
|
314
418
|
end
|
|
419
|
+
|
|
420
|
+
context 'message size is exceeded (#TO3l8)' do
|
|
421
|
+
let(:data) { 101.times.map { { data: 'x' * 655 } } }
|
|
422
|
+
|
|
423
|
+
it 'should raise Ably::Exceptions::MaxMessageSizeExceeded exception' do
|
|
424
|
+
expect { channel.publish([ data: data ]) }.to \
|
|
425
|
+
raise_error(Ably::Exceptions::MaxMessageSizeExceeded)
|
|
426
|
+
end
|
|
427
|
+
end
|
|
315
428
|
end
|
|
316
429
|
|
|
317
430
|
describe '#history' do
|
|
@@ -482,5 +595,23 @@ describe Ably::Rest::Channel do
|
|
|
482
595
|
expect(channel.presence).to be_a(Ably::Rest::Presence)
|
|
483
596
|
end
|
|
484
597
|
end
|
|
598
|
+
|
|
599
|
+
context '#status' do
|
|
600
|
+
let(:channel_name) { "persisted:#{random_str(4)}" }
|
|
601
|
+
let(:channel) { client.channel(channel_name) }
|
|
602
|
+
let(:channel_details) { channel.status }
|
|
603
|
+
|
|
604
|
+
it 'should return channel details status (#RSL8, #RSL8a)' do
|
|
605
|
+
expect(channel_details.channel_id).to eq(channel_name)
|
|
606
|
+
expect(channel_details.name).to eq(channel_name)
|
|
607
|
+
expect(channel_details.status).to be_a(Ably::Models::ChannelStatus)
|
|
608
|
+
expect(channel_details.status.is_active).to eq(true)
|
|
609
|
+
expect(channel_details.status.occupancy.metrics.publishers).to eq(0)
|
|
610
|
+
expect(channel_details.status.occupancy.metrics.subscribers).to eq(0)
|
|
611
|
+
expect(channel_details.status.occupancy.metrics.presence_connections).to eq(0)
|
|
612
|
+
expect(channel_details.status.occupancy.metrics.presence_members).to eq(0)
|
|
613
|
+
expect(channel_details.status.occupancy.metrics.presence_subscribers).to eq(0)
|
|
614
|
+
end
|
|
615
|
+
end
|
|
485
616
|
end
|
|
486
617
|
end
|
|
@@ -5,11 +5,11 @@ describe Ably::Rest::Channels do
|
|
|
5
5
|
shared_examples 'a channel' do
|
|
6
6
|
it 'returns a channel object' do
|
|
7
7
|
expect(channel).to be_a Ably::Rest::Channel
|
|
8
|
-
expect(channel.name).to
|
|
8
|
+
expect(channel.name).to eq(channel_name)
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
it 'returns channel object and passes the provided options' do
|
|
12
|
-
expect(channel_with_options.options).to
|
|
12
|
+
expect(channel_with_options.options.to_h).to eq(options)
|
|
13
13
|
end
|
|
14
14
|
end
|
|
15
15
|
|
|
@@ -32,12 +32,29 @@ describe Ably::Rest::Channels do
|
|
|
32
32
|
it_behaves_like 'a channel'
|
|
33
33
|
end
|
|
34
34
|
|
|
35
|
+
describe '#set_options (#RTL16)' do
|
|
36
|
+
let(:channel) { client.channel(channel_name) }
|
|
37
|
+
|
|
38
|
+
it "updates channel's options" do
|
|
39
|
+
expect { channel.options = options }.to change { channel.options.to_h }.from({}).to(options)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
context 'when providing Ably::Models::ChannelOptions object' do
|
|
43
|
+
let(:options_object) { Ably::Models::ChannelOptions.new(options) }
|
|
44
|
+
|
|
45
|
+
it "updates channel's options" do
|
|
46
|
+
expect { channel.options = options_object}.to change { channel.options.to_h }.from({}).to(options)
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
35
51
|
describe 'accessing an existing channel object with different options' do
|
|
36
52
|
let(:new_channel_options) { { encrypted: true } }
|
|
37
53
|
let(:original_channel) { client.channels.get(channel_name, options) }
|
|
38
54
|
|
|
39
|
-
it 'overrides the existing channel options and returns the channel object' do
|
|
40
|
-
expect(original_channel.options).to_not include(:encrypted)
|
|
55
|
+
it 'overrides the existing channel options and returns the channel object (RSN3c)' do
|
|
56
|
+
expect(original_channel.options.to_h).to_not include(:encrypted)
|
|
57
|
+
|
|
41
58
|
new_channel = client.channels.get(channel_name, new_channel_options)
|
|
42
59
|
expect(new_channel).to be_a(Ably::Rest::Channel)
|
|
43
60
|
expect(new_channel.options[:encrypted]).to eql(true)
|
|
@@ -48,10 +65,10 @@ describe Ably::Rest::Channels do
|
|
|
48
65
|
let(:original_channel) { client.channels.get(channel_name, options) }
|
|
49
66
|
|
|
50
67
|
it 'returns the existing channel without modifying the channel options' do
|
|
51
|
-
expect(original_channel.options).to
|
|
68
|
+
expect(original_channel.options.to_h).to eq(options)
|
|
52
69
|
new_channel = client.channels.get(channel_name)
|
|
53
70
|
expect(new_channel).to be_a(Ably::Rest::Channel)
|
|
54
|
-
expect(original_channel.options).to
|
|
71
|
+
expect(original_channel.options.to_h).to eq(options)
|
|
55
72
|
end
|
|
56
73
|
end
|
|
57
74
|
|
|
@@ -12,7 +12,7 @@ describe Ably::Rest::Client do
|
|
|
12
12
|
http_defaults = Ably::Rest::Client::HTTP_DEFAULTS
|
|
13
13
|
|
|
14
14
|
def encode64(text)
|
|
15
|
-
Base64.
|
|
15
|
+
Base64.urlsafe_encode64(text)
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
context '#initialize' do
|
|
@@ -56,14 +56,6 @@ describe Ably::Rest::Client do
|
|
|
56
56
|
end
|
|
57
57
|
end
|
|
58
58
|
|
|
59
|
-
context 'with a :client_id configured' do
|
|
60
|
-
let(:client) { Ably::Rest::Client.new(client_options.merge(key: api_key, client_id: random_str)) }
|
|
61
|
-
|
|
62
|
-
it 'uses token authentication' do
|
|
63
|
-
expect(client.auth).to be_using_token_auth
|
|
64
|
-
end
|
|
65
|
-
end
|
|
66
|
-
|
|
67
59
|
context 'with a non string :client_id' do
|
|
68
60
|
let(:client) { Ably::Rest::Client.new(client_options.merge(key: api_key, client_id: 1)) }
|
|
69
61
|
|
|
@@ -144,11 +136,12 @@ describe Ably::Rest::Client do
|
|
|
144
136
|
let(:history_querystring) { history_params.map { |k, v| "#{k}=#{v}" }.join("&") }
|
|
145
137
|
|
|
146
138
|
context 'with basic auth', webmock: true do
|
|
147
|
-
let(:client_options) { default_options.merge(key: api_key) }
|
|
139
|
+
let(:client_options) { default_options.merge(key: api_key, client_id: client_id) }
|
|
148
140
|
|
|
149
141
|
let!(:get_message_history_stub) do
|
|
150
|
-
stub_request(:get, "https://#{environment}-#{Ably::Rest::Client::DOMAIN}/channels/#{channel_name}/messages?#{history_querystring}")
|
|
151
|
-
|
|
142
|
+
stub_request(:get, "https://#{environment}-#{Ably::Rest::Client::DOMAIN}/channels/#{channel_name}/messages?#{history_querystring}")
|
|
143
|
+
.with(headers: { 'X-Ably-ClientId' => encode64(client_id) })
|
|
144
|
+
.to_return(body: [], headers: { 'Content-Type' => 'application/json' })
|
|
152
145
|
end
|
|
153
146
|
|
|
154
147
|
it 'sends the API key in authentication part of the secure URL (the Authorization: Basic header is not used with the Faraday HTTP library by default)' do
|
|
@@ -308,30 +301,44 @@ describe Ably::Rest::Client do
|
|
|
308
301
|
context 'configured' do
|
|
309
302
|
let(:client_options) { default_options.merge(key: api_key, environment: 'production') }
|
|
310
303
|
|
|
311
|
-
it 'should make connection attempts to
|
|
304
|
+
it 'should make connection attempts to a.ably-realtime.com, b.ably-realtime.com, c.ably-realtime.com, d.ably-realtime.com, e.ably-realtime.com (#RSC15a)' do
|
|
312
305
|
hosts = []
|
|
313
306
|
5.times do
|
|
314
307
|
hosts << client.fallback_connection.host
|
|
315
308
|
end
|
|
316
|
-
expect(hosts).to match_array(%w(
|
|
309
|
+
expect(hosts).to match_array(%w(a.ably-realtime.com b.ably-realtime.com c.ably-realtime.com d.ably-realtime.com e.ably-realtime.com))
|
|
317
310
|
end
|
|
318
311
|
end
|
|
319
312
|
|
|
320
313
|
context 'when environment is NOT production (#RSC15b)' do
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
314
|
+
context 'and custom fallback hosts are empty' do
|
|
315
|
+
let(:client_options) { default_options.merge(environment: 'sandbox', key: api_key, fallback_hosts: []) }
|
|
316
|
+
let!(:default_host_request_stub) do
|
|
317
|
+
stub_request(:post, "https://#{environment}-#{Ably::Rest::Client::DOMAIN}#{path}").to_return do
|
|
318
|
+
raise Faraday::TimeoutError.new('timeout error message')
|
|
319
|
+
end
|
|
320
|
+
end
|
|
321
|
+
|
|
322
|
+
it 'does not retry failed requests with fallback hosts when there is a connection error' do
|
|
323
|
+
expect { publish_block.call }.to raise_error Ably::Exceptions::ConnectionTimeout
|
|
325
324
|
end
|
|
326
325
|
end
|
|
327
326
|
|
|
328
|
-
|
|
329
|
-
|
|
327
|
+
context 'and no custom fallback hosts are provided' do
|
|
328
|
+
let(:client_options) { default_options.merge(environment: 'sandbox', key: api_key) }
|
|
329
|
+
|
|
330
|
+
it 'should make connection attempts to sandbox-a-fallback.ably-realtime.com, sandbox-b-fallback.ably-realtime.com, sandbox-c-fallback.ably-realtime.com, sandbox-d-fallback.ably-realtime.com, sandbox-e-fallback.ably-realtime.com (#RSC15a)' do
|
|
331
|
+
hosts = []
|
|
332
|
+
5.times do
|
|
333
|
+
hosts << client.fallback_connection.host
|
|
334
|
+
end
|
|
335
|
+
expect(hosts).to match_array(%w(a b c d e).map { |id| "sandbox-#{id}-fallback.ably-realtime.com" })
|
|
336
|
+
end
|
|
330
337
|
end
|
|
331
338
|
end
|
|
332
339
|
|
|
333
340
|
context 'when environment is production' do
|
|
334
|
-
let(:custom_hosts) { %w(
|
|
341
|
+
let(:custom_hosts) { %w(a.ably-realtime.com b.ably-realtime.com) }
|
|
335
342
|
let(:max_retry_count) { 2 }
|
|
336
343
|
let(:max_retry_duration) { 0.5 }
|
|
337
344
|
let(:fallback_block) { proc { raise Faraday::SSLError.new('ssl error message') } }
|
|
@@ -830,11 +837,12 @@ describe Ably::Rest::Client do
|
|
|
830
837
|
end
|
|
831
838
|
|
|
832
839
|
context 'when environment is not production and server returns a 50x error' do
|
|
840
|
+
let(:env) { 'custom-env' }
|
|
841
|
+
let(:default_fallbacks) { %w(a b c d e).map { |id| "#{env}-#{id}-fallback.ably-realtime.com" } }
|
|
833
842
|
let(:custom_hosts) { %w(A.foo.com B.foo.com) }
|
|
834
843
|
let(:max_retry_count) { 2 }
|
|
835
844
|
let(:max_retry_duration) { 0.5 }
|
|
836
845
|
let(:fallback_block) { proc { raise Faraday::SSLError.new('ssl error message') } }
|
|
837
|
-
let(:env) { 'custom-env' }
|
|
838
846
|
let(:production_options) do
|
|
839
847
|
default_options.merge(
|
|
840
848
|
environment: env,
|
|
@@ -858,6 +866,26 @@ describe Ably::Rest::Client do
|
|
|
858
866
|
stub_request(:post, "https://#{env}-#{Ably::Rest::Client::DOMAIN}#{path}").to_return(&fallback_block)
|
|
859
867
|
end
|
|
860
868
|
|
|
869
|
+
context 'with no fallback hosts provided (#TBC, see https://github.com/ably/wiki/issues/361)' do
|
|
870
|
+
let(:client_options) {
|
|
871
|
+
production_options.merge(log_level: :fatal)
|
|
872
|
+
}
|
|
873
|
+
|
|
874
|
+
it 'uses the default fallback hosts for that environment as this is not an authentication failure' do
|
|
875
|
+
fallbacks_called_count = 0
|
|
876
|
+
default_fallbacks.each do |host|
|
|
877
|
+
counting_fallback_proc = proc do
|
|
878
|
+
fallbacks_called_count += 1
|
|
879
|
+
fallback_block.call
|
|
880
|
+
end
|
|
881
|
+
stub_request(:post, "https://#{host}#{path}").to_return(&counting_fallback_proc)
|
|
882
|
+
end
|
|
883
|
+
expect { publish_block.call }.to raise_error(Ably::Exceptions::ServerError)
|
|
884
|
+
expect(default_host_request_stub).to have_been_requested
|
|
885
|
+
expect(fallbacks_called_count).to be >= 2
|
|
886
|
+
end
|
|
887
|
+
end
|
|
888
|
+
|
|
861
889
|
context 'with custom fallback hosts provided (#RSC15b, #TO3k6)' do
|
|
862
890
|
let!(:first_fallback_request_stub) do
|
|
863
891
|
stub_request(:post, "https://#{custom_hosts[0]}#{path}").to_return(&fallback_block)
|
|
@@ -1053,29 +1081,15 @@ describe Ably::Rest::Client do
|
|
|
1053
1081
|
end
|
|
1054
1082
|
|
|
1055
1083
|
context 'version headers', :webmock do
|
|
1056
|
-
[nil, '
|
|
1057
|
-
context "with
|
|
1058
|
-
|
|
1059
|
-
before do
|
|
1060
|
-
Ably.lib_variant = variant
|
|
1061
|
-
end
|
|
1084
|
+
[nil, 'ably-ruby/1.1.1 ruby/3.1.1'].each do |agent|
|
|
1085
|
+
context "with #{agent ? "custom #{agent}" : 'default'} agent" do
|
|
1086
|
+
let(:client_options) { default_options.merge(key: api_key, agent: agent) }
|
|
1062
1087
|
|
|
1063
|
-
after do
|
|
1064
|
-
Ably.lib_variant = nil
|
|
1065
|
-
end
|
|
1066
|
-
end
|
|
1067
|
-
|
|
1068
|
-
let(:client_options) { default_options.merge(key: api_key) }
|
|
1069
1088
|
let!(:publish_message_stub) do
|
|
1070
|
-
lib = ['ruby']
|
|
1071
|
-
lib << variant if variant
|
|
1072
|
-
lib << Ably::VERSION
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
1089
|
stub_request(:post, "#{client.endpoint}/channels/foo/publish").
|
|
1076
1090
|
with(headers: {
|
|
1077
1091
|
'X-Ably-Version' => Ably::PROTOCOL_VERSION,
|
|
1078
|
-
'
|
|
1092
|
+
'Ably-Agent' => agent || Ably::AGENT
|
|
1079
1093
|
}).
|
|
1080
1094
|
to_return(status: 201, body: '{}', headers: { 'Content-Type' => 'application/json' })
|
|
1081
1095
|
end
|
|
@@ -1083,14 +1097,16 @@ describe Ably::Rest::Client do
|
|
|
1083
1097
|
it 'sends a protocol version and lib version header (#G4, #RSC7a, #RSC7b)' do
|
|
1084
1098
|
client.channels.get('foo').publish("event")
|
|
1085
1099
|
expect(publish_message_stub).to have_been_requested
|
|
1086
|
-
expect(Ably::PROTOCOL_VERSION).to eql('1.
|
|
1100
|
+
expect(Ably::PROTOCOL_VERSION).to eql('1.2')
|
|
1087
1101
|
end
|
|
1088
1102
|
end
|
|
1089
1103
|
end
|
|
1090
1104
|
end
|
|
1091
1105
|
|
|
1092
|
-
context '#request (#RSC19
|
|
1106
|
+
context '#request (#RSC19*, #TO3l9)' do
|
|
1093
1107
|
let(:client_options) { default_options.merge(key: api_key) }
|
|
1108
|
+
let(:device_id) { random_str }
|
|
1109
|
+
let(:endpoint) { client.endpoint }
|
|
1094
1110
|
|
|
1095
1111
|
context 'get' do
|
|
1096
1112
|
it 'returns an HttpPaginatedResponse object' do
|
|
@@ -1130,13 +1146,96 @@ describe Ably::Rest::Client do
|
|
|
1130
1146
|
end
|
|
1131
1147
|
end
|
|
1132
1148
|
end
|
|
1149
|
+
|
|
1150
|
+
context 'post', :webmock do
|
|
1151
|
+
before do
|
|
1152
|
+
stub_request(:delete, "#{endpoint}/push/deviceRegistrations/#{device_id}/resetUpdateToken").
|
|
1153
|
+
to_return(status: 200, body: '{}', headers: { 'Content-Type' => 'application/json' })
|
|
1154
|
+
end
|
|
1155
|
+
|
|
1156
|
+
it 'supports post' do
|
|
1157
|
+
response = client.request(:delete, "push/deviceRegistrations/#{device_id}/resetUpdateToken")
|
|
1158
|
+
|
|
1159
|
+
expect(response).to be_success
|
|
1160
|
+
end
|
|
1161
|
+
|
|
1162
|
+
it 'raises an exception once body size in bytes exceeded' do
|
|
1163
|
+
expect {
|
|
1164
|
+
client.request(:post, endpoint, {}, { content: 'x' * Ably::Rest::Client::MAX_FRAME_SIZE })
|
|
1165
|
+
}.to raise_error(Ably::Exceptions::MaxFrameSizeExceeded)
|
|
1166
|
+
end
|
|
1167
|
+
end
|
|
1168
|
+
|
|
1169
|
+
context 'delete', :webmock do
|
|
1170
|
+
before do
|
|
1171
|
+
stub_request(:delete, "#{endpoint}/push/channelSubscriptions?deviceId=#{device_id}").
|
|
1172
|
+
to_return(status: 200, body: '{}', headers: { 'Content-Type' => 'application/json' })
|
|
1173
|
+
end
|
|
1174
|
+
|
|
1175
|
+
it 'supports delete' do
|
|
1176
|
+
response = client.request(:delete, "/push/channelSubscriptions", { deviceId: device_id})
|
|
1177
|
+
|
|
1178
|
+
expect(response).to be_success
|
|
1179
|
+
end
|
|
1180
|
+
end
|
|
1181
|
+
|
|
1182
|
+
context 'patch', :webmock do
|
|
1183
|
+
let(:body_params) { { 'metadata' => { 'key' => 'value' } } }
|
|
1184
|
+
|
|
1185
|
+
before do
|
|
1186
|
+
stub_request(:patch, "#{endpoint}/push/deviceRegistrations/#{device_id}")
|
|
1187
|
+
.with(body: serialize_body(body_params, protocol))
|
|
1188
|
+
.to_return(status: 200, body: '{}', headers: { 'Content-Type' => 'application/json' })
|
|
1189
|
+
end
|
|
1190
|
+
|
|
1191
|
+
it 'supports patch' do
|
|
1192
|
+
response = client.request(:patch, "/push/deviceRegistrations/#{device_id}", {}, body_params)
|
|
1193
|
+
|
|
1194
|
+
expect(response).to be_success
|
|
1195
|
+
end
|
|
1196
|
+
|
|
1197
|
+
it 'raises an exception once body size in bytes exceeded' do
|
|
1198
|
+
expect {
|
|
1199
|
+
client.request(:patch, endpoint, {}, { content: 'x' * Ably::Rest::Client::MAX_FRAME_SIZE })
|
|
1200
|
+
}.to raise_error(Ably::Exceptions::MaxFrameSizeExceeded)
|
|
1201
|
+
end
|
|
1202
|
+
end
|
|
1203
|
+
|
|
1204
|
+
context 'put', :webmock do
|
|
1205
|
+
let(:body_params) do
|
|
1206
|
+
{
|
|
1207
|
+
'id' => random_str,
|
|
1208
|
+
'platform' => 'ios',
|
|
1209
|
+
'formFactor' => 'phone',
|
|
1210
|
+
'metadata' => { 'key' => 'value' }
|
|
1211
|
+
}
|
|
1212
|
+
end
|
|
1213
|
+
|
|
1214
|
+
before do
|
|
1215
|
+
stub_request(:put, "#{endpoint}/push/deviceRegistrations/#{device_id}")
|
|
1216
|
+
.with(body: serialize_body(body_params, protocol))
|
|
1217
|
+
.to_return(status: 200, body: '{}', headers: { 'Content-Type' => 'application/json' })
|
|
1218
|
+
end
|
|
1219
|
+
|
|
1220
|
+
it 'supports put' do
|
|
1221
|
+
response = client.request(:put, "/push/deviceRegistrations/#{device_id}", {}, body_params)
|
|
1222
|
+
|
|
1223
|
+
expect(response).to be_success
|
|
1224
|
+
end
|
|
1225
|
+
|
|
1226
|
+
it 'raises an exception once body size in bytes exceeded' do
|
|
1227
|
+
expect {
|
|
1228
|
+
client.request(:put, endpoint, {}, { content: 'x' * Ably::Rest::Client::MAX_FRAME_SIZE })
|
|
1229
|
+
}.to raise_error(Ably::Exceptions::MaxFrameSizeExceeded)
|
|
1230
|
+
end
|
|
1231
|
+
end
|
|
1133
1232
|
end
|
|
1134
1233
|
|
|
1135
|
-
context 'request_id generation' do
|
|
1234
|
+
context 'request_id generation (#RSC7c)' do
|
|
1136
1235
|
context 'Timeout error' do
|
|
1137
|
-
context 'with option add_request_ids: true', :webmock, :prevent_log_stubbing do
|
|
1236
|
+
context 'with option add_request_ids: true and no fallback hosts', :webmock, :prevent_log_stubbing do
|
|
1138
1237
|
let(:custom_logger_object) { TestLogger.new }
|
|
1139
|
-
let(:client_options) { default_options.merge(key: api_key, logger: custom_logger_object, add_request_ids: true) }
|
|
1238
|
+
let(:client_options) { default_options.merge(key: api_key, logger: custom_logger_object, add_request_ids: true, fallback_hosts: []) }
|
|
1140
1239
|
|
|
1141
1240
|
before do
|
|
1142
1241
|
@request_id = nil
|
|
@@ -1226,8 +1325,8 @@ describe Ably::Rest::Client do
|
|
|
1226
1325
|
end
|
|
1227
1326
|
end
|
|
1228
1327
|
|
|
1229
|
-
context 'without request_id' do
|
|
1230
|
-
let(:client_options) { default_options.merge(key: api_key, http_request_timeout: 0) }
|
|
1328
|
+
context 'without request_id and no fallback hosts' do
|
|
1329
|
+
let(:client_options) { default_options.merge(key: api_key, http_request_timeout: 0, fallback_hosts: []) }
|
|
1231
1330
|
|
|
1232
1331
|
it 'does not include request_id in ConnectionTimeout error' do
|
|
1233
1332
|
begin
|
|
@@ -24,6 +24,57 @@ describe Ably::Rest::Channel, 'messages' do
|
|
|
24
24
|
end
|
|
25
25
|
end
|
|
26
26
|
|
|
27
|
+
context 'a single Message object (#RSL1a)' do
|
|
28
|
+
let(:name) { random_str }
|
|
29
|
+
let(:data) { random_str }
|
|
30
|
+
let(:message) { Ably::Models::Message.new(name: name, data: data) }
|
|
31
|
+
|
|
32
|
+
it 'publishes the message' do
|
|
33
|
+
channel.publish(message)
|
|
34
|
+
expect(channel.history.items.length).to eql(1)
|
|
35
|
+
message = channel.history.items.first
|
|
36
|
+
expect(message.name).to eq(name)
|
|
37
|
+
expect(message.data).to eq(data)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
context 'an array of Message objects (#RSL1a)' do
|
|
42
|
+
let(:data) { random_str }
|
|
43
|
+
let(:message1) { Ably::Models::Message.new(name: random_str, data: data) }
|
|
44
|
+
let(:message2) { Ably::Models::Message.new(name: random_str, data: data) }
|
|
45
|
+
let(:message3) { Ably::Models::Message.new(name: random_str, data: data) }
|
|
46
|
+
|
|
47
|
+
it 'publishes three messages' do
|
|
48
|
+
channel.publish([message1, message2, message3])
|
|
49
|
+
expect(channel.history.items.length).to eql(3)
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
context 'an array of hashes (#RSL1a)' do
|
|
54
|
+
let(:data) { random_str }
|
|
55
|
+
let(:message1) { { name: random_str, data: data } }
|
|
56
|
+
let(:message2) { { name: random_str, data: data } }
|
|
57
|
+
let(:message3) { { name: random_str, data: data } }
|
|
58
|
+
|
|
59
|
+
it 'publishes three messages' do
|
|
60
|
+
channel.publish([message1, message2, message3])
|
|
61
|
+
expect(channel.history.items.length).to eql(3)
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
context 'a name with data payload (#RSL1a, #RSL1b)' do
|
|
66
|
+
let(:name) { random_str }
|
|
67
|
+
let(:data) { random_str }
|
|
68
|
+
|
|
69
|
+
it 'publishes the message' do
|
|
70
|
+
channel.publish(name, data)
|
|
71
|
+
expect(channel.history.items.length).to eql(1)
|
|
72
|
+
message = channel.history.items.first
|
|
73
|
+
expect(message.name).to eq(name)
|
|
74
|
+
expect(message.data).to eq(data)
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
27
78
|
context 'with supported data payload content type' do
|
|
28
79
|
context 'JSON Object (Hash)' do
|
|
29
80
|
let(:data) { { 'Hash' => 'true' } }
|
|
@@ -153,13 +204,20 @@ describe Ably::Rest::Channel, 'messages' do
|
|
|
153
204
|
end
|
|
154
205
|
end
|
|
155
206
|
|
|
156
|
-
specify 'idempotent publishing is disabled by default with 1.1 (#TO3n)' do
|
|
207
|
+
specify 'idempotent publishing is disabled by default with <= 1.1 (#TO3n)' do
|
|
208
|
+
stub_const 'Ably::PROTOCOL_VERSION', '1.0'
|
|
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'
|
|
157
212
|
client = Ably::Rest::Client.new(key: api_key, protocol: protocol)
|
|
158
213
|
expect(client.idempotent_rest_publishing).to be_falsey
|
|
159
214
|
end
|
|
160
215
|
|
|
161
|
-
specify 'idempotent publishing is enabled by default with 1.2 (#TO3n)' do
|
|
162
|
-
stub_const 'Ably::
|
|
216
|
+
specify 'idempotent publishing is enabled by default with >= 1.2 (#TO3n)' do
|
|
217
|
+
stub_const 'Ably::PROTOCOL_VERSION', '1.2'
|
|
218
|
+
client = Ably::Rest::Client.new(key: api_key, protocol: protocol)
|
|
219
|
+
expect(client.idempotent_rest_publishing).to be_truthy
|
|
220
|
+
stub_const 'Ably::PROTOCOL_VERSION', '1.3'
|
|
163
221
|
client = Ably::Rest::Client.new(key: api_key, protocol: protocol)
|
|
164
222
|
expect(client.idempotent_rest_publishing).to be_truthy
|
|
165
223
|
end
|