spec/acceptance/rest/base_spec.rb in ably-0.6.2 vs spec/acceptance/rest/base_spec.rb in ably-0.7.0
- old
+ new
@@ -1,232 +1,164 @@
+# encoding: utf-8
require 'spec_helper'
-require 'securerandom'
-describe 'REST' do
- let(:client) do
- Ably::Rest::Client.new(api_key: api_key, environment: environment)
- end
-
- describe 'protocol' do
+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(api_key: 'appid.keyuid:keysecret'))
end
- context 'transport' do
- let(:now) { Time.now - 1000 }
- let(:body_value) { [as_since_epoch(now)] }
+ 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
+ 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 }
+ 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: true do
- expect(client.protocol).to eql(:msgpack)
- expect(client.time).to be_within(1).of(now)
- end
+ 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|
+ 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 }
+ 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: true do
- expect(client.protocol).to eql(:json)
- expect(client.time).to be_within(1).of(now)
- end
+ 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: :json },
- { use_binary_protocol: false }
- ].each do |client_option|
+ options = [
+ { protocol: :msgpack },
+ { use_binary_protocol: true }
+ ].each do |client_option|
- context "when option #{client_option} is used" do
- let(:client_options) { { protocol: :msgpack } }
- let(:mime) { 'application/x-msgpack' }
- let(:request_body) { body_value.to_msgpack }
+ 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: true do
- expect(client.protocol).to eql(:msgpack)
- expect(client.time).to be_within(1).of(now)
- end
+ it 'uses MsgPack', :webmock do
+ expect(client.protocol).to eql(:msgpack)
+ expect(client.time).to be_within(1).of(now)
end
end
end
end
- describe 'invalid requests in middleware' do
- it 'should raise an InvalidRequest exception with a valid message' do
- invalid_client = Ably::Rest::Client.new(api_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::InvalidToken)
- expect(error.message).to match(/invalid credentials/)
- expect(error.code).to eql(40100)
- expect(error.status).to eql(401)
- end
+ vary_by_protocol do
+ let(:client) do
+ Ably::Rest::Client.new(api_key: api_key, environment: environment, protocol: protocol)
end
- describe 'server error with JSON response', webmock: true 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' })
+ 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(api_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::InvalidRequest)
+ expect(error.message).to match(/invalid credentials/)
+ expect(error.code).to eql(40100)
+ expect(error.status).to eql(401)
+ end
+ end
end
- it 'should raise a ServerError exception' do
- expect { client.time }.to raise_error(Ably::Exceptions::ServerError, /Internal error/)
- end
- end
+ describe 'server error with JSON error response body', :webmock do
+ let(:error_response) { '{ "error": { "statusCode": 500, "code": 50000, "message": "Internal error" } }' }
- describe 'server error', webmock: true do
- before do
- stub_request(:get, "#{client.endpoint}/time").
- to_return(:status => 500, :headers => { 'Content-Type' => 'application/json' })
- end
+ 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, /Unknown/)
+ it 'should raise a ServerError exception' do
+ expect { client.time }.to raise_error(Ably::Exceptions::ServerError, /Internal error/)
+ end
end
- end
- end
- describe 'authentication failure', webmock: true do
- let(:token_1) { { id: SecureRandom.hex } }
- let(:token_2) { { id: SecureRandom.hex } }
- let(:channel) { 'channelname' }
+ 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
- before do
- @token_requests = 0
- @publish_attempts = 0
-
- stub_request(:post, "#{client.endpoint}/keys/#{key_id}/requestToken").to_return do
- @token_requests += 1
- {
- :body => { access_token: send("token_#{@token_requests}").merge(expires: Time.now.to_i + 3600) }.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::InvalidRequest.new('Authentication failure', 401, 40140)
+ it 'should raise a ServerError exception' do
+ expect { client.time }.to raise_error(Ably::Exceptions::ServerError, /Unknown/)
end
end
end
- context 'when auth#token_renewable?' do
+ describe 'token authentication failures', :webmock do
+ let(:token_1) { { id: random_str } }
+ let(:token_2) { { id: random_str } }
+ let(:channel) { 'channelname' }
+
before do
- client.auth.authorise
- end
+ @token_requests = 0
+ @publish_attempts = 0
- it 'should automatically reissue a token' do
- client.channel(channel).publish('evt', 'msg')
- expect(@publish_attempts).to eql(1)
+ stub_request(:post, "#{client.endpoint}/keys/#{key_id}/requestToken").to_return do
+ @token_requests += 1
+ {
+ :body => { access_token: send("token_#{@token_requests}").merge(expires: Time.now.to_i + 3600) }.to_json,
+ :headers => { 'Content-Type' => 'application/json' }
+ }
+ end
- 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_id: 'token ID cannot be used to create a new token', environment: environment) }
- it 'should raise the 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::InvalidToken
- expect(@token_requests).to eql(0)
- end
- end
- end
-
- describe Ably::Rest::Client do
- context '#initialize' do
- context 'with an auth block' do
- let(:client) { Ably::Rest::Client.new(environment: environment) { token_request } }
- let(:token_request) { client.auth.create_token_request(key_id: key_id, key_secret: key_secret, client_id: client_id) }
- let(:client_id) { 'unique_client_id' }
-
- it 'calls the block to get a new token' do
- expect { client.channel('channel_name').publish('event', 'message') }.to change { client.auth.current_token }
- expect(client.auth.current_token.client_id).to eql(client_id)
+ 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::InvalidRequest.new('Authentication failure', 401, 40140)
+ end
end
end
- context 'with an auth URL' do
- let(:client) { Ably::Rest::Client.new(environment: environment, auth_url: token_request_url, auth_method: :get) }
- let(:token_request_url) { 'http://get.token.request.com/' }
- let(:token_request) { client.auth.create_token_request(key_id: key_id, key_secret: key_secret, client_id: client_id) }
- let(:client_id) { 'unique_client_id' }
-
+ context 'when auth#token_renewable?' do
before do
- allow(client.auth).to receive(:token_request_from_auth_url).with(token_request_url, :auth_method => :get).and_return(token_request)
+ client.auth.authorise
end
- it 'sends an HTTP request to get a new token' do
- expect { client.channel('channel_name').publish('event', 'message') }.to change { client.auth.current_token }
- expect(client.auth.current_token.client_id).to eql(client_id)
- end
- end
- end
+ it 'should automatically reissue a token' do
+ client.channel(channel).publish('evt', 'msg')
+ expect(@publish_attempts).to eql(1)
- context 'token expiry' do
- let(:client) do
- Ably::Rest::Client.new(environment: environment) do
- @request_index ||= 0
- @request_index += 1
- send("token_request_#{@request_index}")
+ client.channel(channel).publish('evt', 'msg')
+ expect(@publish_attempts).to eql(3)
+ expect(@token_requests).to eql(2)
end
end
- let(:token_request_1) { client.auth.create_token_request(token_request_options.merge(client_id: SecureRandom.hex)) }
- let(:token_request_2) { client.auth.create_token_request(token_request_options.merge(client_id: SecureRandom.hex)) }
- context 'when expired' do
- let(:token_request_options) { { key_id: key_id, key_secret: key_secret, ttl: Ably::Models::Token::TOKEN_EXPIRY_BUFFER } }
+ context 'when NOT auth#token_renewable?' do
+ let(:client) { Ably::Rest::Client.new(token_id: 'token ID cannot be used to create a new token', environment: environment, protocol: protocol) }
- it 'creates a new token automatically when the old token expires' do
- expect { client.channel('channel_name').publish('event', 'message') }.to change { client.auth.current_token }
- expect(client.auth.current_token.client_id).to eql(token_request_1[:client_id])
-
- sleep 1
-
- expect { client.channel('channel_name').publish('event', 'message') }.to change { client.auth.current_token }
- expect(client.auth.current_token.client_id).to eql(token_request_2[:client_id])
- end
- end
-
- context 'token authentication with long expiry token' do
- let(:token_request_options) { { key_id: key_id, key_secret: key_secret, ttl: 3600 } }
-
- it 'creates a new token automatically when the old token expires' do
- expect { client.channel('channel_name').publish('event', 'message') }.to change { client.auth.current_token }
- expect(client.auth.current_token.client_id).to eql(token_request_1[:client_id])
-
- sleep 1
-
- expect { client.channel('channel_name').publish('event', 'message') }.to_not change { client.auth.current_token }
- expect(client.auth.current_token.client_id).to eql(token_request_1[:client_id])
+ it 'should raise an InvalidToken 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::InvalidToken
+ expect(@token_requests).to eql(0)
end
end
end
end
end