ably-rest 0.8.14 → 0.8.15

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 (26) hide show
  1. checksums.yaml +4 -4
  2. data/lib/submodules/ably-ruby/CHANGELOG.md +48 -61
  3. data/lib/submodules/ably-ruby/README.md +6 -0
  4. data/lib/submodules/ably-ruby/ably.gemspec +1 -1
  5. data/lib/submodules/ably-ruby/lib/ably/models/http_paginated_response.rb +90 -0
  6. data/lib/submodules/ably-ruby/lib/ably/models/paginated_result.rb +5 -0
  7. data/lib/submodules/ably-ruby/lib/ably/modules/event_emitter.rb +30 -15
  8. data/lib/submodules/ably-ruby/lib/ably/modules/model_common.rb +25 -0
  9. data/lib/submodules/ably-ruby/lib/ably/realtime/channel/channel_manager.rb +3 -3
  10. data/lib/submodules/ably-ruby/lib/ably/realtime/client.rb +13 -0
  11. data/lib/submodules/ably-ruby/lib/ably/realtime/client/incoming_message_dispatcher.rb +2 -2
  12. data/lib/submodules/ably-ruby/lib/ably/realtime/presence/members_map.rb +3 -3
  13. data/lib/submodules/ably-ruby/lib/ably/rest/client.rb +60 -3
  14. data/lib/submodules/ably-ruby/lib/ably/version.rb +1 -1
  15. data/lib/submodules/ably-ruby/spec/acceptance/realtime/auth_spec.rb +29 -0
  16. data/lib/submodules/ably-ruby/spec/acceptance/realtime/channel_spec.rb +8 -6
  17. data/lib/submodules/ably-ruby/spec/acceptance/realtime/client_spec.rb +52 -0
  18. data/lib/submodules/ably-ruby/spec/acceptance/realtime/connection_spec.rb +44 -8
  19. data/lib/submodules/ably-ruby/spec/acceptance/realtime/presence_spec.rb +79 -38
  20. data/lib/submodules/ably-ruby/spec/acceptance/rest/channel_spec.rb +2 -4
  21. data/lib/submodules/ably-ruby/spec/acceptance/rest/client_spec.rb +69 -21
  22. data/lib/submodules/ably-ruby/spec/acceptance/rest/presence_spec.rb +10 -12
  23. data/lib/submodules/ably-ruby/spec/unit/models/http_paginated_result_spec.rb +380 -0
  24. data/lib/submodules/ably-ruby/spec/unit/modules/event_emitter_spec.rb +109 -51
  25. data/lib/submodules/ably-ruby/spec/unit/realtime/presence_spec.rb +3 -3
  26. metadata +5 -4
@@ -615,16 +615,23 @@ describe Ably::Realtime::Connection, :event_machine do
615
615
  end
616
616
  end
617
617
 
618
- it 'is set to 0 when a message sent ACK is received' do
619
- channel.publish('event', 'data') do
618
+ it 'is set to 0 when a message is received back' do
619
+ channel.publish('event', 'data')
620
+ channel.subscribe do
620
621
  expect(connection.serial).to eql(0)
621
622
  stop_reactor
622
623
  end
623
624
  end
624
625
 
625
- it 'is set to 1 when the second message sent ACK is received' do
626
+ it 'is set to 1 when the second message is received' do
626
627
  channel.publish('event', 'data') do
627
- channel.publish('event', 'data') do
628
+ channel.publish('event', 'data')
629
+ end
630
+
631
+ messages = []
632
+ channel.subscribe do |message|
633
+ messages << message
634
+ if messages.length == 2
628
635
  expect(connection.serial).to eql(1)
629
636
  stop_reactor
630
637
  end
@@ -884,11 +891,16 @@ describe Ably::Realtime::Connection, :event_machine do
884
891
  expect(connection.serial).to eql(expected_serial)
885
892
 
886
893
  channel.attach do
