ably-rest 1.1.2 → 1.2.2

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 (111) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +3 -0
  3. data/CHANGELOG.md +1 -1
  4. data/MAINTAINERS.md +1 -0
  5. data/README.md +4 -2
  6. data/ably-rest.gemspec +15 -18
  7. data/lib/ably-rest.rb +2 -0
  8. data/lib/submodules/ably-ruby/.github/workflows/check.yml +50 -0
  9. data/lib/submodules/ably-ruby/CHANGELOG.md +200 -0
  10. data/lib/submodules/ably-ruby/COPYRIGHT +1 -0
  11. data/lib/submodules/ably-ruby/LICENSE +172 -11
  12. data/lib/submodules/ably-ruby/MAINTAINERS.md +1 -0
  13. data/lib/submodules/ably-ruby/README.md +24 -22
  14. data/lib/submodules/ably-ruby/SPEC.md +1020 -929
  15. data/lib/submodules/ably-ruby/UPDATING.md +30 -0
  16. data/lib/submodules/ably-ruby/ably.gemspec +16 -23
  17. data/lib/submodules/ably-ruby/lib/ably/agent.rb +3 -0
  18. data/lib/submodules/ably-ruby/lib/ably/auth.rb +20 -10
  19. data/lib/submodules/ably-ruby/lib/ably/exceptions.rb +8 -2
  20. data/lib/submodules/ably-ruby/lib/ably/logger.rb +4 -4
  21. data/lib/submodules/ably-ruby/lib/ably/models/channel_details.rb +59 -0
  22. data/lib/submodules/ably-ruby/lib/ably/models/channel_metrics.rb +84 -0
  23. data/lib/submodules/ably-ruby/lib/ably/models/channel_occupancy.rb +43 -0
  24. data/lib/submodules/ably-ruby/lib/ably/models/channel_options.rb +97 -0
  25. data/lib/submodules/ably-ruby/lib/ably/models/channel_status.rb +53 -0
  26. data/lib/submodules/ably-ruby/lib/ably/models/connection_details.rb +8 -0
  27. data/lib/submodules/ably-ruby/lib/ably/models/delta_extras.rb +29 -0
  28. data/lib/submodules/ably-ruby/lib/ably/models/device_details.rb +1 -1
  29. data/lib/submodules/ably-ruby/lib/ably/models/error_info.rb +6 -2
  30. data/lib/submodules/ably-ruby/lib/ably/models/idiomatic_ruby_wrapper.rb +4 -0
  31. data/lib/submodules/ably-ruby/lib/ably/models/message.rb +28 -3
  32. data/lib/submodules/ably-ruby/lib/ably/models/presence_message.rb +14 -0
  33. data/lib/submodules/ably-ruby/lib/ably/models/protocol_message.rb +31 -14
  34. data/lib/submodules/ably-ruby/lib/ably/models/token_details.rb +7 -2
  35. data/lib/submodules/ably-ruby/lib/ably/models/token_request.rb +1 -1
  36. data/lib/submodules/ably-ruby/lib/ably/modules/ably.rb +11 -1
  37. data/lib/submodules/ably-ruby/lib/ably/modules/channels_collection.rb +22 -2
  38. data/lib/submodules/ably-ruby/lib/ably/modules/conversions.rb +34 -0
  39. data/lib/submodules/ably-ruby/lib/ably/realtime/auth.rb +2 -2
  40. data/lib/submodules/ably-ruby/lib/ably/realtime/channel/channel_manager.rb +19 -7
  41. data/lib/submodules/ably-ruby/lib/ably/realtime/channel/channel_properties.rb +24 -0
  42. data/lib/submodules/ably-ruby/lib/ably/realtime/channel/channel_state_machine.rb +10 -1
  43. data/lib/submodules/ably-ruby/lib/ably/realtime/channel/publisher.rb +6 -0
  44. data/lib/submodules/ably-ruby/lib/ably/realtime/channel.rb +56 -28
  45. data/lib/submodules/ably-ruby/lib/ably/realtime/channels.rb +1 -1
  46. data/lib/submodules/ably-ruby/lib/ably/realtime/client/incoming_message_dispatcher.rb +14 -6
  47. data/lib/submodules/ably-ruby/lib/ably/realtime/client.rb +9 -0
  48. data/lib/submodules/ably-ruby/lib/ably/realtime/connection/connection_manager.rb +13 -4
  49. data/lib/submodules/ably-ruby/lib/ably/realtime/connection/connection_state_machine.rb +4 -0
  50. data/lib/submodules/ably-ruby/lib/ably/realtime/connection/websocket_transport.rb +67 -1
  51. data/lib/submodules/ably-ruby/lib/ably/realtime/connection.rb +6 -5
  52. data/lib/submodules/ably-ruby/lib/ably/realtime/presence.rb +0 -14
  53. data/lib/submodules/ably-ruby/lib/ably/rest/channel.rb +44 -29
  54. data/lib/submodules/ably-ruby/lib/ably/rest/client.rb +60 -29
  55. data/lib/submodules/ably-ruby/lib/ably/rest/middleware/encoder.rb +1 -1
  56. data/lib/submodules/ably-ruby/lib/ably/rest/middleware/exceptions.rb +1 -1
  57. data/lib/submodules/ably-ruby/lib/ably/rest/middleware/external_exceptions.rb +1 -1
  58. data/lib/submodules/ably-ruby/lib/ably/rest/middleware/fail_if_unsupported_mime_type.rb +5 -2
  59. data/lib/submodules/ably-ruby/lib/ably/rest/middleware/logger.rb +1 -1
  60. data/lib/submodules/ably-ruby/lib/ably/rest/middleware/parse_json.rb +1 -1
  61. data/lib/submodules/ably-ruby/lib/ably/rest/middleware/parse_message_pack.rb +1 -1
  62. data/lib/submodules/ably-ruby/lib/ably/util/crypto.rb +1 -1
  63. data/lib/submodules/ably-ruby/lib/ably/version.rb +2 -14
  64. data/lib/submodules/ably-ruby/lib/ably.rb +1 -0
  65. data/lib/submodules/ably-ruby/spec/acceptance/realtime/auth_spec.rb +4 -4
  66. data/lib/submodules/ably-ruby/spec/acceptance/realtime/channel_history_spec.rb +25 -0
  67. data/lib/submodules/ably-ruby/spec/acceptance/realtime/channel_spec.rb +476 -21
  68. data/lib/submodules/ably-ruby/spec/acceptance/realtime/channels_spec.rb +59 -7
  69. data/lib/submodules/ably-ruby/spec/acceptance/realtime/client_spec.rb +72 -16
  70. data/lib/submodules/ably-ruby/spec/acceptance/realtime/connection_failures_spec.rb +85 -13
  71. data/lib/submodules/ably-ruby/spec/acceptance/realtime/connection_spec.rb +301 -34
  72. data/lib/submodules/ably-ruby/spec/acceptance/realtime/message_spec.rb +77 -0
  73. data/lib/submodules/ably-ruby/spec/acceptance/realtime/presence_history_spec.rb +3 -59
  74. data/lib/submodules/ably-ruby/spec/acceptance/realtime/presence_spec.rb +84 -158
  75. data/lib/submodules/ably-ruby/spec/acceptance/realtime/push_admin_spec.rb +3 -19
  76. data/lib/submodules/ably-ruby/spec/acceptance/rest/auth_spec.rb +24 -75
  77. data/lib/submodules/ably-ruby/spec/acceptance/rest/base_spec.rb +8 -4
  78. data/lib/submodules/ably-ruby/spec/acceptance/rest/channel_spec.rb +141 -10
  79. data/lib/submodules/ably-ruby/spec/acceptance/rest/channels_spec.rb +23 -6
  80. data/lib/submodules/ably-ruby/spec/acceptance/rest/client_spec.rb +146 -47
  81. data/lib/submodules/ably-ruby/spec/acceptance/rest/message_spec.rb +61 -3
  82. data/lib/submodules/ably-ruby/spec/acceptance/rest/push_admin_spec.rb +3 -19
  83. data/lib/submodules/ably-ruby/spec/lib/unit/models/channel_options_spec.rb +52 -0
  84. data/lib/submodules/ably-ruby/spec/run_parallel_tests +2 -7
  85. data/lib/submodules/ably-ruby/spec/shared/client_initializer_behaviour.rb +131 -8
  86. data/lib/submodules/ably-ruby/spec/shared/model_behaviour.rb +1 -1
  87. data/lib/submodules/ably-ruby/spec/spec_helper.rb +12 -2
  88. data/lib/submodules/ably-ruby/spec/support/serialization_helper.rb +21 -0
  89. data/lib/submodules/ably-ruby/spec/support/test_app.rb +3 -3
  90. data/lib/submodules/ably-ruby/spec/unit/logger_spec.rb +6 -14
  91. data/lib/submodules/ably-ruby/spec/unit/models/channel_details_spec.rb +30 -0
  92. data/lib/submodules/ably-ruby/spec/unit/models/channel_metrics_spec.rb +42 -0
  93. data/lib/submodules/ably-ruby/spec/unit/models/channel_occupancy_spec.rb +17 -0
  94. data/lib/submodules/ably-ruby/spec/unit/models/channel_status_spec.rb +36 -0
  95. data/lib/submodules/ably-ruby/spec/unit/models/delta_extras_spec.rb +14 -0
  96. data/lib/submodules/ably-ruby/spec/unit/models/error_info_spec.rb +17 -1
  97. data/lib/submodules/ably-ruby/spec/unit/models/message_spec.rb +97 -0
  98. data/lib/submodules/ably-ruby/spec/unit/models/presence_message_spec.rb +49 -0
  99. data/lib/submodules/ably-ruby/spec/unit/models/protocol_message_spec.rb +125 -27
  100. data/lib/submodules/ably-ruby/spec/unit/models/token_details_spec.rb +14 -0
  101. data/lib/submodules/ably-ruby/spec/unit/realtime/channel_spec.rb +3 -2
  102. data/lib/submodules/ably-ruby/spec/unit/realtime/channels_spec.rb +53 -15
  103. data/lib/submodules/ably-ruby/spec/unit/realtime/client_spec.rb +19 -6
  104. data/lib/submodules/ably-ruby/spec/unit/realtime/incoming_message_dispatcher_spec.rb +38 -0
  105. data/lib/submodules/ably-ruby/spec/unit/rest/channel_spec.rb +44 -1
  106. data/lib/submodules/ably-ruby/spec/unit/rest/channels_spec.rb +81 -14
  107. data/lib/submodules/ably-ruby/spec/unit/rest/client_spec.rb +47 -0
  108. data/spec/spec_helper.rb +5 -0
  109. data/spec/unit/client_spec.rb +30 -0
  110. metadata +88 -25
  111. data/lib/submodules/ably-ruby/.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
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe Ably::Models::ChannelOptions do
6
+ let(:modes) { nil }
7
+ let(:params) { {} }
8
+ let(:options) { described_class.new(modes: modes, params: params) }
9
+
10
+ describe '#modes_to_flags' do
11
+ let(:modes) { %w[publish subscribe presence_subscribe] }
12
+
13
+ subject(:protocol_message) do
14
+ Ably::Models::ProtocolMessage.new(action: Ably::Models::ProtocolMessage::ACTION.Attach, flags: options.modes_to_flags)
15
+ end
16
+
17
+ it 'converts modes to ProtocolMessage#flags correctly' do
18
+ expect(protocol_message.has_attach_publish_flag?).to eq(true)
19
+ expect(protocol_message.has_attach_subscribe_flag?).to eq(true)
20
+ expect(protocol_message.has_attach_presence_subscribe_flag?).to eq(true)
21
+
22
+ expect(protocol_message.has_attach_resume_flag?).to eq(false)
23
+ expect(protocol_message.has_attach_presence_flag?).to eq(false)
24
+ end
25
+ end
26
+
27
+ describe '#set_modes_from_flags' do
28
+ let(:subscribe_flag) { 262144 }
29
+
30
+ it 'converts flags to ChannelOptions#modes correctly' do
31
+ result = options.set_modes_from_flags(subscribe_flag)
32
+
33
+ expect(result).to eq(options.modes)
34
+ expect(options.modes.map(&:to_sym)).to eq(%i[subscribe])
35
+ end
36
+ end
37
+
38
+ describe '#set_params' do
39
+ let(:previous_params) { { example_attribute: 1 } }
40
+ let(:new_params) { { new_attribute: 1 } }
41
+ let(:params) { previous_params }
42
+
43
+ it 'should be able to overwrite attributes' do
44
+ expect { options.set_params(new_params) }.to \
45
+ change { options.params }.from(previous_params).to(new_params)
46
+ end
47
+
48
+ it 'should be able to make params empty' do # (1)
49
+ expect { options.set_params({}) }.to change { options.params }.from(previous_params).to({})
50
+ end
51
+ end
52
+ end
@@ -11,13 +11,8 @@ DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
11
11
  bundle exec rspec "${DIR}/unit"
