ably 1.1.6 → 1.2.0

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 (67) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/check.yml +15 -1
  3. data/CHANGELOG.md +131 -0
  4. data/COPYRIGHT +1 -1
  5. data/README.md +14 -2
  6. data/SPEC.md +0 -7
  7. data/UPDATING.md +30 -0
  8. data/ably.gemspec +12 -7
  9. data/lib/ably/agent.rb +3 -0
  10. data/lib/ably/auth.rb +3 -3
  11. data/lib/ably/exceptions.rb +6 -0
  12. data/lib/ably/models/channel_options.rb +97 -0
  13. data/lib/ably/models/connection_details.rb +8 -0
  14. data/lib/ably/models/delta_extras.rb +29 -0
  15. data/lib/ably/models/error_info.rb +6 -2
  16. data/lib/ably/models/idiomatic_ruby_wrapper.rb +4 -0
  17. data/lib/ably/models/message.rb +28 -3
  18. data/lib/ably/models/presence_message.rb +14 -0
  19. data/lib/ably/models/protocol_message.rb +29 -12
  20. data/lib/ably/models/token_details.rb +7 -2
  21. data/lib/ably/modules/channels_collection.rb +22 -2
  22. data/lib/ably/modules/conversions.rb +34 -0
  23. data/lib/ably/realtime/channel/channel_manager.rb +18 -6
  24. data/lib/ably/realtime/channel/channel_state_machine.rb +10 -1
  25. data/lib/ably/realtime/channel/publisher.rb +6 -0
  26. data/lib/ably/realtime/channel.rb +54 -22
  27. data/lib/ably/realtime/channels.rb +1 -1
  28. data/lib/ably/realtime/client/incoming_message_dispatcher.rb +14 -6
  29. data/lib/ably/realtime/connection/connection_manager.rb +13 -4
  30. data/lib/ably/realtime/connection/connection_state_machine.rb +4 -0
  31. data/lib/ably/realtime/connection.rb +2 -2
  32. data/lib/ably/rest/channel.rb +31 -31
  33. data/lib/ably/rest/client.rb +27 -12
  34. data/lib/ably/util/crypto.rb +1 -1
  35. data/lib/ably/version.rb +2 -14
  36. data/lib/ably.rb +1 -0
  37. data/spec/acceptance/realtime/auth_spec.rb +1 -1
  38. data/spec/acceptance/realtime/channel_history_spec.rb +25 -0
  39. data/spec/acceptance/realtime/channel_spec.rb +466 -21
  40. data/spec/acceptance/realtime/channels_spec.rb +59 -7
  41. data/spec/acceptance/realtime/connection_failures_spec.rb +59 -2
  42. data/spec/acceptance/realtime/connection_spec.rb +256 -28
  43. data/spec/acceptance/realtime/message_spec.rb +77 -0
  44. data/spec/acceptance/realtime/presence_history_spec.rb +3 -1
  45. data/spec/acceptance/realtime/presence_spec.rb +31 -159
  46. data/spec/acceptance/rest/auth_spec.rb +18 -0
  47. data/spec/acceptance/rest/channel_spec.rb +84 -9
  48. data/spec/acceptance/rest/channels_spec.rb +23 -6
  49. data/spec/acceptance/rest/client_spec.rb +25 -21
  50. data/spec/acceptance/rest/message_spec.rb +61 -3
  51. data/spec/lib/unit/models/channel_options_spec.rb +52 -0
  52. data/spec/shared/model_behaviour.rb +1 -1
  53. data/spec/spec_helper.rb +11 -2
  54. data/spec/support/test_app.rb +1 -1
  55. data/spec/unit/models/delta_extras_spec.rb +14 -0
  56. data/spec/unit/models/error_info_spec.rb +17 -1
  57. data/spec/unit/models/message_spec.rb +97 -0
  58. data/spec/unit/models/presence_message_spec.rb +49 -0
  59. data/spec/unit/models/protocol_message_spec.rb +125 -27
  60. data/spec/unit/models/token_details_spec.rb +14 -0
  61. data/spec/unit/realtime/channel_spec.rb +3 -2
  62. data/spec/unit/realtime/channels_spec.rb +53 -15
  63. data/spec/unit/realtime/incoming_message_dispatcher_spec.rb +38 -0
  64. data/spec/unit/rest/channel_spec.rb +44 -1
  65. data/spec/unit/rest/channels_spec.rb +81 -14
  66. data/spec/unit/rest/client_spec.rb +47 -0
  67. metadata +60 -24
@@ -570,7 +570,7 @@ describe Ably::Realtime::Connection, 'failures', :event_machine do
570
570
  end
571
571
 
572
572
  context 'when DISCONNECTED ProtocolMessage received from the server' do
573
- it 'reconnects automatically and immediately' do
573
+ it 'reconnects automatically and immediately (#RTN15a)' do
574
574
  fail_if_suspended_or_failed
575
575
 
576
576
  connection.once(:connected) do
@@ -590,6 +590,61 @@ describe Ably::Realtime::Connection, 'failures', :event_machine do
590
590
  end
591
591
  end
592
592
 
593
+ context 'when protocolMessage contains token error' do
594
+ context "library does not have a means to renew the token (#RTN15h1)" do
595
+ let(:auth_url) { 'https://echo.ably.io/createJWT' }
596
+ let(:token) { Faraday.get("#{auth_url}?keyName=#{key_name}&keySecret=#{key_secret}").body }
597
+ let(:client_options) { default_options.merge(token: token, log_level: :none) }
598
+
599
+ let(:error_message) { 'error_message' }
600
+
601
+ it 'moves connection state to failed' do
602
+ connection.on(:failed) do |connection_state_change|
603
+ expect(connection.error_reason.message).to eq(error_message)
604
+ stop_reactor
605
+ end
606
+
607
+ connection.on(:connected) do
608
+ protocol_message = Ably::Models::ProtocolMessage.new(action: Ably::Models::ProtocolMessage::ACTION.Disconnected.to_i, error: { code: 40140, message: error_message })
609
+ connection.__incoming_protocol_msgbus__.publish :protocol_message, protocol_message
610
+ end
611
+
612
+ connection.connect
613
+ end
614
+ end
615
+
616
+ context "library have a means to renew the token (#RTN15h2)" do
617
+ let(:client_options) { default_options.merge(log_level: :none) }
618
+ let(:error_message) { 'error_message' }
619
+
620
+ def send_disconnect_message
621
+ protocol_message = Ably::Models::ProtocolMessage.new(action: Ably::Models::ProtocolMessage::ACTION.Disconnected.to_i, error: { code: 40140, message: error_message })
622
+ connection.__incoming_protocol_msgbus__.publish :protocol_message, protocol_message
623
+ end
624
+
625
+ it 'attempts to reconnect' do
626
+ connection.on(:failed) do |connection_state_change|
627
+ raise "Connection shouldn't be failed"
628
+ end
629
+
630
+ connection.on(:connected) do
631
+ connection.once(:connecting) do
632
+ connection.once(:disconnected) do
633
+ expect(connection.error_reason.message).to eq(error_message)
634
+ stop_reactor
635
+ end
636
+
637
+ send_disconnect_message
638
+ end
639
+
640
+ send_disconnect_message
641
+ end
642
+
643
+ connection.connect
644
+ end
645
+ end
646
+ end
647
+
593
648
  context 'connection state freshness is monitored' do
594
649
  it 'resumes connections when disconnected within the connection_state_ttl period (#RTN15g)' do
595
650
  connection.once(:connected) do
@@ -1320,7 +1375,9 @@ describe Ably::Realtime::Connection, 'failures', :event_machine do
1320
1375
  end)
1321
1376
  end
1322
1377
 