887
- channel.publish('event', 'data') do
894
+ channel.publish('event', 'data')
895
+ channel.subscribe do
896
+ channel.unsubscribe
897
+
888
898
  expected_serial += 1 # attach message received
889
899
  expect(connection.serial).to eql(expected_serial)
890
900
 
891
- channel.publish('event', 'data') do
901
+ channel.publish('event', 'data')
902
+ channel.subscribe do
903
+ channel.unsubscribe
892
904
  expected_serial += 1 # attach message received
893
905
  expect(connection.serial).to eql(expected_serial)
894
906
 
@@ -1278,6 +1290,22 @@ describe Ably::Realtime::Connection, :event_machine do
1278
1290
  end
1279
1291
 
1280
1292
  context 'connection state change' do
1293
+ # See https://github.com/ably/ably-ruby/issues/103
1294
+ it 'emits event to all and single subscribers' do
1295
+ connected_emitted = []
1296
+ block = Proc.new do |state_change|
1297
+ if state_change.current == :connected
1298
+ connected_emitted << state_change
1299
+ EventMachine.add_timer(0.5) do
1300
+ expect(connected_emitted.length).to eql(2)
1301
+ stop_reactor
1302
+ end
1303
+ end
1304
+ end
1305
+ connection.on(&block)
1306
+ connection.on(:connected, &block)
1307
+ end
1308
+
1281
1309
  it 'emits a ConnectionStateChange object' do
1282
1310
  connection.on(:connected) do |connection_state_change|
1283
1311
  expect(connection_state_change).to be_a(Ably::Models::ConnectionStateChange)
@@ -1286,6 +1314,14 @@ describe Ably::Realtime::Connection, :event_machine do
1286
1314
  end
1287
1315
 
1288
1316
  context 'ConnectionStateChange object' do
1317
+ def unbind
1318
+ if connection.transport
1319
+ connection.transport.unbind
1320
+ else
1321
+ EventMachine.add_timer(0.005) { unbind }
1322
+ end
1323
+ end
1324
+
1289
1325
  it 'has current state' do
1290
1326
  connection.on(:connected) do |connection_state_change|
1291
1327
  expect(connection_state_change.current).to eq(:connected)
@@ -1349,7 +1385,7 @@ describe Ably::Realtime::Connection, :event_machine do
1349
1385
  expect(connection_state_change.retry_in).to eql(0)
1350
1386
  stop_reactor
1351
1387
  end
1352
- EventMachine.add_timer(0.005) { connection.transport.unbind }
1388
+ unbind
1353
1389
  end
1354
1390
  end
1355
1391
 
@@ -1370,7 +1406,7 @@ describe Ably::Realtime::Connection, :event_machine do
1370
1406
  expect(connection_state_change.retry_in).to be > 0
1371
1407
  stop_reactor
1372
1408
  end
1373
- EventMachine.add_timer(0.005) { connection.transport.unbind }
1409
+ unbind
1374
1410
  end
1375
1411
  connection.transport.unbind
1376
1412
  end
@@ -42,9 +42,11 @@ describe Ably::Realtime::Presence, :event_machine do
42
42
 
43
43
  def setup_test(method_name, args, options)
44
44
  if options[:enter_first]
45
- presence_client_one.public_send(method_name.to_s.gsub(/leave|update/, 'enter'), args) do
45
+ presence_client_one.subscribe do
46
+ presence_client_one.unsubscribe
46
47
  yield
47
48
  end
49
+ presence_client_one.public_send(method_name.to_s.gsub(/leave|update/, 'enter'), args)
48
50
  else
49
51
  yield
50
52
  end
@@ -468,7 +470,14 @@ describe Ably::Realtime::Presence, :event_machine do
468
470
 
469
471
  context 'once server sync is complete' do
470
472
  it 'behaves like an Enumerable allowing direct access to current members' do