12
12
  unit_status=$?
13
13
 
14
- if ruby -v | grep -e "1.9"; then
15
- # Output with test ID is not supported with this old version of RSpec
16
- # So it will be jumbled sadly for 1.9.*
17
- bundle exec parallel_rspec "${DIR}/acceptance"
18
- else
19
- bundle exec parallel_rspec "${DIR}/acceptance" --prefix-output-with-test-env-number
20
- fi
14
+ bundle exec parallel_rspec "${DIR}/acceptance" --prefix-output-with-test-env-number
15
+
21
16
  acceptance_status=$?
22
17
 
23
18
  if [ $unit_status -ne 0 ]; then
@@ -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
@@ -19,7 +19,7 @@ shared_examples 'a model' do |shared_options = {}|
19
19
  end
20
20
 
21
21
  context '#attributes', :api_private do
22
- let(:model_options) { { action: 5 } }
22
+ let(:model_options) { { action: 5, max_message_size: 65536, max_frame_size: 524288 } }
23
23
 
24
24
  it 'provides access to #attributes' do
25
25
  expect(model.attributes).to eq(model_options)
@@ -5,8 +5,17 @@ def console(message)
5
5
  end
6
6
 
7
7
  unless RUBY_VERSION.match(/^1\./)
8
- require 'coveralls'
9
- Coveralls.wear!
8
+ require 'simplecov'
9
+
10
+ SimpleCov.start do
11
+ require 'simplecov-lcov'
12
+ SimpleCov::Formatter::LcovFormatter.config do |c|
13
+ c.report_with_single_file = true
14
+ c.single_report_path = 'coverage/lcov.info'
15
+ end
16
+ formatter SimpleCov::Formatter::LcovFormatter
17
+ add_filter %w[vendor spec]
18
+ end
10
19
  end
