ably 1.0.6 → 1.1.3

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.
Files changed (93) hide show
  1. checksums.yaml +4 -4
  2. data/.editorconfig +14 -0
  3. data/.travis.yml +10 -8
  4. data/CHANGELOG.md +75 -3
  5. data/LICENSE +1 -3
  6. data/README.md +12 -7
  7. data/Rakefile +32 -0
  8. data/SPEC.md +1277 -835
  9. data/ably.gemspec +14 -9
  10. data/lib/ably/auth.rb +30 -4
  11. data/lib/ably/exceptions.rb +10 -4
  12. data/lib/ably/logger.rb +7 -1
  13. data/lib/ably/models/channel_state_change.rb +1 -1
  14. data/lib/ably/models/connection_state_change.rb +1 -1
  15. data/lib/ably/models/device_details.rb +87 -0
  16. data/lib/ably/models/device_push_details.rb +86 -0
  17. data/lib/ably/models/error_info.rb +23 -2
  18. data/lib/ably/models/idiomatic_ruby_wrapper.rb +4 -4
  19. data/lib/ably/models/protocol_message.rb +32 -2
  20. data/lib/ably/models/push_channel_subscription.rb +89 -0
  21. data/lib/ably/modules/conversions.rb +1 -1
  22. data/lib/ably/modules/encodeable.rb +1 -1
  23. data/lib/ably/modules/exception_codes.rb +128 -0
  24. data/lib/ably/modules/model_common.rb +15 -2
  25. data/lib/ably/modules/state_machine.rb +2 -2
  26. data/lib/ably/realtime.rb +1 -0
  27. data/lib/ably/realtime/auth.rb +1 -1
  28. data/lib/ably/realtime/channel.rb +24 -102
  29. data/lib/ably/realtime/channel/channel_manager.rb +2 -6
  30. data/lib/ably/realtime/channel/channel_state_machine.rb +2 -2
  31. data/lib/ably/realtime/channel/publisher.rb +74 -0
  32. data/lib/ably/realtime/channel/push_channel.rb +62 -0
  33. data/lib/ably/realtime/client.rb +91 -3
  34. data/lib/ably/realtime/client/incoming_message_dispatcher.rb +6 -2
  35. data/lib/ably/realtime/client/outgoing_message_dispatcher.rb +1 -1
  36. data/lib/ably/realtime/connection.rb +34 -20
  37. data/lib/ably/realtime/connection/connection_manager.rb +25 -9
  38. data/lib/ably/realtime/connection/websocket_transport.rb +1 -1
  39. data/lib/ably/realtime/presence.rb +4 -4
  40. data/lib/ably/realtime/presence/members_map.rb +3 -3
  41. data/lib/ably/realtime/push.rb +40 -0
  42. data/lib/ably/realtime/push/admin.rb +61 -0
  43. data/lib/ably/realtime/push/channel_subscriptions.rb +108 -0
  44. data/lib/ably/realtime/push/device_registrations.rb +105 -0
  45. data/lib/ably/rest.rb +1 -0
  46. data/lib/ably/rest/channel.rb +53 -17
  47. data/lib/ably/rest/channel/push_channel.rb +62 -0
  48. data/lib/ably/rest/client.rb +154 -32
  49. data/lib/ably/rest/middleware/parse_message_pack.rb +17 -1
  50. data/lib/ably/rest/presence.rb +1 -0
  51. data/lib/ably/rest/push.rb +42 -0
  52. data/lib/ably/rest/push/admin.rb +54 -0
  53. data/lib/ably/rest/push/channel_subscriptions.rb +121 -0
  54. data/lib/ably/rest/push/device_registrations.rb +103 -0
  55. data/lib/ably/version.rb +7 -2
  56. data/spec/acceptance/realtime/auth_spec.rb +245 -17
  57. data/spec/acceptance/realtime/channel_history_spec.rb +26 -20
  58. data/spec/acceptance/realtime/channel_spec.rb +177 -59
  59. data/spec/acceptance/realtime/client_spec.rb +153 -0
  60. data/spec/acceptance/realtime/connection_failures_spec.rb +72 -6
  61. data/spec/acceptance/realtime/connection_spec.rb +129 -18
  62. data/spec/acceptance/realtime/message_spec.rb +36 -34
  63. data/spec/acceptance/realtime/presence_spec.rb +201 -167
  64. data/spec/acceptance/realtime/push_admin_spec.rb +736 -0
  65. data/spec/acceptance/realtime/push_spec.rb +27 -0
  66. data/spec/acceptance/rest/auth_spec.rb +41 -3
  67. data/spec/acceptance/rest/base_spec.rb +2 -2
  68. data/spec/acceptance/rest/channel_spec.rb +79 -4
  69. data/spec/acceptance/rest/channels_spec.rb +6 -0
  70. data/spec/acceptance/rest/client_spec.rb +129 -10
  71. data/spec/acceptance/rest/message_spec.rb +158 -6
  72. data/spec/acceptance/rest/push_admin_spec.rb +952 -0
  73. data/spec/acceptance/rest/push_spec.rb +25 -0
  74. data/spec/acceptance/rest/time_spec.rb +1 -1
  75. data/spec/run_parallel_tests +33 -0
  76. data/spec/spec_helper.rb +1 -1
  77. data/spec/support/debug_failure_helper.rb +9 -5
  78. data/spec/support/test_app.rb +2 -2
  79. data/spec/unit/logger_spec.rb +10 -3
  80. data/spec/unit/models/device_details_spec.rb +102 -0
  81. data/spec/unit/models/device_push_details_spec.rb +101 -0
  82. data/spec/unit/models/error_info_spec.rb +51 -3
  83. data/spec/unit/models/message_spec.rb +17 -2
  84. data/spec/unit/models/presence_message_spec.rb +1 -1
  85. data/spec/unit/models/push_channel_subscription_spec.rb +86 -0
  86. data/spec/unit/modules/enum_spec.rb +1 -1
  87. data/spec/unit/realtime/client_spec.rb +13 -1
  88. data/spec/unit/realtime/connection_spec.rb +1 -1
  89. data/spec/unit/realtime/push_channel_spec.rb +36 -0
  90. data/spec/unit/rest/channel_spec.rb +8 -1
  91. data/spec/unit/rest/client_spec.rb +30 -0
  92. data/spec/unit/rest/push_channel_spec.rb +36 -0
  93. metadata +95 -26