471
- when_all(presence_client_one.enter, presence_client_two.enter) do
473
+ presence_client_one.enter
474
+ presence_client_two.enter
475
+
476
+ entered = 0
477
+ presence_client_one.subscribe(:enter) do
478
+ entered += 1
479
+ next unless entered == 2
480
+
472
481
  presence_anonymous_client.members.once(:in_sync) do
473
482
  expect(presence_anonymous_client.members.count).to eql(2)
474
483
  member_ids = presence_anonymous_client.members.map(&:member_key)
@@ -495,7 +504,10 @@ describe Ably::Realtime::Presence, :event_machine do
495
504
 
496
505
  context 'when attaching to a channel with members present' do
497
506
  it 'is false and the presence channel will subsequently be synced' do
498
- presence_client_one.enter do
507
+ presence_client_one.enter
508
+ presence_client_one.subscribe(:enter) do
509
+ presence_client_one.unsubscribe :enter
510
+
499
511
  channel_anonymous_client.attach do
500
512
  expect(channel_anonymous_client.presence).to_not be_sync_complete
501
513
  channel_anonymous_client.presence.get(wait_for_sync: true) do
@@ -680,16 +692,18 @@ describe Ably::Realtime::Presence, :event_machine do
680
692
  it 'waits until sync is complete', em_timeout: 30 do # allow for slow connections and lots of messages
681
693
  enter_expected_count.times do |index|
682
694
  EventMachine.add_timer(index / 10) do
683
- presence_client_one.enter_client("client:#{index}") do |message|
684
- entered << message
685
- next unless entered.count == enter_expected_count
695
+ presence_client_one.enter_client("client:#{index}")
696
+ end
697
+ end
686
698
 
687
- presence_anonymous_client.get(wait_for_sync: true) do |members|
688
- expect(members.map(&:client_id).uniq.count).to eql(enter_expected_count)
689
- expect(members.count).to eql(enter_expected_count)
690
- stop_reactor
691
- end
692
- end
699
+ presence_client_one.subscribe(:enter) do |message|
700
+ entered << message
701
+ next unless entered.count == enter_expected_count
702
+
703
+ presence_anonymous_client.get(wait_for_sync: true) do |members|
704
+ expect(members.map(&:client_id).uniq.count).to eql(enter_expected_count)
705
+ expect(members.count).to eql(enter_expected_count)
706
+ stop_reactor
693
707
  end
694
708
  end
695
709
  end
@@ -697,19 +711,21 @@ describe Ably::Realtime::Presence, :event_machine do
697
711
 
698
712
  context 'by default' do
699
713
  it 'it does not wait for sync', em_timeout: 30 do # allow for slow connections and lots of messages
700
- enter_expected_count.times do |index|
701
- EventMachine.add_timer(index / 10) do
702
- presence_client_one.enter_client("client:#{index}") do |message|
703
- entered << message
704
- next unless entered.count == enter_expected_count
705
-
706
- channel_anonymous_client.attach do
707
- presence_anonymous_client.get do |members|
708
- expect(presence_anonymous_client.members).to_not be_in_sync
709
- expect(members.count).to eql(0)
710
- stop_reactor
711
- end
712
- end
714
+ enter_expected_count.times do |indx|
715
+ EventMachine.add_timer(indx / 10) do
716
+ presence_client_one.enter_client "client:#{indx}"
717
+ end
718
+ end
719
+
720
+ presence_client_one.subscribe(:enter) do |message|
721
+ entered << message
722
+ next unless entered.count == enter_expected_count
723
+
724
+ channel_anonymous_client.attach do
725
+ presence_anonymous_client.get do |members|
726
+ expect(presence_anonymous_client.members).to_not be_in_sync
727
+ expect(members.count).to eql(0)
728
+ stop_reactor
713
729
  end
714
730
  end
715
731
  end
@@ -896,15 +912,25 @@ describe Ably::Realtime::Presence, :event_machine do
896
912
 
897
913
  context 'and sync is complete' do
898
914
  it 'does not cache members that have left' do
