ably 1.0.6 → 1.1.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.editorconfig +14 -0
- data/.travis.yml +10 -8
- data/CHANGELOG.md +75 -3
- data/LICENSE +1 -3
- data/README.md +12 -7
- data/Rakefile +32 -0
- data/SPEC.md +1277 -835
- data/ably.gemspec +14 -9
- data/lib/ably/auth.rb +30 -4
- data/lib/ably/exceptions.rb +10 -4
- data/lib/ably/logger.rb +7 -1
- data/lib/ably/models/channel_state_change.rb +1 -1
- data/lib/ably/models/connection_state_change.rb +1 -1
- data/lib/ably/models/device_details.rb +87 -0
- data/lib/ably/models/device_push_details.rb +86 -0
- data/lib/ably/models/error_info.rb +23 -2
- data/lib/ably/models/idiomatic_ruby_wrapper.rb +4 -4
- data/lib/ably/models/protocol_message.rb +32 -2
- data/lib/ably/models/push_channel_subscription.rb +89 -0
- data/lib/ably/modules/conversions.rb +1 -1
- data/lib/ably/modules/encodeable.rb +1 -1
- data/lib/ably/modules/exception_codes.rb +128 -0
- data/lib/ably/modules/model_common.rb +15 -2
- data/lib/ably/modules/state_machine.rb +2 -2
- data/lib/ably/realtime.rb +1 -0
- data/lib/ably/realtime/auth.rb +1 -1
- data/lib/ably/realtime/channel.rb +24 -102
- data/lib/ably/realtime/channel/channel_manager.rb +2 -6
- data/lib/ably/realtime/channel/channel_state_machine.rb +2 -2
- data/lib/ably/realtime/channel/publisher.rb +74 -0
- data/lib/ably/realtime/channel/push_channel.rb +62 -0
- data/lib/ably/realtime/client.rb +91 -3
- data/lib/ably/realtime/client/incoming_message_dispatcher.rb +6 -2
- data/lib/ably/realtime/client/outgoing_message_dispatcher.rb +1 -1
- data/lib/ably/realtime/connection.rb +34 -20
- data/lib/ably/realtime/connection/connection_manager.rb +25 -9
- data/lib/ably/realtime/connection/websocket_transport.rb +1 -1
- data/lib/ably/realtime/presence.rb +4 -4
- data/lib/ably/realtime/presence/members_map.rb +3 -3
- data/lib/ably/realtime/push.rb +40 -0
- data/lib/ably/realtime/push/admin.rb +61 -0
- data/lib/ably/realtime/push/channel_subscriptions.rb +108 -0
- data/lib/ably/realtime/push/device_registrations.rb +105 -0
- data/lib/ably/rest.rb +1 -0
- data/lib/ably/rest/channel.rb +53 -17
- data/lib/ably/rest/channel/push_channel.rb +62 -0
- data/lib/ably/rest/client.rb +154 -32
- data/lib/ably/rest/middleware/parse_message_pack.rb +17 -1
- data/lib/ably/rest/presence.rb +1 -0
- data/lib/ably/rest/push.rb +42 -0
- data/lib/ably/rest/push/admin.rb +54 -0
- data/lib/ably/rest/push/channel_subscriptions.rb +121 -0
- data/lib/ably/rest/push/device_registrations.rb +103 -0
- data/lib/ably/version.rb +7 -2
- data/spec/acceptance/realtime/auth_spec.rb +245 -17
- data/spec/acceptance/realtime/channel_history_spec.rb +26 -20
- data/spec/acceptance/realtime/channel_spec.rb +177 -59
- data/spec/acceptance/realtime/client_spec.rb +153 -0
- data/spec/acceptance/realtime/connection_failures_spec.rb +72 -6
- data/spec/acceptance/realtime/connection_spec.rb +129 -18
- data/spec/acceptance/realtime/message_spec.rb +36 -34
- data/spec/acceptance/realtime/presence_spec.rb +201 -167
- data/spec/acceptance/realtime/push_admin_spec.rb +736 -0
- data/spec/acceptance/realtime/push_spec.rb +27 -0
- data/spec/acceptance/rest/auth_spec.rb +41 -3
- data/spec/acceptance/rest/base_spec.rb +2 -2
- data/spec/acceptance/rest/channel_spec.rb +79 -4
- data/spec/acceptance/rest/channels_spec.rb +6 -0
- data/spec/acceptance/rest/client_spec.rb +129 -10
- data/spec/acceptance/rest/message_spec.rb +158 -6
- data/spec/acceptance/rest/push_admin_spec.rb +952 -0
- data/spec/acceptance/rest/push_spec.rb +25 -0
- data/spec/acceptance/rest/time_spec.rb +1 -1
- data/spec/run_parallel_tests +33 -0
- data/spec/spec_helper.rb +1 -1
- data/spec/support/debug_failure_helper.rb +9 -5
- data/spec/support/test_app.rb +2 -2
- data/spec/unit/logger_spec.rb +10 -3
- data/spec/unit/models/device_details_spec.rb +102 -0
- data/spec/unit/models/device_push_details_spec.rb +101 -0
- data/spec/unit/models/error_info_spec.rb +51 -3
- data/spec/unit/models/message_spec.rb +17 -2
- data/spec/unit/models/presence_message_spec.rb +1 -1
- data/spec/unit/models/push_channel_subscription_spec.rb +86 -0
- data/spec/unit/modules/enum_spec.rb +1 -1
- data/spec/unit/realtime/client_spec.rb +13 -1
- data/spec/unit/realtime/connection_spec.rb +1 -1
- data/spec/unit/realtime/push_channel_spec.rb +36 -0
- data/spec/unit/rest/channel_spec.rb +8 -1
- data/spec/unit/rest/client_spec.rb +30 -0
- data/spec/unit/rest/push_channel_spec.rb +36 -0
- metadata +95 -26
@@ -112,22 +112,26 @@ describe Ably::Realtime::Channel, '#history', :event_machine do
|
|
112
112
|
|
113
113
|
context 'in multiple ProtocolMessages', em_timeout: (30 / 10) + 5 do
|
114
114
|
it 'retrieves limited history forwards with pagination' do
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
115
|
+
channel.attach do
|
116
|
+
messages_sent.times do |index|
|
117
|
+
EventMachine.add_timer(index.to_f / rate_per_second) do
|
118
|
+
channel.publish('event', "history#{index}") do
|
119
|
+
next unless index == messages_sent - 1
|
120
|
+
ensure_message_history_direction_and_paging_is_correct :forwards
|
121
|
+
end
|
120
122
|
end
|
121
123
|
end
|
122
124
|
end
|
123
125
|
end
|
124
126
|
|
125
127
|
it 'retrieves limited history backwards with pagination' do
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
128
|
+
channel.attach do
|
129
|
+
messages_sent.times.to_a.reverse.each do |index|
|
130
|
+
EventMachine.add_timer((messages_sent - index).to_f / rate_per_second) do
|
131
|
+
channel.publish('event', "history#{index}") do
|
132
|
+
next unless index == 0
|
133
|
+
ensure_message_history_direction_and_paging_is_correct :backwards if index == 0
|
134
|
+
end
|
131
135
|
end
|
132
136
|
end
|
133
137
|
end
|
@@ -139,18 +143,20 @@ describe Ably::Realtime::Channel, '#history', :event_machine do
|
|
139
143
|
let(:messages_per_batch) { 10 }
|
140
144
|
|
141
145
|
it 'return the same results with unique matching message IDs' do
|
142
|
-
|
143
|
-
|
144
|
-
|
146
|
+
channel.attach do
|
147
|
+
batches.times do |batch|
|
148
|
+
EventMachine.add_timer(batch.to_f / batches.to_f) do
|
149
|
+
messages_per_batch.times { |index| channel.publish('event') }
|
150
|
+
end
|
145
151
|
end
|
146
|
-
end
|
147
152
|
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
153
|
+
channel.subscribe('event') do |message|
|
154
|
+
messages << message
|
155
|
+
if messages.count == batches * messages_per_batch
|
156
|
+
channel.history do |page|
|
157
|
+
expect(page.items.map(&:id).sort).to eql(messages.map(&:id).sort)
|
158
|
+
stop_reactor
|
159
|
+
end
|
154
160
|
end
|
155
161
|
end
|
156
162
|
end
|
@@ -13,6 +13,9 @@ describe Ably::Realtime::Channel, :event_machine do
|
|
13
13
|
let(:channel) { client.channel(channel_name) }
|
14
14
|
let(:messages) { [] }
|
15
15
|
|
16
|
+
let(:sub_client) { auto_close Ably::Realtime::Client.new(client_options) }
|
17
|
+
let(:sub_channel) { sub_client.channel(channel_name) }
|
18
|
+
|
16
19
|
def disconnect_transport
|
17
20
|
connection.transport.unbind
|
18
21
|
end
|
@@ -276,8 +279,7 @@ describe Ably::Realtime::Channel, :event_machine do
|
|
276
279
|
key: restricted_api_key,
|
277
280
|
log_level: :fatal,
|
278
281
|
use_token_auth: true,
|
279
|
-
|
280
|
-
default_token_params: { capability: { "canpublish:foo" => ["publish"] } }
|
282
|
+
default_token_params: { capability: { "canpublish:foo" => ["*"] } }
|
281
283
|
)
|
282
284
|
end
|
283
285
|
let(:restricted_client) do
|
@@ -726,7 +728,7 @@ describe Ably::Realtime::Channel, :event_machine do
|
|
726
728
|
let(:name) { random_str }
|
727
729
|
let(:data) { random_str }
|
728
730
|
|
729
|
-
context 'when attached' do
|
731
|
+
context 'when channel is attached (#RTL6c1)' do
|
730
732
|
it 'publishes messages' do
|
731
733
|
channel.attach do
|
732
734
|
3.times { channel.publish('event', payload) }
|
@@ -738,81 +740,173 @@ describe Ably::Realtime::Channel, :event_machine do
|
|
738
740
|
end
|
739
741
|
end
|
740
742
|
|
741
|
-
context 'when not
|
742
|
-
it 'publishes
|
743
|
-
|
744
|
-
|
745
|
-
|
746
|
-
|
743
|
+
context 'when channel is not attached in state Initializing (#RTL6c1)' do
|
744
|
+
it 'publishes messages immediately and does not implicitly attach (#RTL6c1)' do
|
745
|
+
sub_channel.attach do
|
746
|
+
sub_channel.subscribe do |message|
|
747
|
+
messages << message if message.name == 'event'
|
748
|
+
if messages.count == 3
|
749
|
+
EventMachine.add_timer(1) do
|
750
|
+
expect(channel.state).to eq(:initialized)
|
751
|
+
stop_reactor
|
752
|
+
end
|
753
|
+
end
|
754
|
+
end
|
755
|
+
3.times { channel.publish('event', random_str) }
|
747
756
|
end
|
748
757
|
end
|
758
|
+
end
|
749
759
|
|
750
|
-
|
751
|
-
|
752
|
-
|
753
|
-
|
754
|
-
|
755
|
-
|
756
|
-
|
757
|
-
|
758
|
-
|
759
|
-
|
760
|
-
|
761
|
-
|
762
|
-
|
763
|
-
|
764
|
-
|
765
|
-
|
760
|
+
context 'when channel is Attaching (#RTL6c1)' do
|
761
|
+
it 'publishes messages immediately (#RTL6c1)' do
|
762
|
+
sub_channel.attach do
|
763
|
+
channel.once(:attaching) do
|
764
|
+
outgoing_message_count = 0
|
765
|
+
client.connection.__outgoing_protocol_msgbus__.subscribe(:protocol_message) do |protocol_message|
|
766
|
+
if protocol_message.action == :message
|
767
|
+
raise "Expected channel state to be attaching when publishing messages, not #{channel.state}" unless channel.attaching?
|
768
|
+
outgoing_message_count += protocol_message.messages.count
|
769
|
+
end
|
770
|
+
end
|
771
|
+
sub_channel.subscribe do |message|
|
772
|
+
messages << message if message.name == 'event'
|
773
|
+
if messages.count == 3
|
774
|
+
expect(outgoing_message_count).to eql(3)
|
775
|
+
stop_reactor
|
776
|
+
end
|
777
|
+
end
|
778
|
+
3.times { channel.publish('event', random_str) }
|
779
|
+
end
|
780
|
+
channel.attach
|
766
781
|
end
|
767
782
|
end
|
783
|
+
end
|
768
784
|
|
769
|
-
|
770
|
-
|
771
|
-
|
772
|
-
|
773
|
-
|
774
|
-
|
775
|
-
|
776
|
-
|
777
|
-
|
785
|
+
context 'when channel is Detaching (#RTL6c1)' do
|
786
|
+
it 'publishes messages immediately (#RTL6c1)' do
|
787
|
+
sub_channel.attach do
|
788
|
+
channel.attach do
|
789
|
+
channel.once(:detaching) do
|
790
|
+
outgoing_message_count = 0
|
791
|
+
client.connection.__outgoing_protocol_msgbus__.subscribe(:protocol_message) do |protocol_message|
|
792
|
+
if protocol_message.action == :message
|
793
|
+
raise "Expected channel state to be attaching when publishing messages, not #{channel.state}" unless channel.detaching?
|
794
|
+
outgoing_message_count += protocol_message.messages.count
|
795
|
+
end
|
796
|
+
end
|
797
|
+
sub_channel.subscribe do |message|
|
798
|
+
messages << message if message.name == 'event'
|
799
|
+
if messages.count == 3
|
800
|
+
expect(outgoing_message_count).to eql(3)
|
801
|
+
stop_reactor
|
802
|
+
end
|
803
|
+
end
|
804
|
+
3.times { channel.publish('event', random_str) }
|
778
805
|
end
|
806
|
+
channel.detach
|
779
807
|
end
|
780
808
|
end
|
809
|
+
end
|
810
|
+
end
|
781
811
|
|
782
|
-
|
783
|
-
|
784
|
-
|
785
|
-
|
786
|
-
|
787
|
-
|
788
|
-
|
789
|
-
|
812
|
+
context 'when channel is Detached (#RTL6c1)' do
|
813
|
+
it 'publishes messages immediately (#RTL6c1)' do
|
814
|
+
sub_channel.attach do
|
815
|
+
channel.attach
|
816
|
+
channel.once(:attached) do
|
817
|
+
channel.once(:detached) do
|
818
|
+
outgoing_message_count = 0
|
819
|
+
client.connection.__outgoing_protocol_msgbus__.subscribe(:protocol_message) do |protocol_message|
|
820
|
+
if protocol_message.action == :message
|
821
|
+
raise "Expected channel state to be attaching when publishing messages, not #{channel.state}" unless channel.detached?
|
822
|
+
outgoing_message_count += protocol_message.messages.count
|
823
|
+
end
|
824
|
+
end
|
825
|
+
sub_channel.subscribe do |message|
|
826
|
+
messages << message if message.name == 'event'
|
827
|
+
if messages.count == 3
|
828
|
+
expect(outgoing_message_count).to eql(3)
|
829
|
+
stop_reactor
|
830
|
+
end
|
790
831
|
end
|
832
|
+
3.times { channel.publish('event', random_str) }
|
833
|
+
end
|
834
|
+
channel.detach
|
835
|
+
end
|
836
|
+
end
|
837
|
+
end
|
838
|
+
end
|
839
|
+
|
840
|
+
context 'with :queue_messages client option set to false (#RTL6c4)' do
|
841
|
+
let(:client_options) { default_options.merge(queue_messages: false) }
|
842
|
+
|
843
|
+
context 'and connection state connected (#RTL6c4)' do
|
844
|
+
it 'publishes the message' do
|
845
|
+
client.connection.once(:connected) do
|
846
|
+
channel.publish('event')
|
847
|
+
stop_reactor
|
848
|
+
end
|
849
|
+
end
|
850
|
+
end
|
851
|
+
|
852
|
+
context 'and connection state initialized (#RTL6c4)' do
|
853
|
+
it 'fails the deferrable' do
|
854
|
+
expect(client.connection).to be_initialized
|
855
|
+
channel.publish('event').errback do |error|
|
856
|
+
expect(error).to be_a(Ably::Exceptions::MessageQueueingDisabled)
|
857
|
+
stop_reactor
|
858
|
+
end
|
859
|
+
end
|
860
|
+
end
|
861
|
+
|
862
|
+
context 'and connection state connecting (#RTL6c4)' do
|
863
|
+
it 'fails the deferrable' do
|
864
|
+
client.connect
|
865
|
+
EventMachine.next_tick do
|
866
|
+
expect(client.connection).to be_connecting
|
867
|
+
channel.publish('event').errback do |error|
|
868
|
+
expect(error).to be_a(Ably::Exceptions::MessageQueueingDisabled)
|
869
|
+
stop_reactor
|
791
870
|
end
|
792
871
|
end
|
793
872
|
end
|
873
|
+
end
|
794
874
|
|
795
|
-
|
875
|
+
[:disconnected, :suspended, :closing, :closed].each do |invalid_connection_state|
|
876
|
+
context "and connection state #{invalid_connection_state} (#RTL6c4)" do
|
796
877
|
let(:client_options) { default_options.merge(queue_messages: false) }
|
797
878
|
it 'fails the deferrable' do
|
798
879
|
client.connection.once(:connected) do
|
799
|
-
client.connection.once(
|
800
|
-
expect(client.connection).to
|
880
|
+
client.connection.once(invalid_connection_state) do
|
881
|
+
expect(client.connection.state).to eq(invalid_connection_state)
|
801
882
|
channel.publish('event').errback do |error|
|
802
883
|
expect(error).to be_a(Ably::Exceptions::MessageQueueingDisabled)
|
803
884
|
stop_reactor
|
804
885
|
end
|
805
886
|
end
|
806
|
-
|
887
|
+
if invalid_connection_state == :closed
|
888
|
+
connection.close
|
889
|
+
else
|
890
|
+
client.connection.transition_state_machine invalid_connection_state
|
891
|
+
end
|
807
892
|
end
|
808
893
|
end
|
809
894
|
end
|
895
|
+
end
|
810
896
|
|
811
|
-
|
812
|
-
|
813
|
-
|
814
|
-
|
815
|
-
|
897
|
+
context 'and the channel state is failed (#RTL6c4)' do
|
898
|
+
let(:client_options) { default_options.merge(queue_messages: false) }
|
899
|
+
it 'fails the deferrable' do
|
900
|
+
client.connection.once(:connected) do
|
901
|
+
channel.attach
|
902
|
+
channel.once(:attached) do
|
903
|
+
channel.once(:failed) do
|
904
|
+
channel.publish('event').errback do |error|
|
905
|
+
expect(error).to be_a(Ably::Exceptions::ChannelInactive)
|
906
|
+
stop_reactor
|
907
|
+
end
|
908
|
+
end
|
909
|
+
channel.transition_state_machine(:failed)
|
816
910
|
end
|
817
911
|
end
|
818
912
|
end
|
@@ -914,9 +1008,6 @@ describe Ably::Realtime::Channel, :event_machine do
|
|
914
1008
|
|
915
1009
|
it 'publishes the message without a name attribute in the payload' do
|
916
1010
|
published = false
|
917
|
-
channel.publish(nil, data) do
|
918
|
-
published = true
|
919
|
-
end
|
920
1011
|
|
921
1012
|
channel.subscribe do |message|
|
922
1013
|
expect(message.name).to be_nil
|
@@ -929,6 +1020,10 @@ describe Ably::Realtime::Channel, :event_machine do
|
|
929
1020
|
end
|
930
1021
|
end
|
931
1022
|
end
|
1023
|
+
|
1024
|
+
channel.publish(nil, data) do
|
1025
|
+
published = true
|
1026
|
+
end
|
932
1027
|
end
|
933
1028
|
end
|
934
1029
|
|
@@ -937,9 +1032,6 @@ describe Ably::Realtime::Channel, :event_machine do
|
|
937
1032
|
|
938
1033
|
it 'publishes the message without a data attribute in the payload' do
|
939
1034
|
published = false
|
940
|
-
channel.publish(name, nil) do
|
941
|
-
published = true
|
942
|
-
end
|
943
1035
|
|
944
1036
|
channel.subscribe do |message|
|
945
1037
|
expect(message.data).to be_nil
|
@@ -952,6 +1044,10 @@ describe Ably::Realtime::Channel, :event_machine do
|
|
952
1044
|
end
|
953
1045
|
end
|
954
1046
|
end
|
1047
|
+
|
1048
|
+
channel.publish(name, nil) do
|
1049
|
+
published = true
|
1050
|
+
end
|
955
1051
|
end
|
956
1052
|
end
|
957
1053
|
|
@@ -1074,6 +1170,21 @@ describe Ably::Realtime::Channel, :event_machine do
|
|
1074
1170
|
end
|
1075
1171
|
end
|
1076
1172
|
|
1173
|
+
context 'with more than allowed messages in a single publish' do
|
1174
|
+
let(:channel_name) { random_str }
|
1175
|
+
|
1176
|
+
it 'rejects the publish' do
|
1177
|
+
messages = (Ably::Realtime::Connection::MAX_PROTOCOL_MESSAGE_BATCH_SIZE + 1).times.map do
|
1178
|
+
{ name: 'foo' }
|
1179
|
+
end
|
1180
|
+
|
1181
|
+
channel.publish(messages).errback do |error|
|
1182
|
+
expect(error).to be_kind_of(Ably::Exceptions::InvalidRequest)
|
1183
|
+
stop_reactor
|
1184
|
+
end
|
1185
|
+
end
|
1186
|
+
end
|
1187
|
+
|
1077
1188
|
context 'identified clients' do
|
1078
1189
|
context 'when authenticated with a wildcard client_id' do
|
1079
1190
|
let(:token) { Ably::Rest::Client.new(default_options).auth.request_token(client_id: '*') }
|
@@ -1887,6 +1998,8 @@ describe Ably::Realtime::Channel, :event_machine do
|
|
1887
1998
|
end
|
1888
1999
|
|
1889
2000
|
context '#resume (#RTL2f)' do
|
2001
|
+
let(:client_options) { default_options.merge(log_level: :fatal) }
|
2002
|
+
|
1890
2003
|
it 'is false when a channel first attaches' do
|
1891
2004
|
channel.attach
|
1892
2005
|
channel.on(:attached) do |channel_state_change|
|
@@ -1953,8 +2066,12 @@ describe Ably::Realtime::Channel, :event_machine do
|
|
1953
2066
|
end
|
1954
2067
|
|
1955
2068
|
context 'moves to' do
|
1956
|
-
%w(suspended
|
2069
|
+
%w(suspended failed).each do |channel_state|
|
1957
2070
|
context(channel_state) do
|
2071
|
+
let(:client) do
|
2072
|
+
auto_close Ably::Realtime::Client.new(default_options.merge(log_level: :error))
|
2073
|
+
end
|
2074
|
+
|
1958
2075
|
specify 'all queued messages fail with NACK (#RTL11)' do
|
1959
2076
|
channel.attach do
|
1960
2077
|
# Move to disconnected
|
@@ -1981,7 +2098,8 @@ describe Ably::Realtime::Channel, :event_machine do
|
|
1981
2098
|
specify 'all published messages awaiting an ACK do nothing (#RTL11a)' do
|
1982
2099
|
connection_been_disconnected = false
|
1983
2100
|
|
1984
|
-
channel.attach
|
2101
|
+
channel.attach
|
2102
|
+
channel.once(:attached) do
|
1985
2103
|
deferrable = channel.publish("foo")
|
1986
2104
|
deferrable.errback do |error|
|
1987
2105
|
fail "Message publish should not fail"
|
@@ -12,6 +12,7 @@ describe Ably::Realtime::Client, :event_machine do
|
|
12
12
|
let(:auth_params) { subject.auth.auth_params_sync }
|
13
13
|
|
14
14
|
subject { auto_close Ably::Realtime::Client.new(client_options) }
|
15
|
+
let(:sub_client) { auto_close Ably::Realtime::Client.new(client_options) }
|
15
16
|
|
16
17
|
context 'initialization' do
|
17
18
|
context 'basic auth' do
|
@@ -24,6 +25,22 @@ describe Ably::Realtime::Client, :event_machine do
|
|
24
25
|
end
|
25
26
|
end
|
26
27
|
|
28
|
+
context 'with an invalid API key' do
|
29
|
+
let(:custom_logger_object) { TestLogger.new }
|
30
|
+
let(:client) { Ably::Realtime::Client.new(client_options.merge(key: 'app.key:secret', logger: custom_logger_object)) }
|
31
|
+
|
32
|
+
it 'logs an entry with a help href url matching the code #TI5' do
|
33
|
+
client.connect
|
34
|
+
client.connection.once(:failed) do
|
35
|
+
expect(custom_logger_object.logs.find do |severity, message|
|
36
|
+
next unless %w(fatal error).include?(severity.to_s)
|
37
|
+
message.match(%r{https://help.ably.io/error/40400})
|
38
|
+
end).to_not be_nil
|
39
|
+
stop_reactor
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
27
44
|
context ':tls option' do
|
28
45
|
context 'set to false to force a plain-text connection' do
|
29
46
|
let(:client_options) { default_options.merge(tls: false, log_level: :none) }
|
@@ -281,5 +298,141 @@ describe Ably::Realtime::Client, :event_machine do
|
|
281
298
|
end
|
282
299
|
end
|
283
300
|
end
|
301
|
+
|
302
|
+
context '#publish (#TBC)' do
|
303
|
+
let(:channel_name) { random_str }
|
304
|
+
let(:channel) { subject.channel(channel_name) }
|
305
|
+
let(:sub_channel) { sub_client.channel(channel_name) }
|
306
|
+
let(:event_name) { random_str }
|
307
|
+
let(:data) { random_str }
|
308
|
+
let(:extras) { { 'push' => { 'notification' => { 'title' => 'Testing' } } } }
|
309
|
+
let(:message) { Ably::Models::Message.new(name: event_name, data: data) }
|
310
|
+
|
311
|
+
specify 'publishing a message implicity connects and publishes the message successfully on the provided channel' do
|
312
|
+
sub_channel.attach do
|
313
|
+
sub_channel.subscribe do |msg|
|
314
|
+
expect(msg.name).to eql(event_name)
|
315
|
+
expect(msg.data).to eql(data)
|
316
|
+
stop_reactor
|
317
|
+
end
|
318
|
+
|
319
|
+
subject.publish channel_name, event_name, data
|
320
|
+
end
|
321
|
+
end
|
322
|
+
|
323
|
+
specify 'publishing does not result in a channel being created' do
|
324
|
+
subject.publish channel_name, event_name, data
|
325
|
+
subject.channels.fetch(channel_name) do
|
326
|
+
# Block called if channel does not exist
|
327
|
+
EventMachine.add_timer(1) do
|
328
|
+
subject.channels.fetch(channel_name) do
|
329
|
+
# Block called if channel does not exist
|
330
|
+
stop_reactor
|
331
|
+
end
|
332
|
+
end
|
333
|
+
end
|
334
|
+
end
|
335
|
+
|
336
|
+
context 'with extras' do
|
337
|
+
let(:channel_name) { "pushenabled:#{random_str}" }
|
338
|
+
|
339
|
+
specify 'publishing supports extras' do
|
340
|
+
sub_channel.attach do
|
341
|
+
sub_channel.subscribe do |msg|
|
342
|
+
expect(msg.extras).to eql(extras)
|
343
|
+
stop_reactor
|
344
|
+
end
|
345
|
+
|
346
|
+
subject.publish channel_name, event_name, {}, extras: extras
|
347
|
+
end
|
348
|
+
end
|
349
|
+
end
|
350
|
+
|
351
|
+
specify 'publishing supports an array of Message objects' do
|
352
|
+
sub_channel.attach do
|
353
|
+
sub_channel.subscribe do |msg|
|
354
|
+
expect(msg.name).to eql(event_name)
|
355
|
+
expect(msg.data).to eql(data)
|
356
|
+
stop_reactor
|
357
|
+
end
|
358
|
+
|
359
|
+
subject.publish channel_name, [message]
|
360
|
+
end
|
361
|
+
end
|
362
|
+
|
363
|
+
specify 'publishing supports an array of Hash objects' do
|
364
|
+
sub_channel.attach do
|
365
|
+
sub_channel.subscribe do |msg|
|
366
|
+
expect(msg.name).to eql(event_name)
|
367
|
+
expect(msg.data).to eql(data)
|
368
|
+
stop_reactor
|
369
|
+
end
|
370
|
+
|
371
|
+
subject.publish channel_name, [name: event_name, data: data]
|
372
|
+
end
|
373
|
+
end
|
374
|
+
|
375
|
+
specify 'publishing on a closed connection fails' do
|
376
|
+
subject.connection.once(:connected) do
|
377
|
+
subject.connection.once(:closed) do
|
378
|
+
subject.publish(channel_name, name: event_name).errback do |error|
|
379
|
+
expect(error).to be_kind_of(Ably::Exceptions::MessageQueueingDisabled)
|
380
|
+
stop_reactor
|
381
|
+
end
|
382
|
+
end
|
383
|
+
connection.close
|
384
|
+
end
|
385
|
+
end
|
386
|
+
|
387
|
+
context 'queue_messages ClientOption' do
|
388
|
+
context 'when true' do
|
389
|
+
subject { auto_close Ably::Realtime::Client.new(client_options.merge(auto_connect: false)) }
|
390
|
+
|
391
|
+
it 'will queue messages whilst connecting and publish once connected' do
|
392
|
+
sub_channel.attach do
|
393
|
+
sub_channel.subscribe do |msg|
|
394
|
+
expect(msg.name).to eql(event_name)
|
395
|
+
stop_reactor
|
396
|
+
end
|
397
|
+
subject.connection.once(:connecting) do
|
398
|
+
subject.publish channel_name, event_name
|
399
|
+
end
|
400
|
+
subject.connection.connect
|
401
|
+
end
|
402
|
+
end
|
403
|
+
end
|
404
|
+
|
405
|
+
context 'when false' do
|
406
|
+
subject { auto_close Ably::Realtime::Client.new(client_options.merge(auto_connect: false, queue_messages: false)) }
|
407
|
+
|
408
|
+
it 'will reject messages on an initializing connection' do
|
409
|
+
sub_channel.attach do
|
410
|
+
subject.connection.once(:connecting) do
|
411
|
+
subject.publish(channel_name, event_name).errback do |error|
|
412
|
+
expect(error).to be_kind_of(Ably::Exceptions::MessageQueueingDisabled)
|
413
|
+
stop_reactor
|
414
|
+
end
|
415
|
+
end
|
416
|
+
subject.connection.connect
|
417
|
+
end
|
418
|
+
end
|
419
|
+
end
|
420
|
+
end
|
421
|
+
|
422
|
+
context 'with more than allowed messages in a single publish' do
|
423
|
+
let(:channel_name) { random_str }
|
424
|
+
|
425
|
+
it 'rejects the publish' do
|
426
|
+
messages = (Ably::Realtime::Connection::MAX_PROTOCOL_MESSAGE_BATCH_SIZE + 1).times.map do
|
427
|
+
{ name: 'foo' }
|
428
|
+
end
|
429
|
+
|
430
|
+
subject.publish(channel_name, messages).errback do |error|
|
431
|
+
expect(error).to be_kind_of(Ably::Exceptions::InvalidRequest)
|
432
|
+
stop_reactor
|
433
|
+
end
|
434
|
+
end
|
435
|
+
end
|
436
|
+
end
|
284
437
|
end
|
285
438
|
end
|