From d29fc30b812bae60892ca1a9598a77c0941023bb Mon Sep 17 00:00:00 2001 From: Ryan Foster Date: Mon, 13 Jun 2016 09:09:17 -0600 Subject: [PATCH 1/2] Split out WePay::Client - paves way for more OO refactoring --- lib/we_pay/client.rb | 123 +++++++++++++++++++++++++++++++++++++++++++ lib/wepay.rb | 116 +--------------------------------------- wepay.gemspec | 4 +- 3 files changed, 127 insertions(+), 116 deletions(-) create mode 100644 lib/we_pay/client.rb diff --git a/lib/we_pay/client.rb b/lib/we_pay/client.rb new file mode 100644 index 0000000..b2cda5a --- /dev/null +++ b/lib/we_pay/client.rb @@ -0,0 +1,123 @@ +## +# Copyright (c) 2012-2016 WePay. +# +# http://opensource.org/licenses/Apache2.0 +## + +require 'cgi' +require 'json' +require 'net/http' +require 'net/https' +require 'rubygems' +require 'uri' + +module WePay + + ## + # A very simple wrapper for the WePay API. + ## + class Client + + # Stage API endpoint + STAGE_API_ENDPOINT = "https://stage.wepayapi.com/v2" + + # Stage UI endpoint + STAGE_UI_ENDPOINT = "https://stage.wepay.com/v2" + + # Production API endpoint + PRODUCTION_API_ENDPOINT = "https://wepayapi.com/v2" + + # Production UI endpoint + PRODUCTION_UI_ENDPOINT = "https://www.wepay.com/v2" + + attr_reader :api_endpoint + attr_reader :api_version + attr_reader :client_id + attr_reader :client_secret + attr_reader :ui_endpoint + + def initialize(client_id, client_secret, use_stage = true, api_version = nil) + @client_id = client_id.to_s + @client_secret = client_secret.to_s + @api_version = api_version.to_s + + if use_stage + @api_endpoint = STAGE_API_ENDPOINT + @ui_endpoint = STAGE_UI_ENDPOINT + else + @api_endpoint = PRODUCTION_API_ENDPOINT + @ui_endpoint = PRODUCTION_UI_ENDPOINT + end + end + + ## + # Execute a call to the WePay API. + ## + def call(call, access_token = false, params = {}) + path = call.start_with?('/') ? call : call.prepend('/') + url = URI.parse(api_endpoint + path) + + call = Net::HTTP::Post.new(url.path, { + 'Content-Type' => 'application/json', + 'User-Agent' => 'WePay Ruby SDK' + }) + + unless params.empty? + call.body = params.to_json + end + + if access_token then call.add_field('Authorization', "Bearer #{access_token}"); end + if @api_version then call.add_field('Api-Version', @api_version); end + + make_request(call, url) + end + + ## + # Returns the OAuth 2.0 URL that users should be redirected to for + # authorizing your API application. The `redirect_uri` must be a + # fully-qualified URL (e.g., `https://www.wepay.com`). + ## + def oauth2_authorize_url( + redirect_uri, + user_email = false, + user_name = false, + permissions = "manage_accounts,collect_payments,view_user,send_money,preapprove_payments,manage_subscriptions", + user_country = false + ) + url = @ui_endpoint + + '/oauth2/authorize?client_id=' + @client_id.to_s + + '&redirect_uri=' + redirect_uri + + '&scope=' + permissions + + url += user_name ? '&user_name=' + CGI::escape(user_name) : '' + url += user_email ? '&user_email=' + CGI::escape(user_email) : '' + url += user_country ? '&user_country=' + CGI::escape(user_country) : '' + end + + ## + # Call the `/v2/oauth2/token` endpoint to exchange an OAuth 2.0 `code` for an `access_token`. + ## + def oauth2_token(code, redirect_uri) + call('/oauth2/token', false, { + 'client_id' => @client_id, + 'client_secret' => @client_secret, + 'redirect_uri' => redirect_uri, + 'code' => code + }) + end + +private + + ## + # Make the HTTP request to the endpoint. + ## + def make_request(call, url) + request = Net::HTTP.new(url.host, url.port) + request.read_timeout = 30 + request.use_ssl = true + + response = request.start { |http| http.request(call) } + JSON.parse(response.body) + end + end +end diff --git a/lib/wepay.rb b/lib/wepay.rb index 78977c6..45d4079 100644 --- a/lib/wepay.rb +++ b/lib/wepay.rb @@ -4,123 +4,9 @@ # http://opensource.org/licenses/Apache2.0 ## -require 'cgi' -require 'json' -require 'net/http' -require 'net/https' -require 'rubygems' -require 'uri' - ## # The root WePay namespace. ## module WePay - - ## - # A very simple wrapper for the WePay API. - ## - class Client - - # Stage API endpoint - STAGE_API_ENDPOINT = "https://stage.wepayapi.com/v2" - - # Stage UI endpoint - STAGE_UI_ENDPOINT = "https://stage.wepay.com/v2" - - # Production API endpoint - PRODUCTION_API_ENDPOINT = "https://wepayapi.com/v2" - - # Production UI endpoint - PRODUCTION_UI_ENDPOINT = "https://www.wepay.com/v2" - - attr_reader :api_endpoint - attr_reader :api_version - attr_reader :client_id - attr_reader :client_secret - attr_reader :ui_endpoint - - def initialize(client_id, client_secret, use_stage = true, api_version = nil) - @client_id = client_id.to_s - @client_secret = client_secret.to_s - @api_version = api_version.to_s - - if use_stage - @api_endpoint = STAGE_API_ENDPOINT - @ui_endpoint = STAGE_UI_ENDPOINT - else - @api_endpoint = PRODUCTION_API_ENDPOINT - @ui_endpoint = PRODUCTION_UI_ENDPOINT - end - end - - ## - # Execute a call to the WePay API. - ## - def call(call, access_token = false, params = {}) - path = call.start_with?('/') ? call : call.prepend('/') - url = URI.parse(api_endpoint + path) - - call = Net::HTTP::Post.new(url.path, { - 'Content-Type' => 'application/json', - 'User-Agent' => 'WePay Ruby SDK' - }) - - unless params.empty? - call.body = params.to_json - end - - if access_token then call.add_field('Authorization', "Bearer #{access_token}"); end - if @api_version then call.add_field('Api-Version', @api_version); end - - make_request(call, url) - end - - ## - # Returns the OAuth 2.0 URL that users should be redirected to for - # authorizing your API application. The `redirect_uri` must be a - # fully-qualified URL (e.g., `https://www.wepay.com`). - ## - def oauth2_authorize_url( - redirect_uri, - user_email = false, - user_name = false, - permissions = "manage_accounts,collect_payments,view_user,send_money,preapprove_payments,manage_subscriptions", - user_country = false - ) - url = @ui_endpoint + - '/oauth2/authorize?client_id=' + @client_id.to_s + - '&redirect_uri=' + redirect_uri + - '&scope=' + permissions - - url += user_name ? '&user_name=' + CGI::escape(user_name) : '' - url += user_email ? '&user_email=' + CGI::escape(user_email) : '' - url += user_country ? '&user_country=' + CGI::escape(user_country) : '' - end - - ## - # Call the `/v2/oauth2/token` endpoint to exchange an OAuth 2.0 `code` for an `access_token`. - ## - def oauth2_token(code, redirect_uri) - call('/oauth2/token', false, { - 'client_id' => @client_id, - 'client_secret' => @client_secret, - 'redirect_uri' => redirect_uri, - 'code' => code - }) - end - -private - - ## - # Make the HTTP request to the endpoint. - ## - def make_request(call, url) - request = Net::HTTP.new(url.host, url.port) - request.read_timeout = 30 - request.use_ssl = true - - response = request.start { |http| http.request(call) } - JSON.parse(response.body) - end - end + autoload :Client, 'we_pay/client' end diff --git a/wepay.gemspec b/wepay.gemspec index dc096df..933e8bc 100644 --- a/wepay.gemspec +++ b/wepay.gemspec @@ -2,11 +2,13 @@ Gem::Specification.new do |s| s.name = 'wepay' s.version = '0.3.0' s.date = '2016-06-11' + s.summary = "WePay SDK for Ruby" s.description = "The WePay SDK for Ruby lets you easily make WePay API calls from Ruby." s.authors = ["WePay"] s.email = 'api@wepay.com' - s.files = ["lib/wepay.rb"] s.homepage = 'https://github.com/wepay/Ruby-SDK' s.license = 'Apache-2.0' + + s.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) } end From c6a83b9caef99b8d75335f42da7b186921e97b7d Mon Sep 17 00:00:00 2001 From: Ryan Foster Date: Mon, 13 Jun 2016 11:57:56 -0600 Subject: [PATCH 2/2] Add testing and production requests - maintain current `0.2.x` API - divide client and request concerns - create `WePay::TestRequest` - create 'WePay::ProductionRequest` --- .gitignore | 1 + lib/we_pay/base_request.rb | 77 +++++ lib/we_pay/client.rb | 99 +++--- lib/we_pay/production_request.rb | 17 + lib/we_pay/test_request.rb | 17 + lib/wepay.rb | 6 +- spec/spec_helper.rb | 4 + spec/we_pay/client_spec.rb | 250 ++++++++++++++ spec/we_pay/production_request_spec.rb | 49 +++ spec/we_pay/test_request_spec.rb | 49 +++ spec/wepay/client_spec.rb | 446 ------------------------- 11 files changed, 526 insertions(+), 489 deletions(-) create mode 100644 lib/we_pay/base_request.rb create mode 100644 lib/we_pay/production_request.rb create mode 100644 lib/we_pay/test_request.rb create mode 100644 spec/we_pay/client_spec.rb create mode 100644 spec/we_pay/production_request_spec.rb create mode 100644 spec/we_pay/test_request_spec.rb delete mode 100644 spec/wepay/client_spec.rb diff --git a/.gitignore b/.gitignore index 1823a57..04b0f90 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +/.DS_STORE /.yardoc /*.gem /*.gemspec diff --git a/lib/we_pay/base_request.rb b/lib/we_pay/base_request.rb new file mode 100644 index 0000000..555ed54 --- /dev/null +++ b/lib/we_pay/base_request.rb @@ -0,0 +1,77 @@ +require 'json' +require 'net/http' +require 'net/https' +require 'uri' + +module WePay + module BaseRequest + + attr_reader :client_id, + :client_secret, + :api_version, + :path, + :access_token, + :params + + def initialize(client_id, client_secret, api_version, path, access_token, params) + @client_id = client_id + @client_secret = client_secret + @api_version = api_version + @path = path + @access_token = access_token + @params = params + end + + def response + JSON.parse(raw_response.body) + end + + private + + def raw_response + @raw_response ||= client.start do |c| + c.request(request) + end + end + + def request + @request ||= Net::HTTP::Post.new(uri.path, default_headers).tap do |r| + if params.any? + r.body = params.to_json + end + + if access_token + r.add_field('Authorization', "Bearer #{access_token}") + end + + if api_version + r.add_field('Api-Version', @api_version) + end + end + end + + def client + @client ||= Net::HTTP.new(uri.host, uri.port).tap do |c| + c.read_timeout = 30 + c.use_ssl = true + end + end + + def uri + @uri ||= URI.join(api_endpoint, normalized_path) + end + + def normalized_path + return path if path.start_with?('/') + + path.prepend('/') + end + + def default_headers + { + 'Content-Type' => 'application/json', + 'User-Agent' => 'WePay Ruby SDK' + } + end + end +end diff --git a/lib/we_pay/client.rb b/lib/we_pay/client.rb index b2cda5a..80da507 100644 --- a/lib/we_pay/client.rb +++ b/lib/we_pay/client.rb @@ -8,8 +8,6 @@ require 'json' require 'net/http' require 'net/https' -require 'rubygems' -require 'uri' module WePay @@ -30,46 +28,30 @@ class Client # Production UI endpoint PRODUCTION_UI_ENDPOINT = "https://www.wepay.com/v2" - attr_reader :api_endpoint - attr_reader :api_version - attr_reader :client_id - attr_reader :client_secret - attr_reader :ui_endpoint + attr_reader :client_id, + :client_secret, + :use_stage, + :api_version def initialize(client_id, client_secret, use_stage = true, api_version = nil) @client_id = client_id.to_s @client_secret = client_secret.to_s + @use_stage = !!use_stage @api_version = api_version.to_s - - if use_stage - @api_endpoint = STAGE_API_ENDPOINT - @ui_endpoint = STAGE_UI_ENDPOINT - else - @api_endpoint = PRODUCTION_API_ENDPOINT - @ui_endpoint = PRODUCTION_UI_ENDPOINT - end end ## # Execute a call to the WePay API. ## - def call(call, access_token = false, params = {}) - path = call.start_with?('/') ? call : call.prepend('/') - url = URI.parse(api_endpoint + path) - - call = Net::HTTP::Post.new(url.path, { - 'Content-Type' => 'application/json', - 'User-Agent' => 'WePay Ruby SDK' - }) - - unless params.empty? - call.body = params.to_json - end - - if access_token then call.add_field('Authorization', "Bearer #{access_token}"); end - if @api_version then call.add_field('Api-Version', @api_version); end - - make_request(call, url) + def call(path, access_token = false, params = {}) + request_class.new( + client_id, + client_secret, + api_version, + path, + access_token, + params + ).response end ## @@ -81,10 +63,10 @@ def oauth2_authorize_url( redirect_uri, user_email = false, user_name = false, - permissions = "manage_accounts,collect_payments,view_user,send_money,preapprove_payments,manage_subscriptions", + permissions = default_oauth_permissions, user_country = false ) - url = @ui_endpoint + + url = ui_endpoint + '/oauth2/authorize?client_id=' + @client_id.to_s + '&redirect_uri=' + redirect_uri + '&scope=' + permissions @@ -106,18 +88,51 @@ def oauth2_token(code, redirect_uri) }) end -private + ## + # Support exisiting API + # + # `WePay::Client#api_endpoint` + ## + def api_endpoint + if use_stage + STAGE_API_ENDPOINT + else + PRODUCTION_API_ENDPOINT + end + end ## - # Make the HTTP request to the endpoint. + # Support exisiting API + # + # `WePay::Client#ui_endpoint` ## - def make_request(call, url) - request = Net::HTTP.new(url.host, url.port) - request.read_timeout = 30 - request.use_ssl = true + def ui_endpoint + if use_stage + STAGE_UI_ENDPOINT + else + PRODUCTION_UI_ENDPOINT + end + end + + private + + def request_class + if use_stage + TestRequest + else + ProductionRequest + end + end - response = request.start { |http| http.request(call) } - JSON.parse(response.body) + def default_oauth_permissions + %w( + manage_accounts + collect_payments + view_user + send_money + preapprove_payments + manage_subscriptions + ).join(',') end end end diff --git a/lib/we_pay/production_request.rb b/lib/we_pay/production_request.rb new file mode 100644 index 0000000..cfec968 --- /dev/null +++ b/lib/we_pay/production_request.rb @@ -0,0 +1,17 @@ +module WePay + class ProductionRequest + include BaseRequest + + private + + def api_endpoint + ::WePay::Client::PRODUCTION_API_ENDPOINT + end + + # :nocov: + def ui_endpoint + ::WePay::Client::PRODUCTION_UI_ENDPOINT + end + # :nocov: + end +end diff --git a/lib/we_pay/test_request.rb b/lib/we_pay/test_request.rb new file mode 100644 index 0000000..591d703 --- /dev/null +++ b/lib/we_pay/test_request.rb @@ -0,0 +1,17 @@ +module WePay + class TestRequest + include BaseRequest + + private + + def api_endpoint + ::WePay::Client::STAGE_API_ENDPOINT + end + + # :nocov: + def ui_endpoint + ::WePay::Client::STAGE_UI_ENDPOINT + end + # :nocov: + end +end diff --git a/lib/wepay.rb b/lib/wepay.rb index 45d4079..febb5c2 100644 --- a/lib/wepay.rb +++ b/lib/wepay.rb @@ -8,5 +8,9 @@ # The root WePay namespace. ## module WePay - autoload :Client, 'we_pay/client' + autoload :Client, 'we_pay/client' + + autoload :BaseRequest, 'we_pay/base_request' + autoload :TestRequest, 'we_pay/test_request' + autoload :ProductionRequest, 'we_pay/production_request' end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 0017bf4..eaf1e54 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -8,6 +8,10 @@ CodeClimate::TestReporter.start require 'simplecov' +SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[ + SimpleCov::Formatter::HTMLFormatter, + Coveralls::SimpleCov::Formatter +] SimpleCov.start require 'wepay' diff --git a/spec/we_pay/client_spec.rb b/spec/we_pay/client_spec.rb new file mode 100644 index 0000000..3667a35 --- /dev/null +++ b/spec/we_pay/client_spec.rb @@ -0,0 +1,250 @@ +require 'spec_helper' + +RSpec.describe WePay::Client do + + context "constants" do + it "returns the staging api endpoint" do + expect(described_class::STAGE_API_ENDPOINT).to eq('https://stage.wepayapi.com/v2') + end + + it "returns the staging ui endpoint" do + expect(described_class::STAGE_UI_ENDPOINT).to eq('https://stage.wepay.com/v2') + end + + it "returns the production api endpoint" do + expect(described_class::PRODUCTION_API_ENDPOINT).to eq('https://wepayapi.com/v2') + end + + it "returns the production ui endpoint" do + expect(described_class::PRODUCTION_UI_ENDPOINT).to eq('https://www.wepay.com/v2') + end + end + + context "an instance" do + subject do + described_class.new( + 'client_id', + 'client_secret' + ) + end + + describe "#initialize" do + it "returns a client" do + expect(subject).to be_a(described_class) + end + end + + describe "#api_endpoint" do + context "for non-production environments" do + subject do + described_class.new( + 'client_id', + 'client_secret', + true + ) + end + + it "returns the stage api endpoint" do + expect(subject.api_endpoint).to eq('https://stage.wepayapi.com/v2') + end + end + + context "for production environments" do + subject do + described_class.new( + 'client_id', + 'client_secret', + false + ) + end + + it "returns the production api endpoint" do + expect(subject.api_endpoint).to eq('https://wepayapi.com/v2') + end + end + end + + describe "#api_version" do + context "when no version is given" do + it "returns nothing" do + expect(subject.api_version).to eq('') + end + end + + context "when a version is given" do + subject do + described_class.new( + 'client_id', + 'client_secret', + true, + 1 + ) + end + + it "returns the version" do + expect(subject.api_version).to eq('1') + end + end + end + + describe "#client_id" do + it "returns the client id" do + expect(subject.client_id).to eq('client_id') + end + end + + describe "#client_secret" do + it "returns the client secret" do + expect(subject.client_secret).to eq('client_secret') + end + end + + describe "#ui_endpoint" do + context "for non-production environments" do + subject do + described_class.new( + 'client_id', + 'client_secret', + true + ) + end + + it "returns the staging ui endpoint" do + expect(subject.ui_endpoint).to eq('https://stage.wepay.com/v2') + end + end + + context "for production environments" do + subject do + described_class.new( + 'client_id', + 'client_secret', + false + ) + end + + it "returns the production ui endpoint" do + expect(subject.ui_endpoint).to eq('https://www.wepay.com/v2') + end + end + end + + describe "#call" do + context "making a non-production request" do + subject do + described_class.new( + 'client_id', + 'client_secret' + ) + end + + let(:request) { double("wepay::test_request") } + + it "makes a staging request" do + allow(WePay::TestRequest).to receive(:new) + .with( + 'client_id', + 'client_secret', + '', + '/app', + false, + {} + ).and_return(request) + + expect(request).to receive(:response) + + subject.call('/app') + end + end + + context "making a production request" do + subject do + described_class.new( + 'client_id', + 'client_secret', + false + ) + end + + let(:request) { double("wepay::production_request") } + + it "makes a production request" do + allow(WePay::ProductionRequest).to receive(:new) + .with( + 'client_id', + 'client_secret', + '', + '/app', + false, + {} + ).and_return(request) + + expect(request).to receive(:response) + + subject.call('/app') + end + end + end + + describe "#oauth2_authorize_url" do + context "with default params" do + it "returns the oauth2 authorize url" do + expect( + subject.oauth2_authorize_url( + 'https://www.wepay.com' + ) + ).to eq( + 'https://stage.wepay.com/v2/oauth2/authorize?client_id=client_id&redirect_uri=https://www.wepay.com&scope=manage_accounts,collect_payments,view_user,send_money,preapprove_payments,manage_subscriptions') + end + end + + context "with custom params" do + it "returns the oauth2 authorize url" do + expect( + subject.oauth2_authorize_url( + 'https://www.wepay.com', + 'user@host.com', + 'username', + 'manage_accounts', + 'US United States' + ) + ).to eq( + 'https://stage.wepay.com/v2/oauth2/authorize?client_id=client_id&redirect_uri=https://www.wepay.com&scope=manage_accounts&user_name=username&user_email=user%40host.com&user_country=US+United+States') + end + end + end + + describe "#oauth2_token" do + subject do + described_class.new( + 'client_id', + 'client_secret', + false + ) + end + + let(:request) { double("wepay::production_request") } + + it "returns a oauth2 token response" do + allow(WePay::ProductionRequest).to receive(:new) + .with( + 'client_id', + 'client_secret', + '', + '/oauth2/token', + false, + { + 'client_id' => 'client_id', + 'client_secret' => 'client_secret', + 'redirect_uri' => 'https://redirect.app.com', + 'code' => 'code' + + } + ).and_return(request) + + expect(request).to receive(:response) + subject.oauth2_token('code', 'https://redirect.app.com') + end + end + end +end diff --git a/spec/we_pay/production_request_spec.rb b/spec/we_pay/production_request_spec.rb new file mode 100644 index 0000000..9723b7b --- /dev/null +++ b/spec/we_pay/production_request_spec.rb @@ -0,0 +1,49 @@ +require 'spec_helper' + +RSpec.describe WePay::ProductionRequest do + + describe "#response" do + let(:http_response) { double("net::http::response") } + let(:http_post) { double("net::http::post") } + let(:http_client) { double("net::http") } + + subject do + described_class.new( + 'client_id', + 'client_secret', + 'api_version', + 'path', + 'access_token', + data: 'data' + ) + end + + before do + allow(http_response).to receive(:body).and_return({ response: 'response' }.to_json) + + allow(Net::HTTP::Post).to receive(:new).with( + "/path", + 'Content-Type' => 'application/json', + 'User-Agent' => 'WePay Ruby SDK' + ).and_return(http_post) + + allow(http_post).to receive(:body=).with({ data: 'data' }.to_json) + allow(http_post).to receive(:add_field).with('Authorization', "Bearer access_token") + allow(http_post).to receive(:add_field).with('Api-Version', "api_version") + + allow(Net::HTTP).to receive(:new).with( + "wepayapi.com", + 443 + ).and_return(http_client) + + allow(http_client).to receive(:read_timeout=).with(30) + allow(http_client).to receive(:use_ssl=).with(true) + allow(http_client).to receive(:request).with(http_post).and_return(http_response) + allow(http_client).to receive(:start).and_yield(http_client) + end + + it "returns response data" do + expect(subject.response).to eq({ 'response' => 'response' }) + end + end +end diff --git a/spec/we_pay/test_request_spec.rb b/spec/we_pay/test_request_spec.rb new file mode 100644 index 0000000..b9cd340 --- /dev/null +++ b/spec/we_pay/test_request_spec.rb @@ -0,0 +1,49 @@ +require 'spec_helper' + +RSpec.describe WePay::TestRequest do + + describe "#response" do + let(:http_response) { double("net::http::response") } + let(:http_post) { double("net::http::post") } + let(:http_client) { double("net::http") } + + subject do + described_class.new( + 'client_id', + 'client_secret', + 'api_version', + 'path', + 'access_token', + data: 'data' + ) + end + + before do + allow(http_response).to receive(:body).and_return({ response: 'response' }.to_json) + + allow(Net::HTTP::Post).to receive(:new).with( + "/path", + 'Content-Type' => 'application/json', + 'User-Agent' => 'WePay Ruby SDK' + ).and_return(http_post) + + allow(http_post).to receive(:body=).with({ data: 'data' }.to_json) + allow(http_post).to receive(:add_field).with('Authorization', "Bearer access_token") + allow(http_post).to receive(:add_field).with('Api-Version', "api_version") + + allow(Net::HTTP).to receive(:new).with( + "stage.wepayapi.com", + 443 + ).and_return(http_client) + + allow(http_client).to receive(:read_timeout=).with(30) + allow(http_client).to receive(:use_ssl=).with(true) + allow(http_client).to receive(:request).with(http_post).and_return(http_response) + allow(http_client).to receive(:start).and_yield(http_client) + end + + it "returns response data" do + expect(subject.response).to eq({ 'response' => 'response' }) + end + end +end diff --git a/spec/wepay/client_spec.rb b/spec/wepay/client_spec.rb deleted file mode 100644 index 588f368..0000000 --- a/spec/wepay/client_spec.rb +++ /dev/null @@ -1,446 +0,0 @@ -require 'spec_helper' - -RSpec.describe WePay::Client do - - context "constants" do - it "returns the staging api endpoint" do - expect(described_class::STAGE_API_ENDPOINT).to eq('https://stage.wepayapi.com/v2') - end - - it "returns the staging ui endpoint" do - expect(described_class::STAGE_UI_ENDPOINT).to eq('https://stage.wepay.com/v2') - end - - it "returns the production api endpoint" do - expect(described_class::PRODUCTION_API_ENDPOINT).to eq('https://wepayapi.com/v2') - end - - it "returns the production ui endpoint" do - expect(described_class::PRODUCTION_UI_ENDPOINT).to eq('https://www.wepay.com/v2') - end - end - - context "an instance" do - subject do - described_class.new( - 'client_id', - 'client_secret' - ) - end - - describe "#initialize" do - it "returns a client" do - expect(subject).to be_a(described_class) - end - end - - describe "#api_endpoint" do - context "for non-production environments" do - subject do - described_class.new( - 'client_id', - 'client_secret', - true - ) - end - - it "returns the stage api endpoint" do - expect(subject.api_endpoint).to eq('https://stage.wepayapi.com/v2') - end - end - - context "for production environments" do - subject do - described_class.new( - 'client_id', - 'client_secret', - false - ) - end - - it "returns the production api endpoint" do - expect(subject.api_endpoint).to eq('https://wepayapi.com/v2') - end - end - end - - describe "#api_version" do - context "when no version is given" do - it "returns nothing" do - expect(subject.api_version).to eq('') - end - end - - context "when a version is given" do - subject do - described_class.new( - 'client_id', - 'client_secret', - true, - 1 - ) - end - - it "returns the version" do - expect(subject.api_version).to eq('1') - end - end - end - - describe "#client_id" do - it "returns the client id" do - expect(subject.client_id).to eq('client_id') - end - end - - describe "#client_secret" do - it "returns the client secret" do - expect(subject.client_secret).to eq('client_secret') - end - end - - describe "#ui_endpoint" do - context "for non-production environments" do - subject do - described_class.new( - 'client_id', - 'client_secret', - true - ) - end - - it "returns the staging ui endpoint" do - expect(subject.ui_endpoint).to eq('https://stage.wepay.com/v2') - end - end - - context "for production environments" do - subject do - described_class.new( - 'client_id', - 'client_secret', - false - ) - end - - it "returns the production ui endpoint" do - expect(subject.ui_endpoint).to eq('https://www.wepay.com/v2') - end - end - end - - describe "#call" do - let(:post_request) { double('net::http::post') } - let(:post_client) { double('net::http') } - let(:post_response) { double('net::http::response') } - - context "making a non-production request" do - subject do - described_class.new( - 'client_id', - 'client_secret' - ) - end - - before do - allow(Net::HTTP::Post).to receive(:new).with( - '/v2/app', - { - 'Content-Type' => 'application/json', - 'User-Agent' => 'WePay Ruby SDK' - } - ).and_return(post_request) - - allow(post_request).to receive(:add_field).with('Authorization', 'Bearer ') - allow(post_request).to receive(:add_field).with('Api-Version', '') - - allow(Net::HTTP).to receive(:new).with( - 'stage.wepayapi.com', - 443 - ).and_return(post_client) - - allow(post_client).to receive(:read_timeout=).with(30) - allow(post_client).to receive(:use_ssl=).with(true) - allow(post_client).to receive(:start).and_return(post_response) - - allow(post_response).to receive(:body).and_return({ status: 200 }.to_json) - end - - it "makes a staging request" do - expect(subject.call('/app')).to eq('status' => 200) - end - end - - context "making a production request" do - subject do - described_class.new( - 'client_id', - 'client_secret', - false - ) - end - - before do - allow(Net::HTTP::Post).to receive(:new).with( - '/v2/app', - { - 'Content-Type' => 'application/json', - 'User-Agent' => 'WePay Ruby SDK' - } - ).and_return(post_request) - - allow(post_request).to receive(:add_field).with('Authorization', 'Bearer ') - allow(post_request).to receive(:add_field).with('Api-Version', '') - - allow(Net::HTTP).to receive(:new).with( - 'wepayapi.com', - 443 - ).and_return(post_client) - - allow(post_client).to receive(:read_timeout=).with(30) - allow(post_client).to receive(:use_ssl=).with(true) - allow(post_client).to receive(:start).and_return(post_response) - - allow(post_response).to receive(:body).and_return({ status: 200 }.to_json) - end - - it "makes a production request" do - expect(subject.call('/app')).to eq('status' => 200) - end - end - - context "making a naked path api call" do - subject do - described_class.new( - 'client_id', - 'client_secret' - ) - end - - before do - allow(Net::HTTP::Post).to receive(:new).with( - '/v2/app', - { - 'Content-Type' => 'application/json', - 'User-Agent' => 'WePay Ruby SDK' - } - ).and_return(post_request) - - allow(post_request).to receive(:add_field).with('Authorization', 'Bearer ') - allow(post_request).to receive(:add_field).with('Api-Version', '') - - allow(Net::HTTP).to receive(:new).with( - 'stage.wepayapi.com', - 443 - ).and_return(post_client) - - allow(post_client).to receive(:read_timeout=).with(30) - allow(post_client).to receive(:use_ssl=).with(true) - allow(post_client).to receive(:start).and_return(post_response) - - allow(post_response).to receive(:body).and_return({ status: 200 }.to_json) - end - - it "resolves to the correct request path" do - expect(subject.call('app')).to eq('status' => 200) - end - end - - context "making a versioned api call" do - subject do - described_class.new( - 'client_id', - 'client_secret', - true, - 1 - ) - end - - before do - allow(Net::HTTP::Post).to receive(:new).with( - '/v2/app', - { - 'Content-Type' => 'application/json', - 'User-Agent' => 'WePay Ruby SDK' - } - ).and_return(post_request) - - allow(post_request).to receive(:add_field).with('Authorization', 'Bearer ') - allow(post_request).to receive(:add_field).with('Api-Version', '1') - - allow(Net::HTTP).to receive(:new).with( - 'stage.wepayapi.com', - 443 - ).and_return(post_client) - - allow(post_client).to receive(:read_timeout=).with(30) - allow(post_client).to receive(:use_ssl=).with(true) - allow(post_client).to receive(:start).and_return(post_response) - - allow(post_response).to receive(:body).and_return({ status: 200 }.to_json) - end - - it "sets the API version" do - expect(subject.call('/app')).to eq('status' => 200) - end - end - - context "making an authorized api call" do - subject do - described_class.new( - 'client_id', - 'client_secret' - ) - end - - before do - allow(Net::HTTP::Post).to receive(:new).with( - '/v2/app', - { - 'Content-Type' => 'application/json', - 'User-Agent' => 'WePay Ruby SDK' - } - ).and_return(post_request) - - allow(post_request).to receive(:add_field).with('Authorization', 'Bearer access_token') - allow(post_request).to receive(:add_field).with('Api-Version', '') - - allow(Net::HTTP).to receive(:new).with( - 'stage.wepayapi.com', - 443 - ).and_return(post_client) - - allow(post_client).to receive(:read_timeout=).with(30) - allow(post_client).to receive(:use_ssl=).with(true) - allow(post_client).to receive(:start).and_return(post_response) - - allow(post_response).to receive(:body).and_return({ status: 200 }.to_json) - end - - it "sets the access token" do - expect(subject.call('/app','access_token')).to eq('status' => 200) - end - end - - context "making an api call with a payload" do - subject do - described_class.new( - 'client_id', - 'client_secret' - ) - end - - before do - allow(Net::HTTP::Post).to receive(:new).with( - '/v2/app', - { - 'Content-Type' => 'application/json', - 'User-Agent' => 'WePay Ruby SDK' - } - ).and_return(post_request) - - allow(post_request).to receive(:body=).with({ app_id: 1 }.to_json) - allow(post_request).to receive(:add_field).with('Authorization', 'Bearer access_token') - allow(post_request).to receive(:add_field).with('Api-Version', '') - - allow(Net::HTTP).to receive(:new).with( - 'stage.wepayapi.com', - 443 - ).and_return(post_client) - - allow(post_client).to receive(:read_timeout=).with(30) - allow(post_client).to receive(:use_ssl=).with(true) - allow(post_client).to receive(:start).and_return(post_response) - - allow(post_response).to receive(:body).and_return({ status: 200 }.to_json) - end - it "sets the post body" do - expect(subject.call('/app','access_token', app_id: 1)).to eq('status' => 200) - end - end - end - - describe "#oauth2_authorize_url" do - context "with default params" do - it "returns the oauth2 authorize url" do - expect( - subject.oauth2_authorize_url( - 'https://www.wepay.com' - ) - ).to eq( - 'https://stage.wepay.com/v2/oauth2/authorize?client_id=client_id&redirect_uri=https://www.wepay.com&scope=manage_accounts,collect_payments,view_user,send_money,preapprove_payments,manage_subscriptions') - end - end - - context "with custom params" do - it "returns the oauth2 authorize url" do - expect( - subject.oauth2_authorize_url( - 'https://www.wepay.com', - 'user@host.com', - 'username', - 'manage_accounts', - 'US United States' - ) - ).to eq( - 'https://stage.wepay.com/v2/oauth2/authorize?client_id=client_id&redirect_uri=https://www.wepay.com&scope=manage_accounts&user_name=username&user_email=user%40host.com&user_country=US+United+States') - end - end - end - - describe "#oauth2_token" do - let(:post_request) { double('net::http::post') } - let(:post_client) { double('net::http') } - let(:post_response) { double('net::http::response') } - - subject do - described_class.new( - 'client_id', - 'client_secret', - false - ) - end - - before do - allow(Net::HTTP::Post).to receive(:new).with( - '/v2/oauth2/token', - { - 'Content-Type' => 'application/json', - 'User-Agent' => 'WePay Ruby SDK' - } - ).and_return(post_request) - - allow(post_request).to receive(:body=).with( - { - client_id: 'client_id', - client_secret: 'client_secret', - redirect_uri: 'redirect.wepay.com', - code: 'code' - }.to_json - ) - allow(post_request).to receive(:add_field).with('Authorization', 'Bearer ') - allow(post_request).to receive(:add_field).with('Api-Version', '') - - allow(Net::HTTP).to receive(:new).with( - 'wepayapi.com', - 443 - ).and_return(post_client) - - allow(post_client).to receive(:read_timeout=).with(30) - allow(post_client).to receive(:use_ssl=).with(true) - allow(post_client).to receive(:start).and_return(post_response) - - allow(post_response).to receive(:body).and_return({ access_token: 'abc123' }.to_json) - end - - it "returns a oauth2 token response" do - expect( - subject.oauth2_token( - 'code', - 'redirect.wepay.com', - ) - ).to eq('access_token' => 'abc123') - end - end - end -end