Last active
May 4, 2016 00:13
-
-
Save pmashchak/751f6cf4c5b3b7bbc1b3e84caff77007 to your computer and use it in GitHub Desktop.
HTTP request wapper test + DynamoDB data class
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'rails_helper' | |
describe HTTPRequest do | |
let(:logger) { ->(params) { } } | |
let(:api_context) { ParentalControls.new('', '', logger: logger) } | |
let(:subject) { HTTPRequest.new(api_context: api_context, headers: { 'Accept' => 'application/xml' }) } | |
let(:response) { double(:response, code: 200, body: {}.to_json) } | |
before do | |
allow_any_instance_of(ParentalControls).to receive(:get).and_return({}) | |
allow_any_instance_of(Manticore::Client).to receive(:get).and_return(response) | |
end | |
context 'Set defaults' do | |
let(:api_options) { Rails.configuration.api.send(ParentalControls.api_name) } | |
it 'raises error if api is blank' do | |
expect { HTTPRequest.new() }.to raise_error('API not found') | |
end | |
it 'sets default options' do | |
options = subject.options | |
expect(options[:request_timeout]).to eql(5) | |
expect(options[:connect_timeout]).to eql(5) | |
expect(options[:socket_timeout]).to eql(5) | |
expect(options[:headers]).to eql('Accept' => 'application/xml') | |
end | |
it 'sets default api_options' do | |
expect(subject.api_config_get(:codebig_key)).to eql(api_options[:codebig_key]) | |
expect(subject.api_config_get(:codebig_secret)).to eql(api_options[:codebig_secret]) | |
expect(subject.api_config_get(:base)).to eql(api_options[:base]) | |
expect(subject.api_config_get(:timeout)).to eql(api_options[:timeout]) | |
end | |
end | |
context '.get' do | |
let(:oauth) { { consumer_key: subject.api_config_get(:codebig_key), | |
consumer_secret: subject.api_config_get(:codebig_secret)} } | |
let(:oauth_header) { SimpleOAuth::Header.new(:get, subject.endpoint, {}, oauth).to_s } | |
it 'should do get request' do | |
expect(subject).to receive(:request).with(:get, {}) | |
subject.get({}) | |
end | |
it 'should set oauth header' do | |
allow_any_instance_of(SimpleOAuth::Header).to receive(:to_s).and_return(oauth_header) | |
subject.get | |
headers = subject.options[:headers] | |
expect(headers['Accept']).to eql('application/json') | |
expect(headers['Content-Type']).to eql('application/json') | |
expect(headers['Authorization']).to eql(oauth_header) | |
end | |
it 'should not set oauth header if key and secret blank' do | |
api_config = subject.api_context.api_config.clone | |
api_config[:codebig_key] = nil | |
allow(subject.api_context).to receive(:api_config).and_return(api_config) | |
subject.get | |
headers = subject.options[:headers] | |
expect(headers['Authorization']).to be_blank | |
end | |
end | |
context '.post' do | |
let(:params) { { user_name: 'John' } } | |
before do | |
allow_any_instance_of(Manticore::Client).to receive(:post).and_return(response) | |
end | |
it 'should do post request' do | |
expect(subject).to receive(:request).with(:post, {}) | |
subject.post({}) | |
end | |
it 'should post body params' do | |
expect(subject.post(body: params)).to eql({}) | |
expect(subject.options[:body]).to eql(params) | |
end | |
end | |
context 'Fails on Exception' do | |
it 'fails on default exception' do | |
expect(subject.client).to receive(:get).exactly(3).times.and_raise(Manticore::Timeout) | |
expect(logger).to receive(:call).exactly(2).times | |
expect { subject.get }.to raise_error(Manticore::Timeout) | |
end | |
it 'fails on custom exception' do | |
subject = HTTPRequest.new(api_context: api_context, exceptions: [RuntimeError]) | |
expect(subject.client).to receive(:get).exactly(3).times.and_raise(RuntimeError) | |
expect(logger).to receive(:call).exactly(2).times | |
expect { subject.get }.to raise_error(RuntimeError) | |
expect(subject.exceptions).to include(RuntimeError) | |
expect(subject.exceptions).to include(Manticore::Timeout) | |
end | |
it 'should retry number of times' do | |
expect(subject.client).to receive(:post).exactly(2).times.and_raise(Manticore::Timeout) | |
expect(logger).to receive(:call).exactly(1).times | |
expect { subject.post({ retries: 1 }) }.to raise_error(Manticore::Timeout) | |
end | |
end | |
context 'Fails on code' do | |
let(:response) { double(:response, code: 422, body: {}.to_json) } | |
it 'fails on 422 code' do | |
expect(subject.client).to receive(:get).exactly(3).times.and_raise(Manticore::ResponseCodeException) | |
expect(logger).to receive(:call).exactly(2).times | |
expect { subject.get }.to raise_error(Manticore::ResponseCodeException) | |
end | |
it 'should not retry on 422 code' do | |
expect(subject.get(fails_on_code: false)).to eql({}) | |
end | |
it 'should raise exception on code' do | |
expect { subject.get }.to raise_error(Manticore::ResponseCodeException) | |
end | |
end | |
end | |
require 'rails_helper' | |
describe Pair do | |
let(:client) { double(:client) } | |
let(:ip_lease_expires) { 5.seconds.from_now.to_i * 1000 } | |
let(:timestamp) { 5.seconds.from_now.to_i * 1000 } | |
let(:item) { double(:item, item: { "id"=>"4453964", "bucket"=>"3", | |
"data"=>"{ \"925820377533335645\": { \"appId\":\"tvxapps.games.dev\", | |
\"deviceId\":\"925820377533335645\", \"comcastSessionId\":\"6fd28a49-7748-4a19-9651-9cd7b8ab897c\", | |
\"billingAccountId\":\"8499101410225087\", \"xboAccountId\":\"7866179556106550654\", | |
\"zip3\":\"191\", \"ipLeaseExpires\":\"#{ip_lease_expires}\", \"cstAuthGuid\":\"109056040722102015Comcast.RTVE\", | |
\"stbFriendlyName\":\"DEV2 XG2V2\", \"gameId\":\"monopoly\",\"whitelisted\":false,\"hsi\":true, | |
\"timestamp\": \"#{timestamp}\" } }" }) } | |
let(:parsed_item) { JSON.parse(item.item['data']).values.first.merge(item.item.slice('id')) } | |
let(:no_item) { double(:item, item: nil) } | |
let(:logger) { ->(params) { params[:retried]; params[:trace]} } | |
let(:items) { double(:items, items: [item.item]) } | |
let(:no_items) { double(:items, items: []) } | |
subject { Pair.new(parsed_item) } | |
before do | |
allow(Pair).to receive(:client).and_return(client) | |
allow(subject).to receive(:client).and_return(client) | |
end | |
context '#delete' do | |
it 'should delete item' do | |
expect(client).to receive(:delete_item).with(table_name: Pair::TABLE_NAME, key: { 'id' => subject.id }) | |
subject.delete | |
end | |
end | |
context '.new' do | |
it 'should parse data item' do | |
expect(subject).to be_a(Pair) | |
expect(subject).to_not be_expired | |
expect(subject.id).to eq('4453964') | |
expect(subject.device_id).to eq('925820377533335645') | |
expect(subject.app_id).to eq('tvxapps.games.dev') | |
expect(subject.comcast_session_id).to eq('6fd28a49-7748-4a19-9651-9cd7b8ab897c') | |
expect(subject.account_number).to eq('8499101410225087') | |
expect(subject.auth_guid).to eq('109056040722102015Comcast.RTVE') | |
expect(subject.xbo_account_id).to eq('7866179556106550654') | |
expect(subject.zip3).to eq('191') | |
expect(subject.stb_friendly_name).to eq('DEV2 XG2V2') | |
expect(subject.ip_lease_expires).to eq(ip_lease_expires.to_s) | |
expect(subject.game_id).to eq('monopoly') | |
expect(subject.whitelisted).to eq(false) | |
expect(subject.hsi).to eq(true) | |
expect(subject.timestamp).to eq(timestamp.to_s) | |
expect(subject).to_not be_collection | |
expect(subject.to_json).to eq("{\"device_id\":\"925820377533335645\",\"stb_friendly_name\":\"DEV2 XG2V2\"}") | |
end | |
it 'should not parse data item' do | |
subject = Pair.new('id'=>'4453964') | |
expect(subject).to_not be_valid | |
end | |
end | |
context '.where' do | |
let(:collection) { Pair.where(ip_address: item.item['id']) } | |
it 'should find item by ip' do | |
expect(client).to receive(:get_item).with(table_name: Pair::TABLE_NAME, key: { 'id' => item.item['id'] }).and_return(item) | |
expect(collection).to be_a(Pair::Collection) | |
expect(collection).to be_valid | |
expect(collection.to_json).to eq("[{\"device_id\":\"925820377533335645\",\"stb_friendly_name\":\"DEV2 XG2V2\"}]") | |
expect(subject).to be_valid | |
expect(collection.item.id).to eq(subject.id) | |
expect(collection).to be_can_pair_device | |
end | |
it 'should return nil' do | |
expect(client).to receive(:get_item).with(table_name: Pair::TABLE_NAME, key: { 'id' => item.item['id'] }).and_return(no_item) | |
expect(collection).to be_a(Pair::Collection) | |
expect(collection).to be_blank | |
expect(collection).to_not be_valid | |
expect(collection).to_not be_collection | |
end | |
it 'should retry and return item' do | |
expect(client).to receive(:get_item).and_raise(Timeout::Error).once | |
expect(logger).to receive(:call).with(retried: 1, trace: Timeout::Error.new.inspect).once | |
expect(client).to receive(:get_item).and_return(item).once | |
collection = Pair.where(ip_address: item.item['id'], logger: logger) | |
expect(collection).to be_a(Pair::Collection) | |
expect(collection).to be_valid | |
end | |
it 'should retry and raise error' do | |
expect(client).to receive(:get_item).and_raise(Timeout::Error).twice | |
expect(logger).to receive(:call).with(retried: 1, trace: Timeout::Error.new.inspect).once | |
expect { Pair.where(ip_address: item.item['id'], logger: logger) }.to raise_error(Timeout::Error) | |
end | |
it 'should detect device' do | |
expect(client).to receive(:get_item).and_return(item) | |
pair = collection.detect_device('925820377533335645') | |
expect(pair).to be_a(Pair) | |
expect(pair).to be_valid | |
expect(pair).to be_can_pair_device | |
end | |
context 'timestamp expires' do | |
let(:timestamp) { 5.minutes.ago.to_i * 1000 } | |
it 'should expire if timestamp is expired' do | |
expect(client).to receive(:get_item).and_return(item) | |
subject = Pair.where(ip_address: item.item['id']) | |
expect(subject).to_not be_valid | |
expect(subject).to be_blank | |
end | |
end | |
context 'ip_lease_expires' do | |
let(:ip_lease_expires) { 5.seconds.ago.to_i * 1000 } | |
it 'should be expired' do | |
expect(client).to receive(:get_item).and_return(item) | |
subject = Pair.where(ip_address: item.item['id']) | |
expect(subject).to_not be_valid | |
expect(subject).to be_blank | |
end | |
end | |
end | |
context '.find_by_pairing_code' do | |
before do | |
expect(client).to receive(:get_item).with(table_name: Pair::TABLE_NAME, key: { 'id' => item.item['id'] }).and_return(item) | |
end | |
it 'should find by pairing code' do | |
subject = Pair.find_by_pairing_code(item.item['id']) | |
expect(subject).to be_a(Pair) | |
expect(subject).to be_valid | |
end | |
it 'should return nil' do | |
expect(JSON).to receive(:parse).and_raise(JSON::ParserError) | |
expect(Rails.logger).to receive(:error) | |
subject = Pair.find_by_pairing_code(item.item['id']) | |
expect(subject).to be(nil) | |
end | |
context 'timestamp' do | |
let(:timestamp) { 5.minutes.ago.to_i * 1000 } | |
it 'should be expired' do | |
subject = Pair.find_by_pairing_code(item.item['id']) | |
expect(subject).to_not be_valid | |
expect(subject.errors[:base]).to be_present | |
expect(subject.conditions).to_not include(:ip_address) | |
expect(subject.conditions).to include(:pairing_code) | |
end | |
end | |
end | |
context '.all' do | |
let(:bulk_items) { double(:bulk_items, items: [item.item], last_evaluated_key: { 'id' => '1' }) } | |
it 'should find all records' do | |
expect(client).to receive(:scan).with(table_name: Pair::TABLE_NAME).and_return(items) | |
subject = Pair.all.first | |
expect(subject).to be_a(Pair) | |
expect(subject).to be_valid | |
end | |
it 'should return blank array' do | |
expect(client).to receive(:scan).with(table_name: Pair::TABLE_NAME).and_return(no_items) | |
items = Pair.all | |
expect(items).to be_blank | |
end | |
it 'should eager load all records' do | |
expect(client).to receive(:scan).with(table_name: Pair::TABLE_NAME).and_return(bulk_items) | |
expect(client).to receive(:scan).with(table_name: Pair::TABLE_NAME, exclusive_start_key: { id: '1' }).and_return(items) | |
expect(items).to receive(:last_evaluated_key).and_return(nil) | |
expect(Pair.all(true).count).to eq(2) | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment