ably-rest 1.2.5 → 1.2.7

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 (56) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +11 -8
  3. data/lib/submodules/ably-ruby/.github/workflows/check.yml +2 -1
  4. data/lib/submodules/ably-ruby/CHANGELOG.md +25 -0
  5. data/lib/submodules/ably-ruby/README.md +24 -7
  6. data/lib/submodules/ably-ruby/SPEC.md +1738 -869
  7. data/lib/submodules/ably-ruby/ably.gemspec +1 -1
  8. data/lib/submodules/ably-ruby/lib/ably/auth.rb +19 -11
  9. data/lib/submodules/ably-ruby/lib/ably/models/protocol_message.rb +4 -26
  10. data/lib/submodules/ably-ruby/lib/ably/modules/safe_deferrable.rb +2 -2
  11. data/lib/submodules/ably-ruby/lib/ably/modules/state_emitter.rb +1 -1
  12. data/lib/submodules/ably-ruby/lib/ably/realtime/auth.rb +4 -0
  13. data/lib/submodules/ably-ruby/lib/ably/realtime/channel/channel_manager.rb +51 -48
  14. data/lib/submodules/ably-ruby/lib/ably/realtime/channel/channel_properties.rb +9 -0
  15. data/lib/submodules/ably-ruby/lib/ably/realtime/channel/channel_state_machine.rb +2 -0
  16. data/lib/submodules/ably-ruby/lib/ably/realtime/channel.rb +4 -3
  17. data/lib/submodules/ably-ruby/lib/ably/realtime/channels.rb +20 -0
  18. data/lib/submodules/ably-ruby/lib/ably/realtime/client/incoming_message_dispatcher.rb +14 -13
  19. data/lib/submodules/ably-ruby/lib/ably/realtime/client.rb +14 -6
  20. data/lib/submodules/ably-ruby/lib/ably/realtime/connection/connection_manager.rb +21 -22
  21. data/lib/submodules/ably-ruby/lib/ably/realtime/connection.rb +77 -109
  22. data/lib/submodules/ably-ruby/lib/ably/realtime/presence/members_map.rb +41 -92
  23. data/lib/submodules/ably-ruby/lib/ably/realtime/presence/presence_manager.rb +12 -17
  24. data/lib/submodules/ably-ruby/lib/ably/realtime/presence.rb +15 -6
  25. data/lib/submodules/ably-ruby/lib/ably/realtime/push.rb +0 -27
  26. data/lib/submodules/ably-ruby/lib/ably/realtime/recovery_key_context.rb +36 -0
  27. data/lib/submodules/ably-ruby/lib/ably/rest/client.rb +4 -6
  28. data/lib/submodules/ably-ruby/lib/ably/rest/push/admin.rb +1 -1
  29. data/lib/submodules/ably-ruby/lib/ably/rest/push.rb +0 -19
  30. data/lib/submodules/ably-ruby/lib/ably/util/ably_extensions.rb +29 -0
  31. data/lib/submodules/ably-ruby/lib/ably/util/crypto.rb +2 -2
  32. data/lib/submodules/ably-ruby/lib/ably/util/safe_deferrable.rb +1 -1
  33. data/lib/submodules/ably-ruby/lib/ably/version.rb +5 -7
  34. data/lib/submodules/ably-ruby/spec/acceptance/realtime/auth_spec.rb +0 -7
  35. data/lib/submodules/ably-ruby/spec/acceptance/realtime/channel_history_spec.rb +8 -12
  36. data/lib/submodules/ably-ruby/spec/acceptance/realtime/channel_spec.rb +474 -300
  37. data/lib/submodules/ably-ruby/spec/acceptance/realtime/client_spec.rb +1 -1
  38. data/lib/submodules/ably-ruby/spec/acceptance/realtime/connection_failures_spec.rb +8 -25
  39. data/lib/submodules/ably-ruby/spec/acceptance/realtime/connection_spec.rb +28 -120
  40. data/lib/submodules/ably-ruby/spec/acceptance/realtime/message_spec.rb +24 -53
  41. data/lib/submodules/ably-ruby/spec/acceptance/realtime/presence_spec.rb +123 -92
  42. data/lib/submodules/ably-ruby/spec/acceptance/rest/channel_spec.rb +2 -2
  43. data/lib/submodules/ably-ruby/spec/acceptance/rest/client_spec.rb +9 -2
  44. data/lib/submodules/ably-ruby/spec/acceptance/rest/message_spec.rb +8 -11
  45. data/lib/submodules/ably-ruby/spec/acceptance/rest/push_admin_spec.rb +20 -15
  46. data/lib/submodules/ably-ruby/spec/shared/client_initializer_behaviour.rb +1 -1
  47. data/lib/submodules/ably-ruby/spec/support/markdown_spec_formatter.rb +1 -1
  48. data/lib/submodules/ably-ruby/spec/unit/models/protocol_message_spec.rb +0 -86
  49. data/lib/submodules/ably-ruby/spec/unit/models/token_details_spec.rb +4 -2
  50. data/lib/submodules/ably-ruby/spec/unit/realtime/channels_spec.rb +1 -1
  51. data/lib/submodules/ably-ruby/spec/unit/realtime/connection_spec.rb +0 -30
  52. data/lib/submodules/ably-ruby/spec/unit/realtime/recovery_key_context_spec.rb +36 -0
  53. data/lib/submodules/ably-ruby/spec/unit/util/crypto_spec.rb +15 -15
  54. metadata +5 -4
  55. data/lib/submodules/ably-ruby/spec/acceptance/realtime/push_spec.rb +0 -27
  56. data/lib/submodules/ably-ruby/spec/acceptance/rest/push_spec.rb +0 -25
@@ -342,8 +342,10 @@ describe Ably::Realtime::Channel, :event_machine do
342
342
  channel.attach
343
343
  end
344
344
 
345
- channel.attach do
346
- channel.detach
345
+ client.connection.once :connected do
346
+ channel.attach do
347
+ channel.detach
348
+ end
347
349
  end
348
350
  end
349
351
  end
@@ -430,9 +432,35 @@ describe Ably::Realtime::Channel, :event_machine do
430
432
  end
431
433
 
432
434
  context 'with connection state' do
435
+
436
+ sent_attach_messages = []
437
+ received_attached_messages = []
438
+ before(:each) do
439
+ sent_attach_messages = []
440
+ received_attached_messages = []
441
+ client.connection.__outgoing_protocol_msgbus__.subscribe do |message|
442
+ if message.action == :attach
443
+ sent_attach_messages << message
444
+ end
445
+ end
446
+ client.connection.__incoming_protocol_msgbus__.subscribe do |message|
447
+ if message.action == :attached
448
+ received_attached_messages << message
449
+ end
450
+ end
451
+ end
452
+
453
+ # Should send/receive attach/attached message only once
454
+ # No duplicates should be sent or received
455
+ let(:check_for_attach_messages) do
456
+ expect(sent_attach_messages.size).to eq(1)
457
+ expect(received_attached_messages.size).to eq(1)
458
+ end
459
+
433
460
  it 'is initialized (#RTL4i)' do
434
461
  expect(connection).to be_initialized
435
462
  channel.attach do
463
+ check_for_attach_messages
436
464
  stop_reactor
437
465
  end
438
466
  end
@@ -440,6 +468,7 @@ describe Ably::Realtime::Channel, :event_machine do
440
468
  it 'is connecting (#RTL4i)' do
441
469
  connection.once(:connecting) do
442
470
  channel.attach do
471
+ check_for_attach_messages
443
472
  stop_reactor
444
473
  end
445
474
  end
@@ -449,6 +478,7 @@ describe Ably::Realtime::Channel, :event_machine do
449
478
  connection.once(:connected) do
