STart refactoring out the Sauce API code into its own module to make it more testable and extendable
This is a precursor to the bug fix for #2 but will also lay the ground work for the more complex user-creation API calls required by #1
This commit is contained in:
parent
b3fd19e0af
commit
500a941d84
|
@ -0,0 +1,2 @@
|
|||
require 'sauce/heroku/api/sauce'
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
require 'httparty'
|
||||
require 'json'
|
||||
|
||||
module Sauce
|
||||
module Heroku
|
||||
module API
|
||||
class Sauce
|
||||
attr_reader :config
|
||||
|
||||
def initialize(config)
|
||||
@config = config
|
||||
end
|
||||
|
||||
def create_scout_session(body)
|
||||
if body.nil? || body.empty?
|
||||
raise Errors::InvalidParametersError, 'body cannot be empty!'
|
||||
end
|
||||
|
||||
unless config.configured?
|
||||
raise Errors::SauceNotConfiguredError, 'we do not have a valid config loaded'
|
||||
end
|
||||
|
||||
response = HTTParty.post(scout_url,
|
||||
:body => body.to_json,
|
||||
:basic_auth => {:username => config.username,
|
||||
:password => config.access_key},
|
||||
:headers => {'Content-Type' => 'application/json'})
|
||||
|
||||
return nil unless (response && response.code == 200)
|
||||
|
||||
response = JSON.parse(response.body)
|
||||
# The response should contain the attribute `embed` which is the
|
||||
# usable scout session URL
|
||||
return response['embed']
|
||||
end
|
||||
|
||||
def scout_url
|
||||
return nil unless config.configured?
|
||||
"https://saucelabs.com/rest/v1/users/#{config.username}/scout"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,10 +1,9 @@
|
|||
require 'heroku'
|
||||
require 'heroku/command/base'
|
||||
require 'httparty'
|
||||
require 'json'
|
||||
#require 'sauce'
|
||||
|
||||
require 'sauce/heroku/api'
|
||||
require 'sauce/heroku/config'
|
||||
require 'sauce/heroku/errors'
|
||||
|
||||
module Heroku
|
||||
module Command
|
||||
|
@ -13,6 +12,7 @@ module Heroku
|
|||
super(*args)
|
||||
@config = ::Sauce::Heroku::Config.new
|
||||
@config.load!
|
||||
@sauceapi = ::Sauce::Heroku::API::Sauce.new(@config)
|
||||
end
|
||||
|
||||
def index
|
||||
|
@ -115,26 +115,17 @@ access_key: #{apikey}
|
|||
:'browser-version' => @browserversion,
|
||||
:url => @url}
|
||||
|
||||
response = HTTParty.post(scout_url,
|
||||
:body => body.to_json,
|
||||
:basic_auth => {:username => @config.username,
|
||||
:password => @config.access_key},
|
||||
:headers => {'Content-Type' => 'application/json'})
|
||||
|
||||
return false unless (response && response.code == 200)
|
||||
|
||||
response = JSON.parse(response.body)
|
||||
|
||||
if response['embed']
|
||||
launchy('Firing up Scout in your browser!', response['embed'])
|
||||
url = nil
|
||||
begin
|
||||
url = @sauceapi.create_scout_session(body)
|
||||
rescue ::Sauce::Heroku::Errors::SauceAuthenticationError
|
||||
puts 'Auth error!'
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
def scout_url
|
||||
return nil unless @config.configured?
|
||||
"https://saucelabs.com/rest/v1/users/#{@config.username}/scout"
|
||||
unless url.nil?
|
||||
launchy('Firing up Scout in your browser!', url)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
module Sauce
|
||||
module Heroku
|
||||
module Errors
|
||||
class SauceAuthenticationError < StandardError; end;
|
||||
class InvalidParametersError < StandardError; end;
|
||||
class SauceNotConfiguredError < StandardError; end;
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,83 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe Sauce::Heroku::API::Sauce do
|
||||
let(:config) { mock('Sauce::Heroku::Config Mock') }
|
||||
# NOTE: The `config` variable is lazily evaluated and the shared context
|
||||
# 'valid config' will overwrite the variable to make `api` contain a valid
|
||||
# config
|
||||
let(:api) { described_class.new(config) }
|
||||
subject { api }
|
||||
|
||||
describe '#initialize' do
|
||||
context 'with no parameters' do
|
||||
end
|
||||
|
||||
context 'with a valid config' do
|
||||
end
|
||||
end
|
||||
|
||||
describe '#create_scout_session' do
|
||||
context 'when passed an empty body' do
|
||||
it 'should raise an error' do
|
||||
expect {
|
||||
api.create_scout_session({})
|
||||
}.to raise_error(Sauce::Heroku::Errors::InvalidParametersError)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when we are not configured' do
|
||||
before :each do
|
||||
config.stub(:configured? => false)
|
||||
end
|
||||
|
||||
it 'should raise an error' do
|
||||
expect {
|
||||
api.create_scout_session({:foo => :bar})
|
||||
}.to raise_error(Sauce::Heroku::Errors::SauceNotConfiguredError)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when passed a valid body' do
|
||||
include_context 'valid config'
|
||||
let(:url) { 'http://fake/scout/url' }
|
||||
let(:body) { {:url => 'http://saucelabs.com/'} }
|
||||
before :each do
|
||||
config.stub(:configured? => true)
|
||||
api.should_receive(:scout_url).and_return(url)
|
||||
end
|
||||
|
||||
it 'should POST to Sauce Labs properly' do
|
||||
headers = {'Content-Type' => 'application/json'}
|
||||
HTTParty.should_receive(:post).with(url,
|
||||
hash_including(:headers => headers))
|
||||
api.create_scout_session(body)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#scout_url' do
|
||||
subject { api.scout_url }
|
||||
|
||||
context 'when not configured' do
|
||||
let(:config) { mock('Mock Config', :configured? => false) }
|
||||
before :each do
|
||||
api.stub(:config => config)
|
||||
end
|
||||
it { should be_nil }
|
||||
end
|
||||
|
||||
context 'when configured' do
|
||||
let(:config) do
|
||||
c = mock('Mock Config', :username => 'rspec')
|
||||
c.stub(:configured? => true)
|
||||
c
|
||||
end
|
||||
before :each do
|
||||
api.stub(:config => config)
|
||||
end
|
||||
|
||||
it { should_not be_nil }
|
||||
it { should_not be_empty }
|
||||
end
|
||||
end
|
||||
end
|
|
@ -5,52 +5,11 @@ describe Heroku::Command::Sauce do
|
|||
|
||||
describe '#scoutup!' do
|
||||
context 'when configured' do
|
||||
let(:config) do
|
||||
c = mock('Sauce::Heroku::Config Mock')
|
||||
c.stub(:configured? => true)
|
||||
c.stub(:username => 'rspec')
|
||||
c.stub(:access_key => 'rspec')
|
||||
c
|
||||
end
|
||||
|
||||
let(:scouturl) { 'http://fakeurl' }
|
||||
|
||||
before :each do
|
||||
command.stub(:scout_url).and_return(scouturl)
|
||||
command.instance_variable_set(:@config, config)
|
||||
end
|
||||
|
||||
it 'should post to Sauce Labs' do
|
||||
HTTParty.should_receive(:post).with(scouturl,
|
||||
hash_including(:headers => {'Content-Type' => 'application/json'}))
|
||||
it 'should create a scout session' do
|
||||
api = command.instance_variable_get(:@sauceapi)
|
||||
api.should_receive(:create_scout_session)
|
||||
command.send(:scoutup!)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#scout_url' do
|
||||
subject { command.send(:scout_url) }
|
||||
|
||||
context 'when not configured' do
|
||||
let(:config) { mock('Mock Config', :configured? => false) }
|
||||
before :each do
|
||||
command.instance_variable_set(:@config, config)
|
||||
end
|
||||
it { should be_nil }
|
||||
end
|
||||
|
||||
context 'when configured' do
|
||||
let(:config) do
|
||||
c = mock('Mock Config', :username => 'rspec')
|
||||
c.stub(:configured? => true)
|
||||
c
|
||||
end
|
||||
before :each do
|
||||
command.instance_variable_set(:@config, config)
|
||||
end
|
||||
|
||||
it { should_not be_nil }
|
||||
it { should_not be_empty }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,3 +3,9 @@ require 'rspec'
|
|||
$LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + '/../lib')
|
||||
|
||||
require 'sauce/heroku/cli'
|
||||
|
||||
|
||||
contexts = File.expand_path(File.dirname(__FILE__) + '/support/contexts')
|
||||
Dir["#{contexts}/**.rb"].each do |f|
|
||||
require f
|
||||
end
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
require 'sauce/heroku/config'
|
||||
|
||||
shared_context 'valid config' do
|
||||
let(:config) do
|
||||
config = Sauce::Heroku::Config.new
|
||||
config.config = {'username' => 'rspec', 'access_key' => 'rspec'}
|
||||
config
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue