-
-
Notifications
You must be signed in to change notification settings - Fork 76
Set source payment_type in cc hosted fields #79
Conversation
Dang. The Travis push hook gets triggered because I accidentally pushed my branch to this repo instead of my fork. I deleted the branch while the build was running. This is why I failed. But the PR hook triggered the correct build of my Fork and this passes 😅 |
Closing and reopen, to get correct Travis result |
It turns out that Travis seem to have mayor caching issues. Sorry about that. Please ignore the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To my knowledge, the "card_type" and friends should be delegated to Braintree, via the delegate call there. As for determining what type of payment the source represents, the source already includes several query methods for that, are those not working in this scenario?
expect(page).to have_content("Your order has been processed successfully") | ||
end | ||
|
||
it "sets the payment type of source to CreditCard" do | ||
expect(SolidusPaypalBraintree::Source.last.payment_type).to eq('CreditCard') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This assertion does not belong in feature spec. Could we do this at the unit test level? We should probably also avoid using last unless we're sure the system is only creating the one record.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should probably also avoid using last unless we're sure the system is only creating the one record.
We know exactly that in this scenario the last source is the one we created through the controller. I had a version where I explicitly tested that we only have on source here, but this seemed overkill for me. I can add this if you want to be extra save.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Feature tests should only ever test user interactions. Since there is no reliable way to ensure that the user can see that this is the case, it should not be included in a feature test. If there was a way for a user to use the site in a manner that would cause a failure, we could test that here. Otherwise this should be tested in a controller/request test.
@@ -10,7 +10,7 @@ class Engine < Rails::Engine | |||
|
|||
initializer "register_solidus_paypal_braintree_gateway", after: "spree.register.payment_methods" do |app| | |||
app.config.spree.payment_methods << SolidusPaypalBraintree::Gateway | |||
Spree::PermittedAttributes.source_attributes << :nonce | |||
Spree::PermittedAttributes.source_attributes.concat [:nonce, :payment_type] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This value isn't whitelisted and can be modified by users. Further if we know the payment type in advance, we should probably avoid requiring it to be set in the form.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This value isn't whitelisted and can be modified by users.
I need to whitelist it, otherwise I can not pass it into the controller from the view where the value needs top be set, as we don't know the type upfront.
Further if we know the payment type in advance, we should probably avoid requiring it to be set in the form.
We don't know the type upfront. I didn't find any code that guarantees this. Maybe you can point me to?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I need to whitelist it, otherwise I can not pass it into the controller from the view where the value needs top be set, as we don't know the type upfront.
I meant that the value isn't whitelisted. I can insert "lol" into this field and it would save correctly. We should probably add an inclusion validation to the model to prevent this.
We don't know the type upfront. I didn't find any code that guarantees this. Maybe you can point me to?
Once we have the token, payment_method.braintree.payment_method.find(source.token).is_a?(Braintree::PaypalAccount)
As we only use this for display purposes, I no longer think that's worth doing though.
The For PayPal and ApplePay sources we set these value explicitly, but not for credit card payments. My pending spec e4e4589 shows that this is currently not working. This is why I chose to test this integrative in stead of on the unit level. The model is polymorphic (not in the AR kind of things, but I plays multiple roles). We can't know the value upfront, so testing it on the unit level did not really made sense for me, we need to set this value while creating it through the controller. Therefore passing it along the params from the view - where we exactly know what type the source is - made the most sense for me. Any idea how to approach this differently? |
The query methods depend on the |
The "best solution" would be to actually provide three payment sources (and even gateways). Then we wouldn't even need to have these query methods at all. I will provide a RFC for this, as I think now that we have a common interface for payment sources in Solidus 2.2 we should start to embrace it. For older stores its an easy back port we would ship with this gem. |
@@ -10,7 +10,7 @@ class Engine < Rails::Engine | |||
|
|||
initializer "register_solidus_paypal_braintree_gateway", after: "spree.register.payment_methods" do |app| | |||
app.config.spree.payment_methods << SolidusPaypalBraintree::Gateway | |||
Spree::PermittedAttributes.source_attributes << :nonce | |||
Spree::PermittedAttributes.source_attributes.concat [:nonce, :payment_type] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I need to whitelist it, otherwise I can not pass it into the controller from the view where the value needs top be set, as we don't know the type upfront.
I meant that the value isn't whitelisted. I can insert "lol" into this field and it would save correctly. We should probably add an inclusion validation to the model to prevent this.
We don't know the type upfront. I didn't find any code that guarantees this. Maybe you can point me to?
Once we have the token, payment_method.braintree.payment_method.find(source.token).is_a?(Braintree::PaypalAccount)
As we only use this for display purposes, I no longer think that's worth doing though.
expect(page).to have_content("Your order has been processed successfully") | ||
end | ||
|
||
it "sets the payment type of source to CreditCard" do | ||
expect(SolidusPaypalBraintree::Source.last.payment_type).to eq('CreditCard') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Feature tests should only ever test user interactions. Since there is no reliable way to ensure that the user can see that this is the case, it should not be included in a feature test. If there was a way for a user to use the site in a manner that would cause a failure, we could test that here. Otherwise this should be tested in a controller/request test.
RE: the query methods, yes you're correct. Missed that, I should have looked at that more closely. I'm 👍 on including on the form, would just prefer the test moved. As for the RFC can you hold off? We've had a couple discussions on that architecture and have the beginnings of a plan in place. If you're interested we can chat about it, but I don't want to duplicate efforts here. |
Build fixes waits for #84 |
reversible do |dir| | ||
dir.up do | ||
SolidusPaypalBraintree::Source.where(payment_type: nil). | ||
update_all(payment_type: 'CreditCard') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn't accurate. Is there a scenario that generated nil payment_types in the past?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. All credit card payments. PayPal and ApplePay payments have this value set via JS tailored params.
Although this isn't accurate it's the only thing we can do about, besides not doing this at all of course.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, fair point.
@@ -10,6 +10,8 @@ class Source < ApplicationRecord | |||
|
|||
belongs_to :customer, class_name: "SolidusPaypalBraintree::Customer" | |||
|
|||
validates :payment_type, presence: true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
validates :payment_type, inclusion: [PAYPAL, APPLE_PAY, CREDIT_CARD]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very good point! 👌🏻
When submiting credit cards in checkout the payment_type is missing. We should validates it’s presence on the source model.
Our javascript takes care of setting this column in the params during checkout for PayPal and ApplePay payments, but not for credit card payments. The easiest way is to send the value is from within the hosted fields form.
The payment_type is used to differ payment soruces. I.E. lots of query methods uses this column to decide which kind of payment this source instance is, even presentor methods uss this clumn to look up the human name in the translation files by this column. Therefore it is necessary to validate its presence and add a not null constrained in the database.
@tvdeyen Have some vcr issues no idea why though :/ |
@Senjai yeah. Pretty strange. Only for Solidus < 2.1. Even locally. Investigated this morning, but gave up because lack of time. |
Closed in favor of #91 thanks thomas. |
The hosted fields does not set the payment_type value on credit card
sources. This leads to sources which type can’t be recognized anymore.