ably 1.1.4.rc → 1.1.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -83,6 +83,16 @@ describe Ably::Realtime::Channel, :event_machine do
83
83
  end
84
84
  end
85
85
 
86
+ it 'sets attach_serial property after the attachment (#RTL15a)' do
87
+ expect(channel.properties.attach_serial).to be_nil
88
+
89
+ channel.attach
90
+ channel.on(:attached) do
91
+ expect(channel.properties.attach_serial).to_not be_nil
92
+ stop_reactor
93
+ end
94
+ end
95
+
86
96
  it 'sends an ATTACH and waits for an ATTACHED (#RTL4c)' do
87
97
  connection.once(:connected) do
88
98
  attach_count = 0
@@ -87,22 +87,6 @@ describe Ably::Realtime::Client, :event_machine do
87
87
  end
88
88
  end
89
89
  end
90
-
91
- context 'with client_id' do
92
- let(:client_options) do
93
- default_options.merge(client_id: random_str)
94
- end
95
- it 'connects using token auth' do
96
- run_reactor do
97
- connection.on(:connected) do
98
- expect(connection.state).to eq(:connected)
99
- expect(auth_params[:access_token]).to_not be_nil
100
- expect(auth_params[:key]).to be_nil
101
- stop_reactor
102
- end
103
- end
104
- end
105
- end
106
90
  end
107
91
  end
108
92
 
@@ -249,6 +233,8 @@ describe Ably::Realtime::Client, :event_machine do
249
233
 
250
234
  context '#request (#RSC19*)' do
251
235
  let(:client_options) { default_options.merge(key: api_key) }
236
+ let(:device_id) { random_str }
237
+ let(:endpoint) { subject.rest_client.endpoint }
252
238
 
253
239
  context 'get' do
254
240
  it 'returns an HttpPaginatedResponse object' do
@@ -297,6 +283,76 @@ describe Ably::Realtime::Client, :event_machine do
297
283
  end
298
284
  end
299
285
  end
286
+
287
+
288
+ context 'post', :webmock do
289
+ before do
290
+ stub_request(:delete, "#{endpoint}/push/deviceRegistrations/#{device_id}/resetUpdateToken").
291
+ to_return(status: 200, body: '{}', headers: { 'Content-Type' => 'application/json' })
292
+ end
293
+
294
+ it 'supports post' do
295
+ subject.request(:delete, "push/deviceRegistrations/#{device_id}/resetUpdateToken").callback do |response|
296
+ expect(response).to be_success
297
+ stop_reactor
298
+ end
299
+ end
300
+ end
301
+
302
+ context 'delete', :webmock do
303
+ before do
304
+ stub_request(:delete, "#{endpoint}/push/channelSubscriptions?deviceId=#{device_id}").
305
+ to_return(status: 200, body: '{}', headers: { 'Content-Type' => 'application/json' })
306
+ end
307
+
308
+ it 'supports delete' do
309
+ subject.request(:delete, "/push/channelSubscriptions", { deviceId: device_id}).callback do |response|
310
+ expect(response).to be_success
311
+ stop_reactor
312
+ end
313
+ end
314
+ end
315
+
316
+ context 'patch', :webmock do
317
+ let(:body_params) { { 'metadata' => { 'key' => 'value' } } }
318
+
319
+ before do
320
+ stub_request(:patch, "#{endpoint}/push/deviceRegistrations/#{device_id}")
321
+ .with(body: serialize_body(body_params, protocol))
322
+ .to_return(status: 200, body: '{}', headers: { 'Content-Type' => 'application/json' })
323
+ end
324
+
325
+ it 'supports patch' do
326
+ subject.request(:patch, "/push/deviceRegistrations/#{device_id}", {}, body_params).callback do |response|
327
+ expect(response).to be_success
328
+ stop_reactor
329
+ end
330
+ end
331
+ end
332
+
333
+ context 'put', :webmock do
334
+ let(:body_params) do
335
+ {
336
+ 'id' => random_str,
337
+ 'platform' => 'ios',
338
+ 'formFactor' => 'phone',
339
+ 'metadata' => { 'key' => 'value' }
340
+ }
341
+ end
342
+
343
+ before do
344
+ stub_request(:put, "#{endpoint}/push/deviceRegistrations/#{device_id}")
345
+ .with(body: serialize_body(body_params, protocol))
346
+ .to_return(status: 200, body: '{}', headers: { 'Content-Type' => 'application/json' })
347
+ end
348
+
349
+ it 'supports put' do
350
+ subject.request(:put, "/push/deviceRegistrations/#{device_id}", {}, body_params).callback do |response|
351
+ expect(response).to be_success
352
+ stop_reactor
353
+ end
354
+ end
355
+ end
300
356
  end
301
357
 
302
358
  context '#publish (#TBC)' do
@@ -77,18 +77,6 @@ describe Ably::Realtime::Connection, :event_machine do
77
77
  end
78
78
  end
79
79
  end
80
-
81
- context 'with implicit authorisation' do
82
- let(:client_options) { default_options.merge(client_id: 'force_token_auth') }
83
-
84
- it 'uses the token created by the implicit authorisation' do
85
- expect(client.rest_client.auth).to receive(:request_token).once.and_call_original
86
-
87
- connection.once(:connected) do
88
- stop_reactor
89
- end
90
- end
91
- end
92
80
  end
93
81
 
94
82
  context 'that expire' do
@@ -1879,5 +1867,33 @@ describe Ably::Realtime::Connection, :event_machine do
1879
1867
  end
1880
1868
  end
1881
1869
  end
1870
+
1871
+ context 'transport_params (#RTC1f)' do
1872
+ let(:client_options) { default_options.merge(transport_params: { 'extra_param' => 'extra_param' }) }
1873
+
1874
+ it 'pases transport_params to query' do
1875
+ expect(EventMachine).to receive(:connect) do |host, port, transport, object, url|
1876
+ uri = URI.parse(url)
1877
+ expect(CGI::parse(uri.query)['extra_param'][0]).to eq('extra_param')
1878
+ stop_reactor
1879
+ end
1880
+
1881
+ client
1882
+ end
1883
+
1884
+ context 'when changing default param' do
1885
+ let(:client_options) { default_options.merge(transport_params: { v: '1.0' }) }
1886
+
1887
+ it 'overrides default param (#RTC1f1)' do
1888
+ expect(EventMachine).to receive(:connect) do |host, port, transport, object, url|
1889
+ uri = URI.parse(url)
1890
+ expect(CGI::parse(uri.query)['v'][0]).to eq('1.0')
1891
+ stop_reactor
1892
+ end
1893
+
1894
+ client
1895
+ end
1896
+ end
1897
+ end
1882
1898
  end
1883
1899
  end
@@ -52,63 +52,5 @@ describe Ably::Realtime::Presence, 'history', :event_machine do
52
52
 
53
53
  presence_client_one.enter(data)
54
54
  end