11
20
 
12
21
  require 'webmock/rspec'
@@ -19,6 +28,7 @@ require 'support/event_emitter_helper'
19
28
  require 'support/private_api_formatter'
20
29
  require 'support/protocol_helper'
21
30
  require 'support/random_helper'
31
+ require 'support/serialization_helper'
22
32
  require 'support/test_logger_helper'
23
33
 
24
34
  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
@@ -59,7 +59,7 @@ class TestApp
59
59
 
60
60
  url = "#{sandbox_client.endpoint}/apps/#{app_id}"
61
61
 
62
- basic_auth = Base64.encode64(api_key).chomp
62
+ basic_auth = Base64.urlsafe_encode64(api_key).chomp
63
63
  headers = { "Authorization" => "Basic #{basic_auth}" }
64
64
 
65
65
  Faraday.delete(url, nil, headers)
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe Ably::Logger do
3
+ describe Ably::Logger, :prevent_log_stubbing do
4
4
  let(:rest_client) do
5
5
  instance_double('Ably::Rest::Client')
6
6
  end
@@ -18,14 +18,10 @@ describe Ably::Logger do
18
18
 
19
19
  context 'internals', :api_private do
20
20
  it 'delegates to the default Logger object' do
21
- received = false
22
21
  expect(subject.logger).to be_a(::Logger)
23
- allow_any_instance_of(::Logger).to receive(:warn) do |*args, &block|
24
- expect(args.concat([block ? block.call : nil]).join(',')).to match(/message/)
25
- received = true
26
- end
22
+ expect(subject.logger).to receive(:warn).with('message')
23
+
27
24
  subject.warn 'message'
28
- expect(received).to be_truthy
29
25
  end
30
26
 
31
27
  context 'formatter' do
@@ -136,18 +132,14 @@ describe Ably::Logger do
136
132
  end
137
133
 
138
134
  it 'delegates log messages to logger', :api_private do
139
- received = false
140
- allow(custom_logger_object).to receive(:fatal) do |*args, &block|
141
- expect(args.concat([block ? block.call : nil]).join(',')).to match(/message/)
142
- received = true
143
- end
135
+ expect(custom_logger_object).to receive(:fatal).with('message')
136
+
144
137
  subject.fatal 'message'
145
- expect(received).to be_truthy
146
138
  end
147
139
  end
148
140
  end
149
141
 
150
- context 'with blocks', :prevent_log_stubbing do
142
+ context 'with blocks' do
151
143
  it 'does not call the block unless the log level is met' do
152
144
  log_level_blocks = []
153
145
  subject.warn { log_level_blocks << :warn }
@@ -0,0 +1,30 @@
1
+ require 'spec_helper'
2
+ require 'shared/model_behaviour'
3
+
4
+ describe Ably::Models::ChannelDetails do
5
+ subject { Ably::Models::ChannelDetails(channel_id: 'channel-id-123-xyz', name: 'name', status: { isActive: 'true', occupancy: { metrics: { connections: 1, presence_connections: 2, presence_members: 2, presence_subscribers: 5, publishers: 7, subscribers: 9 } } }) }
6
+
7
+ describe '#channel_id' do
8
+ it 'should return channel id' do
9
+ expect(subject.channel_id).to eq('channel-id-123-xyz')
10
+ end
11
+ end
12
+
13
+ describe '#name' do
14
+ it 'should return name' do
15
+ expect(subject.name).to eq('name')
16
+ end
17
+ end
18
+
19
+ describe '#status' do
20
+ it 'should return status' do
21
+ expect(subject.status).to be_a(Ably::Models::ChannelStatus)
22
+ expect(subject.status.occupancy.metrics.connections).to eq(1)
23
+ expect(subject.status.occupancy.metrics.presence_connections).to eq(2)
24
+ expect(subject.status.occupancy.metrics.presence_members).to eq(2)
25
+ expect(subject.status.occupancy.metrics.presence_subscribers).to eq(5)
26
+ expect(subject.status.occupancy.metrics.publishers).to eq(7)
27
+ expect(subject.status.occupancy.metrics.subscribers).to eq(9)
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,42 @@
1
+ require 'spec_helper'
2
+ require 'shared/model_behaviour'
3
+
4
+ describe Ably::Models::ChannelMetrics do
5
+ subject { Ably::Models::ChannelMetrics(connections: 1, presence_connections: 2, presence_members: 2, presence_subscribers: 5, publishers: 7, subscribers: 9) }
6
+
7
+ describe '#connections' do
8
+ it 'should return integer' do
9
+ expect(subject.connections).to eq(1)
10
+ end
11
+ end
12
+
13
+ describe '#presence_connections' do
14
+ it 'should return integer' do
15
+ expect(subject.presence_connections).to eq(2)
16
+ end
17
+ end
18
+
19
+ describe '#presence_members' do
20
+ it 'should return integer' do
21
+ expect(subject.presence_members).to eq(2)
22
+ end
23
+ end
24
+
25
+ describe '#presence_subscribers' do
26
+ it 'should return integer' do
27
+ expect(subject.presence_subscribers).to eq(5)
28
+ end
29
+ end
30
+
31
+ describe '#publishers' do
32
+ it 'should return integer' do
33
+ expect(subject.publishers).to eq(7)
34
+ end
35
+ end
36
+
37
+ describe '#subscribers' do
38
+ it 'should return integer' do
39
+ expect(subject.subscribers).to eq(9)
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+ require 'shared/model_behaviour'
3
+
4
+ describe Ably::Models::ChannelOccupancy do
5
+ subject { Ably::Models::ChannelOccupancy({ metrics: { connections: 1, presence_connections: 2, presence_members: 2, presence_subscribers: 5, publishers: 7, subscribers: 9 } }) }
6
+
7
+ describe '#metrics' do
8
+ it 'should return attributes' do
9
+ expect(subject.metrics.connections).to eq(1)
10
+ expect(subject.metrics.presence_connections).to eq(2)
11
+ expect(subject.metrics.presence_members).to eq(2)
12
+ expect(subject.metrics.presence_subscribers).to eq(5)
13
+ expect(subject.metrics.publishers).to eq(7)
14
+ expect(subject.metrics.subscribers).to eq(9)
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,36 @@
1
+ require 'spec_helper'
2
+ require 'shared/model_behaviour'
3
+
4
+ describe Ably::Models::ChannelStatus do
5
+ subject { Ably::Models::ChannelStatus({ isActive: 'true', occupancy: { metrics: { connections: 1, presence_connections: 2, presence_members: 2, presence_subscribers: 5, publishers: 7, subscribers: 9 } } }) }
6
+
7
+ describe '#is_active' do
8
+ context 'when occupancy is active' do
9
+ subject { Ably::Models::ChannelStatus({ isActive: true, occupancy: { metrics: { connections: 1, presence_connections: 2, presence_members: 2, presence_subscribers: 5, publishers: 7, subscribers: 9 } } }) }
10
+
11
+ it 'should return true' do
12
+ expect(subject.is_active).to eq(true)
13
+ end
14
+ end
15
+
16
+ context 'when occupancy is not active' do
17
+ subject { Ably::Models::ChannelStatus({ isActive: false, occupancy: { metrics: { connections: 1, presence_connections: 2, presence_members: 2, presence_subscribers: 5, publishers: 7, subscribers: 9 } } }) }
18
+
19
+ it 'should return false' do
20
+ expect(subject.is_active).to eq(false)
21
+ end
22
+ end
23
+ end
24
+
25
+ describe '#occupancy' do
26
+ it 'should return occupancy object' do
27
+ expect(subject.occupancy).to be_a(Ably::Models::ChannelOccupancy)
28
+ expect(subject.occupancy.metrics.connections).to eq(1)
29
+ expect(subject.occupancy.metrics.presence_connections).to eq(2)
30
+ expect(subject.occupancy.metrics.presence_members).to eq(2)
31
+ expect(subject.occupancy.metrics.presence_subscribers).to eq(5)
32
+ expect(subject.occupancy.metrics.publishers).to eq(7)
33
+ expect(subject.occupancy.metrics.subscribers).to eq(9)
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,14 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+
4
+ describe Ably::Models::DeltaExtras do
5
+ subject { described_class.new({ format: 'vcdiff', from: '1234-4567-8910-1001-1111'}) }
6
+
7
+ it 'should have `from` attribute' do
8
+ expect(subject.from).to eq('1234-4567-8910-1001-1111')
9
+ end
10
+
11
+ it 'should have `format` attribute' do
12
+ expect(subject.format).to eq('vcdiff')
13
+ end
14
+ end
@@ -5,7 +5,7 @@ describe Ably::Models::ErrorInfo do
5
5
  subject { Ably::Models::ErrorInfo }
