ably 1.1.0 → 1.1.4

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 (50) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/check.yml +27 -0
  3. data/CHANGELOG.md +68 -2
  4. data/COPYRIGHT +1 -0
  5. data/LICENSE +172 -11
  6. data/MAINTAINERS.md +1 -0
  7. data/README.md +3 -7
  8. data/SPEC.md +944 -914
  9. data/ably.gemspec +7 -7
  10. data/lib/ably/auth.rb +12 -2
  11. data/lib/ably/exceptions.rb +2 -2
  12. data/lib/ably/logger.rb +7 -1
  13. data/lib/ably/modules/state_machine.rb +1 -1
  14. data/lib/ably/realtime/channel.rb +7 -11
  15. data/lib/ably/realtime/channel/channel_manager.rb +2 -2
  16. data/lib/ably/realtime/channel/channel_properties.rb +24 -0
  17. data/lib/ably/realtime/client.rb +12 -3
  18. data/lib/ably/realtime/connection.rb +31 -19
  19. data/lib/ably/realtime/connection/connection_manager.rb +19 -3
  20. data/lib/ably/realtime/connection/websocket_transport.rb +67 -1
  21. data/lib/ably/realtime/presence.rb +0 -14
  22. data/lib/ably/rest/channel.rb +25 -17
  23. data/lib/ably/rest/client.rb +22 -11
  24. data/lib/ably/version.rb +1 -1
  25. data/spec/acceptance/realtime/auth_spec.rb +16 -13
  26. data/spec/acceptance/realtime/channel_history_spec.rb +26 -20
  27. data/spec/acceptance/realtime/channel_spec.rb +21 -8
  28. data/spec/acceptance/realtime/client_spec.rb +80 -20
  29. data/spec/acceptance/realtime/connection_failures_spec.rb +71 -5
  30. data/spec/acceptance/realtime/connection_spec.rb +153 -26
  31. data/spec/acceptance/realtime/message_spec.rb +17 -17
  32. data/spec/acceptance/realtime/presence_history_spec.rb +0 -58
  33. data/spec/acceptance/realtime/presence_spec.rb +250 -162
  34. data/spec/acceptance/realtime/push_admin_spec.rb +49 -25
  35. data/spec/acceptance/rest/auth_spec.rb +6 -75
  36. data/spec/acceptance/rest/channel_spec.rb +79 -4
  37. data/spec/acceptance/rest/channels_spec.rb +6 -0
  38. data/spec/acceptance/rest/client_spec.rb +72 -12
  39. data/spec/acceptance/rest/message_spec.rb +8 -27
  40. data/spec/acceptance/rest/push_admin_spec.rb +67 -27
  41. data/spec/shared/client_initializer_behaviour.rb +0 -8
  42. data/spec/spec_helper.rb +2 -1
  43. data/spec/support/debug_failure_helper.rb +9 -5
  44. data/spec/support/serialization_helper.rb +21 -0
  45. data/spec/support/test_app.rb +2 -2
  46. data/spec/unit/modules/enum_spec.rb +1 -1
  47. data/spec/unit/realtime/client_spec.rb +20 -7
  48. data/spec/unit/realtime/connection_spec.rb +1 -1
  49. metadata +40 -29
  50. data/.travis.yml +0 -16
@@ -1,3 +1,5 @@
1
+ require 'openssl'
2
+
1
3
  module Ably::Realtime
2
4
  class Connection
3
5
  # EventMachine WebSocket transport
@@ -16,10 +18,13 @@ module Ably::Realtime
16
18
  )
17
19
  include Ably::Modules::StateEmitter
18
20
 
21
+ attr_reader :host
22
+
19
23
  def initialize(connection, url)
20
24
  @connection = connection
21
25
  @state = STATE.Initialized
22
26
  @url = url
27
+ @host = URI.parse(url).hostname
23
28
 
24
29
  setup_event_handlers
25
30
  end
@@ -49,7 +54,7 @@ module Ably::Realtime
49
54
  # Required {http://www.rubydoc.info/github/eventmachine/eventmachine/EventMachine/Connection EventMachine::Connection} interface
50
55
  def connection_completed
51
56
  change_state STATE.Connected
52
- start_tls if client.use_tls?
57
+ start_tls(tls_opts) if client.use_tls?
53
58
  driver.start
54
59
  end
55
60
 
@@ -77,6 +82,51 @@ module Ably::Realtime
77
82
  send_data(data)
78
83
  end
79
84
 
85
+ # TLS verification support, original implementation by Mislav Marohnić:
86
+ #
87
+ # https://github.com/lostisland/faraday/commit/63cf47c95b573539f047c729bd9ad67560bc83ff
88
+ def ssl_verify_peer(cert_string)
89
+ cert = nil
90
+ begin
91
+ cert = OpenSSL::X509::Certificate.new(cert_string)
92
+ rescue OpenSSL::X509::CertificateError => e
93
+ disconnect_with_reason "Websocket host '#{host}' returned an invalid TLS certificate: #{e.message}"
94
+ return false
95
+ end
96
+
97
+ @last_seen_cert = cert
98
+
99
+ if certificate_store.verify(@last_seen_cert)
100
+ begin
101
+ certificate_store.add_cert(@last_seen_cert)
102
+ rescue OpenSSL::X509::StoreError => e
103
+ unless e.message == 'cert already in hash table'
104
+ disconnect_with_reason "Websocket host '#{host}' returned an invalid TLS certificate: #{e.message}"
105
+ return false
106
+ end
107
+ end
108
+ true
109
+ else
110
+ disconnect_with_reason "Websocket host '#{host}' returned an invalid TLS certificate"
111
+ false
112
+ end
113
+ end
114
+
115
+ def ssl_handshake_completed
116
+ unless OpenSSL::SSL.verify_certificate_identity(@last_seen_cert, host)
117
+ disconnect_with_reason "Websocket host '#{host}' returned an invalid TLS certificate"
118
+ false
119
+ else
120
+ true
121
+ end
122
+ end
123
+
124
+ def certificate_store
125
+ @certificate_store ||= OpenSSL::X509::Store.new.tap do |store|
126
+ store.set_default_paths
127
+ end
128
+ end
129
+
80
130
  # True if socket connection is ready to be released
81
131
  # i.e. it is not currently connecting or connected
82
132
  def ready_for_release?
@@ -106,6 +156,12 @@ module Ably::Realtime
106
156
  @connection
107
157
  end
108
158
 
159
+ def disconnect_with_reason(reason)
160
+ client.logger.error { "WebsocketTransport: Disconnecting due to error: #{reason}" }
161
+ @reason_closed = reason
162
+ disconnect
163
+ end
164
+
109
165
  def reason_closed
110
166
  @reason_closed
111
167
  end
@@ -214,6 +270,16 @@ module Ably::Realtime
214
270
  end
215
271
  )
216
272
  end
273
+
274
+ # TLS options to pass to EventMachine::Connection#start_tls
275
+ #
276
+ # See https://www.rubydoc.info/github/eventmachine/eventmachine/EventMachine/Connection#start_tls-instance_method
277
+ def tls_opts
278
+ {
279
+ sni_hostname: host,
280
+ verify_peer: true,
281
+ }
282
+ end
217
283
  end
218
284
  end
219
285
  end
@@ -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
@@ -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 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
46
- # @param data [String, ByteArray, nil] The message payload unless an Array of [Ably::Model::Message] objects passed in the first argument
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
- def publish(name, data = nil, attributes = {})
69
- messages = if name.kind_of?(Enumerable)
70
- name
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
- if name.kind_of?(Ably::Models::Message)
73
- raise ArgumentError, "name argument does not support single Message objects, only arrays of Message objects"
74
- end
75
-
76
- name = ensure_utf_8(:name, name, allow_nil: true)
77
- ensure_supported_payload data
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
- response = client.post("#{base_path}/publish", payload.length == 1 ? payload.first : payload)
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
@@ -32,6 +32,13 @@ module Ably
32
32
 
33
33
  FALLBACK_RETRY_TIMEOUT = 10 * 60
34
34
 
35
+ # Faraday 1.0 introduced new error types, however we want to support Faraday <1 too which only used Faraday::ClientError
36
+ FARADAY_CLIENT_OR_SERVER_ERRORS = if defined?(Faraday::ParsingError)
37
+ [Faraday::ClientError, Faraday::ServerError, Faraday::ConnectionFailed, Faraday::SSLError, Faraday::ParsingError]
38
+ else
39
+ Faraday::ClientError
40
+ end
41
+
35
42
  def_delegators :auth, :client_id, :auth_options
36
43
 
37
44
  # Custom environment to use such as 'sandbox' when testing the client library against an alternate Ably environment
@@ -336,14 +343,14 @@ module Ably
336
343
  #
337
344
  # @return [Ably::Models::HttpPaginatedResponse<>]
338
345
  def request(method, path, params = {}, body = nil, headers = {}, options = {})
339
- raise "Method #{method.to_s.upcase} not supported" unless [:get, :put, :post].include?(method.to_sym)
346
+ raise "Method #{method.to_s.upcase} not supported" unless %i(get put patch post delete).include?(method.to_sym)
340
347
 
341
348
  response = case method.to_sym
342
- when :get
349
+ when :get, :delete
343
350
  reauthorize_on_authorization_failure do
344
351
  send_request(method, path, params, headers: headers)
345
352
  end
346
- when :post
353
+ when :post, :patch, :put
347
354
  path_with_params = Addressable::URI.new
348
355
  path_with_params.query_values = params || {}
349
356
  query = path_with_params.query
@@ -471,11 +478,13 @@ module Ably
471
478
 
472
479
  # Allowable duration for an external auth request
473
480
  # For REST client this defaults to request_timeout
474
- # For Realtime clients this defaults to realtime_request_timeout
481
+ # For Realtime clients this defaults to 250ms less than the realtime_request_timeout
482
+ # ensuring an auth failure will be triggered before the realtime request timeout fires
483
+ # which would lead to a misleading error message (connection timeout as opposed to auth request timeout)
475
484
  # @api private
476
485
  def auth_request_timeout
477
486
  if @realtime_client
478
- @realtime_client.connection.defaults.fetch(:realtime_request_timeout)
487
+ @realtime_client.connection.defaults.fetch(:realtime_request_timeout) - 0.25
479
488
  else
480
489
  http_defaults.fetch(:request_timeout)
481
490
  end
@@ -557,12 +566,14 @@ module Ably
557
566
  request.options.context = {} if request.options.context.nil?
558
567
  request.options.context[:request_id] = request_id
559
568
  end
569
+ if options[:qs_params]
570
+ request.params.merge!(options[:qs_params])
571
+ end
560
572
  unless options[:send_auth_header] == false
561
573
  request.headers[:authorization] = auth.auth_header
562
- if options[:headers]
563
- options[:headers].map do |key, val|
564
- request.headers[key] = val
565
- end
574
+
575
+ options[:headers].to_h.merge(auth.extra_auth_headers).map do |key, val|
576
+ request.headers[key] = val
566
577
  end
567
578
  end
568
579
  end.tap do
@@ -576,7 +587,7 @@ module Ably
576
587
  end
577
588
  end
578
589
 
579
- rescue Faraday::TimeoutError, Faraday::ClientError, Ably::Exceptions::ServerError => error
590
+ rescue *([Faraday::TimeoutError, Ably::Exceptions::ServerError] + FARADAY_CLIENT_OR_SERVER_ERRORS) => error
580
591
  retry_sequence_id ||= SecureRandom.urlsafe_base64(4)
581
592
  time_passed = Time.now - requested_at
582
593
 
