ably 1.0.7 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.editorconfig +14 -0
- data/.travis.yml +4 -4
- data/CHANGELOG.md +26 -3
- data/Rakefile +32 -0
- data/SPEC.md +920 -565
- data/ably.gemspec +9 -4
- data/lib/ably/auth.rb +28 -2
- data/lib/ably/exceptions.rb +8 -2
- data/lib/ably/models/channel_state_change.rb +1 -1
- data/lib/ably/models/connection_state_change.rb +1 -1
- data/lib/ably/models/device_details.rb +87 -0
- data/lib/ably/models/device_push_details.rb +86 -0
- data/lib/ably/models/error_info.rb +23 -2
- data/lib/ably/models/idiomatic_ruby_wrapper.rb +4 -4
- data/lib/ably/models/protocol_message.rb +32 -2
- data/lib/ably/models/push_channel_subscription.rb +89 -0
- data/lib/ably/modules/conversions.rb +1 -1
- data/lib/ably/modules/encodeable.rb +1 -1
- data/lib/ably/modules/exception_codes.rb +128 -0
- data/lib/ably/modules/model_common.rb +15 -2
- data/lib/ably/modules/state_machine.rb +1 -1
- data/lib/ably/realtime.rb +1 -0
- data/lib/ably/realtime/auth.rb +1 -1
- data/lib/ably/realtime/channel.rb +24 -102
- data/lib/ably/realtime/channel/channel_manager.rb +2 -6
- data/lib/ably/realtime/channel/channel_state_machine.rb +2 -2
- data/lib/ably/realtime/channel/publisher.rb +74 -0
- data/lib/ably/realtime/channel/push_channel.rb +62 -0
- data/lib/ably/realtime/client.rb +87 -0
- data/lib/ably/realtime/client/incoming_message_dispatcher.rb +6 -2
- data/lib/ably/realtime/client/outgoing_message_dispatcher.rb +1 -1
- data/lib/ably/realtime/connection.rb +8 -5
- data/lib/ably/realtime/connection/connection_manager.rb +7 -7
- data/lib/ably/realtime/connection/websocket_transport.rb +1 -1
- data/lib/ably/realtime/presence.rb +4 -4
- data/lib/ably/realtime/presence/members_map.rb +3 -3
- data/lib/ably/realtime/push.rb +40 -0
- data/lib/ably/realtime/push/admin.rb +61 -0
- data/lib/ably/realtime/push/channel_subscriptions.rb +108 -0
- data/lib/ably/realtime/push/device_registrations.rb +105 -0
- data/lib/ably/rest.rb +1 -0
- data/lib/ably/rest/channel.rb +33 -5
- data/lib/ably/rest/channel/push_channel.rb +62 -0
- data/lib/ably/rest/client.rb +137 -28
- data/lib/ably/rest/middleware/parse_message_pack.rb +17 -1
- data/lib/ably/rest/presence.rb +1 -0
- data/lib/ably/rest/push.rb +42 -0
- data/lib/ably/rest/push/admin.rb +54 -0
- data/lib/ably/rest/push/channel_subscriptions.rb +121 -0
- data/lib/ably/rest/push/device_registrations.rb +103 -0
- data/lib/ably/version.rb +7 -2
- data/spec/acceptance/realtime/auth_spec.rb +6 -8
- data/spec/acceptance/realtime/channel_spec.rb +166 -51
- data/spec/acceptance/realtime/client_spec.rb +149 -0
- data/spec/acceptance/realtime/connection_failures_spec.rb +1 -1
- data/spec/acceptance/realtime/connection_spec.rb +4 -4
- data/spec/acceptance/realtime/message_spec.rb +19 -17
- data/spec/acceptance/realtime/presence_spec.rb +5 -5
- data/spec/acceptance/realtime/push_admin_spec.rb +696 -0
- data/spec/acceptance/realtime/push_spec.rb +27 -0
- data/spec/acceptance/rest/auth_spec.rb +4 -3
- data/spec/acceptance/rest/base_spec.rb +2 -2
- data/spec/acceptance/rest/client_spec.rb +129 -10
- data/spec/acceptance/rest/message_spec.rb +175 -4
- data/spec/acceptance/rest/push_admin_spec.rb +896 -0
- data/spec/acceptance/rest/push_spec.rb +25 -0
- data/spec/acceptance/rest/time_spec.rb +1 -1
- data/spec/run_parallel_tests +33 -0
- data/spec/unit/logger_spec.rb +10 -3
- data/spec/unit/models/device_details_spec.rb +102 -0
- data/spec/unit/models/device_push_details_spec.rb +101 -0
- data/spec/unit/models/error_info_spec.rb +51 -3
- data/spec/unit/models/message_spec.rb +17 -2
- data/spec/unit/models/presence_message_spec.rb +1 -1
- data/spec/unit/models/push_channel_subscription_spec.rb +86 -0
- data/spec/unit/realtime/client_spec.rb +12 -0
- data/spec/unit/realtime/push_channel_spec.rb +36 -0
- data/spec/unit/rest/channel_spec.rb +8 -1
- data/spec/unit/rest/client_spec.rb +30 -0
- data/spec/unit/rest/push_channel_spec.rb +36 -0
- metadata +71 -8
@@ -0,0 +1,25 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe Ably::Rest::Push do
|
5
|
+
vary_by_protocol do
|
6
|
+
let(:default_options) { { key: api_key, environment: environment, protocol: protocol} }
|
7
|
+
let(:client_options) { default_options }
|
8
|
+
let(:client) do
|
9
|
+
Ably::Rest::Client.new(client_options)
|
10
|
+
end
|
11
|
+
subject { client.push }
|
12
|
+
|
13
|
+
describe '#activate' do
|
14
|
+
it 'raises an unsupported exception' do
|
15
|
+
expect { subject.activate('foo') }.to raise_error(Ably::Exceptions::PushNotificationsNotSupported)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe '#deactivate' do
|
20
|
+
it 'raises an unsupported exception' do
|
21
|
+
expect { subject.deactivate('foo') }.to raise_error(Ably::Exceptions::PushNotificationsNotSupported)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -13,7 +13,7 @@ describe Ably::Rest::Client, '#time' do
|
|
13
13
|
|
14
14
|
context 'with reconfigured HTTP timeout' do
|
15
15
|
let(:client) do
|
16
|
-
Ably::Rest::Client.new(http_request_timeout: 0.0001, key: api_key, environment: environment, protocol: protocol)
|
16
|
+
Ably::Rest::Client.new(http_request_timeout: 0.0001, key: api_key, environment: environment, protocol: protocol, log_retries_as_info: true)
|
17
17
|
end
|
18
18
|
|
19
19
|
it 'should raise a timeout exception' do
|
@@ -0,0 +1,33 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
#
|
3
|
+
# Run the unit tests first without RSpec parallel, then run acceptance tests in parallel
|
4
|
+
#
|
5
|
+
# When splitting all tests across all parallel processes, it's quite plausible
|
6
|
+
# that some processes only run a majority of unit tests, whilst others only run a
|
7
|
+
# a majority of acceptance tests. This ensures acceptance tests are split out.
|
8
|
+
|
9
|
+
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
|
10
|
+
|
11
|
+
bundle exec rspec "${DIR}/unit"
|
12
|
+
unit_status=$?
|
13
|
+
|
14
|
+
if ruby -v | grep -e "1.9"; then
|
15
|
+
# Output with test ID is not supported with this old version of RSpec
|
16
|
+
# So it will be jumbled sadly for 1.9.*
|
17
|
+
bundle exec parallel_rspec "${DIR}/acceptance"
|
18
|
+
else
|
19
|
+
bundle exec parallel_rspec "${DIR}/acceptance" --prefix-output-with-test-env-number
|
20
|
+
fi
|
21
|
+
acceptance_status=$?
|
22
|
+
|
23
|
+
if [ $unit_status -ne 0 ]; then
|
24
|
+
echo -e "\e[31m⚠ Note: Unit tests have also failed, but are not listed in the test failures above. Scroll up to the unit tests ⚠\e[0m"
|
25
|
+
fi
|
26
|
+
|
27
|
+
if [ $unit_status -ne 0 ] || [ $acceptance_status -ne 0 ]; then
|
28
|
+
echo "Unit tests exit code: ${unit_status}"
|
29
|
+
echo "Acceptance tests exit code: ${acceptance_status}"
|
30
|
+
exit 1
|
31
|
+
fi
|
32
|
+
|
33
|
+
|
data/spec/unit/logger_spec.rb
CHANGED
@@ -17,11 +17,15 @@ describe Ably::Logger do
|
|
17
17
|
end
|
18
18
|
|
19
19
|
context 'internals', :api_private do
|
20
|
-
it 'delegates to the
|
21
|
-
|
20
|
+
it 'delegates to the default Logger object' do
|
21
|
+
received = false
|
22
|
+
expect(subject.logger).to be_a(::Logger)
|
23
|
+
allow_any_instance_of(::Logger).to receive(:warn) do |*args, &block|
|
22
24
|
expect(args.concat([block ? block.call : nil]).join(',')).to match(/message/)
|
25
|
+
received = true
|
23
26
|
end
|
24
27
|
subject.warn 'message'
|
28
|
+
expect(received).to be_truthy
|
25
29
|
end
|
26
30
|
|
27
31
|
context 'formatter' do
|
@@ -132,10 +136,13 @@ describe Ably::Logger do
|
|
132
136
|
end
|
133
137
|
|
134
138
|
it 'delegates log messages to logger', :api_private do
|
135
|
-
|
139
|
+
received = false
|
140
|
+
allow(custom_logger_object).to receive(:fatal) do |*args, &block|
|
136
141
|
expect(args.concat([block ? block.call : nil]).join(',')).to match(/message/)
|
142
|
+
received = true
|
137
143
|
end
|
138
144
|
subject.fatal 'message'
|
145
|
+
expect(received).to be_truthy
|
139
146
|
end
|
140
147
|
end
|
141
148
|
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'spec_helper'
|
3
|
+
require 'shared/model_behaviour'
|
4
|
+
|
5
|
+
describe Ably::Models::DeviceDetails do
|
6
|
+
include Ably::Modules::Conversions
|
7
|
+
|
8
|
+
subject { Ably::Models::DeviceDetails }
|
9
|
+
|
10
|
+
%w(id platform form_factor client_id device_secret).each do |string_attribute|
|
11
|
+
let(:empty_device_details) { subject.new }
|
12
|
+
|
13
|
+
describe "##{string_attribute} and ##{string_attribute}=" do
|
14
|
+
let(:new_val) { random_str }
|
15
|
+
|
16
|
+
specify 'setter accepts a string value and getter returns the new value' do
|
17
|
+
expect(empty_device_details.public_send(string_attribute)).to be_nil
|
18
|
+
empty_device_details.public_send("#{string_attribute}=", new_val)
|
19
|
+
expect(empty_device_details.public_send(string_attribute)).to eql(new_val)
|
20
|
+
end
|
21
|
+
|
22
|
+
specify 'setter accepts nil' do
|
23
|
+
empty_device_details.public_send("#{string_attribute}=", new_val)
|
24
|
+
expect(empty_device_details.public_send(string_attribute)).to eql(new_val)
|
25
|
+
empty_device_details.public_send("#{string_attribute}=", nil)
|
26
|
+
expect(empty_device_details.public_send(string_attribute)).to be_nil
|
27
|
+
end
|
28
|
+
|
29
|
+
specify 'rejects non string or nil values' do
|
30
|
+
expect { empty_device_details.public_send("#{string_attribute}=", {}) }.to raise_error(ArgumentError)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context 'camelCase constructor attributes' do
|
36
|
+
let(:client_id) { random_str }
|
37
|
+
let(:device_details) { subject.new("clientId" => client_id ) }
|
38
|
+
|
39
|
+
specify 'are rubyfied and exposed as underscore case' do
|
40
|
+
expect(device_details.client_id).to eql(client_id)
|
41
|
+
end
|
42
|
+
|
43
|
+
specify 'are generated when the object is serialised to JSON' do
|
44
|
+
expect(JSON.parse(device_details.to_json)["clientId"]).to eql(client_id)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe "#metadata and #metadata=" do
|
49
|
+
let(:new_val) { { foo: random_str } }
|
50
|
+
|
51
|
+
specify 'setter accepts a Hash value and getter returns the new value' do
|
52
|
+
expect(empty_device_details.metadata).to eql({})
|
53
|
+
empty_device_details.metadata = new_val
|
54
|
+
expect(empty_device_details.metadata.to_json).to eql(new_val.to_json)
|
55
|
+
end
|
56
|
+
|
57
|
+
specify 'setter accepts nil but always returns an empty hash' do
|
58
|
+
empty_device_details.metadata = new_val
|
59
|
+
expect(empty_device_details.metadata.to_json).to eql(new_val.to_json)
|
60
|
+
empty_device_details.metadata = nil
|
61
|
+
expect(empty_device_details.metadata).to eql({})
|
62
|
+
end
|
63
|
+
|
64
|
+
specify 'rejects non Hash or nil values' do
|
65
|
+
expect { empty_device_details.metadata = "foo" }.to raise_error(ArgumentError)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
describe "#push and #push=" do
|
70
|
+
let(:transport_type) { random_str }
|
71
|
+
let(:new_val) { { recipient: { transport_type: transport_type } } }
|
72
|
+
let(:json_val) { { recipient: { transportType: transport_type } }.to_json }
|
73
|
+
|
74
|
+
specify 'setter accepts a DevicePushDetails object and getter returns a DevicePushDetails object' do
|
75
|
+
expect(empty_device_details.push.to_json).to eql({}.to_json)
|
76
|
+
empty_device_details.push = DevicePushDetails(new_val)
|
77
|
+
expect(empty_device_details.push).to be_a(Ably::Models::DevicePushDetails)
|
78
|
+
expect(empty_device_details.push.recipient[:transport_type]).to eql(transport_type)
|
79
|
+
expect(empty_device_details.push.to_json).to eql(json_val)
|
80
|
+
end
|
81
|
+
|
82
|
+
specify 'setter accepts a Hash value and getter returns a DevicePushDetails object' do
|
83
|
+
expect(empty_device_details.push.to_json).to eql({}.to_json)
|
84
|
+
empty_device_details.push = new_val
|
85
|
+
expect(empty_device_details.push).to be_a(Ably::Models::DevicePushDetails)
|
86
|
+
expect(empty_device_details.push.recipient[:transport_type]).to eql(transport_type)
|
87
|
+
expect(empty_device_details.push.to_json).to eql(json_val)
|
88
|
+
end
|
89
|
+
|
90
|
+
specify 'setter accepts nil but always returns a DevicePushDetails object' do
|
91
|
+
empty_device_details.push = new_val
|
92
|
+
expect(empty_device_details.push.to_json).to eql(json_val)
|
93
|
+
empty_device_details.push = nil
|
94
|
+
expect(empty_device_details.push).to be_a(Ably::Models::DevicePushDetails)
|
95
|
+
expect(empty_device_details.push.to_json).to eql({}.to_json)
|
96
|
+
end
|
97
|
+
|
98
|
+
specify 'rejects non Hash, DevicePushDetails or nil values' do
|
99
|
+
expect { empty_device_details.metadata = "foo" }.to raise_error(ArgumentError)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'spec_helper'
|
3
|
+
require 'shared/model_behaviour'
|
4
|
+
|
5
|
+
describe Ably::Models::DevicePushDetails do
|
6
|
+
include Ably::Modules::Conversions
|
7
|
+
|
8
|
+
subject { Ably::Models::DevicePushDetails }
|
9
|
+
|
10
|
+
%w(state).each do |string_attribute|
|
11
|
+
let(:empty_push_details) { subject.new }
|
12
|
+
|
13
|
+
describe "##{string_attribute} and ##{string_attribute}=" do
|
14
|
+
let(:new_val) { random_str }
|
15
|
+
|
16
|
+
specify 'setter accepts a string value and getter returns the new value' do
|
17
|
+
expect(empty_push_details.public_send(string_attribute)).to be_nil
|
18
|
+
empty_push_details.public_send("#{string_attribute}=", new_val)
|
19
|
+
expect(empty_push_details.public_send(string_attribute)).to eql(new_val)
|
20
|
+
end
|
21
|
+
|
22
|
+
specify 'setter accepts nil' do
|
23
|
+
empty_push_details.public_send("#{string_attribute}=", new_val)
|
24
|
+
expect(empty_push_details.public_send(string_attribute)).to eql(new_val)
|
25
|
+
empty_push_details.public_send("#{string_attribute}=", nil)
|
26
|
+
expect(empty_push_details.public_send(string_attribute)).to be_nil
|
27
|
+
end
|
28
|
+
|
29
|
+
specify 'rejects non string or nil values' do
|
30
|
+
expect { empty_push_details.public_send("#{string_attribute}=", {}) }.to raise_error(ArgumentError)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context 'camelCase constructor attributes' do
|
36
|
+
let(:transport_type) { random_str }
|
37
|
+
let(:push_details) { subject.new('errorReason' => { 'message' => 'foo' }, 'recipient' => { 'transportType' => transport_type }) }
|
38
|
+
|
39
|
+
specify 'are rubyfied and exposed as underscore case' do
|
40
|
+
expect(push_details.recipient[:transport_type]).to eql(transport_type)
|
41
|
+
expect(push_details.error_reason.message).to eql('foo')
|
42
|
+
end
|
43
|
+
|
44
|
+
specify 'are generated when the object is serialised to JSON' do
|
45
|
+
expect(JSON.parse(push_details.to_json)['recipient']['transportType']).to eql(transport_type)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe "#recipient and #recipient=" do
|
50
|
+
let(:new_val) { { foo: random_str } }
|
51
|
+
|
52
|
+
specify 'setter accepts a Hash value and getter returns the new value' do
|
53
|
+
expect(empty_push_details.recipient).to eql({})
|
54
|
+
empty_push_details.recipient = new_val
|
55
|
+
expect(empty_push_details.recipient.to_json).to eql(new_val.to_json)
|
56
|
+
end
|
57
|
+
|
58
|
+
specify 'setter accepts nil but always returns an empty hash' do
|
59
|
+
empty_push_details.recipient = new_val
|
60
|
+
expect(empty_push_details.recipient.to_json).to eql(new_val.to_json)
|
61
|
+
empty_push_details.recipient = nil
|
62
|
+
expect(empty_push_details.recipient).to eql({})
|
63
|
+
end
|
64
|
+
|
65
|
+
specify 'rejects non Hash or nil values' do
|
66
|
+
expect { empty_push_details.recipient = "foo" }.to raise_error(ArgumentError)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
describe "#error_reason and #error_reason=" do
|
71
|
+
let(:error_message) { random_str }
|
72
|
+
let(:error_attributes) { { message: error_message } }
|
73
|
+
|
74
|
+
specify 'setter accepts a ErrorInfo object and getter returns a ErrorInfo object' do
|
75
|
+
expect(empty_push_details.error_reason).to be_nil
|
76
|
+
empty_push_details.error_reason = ErrorInfo(error_attributes)
|
77
|
+
expect(empty_push_details.error_reason).to be_a(Ably::Models::ErrorInfo)
|
78
|
+
expect(empty_push_details.error_reason.message).to eql(error_message)
|
79
|
+
expect(empty_push_details.error_reason.to_json).to eql(error_attributes.to_json)
|
80
|
+
end
|
81
|
+
|
82
|
+
specify 'setter accepts a Hash value and getter returns a ErrorInfo object' do
|
83
|
+
expect(empty_push_details.error_reason).to be_nil
|
84
|
+
empty_push_details.error_reason = error_attributes
|
85
|
+
expect(empty_push_details.error_reason).to be_a(Ably::Models::ErrorInfo)
|
86
|
+
expect(empty_push_details.error_reason.message).to eql(error_message)
|
87
|
+
expect(empty_push_details.error_reason.to_json).to eql(error_attributes.to_json)
|
88
|
+
end
|
89
|
+
|
90
|
+
specify 'setter accepts nil values' do
|
91
|
+
empty_push_details.error_reason = error_attributes
|
92
|
+
expect(empty_push_details.error_reason.to_json).to eql(error_attributes.to_json)
|
93
|
+
empty_push_details.error_reason = nil
|
94
|
+
expect(empty_push_details.error_reason).to be_nil
|
95
|
+
end
|
96
|
+
|
97
|
+
specify 'rejects non Hash, ErrorInfo or nil values' do
|
98
|
+
expect { empty_push_details.error_reason = "foo" }.to raise_error(ArgumentError)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -4,15 +4,63 @@ require 'shared/model_behaviour'
|
|
4
4
|
describe Ably::Models::ErrorInfo do
|
5
5
|
subject { Ably::Models::ErrorInfo }
|
6
6
|
|
7
|
-
|
8
|
-
|
7
|
+
context '#TI1, #TI4' do
|
8
|
+
it_behaves_like 'a model', with_simple_attributes: %w(code status_code href message) do
|
9
|
+
let(:model_args) { [] }
|
10
|
+
end
|
9
11
|
end
|
10
12
|
|
11
|
-
context '#status' do
|
13
|
+
context '#status #TI1, #TI2' do
|
12
14
|
subject { Ably::Models::ErrorInfo.new('statusCode' => 401) }
|
13
15
|
it 'is an alias for #status_code' do
|
14
16
|
expect(subject.status).to eql(subject.status_code)
|
15
17
|
expect(subject.status).to eql(401)
|
16
18
|
end
|
17
19
|
end
|
20
|
+
|
21
|
+
context 'log entries container help link #TI5' do
|
22
|
+
context 'without an error code' do
|
23
|
+
subject { Ably::Models::ErrorInfo.new('statusCode' => 401) }
|
24
|
+
|
25
|
+
it 'does not include the help URL' do
|
26
|
+
expect(subject.to_s.scan(/help\.ably\.io/)).to be_empty
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context 'with a specified error code' do
|
31
|
+
subject { Ably::Models::ErrorInfo.new('code' => 44444) }
|
32
|
+
|
33
|
+
it 'includes https://help.ably.io/error/[CODE] in the stringified object' do
|
34
|
+
expect(subject.to_s).to include('https://help.ably.io/error/44444')
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context 'with an error code and an href attribute' do
|
39
|
+
subject { Ably::Models::ErrorInfo.new('code' => 44444, 'href' => 'http://foo.bar.com/') }
|
40
|
+
|
41
|
+
it 'includes the specified href in the stringified object' do
|
42
|
+
expect(subject.to_s).to include('http://foo.bar.com/')
|
43
|
+
expect(subject.to_s).to_not include('https://help.ably.io/error/44444')
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context 'with an error code and a message with the same error URL' do
|
48
|
+
subject { Ably::Models::ErrorInfo.new('message' => 'error https://help.ably.io/error/44444', 'code' => 44444) }
|
49
|
+
|
50
|
+
it 'includes the specified error URL only once in the stringified object' do
|
51
|
+
expect(subject.to_s.scan(/help.ably.io/).length).to eql(1)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
context 'with an error code and a message with a different error URL' do
|
56
|
+
subject { Ably::Models::ErrorInfo.new('message' => 'error https://help.ably.io/error/123123', 'code' => 44444) }
|
57
|
+
|
58
|
+
it 'includes the specified error URL from the message and the error code URL in the stringified object' do
|
59
|
+
puts subject.to_s
|
60
|
+
expect(subject.to_s.scan(/help.ably.io/).length).to eql(2)
|
61
|
+
expect(subject.to_s.scan(%r{error/123123}).length).to eql(1)
|
62
|
+
expect(subject.to_s.scan(%r{error/44444}).length).to eql(1)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
18
66
|
end
|
@@ -12,8 +12,23 @@ describe Ably::Models::Message do
|
|
12
12
|
let(:protocol_message_timestamp) { as_since_epoch(Time.now) }
|
13
13
|
let(:protocol_message) { Ably::Models::ProtocolMessage.new(action: 1, timestamp: protocol_message_timestamp) }
|
14
14
|
|
15
|
-
|
16
|
-
|
15
|
+
context 'serialization of the Message object (#RSL1j)' do
|
16
|
+
it_behaves_like 'a model', with_simple_attributes: %w(id name client_id data encoding) do
|
17
|
+
let(:model_args) { [protocol_message: protocol_message] }
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
context '#id (#RSL1j)' do
|
22
|
+
let(:id) { random_str }
|
23
|
+
let(:model) { subject.new(id: id) }
|
24
|
+
|
25
|
+
it 'exposes the #id attribute' do
|
26
|
+
expect(model.id).to eql(id)
|
27
|
+
end
|
28
|
+
|
29
|
+
specify '#as_json exposes the #id attribute' do
|
30
|
+
expect(model.as_json['id']).to eql(id)
|
31
|
+
end
|
17
32
|
end
|
18
33
|
|
19
34
|
context '#timestamp' do
|
@@ -547,7 +547,7 @@ describe Ably::Models::PresenceMessage do
|
|
547
547
|
clone = model.shallow_clone(id: 'newId', action: 1, timestamp: protocol_message_timestamp + 1000)
|
548
548
|
expect(clone.id).to match(/newId/)
|
549
549
|
expect(clone.connection_id).to eql(protocol_connection_id)
|
550
|
-
expect(as_since_epoch(clone.timestamp)).to
|
550
|
+
expect(as_since_epoch(clone.timestamp)).to be_within(5).of(protocol_message_timestamp + 1000)
|
551
551
|
expect(clone.action).to eq(1)
|
552
552
|
end
|
553
553
|
|
@@ -0,0 +1,86 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'spec_helper'
|
3
|
+
require 'shared/model_behaviour'
|
4
|
+
|
5
|
+
describe Ably::Models::PushChannelSubscription do
|
6
|
+
include Ably::Modules::Conversions
|
7
|
+
|
8
|
+
subject { Ably::Models::PushChannelSubscription }
|
9
|
+
|
10
|
+
%w(channel client_id device_id).each do |string_attribute|
|
11
|
+
describe "##{string_attribute} and ##{string_attribute}=" do
|
12
|
+
let(:empty_device_details) do
|
13
|
+
if string_attribute == 'device_id'
|
14
|
+
subject.new(channel: 'default', device_id: 'default')
|
15
|
+
else
|
16
|
+
subject.new(channel: 'default', client_id: 'default')
|
17
|
+
end
|
18
|
+
end
|
19
|
+
let(:new_val) { random_str }
|
20
|
+
|
21
|
+
specify 'setter accepts a string value and getter returns the new value' do
|
22
|
+
expect(empty_device_details.public_send(string_attribute)).to eql('default')
|
23
|
+
empty_device_details.public_send("#{string_attribute}=", new_val)
|
24
|
+
expect(empty_device_details.public_send(string_attribute)).to eql(new_val)
|
25
|
+
end
|
26
|
+
|
27
|
+
specify 'setter accepts nil' do
|
28
|
+
empty_device_details.public_send("#{string_attribute}=", new_val)
|
29
|
+
expect(empty_device_details.public_send(string_attribute)).to eql(new_val)
|
30
|
+
empty_device_details.public_send("#{string_attribute}=", nil)
|
31
|
+
expect(empty_device_details.public_send(string_attribute)).to be_nil
|
32
|
+
end
|
33
|
+
|
34
|
+
specify 'rejects non string or nil values' do
|
35
|
+
expect { empty_device_details.public_send("#{string_attribute}=", {}) }.to raise_error(ArgumentError)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
context 'camelCase constructor attributes' do
|
41
|
+
let(:client_id) { random_str }
|
42
|
+
let(:device_details) { subject.new(channel: 'foo', 'clientId' => client_id ) }
|
43
|
+
|
44
|
+
specify 'are rubyfied and exposed as underscore case' do
|
45
|
+
expect(device_details.client_id).to eql(client_id)
|
46
|
+
end
|
47
|
+
|
48
|
+
specify 'are generated when the object is serialised to JSON' do
|
49
|
+
expect(JSON.parse(device_details.to_json)["clientId"]).to eql(client_id)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe 'conversion method PushChannelSubscription' do
|
54
|
+
let(:channel) { 'foo' }
|
55
|
+
let(:device_id) { 'bar' }
|
56
|
+
|
57
|
+
it 'accepts a PushChannelSubscription object' do
|
58
|
+
push_channel_sub = PushChannelSubscription(channel: channel, device_id: device_id)
|
59
|
+
expect(push_channel_sub.channel).to eql('foo')
|
60
|
+
expect(push_channel_sub.client_id).to be_nil
|
61
|
+
expect(push_channel_sub.device_id).to eql('bar')
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe '#for_client_id constructor' do
|
66
|
+
context 'with a valid object' do
|
67
|
+
let(:channel) { 'foo' }
|
68
|
+
let(:client_id) { 'bob' }
|
69
|
+
|
70
|
+
it 'accepts a Hash object' do
|
71
|
+
push_channel_sub = Ably::Models::PushChannelSubscription.for_client_id(channel, client_id)
|
72
|
+
expect(push_channel_sub.channel).to eql('foo')
|
73
|
+
expect(push_channel_sub.client_id).to eql('bob')
|
74
|
+
expect(push_channel_sub.device_id).to be_nil
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
context 'with an invalid valid object' do
|
79
|
+
let(:subscription) { { channel: 'foo' } }
|
80
|
+
|
81
|
+
it 'accepts a Hash object' do
|
82
|
+
expect { Ably::Models::PushChannelSubscription.for_device(subscription) }.to raise_error(ArgumentError)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|