899
- presence_client_one.enter enter_data do
915
+ enter_ack = false
916
+
917
+ presence_client_one.subscribe(:enter) do
918
+ presence_client_one.unsubscribe :enter
919
+
900
920
  expect(presence_client_one.members).to be_in_sync
901
921
  expect(presence_client_one.members.send(:members).count).to eql(1)
902
922
  presence_client_one.leave data
903
923
  end
904
924
 
925
+ presence_client_one.enter(enter_data) do
926
+ enter_ack = true
927
+ end
928
+
905
929
  presence_client_one.subscribe(:leave) do |presence_message|
930
+ presence_client_one.unsubscribe :leave
906
931
  expect(presence_message.data).to eql(data)
907
932
  expect(presence_client_one.members.send(:members).count).to eql(0)
933
+ expect(enter_ack).to eql(true)
908
934
  stop_reactor
909
935
  end
910
936
  end
@@ -1290,7 +1316,9 @@ describe Ably::Realtime::Presence, :event_machine do
1290
1316
  # skip 'it fails if the connection changes to failed state'
1291
1317
 
1292
1318
  it 'returns the current members on the channel' do
1293
- presence_client_one.enter do
1319
+ presence_client_one.enter
1320
+ presence_client_one.subscribe(:enter) do
1321
+ presence_client_one.unsubscribe :enter
1294
1322
  presence_client_one.get do |members|
1295
1323
  expect(members.count).to eq(1)
1296
1324
 
@@ -1351,7 +1379,10 @@ describe Ably::Realtime::Presence, :event_machine do
1351
1379
  end
1352
1380
 
1353
1381
  it 'does not wait for SYNC to complete if :wait_for_sync option is false' do
1354
- presence_client_one.enter do
1382
+ presence_client_one.enter
1383
+ presence_client_one.subscribe(:enter) do
1384
+ presence_client_one.unsubscribe :enter
1385
+
1355
1386
  presence_client_two.get(wait_for_sync: false) do |members|
1356
1387
  expect(members.count).to eql(0)
1357
1388
  stop_reactor
@@ -1362,11 +1393,13 @@ describe Ably::Realtime::Presence, :event_machine do
1362
1393
  context 'when a member enters and then leaves' do
1363
1394
  it 'has no members' do
1364
1395
  presence_client_one.enter do
1365
- presence_client_one.leave do
1366
- presence_client_one.get do |members|
1367
- expect(members.count).to eq(0)
1368
- stop_reactor
1369
- end
1396
+ presence_client_one.leave
1397
+ end
1398
+
1399
+ presence_client_one.subscribe(:leave) do
1400
+ presence_client_one.get do |members|
1401
+ expect(members.count).to eq(0)
1402
+ stop_reactor
1370
1403
  end
1371
1404
  end
1372
1405
  end
@@ -1524,7 +1557,10 @@ describe Ably::Realtime::Presence, :event_machine do
1524
1557
 
1525
1558
  context 'REST #get' do
1526
1559
  it 'returns current members' do
1527
- presence_client_one.enter(data_payload) do
1560
+ presence_client_one.enter data_payload
1561
+ presence_client_one.subscribe(:enter) do
1562
+ presence_client_one.unsubscribe :enter
1563
+
1528
1564
  members_page = channel_rest_client_one.presence.get
1529
1565
  this_member = members_page.items.first
1530
1566
 
@@ -1538,7 +1574,10 @@ describe Ably::Realtime::Presence, :event_machine do
1538
1574
 
1539
1575
  it 'returns no members once left' do
1540
1576
  presence_client_one.enter(data_payload) do
1541
- presence_client_one.leave do
1577
+ presence_client_one.leave
1578
+ presence_client_one.subscribe(:leave) do
1579
+ presence_client_one.unsubscribe :leave
1580
+
1542
1581
  members_page = channel_rest_client_one.presence.get
1543
1582
  expect(members_page.items.count).to eql(0)
1544
1583
  stop_reactor
@@ -1654,7 +1693,8 @@ describe Ably::Realtime::Presence, :event_machine do
1654
1693
 