@@ -596,7 +607,7 @@ module Ably
596
607
  case error
597
608
  when Faraday::TimeoutError
598
609
  raise Ably::Exceptions::ConnectionTimeout.new(error.message, nil, Ably::Exceptions::Codes::CONNECTION_TIMED_OUT, error, { request_id: request_id })
599
- when Faraday::ClientError
610
+ when *FARADAY_CLIENT_OR_SERVER_ERRORS
600
611
  # request_id is also available in the request context
601
612
  raise Ably::Exceptions::ConnectionError.new(error.message, nil, Ably::Exceptions::Codes::CONNECTION_FAILED, error, { request_id: request_id })
602
613
  else
data/lib/ably/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  module Ably
2
- VERSION = '1.1.0'
2
+ VERSION = '1.1.4'
3
3
  PROTOCOL_VERSION = '1.1'
4
4
 
5
5
  # Allow a variant to be configured for all instances of this client library
@@ -661,17 +661,19 @@ describe Ably::Realtime::Auth, :event_machine do
661
661
  client.connection.once(:disconnected) { raise 'Upgrade does not require a disconnect' }
662
662
 
663
663
  channel = client.channels.get('foo')
664
- channel.publish('not-allowed').errback do |error|
665
- expect(error.code).to eql(40160)
666
- expect(error.message).to match(/permission denied/)
664
+ channel.attach do
665
+ channel.publish('not-allowed').errback do |error|
666
+ expect(error.code).to eql(40160)
667
+ expect(error.message).to match(/permission denied/)
667
668
 
668
- client.auth.authorize(nil, auth_callback: upgraded_token_cb)
669
- client.connection.once(:update) do
670
- expect(client.connection.error_reason).to be_nil
671
- channel.subscribe('now-allowed') do |message|
672
- stop_reactor
669
+ client.auth.authorize(nil, auth_callback: upgraded_token_cb)
670
+ client.connection.once(:update) do
671
+ expect(client.connection.error_reason).to be_nil
672
+ channel.subscribe('now-allowed') do |message|
673
+ stop_reactor
674
+ end
675
+ channel.publish 'now-allowed'
673
676
  end
674
- channel.publish 'now-allowed'
675
677
  end
676
678
  end
677
679
  end
@@ -1056,7 +1058,7 @@ describe Ably::Realtime::Auth, :event_machine do
1056
1058
 
1057
1059
  it 'disconnected includes and invalid signature message' do
1058
1060
  client.connection.once(:disconnected) do |state_change|
1059
- expect(state_change.reason.message.match(/invalid signature/i)).to_not be_nil
1061
+ expect(state_change.reason.message.match(/signature verification failed/i)).to_not be_nil
1060
1062
  expect(state_change.reason.code).to eql(40144)
1061
1063
  stop_reactor
1062
1064
  end
@@ -1109,7 +1111,7 @@ describe Ably::Realtime::Auth, :event_machine do
1109
1111
 
1110
1112
  it 'authentication fails and reason for disconnection is invalid signature' do
1111
1113
  client.connection.once(:disconnected) do |state_change|
1112
- expect(state_change.reason.message.match(/invalid signature/i)).to_not be_nil
1114
+ expect(state_change.reason.message.match(/signature verification failed/i)).to_not be_nil
1113
1115
  expect(state_change.reason.code).to eql(40144)
1114
1116
  stop_reactor
1115
1117
  end
@@ -1137,10 +1139,11 @@ describe Ably::Realtime::Auth, :event_machine do
1137
1139
  context 'when credentials are invalid' do
1138
1140
  let(:key_secret) { 'invalid' }
1139
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 } }
1140
1143
 
1141
1144
  it 'fails with an invalid signature error' do
1142
1145
  client.connection.once(:disconnected) do |state_change|
1143
- expect(state_change.reason.message.match(/invalid signature/i)).to_not be_nil
1146
+ expect(state_change.reason.message.match(/signature verification failed/i)).to_not be_nil
1144
1147
  expect(state_change.reason.code).to eql(40144)
1145
1148
  stop_reactor
1146
1149
  end
@@ -1237,7 +1240,7 @@ describe Ably::Realtime::Auth, :event_machine do
1237
1240
  Faraday.get("#{auth_url}?keyName=#{key_name}&keySecret=#{key_secret}&capability=#{URI.escape(basic_capability)}").body
1238
1241
  end
1239
1242
  end
1240
- let(:client_options) { default_options.merge(auth_callback: auth_callback) }
1243
+ let(:client_options) { default_options.merge(auth_callback: auth_callback, log_level: :error) }
1241
1244
 
1242
1245
  it 'client fails to publish to a channel with subscribe-only capability and publishes successfully on a channel with permissions' do
1243
1246
  client.connection.once(:connected) do
@@ -112,22 +112,26 @@ describe Ably::Realtime::Channel, '#history', :event_machine do
112
112
 
113
113
  context 'in multiple ProtocolMessages', em_timeout: (30 / 10) + 5 do
114
114
  it 'retrieves limited history forwards with pagination' do
115
- messages_sent.times do |index|
116
- EventMachine.add_timer(index.to_f / rate_per_second) do
117
- channel.publish('event', "history#{index}") do
118
- next unless index == messages_sent - 1
119
- ensure_message_history_direction_and_paging_is_correct :forwards
115
+ channel.attach do
116
+ messages_sent.times do |index|
117
+ EventMachine.add_timer(index.to_f / rate_per_second) do
118
+ channel.publish('event', "history#{index}") do
119
+ next unless index == messages_sent - 1
120
+ ensure_message_history_direction_and_paging_is_correct :forwards
121
+ end
120
122
  end
121
123
  end
122
124
  end
123
125
  end
124
126
 
125
127
  it 'retrieves limited history backwards with pagination' do
126
- messages_sent.times.to_a.reverse.each do |index|
127
- EventMachine.add_timer((messages_sent - index).to_f / rate_per_second) do
128
- channel.publish('event', "history#{index}") do
129
- next unless index == 0
130
- ensure_message_history_direction_and_paging_is_correct :backwards if index == 0
128
+ channel.attach do
129
+ messages_sent.times.to_a.reverse.each do |index|
130
+ EventMachine.add_timer((messages_sent - index).to_f / rate_per_second) do
131
+ channel.publish('event', "history#{index}") do
132
+ next unless index == 0
133
+ ensure_message_history_direction_and_paging_is_correct :backwards if index == 0
134
+ end
131
135
  end
132
136
  end
133
137
  end
@@ -139,18 +143,20 @@ describe Ably::Realtime::Channel, '#history', :event_machine do
139
143
  let(:messages_per_batch) { 10 }
140
144
 
141
145
  it 'return the same results with unique matching message IDs' do
142
- batches.times do |batch|
143
- EventMachine.add_timer(batch.to_f / batches.to_f) do
144
- messages_per_batch.times { channel.publish('event', 'data') }
146
+ channel.attach do
147
+ batches.times do |batch|
148
+ EventMachine.add_timer(batch.to_f / batches.to_f) do
149
+ messages_per_batch.times { |index| channel.publish('event') }
150
+ end
145
151
  end
146
- end
147
152
 
148
- channel.subscribe('event') do |message|
149
- messages << message
150
- if messages.count == batches * messages_per_batch
151
- channel.history do |page|
152
- expect(page.items.map(&:id).sort).to eql(messages.map(&:id).sort)
153
- stop_reactor
153
+ channel.subscribe('event') do |message|
154
+ messages << message
155
+ if messages.count == batches * messages_per_batch
156
+ channel.history do |page|
157
+ expect(page.items.map(&:id).sort).to eql(messages.map(&:id).sort)
158
+ stop_reactor
159
+ end
154
160
  end
155
161
  end
156
162
  end
@@ -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
- # TODO: Use wildcard / default when intersection issue resolved, realtime#780
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|