ably 1.1.1 → 1.1.5
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/.github/workflows/check.yml +27 -0
- data/CHANGELOG.md +60 -2
- data/COPYRIGHT +1 -0
- data/LICENSE +172 -11
- data/MAINTAINERS.md +1 -0
- data/README.md +2 -14
- data/SPEC.md +1020 -922
- data/ably.gemspec +5 -5
- data/lib/ably/auth.rb +12 -2
- data/lib/ably/exceptions.rb +2 -2
- data/lib/ably/logger.rb +7 -1
- data/lib/ably/modules/ably.rb +11 -1
- data/lib/ably/modules/state_machine.rb +1 -1
- data/lib/ably/realtime/channel.rb +7 -11
- data/lib/ably/realtime/channel/channel_manager.rb +2 -2
- data/lib/ably/realtime/channel/channel_properties.rb +24 -0
- data/lib/ably/realtime/client.rb +9 -0
- data/lib/ably/realtime/connection.rb +7 -4
- data/lib/ably/realtime/connection/connection_manager.rb +19 -1
- data/lib/ably/realtime/connection/websocket_transport.rb +67 -1
- data/lib/ably/realtime/presence.rb +0 -14
- data/lib/ably/rest/channel.rb +25 -17
- data/lib/ably/rest/client.rb +35 -17
- data/lib/ably/rest/middleware/fail_if_unsupported_mime_type.rb +4 -1
- data/lib/ably/version.rb +1 -1
- data/spec/acceptance/realtime/auth_spec.rb +5 -4
- data/spec/acceptance/realtime/channel_spec.rb +21 -8
- data/spec/acceptance/realtime/client_spec.rb +80 -20
- data/spec/acceptance/realtime/connection_failures_spec.rb +90 -9
- data/spec/acceptance/realtime/connection_spec.rb +47 -19
- data/spec/acceptance/realtime/message_spec.rb +2 -4
- data/spec/acceptance/realtime/presence_history_spec.rb +0 -58
- data/spec/acceptance/realtime/presence_spec.rb +54 -0
- data/spec/acceptance/realtime/push_admin_spec.rb +43 -21
- data/spec/acceptance/rest/auth_spec.rb +6 -75
- data/spec/acceptance/rest/base_spec.rb +8 -4
- data/spec/acceptance/rest/channel_spec.rb +42 -4
- data/spec/acceptance/rest/client_spec.rb +121 -26
- data/spec/acceptance/rest/message_spec.rb +1 -2
- data/spec/acceptance/rest/push_admin_spec.rb +67 -27
- data/spec/shared/client_initializer_behaviour.rb +131 -8
- data/spec/spec_helper.rb +1 -0
- data/spec/support/debug_failure_helper.rb +9 -5
- data/spec/support/serialization_helper.rb +21 -0
- data/spec/support/test_app.rb +2 -2
- data/spec/unit/modules/enum_spec.rb +1 -1
- data/spec/unit/realtime/client_spec.rb +20 -7
- data/spec/unit/realtime/connection_spec.rb +1 -1
- metadata +22 -17
- data/.travis.yml +0 -19
@@ -278,28 +278,14 @@ module Ably::Realtime
|
|
278
278
|
|
279
279
|
# Return the presence messages history for the channel
|
280
280
|
#
|
281
|
-
# Once attached to a channel, you can retrieve presence message history on the channel before the
|
282
|
-
# channel was attached with the option <tt>until_attach: true</tt>. This is very useful for
|
283
|
-
# developers who wish to capture new presence events as well as retrieve historical presence state with
|
284
|
-
# the guarantee that no presence history has been missed.
|
285
|
-
#
|
286
281
|
# @param (see Ably::Rest::Presence#history)
|
287
282
|
# @option options (see Ably::Rest::Presence#history)
|
288
|
-
# @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.
|
289
283
|
#
|
290
284
|
# @yield [Ably::Models::PaginatedResult<Ably::Models::PresenceMessage>] First {Ably::Models::PaginatedResult page} of {Ably::Models::PresenceMessage} objects accessible with {Ably::Models::PaginatedResult#items #items}.
|
291
285
|
#
|
292
286
|
# @return [Ably::Util::SafeDeferrable]
|
293
287
|
#
|
294
288
|
def history(options = {}, &callback)
|
295
|
-
if options.delete(:until_attach)
|
296
|
-
unless channel.attached?
|
297
|
-
error = Ably::Exceptions::InvalidRequest.new('option :until_attach is invalid as the channel is not attached')
|
298
|
-
return Ably::Util::SafeDeferrable.new_and_fail_immediately(logger, error)
|
299
|
-
end
|
300
|
-
options[:from_serial] = channel.attached_serial
|
301
|
-
end
|
302
|
-
|
303
289
|
async_wrap(callback) do
|
304
290
|
rest_presence.history(options.merge(async_blocking_operations: true))
|
305
291
|
end
|
data/lib/ably/rest/channel.rb
CHANGED
@@ -40,15 +40,14 @@ module Ably
|
|
40
40
|
@push = PushChannel.new(self)
|
41
41
|
end
|
42
42
|
|
43
|
-
# Publish one or more messages to the channel.
|
44
|
-
#
|
45
|
-
# @param
|
46
|
-
# @param
|
47
|
-
# @param attributes [Hash, nil] Optional additional message attributes such as :extras, :id, :client_id or :connection_id, applied when name attribute is nil or a string
|
43
|
+
# Publish one or more messages to the channel. Three overloaded forms
|
44
|
+
# @param name [String, Array<Ably::Models::Message|Hash>, Ably::Models::Message, nil] The event name of the message to publish, or an Array of [Ably::Model::Message] objects or [Hash] objects with +:name+ and +:data+ pairs, or a single Ably::Model::Message object
|
45
|
+
# @param data [String, ByteArray, Hash, nil] The message payload unless an Array of [Ably::Model::Message] objects passed in the first argument, in which case an optional hash of query parameters
|
46
|
+
# @param attributes [Hash, nil] Optional additional message attributes such as :extras, :id, :client_id or :connection_id, applied when name attribute is nil or a string (Deprecated, will be removed in 2.0 in favour of constructing a Message object)
|
48
47
|
# @return [Boolean] true if the message was published, otherwise false
|
49
48
|
#
|
50
49
|
# @example
|
51
|
-
# # Publish a single message
|
50
|
+
# # Publish a single message with (name, data) form
|
52
51
|
# channel.publish 'click', { x: 1, y: 2 }
|
53
52
|
#
|
54
53
|
# # Publish an array of message Hashes
|
@@ -65,17 +64,25 @@ module Ably
|
|
65
64
|
# ]
|
66
65
|
# channel.publish messages
|
67
66
|
#
|
68
|
-
|
69
|
-
|
70
|
-
|
67
|
+
# # Publish a single Ably::Models::Message object, with a query params
|
68
|
+
# # specifying quickAck: true
|
69
|
+
# message = Ably::Models::Message(name: 'click', { x: 1, y: 2 })
|
70
|
+
# channel.publish message, quickAck: 'true'
|
71
|
+
#
|
72
|
+
def publish(first, second = nil, third = {})
|
73
|
+
messages, qs_params = if first.kind_of?(Enumerable)
|
74
|
+
# ([Message], qs_params) form
|
75
|
+
[first, second]
|
76
|
+
elsif first.kind_of?(Ably::Models::Message)
|
77
|
+
# (Message, qs_params) form
|
78
|
+
[[first], second]
|
71
79
|
else
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
[{ name: name, data: data }.merge(attributes)]
|
80
|
+
# (name, data, attributes) form
|
81
|
+
first = ensure_utf_8(:name, first, allow_nil: true)
|
82
|
+
ensure_supported_payload second
|
83
|
+
# RSL1h - attributes as an extra method parameter is extra-spec but need to
|
84
|
+
# keep it for backcompat until version 2
|
85
|
+
[[{ name: first, data: second }.merge(third)], nil]
|
79
86
|
end
|
80
87
|
|
81
88
|
payload = messages.each_with_index.map do |message, index|
|
@@ -103,7 +110,8 @@ module Ably
|
|
103
110
|
end
|
104
111
|
end
|
105
112
|
|
106
|
-
|
113
|
+
options = qs_params ? { qs_params: qs_params } : {}
|
114
|
+
response = client.post("#{base_path}/publish", payload.length == 1 ? payload.first : payload, options)
|
107
115
|
|
108
116
|
[201, 204].include?(response.status)
|
109
117
|
end
|
data/lib/ably/rest/client.rb
CHANGED
@@ -3,6 +3,9 @@ require 'json'
|
|
3
3
|
require 'logger'
|
4
4
|
require 'uri'
|
5
5
|
|
6
|
+
require 'typhoeus'
|
7
|
+
require 'typhoeus/adapters/faraday'
|
8
|
+
|
6
9
|
require 'ably/rest/middleware/exceptions'
|
7
10
|
|
8
11
|
module Ably
|
@@ -32,6 +35,13 @@ module Ably
|
|
32
35
|
|
33
36
|
FALLBACK_RETRY_TIMEOUT = 10 * 60
|
34
37
|
|
38
|
+
# Faraday 1.0 introduced new error types, however we want to support Faraday <1 too which only used Faraday::ClientError
|
39
|
+
FARADAY_CLIENT_OR_SERVER_ERRORS = if defined?(Faraday::ParsingError)
|
40
|
+
[Faraday::ClientError, Faraday::ServerError, Faraday::ConnectionFailed, Faraday::SSLError, Faraday::ParsingError]
|
41
|
+
else
|
42
|
+
Faraday::ClientError
|
43
|
+
end
|
44
|
+
|
35
45
|
def_delegators :auth, :client_id, :auth_options
|
36
46
|
|
37
47
|
# Custom environment to use such as 'sandbox' when testing the client library against an alternate Ably environment
|
@@ -174,16 +184,18 @@ module Ably
|
|
174
184
|
@idempotent_rest_publishing = options.delete(:idempotent_rest_publishing) || Ably.major_minor_version_numeric > 1.1
|
175
185
|
|
176
186
|
|
177
|
-
if options[:fallback_hosts_use_default] && options[:
|
178
|
-
raise ArgumentError, "fallback_hosts_use_default cannot be set to
|
187
|
+
if options[:fallback_hosts_use_default] && options[:fallback_hosts]
|
188
|
+
raise ArgumentError, "fallback_hosts_use_default cannot be set to try when fallback_hosts is also provided"
|
179
189
|
end
|
180
190
|
@fallback_hosts = case
|
181
191
|
when options.delete(:fallback_hosts_use_default)
|
182
192
|
Ably::FALLBACK_HOSTS
|
183
193
|
when options_fallback_hosts = options.delete(:fallback_hosts)
|
184
194
|
options_fallback_hosts
|
185
|
-
when
|
195
|
+
when custom_host || options[:realtime_host] || custom_port || custom_tls_port
|
186
196
|
[]
|
197
|
+
when environment
|
198
|
+
CUSTOM_ENVIRONMENT_FALLBACKS_SUFFIXES.map { |host| "#{environment}#{host}" }
|
187
199
|
else
|
188
200
|
Ably::FALLBACK_HOSTS
|
189
201
|
end
|
@@ -195,6 +207,8 @@ module Ably
|
|
195
207
|
@http_defaults = HTTP_DEFAULTS.dup
|
196
208
|
options.each do |key, val|
|
197
209
|
if http_key = key[/^http_(.+)/, 1]
|
210
|
+
# Typhoeus converts decimal durations to milliseconds, so 0.0001 timeout is treated as 0 (no timeout)
|
211
|
+
val = 0.001 if val.kind_of?(Numeric) && (val > 0) && (val < 0.001)
|
198
212
|
@http_defaults[http_key.to_sym] = val if val && @http_defaults.has_key?(http_key.to_sym)
|
199
213
|
end
|
200
214
|
end
|
@@ -336,14 +350,14 @@ module Ably
|
|
336
350
|
#
|
337
351
|
# @return [Ably::Models::HttpPaginatedResponse<>]
|
338
352
|
def request(method, path, params = {}, body = nil, headers = {}, options = {})
|
339
|
-
raise "Method #{method.to_s.upcase} not supported" unless
|
353
|
+
raise "Method #{method.to_s.upcase} not supported" unless %i(get put patch post delete).include?(method.to_sym)
|
340
354
|
|
341
355
|
response = case method.to_sym
|
342
|
-
when :get
|
356
|
+
when :get, :delete
|
343
357
|
reauthorize_on_authorization_failure do
|
344
358
|
send_request(method, path, params, headers: headers)
|
345
359
|
end
|
346
|
-
when :post
|
360
|
+
when :post, :patch, :put
|
347
361
|
path_with_params = Addressable::URI.new
|
348
362
|
path_with_params.query_values = params || {}
|
349
363
|
query = path_with_params.query
|
@@ -471,11 +485,13 @@ module Ably
|
|
471
485
|
|
472
486
|
# Allowable duration for an external auth request
|
473
487
|
# For REST client this defaults to request_timeout
|
474
|
-
# For Realtime clients this defaults to realtime_request_timeout
|
488
|
+
# For Realtime clients this defaults to 250ms less than the realtime_request_timeout
|
489
|
+
# ensuring an auth failure will be triggered before the realtime request timeout fires
|
490
|
+
# which would lead to a misleading error message (connection timeout as opposed to auth request timeout)
|
475
491
|
# @api private
|
476
492
|
def auth_request_timeout
|
477
493
|
if @realtime_client
|
478
|
-
@realtime_client.connection.defaults.fetch(:realtime_request_timeout)
|
494
|
+
@realtime_client.connection.defaults.fetch(:realtime_request_timeout) - 0.25
|
479
495
|
else
|
480
496
|
http_defaults.fetch(:request_timeout)
|
481
497
|
end
|
@@ -557,12 +573,14 @@ module Ably
|
|
557
573
|
request.options.context = {} if request.options.context.nil?
|
558
574
|
request.options.context[:request_id] = request_id
|
559
575
|
end
|
576
|
+
if options[:qs_params]
|
577
|
+
request.params.merge!(options[:qs_params])
|
578
|
+
end
|
560
579
|
unless options[:send_auth_header] == false
|
561
580
|
request.headers[:authorization] = auth.auth_header
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
end
|
581
|
+
|
582
|
+
options[:headers].to_h.merge(auth.extra_auth_headers).map do |key, val|
|
583
|
+
request.headers[key] = val
|
566
584
|
end
|
567
585
|
end
|
568
586
|
end.tap do
|
@@ -576,7 +594,7 @@ module Ably
|
|
576
594
|
end
|
577
595
|
end
|
578
596
|
|
579
|
-
rescue Faraday::TimeoutError,
|
597
|
+
rescue *([Faraday::TimeoutError, Ably::Exceptions::ServerError] + FARADAY_CLIENT_OR_SERVER_ERRORS) => error
|
580
598
|
retry_sequence_id ||= SecureRandom.urlsafe_base64(4)
|
581
599
|
time_passed = Time.now - requested_at
|
582
600
|
|
@@ -596,7 +614,7 @@ module Ably
|
|
596
614
|
case error
|
597
615
|
when Faraday::TimeoutError
|
598
616
|
raise Ably::Exceptions::ConnectionTimeout.new(error.message, nil, Ably::Exceptions::Codes::CONNECTION_TIMED_OUT, error, { request_id: request_id })
|
599
|
-
when
|
617
|
+
when *FARADAY_CLIENT_OR_SERVER_ERRORS
|
600
618
|
# request_id is also available in the request context
|
601
619
|
raise Ably::Exceptions::ConnectionError.new(error.message, nil, Ably::Exceptions::Codes::CONNECTION_FAILED, error, { request_id: request_id })
|
602
620
|
else
|
@@ -654,7 +672,7 @@ module Ably
|
|
654
672
|
}
|
655
673
|
end
|
656
674
|
|
657
|
-
# Return a Faraday middleware stack to initiate the Faraday::
|
675
|
+
# Return a Faraday middleware stack to initiate the Faraday::RackBuilder with
|
658
676
|
#
|
659
677
|
# @see http://mislav.uniqpath.com/2011/07/faraday-advanced-http/
|
660
678
|
def middleware
|
@@ -666,8 +684,8 @@ module Ably
|
|
666
684
|
|
667
685
|
setup_incoming_middleware builder, logger, fail_if_unsupported_mime_type: true
|
668
686
|
|
669
|
-
# Set Faraday's HTTP adapter
|
670
|
-
builder.adapter :
|
687
|
+
# Set Faraday's HTTP adapter with support for HTTP/2
|
688
|
+
builder.adapter :typhoeus, http_version: :httpv2_0
|
671
689
|
end
|
672
690
|
end
|
673
691
|
|
@@ -7,7 +7,10 @@ module Ably
|
|
7
7
|
class FailIfUnsupportedMimeType < Faraday::Response::Middleware
|
8
8
|
def on_complete(env)
|
9
9
|
unless env.response_headers['Ably-Middleware-Parsed'] == true
|
10
|
-
|
10
|
+
# Ignore empty body with success status code for no body response
|
11
|
+
return if env.body.to_s.empty? && env.status == 204
|
12
|
+
|
13
|
+
unless (500..599).include?(env.status)
|
11
14
|
raise Ably::Exceptions::InvalidResponseBody,
|
12
15
|
"Content Type #{env.response_headers['Content-Type']} is not supported by this client library"
|
13
16
|
end
|
data/lib/ably/version.rb
CHANGED
@@ -1058,7 +1058,7 @@ describe Ably::Realtime::Auth, :event_machine do
|
|
1058
1058
|
|
1059
1059
|
it 'disconnected includes and invalid signature message' do
|
1060
1060
|
client.connection.once(:disconnected) do |state_change|
|
1061
|
-
expect(state_change.reason.message.match(/
|
1061
|
+
expect(state_change.reason.message.match(/signature verification failed/i)).to_not be_nil
|
1062
1062
|
expect(state_change.reason.code).to eql(40144)
|
1063
1063
|
stop_reactor
|
1064
1064
|
end
|
@@ -1111,7 +1111,7 @@ describe Ably::Realtime::Auth, :event_machine do
|
|
1111
1111
|
|
1112
1112
|
it 'authentication fails and reason for disconnection is invalid signature' do
|
1113
1113
|
client.connection.once(:disconnected) do |state_change|
|
1114
|
-
expect(state_change.reason.message.match(/
|
1114
|
+
expect(state_change.reason.message.match(/signature verification failed/i)).to_not be_nil
|
1115
1115
|
expect(state_change.reason.code).to eql(40144)
|
1116
1116
|
stop_reactor
|
1117
1117
|
end
|
@@ -1139,10 +1139,11 @@ describe Ably::Realtime::Auth, :event_machine do
|
|
1139
1139
|
context 'when credentials are invalid' do
|
1140
1140
|
let(:key_secret) { 'invalid' }
|
1141
1141
|
let(:token) { Faraday.get("#{auth_url}?keyName=#{key_name}&keySecret=#{key_secret}").body }
|
1142
|
+
let(:client_options) { { token: token, environment: environment, protocol: protocol, log_level: :none } }
|
1142
1143
|
|
1143
1144
|
it 'fails with an invalid signature error' do
|
1144
1145
|
client.connection.once(:disconnected) do |state_change|
|
1145
|
-
expect(state_change.reason.message.match(/
|
1146
|
+
expect(state_change.reason.message.match(/signature verification failed/i)).to_not be_nil
|
1146
1147
|
expect(state_change.reason.code).to eql(40144)
|
1147
1148
|
stop_reactor
|
1148
1149
|
end
|
@@ -1239,7 +1240,7 @@ describe Ably::Realtime::Auth, :event_machine do
|
|
1239
1240
|
Faraday.get("#{auth_url}?keyName=#{key_name}&keySecret=#{key_secret}&capability=#{URI.escape(basic_capability)}").body
|
1240
1241
|
end
|
1241
1242
|
end
|
1242
|
-
let(:client_options) { default_options.merge(auth_callback: auth_callback) }
|
1243
|
+
let(:client_options) { default_options.merge(auth_callback: auth_callback, log_level: :error) }
|
1243
1244
|
|
1244
1245
|
it 'client fails to publish to a channel with subscribe-only capability and publishes successfully on a channel with permissions' do
|
1245
1246
|
client.connection.once(:connected) do
|
@@ -83,6 +83,16 @@ describe Ably::Realtime::Channel, :event_machine do
|
|
83
83
|
end
|
84
84
|
end
|
85
85
|
|
86
|
+
it 'sets attach_serial property after the attachment (#RTL15a)' do
|
87
|
+
expect(channel.properties.attach_serial).to be_nil
|
88
|
+
|
89
|
+
channel.attach
|
90
|
+
channel.on(:attached) do
|
91
|
+
expect(channel.properties.attach_serial).to_not be_nil
|
92
|
+
stop_reactor
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
86
96
|
it 'sends an ATTACH and waits for an ATTACHED (#RTL4c)' do
|
87
97
|
connection.once(:connected) do
|
88
98
|
attach_count = 0
|
@@ -279,8 +289,7 @@ describe Ably::Realtime::Channel, :event_machine do
|
|
279
289
|
key: restricted_api_key,
|
280
290
|
log_level: :fatal,
|
281
291
|
use_token_auth: true,
|
282
|
-
|
283
|
-
default_token_params: { capability: { "canpublish:foo" => ["publish"] } }
|
292
|
+
default_token_params: { capability: { "canpublish:foo" => ["*"] } }
|
284
293
|
)
|
285
294
|
end
|
286
295
|
let(:restricted_client) do
|
@@ -1009,9 +1018,6 @@ describe Ably::Realtime::Channel, :event_machine do
|
|
1009
1018
|
|
1010
1019
|
it 'publishes the message without a name attribute in the payload' do
|
1011
1020
|
published = false
|
1012
|
-
channel.publish(nil, data) do
|
1013
|
-
published = true
|
1014
|
-
end
|
1015
1021
|
|
1016
1022
|
channel.subscribe do |message|
|
1017
1023
|
expect(message.name).to be_nil
|
@@ -1024,6 +1030,10 @@ describe Ably::Realtime::Channel, :event_machine do
|
|
1024
1030
|
end
|
1025
1031
|
end
|
1026
1032
|
end
|
1033
|
+
|
1034
|
+
channel.publish(nil, data) do
|
1035
|
+
published = true
|
1036
|
+
end
|
1027
1037
|
end
|
1028
1038
|
end
|
1029
1039
|
|
@@ -1032,9 +1042,6 @@ describe Ably::Realtime::Channel, :event_machine do
|
|
1032
1042
|
|
1033
1043
|
it 'publishes the message without a data attribute in the payload' do
|
1034
1044
|
published = false
|
1035
|
-
channel.publish(name, nil) do
|
1036
|
-
published = true
|
1037
|
-
end
|
1038
1045
|
|
1039
1046
|
channel.subscribe do |message|
|
1040
1047
|
expect(message.data).to be_nil
|
@@ -1047,6 +1054,10 @@ describe Ably::Realtime::Channel, :event_machine do
|
|
1047
1054
|
end
|
1048
1055
|
end
|
1049
1056
|
end
|
1057
|
+
|
1058
|
+
channel.publish(name, nil) do
|
1059
|
+
published = true
|
1060
|
+
end
|
1050
1061
|
end
|
1051
1062
|
end
|
1052
1063
|
|
@@ -1997,6 +2008,8 @@ describe Ably::Realtime::Channel, :event_machine do
|
|
1997
2008
|
end
|
1998
2009
|
|
1999
2010
|
context '#resume (#RTL2f)' do
|
2011
|
+
let(:client_options) { default_options.merge(log_level: :fatal) }
|
2012
|
+
|
2000
2013
|
it 'is false when a channel first attaches' do
|
2001
2014
|
channel.attach
|
2002
2015
|
channel.on(:attached) do |channel_state_change|
|
@@ -87,22 +87,6 @@ describe Ably::Realtime::Client, :event_machine do
|
|
87
87
|
end
|
88
88
|
end
|
89
89
|
end
|
90
|
-
|
91
|
-
context 'with client_id' do
|
92
|
-
let(:client_options) do
|
93
|
-
default_options.merge(client_id: random_str)
|
94
|
-
end
|
95
|
-
it 'connects using token auth' do
|
96
|
-
run_reactor do
|
97
|
-
connection.on(:connected) do
|
98
|
-
expect(connection.state).to eq(:connected)
|
99
|
-
expect(auth_params[:access_token]).to_not be_nil
|
100
|
-
expect(auth_params[:key]).to be_nil
|
101
|
-
stop_reactor
|
102
|
-
end
|
103
|
-
end
|
104
|
-
end
|
105
|
-
end
|
106
90
|
end
|
107
91
|
end
|
108
92
|
|
@@ -249,6 +233,8 @@ describe Ably::Realtime::Client, :event_machine do
|
|
249
233
|
|
250
234
|
context '#request (#RSC19*)' do
|
251
235
|
let(:client_options) { default_options.merge(key: api_key) }
|
236
|
+
let(:device_id) { random_str }
|
237
|
+
let(:endpoint) { subject.rest_client.endpoint }
|
252
238
|
|
253
239
|
context 'get' do
|
254
240
|
it 'returns an HttpPaginatedResponse object' do
|
@@ -297,6 +283,76 @@ describe Ably::Realtime::Client, :event_machine do
|
|
297
283
|
end
|
298
284
|
end
|
299
285
|
end
|
286
|
+
|
287
|
+
|
288
|
+
context 'post', :webmock do
|
289
|
+
before do
|
290
|
+
stub_request(:delete, "#{endpoint}/push/deviceRegistrations/#{device_id}/resetUpdateToken").
|
291
|
+
to_return(status: 200, body: '{}', headers: { 'Content-Type' => 'application/json' })
|
292
|
+
end
|
293
|
+
|
294
|
+
it 'supports post' do
|
295
|
+
subject.request(:delete, "push/deviceRegistrations/#{device_id}/resetUpdateToken").callback do |response|
|
296
|
+
expect(response).to be_success
|
297
|
+
stop_reactor
|
298
|
+
end
|
299
|
+
end
|
300
|
+
end
|
301
|
+
|
302
|
+
context 'delete', :webmock do
|
303
|
+
before do
|
304
|
+
stub_request(:delete, "#{endpoint}/push/channelSubscriptions?deviceId=#{device_id}").
|
305
|
+
to_return(status: 200, body: '{}', headers: { 'Content-Type' => 'application/json' })
|
306
|
+
end
|
307
|
+
|
308
|
+
it 'supports delete' do
|
309
|
+
subject.request(:delete, "/push/channelSubscriptions", { deviceId: device_id}).callback do |response|
|
310
|
+
expect(response).to be_success
|
311
|
+
stop_reactor
|
312
|
+
end
|
313
|
+
end
|
314
|
+
end
|
315
|
+
|
316
|
+
context 'patch', :webmock do
|
317
|
+
let(:body_params) { { 'metadata' => { 'key' => 'value' } } }
|
318
|
+
|
319
|
+
before do
|
320
|
+
stub_request(:patch, "#{endpoint}/push/deviceRegistrations/#{device_id}")
|
321
|
+
.with(body: serialize_body(body_params, protocol))
|
322
|
+
.to_return(status: 200, body: '{}', headers: { 'Content-Type' => 'application/json' })
|
323
|
+
end
|
324
|
+
|
325
|
+
it 'supports patch' do
|
326
|
+
subject.request(:patch, "/push/deviceRegistrations/#{device_id}", {}, body_params).callback do |response|
|
327
|
+
expect(response).to be_success
|
328
|
+
stop_reactor
|
329
|
+
end
|
330
|
+
end
|
331
|
+
end
|
332
|
+
|
333
|
+
context 'put', :webmock do
|
334
|
+
let(:body_params) do
|
335
|
+
{
|
336
|
+
'id' => random_str,
|
337
|
+
'platform' => 'ios',
|
338
|
+
'formFactor' => 'phone',
|
339
|
+
'metadata' => { 'key' => 'value' }
|
340
|
+
}
|
341
|
+
end
|
342
|
+
|
343
|
+
before do
|
344
|
+
stub_request(:put, "#{endpoint}/push/deviceRegistrations/#{device_id}")
|
345
|
+
.with(body: serialize_body(body_params, protocol))
|
346
|
+
.to_return(status: 200, body: '{}', headers: { 'Content-Type' => 'application/json' })
|
347
|
+
end
|
348
|
+
|
349
|
+
it 'supports put' do
|
350
|
+
subject.request(:put, "/push/deviceRegistrations/#{device_id}", {}, body_params).callback do |response|
|
351
|
+
expect(response).to be_success
|
352
|
+
stop_reactor
|
353
|
+
end
|
354
|
+
end
|
355
|
+
end
|
300
356
|
end
|
301
357
|
|
302
358
|
context '#publish (#TBC)' do
|
@@ -315,8 +371,9 @@ describe Ably::Realtime::Client, :event_machine do
|
|
315
371
|
expect(msg.data).to eql(data)
|
316
372
|
stop_reactor
|
317
373
|
end
|
374
|
+
|
375
|
+
subject.publish channel_name, event_name, data
|
318
376
|
end
|
319
|
-
subject.publish channel_name, event_name, data
|
320
377
|
end
|
321
378
|
|
322
379
|
specify 'publishing does not result in a channel being created' do
|
@@ -341,8 +398,9 @@ describe Ably::Realtime::Client, :event_machine do
|
|
341
398
|
expect(msg.extras).to eql(extras)
|
342
399
|
stop_reactor
|
343
400
|
end
|
401
|
+
|
402
|
+
subject.publish channel_name, event_name, {}, extras: extras
|
344
403
|
end
|
345
|
-
subject.publish channel_name, event_name, {}, extras: extras
|
346
404
|
end
|
347
405
|
end
|
348
406
|
|
@@ -353,8 +411,9 @@ describe Ably::Realtime::Client, :event_machine do
|
|
353
411
|
expect(msg.data).to eql(data)
|
354
412
|
stop_reactor
|
355
413
|
end
|
414
|
+
|
415
|
+
subject.publish channel_name, [message]
|
356
416
|
end
|
357
|
-
subject.publish channel_name, [message]
|
358
417
|
end
|
359
418
|
|
360
419
|
specify 'publishing supports an array of Hash objects' do
|
@@ -364,8 +423,9 @@ describe Ably::Realtime::Client, :event_machine do
|
|
364
423
|
expect(msg.data).to eql(data)
|
365
424
|
stop_reactor
|
366
425
|
end
|
426
|
+
|
427
|
+
subject.publish channel_name, [name: event_name, data: data]
|
367
428
|
end
|
368
|
-
subject.publish channel_name, [name: event_name, data: data]
|
369
429
|
end
|
370
430
|
|
371
431
|
specify 'publishing on a closed connection fails' do
|