55
-
56
- context 'with option until_attach: true' do
57
- let(:event) { random_str }
58
- let(:presence_data_before_attach) { random_str }
59
- let(:presence_data_after_attach) { random_str }
60
-
61
- it 'retrieves all presence messages before channel was attached' do
62
- presence_client_two.enter(presence_data_before_attach) do
63
- presence_client_one.enter(presence_data_after_attach) do
64
- presence_client_one.history(until_attach: true) do |presence_page|
65
- expect(presence_page.items.count).to eql(1)
66
- expect(presence_page.items.first.data).to eql(presence_data_before_attach)
67
- stop_reactor
68
- end
69
- end
70
- end
71
- end
72
-
73
- context 'and two pages of messages' do
74
- let(:wildcard_token) { lambda { |token_params| Ably::Rest::Client.new(default_options).auth.request_token(client_id: '*') } }
75
- let(:client_one) { auto_close Ably::Realtime::Client.new(default_options.merge(auth_callback: wildcard_token)) }
76
- let(:client_two) { auto_close Ably::Realtime::Client.new(default_options.merge(auth_callback: wildcard_token)) }
77
-
78
- # TODO: Remove retry logic when presence history regression fixed
79
- # https://github.com/ably/realtime/issues/1707
80
- #
81
- it 'retrieves two pages of messages before channel was attached', retry: 10, :retry_wait => 5 do
82
- when_all(*10.times.map { |i| presence_client_two.enter_client("client:#{i}", presence_data_before_attach) }) do
83
- when_all(*10.times.map { |i| presence_client_one.enter_client("client:#{i}", presence_data_after_attach) }) do
84
- presence_client_one.history(until_attach: true, limit: 5) do |presence_page|
85
- expect(presence_page.items.count).to eql(5)
86
- expect(presence_page.items.map(&:data).uniq.first).to eql(presence_data_before_attach)
87
-
88
- presence_page.next do |presence_next_page|
89
- expect(presence_next_page.items.count).to eql(5)
90
- expect(presence_next_page.items.map(&:data).uniq.first).to eql(presence_data_before_attach)
91
- if presence_next_page.has_next?
92
- presence_next_page.next do |last|
93
- expect(last.items.count).to eql(0)
94
- end
95
- else
96
- expect(presence_next_page).to be_last
97
- end
98
- stop_reactor
99
- end
100
- end
101
- end
102
- end
103
- end
104
- end
105
-
106
- it 'fails with an exception unless state is attached' do
107
- presence_client_one.history(until_attach: true).errback do |error|
108
- expect(error.message).to match(/not attached/)
109
- stop_reactor
110
- end
111
- end
112
- end
113
55
  end
114
56
  end
@@ -2449,6 +2449,60 @@ describe Ably::Realtime::Presence, :event_machine do
2449
2449
  end
2450
2450
  end
2451
2451
 
2452
+ describe '#RTP17b' do
2453
+ let(:leave_action) { Ably::Models::PresenceMessage::ACTION.Leave }
2454
+
2455
+ it 'updates presence members on leave' do
2456
+ presence_client_two.subscribe(:enter) do
2457
+ channel_anonymous_client.attach do
2458
+ channel_anonymous_client.presence.get do |members|
2459
+ presence_client_two.subscribe(:leave) do
2460
+ expect(presence_client_two.members.local_members).to be_empty
2461
+ stop_reactor
2462
+ end
2463
+
2464
+ leave_message = Ably::Models::PresenceMessage.new(
2465
+ 'id' => "#{client_two.connection.id}:#{presence_client_two.client_id}:1",
2466
+ 'clientId' => presence_client_two.client_id,
2467
+ 'connectionId' => client_two.connection.id,
2468
+ 'timestamp' => as_since_epoch(Time.now),
2469
+ 'action' => leave_action
2470
+ )
2471
+
2472
+ presence_client_two.__incoming_msgbus__.publish :presence, leave_message
2473
+ end
2474
+ end
2475
+ end
2476
+
2477
+ presence_client_two.enter
2478
+ end
2479
+
2480
+ it 'does no update presence members on fabricated leave' do
2481
+ presence_client_two.subscribe(:enter) do
2482
+ channel_anonymous_client.attach do
2483
+ channel_anonymous_client.presence.get do |members|
2484
+ presence_client_two.subscribe(:leave) do
2485
+ expect(presence_client_two.members.local_members).to_not be_empty
2486
+ stop_reactor
2487
+ end
2488
+
2489
+ fabricated_leave_message = Ably::Models::PresenceMessage.new(
2490
+ 'id' => "#{client_two.connection.id}:#{presence_client_two.client_id}:1",
2491
+ 'clientId' => presence_client_two.client_id,
2492
+ 'connectionId' => "fabricated:#{presence_client_two.client_id}:0",
2493
+ 'timestamp' => as_since_epoch(Time.now),
2494
+ 'action' => leave_action
2495
+ )
2496
+
2497
+ presence_client_two.__incoming_msgbus__.publish :presence, fabricated_leave_message
2498
+ end
2499
+ end
2500
+ end
2501
+
2502
+ presence_client_two.enter
2503
+ end
2504
+ end
2505
+
2452
2506
  context 'when a channel becomes attached again' do
