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
@@ -65,32 +65,32 @@ describe Ably::Rest::Channel, 'messages' do
65
65
  context 'Integer' do
66
66
  let(:data) { 1 }
67
67
 
68
- it 'is raises an UnsupportedDataTypeError 40011 exception' do
69
- expect { channel.publish 'event', data }.to raise_error(Ably::Exceptions::UnsupportedDataTypeError)
68
+ it 'is raises an UnsupportedDataType 40011 exception' do
69
+ expect { channel.publish 'event', data }.to raise_error(Ably::Exceptions::UnsupportedDataType)
70
70
  end
71
71
  end
72
72
 
73
73
  context 'Float' do
74
74
  let(:data) { 1.1 }
75
75
 
76
- it 'is raises an UnsupportedDataTypeError 40011 exception' do
77
- expect { channel.publish 'event', data }.to raise_error(Ably::Exceptions::UnsupportedDataTypeError)
76
+ it 'is raises an UnsupportedDataType 40011 exception' do
77
+ expect { channel.publish 'event', data }.to raise_error(Ably::Exceptions::UnsupportedDataType)
78
78
  end
79
79
  end
80
80
 
81
81
  context 'Boolean' do
82
82
  let(:data) { true }
83
83
 
84
- it 'is raises an UnsupportedDataTypeError 40011 exception' do
85
- expect { channel.publish 'event', data }.to raise_error(Ably::Exceptions::UnsupportedDataTypeError)
84
+ it 'is raises an UnsupportedDataType 40011 exception' do
85
+ expect { channel.publish 'event', data }.to raise_error(Ably::Exceptions::UnsupportedDataType)
86
86
  end
87
87
  end
88
88
 
89
89
  context 'False' do
90
90
  let(:data) { false }
91
91
 
92
- it 'is raises an UnsupportedDataTypeError 40011 exception' do
93
- expect { channel.publish 'event', data }.to raise_error(Ably::Exceptions::UnsupportedDataTypeError)
92
+ it 'is raises an UnsupportedDataType 40011 exception' do
93
+ expect { channel.publish 'event', data }.to raise_error(Ably::Exceptions::UnsupportedDataType)
94
94
  end
95
95
  end
96
96
  end
@@ -39,10 +39,12 @@ describe Ably::Rest::Presence do
39
39
  let(:presence_page) { fixtures_channel.presence.get }
40
40
 
41
41
  it 'returns current members on the channel with their action set to :present' do
42
+ expect(presence_page).to be_a(Ably::Models::PaginatedResult)
42
43
  expect(presence_page.items.size).to eql(fixtures.count)
43
44
 
44
45
  non_encoded_fixtures.each do |fixture|
45
46
  presence_message = presence_page.items.find { |client| client.client_id == fixture[:client_id] }
47
+ expect(presence_message).to be_a(Ably::Models::PresenceMessage)
46
48
  expect(presence_message.data).to eq(fixture[:data])
47
49
  expect(presence_message.action).to eq(:present)
48
50
  end
@@ -54,27 +56,87 @@ describe Ably::Rest::Presence do
54
56
 
55
57
  it 'returns a paged response limiting number of members per page' do
56
58
  expect(presence_page.items.size).to eql(page_size)
57
- # TODO: To be enabled once Realtime Presence issue #164 is resolved
58
- # expect(presence_page).to be_first
59
59
  next_page = presence_page.next
60
60
  expect(next_page.items.size).to eql(page_size)
61
61
  expect(next_page).to be_last
62
62
  end
63
63
  end
