Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: v2 changes #153

Open
wants to merge 23 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
uses: actions/checkout@v2

- name: Set up Ruby ${{ matrix.ruby }}
uses: actions/setup-ruby@v1
uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ matrix.ruby }}

Expand Down
7 changes: 7 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
v2.0.0
- Drop support for ruby 1.9.3, require a minimum of ruby 2.2
- Upgrade to Rspec 3
- Upgrade all dependencies to current stable versions
- Catch MultiJson::ParseErrors and return SparkApi::InvalidJSON error instead
- Add default 1 second open_timeout to HTTP requests

v1.4.34
- Version update for releasing v1.4.33 as the tags were set wrong for v1.4.32 release

Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.4.34
2.0.0
2 changes: 0 additions & 2 deletions lib/spark_api/authentication/oauth2_impl/cli_provider.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
require "highline/import"

module SparkApi
module Authentication
module OAuth2Impl
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ def create_session(token_params)
response.expires_in = provider.session_timeout if response.expires_in.nil?
SparkApi.logger.debug { "[oauth2] New session created #{response}" }
response
rescue Faraday::Error::ConnectionFailed => e
rescue Faraday::ConnectionFailed => e
if @client.ssl_verify && e.message =~ /certificate verify failed/
SparkApi.logger.error { SparkApi::Errors.ssl_verification_error }
end
Expand Down
4 changes: 3 additions & 1 deletion lib/spark_api/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ module Configuration
# valid configuration options
VALID_OPTION_KEYS = [:api_key, :api_secret, :api_user, :endpoint,
:user_agent, :version, :ssl, :ssl_verify, :oauth2_provider, :authentication_mode,
:auth_endpoint, :callback, :compress, :timeout, :middleware, :dictionary_version, :request_id_chain].freeze
:auth_endpoint, :callback, :compress, :open_timeout, :timeout, :middleware, :dictionary_version, :request_id_chain].freeze
OAUTH2_KEYS = [:authorization_uri, :access_uri, :client_id, :client_secret,
# Requirements for authorization_code grant type
:redirect_uri,
Expand Down Expand Up @@ -42,6 +42,7 @@ module Configuration
DEFAULT_SSL_VERIFY = true
DEFAULT_OAUTH2 = nil
DEFAULT_COMPRESS = false
DEFAULT_OPEN_TIMEOUT = 1 # seconds
DEFAULT_TIMEOUT = 5 # seconds
DEFAULT_MIDDLEWARE = 'spark_api'
DEFAULT_DICTIONARY_VERSION = nil
Expand Down Expand Up @@ -78,6 +79,7 @@ def reset_configuration
self.ssl_verify = DEFAULT_SSL_VERIFY
self.version = DEFAULT_VERSION
self.compress = DEFAULT_COMPRESS
self.open_timeout = DEFAULT_OPEN_TIMEOUT
self.timeout = DEFAULT_TIMEOUT
self.middleware = DEFAULT_MIDDLEWARE
self.dictionary_version = DEFAULT_DICTIONARY_VERSION
Expand Down
1 change: 1 addition & 0 deletions lib/spark_api/connection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ def connection(force_ssl = false)

conn = Faraday.new(opts) do |conn|
conn.response self.middleware.to_sym
conn.options[:open_timeout] = self.open_timeout
conn.options[:timeout] = self.timeout
conn.adapter Faraday.default_adapter
end
Expand Down
1 change: 1 addition & 0 deletions lib/spark_api/errors.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ module ResponseCodes
end

# Errors built from API responses
class InvalidJSON < StandardError; end
class InvalidResponse < StandardError; end
class ClientError < StandardError
attr_reader :code, :status, :details, :request_path, :request_id, :errors
Expand Down
7 changes: 6 additions & 1 deletion lib/spark_api/faraday_middleware.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,12 @@ def initialize(app)
def on_complete(env)
env[:body] = decompress_body(env)

body = MultiJson.decode(env[:body])
begin
body = MultiJson.decode(env[:body])
rescue MultiJson::ParseError => e
raise InvalidJSON, "Invalid JSON returned with HTTP #{env[:status]} for URI #{env[:url]}"
end

SparkApi.logger.debug{ "Response Body: #{body.inspect}" }
unless body.is_a?(Hash) && body.key?("D")
raise InvalidResponse, "The server response could not be understood"
Expand Down
2 changes: 1 addition & 1 deletion lib/spark_api/request.rb
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ def request(method, path, body, options)
else
return response.body
end
rescue Faraday::Error::ConnectionFailed => e
rescue Faraday::ConnectionFailed => e
if self.ssl_verify && e.message =~ /certificate verify failed/
SparkApi.logger.error { SparkApi::Errors.ssl_verification_error }
end
Expand Down
40 changes: 13 additions & 27 deletions spark_api.gemspec
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
# -*- encoding: utf-8 -*-
lib = File.expand_path('../lib/', __FILE__)
$:.unshift lib unless $:.include?(lib)

require 'spark_api/version'
# coding: utf-8
lib = File.expand_path("../lib", __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require "spark_api/version"
require 'rubygems/user_interaction'

Gem::Specification.new do |s|
Expand All @@ -16,6 +15,7 @@ Gem::Specification.new do |s|
s.description = %q{The spark_api gem handles most of the boilerplate for communicating with the Spark API rest services, including authentication and request parsing.}

s.required_rubygems_version = ">= 1.8"
s.required_ruby_version = '>= 2.2.4'
s.rubyforge_project = "spark_api"

s.extra_rdoc_files = [
Expand All @@ -31,30 +31,16 @@ Gem::Specification.new do |s|
s.default_executable = %q{spark_api}
s.require_paths = ["lib"]

s.add_dependency 'faraday', '~> 0.9.0'
s.add_dependency 'multi_json', '~> 1.0'
s.add_dependency 'json', '~> 1.7'
s.add_dependency 'builder', '>= 2.1.2', '< 4.0.0'
s.add_dependency 'will_paginate', '>= 3.0.pre2', '< 4.0.0'
s.add_dependency 'highline', '>= 1.0'

# spark_api doesn't use public_suffix directly. spark_api uses Webmock, which
# uses addressable, which uses public_suffix. Bundler has suddenly started
# trying to install public_suffix 2.0.4, which requires Ruby 2. When spark_api
# starts to require Ruby 2, this dependency can be removed.
s.add_development_dependency 'public_suffix', '~> 1.4.6'
s.add_dependency 'faraday'
s.add_dependency 'multi_json'
s.add_dependency 'json'
s.add_dependency 'will_paginate'

# TEST GEMS
s.add_development_dependency 'rake', '~> 0.9.2'
s.add_development_dependency 'rspec', '~> 2.14.0'
s.add_development_dependency 'webmock', '~> 1.9'
s.add_development_dependency 'typhoeus', '~> 0.3'
s.add_development_dependency 'ci_reporter', '~> 1.7.0'
s.add_development_dependency 'rb-readline'
s.add_development_dependency 'rb-fsevent'
s.add_development_dependency 'simplecov'
s.add_development_dependency 'rake'
s.add_development_dependency 'rspec'
s.add_development_dependency 'webmock'
s.add_development_dependency 'ci_reporter_rspec'
s.add_development_dependency 'simplecov-rcov'
s.add_development_dependency 'listen', '~> 3.0.8' # for guard-rspec with ruby 1.9.3
s.add_development_dependency 'guard-rspec'
end

51 changes: 13 additions & 38 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
@@ -1,66 +1,41 @@
if ENV['COVERAGE'] == "on"
require 'simplecov'
require 'simplecov-rcov'
SimpleCov.formatter = SimpleCov::Formatter::RcovFormatter
SimpleCov.start do
add_filter '/vendor'
add_filter '/spec'
add_filter '/test'
end
end

require "rubygems"
require "rspec"
require 'rspec/autorun'
require 'webmock/rspec'
require "json"
require 'multi_json'

path = File.expand_path(File.dirname(__FILE__) + "/../lib/")
$LOAD_PATH.unshift(path) unless $LOAD_PATH.include?(path)
require path + '/spark_api'

require 'spark_api'

FileUtils.mkdir 'log' unless File.exists? 'log'

module SparkApi
def self.logger
if @logger.nil?
@logger = Logger.new('log/test.log')
@logger.level = Logger::DEBUG
end
@logger
end
if ENV['COVERAGE'] == "on"
require 'simplecov'
require 'simplecov-rcov'
SimpleCov.formatter = SimpleCov::Formatter::RcovFormatter
SimpleCov.start { add_filter %w(/vendor /spec /test) }
end

SparkApi.logger.info("Setup gem for rspec testing")
FileUtils.mkdir 'log' unless File.exists? 'log'

include SparkApi::Models

def reset_config
SparkApi.reset
SparkApi.configure { |c| c.api_user = "foobar" }
end
SparkApi.logger = ::Logger.new('log/test.log')

# Requires supporting ruby files with custom matchers and macros, etc,
# # in spec/support/ and its subdirectories.
Dir[File.expand_path(File.join(File.dirname(__FILE__),'support','**','*.rb'))].each {|f| require f}

RSpec.configure do |config|

config.include WebMock::API
config.include StubApiRequests

config.treat_symbols_as_metadata_keys_with_true_values = true
config.alias_example_to :on_get_it, :method => 'GET'
config.alias_example_to :on_put_it, :method => 'PUT'
config.alias_example_to :on_post_it, :method => 'POST'
config.alias_example_to :on_delete_it, :method => 'DELETE'
config.before(:all) { reset_config }
config.color_enabled = true
config.color= true
end

def jruby?
RUBY_PLATFORM == "java"
end

def reset_config
SparkApi.reset
SparkApi.configure { |c| c.api_user = "foobar" }
end
43 changes: 21 additions & 22 deletions spec/unit/spark_api/authentication/api_auth_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,14 @@
subject {SparkApi::Authentication::ApiAuth.new(nil) }
describe "build_param_hash" do
it "should return a blank string when passed nil" do
subject.build_param_string(nil).should be_empty
expect(subject.build_param_string(nil)).to be_empty
end
it "should return a correct param string for one item" do
subject.build_param_string({:foo => "bar"}).should match("foobar")
expect(subject.build_param_string({:foo => "bar"})).to match("foobar")
end
it "should alphabatize the param names by key first, then by value" do
subject.build_param_string({:zoo => "zar", :ooo => "car"}).should match("ooocarzoozar")
subject.build_param_string({:Akey => "aValue", :aNotherkey => "AnotherValue"}).should
match "AkeyaValueaNotherkeyAnotherValue"
expect(subject.build_param_string({:zoo => "zar", :ooo => "car"})).to match("ooocarzoozar")
expect(subject.build_param_string({:Akey => "aValue", :aNotherkey => "AnotherValue"})).to match("AkeyaValueaNotherkeyAnotherValue")
end
end

Expand All @@ -33,24 +32,24 @@
stub_request(:post, "https://api.sparkapi.com/#{SparkApi.version}/session").
with(:query => {:ApiKey => "my_key", :ApiSig => "c731cf2455fbc7a4ef937b2301108d7a"}).
to_return(:body => fixture("authentication_failure.json"), :status=>401)
expect {subject.authenticate()}.to raise_error(SparkApi::ClientError){ |e| e.status.should == 401 }
expect {subject.authenticate()}.to raise_error(SparkApi::ClientError){ |e| expect(e.status).to eq(401) }
end
end

describe "authenticated?" do
let(:session) { Object.new }
it "should return true when session is active" do
subject.session = session
session.stub(:expired?) { false }
subject.authenticated?.should eq(true)
allow(session).to receive(:expired?) { false }
expect(subject.authenticated?).to eq(true)
end
it "should return false when session is expired" do
subject.session = session
session.stub(:expired?) { true }
subject.authenticated?.should eq(false)
allow(session).to receive(:expired?) { true }
expect(subject.authenticated?).to eq(false)
end
it "should return false when session is uninitialized" do
subject.authenticated?.should eq(false)
expect(subject.authenticated?).to eq(false)
end
end

Expand All @@ -61,14 +60,14 @@
it "should logout when there is an active session" do
logged_out = false
subject.session = session
client.stub(:delete).with("/session/1234") { logged_out = true }
allow(client).to receive(:delete).with("/session/1234") { logged_out = true }
subject.logout
subject.session.should eq(nil)
logged_out.should eq(true)
expect(subject.session).to eq(nil)
expect(logged_out).to eq(true)
end
it "should skip logging out when there is no active session information" do
client.stub(:delete) { raise "Should not be called" }
subject.logout.should eq(nil)
allow(client).to receive(:delete) { raise "Should not be called" }
expect(subject.logout).to eq(nil)
end
end

Expand Down Expand Up @@ -98,7 +97,7 @@
:AuthToken => "1234"}.merge(args)).
to_return(:body => fixture("listings/no_subresources.json"))
subject.session = session
subject.request(:get, "/#{SparkApi.version}/listings", nil, args).status.should eq(200)
expect(subject.request(:get, "/#{SparkApi.version}/listings", nil, args).status).to eq(200)
end
it "should handle a post request" do
stub_auth_request
Expand All @@ -118,14 +117,14 @@
}]}
}',
:status=>201)
subject.request(:post, "/#{SparkApi.version}/contacts", contact, args).status.should eq(201)
expect(subject.request(:post, "/#{SparkApi.version}/contacts", contact, args).status).to eq(201)
end
end

