forked from ably/ably-ruby
-
Notifications
You must be signed in to change notification settings - Fork 0
/
base_spec.rb
167 lines (139 loc) · 5.77 KB
/
base_spec.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
# encoding: utf-8
require 'spec_helper'
describe Ably::Rest do
describe 'transport protocol' do
include Ably::Modules::Conversions
let(:client_options) { {} }
let(:client) do
Ably::Rest::Client.new(client_options.merge(key: 'appid.keyuid:keysecret', log_retries_as_info: true))
end
let(:now) { Time.now - 1000 }
let(:body_value) { [as_since_epoch(now)] }
before do
stub_request(:get, "#{client.endpoint}/time").
with(:headers => { 'Accept' => mime }).
to_return(:status => 200, :body => request_body, :headers => { 'Content-Type' => mime })
end
context 'when protocol is not defined it defaults to :msgpack' do
let(:client_options) { { } }
let(:mime) { 'application/x-msgpack' }
let(:request_body) { body_value.to_msgpack }
it 'uses MsgPack', :webmock do
expect(client.protocol).to eql(:msgpack)
expect(client.time).to be_within(1).of(now)
end
end
options = [
{ protocol: :json },
{ use_binary_protocol: false }
].each do |client_option|
context "when option #{client_option} is used" do
let(:client_options) { client_option }
let(:mime) { 'application/json' }
let(:request_body) { body_value.to_json }
it 'uses JSON', :webmock do
expect(client.protocol).to eql(:json)
expect(client.time).to be_within(1).of(now)
end
end
end
options = [
{ protocol: :msgpack },
{ use_binary_protocol: true }
].each do |client_option|
context "when option #{client_option} is used" do
let(:client_options) { client_option }
let(:mime) { 'application/x-msgpack' }
let(:request_body) { body_value.to_msgpack }
it 'uses MsgPack', :webmock do
expect(client.protocol).to eql(:msgpack)
expect(client.time).to be_within(1).of(now)
end
end
end
end
vary_by_protocol do
let(:client) do
Ably::Rest::Client.new(key: api_key, environment: environment, protocol: protocol, log_retries_as_info: true)
end
describe 'failed requests' do
context 'due to invalid Auth' do
it 'should raise an InvalidRequest exception with a valid error message and code' do
invalid_client = Ably::Rest::Client.new(key: 'appid.keyuid:keysecret', environment: environment)
expect { invalid_client.channel('test').publish('foo', 'choo') }.to raise_error do |error|
expect(error).to be_a(Ably::Exceptions::ResourceMissing)
expect(error.message).to match(/No application found/)
expect(error.code).to eql(40400)
expect(error.status).to eql(404)
end
end
end
describe 'server error with JSON error response body', :webmock do
let(:error_response) { '{ "error": { "statusCode": 500, "code": 50000, "message": "Internal error" } }' }
before do
stub_request(:get, "#{client.endpoint}/time").
to_return(:status => 500, :body => error_response, :headers => { 'Content-Type' => 'application/json' })
end
it 'should raise a ServerError exception' do
expect { client.time }.to raise_error(Ably::Exceptions::ServerError, /Internal error/)
end
end
describe '500 server error without a valid JSON response body', :webmock do
before do
stub_request(:get, "#{client.endpoint}/time").
to_return(:status => 500, :headers => { 'Content-Type' => 'application/json' })
end
it 'should raise a ServerError exception' do
expect { client.time }.to raise_error(Ably::Exceptions::ServerError, /Unknown/)
end
end
end
describe 'token authentication failures', :webmock do
let(:token_1) { { token: random_str } }
let(:token_2) { { token: random_str } }
let(:channel) { random_str }
before do
@token_requests = 0
@publish_attempts = 0
stub_request(:post, "#{client.endpoint}/keys/#{key_name}/requestToken").to_return do
@token_requests += 1
{
:body => public_send("token_#{@token_requests}").merge(expires: (Time.now.to_i + 60) * 1000).to_json,
:headers => { 'Content-Type' => 'application/json' }
}
end
stub_request(:post, "#{client.endpoint}/channels/#{channel}/publish").to_return do
@publish_attempts += 1
if [1, 3].include?(@publish_attempts)
{ status: 201, :body => '[]', :headers => { 'Content-Type' => 'application/json' } }
else
raise Ably::Exceptions::TokenExpired.new('Authentication failure', 401, 40142)
end
end
end
context 'when auth#token_renewable?' do
before do
client.auth.authorize
end
it 'should automatically reissue a token' do
client.channel(channel).publish('evt', 'msg')
expect(@publish_attempts).to eql(1)
expect(@token_requests).to eql(1)
# Triggers an authentication 401 failure which should automatically request a new token
client.channel(channel).publish('evt', 'msg')
expect(@publish_attempts).to eql(3)
expect(@token_requests).to eql(2)
end
end
context 'when NOT auth#token_renewable?' do
let(:client) { Ably::Rest::Client.new(token: 'token ID cannot be used to create a new token', environment: environment, protocol: protocol) }
it 'should raise an TokenExpired exception' do
client.channel(channel).publish('evt', 'msg')
expect(@publish_attempts).to eql(1)
expect { client.channel(channel).publish('evt', 'msg') }.to raise_error Ably::Exceptions::TokenExpired
expect(@token_requests).to eql(0)
end
end
end
end
end