1323
- it 'triggers a re-authentication and then resumes the connection' do
1378
+ xit 'triggers a re-authentication and then resumes the connection' do
1379
+ # [PENDING] After sandbox env update connection isn't found and a new connection is created. Spec fails
1380
+ #
1324
1381
  connection.once(:connected) do
1325
1382
  connection_id = connection.id
1326
1383
 
@@ -482,6 +482,118 @@ describe Ably::Realtime::Connection, :event_machine do
482
482
  end
483
483
  end
484
484
 
485
+ context 'when explicitly reconnecting disconnected/suspended connection in retry (#RTN11c)' do
486
+ let(:close_connection_proc) do
487
+ lambda do
488
+ EventMachine.add_timer(0.001) do
489
+ if connection.transport.nil?
490
+ close_connection_proc.call
491
+ else
492
+ connection.transport.close_connection_after_writing
493
+ end
494
+ end
495
+ end
496
+ end
497
+
498
+ context 'when suspended' do
499
+ let(:suspended_retry_timeout) { 60 }
500
+ let(:client_options) do
501
+ default_options.merge(
502
+ disconnected_retry_timeout: 0.02,
503
+ suspended_retry_timeout: suspended_retry_timeout,
504
+ connection_state_ttl: 0
505
+ )
506
+ end
507
+
508
+ it 'reconnects immediately' do
509
+ connection.once(:connecting) { close_connection_proc.call }
510
+
511
+ connection.on(:suspended) do |connection_state_change|
512
+ if connection_state_change.retry_in.zero?
513
+ # Exhausting immediate retries
514
+ connection.once(:connecting) { close_connection_proc.call }
515
+ else
516
+ suspended_at = Time.now.to_f
517
+ connection.on(:connected) do
518
+ expect(connection_state_change.retry_in).to eq(suspended_retry_timeout)
519
+ expect(connection.state).to eq(:connected)
520
+ expect(Time.now.to_f).to be_within(4).of(suspended_at)
521
+ stop_reactor
522
+ end
523
+ end
524
+
525
+ connection.connect
526
+ end
527
+
528
+ connection.connect
529
+ end
530
+ end
531
+
532
+ context 'when disconnected' do
533
+ let(:retry_timeout) { 60 }
534
+ let(:client_options) do
535
+ default_options.merge(
536
+ disconnected_retry_timeout: retry_timeout,
537
+ suspended_retry_timeout: retry_timeout,
538
+ connection_state_ttl: 0
539
+ )
540
+ end
541
+
542
+ it 'reconnects immediately' do
543
+ connection.once(:connected) do
544
+ connection.on(:disconnected) do |connection_state_change|
545
+ disconnected_at = Time.now.to_f
546
+ connection.on(:connected) do
547
+ if connection_state_change.retry_in.zero?
548
+ # Exhausting immediate retries
549
+ close_connection_proc.call
550
+ else
551
+ expect(connection_state_change.retry_in).to eq(retry_timeout)
552
+ expect(connection.state).to eq(:connected)
553
+ expect(Time.now.to_f).to be_within(4).of(disconnected_at)
554
+ stop_reactor
555
+ end
556
+ end
557
+ connection.connect
558
+ end
559
+
560
+ close_connection_proc.call
561
+ end
562
+
563
+ connection.connect
564
+ end
565
+ end
566
+ end
567
+
568
+ context 'when reconnecting a failed connection' do
569
+ let(:channel) { client.channel(random_str) }
570
+ let(:client_options) { default_options.merge(log_level: :none) }
571
+
572
+ it 'transitions all channels state to initialized and cleares error_reason' do
573
+ connection.on(:failed) do |connection_state_change|
574
+ expect(connection.error_reason).to be_a(Ably::Exceptions::BaseAblyException)
575
+ expect(channel.error_reason).to be_a(Ably::Exceptions::BaseAblyException)
576
+ expect(channel).to be_failed
577
+
578
+ connection.on(:connected) do
579
+ expect(connection.error_reason).to eq(nil)
580
+ expect(channel).to be_initialized
581
+ expect(channel.error_reason).to eq(nil)
582
+ stop_reactor
583
+ end
584
+
585
+ connection.connect
586
+ end
587
+
588
+ connection.connect do
589
+ channel.attach do
590
+ error = Ably::Exceptions::ConnectionFailed.new('forced failure', 500, 50000)
591
+ client.connection.manager.error_received_from_server error
592
+ end
593
+ end
594
+ end
595
+ end
596
+
485
597
  context 'with invalid auth details' do
