ably-rest 0.9.3 → 1.0.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.
- checksums.yaml +4 -4
- data/ably-rest.gemspec +2 -1
- data/lib/submodules/ably-ruby/.travis.yml +6 -4
- data/lib/submodules/ably-ruby/CHANGELOG.md +52 -61
- data/lib/submodules/ably-ruby/README.md +10 -0
- data/lib/submodules/ably-ruby/SPEC.md +1473 -852
- data/lib/submodules/ably-ruby/ably.gemspec +2 -1
- data/lib/submodules/ably-ruby/lib/ably/auth.rb +57 -25
- data/lib/submodules/ably-ruby/lib/ably/exceptions.rb +34 -8
- data/lib/submodules/ably-ruby/lib/ably/logger.rb +10 -1
- data/lib/submodules/ably-ruby/lib/ably/models/auth_details.rb +42 -0
- data/lib/submodules/ably-ruby/lib/ably/models/channel_state_change.rb +18 -4
- data/lib/submodules/ably-ruby/lib/ably/models/connection_details.rb +6 -3
- data/lib/submodules/ably-ruby/lib/ably/models/connection_state_change.rb +4 -3
- data/lib/submodules/ably-ruby/lib/ably/models/error_info.rb +1 -1
- data/lib/submodules/ably-ruby/lib/ably/models/message.rb +12 -1
- data/lib/submodules/ably-ruby/lib/ably/models/message_encoders/base.rb +101 -97
- data/lib/submodules/ably-ruby/lib/ably/models/presence_message.rb +13 -1
- data/lib/submodules/ably-ruby/lib/ably/models/protocol_message.rb +20 -3
- data/lib/submodules/ably-ruby/lib/ably/modules/async_wrapper.rb +7 -3
- data/lib/submodules/ably-ruby/lib/ably/modules/enum.rb +17 -7
- data/lib/submodules/ably-ruby/lib/ably/modules/event_emitter.rb +29 -14
- data/lib/submodules/ably-ruby/lib/ably/modules/state_emitter.rb +7 -4
- data/lib/submodules/ably-ruby/lib/ably/modules/state_machine.rb +2 -4
- data/lib/submodules/ably-ruby/lib/ably/modules/uses_state_machine.rb +7 -3
- data/lib/submodules/ably-ruby/lib/ably/realtime.rb +2 -0
- data/lib/submodules/ably-ruby/lib/ably/realtime/auth.rb +79 -31
- data/lib/submodules/ably-ruby/lib/ably/realtime/channel.rb +62 -26
- data/lib/submodules/ably-ruby/lib/ably/realtime/channel/channel_manager.rb +154 -65
- data/lib/submodules/ably-ruby/lib/ably/realtime/channel/channel_state_machine.rb +14 -15
- data/lib/submodules/ably-ruby/lib/ably/realtime/client.rb +16 -3
- data/lib/submodules/ably-ruby/lib/ably/realtime/client/incoming_message_dispatcher.rb +38 -29
- data/lib/submodules/ably-ruby/lib/ably/realtime/client/outgoing_message_dispatcher.rb +6 -1
- data/lib/submodules/ably-ruby/lib/ably/realtime/connection.rb +108 -49
- data/lib/submodules/ably-ruby/lib/ably/realtime/connection/connection_manager.rb +165 -59
- data/lib/submodules/ably-ruby/lib/ably/realtime/connection/connection_state_machine.rb +22 -3
- data/lib/submodules/ably-ruby/lib/ably/realtime/connection/websocket_transport.rb +19 -10
- data/lib/submodules/ably-ruby/lib/ably/realtime/presence.rb +67 -45
- data/lib/submodules/ably-ruby/lib/ably/realtime/presence/members_map.rb +198 -36
- data/lib/submodules/ably-ruby/lib/ably/realtime/presence/presence_manager.rb +30 -6
- data/lib/submodules/ably-ruby/lib/ably/realtime/presence/presence_state_machine.rb +5 -12
- data/lib/submodules/ably-ruby/lib/ably/rest/channel.rb +3 -3
- data/lib/submodules/ably-ruby/lib/ably/rest/client.rb +21 -8
- data/lib/submodules/ably-ruby/lib/ably/rest/middleware/exceptions.rb +1 -3
- data/lib/submodules/ably-ruby/lib/ably/rest/middleware/logger.rb +2 -2
- data/lib/submodules/ably-ruby/lib/ably/rest/presence.rb +1 -1
- data/lib/submodules/ably-ruby/lib/ably/util/pub_sub.rb +1 -1
- data/lib/submodules/ably-ruby/lib/ably/util/safe_deferrable.rb +26 -0
- data/lib/submodules/ably-ruby/lib/ably/version.rb +2 -2
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/auth_spec.rb +416 -99
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/channel_history_spec.rb +5 -3
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/channel_spec.rb +1011 -160
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/client_spec.rb +2 -2
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/connection_failures_spec.rb +458 -27
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/connection_spec.rb +436 -97
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/message_spec.rb +52 -23
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/presence_history_spec.rb +5 -3
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/presence_spec.rb +1160 -105
- data/lib/submodules/ably-ruby/spec/acceptance/rest/auth_spec.rb +151 -22
- data/lib/submodules/ably-ruby/spec/acceptance/rest/channel_spec.rb +1 -1
- data/lib/submodules/ably-ruby/spec/acceptance/rest/client_spec.rb +88 -27
- data/lib/submodules/ably-ruby/spec/acceptance/rest/message_spec.rb +42 -15
- data/lib/submodules/ably-ruby/spec/acceptance/rest/presence_spec.rb +4 -4
- data/lib/submodules/ably-ruby/spec/rspec_config.rb +2 -1
- data/lib/submodules/ably-ruby/spec/shared/client_initializer_behaviour.rb +2 -2
- data/lib/submodules/ably-ruby/spec/shared/safe_deferrable_behaviour.rb +6 -2
- data/lib/submodules/ably-ruby/spec/support/debug_failure_helper.rb +20 -4
- data/lib/submodules/ably-ruby/spec/support/event_machine_helper.rb +32 -1
- data/lib/submodules/ably-ruby/spec/unit/auth_spec.rb +4 -11
- data/lib/submodules/ably-ruby/spec/unit/logger_spec.rb +28 -2
- data/lib/submodules/ably-ruby/spec/unit/models/auth_details_spec.rb +49 -0
- data/lib/submodules/ably-ruby/spec/unit/models/channel_state_change_spec.rb +23 -3
- data/lib/submodules/ably-ruby/spec/unit/models/connection_details_spec.rb +12 -1
- data/lib/submodules/ably-ruby/spec/unit/models/connection_state_change_spec.rb +15 -4
- data/lib/submodules/ably-ruby/spec/unit/models/message_spec.rb +34 -2
- data/lib/submodules/ably-ruby/spec/unit/models/presence_message_spec.rb +73 -2
- data/lib/submodules/ably-ruby/spec/unit/models/protocol_message_spec.rb +64 -6
- data/lib/submodules/ably-ruby/spec/unit/models/token_details_spec.rb +1 -1
- data/lib/submodules/ably-ruby/spec/unit/models/token_request_spec.rb +1 -1
- data/lib/submodules/ably-ruby/spec/unit/modules/async_wrapper_spec.rb +2 -1
- data/lib/submodules/ably-ruby/spec/unit/modules/enum_spec.rb +69 -0
- data/lib/submodules/ably-ruby/spec/unit/modules/event_emitter_spec.rb +149 -22
- data/lib/submodules/ably-ruby/spec/unit/modules/state_emitter_spec.rb +9 -3
- data/lib/submodules/ably-ruby/spec/unit/realtime/client_spec.rb +1 -1
- data/lib/submodules/ably-ruby/spec/unit/realtime/connection_spec.rb +8 -5
- data/lib/submodules/ably-ruby/spec/unit/realtime/incoming_message_dispatcher_spec.rb +1 -1
- data/lib/submodules/ably-ruby/spec/unit/realtime/presence_spec.rb +4 -3
- data/lib/submodules/ably-ruby/spec/unit/rest/client_spec.rb +1 -1
- data/lib/submodules/ably-ruby/spec/unit/util/crypto_spec.rb +3 -3
- metadata +7 -5
|
@@ -61,6 +61,33 @@ describe Ably::Rest::Channel, 'messages' do
|
|
|
61
61
|
end
|
|
62
62
|
end
|
|
63
63
|
|
|
64
|
+
context 'with supported extra payload content type (#RSL1h, #RSL6a2)' do
|
|
65
|
+
context 'JSON Object (Hash)' do
|
|
66
|
+
let(:data) { { 'push' => { 'title' => 'Testing' } } }
|
|
67
|
+
|
|
68
|
+
it 'is encoded and decoded to the same hash' do
|
|
69
|
+
channel.publish 'event', {}, extras: data
|
|
70
|
+
expect(channel.history.items.first.extras).to eql(data)
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
context 'JSON Array' do
|
|
75
|
+
let(:data) { { 'push' => [ nil, true, false, 55, 'string', { 'Hash' => true }, ['array'] ] } }
|
|
76
|
+
|
|
77
|
+
it 'is encoded and decoded to the same Array' do
|
|
78
|
+
channel.publish 'event', {}, extras: data
|
|
79
|
+
expect(channel.history.items.first.extras).to eql(data)
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
context 'nil' do
|
|
84
|
+
it 'is encoded and decoded to the same Array' do
|
|
85
|
+
channel.publish 'event', {}, extras: nil
|
|
86
|
+
expect(channel.history.items.first.extras).to be_nil
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
64
91
|
context 'with unsupported data payload content type' do
|
|
65
92
|
context 'Integer' do
|
|
66
93
|
let(:data) { 1 }
|
|
@@ -134,7 +161,7 @@ describe Ably::Rest::Channel, 'messages' do
|
|
|
134
161
|
end
|
|
135
162
|
end
|
|
136
163
|
|
|
137
|
-
it 'encrypts message automatically when published' do
|
|
164
|
+
it 'encrypts message automatically when published (#RTL7d)' do
|
|
138
165
|
expect(client).to receive(:post) do |path, message|
|
|
139
166
|
if protocol == :json
|
|
140
167
|
expect(message['encoding']).to eql(encrypted_encoding)
|
|
@@ -149,7 +176,7 @@ describe Ably::Rest::Channel, 'messages' do
|
|
|
149
176
|
encrypted_channel.publish 'example', encoded_data_decoded
|
|
150
177
|
end
|
|
151
178
|
|
|
152
|
-
it 'sends and retrieves messages that are encrypted & decrypted by the Ably library' do
|
|
179
|
+
it 'sends and retrieves messages that are encrypted & decrypted by the Ably library (#RTL7d)' do
|
|
153
180
|
encrypted_channel.publish 'example', encoded_data_decoded
|
|
154
181
|
|
|
155
182
|
message = encrypted_channel.history.items.first
|
|
@@ -168,12 +195,12 @@ describe Ably::Rest::Channel, 'messages' do
|
|
|
168
195
|
end
|
|
169
196
|
end
|
|
170
197
|
|
|
171
|
-
context 'with AES-128-CBC using crypto-data-128.json fixtures' do
|
|
198
|
+
context 'with AES-128-CBC using crypto-data-128.json fixtures (#RTL7d)' do
|
|
172
199
|
data = JSON.parse(File.read(File.join(resources_root, 'crypto-data-128.json')))
|
|
173
200
|
add_tests_for_data data
|
|
174
201
|
end
|
|
175
202
|
|
|
176
|
-
context 'with AES-256-CBC using crypto-data-256.json fixtures' do
|
|
203
|
+
context 'with AES-256-CBC using crypto-data-256.json fixtures (#RTL7d)' do
|
|
177
204
|
data = JSON.parse(File.read(File.join(resources_root, 'crypto-data-256.json')))
|
|
178
205
|
add_tests_for_data data
|
|
179
206
|
end
|
|
@@ -246,21 +273,21 @@ describe Ably::Rest::Channel, 'messages' do
|
|
|
246
273
|
encrypted_channel.publish 'example', payload
|
|
247
274
|
end
|
|
248
275
|
|
|
249
|
-
it 'retrieves the message that remains encrypted with an encrypted encoding attribute' do
|
|
276
|
+
it 'retrieves the message that remains encrypted with an encrypted encoding attribute (#RTL7e)' do
|
|
250
277
|
message = other_client_unencrypted_channel.history.items.first
|
|
251
278
|
expect(message.data).to_not eql(payload)
|
|
252
279
|
expect(message.encoding).to match(/^cipher\+aes-256-cbc/)
|
|
253
280
|
end
|
|
254
281
|
|
|
255
|
-
it 'logs a Cipher exception' do
|
|
256
|
-
expect(other_client.logger).to receive(:error) do |
|
|
257
|
-
expect(
|
|
282
|
+
it 'logs a Cipher exception (#RTL7e)' do
|
|
283
|
+
expect(other_client.logger).to receive(:error) do |*args, &block|
|
|
284
|
+
expect(args.concat([block ? block.call : nil]).join(',')).to match(/Message cannot be decrypted/)
|
|
258
285
|
end
|
|
259
286
|
other_client_unencrypted_channel.history
|
|
260
287
|
end
|
|
261
288
|
end
|
|
262
289
|
|
|
263
|
-
context 'publishing on an encrypted channel and retrieving #history with a different algorithm on another client' do
|
|
290
|
+
context 'publishing on an encrypted channel and retrieving #history with a different algorithm on another client (#RTL7e)' do
|
|
264
291
|
let(:client_options) { default_client_options.merge(log_level: :fatal) }
|
|
265
292
|
let(:cipher_options_client1) { { key: Ably::Util::Crypto.generate_random_key(256), algorithm: 'aes', mode: 'cbc', key_length: 256 } }
|
|
266
293
|
let(:encrypted_channel_client1) { client.channel(channel_name, cipher: cipher_options_client1) }
|
|
@@ -273,15 +300,15 @@ describe Ably::Rest::Channel, 'messages' do
|
|
|
273
300
|
encrypted_channel_client1.publish 'example', payload
|
|
274
301
|
end
|
|
275
302
|
|
|
276
|
-
it 'retrieves the message that remains encrypted with an encrypted encoding attribute' do
|
|
303
|
+
it 'retrieves the message that remains encrypted with an encrypted encoding attribute (#RTL7e)' do
|
|
277
304
|
message = encrypted_channel_client2.history.items.first
|
|
278
305
|
expect(message.data).to_not eql(payload)
|
|
279
306
|
expect(message.encoding).to match(/^cipher\+aes-256-cbc/)
|
|
280
307
|
end
|
|
281
308
|
|
|
282
|
-
it 'logs a Cipher exception' do
|
|
283
|
-
expect(other_client.logger).to receive(:error) do |
|
|
284
|
-
expect(
|
|
309
|
+
it 'logs a Cipher exception (#RTL7e)' do
|
|
310
|
+
expect(other_client.logger).to receive(:error) do |*args, &block|
|
|
311
|
+
expect(args.concat([block ? block.call : nil]).join(',')).to match(/Cipher algorithm [\w-]+ does not match/)
|
|
285
312
|
end
|
|
286
313
|
encrypted_channel_client2.history
|
|
287
314
|
end
|
|
@@ -307,8 +334,8 @@ describe Ably::Rest::Channel, 'messages' do
|
|
|
307
334
|
end
|
|
308
335
|
|
|
309
336
|
it 'logs a Cipher exception' do
|
|
310
|
-
expect(other_client.logger).to receive(:error) do |
|
|
311
|
-
expect(
|
|
337
|
+
expect(other_client.logger).to receive(:error) do |*args, &block|
|
|
338
|
+
expect(args.concat([block ? block.call : nil]).join(',')).to match(/CipherError decrypting data/)
|
|
312
339
|
end
|
|
313
340
|
encrypted_channel_client2.history
|
|
314
341
|
end
|
|
@@ -399,8 +399,8 @@ describe Ably::Rest::Presence do
|
|
|
399
399
|
end
|
|
400
400
|
|
|
401
401
|
it 'logs a cipher error' do
|
|
402
|
-
expect(client.logger).to receive(:error) do |
|
|
403
|
-
expect(
|
|
402
|
+
expect(client.logger).to receive(:error) do |*args, &block|
|
|
403
|
+
expect(args.concat([block ? block.call : nil]).join(',')).to match(/Cipher algorithm [\w-]+ does not match/)
|
|
404
404
|
end
|
|
405
405
|
presence.get
|
|
406
406
|
end
|
|
@@ -423,8 +423,8 @@ describe Ably::Rest::Presence do
|
|
|
423
423
|
end
|
|
424
424
|
|
|
425
425
|
it 'logs a cipher error' do
|
|
426
|
-
expect(client.logger).to receive(:error) do |
|
|
427
|
-
expect(
|
|
426
|
+
expect(client.logger).to receive(:error) do |*args, &block|
|
|
427
|
+
expect(args.concat([block ? block.call : nil]).join(',')).to match(/Cipher algorithm [\w-]+ does not match/)
|
|
428
428
|
end
|
|
429
429
|
presence.history
|
|
430
430
|
end
|
|
@@ -41,7 +41,7 @@ RSpec.configure do |config|
|
|
|
41
41
|
end
|
|
42
42
|
|
|
43
43
|
if defined?(EventMachine)
|
|
44
|
-
config.before(:example) do
|
|
44
|
+
config.before(:example, :event_machine) do
|
|
45
45
|
# Ensure EventMachine shutdown hooks are deregistered for every test
|
|
46
46
|
EventMachine.instance_variable_set '@tails', []
|
|
47
47
|
end
|
|
@@ -52,6 +52,7 @@ RSpec.configure do |config|
|
|
|
52
52
|
if ENV['RSPEC_RETRY']
|
|
53
53
|
puts 'Running tests using RSpec retry'
|
|
54
54
|
config.verbose_retry = true # show retry status in spec process
|
|
55
|
+
config.display_try_failure_messages = true # show exception that triggered the try
|
|
55
56
|
config.default_retry_count = 3
|
|
56
57
|
config.default_sleep_interval = 2
|
|
57
58
|
end
|
|
@@ -154,9 +154,9 @@ shared_examples 'a client initializer' do
|
|
|
154
154
|
end
|
|
155
155
|
|
|
156
156
|
context 'with token_params' do
|
|
157
|
-
let(:client_options) { {
|
|
157
|
+
let(:client_options) { { default_token_params: { ttl: 777, client_id: 'john' }, token: 'token', auto_connect: false } }
|
|
158
158
|
|
|
159
|
-
it 'configures
|
|
159
|
+
it 'configures default_token_params' do
|
|
160
160
|
expect(subject.auth.token_params.fetch(:ttl)).to eql(777)
|
|
161
161
|
expect(subject.auth.token_params.fetch(:client_id)).to eql('john')
|
|
162
162
|
end
|
|
@@ -20,7 +20,9 @@ shared_examples 'a safe Deferrable' do
|
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
it 'catches exceptions in the callback and logs the error to the logger' do
|
|
23
|
-
expect(subject.send(:logger)).to receive(:error)
|
|
23
|
+
expect(subject.send(:logger)).to receive(:error) do |*args, &block|
|
|
24
|
+
expect(args.concat([block ? block.call : nil]).join(',')).to match(/#{exception.message}/)
|
|
25
|
+
end
|
|
24
26
|
subject.errback do
|
|
25
27
|
raise exception
|
|
26
28
|
end
|
|
@@ -49,7 +51,9 @@ shared_examples 'a safe Deferrable' do
|
|
|
49
51
|
end
|
|
50
52
|
|
|
51
53
|
it 'catches exceptions in the callback and logs the error to the logger' do
|
|
52
|
-
expect(subject.send(:logger)).to receive(:error)
|
|
54
|
+
expect(subject.send(:logger)).to receive(:error) do |*args, &block|
|
|
55
|
+
expect(args.concat([block ? block.call : nil]).join(',')).to match(/#{exception.message}/)
|
|
56
|
+
end
|
|
53
57
|
subject.callback do
|
|
54
58
|
raise exception
|
|
55
59
|
end
|
|
@@ -1,15 +1,31 @@
|
|
|
1
1
|
RSpec.configure do |config|
|
|
2
|
-
config.before(:example) do
|
|
2
|
+
config.before(:example) do |example|
|
|
3
|
+
next if example.metadata[:prevent_log_stubbing]
|
|
4
|
+
|
|
3
5
|
@log_output = []
|
|
4
6
|
%w(fatal error warn info debug).each do |method_name|
|
|
5
|
-
allow_any_instance_of(Ably::Logger).to receive(method_name.to_sym).and_wrap_original do |method, *args|
|
|
6
|
-
|
|
7
|
-
|
|
7
|
+
allow_any_instance_of(Ably::Logger).to receive(method_name.to_sym).and_wrap_original do |method, *args, &block|
|
|
8
|
+
# Don't log shutdown sequence to keep log noise to a minimum
|
|
9
|
+
next if RSpec.const_defined?(:EventMachine) && RSpec::EventMachine.reactor_stopping?
|
|
10
|
+
|
|
11
|
+
prefix = "#{Time.now.strftime('%H:%M:%S.%L')} [\e[33m#{method_name}\e[0m] "
|
|
12
|
+
|
|
13
|
+
begin
|
|
14
|
+
args << block.call unless block.nil?
|
|
15
|
+
@log_output << "#{prefix}#{args.compact.join(' ')}"
|
|
16
|
+
rescue StandardError => e
|
|
17
|
+
@log_output << "#{prefix}Failed to log block - #{e.class}: #{e.message}\n#{e.backtrace.join("\n")}}"
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Call original
|
|
21
|
+
method.call(*args, &block)
|
|
8
22
|
end
|
|
9
23
|
end
|
|
10
24
|
end
|
|
11
25
|
|
|
12
26
|
config.after(:example) do |example|
|
|
27
|
+
next if example.metadata[:prevent_log_stubbing]
|
|
28
|
+
|
|
13
29
|
exception = example.exception
|
|
14
30
|
puts "\n#{'-'*34}\n\e[36mVerbose Ably log from test failure\e[0m\n#{'-'*34}\n#{@log_output.join("\n")}\n\n" if exception
|
|
15
31
|
end
|
|
@@ -9,6 +9,8 @@ module RSpec
|
|
|
9
9
|
DEFAULT_TIMEOUT = 15
|
|
10
10
|
|
|
11
11
|
def run_reactor(timeout = DEFAULT_TIMEOUT)
|
|
12
|
+
@reactor_stopping = false
|
|
13
|
+
|
|
12
14
|
Timeout::timeout(timeout + 0.5) do
|
|
13
15
|
::EventMachine.run do
|
|
14
16
|
yield
|
|
@@ -16,7 +18,13 @@ module RSpec
|
|
|
16
18
|
end
|
|
17
19
|
end
|
|
18
20
|
|
|
21
|
+
def reactor_stopping?
|
|
22
|
+
@reactor_stopping
|
|
23
|
+
end
|
|
24
|
+
|
|
19
25
|
def stop_reactor
|
|
26
|
+
mark_reactor_stopping
|
|
27
|
+
|
|
20
28
|
unless realtime_clients.empty?
|
|
21
29
|
realtime_clients.shift.tap do |client|
|
|
22
30
|
# Ensure close appens outside of the caller as this can cause errbacks on Deferrables
|
|
@@ -45,6 +53,10 @@ module RSpec
|
|
|
45
53
|
@realtime_clients ||= []
|
|
46
54
|
end
|
|
47
55
|
|
|
56
|
+
def mark_reactor_stopping
|
|
57
|
+
@reactor_stopping = true
|
|
58
|
+
end
|
|
59
|
+
|
|
48
60
|
# Allows multiple Deferrables to be passed in and calls the provided block when
|
|
49
61
|
# all success callbacks have completed
|
|
50
62
|
def when_all(*deferrables)
|
|
@@ -123,8 +135,27 @@ RSpec.configure do |config|
|
|
|
123
135
|
example.run
|
|
124
136
|
end
|
|
125
137
|
|
|
126
|
-
config.before(:example) do
|
|
138
|
+
config.before(:example, :event_machine) do
|
|
127
139
|
# Ensure EventMachine shutdown hooks are deregistered for every test
|
|
128
140
|
EventMachine.instance_variable_set '@tails', []
|
|
129
141
|
end
|
|
130
142
|
end
|
|
143
|
+
|
|
144
|
+
module RSpec
|
|
145
|
+
module Expectations
|
|
146
|
+
module ExpectationHelper
|
|
147
|
+
class << self
|
|
148
|
+
# This is very hacky and ties into the internals of RSpec which is likely to break in future versions
|
|
149
|
+
# However, this is just a convenience to reduce log noise when the reactor is stopping
|
|
150
|
+
# i.e. debug_failure_helper logs the verbose messages generated by the libraries, however it also often
|
|
151
|
+
# catches all the shutdown messages which is unnecessary
|
|
152
|
+
alias_method :orig_handle_failure, :handle_failure
|
|
153
|
+
|
|
154
|
+
def handle_failure(*args, &block)
|
|
155
|
+
RSpec::EventMachine.mark_reactor_stopping
|
|
156
|
+
orig_handle_failure(*args, &block)
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
end
|
|
@@ -68,19 +68,12 @@ describe Ably::Auth do
|
|
|
68
68
|
end
|
|
69
69
|
|
|
70
70
|
context 'defaults' do
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
it 'should default TTL to 1 hour' do
|
|
75
|
-
expect(Ably::Auth::TOKEN_DEFAULTS.fetch(:ttl)).to eql(one_hour)
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
it 'should default capability to all' do
|
|
79
|
-
expect(Ably::Auth::TOKEN_DEFAULTS.fetch(:capability)).to eql(all_capabilities)
|
|
71
|
+
it 'should have no default TTL' do
|
|
72
|
+
expect(Ably::Auth::TOKEN_DEFAULTS[:ttl]).to be_nil
|
|
80
73
|
end
|
|
81
74
|
|
|
82
|
-
it 'should have
|
|
83
|
-
expect(Ably::Auth::TOKEN_DEFAULTS
|
|
75
|
+
it 'should have no default capability' do
|
|
76
|
+
expect(Ably::Auth::TOKEN_DEFAULTS[:capability]).to be_nil
|
|
84
77
|
end
|
|
85
78
|
end
|
|
86
79
|
end
|
|
@@ -18,7 +18,9 @@ describe Ably::Logger do
|
|
|
18
18
|
|
|
19
19
|
context 'internals', :api_private do
|
|
20
20
|
it 'delegates to the logger object' do
|
|
21
|
-
expect(subject.logger).to receive(:warn)
|
|
21
|
+
expect(subject.logger).to receive(:warn) do |*args, &block|
|
|
22
|
+
expect(args.concat([block ? block.call : nil]).join(',')).to match(/message/)
|
|
23
|
+
end
|
|
22
24
|
subject.warn 'message'
|
|
23
25
|
end
|
|
24
26
|
|
|
@@ -138,9 +140,33 @@ describe Ably::Logger do
|
|
|
138
140
|
end
|
|
139
141
|
|
|
140
142
|
it 'delegates log messages to logger', :api_private do
|
|
141
|
-
expect(custom_logger_object).to receive(:fatal)
|
|
143
|
+
expect(custom_logger_object).to receive(:fatal) do |*args, &block|
|
|
144
|
+
expect(args.concat([block ? block.call : nil]).join(',')).to match(/message/)
|
|
145
|
+
end
|
|
142
146
|
subject.fatal 'message'
|
|
143
147
|
end
|
|
144
148
|
end
|
|
145
149
|
end
|
|
150
|
+
|
|
151
|
+
context 'with blocks', :prevent_log_stubbing do
|
|
152
|
+
it 'does not call the block unless the log level is met' do
|
|
153
|
+
log_level_blocks = []
|
|
154
|
+
subject.warn { log_level_blocks << :warn }
|
|
155
|
+
subject.info { log_level_blocks << :info }
|
|
156
|
+
subject.debug { log_level_blocks << :debug }
|
|
157
|
+
expect(log_level_blocks).to contain_exactly(:warn, :info)
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
context 'with an exception in the logger block' do
|
|
161
|
+
before do
|
|
162
|
+
expect(subject.logger).to receive(:error) do |*args, &block|
|
|
163
|
+
expect(args.concat([block ? block.call : nil]).join(',')).to match(/Raise an error in the block/)
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
it 'catches the error and continues' do
|
|
168
|
+
subject.info { raise "Raise an error in the block" }
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
end
|
|
146
172
|
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'shared/model_behaviour'
|
|
3
|
+
|
|
4
|
+
describe Ably::Models::AuthDetails do
|
|
5
|
+
include Ably::Modules::Conversions
|
|
6
|
+
|
|
7
|
+
subject { Ably::Models::AuthDetails }
|
|
8
|
+
|
|
9
|
+
# Spec model items AD2*
|
|
10
|
+
it_behaves_like 'a model', with_simple_attributes: %w(access_token) do
|
|
11
|
+
let(:model_args) { [] }
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
context '==' do
|
|
15
|
+
let(:attributes) { { access_token: 'unique' } }
|
|
16
|
+
|
|
17
|
+
it 'is true when attributes are the same' do
|
|
18
|
+
auth_details = -> { Ably::Models::AuthDetails.new(attributes) }
|
|
19
|
+
expect(auth_details.call).to eq(auth_details.call)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it 'is false when attributes are not the same' do
|
|
23
|
+
expect(Ably::Models::AuthDetails.new(access_token: '1')).to_not eq(Ably::Models::AuthDetails.new(access_token: '2'))
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it 'is false when class type differs' do
|
|
27
|
+
expect(Ably::Models::AuthDetails.new(access_token: '1')).to_not eq(nil)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
context 'AuthDetails conversion methods', :api_private do
|
|
32
|
+
context 'with a AuthDetails object' do
|
|
33
|
+
let(:details) { Ably::Models::AuthDetails.new(access_token: random_str) }
|
|
34
|
+
|
|
35
|
+
it 'returns the AuthDetails object' do
|
|
36
|
+
expect(Ably::Models::AuthDetails(details)).to eql(details)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
context 'with a JSON object' do
|
|
41
|
+
let(:access_token) { random_str }
|
|
42
|
+
let(:details_json) { { access_token: access_token } }
|
|
43
|
+
|
|
44
|
+
it 'returns a new AuthDetails object from the JSON' do
|
|
45
|
+
expect(Ably::Models::AuthDetails(details_json).access_token).to eql(access_token)
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -6,7 +6,7 @@ describe Ably::Models::ChannelStateChange do
|
|
|
6
6
|
|
|
7
7
|
subject { Ably::Models::ChannelStateChange }
|
|
8
8
|
|
|
9
|
-
context '#current' do
|
|
9
|
+
context '#current (#TH1)' do
|
|
10
10
|
it 'is required' do
|
|
11
11
|
expect { subject.new(previous: true) }.to raise_error ArgumentError
|
|
12
12
|
end
|
|
@@ -16,7 +16,7 @@ describe Ably::Models::ChannelStateChange do
|
|
|
16
16
|
end
|
|
17
17
|
end
|
|
18
18
|
|
|
19
|
-
context '#previous' do
|
|
19
|
+
context '#previous (#TH2)' do
|
|
20
20
|
it 'is required' do
|
|
21
21
|
expect { subject.new(current: true) }.to raise_error ArgumentError
|
|
22
22
|
end
|
|
@@ -26,7 +26,17 @@ describe Ably::Models::ChannelStateChange do
|
|
|
26
26
|
end
|
|
27
27
|
end
|
|
28
28
|
|
|
29
|
-
context '#
|
|
29
|
+
context '#event (#TH5)' do
|
|
30
|
+
it 'is not required' do
|
|
31
|
+
expect { subject.new(previous: true, current: true) }.to_not raise_error
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it 'is an attribute' do
|
|
35
|
+
expect(subject.new(event: unique, previous: unique, current: true).event).to eql(unique)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
context '#reason (#TH3)' do
|
|
30
40
|
it 'is not required' do
|
|
31
41
|
expect { subject.new(previous: true, current: true) }.to_not raise_error
|
|
32
42
|
end
|
|
@@ -36,6 +46,16 @@ describe Ably::Models::ChannelStateChange do
|
|
|
36
46
|
end
|
|
37
47
|
end
|
|
38
48
|
|
|
49
|
+
context '#resumed (#TH4)' do
|
|
50
|
+
it 'is false when ommitted' do
|
|
51
|
+
expect(subject.new(previous: true, current: true).resumed).to be_falsey
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
it 'is true when provided' do
|
|
55
|
+
expect(subject.new(previous: true, current: true, resumed: true).resumed).to be_truthy
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
39
59
|
context 'invalid attributes' do
|
|
40
60
|
it 'raises an argument error' do
|
|
41
61
|
expect { subject.new(invalid: true, current: true, previous: true) }.to raise_error ArgumentError
|