@@ -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 eq(protocol_message_timestamp + 1000)
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
@@ -53,7 +53,7 @@ describe Ably::Modules::Enum, :api_private do
53
53
  end
54
54
 
55
55
  it 'allows different type comparison 2' do
56
- skip 'Unless we monkeypath Symbols, the == operator is never invoked'
56
+ skip 'Unless we monkeypatch Symbols, the == operator is never invoked'
57
57
  expect([:value_zero].include?(subject.ValueZero)).to eql(true)
58
58
  end
59
59
 
@@ -13,7 +13,7 @@ describe Ably::Realtime::Client do
13
13
  let(:client_options) { { key: 'appid.keyuid:keysecret', auto_connect: false } }
14
14
 
15
15
  it 'passes on the options to the initializer' do
16
- rest_client = instance_double('Ably::Rest::Client', auth: instance_double('Ably::Auth'), options: client_options)
16
+ rest_client = instance_double('Ably::Rest::Client', auth: instance_double('Ably::Auth'), options: client_options, environment: 'production', use_tls?: true, custom_tls_port: nil)
17
17
  expect(Ably::Rest::Client).to receive(:new).with(hash_including(client_options)).and_return(rest_client)
18
18
  subject
19
19
  end
@@ -28,6 +28,18 @@ describe Ably::Realtime::Client do
28
28
  end
29
29
  end
30
30
 