1655
1694
  context '#get' do
1656
1695
  it 'returns a list of members with decrypted data' do
1657
- encrypted_channel.presence.enter(data) do
1696
+ encrypted_channel.presence.enter(data)
1697
+ encrypted_channel.presence.subscribe(:enter) do
1658
1698
  encrypted_channel.presence.get do |members|
1659
1699
  member = members.first
1660
1700
  expect(member.encoding).to be_nil
@@ -1667,7 +1707,8 @@ describe Ably::Realtime::Presence, :event_machine do
1667
1707
 
1668
1708
  context 'REST #get' do
1669
1709
  it 'returns a list of members with decrypted data' do
1670
- encrypted_channel.presence.enter(data) do
1710
+ encrypted_channel.presence.enter(data)
1711
+ encrypted_channel.presence.subscribe(:enter) do
1671
1712
  member = channel_rest_client_one.presence.get.items.first
1672
1713
  expect(member.encoding).to be_nil
1673
1714
  expect(member.data).to eql(data)
@@ -1738,7 +1779,7 @@ describe Ably::Realtime::Presence, :event_machine do
1738
1779
  context 'connection failure mid-way through a large member sync' do
1739
1780
  let(:members_count) { 250 }
1740
1781
  let(:sync_pages_received) { [] }
1741
- let(:client_options) { default_options.merge(log_level: :error) }
1782
+ let(:client_options) { default_options.merge(log_level: :fatal) }
1742
1783
 
1743
1784
  it 'resumes the SYNC operation', em_timeout: 15 do
