ably 1.1.2 → 1.1.6

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 (43) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/check.yml +27 -0
  3. data/CHANGELOG.md +67 -0
  4. data/COPYRIGHT +1 -0
  5. data/LICENSE +172 -11
  6. data/MAINTAINERS.md +1 -0
  7. data/README.md +11 -21
  8. data/SPEC.md +1020 -922
  9. data/ably.gemspec +4 -4
  10. data/lib/ably/auth.rb +12 -2
  11. data/lib/ably/exceptions.rb +2 -2
  12. data/lib/ably/modules/ably.rb +11 -1
  13. data/lib/ably/realtime/channel.rb +7 -11
  14. data/lib/ably/realtime/channel/channel_manager.rb +2 -2
  15. data/lib/ably/realtime/channel/channel_properties.rb +24 -0
  16. data/lib/ably/realtime/client.rb +9 -0
  17. data/lib/ably/realtime/connection.rb +5 -4
  18. data/lib/ably/realtime/connection/websocket_transport.rb +67 -1
  19. data/lib/ably/realtime/presence.rb +0 -14
  20. data/lib/ably/rest/channel.rb +27 -19
  21. data/lib/ably/rest/client.rb +31 -15
  22. data/lib/ably/rest/middleware/fail_if_unsupported_mime_type.rb +4 -1
  23. data/lib/ably/version.rb +1 -1
  24. data/spec/acceptance/realtime/auth_spec.rb +3 -3
  25. data/spec/acceptance/realtime/channel_spec.rb +10 -0
  26. data/spec/acceptance/realtime/client_spec.rb +72 -16
  27. data/spec/acceptance/realtime/connection_failures_spec.rb +26 -11
  28. data/spec/acceptance/realtime/connection_spec.rb +36 -17
  29. data/spec/acceptance/realtime/presence_history_spec.rb +0 -58
  30. data/spec/acceptance/realtime/presence_spec.rb +54 -0
  31. data/spec/acceptance/realtime/push_admin_spec.rb +3 -19
  32. data/spec/acceptance/rest/auth_spec.rb +6 -75
  33. data/spec/acceptance/rest/base_spec.rb +8 -4
  34. data/spec/acceptance/rest/channel_spec.rb +42 -4
  35. data/spec/acceptance/rest/client_spec.rb +121 -26
  36. data/spec/acceptance/rest/push_admin_spec.rb +3 -19
  37. data/spec/shared/client_initializer_behaviour.rb +131 -8
  38. data/spec/spec_helper.rb +1 -0
  39. data/spec/support/serialization_helper.rb +21 -0
  40. data/spec/support/test_app.rb +2 -2
  41. data/spec/unit/realtime/client_spec.rb +19 -6
  42. metadata +20 -15
  43. data/.travis.yml +0 -19
@@ -89,31 +89,15 @@ describe Ably::Rest::Push::Admin do
89
89
  end
90
90
  end
91
91
 
92
- def request_body(request, protocol)
93
- if protocol == :msgpack
94
- MessagePack.unpack(request.body)
95
- else
96
- JSON.parse(request.body)
97
- end
98
- end
99
-
100
- def serialize(object, protocol)
101
- if protocol == :msgpack
102
- MessagePack.pack(object)
103
- else
104
- JSON.dump(object)
105
- end
106
- end
107
-
108
92
  let!(:publish_stub) do
109
93
  stub_request(:post, "#{client.endpoint}/push/publish").
110
94
  with do |request|
111
- expect(request_body(request, protocol)['recipient']['camelCase']['secondLevelCamelCase']).to eql('val')
112
- expect(request_body(request, protocol)['recipient']).to_not have_key('camel_case')
95
+ expect(deserialize_body(request.body, protocol)['recipient']['camelCase']['secondLevelCamelCase']).to eql('val')
96
+ expect(deserialize_body(request.body, protocol)['recipient']).to_not have_key('camel_case')
113
97
  true
114
98
  end.to_return(
115
99
  :status => 201,
116
- :body => serialize({}, protocol),
100
+ :body => serialize_body({}, protocol),
117
101
  :headers => { 'Content-Type' => content_type }
118
102
  )
119
103
  end
@@ -69,14 +69,6 @@ shared_examples 'a client initializer' do
69
69
  expect { subject }.to raise_error(ArgumentError, /key and key_name or key_secret are mutually exclusive/)
70
70
  end
