summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMattia Roccoberton <mattiaroccoberton@nebulab.it>2021-03-05 10:25:59 +0100
committerAlessandro Desantis <desa.alessandro@gmail.com>2021-03-28 10:41:04 +0200
commit7559ec52ced8ab0894ba2f3159036c4450477116 (patch)
treeee751ed3effbd507964a39ba85e86d1f931d4bd4
parent5f14a24c9e9c1a701077d3ac56a632583e51742b (diff)
Accept shipping address, bill address and payment attributes
We also check for the existence of the payment source class in order to avoid a runtime error.
-rw-r--r--app/controllers/solidus_subscriptions/api/v1/subscriptions_controller.rb40
-rw-r--r--config/locales/en.yml1
-rw-r--r--spec/requests/api/v1/subscriptions_spec.rb64
3 files changed, 100 insertions, 5 deletions
diff --git a/app/controllers/solidus_subscriptions/api/v1/subscriptions_controller.rb b/app/controllers/solidus_subscriptions/api/v1/subscriptions_controller.rb
index 0ff53ba..0ac694d 100644
--- a/app/controllers/solidus_subscriptions/api/v1/subscriptions_controller.rb
+++ b/app/controllers/solidus_subscriptions/api/v1/subscriptions_controller.rb
@@ -8,13 +8,21 @@ module SolidusSubscriptions
def create
store = params[:store_id].nil? ? ::Spree::Store.default : ::Spree::Store.find(id: params[:store_id])
- attributes = subscription_params.merge(user: current_api_user, store: store)
- subscription = SolidusSubscriptions::Subscription.new(attributes)
+ attributes = create_subscription_params.merge(user: current_api_user, store: store)
+ acceptable_payment_details = update_payment_attributes(attributes)
- if subscription.save
- render json: subscription.to_json(include: [:line_items, :shipping_address, :billing_address])
+ if acceptable_payment_details
+ subscription = SolidusSubscriptions::Subscription.new(attributes)
+
+ if subscription.save
+ render json: subscription.to_json(include: [:line_items, :shipping_address, :billing_address])
+ else
+ render json: subscription.errors.to_json, status: :unprocessable_entity
+ end
else
- render json: subscription.errors.to_json, status: :unprocessable_entity
+ error_message = I18n.t('solidus_subscriptions.subscription.invalid_payment_details')
+
+ render json: { payment_source_type: [error_message] }.to_json, status: :unprocessable_entity
end
end
@@ -55,6 +63,14 @@ module SolidusSubscriptions
authorize! action_name.to_sym, @subscription, subscription_guest_token
end
+ def create_subscription_params
+ params.require(:subscription).permit(
+ %i[payment_method_id payment_source_id shipping_address_id billing_address_id] |
+ SolidusSubscriptions.configuration.subscription_attributes |
+ [line_items_attributes: line_item_attributes]
+ )
+ end
+
def subscription_params
params.require(:subscription).permit(SolidusSubscriptions.configuration.subscription_attributes | [
line_items_attributes: line_item_attributes,
@@ -64,6 +80,20 @@ module SolidusSubscriptions
def line_item_attributes
SolidusSubscriptions.configuration.subscription_line_item_attributes - [:subscribable_id] + [:id]
end
+
+ def update_payment_attributes(attributes)
+ return true if attributes[:payment_method_id].blank? && attributes[:payment_source_id].blank?
+
+ payment_method = ::Spree::PaymentMethod.find_by(id: attributes[:payment_method_id])
+ payment_source = payment_method&.payment_source_class&.find_by(id: attributes[:payment_source_id])
+ if payment_method && payment_source
+ attributes[:payment_method] = payment_method
+ attributes[:payment_source] = payment_source
+ true
+ else
+ false
+ end
+ end
end
end
end
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 79d400a..9f26f8b 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -8,6 +8,7 @@ en:
solidus_subscriptions:
subscription:
actionable_date: "Actionable Date"
+ invalid_payment_details: Invalid payment method or source
installment_details:
out_of_stock: >
This installment could not be processed because of insufficient
diff --git a/spec/requests/api/v1/subscriptions_spec.rb b/spec/requests/api/v1/subscriptions_spec.rb
index 3031f14..02fa6d5 100644
--- a/spec/requests/api/v1/subscriptions_spec.rb
+++ b/spec/requests/api/v1/subscriptions_spec.rb
@@ -35,6 +35,70 @@ RSpec.describe '/api/v1/subscriptions' do
expect(response.status).to eq(422)
end
end
+
+ context 'when valid payment attributes are provided' do
+ # rubocop:disable RSpec/MultipleExpectations
+ it 'creates the subscription using the specified payment' do
+ user = create(:user, &:generate_spree_api_key!)
+ payment_source = create(:credit_card, user: user)
+ payment_params = { payment_method_id: payment_source.payment_method.id, payment_source_id: payment_source.id }
+
+ expect(user.wallet.default_wallet_payment_source).to be_nil
+ expect do
+ post(
+ api_v1_subscriptions_path,
+ params: { subscription: { interval_length: 7 }.merge(payment_params) },
+ headers: { 'Authorization' => "Bearer #{user.spree_api_key}" },
+ )
+ end.to change(SolidusSubscriptions::Subscription, :count).from(0).to(1)
+ expect(SolidusSubscriptions::Subscription.last).to have_attributes(payment_params)
+ end
+ # rubocop:enable RSpec/MultipleExpectations
+ end
+
+ # rubocop:disable RSpec/MultipleExpectations
+ context 'when an invalid payment method is provided' do
+ it "doesn't create the subscription and responds with 422 Unprocessable Entity" do
+ user = create(:user, &:generate_spree_api_key!)
+ payment_source = create(:credit_card)
+ payment_params = { payment_source_id: payment_source.id }
+
+ expect do
+ post(
+ api_v1_subscriptions_path,
+ params: { subscription: { interval_length: 7 }.merge(payment_params) },
+ headers: { 'Authorization' => "Bearer #{user.spree_api_key}" },
+ )
+ end.not_to change(SolidusSubscriptions::Subscription, :count)
+
+ error_message = I18n.t('solidus_subscriptions.subscription.invalid_payment_details')
+ response_body = JSON.parse(response.body)
+ expect(response_body).to eq('payment_source_type' => [error_message])
+ expect(response.status).to eq(422)
+ end
+ end
+
+ context 'when an invalid payment source is provided' do
+ it "doesn't create the subscription and responds with 422 Unprocessable Entity" do
+ user = create(:user, &:generate_spree_api_key!)
+ payment_source = create(:credit_card)
+ payment_params = { payment_method_id: payment_source.payment_method.id }
+
+ expect do
+ post(
+ api_v1_subscriptions_path,
+ params: { subscription: { interval_length: 7 }.merge(payment_params) },
+ headers: { 'Authorization' => "Bearer #{user.spree_api_key}" },
+ )
+ end.not_to change(SolidusSubscriptions::Subscription, :count)
+
+ error_message = I18n.t('solidus_subscriptions.subscription.invalid_payment_details')
+ response_body = JSON.parse(response.body)
+ expect(response_body).to eq('payment_source_type' => [error_message])
+ expect(response.status).to eq(422)
+ end
+ end
+ # rubocop:enable RSpec/MultipleExpectations
end
describe 'PATCH /:id' do