64
+
65
+ context 'default :limit', webmock: true do
66
+ let(:query_options) do
67
+ {
68
+ limit: 100
69
+ }
70
+ end
71
+ let(:endpoint) do
72
+ client.endpoint.tap do |client_end_point|
73
+ client_end_point.user = key_name
74
+ client_end_point.password = key_secret
75
+ end
76
+ end
77
+ let!(:get_stub) {
78
+ query_params = query_options.map { |k, v| "#{k}=#{v}" }.join('&')
79
+ stub_request(:get, "#{endpoint}/channels/#{CGI.escape(channel_name)}/presence?#{query_params}").
80
+ to_return(:body => '{}', :headers => { 'Content-Type' => 'application/json' })
81
+ }
82
+ let(:channel_name) { random_str }
83
+ let(:channel) { client.channels.get(channel_name) }
84
+
85
+ before do
86
+ channel.presence.get
87
+ end
88
+
89
+ it 'defaults to a limit of 100' do
90
+ expect(get_stub).to have_been_requested
91
+ end
92
+ end
93
+
94
+ context 'with :client_id option' do
95
+ let(:client_id) { non_encoded_fixtures.first[:client_id] }
96
+ let(:presence_page) { fixtures_channel.presence.get(client_id: client_id) }
97
+
98
+ it 'returns a list members filtered by the provided client ID' do
99
+ pending 'not implemented in the REST API yet' # TODO realtime/issues/243
100
+ expect(presence_page.items.count).to eql(1)
101
+ expect(presence_page.items.first.client_id).to eql(client_id)
102
+ end
103
+ end
104
+
105
+ context 'with :connection_id option' do
106
+ let(:connection_id) { fixtures_channel.presence.get.first.connection_id }
107
+ let(:presence_page) { fixtures_channel.presence.get(connection_id: connection_id) }
108
+
109
+ it 'returns a list members filtered by the provided connection ID' do
110
+ pending 'not implemented in the REST API yet' # TODO realtime/issues/243
111
+ expect(presence_page.items.count).to eql(1)
112
+ expect(presence_page.items.first.connetion_id).to eql(connetion_id)
113
+ end
114
+ end
64
115
  end
65
116
 
66
117
  describe '#history' do
67
118
  let(:history_page) { fixtures_channel.presence.history }
68
119
 
69
120
  it 'returns recent presence activity' do
121
+ expect(history_page).to be_a(Ably::Models::PaginatedResult)
70
122
  expect(history_page.items.size).to eql(fixtures.count)
71
123
 
72
124
  non_encoded_fixtures.each do |fixture|
73
125
  presence_message = history_page.items.find { |client| client.client_id == fixture['clientId'] }
126
+ expect(presence_message).to be_a(Ably::Models::PresenceMessage)
74
127
  expect(presence_message.data).to eq(fixture[:data])
75
128
  end
76
129
  end
77
130
 
131
+ context 'default behaviour' do
132
+ let(:default_page) { fixtures_channel.presence.history }
133
+ let(:backwards_page) { fixtures_channel.presence.history(direction: :backwards) }
134
+
135
+ it 'uses backwards direction' do
136
+ expect(default_page.items).to eq(backwards_page.items)
137
+ end
138
+ end
139
+
78
140
  context 'with options' do
79
141
  let(:page_size) { 3 }
80
142
 
@@ -112,7 +174,7 @@ describe Ably::Rest::Presence do
112
174
  end
113
175
 
114
176
  describe '#history' do
115
- context 'with time range options' do
177
+ context 'with options' do
116
178
  let(:channel_name) { "persisted:#{random_str(4)}" }
117
179
  let(:presence) { client.channel(channel_name).presence }
118
180
  let(:user) { 'appid.keyuid' }
@@ -126,44 +188,93 @@ describe Ably::Rest::Presence do
126
188
  let(:client) do
127
189
  Ably::Rest::Client.new(key: "#{user}:#{secret}")
128
190
  end
129
- let(:default_options) do
191
+ let(:history_options) do
130
192
  {
131
193
  direction: :backwards,
132
194
  limit: 100
133
195
  }
134
196
  end
135
197
 
136
- [:start, :end].each do |option|
137
- describe ":#{option}", :webmock do
138
- let!(:history_stub) {
139
- query_params = default_options.merge(option => milliseconds).map { |k, v| "#{k}=#{v}" }.join('&')
140
- stub_request(:get, "#{endpoint}/channels/#{CGI.escape(channel_name)}/presence/history?#{query_params}").
141
- to_return(:body => '{}', :headers => { 'Content-Type' => 'application/json' })
142
- }
198
+ context 'limit options', :webmock do
199
+ let!(:history_stub) {
200
+ query_params = history_options.map { |k, v| "#{k}=#{v}" }.join('&')
201
+ stub_request(:get, "#{endpoint}/channels/#{CGI.escape(channel_name)}/presence/history?#{query_params}").
202
+ to_return(:body => '{}', :headers => { 'Content-Type' => 'application/json' })
203
+ }
143
204
 
144
- before do
145
- presence.history(options)
205
+ before do
206
+ presence.history(history_options)
207
+ end
208
+
209
+ context 'default' do
210
+ it 'is set to 100' do
211
+ expect(history_stub).to have_been_requested
146
212
  end
213
+ end
147
214
 
