ably-rest 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.
Files changed (65) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1 -43
  3. data/SPEC.md +707 -580
  4. data/lib/submodules/ably-ruby/.travis.yml +1 -0
  5. data/lib/submodules/ably-ruby/CHANGELOG.md +143 -3
  6. data/lib/submodules/ably-ruby/README.md +1 -1
  7. data/lib/submodules/ably-ruby/SPEC.md +842 -520
  8. data/lib/submodules/ably-ruby/ably.gemspec +1 -1
  9. data/lib/submodules/ably-ruby/lib/ably/auth.rb +114 -87
  10. data/lib/submodules/ably-ruby/lib/ably/exceptions.rb +40 -14
  11. data/lib/submodules/ably-ruby/lib/ably/models/message.rb +3 -5
  12. data/lib/submodules/ably-ruby/lib/ably/models/paginated_result.rb +3 -12
  13. data/lib/submodules/ably-ruby/lib/ably/models/presence_message.rb +8 -2
  14. data/lib/submodules/ably-ruby/lib/ably/models/protocol_message.rb +15 -3
  15. data/lib/submodules/ably-ruby/lib/ably/models/stat.rb +1 -1
  16. data/lib/submodules/ably-ruby/lib/ably/models/token_details.rb +1 -1
  17. data/lib/submodules/ably-ruby/lib/ably/modules/channels_collection.rb +7 -1
  18. data/lib/submodules/ably-ruby/lib/ably/modules/conversions.rb +1 -1
  19. data/lib/submodules/ably-ruby/lib/ably/modules/encodeable.rb +6 -3
  20. data/lib/submodules/ably-ruby/lib/ably/modules/message_pack.rb +2 -2
  21. data/lib/submodules/ably-ruby/lib/ably/modules/model_common.rb +1 -1
  22. data/lib/submodules/ably-ruby/lib/ably/modules/state_machine.rb +2 -2
  23. data/lib/submodules/ably-ruby/lib/ably/realtime.rb +1 -0
  24. data/lib/submodules/ably-ruby/lib/ably/realtime/auth.rb +191 -0
  25. data/lib/submodules/ably-ruby/lib/ably/realtime/channel.rb +97 -25
  26. data/lib/submodules/ably-ruby/lib/ably/realtime/channel/channel_manager.rb +11 -3
  27. data/lib/submodules/ably-ruby/lib/ably/realtime/client.rb +22 -6
  28. data/lib/submodules/ably-ruby/lib/ably/realtime/connection.rb +73 -40
  29. data/lib/submodules/ably-ruby/lib/ably/realtime/connection/connection_manager.rb +48 -33
  30. data/lib/submodules/ably-ruby/lib/ably/realtime/presence.rb +17 -3
  31. data/lib/submodules/ably-ruby/lib/ably/rest/channel.rb +43 -16
  32. data/lib/submodules/ably-ruby/lib/ably/rest/client.rb +57 -26
  33. data/lib/submodules/ably-ruby/lib/ably/rest/middleware/exceptions.rb +3 -1
  34. data/lib/submodules/ably-ruby/lib/ably/rest/middleware/fail_if_unsupported_mime_type.rb +4 -2
  35. data/lib/submodules/ably-ruby/lib/ably/rest/presence.rb +1 -0
  36. data/lib/submodules/ably-ruby/lib/ably/version.rb +1 -1
  37. data/lib/submodules/ably-ruby/spec/acceptance/realtime/auth_spec.rb +242 -0
  38. data/lib/submodules/ably-ruby/spec/acceptance/realtime/channel_spec.rb +277 -5
  39. data/lib/submodules/ably-ruby/spec/acceptance/realtime/channels_spec.rb +64 -0
  40. data/lib/submodules/ably-ruby/spec/acceptance/realtime/client_spec.rb +26 -5
  41. data/lib/submodules/ably-ruby/spec/acceptance/realtime/connection_failures_spec.rb +23 -6
  42. data/lib/submodules/ably-ruby/spec/acceptance/realtime/connection_spec.rb +167 -16
  43. data/lib/submodules/ably-ruby/spec/acceptance/realtime/message_spec.rb +9 -8
  44. data/lib/submodules/ably-ruby/spec/acceptance/realtime/presence_history_spec.rb +1 -0
  45. data/lib/submodules/ably-ruby/spec/acceptance/realtime/presence_spec.rb +121 -10
  46. data/lib/submodules/ably-ruby/spec/acceptance/realtime/stats_spec.rb +13 -1
  47. data/lib/submodules/ably-ruby/spec/acceptance/rest/auth_spec.rb +161 -79
  48. data/lib/submodules/ably-ruby/spec/acceptance/rest/base_spec.rb +3 -3
  49. data/lib/submodules/ably-ruby/spec/acceptance/rest/channel_spec.rb +142 -15
  50. data/lib/submodules/ably-ruby/spec/acceptance/rest/channels_spec.rb +23 -0
  51. data/lib/submodules/ably-ruby/spec/acceptance/rest/client_spec.rb +180 -18
  52. data/lib/submodules/ably-ruby/spec/acceptance/rest/message_spec.rb +8 -8
  53. data/lib/submodules/ably-ruby/spec/acceptance/rest/presence_spec.rb +136 -25
  54. data/lib/submodules/ably-ruby/spec/acceptance/rest/stats_spec.rb +60 -4
  55. data/lib/submodules/ably-ruby/spec/shared/client_initializer_behaviour.rb +54 -3
  56. data/lib/submodules/ably-ruby/spec/unit/auth_spec.rb +7 -6
  57. data/lib/submodules/ably-ruby/spec/unit/models/message_spec.rb +1 -9
  58. data/lib/submodules/ably-ruby/spec/unit/models/paginated_result_spec.rb +1 -18
  59. data/lib/submodules/ably-ruby/spec/unit/models/presence_message_spec.rb +1 -1
  60. data/lib/submodules/ably-ruby/spec/unit/models/protocol_message_spec.rb +21 -1
  61. data/lib/submodules/ably-ruby/spec/unit/realtime/channel_spec.rb +10 -3
  62. data/lib/submodules/ably-ruby/spec/unit/realtime/channels_spec.rb +27 -8
  63. data/lib/submodules/ably-ruby/spec/unit/rest/channel_spec.rb +0 -8
  64. data/lib/submodules/ably-ruby/spec/unit/rest/client_spec.rb +7 -7
  65. metadata +5 -2
@@ -25,30 +25,51 @@ module Ably
25
25
  def initialize(client, name, channel_options = {})
26
26
  ensure_utf_8 :name, name
27
27
 
28
+ update_options channel_options
28
29
  @client = client
29
30
  @name = name
30
- @options = channel_options.clone.freeze
31
31
  end
32
32
 
33
- # Publish a message to the channel
33
+ # Publish one or more messages to the channel.
34
34
  #
35
- # @param name [String] The event name of the message to publish
36
- # @param data [String] The message payload
37
- # @return [Boolean] true if the message was published, otherwise false
38
- def publish(name, data)
39
- ensure_utf_8 :name, name
40
- ensure_supported_payload data
41
-
42
- payload = {
43
- name: name,
44
- data: data
45
- }
35
+ # @param name [String, Array<Ably::Models::Message|Hash>, 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
36
+ # @param data [String, ByteArray, nil] The message payload unless an Array of [Ably::Model::Message] objects passed in the first argument
37
+ # @return [Boolean] true if the message was published, otherwise false
38
+ #
39
+ # @example
40
+ # # Publish a single message
41
+ # channel.publish 'click', { x: 1, y: 2 }
42
+ #
43
+ # # Publish an array of message Hashes
44
+ # messages = [
45
+ # { name: 'click', { x: 1, y: 2 } },
46
+ # { name: 'click', { x: 2, y: 3 } }
47
+ # ]
48
+ # channel.publish messages
49
+ #
50
+ # # Publish an array of Ably::Models::Message objects
51
+ # messages = [
52
+ # Ably::Models::Message(name: 'click', { x: 1, y: 2 })
53
+ # Ably::Models::Message(name: 'click', { x: 2, y: 3 })
54
+ # ]
55
+ # channel.publish messages
56
+ #
57
+ def publish(name, data = nil)
58
+ messages = if name.kind_of?(Enumerable)
59
+ name
60
+ else
61
+ ensure_utf_8 :name, name, allow_nil: true
62
+ ensure_supported_payload data
63
+ [{ name: name, data: data }]
64
+ end
46
65
 
47
- message = Ably::Models::Message.new(payload).tap do |message|
48
- message.encode self
66
+ payload = messages.map do |message|
67
+ Ably::Models::Message(message.dup).tap do |message|
68
+ message.encode self
69
+ end.as_json
49
70
  end
50
71
 
51
- response = client.post("#{base_path}/publish", message)
72
+ response = client.post("#{base_path}/publish", payload.length == 1 ? payload.first : payload)
52
73
 
53
74
  [201, 204].include?(response.status)
54
75
  end
@@ -71,6 +92,7 @@ module Ably
71
92
  }.merge(options)
72
93
 
73
94
  [:start, :end].each { |option| options[option] = as_since_epoch(options[option]) if options.has_key?(option) }
95
+ raise ArgumentError, ":end must be equal to or after :start" if options[:start] && options[:end] && (options[:start] > options[:end])
74
96
 
75
97
  paginated_options = {
76
98
  coerce_into: 'Ably::Models::Message',
@@ -93,6 +115,11 @@ module Ably
93
115
  @presence ||= Presence.new(client, self)
94
116
  end
95
117
 
118
+ # @api private
119
+ def update_options(channel_options)
120
+ @options = channel_options.clone.freeze
121
+ end
122
+
96
123
  private
97
124
  def base_path
98
125
  "/channels/#{CGI.escape(name)}"
@@ -55,6 +55,14 @@ module Ably
55
55
  # @return [String,Nil]
56
56
  attr_reader :custom_host
57
57
 
58
+ # The custom port for non-TLS requests if it was provided with the option `:port` when the {Client} was created
59
+ # @return [Integer,Nil]
60
+ attr_reader :custom_port
61
+
62
+ # The custom TLS port for TLS requests if it was provided with the option `:tls_port` when the {Client} was created
63
+ # @return [Integer,Nil]
64
+ attr_reader :custom_tls_port
65
+
58
66
  # The registered encoders that are used to encode and decode message payloads
59
67
  # @return [Array<Ably::Models::MessageEncoder::Base>]
60
68
  # @api private
@@ -68,17 +76,25 @@ module Ably
68
76
  # Creates a {Ably::Rest::Client Rest Client} and configures the {Ably::Auth} object for the connection.
69
77
  #
70
78
  # @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
- # @option options (see Ably::Auth#authorise)
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.
79
+ # @option options [Boolean] :tls (true) When fales, TLS is disabled. Please note Basic Auth is disallowed without TLS as secrets cannot be transmitted over unsecured connections.
73
80
  # @option options [String] :key API key comprising the key name and key secret in a single string
74
81
  # @option options [String] :token Token string or {Models::TokenDetails} used to authenticate requests
75
82
  # @option options [String] :token_details {Models::TokenDetails} used to authenticate requests
76
83
  # @option options [Boolean] :use_token_auth Will force Basic Auth if set to false, and Token auth if set to true
77
84
  # @option options [String] :environment Specify 'sandbox' when testing the client library against an alternate Ably environment
78
- # @option options [Symbol] :protocol Protocol used to communicate with Ably, :json and :msgpack currently supported. Defaults to :msgpack
79
- # @option options [Boolean] :use_binary_protocol Protocol used to communicate with Ably, defaults to true and uses MessagePack protocol. This option will overide :protocol option
80
- # @option options [Logger::Severity,Symbol] :log_level Log level for the standard Logger that outputs to STDOUT. Defaults to Logger::ERROR, can be set to :fatal (Logger::FATAL), :error (Logger::ERROR), :warn (Logger::WARN), :info (Logger::INFO), :debug (Logger::DEBUG) or :none
85
+ # @option options [Symbol] :protocol (:msgpack) Protocol used to communicate with Ably, :json and :msgpack currently supported
86
+ # @option options [Boolean] :use_binary_protocol (true) When true will use the MessagePack binary protocol, when false it will use JSON encoding. This option will overide :protocol option
87
+ # @option options [Logger::Severity,Symbol] :log_level (Logger::WARN) Log level for the standard Logger that outputs to STDOUT. Can be set to :fatal (Logger::FATAL), :error (Logger::ERROR), :warn (Logger::WARN), :info (Logger::INFO), :debug (Logger::DEBUG) or :none
81
88
  # @option options [Logger] :logger A custom logger can be used however it must adhere to the Ruby Logger interface, see http://www.ruby-doc.org/stdlib-1.9.3/libdoc/logger/rdoc/Logger.html
89
+ # @option options [String] :client_id client ID identifying this connection to other clients
90
+ # @option options [String] :auth_url a URL to be used to GET or POST a set of token request params, to obtain a signed token request
91
+ # @option options [Hash] :auth_headers a set of application-specific headers to be added to any request made to the +auth_url+
92
+ # @option options [Hash] :auth_params a set of application-specific query params to be added to any request made to the +auth_url+
93
+ # @option options [Symbol] :auth_method (:get) HTTP method to use with +auth_url+, must be either +:get+ or +:post+
94
+ # @option options [Proc] :auth_callback when provided, the Proc will be called with the token params hash as the first argument, whenever a new token is required.
95
+ # The Proc should return a token string, {Ably::Models::TokenDetails} or JSON equivalent, {Ably::Models::TokenRequest} or JSON equivalent
96
+ # @option options [Boolean] :query_time when true will query the {https://www.ably.io Ably} system for the current time instead of using the local time
97
+ # @option options [Hash] :token_params convenience to pass in +token_params+ that will be used as a default for all token requests. See {Auth#create_token_request}
82
98
  #
83
99
  # @return [Ably::Rest::Client]
84
100
  #
@@ -101,13 +117,15 @@ module Ably
101
117
  end
102
118
  end
103
119
 
104
- @tls = options.delete(:tls) == false ? false : true
105
- @environment = options.delete(:environment) # nil is production
106
- @protocol = options.delete(:protocol) || :msgpack
107
- @debug_http = options.delete(:debug_http)
108
- @log_level = options.delete(:log_level) || ::Logger::ERROR
109
- @custom_logger = options.delete(:logger)
110
- @custom_host = options.delete(:rest_host)
120
+ @tls = options.delete(:tls) == false ? false : true
121
+ @environment = options.delete(:environment) # nil is production
122
+ @protocol = options.delete(:protocol) || :msgpack
123
+ @debug_http = options.delete(:debug_http)
124
+ @log_level = options.delete(:log_level) || ::Logger::WARN
125
+ @custom_logger = options.delete(:logger)
126
+ @custom_host = options.delete(:rest_host)
127
+ @custom_port = options.delete(:port)
128
+ @custom_tls_port = options.delete(:tls_port)
111
129
 
112
130
  if @log_level == :none
113
131
  @custom_logger = Ably::Models::NilLogger.new
@@ -124,11 +142,14 @@ module Ably
124
142
  end
125
143
  raise ArgumentError, 'Protocol is invalid. Must be either :msgpack or :json' unless [:msgpack, :json].include?(@protocol)
126
144
 
127
- @options = options.freeze
128
- @auth = Auth.new(self, options)
145
+ token_params = options.delete(:token_params) || {}
146
+ @options = options
147
+ @auth = Auth.new(self, options, token_params)
129
148
  @channels = Ably::Rest::Channels.new(self)
130
149
  @encoders = []
131
150
 
151
+ options.freeze
152
+
132
153
  initialize_default_encoders
133
154
  end
134
155
 
@@ -160,6 +181,7 @@ module Ably
160
181
  }.merge(options)