1744
1785
  when_all(*members_count.times.map do |index|
@@ -360,10 +360,7 @@ describe Ably::Rest::Channel do
360
360
  let(:channel_name) { "persisted:#{random_str(4)}" }
361
361
  let(:channel) { client.channel(channel_name) }
362
362
  let(:endpoint) do
363
- client.endpoint.tap do |client_end_point|
364
- client_end_point.user = key_name
365
- client_end_point.password = key_secret
366
- end
363
+ client.endpoint
367
364
  end
368
365
  let(:default_history_options) do
369
366
  {
@@ -378,6 +375,7 @@ describe Ably::Rest::Channel do
378
375
  query_params = default_history_options
379
376
  .merge(option => milliseconds).map { |k, v| "#{k}=#{v}" }.join('&')
380
377
  stub_request(:get, "#{endpoint}/channels/#{Addressable::URI.encode(channel_name)}/messages?#{query_params}").
378
+ with(basic_auth: [key_name, key_secret]).
381
379
  to_return(:body => '{}', :headers => { 'Content-Type' => 'application/json' })
382
380
  }
383
381
 
@@ -111,7 +111,8 @@ describe Ably::Rest::Client do
111
111
  let(:client_options) { default_options.merge(key: api_key) }
112
112
 
113
113
  let!(:get_message_history_stub) do
114
- stub_request(:get, "https://#{api_key}@#{environment}-#{Ably::Rest::Client::DOMAIN}/channels/#{channel_name}/messages?#{history_querystring}").
114
+ stub_request(:get, "https://#{environment}-#{Ably::Rest::Client::DOMAIN}/channels/#{channel_name}/messages?#{history_querystring}").
115
+ with(basic_auth: [key_name, key_secret]).
115
116
  to_return(body: [], headers: { 'Content-Type' => 'application/json' })
116
117
  end
117
118
 
@@ -284,7 +285,9 @@ describe Ably::Rest::Client do
284
285
  context 'when environment is NOT production' do
285
286
  let(:client_options) { default_options.merge(environment: 'sandbox', key: api_key) }
286
287
  let!(:default_host_request_stub) do
287
- stub_request(:post, "https://#{api_key}@#{environment}-#{Ably::Rest::Client::DOMAIN}#{path}").to_return do
288
+ stub_request(:post, "https://#{environment}-#{Ably::Rest::Client::DOMAIN}#{path}").
289
+ with(basic_auth: [key_name, key_secret]).
290
+ to_return do
288
291
  raise Faraday::TimeoutError.new('timeout error message')
289
292
  end
290
293
  end
@@ -313,16 +316,16 @@ describe Ably::Rest::Client do
313
316
  end
314
317
 
315
318
  let!(:first_fallback_request_stub) do
316
- stub_request(:post, "https://#{api_key}@#{custom_hosts[0]}#{path}").to_return(&fallback_block)
319
+ stub_request(:post, "https://#{custom_hosts[0]}#{path}").with(basic_auth: [key_name, key_secret]).to_return(&fallback_block)
317
320
  end
318
321
 
319
322
  let!(:second_fallback_request_stub) do
320
- stub_request(:post, "https://#{api_key}@#{custom_hosts[1]}#{path}").to_return(&fallback_block)
323
+ stub_request(:post, "https://#{custom_hosts[1]}#{path}").with(basic_auth: [key_name, key_secret]).to_return(&fallback_block)
321
324
  end
322
325
 
323
326
  context 'and connection times out' do
324
327
  let!(:default_host_request_stub) do
325
- stub_request(:post, "https://#{api_key}@#{Ably::Rest::Client::DOMAIN}#{path}").to_return do
328
+ stub_request(:post, "https://#{Ably::Rest::Client::DOMAIN}#{path}").with(basic_auth: [key_name, key_secret]).to_return do
326
329
  raise Faraday::TimeoutError.new('timeout error message')
327
330
  end
328
331
  end
@@ -336,7 +339,7 @@ describe Ably::Rest::Client do
336
339
 
337
340
  context "and the total request time exeeds #{http_defaults.fetch(:max_retry_duration)} seconds" do
338
341
  let!(:default_host_request_stub) do
339
- stub_request(:post, "https://#{api_key}@#{Ably::Rest::Client::DOMAIN}#{path}").to_return do
342
+ stub_request(:post, "https://#{Ably::Rest::Client::DOMAIN}#{path}").with(basic_auth: [key_name, key_secret]).to_return do
340
343
  sleep max_retry_duration * 1.5
341
344
  raise Faraday::TimeoutError.new('timeout error message')
342
345
  end
@@ -353,7 +356,7 @@ describe Ably::Rest::Client do
353
356
 
354
357
  context 'and connection fails' do
355
358
  let!(:default_host_request_stub) do
356
- stub_request(:post, "https://#{api_key}@#{Ably::Rest::Client::DOMAIN}#{path}").to_return do
359
+ stub_request(:post, "https://#{Ably::Rest::Client::DOMAIN}#{path}").with(basic_auth: [key_name, key_secret]).to_return do
357
360
  raise Faraday::ConnectionFailed.new('connection failure error message')
358
361
  end
359
362
  end
@@ -369,7 +372,7 @@ describe Ably::Rest::Client do
369
372
  context 'and basic authentication fails' do
370
373
  let(:status) { 401 }
371
374
  let!(:default_host_request_stub) do
372
- stub_request(:post, "https://#{api_key}@#{Ably::Rest::Client::DOMAIN}#{path}").to_return(
375
+ stub_request(:post, "https://#{Ably::Rest::Client::DOMAIN}#{path}").with(basic_auth: [key_name, key_secret]).to_return(
373
376
  headers: { 'Content-Type' => 'application/json' },
374
377
  status: status,
375
378
  body: {
@@ -401,7 +404,7 @@ describe Ably::Rest::Client do
401
404
  end
402
405
  end
403
406
  let!(:default_host_request_stub) do
404
- stub_request(:post, "https://#{api_key}@#{Ably::Rest::Client::DOMAIN}#{path}").to_return(&fallback_block)
407
+ stub_request(:post, "https://#{Ably::Rest::Client::DOMAIN}#{path}").with(basic_auth: [key_name, key_secret]).to_return(&fallback_block)
405
408
  end
406
409
 
407
410
  it 'attempts the fallback hosts as this is an authentication failure' do
@@ -437,20 +440,20 @@ describe Ably::Rest::Client do
437
440
  end
438
441
  end
439
442
  let!(:default_host_request_stub) do
440
- stub_request(:post, "https://#{api_key}@#{Ably::Rest::Client::DOMAIN}#{path}").to_return(&fallback_block)
443
+ stub_request(:post, "https://#{Ably::Rest::Client::DOMAIN}#{path}").with(basic_auth: [key_name, key_secret]).to_return(&fallback_block)
441
444
  end
442
445
 
443
446
  context 'with custom fallback hosts provided' do
444
447
  let!(:first_fallback_request_stub) do
445
- stub_request(:post, "https://#{api_key}@#{custom_hosts[0]}#{path}").to_return(&fallback_block)
448
+ stub_request(:post, "https://#{custom_hosts[0]}#{path}").with(basic_auth: [key_name, key_secret]).to_return(&fallback_block)
446
449
  end
447
450
 
448
451
  let!(:second_fallback_request_stub) do
449
- stub_request(:post, "https://#{api_key}@#{custom_hosts[1]}#{path}").to_return(&fallback_block)
452
+ stub_request(:post, "https://#{custom_hosts[1]}#{path}").with(basic_auth: [key_name, key_secret]).to_return(&fallback_block)
450
453
  end
451
454
 
452
455
  let(:client_options) {
453
- production_options.merge(fallback_hosts: custom_hosts)
456
+ production_options.merge(fallback_hosts: custom_hosts, log_level: :error)
454
457
  }
455
458
 
456
459
  it 'attempts the fallback hosts as this is an authentication failure (#RSC15b, #TO3k6)' do
@@ -516,7 +519,8 @@ describe Ably::Rest::Client do
516
519
  port: port,
517
520
  tls: false,
518
521
  http_request_timeout: request_timeout,
519
- max_retry_duration: request_timeout * 3
522
+ max_retry_duration: request_timeout * 3,
523
+ log_level: :error
520
524
  )
521
525
  end
522
526
  let(:fail_fallback_request_count) { 1 }
@@ -619,16 +623,16 @@ describe Ably::Rest::Client do
619
623
  end
620
624
  end
621
625
  let!(:default_host_request_stub) do
622
- stub_request(:post, "https://#{api_key}@#{env}-#{Ably::Rest::Client::DOMAIN}#{path}").to_return(&fallback_block)
626
+ stub_request(:post, "https://#{env}-#{Ably::Rest::Client::DOMAIN}#{path}").with(basic_auth: [key_name, key_secret]).to_return(&fallback_block)
623
627
  end
624
628
 
625
629
  context 'with custom fallback hosts provided (#RSC15b, #TO3k6)' do
626
630
  let!(:first_fallback_request_stub) do
627
- stub_request(:post, "https://#{api_key}@#{custom_hosts[0]}#{path}").to_return(&fallback_block)
631
+ stub_request(:post, "https://#{custom_hosts[0]}#{path}").with(basic_auth: [key_name, key_secret]).to_return(&fallback_block)
628
632
  end
629
633
 
630
634
  let!(:second_fallback_request_stub) do
631
- stub_request(:post, "https://#{api_key}@#{custom_hosts[1]}#{path}").to_return(&fallback_block)
635
+ stub_request(:post, "https://#{custom_hosts[1]}#{path}").with(basic_auth: [key_name, key_secret]).to_return(&fallback_block)
632
636
  end
633
637
 
634
638
  let(:client_options) {
@@ -666,11 +670,11 @@ describe Ably::Rest::Client do
666
670
  }
667
671
 
668
672
  let!(:first_fallback_request_stub) do
669
- stub_request(:post, "https://#{api_key}@#{Ably::FALLBACK_HOSTS[0]}#{path}").to_return(&fallback_block)
673
+ stub_request(:post, "https://#{Ably::FALLBACK_HOSTS[0]}#{path}").with(basic_auth: [key_name, key_secret]).to_return(&fallback_block)
670
674
  end
671
675
 
672
676
  let!(:second_fallback_request_stub) do
673
- stub_request(:post, "https://#{api_key}@#{Ably::FALLBACK_HOSTS[1]}#{path}").to_return(&fallback_block)
677
+ stub_request(:post, "https://#{Ably::FALLBACK_HOSTS[1]}#{path}").with(basic_auth: [key_name, key_secret]).to_return(&fallback_block)
674
678
  end
675
679
 
676
680
  let(:client_options) {
@@ -701,7 +705,7 @@ describe Ably::Rest::Client do
701
705
  let(:path) { '/channels/test/publish' }
702
706
 
703
707
  let!(:custom_host_request_stub) do
704
- stub_request(:post, "https://#{api_key}@#{custom_host}#{path}").to_return do
708
+ stub_request(:post, "https://#{custom_host}#{path}").with(basic_auth: [key_name, key_secret]).to_return do
705
709
  raise Faraday::ConnectionFailed.new('connection failure error message')
706
710
  end
707
711
  end
@@ -840,11 +844,12 @@ describe Ably::Rest::Client do
840
844
  lib << Ably::VERSION
841
845
 
842
846
 
843
- stub_request(:post, "#{client.endpoint.to_s.gsub('://', "://#{api_key}@")}/channels/foo/publish").
847
+ stub_request(:post, "#{client.endpoint.to_s.gsub('://', "://")}/channels/foo/publish").
844
848
  with(headers: {
845
849
  'X-Ably-Version' => Ably::PROTOCOL_VERSION,
846
850
  'X-Ably-Lib' => lib.join('-')
847
851
  }).
852
+ with(basic_auth: [key_name, key_secret]).
848
853
  to_return(status: 201, body: '{}', headers: { 'Content-Type' => 'application/json' })
849
854
  end
850
855
 
@@ -855,5 +860,48 @@ describe Ably::Rest::Client do
855
860
  end
856
861
  end
857
862
  end
863
+
864
+ context '#request (#RSC19*)' do
865
+ let(:client_options) { default_options.merge(key: api_key) }
866
+
867
+ context 'get' do
868
+ it 'returns an HttpPaginatedResponse object' do
869
+ response = client.request(:get, 'time')
870
+ expect(response).to be_a(Ably::Models::HttpPaginatedResponse)
871
+ expect(response.status_code).to eql(200)
872
+ end
873
+
874
+ context '404 request to invalid URL' do
875
+ it 'returns an object with 404 status code and error message' do
876
+ response = client.request(:get, 'does-not-exist')
877
+ expect(response).to be_a(Ably::Models::HttpPaginatedResponse)
878
+ expect(response.error_message).to match(/Could not find/)
879
+ expect(response.error_code).to eql(40400)
880
+ expect(response.status_code).to eql(404)
881
+ end
882
+ end
883
+
884
+ context 'paged results' do
885
+ let(:channel_name) { random_str }
886
+
887
+ it 'provides paging' do
888
+ 10.times do
889
+ client.request(:post, "/channels/#{channel_name}/publish", {}, { 'name': 'test' })
890
+ end
891
+ response = client.request(:get, "/channels/#{channel_name}/messages", { limit: 2 })
892
+ expect(response.items.length).to eql(2)
893
+ expect(response).to be_has_next
894
+ next_page = response.next
895
+ expect(next_page.items.length).to eql(2)
896
+ expect(next_page).to be_has_next
897
+ first_page_ids = response.items.map { |message| message['id'] }.uniq.sort
898
+ next_page_ids = next_page.items.map { |message| message['id'] }.uniq.sort
899
+ expect(first_page_ids).to_not eql(next_page_ids)
900
+ next_page = next_page.next
901
+ expect(next_page.items.length).to eql(2)
902
+ end
903
+ end
904
+ end
905
+ end
858
906
  end
859
907
  end