ably-rest 1.1.0 → 1.1.2

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 (33) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +9 -1
  3. data/ably-rest.gemspec +1 -1
  4. data/lib/submodules/ably-ruby/.travis.yml +9 -6
  5. data/lib/submodules/ably-ruby/CHANGELOG.md +25 -2
  6. data/lib/submodules/ably-ruby/README.md +9 -1
  7. data/lib/submodules/ably-ruby/ably.gemspec +4 -4
  8. data/lib/submodules/ably-ruby/lib/ably/logger.rb +7 -1
  9. data/lib/submodules/ably-ruby/lib/ably/modules/state_machine.rb +1 -1
  10. data/lib/submodules/ably-ruby/lib/ably/realtime/client.rb +4 -3
  11. data/lib/submodules/ably-ruby/lib/ably/realtime/connection.rb +26 -15
  12. data/lib/submodules/ably-ruby/lib/ably/realtime/connection/connection_manager.rb +19 -3
  13. data/lib/submodules/ably-ruby/lib/ably/rest/client.rb +4 -2
  14. data/lib/submodules/ably-ruby/lib/ably/version.rb +1 -1
  15. data/lib/submodules/ably-ruby/spec/acceptance/realtime/auth_spec.rb +13 -10
  16. data/lib/submodules/ably-ruby/spec/acceptance/realtime/channel_history_spec.rb +26 -20
  17. data/lib/submodules/ably-ruby/spec/acceptance/realtime/channel_spec.rb +11 -8
  18. data/lib/submodules/ably-ruby/spec/acceptance/realtime/client_spec.rb +8 -4
  19. data/lib/submodules/ably-ruby/spec/acceptance/realtime/connection_failures_spec.rb +71 -5
  20. data/lib/submodules/ably-ruby/spec/acceptance/realtime/connection_spec.rb +125 -14
  21. data/lib/submodules/ably-ruby/spec/acceptance/realtime/message_spec.rb +17 -17
  22. data/lib/submodules/ably-ruby/spec/acceptance/realtime/presence_spec.rb +196 -162
  23. data/lib/submodules/ably-ruby/spec/acceptance/realtime/push_admin_spec.rb +46 -6
  24. data/lib/submodules/ably-ruby/spec/acceptance/rest/channel_spec.rb +37 -0
  25. data/lib/submodules/ably-ruby/spec/acceptance/rest/channels_spec.rb +6 -0
  26. data/lib/submodules/ably-ruby/spec/acceptance/rest/message_spec.rb +8 -27
  27. data/lib/submodules/ably-ruby/spec/acceptance/rest/push_admin_spec.rb +64 -8
  28. data/lib/submodules/ably-ruby/spec/spec_helper.rb +1 -1
  29. data/lib/submodules/ably-ruby/spec/support/debug_failure_helper.rb +9 -5
  30. data/lib/submodules/ably-ruby/spec/unit/modules/enum_spec.rb +1 -1
  31. data/lib/submodules/ably-ruby/spec/unit/realtime/client_spec.rb +1 -1
  32. data/lib/submodules/ably-ruby/spec/unit/realtime/connection_spec.rb +1 -1
  33. metadata +7 -7
@@ -63,20 +63,22 @@ describe Ably::Realtime::Push::Admin, :event_machine do
63
63
  end
64
64
 
65
65
  context 'invalid recipient' do
66
+ let(:default_options) { { key: api_key, environment: environment, protocol: protocol, log_level: :fatal } }
67
+
66
68
  it 'raises an error after receiving a 40x realtime response' do
67
- skip 'validation on raw push is not enabled in realtime'
68
69
  subject.publish({ invalid_recipient_details: 'foo.bar' }, basic_notification_payload).errback do |error|
69
- expect(error.message).to match(/Invalid recipient/)
70
+ expect(error.message).to match(/recipient must contain/)
70
71
  stop_reactor
71
72
  end
72
73
  end
73
74
  end
74
75
 
75
76
  context 'invalid push data' do
77
+ let(:default_options) { { key: api_key, environment: environment, protocol: protocol, log_level: :fatal } }
78
+
76
79
  it 'raises an error after receiving a 40x realtime response' do