31
+ context 'push' do
32
+ let(:client_options) { { key: 'appid.keyuid:keysecret' } }
33
+
34
+ specify '#device is not supported and raises an exception' do
35
+ expect { subject.device }.to raise_error Ably::Exceptions::PushNotificationsNotSupported
36
+ end
37
+
38
+ specify '#push returns a Push object' do
39
+ expect(subject.push).to be_a(Ably::Realtime::Push)
40
+ end
41
+ end
42
+
31
43
  after(:all) do
32
44
  sleep 1 # let realtime library shut down any open clients
33
45
  end
@@ -2,7 +2,7 @@ require 'spec_helper'
2
2
  require 'shared/protocol_msgbus_behaviour'
3
3
 
4
4
  describe Ably::Realtime::Connection do
5
- let(:client) { instance_double('Ably::Realtime::Client', logger: double('logger').as_null_object) }
5
+ let(:client) { instance_double('Ably::Realtime::Client', logger: double('logger').as_null_object, recover: nil, endpoint: double('endpoint', host: 'realtime.ably.io')) }
6
6
 
7
7
  subject do
8
8
  Ably::Realtime::Connection.new(client, {}).tap do |connection|
@@ -0,0 +1,36 @@
1
+ require 'spec_helper'
2
+
3
+ describe Ably::Realtime::Channel::PushChannel do
4
+ subject { Ably::Realtime::Channel::PushChannel }
5
+
6
+ let(:channel_name) { 'unique' }
7
+ let(:client) { double('client').as_null_object }
8
+ let(:channel) { Ably::Realtime::Channel.new(client, channel_name) }
9
+
10
+ it 'is constructed with a channel' do
11
+ expect(subject.new(channel)).to be_a(Ably::Realtime::Channel::PushChannel)
12
+ end
13
+
14
+ it 'raises an exception if constructed with an invalid type' do
15
+ expect { subject.new(Hash.new) }.to raise_error(ArgumentError)
16
+ end
17
+
18
+ it 'exposes the channel as attribute #channel' do
19
+ expect(subject.new(channel).channel).to eql(channel)
20
+ end
21
+
22
+ it 'is available in the #push attribute of the channel' do
23
+ expect(channel.push).to be_a(Ably::Realtime::Channel::PushChannel)
24
+ expect(channel.push.channel).to eql(channel)
25
+ end
26
+
27
+ context 'methods not implemented as push notifications' do
28
+ subject { Ably::Realtime::Channel::PushChannel.new(channel) }
29
+
30
+ %w(subscribe_device subscribe_client_id unsubscribe_device unsubscribe_client_id get_subscriptions).each do |method_name|
31
+ specify "##{method_name} raises an unsupported exception" do
32
+ expect { subject.public_send(method_name, 'foo') }.to raise_error(Ably::Exceptions::PushNotificationsNotSupported)
33
+ end
34
+ end
35
+ end
36
+ end
@@ -2,7 +2,14 @@
2
2
  require 'spec_helper'
3
3
 
4
4
  describe Ably::Rest::Channel do
5
- let(:client) { instance_double('Ably::Rest::Client', encoders: [], post: instance_double('Faraday::Response', status: 201)) }
5
+ let(:client) do
6
+ instance_double(
7
+ 'Ably::Rest::Client',
8
+ encoders: [],
9
+ post: instance_double('Faraday::Response', status: 201),
10
+ idempotent_rest_publishing: false,
11
+ )
12
+ end
6
13
  let(:channel_name) { 'unique' }
7
14
 
8
15
  subject { Ably::Rest::Channel.new(client, channel_name) }
@@ -20,6 +20,24 @@ describe Ably::Rest::Client do
20
20
  end
21
21
  end
22
22
 
