ably 0.8.15 → 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/.travis.yml +6 -4
- data/CHANGELOG.md +6 -2
- data/README.md +5 -1
- data/SPEC.md +1473 -852
- data/ably.gemspec +11 -8
- data/lib/ably/auth.rb +90 -53
- data/lib/ably/exceptions.rb +37 -8
- data/lib/ably/logger.rb +10 -1
- data/lib/ably/models/auth_details.rb +42 -0
- data/lib/ably/models/channel_state_change.rb +18 -4
- data/lib/ably/models/connection_details.rb +6 -3
- data/lib/ably/models/connection_state_change.rb +4 -3
- data/lib/ably/models/error_info.rb +1 -1
- data/lib/ably/models/message.rb +17 -1
- data/lib/ably/models/message_encoders/base.rb +103 -82
- data/lib/ably/models/message_encoders/base64.rb +1 -1
- data/lib/ably/models/presence_message.rb +16 -1
- data/lib/ably/models/protocol_message.rb +20 -3
- data/lib/ably/models/token_details.rb +11 -1
- data/lib/ably/models/token_request.rb +16 -6
- data/lib/ably/modules/async_wrapper.rb +7 -3
- data/lib/ably/modules/encodeable.rb +51 -12
- data/lib/ably/modules/enum.rb +17 -7
- data/lib/ably/modules/event_emitter.rb +29 -14
- data/lib/ably/modules/model_common.rb +13 -21
- data/lib/ably/modules/state_emitter.rb +7 -4
- data/lib/ably/modules/state_machine.rb +2 -4
- data/lib/ably/modules/uses_state_machine.rb +7 -3
- data/lib/ably/realtime.rb +2 -0
- data/lib/ably/realtime/auth.rb +102 -42
- data/lib/ably/realtime/channel.rb +68 -26
- data/lib/ably/realtime/channel/channel_manager.rb +154 -65
- data/lib/ably/realtime/channel/channel_state_machine.rb +14 -15
- data/lib/ably/realtime/client.rb +18 -3
- data/lib/ably/realtime/client/incoming_message_dispatcher.rb +38 -29
- data/lib/ably/realtime/client/outgoing_message_dispatcher.rb +6 -1
- data/lib/ably/realtime/connection.rb +108 -49
- data/lib/ably/realtime/connection/connection_manager.rb +167 -61
- data/lib/ably/realtime/connection/connection_state_machine.rb +22 -3
- data/lib/ably/realtime/connection/websocket_transport.rb +19 -10
- data/lib/ably/realtime/presence.rb +70 -45
- data/lib/ably/realtime/presence/members_map.rb +201 -36
- data/lib/ably/realtime/presence/presence_manager.rb +30 -6
- data/lib/ably/realtime/presence/presence_state_machine.rb +5 -12
- data/lib/ably/rest.rb +2 -2
- data/lib/ably/rest/channel.rb +5 -5
- data/lib/ably/rest/client.rb +31 -27
- data/lib/ably/rest/middleware/exceptions.rb +1 -3
- data/lib/ably/rest/middleware/logger.rb +2 -2
- data/lib/ably/rest/presence.rb +2 -2
- data/lib/ably/util/pub_sub.rb +1 -1
- data/lib/ably/util/safe_deferrable.rb +26 -0
- data/lib/ably/version.rb +2 -2
- data/spec/acceptance/realtime/auth_spec.rb +470 -111
- data/spec/acceptance/realtime/channel_history_spec.rb +5 -3
- data/spec/acceptance/realtime/channel_spec.rb +1017 -168
- data/spec/acceptance/realtime/client_spec.rb +6 -6
- data/spec/acceptance/realtime/connection_failures_spec.rb +458 -27
- data/spec/acceptance/realtime/connection_spec.rb +424 -105
- data/spec/acceptance/realtime/message_spec.rb +52 -23
- data/spec/acceptance/realtime/presence_history_spec.rb +5 -3
- data/spec/acceptance/realtime/presence_spec.rb +1110 -96
- data/spec/acceptance/rest/auth_spec.rb +222 -59
- data/spec/acceptance/rest/base_spec.rb +1 -1
- data/spec/acceptance/rest/channel_spec.rb +1 -2
- data/spec/acceptance/rest/client_spec.rb +104 -48
- data/spec/acceptance/rest/message_spec.rb +42 -15
- data/spec/acceptance/rest/presence_spec.rb +4 -11
- data/spec/rspec_config.rb +2 -1
- data/spec/shared/client_initializer_behaviour.rb +2 -2
- data/spec/shared/safe_deferrable_behaviour.rb +6 -2
- data/spec/spec_helper.rb +4 -2
- data/spec/support/debug_failure_helper.rb +20 -4
- data/spec/support/event_machine_helper.rb +32 -1
- data/spec/unit/auth_spec.rb +4 -11
- data/spec/unit/logger_spec.rb +28 -2
- data/spec/unit/models/auth_details_spec.rb +49 -0
- data/spec/unit/models/channel_state_change_spec.rb +23 -3
- data/spec/unit/models/connection_details_spec.rb +12 -1
- data/spec/unit/models/connection_state_change_spec.rb +15 -4
- data/spec/unit/models/message_encoders/base64_spec.rb +2 -1
- data/spec/unit/models/message_spec.rb +153 -0
- data/spec/unit/models/presence_message_spec.rb +192 -0
- data/spec/unit/models/protocol_message_spec.rb +64 -6
- data/spec/unit/models/token_details_spec.rb +75 -0
- data/spec/unit/models/token_request_spec.rb +74 -0
- data/spec/unit/modules/async_wrapper_spec.rb +2 -1
- data/spec/unit/modules/enum_spec.rb +69 -0
- data/spec/unit/modules/event_emitter_spec.rb +149 -22
- data/spec/unit/modules/state_emitter_spec.rb +9 -3
- data/spec/unit/realtime/client_spec.rb +1 -1
- data/spec/unit/realtime/connection_spec.rb +8 -5
- data/spec/unit/realtime/incoming_message_dispatcher_spec.rb +1 -1
- data/spec/unit/realtime/presence_spec.rb +4 -3
- data/spec/unit/rest/client_spec.rb +1 -1
- data/spec/unit/util/crypto_spec.rb +3 -3
- metadata +22 -19
@@ -74,7 +74,6 @@ describe Ably::Rest::Presence do
|
|
74
74
|
let!(:get_stub) {
|
75
75
|
query_params = query_options.map { |k, v| "#{k}=#{v}" }.join('&')
|
76
76
|
stub_request(:get, "#{endpoint}/channels/#{Addressable::URI.encode(channel_name)}/presence?#{query_params}").
|
77
|
-
with(basic_auth: [key_name, key_secret]).
|
78
77
|
to_return(:body => '{}', :headers => { 'Content-Type' => 'application/json' })
|
79
78
|
}
|
80
79
|
let(:channel_name) { random_str }
|
@@ -196,7 +195,6 @@ describe Ably::Rest::Presence do
|
|
196
195
|
let!(:history_stub) {
|
197
196
|
query_params = history_options.map { |k, v| "#{k}=#{v}" }.join('&')
|
198
197
|
stub_request(:get, "#{endpoint}/channels/#{Addressable::URI.encode(channel_name)}/presence/history?#{query_params}").
|
199
|
-
with(basic_auth: [user, secret]).
|
200
198
|
to_return(:body => '{}', :headers => { 'Content-Type' => 'application/json' })
|
201
199
|
}
|
202
200
|
|
@@ -237,7 +235,6 @@ describe Ably::Rest::Presence do
|
|
237
235
|
let!(:history_stub) {
|
238
236
|
query_params = history_options.map { |k, v| "#{k}=#{v}" }.join('&')
|
239
237
|
stub_request(:get, "#{endpoint}/channels/#{Addressable::URI.encode(channel_name)}/presence/history?#{query_params}").
|
240
|
-
with(basic_auth: [user, secret]).
|
241
238
|
to_return(:body => '{}', :headers => { 'Content-Type' => 'application/json' })
|
242
239
|
}
|
243
240
|
|
@@ -342,7 +339,6 @@ describe Ably::Rest::Presence do
|
|
342
339
|
context '#get' do
|
343
340
|
let!(:get_stub) {
|
344
341
|
stub_request(:get, "#{endpoint}/channels/#{Addressable::URI.encode(channel_name)}/presence?limit=100").
|
345
|
-
with(basic_auth: [user, secret]).
|
346
342
|
to_return(:body => serialized_encoded_message, :headers => { 'Content-Type' => content_type })
|
347
343
|
}
|
348
344
|
|
@@ -360,7 +356,6 @@ describe Ably::Rest::Presence do
|
|
360
356
|
context '#history' do
|
361
357
|
let!(:history_stub) {
|
362
358
|
stub_request(:get, "#{endpoint}/channels/#{Addressable::URI.encode(channel_name)}/presence/history?direction=backwards&limit=100").
|
363
|
-
with(basic_auth: [user, secret]).
|
364
359
|
to_return(:body => serialized_encoded_message, :headers => { 'Content-Type' => content_type })
|
365
360
|
}
|
366
361
|
|
@@ -391,7 +386,6 @@ describe Ably::Rest::Presence do
|
|
391
386
|
let(:client_options) { default_options.merge(log_level: :fatal) }
|
392
387
|
let!(:get_stub) {
|
393
388
|
stub_request(:get, "#{endpoint}/channels/#{Addressable::URI.encode(channel_name)}/presence?limit=100").
|
394
|
-
with(basic_auth: [user, secret]).
|
395
389
|
to_return(:body => serialized_encoded_message_with_invalid_encoding, :headers => { 'Content-Type' => content_type })
|
396
390
|
}
|
397
391
|
let(:presence_message) { presence.get.items.first }
|
@@ -405,8 +399,8 @@ describe Ably::Rest::Presence do
|
|
405
399
|
end
|
406
400
|
|
407
401
|
it 'logs a cipher error' do
|
408
|
-
expect(client.logger).to receive(:error) do |
|
409
|
-
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/)
|
410
404
|
end
|
411
405
|
presence.get
|
412
406
|
end
|
@@ -416,7 +410,6 @@ describe Ably::Rest::Presence do
|
|
416
410
|
let(:client_options) { default_options.merge(log_level: :fatal) }
|
417
411
|
let!(:history_stub) {
|
418
412
|
stub_request(:get, "#{endpoint}/channels/#{Addressable::URI.encode(channel_name)}/presence/history?direction=backwards&limit=100").
|
419
|
-
with(basic_auth: [user, secret]).
|
420
413
|
to_return(:body => serialized_encoded_message_with_invalid_encoding, :headers => { 'Content-Type' => content_type })
|
421
414
|
}
|
422
415
|
let(:presence_message) { presence.history.items.first }
|
@@ -430,8 +423,8 @@ describe Ably::Rest::Presence do
|
|
430
423
|
end
|
431
424
|
|
432
425
|
it 'logs a cipher error' do
|
433
|
-
expect(client.logger).to receive(:error) do |
|
434
|
-
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/)
|
435
428
|
end
|
436
429
|
presence.history
|
437
430
|
end
|
data/spec/rspec_config.rb
CHANGED
@@ -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
|
data/spec/spec_helper.rb
CHANGED
@@ -4,8 +4,10 @@ def console(message)
|
|
4
4
|
puts "\033[31m[#{Time.now.strftime('%H:%M:%S.%L')}]\033[0m \033[33m#{message}\033[0m"
|
5
5
|
end
|
6
6
|
|
7
|
-
|
8
|
-
|
7
|
+
unless RUBY_VERSION.match(/^1/)
|
8
|
+
require 'coveralls'
|
9
|
+
Coveralls.wear!
|
10
|
+
end
|
9
11
|
|
10
12
|
require 'webmock/rspec'
|
11
13
|
|
@@ -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
|
data/spec/unit/auth_spec.rb
CHANGED
@@ -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
|
data/spec/unit/logger_spec.rb
CHANGED
@@ -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
|
@@ -6,6 +6,7 @@ describe Ably::Models::ConnectionDetails do
|
|
6
6
|
|
7
7
|
subject { Ably::Models::ConnectionDetails }
|
8
8
|
|
9
|
+
# Spec model items CD2*
|
9
10
|
it_behaves_like 'a model', with_simple_attributes: %w(client_id connection_key max_message_size max_frame_size max_inbound_rate) do
|
10
11
|
let(:model_args) { [] }
|
11
12
|
end
|
@@ -13,13 +14,23 @@ describe Ably::Models::ConnectionDetails do
|
|
13
14
|
context 'attributes' do
|
14
15
|
let(:connection_state_ttl_ms) { 5_000 }
|
15
16
|
|
16
|
-
context '#connection_state_ttl' do
|
17
|
+
context '#connection_state_ttl (#CD2f)' do
|
17
18
|
subject { Ably::Models::ConnectionDetails.new({ connection_state_ttl: connection_state_ttl_ms }) }
|
18
19
|
|
19
20
|
it 'retrieves attribute :connection_state_ttl and converts it from ms to s' do
|
20
21
|
expect(subject.connection_state_ttl).to eql(connection_state_ttl_ms / 1000)
|
21
22
|
end
|
22
23
|
end
|
24
|
+
|
25
|
+
let(:max_idle_interval) { 6_000 }
|
26
|
+
|
27
|
+
context '#max_idle_interval (#CD2h)' do
|
28
|
+
subject { Ably::Models::ConnectionDetails.new({ max_idle_interval: max_idle_interval }) }
|
29
|
+
|
30
|
+
it 'retrieves attribute :max_idle_interval and converts it from ms to s' do
|
31
|
+
expect(subject.max_idle_interval).to eql(max_idle_interval / 1000)
|
32
|
+
end
|
33
|
+
end
|
23
34
|
end
|
24
35
|
|
25
36
|
context '==' do
|