77
- skip 'validation on raw push is not enabled in realtime'
78
80
  subject.publish(basic_recipient, { invalid_property_only: true }).errback do |error|
79
- expect(error.message).to match(/Invalid push notification data/)
81
+ expect(error.message).to match(/Unexpected field/)
80
82
  stop_reactor
81
83
  end
82
84
  end
@@ -215,6 +217,12 @@ describe Ably::Realtime::Push::Admin, :event_machine do
215
217
  let(:client_id) { random_str }
216
218
  let(:fixture_count) { 6 }
217
219
 
220
+ before(:all) do
221
+ # As push tests often use the global scope (devices),
222
+ # we need to ensure tests cannot conflict
223
+ reload_test_app
224
+ end
225
+
218
226
  before do
219
227
  fixture_count.times.map do |index|
220
228
  Thread.new do # Parallelise the setup
@@ -272,6 +280,12 @@ describe Ably::Realtime::Push::Admin, :event_machine do
272
280
  let(:fixture_count) { 2 }
273
281
  let(:client_id) { random_str }
274
282
 
283
+ before(:all) do
284
+ # As push tests often use the global scope (devices),
285
+ # we need to ensure tests cannot conflict
286
+ reload_test_app
287
+ end
288
+
275
289
  before do
276
290
  fixture_count.times.map do |index|
277
291
  Thread.new do # Parallelise the setup
@@ -351,6 +365,12 @@ describe Ably::Realtime::Push::Admin, :event_machine do
351
365
  }
352
366
  end
353
367
 
368
+ before(:all) do
369
+ # As push tests often use the global scope (devices),
370
+ # we need to ensure tests cannot conflict
371
+ reload_test_app
372
+ end
373
+
354
374
  after do
355
375
  rest_device_registrations.remove_where client_id: client_id
356
376
  end
@@ -386,6 +406,12 @@ describe Ably::Realtime::Push::Admin, :event_machine do
386
406
  let(:device_id) { random_str }
387
407
  let(:client_id) { random_str }
388
408
 
409
+ before(:all) do
410
+ # As push tests often use the global scope (devices),
411
+ # we need to ensure tests cannot conflict
412
+ reload_test_app
413
+ end
414
+
389
415
  before do