23
+ context 'fallback_retry_timeout (#RSC15f)' do
24
+ context 'default' do
25
+ let(:client_options) { { key: 'appid.keyuid:keysecret' } }
26
+
27
+ it 'is set to 10 minutes' do
28
+ expect(subject.options.fetch(:fallback_retry_timeout)).to eql(10 * 60)
29
+ end
30
+ end
31
+
32
+ context 'when provided' do
33
+ let(:client_options) { { key: 'appid.keyuid:keysecret', fallback_retry_timeout: 30 } }
34
+
35
+ it 'configures a new timeout' do
36
+ expect(subject.options.fetch(:fallback_retry_timeout)).to eql(30)
37
+ end
38
+ end
39
+ end
40
+
23
41
  context ':use_token_auth' do
24
42
  context 'set to false' do
25
43
  context 'with a key and :tls => false' do
@@ -57,4 +75,16 @@ describe Ably::Rest::Client do
57
75
  expect(subject.add_request_ids).to eql(true)
58
76
  end
59
77
  end
78
+
79
+ context 'push' do
80
+ let(:client_options) { { key: 'appid.keyuid:keysecret' } }
81
+
82
+ specify '#device is not supported and raises an exception' do
83
+ expect { subject.device }.to raise_error Ably::Exceptions::PushNotificationsNotSupported
84
+ end
85
+
86
+ specify '#push returns a Push object' do
87
+ expect(subject.push).to be_a(Ably::Rest::Push)
88
+ end
89
+ end
60
90
  end
@@ -0,0 +1,36 @@
1
+ require 'spec_helper'
2
+
3
+ describe Ably::Rest::Channel::PushChannel do
4
+ subject { Ably::Rest::Channel::PushChannel }
5
+
6
+ let(:channel_name) { 'unique' }
7
+ let(:client) { double('client').as_null_object }
8
+ let(:channel) { Ably::Rest::Channel.new(client, channel_name) }
9
+
10
+ it 'is constructed with a channel' do
11
+ expect(subject.new(channel)).to be_a(Ably::Rest::Channel::PushChannel)
12
+ end
13
+
14
+ it 'raises an exception if constructed with an invalid type' do
15
+ expect { subject.new(Hash.new) }.to raise_error(ArgumentError)
16
+ end
17
+
18
+ it 'exposes the channel as attribute #channel' do
19
+ expect(subject.new(channel).channel).to eql(channel)
20
+ end
21
+
22
+ it 'is available in the #push attribute of the channel' do
23
+ expect(channel.push).to be_a(Ably::Rest::Channel::PushChannel)
24
+ expect(channel.push.channel).to eql(channel)
25
+ end
26
+
27
+ context 'methods not implemented as push notifications' do
28
+ subject { Ably::Rest::Channel::PushChannel.new(channel) }
29
+
30
+ %w(subscribe_device subscribe_client_id unsubscribe_device unsubscribe_client_id get_subscriptions).each do |method_name|
31
+ specify "##{method_name} raises an unsupported exception" do
32
+ expect { subject.public_send(method_name, 'foo') }.to raise_error(Ably::Exceptions::PushNotificationsNotSupported)
33
+ end
34
+ end
35
+ end
36
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ably
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.6
4
+ version: 1.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lewis Marshall
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2018-05-01 00:00:00.000000000 Z
12
+ date: 2020-12-15 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: eventmachine
@@ -57,16 +57,22 @@ dependencies:
57
57
  name: faraday
58
58
  requirement: !ruby/object:Gem::Requirement
59
59
  requirements:
60
- - - "~>"
60
+ - - ">="
61
61
  - !ruby/object:Gem::Version
62
62
  version: '0.12'
63
+ - - "<"
64
+ - !ruby/object:Gem::Version
65
+ version: 2.0.0
63
66
  type: :runtime
64
67
  prerelease: false
65
68
  version_requirements: !ruby/object:Gem::Requirement
66
69
  requirements:
67
- - - "~>"
70
+ - - ">="
68
71
  - !ruby/object:Gem::Version
69
72
  version: '0.12'
73
+ - - "<"
74
+ - !ruby/object:Gem::Version
75
+ version: 2.0.0
70
76
  - !ruby/object:Gem::Dependency
71
77
  name: excon
72
78
  requirement: !ruby/object:Gem::Requirement