450
479
  connection.once(:disconnected) do
451
480
  channel.attach do
481
+ check_for_attach_messages
452
482
  stop_reactor
453
483
  end
454
484
  end
@@ -467,7 +497,9 @@ describe Ably::Realtime::Channel, :event_machine do
467
497
  stop_reactor
468
498
  end
469
499
 
470
- channel.attach
500
+ client.connection.once :connected do
501
+ channel.attach
502
+ end
471
503
  end
472
504
  end
473
505
 
@@ -488,7 +520,9 @@ describe Ably::Realtime::Channel, :event_machine do
488
520
  channel.detach
489
521
  end
490
522
 
491
- channel.attach
523
+ client.connection.once :connected do
524
+ channel.attach
525
+ end
492
526
  end
493
527
  end
494
528
  end
@@ -497,23 +531,29 @@ describe Ably::Realtime::Channel, :event_machine do
497
531
  describe '#detach' do
498
532
  context 'when state is :attached' do
499
533
  it 'it detaches from a channel (#RTL5d)' do
500
- channel.attach do
534
+ channel.once :attached do
501
535
  channel.detach
502
536
  channel.on(:detached) do
503
537
  expect(channel.state).to eq(:detached)
504
538
  stop_reactor
505
539
  end
506
540
  end
541
+ connection.once :connected do
542
+ channel.attach
543
+ end
507
544
  end
508
545
 
509
546
  it 'detaches from a channel and calls the provided block (#RTL5d, #RTL5e)' do
510
- channel.attach do
547
+ channel.once :attached do
511
548
  expect(channel.state).to eq(:attached)
512
549
  channel.detach do
513
550
  expect(channel.state).to eq(:detached)
514
551
  stop_reactor
515
552
  end
516
553
  end
554
+ connection.once :connected do
555
+ channel.attach
556
+ end
517
557
  end
518
558
 
519
559
  it 'emits :detaching then :detached events' do
@@ -523,26 +563,34 @@ describe Ably::Realtime::Channel, :event_machine do
523
563
  end
524
564
  end
525
565
 
526
- channel.attach do
527
- channel.detach
566
+ connection.once :connected do
567
+ channel.attach do
568
+ channel.detach
569
+ end
528
570
  end
529
571
  end
530
572
 
531
573
  it 'returns a SafeDeferrable that catches exceptions in callbacks and logs them' do
532
- channel.attach do
574
+ channel.once :attached do
533
575
  expect(channel.detach).to be_a(Ably::Util::SafeDeferrable)
534
576
  stop_reactor
535
577
  end
578
+ connection.once :connected do
579
+ channel.attach
580
+ end
536
581
  end
537
582
 
538
583
  it 'calls the Deferrable callback on success' do
539
- channel.attach do
584
+ channel.once :attached do
540
585
  channel.detach.callback do
541
586
  expect(channel).to be_a(Ably::Realtime::Channel)
542
587
  expect(channel.state).to eq(:detached)
543
588
  stop_reactor
544
589
  end
545
590
  end
591
+ connection.once :connected do
592
+ channel.attach
593
+ end
546
594
  end
547
595
 
548
596
  context 'and DETACHED message is not received within realtime request timeout' do
@@ -551,7 +599,6 @@ describe Ably::Realtime::Channel, :event_machine do
551
599
 
552
600
  it 'fails the deferrable and returns to the previous state (#RTL5f, #RTL5e)' do
553
601
  channel.attach do
554
- # don't process any incoming ProtocolMessages so the channel never becomes detached
555
602
  connection.__incoming_protocol_msgbus__.unsubscribe
556
603
  detached_requested_at = Time.now.to_i
557
604
  channel.detach do
@@ -566,6 +613,7 @@ describe Ably::Realtime::Channel, :event_machine do
566
613
  end
567
614
  end
568
615
 
616
+
569
617
  context 'when state is :failed' do
570
618
  let(:client_options) { default_options.merge(log_level: :fatal) }
571
619
 
@@ -609,15 +657,17 @@ describe Ably::Realtime::Channel, :event_machine do
609
657
  channel.detach
610
658
  end
611
659
 
612
- channel.attach do
613
- channel.detach
660
+ connection.once :connected do
661
+ channel.attach do
662
+ channel.detach
663
+ end
614
664
  end
615
665
  end
616
666
  end
617
667
 
618
668
  context 'when state is :suspended' do
619
669
  it 'moves the channel state immediately to DETACHED state (#RTL5j)' do
620
- channel.attach do
670
+ channel.once :attached do
621
671
  channel.once(:suspended) do
622
672
  channel.on do |channel_state_change|
623
673
  expect(channel_state_change.current).to eq(:detached)
@@ -632,6 +682,9 @@ describe Ably::Realtime::Channel, :event_machine do
632
682
  end
633
683
  channel.transition_state_machine :suspended
634
684
  end
685
+ connection.once :connected do
686
+ channel.attach
687
+ end
635
688
  end
636
689
  end
637
690
 
@@ -655,7 +708,7 @@ describe Ably::Realtime::Channel, :event_machine do
655
708
 
656
709
  context 'when state is :detached' do
657
710
  it 'does nothing as the channel is detached (#RTL5a)' do
658
- channel.attach do
711
+ channel.once :attached do
659
712
  channel.detach do
660
713
  expect(channel).to be_detached
661
714
  channel.on do
@@ -666,6 +719,9 @@ describe Ably::Realtime::Channel, :event_machine do
666
719
  end
667
720
  end
668
721
  end
722
+ connection.once :connected do
723
+ channel.attach
724
+ end
669
725
  end
670
726
  end
671
727
 
@@ -735,8 +791,10 @@ describe Ably::Realtime::Channel, :event_machine do
735
791
  context 'initialized' do
736
792
  it 'does the detach operation once the connection state is connected (#RTL5h)' do
737
793
  expect(connection).to be_initialized
794
+ channel.on :attaching do
795
+ channel.detach
796
+ end
738
797
  channel.attach
739
- channel.detach
740
798
  connection.once(:connected) do
741
799
  channel.once(:attached) do
742
800
  channel.once(:detached) do
@@ -750,8 +808,10 @@ describe Ably::Realtime::Channel, :event_machine do
750
808
  context 'connecting' do
751
809
  it 'does the detach operation once the connection state is connected (#RTL5h)' do
752
810
  connection.once(:connecting) do
811
+ channel.on :attaching do
812
+ channel.detach
813
+ end
753
814
  channel.attach
754
- channel.detach
755
815
  connection.once(:connected) do
756
816
  channel.once(:attached) do
757
817
  channel.once(:detached) do
@@ -877,84 +937,92 @@ describe Ably::Realtime::Channel, :event_machine do
877
937
  describe '#(RTL17)' do
878
938
  context 'when channel is initialized' do
879
939
  it 'sends messages only on attach' do
880
- expect(channel).to be_initialized
881
- channel.publish('event', payload)
940
+ connection.once :connected do
941
+ expect(channel).to be_initialized
942
+ channel.publish('event', payload)
882
943
 
883
- channel.subscribe do |message|
884
- stop_reactor if message.data == payload && channel.attached?
885
- end
944
+ channel.subscribe do |message|
945
+ stop_reactor if message.data == payload && channel.attached?
946
+ end
886
947
 
887
- channel.attach
948
+ channel.attach
949
+ end
888
950
  end
889
951
  end
890
952
 
891
953
  context 'when channel is attaching' do
892
954
  it 'sends messages only on attach' do
893
- channel.publish('event', payload)
955
+ connection.once :connected do
956
+ channel.publish('event', payload)
894
957
 
