ably 0.7.5 → 0.7.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.
- checksums.yaml +5 -13
- data/.gitignore +1 -0
- data/.gitmodules +3 -0
- data/README.md +46 -22
- data/SPEC.md +345 -240
- data/ably.gemspec +4 -2
- data/lib/ably/auth.rb +18 -14
- data/lib/ably/models/message.rb +1 -1
- data/lib/ably/models/paginated_resource.rb +31 -44
- data/lib/ably/models/presence_message.rb +1 -1
- data/lib/ably/models/stat.rb +67 -24
- data/lib/ably/models/stats_types.rb +131 -0
- data/lib/ably/modules/async_wrapper.rb +3 -2
- data/lib/ably/modules/message_emitter.rb +2 -2
- data/lib/ably/realtime.rb +1 -1
- data/lib/ably/realtime/channel.rb +24 -3
- data/lib/ably/realtime/channel/channel_manager.rb +1 -0
- data/lib/ably/realtime/client.rb +2 -2
- data/lib/ably/realtime/connection.rb +1 -1
- data/lib/ably/realtime/presence.rb +12 -1
- data/lib/ably/rest.rb +1 -1
- data/lib/ably/rest/channel.rb +4 -5
- data/lib/ably/rest/client.rb +5 -5
- data/lib/ably/rest/presence.rb +2 -2
- data/lib/ably/version.rb +1 -1
- data/spec/acceptance/realtime/channel_history_spec.rb +74 -23
- data/spec/acceptance/realtime/channel_spec.rb +3 -3
- data/spec/acceptance/realtime/client_spec.rb +3 -3
- data/spec/acceptance/realtime/connection_failures_spec.rb +2 -2
- data/spec/acceptance/realtime/connection_spec.rb +4 -4
- data/spec/acceptance/realtime/message_spec.rb +5 -5
- data/spec/acceptance/realtime/presence_history_spec.rb +56 -13
- data/spec/acceptance/realtime/presence_spec.rb +8 -8
- data/spec/acceptance/realtime/stats_spec.rb +1 -1
- data/spec/acceptance/realtime/time_spec.rb +1 -1
- data/spec/acceptance/rest/auth_spec.rb +31 -4
- data/spec/acceptance/rest/base_spec.rb +3 -3
- data/spec/acceptance/rest/channel_spec.rb +19 -19
- data/spec/acceptance/rest/channels_spec.rb +1 -1
- data/spec/acceptance/rest/client_spec.rb +9 -6
- data/spec/acceptance/rest/encoders_spec.rb +1 -1
- data/spec/acceptance/rest/message_spec.rb +10 -10
- data/spec/acceptance/rest/presence_spec.rb +81 -51
- data/spec/acceptance/rest/stats_spec.rb +46 -41
- data/spec/acceptance/rest/time_spec.rb +1 -1
- data/spec/shared/client_initializer_behaviour.rb +30 -19
- data/spec/spec_helper.rb +3 -0
- data/spec/support/markdown_spec_formatter.rb +1 -1
- data/spec/support/test_app.rb +11 -24
- data/spec/unit/auth_spec.rb +1 -1
- data/spec/unit/models/paginated_resource_spec.rb +81 -72
- data/spec/unit/models/stats_spec.rb +289 -0
- data/spec/unit/modules/async_wrapper_spec.rb +1 -1
- data/spec/unit/realtime/client_spec.rb +1 -1
- data/spec/unit/realtime/realtime_spec.rb +1 -1
- data/spec/unit/rest/channel_spec.rb +1 -1
- data/spec/unit/rest/client_spec.rb +8 -8
- data/spec/unit/rest/rest_spec.rb +1 -1
- data/spec/unit/util/crypto_spec.rb +1 -1
- metadata +55 -43
- data/spec/resources/crypto-data-128.json +0 -56
- data/spec/resources/crypto-data-256.json +0 -56
- data/spec/unit/models/stat_spec.rb +0 -113
@@ -15,7 +15,7 @@ describe Ably::Rest::Channels do
|
|
15
15
|
|
16
16
|
vary_by_protocol do
|
17
17
|
let(:client) do
|
18
|
-
Ably::Rest::Client.new(
|
18
|
+
Ably::Rest::Client.new(key: api_key, environment: environment, protocol: protocol)
|
19
19
|
end
|
20
20
|
let(:channel_name) { random_str }
|
21
21
|
let(:options) { { key: 'value' } }
|
@@ -43,12 +43,15 @@ describe Ably::Rest::Client do
|
|
43
43
|
Ably::Rest::Client.new(client_options) do
|
44
44
|
@request_index ||= 0
|
45
45
|
@request_index += 1
|
46
|
-
send("token_request_#{@request_index}")
|
46
|
+
send("token_request_#{@request_index > 2 ? 'next' : @request_index}")
|
47
47
|
end
|
48
48
|
end
|
49
49
|
let(:token_request_1) { client.auth.create_token_request(token_request_options.merge(client_id: random_str)) }
|
50
50
|
let(:token_request_2) { client.auth.create_token_request(token_request_options.merge(client_id: random_str)) }
|
51
51
|
|
52
|
+
# If token expires against whilst runnig tests in a slower CI environment then use this token
|
53
|
+
let(:token_request_next) { client.auth.create_token_request(token_request_options.merge(client_id: random_str)) }
|
54
|
+
|
52
55
|
context 'when expired' do
|
53
56
|
let(:token_request_options) { { key_id: key_id, key_secret: key_secret, ttl: Ably::Models::Token::TOKEN_EXPIRY_BUFFER } }
|
54
57
|
|
@@ -79,7 +82,7 @@ describe Ably::Rest::Client do
|
|
79
82
|
end
|
80
83
|
|
81
84
|
context 'connection transport' do
|
82
|
-
let(:client_options) { default_options.merge(
|
85
|
+
let(:client_options) { default_options.merge(key: api_key) }
|
83
86
|
|
84
87
|
context 'for default host' do
|
85
88
|
it "is configured to timeout connection opening in #{connection_retry.fetch(:single_request_open_timeout)} seconds" do
|
@@ -107,7 +110,7 @@ describe Ably::Rest::Client do
|
|
107
110
|
let(:publish_block) { proc { client.channel('test').publish('event', 'data') } }
|
108
111
|
|
109
112
|
context 'configured' do
|
110
|
-
let(:client_options) { default_options.merge(
|
113
|
+
let(:client_options) { default_options.merge(key: api_key) }
|
111
114
|
|
112
115
|
it 'should make connection attempts to A.ably-realtime.com, B.ably-realtime.com, C.ably-realtime.com, D.ably-realtime.com, E.ably-realtime.com' do
|
113
116
|
hosts = []
|
@@ -119,7 +122,7 @@ describe Ably::Rest::Client do
|
|
119
122
|
end
|
120
123
|
|
121
124
|
context 'when environment is NOT production' do
|
122
|
-
let(:client_options) { default_options.merge(environment: 'sandbox',
|
125
|
+
let(:client_options) { default_options.merge(environment: 'sandbox', key: api_key) }
|
123
126
|
let!(:default_host_request_stub) do
|
124
127
|
stub_request(:post, "https://#{api_key}@#{environment}-#{Ably::Rest::Client::DOMAIN}#{path}").to_return do
|
125
128
|
raise Faraday::TimeoutError.new('timeout error message')
|
@@ -135,7 +138,7 @@ describe Ably::Rest::Client do
|
|
135
138
|
let(:custom_hosts) { %w(A.ably-realtime.com B.ably-realtime.com) }
|
136
139
|
let(:max_attempts) { 2 }
|
137
140
|
let(:cumulative_timeout) { 0.5 }
|
138
|
-
let(:client_options) { default_options.merge(environment: nil,
|
141
|
+
let(:client_options) { default_options.merge(environment: nil, key: api_key) }
|
139
142
|
|
140
143
|
before do
|
141
144
|
stub_const 'Ably::FALLBACK_HOSTS', custom_hosts
|
@@ -209,7 +212,7 @@ describe Ably::Rest::Client do
|
|
209
212
|
|
210
213
|
context 'with a custom host' do
|
211
214
|
let(:custom_host) { 'host.does.not.exist' }
|
212
|
-
let(:client_options) { default_options.merge(
|
215
|
+
let(:client_options) { default_options.merge(key: api_key, rest_host: custom_host) }
|
213
216
|
let(:capability) { { :foo => ["publish"] } }
|
214
217
|
|
215
218
|
context 'that does not exist' do
|
@@ -3,7 +3,7 @@ require 'spec_helper'
|
|
3
3
|
require 'base64'
|
4
4
|
|
5
5
|
describe Ably::Models::MessageEncoders do
|
6
|
-
let(:default_client_options) { {
|
6
|
+
let(:default_client_options) { { key: api_key, environment: environment } }
|
7
7
|
let(:client) { Ably::Rest::Client.new(default_client_options.merge(protocol: protocol)) }
|
8
8
|
let(:channel_options) { {} }
|
9
9
|
let(:channel) { client.channel('test', channel_options) }
|
@@ -6,7 +6,7 @@ describe Ably::Rest::Channel, 'messages' do
|
|
6
6
|
include Ably::Modules::Conversions
|
7
7
|
|
8
8
|
vary_by_protocol do
|
9
|
-
let(:default_client_options) { {
|
9
|
+
let(:default_client_options) { { key: api_key, environment: environment, protocol: protocol } }
|
10
10
|
let(:client_options) { default_client_options }
|
11
11
|
let(:client) { Ably::Rest::Client.new(client_options) }
|
12
12
|
let(:other_client) { Ably::Rest::Client.new(client_options) }
|
@@ -17,7 +17,7 @@ describe Ably::Rest::Channel, 'messages' do
|
|
17
17
|
|
18
18
|
it 'is converted into UTF_8' do
|
19
19
|
channel.publish message_name, 'example'
|
20
|
-
message = channel.history.first
|
20
|
+
message = channel.history.items.first
|
21
21
|
expect(message.name.encoding).to eql(Encoding::UTF_8)
|
22
22
|
expect(message.name.encode(Encoding::ASCII_8BIT)).to eql(message_name)
|
23
23
|
end
|
@@ -80,13 +80,13 @@ describe Ably::Rest::Channel, 'messages' do
|
|
80
80
|
it 'sends and retrieves messages that are encrypted & decrypted by the Ably library' do
|
81
81
|
encrypted_channel.publish 'example', encoded_data_decoded
|
82
82
|
|
83
|
-
message = encrypted_channel.history.first
|
83
|
+
message = encrypted_channel.history.items.first
|
84
84
|
expect(message.data).to eql(encoded_data_decoded)
|
85
85
|
expect(message.encoding).to be_nil
|
86
86
|
end
|
87
87
|
end
|
88
88
|
|
89
|
-
resources_root = File.expand_path('
|
89
|
+
resources_root = File.expand_path('../../../../lib/submodules/ably-common/test-resources', __FILE__)
|
90
90
|
|
91
91
|
def self.add_tests_for_data(data)
|
92
92
|
data['items'].each_with_index do |item, index|
|
@@ -115,7 +115,7 @@ describe Ably::Rest::Channel, 'messages' do
|
|
115
115
|
encrypted_channel.publish index.to_s, "#{index}-#{data}"
|
116
116
|
end
|
117
117
|
|
118
|
-
messages = encrypted_channel.history
|
118
|
+
messages = encrypted_channel.history.items
|
119
119
|
|
120
120
|
expect(messages.count).to eql(message_count)
|
121
121
|
messages.each do |message|
|
@@ -140,7 +140,7 @@ describe Ably::Rest::Channel, 'messages' do
|
|
140
140
|
specify "delivers a #{payload_description} payload to the receiver" do
|
141
141
|
encrypted_channel.publish 'example', payload
|
142
142
|
|
143
|
-
message = other_client_channel.history.first
|
143
|
+
message = other_client_channel.history.items.first
|
144
144
|
expect(message.data).to eql(payload)
|
145
145
|
expect(message.encoding).to be_nil
|
146
146
|
end
|
@@ -156,7 +156,7 @@ describe Ably::Rest::Channel, 'messages' do
|
|
156
156
|
it 'does not attempt to decrypt the message' do
|
157
157
|
unencrypted_channel.publish 'example', payload
|
158
158
|
|
159
|
-
message = other_client_encrypted_channel.history.first
|
159
|
+
message = other_client_encrypted_channel.history.items.first
|
160
160
|
expect(message.data).to eql(payload)
|
161
161
|
expect(message.encoding).to be_nil
|
162
162
|
end
|
@@ -175,7 +175,7 @@ describe Ably::Rest::Channel, 'messages' do
|
|
175
175
|
end
|
176
176
|
|
177
177
|
it 'retrieves the message that remains encrypted with an encrypted encoding attribute' do
|
178
|
-
message = other_client_unencrypted_channel.history.first
|
178
|
+
message = other_client_unencrypted_channel.history.items.first
|
179
179
|
expect(message.data).to_not eql(payload)
|
180
180
|
expect(message.encoding).to match(/^cipher\+aes-256-cbc/)
|
181
181
|
end
|
@@ -202,7 +202,7 @@ describe Ably::Rest::Channel, 'messages' do
|
|
202
202
|
end
|
203
203
|
|
204
204
|
it 'retrieves the message that remains encrypted with an encrypted encoding attribute' do
|
205
|
-
message = encrypted_channel_client2.history.first
|
205
|
+
message = encrypted_channel_client2.history.items.first
|
206
206
|
expect(message.data).to_not eql(payload)
|
207
207
|
expect(message.encoding).to match(/^cipher\+aes-256-cbc/)
|
208
208
|
end
|
@@ -229,7 +229,7 @@ describe Ably::Rest::Channel, 'messages' do
|
|
229
229
|
end
|
230
230
|
|
231
231
|
it 'retrieves the message that remains encrypted with an encrypted encoding attribute' do
|
232
|
-
message = encrypted_channel_client2.history.first
|
232
|
+
message = encrypted_channel_client2.history.items.first
|
233
233
|
expect(message.data).to_not eql(payload)
|
234
234
|
expect(message.encoding).to match(/^cipher\+aes-256-cbc/)
|
235
235
|
end
|
@@ -5,7 +5,7 @@ describe Ably::Rest::Presence do
|
|
5
5
|
include Ably::Modules::Conversions
|
6
6
|
|
7
7
|
vary_by_protocol do
|
8
|
-
let(:default_options) { {
|
8
|
+
let(:default_options) { { key: api_key, environment: environment, protocol: protocol } }
|
9
9
|
let(:client_options) { default_options }
|
10
10
|
let(:client) do
|
11
11
|
Ably::Rest::Client.new(client_options)
|
@@ -16,88 +16,93 @@ describe Ably::Rest::Presence do
|
|
16
16
|
IdiomaticRubyWrapper(fixture, stop_at: [:data])
|
17
17
|
end
|
18
18
|
end
|
19
|
+
let(:non_encoded_fixtures) { fixtures.reject { |fixture| fixture['encoding'] } }
|
20
|
+
|
21
|
+
# Encrypted fixtures need encryption details or an error will be raised
|
22
|
+
let(:cipher_details) { TestApp::APP_SPEC_CIPHER }
|
23
|
+
let(:algorithm) { cipher_details.fetch('algorithm').upcase }
|
24
|
+
let(:mode) { cipher_details.fetch('mode').upcase }
|
25
|
+
let(:key_length) { cipher_details.fetch('keylength') }
|
26
|
+
let(:secret_key) { Base64.decode64(cipher_details.fetch('key')) }
|
27
|
+
let(:iv) { Base64.decode64(cipher_details.fetch('iv')) }
|
28
|
+
|
29
|
+
let(:cipher_options) { { key: secret_key, algorithm: algorithm, mode: mode, key_length: key_length, iv: iv } }
|
30
|
+
let(:fixtures_channel) { client.channel('persisted:presence_fixtures', encrypted: true, cipher_params: cipher_options, iv: iv) }
|
19
31
|
|
20
32
|
context 'tested against presence fixture data set up in test app' do
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
end
|
33
|
+
before(:context) do
|
34
|
+
# When this test is run as a part of a test suite, the presence data injected in the test app may have expired
|
35
|
+
reload_test_app
|
36
|
+
end
|
26
37
|
|
27
|
-
|
28
|
-
let(:
|
38
|
+
describe '#get' do
|
39
|
+
let(:presence_page) { fixtures_channel.presence.get }
|
29
40
|
|
30
41
|
it 'returns current members on the channel with their action set to :present' do
|
31
|
-
expect(
|
42
|
+
expect(presence_page.items.size).to eql(fixtures.count)
|
32
43
|
|
33
|
-
|
34
|
-
presence_message =
|
44
|
+
non_encoded_fixtures.each do |fixture|
|
45
|
+
presence_message = presence_page.items.find { |client| client.client_id == fixture[:client_id] }
|
35
46
|
expect(presence_message.data).to eq(fixture[:data])
|
36
47
|
expect(presence_message.action).to eq(:present)
|
37
48
|
end
|
38
49
|
end
|
39
50
|
|
40
51
|
context 'with :limit option' do
|
41
|
-
let(:page_size) {
|
42
|
-
let(:
|
52
|
+
let(:page_size) { 3 }
|
53
|
+
let(:presence_page) { fixtures_channel.presence.get(limit: page_size) }
|
43
54
|
|
44
55
|
it 'returns a paged response limiting number of members per page' do
|
45
|
-
expect(
|
46
|
-
next_page =
|
47
|
-
expect(next_page.size).to eql(
|
48
|
-
expect(next_page).to
|
56
|
+
expect(presence_page.items.size).to eql(page_size)
|
57
|
+
next_page = presence_page.next
|
58
|
+
expect(next_page.items.size).to eql(page_size)
|
59
|
+
expect(next_page).to be_last
|
49
60
|
end
|
50
61
|
end
|
51
62
|
end
|
52
63
|
|
53
64
|
describe '#history' do
|
54
|
-
|
55
|
-
# When this test is run as a part of a test suite, the presence data injected in the test app may have expired
|
56
|
-
reload_test_app
|
57
|
-
end
|
58
|
-
|
59
|
-
let(:channel) { client.channel('persisted:presence_fixtures') }
|
60
|
-
let(:presence_history) { channel.presence.history }
|
65
|
+
let(:history_page) { fixtures_channel.presence.history }
|
61
66
|
|
62
67
|
it 'returns recent presence activity' do
|
63
|
-
expect(
|
68
|
+
expect(history_page.items.size).to eql(fixtures.count)
|
64
69
|
|
65
|
-
|
66
|
-
presence_message =
|
70
|
+
non_encoded_fixtures.each do |fixture|
|
71
|
+
presence_message = history_page.items.find { |client| client.client_id == fixture['clientId'] }
|
67
72
|
expect(presence_message.data).to eq(fixture[:data])
|
68
73
|
end
|
69
74
|
end
|
70
75
|
|
71
76
|
context 'with options' do
|
72
|
-
let(:page_size) {
|
77
|
+
let(:page_size) { 3 }
|
73
78
|
|
74
79
|
context 'direction: :forwards' do
|
75
|
-
let(:
|
76
|
-
let(:paged_history_forward) {
|
80
|
+
let(:history_page) { fixtures_channel.presence.history(direction: :forwards) }
|
81
|
+
let(:paged_history_forward) { fixtures_channel.presence.history(limit: page_size, direction: :forwards) }
|
77
82
|
|
78
83
|
it 'returns recent presence activity forwards with most recent history last' do
|
79
84
|
expect(paged_history_forward).to be_a(Ably::Models::PaginatedResource)
|
80
|
-
expect(paged_history_forward.size).to eql(
|
85
|
+
expect(paged_history_forward.items.size).to eql(page_size)
|
81
86
|
|
82
|
-
next_page = paged_history_forward.
|
87
|
+
next_page = paged_history_forward.next
|
83
88
|
|
84
|
-
expect(paged_history_forward.first.id).to eql(
|
85
|
-
expect(next_page.first.id).to eql(
|
89
|
+
expect(paged_history_forward.items.first.id).to eql(history_page.items.first.id)
|
90
|
+
expect(next_page.items.first.id).to eql(history_page.items[page_size].id)
|
86
91
|
end
|
87
92
|
end
|
88
93
|
|
89
94
|
context 'direction: :backwards' do
|
90
|
-
let(:
|
91
|
-
let(:paged_history_backward) {
|
95
|
+
let(:history_page) { fixtures_channel.presence.history(direction: :backwards) }
|
96
|
+
let(:paged_history_backward) { fixtures_channel.presence.history(limit: page_size, direction: :backwards) }
|
92
97
|
|
93
98
|
it 'returns recent presence activity backwards with most recent history first' do
|
94
99
|
expect(paged_history_backward).to be_a(Ably::Models::PaginatedResource)
|
95
|
-
expect(paged_history_backward.size).to eql(
|
100
|
+
expect(paged_history_backward.items.size).to eql(page_size)
|
96
101
|
|
97
|
-
next_page = paged_history_backward.
|
102
|
+
next_page = paged_history_backward.next
|
98
103
|
|
99
|
-
expect(paged_history_backward.first.id).to eql(
|
100
|
-
expect(next_page.first.id).to eql(
|
104
|
+
expect(paged_history_backward.items.first.id).to eql(history_page.items.first.id)
|
105
|
+
expect(next_page.items.first.id).to eql(history_page.items[page_size].id)
|
101
106
|
end
|
102
107
|
end
|
103
108
|
end
|
@@ -117,7 +122,7 @@ describe Ably::Rest::Presence do
|
|
117
122
|
end
|
118
123
|
end
|
119
124
|
let(:client) do
|
120
|
-
Ably::Rest::Client.new(
|
125
|
+
Ably::Rest::Client.new(key: "#{user}:#{secret}")
|
121
126
|
end
|
122
127
|
|
123
128
|
[:start, :end].each do |option|
|
@@ -154,7 +159,32 @@ describe Ably::Rest::Presence do
|
|
154
159
|
end
|
155
160
|
end
|
156
161
|
|
157
|
-
describe 'decoding'
|
162
|
+
describe 'decoding' do
|
163
|
+
context 'with encoded fixture data' do
|
164
|
+
let(:decoded_client_id) { 'client_decoded' }
|
165
|
+
let(:encoded_client_id) { 'client_encoded' }
|
166
|
+
|
167
|
+
def message(client_id, messages)
|
168
|
+
messages.items.find { |message| message.client_id == client_id }
|
169
|
+
end
|
170
|
+
|
171
|
+
describe '#history' do
|
172
|
+
let(:history) { fixtures_channel.presence.history }
|
173
|
+
it 'decodes encoded and encryped presence fixture data automatically' do
|
174
|
+
expect(message(decoded_client_id, history).data).to eql(message(encoded_client_id, history).data)
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
describe '#get' do
|
179
|
+
let(:present) { fixtures_channel.presence.get }
|
180
|
+
it 'decodes encoded and encryped presence fixture data automatically' do
|
181
|
+
expect(message(decoded_client_id, present).data).to eql(message(encoded_client_id, present).data)
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
describe 'decoding permutations using mocked #history', :webmock do
|
158
188
|
let(:user) { 'appid.keyuid' }
|
159
189
|
let(:secret) { random_str(8) }
|
160
190
|
let(:endpoint) do
|
@@ -164,7 +194,7 @@ describe Ably::Rest::Presence do
|
|
164
194
|
end
|
165
195
|
end
|
166
196
|
let(:client) do
|
167
|
-
Ably::Rest::Client.new(client_options.merge(
|
197
|
+
Ably::Rest::Client.new(client_options.merge(key: "#{user}:#{secret}"))
|
168
198
|
end
|
169
199
|
|
170
200
|
let(:data) { random_str(32) }
|
@@ -204,9 +234,9 @@ describe Ably::Rest::Presence do
|
|
204
234
|
end
|
205
235
|
|
206
236
|
it 'automaticaly decodes presence messages' do
|
207
|
-
|
208
|
-
expect(
|
209
|
-
expect(
|
237
|
+
present_page = presence.get
|
238
|
+
expect(present_page.items.first.encoding).to be_nil
|
239
|
+
expect(present_page.items.first.data).to eql(data)
|
210
240
|
end
|
211
241
|
end
|
212
242
|
|
@@ -221,9 +251,9 @@ describe Ably::Rest::Presence do
|
|
221
251
|
end
|
222
252
|
|
223
253
|
it 'automaticaly decodes presence messages' do
|
224
|
-
|
225
|
-
expect(
|
226
|
-
expect(
|
254
|
+
history_page = presence.history
|
255
|
+
expect(history_page.items.first.encoding).to be_nil
|
256
|
+
expect(history_page.items.first.data).to eql(data)
|
227
257
|
end
|
228
258
|
end
|
229
259
|
end
|
@@ -245,7 +275,7 @@ describe Ably::Rest::Presence do
|
|
245
275
|
stub_request(:get, "#{endpoint}/channels/#{CGI.escape(channel_name)}/presence").
|
246
276
|
to_return(:body => serialized_encoded_message_with_invalid_encoding, :headers => { 'Content-Type' => content_type })
|
247
277
|
}
|
248
|
-
let(:presence_message) { presence.get.first }
|
278
|
+
let(:presence_message) { presence.get.items.first }
|
249
279
|
|
250
280
|
after do
|
251
281
|
expect(get_stub).to have_been_requested
|
@@ -269,7 +299,7 @@ describe Ably::Rest::Presence do
|
|
269
299
|
stub_request(:get, "#{endpoint}/channels/#{CGI.escape(channel_name)}/presence/history").
|
270
300
|
to_return(:body => serialized_encoded_message_with_invalid_encoding, :headers => { 'Content-Type' => content_type })
|
271
301
|
}
|
272
|
-
let(:presence_message) { presence.history.first }
|
302
|
+
let(:presence_message) { presence.history.items.first }
|
273
303
|
|
274
304
|
after do
|
275
305
|
expect(history_stub).to have_been_requested
|
@@ -9,17 +9,17 @@ describe Ably::Rest::Client, '#stats' do
|
|
9
9
|
|
10
10
|
STATS_FIXTURES = [
|
11
11
|
{
|
12
|
-
intervalId: Ably::Models::
|
12
|
+
intervalId: Ably::Models::Stats.to_interval_id(LAST_INTERVAL - 120, :minute),
|
13
13
|
inbound: { realtime: { messages: { count: 50, data: 5000 } } },
|
14
14
|
outbound: { realtime: { messages: { count: 20, data: 2000 } } }
|
15
15
|
},
|
16
16
|
{
|
17
|
-
intervalId: Ably::Models::
|
17
|
+
intervalId: Ably::Models::Stats.to_interval_id(LAST_INTERVAL - 60, :minute),
|
18
18
|
inbound: { realtime: { messages: { count: 60, data: 6000 } } },
|
19
19
|
outbound: { realtime: { messages: { count: 10, data: 1000 } } }
|
20
20
|
},
|
21
21
|
{
|
22
|
-
intervalId: Ably::Models::
|
22
|
+
intervalId: Ably::Models::Stats.to_interval_id(LAST_INTERVAL, :minute),
|
23
23
|
inbound: { realtime: { messages: { count: 70, data: 7000 } } },
|
24
24
|
outbound: { realtime: { messages: { count: 40, data: 4000 } } },
|
25
25
|
persisted: { presence: { count: 20, data: 2000 } },
|
@@ -36,7 +36,7 @@ describe Ably::Rest::Client, '#stats' do
|
|
36
36
|
end
|
37
37
|
|
38
38
|
vary_by_protocol do
|
39
|
-
let(:client) { Ably::Rest::Client.new(
|
39
|
+
let(:client) { Ably::Rest::Client.new(key: api_key, environment: environment, protocol: protocol) }
|
40
40
|
|
41
41
|
describe 'fetching application stats' do
|
42
42
|
context 'by minute' do
|
@@ -45,55 +45,60 @@ describe Ably::Rest::Client, '#stats' do
|
|
45
45
|
|
46
46
|
context 'with :from set to last interval and :limit set to 1' do
|
47
47
|
let(:subject) { client.stats(start: as_since_epoch(LAST_INTERVAL), by: :minute, limit: 1) }
|
48
|
-
let(:stat) { subject.first}
|
48
|
+
let(:stat) { subject.items.first }
|
49
49
|
|
50
50
|
it 'retrieves only one stat' do
|
51
|
-
expect(subject.count).to eql(1)
|
51
|
+
expect(subject.items.count).to eql(1)
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'returns zero value for any missing metrics' do
|
55
|
+
expect(stat.channels.refused).to eql(0)
|
56
|
+
expect(stat.outbound.webhook.all.count).to eql(0)
|
52
57
|
end
|
53
58
|
|
54
59
|
it 'returns all aggregated message data' do
|
55
|
-
expect(stat.all
|
56
|
-
expect(stat.all
|
60
|
+
expect(stat.all.messages.count).to eql(70 + 40) # inbound + outbound
|
61
|
+
expect(stat.all.messages.data).to eql(7000 + 4000) # inbound + outbound
|
57
62
|
end
|
58
63
|
|
59
64
|
it 'returns inbound realtime all data' do
|
60
|
-
expect(stat.inbound
|
61
|
-
expect(stat.inbound
|
65
|
+
expect(stat.inbound.realtime.all.count).to eql(70)
|
66
|
+
expect(stat.inbound.realtime.all.data).to eql(7000)
|
62
67
|
end
|
63
68
|
|
64
69
|
it 'returns inbound realtime message data' do
|
65
|
-
expect(stat.inbound
|
66
|
-
expect(stat.inbound
|
70
|
+
expect(stat.inbound.realtime.messages.count).to eql(70)
|
71
|
+
expect(stat.inbound.realtime.messages.data).to eql(7000)
|
67
72
|
end
|
68
73
|
|
69
74
|
it 'returns outbound realtime all data' do
|
70
|
-
expect(stat.outbound
|
71
|
-
expect(stat.outbound
|
75
|
+
expect(stat.outbound.realtime.all.count).to eql(40)
|
76
|
+
expect(stat.outbound.realtime.all.data).to eql(4000)
|
72
77
|
end
|
73
78
|
|
74
79
|
it 'returns persisted presence all data' do
|
75
|
-
expect(stat.persisted
|
76
|
-
expect(stat.persisted
|
80
|
+
expect(stat.persisted.all.count).to eql(20)
|
81
|
+
expect(stat.persisted.all.data).to eql(2000)
|
77
82
|
end
|
78
83
|
|
79
84
|
it 'returns connections all data' do
|
80
|
-
expect(stat.connections
|
81
|
-
expect(stat.connections
|
85
|
+
expect(stat.connections.tls.peak).to eql(20)
|
86
|
+
expect(stat.connections.tls.opened).to eql(10)
|
82
87
|
end
|
83
88
|
|
84
89
|
it 'returns channels all data' do
|
85
|
-
expect(stat.channels
|
86
|
-
expect(stat.channels
|
90
|
+
expect(stat.channels.peak).to eql(50)
|
91
|
+
expect(stat.channels.opened).to eql(30)
|
87
92
|
end
|
88
93
|
|
89
94
|
it 'returns api_requests data' do
|
90
|
-
expect(stat.api_requests
|
91
|
-
expect(stat.api_requests
|
95
|
+
expect(stat.api_requests.succeeded).to eql(50)
|
96
|
+
expect(stat.api_requests.failed).to eql(10)
|
92
97
|
end
|
93
98
|
|
94
99
|
it 'returns token_requests data' do
|
95
|
-
expect(stat.token_requests
|
96
|
-
expect(stat.token_requests
|
100
|
+
expect(stat.token_requests.succeeded).to eql(60)
|
101
|
+
expect(stat.token_requests.failed).to eql(20)
|
97
102
|
end
|
98
103
|
|
99
104
|
it 'returns stat objects with #interval_granularity equal to :minute' do
|
@@ -112,34 +117,34 @@ describe Ably::Rest::Client, '#stats' do
|
|
112
117
|
context 'with :start set to first interval, :limit set to 1 and direction :forwards' do
|
113
118
|
let(:first_interval) { LAST_INTERVAL - 120 }
|
114
119
|
let(:subject) { client.stats(start: as_since_epoch(first_interval), by: :minute, direction: :forwards, limit: 1) }
|
115
|
-
let(:stat) { subject.first}
|
120
|
+
let(:stat) { subject.items.first }
|
116
121
|
|
117
122
|
it 'returns the first interval stats as stats are provided forwards from :start' do
|
118
|
-
expect(stat.inbound
|
123
|
+
expect(stat.inbound.realtime.all.count).to eql(first_inbound_realtime_count)
|
119
124
|
end
|
120
125
|
|
121
126
|
it 'returns 3 pages of stats' do
|
122
|
-
expect(subject).to
|
123
|
-
expect(subject).to_not
|
124
|
-
page3 = subject.
|
125
|
-
expect(page3).to
|
126
|
-
expect(page3.first.inbound
|
127
|
+
expect(subject).to be_first
|
128
|
+
expect(subject).to_not be_last
|
129
|
+
page3 = subject.next.next
|
130
|
+
expect(page3).to be_last
|
131
|
+
expect(page3.items.first.inbound.realtime.all.count).to eql(last_inbound_realtime_count)
|
127
132
|
end
|
128
133
|
end
|
129
134
|
|
130
135
|
context 'with :end set to last interval, :limit set to 1 and direction :backwards' do
|
131
136
|
let(:subject) { client.stats(:end => as_since_epoch(LAST_INTERVAL), by: :minute, direction: :backwards, limit: 1) }
|
132
|
-
let(:stat) { subject.first}
|
137
|
+
let(:stat) { subject.items.first }
|
133
138
|
|
134
139
|
it 'returns the 3rd interval stats first as stats are provided backwards from :end' do
|
135
|
-
expect(stat.inbound
|
140
|
+
expect(stat.inbound.realtime.all.count).to eql(last_inbound_realtime_count)
|
136
141
|
end
|
137
142
|
|
138
143
|
it 'returns 3 pages of stats' do
|
139
|
-
expect(subject).to
|
140
|
-
expect(subject).to_not
|
141
|
-
page3 = subject.
|
142
|
-
expect(page3.first.inbound
|
144
|
+
expect(subject).to be_first
|
145
|
+
expect(subject).to_not be_last
|
146
|
+
page3 = subject.next.next
|
147
|
+
expect(page3.items.first.inbound.realtime.all.count).to eql(first_inbound_realtime_count)
|
143
148
|
end
|
144
149
|
end
|
145
150
|
end
|
@@ -147,7 +152,7 @@ describe Ably::Rest::Client, '#stats' do
|
|
147
152
|
[:hour, :day, :month].each do |interval|
|
148
153
|
context "by #{interval}" do
|
149
154
|
let(:subject) { client.stats(start: as_since_epoch(LAST_INTERVAL), by: interval, direction: 'forwards', limit: 1) }
|
150
|
-
let(:stat) { subject.first }
|
155
|
+
let(:stat) { subject.items.first }
|
151
156
|
let(:aggregate_messages_count) do
|
152
157
|
STATS_FIXTURES.inject(0) do |sum, fixture|
|
153
158
|
sum + fixture[:inbound][:realtime][:messages][:count] + fixture[:outbound][:realtime][:messages][:count]
|
@@ -160,10 +165,10 @@ describe Ably::Rest::Client, '#stats' do
|
|
160
165
|
end
|
161
166
|
|
162
167
|
it 'should aggregate the stats for that period' do
|
163
|
-
expect(subject.count).to eql(1)
|
168
|
+
expect(subject.items.count).to eql(1)
|
164
169
|
|
165
|
-
expect(stat.all
|
166
|
-
expect(stat.all
|
170
|
+
expect(stat.all.messages.count).to eql(aggregate_messages_count)
|
171
|
+
expect(stat.all.messages.data).to eql(aggregate_messages_data)
|
167
172
|
end
|
168
173
|
end
|
169
174
|
end
|