ably-rest 0.7.5 → 0.8.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/.travis.yml +2 -0
- data/README.md +41 -15
- data/SPEC.md +654 -518
- data/lib/submodules/ably-ruby/.gitignore +1 -0
- data/lib/submodules/ably-ruby/.gitmodules +3 -0
- data/lib/submodules/ably-ruby/README.md +54 -26
- data/lib/submodules/ably-ruby/SPEC.md +468 -322
- data/lib/submodules/ably-ruby/ably.gemspec +4 -2
- data/lib/submodules/ably-ruby/lib/ably/auth.rb +185 -131
- data/lib/submodules/ably-ruby/lib/ably/models/message.rb +1 -1
- data/lib/submodules/ably-ruby/lib/ably/models/paginated_resource.rb +31 -44
- data/lib/submodules/ably-ruby/lib/ably/models/presence_message.rb +2 -2
- data/lib/submodules/ably-ruby/lib/ably/models/protocol_message.rb +1 -2
- data/lib/submodules/ably-ruby/lib/ably/models/stat.rb +67 -24
- data/lib/submodules/ably-ruby/lib/ably/models/stats_types.rb +131 -0
- data/lib/submodules/ably-ruby/lib/ably/models/token_details.rb +101 -0
- data/lib/submodules/ably-ruby/lib/ably/models/token_request.rb +108 -0
- data/lib/submodules/ably-ruby/lib/ably/modules/async_wrapper.rb +3 -2
- data/lib/submodules/ably-ruby/lib/ably/modules/http_helpers.rb +1 -1
- data/lib/submodules/ably-ruby/lib/ably/modules/message_emitter.rb +2 -2
- data/lib/submodules/ably-ruby/lib/ably/realtime.rb +3 -7
- data/lib/submodules/ably-ruby/lib/ably/realtime/channel.rb +32 -5
- data/lib/submodules/ably-ruby/lib/ably/realtime/channel/channel_manager.rb +1 -0
- data/lib/submodules/ably-ruby/lib/ably/realtime/client.rb +4 -8
- data/lib/submodules/ably-ruby/lib/ably/realtime/connection.rb +5 -3
- data/lib/submodules/ably-ruby/lib/ably/realtime/presence.rb +12 -1
- data/lib/submodules/ably-ruby/lib/ably/rest.rb +3 -7
- data/lib/submodules/ably-ruby/lib/ably/rest/channel.rb +13 -10
- data/lib/submodules/ably-ruby/lib/ably/rest/client.rb +19 -20
- data/lib/submodules/ably-ruby/lib/ably/rest/presence.rb +14 -12
- data/lib/submodules/ably-ruby/lib/ably/version.rb +1 -1
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/channel_history_spec.rb +74 -23
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/channel_spec.rb +3 -3
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/client_spec.rb +18 -18
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/connection_failures_spec.rb +5 -5
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/connection_spec.rb +12 -12
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/message_spec.rb +5 -5
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/presence_history_spec.rb +56 -13
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/presence_spec.rb +8 -8
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/stats_spec.rb +1 -1
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/time_spec.rb +1 -1
- data/lib/submodules/ably-ruby/spec/acceptance/rest/auth_spec.rb +262 -158
- data/lib/submodules/ably-ruby/spec/acceptance/rest/base_spec.rb +11 -9
- data/lib/submodules/ably-ruby/spec/acceptance/rest/channel_spec.rb +28 -21
- data/lib/submodules/ably-ruby/spec/acceptance/rest/channels_spec.rb +1 -1
- data/lib/submodules/ably-ruby/spec/acceptance/rest/client_spec.rb +30 -27
- data/lib/submodules/ably-ruby/spec/acceptance/rest/encoders_spec.rb +1 -1
- data/lib/submodules/ably-ruby/spec/acceptance/rest/message_spec.rb +10 -10
- data/lib/submodules/ably-ruby/spec/acceptance/rest/presence_spec.rb +93 -56
- data/lib/submodules/ably-ruby/spec/acceptance/rest/stats_spec.rb +50 -45
- data/lib/submodules/ably-ruby/spec/acceptance/rest/time_spec.rb +1 -1
- data/lib/submodules/ably-ruby/spec/rspec_config.rb +3 -2
- data/lib/submodules/ably-ruby/spec/shared/client_initializer_behaviour.rb +36 -28
- data/lib/submodules/ably-ruby/spec/spec_helper.rb +3 -0
- data/lib/submodules/ably-ruby/spec/support/api_helper.rb +3 -3
- data/lib/submodules/ably-ruby/spec/support/markdown_spec_formatter.rb +1 -1
- data/lib/submodules/ably-ruby/spec/support/test_app.rb +20 -33
- data/lib/submodules/ably-ruby/spec/unit/auth_spec.rb +18 -1
- data/lib/submodules/ably-ruby/spec/unit/models/paginated_resource_spec.rb +81 -72
- data/lib/submodules/ably-ruby/spec/unit/models/stats_spec.rb +289 -0
- data/lib/submodules/ably-ruby/spec/unit/models/token_details_spec.rb +111 -0
- data/lib/submodules/ably-ruby/spec/unit/models/token_request_spec.rb +110 -0
- data/lib/submodules/ably-ruby/spec/unit/modules/async_wrapper_spec.rb +1 -1
- data/lib/submodules/ably-ruby/spec/unit/realtime/client_spec.rb +1 -1
- data/lib/submodules/ably-ruby/spec/unit/realtime/realtime_spec.rb +1 -1
- data/lib/submodules/ably-ruby/spec/unit/rest/channel_spec.rb +1 -1
- data/lib/submodules/ably-ruby/spec/unit/rest/client_spec.rb +8 -8
- data/lib/submodules/ably-ruby/spec/unit/rest/rest_spec.rb +1 -1
- data/lib/submodules/ably-ruby/spec/unit/util/crypto_spec.rb +1 -1
- metadata +9 -7
- data/lib/submodules/ably-ruby/lib/ably/models/token.rb +0 -74
- data/lib/submodules/ably-ruby/spec/resources/crypto-data-128.json +0 -56
- data/lib/submodules/ably-ruby/spec/resources/crypto-data-256.json +0 -56
- data/lib/submodules/ably-ruby/spec/unit/models/stat_spec.rb +0 -113
- data/lib/submodules/ably-ruby/spec/unit/models/token_spec.rb +0 -86
@@ -4,7 +4,7 @@ require 'shared/protocol_msgbus_behaviour'
|
|
4
4
|
describe Ably::Auth do
|
5
5
|
let(:client) { double('client').as_null_object }
|
6
6
|
let(:client_id) { nil }
|
7
|
-
let(:options) { {
|
7
|
+
let(:options) { { key: 'appid.keyuid:keysecret', client_id: client_id } }
|
8
8
|
|
9
9
|
subject do
|
10
10
|
Ably::Auth.new(client, options)
|
@@ -65,4 +65,21 @@ describe Ably::Auth do
|
|
65
65
|
end
|
66
66
|
end
|
67
67
|
end
|
68
|
+
|
69
|
+
context 'defaults' do
|
70
|
+
let(:one_hour) { 60 * 60 }
|
71
|
+
let(:all_capabilities) { { "*" => ["*"] } }
|
72
|
+
|
73
|
+
it 'should default TTL to 1 hour' do
|
74
|
+
expect(Ably::Auth::TOKEN_DEFAULTS.fetch(:ttl)).to eql(one_hour)
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'should default capability to all' do
|
78
|
+
expect(Ably::Auth::TOKEN_DEFAULTS.fetch(:capability)).to eql(all_capabilities)
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'should only have defaults for :ttl and :capability' do
|
82
|
+
expect(Ably::Auth::TOKEN_DEFAULTS.keys).to contain_exactly(:ttl, :capability)
|
83
|
+
end
|
84
|
+
end
|
68
85
|
end
|
@@ -5,7 +5,7 @@ describe Ably::Models::PaginatedResource do
|
|
5
5
|
let(:paginated_resource_class) { Ably::Models::PaginatedResource }
|
6
6
|
let(:headers) { Hash.new }
|
7
7
|
let(:client) do
|
8
|
-
instance_double('Ably::Rest::Client', logger:
|
8
|
+
instance_double('Ably::Rest::Client', logger: Ably::Models::NilLogger.new).tap do |client|
|
9
9
|
allow(client).to receive(:get).and_return(http_response)
|
10
10
|
end
|
11
11
|
end
|
@@ -27,57 +27,54 @@ describe Ably::Models::PaginatedResource do
|
|
27
27
|
let(:first_paged_request) { paginated_resource_class.new(http_response, full_url, client, paginated_resource_options) }
|
28
28
|
subject { first_paged_request }
|
29
29
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
it 'supports alias methods for length' do
|
35
|
-
expect(subject.count).to eql(subject.length)
|
36
|
-
expect(subject.size).to eql(subject.length)
|
37
|
-
end
|
38
|
-
|
39
|
-
it 'is Enumerable' do
|
40
|
-
expect(subject).to be_kind_of(Enumerable)
|
41
|
-
end
|
30
|
+
context '#items' do
|
31
|
+
it 'returns correct length from body' do
|
32
|
+
expect(subject.items.length).to eql(body.length)
|
33
|
+
end
|
42
34
|
|
43
|
-
|
44
|
-
|
45
|
-
|
35
|
+
it 'is Enumerable' do
|
36
|
+
expect(subject.items).to be_kind_of(Enumerable)
|
37
|
+
end
|
46
38
|
|
47
|
-
|
48
|
-
|
49
|
-
expect(subject.each).to be_a(Enumerator)
|
39
|
+
it 'is iterable' do
|
40
|
+
expect(subject.items.map { |d| d }).to eql(body)
|
50
41
|
end
|
51
42
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
43
|
+
context '#each' do
|
44
|
+
it 'returns an enumerator' do
|
45
|
+
expect(subject.items.each).to be_a(Enumerator)
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'yields each item' do
|
49
|
+
items = []
|
50
|
+
subject.items.each do |item|
|
51
|
+
items << item
|
52
|
+
end
|
53
|
+
expect(items).to eq(body)
|
56
54
|
end
|
57
|
-
expect(items).to eq(body)
|
58
55
|
end
|
59
|
-
end
|
60
56
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
57
|
+
it 'provides [] accessor method' do
|
58
|
+
expect(subject.items[0][:id]).to eql(body[0][:id])
|
59
|
+
expect(subject.items[1][:id]).to eql(body[1][:id])
|
60
|
+
expect(subject.items[2]).to be_nil
|
61
|
+
end
|
66
62
|
|
67
|
-
|
68
|
-
|
69
|
-
|
63
|
+
specify '#first gets the first item in page' do
|
64
|
+
expect(subject.items.first[:id]).to eql(body[0][:id])
|
65
|
+
end
|
70
66
|
|
71
|
-
|
72
|
-
|
73
|
-
|
67
|
+
specify '#last gets the last item in page' do
|
68
|
+
expect(subject.items.last[:id]).to eql(body[1][:id])
|
69
|
+
end
|
74
70
|
|
75
|
-
|
76
|
-
|
71
|
+
context 'with coercion', :api_private do
|
72
|
+
let(:paginated_resource_options) { { coerce_into: 'OpenStruct' } }
|
77
73
|
|
78
|
-
|
79
|
-
|
80
|
-
|
74
|
+
it 'returns coerced objects' do
|
75
|
+
expect(subject.items.first).to be_a(OpenStruct)
|
76
|
+
expect(subject.items.first.id).to eql(body.first[:id])
|
77
|
+
end
|
81
78
|
end
|
82
79
|
end
|
83
80
|
|
@@ -90,7 +87,7 @@ describe Ably::Models::PaginatedResource do
|
|
90
87
|
}
|
91
88
|
end
|
92
89
|
let(:paged_client) do
|
93
|
-
instance_double('Ably::Rest::Client', logger:
|
90
|
+
instance_double('Ably::Rest::Client', logger: Ably::Models::NilLogger.new).tap do |client|
|
94
91
|
allow(client).to receive(:get).and_return(http_response_page2)
|
95
92
|
end
|
96
93
|
end
|
@@ -116,15 +113,15 @@ describe Ably::Models::PaginatedResource do
|
|
116
113
|
end
|
117
114
|
|
118
115
|
it 'calls the block for each resource after retrieving the resources' do
|
119
|
-
expect(subject[0][:added_attribute_from_block]).to eql("id:#{body[0][:id]}")
|
116
|
+
expect(subject.items[0][:added_attribute_from_block]).to eql("id:#{body[0][:id]}")
|
120
117
|
end
|
121
118
|
|
122
119
|
it 'calls the block for each resource on second page after retrieving the resources' do
|
123
|
-
page_1_first_id = subject[0][:id]
|
124
|
-
next_page = subject.
|
120
|
+
page_1_first_id = subject.items[0][:id]
|
121
|
+
next_page = subject.next
|
125
122
|
|
126
|
-
expect(next_page[0][:added_attribute_from_block]).to eql("id:#{body_page2[0][:id]}")
|
127
|
-
expect(next_page[0][:id]).to_not eql(page_1_first_id)
|
123
|
+
expect(next_page.items[0][:added_attribute_from_block]).to eql("id:#{body_page2[0][:id]}")
|
124
|
+
expect(next_page.items[0][:id]).to_not eql(page_1_first_id)
|
128
125
|
end
|
129
126
|
end
|
130
127
|
|
@@ -136,17 +133,17 @@ describe Ably::Models::PaginatedResource do
|
|
136
133
|
paginated_resource_class.new(http_response, full_url, paged_client, async_blocking_operations: true)
|
137
134
|
end
|
138
135
|
|
139
|
-
context '#
|
136
|
+
context '#next' do
|
140
137
|
it 'returns a SafeDeferrable that catches exceptions in callbacks and logs them' do
|
141
138
|
run_reactor do
|
142
|
-
expect(subject.
|
139
|
+
expect(subject.next).to be_a(Ably::Util::SafeDeferrable)
|
143
140
|
stop_reactor
|
144
141
|
end
|
145
142
|
end
|
146
143
|
|
147
144
|
it 'allows a success callback block to be added' do
|
148
145
|
run_reactor do
|
149
|
-
subject.
|
146
|
+
subject.next do |paginated_resource|
|
150
147
|
expect(paginated_resource).to be_a(Ably::Models::PaginatedResource)
|
151
148
|
stop_reactor
|
152
149
|
end
|
@@ -154,11 +151,11 @@ describe Ably::Models::PaginatedResource do
|
|
154
151
|
end
|
155
152
|
end
|
156
153
|
|
157
|
-
context '#
|
154
|
+
context '#first' do
|
158
155
|
it 'calls the errback callback when first page headers are missing' do
|
159
156
|
run_reactor do
|
160
|
-
subject.
|
161
|
-
deferrable = subject.
|
157
|
+
subject.next do |paginated_resource|
|
158
|
+
deferrable = subject.first
|
162
159
|
deferrable.errback do |error|
|
163
160
|
expect(error).to be_a(Ably::Exceptions::InvalidPageError)
|
164
161
|
stop_reactor
|
@@ -173,23 +170,27 @@ describe Ably::Models::PaginatedResource do
|
|
173
170
|
|
174
171
|
context 'with non paged http response' do
|
175
172
|
it 'is the first page' do
|
176
|
-
expect(subject).to
|
173
|
+
expect(subject).to be_first
|
177
174
|
end
|
178
175
|
|
179
176
|
it 'is the last page' do
|
180
|
-
expect(subject).to
|
177
|
+
expect(subject).to be_last
|
178
|
+
end
|
179
|
+
|
180
|
+
it 'does not have next page' do
|
181
|
+
expect(subject).to_not have_next
|
181
182
|
end
|
182
183
|
|
183
184
|
it 'does not support pagination' do
|
184
185
|
expect(subject.supports_pagination?).to_not eql(true)
|
185
186
|
end
|
186
187
|
|
187
|
-
it '
|
188
|
-
expect
|
188
|
+
it 'returns nil when accessing next page' do
|
189
|
+
expect(subject.next).to be_nil
|
189
190
|
end
|
190
191
|
|
191
|
-
it '
|
192
|
-
expect
|
192
|
+
it 'returns nil when accessing first page' do
|
193
|
+
expect(subject.first).to be_nil
|
193
194
|
end
|
194
195
|
end
|
195
196
|
|
@@ -207,11 +208,15 @@ describe Ably::Models::PaginatedResource do
|
|
207
208
|
end
|
208
209
|
|
209
210
|
it 'is the first page' do
|
210
|
-
expect(subject).to
|
211
|
+
expect(subject).to be_first
|
212
|
+
end
|
213
|
+
|
214
|
+
it 'has next page' do
|
215
|
+
expect(subject).to have_next
|
211
216
|
end
|
212
217
|
|
213
218
|
it 'is not the last page' do
|
214
|
-
expect(subject).to_not
|
219
|
+
expect(subject).to_not be_last
|
215
220
|
end
|
216
221
|
|
217
222
|
it 'supports pagination' do
|
@@ -236,7 +241,7 @@ describe Ably::Models::PaginatedResource do
|
|
236
241
|
headers: next_headers
|
237
242
|
})
|
238
243
|
end
|
239
|
-
let(:subject) { first_paged_request.
|
244
|
+
let(:subject) { first_paged_request.next }
|
240
245
|
|
241
246
|
before do
|
242
247
|
expect(client).to receive(:get).with("#{base_url}/history?index=1").and_return(next_http_response).once
|
@@ -247,39 +252,43 @@ describe Ably::Models::PaginatedResource do
|
|
247
252
|
end
|
248
253
|
|
249
254
|
it 'retrieves the next page of results' do
|
250
|
-
expect(subject.length).to eql(next_body.length)
|
251
|
-
expect(subject[0][:id]).to eql(next_body[0][:id])
|
255
|
+
expect(subject.items.length).to eql(next_body.length)
|
256
|
+
expect(subject.items[0][:id]).to eql(next_body[0][:id])
|
252
257
|
end
|
253
258
|
|
254
259
|
it 'is not the first page' do
|
255
|
-
expect(subject).to_not
|
260
|
+
expect(subject).to_not be_first
|
261
|
+
end
|
262
|
+
|
263
|
+
it 'does not have a next page' do
|
264
|
+
expect(subject).to_not have_next
|
256
265
|
end
|
257
266
|
|
258
267
|
it 'is the last page' do
|
259
|
-
expect(subject).to
|
268
|
+
expect(subject).to be_last
|
260
269
|
end
|
261
270
|
|
262
|
-
it '
|
263
|
-
expect(subject).to
|
264
|
-
expect
|
271
|
+
it 'returns nil when trying to access the last page when it is the last page' do
|
272
|
+
expect(subject).to be_last
|
273
|
+
expect(subject.next).to be_nil
|
265
274
|
end
|
266
275
|
|
267
276
|
context 'and then first page' do
|
268
277
|
before do
|
269
278
|
expect(client).to receive(:get).with("#{base_url}/history?index=0").and_return(http_response).once
|
270
279
|
end
|
271
|
-
subject { first_paged_request.
|
280
|
+
subject { first_paged_request.next.first }
|
272
281
|
|
273
282
|
it 'returns a PaginatedResource' do
|
274
283
|
expect(subject).to be_a(paginated_resource_class)
|
275
284
|
end
|
276
285
|
|
277
286
|
it 'retrieves the first page of results' do
|
278
|
-
expect(subject.length).to eql(body.length)
|
287
|
+
expect(subject.items.length).to eql(body.length)
|
279
288
|
end
|
280
289
|
|
281
290
|
it 'is the first page' do
|
282
|
-
expect(subject).to
|
291
|
+
expect(subject).to be_first
|
283
292
|
end
|
284
293
|
end
|
285
294
|
end
|
@@ -0,0 +1,289 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'spec_helper'
|
3
|
+
require 'shared/model_behaviour'
|
4
|
+
|
5
|
+
describe Ably::Models::Stats do
|
6
|
+
include Ably::Modules::Conversions
|
7
|
+
|
8
|
+
subject { Ably::Models::Stats }
|
9
|
+
|
10
|
+
%w(all persisted).each do |attribute|
|
11
|
+
context "##{attribute} stats" do
|
12
|
+
let(:data) do
|
13
|
+
{ attribute.to_sym => { messages: { count: 5 }, all: { data: 10 } } }
|
14
|
+
end
|
15
|
+
subject { Ably::Models::Stats.new(data.merge(interval_id: '2004-02')).public_send(attribute) }
|
16
|
+
|
17
|
+
it 'returns a MessageTypes object' do
|
18
|
+
expect(subject).to be_a(Ably::Models::Stats::MessageTypes)
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'returns value for message counts' do
|
22
|
+
expect(subject.messages.count).to eql(5)
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'returns value for all data transferred' do
|
26
|
+
expect(subject.all.data).to eql(10)
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'returns zero for empty values' do
|
30
|
+
expect(subject.presence.count).to eql(0)
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'raises an exception for unknown attributes' do
|
34
|
+
expect { subject.unknown }.to raise_error NoMethodError
|
35
|
+
end
|
36
|
+
|
37
|
+
%w(all presence messages).each do |type|
|
38
|
+
context "##{type}" do
|
39
|
+
it 'is a MessageCount object' do
|
40
|
+
expect(subject.public_send(type)).to be_a(Ably::Models::Stats::MessageCount)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
%w(inbound outbound).each do |direction|
|
48
|
+
context "##{direction} stats" do
|
49
|
+
let(:data) do
|
50
|
+
{
|
51
|
+
direction.to_sym => {
|
52
|
+
realtime: { messages: { count: 5 }, presence: { data: 10 } },
|
53
|
+
all: { messages: { count: 25 }, presence: { data: 210 } }
|
54
|
+
}
|
55
|
+
}
|
56
|
+
end
|
57
|
+
subject { Ably::Models::Stats.new(data.merge(interval_id: '2004-02')).public_send(direction) }
|
58
|
+
|
59
|
+
it 'returns a MessageTraffic object' do
|
60
|
+
expect(subject).to be_a(Ably::Models::Stats::MessageTraffic)
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'returns value for realtime message counts' do
|
64
|
+
expect(subject.realtime.messages.count).to eql(5)
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'returns value for all presence data' do
|
68
|
+
expect(subject.all.presence.data).to eql(210)
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'raises an exception for unknown attributes' do
|
72
|
+
expect { subject.unknown }.to raise_error NoMethodError
|
73
|
+
end
|
74
|
+
|
75
|
+
%w(realtime rest webhook all).each do |type|
|
76
|
+
context "##{type}" do
|
77
|
+
it 'is a MessageTypes object' do
|
78
|
+
expect(subject.public_send(type)).to be_a(Ably::Models::Stats::MessageTypes)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
context '#connections stats' do
|
86
|
+
let(:data) do
|
87
|
+
{ connections: { tls: { opened: 5 }, all: { peak: 10 } } }
|
88
|
+
end
|
89
|
+
subject { Ably::Models::Stats.new(data.merge(interval_id: '2004-02')).connections }
|
90
|
+
|
91
|
+
it 'returns a ConnectionTypes object' do
|
92
|
+
expect(subject).to be_a(Ably::Models::Stats::ConnectionTypes)
|
93
|
+
end
|
94
|
+
|
95
|
+
it 'returns value for tls opened counts' do
|
96
|
+
expect(subject.tls.opened).to eql(5)
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'returns value for all peak connections' do
|
100
|
+
expect(subject.all.peak).to eql(10)
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'returns zero for empty values' do
|
104
|
+
expect(subject.all.refused).to eql(0)
|
105
|
+
end
|
106
|
+
|
107
|
+
it 'raises an exception for unknown attributes' do
|
108
|
+
expect { subject.unknown }.to raise_error NoMethodError
|
109
|
+
end
|
110
|
+
|
111
|
+
%w(tls plain all).each do |type|
|
112
|
+
context "##{type}" do
|
113
|
+
it 'is a ResourceCount object' do
|
114
|
+
expect(subject.public_send(type)).to be_a(Ably::Models::Stats::ResourceCount)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
context '#channels stats' do
|
121
|
+
let(:data) do
|
122
|
+
{ channels: { opened: 5, peak: 10 } }
|
123
|
+
end
|
124
|
+
subject { Ably::Models::Stats.new(data.merge(interval_id: '2004-02')).channels }
|
125
|
+
|
126
|
+
it 'returns a ResourceCount object' do
|
127
|
+
expect(subject).to be_a(Ably::Models::Stats::ResourceCount)
|
128
|
+
end
|
129
|
+
|
130
|
+
it 'returns value for opened counts' do
|
131
|
+
expect(subject.opened).to eql(5)
|
132
|
+
end
|
133
|
+
|
134
|
+
it 'returns value for peak channels' do
|
135
|
+
expect(subject.peak).to eql(10)
|
136
|
+
end
|
137
|
+
|
138
|
+
it 'returns zero for empty values' do
|
139
|
+
expect(subject.refused).to eql(0)
|
140
|
+
end
|
141
|
+
|
142
|
+
it 'raises an exception for unknown attributes' do
|
143
|
+
expect { subject.unknown }.to raise_error NoMethodError
|
144
|
+
end
|
145
|
+
|
146
|
+
%w(opened peak mean min refused).each do |type|
|
147
|
+
context "##{type}" do
|
148
|
+
it 'is a Integer object' do
|
149
|
+
expect(subject.public_send(type)).to be_a(Integer)
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
%w(api_requests token_requests).each do |request_type|
|
156
|
+
context "##{request_type} stats" do
|
157
|
+
let(:data) do
|
158
|
+
{
|
159
|
+
request_type.to_sym => { succeeded: 5, failed: 10 }
|
160
|
+
}
|
161
|
+
end
|
162
|
+
subject { Ably::Models::Stats.new(data.merge(interval_id: '2004-02')).public_send(request_type) }
|
163
|
+
|
164
|
+
it 'returns a RequestCount object' do
|
165
|
+
expect(subject).to be_a(Ably::Models::Stats::RequestCount)
|
166
|
+
end
|
167
|
+
|
168
|
+
it 'returns value for succeeded' do
|
169
|
+
expect(subject.succeeded).to eql(5)
|
170
|
+
end
|
171
|
+
|
172
|
+
it 'returns value for failed' do
|
173
|
+
expect(subject.failed).to eql(10)
|
174
|
+
end
|
175
|
+
|
176
|
+
it 'raises an exception for unknown attributes' do
|
177
|
+
expect { subject.unknown }.to raise_error NoMethodError
|
178
|
+
end
|
179
|
+
|
180
|
+
%w(succeeded failed refused).each do |type|
|
181
|
+
context "##{type}" do
|
182
|
+
it 'is a Integer object' do
|
183
|
+
expect(subject.public_send(type)).to be_a(Integer)
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
describe '#interval_granularity' do
|
191
|
+
subject { Ably::Models::Stats.new(interval_id: '2004-02') }
|
192
|
+
|
193
|
+
it 'returns the granularity of the interval_id' do
|
194
|
+
expect(subject.interval_granularity).to eq(:month)
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
describe '#interval_time' do
|
199
|
+
subject { Ably::Models::Stats.new(interval_id: '2004-02-01:05:06') }
|
200
|
+
|
201
|
+
it 'returns a Time object representing the start of the interval' do
|
202
|
+
expect(subject.interval_time.to_i).to eql(Time.new(2004, 02, 01, 05, 06, 00, '+00:00').to_i)
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
context 'class methods' do
|
207
|
+
describe '#to_interval_id' do
|
208
|
+
context 'when time zone of time argument is UTC' do
|
209
|
+
it 'converts time 2014-02-03:05:06 with granularity :month into 2014-02' do
|
210
|
+
expect(subject.to_interval_id(Time.new(2014, 2, 1, 0, 0, 0, '+00:00'), :month)).to eql('2014-02')
|
211
|
+
end
|
212
|
+
|
213
|
+
it 'converts time 2014-02-03:05:06 with granularity :day into 2014-02-03' do
|
214
|
+
expect(subject.to_interval_id(Time.new(2014, 2, 3, 0, 0, 0, '+00:00'), :day)).to eql('2014-02-03')
|
215
|
+
end
|
216
|
+
|
217
|
+
it 'converts time 2014-02-03:05:06 with granularity :hour into 2014-02-03:05' do
|
218
|
+
expect(subject.to_interval_id(Time.new(2014, 2, 3, 5, 0, 0, '+00:00'), :hour)).to eql('2014-02-03:05')
|
219
|
+
end
|
220
|
+
|
221
|
+
it 'converts time 2014-02-03:05:06 with granularity :minute into 2014-02-03:05:06' do
|
222
|
+
expect(subject.to_interval_id(Time.new(2014, 2, 3, 5, 6, 0, '+00:00'), :minute)).to eql('2014-02-03:05:06')
|
223
|
+
end
|
224
|
+
|
225
|
+
it 'fails with invalid granularity' do
|
226
|
+
expect { subject.to_interval_id(Time.now, :invalid) }.to raise_error KeyError
|
227
|
+
end
|
228
|
+
|
229
|
+
it 'fails with invalid time' do
|
230
|
+
expect { subject.to_interval_id(nil, :month) }.to raise_error ArgumentError
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
context 'when time zone of time argument is +02:00' do
|
235
|
+
it 'converts time 2014-02-03:06 with granularity :hour into 2014-02-03:04 at UTC +00:00' do
|
236
|
+
expect(subject.to_interval_id(Time.new(2014, 2, 3, 6, 0, 0, '+02:00'), :hour)).to eql('2014-02-03:04')
|
237
|
+
end
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
describe '#from_interval_id' do
|
242
|
+
it 'converts a month interval_id 2014-02 into a Time object in UTC 0' do
|
243
|
+
expect(subject.from_interval_id('2014-02')).to eql(Time.gm(2014, 2))
|
244
|
+
expect(subject.from_interval_id('2014-02').utc_offset).to eql(0)
|
245
|
+
end
|
246
|
+
|
247
|
+
it 'converts a day interval_id 2014-02-03 into a Time object in UTC 0' do
|
248
|
+
expect(subject.from_interval_id('2014-02-03')).to eql(Time.gm(2014, 2, 3))
|
249
|
+
expect(subject.from_interval_id('2014-02-03').utc_offset).to eql(0)
|
250
|
+
end
|
251
|
+
|
252
|
+
it 'converts an hour interval_id 2014-02-03:05 into a Time object in UTC 0' do
|
253
|
+
expect(subject.from_interval_id('2014-02-03:05')).to eql(Time.gm(2014, 2, 3, 5))
|
254
|
+
expect(subject.from_interval_id('2014-02-03:05').utc_offset).to eql(0)
|
255
|
+
end
|
256
|
+
|
257
|
+
it 'converts a minute interval_id 2014-02-03:05:06 into a Time object in UTC 0' do
|
258
|
+
expect(subject.from_interval_id('2014-02-03:05:06')).to eql(Time.gm(2014, 2, 3, 5, 6))
|
259
|
+
expect(subject.from_interval_id('2014-02-03:05:06').utc_offset).to eql(0)
|
260
|
+
end
|
261
|
+
|
262
|
+
it 'fails with an invalid interval_id 14-20' do
|
263
|
+
expect { subject.from_interval_id('14-20') }.to raise_error ArgumentError
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
describe '#granularity_from_interval_id' do
|
268
|
+
it 'returns a :month interval_id for 2014-02' do
|
269
|
+
expect(subject.granularity_from_interval_id('2014-02')).to eq(:month)
|
270
|
+
end
|
271
|
+
|
272
|
+
it 'returns a :day interval_id for 2014-02-03' do
|
273
|
+
expect(subject.granularity_from_interval_id('2014-02-03')).to eq(:day)
|
274
|
+
end
|
275
|
+
|
276
|
+
it 'returns a :hour interval_id for 2014-02-03:05' do
|
277
|
+
expect(subject.granularity_from_interval_id('2014-02-03:05')).to eq(:hour)
|
278
|
+
end
|
279
|
+
|
280
|
+
it 'returns a :minute interval_id for 2014-02-03:05:06' do
|
281
|
+
expect(subject.granularity_from_interval_id('2014-02-03:05:06')).to eq(:minute)
|
282
|
+
end
|
283
|
+
|
284
|
+
it 'fails with an invalid interval_id 14-20' do
|
285
|
+
expect { subject.granularity_from_interval_id('14-20') }.to raise_error ArgumentError
|
286
|
+
end
|
287
|
+
end
|
288
|
+
end
|
289
|
+
end
|