895
- sent_message = nil
896
- channel.subscribe do |message|
897
- return if message.data != payload
898
- sent_message = message
958
+ sent_message = nil
959
+ channel.subscribe do |message|
960
+ return if message.data != payload
961
+ sent_message = message
899
962
 
900
- stop_reactor if channel.attached?
901
- end
963
+ stop_reactor if channel.attached?
964
+ end
902
965
 
903
- channel.on(:attaching) do
904
- expect(channel).to be_attaching
905
- expect(sent_message).to be_nil
906
- end
966
+ channel.on(:attaching) do
967
+ expect(channel).to be_attaching
968
+ expect(sent_message).to be_nil
969
+ end
907
970
 
908
- channel.attach
971
+ channel.attach
972
+ end
909
973
  end
910
974
  end
911
975
 
912
976
  context 'when channel is detaching' do
913
977
  it 'stops sending message' do
914
- sent_message = nil
915
- event_published = false
916
- channel.subscribe do |message|
917
- sent_message = message if message.data == payload
918
- end
978
+ connection.once :connected do
979
+ sent_message = nil
980
+ event_published = false
981
+ channel.subscribe do |message|
982
+ sent_message = message if message.data == payload
983
+ end
919
984
 
920
- channel.on(:detaching) do
921
- channel.publish('event', payload)
922
- event_published = true
923
- end
985
+ channel.on(:detaching) do
986
+ channel.publish('event', payload)
987
+ event_published = true
988
+ end
924
989
 
925
- channel.on(:detaching) do
926
- EventMachine.next_tick do
927
- expect(sent_message).to be_nil
928
- stop_reactor if event_published
990
+ channel.on(:detaching) do
991
+ EventMachine.next_tick do
992
+ expect(sent_message).to be_nil
993
+ stop_reactor if event_published
994
+ end
929
995
  end
930
- end
931
996
 
932
- channel.attach do
933
- channel.detach
997
+ channel.attach do
998
+ channel.detach
999
+ end
934
1000
  end
935
1001
  end
936
1002
  end
937
1003
 
938
1004
  context 'when channel is detached' do
939
1005
  it 'stops sending message' do
940
- sent_message = nil
941
- event_published = false
942
- channel.subscribe do |message|
943
- sent_message = message if message.data == payload
944
- end
1006
+ connection.once :connected do
1007
+ sent_message = nil
1008
+ event_published = false
1009
+ channel.subscribe do |message|
1010
+ sent_message = message if message.data == payload
1011
+ end
945
1012
 
946
- channel.on(:detaching) do
947
- channel.publish('event', payload)
948
- event_published = true
949
- end
1013
+ channel.on(:detaching) do
1014
+ channel.publish('event', payload)
1015
+ event_published = true
1016
+ end
950
1017
 
951
- channel.on(:detached) do
952
- expect(sent_message).to be_nil
953
- stop_reactor if event_published
954
- end
1018
+ channel.on(:detached) do
1019
+ expect(sent_message).to be_nil
1020
+ stop_reactor if event_published
1021
+ end
955
1022
 
956
- channel.attach do
957
- channel.detach
1023
+ channel.attach do
1024
+ channel.detach
1025
+ end
958
1026
  end
959
1027
  end
960
1028
  end
@@ -968,8 +1036,10 @@ describe Ably::Realtime::Channel, :event_machine do
968
1036
  end
969
1037
  end
970
1038
 
971
- channel.attach do
972
- channel.transition_state_machine(:failed)
1039
+ connection.once :connected do
1040
+ channel.attach do
1041
+ channel.transition_state_machine(:failed)
1042
+ end
973
1043
  end
974
1044
  end
975
1045
  end
@@ -1019,7 +1089,7 @@ describe Ably::Realtime::Channel, :event_machine do
1019
1089
 
1020
1090
  context 'when channel is Detaching (#RTL6c1)' do
1021
1091
  it 'publishes messages immediately (#RTL6c1)' do
1022
- sub_channel.attach do
1092
+ sub_channel.once :attached do
1023
1093
  channel.attach do
1024
1094
  channel.once(:detaching) do
1025
1095
  outgoing_message_count = 0
@@ -1041,32 +1111,37 @@ describe Ably::Realtime::Channel, :event_machine do
1041
1111
  channel.detach
1042
1112
  end
1043
1113
  end
1114
+ connection.once :connected do
1115
+ sub_channel.attach
1116
+ end
1044
1117
  end
1045
1118
  end
1046
1119
 
1047
1120
  context 'when channel is Detached (#RTL6c1)' do
1048
1121
  it 'publishes messages immediately (#RTL6c1)' do
1049
- sub_channel.attach do
1050
- channel.attach
1051
- channel.once(:attached) do
1052
- channel.once(:detached) do
1053
- outgoing_message_count = 0
1054
- client.connection.__outgoing_protocol_msgbus__.subscribe(:protocol_message) do |protocol_message|
1055
- if protocol_message.action == :message
1056
- raise "Expected channel state to be attaching when publishing messages, not #{channel.state}" unless channel.detached?
1057
- outgoing_message_count += protocol_message.messages.count
1122
+ connection.once :connected do
1123
+ sub_channel.attach do
1124
+ channel.attach
1125
+ channel.once(:attached) do
1126
+ channel.once(:detached) do
1127
+ outgoing_message_count = 0
1128
+ client.connection.__outgoing_protocol_msgbus__.subscribe(:protocol_message) do |protocol_message|
1129
+ if protocol_message.action == :message
1130
+ raise "Expected channel state to be attaching when publishing messages, not #{channel.state}" unless channel.detached?
1131
+ outgoing_message_count += protocol_message.messages.count
1132
+ end
1058
1133
  end
1059
- end
1060
- sub_channel.subscribe do |message|
1061
- messages << message if message.name == 'event'
1062
- if messages.count == 3
1063
- expect(outgoing_message_count).to eql(3)
1064
- stop_reactor
1134
+ sub_channel.subscribe do |message|
1135
+ messages << message if message.name == 'event'
1136
+ if messages.count == 3
1137
+ expect(outgoing_message_count).to eql(3)
1138
+ stop_reactor
1139
+ end
1065
1140
  end
1141
+ 3.times { channel.publish('event', random_str) }
1066
1142
  end
1067
- 3.times { channel.publish('event', random_str) }
1143
+ channel.detach
1068
1144
  end
1069
- channel.detach
1070
1145
  end
1071
1146
  end
1072
1147
  end
@@ -1429,12 +1504,14 @@ describe Ably::Realtime::Channel, :event_machine do
1429
1504
 
1430
1505
  context 'with a valid client_id in the message' do
1431
1506
  it 'succeeds' do
1432
- channel.publish([name: 'event', client_id: 'validClient']).tap do |deferrable|
1433
- deferrable.errback { raise 'Should have succeeded' }
1434
- end
1435
- channel.subscribe('event') do |message|
1436
- expect(message.client_id).to eql('validClient')
1437
- EM.add_timer(0.5) { stop_reactor }
1507
+ connection.once :connected do
1508
+ channel.publish([name: 'event', client_id: 'validClient']).tap do |deferrable|
1509
+ deferrable.errback { raise 'Should have succeeded' }
1510
+ end
1511
+ channel.subscribe('event') do |message|
1512
+ expect(message.client_id).to eql('validClient')
1513
+ EM.add_timer(0.5) { stop_reactor }
1514
+ end
1438
1515
  end
1439
1516
  end
1440
1517
  end
@@ -1455,12 +1532,14 @@ describe Ably::Realtime::Channel, :event_machine do
1455
1532
 
1456
1533
  context 'with an empty client_id in the message' do
1457
1534
  it 'succeeds and publishes without a client_id' do