@@ -115,14 +121,14 @@ dependencies:
115
121
  requirements:
116
122
  - - ">="
117
123
  - !ruby/object:Gem::Version
118
- version: 0.6.2
124
+ version: 1.3.0
119
125
  type: :runtime
120
126
  prerelease: false
121
127
  version_requirements: !ruby/object:Gem::Requirement
122
128
  requirements:
123
129
  - - ">="
124
130
  - !ruby/object:Gem::Version
125
- version: 0.6.2
131
+ version: 1.3.0
126
132
  - !ruby/object:Gem::Dependency
127
133
  name: addressable
128
134
  requirement: !ruby/object:Gem::Requirement
@@ -137,20 +143,6 @@ dependencies:
137
143
  - - ">="
138
144
  - !ruby/object:Gem::Version
139
145
  version: 2.0.0
140
- - !ruby/object:Gem::Dependency
141
- name: bundler
142
- requirement: !ruby/object:Gem::Requirement
143
- requirements:
144
- - - "~>"
145
- - !ruby/object:Gem::Version
146
- version: '1.3'
147
- type: :development
148
- prerelease: false
149
- version_requirements: !ruby/object:Gem::Requirement
150
- requirements:
151
- - - "~>"
152
- - !ruby/object:Gem::Version
153
- version: '1.3'
154
146
  - !ruby/object:Gem::Dependency
155
147
  name: rake
156
148
  requirement: !ruby/object:Gem::Requirement
@@ -185,28 +177,28 @@ dependencies:
185
177
  requirements:
186
178
  - - "~>"
187
179
  - !ruby/object:Gem::Version
188
- version: 3.2.0
180
+ version: 3.3.0
189
181
  type: :development
190
182
  prerelease: false
191
183
  version_requirements: !ruby/object:Gem::Requirement
192
184
  requirements:
193
185
  - - "~>"
194
186
  - !ruby/object:Gem::Version
195
- version: 3.2.0
187
+ version: 3.3.0
196
188
  - !ruby/object:Gem::Dependency
197
189
  name: rspec-retry
198
190
  requirement: !ruby/object:Gem::Requirement
199
191
  requirements:
200
192
  - - "~>"
201
193
  - !ruby/object:Gem::Version
202
- version: '0.4'
194
+ version: '0.6'
203
195
  type: :development
204
196
  prerelease: false
205
197
  version_requirements: !ruby/object:Gem::Requirement
206
198
  requirements:
207
199
  - - "~>"
208
200
  - !ruby/object:Gem::Version
209
- version: '0.4'
201
+ version: '0.6'
210
202
  - !ruby/object:Gem::Dependency
211
203
  name: yard
212
204
  requirement: !ruby/object:Gem::Requirement
@@ -221,6 +213,34 @@ dependencies:
221
213
  - - "~>"
222
214
  - !ruby/object:Gem::Version
223
215
  version: '0.9'
216
+ - !ruby/object:Gem::Dependency
217
+ name: rspec-instafail
218
+ requirement: !ruby/object:Gem::Requirement
219
+ requirements:
220
+ - - "~>"
221
+ - !ruby/object:Gem::Version
222
+ version: '1.0'
223
+ type: :development
224
+ prerelease: false
225
+ version_requirements: !ruby/object:Gem::Requirement
226
+ requirements:
227
+ - - "~>"
228
+ - !ruby/object:Gem::Version
229
+ version: '1.0'
230
+ - !ruby/object:Gem::Dependency
231
+ name: bundler
232
+ requirement: !ruby/object:Gem::Requirement
233
+ requirements:
234
+ - - ">="
235
+ - !ruby/object:Gem::Version
236
+ version: 1.3.0
237
+ type: :development
238
+ prerelease: false
239
+ version_requirements: !ruby/object:Gem::Requirement
240
+ requirements:
241
+ - - ">="
242
+ - !ruby/object:Gem::Version
243
+ version: 1.3.0
224
244
  - !ruby/object:Gem::Dependency
225
245
  name: webmock