2453
2507
  let(:attached_action) { Ably::Models::ProtocolMessage::ACTION.Attached.to_i }
2454
2508
  let(:sync_action) { Ably::Models::ProtocolMessage::ACTION.Sync.to_i }
@@ -101,31 +101,15 @@ describe Ably::Realtime::Push::Admin, :event_machine do
101
101
  end
102
102
  end
103
103
 
104
- def request_body(request, protocol)
105
- if protocol == :msgpack
106
- MessagePack.unpack(request.body)
107
- else
108
- JSON.parse(request.body)
109
- end
110
- end
111
-
112
- def serialize(object, protocol)
113
- if protocol == :msgpack
114
- MessagePack.pack(object)
115
- else
116
- JSON.dump(object)
117
- end
118
- end
119
-
120
104
  let!(:publish_stub) do
121
105
  stub_request(:post, "#{client.rest_client.endpoint}/push/publish").
122
106
  with do |request|
123
- expect(request_body(request, protocol)['recipient']['camelCase']['secondLevelCamelCase']).to eql('val')
124
- expect(request_body(request, protocol)['recipient']).to_not have_key('camel_case')
107
+ expect(deserialize_body(request.body, protocol)['recipient']['camelCase']['secondLevelCamelCase']).to eql('val')
108
+ expect(deserialize_body(request.body, protocol)['recipient']).to_not have_key('camel_case')
125
109
  true
126
110
  end.to_return(
127
111
  :status => 201,
128
- :body => serialize({}, protocol),
112
+ :body => serialize_body({}, protocol),
129
113
  :headers => { 'Content-Type' => content_type }
130
114
  )
131
115
  end
@@ -41,22 +41,10 @@ describe Ably::Auth do
41
41
  end
42
42
 
43
43
  def request_body_includes(request, protocol, key, val)
44
- body = if protocol == :msgpack
45
- MessagePack.unpack(request.body)
46
- else
47
- JSON.parse(request.body)
48
- end
44
+ body = deserialize_body(request.body, protocol)
49
45
  body[convert_to_mixed_case(key)].to_s == val.to_s
50
46
  end
51
47
 
52
- def serialize(object, protocol)
53
- if protocol == :msgpack
54
- MessagePack.pack(object)
55
- else
56
- JSON.dump(object)
57
- end
58
- end
59
-
60
48
  it 'has immutable options' do
61
49
  expect { auth.options['key_name'] = 'new_name' }.to raise_error RuntimeError, /can't modify frozen.*Hash/
62
50
  end
@@ -74,7 +62,7 @@ describe Ably::Auth do
74
62
 
75
63
  it 'creates a TokenRequest automatically and sends it to Ably to obtain a token', webmock: true do
76
64
  token_request_stub = stub_request(:post, "#{client.endpoint}/keys/#{key_name}/requestToken").
77
- to_return(status: 201, body: serialize({}, protocol), headers: { 'Content-Type' => content_type })
65
+ to_return(status: 201, body: serialize_body({}, protocol), headers: { 'Content-Type' => content_type })
78
66
  expect(auth).to receive(:create_token_request).and_call_original
79
67
  auth.request_token
80
68
 
@@ -107,7 +95,7 @@ describe Ably::Auth do
107
95
  request_body_includes(request, protocol, token_param, coerce_if_time_value(token_param, random, multiply: 1000))
108
96
  end.to_return(
109
97
  :status => 201,
110
- :body => serialize(token_response, protocol),
98
+ :body => serialize_body(token_response, protocol),
111
99
  :headers => { 'Content-Type' => content_type }
112
100
  )
113
101
  end
@@ -138,7 +126,7 @@ describe Ably::Auth do
138
126
  request_body_includes(request, protocol, 'mac', mac)
