ably 0.8.8 → 0.8.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +16 -2
  3. data/LICENSE +2 -2
  4. data/README.md +81 -20
  5. data/SPEC.md +235 -178
  6. data/lib/ably/auth.rb +1 -1
  7. data/lib/ably/exceptions.rb +10 -1
  8. data/lib/ably/models/cipher_params.rb +114 -0
  9. data/lib/ably/models/connection_details.rb +8 -6
  10. data/lib/ably/models/error_info.rb +3 -3
  11. data/lib/ably/models/idiomatic_ruby_wrapper.rb +27 -20
  12. data/lib/ably/models/message.rb +15 -15
  13. data/lib/ably/models/message_encoders/cipher.rb +8 -7
  14. data/lib/ably/models/presence_message.rb +17 -17
  15. data/lib/ably/models/protocol_message.rb +26 -19
  16. data/lib/ably/models/stats.rb +15 -15
  17. data/lib/ably/models/token_details.rb +14 -12
  18. data/lib/ably/models/token_request.rb +16 -14
  19. data/lib/ably/modules/async_wrapper.rb +1 -1
  20. data/lib/ably/modules/encodeable.rb +10 -10
  21. data/lib/ably/modules/model_common.rb +13 -5
  22. data/lib/ably/realtime/channel.rb +1 -2
  23. data/lib/ably/realtime/presence.rb +29 -58
  24. data/lib/ably/realtime/presence/members_map.rb +2 -2
  25. data/lib/ably/rest/channel.rb +1 -2
  26. data/lib/ably/rest/middleware/exceptions.rb +14 -4
  27. data/lib/ably/rest/presence.rb +3 -1
  28. data/lib/ably/util/crypto.rb +50 -40
  29. data/lib/ably/version.rb +1 -1
  30. data/spec/acceptance/realtime/message_spec.rb +20 -20
  31. data/spec/acceptance/realtime/presence_history_spec.rb +7 -7
  32. data/spec/acceptance/realtime/presence_spec.rb +65 -77
  33. data/spec/acceptance/rest/auth_spec.rb +8 -8
  34. data/spec/acceptance/rest/base_spec.rb +4 -4
  35. data/spec/acceptance/rest/channel_spec.rb +1 -1
  36. data/spec/acceptance/rest/client_spec.rb +1 -1
  37. data/spec/acceptance/rest/encoders_spec.rb +4 -4
  38. data/spec/acceptance/rest/message_spec.rb +15 -15
  39. data/spec/acceptance/rest/presence_spec.rb +4 -4
  40. data/spec/shared/model_behaviour.rb +7 -7
  41. data/spec/unit/models/cipher_params_spec.rb +140 -0
  42. data/spec/unit/models/idiomatic_ruby_wrapper_spec.rb +15 -8
  43. data/spec/unit/models/message_encoders/cipher_spec.rb +28 -22
  44. data/spec/unit/models/message_encoders/json_spec.rb +24 -0
  45. data/spec/unit/models/protocol_message_spec.rb +3 -3
  46. data/spec/unit/util/crypto_spec.rb +50 -17
  47. metadata +5 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8b659327cc341068fce6404895940be1547529f7
4
- data.tar.gz: 1cefe9e6c6ea0a874b71f37834088d85efd76307
3
+ metadata.gz: 8cd4a525c4afb786a1994c05d636351ad5440585
4
+ data.tar.gz: eed7ec593d7bfeb68d5b7663bd438549d30f8c9a
5
5
  SHA512:
6
- metadata.gz: ca4059010c9811beb36753c2cc346c74fed4ac94a20caa45d3a62ec3d4abf5ba32dc90d0687c0f7a88bd642224e843a78dcc1a4537215d3d9a24b7adbb31c84c
7
- data.tar.gz: a24b1ecf027d74490030d49bffafff647c4d9066b70ce603f7b82f1e987679817931267857e5087b3a0d84d197e6d058136417aa2b98c44fb7f64da109821a14
6
+ metadata.gz: b530e68c8e7f13cadd783e43061d1f52230aa60e7744714635e9c097753ef84ce9491016a1fa2ee9718c587a0f8d5a8cec4b554b85b646291d8e04a7f434fea0
7
+ data.tar.gz: 1a6fc49f90ce35216ba8290acad13e80f7d4b62f5a88d8658b11bed27261708b290a2bf509b079c78f3fc1858d502f9c05a187bd2006def26c43519779280ab4
@@ -1,13 +1,27 @@
1
1
  # Change Log
2
2
 
3
- ## [v0.8.8](https://github.com/ably/ably-ruby/tree/v0.8.8)
3
+ ## [v0.8.4](https://github.com/ably/ably-ruby/tree/v0.8.9) (2015-03-01)
4
4
 