148
- context 'with milliseconds since epoch value' do
149
- let(:milliseconds) { as_since_epoch(Time.now) }
150
- let(:options) { { option => milliseconds } }
215
+ context 'set to 1000' do
216
+ let(:history_options) do
217
+ {
218
+ direction: :backwards,
219
+ limit: 1000
220
+ }
221
+ end
151
222
 
152
- it 'uses this value in the history request' do
153
- expect(history_stub).to have_been_requested
154
- end
223
+ it 'is passes the limit query param value 1000' do
224
+ expect(history_stub).to have_been_requested
155
225
  end
226
+ end
227
+ end
228
+
229
+ context 'with time range options' do
230
+ [:start, :end].each do |option|
231
+ describe ":#{option}", :webmock do
232
+ let(:history_options) {
233
+ {
234
+ direction: :backwards,
235
+ limit: 100,
236
+ option => milliseconds
237
+ }
238
+ }
239
+ let!(:history_stub) {
240
+ query_params = history_options.map { |k, v| "#{k}=#{v}" }.join('&')
241
+ stub_request(:get, "#{endpoint}/channels/#{CGI.escape(channel_name)}/presence/history?#{query_params}").
242
+ to_return(:body => '{}', :headers => { 'Content-Type' => 'application/json' })
243
+ }
244
+
245
+ before do
246
+ presence.history(history_options)
247
+ end
248
+
249
+ context 'with milliseconds since epoch value' do
250
+ let(:milliseconds) { as_since_epoch(Time.now) }
251
+ let(:options) { { option => milliseconds } }
252
+
253
+ it 'uses this value in the history request' do
254
+ expect(history_stub).to have_been_requested
255
+ end
256
+ end
156
257
 
157
- context 'with Time object value' do
158
- let(:time) { Time.now }
159
- let(:milliseconds) { as_since_epoch(time) }
160
- let(:options) { { option => time } }
258
+ context 'with Time object value' do
259
+ let(:time) { Time.now }
260
+ let(:milliseconds) { as_since_epoch(time) }
261
+ let(:options) { { option => time } }
161
262
 
162
- it 'converts the value to milliseconds since epoch in the hisotry request' do
163
- expect(history_stub).to have_been_requested
263
+ it 'converts the value to milliseconds since epoch in the hisotry request' do
264
+ expect(history_stub).to have_been_requested
265
+ end
164
266
  end
165
267
  end
166
268
  end
269
+
270
+ context 'when argument start is after end' do
271
+ let(:presence) { client.channel(random_str).presence }
272
+ let(:subject) { presence.history(start: as_since_epoch(Time.now), end: Time.now - 120) }
273
+
274
+ it 'should raise an exception' do
275
+ expect { subject.items }.to raise_error ArgumentError
276
+ end
277
+ end
167
278
  end
168
279
  end
169
280
  end
@@ -7,6 +7,11 @@ describe Ably::Rest::Client, '#stats' do
7
7
  LAST_YEAR = Time.now.year - 1
8
8
  LAST_INTERVAL = Time.new(LAST_YEAR, 2, 3, 15, 5, 0) # 3rd Feb 20(x) 16:05:00
9
9
 
10
+ # Ensure metrics in previous year do not impact on tests for last year
11
+ PREVIOUS_YEAR = Time.now.year - 2
12
+ PREVIOUS_INTERVAL = Time.new(PREVIOUS_YEAR, 2, 3, 15, 5, 0)
13
+ PREVIOUS_YEAR_STATS = 120
14
+
10
15
  STATS_FIXTURES = [
11
16
  {
12
17
  intervalId: Ably::Models::Stats.to_interval_id(LAST_INTERVAL - 120, :minute),
@@ -30,19 +35,39 @@ describe Ably::Rest::Client, '#stats' do
30
35
  }
31
36
  ]
32
37
 
38
+ PREVIOUS_YEAR_STATS_FIXTURES = PREVIOUS_YEAR_STATS.times.map do |index|
39
+ {
40
+ intervalId: Ably::Models::Stats.to_interval_id(PREVIOUS_INTERVAL - (index * 60), :minute),
41
+ inbound: { realtime: { messages: { count: index } } }
42
+ }
43
+ end
44
+
33
45
  before(:context) do
34
46
  reload_test_app # ensure no previous stats interfere
35
- TestApp.instance.create_test_stats(STATS_FIXTURES)
47
+ TestApp.instance.create_test_stats(STATS_FIXTURES + PREVIOUS_YEAR_STATS_FIXTURES)
36
48
  end