71
71
  end
72
-
73
- context 'client_id as only option' do
74
- let(:client_options) { { client_id: 'valid' } }
75
-
76
- it 'requires a valid key' do
77
- expect { subject }.to raise_error(ArgumentError, /client_id cannot be provided without a complete API key or means to authenticate/)
78
- end
79
- end
80
72
  end
81
73
 
82
74
  context 'with valid arguments' do
@@ -273,6 +265,137 @@ shared_examples 'a client initializer' do
273
265
  end
274
266
  end
275
267
  end
268
+
269
+ context 'environment' do
270
+ context 'when set without custom fallback hosts configured' do
271
+ let(:environment) { 'foo' }
272
+ let(:client_options) { default_options.merge(environment: environment) }
273
+ let(:default_fallbacks) { %w(a b c d e).map { |id| "#{environment}-#{id}-fallback.ably-realtime.com" } }
274
+
275
+ it 'sets the environment attribute' do
276
+ expect(subject.environment).to eql(environment)
277
+ end
278
+
279
+ it 'uses the default fallback hosts (#TBC, see https://github.com/ably/wiki/issues/361)' do
280
+ expect(subject.fallback_hosts.sort).to eql(default_fallbacks)
281
+ end
282
+ end
283
+
284
+ context 'when set with custom fallback hosts configured' do
285
+ let(:environment) { 'foo' }
286
+ let(:custom_fallbacks) { %w(a b c).map { |id| "#{environment}-#{id}.foo.com" } }
287
+ let(:client_options) { default_options.merge(environment: environment, fallback_hosts: custom_fallbacks) }
288
+
289
+ it 'sets the environment attribute' do
290
+ expect(subject.environment).to eql(environment)
291
+ end
292
+
293
+ it 'uses the custom provided fallback hosts (#RSC15a)' do
294
+ expect(subject.fallback_hosts.sort).to eql(custom_fallbacks)
295
+ end
296
+ end
297
+
298
+ context 'when set with fallback_hosts_use_default' do
299
+ let(:environment) { 'foo' }
300
+ let(:custom_fallbacks) { %w(a b c).map { |id| "#{environment}-#{id}.foo.com" } }
301
+ let(:default_production_fallbacks) { %w(a b c d e).map { |id| "#{id}.ably-realtime.com" } }
302
+ let(:client_options) { default_options.merge(environment: environment, fallback_hosts_use_default: true) }
303
+
304
+ it 'sets the environment attribute' do
305
+ expect(subject.environment).to eql(environment)
306
+ end
307
+
308
+ it 'uses the production default fallback hosts (#RTN17b)' do
309
+ expect(subject.fallback_hosts.sort).to eql(default_production_fallbacks)
310
+ end
311
+ end
312
+ end
313
+
314
+ context 'rest_host' do
315
+ context 'when set without custom fallback hosts configured' do
316
+ let(:custom_rest_host) { 'foo.com' }
317
+ let(:client_options) { default_options.merge(rest_host: custom_rest_host) }
318
+
319
+ it 'sets the custom_host attribute' do
320
+ expect(subject.custom_host).to eql(custom_rest_host)
321
+ end
322
+
323
+ it 'has no default fallback hosts' do
324
+ expect(subject.fallback_hosts).to be_empty
325
+ end
326
+ end
327
+
328
+ context 'when set with environment and without custom fallback hosts configured' do
329
+ let(:environment) { 'foobar' }
330
+ let(:custom_rest_host) { 'foo.com' }
331
+ let(:client_options) { default_options.merge(environment: environment, rest_host: custom_rest_host) }
332
+
333
+ it 'sets the environment attribute' do
334
+ expect(subject.environment).to eql(environment)
335
+ end
336
+
337
+ it 'sets the custom_host attribute' do
338
+ expect(subject.custom_host).to eql(custom_rest_host)
339
+ end
340
+
341
+ it 'has no default fallback hosts' do
342
+ expect(subject.fallback_hosts).to be_empty
343
+ end
344
+ end
345
+
346
+ context 'when set with custom fallback hosts configured' do
347
+ let(:custom_rest_host) { 'foo.com' }
348
+ let(:custom_fallbacks) { %w(a b c).map { |id| "#{environment}-#{id}.foo.com" } }
349
+ let(:client_options) { default_options.merge(rest_host: custom_rest_host, fallback_hosts: custom_fallbacks) }
350
+
351
+ it 'sets the custom_host attribute' do
352
+ expect(subject.custom_host).to eql(custom_rest_host)
353
+ end
354
+
355
+ it 'has no default fallback hosts' do
356
+ expect(subject.fallback_hosts.sort).to eql(custom_fallbacks)
357
+ end
358
+ end
359
+ end
360
+
361
+ context 'realtime_host' do
362
+ context 'when set without custom fallback hosts configured' do
363
+ let(:custom_realtime_host) { 'realtime.foo.com' }
364
+ let(:client_options) { default_options.merge(realtime_host: custom_realtime_host) }
365
+
366
+ # These tests are shared between realtime & rest clients
367
+ # So don't test for the attribute, instead test the options
368
+ it 'sets the realtime_host option' do
369
+ expect(subject.options[:realtime_host]).to eql(custom_realtime_host)
370
+ end
371
+
372
+ it 'has no default fallback hosts' do
373
+ expect(subject.fallback_hosts).to be_empty
374
+ end
375
+ end
376
+ end
377
+
378
+ context 'custom port' do
379
+ context 'when set without custom fallback hosts configured' do
380
+ let(:custom_port) { 555 }
381
+ let(:client_options) { default_options.merge(port: custom_port) }
382
+
383
+ it 'has no default fallback hosts' do
384
+ expect(subject.fallback_hosts).to be_empty
385
+ end
386
+ end
387
+ end
388
+
389
+ context 'custom TLS port' do
390
+ context 'when set without custom fallback hosts configured' do
391
+ let(:custom_port) { 555 }
392
+ let(:client_options) { default_options.merge(tls_port: custom_port) }
393
+
394
+ it 'has no default fallback hosts' do
395
+ expect(subject.fallback_hosts).to be_empty
396
+ end
397
+ end
398
+ end
276
399
  end
277
400
 
278
401
  context 'delegators' do
data/spec/spec_helper.rb CHANGED
@@ -19,6 +19,7 @@ require 'support/event_emitter_helper'
19
19
  require 'support/private_api_formatter'
20
20
  require 'support/protocol_helper'
21
21
  require 'support/random_helper'
22
+ require 'support/serialization_helper'
22
23
  require 'support/test_logger_helper'
23
24
 
24
25
  require 'rspec_config'
@@ -0,0 +1,21 @@
1
+ module SerializationHelper
2
+ def serialize_body(object, protocol)
3
+ if protocol == :msgpack
4
+ MessagePack.pack(object)
5
+ else
6
+ JSON.dump(object)
7
+ end
8
+ end
9
+
10
+ def deserialize_body(object, protocol)
11
+ if protocol == :msgpack
12
+ MessagePack.unpack(object)
13
+ else
14
+ JSON.parse(object)
15
+ end
16
+ end
17
+
18
+ RSpec.configure do |config|
19
+ config.include self
20
+ end
21
+ end
@@ -4,11 +4,11 @@ class TestApp
4
4
  TEST_RESOURCES_PATH = File.expand_path('../../../lib/submodules/ably-common/test-resources', __FILE__)
5
5
 
6
6
  # App configuration for test app
7
- # See https://github.com/ably/ably-common/blob/master/test-resources/test-app-setup.json
7
+ # See https://github.com/ably/ably-common/blob/main/test-resources/test-app-setup.json
8
8
  APP_SPEC = JSON.parse(File.read(File.join(TEST_RESOURCES_PATH, 'test-app-setup.json')))['post_apps']
9
9
 
10
10
  # Cipher details used for client_encoded presence data in test app
11
- # See https://github.com/ably/ably-common/blob/master/test-resources/test-app-setup.json
11
+ # See https://github.com/ably/ably-common/blob/main/test-resources/test-app-setup.json
12
12
  APP_SPEC_CIPHER = JSON.parse(File.read(File.join(TEST_RESOURCES_PATH, 'test-app-setup.json')))['cipher']
13
13
 
14
14
  # If an app has already been created and we need a new app, create a new test app
@@ -3,7 +3,7 @@ require 'spec_helper'
3
3
  require 'shared/client_initializer_behaviour'
4
4
 
5
5
  describe Ably::Realtime::Client do
6
- subject do
6
+ subject(:realtime_client) do
7
7
  Ably::Realtime::Client.new(client_options)
8
8
  end
9
9
 
