ably 0.8.2 → 0.8.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.
- checksums.yaml +4 -4
- data/.travis.yml +1 -0
- data/CHANGELOG.md +185 -0
- data/LICENSE +15 -0
- data/README.md +8 -4
- data/SPEC.md +999 -531
- data/ably.gemspec +1 -1
- data/lib/ably.rb +1 -1
- data/lib/ably/auth.rb +114 -87
- data/lib/ably/exceptions.rb +40 -14
- data/lib/ably/models/message.rb +3 -5
- data/lib/ably/models/paginated_result.rb +3 -12
- data/lib/ably/models/presence_message.rb +8 -2
- data/lib/ably/models/protocol_message.rb +15 -3
- data/lib/ably/models/stat.rb +1 -1
- data/lib/ably/models/token_details.rb +1 -1
- data/lib/ably/modules/channels_collection.rb +7 -1
- data/lib/ably/modules/conversions.rb +1 -1
- data/lib/ably/modules/encodeable.rb +6 -3
- data/lib/ably/modules/message_pack.rb +2 -2
- data/lib/ably/modules/model_common.rb +1 -1
- data/lib/ably/modules/state_machine.rb +2 -2
- data/lib/ably/realtime.rb +1 -0
- data/lib/ably/realtime/auth.rb +191 -0
- data/lib/ably/realtime/channel.rb +97 -25
- data/lib/ably/realtime/channel/channel_manager.rb +11 -3
- data/lib/ably/realtime/client.rb +22 -6
- data/lib/ably/realtime/connection.rb +74 -41
- data/lib/ably/realtime/connection/connection_manager.rb +48 -33
- data/lib/ably/realtime/presence.rb +17 -3
- data/lib/ably/rest/channel.rb +43 -16
- data/lib/ably/rest/client.rb +57 -26
- data/lib/ably/rest/middleware/exceptions.rb +3 -1
- data/lib/ably/rest/middleware/fail_if_unsupported_mime_type.rb +4 -2
- data/lib/ably/rest/presence.rb +1 -0
- data/lib/ably/version.rb +1 -1
- data/spec/acceptance/realtime/auth_spec.rb +242 -0
- data/spec/acceptance/realtime/channel_spec.rb +277 -5
- data/spec/acceptance/realtime/channels_spec.rb +64 -0
- data/spec/acceptance/realtime/client_spec.rb +26 -5
- data/spec/acceptance/realtime/connection_failures_spec.rb +23 -6
- data/spec/acceptance/realtime/connection_spec.rb +167 -16
- data/spec/acceptance/realtime/message_spec.rb +9 -8
- data/spec/acceptance/realtime/presence_history_spec.rb +1 -0
- data/spec/acceptance/realtime/presence_spec.rb +121 -10
- data/spec/acceptance/realtime/stats_spec.rb +13 -1
- data/spec/acceptance/rest/auth_spec.rb +161 -79
- data/spec/acceptance/rest/base_spec.rb +3 -3
- data/spec/acceptance/rest/channel_spec.rb +142 -15
- data/spec/acceptance/rest/channels_spec.rb +23 -0
- data/spec/acceptance/rest/client_spec.rb +180 -18
- data/spec/acceptance/rest/message_spec.rb +8 -8
- data/spec/acceptance/rest/presence_spec.rb +136 -25
- data/spec/acceptance/rest/stats_spec.rb +60 -4
- data/spec/shared/client_initializer_behaviour.rb +54 -3
- data/spec/unit/auth_spec.rb +7 -6
- data/spec/unit/models/message_spec.rb +1 -9
- data/spec/unit/models/paginated_result_spec.rb +1 -18
- data/spec/unit/models/presence_message_spec.rb +1 -1
- data/spec/unit/models/protocol_message_spec.rb +21 -1
- data/spec/unit/realtime/channel_spec.rb +10 -3
- data/spec/unit/realtime/channels_spec.rb +27 -8
- data/spec/unit/rest/channel_spec.rb +0 -8
- data/spec/unit/rest/client_spec.rb +7 -7
- metadata +13 -7
- data/LICENSE.txt +0 -22
data/spec/unit/auth_spec.rb
CHANGED
@@ -2,12 +2,13 @@ require 'spec_helper'
|
|
2
2
|
require 'shared/protocol_msgbus_behaviour'
|
3
3
|
|
4
4
|
describe Ably::Auth do
|
5
|
-
let(:client)
|
6
|
-
let(:client_id)
|
7
|
-
let(:
|
5
|
+
let(:client) { double('client').as_null_object }
|
6
|
+
let(:client_id) { nil }
|
7
|
+
let(:auth_options) { { key: 'appid.keyuid:keysecret', client_id: client_id } }
|
8
|
+
let(:token_params) { { } }
|
8
9
|
|
9
10
|
subject do
|
10
|
-
Ably::Auth.new(client,
|
11
|
+
Ably::Auth.new(client, auth_options, token_params)
|
11
12
|
end
|
12
13
|
|
13
14
|
describe 'client_id option' do
|
@@ -78,8 +79,8 @@ describe Ably::Auth do
|
|
78
79
|
expect(Ably::Auth::TOKEN_DEFAULTS.fetch(:capability)).to eql(all_capabilities)
|
79
80
|
end
|
80
81
|
|
81
|
-
it 'should
|
82
|
-
expect(Ably::Auth::TOKEN_DEFAULTS.keys).to
|
82
|
+
it 'should have defaults for :ttl and :capability' do
|
83
|
+
expect(Ably::Auth::TOKEN_DEFAULTS.keys).to include(:ttl, :capability)
|
83
84
|
end
|
84
85
|
end
|
85
86
|
end
|
@@ -12,7 +12,7 @@ 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
|
-
it_behaves_like 'a model', with_simple_attributes: %w(name client_id data encoding) do
|
15
|
+
it_behaves_like 'a model', with_simple_attributes: %w(id name client_id data encoding) do
|
16
16
|
let(:model_args) { [protocol_message: protocol_message] }
|
17
17
|
end
|
18
18
|
|
@@ -150,14 +150,6 @@ describe Ably::Models::Message do
|
|
150
150
|
end
|
151
151
|
end
|
152
152
|
|
153
|
-
context 'with invalid data' do
|
154
|
-
let(:model) { subject.new({ clientId: 'joe' }, protocol_message: protocol_message) }
|
155
|
-
|
156
|
-
it 'raises an exception' do
|
157
|
-
expect { model.to_json }.to raise_error RuntimeError, /cannot generate a valid Hash/
|
158
|
-
end
|
159
|
-
end
|
160
|
-
|
161
153
|
context 'with binary data' do
|
162
154
|
let(:data) { MessagePack.pack(random_str(32)) }
|
163
155
|
let(:model) { subject.new({ name: 'test', data: data }, protocol_message: protocol_message) }
|
@@ -157,7 +157,7 @@ describe Ably::Models::PaginatedResult do
|
|
157
157
|
subject.next do |paginated_result|
|
158
158
|
deferrable = subject.first
|
159
159
|
deferrable.errback do |error|
|
160
|
-
expect(error).to be_a(Ably::Exceptions::
|
160
|
+
expect(error).to be_a(Ably::Exceptions::PageMissing)
|
161
161
|
stop_reactor
|
162
162
|
end
|
163
163
|
end
|
@@ -169,10 +169,6 @@ describe Ably::Models::PaginatedResult do
|
|
169
169
|
end
|
170
170
|
|
171
171
|
context 'with non paged http response' do
|
172
|
-
it 'is the first page' do
|
173
|
-
expect(subject).to be_first
|
174
|
-
end
|
175
|
-
|
176
172
|
it 'is the last page' do
|
177
173
|
expect(subject).to be_last
|
178
174
|
end
|
@@ -207,10 +203,6 @@ describe Ably::Models::PaginatedResult do
|
|
207
203
|
}
|
208
204
|
end
|
209
205
|
|
210
|
-
it 'is the first page' do
|
211
|
-
expect(subject).to be_first
|
212
|
-
end
|
213
|
-
|
214
206
|
it 'has next page' do
|
215
207
|
expect(subject).to have_next
|
216
208
|
end
|
@@ -256,10 +248,6 @@ describe Ably::Models::PaginatedResult do
|
|
256
248
|
expect(subject.items[0][:id]).to eql(next_body[0][:id])
|
257
249
|
end
|
258
250
|
|
259
|
-
it 'is not the first page' do
|
260
|
-
expect(subject).to_not be_first
|
261
|
-
end
|
262
|
-
|
263
251
|
it 'does not have a next page' do
|
264
252
|
expect(subject).to_not have_next
|
265
253
|
end
|
@@ -286,12 +274,7 @@ describe Ably::Models::PaginatedResult do
|
|
286
274
|
it 'retrieves the first page of results' do
|
287
275
|
expect(subject.items.length).to eql(body.length)
|
288
276
|
end
|
289
|
-
|
290
|
-
it 'is the first page' do
|
291
|
-
expect(subject).to be_first
|
292
|
-
end
|
293
277
|
end
|
294
278
|
end
|
295
279
|
end
|
296
280
|
end
|
297
|
-
|
@@ -9,7 +9,7 @@ describe Ably::Models::PresenceMessage do
|
|
9
9
|
let(:protocol_message_timestamp) { as_since_epoch(Time.now) }
|
10
10
|
let(:protocol_message) { Ably::Models::ProtocolMessage.new(action: 1, timestamp: protocol_message_timestamp) }
|
11
11
|
|
12
|
-
it_behaves_like 'a model', with_simple_attributes: %w(client_id data encoding) do
|
12
|
+
it_behaves_like 'a model', with_simple_attributes: %w(id client_id data encoding) do
|
13
13
|
let(:model_args) { [protocol_message] }
|
14
14
|
end
|
15
15
|
|
@@ -11,7 +11,7 @@ describe Ably::Models::ProtocolMessage do
|
|
11
11
|
end
|
12
12
|
|
13
13
|
it_behaves_like 'a model',
|
14
|
-
with_simple_attributes: %w(id channel channel_serial connection_id),
|
14
|
+
with_simple_attributes: %w(id channel channel_serial connection_id connection_key),
|
15
15
|
base_model_options: { action: 1 } do
|
16
16
|
|
17
17
|
let(:model_args) { [] }
|
@@ -264,6 +264,26 @@ describe Ably::Models::ProtocolMessage do
|
|
264
264
|
end
|
265
265
|
end
|
266
266
|
end
|
267
|
+
|
268
|
+
context '#messages' do
|
269
|
+
let(:protocol_message) { new_protocol_message(messages: [{ name: 'test' }]) }
|
270
|
+
|
271
|
+
it 'contains Message objects' do
|
272
|
+
expect(protocol_message.messages.count).to eql(1)
|
273
|
+
expect(protocol_message.messages.first).to be_a(Ably::Models::Message)
|
274
|
+
expect(protocol_message.messages.first.name).to eql('test')
|
275
|
+
end
|
276
|
+
end
|
277
|
+
|
278
|
+
context '#presence' do
|
279
|
+
let(:protocol_message) { new_protocol_message(presence: [{ action: 1, data: 'test' }]) }
|
280
|
+
|
281
|
+
it 'contains PresenceMessage objects' do
|
282
|
+
expect(protocol_message.presence.count).to eql(1)
|
283
|
+
expect(protocol_message.presence.first).to be_a(Ably::Models::PresenceMessage)
|
284
|
+
expect(protocol_message.presence.first.data).to eql('test')
|
285
|
+
end
|
286
|
+
end
|
267
287
|
end
|
268
288
|
|
269
289
|
context '#to_json', :api_private do
|
@@ -71,6 +71,7 @@ describe Ably::Realtime::Channel do
|
|
71
71
|
|
72
72
|
before do
|
73
73
|
allow(subject).to receive(:create_message).and_return('message_stubbed')
|
74
|
+
allow(subject).to receive(:attach).and_return(:true)
|
74
75
|
end
|
75
76
|
|
76
77
|
context 'as UTF_8 string' do
|
@@ -108,8 +109,8 @@ describe Ably::Realtime::Channel do
|
|
108
109
|
context 'as Nil' do
|
109
110
|
let(:encoded_value) { nil }
|
110
111
|
|
111
|
-
it '
|
112
|
-
expect
|
112
|
+
it 'is permitted' do
|
113
|
+
expect(subject.publish(encoded_value, 'data')).to eql('message_stubbed')
|
113
114
|
end
|
114
115
|
end
|
115
116
|
end
|
@@ -159,6 +160,10 @@ describe Ably::Realtime::Channel do
|
|
159
160
|
let(:blur_message) { instance_double('Ably::Models::Message', name: 'blur', encode: nil, decode: nil) }
|
160
161
|
|
161
162
|
context '#subscribe' do
|
163
|
+
before do
|
164
|
+
allow(subject).to receive(:attach).and_return(:true)
|
165
|
+
end
|
166
|
+
|
162
167
|
specify 'without a block raises an invalid ArgumentError' do
|
163
168
|
expect { subject.subscribe }.to raise_error ArgumentError
|
164
169
|
end
|
@@ -199,8 +204,10 @@ describe Ably::Realtime::Channel do
|
|
199
204
|
let(:callback) do
|
200
205
|
Proc.new { |message| message_history[:received] += 1 }
|
201
206
|
end
|
207
|
+
|
202
208
|
before do
|
203
|
-
subject.
|
209
|
+
allow(subject).to receive(:attach).and_return(:true)
|
210
|
+
subject.subscribe click_event, &callback
|
204
211
|
end
|
205
212
|
|
206
213
|
specify 'with no event name specified unsubscribes that block from all events' do
|
@@ -10,15 +10,34 @@ describe Ably::Realtime::Channels do
|
|
10
10
|
subject { Ably::Realtime::Channels.new(client) }
|
11
11
|
|
12
12
|
context 'creating channels' do
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
13
|
+
context '#get' do
|
14
|
+
it 'creates a channel if it does not exist' do
|
15
|
+
expect(Ably::Realtime::Channel).to receive(:new).with(client, channel_name, options)
|
16
|
+
subject.get(channel_name, options)
|
17
|
+
end
|
17
18
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
19
|
+
context 'when an existing channel exists' do
|
20
|
+
it 'will reuse a channel object if it exists' do
|
21
|
+
channel = subject.get(channel_name, options)
|
22
|
+
expect(channel).to be_a(Ably::Realtime::Channel)
|
23
|
+
expect(subject.get(channel_name, options).object_id).to eql(channel.object_id)
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'will update the options on the channel if provided' do
|
27
|
+
channel = subject.get(channel_name, options)
|
28
|
+
expect(channel.options).to eql(options)
|
29
|
+
expect(channel.options).to_not include(:encrypted)
|
30
|
+
subject.get(channel_name, encrypted: true)
|
31
|
+
expect(channel.options[:encrypted]).to eql(true)
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'will leave the options intact on the channel if not provided' do
|
35
|
+
channel = subject.get(channel_name, options)
|
36
|
+
expect(channel.options).to eql(options)
|
37
|
+
subject.get(channel_name)
|
38
|
+
expect(channel.options).to eql(options)
|
39
|
+
end
|
40
|
+
end
|
22
41
|
end
|
23
42
|
|
24
43
|
it '[] creates a channel' do
|
@@ -97,13 +97,5 @@ describe Ably::Rest::Channel do
|
|
97
97
|
expect { subject.publish(encoded_value, 'data') }.to raise_error ArgumentError, /must be a String/
|
98
98
|
end
|
99
99
|
end
|
100
|
-
|
101
|
-
context 'as Nil' do
|
102
|
-
let(:encoded_value) { nil }
|
103
|
-
|
104
|
-
it 'raises an argument error' do
|
105
|
-
expect { subject.publish(encoded_value, 'data') }.to raise_error ArgumentError, /must be a String/
|
106
|
-
end
|
107
|
-
end
|
108
100
|
end
|
109
101
|
end
|
@@ -15,35 +15,35 @@ describe Ably::Rest::Client do
|
|
15
15
|
let(:client_options) { { key: 'appid.keyuid:keysecret', tls: false } }
|
16
16
|
|
17
17
|
it 'fails for any operation with basic auth and attempting to send an API key over a non-secure connection' do
|
18
|
-
expect { subject.channel('a').publish('event', 'message') }.to raise_error(Ably::Exceptions::
|
18
|
+
expect { subject.channel('a').publish('event', 'message') }.to raise_error(Ably::Exceptions::InsecureRequest)
|
19
19
|
end
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
23
|
context ':use_token_auth' do
|
24
24
|
context 'set to false' do
|
25
|
-
context 'with
|
25
|
+
context 'with a key and :tls => false' do
|
26
26
|
let(:client_options) { { use_token_auth: false, key: 'appid.keyuid:keysecret', tls: false } }
|
27
27
|
|
28
28
|
it 'fails for any operation with basic auth and attempting to send an API key over a non-secure connection' do
|
29
|
-
expect { subject.channel('a').publish('event', 'message') }.to raise_error(Ably::Exceptions::
|
29
|
+
expect { subject.channel('a').publish('event', 'message') }.to raise_error(Ably::Exceptions::InsecureRequest)
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
33
|
-
context 'without
|
33
|
+
context 'without a key' do
|
34
34
|
let(:client_options) { { use_token_auth: false } }
|
35
35
|
|
36
|
-
it 'fails as
|
36
|
+
it 'fails as a key is required if not using token auth' do
|
37
37
|
expect { subject.channel('a').publish('event', 'message') }.to raise_error(ArgumentError)
|
38
38
|
end
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
42
42
|
context 'set to true' do
|
43
|
-
context 'without
|
43
|
+
context 'without a key or token' do
|
44
44
|
let(:client_options) { { use_token_auth: true, key: true } }
|
45
45
|
|
46
|
-
it 'fails as
|
46
|
+
it 'fails as a key is required to issue tokens' do
|
47
47
|
expect { subject.channel('a').publish('event', 'message') }.to raise_error(ArgumentError)
|
48
48
|
end
|
49
49
|
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: 0.8.
|
4
|
+
version: 0.8.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: 2015-
|
12
|
+
date: 2015-08-19 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: eventmachine
|
@@ -99,16 +99,16 @@ dependencies:
|
|
99
99
|
name: msgpack
|
100
100
|
requirement: !ruby/object:Gem::Requirement
|
101
101
|
requirements:
|
102
|
-
- -
|
102
|
+
- - ">="
|
103
103
|
- !ruby/object:Gem::Version
|
104
|
-
version: 0.6.
|
104
|
+
version: 0.6.2
|
105
105
|
type: :runtime
|
106
106
|
prerelease: false
|
107
107
|
version_requirements: !ruby/object:Gem::Requirement
|
108
108
|
requirements:
|
109
|
-
- -
|
109
|
+
- - ">="
|
110
110
|
- !ruby/object:Gem::Version
|
111
|
-
version: 0.6.
|
111
|
+
version: 0.6.2
|
112
112
|
- !ruby/object:Gem::Dependency
|
113
113
|
name: bundler
|
114
114
|
requirement: !ruby/object:Gem::Requirement
|
@@ -233,8 +233,9 @@ files:
|
|
233
233
|
- ".gitmodules"
|
234
234
|
- ".rspec"
|
235
235
|
- ".travis.yml"
|
236
|
+
- CHANGELOG.md
|
236
237
|
- Gemfile
|
237
|
-
- LICENSE
|
238
|
+
- LICENSE
|
238
239
|
- README.md
|
239
240
|
- Rakefile
|
240
241
|
- SPEC.md
|
@@ -278,6 +279,7 @@ files:
|
|
278
279
|
- lib/ably/modules/statesman_monkey_patch.rb
|
279
280
|
- lib/ably/modules/uses_state_machine.rb
|
280
281
|
- lib/ably/realtime.rb
|
282
|
+
- lib/ably/realtime/auth.rb
|
281
283
|
- lib/ably/realtime/channel.rb
|
282
284
|
- lib/ably/realtime/channel/channel_manager.rb
|
283
285
|
- lib/ably/realtime/channel/channel_state_machine.rb
|
@@ -310,8 +312,10 @@ files:
|
|
310
312
|
- lib/ably/util/pub_sub.rb
|
311
313
|
- lib/ably/util/safe_deferrable.rb
|
312
314
|
- lib/ably/version.rb
|
315
|
+
- spec/acceptance/realtime/auth_spec.rb
|
313
316
|
- spec/acceptance/realtime/channel_history_spec.rb
|
314
317
|
- spec/acceptance/realtime/channel_spec.rb
|
318
|
+
- spec/acceptance/realtime/channels_spec.rb
|
315
319
|
- spec/acceptance/realtime/client_spec.rb
|
316
320
|
- spec/acceptance/realtime/connection_failures_spec.rb
|
317
321
|
- spec/acceptance/realtime/connection_spec.rb
|
@@ -404,8 +408,10 @@ signing_key:
|
|
404
408
|
specification_version: 4
|
405
409
|
summary: A Ruby client library for ably.io, the realtime messaging service
|
406
410
|
test_files:
|
411
|
+
- spec/acceptance/realtime/auth_spec.rb
|
407
412
|
- spec/acceptance/realtime/channel_history_spec.rb
|
408
413
|
- spec/acceptance/realtime/channel_spec.rb
|
414
|
+
- spec/acceptance/realtime/channels_spec.rb
|
409
415
|
- spec/acceptance/realtime/client_spec.rb
|
410
416
|
- spec/acceptance/realtime/connection_failures_spec.rb
|
411
417
|
- spec/acceptance/realtime/connection_spec.rb
|
data/LICENSE.txt
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
Copyright (c) 2015 Ably
|
2
|
-
|
3
|
-
MIT License
|
4
|
-
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
-
a copy of this software and associated documentation files (the
|
7
|
-
"Software"), to deal in the Software without restriction, including
|
8
|
-
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
-
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
-
permit persons to whom the Software is furnished to do so, subject to
|
11
|
-
the following conditions:
|
12
|
-
|
13
|
-
The above copyright notice and this permission notice shall be
|
14
|
-
included in all copies or substantial portions of the Software.
|
15
|
-
|
16
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
-
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
-
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
-
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
-
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
-
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
-
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|