6
6
 
7
7
  context '#TI1, #TI4' do
8
- it_behaves_like 'a model', with_simple_attributes: %w(code status_code href message) do
8
+ it_behaves_like 'a model', with_simple_attributes: %w(code status_code href message request_id cause) do
9
9
  let(:model_args) { [] }
10
10
  end
11
11
  end
@@ -18,6 +18,22 @@ describe Ably::Models::ErrorInfo do
18
18
  end
19
19
  end
20
20
 
21
+ context '#request_id #RSC7c' do
22
+ subject { Ably::Models::ErrorInfo.new('request_id' => '123-456-789-001') }
23
+
24
+ it 'should return request ID' do
25
+ expect(subject.request_id).to eql('123-456-789-001')
26
+ end
27
+ end
28
+
29
+ context '#cause #TI1' do
30
+ subject { Ably::Models::ErrorInfo.new('cause' => Ably::Models::ErrorInfo.new({})) }
31
+
32
+ it 'should return cause attribute' do
33
+ expect(subject.cause).to be_kind_of(Ably::Models::ErrorInfo)
34
+ end
35
+ end
36
+
21
37
  context 'log entries container help link #TI5' do
22
38
  context 'without an error code' do
23
39
  subject { Ably::Models::ErrorInfo.new('statusCode' => 401) }