@@ -15,28 +15,41 @@ describe Ably::Realtime::Client do
15
15
  it 'passes on the options to the initializer' do
16
16
  rest_client = instance_double('Ably::Rest::Client', auth: instance_double('Ably::Auth'), options: client_options, environment: 'production', use_tls?: true, custom_tls_port: nil)
17
17
  expect(Ably::Rest::Client).to receive(:new).with(hash_including(client_options)).and_return(rest_client)
18
- subject
18
+ realtime_client
19
19
  end
20
20
 
21
21
  context 'for attribute' do
22
22
  [:environment, :use_tls?, :log_level, :custom_host].each do |attribute|
23
23
  specify "##{attribute}" do
24
- expect(subject.rest_client).to receive(attribute)
25
- subject.public_send attribute
24
+ expect(realtime_client.rest_client).to receive(attribute)
25
+ realtime_client.public_send attribute
26
26
  end
27
27
  end
28
28
  end
29
29
  end
30
30
 
31
+ context 'when :transport_params option is passed' do
32
+ let(:expected_transport_params) do
33
+ { 'heartbeats' => 'true', 'v' => '1.0', 'extra_param' => 'extra_param' }
34
+ end
35
+ let(:client_options) do
36
+ { key: 'appid.keyuid:keysecret', transport_params: { heartbeats: true, v: 1.0, extra_param: 'extra_param'} }
37
+ end
38
+
39
+ it 'converts options to strings' do
40
+ expect(realtime_client.transport_params).to eq(expected_transport_params)
41
+ end
42
+ end
43
+
31
44
  context 'push' do
32
45
  let(:client_options) { { key: 'appid.keyuid:keysecret' } }
33
46
 
34
47
  specify '#device is not supported and raises an exception' do
35
- expect { subject.device }.to raise_error Ably::Exceptions::PushNotificationsNotSupported
48
+ expect { realtime_client.device }.to raise_error Ably::Exceptions::PushNotificationsNotSupported
36
49
  end
37
50
 
38
51
  specify '#push returns a Push object' do
39
- expect(subject.push).to be_a(Ably::Realtime::Push)
52
+ expect(realtime_client.push).to be_a(Ably::Realtime::Push)
40
53
  end
41
54
  end
42
55
 
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ably
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.2
4
+ version: 1.1.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lewis Marshall
8
8
  - Matthew O'Riordan
9
- autorequire:
9
+ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2019-08-06 00:00:00.000000000 Z
12
+ date: 2021-05-25 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: eventmachine
@@ -45,42 +45,42 @@ dependencies:
45
45
  requirements:
46
46
  - - "~>"
47
47
  - !ruby/object:Gem::Version
48
- version: 1.0.0
48
+ version: '7.4'
49
49
  type: :runtime
50
50
  prerelease: false
51
51
  version_requirements: !ruby/object:Gem::Requirement
52
52
  requirements:
53
53
  - - "~>"
54
54
  - !ruby/object:Gem::Version
55
- version: 1.0.0
55
+ version: '7.4'
56
56
  - !ruby/object:Gem::Dependency
57
57
  name: faraday
58
58
  requirement: !ruby/object:Gem::Requirement
59
59
  requirements:
60
60
  - - "~>"
61
61
  - !ruby/object:Gem::Version
62
- version: '0.12'
62
+ version: '1.0'
63
63
  type: :runtime
64
64
  prerelease: false
65
65
  version_requirements: !ruby/object:Gem::Requirement
66
66
  requirements:
67
67
  - - "~>"
68
68
  - !ruby/object:Gem::Version
69
- version: '0.12'
69
+ version: '1.0'
70
70
  - !ruby/object:Gem::Dependency
71
- name: excon
71
+ name: typhoeus
72
72
  requirement: !ruby/object:Gem::Requirement
73
73
  requirements:
74
74
  - - "~>"
75
75
  - !ruby/object:Gem::Version
76
- version: '0.55'
76
+ version: '1.4'
77
77
  type: :runtime
78
78
  prerelease: false
79
79
  version_requirements: !ruby/object:Gem::Requirement
80
80
  requirements:
81
81
  - - "~>"
82
82
  - !ruby/object:Gem::Version
83
- version: '0.55'
83
+ version: '1.4'
84
84
  - !ruby/object:Gem::Dependency
85
85
  name: json
86
86
  requirement: !ruby/object:Gem::Requirement
@@ -241,14 +241,14 @@ dependencies:
241
241
  requirements:
