ably 0.8.14 → 0.8.15
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +48 -61
- data/README.md +6 -0
- data/ably.gemspec +1 -1
- data/lib/ably/models/http_paginated_response.rb +90 -0
- data/lib/ably/models/paginated_result.rb +5 -0
- data/lib/ably/modules/event_emitter.rb +30 -15
- data/lib/ably/modules/model_common.rb +25 -0
- data/lib/ably/realtime/channel/channel_manager.rb +3 -3
- data/lib/ably/realtime/client.rb +13 -0
- data/lib/ably/realtime/client/incoming_message_dispatcher.rb +2 -2
- data/lib/ably/realtime/presence/members_map.rb +3 -3
- data/lib/ably/rest/client.rb +60 -3
- data/lib/ably/version.rb +1 -1
- data/spec/acceptance/realtime/auth_spec.rb +29 -0
- data/spec/acceptance/realtime/channel_spec.rb +8 -6
- data/spec/acceptance/realtime/client_spec.rb +52 -0
- data/spec/acceptance/realtime/connection_spec.rb +44 -8
- data/spec/acceptance/realtime/presence_spec.rb +79 -38
- data/spec/acceptance/rest/channel_spec.rb +2 -4
- data/spec/acceptance/rest/client_spec.rb +69 -21
- data/spec/acceptance/rest/presence_spec.rb +10 -12
- data/spec/unit/models/http_paginated_result_spec.rb +380 -0
- data/spec/unit/modules/event_emitter_spec.rb +109 -51
- data/spec/unit/realtime/presence_spec.rb +3 -3
- metadata +10 -8
@@ -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
|
619
|
-
channel.publish('event', 'data')
|
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
|
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')
|
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')
|
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')
|
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
|
-
|
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
|
-
|
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.
|
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
|
-
|
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
|
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}")
|
684
|
-
|
685
|
-
|
695
|
+
presence_client_one.enter_client("client:#{index}")
|
696
|
+
end
|
697
|
+
end
|
686
698
|
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
|
691
|
-
|
692
|
-
|
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 |
|
701
|
-
EventMachine.add_timer(
|
702
|
-
presence_client_one.enter_client
|
703
|
-
|
704
|
-
|
705
|
-
|
706
|
-
|
707
|
-
|
708
|
-
|
709
|
-
|
710
|
-
|
711
|
-
|
712
|
-
|
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
|
-
|
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
|
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
|
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
|
1366
|
-
|
1367
|
-
|
1368
|
-
|
1369
|
-
|
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
|
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
|
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)
|
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)
|
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: :
|
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
|
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://#{
|
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://#{
|
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://#{
|
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://#{
|
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://#{
|
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://#{
|
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://#{
|
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://#{
|
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://#{
|
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://#{
|
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://#{
|
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://#{
|
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://#{
|
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://#{
|
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://#{
|
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://#{
|
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://#{
|
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://#{
|
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('://', "
|
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
|