1458
- channel.publish([name: 'event', client_id: nil]).tap do |deferrable|
1459
- deferrable.errback { raise 'Should have succeeded' }
1460
- end
1461
- channel.subscribe('event') do |message|
1462
- expect(message.client_id).to be_nil
1463
- EM.add_timer(0.5) { stop_reactor }
1535
+ connection.once :connected do
1536
+ channel.publish([name: 'event', client_id: nil]).tap do |deferrable|
1537
+ deferrable.errback { raise 'Should have succeeded' }
1538
+ end
1539
+ channel.subscribe('event') do |message|
1540
+ expect(message.client_id).to be_nil
1541
+ EM.add_timer(0.5) { stop_reactor }
1542
+ end
1464
1543
  end
1465
1544
  end
1466
1545
  end
@@ -1475,20 +1554,25 @@ describe Ably::Realtime::Channel, :event_machine do
1475
1554
  context 'before the client is CONNECTED and the client\'s identity has been obtained' do
1476
1555
  context 'with a valid client_id in the message' do
1477
1556
  it 'succeeds' do
1478
- channel.publish([name: 'event', client_id: 'valid']).tap do |deferrable|
1479
- deferrable.errback { raise 'Should have succeeded' }
1480
- end
1481
- channel.subscribe('event') do |message|
1482
- expect(message.client_id).to eql('valid')
1483
- EM.add_timer(0.5) { stop_reactor }
1557
+ connection.once :connected do
1558
+ channel.publish([name: 'event', client_id: 'valid']).tap do |deferrable|
1559
+ deferrable.errback { raise 'Should have succeeded' }
1560
+ end
1561
+ channel.subscribe('event') do |message|
1562
+ expect(message.client_id).to eql('valid')
1563
+ EM.add_timer(0.5) { stop_reactor }
1564
+ end
1484
1565
  end
1485
1566
  end
1486
1567
  end
1487
1568
 
1488
1569
  context 'with an invalid client_id in the message' do
1489
1570
  let(:client_options) { default_options.merge(key: nil, token: token, log_level: :error) }
1490
- it 'succeeds in the client library but then fails when delivered to Ably' do
1571
+ it 'succeeds in the client library ( while connecting ) but then fails when delivered to Ably' do
1491
1572
  channel.publish([name: 'event', client_id: 'invalid']).tap do |deferrable|
1573
+ deferrable.errback do |err|
1574
+ expect(err).to be_truthy
1575
+ end
1492
1576
  EM.add_timer(0.5) { stop_reactor }
1493
1577
  end
1494
1578
  channel.subscribe('event') do |message|
@@ -1499,12 +1583,14 @@ describe Ably::Realtime::Channel, :event_machine do
1499
1583
 
1500
1584
  context 'with an empty client_id in the message' do
1501
1585
  it 'succeeds and publishes with an implicit client_id' do
1502
- channel.publish([name: 'event', client_id: nil]).tap do |deferrable|
1503
- deferrable.errback { raise 'Should have succeeded' }
1504
- end
1505
- channel.subscribe('event') do |message|
1506
- expect(message.client_id).to eql('valid')
1507
- EM.add_timer(0.5) { stop_reactor }
1586
+ connection.once :connected do
1587
+ channel.publish([name: 'event', client_id: nil]).tap do |deferrable|
1588
+ deferrable.errback { raise 'Should have succeeded' }
1589
+ end
1590
+ channel.subscribe('event') do |message|
1591
+ expect(message.client_id).to eql('valid')
1592
+ EM.add_timer(0.5) { stop_reactor }
1593
+ end
1508
1594
  end
1509
1595
  end
1510
1596
  end
@@ -1558,12 +1644,14 @@ describe Ably::Realtime::Channel, :event_machine do
1558
1644
 
1559
1645
  context 'with a valid client_id' do
1560
1646
  it 'succeeds' do
1561
- channel.publish([name: 'event', client_id: 'valid']).tap do |deferrable|
1562
- deferrable.errback { raise 'Should have succeeded' }
1563
- end
1564
- channel.subscribe('event') do |message|
1565
- expect(message.client_id).to eql('valid')
1566
- EM.add_timer(0.5) { stop_reactor }
1647
+ connection.once :connected do
1648
+ channel.publish([name: 'event', client_id: 'valid']).tap do |deferrable|
1649
+ deferrable.errback { raise 'Should have succeeded' }
1650
+ end
1651
+ channel.subscribe('event') do |message|
1652
+ expect(message.client_id).to eql('valid')
1653
+ EM.add_timer(0.5) { stop_reactor }
1654
+ end
1567
1655
  end
1568
1656
  end
1569
1657
  end
@@ -1584,12 +1672,14 @@ describe Ably::Realtime::Channel, :event_machine do
1584
1672
 
1585
1673
  context 'with an empty client_id in the message' do
1586
1674
  it 'succeeds and publishes with an implicit client_id' do
1587
- channel.publish([name: 'event', client_id: nil]).tap do |deferrable|
1588
- deferrable.errback { raise 'Should have succeeded' }
1589
- end
1590
- channel.subscribe('event') do |message|
1591
- expect(message.client_id).to eql('valid')
1592
- EM.add_timer(0.5) { stop_reactor }
1675
+ connection.once :connected do
1676
+ channel.publish([name: 'event', client_id: nil]).tap do |deferrable|
1677
+ deferrable.errback { raise 'Should have succeeded' }
1678
+ end
1679
+ channel.subscribe('event') do |message|
1680
+ expect(message.client_id).to eql('valid')
1681
+ EM.add_timer(0.5) { stop_reactor }
1682
+ end
1593
1683
  end
1594
1684
  end
1595
1685
  end
@@ -1617,12 +1707,14 @@ describe Ably::Realtime::Channel, :event_machine do
1617
1707
 
1618
1708
  context 'with an empty client_id in the message' do
1619
1709
  it 'succeeds and publishes with an implicit client_id' do
1620
- channel.publish([name: 'event', client_id: nil]).tap do |deferrable|
1621
- deferrable.errback { raise 'Should have succeeded' }
1622
- end
1623
- channel.subscribe('event') do |message|
1624
- expect(message.client_id).to be_nil
1625
- EM.add_timer(0.5) { stop_reactor }
1710
+ connection.once :connected do
1711
+ channel.publish([name: 'event', client_id: nil]).tap do |deferrable|
1712
+ deferrable.errback { raise 'Should have succeeded' }
1713
+ end
1714
+ channel.subscribe('event') do |message|
1715
+ expect(message.client_id).to be_nil
1716
+ EM.add_timer(0.5) { stop_reactor }
1717
+ end
1626
1718
  end
1627
1719
  end
1628
1720
  end
@@ -1766,18 +1858,20 @@ describe Ably::Realtime::Channel, :event_machine do
1766
1858
  let(:exception) { StandardError.new("Intentional error") }
1767
1859
 
1768
1860
  it 'logs the error and continues' do