390
416
  rest_device_registrations.save({
391
417
  id: "device-#{client_id}-0",
@@ -419,6 +445,12 @@ describe Ably::Realtime::Push::Admin, :event_machine do
419
445
  let(:device_id) { random_str }
420
446
  let(:client_id) { random_str }
421
447
 
448
+ before(:all) do
449
+ # As push tests often use the global scope (devices),
450
+ # we need to ensure tests cannot conflict
451
+ reload_test_app
452
+ end
453
+
422
454
  before do
423
455
  rest_device_registrations.save({
424
456
  id: "device-#{client_id}-0",
@@ -479,6 +511,12 @@ describe Ably::Realtime::Push::Admin, :event_machine do
479
511
  client.push.admin.channel_subscriptions
480
512
  }
481
513
 
514
+ before(:all) do
515
+ # As push tests often use the global scope (devices),
516
+ # we need to ensure tests cannot conflict
517
+ reload_test_app
518
+ end
519
+
482
520
  # Set up 2 devices with the same client_id
483
521
  # and two device with the unique device_id and no client_id
484
522
  before do
@@ -541,8 +579,10 @@ describe Ably::Realtime::Push::Admin, :event_machine do
541
579
  describe '#list_channels' do
542
580
  let(:fixture_count) { 6 }
543
581
 
544
- before(:context) do
545
- reload_test_app # TODO: Review if necessary later, currently other tests may affect list_channels
582
+ before(:all) do
583
+ # As push tests often use the global scope (devices),
584
+ # we need to ensure tests cannot conflict
585
+ reload_test_app
546
586
  end
547
587
 
548
588
  before do
@@ -275,6 +275,43 @@ describe Ably::Rest::Channel do
275
275
  end
276
276
  end
277
277
  end
278
+
279
+ context 'with a frozen message event name' do
280
+ let(:event_name) { random_str.freeze }
281
+
282
+ it 'succeeds and publishes with an implicit client_id' do
283
+ channel.publish([name: event_name])
284
+ channel.publish(event_name)
285
+
286
+ if !(RUBY_VERSION.match(/^1\./) || RUBY_VERSION.match(/^2\.[012]/))
287
+ channel.publish(+'foo-bar') # new style freeze, see https://github.com/ably/ably-ruby/issues/132
288
+ else
289
+ channel.publish('foo-bar'.freeze) # new + style not supported until Ruby 2.3
290
+ end
291
+
292
+ channel.history do |messages|
293
+ expect(messages.length).to eql(3)
294
+ expect(messages.first.name).to eql(event_name)
295
+ expect(messages[1].name).to eql(event_name)
296
+ expect(messages.last.name).to eql('foo-bar')
297
+ end
298
+ end
299
+ end
300
+
301
+ context 'with a frozen payload' do
302
+ let(:payload) { { foo: random_str.freeze }.freeze }
303
+
304
+ it 'succeeds and publishes with an implicit client_id' do
305
+ channel.publish([data: payload])
306
+ channel.publish(nil, payload)
307
+
308
+ channel.history do |messages|
309
+ expect(messages.length).to eql(2)
310
+ expect(messages.first.data).to eql(payload)
311
+ expect(messages.last.data).to eql(payload)
312
+ end
313
+ end
314
+ end
278
315
  end
279
316
 
280
317
  describe '#history' do
@@ -60,5 +60,11 @@ describe Ably::Rest::Channels do
60
60
  let(:channel_with_options) { client.channels[channel_name, options] }
61
61
  it_behaves_like 'a channel'
62
62
  end
63
+
64
+ describe 'using a frozen channel name' do
65
+ let(:channel) { client.channels[channel_name.freeze] }
66
+ let(:channel_with_options) { client.channels[channel_name.freeze, options] }
67
+ it_behaves_like 'a channel'
68
+ end
63
69
  end
64
70
  end
@@ -75,8 +75,7 @@ describe Ably::Rest::Channel, 'messages' do
75
75
  end
76
76
 
77
77
  context 'JSON Array' do
78
- # TODO: Add nil type back in
79
- let(:data) { { 'push' => { 'data' => { 'key' => [ true, false, 55, 'string', { 'Hash' => true }, ['array'] ] } } } }
78
+ let(:data) { { 'push' => { 'data' => { 'key' => [ true, false, 55, nil, 'string', { 'Hash' => true }, ['array'] ] } } } }
80
79
 
81
80
  it 'is encoded and decoded to the same deep multi-type object' do
82
81
  channel.publish 'event', {}, extras: data
@@ -120,8 +119,6 @@ describe Ably::Rest::Channel, 'messages' do
120
119
  let(:message) { Ably::Models::Message.new(id: id, data: data) }
121
120
 
122
121
  specify 'three REST publishes result in only one message being published' do
123
- pending 'idempotency rolled out to global cluster'
124
-
125
122
  3.times { channel.publish [message] }
126
123
  expect(channel.history.items.length).to eql(1)
127
124
  expect(channel.history.items[0].id).to eql(id)
@@ -130,8 +127,6 @@ describe Ably::Rest::Channel, 'messages' do
130
127
 
131
128
  context 'with #publish arguments only' do
132
129
  it 'three REST publishes result in only one message being published' do
133
- pending 'idempotency rolled out to global cluster'
134
-
135
130
  3.times { channel.publish 'event', data, id: id }
136
131
  expect(channel.history.items.length).to eql(1)
137
132
  end
@@ -143,8 +138,6 @@ describe Ably::Rest::Channel, 'messages' do
143
138
  end
144
139
 
145
140
  specify 'for multiple messages in one publish operation (#RSL1k3)' do
146
- pending 'idempotency rolled out to global cluster'
147
-
148
141
  message_arr = 3.times.map { Ably::Models::Message.new(id: id, data: data) }
149
142
  expect { channel.publish message_arr }.to raise_error do |error|
150
143
  expect(error.code).to eql(40031) # Invalid publish request (invalid client-specified id), see https://github.com/ably/ably-common/pull/30
@@ -152,12 +145,10 @@ describe Ably::Rest::Channel, 'messages' do
152
145
  end
153
146
 
154
147
  specify 'for multiple messages in one publish operation with IDs following the required format described in RSL1k1 (#RSL1k3)' do
155
- pending 'idempotency rolled out to global cluster'
156
-
157
148
  message_arr = 3.times.map { |index| Ably::Models::Message.new(id: "#{id}:#{index}", data: data) }
158
149
  channel.publish message_arr
159
- expect(channel.history.items[0].id).to eql("{id}:0")
160
- expect(channel.history.items[2].id).to eql("{id}:2")
150
+ expect(channel.history.items[2].id).to eql("#{id}:0")
151
+ expect(channel.history.items[0].id).to eql("#{id}:2")
161
152
  expect(channel.history.items.length).to eql(3)
162
153
  end
163
154
  end
@@ -174,7 +165,7 @@ describe Ably::Rest::Channel, 'messages' do
174
165
  end
175
166
 
176
167
  context 'when idempotent publishing is enabled in the client library ClientOptions (#TO3n)' do
177
- let(:client_options) { default_client_options.merge(idempotent_rest_publishing: true, log_level: :error) }
168
+ let(:client_options) { default_client_options.merge(idempotent_rest_publishing: true, log_level: :error, fallback_hosts: ["#{environment}-realtime.ably.io"]) }
178
169
 
179
170
  context 'when there is a network failure triggering an automatic retry (#RSL1k4)' do
180
171
  def mock_for_two_publish_failures
@@ -195,8 +186,6 @@ describe Ably::Rest::Channel, 'messages' do
195
186
  before { mock_for_two_publish_failures }
196
187
 
197
188
  specify 'two REST publish retries result in only one message being published' do
198
- pending 'idempotency rolled out to global cluster'
199
-
200
189
  channel.publish [message]
201
190
  expect(channel.history.items.length).to eql(1)
202
191
  expect(@failed_http_posts).to eql(2)
@@ -207,8 +196,6 @@ describe Ably::Rest::Channel, 'messages' do
207
196
  before { mock_for_two_publish_failures }
208
197
 
209
198
  specify 'two REST publish retries result in only one message being published' do
210
- pending 'idempotency rolled out to global cluster'
211
-
212
199
  channel.publish 'event', data
213
200
  expect(channel.history.items.length).to eql(1)
214
201
  expect(@failed_http_posts).to eql(2)
@@ -221,8 +208,6 @@ describe Ably::Rest::Channel, 'messages' do
221
208
  before { mock_for_two_publish_failures }
222
209
 
223
210
  specify 'two REST publish retries result in only one message being published' do
224
- pending 'idempotency rolled out to global cluster'
225
-
226
211
  channel.publish 'event', data, id: id
227
212
  expect(channel.history.items.length).to eql(1)
228
213
  expect(channel.history.items[0].id).to eql(id)
@@ -231,11 +216,9 @@ describe Ably::Rest::Channel, 'messages' do
231
216
  end
232
217
 
233
218
  specify 'for multiple messages in one publish operation' do
234
- pending 'idempotency rolled out to global cluster'
235
-
236
219
  message_arr = 3.times.map { Ably::Models::Message.new(data: data) }
237
220
  3.times { channel.publish message_arr }
238
- expect(channel.history.items.length).to eql(message_arr.length)
221
+ expect(channel.history.items.length).to eql(message_arr.length * 3)
239
222
  end
240
223
  end
241
224
 
@@ -248,13 +231,11 @@ describe Ably::Rest::Channel, 'messages' do
248
231
 
249
232
  context 'when publishing a batch of messages' do
250
233
  specify 'the ID is populated with a single random ID and sequence of serials from this lib (#RSL1k1)' do
251
- pending 'idempotency rolled out to global cluster'
252
-
253
234
  message = { name: 'event' }
254
235
  channel.publish [message, message, message]
255
- expect(channel.history.items[0].length).to eql(3)
256
- expect(channel.history.items[0].id).to match(/^[A-Za-z0-9\+\/]+:0$/)
257
- expect(channel.history.items[2].id).to match(/^[A-Za-z0-9\+\/]+:2$/)
236
+ expect(channel.history.items.length).to eql(3)
237
+ expect(channel.history.items[0].id).to match(/^[A-Za-z0-9\+\/]+:2$/)
238
+ expect(channel.history.items[2].id).to match(/^[A-Za-z0-9\+\/]+:0$/)
258
239
  base_64_id = channel.history.items[0].id.split(':')[0]
259
240
  expect(Base64.decode64(base_64_id).length).to eql(9)
260
241
  end
@@ -181,6 +181,12 @@ describe Ably::Rest::Push::Admin do
181
181
  let(:client_id) { random_str }
182
182
  let(:fixture_count) { 6 }
183
183
 
184
+ before(:all) do
185
+ # As push tests often use the global scope (devices),
186
+ # we need to ensure tests cannot conflict
187
+ reload_test_app
188
+ end
189
+
184
190
  before do
185
191
  fixture_count.times.map do |index|
186
192
  Thread.new do
@@ -244,6 +250,12 @@ describe Ably::Rest::Push::Admin do
244
250
  let(:fixture_count) { 2 }
245
251
  let(:client_id) { random_str }
246
252
 
253
+ before(:all) do
254
+ # As push tests often use the global scope (devices),
255
+ # we need to ensure tests cannot conflict
256
+ reload_test_app
257
+ end
258
+
247
259
  before do
248
260
  fixture_count.times.map do |index|
249
261
  Thread.new do
@@ -318,6 +330,12 @@ describe Ably::Rest::Push::Admin do
318
330
  }
319
331
  end
320
332
 
333
+ before(:all) do
334
+ # As push tests often use the global scope (devices),
335
+ # we need to ensure tests cannot conflict
336
+ reload_test_app
337
+ end
338
+
321
339
  after do
322
340
  subject.remove_where client_id: client_id, full_wait: true
323
341
  end
@@ -444,6 +462,12 @@ describe Ably::Rest::Push::Admin do
444
462
  let(:device_id) { random_str }
445
463
  let(:client_id) { random_str }
446
464
 
465
+ before(:all) do
466
+ # As push tests often use the global scope (devices),
467
+ # we need to ensure tests cannot conflict
468
+ reload_test_app
469
+ end
470
+
447
471
  before do
448
472
  [
449
473
  Thread.new do
@@ -501,6 +525,12 @@ describe Ably::Rest::Push::Admin do
501
525
  let(:device_id) { random_str }
502
526
  let(:client_id) { random_str }
503
527
 
528
+ before(:all) do
529
+ # As push tests often use the global scope (devices),
530
+ # we need to ensure tests cannot conflict
531
+ reload_test_app
532
+ end
533
+
504
534
  before do
505
535
  [
506
536
  Thread.new do
@@ -585,8 +615,8 @@ describe Ably::Rest::Push::Admin do
585
615
  # and two device with the unique device_id and no client_id
586
616
  before do
587
617
  [
588
- lambda { device_registrations.save(default_device_attr.merge(id: device_id)) },
589
- lambda { device_registrations.save(default_device_attr.merge(id: device_id_2)) },
618
+ lambda { device_registrations.save(default_device_attr.merge(id: device_id, client_id: nil)) },
619
+ lambda { device_registrations.save(default_device_attr.merge(id: device_id_2, client_id: nil)) },
590
620
  lambda { device_registrations.save(default_device_attr.merge(client_id: client_id, id: random_str)) },
591
621
  lambda { device_registrations.save(default_device_attr.merge(client_id: client_id, id: random_str)) }
592
622
  ].map do |proc|
@@ -602,6 +632,12 @@ describe Ably::Rest::Push::Admin do
602
632
  describe '#list (#RSH1c1)' do
603
633
  let(:fixture_count) { 6 }
604
634
 
635
+ before(:all) do
636
+ # As push tests often use the global scope (devices),
637
+ # we need to ensure tests cannot conflict
638
+ reload_test_app
639
+ end
640
+
605
641
  before do
606
642
  fixture_count.times.map do |index|
607
643
  Thread.new { subject.save(channel: "pushenabled:#{random_str}", client_id: client_id) }
@@ -670,11 +706,14 @@ describe Ably::Rest::Push::Admin do
670
706
  describe '#list_channels (#RSH1c2)' do
671
707
  let(:fixture_count) { 6 }
672
708
 
673
- before(:context) do
674
- reload_test_app # TODO: Review if necessary late, currently other tests may affect list_channels
709
+ before(:all) do
710
+ # As push tests often use the global scope (devices),
711
+ # we need to ensure tests cannot conflict
712
+ reload_test_app
675
713
  end
676
714
 
677
715
  before do
716
+ # Create 6 channel subscriptions to the client ID for this test
678
717
  fixture_count.times.map do |index|
679
718
  Thread.new do
680
719
  subject.save(channel: "pushenabled:#{index}:#{random_str}", client_id: client_id)
@@ -694,9 +733,6 @@ describe Ably::Rest::Push::Admin do
694
733
  end
695
734
 
696
735
  it 'supports paging' do
697
- skip 'Channel lists with limits is not reliable immediately after fixture creation'
698
- # TODO: Remove this once list channels with limits is reliable immediately after fixtures created
699
- # See https://github.com/ably/realtime/issues/1882
700
736
  subject.list_channels
701
737
  page = subject.list_channels(limit: 3)
702
738
  expect(page).to be_a(Ably::Models::PaginatedResult)
@@ -730,6 +766,12 @@ describe Ably::Rest::Push::Admin do
730
766
  let(:client_id) { random_str }
731
767
  let(:device_id) { random_str }
732
768
 
769
+ before(:all) do
770
+ # As push tests often use the global scope (devices),
771
+ # we need to ensure tests cannot conflict
772
+ reload_test_app
773
+ end
774
+
733
775
  it 'saves the new client_id PushChannelSubscription Hash object' do
734
776
  subject.save(channel: channel, client_id: client_id)
735
777
 
@@ -802,6 +844,12 @@ describe Ably::Rest::Push::Admin do
802
844
 
803
845
  let(:fixture_count) { 6 }
804
846
 
847
+ before(:all) do
848
+ # As push tests often use the global scope (devices),
849
+ # we need to ensure tests cannot conflict
850
+ reload_test_app
851
+ end
852
+
805
853
  before do
806
854
  fixture_count.times.map do |index|
807
855
  [
@@ -814,8 +862,10 @@ describe Ably::Rest::Push::Admin do
814
862
  end.each(&:join) # Wait for all threads to complete
815
863
  end
816
864
 
865
+ # TODO: Reinstate once delete subscriptions by channel is possible
866
+ # See https://github.com/ably/realtime/issues/1359
817
867
  it 'removes matching channels' do
818
- skip 'Delete by channel is not yet supported'
868
+ skip 'deleting subscriptions is not yet supported realtime#1359'
819
869
  subject.remove_where channel: fixed_channel, full_wait: true
820
870
  expect(subject.list(channel: fixed_channel).items.count).to eql(0)
821
871
  expect(subject.list(client_id: client_id).items.count).to eql(0)
@@ -852,6 +902,12 @@ describe Ably::Rest::Push::Admin do
852
902
  let(:client_id) { random_str }
853
903
  let(:device_id) { random_str }
854
904
 
905
+ before(:all) do
906
+ # As push tests often use the global scope (devices),
907
+ # we need to ensure tests cannot conflict
908
+ reload_test_app
909
+ end
910
+
855
911
  before do
856
912
  [
857
913
  lambda { subject.save(channel: channel, client_id: client_id) },
@@ -4,7 +4,7 @@ def console(message)
4
4
  puts "\033[31m[#{Time.now.strftime('%H:%M:%S.%L')}]\033[0m \033[33m#{message}\033[0m"
5
5
  end
6
6
 
7
- unless RUBY_VERSION.match(/^1/)
7
+ unless RUBY_VERSION.match(/^1\./)
8
8
  require 'coveralls'
9
9
  Coveralls.wear!
10
10
  end