139
127
  end.to_return(
140
128
  :status => 201,
141
- :body => serialize(token_response, protocol),
129
+ :body => serialize_body(token_response, protocol),
142
130
  :headers => { 'Content-Type' => content_type })
143
131
  end
144
132
 
@@ -168,7 +156,7 @@ describe Ably::Auth do
168
156
  request_body_includes(request, protocol, 'mac', mac)
169
157
  end.to_return(
170
158
  :status => 201,
171
- :body => serialize(token_response, protocol),
159
+ :body => serialize_body(token_response, protocol),
172
160
  :headers => { 'Content-Type' => content_type })
173
161
  end
174
162
 
@@ -310,7 +298,7 @@ describe Ably::Auth do
310
298
  request_body_includes(request, protocol, 'key_name', key_name)
311
299
  end.to_return(
312
300
  :status => 201,
313
- :body => serialize(token_response, protocol),
301
+ :body => serialize_body(token_response, protocol),
314
302
  :headers => { 'Content-Type' => content_type }
315
303
  )
316
304
  end
@@ -1129,63 +1117,6 @@ describe Ably::Auth do
1129
1117
  end
1130
1118
  end
1131
1119
 
1132
- context 'when implicit as a result of using :client_id' do
1133
- let(:client_id) { '999' }
1134
- let(:client) do
1135
- Ably::Rest::Client.new(key: api_key, client_id: client_id, environment: environment, protocol: protocol)
1136
- end
1137
- let(:token) { 'unique-token' }
1138
- let(:token_response) do
1139
- {
1140
- token: token
1141
- }.to_json
1142
- end
1143
-
1144
- context 'and requests to the Ably server are mocked', :webmock do
1145
- let!(:request_token_stub) do
1146
- stub_request(:post, "#{client.endpoint}/keys/#{key_name}/requestToken").
1147
- to_return(:status => 201, :body => token_response, :headers => { 'Content-Type' => 'application/json' })
1148
- end
1149
- let!(:publish_message_stub) do
1150
- stub_request(:post, "#{client.endpoint}/channels/foo/publish").
1151
- with(headers: { 'Authorization' => "Bearer #{encode64(token)}" }).
1152
- to_return(status: 201, body: '{}', headers: { 'Content-Type' => 'application/json' })
1153
- end
1154
-
1155
- it 'will send a token request to the server' do
1156
- client.channel('foo').publish('event', 'data')
1157
- expect(request_token_stub).to have_been_requested
1158
- end
1159
- end
1160
-
1161
- describe 'a token is created' do
1162
- let(:token) { client.auth.current_token_details }
1163
-
1164
- it 'before a request is made' do
1165
- expect(token).to be_nil
1166
- end
1167
-
1168
- it 'when a message is published' do
1169
- expect(client.channel('foo').publish('event', 'data')).to be_truthy
1170
- end
1171
-
1172
- it 'with capability and TTL defaults (#TK2a, #TK2b)' do
1173
- client.channel('foo').publish('event', 'data')
1174
-
1175
- expect(token).to be_a(Ably::Models::TokenDetails)
1176
- capability_with_str_key = { "*" => ["*"] } # Ably default is all capabilities
1177
- capability = Hash[capability_with_str_key.keys.map(&:to_s).zip(capability_with_str_key.values)]
1178
- expect(token.capability).to eq(capability)
1179
- expect(token.expires.to_i).to be_within(2).of(Time.now.to_i + 60 * 60) # Ably default is 1hr
1180
- expect(token.client_id).to eq(client_id)
1181
- end
1182
-
1183
- specify '#client_id contains the client_id' do
1184
- expect(client.auth.client_id).to eql(client_id)
1185
- end
1186
- end
1187
- end
1188
-
1189
1120
  context 'when token expires' do
1190
1121
  before do
1191
1122
  stub_const 'Ably::Models::TokenDetails::TOKEN_EXPIRY_BUFFER', 0 # allow token to be used even if about to expire