486
598
  let(:client_options) { default_options.merge(key: 'this.is:invalid', log_level: :none) }
487
599
 
@@ -693,6 +805,18 @@ describe Ably::Realtime::Connection, :event_machine do
693
805
  end
694
806
 
695
807
  context '#close' do
808
+ let(:close_connection_proc) do
809
+ lambda do
810
+ EventMachine.add_timer(0.001) do
811
+ if connection.transport.nil?
812
+ close_connection_proc.call
813
+ else
814
+ connection.transport.close_connection_after_writing
815
+ end
816
+ end
817
+ end
818
+ end
819
+
696
820
  it 'returns a SafeDeferrable that catches exceptions in callbacks and logs them' do
697
821
  connection.connect do
698
822
  expect(connection.close).to be_a(Ably::Util::SafeDeferrable)
@@ -754,6 +878,56 @@ describe Ably::Realtime::Connection, :event_machine do
754
878
  end
755
879
  end
756
880
 
881
+ context ':connecting RTN12f' do
882
+ context ":connected does not arrive when trying to close" do
883
+ it 'moves to closed' do
884
+ connection.on(:closed) do |state_change|
885
+ state_changes = connection.state_history.map { |t| t[:state].to_sym }
886
+
887
+ expect(state_changes).to eq([:connecting, :closing, :closed])
888
+ stop_reactor
889
+ end
890
+
891
+ connection.on(:connecting) do
892
+ connection.close
893
+ connection.__outgoing_protocol_msgbus__.unsubscribe
894
+ end
895
+
896
+ connection.connect
897
+ end
898
+ end
899
+
900
+ context ":connected arrive when trying to close" do
901
+ let(:protocol_message_attributes) do
902
+ {
903
+ action: Ably::Models::ProtocolMessage::ACTION.Connected.to_i,
904
+ connection_serial: 55,
905
+ connection_details: {
906
+ max_idle_interval: 2 * 1000
907
+ }
908
+ }
909
+ end
910
+
911
+ it 'moves to connected and then to closed' do
912
+ connection.on(:closed) do |state_change|
913
+ state_changes = connection.state_history.map { |t| t[:state].to_sym }
914
+
915
+ expect(state_changes).to eq([:connecting, :connected, :closing, :closed])
916
+ stop_reactor
917
+ end
918
+
919
+ connection.on(:connecting) do
920
+ connection.__outgoing_protocol_msgbus__.unsubscribe
921
+
922
+ connection.__incoming_protocol_msgbus__.publish :protocol_message, Ably::Models::ProtocolMessage.new(protocol_message_attributes)
923
+ connection.close
924
+ end
925
+
926
+ connection.connect
927
+ end
928
+ end
929
+ end
930
+
757
931
  context ':connected' do
758
932
  it 'changes the connection state to :closing and waits for the server to confirm connection is :closed with a ProtocolMessage' do
759
933
  connection.on(:connected) do
@@ -800,6 +974,81 @@ describe Ably::Realtime::Connection, :event_machine do
800
974
  end
801
975
  end
802
976
  end