226
246
  requirement: !ruby/object:Gem::Requirement
@@ -249,6 +269,20 @@ dependencies:
249
269
  - - ">="
250
270
  - !ruby/object:Gem::Version
251
271
  version: '0'
272
+ - !ruby/object:Gem::Dependency
273
+ name: parallel_tests
274
+ requirement: !ruby/object:Gem::Requirement
275
+ requirements:
276
+ - - "~>"
277
+ - !ruby/object:Gem::Version
278
+ version: '2.22'
279
+ type: :development
280
+ prerelease: false
281
+ version_requirements: !ruby/object:Gem::Requirement
282
+ requirements:
283
+ - - "~>"
284
+ - !ruby/object:Gem::Version
285
+ version: '2.22'
252
286
  - !ruby/object:Gem::Dependency
253
287
  name: pry
254
288
  requirement: !ruby/object:Gem::Requirement
@@ -285,6 +319,7 @@ executables: []
285
319
  extensions: []
286
320
  extra_rdoc_files: []
287
321
  files:
322
+ - ".editorconfig"
288
323
  - ".gitignore"
289
324
  - ".gitmodules"
290
325
  - ".rspec"
@@ -305,6 +340,8 @@ files:
305
340
  - lib/ably/models/cipher_params.rb
306
341
  - lib/ably/models/connection_details.rb
307
342
  - lib/ably/models/connection_state_change.rb
343
+ - lib/ably/models/device_details.rb
344
+ - lib/ably/models/device_push_details.rb
308
345
  - lib/ably/models/error_info.rb
309
346
  - lib/ably/models/http_paginated_response.rb
310
347
  - lib/ably/models/idiomatic_ruby_wrapper.rb
@@ -318,6 +355,7 @@ files:
318
355
  - lib/ably/models/paginated_result.rb
319
356
  - lib/ably/models/presence_message.rb
320
357
  - lib/ably/models/protocol_message.rb
358
+ - lib/ably/models/push_channel_subscription.rb
321
359
  - lib/ably/models/stats.rb
322
360
  - lib/ably/models/stats_types.rb
323
361
  - lib/ably/models/token_details.rb
@@ -330,6 +368,7 @@ files:
330
368
  - lib/ably/modules/enum.rb
331
369
  - lib/ably/modules/event_emitter.rb
332
370
  - lib/ably/modules/event_machine_helpers.rb
371
+ - lib/ably/modules/exception_codes.rb
333
372
  - lib/ably/modules/http_helpers.rb
334
373
  - lib/ably/modules/message_emitter.rb
335
374
  - lib/ably/modules/message_pack.rb
@@ -345,6 +384,8 @@ files:
345
384
  - lib/ably/realtime/channel.rb
346
385
  - lib/ably/realtime/channel/channel_manager.rb
347
386
  - lib/ably/realtime/channel/channel_state_machine.rb
387
+ - lib/ably/realtime/channel/publisher.rb
388
+ - lib/ably/realtime/channel/push_channel.rb
348
389
  - lib/ably/realtime/channels.rb
349
390
  - lib/ably/realtime/client.rb
350
391
  - lib/ably/realtime/client/incoming_message_dispatcher.rb
@@ -358,8 +399,13 @@ files:
358
399
  - lib/ably/realtime/presence/members_map.rb
359
400
  - lib/ably/realtime/presence/presence_manager.rb
360
401
  - lib/ably/realtime/presence/presence_state_machine.rb
402
+ - lib/ably/realtime/push.rb
403
+ - lib/ably/realtime/push/admin.rb
404
+ - lib/ably/realtime/push/channel_subscriptions.rb
405
+ - lib/ably/realtime/push/device_registrations.rb
361
406
  - lib/ably/rest.rb
362
407
  - lib/ably/rest/channel.rb
408
+ - lib/ably/rest/channel/push_channel.rb
363
409
  - lib/ably/rest/channels.rb
364
410
  - lib/ably/rest/client.rb
365
411
  - lib/ably/rest/middleware/encoder.rb
