ably 0.7.5 → 0.7.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -13
- data/.gitignore +1 -0
- data/.gitmodules +3 -0
- data/README.md +46 -22
- data/SPEC.md +345 -240
- data/ably.gemspec +4 -2
- data/lib/ably/auth.rb +18 -14
- data/lib/ably/models/message.rb +1 -1
- data/lib/ably/models/paginated_resource.rb +31 -44
- data/lib/ably/models/presence_message.rb +1 -1
- data/lib/ably/models/stat.rb +67 -24
- data/lib/ably/models/stats_types.rb +131 -0
- data/lib/ably/modules/async_wrapper.rb +3 -2
- data/lib/ably/modules/message_emitter.rb +2 -2
- data/lib/ably/realtime.rb +1 -1
- data/lib/ably/realtime/channel.rb +24 -3
- data/lib/ably/realtime/channel/channel_manager.rb +1 -0
- data/lib/ably/realtime/client.rb +2 -2
- data/lib/ably/realtime/connection.rb +1 -1
- data/lib/ably/realtime/presence.rb +12 -1
- data/lib/ably/rest.rb +1 -1
- data/lib/ably/rest/channel.rb +4 -5
- data/lib/ably/rest/client.rb +5 -5
- data/lib/ably/rest/presence.rb +2 -2
- data/lib/ably/version.rb +1 -1
- data/spec/acceptance/realtime/channel_history_spec.rb +74 -23
- data/spec/acceptance/realtime/channel_spec.rb +3 -3
- data/spec/acceptance/realtime/client_spec.rb +3 -3
- data/spec/acceptance/realtime/connection_failures_spec.rb +2 -2
- data/spec/acceptance/realtime/connection_spec.rb +4 -4
- data/spec/acceptance/realtime/message_spec.rb +5 -5
- data/spec/acceptance/realtime/presence_history_spec.rb +56 -13
- data/spec/acceptance/realtime/presence_spec.rb +8 -8
- data/spec/acceptance/realtime/stats_spec.rb +1 -1
- data/spec/acceptance/realtime/time_spec.rb +1 -1
- data/spec/acceptance/rest/auth_spec.rb +31 -4
- data/spec/acceptance/rest/base_spec.rb +3 -3
- data/spec/acceptance/rest/channel_spec.rb +19 -19
- data/spec/acceptance/rest/channels_spec.rb +1 -1
- data/spec/acceptance/rest/client_spec.rb +9 -6
- data/spec/acceptance/rest/encoders_spec.rb +1 -1
- data/spec/acceptance/rest/message_spec.rb +10 -10
- data/spec/acceptance/rest/presence_spec.rb +81 -51
- data/spec/acceptance/rest/stats_spec.rb +46 -41
- data/spec/acceptance/rest/time_spec.rb +1 -1
- data/spec/shared/client_initializer_behaviour.rb +30 -19
- data/spec/spec_helper.rb +3 -0
- data/spec/support/markdown_spec_formatter.rb +1 -1
- data/spec/support/test_app.rb +11 -24
- data/spec/unit/auth_spec.rb +1 -1
- data/spec/unit/models/paginated_resource_spec.rb +81 -72
- data/spec/unit/models/stats_spec.rb +289 -0
- data/spec/unit/modules/async_wrapper_spec.rb +1 -1
- data/spec/unit/realtime/client_spec.rb +1 -1
- data/spec/unit/realtime/realtime_spec.rb +1 -1
- data/spec/unit/rest/channel_spec.rb +1 -1
- data/spec/unit/rest/client_spec.rb +8 -8
- data/spec/unit/rest/rest_spec.rb +1 -1
- data/spec/unit/util/crypto_spec.rb +1 -1
- metadata +55 -43
- data/spec/resources/crypto-data-128.json +0 -56
- data/spec/resources/crypto-data-256.json +0 -56
- data/spec/unit/models/stat_spec.rb +0 -113
@@ -47,8 +47,9 @@ module Ably::Modules
|
|
47
47
|
operation_with_exception_handling = proc do
|
48
48
|
begin
|
49
49
|
yield
|
50
|
-
rescue StandardError =>
|
51
|
-
|
50
|
+
rescue StandardError => err
|
51
|
+
logger.error "An exception in an AsyncWrapper block was caught. #{err.class}: #{err.message}\n#{err.backtrace.join("\n")}"
|
52
|
+
deferrable.fail err
|
52
53
|
end
|
53
54
|
end
|
54
55
|
|
@@ -6,7 +6,7 @@ module Ably::Modules
|
|
6
6
|
module MessageEmitter
|
7
7
|
# Subscribe to events on this object
|
8
8
|
#
|
9
|
-
# @param
|
9
|
+
# @param names [String,Symbol] Optional, the event name(s) to subscribe to. Defaults to `:all` events
|
10
10
|
# @yield [Object] For each event, the provided block is called with the event payload object
|
11
11
|
#
|
12
12
|
# @return [void]
|
@@ -22,7 +22,7 @@ module Ably::Modules
|
|
22
22
|
# Unsubscribe the matching block for events on the this object.
|
23
23
|
# If a block is not provided, all subscriptions will be unsubscribed
|
24
24
|
#
|
25
|
-
# @param
|
25
|
+
# @param names [String,Symbol] Optional, the event name(s) to unsubscribe from. Defaults to `:all` events
|
26
26
|
#
|
27
27
|
# @return [void]
|
28
28
|
#
|
data/lib/ably/realtime.rb
CHANGED
@@ -50,7 +50,7 @@ module Ably
|
|
50
50
|
# client = Ably::Realtime.new('key.id:secret')
|
51
51
|
#
|
52
52
|
# # create a new client authenticating with basic auth and a client_id
|
53
|
-
# client = Ably::Realtime.new(
|
53
|
+
# client = Ably::Realtime.new(key: 'key.id:secret', client_id: 'john')
|
54
54
|
#
|
55
55
|
def self.new(options, &token_request_block)
|
56
56
|
Ably::Realtime::Client.new(options, &token_request_block)
|
@@ -23,7 +23,7 @@ module Ably
|
|
23
23
|
# Channel::STATE.Detached
|
24
24
|
# Channel::STATE.Failed
|
25
25
|
#
|
26
|
-
# Channels emit errors - use
|
26
|
+
# Channels emit errors - use +on(:error)+ to subscribe to errors
|
27
27
|
#
|
28
28
|
# @!attribute [r] state
|
29
29
|
# @return {Ably::Realtime::Connection::STATE} channel state
|
@@ -71,13 +71,18 @@ module Ably
|
|
71
71
|
# @api private
|
72
72
|
attr_reader :manager
|
73
73
|
|
74
|
+
# Serial number assigned to this channel when it was attached
|
75
|
+
# @return [Integer]
|
76
|
+
# @api private
|
77
|
+
attr_reader :attached_serial
|
78
|
+
|
74
79
|
# Initialize a new Channel object
|
75
80
|
#
|
76
81
|
# @param client [Ably::Rest::Client]
|
77
82
|
# @param name [String] The name of the channel
|
78
83
|
# @param channel_options [Hash] Channel options, currently reserved for Encryption options
|
79
84
|
# @option channel_options [Boolean] :encrypted setting this to true for this channel will encrypt & decrypt all messages automatically
|
80
|
-
# @option channel_options [Hash] :cipher_params A hash of options to configure the encryption. *:key* is required, all other options are optional. See {Ably::Util::Crypto#initialize} for a list of
|
85
|
+
# @option channel_options [Hash] :cipher_params A hash of options to configure the encryption. *:key* is required, all other options are optional. See {Ably::Util::Crypto#initialize} for a list of +cipher_params+ options
|
81
86
|
#
|
82
87
|
def initialize(client, name, channel_options = {})
|
83
88
|
ensure_utf_8 :name, name
|
@@ -181,13 +186,24 @@ module Ably
|
|
181
186
|
|
182
187
|
# Return the message history of the channel
|
183
188
|
#
|
189
|
+
# Once attached to a channel, you can retrieve messages published on the channel before the
|
190
|
+
# channel was attached with the option <tt>until_attach: true</tt>. This is very useful for
|
191
|
+
# developers who wish to subscribe to new realtime messages yet also display historical messages with
|
192
|
+
# the guarantee that no messages have been missed.
|
193
|
+
#
|
184
194
|
# @param (see Ably::Rest::Channel#history)
|
185
195
|
# @option options (see Ably::Rest::Channel#history)
|
196
|
+
# @option options [Boolean] :until_attach When true, request for history will be limited only to messages published before this channel was attached. Channel must be attached.
|
186
197
|
#
|
187
|
-
# @yield [Ably::Models::PaginatedResource<Ably::Models::Message>]
|
198
|
+
# @yield [Ably::Models::PaginatedResource<Ably::Models::Message>] First {Ably::Models::PaginatedResource page} of {Ably::Models::Message} objects accessible with {Ably::Models::PaginatedResource#items #items}.
|
188
199
|
#
|
189
200
|
# @return [Ably::Util::SafeDeferrable]
|
190
201
|
def history(options = {}, &callback)
|
202
|
+
if options.delete(:until_attach)
|
203
|
+
raise ArgumentError, 'option :until_attach cannot be specified if the channel is not attached' unless attached?
|
204
|
+
options[:from_serial] = attached_serial
|
205
|
+
end
|
206
|
+
|
191
207
|
async_wrap(callback) do
|
192
208
|
rest_channel.history(options.merge(async_blocking_operations: true))
|
193
209
|
end
|
@@ -212,6 +228,11 @@ module Ably
|
|
212
228
|
@error_reason = nil
|
213
229
|
end
|
214
230
|
|
231
|
+
# @api private
|
232
|
+
def set_attached_serial(serial)
|
233
|
+
@attached_serial = serial
|
234
|
+
end
|
235
|
+
|
215
236
|
# Used by {Ably::Modules::StateEmitter} to debug state changes
|
216
237
|
# @api private
|
217
238
|
def logger
|
data/lib/ably/realtime/client.rb
CHANGED
@@ -75,7 +75,7 @@ module Ably
|
|
75
75
|
# client = Ably::Realtime::Client.new('key.id:secret')
|
76
76
|
#
|
77
77
|
# # create a new client and configure a client ID used for presence
|
78
|
-
# client = Ably::Realtime::Client.new(
|
78
|
+
# client = Ably::Realtime::Client.new(key: 'key.id:secret', client_id: 'john')
|
79
79
|
#
|
80
80
|
def initialize(options, &token_request_block)
|
81
81
|
@rest_client = Ably::Rest::Client.new(options, &token_request_block)
|
@@ -114,7 +114,7 @@ module Ably
|
|
114
114
|
# @param (see Ably::Rest::Client#stats)
|
115
115
|
# @option options (see Ably::Rest::Client#stats)
|
116
116
|
#
|
117
|
-
# @yield [Ably::Models::PaginatedResource<Ably::Models::
|
117
|
+
# @yield [Ably::Models::PaginatedResource<Ably::Models::Stats>] An Array of Stats
|
118
118
|
#
|
119
119
|
# @return [Ably::Util::SafeDeferrable]
|
120
120
|
#
|
@@ -150,7 +150,7 @@ module Ably
|
|
150
150
|
# @yield [Integer] if a block is passed to this method, then this block will be called once the ping heartbeat is received with the time elapsed in milliseconds
|
151
151
|
#
|
152
152
|
# @example
|
153
|
-
# client = Ably::Rest::Client.new(
|
153
|
+
# client = Ably::Rest::Client.new(key: 'key.id:secret')
|
154
154
|
# client.connection.ping do |ms_elapsed|
|
155
155
|
# puts "Ping took #{ms_elapsed}ms"
|
156
156
|
# end
|
@@ -265,14 +265,25 @@ module Ably::Realtime
|
|
265
265
|
|
266
266
|
# Return the presence messages history for the channel
|
267
267
|
#
|
268
|
+
# Once attached to a channel, you can retrieve presence message history on the channel before the
|
269
|
+
# channel was attached with the option <tt>until_attach: true</tt>. This is very useful for
|
270
|
+
# developers who wish to capture new presence events as well as retrieve historical presence state with
|
271
|
+
# the guarantee that no presence history has been missed.
|
272
|
+
#
|
268
273
|
# @param (see Ably::Rest::Presence#history)
|
269
274
|
# @option options (see Ably::Rest::Presence#history)
|
275
|
+
# @option options [Boolean] :until_attach When true, request for history will be limited only to messages published before the associated channel was attached. The associated channel must be attached.
|
270
276
|
#
|
271
|
-
# @yield [Ably::Models::PaginatedResource<Ably::Models::PresenceMessage>]
|
277
|
+
# @yield [Ably::Models::PaginatedResource<Ably::Models::PresenceMessage>] First {Ably::Models::PaginatedResource page} of {Ably::Models::PresenceMessage} objects accessible with {Ably::Models::PaginatedResource#items #items}.
|
272
278
|
#
|
273
279
|
# @return [Ably::Util::SafeDeferrable]
|
274
280
|
#
|
275
281
|
def history(options = {}, &callback)
|
282
|
+
if options.delete(:until_attach)
|
283
|
+
raise ArgumentError, 'option :until_attach cannot be specified if the channel is not attached' unless channel.attached?
|
284
|
+
options[:from_serial] = channel.attached_serial
|
285
|
+
end
|
286
|
+
|
276
287
|
async_wrap(callback) do
|
277
288
|
rest_presence.history(options.merge(async_blocking_operations: true))
|
278
289
|
end
|
data/lib/ably/rest.rb
CHANGED
@@ -34,7 +34,7 @@ module Ably
|
|
34
34
|
# client = Ably::Rest.new('key.id:secret')
|
35
35
|
#
|
36
36
|
# # create a new client authenticating with basic auth and a client_id
|
37
|
-
# client = Ably::Rest.new(
|
37
|
+
# client = Ably::Rest.new(key: 'key.id:secret', client_id: 'john')
|
38
38
|
#
|
39
39
|
def self.new(options, &token_request_block)
|
40
40
|
Ably::Rest::Client.new(options, &token_request_block)
|
data/lib/ably/rest/channel.rb
CHANGED
@@ -20,7 +20,7 @@ module Ably
|
|
20
20
|
# @param name [String] The name of the channel
|
21
21
|
# @param channel_options [Hash] Channel options, currently reserved for Encryption options
|
22
22
|
# @option channel_options [Boolean] :encrypted setting this to true for this channel will encrypt & decrypt all messages automatically
|
23
|
-
# @option channel_options [Hash] :cipher_params A hash of options to configure the encryption. *:key* is required, all other options are optional. See {Ably::Util::Crypto#initialize} for a list of
|
23
|
+
# @option channel_options [Hash] :cipher_params A hash of options to configure the encryption. *:key* is required, all other options are optional. See {Ably::Util::Crypto#initialize} for a list of +cipher_params+ options
|
24
24
|
#
|
25
25
|
def initialize(client, name, channel_options = {})
|
26
26
|
ensure_utf_8 :name, name
|
@@ -52,16 +52,15 @@ module Ably
|
|
52
52
|
[201, 204].include?(response.status)
|
53
53
|
end
|
54
54
|
|
55
|
-
# Return the message
|
55
|
+
# Return the message of the channel
|
56
56
|
#
|
57
57
|
# @param [Hash] options the options for the message history request
|
58
58
|
# @option options [Integer,Time] :start Time or millisecond since epoch
|
59
59
|
# @option options [Integer,Time] :end Time or millisecond since epoch
|
60
|
-
# @option options [Symbol] :direction
|
60
|
+
# @option options [Symbol] :direction +:forwards+ or +:backwards+
|
61
61
|
# @option options [Integer] :limit Maximum number of messages to retrieve up to 10,000
|
62
|
-
# @option options [Symbol] :by `:message`, `:bundle` or `:hour`. Defaults to `:message`
|
63
62
|
#
|
64
|
-
# @return [Ably::Models::PaginatedResource<Ably::Models::Message>]
|
63
|
+
# @return [Ably::Models::PaginatedResource<Ably::Models::Message>] First {Ably::Models::PaginatedResource page} of {Ably::Models::Message} objects accessible with {Ably::Models::PaginatedResource#items #items}.
|
65
64
|
def history(options = {})
|
66
65
|
url = "#{base_path}/messages"
|
67
66
|
options = options.dup
|
data/lib/ably/rest/client.rb
CHANGED
@@ -70,7 +70,7 @@ module Ably
|
|
70
70
|
# @param [Hash,String] options an options Hash used to configure the client and the authentication, or String with an API key or Token ID
|
71
71
|
# @option options (see Ably::Auth#authorise)
|
72
72
|
# @option options [Boolean] :tls TLS is used by default, providing a value of false disables TLS. Please note Basic Auth is disallowed without TLS as secrets cannot be transmitted over unsecured connections.
|
73
|
-
# @option options [String] :
|
73
|
+
# @option options [String] :key API key comprising the key ID and key secret in a single string
|
74
74
|
# @option options [Boolean] :use_token_auth Will force Basic Auth if set to false, and TOken auth if set to true
|
75
75
|
# @option options [String] :environment Specify 'sandbox' when testing the client library against an alternate Ably environment
|
76
76
|
# @option options [Symbol] :protocol Protocol used to communicate with Ably, :json and :msgpack currently supported. Defaults to :msgpack
|
@@ -89,7 +89,7 @@ module Ably
|
|
89
89
|
# client = Ably::Rest::Client.new('key.id:secret')
|
90
90
|
#
|
91
91
|
# # create a new client and configure a client ID used for presence
|
92
|
-
# client = Ably::Rest::Client.new(
|
92
|
+
# client = Ably::Rest::Client.new(key: 'key.id:secret', client_id: 'john')
|
93
93
|
#
|
94
94
|
def initialize(options, &token_request_block)
|
95
95
|
raise ArgumentError, 'Options Hash is expected' if options.nil?
|
@@ -97,7 +97,7 @@ module Ably
|
|
97
97
|
options = options.clone
|
98
98
|
if options.kind_of?(String)
|
99
99
|
options = if options.match(/^[\w]{2,}\.[\w]{2,}:[\w]{2,}$/)
|
100
|
-
{
|
100
|
+
{ key: options }
|
101
101
|
else
|
102
102
|
{ token_id: options }
|
103
103
|
end
|
@@ -152,7 +152,7 @@ module Ably
|
|
152
152
|
# @option options [Integer] :limit Maximum number of stats to retrieve up to 10,000
|
153
153
|
# @option options [Symbol] :by `:minute`, `:hour`, `:day` or `:month`. Defaults to `:minute`
|
154
154
|
#
|
155
|
-
# @return [Ably::Models::PaginatedResource<Ably::Models::
|
155
|
+
# @return [Ably::Models::PaginatedResource<Ably::Models::Stats>] An Array of Stats
|
156
156
|
#
|
157
157
|
def stats(options = {})
|
158
158
|
options = {
|
@@ -163,7 +163,7 @@ module Ably
|
|
163
163
|
[:start, :end].each { |option| options[option] = as_since_epoch(options[option]) if options.has_key?(option) }
|
164
164
|
|
165
165
|
paginated_options = {
|
166
|
-
coerce_into: 'Ably::Models::
|
166
|
+
coerce_into: 'Ably::Models::Stats'
|
167
167
|
}
|
168
168
|
|
169
169
|
url = '/stats'
|
data/lib/ably/rest/presence.rb
CHANGED
@@ -28,7 +28,7 @@ module Ably
|
|
28
28
|
# @option options [Symbol] :direction `:forwards` or `:backwards`
|
29
29
|
# @option options [Integer] :limit Maximum number of members to retrieve up to 10,000
|
30
30
|
#
|
31
|
-
# @return [Ably::Models::PaginatedResource<Ably::Models::PresenceMessage>]
|
31
|
+
# @return [Ably::Models::PaginatedResource<Ably::Models::PresenceMessage>] First {Ably::Models::PaginatedResource page} of {Ably::Models::PresenceMessage} objects accessible with {Ably::Models::PaginatedResource#items #items}.
|
32
32
|
#
|
33
33
|
def get(options = {})
|
34
34
|
options = options.dup
|
@@ -55,7 +55,7 @@ module Ably
|
|
55
55
|
# @option options [Symbol] :direction `:forwards` or `:backwards`
|
56
56
|
# @option options [Integer] :limit Maximum number of presence messages to retrieve up to 10,000
|
57
57
|
#
|
58
|
-
# @return [Ably::Models::PaginatedResource<Ably::Models::PresenceMessage>]
|
58
|
+
# @return [Ably::Models::PaginatedResource<Ably::Models::PresenceMessage>] First {Ably::Models::PaginatedResource page} of {Ably::Models::PresenceMessage} objects accessible with {Ably::Models::PaginatedResource#items #items}.
|
59
59
|
#
|
60
60
|
def history(options = {})
|
61
61
|
url = "#{base_path}/history"
|
data/lib/ably/version.rb
CHANGED
@@ -3,10 +3,11 @@ require 'spec_helper'
|
|
3
3
|
|
4
4
|
describe Ably::Realtime::Channel, '#history', :event_machine do
|
5
5
|
vary_by_protocol do
|
6
|
-
let(:default_options) { options.merge(
|
6
|
+
let(:default_options) { options.merge(key: api_key, environment: environment, protocol: protocol) }
|
7
7
|
|
8
8
|
let(:client) { Ably::Realtime::Client.new(default_options) }
|
9
9
|
let(:channel) { client.channel(channel_name) }
|
10
|
+
let(:rest_channel) { client.rest_client.channel(channel_name) }
|
10
11
|
|
11
12
|
let(:client2) { Ably::Realtime::Client.new(default_options) }
|
12
13
|
let(:channel2) { client2.channel(channel_name) }
|
@@ -21,20 +22,20 @@ describe Ably::Realtime::Channel, '#history', :event_machine do
|
|
21
22
|
channel.publish('event', payload) do |message|
|
22
23
|
history = channel.history
|
23
24
|
expect(history).to be_a(Ably::Util::SafeDeferrable)
|
24
|
-
history.callback do |
|
25
|
-
expect(
|
26
|
-
expect(
|
25
|
+
history.callback do |page|
|
26
|
+
expect(page.items.count).to eql(1)
|
27
|
+
expect(page).to be_a(Ably::Models::PaginatedResource)
|
27
28
|
stop_reactor
|
28
29
|
end
|
29
30
|
end
|
30
31
|
end
|
31
32
|
|
32
33
|
context 'with a single client publishing and receiving' do
|
33
|
-
it 'retrieves
|
34
|
+
it 'retrieves realtime history' do
|
34
35
|
channel.publish('event', payload) do |message|
|
35
|
-
channel.history do |
|
36
|
-
expect(
|
37
|
-
expect(
|
36
|
+
channel.history do |page|
|
37
|
+
expect(page.items.length).to eql(1)
|
38
|
+
expect(page.items[0].data).to eql(payload)
|
38
39
|
stop_reactor
|
39
40
|
end
|
40
41
|
end
|
@@ -42,15 +43,15 @@ describe Ably::Realtime::Channel, '#history', :event_machine do
|
|
42
43
|
end
|
43
44
|
|
44
45
|
context 'with two clients publishing messages on the same channel' do
|
45
|
-
it 'retrieves
|
46
|
+
it 'retrieves realtime history on both channels' do
|
46
47
|
channel.publish('event', payload) do |message|
|
47
48
|
channel2.publish('event', payload) do |message|
|
48
|
-
channel.history do |
|
49
|
-
expect(
|
50
|
-
expect(
|
49
|
+
channel.history do |page|
|
50
|
+
expect(page.items.length).to eql(2)
|
51
|
+
expect(page.items.map(&:data).uniq).to eql([payload])
|
51
52
|
|
52
|
-
channel2.history do |
|
53
|
-
expect(
|
53
|
+
channel2.history do |page_2|
|
54
|
+
expect(page_2.items.length).to eql(2)
|
54
55
|
stop_reactor
|
55
56
|
end
|
56
57
|
end
|
@@ -65,18 +66,18 @@ describe Ably::Realtime::Channel, '#history', :event_machine do
|
|
65
66
|
let(:limit) { 15 }
|
66
67
|
|
67
68
|
def ensure_message_history_direction_and_paging_is_correct(direction)
|
68
|
-
channel.history(direction: direction, limit: limit) do |
|
69
|
-
expect(
|
69
|
+
channel.history(direction: direction, limit: limit) do |history_page|
|
70
|
+
expect(history_page.items.length).to eql(limit)
|
70
71
|
limit.times do |index|
|
71
|
-
expect(
|
72
|
+
expect(history_page.items[index].data).to eql("history#{index}")
|
72
73
|
end
|
73
74
|
|
74
|
-
|
75
|
-
expect(
|
75
|
+
history_page.next do |next_page|
|
76
|
+
expect(next_page.items.length).to eql(limit)
|
76
77
|
limit.times do |index|
|
77
|
-
expect(
|
78
|
+
expect(next_page.items[index].data).to eql("history#{index + limit}")
|
78
79
|
end
|
79
|
-
expect(
|
80
|
+
expect(next_page).to be_last
|
80
81
|
|
81
82
|
stop_reactor
|
82
83
|
end
|
@@ -141,8 +142,8 @@ describe Ably::Realtime::Channel, '#history', :event_machine do
|
|
141
142
|
channel.subscribe('event') do |message|
|
142
143
|
messages << message
|
143
144
|
if messages.count == batches * messages_per_batch
|
144
|
-
channel.history do |
|
145
|
-
expect(
|
145
|
+
channel.history do |page|
|
146
|
+
expect(page.items.map(&:id).sort).to eql(messages.map(&:id).sort)
|
146
147
|
stop_reactor
|
147
148
|
end
|
148
149
|
end
|
@@ -150,5 +151,55 @@ describe Ably::Realtime::Channel, '#history', :event_machine do
|
|
150
151
|
end
|
151
152
|
end
|
152
153
|
end
|
154
|
+
|
155
|
+
context 'with option until_attach: true' do
|
156
|
+
let(:event) { random_str }
|
157
|
+
let(:message_before_attach) { random_str }
|
158
|
+
let(:message_after_attach) { random_str }
|
159
|
+
|
160
|
+
it 'retrieves all messages before channel was attached' do
|
161
|
+
rest_channel.publish event, message_before_attach
|
162
|
+
|
163
|
+
channel.attach do
|
164
|
+
channel.publish(event, message_after_attach) do
|
165
|
+
channel.history(until_attach: true) do |messages|
|
166
|
+
expect(messages.items.count).to eql(1)
|
167
|
+
expect(messages.items.first.data).to eql(message_before_attach)
|
168
|
+
stop_reactor
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
context 'and two pages of messages' do
|
175
|
+
it 'retrieves two pages of messages before channel was attached' do
|
176
|
+
10.times { rest_channel.publish event, message_before_attach }
|
177
|
+
|
178
|
+
channel.attach do
|
179
|
+
10.times { rest_channel.publish event, message_after_attach }
|
180
|
+
|
181
|
+
EventMachine.add_timer(0.5) do
|
182
|
+
channel.history(until_attach: true, limit: 5) do |messages|
|
183
|
+
expect(messages.items.count).to eql(5)
|
184
|
+
expect(messages.items.map(&:data).uniq.first).to eql(message_before_attach)
|
185
|
+
|
186
|
+
messages.next do |next_page_messages|
|
187
|
+
expect(next_page_messages.items.count).to eql(5)
|
188
|
+
expect(next_page_messages.items.map(&:data).uniq.first).to eql(message_before_attach)
|
189
|
+
expect(next_page_messages).to be_last
|
190
|
+
|
191
|
+
stop_reactor
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
it 'raises an exception unless state is attached' do
|
200
|
+
expect { channel.history(until_attach: true) }.to raise_error(ArgumentError, /not attached/)
|
201
|
+
stop_reactor
|
202
|
+
end
|
203
|
+
end
|
153
204
|
end
|
154
205
|
end
|
@@ -3,7 +3,7 @@ require 'spec_helper'
|
|
3
3
|
|
4
4
|
describe Ably::Realtime::Channel, :event_machine do
|
5
5
|
vary_by_protocol do
|
6
|
-
let(:default_options) { {
|
6
|
+
let(:default_options) { { key: api_key, environment: environment, protocol: protocol } }
|
7
7
|
let(:client_options) { default_options }
|
8
8
|
|
9
9
|
let(:client) { Ably::Realtime::Client.new(client_options) }
|
@@ -158,7 +158,7 @@ describe Ably::Realtime::Channel, :event_machine do
|
|
158
158
|
|
159
159
|
context 'failure as a result of insufficient key permissions' do
|
160
160
|
let(:restricted_client) do
|
161
|
-
Ably::Realtime::Client.new(default_options.merge(
|
161
|
+
Ably::Realtime::Client.new(default_options.merge(key: restricted_api_key, log_level: :fatal))
|
162
162
|
end
|
163
163
|
let(:restricted_channel) { restricted_client.channel("cannot_subscribe") }
|
164
164
|
|
@@ -202,7 +202,7 @@ describe Ably::Realtime::Channel, :event_machine do
|
|
202
202
|
restricted_channel.once(:failed) do
|
203
203
|
restricted_client.close do
|
204
204
|
# A direct call to #authorise is synchronous
|
205
|
-
restricted_client.auth.authorise(
|
205
|
+
restricted_client.auth.authorise(key: api_key)
|
206
206
|
|
207
207
|
restricted_client.connect do
|
208
208
|
restricted_channel.once(:attached) do
|