37
49
 
38
50
  vary_by_protocol do
39
51
  let(:client) { Ably::Rest::Client.new(key: api_key, environment: environment, protocol: protocol) }
40
52
 
41
53
  describe 'fetching application stats' do
54
+ it 'returns a PaginatedResult object' do
55
+ expect(client.stats).to be_kind_of(Ably::Models::PaginatedResult)
56
+ end
57
+
42
58
  context 'by minute' do
43
59
  let(:first_inbound_realtime_count) { STATS_FIXTURES.first[:inbound][:realtime][:messages][:count] }
44
60
  let(:last_inbound_realtime_count) { STATS_FIXTURES.last[:inbound][:realtime][:messages][:count] }
45
61
 
62
+ context 'with no options' do
63
+ let(:subject) { client.stats(end: LAST_INTERVAL) } # end is needed to ensure no other tests have effected the stats
64
+ let(:stat) { subject.items.first }
65
+
66
+ it 'uses the minute interval by default' do
67
+ expect(stat.interval_granularity).to eq(:minute)
68
+ end
69
+ end
70
+
46
71
  context 'with :from set to last interval and :limit set to 1' do
47
72
  let(:subject) { client.stats(start: as_since_epoch(LAST_INTERVAL), end: LAST_INTERVAL, unit: :minute, limit: 1) }
48
73
  let(:stat) { subject.items.first }
@@ -124,7 +149,6 @@ describe Ably::Rest::Client, '#stats' do
124
149
  end
125
150
 
126
151
  it 'returns 3 pages of stats' do
127
- expect(subject).to be_first
128
152
  expect(subject).to_not be_last
129
153
  page3 = subject.next.next
130
154
  expect(page3).to be_last
@@ -133,7 +157,7 @@ describe Ably::Rest::Client, '#stats' do
133
157
  end
134
158
 
135
159
  context 'with :end set to last interval, :limit set to 1 and direction :backwards' do
136
- let(:subject) { client.stats(:end => as_since_epoch(LAST_INTERVAL), end: LAST_INTERVAL, unit: :minute, direction: :backwards, limit: 1) }
160
+ let(:subject) { client.stats(end: LAST_INTERVAL, unit: :minute, direction: :backwards, limit: 1) }
137
161
  let(:stat) { subject.items.first }
138
162
 
139
163
  it 'returns the 3rd interval stats first as stats are provided backwards from :end' do
@@ -141,12 +165,36 @@ describe Ably::Rest::Client, '#stats' do
141
165
  end
142
166
 
143
167
  it 'returns 3 pages of stats' do
144
- expect(subject).to be_first
145
168
  expect(subject).to_not be_last
146
169
  page3 = subject.next.next
147
170
  expect(page3.items.first.inbound.realtime.all.count).to eql(first_inbound_realtime_count)
148
171
  end
149
172
  end
173
+
174
+ context 'with :end set to last interval and :limit set to 3 to ensure only last years stats are included' do
175
+ let(:subject) { client.stats(end: LAST_INTERVAL, unit: :minute, limit: 3) }
176
+ let(:stats) { subject.items }
177
+
178
+ context 'the REST API' do
179
+ it 'defaults to direction :backwards' do
180
+ expect(stats.first.inbound.realtime.messages.count).to eql(70) # current minute
181
+ expect(stats.last.inbound.realtime.messages.count).to eql(50) # 2 minutes back
182
+ end
183
+ end
184
+ end
185
+
186
+ context 'with :end set to previous year interval' do
187
+ let(:subject) { client.stats(end: PREVIOUS_INTERVAL, unit: :minute) }
188
+ let(:stats) { subject.items }
189
+
190
+ context 'the REST API' do
191
+ it 'defaults to 100 items for pagination' do
192
+ expect(stats.count).to eql(100)
193
+ next_page_of_stats = subject.next.items
194
+ expect(next_page_of_stats.count).to eql(PREVIOUS_YEAR_STATS - 100)
195
+ end
196
+ end
197
+ end
150
198
  end
151
199
 
152
200
  [:hour, :day, :month].each do |interval|
@@ -172,6 +220,14 @@ describe Ably::Rest::Client, '#stats' do
172
220
  end
173
221
  end
174
222
  end