161
182
 
162
183
  [:start, :end].each { |option| options[option] = as_since_epoch(options[option]) if options.has_key?(option) }
184
+ raise ArgumentError, ":end must be equal to or after :start" if options[:start] && options[:end] && (options[:start] > options[:end])
163
185
 
164
186
  paginated_options = {
165
187
  coerce_into: 'Ably::Models::Stats'
@@ -314,7 +336,7 @@ module Ably
314
336
  end
315
337
  end
316
338
 
317
- rescue Faraday::TimeoutError, Faraday::ClientError => error
339
+ rescue Faraday::TimeoutError, Faraday::ClientError, Ably::Exceptions::ServerError => error
318
340
  time_passed = Time.now - requested_at
319
341
  if can_fallback_to_alternate_ably_host? && retry_count < max_retry_attempts && time_passed <= cumulative_timeout
320
342
  retry_count += 1
@@ -323,33 +345,42 @@ module Ably
323
345
 
324
346
  case error
325
347
  when Faraday::TimeoutError
326
- raise Ably::Exceptions::ConnectionTimeoutError.new(error.message, nil, 80014, error)
348
+ raise Ably::Exceptions::ConnectionTimeout.new(error.message, nil, 80014, error)
327
349
  when Faraday::ClientError
328
350
  raise Ably::Exceptions::ConnectionError.new(error.message, nil, 80000, error)
351
+ else
352
+ raise error
329
353
  end
330
354
  end
331
355
  end
332
356
 
333
357
  def reauthorise_on_authorisation_failure
334
358
  yield
335
- rescue Ably::Exceptions::InvalidRequest => e
336
- if e.code == 40140
337
- if auth.token_renewable?
338
- auth.authorise force: true
339
- yield
340
- else
341
- raise Ably::Exceptions::InvalidToken.new(e.message, e.status, e.code)
342
- end
359
+ rescue Ably::Exceptions::TokenExpired => e
360
+ if auth.token_renewable?
361
+ auth.authorise force: true
362
+ yield
343
363
  else
344
364
  raise e
345
365
  end
346
366
  end
347
367
 
348
368
  def endpoint_for_host(host)
349
- URI::Generic.build(
369
+ port = if use_tls?
370
+ custom_tls_port
371
+ else
372
+ custom_port
373
+ end
374
+
375
+ raise ArgumentError, "Custom port must be an Integer or nil" if port && !port.kind_of?(Integer)
376
+
377
+ options = {
350
378
  scheme: use_tls? ? 'https' : 'http',
351
379
  host: host
352
- )
380
+ }
381
+ options.merge!(port: port) if port
382
+
383
+ URI::Generic.build(options)
353
384
  end
354
385
 
355
386
  # Return a Hash of connection options to initiate the Faraday::Connection with
@@ -29,7 +29,9 @@ module Ably
29
29
  message = 'Unknown server error' if message.to_s.strip == ''
30
30
 
31
31
  if env.status >= 500
32
- raise Ably::Exceptions::ServerError, message
32
+ raise Ably::Exceptions::ServerError.new(message, error_status_code, error_code)
33
+ elsif env.status == 401 && error_code == 40140
34
+ raise Ably::Exceptions::TokenExpired.new(message, error_status_code, error_code)
33
35
  else
34
36
  raise Ably::Exceptions::InvalidRequest.new(message, error_status_code, error_code)
35
37
  end
@@ -7,8 +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
- raise Ably::Exceptions::InvalidResponseBody,
11
- "Content Type #{env.response_headers['Content-Type']} is not supported by this client library"
10
+ unless (500..599).include?(env.status)
11
+ raise Ably::Exceptions::InvalidResponseBody,
12
+ "Content Type #{env.response_headers['Content-Type']} is not supported by this client library"
13
+ end
12
14
  end
13
15
  end
14
16
  end
@@ -64,6 +64,7 @@ module Ably
64
64
  }.merge(options)
65
65
 
66
66
  [:start, :end].each { |option| options[option] = as_since_epoch(options[option]) if options.has_key?(option) }
67
+ raise ArgumentError, ":end must be equal to or after :start" if options[:start] && options[:end] && (options[:start] > options[:end])
67
68
 
68
69
  paginated_options = {
69
70
  coerce_into: 'Ably::Models::PresenceMessage',
@@ -1,3 +1,3 @@
1
1
  module Ably
2
- VERSION = '0.8.2'
2
+ VERSION = '0.8.3'
3
3
  end
@@ -0,0 +1,242 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+
4
+ # Very high level test coverage of the Realtime::Auth object which is just an async
5
+ # wrapper around the Ably::Auth object
6
+ #
7
+ describe Ably::Realtime::Auth, :event_machine do
8
+ vary_by_protocol do
9
+ let(:default_options) { { key: api_key, environment: environment, protocol: protocol } }
10
+ let(:client_options) { default_options }
11
+ let(:client) { Ably::Realtime::Client.new(client_options) }
12
+ let(:auth) { client.auth }
13
+
14
+ context 'with basic auth' do
15
+ context '#authentication_security_requirements_met?' do
16
+ before do
17
+ expect(client.use_tls?).to eql(true)
18
+ end
19
+
20
+ it 'returns true' do
21
+ expect(auth.authentication_security_requirements_met?).to eql(true)
22
+ stop_reactor
23
+ end
24
+ end
25
+
26
+ context '#key' do
27
+ it 'contains the API key' do
28
+ expect(auth.key).to eql(api_key)
29
+ stop_reactor
30
+ end
31
+ end
32
+
33
+ context '#key_name' do
34
+ it 'contains the API key name' do
35
+ expect(auth.key_name).to eql(key_name)
36
+ stop_reactor
37
+ end
38
+ end
39
+
40
+ context '#key_secret' do
41
+ it 'contains the API key secret' do
42
+ expect(auth.key_secret).to eql(key_secret)
43
+ stop_reactor
44
+ end
45
+ end
46
+
47
+ context '#using_basic_auth?' do
48
+ it 'is true when using Basic Auth' do
49
+ expect(auth).to be_using_basic_auth
50
+ stop_reactor
51
+ end
52
+ end
53
+
54
+ context '#using_token_auth?' do
55
+ it 'is false when using Basic Auth' do
56
+ expect(auth).to_not be_using_token_auth
57
+ stop_reactor
58
+ end
59
+ end
60
+ end
61
+
62
+ context 'with token auth' do
63
+ let(:client_id) { random_str }
64
+ let(:client_options) { default_options.merge(client_id: client_id) }
65
+
66
+ context '#client_id' do
67
+ it 'contains the ClientOptions client ID' do
68
+ expect(auth.client_id).to eql(client_id)
69
+ stop_reactor
70
+ end
71
+ end
72
+
73
+ context '#token' do
74
+ let(:client_options) { default_options.merge(token: random_str) }
75
+
76
+ it 'contains the current token after auth' do
77
+ expect(auth.token).to_not be_nil
78
+ stop_reactor
79
+ end
80
+ end
81
+
82
+ context '#current_token_details' do
83
+ it 'contains the current token after auth' do
84
+ expect(auth.current_token_details).to be_nil
85
+ auth.authorise do
86
+ expect(auth.current_token_details).to be_a(Ably::Models::TokenDetails)
87
+ stop_reactor
88
+ end
89
+ end
90
+ end
91
+
92
+ context '#token_renewable?' do
93
+ it 'is true when an API key exists' do
94
+ expect(auth).to be_token_renewable
95
+ stop_reactor
96
+ end
97
+ end
98
+
99
+ context '#options (auth_options)' do
100
+ let(:auth_url) { "https://echo.ably.io/?type=text" }
101
+ let(:auth_params) { { :body => random_str } }
102
+
103
+ it 'contains the configured auth options' do
104
+ auth.authorise(auth_url: auth_url, auth_params: auth_params) do
105
+ expect(auth.options[:auth_url]).to eql(auth_url)
106
+ stop_reactor
107
+ end
108
+ end
109
+ end
110
+
111
+ context '#token_params' do
112
+ let(:custom_ttl) { 33 }
113
+
114
+ it 'contains the configured auth options' do
115
+ auth.authorise({}, ttl: custom_ttl) do
116
+ expect(auth.token_params[:ttl]).to eql(custom_ttl)
117
+ stop_reactor
118
+ end
119
+ end
120
+ end
121
+
122
+ context '#using_basic_auth?' do
123
+ it 'is false when using Token Auth' do
124
+ auth.authorise do
125
+ expect(auth).to_not be_using_basic_auth
126
+ stop_reactor
127
+ end
128
+ end
129
+ end
130
+
131
+ context '#using_token_auth?' do
132
+ it 'is true when using Token Auth' do
133
+ auth.authorise do
134
+ expect(auth).to be_using_token_auth
135
+ stop_reactor
136
+ end
137
+ end
138
+ end
139
+ end
140
+
141
+ context do
142
+ let(:custom_ttl) { 33 }
143
+ let(:custom_client_id) { random_str }
144
+
145
+ context '#create_token_request' do
146
+ it 'returns a token request asynchronously' do
147
+ auth.create_token_request({}, { ttl: custom_ttl }) do |token_request|
148
+ expect(token_request).to be_a(Ably::Models::TokenRequest)
149
+ expect(token_request.ttl).to eql(custom_ttl)
150
+ stop_reactor
151
+ end
152
+ end
153
+ end
154
+
155
+ context '#create_token_request_async' do
156
+ it 'returns a token request synchronously' do
157
+ auth.create_token_request_sync(token_params: { ttl: custom_ttl }).tap do |token_request|
158
+ expect(token_request).to be_a(Ably::Models::TokenRequest)
159
+ expect(token_request.ttl).to eql(custom_ttl)
160
+ stop_reactor
161
+ end
162
+ end
163
+ end
164
+
165
+ context '#request_token' do
166
+ it 'returns a token asynchronously' do
167
+ auth.request_token({ client_id: custom_client_id }, ttl: custom_ttl) do |token_details|
168
+ expect(token_details).to be_a(Ably::Models::TokenDetails)
169
+ expect(token_details.expires.to_i).to be_within(3).of(Time.now.to_i + custom_ttl)
170
+ expect(token_details.client_id).to eql(custom_client_id)
171
+ stop_reactor
172
+ end
173
+ end
174
+ end
175
+
176
+ context '#request_token_async' do
177
+ it 'returns a token synchronously' do
178
+ auth.request_token_sync(client_id: custom_client_id, token_params: { ttl: custom_ttl }).tap do |token_details|
179
+ expect(token_details).to be_a(Ably::Models::TokenDetails)
180
+ expect(token_details.expires.to_i).to be_within(3).of(Time.now.to_i + custom_ttl)
181
+ expect(token_details.client_id).to eql(custom_client_id)
182
+ stop_reactor
183
+ end
184
+ end
185
+ end
186
+
187
+ context '#authorise' do
188
+ it 'returns a token asynchronously' do
189
+ auth.authorise({ client_id: custom_client_id }, ttl: custom_ttl) do |token_details|
190
+ expect(token_details).to be_a(Ably::Models::TokenDetails)
191
+ expect(token_details.expires.to_i).to be_within(3).of(Time.now.to_i + custom_ttl)
192
+ expect(token_details.client_id).to eql(custom_client_id)
193
+ stop_reactor
194
+ end
195
+ end
196
+ end
197
+
198
+ context '#authorise_async' do
199
+ it 'returns a token synchronously' do
200
+ auth.authorise_sync(client_id: custom_client_id, token_params: { ttl: custom_ttl }).tap do |token_details|
201
+ expect(auth.authorise_sync).to be_a(Ably::Models::TokenDetails)
202
+ expect(token_details.expires.to_i).to be_within(3).of(Time.now.to_i + custom_ttl)
203
+ expect(token_details.client_id).to eql(custom_client_id)
204
+ stop_reactor
205
+ end
206
+ end
207
+ end
208
+ end
209
+
210
+ context '#auth_params' do
211
+ it 'returns the auth params asynchronously' do
212
+ auth.auth_params do |auth_params|
213
+ expect(auth_params).to be_a(Hash)
214
+ stop_reactor
215
+ end
216
+ end
217
+ end
218
+
219
+ context '#auth_params' do
220
+ it 'returns the auth params synchronously' do
221
+ expect(auth.auth_params_sync).to be_a(Hash)
222
+ stop_reactor
223
+ end
224
+ end
225
+
226
+ context '#auth_header' do
227
+ it 'returns an auth header asynchronously' do
228
+ auth.auth_header do |auth_header|
229
+ expect(auth_header).to be_a(String)
230
+ stop_reactor
231
+ end
232
+ end
233
+ end
234
+
235
+ context '#auth_header' do
236
+ it 'returns an auth header synchronously' do
237
+ expect(auth.auth_header_sync).to be_a(String)
238
+ stop_reactor
239
+ end
240
+ end
241
+ end
242
+ end