242
242
  - - "~>"
243
243
  - !ruby/object:Gem::Version
244
- version: '2.2'
244
+ version: '3.11'
245
245
  type: :development
246
246
  prerelease: false
247
247
  version_requirements: !ruby/object:Gem::Requirement
248
248
  requirements:
249
249
  - - "~>"
250
250
  - !ruby/object:Gem::Version
251
- version: '2.2'
251
+ version: '3.11'
252
252
  - !ruby/object:Gem::Dependency
253
253
  name: coveralls
254
254
  requirement: !ruby/object:Gem::Requirement
@@ -314,13 +314,15 @@ extensions: []
314
314
  extra_rdoc_files: []
315
315
  files:
316
316
  - ".editorconfig"
317
+ - ".github/workflows/check.yml"
317
318
  - ".gitignore"
318
319
  - ".gitmodules"
319
320
  - ".rspec"
320
- - ".travis.yml"
321
321
  - CHANGELOG.md
322
+ - COPYRIGHT
322
323
  - Gemfile
323
324
  - LICENSE
325
+ - MAINTAINERS.md
324
326
  - README.md
325
327
  - Rakefile
326
328
  - SPEC.md
@@ -377,6 +379,7 @@ files:
377
379
  - lib/ably/realtime/auth.rb
378
380
  - lib/ably/realtime/channel.rb
379
381
  - lib/ably/realtime/channel/channel_manager.rb
382
+ - lib/ably/realtime/channel/channel_properties.rb
380
383
  - lib/ably/realtime/channel/channel_state_machine.rb
381
384
  - lib/ably/realtime/channel/publisher.rb
382
385
  - lib/ably/realtime/channel/push_channel.rb
@@ -460,6 +463,7 @@ files:
460
463
  - spec/support/protocol_helper.rb
461
464
  - spec/support/random_helper.rb
462
465
  - spec/support/rest_testapp_before_retry.rb
466
+ - spec/support/serialization_helper.rb
463
467
  - spec/support/test_app.rb
464
468
  - spec/support/test_logger_helper.rb
465
469
  - spec/unit/auth_spec.rb
@@ -512,7 +516,7 @@ homepage: http://github.com/ably/ably-ruby
512
516
  licenses:
513
517
  - Apache-2.0
514
518
  metadata: {}
515
- post_install_message:
519
+ post_install_message:
516
520
  rdoc_options: []
517
521
  require_paths:
518
522
  - lib
@@ -528,7 +532,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
528
532
  version: '0'
529
533
  requirements: []
530
534
  rubygems_version: 3.0.3
531
- signing_key:
535
+ signing_key:
532
536
  specification_version: 4
533
537
  summary: A Ruby client library for ably.io realtime messaging implemented using EventMachine
534
538
  test_files:
@@ -574,6 +578,7 @@ test_files:
574
578
  - spec/support/protocol_helper.rb
575
579
  - spec/support/random_helper.rb
576
580
  - spec/support/rest_testapp_before_retry.rb
581
+ - spec/support/serialization_helper.rb
577
582
  - spec/support/test_app.rb
578
583
  - spec/support/test_logger_helper.rb
579
584
  - spec/unit/auth_spec.rb
data/.travis.yml DELETED
@@ -1,19 +0,0 @@
1
- sudo: false
2
- env:
3
- - RSPEC_RETRY=true PARALLEL_TEST_PROCESSORS=2 PROTOCOL=json
4
- - RSPEC_RETRY=true PARALLEL_TEST_PROCESSORS=2 PROTOCOL=msgpack
5
- language: ruby
6
- rvm:
7
- - 1.9.3
8
- - 2.1.10
9
- - 2.2.10
10
- - 2.3.8
11
- - 2.5.5
12
- - 2.6.0
13
- - 2.6.1
14
- - 2.6.2
15
- - 2.6.3
16
- script: spec/run_parallel_tests
17
- notifications:
18
- slack:
19
- secure: Xe8MwDcV2C8XLGk6O6Co31LpQiRSxsmS7Toy5vM7rHds5fnVRBNn5iX6Q5mXMdLOlnsMhjKLt7zl4fsBOZv+siQ+Us0omZSIYpXCYSCIj8nofReF0Lj8M4oa6lFSL5OuygO7PH+wLKTRxQURGZ6Pi1nHU+RE5izRmsewQHkhtY0=