ably-rest 1.1.0 → 1.1.2.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +9 -1
  3. data/ably-rest.gemspec +2 -2
  4. data/lib/submodules/ably-ruby/.travis.yml +9 -6
  5. data/lib/submodules/ably-ruby/CHANGELOG.md +18 -1
  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 +11 -11
@@ -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