From 34f85e9cbe5e02a0534927e00e5e718afe1bb900 Mon Sep 17 00:00:00 2001 From: Robot Date: Fri, 17 May 2024 15:59:53 +0000 Subject: [PATCH 1/3] Changes from gocardless/gocardless-pro-ruby-template@1270f620323edfc0e45fb145cbf45a92fd5d0529 --- lib/gocardless_pro.rb | 3 ++ lib/gocardless_pro/client.rb | 5 +++ lib/gocardless_pro/resources/logo.rb | 38 ++++++++++++++++++++ lib/gocardless_pro/services/logos_service.rb | 28 +++++++++++++++ spec/resources/logo_spec.rb | 11 ++++++ spec/services/logos_service_spec.rb | 11 ++++++ 6 files changed, 96 insertions(+) create mode 100644 lib/gocardless_pro/resources/logo.rb create mode 100644 lib/gocardless_pro/services/logos_service.rb create mode 100644 spec/resources/logo_spec.rb create mode 100644 spec/services/logos_service_spec.rb diff --git a/lib/gocardless_pro.rb b/lib/gocardless_pro.rb index ba22201..a7d02cf 100644 --- a/lib/gocardless_pro.rb +++ b/lib/gocardless_pro.rb @@ -84,6 +84,9 @@ module GoCardlessPro require_relative 'gocardless_pro/resources/institution' require_relative 'gocardless_pro/services/institutions_service' +require_relative 'gocardless_pro/resources/logo' +require_relative 'gocardless_pro/services/logos_service' + require_relative 'gocardless_pro/resources/mandate' require_relative 'gocardless_pro/services/mandates_service' diff --git a/lib/gocardless_pro/client.rb b/lib/gocardless_pro/client.rb index 4e8d8eb..3a41511 100644 --- a/lib/gocardless_pro/client.rb +++ b/lib/gocardless_pro/client.rb @@ -78,6 +78,11 @@ def institutions @institutions ||= Services::InstitutionsService.new(@api_service) end + # Access to the service for logo to make API calls + def logos + @logos ||= Services::LogosService.new(@api_service) + end + # Access to the service for mandate to make API calls def mandates @mandates ||= Services::MandatesService.new(@api_service) diff --git a/lib/gocardless_pro/resources/logo.rb b/lib/gocardless_pro/resources/logo.rb new file mode 100644 index 0000000..e171847 --- /dev/null +++ b/lib/gocardless_pro/resources/logo.rb @@ -0,0 +1,38 @@ +# +# This client is automatically generated from a template and JSON schema definition. +# See https://github.com/gocardless/gocardless-pro-ruby#contributing before editing. +# + +require 'uri' + +module GoCardlessPro + # A module containing classes for each of the resources in the GC Api + module Resources + # Represents an instance of a logo resource returned from the API + + # Logos are image uploads that, when associated with a creditor, are shown + # on the [billing request flow](#billing-requests-billing-request-flows) + # payment pages. + class Logo + attr_reader :id + + # Initialize a logo resource instance + # @param object [Hash] an object returned from the API + def initialize(object, response = nil) + @object = object + + @id = object['id'] + @response = response + end + + def api_response + ApiResponse.new(@response) + end + + # Provides the logo resource as a hash of all its readable attributes + def to_h + @object + end + end + end +end diff --git a/lib/gocardless_pro/services/logos_service.rb b/lib/gocardless_pro/services/logos_service.rb new file mode 100644 index 0000000..e72f978 --- /dev/null +++ b/lib/gocardless_pro/services/logos_service.rb @@ -0,0 +1,28 @@ +require_relative './base_service' + +# encoding: utf-8 +# +# This client is automatically generated from a template and JSON schema definition. +# See https://github.com/gocardless/gocardless-pro-ruby#contributing before editing. +# + +module GoCardlessPro + module Services + # Service for making requests to the Logo endpoints + class LogosService < BaseService + private + + # Unenvelope the response of the body using the service's `envelope_key` + # + # @param body [Hash] + def unenvelope_body(body) + body[envelope_key] || body['data'] + end + + # return the key which API responses will envelope data under + def envelope_key + 'logos' + end + end + end +end diff --git a/spec/resources/logo_spec.rb b/spec/resources/logo_spec.rb new file mode 100644 index 0000000..8e1709d --- /dev/null +++ b/spec/resources/logo_spec.rb @@ -0,0 +1,11 @@ +require 'spec_helper' + +describe GoCardlessPro::Resources::Logo do + let(:client) do + GoCardlessPro::Client.new( + access_token: 'SECRET_TOKEN' + ) + end + + let(:response_headers) { { 'Content-Type' => 'application/json' } } +end diff --git a/spec/services/logos_service_spec.rb b/spec/services/logos_service_spec.rb new file mode 100644 index 0000000..4e5f097 --- /dev/null +++ b/spec/services/logos_service_spec.rb @@ -0,0 +1,11 @@ +require 'spec_helper' + +describe GoCardlessPro::Services::LogosService do + let(:client) do + GoCardlessPro::Client.new( + access_token: 'SECRET_TOKEN' + ) + end + + let(:response_headers) { { 'Content-Type' => 'application/json' } } +end From bf82ab1d0791cd799e3845862c77e57a3ee7a068 Mon Sep 17 00:00:00 2001 From: Robot Date: Tue, 28 May 2024 12:50:14 +0000 Subject: [PATCH 2/3] Changes from gocardless/gocardless-pro-ruby-template@7d42c692d543d5a1308b0cb2435d1e3bd94c7d93 --- lib/gocardless_pro.rb | 3 + lib/gocardless_pro/client.rb | 5 + lib/gocardless_pro/resources/payer_theme.rb | 36 +++++ lib/gocardless_pro/services/logos_service.rb | 20 +++ .../services/payer_themes_service.rb | 49 +++++++ spec/resources/logo_spec.rb | 102 +++++++++++++ spec/resources/payer_theme_spec.rb | 113 +++++++++++++++ spec/services/logos_service_spec.rb | 125 ++++++++++++++++ spec/services/payer_themes_service_spec.rb | 136 ++++++++++++++++++ 9 files changed, 589 insertions(+) create mode 100644 lib/gocardless_pro/resources/payer_theme.rb create mode 100644 lib/gocardless_pro/services/payer_themes_service.rb create mode 100644 spec/resources/payer_theme_spec.rb create mode 100644 spec/services/payer_themes_service_spec.rb diff --git a/lib/gocardless_pro.rb b/lib/gocardless_pro.rb index a7d02cf..bab1ca2 100644 --- a/lib/gocardless_pro.rb +++ b/lib/gocardless_pro.rb @@ -105,6 +105,9 @@ module GoCardlessPro require_relative 'gocardless_pro/resources/payer_authorisation' require_relative 'gocardless_pro/services/payer_authorisations_service' +require_relative 'gocardless_pro/resources/payer_theme' +require_relative 'gocardless_pro/services/payer_themes_service' + require_relative 'gocardless_pro/resources/payment' require_relative 'gocardless_pro/services/payments_service' diff --git a/lib/gocardless_pro/client.rb b/lib/gocardless_pro/client.rb index 3a41511..2cdaa77 100644 --- a/lib/gocardless_pro/client.rb +++ b/lib/gocardless_pro/client.rb @@ -113,6 +113,11 @@ def payer_authorisations @payer_authorisations ||= Services::PayerAuthorisationsService.new(@api_service) end + # Access to the service for payer_theme to make API calls + def payer_themes + @payer_themes ||= Services::PayerThemesService.new(@api_service) + end + # Access to the service for payment to make API calls def payments @payments ||= Services::PaymentsService.new(@api_service) diff --git a/lib/gocardless_pro/resources/payer_theme.rb b/lib/gocardless_pro/resources/payer_theme.rb new file mode 100644 index 0000000..95e8ce2 --- /dev/null +++ b/lib/gocardless_pro/resources/payer_theme.rb @@ -0,0 +1,36 @@ +# +# This client is automatically generated from a template and JSON schema definition. +# See https://github.com/gocardless/gocardless-pro-ruby#contributing before editing. +# + +require 'uri' + +module GoCardlessPro + # A module containing classes for each of the resources in the GC Api + module Resources + # Represents an instance of a payer_theme resource returned from the API + + # Custom colour themes for payment pages and customer notifications. + class PayerTheme + attr_reader :id + + # Initialize a payer_theme resource instance + # @param object [Hash] an object returned from the API + def initialize(object, response = nil) + @object = object + + @id = object['id'] + @response = response + end + + def api_response + ApiResponse.new(@response) + end + + # Provides the payer_theme resource as a hash of all its readable attributes + def to_h + @object + end + end + end +end diff --git a/lib/gocardless_pro/services/logos_service.rb b/lib/gocardless_pro/services/logos_service.rb index e72f978..09addf7 100644 --- a/lib/gocardless_pro/services/logos_service.rb +++ b/lib/gocardless_pro/services/logos_service.rb @@ -10,6 +10,26 @@ module GoCardlessPro module Services # Service for making requests to the Logo endpoints class LogosService < BaseService + # Creates a new logo associated with a creditor. If a creditor already has a + # logo, this will update the existing logo linked to the creditor. + # Example URL: /branding/logos + # @param options [Hash] parameters as a hash, under a params key. + def create_for_creditor(options = {}) + path = '/branding/logos' + + params = options.delete(:params) || {} + options[:params] = {} + options[:params][envelope_key] = params + + options[:retry_failures] = true + + response = make_request(:post, path, options) + + return if response.body.nil? + + Resources::Logo.new(unenvelope_body(response.body), response) + end + private # Unenvelope the response of the body using the service's `envelope_key` diff --git a/lib/gocardless_pro/services/payer_themes_service.rb b/lib/gocardless_pro/services/payer_themes_service.rb new file mode 100644 index 0000000..290d845 --- /dev/null +++ b/lib/gocardless_pro/services/payer_themes_service.rb @@ -0,0 +1,49 @@ +require_relative './base_service' + +# encoding: utf-8 +# +# This client is automatically generated from a template and JSON schema definition. +# See https://github.com/gocardless/gocardless-pro-ruby#contributing before editing. +# + +module GoCardlessPro + module Services + # Service for making requests to the PayerTheme endpoints + class PayerThemesService < BaseService + # Creates a new payer theme associated with a creditor. If a creditor already + # has payer themes, this will update the existing payer theme linked to the + # creditor. + # Example URL: /branding/payer_themes + # @param options [Hash] parameters as a hash, under a params key. + def create_for_creditor(options = {}) + path = '/branding/payer_themes' + + params = options.delete(:params) || {} + options[:params] = {} + options[:params][envelope_key] = params + + options[:retry_failures] = true + + response = make_request(:post, path, options) + + return if response.body.nil? + + Resources::PayerTheme.new(unenvelope_body(response.body), response) + end + + private + + # Unenvelope the response of the body using the service's `envelope_key` + # + # @param body [Hash] + def unenvelope_body(body) + body[envelope_key] || body['data'] + end + + # return the key which API responses will envelope data under + def envelope_key + 'payer_themes' + end + end + end +end diff --git a/spec/resources/logo_spec.rb b/spec/resources/logo_spec.rb index 8e1709d..4e20624 100644 --- a/spec/resources/logo_spec.rb +++ b/spec/resources/logo_spec.rb @@ -8,4 +8,106 @@ end let(:response_headers) { { 'Content-Type' => 'application/json' } } + + describe '#create' do + subject(:post_create_response) { client.logos.create_for_creditor(params: new_resource) } + context 'with a valid request' do + let(:new_resource) do + { + + 'id' => 'id-input', + } + end + + before do + stub_request(:post, %r{.*api.gocardless.com/branding/logos}). + with( + body: { + 'logos' => { + + 'id' => 'id-input', + }, + } + ). + to_return( + body: { + 'logos' => + + { + + 'id' => 'id-input', + }, + + }.to_json, + headers: response_headers + ) + end + + it 'creates and returns the resource' do + expect(post_create_response).to be_a(GoCardlessPro::Resources::Logo) + end + end + + context 'with a request that returns a validation error' do + let(:new_resource) { {} } + + before do + stub_request(:post, %r{.*api.gocardless.com/branding/logos}).to_return( + body: { + error: { + type: 'validation_failed', + code: 422, + errors: [ + { message: 'test error message', field: 'test_field' }, + ], + }, + }.to_json, + headers: response_headers, + status: 422 + ) + end + + it 'throws the correct error' do + expect { post_create_response }.to raise_error(GoCardlessPro::ValidationError) + end + end + + context 'with a request that returns an idempotent creation conflict error' do + let(:id) { 'ID123' } + + let(:new_resource) do + { + + 'id' => 'id-input', + } + end + + let!(:post_stub) do + stub_request(:post, %r{.*api.gocardless.com/branding/logos}).to_return( + body: { + error: { + type: 'invalid_state', + code: 409, + errors: [ + { + message: 'A resource has already been created with this idempotency key', + reason: 'idempotent_creation_conflict', + links: { + conflicting_resource_id: id, + }, + }, + ], + }, + }.to_json, + headers: response_headers, + status: 409 + ) + end + + it 'raises an InvalidStateError' do + expect { post_create_response }.to raise_error(GoCardlessPro::InvalidStateError) + expect(post_stub).to have_been_requested + end + end + end end diff --git a/spec/resources/payer_theme_spec.rb b/spec/resources/payer_theme_spec.rb new file mode 100644 index 0000000..f5d0381 --- /dev/null +++ b/spec/resources/payer_theme_spec.rb @@ -0,0 +1,113 @@ +require 'spec_helper' + +describe GoCardlessPro::Resources::PayerTheme do + let(:client) do + GoCardlessPro::Client.new( + access_token: 'SECRET_TOKEN' + ) + end + + let(:response_headers) { { 'Content-Type' => 'application/json' } } + + describe '#create' do + subject(:post_create_response) { client.payer_themes.create_for_creditor(params: new_resource) } + context 'with a valid request' do + let(:new_resource) do + { + + 'id' => 'id-input', + } + end + + before do + stub_request(:post, %r{.*api.gocardless.com/branding/payer_themes}). + with( + body: { + 'payer_themes' => { + + 'id' => 'id-input', + }, + } + ). + to_return( + body: { + 'payer_themes' => + + { + + 'id' => 'id-input', + }, + + }.to_json, + headers: response_headers + ) + end + + it 'creates and returns the resource' do + expect(post_create_response).to be_a(GoCardlessPro::Resources::PayerTheme) + end + end + + context 'with a request that returns a validation error' do + let(:new_resource) { {} } + + before do + stub_request(:post, %r{.*api.gocardless.com/branding/payer_themes}).to_return( + body: { + error: { + type: 'validation_failed', + code: 422, + errors: [ + { message: 'test error message', field: 'test_field' }, + ], + }, + }.to_json, + headers: response_headers, + status: 422 + ) + end + + it 'throws the correct error' do + expect { post_create_response }.to raise_error(GoCardlessPro::ValidationError) + end + end + + context 'with a request that returns an idempotent creation conflict error' do + let(:id) { 'ID123' } + + let(:new_resource) do + { + + 'id' => 'id-input', + } + end + + let!(:post_stub) do + stub_request(:post, %r{.*api.gocardless.com/branding/payer_themes}).to_return( + body: { + error: { + type: 'invalid_state', + code: 409, + errors: [ + { + message: 'A resource has already been created with this idempotency key', + reason: 'idempotent_creation_conflict', + links: { + conflicting_resource_id: id, + }, + }, + ], + }, + }.to_json, + headers: response_headers, + status: 409 + ) + end + + it 'raises an InvalidStateError' do + expect { post_create_response }.to raise_error(GoCardlessPro::InvalidStateError) + expect(post_stub).to have_been_requested + end + end + end +end diff --git a/spec/services/logos_service_spec.rb b/spec/services/logos_service_spec.rb index 4e5f097..e8dcded 100644 --- a/spec/services/logos_service_spec.rb +++ b/spec/services/logos_service_spec.rb @@ -8,4 +8,129 @@ end let(:response_headers) { { 'Content-Type' => 'application/json' } } + + describe '#create' do + subject(:post_create_response) { client.logos.create_for_creditor(params: new_resource) } + context 'with a valid request' do + let(:new_resource) do + { + + 'id' => 'id-input', + } + end + + before do + stub_request(:post, %r{.*api.gocardless.com/branding/logos}). + with( + body: { + 'logos' => { + + 'id' => 'id-input', + }, + } + ). + to_return( + body: { + 'logos' => + + { + + 'id' => 'id-input', + }, + + }.to_json, + headers: response_headers + ) + end + + it 'creates and returns the resource' do + expect(post_create_response).to be_a(GoCardlessPro::Resources::Logo) + end + + describe 'retry behaviour' do + before { allow_any_instance_of(GoCardlessPro::Request).to receive(:sleep) } + + it 'retries timeouts' do + stub = stub_request(:post, %r{.*api.gocardless.com/branding/logos}). + to_timeout.then.to_return({ status: 200, headers: response_headers }) + + post_create_response + expect(stub).to have_been_requested.twice + end + + it 'retries 5XX errors' do + stub = stub_request(:post, %r{.*api.gocardless.com/branding/logos}). + to_return({ status: 502, + headers: { 'Content-Type' => 'text/html' }, + body: 'Response from Cloudflare' }). + then.to_return({ status: 200, headers: response_headers }) + + post_create_response + expect(stub).to have_been_requested.twice + end + end + end + + context 'with a request that returns a validation error' do + let(:new_resource) { {} } + + before do + stub_request(:post, %r{.*api.gocardless.com/branding/logos}).to_return( + body: { + error: { + type: 'validation_failed', + code: 422, + errors: [ + { message: 'test error message', field: 'test_field' }, + ], + }, + }.to_json, + headers: response_headers, + status: 422 + ) + end + + it 'throws the correct error' do + expect { post_create_response }.to raise_error(GoCardlessPro::ValidationError) + end + end + + context 'with a request that returns an idempotent creation conflict error' do + let(:id) { 'ID123' } + + let(:new_resource) do + { + + 'id' => 'id-input', + } + end + + let!(:post_stub) do + stub_request(:post, %r{.*api.gocardless.com/branding/logos}).to_return( + body: { + error: { + type: 'invalid_state', + code: 409, + errors: [ + { + message: 'A resource has already been created with this idempotency key', + reason: 'idempotent_creation_conflict', + links: { + conflicting_resource_id: id, + }, + }, + ], + }, + }.to_json, + headers: response_headers, + status: 409 + ) + end + + it 'raises an InvalidStateError' do + expect { post_create_response }.to raise_error(GoCardlessPro::InvalidStateError) + expect(post_stub).to have_been_requested + end + end + end end diff --git a/spec/services/payer_themes_service_spec.rb b/spec/services/payer_themes_service_spec.rb new file mode 100644 index 0000000..905a8f2 --- /dev/null +++ b/spec/services/payer_themes_service_spec.rb @@ -0,0 +1,136 @@ +require 'spec_helper' + +describe GoCardlessPro::Services::PayerThemesService do + let(:client) do + GoCardlessPro::Client.new( + access_token: 'SECRET_TOKEN' + ) + end + + let(:response_headers) { { 'Content-Type' => 'application/json' } } + + describe '#create' do + subject(:post_create_response) { client.payer_themes.create_for_creditor(params: new_resource) } + context 'with a valid request' do + let(:new_resource) do + { + + 'id' => 'id-input', + } + end + + before do + stub_request(:post, %r{.*api.gocardless.com/branding/payer_themes}). + with( + body: { + 'payer_themes' => { + + 'id' => 'id-input', + }, + } + ). + to_return( + body: { + 'payer_themes' => + + { + + 'id' => 'id-input', + }, + + }.to_json, + headers: response_headers + ) + end + + it 'creates and returns the resource' do + expect(post_create_response).to be_a(GoCardlessPro::Resources::PayerTheme) + end + + describe 'retry behaviour' do + before { allow_any_instance_of(GoCardlessPro::Request).to receive(:sleep) } + + it 'retries timeouts' do + stub = stub_request(:post, %r{.*api.gocardless.com/branding/payer_themes}). + to_timeout.then.to_return({ status: 200, headers: response_headers }) + + post_create_response + expect(stub).to have_been_requested.twice + end + + it 'retries 5XX errors' do + stub = stub_request(:post, %r{.*api.gocardless.com/branding/payer_themes}). + to_return({ status: 502, + headers: { 'Content-Type' => 'text/html' }, + body: 'Response from Cloudflare' }). + then.to_return({ status: 200, headers: response_headers }) + + post_create_response + expect(stub).to have_been_requested.twice + end + end + end + + context 'with a request that returns a validation error' do + let(:new_resource) { {} } + + before do + stub_request(:post, %r{.*api.gocardless.com/branding/payer_themes}).to_return( + body: { + error: { + type: 'validation_failed', + code: 422, + errors: [ + { message: 'test error message', field: 'test_field' }, + ], + }, + }.to_json, + headers: response_headers, + status: 422 + ) + end + + it 'throws the correct error' do + expect { post_create_response }.to raise_error(GoCardlessPro::ValidationError) + end + end + + context 'with a request that returns an idempotent creation conflict error' do + let(:id) { 'ID123' } + + let(:new_resource) do + { + + 'id' => 'id-input', + } + end + + let!(:post_stub) do + stub_request(:post, %r{.*api.gocardless.com/branding/payer_themes}).to_return( + body: { + error: { + type: 'invalid_state', + code: 409, + errors: [ + { + message: 'A resource has already been created with this idempotency key', + reason: 'idempotent_creation_conflict', + links: { + conflicting_resource_id: id, + }, + }, + ], + }, + }.to_json, + headers: response_headers, + status: 409 + ) + end + + it 'raises an InvalidStateError' do + expect { post_create_response }.to raise_error(GoCardlessPro::InvalidStateError) + expect(post_stub).to have_been_requested + end + end + end +end From 8e0df9b42a556989726a8331e40f4c6be923f2af Mon Sep 17 00:00:00 2001 From: Robot Date: Tue, 28 May 2024 13:08:58 +0000 Subject: [PATCH 3/3] Changes from gocardless/gocardless-pro-ruby-template@d78c1a4f13040e318cdbb90b5805754b8a701127 --- lib/gocardless_pro/client.rb | 2 +- lib/gocardless_pro/version.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/gocardless_pro/client.rb b/lib/gocardless_pro/client.rb index 2cdaa77..f50b0ae 100644 --- a/lib/gocardless_pro/client.rb +++ b/lib/gocardless_pro/client.rb @@ -228,7 +228,7 @@ def default_options 'User-Agent' => "#{user_agent}", 'Content-Type' => 'application/json', 'GoCardless-Client-Library' => 'gocardless-pro-ruby', - 'GoCardless-Client-Version' => '2.55.0', + 'GoCardless-Client-Version' => '2.56.0', }, } end diff --git a/lib/gocardless_pro/version.rb b/lib/gocardless_pro/version.rb index aa1d9fb..01b5abe 100644 --- a/lib/gocardless_pro/version.rb +++ b/lib/gocardless_pro/version.rb @@ -3,5 +3,5 @@ module GoCardlessPro module GoCardlessPro # Current version of the GC gem - VERSION = '2.55.0' + VERSION = '2.56.0' end