1769
- emitted_exception = false
1770
- expect(client.logger).to receive(:error) do |*args, &block|
1771
- expect(args.concat([block ? block.call : nil]).join(',')).to match(/#{exception.message}/)
1772
- end
1773
- channel.subscribe('click') do |message|
1774
- emitted_exception = true
1775
- raise exception
1776
- end
1777
- channel.publish('click', 'data') do
1778
- EventMachine.add_timer(1) do
1779
- expect(emitted_exception).to eql(true)
1780
- stop_reactor
1861
+ connection.once :connected do
1862
+ emitted_exception = false
1863
+ expect(client.logger).to receive(:error) do |*args, &block|
1864
+ expect(args.concat([block ? block.call : nil]).join(',')).to match(/#{exception.message}/)
1865
+ end
1866
+ channel.subscribe('click') do |message|
1867
+ emitted_exception = true
1868
+ raise exception
1869
+ end
1870
+ channel.publish('click', 'data') do
1871
+ EventMachine.add_timer(1) do
1872
+ expect(emitted_exception).to eql(true)
1873
+ stop_reactor
1874
+ end
1781
1875
  end
1782
1876
  end
1783
1877
  end
@@ -1785,19 +1879,21 @@ describe Ably::Realtime::Channel, :event_machine do
1785
1879
 
1786
1880
  context 'many times with different event names' do
1787
1881
  it 'filters events accordingly to each callback' do
1788
- click_callback = lambda { |message| messages << message }
1882
+ connection.once :connected do
1883
+ click_callback = lambda { |message| messages << message }
1789
1884
 
1790
- channel.subscribe('click', &click_callback)
1791
- channel.subscribe('move', &click_callback)
1792
- channel.subscribe('press', &click_callback)
1885
+ channel.subscribe('click', &click_callback)
1886
+ channel.subscribe('move', &click_callback)
1887
+ channel.subscribe('press', &click_callback)
1793
1888
 
1794
- channel.attach do
1795
- channel.publish('click', 'data')
1796
- channel.publish('move', 'data')
1797
- channel.publish('press', 'data') do
1798
- EventMachine.add_timer(2) do
1799
- expect(messages.count).to eql(3)
1800
- stop_reactor
1889
+ channel.attach do
1890
+ channel.publish('click', 'data')
1891
+ channel.publish('move', 'data')
1892
+ channel.publish('press', 'data') do
1893
+ EventMachine.add_timer(2) do
1894
+ expect(messages.count).to eql(3)
1895
+ stop_reactor
1896
+ end
1801
1897
  end
1802
1898
  end
1803
1899
  end
@@ -1808,12 +1904,14 @@ describe Ably::Realtime::Channel, :event_machine do
1808
1904
  describe '#unsubscribe' do
1809
1905
  context 'with an event argument' do
1810
1906
  it 'unsubscribes for a single event' do
1811
- channel.subscribe('click') { raise 'Should not have been called' }
1812
- channel.unsubscribe('click')
1907
+ connection.once :connected do
1908
+ channel.subscribe('click') { raise 'Should not have been called' }
1909
+ channel.unsubscribe('click')
1813
1910
 
1814
- channel.publish('click', 'data') do
1815
- EventMachine.add_timer(1) do
1816
- stop_reactor
1911
+ channel.publish('click', 'data') do
1912
+ EventMachine.add_timer(1) do
1913
+ stop_reactor
1914
+ end
1817
1915
  end
1818
1916
  end
1819
1917
  end
@@ -1821,12 +1919,14 @@ describe Ably::Realtime::Channel, :event_machine do
1821
1919
 
1822
1920
  context 'with no event argument' do
1823
1921
  it 'unsubscribes for a single event' do
1824
- channel.subscribe { raise 'Should not have been called' }
1825
- channel.unsubscribe
1922
+ connection.once :connected do
1923
+ channel.subscribe { raise 'Should not have been called' }
1924
+ channel.unsubscribe
1826
1925
 
1827
- channel.publish('click', 'data') do
1828
- EventMachine.add_timer(1) do
1829
- stop_reactor
1926
+ channel.publish('click', 'data') do
1927
+ EventMachine.add_timer(1) do
1928
+ stop_reactor
1929
+ end
1830
1930
  end
1831
1931
  end
1832
1932
  end
@@ -1861,33 +1961,37 @@ describe Ably::Realtime::Channel, :event_machine do
1861
1961
 
1862
1962
  context 'an :attached channel' do
1863
1963
  it 'transitions state to :failed (#RTL3a)' do
1864
- channel.attach do
1865
- channel.on(:failed) do |connection_state_change|
1866
- error = connection_state_change.reason
1867
- expect(error).to be_a(Ably::Exceptions::ConnectionFailed)
1868
- expect(error.code).to eql(50000)
1869
- stop_reactor
1964
+ connection.once :connected do
1965
+ channel.attach do
1966
+ channel.on(:failed) do |connection_state_change|
1967
+ error = connection_state_change.reason
1968
+ expect(error).to be_a(Ably::Exceptions::ConnectionFailed)
1969
+ expect(error.code).to eql(50000)
1970
+ stop_reactor
1971
+ end
1972
+ fake_error connection_error
1870
1973
  end
1871
- fake_error connection_error
1872
1974
  end
1873
1975
  end
1874
1976
 
1875
1977
  it 'updates the channel error_reason (#RTL3a)' do
1876
- channel.attach do
1877
- channel.on(:failed) do |connection_state_change|
1878
- error = connection_state_change.reason
1879
- expect(error).to be_a(Ably::Exceptions::ConnectionFailed)
1880
- expect(error.code).to eql(50000)
1881
- stop_reactor
1978
+ connection.once :connected do
1979
+ channel.attach do
1980
+ channel.on(:failed) do |connection_state_change|
1981
+ error = connection_state_change.reason
1982
+ expect(error).to be_a(Ably::Exceptions::ConnectionFailed)
1983
+ expect(error.code).to eql(50000)
1984
+ stop_reactor
1985
+ end
1986
+ fake_error connection_error
1882
1987
  end
1883
- fake_error connection_error
1884
1988
  end
1885
1989
  end
1886
1990
  end
1887
1991
 
1888
1992
  context 'a :detached channel' do
1889
1993
  it 'remains in the :detached state (#RTL3a)' do
1890
- channel.attach do
1994
+ channel.once :attached do
1891
1995
  channel.on(:failed) { raise 'Failed state should not have been reached' }
1892
1996
 
1893
1997
  channel.detach do
@@ -1899,6 +2003,10 @@ describe Ably::Realtime::Channel, :event_machine do
1899
2003
  fake_error connection_error
1900
2004
  end
1901
2005
  end
2006
+
2007
+ connection.once :connected do
2008
+ channel.attach
2009
+ end
1902
2010
  end
1903
2011
  end
1904
2012
 
@@ -1906,20 +2014,22 @@ describe Ably::Realtime::Channel, :event_machine do
1906
2014
  let(:original_error) { RuntimeError.new }
1907
2015
 
1908
2016
  it 'remains in the :failed state and ignores the failure error (#RTL3a)' do
1909
- channel.attach do
1910
- channel.on(:failed) do
1911
- channel.on(:failed) { raise 'Failed state should not have been reached' }
2017
+ connection.once :connected do
2018
+ channel.attach do
2019
+ channel.on(:failed) do
2020
+ channel.on(:failed) { raise 'Failed state should not have been reached' }
1912
2021
 
1913
- EventMachine.add_timer(1) do
1914
- expect(channel).to be_failed
1915
- expect(channel.error_reason).to eql(original_error)
1916
- stop_reactor
2022
+ EventMachine.add_timer(1) do
2023
+ expect(channel).to be_failed
2024
+ expect(channel.error_reason).to eql(original_error)
2025
+ stop_reactor
2026
+ end
2027
+
2028
+ fake_error connection_error
1917
2029
  end
1918
2030
 
1919
- fake_error connection_error
2031
+ channel.transition_state_machine :failed, reason: original_error
1920
2032
  end
1921
-
1922
- channel.transition_state_machine :failed, reason: original_error
1923
2033
  end
1924
2034
  end
1925
2035
  end
@@ -1942,11 +2052,13 @@ describe Ably::Realtime::Channel, :event_machine do
1942
2052
  context ':closed' do
1943
2053
  context 'an :attached channel' do
1944
2054
  it 'transitions state to :detached (#RTL3b)' do
1945
- channel.attach do
1946
- channel.on(:detached) do
1947
- stop_reactor
2055
+ connection.once :connected do
2056
+ channel.attach do
2057
+ channel.on(:detached) do
2058
+ stop_reactor
2059
+ end
2060
+ client.connection.close
1948
2061
  end
1949
- client.connection.close
1950
2062
  end
1951
2063
  end
1952
2064
  end
@@ -1962,13 +2074,15 @@ describe Ably::Realtime::Channel, :event_machine do
1962
2074
  closed_message = Ably::Models::ProtocolMessage.new(action: 8) # CLOSED
1963
2075
  client.connection.__incoming_protocol_msgbus__.publish :protocol_message, closed_message
1964
2076
  end
1965
- channel.attach
2077
+ connection.once :connected do
2078
+ channel.attach
2079
+ end
1966
2080
  end
1967
2081
  end
1968
2082
 
1969
2083
  context 'a :detached channel' do
1970
2084
  it 'remains in the :detached state (#RTL3b)' do
1971
- channel.attach do
2085
+ channel.once :attached do
1972
2086
  channel.detach do
1973
2087
  channel.on(:detached) { raise 'Detached state should not have been reached' }
1974
2088
 
@@ -1980,6 +2094,9 @@ describe Ably::Realtime::Channel, :event_machine do
1980
2094
  client.connection.close
1981
2095
  end
1982
2096
  end
2097
+ connection.once :connected do
2098
+ channel.attach
2099
+ end
1983
2100
  end
1984
2101
  end
1985
2102
 
@@ -1988,20 +2105,22 @@ describe Ably::Realtime::Channel, :event_machine do
1988
2105
  let(:original_error) { Ably::Models::ErrorInfo.new(message: 'Error') }
1989
2106
 
1990
2107
  it 'remains in the :failed state and retains the error_reason (#RTL3b)' do
1991
- channel.attach do
1992
- channel.once(:failed) do
1993
- channel.on(:detached) { raise 'Detached state should not have been reached' }
2108
+ connection.on :connected do
2109
+ channel.attach do
2110
+ channel.once(:failed) do
2111
+ channel.on(:detached) { raise 'Detached state should not have been reached' }
1994
2112
 
1995
- EventMachine.add_timer(1) do
1996
- expect(channel).to be_failed
1997
- expect(channel.error_reason).to eql(original_error)
1998
- stop_reactor
2113
+ EventMachine.add_timer(1) do
2114
+ expect(channel).to be_failed
2115
+ expect(channel.error_reason).to eql(original_error)
2116
+ stop_reactor
2117
+ end
2118
+
2119
+ client.connection.close
1999
2120
  end
2000
2121
 
2001
- client.connection.close
2122
+ channel.transition_state_machine :failed, reason: original_error
2002
2123
  end
2003
-
2004
- channel.transition_state_machine :failed, reason: original_error
2005
2124
  end
2006
2125
  end
2007
2126
  end
@@ -2046,23 +2165,26 @@ describe Ably::Realtime::Channel, :event_machine do
2046
2165
  client.connection.transition_state_machine :suspended
2047
2166
  end
2048
2167
  end
2049
- channel.attach
2168
+ channel.attach
2050
2169
  end
2051
2170
  end
2052
2171
 
2053
2172
  context 'an :attached channel' do
2054
2173
  it 'transitions state to :suspended (#RTL3c)' do
2055
- channel.attach do
2174
+ channel.once :attached do
2056
2175
  channel.on(:suspended) do
2057
2176
  stop_reactor
2058
2177
  end
2059
2178
  client.connection.transition_state_machine :suspended
2060
2179
  end
2180
+ connection.once :connected do
2181
+ channel.attach
2182
+ end
2061
2183
  end
2062
2184
 
2063
2185
  describe 'reattaching (#RTN15c3)' do
2064
2186
  it 'transitions state automatically to :attaching once the connection is re-established ' do
2065
- channel.attach do
2187
+ channel.once :attached do
2066
2188
  channel.on(:suspended) do
2067
2189
  client.connection.connect
2068
2190
  channel.once(:attached) do
@@ -2071,10 +2193,13 @@ describe Ably::Realtime::Channel, :event_machine do
2071
2193
  end
2072
2194
  client.connection.transition_state_machine :suspended
2073
2195
  end
2196
+ connection.once :connected do
2197
+ channel.attach
2198
+ end
2074
2199
  end
2075
2200
 
2076
2201
  it 'sends ATTACH_RESUME flag when reattaching (RTL4j)' do
2077
- channel.attach do
2202
+ channel.once :attached do
2078
2203
  channel.on(:suspended) do
2079
2204
  client.connection.__outgoing_protocol_msgbus__.subscribe(:protocol_message) do |protocol_message|
2080
2205
  next if protocol_message.action != :attach
@@ -2087,13 +2212,16 @@ describe Ably::Realtime::Channel, :event_machine do
2087
2212
  end
2088
2213
  client.connection.transition_state_machine :suspended
2089
2214
  end
2215
+ connection.once :connected do
2216
+ channel.attach
2217
+ end
2090
2218
  end
2091
2219
  end
2092
2220
  end
2093
2221
 
2094
2222
  context 'a :detached channel' do
2095
2223
  it 'remains in the :detached state (#RTL3c)' do
2096
- channel.attach do
2224
+ channel.once :attached do
2097
2225
  channel.detach do
2098
2226
  channel.on(:detached) { raise 'Detached state should not have been reached' }
2099
2227
 
@@ -2105,6 +2233,9 @@ describe Ably::Realtime::Channel, :event_machine do
2105
2233
  client.connection.transition_state_machine :suspended
2106
2234
  end
2107
2235
  end
2236
+ connection.once :connected do
2237
+ channel.attach
2238
+ end
2108
2239
  end
2109
2240
  end
2110
2241
 
@@ -2113,20 +2244,22 @@ describe Ably::Realtime::Channel, :event_machine do
2113
2244
  let(:client_options) { default_options.merge(log_level: :fatal) }
2114
2245
 
2115
2246
  it 'remains in the :failed state and retains the error_reason (#RTL3c)' do
2116
- channel.attach do
2117
- channel.once(:failed) do
2118
- channel.on(:detached) { raise 'Detached state should not have been reached' }
2247
+ connection.once :connected do
2248
+ channel.attach do
2249
+ channel.once(:failed) do
2250
+ channel.on(:detached) { raise 'Detached state should not have been reached' }
2119
2251
 
2120
- EventMachine.add_timer(1) do
2121
- expect(channel).to be_failed
2122
- expect(channel.error_reason).to eql(original_error)
2123
- stop_reactor
2252
+ EventMachine.add_timer(1) do
2253
+ expect(channel).to be_failed
2254
+ expect(channel.error_reason).to eql(original_error)
2255
+ stop_reactor
2256
+ end
2257
+
2258
+ client.connection.transition_state_machine :suspended
2124
2259
  end
2125
2260
 
2126
- client.connection.transition_state_machine :suspended
2261
+ channel.transition_state_machine :failed, reason: original_error
2127
2262
  end
2128
-
2129
- channel.transition_state_machine :failed, reason: original_error
2130
2263
  end
2131
2264
  end
2132
2265
  end
@@ -2151,14 +2284,16 @@ describe Ably::Realtime::Channel, :event_machine do
2151
2284
  context ':connected' do
2152
2285
  context 'a :suspended channel' do
2153
2286
  it 'is automatically reattached (#RTL3d)' do
2154
- channel.attach do
2155
- channel.once(:suspended) do
2156
- client.connection.connect
2157
- channel.once(:attached) do
2158
- stop_reactor
2287
+ connection.once :connected do
2288
+ channel.attach do
2289
+ channel.once(:suspended) do
2290
+ client.connection.connect
2291
+ channel.once(:attached) do
2292
+ stop_reactor
2293
+ end
2159
2294
  end
2295
+ client.connection.transition_state_machine :suspended
2160
2296
  end
2161
- client.connection.transition_state_machine :suspended
2162
2297
  end
2163
2298
  end
2164
2299
 
@@ -2168,29 +2303,32 @@ describe Ably::Realtime::Channel, :event_machine do
2168
2303
  end
2169
2304
 
2170
2305
  it 'returns to a suspended state (#RTL3d)' do
2171
- channel.attach do
2172
- channel.once(:attached) do
2173
- fail "Channel should not have become attached"
2174
- end
2306
+ connection.once :connected do
2307
+ channel.attach do
2308
+ channel.once(:attached) do
2309
+ fail "Channel should not have become attached"
2310
+ end
2175
2311
 
2176
- channel.once(:suspended) do
2177
- client.connection.connect
2178
- channel.once(:attaching) do
2179
- # don't process any incoming ProtocolMessages so the connection never opens
2180
- client.connection.__incoming_protocol_msgbus__.unsubscribe
2181
- channel.once(:suspended) do |state_change|
2182
- expect(state_change.reason.code).to eql(90007)
2183
- stop_reactor
2312
+ channel.once(:suspended) do
2313
+ client.connection.connect
2314
+ channel.once(:attaching) do
2315
+ # don't process any incoming ProtocolMessages so the connection never opens
2316
+ client.connection.__incoming_protocol_msgbus__.unsubscribe
2317
+ channel.once(:suspended) do |state_change|
2318
+ expect(state_change.reason.code).to eql(90007)
2319
+ stop_reactor
2320
+ end
2184
2321
  end
2185
2322
  end
2323
+ client.connection.transition_state_machine :suspended
2186
2324
  end
2187
- client.connection.transition_state_machine :suspended
2188
2325
  end
2189
2326
  end
2190
2327
  end
2191
2328
  end
2192
2329
  end
2193
2330
 
2331
+
2194
2332
  context ':disconnected' do
2195
2333
  context 'with an initialized channel' do
2196
2334
  it 'has no effect on the channel states (#RTL3e)' do
@@ -2222,25 +2360,31 @@ describe Ably::Realtime::Channel, :event_machine do
2222
2360
 
2223
2361
  context 'with an attached channel' do
2224
2362
  it 'has no effect on the channel states (#RTL3e)' do
2225
- channel.attach do
2363
+ channel.once :attached do
2226
2364
  connection.once(:disconnected) do
2227
2365
  expect(channel).to be_attached
2228
2366
  stop_reactor
2229
2367
  end
2230
2368
  disconnect_transport
2231
2369
  end
2370
+
2371
+ connection.once :connected do
2372
+ channel.attach
2373
+ end
2232
2374
  end
2233
2375
  end
2234
2376
 
2235
2377
  context 'with a detached channel' do
2236
2378
  it 'has no effect on the channel states (#RTL3e)' do
2237
- channel.attach do
2238
- channel.detach do
2239
- connection.once(:disconnected) do
2240
- expect(channel).to be_detached
2241
- stop_reactor
2379
+ connection.once :connected do
2380
+ channel.attach do
2381
+ channel.detach do
2382
+ connection.once(:disconnected) do
2383
+ expect(channel).to be_detached
2384
+ stop_reactor
2385
+ end
2386
+ disconnect_transport
2242
2387
  end
2243
- disconnect_transport
2244
2388
  end
2245
2389
  end
2246
2390
  end
@@ -2288,12 +2432,12 @@ describe Ably::Realtime::Channel, :event_machine do
2288
2432
 
2289
2433
  shared_examples 'an update that sends ATTACH message' do |state, flags|
2290
2434
  it 'sends an ATTACH message on options change' do
2291
- attach_sent = nil
2435
+ attach_sent_with_flags_set_via_channel_options = nil
2292
2436
 
2293
2437
  client.connection.__outgoing_protocol_msgbus__.subscribe(:protocol_message) do |protocol_message|
2294
2438
  if protocol_message.action == :attach && protocol_message.flags.nonzero?
2295
- attach_sent = true
2296
2439
  expect(protocol_message.flags).to eq(flags)
2440
+ attach_sent_with_flags_set_via_channel_options = true
2297
2441
  end
2298
2442
  end
2299
2443
 
@@ -2302,10 +2446,7 @@ describe Ably::Realtime::Channel, :event_machine do
2302
2446
  end
2303
2447
 
2304
2448
  channel.on(:attached) do
2305
- client.connection.__incoming_protocol_msgbus__.subscribe(:protocol_message) do |protocol_message|
2306
- next if protocol_message.action != :attached
2307
-
2308
- expect(attach_sent).to eq(true)
2449
+ wait_until(lambda { attach_sent_with_flags_set_via_channel_options }) do
2309
2450
  stop_reactor
2310
2451
  end
2311
2452
  end
@@ -2318,7 +2459,7 @@ describe Ably::Realtime::Channel, :event_machine do
2318
2459
  it_behaves_like 'an update that sends ATTACH message', :attaching, build_flags(%i[subscribe])
2319
2460
  end
2320
2461
 
2321
- context 'when channel is attaching' do
2462
+ context 'when channel is attached' do
2322
2463
  it_behaves_like 'an update that sends ATTACH message', :attached, build_flags(%i[resume subscribe])
2323
2464
  end
2324
2465
 
@@ -2389,8 +2530,10 @@ describe Ably::Realtime::Channel, :event_machine do
2389
2530
  expect(channel_state_change.reason).to be_nil
2390
2531
  stop_reactor
2391
2532
  end
2392
- channel.attach do
2393
- channel.detach
2533
+ connection.once :connected do
2534
+ channel.attach do
2535
+ channel.detach
2536
+ end
2394
2537
  end
2395
2538
  end
2396
2539
 
@@ -2426,7 +2569,7 @@ describe Ably::Realtime::Channel, :event_machine do
2426
2569
  connection_id = client.connection.id
2427
2570
  expect(channel_state_change.resumed).to be_falsey
2428
2571
 
2429
- recover_client = auto_close Ably::Realtime::Client.new(client_options.merge(recover: client.connection.recovery_key))
2572
+ recover_client = auto_close Ably::Realtime::Client.new(client_options.merge(recover: client.connection.create_recovery_key))
2430
2573
  recover_client.connection.once(:connected) do
2431
2574
  expect(recover_client.connection.id).to eql(connection_id)
2432
2575
  recover_channel = recover_client.channels.get(channel_name)
@@ -2441,7 +2584,7 @@ describe Ably::Realtime::Channel, :event_machine do
2441
2584
 
2442
2585
  it 'is false when a connection fails to recover and the channel is attached' do
2443
2586
  client.connection.once(:connected) do
2444
- recovery_key = client.connection.recovery_key
2587
+ recovery_key = client.connection.create_recovery_key
2445
2588
  client.connection.once(:closed) do
2446
2589
  recover_client = auto_close Ably::Realtime::Client.new(client_options.merge(recover: recovery_key, log_level: :error))
2447
2590
  recover_client.connection.once(:connected) do
@@ -2458,11 +2601,11 @@ describe Ably::Realtime::Channel, :event_machine do
2458
2601
  end
2459
2602
  end
2460
2603
 
2461
- context 'when a resume fails' do
2604
+ context 'when a connection resume fails' do
2462
2605
  let(:client_options) { default_options.merge(log_level: :error) }
2463
2606
 
2464
- it 'is false when a resume fails to recover and the channel is automatically re-attached' do
2465
- channel.attach do
2607
+ it 'is false when channel_serial goes nil (RTP5a1) and the channel is automatically re-attached' do
2608
+ channel.once :attached do
2466
2609
  connection_id = client.connection.id
2467
2610
  channel.once(:attached) do |channel_state_change|
2468
2611
  expect(client.connection.id).to_not eql(connection_id)
@@ -2470,7 +2613,29 @@ describe Ably::Realtime::Channel, :event_machine do
2470
2613
  stop_reactor
2471
2614
  end
2472
2615
  client.connection.transport.close_connection_after_writing
2473
- client.connection.configure_new '0123456789abcdef', 'wVIsgTHAB1UvXh7z-1991d8586', -1 # force the resume connection key to be invalid
2616
+ channel.properties.channel_serial = nil
2617
+ client.connection.configure_new '0123456789abcdef', 'wVIsgTHAB1UvXh7z-1991d8586' # force the resume connection key to be invalid
2618
+ end
2619
+
2620
+ connection.once :connected do
2621
+ channel.attach
2622
+ end
2623
+ end
2624
+
2625
+ it 'is true when channel_serial is intact and the channel is automatically re-attached' do
2626
+ channel.once :attached do
2627
+ connection_id = client.connection.id
2628
+ channel.once(:attached) do |channel_state_change|
2629
+ expect(client.connection.id).to_not eql(connection_id)
2630
+ expect(channel_state_change.resumed).to be_truthy
2631
+ stop_reactor
2632
+ end
2633
+ client.connection.transport.close_connection_after_writing
2634
+ client.connection.configure_new '0123456789abcdef', 'wVIsgTHAB1UvXh7z-1991d8586' # force the resume connection key to be invalid
2635
+ end
2636
+
2637
+ connection.once :connected do
2638
+ channel.attach
2474
2639
  end
2475
2640
  end
2476
2641
  end
@@ -2601,7 +2766,9 @@ describe Ably::Realtime::Channel, :event_machine do
2601
2766
  client.connection.__incoming_protocol_msgbus__.publish :protocol_message, detach_message
2602
2767
  end
2603
2768
 
2604
- channel.attach
2769
+ connection.once :connected do
2770
+ channel.attach
2771
+ end
2605
2772
  end
2606
2773
  end
2607
2774
 
@@ -2632,26 +2799,30 @@ describe Ably::Realtime::Channel, :event_machine do
2632
2799
  client.connection.__incoming_protocol_msgbus__.publish :protocol_message, detach_message
2633
2800
  end
2634
2801
 
2635
- channel.attach
2802
+ connection.once :connected do
2803
+ channel.attach
2804
+ end
2636
2805
  end
2637
2806
 
2638
2807
  context 'when connection is no longer connected' do
2639
2808
  it 'will not attempt to reattach (#RTL13c)' do
2640
- channel.attach do
2641
- connection.once(:closing) do
2642
- channel.once(:attaching) do |state_change|
2643
- raise 'Channel should not attempt to reattach'
2809
+ connection.once :connected do
2810
+ channel.attach do
2811
+ connection.once(:closing) do
2812
+ channel.once(:attaching) do |state_change|
2813
+ raise 'Channel should not attempt to reattach'
2814
+ end
2815
+
2816
+ channel.transition_state_machine! :suspended
2644
2817
  end
2645
2818
 
2646
- channel.transition_state_machine! :suspended
2647
- end
2819
+ connection.once(:closed) do
2820
+ expect(channel).to be_suspended
2821
+ stop_reactor
2822
+ end
2648
2823
 
2649
- connection.once(:closed) do
2650
- expect(channel).to be_suspended
2651
- stop_reactor
2824
+ connection.close
2652
2825
  end
2653
-
2654
- connection.close
2655
2826
  end
2656
2827
  end
2657
2828
  end
@@ -2672,35 +2843,36 @@ describe Ably::Realtime::Channel, :event_machine do
2672
2843
  end
2673
2844
  end
2674
2845
  prevent_protocol_messages_proc.call
2675
- end
2676
2846
 
2677
- channel.once(:attaching) do
2678
- attaching_at = Time.now
2679
- # First attaching fails during server-initiated ATTACHED received
2680
- channel.once(:suspended) do |state_change|
2681
- expect(Time.now.to_i - attaching_at.to_i).to be_within(1).of(1)
2682
-
2683
- suspended_at = Time.now
2684
- # Automatic attach happens at channel_retry_timeout
2685
- channel.once(:attaching) do
2686
- expect(Time.now.to_i - attaching_at.to_i).to be_within(1).of(2)
2687
- channel.once(:suspended) do
2688
- channel.once(:attaching) do
2689
- channel.once(:attached) do
2690
- stop_reactor
2847
+ channel.once(:attaching) do
2848
+ attaching_at = Time.now
2849
+ # First attaching fails during server-initiated ATTACHED received
2850
+ channel.once(:suspended) do |state_change|
2851
+ expect(Time.now.to_i - attaching_at.to_i).to be_within(1).of(1)
2852
+
2853
+ suspended_at = Time.now
2854
+ # Automatic attach happens at channel_retry_timeout
2855
+ channel.once(:attaching) do
2856
+ expect(Time.now.to_i - attaching_at.to_i).to be_within(1).of(2)
2857
+ channel.once(:suspended) do
2858
+ channel.once(:attaching) do
2859
+ channel.once(:attached) do
2860
+ stop_reactor
2861
+ end
2862
+ # Simulate ATTACHED from Ably
2863
+ attached_message = Ably::Models::ProtocolMessage.new(action: 11, channel: channel_name) # ATTACHED
2864
+ client.connection.__incoming_protocol_msgbus__.publish :protocol_message, attached_message
2691
2865
  end
2692
- # Simulate ATTACHED from Ably
2693
- attached_message = Ably::Models::ProtocolMessage.new(action: 11, channel: channel_name) # ATTACHED
2694
- client.connection.__incoming_protocol_msgbus__.publish :protocol_message, attached_message
2695
2866
  end
2696
2867
  end
2697
2868
  end
2869
+
2870
+ detach_message = Ably::Models::ProtocolMessage.new(action: detached_action, channel: channel_name)
2871
+ client.connection.__incoming_protocol_msgbus__.publish :protocol_message, detach_message
2698
2872
  end
2699
2873
 
2700
- detach_message = Ably::Models::ProtocolMessage.new(action: detached_action, channel: channel_name)
2701
- client.connection.__incoming_protocol_msgbus__.publish :protocol_message, detach_message
2874
+ channel.attach
2702
2875
  end
2703
- channel.attach
2704
2876
  end
2705
2877
  end
2706
2878
  end
@@ -2709,14 +2881,16 @@ describe Ably::Realtime::Channel, :event_machine do
2709
2881
  let(:client_options) { default_options.merge(log_level: :fatal) }
2710
2882
 
2711
2883
  it 'should transition to the failed state and the error_reason should be set (#RTL14)' do
2712
- channel.attach do
2713
- channel.once(:failed) do |state_change|
2714
- expect(state_change.reason.code).to eql(50505)
2715
- expect(channel.error_reason.code).to eql(50505)
2716
- stop_reactor
2884
+ connection.once :connected do
2885
+ channel.attach do
2886
+ channel.once(:failed) do |state_change|
2887
+ expect(state_change.reason.code).to eql(50505)
2888
+ expect(channel.error_reason.code).to eql(50505)
2889
+ stop_reactor
2890
+ end
2891
+ error_message = Ably::Models::ProtocolMessage.new(action: 9, channel: channel_name, error: { code: 50505 }) # ProtocolMessage ERROR type
2892
+ client.connection.__incoming_protocol_msgbus__.publish :protocol_message, error_message
2717
2893
  end
2718
- error_message = Ably::Models::ProtocolMessage.new(action: 9, channel: channel_name, error: { code: 50505 }) # ProtocolMessage ERROR type
2719
- client.connection.__incoming_protocol_msgbus__.publish :protocol_message, error_message
2720
2894
  end
2721
2895
  end
2722
2896
  end