@@ -211,6 +211,79 @@ describe Ably::Models::Message do
211
211
  end
212
212
  end
213
213
 
214
+ describe '#size' do
215
+ let(:model) { subject.new({ name: name, data: data, client_id: client_id, extras: extras }, protocol_message: protocol_message) }
216
+
217
+ context 'String (#TO3l8a)' do
218
+ let(:data) { 'example string data' }
219
+ let(:client_id) { '1' }
220
+ let(:name) { 'My Name' }
221
+ let(:extras) { 'extras' }
222
+
223
+ it 'should return 33 bytes' do
224
+ expect(model.size).to eq(33)
225
+ end
226
+ end
227
+
228
+ context 'Object (#TO3l8b)' do
229
+ let(:data) { Object.new }
230
+ let(:client_id) { String('10') }
231
+ let(:name) { 'John' }
232
+ let(:extras) { Hash.new }
233
+
234
+ it 'should return 38 bytes' do
235
+ expect(model.size).to eq(38)
236
+ end
237
+ end
238
+
239
+ context 'Array (#TO3l8b)' do
240
+ let(:data) { [1, 'two', :three] }
241
+ let(:client_id) { '2' }
242
+ let(:name) { 'Kate' }
243
+ let(:extras) { [] }
244
+
245
+ it 'should return 24 bytes' do
246
+ expect(model.size).to eq(24)
247
+ end
248
+ end
249
+
250
+ context 'extras (#TO3l8d)' do
251
+ let(:data) { { example: 'value', score: 1, hash: { test: true } } }
252
+ let(:client_id) { '3' }
253
+ let(:name) { 'John' }
254
+ let(:extras) { {} }
255
+
256
+ it 'should return 57 bytes' do
257
+ expect(model.size).to eq(57)
258
+ end
259
+ end
260
+
261
+ context 'nil (#TO3l8e)' do
262
+ let(:data) { nil }
263
+ let(:client_id) { '' }
264
+ let(:name) { '' }
265
+ let(:extras) { nil}
266
+
267
+ it 'should return 19 bytes' do
268
+ expect(model.size).to eq(0)
269
+ end
270
+ end
271
+ end
272
+
273
+ describe '#protocol_message_index (#RTL21)' do
274
+ let(:messages) { [{ name: 'test1' }, { name: 'test2' }, { name: 'test3' }] }
275
+
276
+ let(:protocol_message) do
277
+ Ably::Models::ProtocolMessage.new({ action: 1 }.merge(messages: messages))
278
+ end
279
+
280
+ it 'should return correct protocol_message_index' do
281
+ expect(protocol_message.messages[0].protocol_message_index).to eq(0)
282
+ expect(protocol_message.messages[1].protocol_message_index).to eq(1)
283
+ expect(protocol_message.messages[2].protocol_message_index).to eq(2)
284
+ end
285
+ end
286
+
214
287
  context 'from REST request with embedded fields', :api_private do
215
288
  let(:id) { random_str }
216
289
  let(:protocol_message_id) { random_str }
@@ -547,4 +620,28 @@ describe Ably::Models::Message do
547
620
  end
548
621
  end
549
622
  end
623
+
624
+ context '#delta_extras (TM2i)' do
625
+ let(:delta_extras) { message.delta_extras }
626
+
627
+ context 'when delta' do
628
+ let(:message) { subject.new({ extras: { delta: { from: '1234-1234-5678-9009', format: 'vcdiff' } } }) }
629
+
630
+ it 'should return vcdiff format' do
631
+ expect(delta_extras.format).to eq('vcdiff')
632
+ end
633
+
634
+ it 'should return 1234-1234-5678-9009 message id' do
635
+ expect(delta_extras.from).to eq('1234-1234-5678-9009')
636
+ end
637
+ end
638
+
639
+ context 'when no delta' do
640
+ let(:message) { subject.new({ extras: {} }) }
641
+
642
+ it 'should return nil' do
643
+ expect(delta_extras).to eq(nil)
644
+ end
645
+ end
646
+ end
550
647
  end