describe "sign" do
it "should sign the auth parameters correctly" do
sign_token = "my_secretApiKeymy_key"
subject.sign(sign_token).should eq("c731cf2455fbc7a4ef937b2301108d7a")
expect(subject.sign(sign_token)).to eq("c731cf2455fbc7a4ef937b2301108d7a")
end
end

Expand All @@ -134,7 +133,7 @@
subject {SparkApi::Authentication::ApiAuth.new(client) }
it "should fully sign the token" do
parms = {:AuthToken => "1234", :ApiUser => "CoolAsIce"}
subject.sign_token("/test", parms).should eq("7bbe3384a8b64368357f8551cab271e3")
expect(subject.sign_token("/test", parms)).to eq("7bbe3384a8b64368357f8551cab271e3")
end
end

Expand All @@ -160,8 +159,8 @@
to_return(:body => fixture('listings/with_documents.json'))
l = Listing.find('1234', :_expand => "Documents")

count.should eq(2)
SparkApi.client.session.expired?.should eq(false)
expect(count).to eq(2)
expect(SparkApi.client.session.expired?).to eq(false)
end
end

Expand Down
6 changes: 3 additions & 3 deletions spec/unit/spark_api/authentication/base_auth_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
describe SparkApi::Authentication::BaseAuth do
subject {SparkApi::Authentication::BaseAuth.new(nil) }
it "should raise an error" do
expect {subject.authenticate()}.to raise_error(){ |e| e.message.should == "Implement me!"}
expect {subject.logout()}.to raise_error(){ |e| e.message.should == "Implement me!"}
expect {subject.request(nil, nil, nil, nil)}.to raise_error(){ |e| e.message.should == "Implement me!"}
expect {subject.authenticate()}.to raise_error(){ |e| expect(e.message).to eq("Implement me!")}
expect {subject.logout()}.to raise_error(){ |e| expect(e.message).to eq("Implement me!")}
expect {subject.request(nil, nil, nil, nil)}.to raise_error(){ |e| expect(e.message).to eq("Implement me!")}
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
:status => 201
}
subject.on_complete env
env[:body]["token"].should eq("sp4rkb4rt0k3n")
expect(env[:body]["token"]).to eq("sp4rkb4rt0k3n")
end

it "should raise error on unsuccessful response" do
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@
subject { SparkApi::Authentication::OAuth2Impl::GrantTypeBase }
# Make sure the client boostraps the right plugin based on configuration.
it "create should " do
expect {subject.create(nil, InvalidAuth2Provider.new())}.to raise_error(SparkApi::ClientError){ |e| e.message.should == "Unsupported grant type [not_a_real_type]" }
expect {subject.create(nil, InvalidAuth2Provider.new())}.to raise_error(SparkApi::ClientError){ |e| expect(e.message).to eq("Unsupported grant type [not_a_real_type]") }
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
describe SparkApi::Authentication::SingleSessionProvider do
subject { SparkApi::Authentication::SingleSessionProvider.new({ :access_token => "the_token" }) }
it "should initialize a new session with access_token" do
subject.load_session.should respond_to(:access_token)
subject.load_session.access_token.should eq("the_token")
expect(subject.load_session).to respond_to(:access_token)
expect(subject.load_session.access_token).to eq("the_token")
end
end
Loading