5
- [Full Changelog](https://github.com/ably/ably-ruby/compare/v0.8.7...v0.8.8)
5
+ [Full Changelog](https://github.com/ably/ably-ruby/compare/v0.8.7...v0.8.9)
6
+
7
+ **Fixed bugs:**
8
+
9
+ - Support enter\(data\) [\#79](https://github.com/ably/ably-ruby/issues/79)
10
+
11
+ - Update documentation to hide private API methods [\#77](https://github.com/ably/ably-ruby/issues/77)
6
12
 
7
13
  **Closed issues:**
8
14
 
15
+ - New Crypto Spec [\#80](https://github.com/ably/ably-ruby/issues/80)
16
+
9
17
  - Support :key in ClientOptions and deprecate :api\_key [\#73](https://github.com/ably/ably-ruby/issues/73)
10
18
 
19
+ **Merged pull requests:**
20
+
21
+ - Various fixes for open issues [\#82](https://github.com/ably/ably-ruby/pull/82) ([mattheworiordan](https://github.com/mattheworiordan))
22
+
23
+ - Encryption spec update [\#81](https://github.com/ably/ably-ruby/pull/81) ([mattheworiordan](https://github.com/mattheworiordan))
24
+
11
25
  ## [v0.8.7](https://github.com/ably/ably-ruby/tree/v0.8.7) (2015-12-31)
12
26
 
13
27
  [Full Changelog](https://github.com/ably/ably-ruby/compare/v0.8.6...v0.8.7)
data/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
- Copyright (c) 2015 Ably
1
+ Copyright (c) 2016 Ably
2
2
 
3
- Copyright 2015 Ably Real-time Ltd
3
+ Copyright 2016 Ably Real-time Ltd
4
4
 
5
5
  Licensed under the Apache License, Version 2.0 (the "License");
6
6
  you may not use this file except in compliance with the License.
data/README.md CHANGED
@@ -38,7 +38,7 @@ EventMachine.run do
38
38
  end
39
39
  ```
40
40
 
41
- All examples assume a client has been created as follows:
41
+ All examples assume a client has been created using one of the following:
42
42
 
43
43
  ```ruby
44
44
  # basic auth with an API key
@@ -48,6 +48,8 @@ client = Ably::Realtime.new(key: 'xxxxx')
48
48
  client = Ably::Realtime.new(token: 'xxxxx')
49
49
  ```
50
50
 
51
+ If you do not have an API key, [sign up for a free API key now](https://www.ably.io/signup)
52
+
51
53
  ### Connection
52
54
 
53
55
  Successful connection:
@@ -67,20 +69,29 @@ connection_result.errback = Proc.new do
67
69
  end
68
70
  ```
69
71
 
72
+ Subscribing to connection state changes:
73
+
74
+ ```ruby
75
+ client.connection.on do |state_change|
76
+ state_change.current #=> :connected
77
+ state_change.previous #=> :connecting
78
+ end
79
+ ```
80
+
70
81
  ### Subscribing to a channel
71
82
 
72
- Given:
83
+ Given a channel is created as follows:
73
84
 
74
85
  ```ruby
75
- channel = client.channel('test')
86
+ channel = client.channels.get('test')
76
87
  ```
77
88
 
78
89
  Subscribe to all events:
79
90
 
80
91
  ```ruby
81
92
  channel.subscribe do |message|
82
- message[:name] #=> "greeting"
83
- message[:data] #=> "Hello World!"
93
+ message.name #=> "greeting"
94
+ message.data #=> "Hello World!"
84
95
  end
85
96
  ```
86
97
 
@@ -88,12 +99,12 @@ Only certain events:
88
99
 
89
100
  ```ruby
90
101
  channel.subscribe('myEvent') do |message|
91
- message[:name] #=> "myEvent"
92
- message[:data] #=> "myData"
102
+ message.name #=> "myEvent"
103
+ message.data #=> "myData"
93
104
  end
94
105
  ```
95
106
 
96
- ### Publishing to a channel
107
+ ### Publishing a message to a channel
97
108
 
98
109
  ```ruby
99
110
  channel.publish('greeting', 'Hello World!')
@@ -107,7 +118,9 @@ channel.history do |messages_page|
107
118
  messages_page.items.first # #<Ably::Models::Message ...>
108
119
  messages_page.items.first.data # payload for the message
109
120
  messages_page.items.length # number of messages in the current page of history
110
- messages_page.next # retrieves the next page => #<Ably::Models::PaginatedResult ...>
121
+ messages_page.next do |next_page|
122
+ next_page #=> the next page => #<Ably::Models::PaginatedResult ...>
123
+ end
111
124
  messages_page.has_next? # false, there are more pages
112
125
  end
113
126
  ```
@@ -115,8 +128,18 @@ end
115
128
  ### Presence on a channel
116
129
 
117
130
  ```ruby
118
- channel.presence.enter(data: 'john.doe') do |presence|
119
- presence.get #=> [Array of members present]
131
+ channel.presence.enter(data: 'metadata') do |presence|
132
+ presence.get do |members|
133
+ members #=> [Array of members present]
134
+ end
135
+ end
136
+ ```
137
+
138
+ ### Subscribing to presence events
139
+
140
+ ```ruby
141
+ channel.presence.subscribe do |member|
142
+ member #=> { action: :enter, client_id: 'bob' }
120
143
  end
121
144
  ```
122
145
 
@@ -127,10 +150,26 @@ channel.presence.history do |presence_page|
127
150
  presence_page.items.first.action # Any of :enter, :update or :leave
128
151
  presence_page.items.first.client_id # client ID of member
129
152
  presence_page.items.first.data # optional data payload of member
130
- presence_page.next # retrieves the next page => #<Ably::Models::PaginatedResult ...>
153
+ presence_page.next do |next_page|
154
+ next_page #=> the next page => #<Ably::Models::PaginatedResult ...>
155
+ end
156
+ presence_page.has_next? # false, there are more pages
131
157
  end
132
158
  ```
133
159
 
160
+ ### Symmetric end-to-end encrypted payloads on a channel
161
+
162
+ When a 128 bit or 256 bit key is provided to the library, all payloads are encrypted and decrypted automatically using that key on the channel. The secret key is never transmitted to Ably and thus it is the developer's responsibility to distribute a secret key to both publishers and subscribers.
163
+
164
+ ```ruby
165
+ secret_key = Ably::Util::Crypto.generate_random_key
166
+ channel = client.channels.get('test', cipher: { key: secret_key })
167
+ channel.subscribe do |message|
168
+ message.data #=> "sensitive data (encrypted before being published)"
169
+ end
170
+ channel.publish "name (not encrypted)", "sensitive data (encrypted before being published)"
171
+ ```
172
+
134
173
  ## Using the REST API
135
174
 
136
175
  ### Introduction
@@ -160,7 +199,7 @@ messages_page.next # retrieves the next page => #<Ably::Models::PaginatedResult
160
199
  messages_page.has_next? # false, there are more pages
161
200
  ```
162
201
 
163
- ### Presence on a channel
202
+ ### Current presence members on a channel
164
203
 
165
204
  ```ruby
166
205
  members_page = channel.presence.get # => #<Ably::Models::PaginatedResult ...>
@@ -170,7 +209,7 @@ members_page.next # retrieves the next page => #<Ably::Models::PaginatedResult .
170
209
  members_page.has_next? # false, there are more pages
171
210
  ```
172
211
 
173
- ### Querying the Presence History
212
+ ### Querying the presence history
174
213
 
175
214
  ```ruby
176
215
  presence_page = channel.presence.history #=> #<Ably::Models::PaginatedResult ...>
@@ -179,22 +218,44 @@ presence_page.items.first.client_id # client ID of first member
179
218
  presence_page.next # retrieves the next page => #<Ably::Models::PaginatedResult ...>
180
219
  ```
181
220
 
182
- ### Generate Token and Token Request
221
+ ### Symmetric end-to-end encrypted payloads on a channel
222
+
223
+ When a 128 bit or 256 bit key is provided to the library, all payloads are encrypted and decrypted automatically using that key on the channel. The secret key is never transmitted to Ably and thus it is the developer's responsibility to distribute a secret key to both publishers and subscribers.
224
+
225
+ ```ruby
226
+ secret_key = Ably::Util::Crypto.generate_random_key
227
+ channel = client.channels.get('test', cipher: { key: secret_key })
228
+ channel.publish nil, "sensitive data" # data will be encrypted before publish
229
+ messages_page = channel.history
230
+ messages_page.first.data #=> "sensitive data"
231
+ ```
232
+
233
+ ### Generate Token
234
+
235
+ Tokens are issued by Ably and are readily usable by any client to connect to Ably:
183
236
 
184
237
  ```ruby
185
238
  token_details = client.auth.request_token
186
239
  # => #<Ably::Models::TokenDetails ...>
187
240
  token_details.token # => "xVLyHw.CLchevH3hF....MDh9ZC_Q"
188
- client = Ably::Rest.new(token: token_details.token)
241
+ client = Ably::Rest.new(token: token_details)
242
+ ```
189
243
 
190
- token = client.auth.create_token_request(ttl: 3600)
244
+ ### Generate a TokenRequest
245
+
246
+ Token requests are issued by your servers and signed using your private API key. This is the preferred method of authentication as no secrets are ever shared, and the token request can be issued to trusted clients without communicating with Ably.
247
+
248
+ ```ruby
249
+ token_request = client.auth.create_token_request(ttl: 3600, client_id: 'jim')
191
250
  # => {"id"=>...,
192
- # "clientId"=>nil,
251
+ # "clientId"=>"jim",
193
252
  # "ttl"=>3600,
194
253
  # "timestamp"=>...,
195
254
  # "capability"=>"{\"*\":[\"*\"]}",
196
255
  # "nonce"=>...,
197
256
  # "mac"=>...}
257
+
258
+ client = Ably::Rest.new(token: token_request)
198
259
  ```
199
260
 
200
261
  ### Fetching your application's stats
@@ -213,7 +274,7 @@ client.time #=> 2013-12-12 14:23:34 +0000
213
274
 
214
275
  ## Dependencies
215
276
 
216
- If you only need to use the REST features of this library and do not want EventMachine as a dependency, then you should use the [Ably Ruby REST gem](https://rubygems.org/gems/ably-rest).
277
+ If you only need to use the REST features of this library and do not want EventMachine as a dependency, then you should consider using the [Ably Ruby REST gem](https://rubygems.org/gems/ably-rest).
217
278
 
218
279
  ## Support, feedback and troubleshooting
219
280
 
@@ -234,4 +295,4 @@ To see what has changed in recent versions of Bundler, see the [CHANGELOG](CHANG
234
295
 
235
296
  ## License
236
297
 
237
- Copyright (c) 2015 Ably Real-time Ltd, Licensed under the Apache License, Version 2.0. Refer to [LICENSE](LICENSE) for the license terms.
298
+ Copyright (c) 2016 Ably Real-time Ltd, Licensed under the Apache License, Version 2.0. Refer to [LICENSE](LICENSE) for the license terms.
data/SPEC.md CHANGED
@@ -1,4 +1,4 @@
1
- # Ably Realtime & REST Client Library 0.8.6 Specification
1
+ # Ably Realtime & REST Client Library 0.8.9 Specification
2
2
 
3
3
  ### Ably::Realtime::Auth
4
4
  _(see [spec/acceptance/realtime/auth_spec.rb](./spec/acceptance/realtime/auth_spec.rb))_
@@ -431,25 +431,25 @@ _(see [spec/acceptance/realtime/connection_failures_spec.rb](./spec/acceptance/r
431
431
  * [emits any error received from Ably but leaves the channels attached](./spec/acceptance/realtime/connection_failures_spec.rb#L452)
432
432
  * [retains channel subscription state](./spec/acceptance/realtime/connection_failures_spec.rb#L483)
433
433
  * when messages were published whilst the client was disconnected
434
- * [receives the messages published whilst offline](./spec/acceptance/realtime/connection_failures_spec.rb#L513)
434
+ * [receives the messages published whilst offline](./spec/acceptance/realtime/connection_failures_spec.rb#L511)
435
435
  * when failing to resume
436
436
  * because the connection_key is not or no longer valid
437
- * [updates the connection_id and connection_key](./spec/acceptance/realtime/connection_failures_spec.rb#L556)
438
- * [detaches all channels](./spec/acceptance/realtime/connection_failures_spec.rb#L571)
439
- * [emits an error on the channel and sets the error reason](./spec/acceptance/realtime/connection_failures_spec.rb#L591)
437
+ * [updates the connection_id and connection_key](./spec/acceptance/realtime/connection_failures_spec.rb#L554)
438
+ * [detaches all channels](./spec/acceptance/realtime/connection_failures_spec.rb#L569)
439
+ * [emits an error on the channel and sets the error reason](./spec/acceptance/realtime/connection_failures_spec.rb#L589)
440
440
  * fallback host feature
441
441
  * with custom realtime websocket host option
442
- * [never uses a fallback host](./spec/acceptance/realtime/connection_failures_spec.rb#L631)
442
+ * [never uses a fallback host](./spec/acceptance/realtime/connection_failures_spec.rb#L629)
443
443
  * with custom realtime websocket port option
444
- * [never uses a fallback host](./spec/acceptance/realtime/connection_failures_spec.rb#L649)
444
+ * [never uses a fallback host](./spec/acceptance/realtime/connection_failures_spec.rb#L647)
445
445
  * with non-production environment
446
- * [never uses a fallback host](./spec/acceptance/realtime/connection_failures_spec.rb#L668)
446
+ * [never uses a fallback host](./spec/acceptance/realtime/connection_failures_spec.rb#L666)
447
447
  * with production environment
448
448
  * when the Internet is down
449
- * [never uses a fallback host](./spec/acceptance/realtime/connection_failures_spec.rb#L698)
449
+ * [never uses a fallback host](./spec/acceptance/realtime/connection_failures_spec.rb#L696)
450
450
  * when the Internet is up
451
- * [uses a fallback host on every subsequent disconnected attempt until suspended](./spec/acceptance/realtime/connection_failures_spec.rb#L717)
452
- * [uses the primary host when suspended, and a fallback host on every subsequent suspended attempt](./spec/acceptance/realtime/connection_failures_spec.rb#L736)
451
+ * [uses a fallback host on every subsequent disconnected attempt until suspended](./spec/acceptance/realtime/connection_failures_spec.rb#L716)
452
+ * [uses the primary host when suspended, and a fallback host on every subsequent suspended attempt](./spec/acceptance/realtime/connection_failures_spec.rb#L735)
453
453
 
454
454
  ### Ably::Realtime::Connection
455
455
  _(see [spec/acceptance/realtime/connection_spec.rb](./spec/acceptance/realtime/connection_spec.rb))_
@@ -554,69 +554,73 @@ _(see [spec/acceptance/realtime/connection_spec.rb](./spec/acceptance/realtime/c
554
554
  * when ping times out
555
555
  * [logs a warning](./spec/acceptance/realtime/connection_spec.rb#L781)
556
556
  * [yields to the block with a nil value](./spec/acceptance/realtime/connection_spec.rb#L791)
557
+ * #details
558
+ * [is nil before connected](./spec/acceptance/realtime/connection_spec.rb#L806)
559
+ * [contains the ConnectionDetails object once connected](./spec/acceptance/realtime/connection_spec.rb#L813)
560
+ * [contains the new ConnectionDetails object once a subsequent connection is created](./spec/acceptance/realtime/connection_spec.rb#L822)
557
561
  * recovery
558
562
  * #recovery_key
559
- * [is composed of connection key and serial that is kept up to date with each message ACK received](./spec/acceptance/realtime/connection_spec.rb#L828)
560
- * [is available when connection is in one of the states: connecting, connected, disconnected, suspended, failed](./spec/acceptance/realtime/connection_spec.rb#L851)
561
- * [is nil when connection is explicitly CLOSED](./spec/acceptance/realtime/connection_spec.rb#L880)
563
+ * [is composed of connection key and serial that is kept up to date with each message ACK received](./spec/acceptance/realtime/connection_spec.rb#L864)
564
+ * [is available when connection is in one of the states: connecting, connected, disconnected, suspended, failed](./spec/acceptance/realtime/connection_spec.rb#L887)
565
+ * [is nil when connection is explicitly CLOSED](./spec/acceptance/realtime/connection_spec.rb#L916)
562
566
  * opening a new connection using a recently disconnected connection's #recovery_key
563
567
  * connection#id and connection#key after recovery
564
- * [remains the same](./spec/acceptance/realtime/connection_spec.rb#L892)
568
+ * [remains the same for id and party for key](./spec/acceptance/realtime/connection_spec.rb#L928)
565
569
  * when messages have been sent whilst the old connection is disconnected
566
570
  * the new connection
567
- * [recovers server-side queued messages](./spec/acceptance/realtime/connection_spec.rb#L932)
571
+ * [recovers server-side queued messages](./spec/acceptance/realtime/connection_spec.rb#L970)
568
572
  * with :recover option
569
573
  * with invalid syntax
570
- * [raises an exception](./spec/acceptance/realtime/connection_spec.rb#L958)
574
+ * [raises an exception](./spec/acceptance/realtime/connection_spec.rb#L996)
571
575
  * with invalid formatted value sent to server
572
- * [emits a fatal error on the connection object, sets the #error_reason and disconnects](./spec/acceptance/realtime/connection_spec.rb#L967)
576
+ * [emits a fatal error on the connection object, sets the #error_reason and disconnects](./spec/acceptance/realtime/connection_spec.rb#L1005)
573
577
  * with expired (missing) value sent to server
574
- * [emits an error on the connection object, sets the #error_reason, yet will connect anyway](./spec/acceptance/realtime/connection_spec.rb#L982)
578
+ * [emits an error on the connection object, sets the #error_reason, yet will connect anyway](./spec/acceptance/realtime/connection_spec.rb#L1020)
575
579
  * with many connections simultaneously
576
- * [opens each with a unique connection#id and connection#key](./spec/acceptance/realtime/connection_spec.rb#L1001)
580
+ * [opens each with a unique connection#id and connection#key](./spec/acceptance/realtime/connection_spec.rb#L1039)
577
581
  * when a state transition is unsupported
578
- * [emits a InvalidStateChange](./spec/acceptance/realtime/connection_spec.rb#L1021)
582
+ * [emits a InvalidStateChange](./spec/acceptance/realtime/connection_spec.rb#L1059)
579
583
  * protocol failure
580
584
  * receiving an invalid ProtocolMessage
581
- * [emits an error on the connection and logs a fatal error message](./spec/acceptance/realtime/connection_spec.rb#L1037)
585
+ * [emits an error on the connection and logs a fatal error message](./spec/acceptance/realtime/connection_spec.rb#L1075)
582
586
  * undocumented method
583
587
  * #internet_up?
584
- * [returns a Deferrable](./spec/acceptance/realtime/connection_spec.rb#L1053)
588
+ * [returns a Deferrable](./spec/acceptance/realtime/connection_spec.rb#L1091)
585
589
  * internet up URL protocol
586
590
  * when using TLS for the connection
587
- * [uses TLS for the Internet check to https://internet-up.ably-realtime.com/is-the-internet-up.txt](./spec/acceptance/realtime/connection_spec.rb#L1064)
591
+ * [uses TLS for the Internet check to https://internet-up.ably-realtime.com/is-the-internet-up.txt](./spec/acceptance/realtime/connection_spec.rb#L1102)
588
592
  * when using a non-secured connection
589
- * [uses TLS for the Internet check to http://internet-up.ably-realtime.com/is-the-internet-up.txt](./spec/acceptance/realtime/connection_spec.rb#L1074)
593
+ * [uses TLS for the Internet check to http://internet-up.ably-realtime.com/is-the-internet-up.txt](./spec/acceptance/realtime/connection_spec.rb#L1112)
590
594
  * when the Internet is up
591
- * [calls the block with true](./spec/acceptance/realtime/connection_spec.rb#L1105)
592
- * [calls the success callback of the Deferrable](./spec/acceptance/realtime/connection_spec.rb#L1112)
595
+ * [calls the block with true](./spec/acceptance/realtime/connection_spec.rb#L1143)
596
+ * [calls the success callback of the Deferrable](./spec/acceptance/realtime/connection_spec.rb#L1150)
593
597
  * with a TLS connection
594
- * [checks the Internet up URL over TLS](./spec/acceptance/realtime/connection_spec.rb#L1088)
598
+ * [checks the Internet up URL over TLS](./spec/acceptance/realtime/connection_spec.rb#L1126)
595
599
  * with a non-TLS connection
596
- * [checks the Internet up URL over TLS](./spec/acceptance/realtime/connection_spec.rb#L1098)
600
+ * [checks the Internet up URL over TLS](./spec/acceptance/realtime/connection_spec.rb#L1136)
597
601
  * when the Internet is down
598
- * [calls the block with false](./spec/acceptance/realtime/connection_spec.rb#L1127)
599
- * [calls the failure callback of the Deferrable](./spec/acceptance/realtime/connection_spec.rb#L1134)
602
+ * [calls the block with false](./spec/acceptance/realtime/connection_spec.rb#L1165)
603
+ * [calls the failure callback of the Deferrable](./spec/acceptance/realtime/connection_spec.rb#L1172)
600
604
  * state change side effects
601
605
  * when connection enters the :disconnected state
602
- * [queues messages to be sent and all channels remain attached](./spec/acceptance/realtime/connection_spec.rb#L1148)
606
+ * [queues messages to be sent and all channels remain attached](./spec/acceptance/realtime/connection_spec.rb#L1186)
603
607
  * when connection enters the :suspended state
604
- * [detaches the channels and prevents publishing of messages on those channels](./spec/acceptance/realtime/connection_spec.rb#L1181)
608
+ * [detaches the channels and prevents publishing of messages on those channels](./spec/acceptance/realtime/connection_spec.rb#L1219)
605
609
  * when connection enters the :failed state
606
- * [sets all channels to failed and prevents publishing of messages on those channels](./spec/acceptance/realtime/connection_spec.rb#L1210)
610
+ * [sets all channels to failed and prevents publishing of messages on those channels](./spec/acceptance/realtime/connection_spec.rb#L1248)
607
611
  * connection state change
608
- * [emits a ConnectionStateChange object](./spec/acceptance/realtime/connection_spec.rb#L1221)
612
+ * [emits a ConnectionStateChange object](./spec/acceptance/realtime/connection_spec.rb#L1259)
609
613
  * ConnectionStateChange object
610
- * [has current state](./spec/acceptance/realtime/connection_spec.rb#L1229)
611
- * [has a previous state](./spec/acceptance/realtime/connection_spec.rb#L1236)
612
- * [has an empty reason when there is no error](./spec/acceptance/realtime/connection_spec.rb#L1251)
614
+ * [has current state](./spec/acceptance/realtime/connection_spec.rb#L1267)
615
+ * [has a previous state](./spec/acceptance/realtime/connection_spec.rb#L1274)
616
+ * [has an empty reason when there is no error](./spec/acceptance/realtime/connection_spec.rb#L1289)
613
617
  * on failure
614
- * [has a reason Error object when there is an error on the connection](./spec/acceptance/realtime/connection_spec.rb#L1264)
618
+ * [has a reason Error object when there is an error on the connection](./spec/acceptance/realtime/connection_spec.rb#L1302)
615
619
  * retry_in
616
- * [is nil when a retry is not required](./spec/acceptance/realtime/connection_spec.rb#L1279)
617
- * [is 0 when first attempt to connect fails](./spec/acceptance/realtime/connection_spec.rb#L1286)
618
- * [is 0 when an immediate reconnect will occur](./spec/acceptance/realtime/connection_spec.rb#L1296)
619
- * [contains the next retry period when an immediate reconnect will not occur](./spec/acceptance/realtime/connection_spec.rb#L1306)
620
+ * [is nil when a retry is not required](./spec/acceptance/realtime/connection_spec.rb#L1317)
621
+ * [is 0 when first attempt to connect fails](./spec/acceptance/realtime/connection_spec.rb#L1324)
622
+ * [is 0 when an immediate reconnect will occur](./spec/acceptance/realtime/connection_spec.rb#L1334)
623
+ * [contains the next retry period when an immediate reconnect will not occur](./spec/acceptance/realtime/connection_spec.rb#L1344)
620
624
 
621
625
  ### Ably::Realtime::Channel Message
622
626
  _(see [spec/acceptance/realtime/message_spec.rb](./spec/acceptance/realtime/message_spec.rb))_
@@ -756,29 +760,27 @@ _(see [spec/acceptance/realtime/presence_spec.rb](./spec/acceptance/realtime/pre
756
760
  * 250 existing (present) members on a channel (3 SYNC pages)
757
761
  * requires at least 3 SYNC ProtocolMessages
758
762
  * when a client attaches to the presence channel
759
- * [emits :present for each member](./spec/acceptance/realtime/presence_spec.rb#L530)
763
+ * [emits :present for each member](./spec/acceptance/realtime/presence_spec.rb#L533)
760
764
  * and a member leaves before the SYNC operation is complete
761
- * [emits :leave immediately as the member leaves](./spec/acceptance/realtime/presence_spec.rb#L544)
762
- * [ignores presence events with timestamps prior to the current :present event in the MembersMap](./spec/acceptance/realtime/presence_spec.rb#L585)
763
- * [does not emit :present after the :leave event has been emitted, and that member is not included in the list of members via #get with :wait_for_sync](./spec/acceptance/realtime/presence_spec.rb#L627)
765
+ * [emits :leave immediately as the member leaves](./spec/acceptance/realtime/presence_spec.rb#L547)
766
+ * [ignores presence events with timestamps prior to the current :present event in the MembersMap](./spec/acceptance/realtime/presence_spec.rb#L588)
767
+ * [does not emit :present after the :leave event has been emitted, and that member is not included in the list of members via #get with :wait_for_sync](./spec/acceptance/realtime/presence_spec.rb#L630)
764
768
  * #get
765
769
  * with :wait_for_sync option set to true
766
- * [waits until sync is complete](./spec/acceptance/realtime/presence_spec.rb#L677)
770
+ * [waits until sync is complete](./spec/acceptance/realtime/presence_spec.rb#L680)
767
771
  * by default
768
- * [it does not wait for sync](./spec/acceptance/realtime/presence_spec.rb#L694)
772
+ * [it does not wait for sync](./spec/acceptance/realtime/presence_spec.rb#L699)
769
773
  * state
770
774
  * once opened
771
- * [once opened, enters the :left state if the channel detaches](./spec/acceptance/realtime/presence_spec.rb#L718)
775
+ * [once opened, enters the :left state if the channel detaches](./spec/acceptance/realtime/presence_spec.rb#L725)
772
776
  * #enter
773
- * [allows client_id to be set on enter for anonymous clients](./spec/acceptance/realtime/presence_spec.rb#L741)
774
- * [raises an exception if client_id is not set](./spec/acceptance/realtime/presence_spec.rb#L788)
775
777
  * data attribute
776
778
  * when provided as argument option to #enter
777
- * [remains intact following #leave](./spec/acceptance/realtime/presence_spec.rb#L752)
779
+ * [changes to value provided in #leave](./spec/acceptance/realtime/presence_spec.rb#L750)
778
780
  * message #connection_id
779
- * [matches the current client connection_id](./spec/acceptance/realtime/presence_spec.rb#L776)
781
+ * [matches the current client connection_id](./spec/acceptance/realtime/presence_spec.rb#L774)
780
782
  * without necessary capabilities to join presence
781
- * [calls the Deferrable errback on capabilities failure](./spec/acceptance/realtime/presence_spec.rb#L800)
783
+ * [calls the Deferrable errback on capabilities failure](./spec/acceptance/realtime/presence_spec.rb#L793)
782
784
  * it should behave like a public presence method
783
785
  * [raise an exception if the channel is detached](./spec/acceptance/realtime/presence_spec.rb#L54)
784
786
  * [raise an exception if the channel is failed](./spec/acceptance/realtime/presence_spec.rb#L66)
@@ -817,11 +819,11 @@ _(see [spec/acceptance/realtime/presence_spec.rb](./spec/acceptance/realtime/pre
817
819
  * if connection fails before success
818
820
  * [calls the Deferrable errback if channel is detached](./spec/acceptance/realtime/presence_spec.rb#L271)
819
821
  * #update
820
- * [without previous #enter automatically enters](./spec/acceptance/realtime/presence_spec.rb#L812)
821
- * [updates the data if :data argument provided](./spec/acceptance/realtime/presence_spec.rb#L837)
822
- * [updates the data to nil if :data argument is not provided (assumes nil value)](./spec/acceptance/realtime/presence_spec.rb#L847)
822
+ * [without previous #enter automatically enters](./spec/acceptance/realtime/presence_spec.rb#L805)
823
+ * [updates the data if :data argument provided](./spec/acceptance/realtime/presence_spec.rb#L830)
824
+ * [updates the data to nil if :data argument is not provided (assumes nil value)](./spec/acceptance/realtime/presence_spec.rb#L840)
823
825
  * when ENTERED
824
- * [has no effect on the state](./spec/acceptance/realtime/presence_spec.rb#L822)
826
+ * [has no effect on the state](./spec/acceptance/realtime/presence_spec.rb#L815)
825
827
  * it should behave like a public presence method
826
828
  * [raise an exception if the channel is detached](./spec/acceptance/realtime/presence_spec.rb#L54)
827
829
  * [raise an exception if the channel is failed](./spec/acceptance/realtime/presence_spec.rb#L66)
@@ -860,16 +862,16 @@ _(see [spec/acceptance/realtime/presence_spec.rb](./spec/acceptance/realtime/pre
860
862
  * if connection fails before success
861
863
  * [calls the Deferrable errback if channel is detached](./spec/acceptance/realtime/presence_spec.rb#L271)
862
864
  * #leave
863
- * [raises an exception if not entered](./spec/acceptance/realtime/presence_spec.rb#L921)
865
+ * [raises an exception if not entered](./spec/acceptance/realtime/presence_spec.rb#L914)
864
866
  * :data option
865
867
  * when set to a string
866
- * [emits the new data for the leave event](./spec/acceptance/realtime/presence_spec.rb#L866)
868
+ * [emits the new data for the leave event](./spec/acceptance/realtime/presence_spec.rb#L859)
867
869
  * when set to nil
868
- * [emits a nil value for the data attribute when leaving](./spec/acceptance/realtime/presence_spec.rb#L879)
869
- * when not passed as an argument
870
- * [emits the previously defined value as a convenience](./spec/acceptance/realtime/presence_spec.rb#L892)
870
+ * [emits the last value for the data attribute when leaving](./spec/acceptance/realtime/presence_spec.rb#L872)
871
+ * when not passed as an argument (i.e. nil)
872
+ * [emits the previous value for the data attribute when leaving](./spec/acceptance/realtime/presence_spec.rb#L885)
871
873
  * and sync is complete
872
- * [does not cache members that have left](./spec/acceptance/realtime/presence_spec.rb#L905)
874
+ * [does not cache members that have left](./spec/acceptance/realtime/presence_spec.rb#L898)
873
875
  * it should behave like a public presence method
874
876
  * [returns a SafeDeferrable that catches exceptions in callbacks and logs them](./spec/acceptance/realtime/presence_spec.rb#L234)
875
877
  * [allows a block to be passed in that is executed upon success](./spec/acceptance/realtime/presence_spec.rb#L241)
@@ -896,17 +898,17 @@ _(see [spec/acceptance/realtime/presence_spec.rb](./spec/acceptance/realtime/pre
896
898
  * if connection fails before success
897
899
  * [calls the Deferrable errback if channel is detached](./spec/acceptance/realtime/presence_spec.rb#L271)
898
900
  * :left event
899
- * [emits the data defined in enter](./spec/acceptance/realtime/presence_spec.rb#L930)
900
- * [emits the data defined in update](./spec/acceptance/realtime/presence_spec.rb#L941)
901
+ * [emits the data defined in enter](./spec/acceptance/realtime/presence_spec.rb#L923)
902
+ * [emits the data defined in update](./spec/acceptance/realtime/presence_spec.rb#L934)
901
903
  * entering/updating/leaving presence state on behalf of another client_id
902
904
  * #enter_client
903
905
  * multiple times on the same channel with different client_ids
904
- * [has no affect on the client's presence state and only enters on behalf of the provided client_id](./spec/acceptance/realtime/presence_spec.rb#L964)
905
- * [enters a channel and sets the data based on the provided :data option](./spec/acceptance/realtime/presence_spec.rb#L978)
906
+ * [has no affect on the client's presence state and only enters on behalf of the provided client_id](./spec/acceptance/realtime/presence_spec.rb#L957)
907
+ * [enters a channel and sets the data based on the provided :data option](./spec/acceptance/realtime/presence_spec.rb#L971)
906
908
  * message #connection_id
907
- * [matches the current client connection_id](./spec/acceptance/realtime/presence_spec.rb#L997)
909
+ * [matches the current client connection_id](./spec/acceptance/realtime/presence_spec.rb#L990)
908
910
  * without necessary capabilities to enter on behalf of another client
909
- * [calls the Deferrable errback on capabilities failure](./spec/acceptance/realtime/presence_spec.rb#L1017)
911
+ * [calls the Deferrable errback on capabilities failure](./spec/acceptance/realtime/presence_spec.rb#L1010)
910
912
  * it should behave like a public presence method
911
913
  * [raise an exception if the channel is detached](./spec/acceptance/realtime/presence_spec.rb#L54)
912
914
  * [raise an exception if the channel is failed](./spec/acceptance/realtime/presence_spec.rb#L66)
@@ -974,9 +976,9 @@ _(see [spec/acceptance/realtime/presence_spec.rb](./spec/acceptance/realtime/pre
974
976
  * [throws an exception](./spec/acceptance/realtime/presence_spec.rb#L403)
975
977
  * #update_client
976
978
  * multiple times on the same channel with different client_ids
977
- * [updates the data attribute for the member when :data option provided](./spec/acceptance/realtime/presence_spec.rb#L1031)
978
- * [updates the data attribute to null for the member when :data option is not provided (assumed null)](./spec/acceptance/realtime/presence_spec.rb#L1055)
979
- * [enters if not already entered](./spec/acceptance/realtime/presence_spec.rb#L1067)
979
+ * [updates the data attribute for the member when :data option provided](./spec/acceptance/realtime/presence_spec.rb#L1024)
980
+ * [updates the data attribute to null for the member when :data option is not provided (assumed null)](./spec/acceptance/realtime/presence_spec.rb#L1048)
981
+ * [enters if not already entered](./spec/acceptance/realtime/presence_spec.rb#L1060)
980
982
  * it should behave like a public presence method
981
983
  * [raise an exception if the channel is detached](./spec/acceptance/realtime/presence_spec.rb#L54)
982
984
  * [raise an exception if the channel is failed](./spec/acceptance/realtime/presence_spec.rb#L66)
@@ -1045,14 +1047,14 @@ _(see [spec/acceptance/realtime/presence_spec.rb](./spec/acceptance/realtime/pre
1045
1047
  * #leave_client
1046
1048
  * leaves a channel
1047
1049
  * multiple times on the same channel with different client_ids
1048
- * [emits the :leave event for each client_id](./spec/acceptance/realtime/presence_spec.rb#L1097)
1049
- * [succeeds if that client_id has not previously entered the channel](./spec/acceptance/realtime/presence_spec.rb#L1121)
1050
+ * [emits the :leave event for each client_id](./spec/acceptance/realtime/presence_spec.rb#L1090)
1051
+ * [succeeds if that client_id has not previously entered the channel](./spec/acceptance/realtime/presence_spec.rb#L1114)
1050
1052
  * with a new value in :data option
1051
- * [emits the leave event with the new data value](./spec/acceptance/realtime/presence_spec.rb#L1145)
1053
+ * [emits the leave event with the new data value](./spec/acceptance/realtime/presence_spec.rb#L1138)
1052
1054
  * with a nil value in :data option
1053
- * [emits the leave event with the previous value as a convenience](./spec/acceptance/realtime/presence_spec.rb#L1158)
1055
+ * [emits the leave event with the previous value as a convenience](./spec/acceptance/realtime/presence_spec.rb#L1151)
1054
1056
  * with no :data option
1055
- * [emits the leave event with the previous value as a convenience](./spec/acceptance/realtime/presence_spec.rb#L1171)
1057
+ * [emits the leave event with the previous value as a convenience](./spec/acceptance/realtime/presence_spec.rb#L1164)
1056
1058
  * it should behave like a public presence method
1057
1059
  * [raise an exception if the channel is detached](./spec/acceptance/realtime/presence_spec.rb#L54)
1058
1060
  * [raise an exception if the channel is failed](./spec/acceptance/realtime/presence_spec.rb#L66)
@@ -1119,60 +1121,60 @@ _(see [spec/acceptance/realtime/presence_spec.rb](./spec/acceptance/realtime/pre
1119
1121
  * and an empty client_id
1120
1122
  * [throws an exception](./spec/acceptance/realtime/presence_spec.rb#L403)
1121
1123
  * #get
1122
- * [returns a SafeDeferrable that catches exceptions in callbacks and logs them](./spec/acceptance/realtime/presence_spec.rb#L1190)
1123
- * [calls the Deferrable callback on success](./spec/acceptance/realtime/presence_spec.rb#L1195)
1124
- * [catches exceptions in the provided method block](./spec/acceptance/realtime/presence_spec.rb#L1202)
1125
- * [raise an exception if the channel is detached](./spec/acceptance/realtime/presence_spec.rb#L1209)
1126
- * [raise an exception if the channel is failed](./spec/acceptance/realtime/presence_spec.rb#L1219)
1127
- * [returns the current members on the channel](./spec/acceptance/realtime/presence_spec.rb#L1291)
1128
- * [filters by connection_id option if provided](./spec/acceptance/realtime/presence_spec.rb#L1306)
1129
- * [filters by client_id option if provided](./spec/acceptance/realtime/presence_spec.rb#L1328)
1130
- * [does not wait for SYNC to complete if :wait_for_sync option is false](./spec/acceptance/realtime/presence_spec.rb#L1352)
1124
+ * [returns a SafeDeferrable that catches exceptions in callbacks and logs them](./spec/acceptance/realtime/presence_spec.rb#L1183)
1125
+ * [calls the Deferrable callback on success](./spec/acceptance/realtime/presence_spec.rb#L1188)
1126
+ * [catches exceptions in the provided method block](./spec/acceptance/realtime/presence_spec.rb#L1195)
1127
+ * [raise an exception if the channel is detached](./spec/acceptance/realtime/presence_spec.rb#L1202)
1128
+ * [raise an exception if the channel is failed](./spec/acceptance/realtime/presence_spec.rb#L1212)
1129
+ * [returns the current members on the channel](./spec/acceptance/realtime/presence_spec.rb#L1292)
1130
+ * [filters by connection_id option if provided](./spec/acceptance/realtime/presence_spec.rb#L1307)
1131
+ * [filters by client_id option if provided](./spec/acceptance/realtime/presence_spec.rb#L1329)
1132
+ * [does not wait for SYNC to complete if :wait_for_sync option is false](./spec/acceptance/realtime/presence_spec.rb#L1353)
1131
1133
  * during a sync
1132
1134
  * when :wait_for_sync is true
1133
- * [fails if the connection fails](./spec/acceptance/realtime/presence_spec.rb#L1242)
1134
- * [fails if the channel is detached](./spec/acceptance/realtime/presence_spec.rb#L1265)
1135
+ * [fails if the connection fails](./spec/acceptance/realtime/presence_spec.rb#L1243)
1136
+ * [fails if the channel is detached](./spec/acceptance/realtime/presence_spec.rb#L1266)
1135
1137
  * when a member enters and then leaves
1136
- * [has no members](./spec/acceptance/realtime/presence_spec.rb#L1362)
1138
+ * [has no members](./spec/acceptance/realtime/presence_spec.rb#L1363)
1137
1139
  * with lots of members on different clients
1138
- * [returns a complete list of members on all clients](./spec/acceptance/realtime/presence_spec.rb#L1381)
1140
+ * [returns a complete list of members on all clients](./spec/acceptance/realtime/presence_spec.rb#L1382)
1139
1141
  * #subscribe
1140
- * [implicitly attaches](./spec/acceptance/realtime/presence_spec.rb#L1456)
1142
+ * [implicitly attaches](./spec/acceptance/realtime/presence_spec.rb#L1457)
1141
1143
  * with no arguments
1142
- * [calls the callback for all presence events](./spec/acceptance/realtime/presence_spec.rb#L1417)
1144
+ * [calls the callback for all presence events](./spec/acceptance/realtime/presence_spec.rb#L1418)
1143
1145
  * with event name
1144
- * [calls the callback for specified presence event](./spec/acceptance/realtime/presence_spec.rb#L1437)
1146
+ * [calls the callback for specified presence event](./spec/acceptance/realtime/presence_spec.rb#L1438)
1145
1147
  * #unsubscribe
1146
1148
  * with no arguments
1147
- * [removes the callback for all presence events](./spec/acceptance/realtime/presence_spec.rb#L1469)
1149
+ * [removes the callback for all presence events](./spec/acceptance/realtime/presence_spec.rb#L1470)
1148
1150
  * with event name
1149
- * [removes the callback for specified presence event](./spec/acceptance/realtime/presence_spec.rb#L1487)
1151
+ * [removes the callback for specified presence event](./spec/acceptance/realtime/presence_spec.rb#L1488)
1150
1152
  * REST #get
1151
- * [returns current members](./spec/acceptance/realtime/presence_spec.rb#L1506)
1152
- * [returns no members once left](./spec/acceptance/realtime/presence_spec.rb#L1519)
1153
+ * [returns current members](./spec/acceptance/realtime/presence_spec.rb#L1507)
1154
+ * [returns no members once left](./spec/acceptance/realtime/presence_spec.rb#L1520)
1153
1155
  * client_id with ASCII_8BIT
1154
1156
  * in connection set up
1155
- * [is converted into UTF_8](./spec/acceptance/realtime/presence_spec.rb#L1536)
1157
+ * [is converted into UTF_8](./spec/acceptance/realtime/presence_spec.rb#L1537)
1156
1158
  * in channel options
1157
- * [is converted into UTF_8](./spec/acceptance/realtime/presence_spec.rb#L1549)
1159
+ * [is converted into UTF_8](./spec/acceptance/realtime/presence_spec.rb#L1550)
1158
1160
  * encoding and decoding of presence message data
1159
- * [encrypts presence message data](./spec/acceptance/realtime/presence_spec.rb#L1573)
1161
+ * [encrypts presence message data](./spec/acceptance/realtime/presence_spec.rb#L1576)
1160
1162
  * #subscribe
1161
- * [emits decrypted enter events](./spec/acceptance/realtime/presence_spec.rb#L1592)
1162
- * [emits decrypted update events](./spec/acceptance/realtime/presence_spec.rb#L1604)
1163
- * [emits previously set data for leave events](./spec/acceptance/realtime/presence_spec.rb#L1618)
1163
+ * [emits decrypted enter events](./spec/acceptance/realtime/presence_spec.rb#L1595)
1164
+ * [emits decrypted update events](./spec/acceptance/realtime/presence_spec.rb#L1607)
1165
+ * [emits previously set data for leave events](./spec/acceptance/realtime/presence_spec.rb#L1621)
1164
1166
  * #get
1165
- * [returns a list of members with decrypted data](./spec/acceptance/realtime/presence_spec.rb#L1634)
1167
+ * [returns a list of members with decrypted data](./spec/acceptance/realtime/presence_spec.rb#L1637)
1166
1168
  * REST #get
1167
- * [returns a list of members with decrypted data](./spec/acceptance/realtime/presence_spec.rb#L1647)
1169
+ * [returns a list of members with decrypted data](./spec/acceptance/realtime/presence_spec.rb#L1650)
1168
1170
  * when cipher settings do not match publisher
1169
- * [delivers an unencoded presence message left with encoding value](./spec/acceptance/realtime/presence_spec.rb#L1662)
1170
- * [emits an error when cipher does not match and presence data cannot be decoded](./spec/acceptance/realtime/presence_spec.rb#L1675)
1171
+ * [delivers an unencoded presence message left with encoding value](./spec/acceptance/realtime/presence_spec.rb#L1665)
1172
+ * [emits an error when cipher does not match and presence data cannot be decoded](./spec/acceptance/realtime/presence_spec.rb#L1678)
1171
1173
  * leaving
1172
- * [expect :left event once underlying connection is closed](./spec/acceptance/realtime/presence_spec.rb#L1692)
1173
- * [expect :left event with client data from enter event](./spec/acceptance/realtime/presence_spec.rb#L1702)
1174
+ * [expect :left event once underlying connection is closed](./spec/acceptance/realtime/presence_spec.rb#L1695)
1175
+ * [expect :left event with client data from enter event](./spec/acceptance/realtime/presence_spec.rb#L1705)
1174
1176
  * connection failure mid-way through a large member sync
1175
- * [resumes the SYNC operation](./spec/acceptance/realtime/presence_spec.rb#L1721)
1177
+ * [resumes the SYNC operation](./spec/acceptance/realtime/presence_spec.rb#L1724)
1176
1178
 
1177
1179
  ### Ably::Realtime::Client#stats
1178
1180
  _(see [spec/acceptance/realtime/stats_spec.rb](./spec/acceptance/realtime/stats_spec.rb))_
@@ -1866,6 +1868,45 @@ _(see [spec/unit/models/channel_state_change_spec.rb](./spec/unit/models/channel
1866
1868
  * invalid attributes
1867
1869
  * [raises an argument error](./spec/unit/models/channel_state_change_spec.rb#L40)
1868
1870
 
1871
+ ### Ably::Models::CipherParams
1872
+ _(see [spec/unit/models/cipher_params_spec.rb](./spec/unit/models/cipher_params_spec.rb))_
1873
+ * :key missing from constructor
1874
+ * [raises an exception](./spec/unit/models/cipher_params_spec.rb#L8)
1875
+ * #key
1876
+ * with :key in constructor
1877
+ * as nil
1878
+ * [raises an exception](./spec/unit/models/cipher_params_spec.rb#L20)
1879
+ * as a base64 encoded string
1880
+ * [is a binary representation of the base64 encoded string](./spec/unit/models/cipher_params_spec.rb#L29)
1881
+ * as a URL safe base64 encoded string
1882
+ * [is a binary representation of the URL safe base64 encoded string](./spec/unit/models/cipher_params_spec.rb#L40)
1883
+ * as a binary encoded string
1884
+ * [contains the binary string](./spec/unit/models/cipher_params_spec.rb#L48)
1885
+ * with an incompatible :key_length constructor param
1886
+ * [raises an exception](./spec/unit/models/cipher_params_spec.rb#L58)
1887
+ * with an unsupported :key_length for aes-cbc encryption
1888
+ * [raises an exception](./spec/unit/models/cipher_params_spec.rb#L67)
1889
+ * with an invalid type
1890
+ * [raises an exception](./spec/unit/models/cipher_params_spec.rb#L76)
1891
+ * with specified params in the constructor
1892
+ * #cipher_type
1893
+ * [contains the complete algorithm string as an upper case string](./spec/unit/models/cipher_params_spec.rb#L88)
1894
+ * #mode
1895
+ * [contains the mode](./spec/unit/models/cipher_params_spec.rb#L94)
1896
+ * #algorithm
1897
+ * [contains the algorithm](./spec/unit/models/cipher_params_spec.rb#L100)
1898
+ * #key_length
1899
+ * [contains the key_length](./spec/unit/models/cipher_params_spec.rb#L106)
1900
+ * with combined param in the constructor
1901
+ * #cipher_type
1902
+ * [contains the complete algorithm string as an upper case string](./spec/unit/models/cipher_params_spec.rb#L117)
1903
+ * #mode
1904
+ * [contains the mode](./spec/unit/models/cipher_params_spec.rb#L123)
1905
+ * #algorithm
1906
+ * [contains the algorithm](./spec/unit/models/cipher_params_spec.rb#L129)
1907
+ * #key_length
1908
+ * [contains the key_length](./spec/unit/models/cipher_params_spec.rb#L135)
1909
+
1869
1910
  ### Ably::Models::ConnectionDetails
1870
1911
  _(see [spec/unit/models/connection_details_spec.rb](./spec/unit/models/connection_details_spec.rb))_
1871
1912
  * behaves like a model
@@ -1993,46 +2034,47 @@ _(see [spec/unit/models/message_encoders/cipher_spec.rb](./spec/unit/models/mess
1993
2034
  * message with another payload
1994
2035
  * [leaves the message data intact](./spec/unit/models/message_encoders/cipher_spec.rb#L72)
1995
2036
  * [leaves the encoding intact](./spec/unit/models/message_encoders/cipher_spec.rb#L76)
1996
- * with invalid channel_option cipher params
1997
- * [raise an exception](./spec/unit/models/message_encoders/cipher_spec.rb#L87)
1998
- * without any configured encryption
1999
- * [raise an exception](./spec/unit/models/message_encoders/cipher_spec.rb#L97)
2037
+ * 256 bit key
2038
+ * with invalid channel_option cipher params
2039
+ * [raise an exception](./spec/unit/models/message_encoders/cipher_spec.rb#L90)
2040
+ * without any configured encryption
2041
+ * [raise an exception](./spec/unit/models/message_encoders/cipher_spec.rb#L100)
2000
2042
  * with invalid cipher data
2001
- * [raise an exception](./spec/unit/models/message_encoders/cipher_spec.rb#L106)
2043
+ * [raise an exception](./spec/unit/models/message_encoders/cipher_spec.rb#L110)
2002
2044
  * with AES-256-CBC
2003
2045
  * message with cipher payload
2004
- * [decodes cipher](./spec/unit/models/message_encoders/cipher_spec.rb#L122)
2005
- * [strips the encoding](./spec/unit/models/message_encoders/cipher_spec.rb#L126)
2046
+ * [decodes cipher](./spec/unit/models/message_encoders/cipher_spec.rb#L127)
2047
+ * [strips the encoding](./spec/unit/models/message_encoders/cipher_spec.rb#L131)
2006
2048
  * #encode
2007
2049
  * with channel set up for AES-128-CBC
2008
2050
  * with encrypted set to true
2009
2051
  * message with string payload
2010
- * [encodes cipher](./spec/unit/models/message_encoders/cipher_spec.rb#L146)
2011
- * [adds the encoding with utf-8](./spec/unit/models/message_encoders/cipher_spec.rb#L151)
2052
+ * [encodes cipher](./spec/unit/models/message_encoders/cipher_spec.rb#L151)
2053
+ * [adds the encoding with utf-8](./spec/unit/models/message_encoders/cipher_spec.rb#L156)
2012
2054
  * message with binary payload
2013
- * [encodes cipher](./spec/unit/models/message_encoders/cipher_spec.rb#L159)
2014
- * [adds the encoding without utf-8 prefixed](./spec/unit/models/message_encoders/cipher_spec.rb#L164)
2015
- * [returns ASCII_8BIT encoded binary data](./spec/unit/models/message_encoders/cipher_spec.rb#L168)
2055
+ * [encodes cipher](./spec/unit/models/message_encoders/cipher_spec.rb#L164)
2056
+ * [adds the encoding without utf-8 prefixed](./spec/unit/models/message_encoders/cipher_spec.rb#L169)
2057
+ * [returns ASCII_8BIT encoded binary data](./spec/unit/models/message_encoders/cipher_spec.rb#L173)
2016
2058
  * message with json payload
2017
- * [encodes cipher](./spec/unit/models/message_encoders/cipher_spec.rb#L176)
2018
- * [adds the encoding with utf-8](./spec/unit/models/message_encoders/cipher_spec.rb#L181)
2059
+ * [encodes cipher](./spec/unit/models/message_encoders/cipher_spec.rb#L181)
2060
+ * [adds the encoding with utf-8](./spec/unit/models/message_encoders/cipher_spec.rb#L186)
2019
2061
  * message with existing cipher encoding before
2020
- * [leaves message intact as it is already encrypted](./spec/unit/models/message_encoders/cipher_spec.rb#L189)
2021
- * [leaves encoding intact](./spec/unit/models/message_encoders/cipher_spec.rb#L193)
2062
+ * [leaves message intact as it is already encrypted](./spec/unit/models/message_encoders/cipher_spec.rb#L194)
2063
+ * [leaves encoding intact](./spec/unit/models/message_encoders/cipher_spec.rb#L198)
2022
2064
  * with encryption set to to false
2023
- * [leaves message intact as encryption is not enable](./spec/unit/models/message_encoders/cipher_spec.rb#L202)
2024
- * [leaves encoding intact](./spec/unit/models/message_encoders/cipher_spec.rb#L206)
2065
+ * [leaves message intact as encryption is not enable](./spec/unit/models/message_encoders/cipher_spec.rb#L207)
2066
+ * [leaves encoding intact](./spec/unit/models/message_encoders/cipher_spec.rb#L211)
2025
2067
  * channel_option cipher params
2026
2068
  * have invalid key length
2027
- * [raise an exception](./spec/unit/models/message_encoders/cipher_spec.rb#L218)
2069
+ * [raise an exception](./spec/unit/models/message_encoders/cipher_spec.rb#L223)
2028
2070
  * have invalid algorithm
2029
- * [raise an exception](./spec/unit/models/message_encoders/cipher_spec.rb#L225)
2071
+ * [raise an exception](./spec/unit/models/message_encoders/cipher_spec.rb#L230)
2030
2072
  * have missing key
2031
- * [raise an exception](./spec/unit/models/message_encoders/cipher_spec.rb#L232)
2073
+ * [raise an exception](./spec/unit/models/message_encoders/cipher_spec.rb#L237)
2032
2074
  * with AES-256-CBC
2033
2075
  * message with cipher payload
2034
- * [decodes cipher](./spec/unit/models/message_encoders/cipher_spec.rb#L249)
2035
- * [strips the encoding](./spec/unit/models/message_encoders/cipher_spec.rb#L254)
2076
+ * [decodes cipher](./spec/unit/models/message_encoders/cipher_spec.rb#L255)
2077
+ * [strips the encoding](./spec/unit/models/message_encoders/cipher_spec.rb#L260)
2036
2078
 
2037
2079
  ### Ably::Models::MessageEncoders::Json
2038
2080
  _(see [spec/unit/models/message_encoders/json_spec.rb](./spec/unit/models/message_encoders/json_spec.rb))_
@@ -2040,31 +2082,37 @@ _(see [spec/unit/models/message_encoders/json_spec.rb](./spec/unit/models/messag
2040
2082
  * message with json payload
2041
2083
  * [decodes json](./spec/unit/models/message_encoders/json_spec.rb#L24)
2042
2084
  * [strips the encoding](./spec/unit/models/message_encoders/json_spec.rb#L28)
2043
- * message with json payload before other payloads
2085
+ * message with json payload in camelCase
2044
2086
  * [decodes json](./spec/unit/models/message_encoders/json_spec.rb#L36)
2045
2087
  * [strips the encoding](./spec/unit/models/message_encoders/json_spec.rb#L40)
2088
+ * message with json payload before other payloads
2089
+ * [decodes json](./spec/unit/models/message_encoders/json_spec.rb#L48)
2090
+ * [strips the encoding](./spec/unit/models/message_encoders/json_spec.rb#L52)
2046
2091
  * message with another payload
2047
- * [leaves the message data intact](./spec/unit/models/message_encoders/json_spec.rb#L48)
2048
- * [leaves the encoding intact](./spec/unit/models/message_encoders/json_spec.rb#L52)
2092
+ * [leaves the message data intact](./spec/unit/models/message_encoders/json_spec.rb#L60)
2093
+ * [leaves the encoding intact](./spec/unit/models/message_encoders/json_spec.rb#L64)
2049
2094
  * #encode
2050
2095
  * message with hash payload
2051
- * [encodes hash payload data as json](./spec/unit/models/message_encoders/json_spec.rb#L66)
2052
- * [adds the encoding](./spec/unit/models/message_encoders/json_spec.rb#L70)
2053
- * already encoded message with hash payload
2054
2096
  * [encodes hash payload data as json](./spec/unit/models/message_encoders/json_spec.rb#L78)
2055
2097
  * [adds the encoding](./spec/unit/models/message_encoders/json_spec.rb#L82)
2056
- * message with Array payload
2057
- * [encodes Array payload data as json](./spec/unit/models/message_encoders/json_spec.rb#L90)
2098
+ * message with hash payload and underscore case keys
2099
+ * [encodes hash payload data as json and leaves underscore case in tact](./spec/unit/models/message_encoders/json_spec.rb#L90)
2058
2100
  * [adds the encoding](./spec/unit/models/message_encoders/json_spec.rb#L94)
2101
+ * already encoded message with hash payload
2102
+ * [encodes hash payload data as json](./spec/unit/models/message_encoders/json_spec.rb#L102)
2103
+ * [adds the encoding](./spec/unit/models/message_encoders/json_spec.rb#L106)
2104
+ * message with Array payload
2105
+ * [encodes Array payload data as json](./spec/unit/models/message_encoders/json_spec.rb#L114)
2106
+ * [adds the encoding](./spec/unit/models/message_encoders/json_spec.rb#L118)
2059
2107
  * message with UTF-8 payload
2060
- * [leaves the message data intact](./spec/unit/models/message_encoders/json_spec.rb#L102)
2061
- * [leaves the encoding intact](./spec/unit/models/message_encoders/json_spec.rb#L106)
2062
- * message with nil payload
2063
- * [leaves the message data intact](./spec/unit/models/message_encoders/json_spec.rb#L114)
2064
- * [leaves the encoding intact](./spec/unit/models/message_encoders/json_spec.rb#L118)
2065
- * message with no data payload
2066
2108
  * [leaves the message data intact](./spec/unit/models/message_encoders/json_spec.rb#L126)
2067
2109
  * [leaves the encoding intact](./spec/unit/models/message_encoders/json_spec.rb#L130)
2110
+ * message with nil payload
2111
+ * [leaves the message data intact](./spec/unit/models/message_encoders/json_spec.rb#L138)
2112
+ * [leaves the encoding intact](./spec/unit/models/message_encoders/json_spec.rb#L142)
2113
+ * message with no data payload
2114
+ * [leaves the message data intact](./spec/unit/models/message_encoders/json_spec.rb#L150)
2115
+ * [leaves the encoding intact](./spec/unit/models/message_encoders/json_spec.rb#L154)
2068
2116
 
2069
2117
  ### Ably::Models::MessageEncoders::Utf8
2070
2118
  _(see [spec/unit/models/message_encoders/utf8_spec.rb](./spec/unit/models/message_encoders/utf8_spec.rb))_
@@ -2512,29 +2560,30 @@ _(see [spec/unit/models/token_details_spec.rb](./spec/unit/models/token_details_
2512
2560
  * attributes
2513
2561
  * #capability
2514
2562
  * [retrieves attribute :capability as parsed JSON](./spec/unit/models/token_details_spec.rb#L21)
2515
- * #issued with :issued option as milliseconds in constructor
2516
- * [retrieves attribute :issued as Time](./spec/unit/models/token_details_spec.rb#L31)
2517
- * #issued with :issued option as a Time in constructor
2518
- * [retrieves attribute :issued as Time](./spec/unit/models/token_details_spec.rb#L40)
2519
- * #issued when converted to JSON
2520
- * [is in milliseconds](./spec/unit/models/token_details_spec.rb#L49)
2521
- * #expires with :expires option as milliseconds in constructor
2522
- * [retrieves attribute :expires as Time](./spec/unit/models/token_details_spec.rb#L31)
2523
- * #expires with :expires option as a Time in constructor
2524
- * [retrieves attribute :expires as Time](./spec/unit/models/token_details_spec.rb#L40)
2525
- * #expires when converted to JSON
2526
- * [is in milliseconds](./spec/unit/models/token_details_spec.rb#L49)
2563
+ *
2564
+ * #issued with :issued option as milliseconds in constructor
2565
+ * [retrieves attribute :issued as Time](./spec/unit/models/token_details_spec.rb#L32)
2566
+ * #issued with :issued option as a Time in constructor
2567
+ * [retrieves attribute :issued as Time](./spec/unit/models/token_details_spec.rb#L41)
2568
+ * #issued when converted to JSON
2569
+ * [is in milliseconds](./spec/unit/models/token_details_spec.rb#L50)
2570
+ * #expires with :expires option as milliseconds in constructor
2571
+ * [retrieves attribute :expires as Time](./spec/unit/models/token_details_spec.rb#L32)
2572
+ * #expires with :expires option as a Time in constructor
2573
+ * [retrieves attribute :expires as Time](./spec/unit/models/token_details_spec.rb#L41)
2574
+ * #expires when converted to JSON
2575
+ * [is in milliseconds](./spec/unit/models/token_details_spec.rb#L50)
2527
2576
  * #expired?
2528
2577
  * once grace period buffer has passed
2529
- * [is true](./spec/unit/models/token_details_spec.rb#L61)
2578
+ * [is true](./spec/unit/models/token_details_spec.rb#L63)
2530
2579
  * within grace period buffer
2531
- * [is false](./spec/unit/models/token_details_spec.rb#L69)
2580
+ * [is false](./spec/unit/models/token_details_spec.rb#L71)
2532
2581
  * when expires is not available (i.e. string tokens)
2533
- * [is always false](./spec/unit/models/token_details_spec.rb#L77)
2582
+ * [is always false](./spec/unit/models/token_details_spec.rb#L79)
2534
2583
  * ==
2535
- * [is true when attributes are the same](./spec/unit/models/token_details_spec.rb#L87)
2536
- * [is false when attributes are not the same](./spec/unit/models/token_details_spec.rb#L92)
2537
- * [is false when class type differs](./spec/unit/models/token_details_spec.rb#L96)
2584
+ * [is true when attributes are the same](./spec/unit/models/token_details_spec.rb#L89)
2585
+ * [is false when attributes are not the same](./spec/unit/models/token_details_spec.rb#L94)
2586
+ * [is false when class type differs](./spec/unit/models/token_details_spec.rb#L98)
2538
2587
 
2539
2588
  ### Ably::Models::TokenRequest
2540
2589
  _(see [spec/unit/models/token_request_spec.rb](./spec/unit/models/token_request_spec.rb))_
@@ -2960,26 +3009,34 @@ _(see [spec/unit/rest/rest_spec.rb](./spec/unit/rest/rest_spec.rb))_
2960
3009
  ### Ably::Util::Crypto
2961
3010
  _(see [spec/unit/util/crypto_spec.rb](./spec/unit/util/crypto_spec.rb))_
2962
3011
  * defaults
2963
- * [match other client libraries](./spec/unit/util/crypto_spec.rb#L18)
3012
+ * [match other client libraries](./spec/unit/util/crypto_spec.rb#L19)
2964
3013
  * get_default_params
2965
- * [uses the defaults and generates a key if not provided](./spec/unit/util/crypto_spec.rb#L25)
2966
- * [uses the defaults and sets the key size when key is provided](./spec/unit/util/crypto_spec.rb#L32)
3014
+ * with just a :key param
3015
+ * [uses the defaults](./spec/unit/util/crypto_spec.rb#L29)
3016
+ * [contains the provided key](./spec/unit/util/crypto_spec.rb#L35)
3017
+ * [returns a CipherParams object](./spec/unit/util/crypto_spec.rb#L39)
3018
+ * without a :key param
3019
+ * [raises an exception](./spec/unit/util/crypto_spec.rb#L47)
3020
+ * with a base64-encoded :key param
3021
+ * [converts the key to binary](./spec/unit/util/crypto_spec.rb#L55)
3022
+ * with provided params
3023
+ * [overrides the defaults](./spec/unit/util/crypto_spec.rb#L67)
2967
3024
  * encrypts & decrypt
2968
- * [#encrypt encrypts a string](./spec/unit/util/crypto_spec.rb#L46)
2969
- * [#decrypt decrypts a string](./spec/unit/util/crypto_spec.rb#L51)
3025
+ * [#encrypt encrypts a string](./spec/unit/util/crypto_spec.rb#L79)
3026
+ * [#decrypt decrypts a string](./spec/unit/util/crypto_spec.rb#L84)
2970
3027
  * encrypting an empty string
2971
- * [raises an ArgumentError](./spec/unit/util/crypto_spec.rb#L60)
3028
+ * [raises an ArgumentError](./spec/unit/util/crypto_spec.rb#L93)
2972
3029
  * using shared client lib fixture data
2973
3030
  * with AES-128-CBC
2974
3031
  * behaves like an Ably encrypter and decrypter
2975
3032
  * text payload
2976
- * [encrypts exactly the same binary data as other client libraries](./spec/unit/util/crypto_spec.rb#L83)
2977
- * [decrypts exactly the same binary data as other client libraries](./spec/unit/util/crypto_spec.rb#L87)
3033
+ * [encrypts exactly the same binary data as other client libraries](./spec/unit/util/crypto_spec.rb#L116)
3034
+ * [decrypts exactly the same binary data as other client libraries](./spec/unit/util/crypto_spec.rb#L120)
2978
3035
  * with AES-256-CBC
2979
3036
  * behaves like an Ably encrypter and decrypter
2980
3037
  * text payload
2981
- * [encrypts exactly the same binary data as other client libraries](./spec/unit/util/crypto_spec.rb#L83)
2982
- * [decrypts exactly the same binary data as other client libraries](./spec/unit/util/crypto_spec.rb#L87)
3038
+ * [encrypts exactly the same binary data as other client libraries](./spec/unit/util/crypto_spec.rb#L116)
3039
+ * [decrypts exactly the same binary data as other client libraries](./spec/unit/util/crypto_spec.rb#L120)
2983
3040
 
2984
3041
  ### Ably::Util::PubSub
2985
3042
  _(see [spec/unit/util/pub_sub_spec.rb](./spec/unit/util/pub_sub_spec.rb))_
@@ -2995,6 +3052,6 @@ _(see [spec/unit/util/pub_sub_spec.rb](./spec/unit/util/pub_sub_spec.rb))_
2995
3052
 
2996
3053
  ## Test summary
2997
3054
 
2998
- * Passing tests: 1467
3055
+ * Passing tests: 1492
2999
3056
  * Pending tests: 6
3000
3057
  * Failing tests: 0