@@ -370,6 +416,10 @@ files:
370
416
  - lib/ably/rest/middleware/parse_json.rb
371
417
  - lib/ably/rest/middleware/parse_message_pack.rb
372
418
  - lib/ably/rest/presence.rb
419
+ - lib/ably/rest/push.rb
420
+ - lib/ably/rest/push/admin.rb
421
+ - lib/ably/rest/push/channel_subscriptions.rb
422
+ - lib/ably/rest/push/device_registrations.rb
373
423
  - lib/ably/util/crypto.rb
374
424
  - lib/ably/util/pub_sub.rb
375
425
  - lib/ably/util/safe_deferrable.rb
@@ -384,6 +434,8 @@ files:
384
434
  - spec/acceptance/realtime/message_spec.rb
385
435
  - spec/acceptance/realtime/presence_history_spec.rb
386
436
  - spec/acceptance/realtime/presence_spec.rb
437
+ - spec/acceptance/realtime/push_admin_spec.rb
438
+ - spec/acceptance/realtime/push_spec.rb
387
439
  - spec/acceptance/realtime/stats_spec.rb
388
440
  - spec/acceptance/realtime/time_spec.rb
389
441
  - spec/acceptance/rest/auth_spec.rb
@@ -394,9 +446,12 @@ files:
394
446
  - spec/acceptance/rest/encoders_spec.rb
395
447
  - spec/acceptance/rest/message_spec.rb
396
448
  - spec/acceptance/rest/presence_spec.rb
449
+ - spec/acceptance/rest/push_admin_spec.rb
450
+ - spec/acceptance/rest/push_spec.rb
397
451
  - spec/acceptance/rest/stats_spec.rb
398
452
  - spec/acceptance/rest/time_spec.rb
399
453
  - spec/rspec_config.rb
454
+ - spec/run_parallel_tests
400
455
  - spec/shared/client_initializer_behaviour.rb
401
456
  - spec/shared/model_behaviour.rb
402
457
  - spec/shared/protocol_msgbus_behaviour.rb
@@ -420,6 +475,8 @@ files:
420
475
  - spec/unit/models/cipher_params_spec.rb
421
476
  - spec/unit/models/connection_details_spec.rb
422
477
  - spec/unit/models/connection_state_change_spec.rb
478
+ - spec/unit/models/device_details_spec.rb
479
+ - spec/unit/models/device_push_details_spec.rb
423
480
  - spec/unit/models/error_info_spec.rb
424
481
  - spec/unit/models/http_paginated_result_spec.rb
425
482
  - spec/unit/models/idiomatic_ruby_wrapper_spec.rb
@@ -431,6 +488,7 @@ files:
431
488
  - spec/unit/models/paginated_result_spec.rb
432
489
  - spec/unit/models/presence_message_spec.rb
433
490
  - spec/unit/models/protocol_message_spec.rb
491
+ - spec/unit/models/push_channel_subscription_spec.rb
434
492
  - spec/unit/models/stats_spec.rb
435
493
  - spec/unit/models/token_details_spec.rb
436
494
  - spec/unit/models/token_request_spec.rb
@@ -445,12 +503,14 @@ files:
445
503
  - spec/unit/realtime/connection_spec.rb
446
504
  - spec/unit/realtime/incoming_message_dispatcher_spec.rb
447
505
  - spec/unit/realtime/presence_spec.rb
506
+ - spec/unit/realtime/push_channel_spec.rb
448
507
  - spec/unit/realtime/realtime_spec.rb
449
508
  - spec/unit/realtime/safe_deferrable_spec.rb
450
509
  - spec/unit/realtime/websocket_transport_spec.rb
451
510
  - spec/unit/rest/channel_spec.rb
452
511
  - spec/unit/rest/channels_spec.rb
453
512
  - spec/unit/rest/client_spec.rb
513
+ - spec/unit/rest/push_channel_spec.rb
454
514
  - spec/unit/rest/rest_spec.rb