977
+
978
+ context ':suspended RTN12d' do
979
+ let(:suspended_retry_timeout) { 60 }
980
+ let(:client_options) do
981
+ default_options.merge(
982
+ disconnected_retry_timeout: 0.02,
983
+ suspended_retry_timeout: suspended_retry_timeout,
984
+ connection_state_ttl: 0
985
+ )
986
+ end
987
+
988
+ it 'immediatly closes connection' do
989
+ connection.on(:connecting) { close_connection_proc.call }
990
+ connection.on(:suspended) do |connection_state_change|
991
+ if connection_state_change.retry_in.zero?
992
+ # Exhausting immediate retries
993
+ connection.once(:connecting) { close_connection_proc.call }
994
+ else
995
+ suspended_at = Time.now.to_f
996
+ connection.on(:closed) do
997
+ expect(connection_state_change.retry_in).to eq(suspended_retry_timeout)
998
+ expect(connection.state).to eq(:closed)
999
+ expect(Time.now.to_f).to be_within(4).of(suspended_at)
1000
+ stop_reactor
1001
+ end
1002
+
1003
+ connection.close
1004
+ end
1005
+
1006
+ connection.connect
1007
+ end
1008
+
1009
+ connection.connect
1010
+ end
1011
+ end
1012
+
1013
+ context ':disconnected RTN12d' do
1014
+ let(:retry_timeout) { 60 }
1015
+ let(:client_options) do
1016
+ default_options.merge(
1017
+ disconnected_retry_timeout: retry_timeout,
1018
+ suspended_retry_timeout: retry_timeout,
1019
+ connection_state_ttl: 0
1020
+ )
1021
+ end
1022
+
1023
+ it 'immediatly closes connection' do
1024
+ connection.once(:connected) do
1025
+ connection.on(:disconnected) do |connection_state_change|
1026
+ disconnected_at = Time.now.to_f
1027
+ connection.on(:connected) do
1028
+ if connection_state_change.retry_in.zero?
1029
+ # Exhausting immediate retries
1030
+ close_connection_proc.call
1031
+ else
1032
+ connection.once(:closed) do
1033
+ expect(connection_state_change.retry_in).to eq(retry_timeout)
1034
+ expect(connection.state).to eq(:closed)
1035
+ expect(Time.now.to_f).to be_within(4).of(disconnected_at)
1036
+ stop_reactor
1037
+ end
1038
+
1039
+ connection.close
1040
+ end
1041
+ end
1042
+
1043
+ connection.connect
1044
+ end
1045
+
1046
+ close_connection_proc.call
1047
+ end
1048
+
1049
+ connection.connect
1050
+ end
1051
+ end
803
1052
  end
804
1053
  end
805
1054
 
@@ -1454,7 +1703,7 @@ describe Ably::Realtime::Connection, :event_machine do
1454
1703
  let(:client_options) { default_options.merge(tls: true) }
1455
1704
 
1456
1705
  it 'uses TLS for the Internet check to https://internet-up.ably-realtime.com/is-the-internet-up.txt' do
1457
- expect(EventMachine::HttpRequest).to receive(:new).with('https://internet-up.ably-realtime.com/is-the-internet-up.txt').and_return(http_request)
1706
+ expect(EventMachine::HttpRequest).to receive(:new).with('https://internet-up.ably-realtime.com/is-the-internet-up.txt', { tls: { verify_peer: true } }).and_return(http_request)
1458
1707
  connection.internet_up?
1459
1708
  stop_reactor
1460
1709
  end
@@ -1464,7 +1713,7 @@ describe Ably::Realtime::Connection, :event_machine do
1464
1713
  let(:client_options) { default_options.merge(tls: false, use_token_auth: true) }
1465
1714
 
1466
1715
  it 'uses TLS for the Internet check to http://internet-up.ably-realtime.com/is-the-internet-up.txt' do
1467
- expect(EventMachine::HttpRequest).to receive(:new).with('http://internet-up.ably-realtime.com/is-the-internet-up.txt').and_return(http_request)
1716
+ expect(EventMachine::HttpRequest).to receive(:new).with('http://internet-up.ably-realtime.com/is-the-internet-up.txt', { tls: { verify_peer: true } }).and_return(http_request)
1468
1717
  connection.internet_up?
1469
1718
  stop_reactor
1470
1719
  end