223
+
224
+ context 'when argument start is after end' do
225
+ let(:subject) { client.stats(start: as_since_epoch(LAST_INTERVAL), end: LAST_INTERVAL - 120, unit: :minute) }
226
+
227
+ it 'should raise an exception' do
228
+ expect { subject.items }.to raise_error ArgumentError
229
+ end
230
+ end
175
231
  end
176
232
  end
177
233
  end
@@ -87,12 +87,16 @@ shared_examples 'a client initializer' do
87
87
  it 'connects to the Ably service' do
88
88
  expect { subject }.to_not raise_error
89
89
  end
90
+
91
+ it 'uses basic auth' do
92
+ expect(subject.auth).to be_using_basic_auth
93
+ end
90
94
  end
91
95
 
92
96
  context 'key_name and key_secret', api_private: true do
93
97
  let(:client_options) { { key_name: 'id', key_secret: 'secret' } }
94
98
 
95
- it 'constructs an key' do
99
+ it 'constructs a key' do
96
100
  expect(subject.auth.key).to eql('id:secret')
97
101
  end
98
102
  end
@@ -111,6 +115,10 @@ shared_examples 'a client initializer' do
111
115
  it 'sets the key_secret' do
112
116
  expect(subject.auth.key_secret).to eql('secret')
113
117
  end
118
+
119
+ it 'uses basic auth' do
120
+ expect(subject.auth).to be_using_basic_auth
121
+ end
114
122
  end
115
123
 
116
124
  context 'with a string token key instead of options hash' do
@@ -137,6 +145,15 @@ shared_examples 'a client initializer' do
137
145
  end
138
146
  end
139
147
 
148
+ context 'with token_params' do
149
+ let(:client_options) { { token_params: { ttl: 777, client_id: 'john' }, token: 'token' } }
150
+
151
+ it 'configures the default token_params' do
152
+ expect(subject.auth.token_params.fetch(:ttl)).to eql(777)
153
+ expect(subject.auth.token_params.fetch(:client_id)).to eql('john')
154
+ end
155
+ end
156
+
140
157
  context 'endpoint' do
141
158
  it 'defaults to production' do
142
159
  expect(subject.endpoint.to_s).to eql("#{protocol}s://#{subdomain}.ably.io")
@@ -149,6 +166,40 @@ shared_examples 'a client initializer' do
149
166
  expect(subject.endpoint.to_s).to eql("#{protocol}s://sandbox-#{subdomain}.ably.io")
150
167
  end
151
168
  end
169
+
170
+ context 'with rest_host option' do
171
+ let(:client_options) { default_options.merge(rest_host: 'custom-rest.host.com') }
172
+
173
+ it 'uses an alternate endpoint for REST clients' do
174
+ skip 'does not apply as testing a Realtime client' unless rest?
175
+ expect(subject.endpoint.to_s).to eql("#{protocol}s://custom-rest.host.com")
176
+ end
177
+ end
178
+
179
+ context 'with realtime_host option' do
180
+ let(:client_options) { default_options.merge(realtime_host: 'custom-realtime.host.com') }
181
+
182
+ it 'uses an alternate endpoint for Realtime clients' do
183
+ skip 'does not apply as testing a REST client' if rest?
184
+ expect(subject.endpoint.to_s).to eql("#{protocol}s://custom-realtime.host.com")
185
+ end
186
+ end
187
+
188
+ context 'with port option and non-TLS connections' do
189
+ let(:client_options) { default_options.merge(port: 999, tls: false) }
190
+
191
+ it 'uses the custom port for non-TLS requests' do
192
+ expect(subject.endpoint.to_s).to include(":999")
193
+ end
194
+ end
195
+
196
+ context 'with tls_port option and a TLS connection' do
197
+ let(:client_options) { default_options.merge(tls_port: 666, tls: true) }
198
+
199
+ it 'uses the custom port for TLS requests' do
200
+ expect(subject.endpoint.to_s).to include(":666")
201
+ end
202
+ end
152
203
  end
153
204
 
154
205
  context 'tls' do
@@ -175,8 +226,8 @@ shared_examples 'a client initializer' do
175
226
  expect(subject.logger.logger).to be_a(::Logger)
176
227
  end
177
228
 
178
- it 'specifies Logger::ERROR log level' do
179
- expect(subject.logger.log_level).to eql(::Logger::ERROR)
229
+ it 'specifies Logger::WARN log level' do
230
+ expect(subject.logger.log_level).to eql(::Logger::WARN)
180
231
  end
181
232
  end
182
233