455
515
  - spec/unit/util/crypto_spec.rb
456
516
  - spec/unit/util/pub_sub_spec.rb
@@ -473,8 +533,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
473
533
  - !ruby/object:Gem::Version
474
534
  version: '0'
475
535
  requirements: []
476
- rubyforge_project:
477
- rubygems_version: 2.7.6
536
+ rubygems_version: 3.1.2
478
537
  signing_key:
479
538
  specification_version: 4
480
539
  summary: A Ruby client library for ably.io realtime messaging implemented using EventMachine
@@ -489,6 +548,8 @@ test_files:
489
548
  - spec/acceptance/realtime/message_spec.rb
490
549
  - spec/acceptance/realtime/presence_history_spec.rb
491
550
  - spec/acceptance/realtime/presence_spec.rb
551
+ - spec/acceptance/realtime/push_admin_spec.rb
552
+ - spec/acceptance/realtime/push_spec.rb
492
553
  - spec/acceptance/realtime/stats_spec.rb
493
554
  - spec/acceptance/realtime/time_spec.rb
494
555
  - spec/acceptance/rest/auth_spec.rb
@@ -499,9 +560,12 @@ test_files:
499
560
  - spec/acceptance/rest/encoders_spec.rb
500
561
  - spec/acceptance/rest/message_spec.rb
501
562
  - spec/acceptance/rest/presence_spec.rb
563
+ - spec/acceptance/rest/push_admin_spec.rb
564
+ - spec/acceptance/rest/push_spec.rb
502
565
  - spec/acceptance/rest/stats_spec.rb
503
566
  - spec/acceptance/rest/time_spec.rb
504
567
  - spec/rspec_config.rb
568
+ - spec/run_parallel_tests
505
569
  - spec/shared/client_initializer_behaviour.rb
506
570
  - spec/shared/model_behaviour.rb
507
571
  - spec/shared/protocol_msgbus_behaviour.rb
@@ -525,6 +589,8 @@ test_files:
525
589
  - spec/unit/models/cipher_params_spec.rb
526
590
  - spec/unit/models/connection_details_spec.rb
527
591
  - spec/unit/models/connection_state_change_spec.rb
592
+ - spec/unit/models/device_details_spec.rb
593
+ - spec/unit/models/device_push_details_spec.rb
528
594
  - spec/unit/models/error_info_spec.rb
529
595
  - spec/unit/models/http_paginated_result_spec.rb
530
596
  - spec/unit/models/idiomatic_ruby_wrapper_spec.rb
@@ -536,6 +602,7 @@ test_files:
536
602
  - spec/unit/models/paginated_result_spec.rb
537
603
  - spec/unit/models/presence_message_spec.rb
538
604
  - spec/unit/models/protocol_message_spec.rb
605
+ - spec/unit/models/push_channel_subscription_spec.rb
539
606
  - spec/unit/models/stats_spec.rb
540
607
  - spec/unit/models/token_details_spec.rb
541
608
  - spec/unit/models/token_request_spec.rb
@@ -550,12 +617,14 @@ test_files:
550
617
  - spec/unit/realtime/connection_spec.rb
551
618
  - spec/unit/realtime/incoming_message_dispatcher_spec.rb
552
619
  - spec/unit/realtime/presence_spec.rb
620
+ - spec/unit/realtime/push_channel_spec.rb
553
621
  - spec/unit/realtime/realtime_spec.rb
554
622
  - spec/unit/realtime/safe_deferrable_spec.rb
555
623
  - spec/unit/realtime/websocket_transport_spec.rb
556
624
  - spec/unit/rest/channel_spec.rb
557
625
  - spec/unit/rest/channels_spec.rb
558
626
  - spec/unit/rest/client_spec.rb
627
+ - spec/unit/rest/push_channel_spec.rb
559
628
  - spec/unit/rest/rest_spec.rb
560
629
  - spec/unit/util/crypto_spec.rb
561
630
  - spec/unit/util/pub_sub_spec.rb