@@ -1478,7 +1727,7 @@ describe Ably::Realtime::Connection, :event_machine do
1478
1727
  let(:client_options) { default_options.merge(tls: true) }
1479
1728
 
1480
1729
  it 'checks the Internet up URL over TLS' do
1481
- expect(EventMachine::HttpRequest).to receive(:new).with("https:#{Ably::INTERNET_CHECK.fetch(:url)}").and_return(double('request', get: EventMachine::DefaultDeferrable.new))
1730
+ expect(EventMachine::HttpRequest).to receive(:new).with("https:#{Ably::INTERNET_CHECK.fetch(:url)}", { tls: { verify_peer: true } }).and_return(double('request', get: EventMachine::DefaultDeferrable.new))
1482
1731
  connection.internet_up?
1483
1732
  stop_reactor
1484
1733
  end
@@ -1488,7 +1737,7 @@ describe Ably::Realtime::Connection, :event_machine do
1488
1737
  let(:client_options) { default_options.merge(tls: false, use_token_auth: true) }
1489
1738
 
1490
1739
  it 'checks the Internet up URL over TLS' do
1491
- expect(EventMachine::HttpRequest).to receive(:new).with("http:#{Ably::INTERNET_CHECK.fetch(:url)}").and_return(double('request', get: EventMachine::DefaultDeferrable.new))
1740
+ expect(EventMachine::HttpRequest).to receive(:new).with("http:#{Ably::INTERNET_CHECK.fetch(:url)}", { tls: { verify_peer: true } }).and_return(double('request', get: EventMachine::DefaultDeferrable.new))
1492
1741
  connection.internet_up?
1493
1742
  stop_reactor
1494
1743
  end
@@ -1834,41 +2083,20 @@ describe Ably::Realtime::Connection, :event_machine do
1834
2083
  it 'sends the protocol version param v (#G4, #RTN2f)' do
1835
2084
  expect(EventMachine).to receive(:connect) do |host, port, transport, object, url|
1836
2085
  uri = URI.parse(url)
1837
- expect(CGI::parse(uri.query)['v'][0]).to eql('1.1')
2086
+ expect(CGI::parse(uri.query)['v'][0]).to eql('1.2')
1838
2087
  stop_reactor
1839
2088
  end
1840
2089
  client
1841
2090
  end
1842
2091
 
1843
- it 'sends the lib version param lib (#RTN2g)' do
2092
+ it 'sends the lib version param agent (#RCS7d)' do
1844
2093
  expect(EventMachine).to receive(:connect) do |host, port, transport, object, url|
1845
2094
  uri = URI.parse(url)
1846
- expect(CGI::parse(uri.query)['lib'][0]).to match(/^ruby-1\.1\.\d+(-[\w\.]+)?+$/)
2095
+ expect(CGI::parse(uri.query)['agent'][0]).to match(/^ably-ruby\/\d\.\d\.\d ruby\/\d\.\d\.\d$/)
1847
2096
  stop_reactor
1848
2097
  end
1849
2098
  client
1850
2099
  end
1851
-
1852
- context 'with variant' do
1853
- let(:variant) { 'foo' }
1854
-
1855
- before do
1856
- Ably.lib_variant = variant
1857
- end
1858
-
1859
- after do
1860
- Ably.lib_variant = nil
1861
- end
1862
-
1863
- it 'sends the lib version param lib with the variant (#RTN2g + #RSC7b)' do
1864
- expect(EventMachine).to receive(:connect) do |host, port, transport, object, url|
1865
- uri = URI.parse(url)
1866
- expect(CGI::parse(uri.query)['lib'][0]).to match(/^ruby-#{variant}-1\.1\.\d+(-[\w\.]+)?$/)
1867
- stop_reactor
1868
- end
1869
- client
1870
- end
1871
- end
1872
2100
  end
1873
2101
 
1874
2102
  context 'transport_params (#RTC1f)' do
@@ -75,6 +75,83 @@ describe 'Ably::Realtime::Channel Message', :event_machine do
75
75
  end
76
76
  end
77
77
 
78
+ context 'a single Message object (#RSL1a)' do
79
+ let(:name) { random_str }
80
+ let(:data) { random_str }
81
+ let(:message) { Ably::Models::Message.new(name: name, data: data) }
82
+
83
+ it 'publishes the message' do
84
+ channel.attach
85
+ channel.publish(message)
86
+ channel.subscribe do |msg|
87
+ expect(msg.name).to eq(message.name)
88
+ expect(msg.data).to eq(message.data)
89
+ stop_reactor
90
+ end
91
+ end
92
+ end
93
+
94
+ context 'an array of Message objects (#RSL1a)' do
95
+ let(:data) { random_str }
96
+ let(:message1) { Ably::Models::Message.new(name: random_str, data: data) }
97
+ let(:message2) { Ably::Models::Message.new(name: random_str, data: data) }
98
+ let(:message3) { Ably::Models::Message.new(name: random_str, data: data) }
99
+
100
+ it 'publishes three messages' do
101
+ channel.attach
102
+ channel.publish([message1, message2, message3])
103
+ counter = 0
104
+ channel.subscribe do |message|
105
+ counter += 1
106
+ expect(message.data).to eq(data)
107
+ expect(message.name).to eq(message1.name) if counter == 1
108
+ expect(message.name).to eq(message2.name) if counter == 2
109
+ if counter == 3
110
+ expect(message.name).to eq(message3.name)
111
+ stop_reactor
112
+ end
113
+ end
114
+ end
115
+ end
116
+
117
+ context 'an array of hashes (#RSL1a)' do
118
+ let(:data) { random_str }
119
+ let(:message1) { { name: random_str, data: data } }
120
+ let(:message2) { { name: random_str, data: data } }
121
+ let(:message3) { { name: random_str, data: data } }
122
+
123
+ it 'publishes three messages' do
124
+ channel.attach
125
+ channel.publish([message1, message2, message3])
126
+ counter = 0
127
+ channel.subscribe do |message|
128
+ counter += 1
129
+ expect(message.data).to eq(data)
130
+ expect(message.name).to eq(message1[:name]) if counter == 1
131
+ expect(message.name).to eq(message2[:name]) if counter == 2
132
+ if counter == 3
133
+ expect(message.name).to eq(message3[:name])
134
+ stop_reactor
135
+ end
136
+ end
137
+ end
138
+ end
139
+
140
+ context 'a name with data payload (#RSL1a, #RSL1b)' do
141
+ let(:name) { random_str }
142
+ let(:data) { random_str }
143
+
144
+ it 'publishes a message' do
145
+ channel.attach
146
+ channel.publish(name, data)
147
+ channel.subscribe do |message|
148
+ expect(message.name).to eql(name)
149
+ expect(message.data).to eq(data)
150
+ stop_reactor
151
+ end
152
+ end
153
+ end
154
+
78
155
  context 'with supported extra payload content type (#RTL6h, #RSL6a2)' do
79
156
  let(:channel) { client.channel("pushenabled:#{random_str}") }
80
157
 
@@ -20,7 +20,7 @@ describe Ably::Realtime::Presence, 'history', :event_machine do
20
20
 
21
21
  it 'provides up to the moment presence history' do
22
22
  presence_client_one.enter(data) do
23
- presence_client_one.leave(leave_data) do
23
+ presence_client_one.subscribe(:leave) do
24
24
  presence_client_one.history do |history_page|
25
25
  expect(history_page).to be_a(Ably::Models::PaginatedResult)
26
26
  expect(history_page.items.count).to eql(2)
@@ -36,6 +36,8 @@ describe Ably::Realtime::Presence, 'history', :event_machine do
36
36
  stop_reactor
37
37
  end
38
38
  end
39
+
40
+ presence_client_one.leave(leave_data)
39
41
  end
40
42
  end
41
43