From fc0cca2210dcd78f4554fea0dc76af712c05922c Mon Sep 17 00:00:00 2001 From: Mohamed ABDELLANI Date: Wed, 31 May 2023 12:34:47 +0100 Subject: [PATCH 01/16] remove legacy checkout view --- .../checkout/accordion_controller.js.coffee | 22 ------- .../checkout/billing_controller.js.coffee | 12 ---- .../checkout/checkout_controller.js.coffee | 43 ------------- .../checkout/country_controller.js.coffee | 8 --- .../checkout/details_controller.js.coffee | 24 -------- .../checkout/payment_controller.js.coffee | 19 ------ .../checkout/shipping_controller.js.coffee | 11 ---- app/helpers/injection_helper.rb | 10 --- app/helpers/terms_and_conditions_helper.rb | 10 --- .../checkout/_accordion_heading.html.haml | 17 ------ .../_all_terms_and_conditions.html.haml | 4 -- app/views/checkout/_already_ordered.html.haml | 2 - app/views/checkout/_authentication.html.haml | 19 ------ app/views/checkout/_billing.html.haml | 46 -------------- app/views/checkout/_details.html.haml | 33 ---------- app/views/checkout/_form.html.haml | 22 ------- app/views/checkout/_payment.html.haml | 37 ----------- .../_platform_terms_of_service.html.haml | 10 --- app/views/checkout/_shipping.html.haml | 61 ------------------- .../checkout/_shipping_ship_address.html.haml | 28 --------- app/views/checkout/_summary.html.haml | 34 ----------- .../checkout/_terms_and_conditions.html.haml | 3 - app/views/checkout/edit.html.haml | 36 ----------- .../spree/checkout/payment/_check.html.erb | 0 .../spree/checkout/payment/_gateway.html.haml | 27 -------- .../spree/checkout/payment/_paypal.html.haml | 1 - .../spree/checkout/payment/_stripe.html.haml | 22 ------- .../checkout/payment/_stripe_sca.html.haml | 22 ------- 28 files changed, 583 deletions(-) delete mode 100644 app/assets/javascripts/darkswarm/controllers/checkout/accordion_controller.js.coffee delete mode 100644 app/assets/javascripts/darkswarm/controllers/checkout/billing_controller.js.coffee delete mode 100644 app/assets/javascripts/darkswarm/controllers/checkout/checkout_controller.js.coffee delete mode 100644 app/assets/javascripts/darkswarm/controllers/checkout/country_controller.js.coffee delete mode 100644 app/assets/javascripts/darkswarm/controllers/checkout/details_controller.js.coffee delete mode 100644 app/assets/javascripts/darkswarm/controllers/checkout/payment_controller.js.coffee delete mode 100644 app/assets/javascripts/darkswarm/controllers/checkout/shipping_controller.js.coffee delete mode 100644 app/views/checkout/_accordion_heading.html.haml delete mode 100644 app/views/checkout/_all_terms_and_conditions.html.haml delete mode 100644 app/views/checkout/_already_ordered.html.haml delete mode 100644 app/views/checkout/_authentication.html.haml delete mode 100644 app/views/checkout/_billing.html.haml delete mode 100644 app/views/checkout/_details.html.haml delete mode 100644 app/views/checkout/_form.html.haml delete mode 100644 app/views/checkout/_payment.html.haml delete mode 100644 app/views/checkout/_platform_terms_of_service.html.haml delete mode 100644 app/views/checkout/_shipping.html.haml delete mode 100644 app/views/checkout/_shipping_ship_address.html.haml delete mode 100644 app/views/checkout/_summary.html.haml delete mode 100644 app/views/checkout/_terms_and_conditions.html.haml delete mode 100644 app/views/checkout/edit.html.haml delete mode 100644 app/views/spree/checkout/payment/_check.html.erb delete mode 100644 app/views/spree/checkout/payment/_gateway.html.haml delete mode 100644 app/views/spree/checkout/payment/_paypal.html.haml delete mode 100644 app/views/spree/checkout/payment/_stripe.html.haml delete mode 100644 app/views/spree/checkout/payment/_stripe_sca.html.haml diff --git a/app/assets/javascripts/darkswarm/controllers/checkout/accordion_controller.js.coffee b/app/assets/javascripts/darkswarm/controllers/checkout/accordion_controller.js.coffee deleted file mode 100644 index d10f4be1b9f..00000000000 --- a/app/assets/javascripts/darkswarm/controllers/checkout/accordion_controller.js.coffee +++ /dev/null @@ -1,22 +0,0 @@ -angular.module('Darkswarm').controller "AccordionCtrl", ($scope, localStorageService, $timeout, $document, CurrentHub) -> - $scope.accordionSections = ["details", "billing", "shipping", "payment"] - $scope.accordion = { details: true, billing: true, shipping: true, payment: true } - - $scope.show = (section) -> - $scope.accordion[section] = true - - $scope.scrollTo = (section) -> - # Scrolling is confused by our position:fixed top bar - add an offset to scroll - # to the correct location, plus 5px buffer - offset_height = $("nav.top-bar").height() + 5 - $document.scrollTo($("##{section}"), offset_height, 400) - - $scope.$on 'purchaseFormInvalid', (event, form) -> - # Scroll to first invalid section - for section in $scope.accordionSections - if not form[section].$valid - $scope.show section - $timeout -> - $scope.scrollTo(section) - , 50 - break diff --git a/app/assets/javascripts/darkswarm/controllers/checkout/billing_controller.js.coffee b/app/assets/javascripts/darkswarm/controllers/checkout/billing_controller.js.coffee deleted file mode 100644 index 4e7332be278..00000000000 --- a/app/assets/javascripts/darkswarm/controllers/checkout/billing_controller.js.coffee +++ /dev/null @@ -1,12 +0,0 @@ -angular.module('Darkswarm').controller "BillingCtrl", ($scope, $timeout, $controller) -> - angular.extend this, $controller('FieldsetMixin', {$scope: $scope}) - - $scope.name = "billing" - $scope.nextPanel = "shipping" - - $scope.summary = -> - [$scope.order.bill_address.address1, - $scope.order.bill_address.city, - $scope.order.bill_address.zipcode] - - $timeout $scope.onTimeout diff --git a/app/assets/javascripts/darkswarm/controllers/checkout/checkout_controller.js.coffee b/app/assets/javascripts/darkswarm/controllers/checkout/checkout_controller.js.coffee deleted file mode 100644 index 294a0c4d104..00000000000 --- a/app/assets/javascripts/darkswarm/controllers/checkout/checkout_controller.js.coffee +++ /dev/null @@ -1,43 +0,0 @@ -angular.module('Darkswarm').controller "CheckoutCtrl", ($scope, localStorageService, Checkout, CurrentUser, CurrentHub, $http) -> - $scope.Checkout = Checkout - $scope.submitted = false - - # Bind to local storage - $scope.fieldsToBind = ["bill_address", "email", "payment_method_id", "shipping_method_id", "ship_address"] - prefix = "order_#{Checkout.order.id}#{CurrentUser.id or ""}#{CurrentHub.hub.id}" - - for field in $scope.fieldsToBind - localStorageService.bind $scope, "Checkout.order.#{field}", Checkout.order[field], "#{prefix}_#{field}" - - localStorageService.bind $scope, "Checkout.ship_address_same_as_billing", true, "#{prefix}_sameasbilling" - localStorageService.bind $scope, "Checkout.default_bill_address", false, "#{prefix}_defaultasbilladdress" - localStorageService.bind $scope, "Checkout.default_ship_address", false, "#{prefix}_defaultasshipaddress" - - $scope.order = Checkout.order # Ordering is important - $scope.secrets = Checkout.secrets - - $scope.enabled = !!CurrentUser.id? - - $scope.purchase = (event, form) -> - event.preventDefault() - $scope.formdata = form - $scope.submitted = true - - if CurrentUser.id - $scope.validateForm(form) - else - $scope.ensureUserIsGuest() - - $scope.validateForm = -> - if $scope.formdata.$valid - $scope.Checkout.purchase() - else - $scope.$broadcast 'purchaseFormInvalid', $scope.formdata - - $scope.ensureUserIsGuest = (callback = null) -> - $http.post("/user/registered_email", {email: $scope.order.email}) - .then (response)-> - window.CableReady.perform(response.data) - .catch -> - $scope.validateForm() if $scope.submitted - callback() if callback diff --git a/app/assets/javascripts/darkswarm/controllers/checkout/country_controller.js.coffee b/app/assets/javascripts/darkswarm/controllers/checkout/country_controller.js.coffee deleted file mode 100644 index 101469eac99..00000000000 --- a/app/assets/javascripts/darkswarm/controllers/checkout/country_controller.js.coffee +++ /dev/null @@ -1,8 +0,0 @@ -angular.module('Darkswarm').controller "CountryCtrl", ($scope, availableCountries) -> - - $scope.countries = availableCountries - - $scope.countriesById = $scope.countries.reduce (obj, country) -> - obj[country.id] = country - obj - , {} diff --git a/app/assets/javascripts/darkswarm/controllers/checkout/details_controller.js.coffee b/app/assets/javascripts/darkswarm/controllers/checkout/details_controller.js.coffee deleted file mode 100644 index 26bc7837431..00000000000 --- a/app/assets/javascripts/darkswarm/controllers/checkout/details_controller.js.coffee +++ /dev/null @@ -1,24 +0,0 @@ -angular.module('Darkswarm').controller "DetailsCtrl", ($scope, $timeout, $http, CurrentUser, SpreeUser, $controller) -> - angular.extend this, $controller('FieldsetMixin', {$scope: $scope}) - - $scope.name = "details" - $scope.nextPanel = "billing" - - $scope.login_or_next = (event) -> - event.preventDefault() - unless CurrentUser.id - $scope.ensureUserIsGuest($scope.next) - return - - $scope.next() - - $scope.summary = -> - [$scope.fullName(), - $scope.order.email, - $scope.order.bill_address.phone] - - $scope.fullName = -> - [$scope.order.bill_address.firstname ? null, - $scope.order.bill_address.lastname ? null].join(" ").trim() - - $timeout $scope.onTimeout diff --git a/app/assets/javascripts/darkswarm/controllers/checkout/payment_controller.js.coffee b/app/assets/javascripts/darkswarm/controllers/checkout/payment_controller.js.coffee deleted file mode 100644 index b95bb283382..00000000000 --- a/app/assets/javascripts/darkswarm/controllers/checkout/payment_controller.js.coffee +++ /dev/null @@ -1,19 +0,0 @@ -angular.module('Darkswarm').controller "PaymentCtrl", ($scope, $timeout, savedCreditCards, Dates, $controller) -> - angular.extend this, $controller('FieldsetMixin', {$scope: $scope}) - - $scope.savedCreditCards = savedCreditCards - $scope.name = "payment" - $scope.months = Dates.months - $scope.years = Dates.years - - $scope.secrets.card_month = "1" - $scope.secrets.card_year = moment().year() - - for card in savedCreditCards when card.is_default - $scope.secrets.selected_card = card.id - break - - $scope.summary = -> - [$scope.Checkout.paymentMethod()?.name] - - $timeout $scope.onTimeout diff --git a/app/assets/javascripts/darkswarm/controllers/checkout/shipping_controller.js.coffee b/app/assets/javascripts/darkswarm/controllers/checkout/shipping_controller.js.coffee deleted file mode 100644 index 58aaad55740..00000000000 --- a/app/assets/javascripts/darkswarm/controllers/checkout/shipping_controller.js.coffee +++ /dev/null @@ -1,11 +0,0 @@ -angular.module('Darkswarm').controller "ShippingCtrl", ($scope, $timeout, ShippingMethods, $controller) -> - angular.extend this, $controller('FieldsetMixin', {$scope: $scope}) - - $scope.ShippingMethods = ShippingMethods - $scope.name = "shipping" - $scope.nextPanel = "payment" - - $scope.summary = -> - [$scope.Checkout.shippingMethod()?.name] - - $timeout $scope.onTimeout diff --git a/app/helpers/injection_helper.rb b/app/helpers/injection_helper.rb index d9edfd87a40..8cea6426f45 100644 --- a/app/helpers/injection_helper.rb +++ b/app/helpers/injection_helper.rb @@ -89,16 +89,6 @@ def inject_current_order_cycle render partial: "json/injection_ams", locals: { name: "orderCycleData", json: json } end - def inject_available_shipping_methods - inject_json_array "shippingMethods", available_shipping_methods, - Api::ShippingMethodSerializer, current_order: current_order - end - - def inject_available_payment_methods - inject_json_array "paymentMethods", available_payment_methods, - Api::PaymentMethodSerializer, current_order: current_order - end - def inject_taxons inject_json_array "taxons", Spree::Taxon.all.to_a, Api::TaxonSerializer end diff --git a/app/helpers/terms_and_conditions_helper.rb b/app/helpers/terms_and_conditions_helper.rb index c30b57164bd..0b848433cc5 100644 --- a/app/helpers/terms_and_conditions_helper.rb +++ b/app/helpers/terms_and_conditions_helper.rb @@ -6,16 +6,6 @@ def link_to_platform_terms rel: "noopener") end - def render_terms_and_conditions - if platform_terms_required? && distributor_terms_required? - render("checkout/all_terms_and_conditions") - elsif platform_terms_required? - render "checkout/platform_terms_of_service" - elsif distributor_terms_required? - render "checkout/terms_and_conditions" - end - end - def any_terms_required?(distributor) TermsOfService.required?(distributor) end diff --git a/app/views/checkout/_accordion_heading.html.haml b/app/views/checkout/_accordion_heading.html.haml deleted file mode 100644 index 443897b2b52..00000000000 --- a/app/views/checkout/_accordion_heading.html.haml +++ /dev/null @@ -1,17 +0,0 @@ -%accordion-heading - .row - .small-8.medium-9.columns - %em - %small - {{ summary() | printArray }} - .small-4.medium-3.columns.text-right - %span.accordion-up - %em - %small - = t :checkout_hide - %i.ofn-i_053-point-up - %span.accordion-down - %em - %small - = t :checkout_expand - %i.ofn-i_052-point-down diff --git a/app/views/checkout/_all_terms_and_conditions.html.haml b/app/views/checkout/_all_terms_and_conditions.html.haml deleted file mode 100644 index 6af53262845..00000000000 --- a/app/views/checkout/_all_terms_and_conditions.html.haml +++ /dev/null @@ -1,4 +0,0 @@ -%p - %input{ type: 'checkbox', id: 'accept_terms', ng: { model: "terms_and_conditions_accepted", init: "terms_and_conditions_accepted = #{all_terms_and_conditions_already_accepted?}" } } - %label.small{for: "accept_terms"} - = t('.message_html', terms_and_conditions_link: link_to( t(".terms_and_conditions"), current_order.distributor.terms_and_conditions, target: '_blank'), tos_link: link_to_platform_terms) diff --git a/app/views/checkout/_already_ordered.html.haml b/app/views/checkout/_already_ordered.html.haml deleted file mode 100644 index 3e435913628..00000000000 --- a/app/views/checkout/_already_ordered.html.haml +++ /dev/null @@ -1,2 +0,0 @@ -%p.alert-box.info - = t '.message_html', cart: link_to(t('.cart'), "#{main_app.cart_path}#bought-products") diff --git a/app/views/checkout/_authentication.html.haml b/app/views/checkout/_authentication.html.haml deleted file mode 100644 index d3362107a80..00000000000 --- a/app/views/checkout/_authentication.html.haml +++ /dev/null @@ -1,19 +0,0 @@ -%section{"ng-show" => "!enabled"} - .row - .small-12.columns.text-center - %h3.pad-top - = t :checkout_headline - .row.pad-top{ "data-controller": "login-modal" } - - if guest_checkout_allowed? - .small-5.columns.text-center - %button.primary.expand{ "data-action": "click->login-modal#call" } - = t :label_login - .small-2.columns.text-center - %p.pad-top= "#{t :action_or}" - .small-5.columns.text-center - %button.neutral-btn.dark.expand{"ng-click" => "enabled = true"} - = t :checkout_as_guest - - else - .small-6.columns.small-centered - %button.primary.expand{ "data-action": "click->login-modal#call" } - = t :label_login diff --git a/app/views/checkout/_billing.html.haml b/app/views/checkout/_billing.html.haml deleted file mode 100644 index 9be3ed6e450..00000000000 --- a/app/views/checkout/_billing.html.haml +++ /dev/null @@ -1,46 +0,0 @@ -%fieldset#billing - %ng-form{"ng-controller" => "BillingCtrl", name: "billing"} - - %h5{"ng-class" => "{valid: billing.$valid, dirty: billing.$dirty || submitted}"} - %span.right - %label.label.round.alert.right - %i.ofn-i_009-close - %label.label.round.success.right - %i.ofn-i_051-check-big - = t :checkout_billing - - %accordion-group{"is-open" => "accordion.billing", - "ng-class" => "{valid: billing.$valid, open: accordion.billing}"} - = render 'checkout/accordion_heading' - - - if spree_current_user - .small-12.columns - %label - %input{type: :checkbox, "ng-model" => "Checkout.default_bill_address"} - = t :checkout_default_bill_address - - %div{ "ng-controller" => "CountryCtrl" } - = f.fields_for :bill_address, @order.bill_address do |ba| - .row - .small-12.columns - = validated_input t(:address), "order.bill_address.address1", "ofn-focus" => "accordion['billing']" - .row - .small-12.columns - = validated_input t(:address2), "order.bill_address.address2", required: false - .row - .small-6.columns - = validated_input t(:city), "order.bill_address.city" - - .small-6.columns - = validated_select t(:state), "order.bill_address.state_id", {}, {"ng-options" => "s.id as s.name for s in countriesById[order.bill_address.country_id].states"} - .row - .small-6.columns - = validated_input t(:postcode), "order.bill_address.zipcode" - - .small-6.columns.right - = validated_select t(:country), "order.bill_address.country_id", {}, {"ng-init" => "order.bill_address.country_id = order.bill_address.country_id || #{DefaultCountry.id}", "ng-options" => "c.id as c.name for c in countries"} - - .row - .small-12.columns.text-right - %button.primary{"ng-disabled" => "billing.$invalid", "ng-click" => "next($event)"} - = t :next diff --git a/app/views/checkout/_details.html.haml b/app/views/checkout/_details.html.haml deleted file mode 100644 index c5761ffd095..00000000000 --- a/app/views/checkout/_details.html.haml +++ /dev/null @@ -1,33 +0,0 @@ -%fieldset#details - %ng-form{"ng-controller" => "DetailsCtrl", name: "details"} - - %h5{"ng-class" => "{valid: details.$valid, dirty: details.$dirty || submitted}"} - %span.right - %label.label.round.alert.right - %i.ofn-i_009-close - %label.label.round.success.right - %i.ofn-i_051-check-big - = t :checkout_details - - %accordion-group{"is-open" => "accordion.details", - "ng-class" => "{valid: details.$valid, open: accordion.details}"} - = render 'checkout/accordion_heading' - - .row - .small-6.columns - = validated_input t(:first_name), "order.bill_address.firstname" - .small-6.columns - = validated_input t(:last_name), "order.bill_address.lastname" - - .row - .small-6.columns - = validated_input t(:email), 'order.email', type: "email", inputmode: "email", "ofn-focus" => "accordion['details']" - - .small-6.columns - = validated_input t(:phone), 'order.bill_address.phone', inputmode: "tel" - - .row - .small-12.columns.text-right - %button.primary{"ng-disabled" => "details.$invalid", "ng-click" => "login_or_next($event)"} - = t :next - diff --git a/app/views/checkout/_form.html.haml b/app/views/checkout/_form.html.haml deleted file mode 100644 index 84601fd4105..00000000000 --- a/app/views/checkout/_form.html.haml +++ /dev/null @@ -1,22 +0,0 @@ -- content_for :injection_data do - = inject_available_shipping_methods - = inject_available_payment_methods - = inject_saved_credit_cards - -= form_for current_order, - url: order_path(current_order), - html: {name: "checkout", - id: "checkout_form", - novalidate: true, - "ng-submit" => "purchase($event, checkout)"} do |f| - - = render "checkout/details", f: f - = render "checkout/billing", f: f - = render "checkout/shipping", f: f - = render "checkout/payment", f: f - = render "checkout/already_ordered", f: f if show_bought_items? - = render_terms_and_conditions - %p - %button.button.primary{ type: :submit, ng: { disabled: "terms_and_conditions_accepted == false || platform_tos_accepted == false" } } - = t :checkout_send - / {{ checkout.$valid }} diff --git a/app/views/checkout/_payment.html.haml b/app/views/checkout/_payment.html.haml deleted file mode 100644 index cd4b7c50098..00000000000 --- a/app/views/checkout/_payment.html.haml +++ /dev/null @@ -1,37 +0,0 @@ -%fieldset#payment - %ng-form{"ng-controller" => "PaymentCtrl", name: "payment"} - - %h5{"ng-class" => "{valid: payment.$valid, dirty: payment.$dirty || submitted}"} - %span.right - %label.label.round.alert.right - %i.ofn-i_009-close - %label.label.round.success.right - %i.ofn-i_051-check-big - = t :checkout_payment - - %accordion-group{"is-open" => "accordion.payment", - "ng-class" => "{valid: payment.$valid, open: accordion.payment}"} - = render 'checkout/accordion_heading' - - .row - .small-12.medium-12.large-6.columns - - available_payment_methods.each do |method| - .row - .small-12.columns - %label - = radio_button_tag "order[payments_attributes][][payment_method_id]", method.id, false, - required: true, - name: "order.payment_method_id", - "ng-model" => "order.payment_method_id" - = method.name - = "(#{payment_method_price(method, @order)})" - - %small.error.medium.input-text{"ng-show" => "!fieldValid('order.payment_method_id')"} - = "{{ fieldErrors('order.payment_method_id') }}" - - .row{"ng-if" => "order.payment_method_id == #{method.id}"} - .small-12.columns - = render partial: "spree/checkout/payment/#{method.method_type}", :locals => { :payment_method => method } - .small-12.medium-12.large-6.columns - #distributor_address.panel{"ng-show" => "Checkout.paymentMethod().description"} - %span.pre-wrap {{ Checkout.paymentMethod().description }} diff --git a/app/views/checkout/_platform_terms_of_service.html.haml b/app/views/checkout/_platform_terms_of_service.html.haml deleted file mode 100644 index 884ca0f865a..00000000000 --- a/app/views/checkout/_platform_terms_of_service.html.haml +++ /dev/null @@ -1,10 +0,0 @@ -%p - %input{ type: "checkbox", - id: "accept_terms", - ng: { - model: "platform_tos_accepted", - init: "platform_tos_accepted = #{platform_tos_already_accepted?}" - } - } - %label.small{for: "accept_terms"} - = t(".message_html", tos_link: link_to_platform_terms) diff --git a/app/views/checkout/_shipping.html.haml b/app/views/checkout/_shipping.html.haml deleted file mode 100644 index 1e50dc33f83..00000000000 --- a/app/views/checkout/_shipping.html.haml +++ /dev/null @@ -1,61 +0,0 @@ -%fieldset#shipping - %ng-form{"ng-controller" => "ShippingCtrl", name: "shipping"} - - %h5{"ng-class" => "{valid: shipping.$valid, dirty: shipping.$dirty || submitted}"} - %span.right - %label.label.round.alert.right - %i.ofn-i_009-close - %label.label.round.success.right - %i.ofn-i_051-check-big - = t :checkout_shipping - - %accordion-group{"is-open" => "accordion.shipping", - "ng-class" => "{valid: shipping.$valid, open: accordion.shipping}"} - = render 'checkout/accordion_heading' - - .small-12.columns.medium-12.columns.large-6.columns - %label{"ng-repeat" => "method in ShippingMethods.shipping_methods | orderBy: 'name'"} - %input{type: :radio, - required: true, - name: "order.shipping_method_id", - "ng-value" => "method.id", - "ng-model" => "order.shipping_method_id"} - {{ method.name }} - %em.light{"ng-show" => "!method.price || method.price == 0"} - = "(#{t(:checkout_method_free)})" - %em.light{"ng-hide" => "!method.price || method.price == 0"} - ({{ method.price | localizeCurrency }}) - - %small.error.medium.input-text{"ng-show" => "!fieldValid('order.shipping_method_id')"} - = "{{ fieldErrors('order.shipping_method_id') }}" - - %label{"ng-if" => "Checkout.requireShipAddress()"} - %input{type: :checkbox, "ng-model" => "Checkout.ship_address_same_as_billing"} - = t :checkout_address_same - - - if spree_current_user - %label{"ng-if" => "Checkout.requireShipAddress()"} - %input{type: :checkbox, "ng-model" => "Checkout.default_ship_address"} - = t :checkout_default_ship_address - - .small-12.columns.medium-12.columns.large-6.columns - #distributor_address.panel{"ng-show" => "Checkout.shippingMethod().description"} - %span{ style: "white-space: pre-wrap;" }{{ Checkout.shippingMethod().description }} - %br/ - %br/ - - if @order.order_cycle.pickup_time_for(@order.distributor) - = t :checkout_ready_for - = @order.order_cycle.pickup_time_for(@order.distributor) - - = f.fields_for :ship_address, @order.ship_address do |sa| - = render 'checkout/shipping_ship_address' - - .row - .small-12.columns - %label{ for: 'order_special_instructions'}= t(:checkout_instructions) - = f.text_area :special_instructions, size: "60x4", "ng-model" => "order.special_instructions" - - .row - .small-12.columns.text-right - %button.primary{"ng-disabled" => "shipping.$invalid", "ng-click" => "next($event)"} - = t :next diff --git a/app/views/checkout/_shipping_ship_address.html.haml b/app/views/checkout/_shipping_ship_address.html.haml deleted file mode 100644 index ac399d544ca..00000000000 --- a/app/views/checkout/_shipping_ship_address.html.haml +++ /dev/null @@ -1,28 +0,0 @@ -.small-12.columns - #ship_address{"ng-if" => "Checkout.requireShipAddress()"} - %div.visible{"ng-if" => "!Checkout.ship_address_same_as_billing"} - %div{ "ng-controller" => "CountryCtrl" } - .row - .small-6.columns - = validated_input t(:first_name), "order.ship_address.firstname", "ofn-focus" => "accordion['shipping']" - .small-6.columns - = validated_input t(:last_name), "order.ship_address.lastname" - .row - .small-12.columns - = validated_input t(:address), "order.ship_address.address1" - .row - .small-12.columns - = validated_input t(:address2), "order.ship_address.address2", required: false - .row - .small-6.columns - = validated_input t(:city), "order.ship_address.city" - .small-6.columns - = validated_select t(:state), "order.ship_address.state_id", {}, {"ng-options" => "s.id as s.name for s in countriesById[order.ship_address.country_id].states"} - .row - .small-6.columns - = validated_input t(:postcode), "order.ship_address.zipcode" - .small-6.columns.right - = validated_select t(:country), "order.ship_address.country_id", {}, {"ng-init" => "order.ship_address.country_id = order.ship_address.country_id || #{DefaultCountry.id}", "ng-options" => "c.id as c.name for c in countries"} - .row - .small-6.columns - = validated_input t(:phone), "order.ship_address.phone" diff --git a/app/views/checkout/_summary.html.haml b/app/views/checkout/_summary.html.haml deleted file mode 100644 index 64103efd473..00000000000 --- a/app/views/checkout/_summary.html.haml +++ /dev/null @@ -1,34 +0,0 @@ -%orderdetails - = form_for current_order, url: "#", html: {"ng-submit" => "purchase($event, checkout)"} do |f| - %fieldset - %legend - = t :checkout_your_order - %table - %tr.subtotal - %th - = t :checkout_cart_total - %td.cart-total.text-right= display_checkout_subtotal(@order) - - - checkout_adjustments_for(current_order, exclude: [:shipping, :payment, :line_item]).each do |adjustment| - %tr.adjustment - %th= adjustment.label - %td.text-right= adjustment.display_amount.to_html - - %tr.shipping - %th - = t :checkout_shipping_price - %td.text-right {{ Checkout.shippingPrice() | localizeCurrency }} - - %tr.transaction-fee - %th - = t :payment_method_fee - %td.text-right {{ Checkout.paymentPrice() | localizeCurrency }} - - %tr.total - %th - = t :checkout_total_price - %td.text-right {{ Checkout.cartTotal() | localizeCurrency }} - - //= f.submit "Purchase", class: "button", "ofn-focus" => "accordion['payment']" - %a.button.secondary{href: main_app.cart_url} - = t :checkout_back_to_cart diff --git a/app/views/checkout/_terms_and_conditions.html.haml b/app/views/checkout/_terms_and_conditions.html.haml deleted file mode 100644 index 608a0fd66b8..00000000000 --- a/app/views/checkout/_terms_and_conditions.html.haml +++ /dev/null @@ -1,3 +0,0 @@ -%p - %input{ type: 'checkbox', id: 'accept_terms', ng: { model: "terms_and_conditions_accepted", init: "terms_and_conditions_accepted=#{terms_and_conditions_already_accepted?}" } } - %label.small{for: "accept_terms"}= t('.message_html', terms_and_conditions_link: link_to( t( '.link_text' ), current_order.distributor.terms_and_conditions, target: '_blank')) diff --git a/app/views/checkout/edit.html.haml b/app/views/checkout/edit.html.haml deleted file mode 100644 index 085542294a7..00000000000 --- a/app/views/checkout/edit.html.haml +++ /dev/null @@ -1,36 +0,0 @@ -- content_for(:title) do - = t :checkout_title - -- content_for :injection_data do - = inject_enterprise_and_relatives - = inject_available_countries - -.darkswarm.footer-pad - - content_for :order_cycle_form do - %closing - = t :checkout_now - %p - = t :checkout_order_ready - %strong - = pickup_time current_order_cycle - - - content_for :ordercycle_sidebar do - .show-for-large-up.large-4.columns - = render partial: "shopping_shared/order_cycles" - - = render partial: "shopping_shared/header" - - .sub-header.show-for-medium-down - = render partial: "shopping_shared/order_cycles" - - %accordion{"close-others" => "false"} - %checkout.row{"ng-controller" => "CheckoutCtrl"} - .small-12.medium-8.columns - - unless spree_current_user - = render partial: "checkout/authentication" - %div{"ng-show" => "enabled", "ng-controller" => "AccordionCtrl"} - = render partial: "checkout/form" - .small-12.medium-4.columns - = render partial: "checkout/summary" - -= render partial: "shared/footer" diff --git a/app/views/spree/checkout/payment/_check.html.erb b/app/views/spree/checkout/payment/_check.html.erb deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/app/views/spree/checkout/payment/_gateway.html.haml b/app/views/spree/checkout/payment/_gateway.html.haml deleted file mode 100644 index 0bcf038cb9b..00000000000 --- a/app/views/spree/checkout/payment/_gateway.html.haml +++ /dev/null @@ -1,27 +0,0 @@ -.row - .small-6.columns - %label - = t :first_name - -# Changing name not permitted by default (in checkout) - can be enabled by setting an allow_name_change variable in $scope - %input{type: :text, "ng-disabled" => "!allow_name_change", "ng-value" => "order.bill_address.firstname"} - - .small-6.columns - %label - = t :last_name - %input{type: :text, "ng-disabled" => "!allow_name_change", "ng-value" => "order.bill_address.lastname"} - - .small-6.columns - = validated_input t(:card_number), "secrets.card_number", maxlength: 19, autocomplete: "off" - .small-6.columns - = validated_input t(:card_securitycode), "secrets.card_verification_value" - -.row - .small-12.columns - %label{for: "secrets.card_month"} - = t :card_expiry_date - -.row - .small-6.columns - %select{"ng-model" => "secrets.card_month", "ng-options" => "currMonth.value as currMonth.key for currMonth in months", name: "secrets.card_month"} - .small-6.columns - %select{"ng-model" => "secrets.card_year", "ng-options" => "year for year in years", name: "secrets.card_year"} diff --git a/app/views/spree/checkout/payment/_paypal.html.haml b/app/views/spree/checkout/payment/_paypal.html.haml deleted file mode 100644 index 1cc8aa25a75..00000000000 --- a/app/views/spree/checkout/payment/_paypal.html.haml +++ /dev/null @@ -1 +0,0 @@ --# This file intentionally overrides the view in the spree_paypal_express gem diff --git a/app/views/spree/checkout/payment/_stripe.html.haml b/app/views/spree/checkout/payment/_stripe.html.haml deleted file mode 100644 index 2929b90d3ec..00000000000 --- a/app/views/spree/checkout/payment/_stripe.html.haml +++ /dev/null @@ -1,22 +0,0 @@ -- content_for :injection_data do - - if Stripe.publishable_key - :javascript - angular.module('Darkswarm').value("stripeObject", Stripe("#{Stripe.publishable_key}")) - -.row{ "ng-show" => "savedCreditCards.length > 0" } - .small-12.columns - %h6= t('.used_saved_card') - %select{ name: "selected_card", required: false, ng: { model: "secrets.selected_card", options: "card.id as card.formatted for card in savedCreditCards" } } - %option{ value: "" }= "{{ secrets.selected_card ? '#{t('.enter_new_card')}' : '#{t('.choose_one')}' }}" - - %h6{ ng: { if: '!secrets.selected_card' } } - = t('.or_enter_new_card') - -%div{ ng: { if: '!secrets.selected_card' } } - %stripe-elements - - - if spree_current_user - .row - .small-12.columns.text-right - = check_box_tag 'secrets.save_requested_by_customer', '1', false, 'ng-model' => 'secrets.save_requested_by_customer' - = label_tag 'secrets.save_requested_by_customer', t('.remember_this_card') diff --git a/app/views/spree/checkout/payment/_stripe_sca.html.haml b/app/views/spree/checkout/payment/_stripe_sca.html.haml deleted file mode 100644 index 2929b90d3ec..00000000000 --- a/app/views/spree/checkout/payment/_stripe_sca.html.haml +++ /dev/null @@ -1,22 +0,0 @@ -- content_for :injection_data do - - if Stripe.publishable_key - :javascript - angular.module('Darkswarm').value("stripeObject", Stripe("#{Stripe.publishable_key}")) - -.row{ "ng-show" => "savedCreditCards.length > 0" } - .small-12.columns - %h6= t('.used_saved_card') - %select{ name: "selected_card", required: false, ng: { model: "secrets.selected_card", options: "card.id as card.formatted for card in savedCreditCards" } } - %option{ value: "" }= "{{ secrets.selected_card ? '#{t('.enter_new_card')}' : '#{t('.choose_one')}' }}" - - %h6{ ng: { if: '!secrets.selected_card' } } - = t('.or_enter_new_card') - -%div{ ng: { if: '!secrets.selected_card' } } - %stripe-elements - - - if spree_current_user - .row - .small-12.columns.text-right - = check_box_tag 'secrets.save_requested_by_customer', '1', false, 'ng-model' => 'secrets.save_requested_by_customer' - = label_tag 'secrets.save_requested_by_customer', t('.remember_this_card') From c2aaf88e98c4e41697993c963a8962ecdcc2a6e0 Mon Sep 17 00:00:00 2001 From: Mohamed ABDELLANI Date: Wed, 31 May 2023 19:37:36 +0100 Subject: [PATCH 02/16] remove checkout controller --- app/controllers/checkout_controller.rb | 187 ---------- app/controllers/concerns/order_stock_check.rb | 8 - app/models/spree/order.rb | 7 +- app/services/checkout/form_data_adapter.rb | 85 ----- app/services/permitted_attributes/checkout.rb | 25 -- config/routes.rb | 21 +- spec/controllers/checkout_controller_spec.rb | 346 ------------------ 7 files changed, 8 insertions(+), 671 deletions(-) delete mode 100644 app/controllers/checkout_controller.rb delete mode 100644 app/services/checkout/form_data_adapter.rb delete mode 100644 app/services/permitted_attributes/checkout.rb delete mode 100644 spec/controllers/checkout_controller_spec.rb diff --git a/app/controllers/checkout_controller.rb b/app/controllers/checkout_controller.rb deleted file mode 100644 index ea4ad42ac7d..00000000000 --- a/app/controllers/checkout_controller.rb +++ /dev/null @@ -1,187 +0,0 @@ -# frozen_string_literal: true - -require 'open_food_network/address_finder' - -class CheckoutController < ::BaseController - include OrderStockCheck - include OrderCompletion - include WhiteLabel - - layout 'darkswarm' - - helper 'terms_and_conditions' - helper 'checkout' - - # We need pessimistic locking to avoid race conditions. - # Otherwise we fail on duplicate indexes or end up with negative stock. - prepend_around_action CurrentOrderLocker, only: [:edit, :update] - - prepend_before_action :check_hub_ready_for_checkout - prepend_before_action :check_order_cycle_expiry - prepend_before_action :require_order_cycle - prepend_before_action :require_distributor_chosen - - before_action :load_order - - before_action :handle_insufficient_stock - - before_action :associate_user - before_action :check_authorization - - before_action :hide_ofn_navigation, only: :edit - - helper 'spree/orders' - - def edit; end - - def update - params_adapter = Checkout::FormDataAdapter.new(permitted_params, @order, spree_current_user) - return action_failed unless @order.update(params_adapter.params[:order] || {}) - - checkout_workflow(params_adapter.shipping_method_id) - rescue Spree::Core::GatewayError => e - gateway_error(e) - action_failed(e) - rescue StandardError => e - flash[:error] = I18n.t("checkout.failed") - action_failed(e) - ensure - @order.update_order! - end - - private - - def check_authorization - authorize!(:edit, current_order, session[:access_token]) - end - - def load_order - load_checkout_order - - return handle_invalid_stock unless valid_order_line_items? - - before_address - setup_for_current_state - end - - def handle_invalid_stock - reset_order_to_cart - - respond_to do |format| - format.html do - redirect_to main_app.cart_path - end - - format.json do - render json: { path: main_app.cart_path }, status: :bad_request - end - end - end - - def setup_for_current_state - method_name = :"before_#{@order.state}" - __send__(method_name) if respond_to?(method_name, true) - end - - def before_address - associate_user - - finder = OpenFoodNetwork::AddressFinder.new(@order.email, @order.customer, spree_current_user) - - @order.bill_address = finder.bill_address - @order.ship_address = finder.ship_address - end - - def before_payment - current_order.payments.destroy_all if request.put? - end - - def checkout_workflow(shipping_method_id) - while @order.state != "complete" - if @order.state == "payment" - update_payment_total - return if redirect_to_payment_gateway - - return action_failed if @order.errors.any? - return action_failed unless @order.process_payments! - end - - next if OrderWorkflow.new(@order).next({ "shipping_method_id" => shipping_method_id }) - - return action_failed - end - - update_response - end - - def update_payment_total - @order.update_totals - @order.updater.update_pending_payment - end - - def redirect_to_payment_gateway - return unless selected_payment_method.external_gateway? - return unless (redirect_url = selected_payment_method.external_payment_url(order: @order)) - - render json: { path: redirect_url }, status: :ok - true - end - - def selected_payment_method - @selected_payment_method ||= Spree::PaymentMethod.find( - params.dig(:order, :payments_attributes, 0, :payment_method_id) - ) - end - - def update_response - if order_complete? - processing_succeeded - update_succeeded_response - else - action_failed(RuntimeError.new("Order not complete after the checkout workflow")) - end - end - - def order_complete? - @order.state == "complete" || @order.completed? - end - - def update_succeeded_response - respond_to do |format| - format.html do - respond_with(@order, location: order_completion_route) - end - format.json do - render json: { path: order_completion_route }, status: :ok - end - end - end - - def action_failed(error = RuntimeError.new(order_processing_error)) - processing_failed(error) - action_failed_response - end - - def action_failed_response - respond_to do |format| - format.html do - render :edit - end - format.json do - discard_flash_errors - render json: { errors: @order.errors, flash: flash.to_hash }.to_json, status: :bad_request - end - end - end - - def permitted_params - PermittedAttributes::Checkout.new(params).call - end - - def discard_flash_errors - # Marks flash errors for deletion after the current action has completed. - # This ensures flash errors generated during XHR requests are not persisted in the - # session for longer than expected. - flash.discard(:error) - end -end diff --git a/app/controllers/concerns/order_stock_check.rb b/app/controllers/concerns/order_stock_check.rb index 7ada12ab736..c9799486865 100644 --- a/app/controllers/concerns/order_stock_check.rb +++ b/app/controllers/concerns/order_stock_check.rb @@ -13,8 +13,6 @@ def valid_order_line_items? def handle_insufficient_stock return if sufficient_stock? - reset_order_to_cart - flash[:error] = Spree.t(:inventory_error_flash_for_insufficient_quantity) redirect_to main_app.cart_path end @@ -43,10 +41,4 @@ def check_order_cycle_expiry def sufficient_stock? @sufficient_stock ||= @order.insufficient_stock_lines.blank? end - - def reset_order_to_cart - return if OpenFoodNetwork::FeatureToggle.enabled? :split_checkout, spree_current_user - - OrderCheckoutRestart.new(@order).call - end end diff --git a/app/models/spree/order.rb b/app/models/spree/order.rb index 47dc49be26e..d180a4b8333 100644 --- a/app/models/spree/order.rb +++ b/app/models/spree/order.rb @@ -25,9 +25,7 @@ class Order < ApplicationRecord order.update_totals order.payment_required? } - go_to_state :confirmation, if: ->(order) { - OpenFoodNetwork::FeatureToggle.enabled? :split_checkout, order.created_by - } + go_to_state :confirmation go_to_state :complete end @@ -319,8 +317,7 @@ def ship_total # Creates new tax charges if there are any applicable rates. If prices already # include taxes then price adjustments are created instead. def create_tax_charge! - return if state.in?(["cart", "address", "delivery"]) && - OpenFoodNetwork::FeatureToggle.enabled?(:split_checkout) + return if state.in?(["cart", "address", "delivery"]) clear_legacy_taxes! diff --git a/app/services/checkout/form_data_adapter.rb b/app/services/checkout/form_data_adapter.rb deleted file mode 100644 index f5550126d1a..00000000000 --- a/app/services/checkout/form_data_adapter.rb +++ /dev/null @@ -1,85 +0,0 @@ -# frozen_string_literal: true - -# Adapts checkout form data (params) so that the order can be directly saved to the database -module Checkout - class FormDataAdapter - attr_reader :params, :shipping_method_id - - def initialize(params, order, current_user) - @params = params.deep_dup.to_h.with_indifferent_access - @order = order - @current_user = current_user - - move_payment_source_to_payment_attributes! - - fill_in_card_type - - set_amount_in_payments_attributes - - construct_saved_card_attributes if @params.dig(:order, :existing_card_id) - - @shipping_method_id = @params[:order]&.delete(:shipping_method_id) - end - - private - - # For payment step, filter order parameters to produce the expected - # nested attributes for a single payment and its source, - # discarding attributes for payment methods other than the one selected - def move_payment_source_to_payment_attributes! - return unless @params[:payment_source].present? && - payment_source_params = delete_payment_source_params! - - @params.dig(:order, :payments_attributes).first[:source_attributes] = payment_source_params - end - - # Ensures cc_type is always passed to the model by inferring the type when - # the frontend didn't provide it. - def fill_in_card_type - return unless payment_source_attributes - - return if payment_source_attributes.dig(:number).blank? - - payment_source_attributes[:cc_type] ||= card_brand(payment_source_attributes[:number]) - end - - def payment_source_attributes - @payment_source_attributes ||= - @params.dig(:order, :payments_attributes)&.first&.dig(:source_attributes) - end - - def card_brand(number) - ActiveMerchant::Billing::CreditCard.brand?(number) - end - - def delete_payment_source_params! - @params.delete(:payment_source)[ - @params.dig(:order, :payments_attributes).first[:payment_method_id].underscore - ] - end - - def set_amount_in_payments_attributes - return unless @params.dig(:order, :payments_attributes) - - @params.dig(:order, :payments_attributes).first[:amount] = @order.total - end - - def construct_saved_card_attributes - existing_card_id = @params[:order].delete(:existing_card_id) - return if existing_card_id.blank? - - add_to_payment_attributes(existing_card_id) - - @params.dig(:order, :payments_attributes).first.delete :source_attributes - end - - def add_to_payment_attributes(existing_card_id) - credit_card = Spree::CreditCard.find(existing_card_id) - if credit_card.try(:user_id).blank? || credit_card.user_id != @current_user.try(:id) - raise Spree::Core::GatewayError, I18n.t(:invalid_credit_card) - end - - @params.dig(:order, :payments_attributes).first[:source] = credit_card - end - end -end diff --git a/app/services/permitted_attributes/checkout.rb b/app/services/permitted_attributes/checkout.rb deleted file mode 100644 index e9d486d9690..00000000000 --- a/app/services/permitted_attributes/checkout.rb +++ /dev/null @@ -1,25 +0,0 @@ -# frozen_string_literal: true - -module PermittedAttributes - class Checkout - def initialize(params) - @params = params - end - - def call - @params.permit( - order: [ - :email, :special_instructions, - :existing_card_id, :shipping_method_id, - { payments_attributes: [ - :payment_method_id, - { source_attributes: PermittedAttributes::PaymentSource.attributes } - ], - ship_address_attributes: PermittedAttributes::Address.attributes, - bill_address_attributes: PermittedAttributes::Address.attributes } - ], - payment_source: PermittedAttributes::PaymentSource.attributes - ) - end - end -end diff --git a/config/routes.rb b/config/routes.rb index be14086b9cd..1d933363ac7 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -84,24 +84,15 @@ get "/stripe/authorize/:order_number", to: "stripe#authorize", as: :authorize_stripe end - constraints FeatureToggleConstraint.new(:split_checkout) do - get '/checkout', to: 'split_checkout#edit' + get '/checkout', to: 'split_checkout#edit' - constraints step: /(details|payment|summary)/ do - get '/checkout/:step', to: 'split_checkout#edit', as: :checkout_step - put '/checkout/:step', to: 'split_checkout#update', as: :checkout_update - end - - # Redirects to the new checkout for any other 'step' (ie. /checkout/cart from the legacy checkout) - get '/checkout/:other', to: redirect('/checkout') + constraints step: /(details|payment|summary)/ do + get '/checkout/:step', to: 'split_checkout#edit', as: :checkout_step + put '/checkout/:step', to: 'split_checkout#update', as: :checkout_update end - # When the split_checkout feature is disabled for the current user, use the legacy checkout - constraints FeatureToggleConstraint.new(:split_checkout, negate: true) do - get '/checkout', to: 'checkout#edit' - put '/checkout', to: 'checkout#update', as: :update_checkout - get '/checkout/:state', to: 'checkout#edit', as: :checkout_state - end + # Redirects to the new checkout for any other 'step' (ie. /checkout/cart from the legacy checkout) + get '/checkout/:other', to: redirect('/checkout') get 'embedded_shopfront/shopfront_session', to: 'application#shopfront_session' post 'embedded_shopfront/enable', to: 'application#enable_embedded_styles' diff --git a/spec/controllers/checkout_controller_spec.rb b/spec/controllers/checkout_controller_spec.rb deleted file mode 100644 index e0661caaf7a..00000000000 --- a/spec/controllers/checkout_controller_spec.rb +++ /dev/null @@ -1,346 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -describe CheckoutController, type: :controller do - include StripeStubs - - let(:distributor) { create(:distributor_enterprise, with_payment_and_shipping: true) } - let(:order_cycle) { create(:simple_order_cycle) } - let(:order) { create(:order) } - - before do - allow(order).to receive(:checkout_allowed?).and_return true - allow(controller).to receive(:check_authorization).and_return true - end - - it "redirects home when no distributor is selected" do - get :edit - expect(response).to redirect_to root_path - end - - it "redirects to the shop when no order cycle is selected" do - allow(controller).to receive(:current_distributor).and_return(distributor) - get :edit - expect(response).to redirect_to shop_path - end - - it "redirects to shopfront with message if order cycle is expired" do - allow(controller).to receive(:current_distributor).and_return(distributor) - expect(controller).to receive(:current_order_cycle).and_return(order_cycle).at_least(:once) - expect(controller).to receive(:current_order).and_return(order).at_least(:once) - expect(order_cycle).to receive(:closed?).and_return(true) - expect(order).to receive(:empty!) - expect(order).to receive(:set_order_cycle!).with(nil) - - get :edit - - expect(response).to redirect_to shop_url - expect(flash[:info]).to eq 'The order cycle you\'ve selected has just closed. Please try again!' - end - - it "redirects home with message if hub is not ready for checkout" do - allow(distributor).to receive(:ready_for_checkout?) { false } - allow(order).to receive_messages(distributor: distributor, order_cycle: order_cycle) - allow(controller).to receive(:current_order).and_return(order) - - expect(order).to receive(:empty!) - expect(order).to receive(:set_distribution!).with(nil, nil) - - get :edit - - expect(response).to redirect_to root_url - expect(flash[:info]).to eq('The hub you have selected is temporarily closed for orders. Please try again later.') - end - - describe "#update" do - let(:user) { order.user } - let(:distributor) { create(:distributor_enterprise, with_payment_and_shipping: true) } - let(:order_cycle) { create(:order_cycle, distributors: [distributor]) } - let(:order) { create(:order, distributor: distributor, order_cycle: order_cycle) } - let(:payment_method) { distributor.payment_methods.first } - let(:shipping_method) { distributor.shipping_methods.first } - - before do - order.contents.add(order_cycle.variants_distributed_by(distributor).first) - - allow(controller).to receive(:current_distributor).and_return(distributor) - allow(controller).to receive(:current_order_cycle).and_return(order_cycle) - allow(controller).to receive(:current_order).and_return(order) - allow(controller).to receive(:spree_current_user).and_return(user) - - user.bill_address = create(:address) - user.ship_address = create(:address) - user.save! - end - - it "completes the order and redirects to the order confirmation page" do - params = { - "order" => { - "bill_address_attributes" => order.bill_address.attributes, - "default_bill_address" => false, - "default_ship_address" => false, - "email" => user.email, - "payments_attributes" => [{ "payment_method_id" => payment_method.id }], - "ship_address_attributes" => order.bill_address.attributes, - "shipping_method_id" => shipping_method.id - } - } - expect { post :update, params: params }. - to change { Customer.count }.by(1) - expect(order.completed?).to be true - expect(response).to redirect_to order_path(order, order_token: order.token) - end - end - - describe "running out of stock" do - let(:order_cycle_distributed_variants) { double(:order_cycle_distributed_variants) } - - before do - allow(controller).to receive(:current_order).and_return(order) - allow(order).to receive(:distributor).and_return(distributor) - order.update(order_cycle: order_cycle) - - allow(OrderCycleDistributedVariants).to receive(:new).and_return(order_cycle_distributed_variants) - end - - context "handling stock issues" do - it "redirects when some items are out of stock" do - allow(order).to receive_message_chain(:insufficient_stock_lines, :empty?).and_return false - - get :edit - expect(response).to redirect_to cart_path - end - - it "redirects when some items are not available" do - allow(order).to receive_message_chain(:insufficient_stock_lines, :empty?).and_return true - expect(order_cycle_distributed_variants).to receive(:distributes_order_variants?).with(order).and_return(false) - - get :edit - expect(response).to redirect_to cart_path - end - end - end - - describe "building the order" do - before do - allow(controller).to receive(:current_distributor).and_return(distributor) - allow(controller).to receive(:current_order_cycle).and_return(order_cycle) - allow(controller).to receive(:current_order).and_return(order) - end - - it "set shipping_address_from_distributor when re-rendering edit" do - expect(order.updater).to receive(:shipping_address_from_distributor) - allow(order).to receive(:update).and_return false - spree_post :update, format: :json, order: {} - end - - it "set shipping_address_from_distributor when the order state cannot be advanced" do - expect(order.updater).to receive(:shipping_address_from_distributor) - allow(order).to receive(:update).and_return true - allow(order).to receive(:next).and_return false - spree_post :update, format: :json, order: {} - end - - context "#update with shipping_method_id" do - let(:test_shipping_method_id) { "111" } - - before do - allow(controller).to receive(:order_completion_reset) - allow(order).to receive(:update).and_return true - allow(controller).to receive(:current_order).and_return order - - # make order workflow pass through delivery - allow(order).to receive(:next).twice do - if order.state == 'cart' - order.update_column :state, 'delivery' - else - order.update_column :state, 'complete' - end - end - end - - it "does not fail to update" do - expect(controller).to_not receive(:clear_ship_address) - spree_post :update, order: { shipping_method_id: test_shipping_method_id } - end - - it "does not send shipping_method_id to the order model as an attribute" do - expect(order).to receive(:update).with({}) - spree_post :update, order: { shipping_method_id: test_shipping_method_id } - end - - it "selects the shipping_method in the order" do - expect(order).to receive(:select_shipping_method).with(test_shipping_method_id) - spree_post :update, order: { shipping_method_id: test_shipping_method_id } - end - end - - context 'when completing the order' do - before do - order.state = 'complete' - order.save! - allow(order).to receive(:update).and_return(true) - allow(order).to receive(:next).and_return(true) - allow(order).to receive(:set_distributor!).and_return(true) - end - - it "sets the new order's token to the same as the old order" do - order = controller.current_order(true) - spree_post :update, order: {} - expect(controller.current_order.token).to eq order.token - end - - it 'expires the current order' do - allow(controller).to receive(:expire_current_order) - put :update, params: { order: {} } - expect(controller).to have_received(:expire_current_order) - end - - it 'sets the access_token of the session' do - put :update, params: { order: {} } - expect(session[:access_token]).to eq(controller.current_order.token) - end - end - end - - describe '#expire_current_order' do - it 'empties the order_id of the session' do - expect(session).to receive(:[]=).with(:order_id, nil) - controller.send(:expire_current_order) - end - - it 'resets the @current_order ivar' do - controller.send(:expire_current_order) - expect(controller.instance_variable_get(:@current_order)).to be_nil - end - end - - context "via xhr" do - before do - allow(controller).to receive(:current_distributor).and_return(distributor) - - allow(controller).to receive(:current_order_cycle).and_return(order_cycle) - allow(controller).to receive(:current_order).and_return(order) - end - - it "returns errors and flash if order.update fails" do - spree_post :update, format: :json, order: {} - expect(response.status).to eq(400) - expect(response.body).to eq({ errors: assigns[:order].errors, - flash: { error: order.errors.full_messages.to_sentence } }.to_json) - end - - it "returns errors and flash if order.next fails" do - allow(order).to receive(:update).and_return true - allow(order).to receive(:next).and_return false - spree_post :update, format: :json, order: {} - expect(response.body).to eq({ errors: assigns[:order].errors, - flash: { error: "Payment could not be processed, please check the details you entered" } }.to_json) - end - - it "returns order confirmation url on success" do - expect(controller).to receive(:expire_current_order) - expect(controller).to receive(:build_new_order).with(order.distributor, order.token) - - allow(order).to receive(:update).and_return true - allow(order).to receive(:state).and_return "complete" - - spree_post :update, format: :json, order: {} - expect(response.status).to eq(200) - expect(response.body).to eq({ path: order_path(order, order_token: order.token) }.to_json) - end - - it "returns an error on unexpected failure" do - allow(order).to receive(:update).and_raise - - spree_post :update, format: :json, order: {} - expect(response.status).to eq(400) - expect(response.body).to eq({ errors: {}, - flash: { error: 'The checkout failed. Please let us know so that we can process your order.' } }.to_json) - end - - it "returns a specific error on Spree::Core::GatewayError" do - allow(order).to receive(:update).and_raise(Spree::Core::GatewayError.new("Gateway blow up")) - spree_post :update, format: :json, order: {} - - expect(response.status).to eq(400) - flash_message = "There was a problem with your payment information: %s" % 'Gateway blow up' - expect(json_response["flash"]["error"]).to eq flash_message - end - - describe "stale object handling" do - it "retries when a stale object error is encountered" do - expect(controller).to receive(:expire_current_order) - expect(controller).to receive(:build_new_order).with(order.distributor, order.token) - - allow(order).to receive(:update).and_return true - allow(controller).to receive(:state_callback) - - # The first time, raise a StaleObjectError. The second time, succeed. - allow(order).to receive(:next).once. - and_raise(ActiveRecord::StaleObjectError.new(Spree::Variant.new, 'update')) - allow(order).to receive(:next).once do - order.update_column :state, 'complete' - true - end - - spree_post :update, format: :json, order: {} - expect(response.status).to eq(200) - end - - it "tries a maximum of 3 times before giving up and returning an error" do - allow(order).to receive(:update).and_return true - allow(order).to receive(:next) { - raise ActiveRecord::StaleObjectError.new(Spree::Variant.new, 'update') - } - - spree_post :update, format: :json, order: {} - expect(response.status).to eq(400) - end - end - end - - describe "Payment redirects" do - before do - allow(controller).to receive(:current_distributor) { distributor } - allow(controller).to receive(:current_order_cycle) { order_cycle } - allow(controller).to receive(:current_order) { order } - allow(order).to receive(:update) { true } - allow(order).to receive(:state) { "payment" } - end - - describe "redirecting to an external payment gateway" do - let(:payment_method) { create(:payment_method) } - - it "should call Stripe redirect and redirect if a path is provided" do - expect(Spree::PaymentMethod).to receive(:find).and_return(payment_method) - expect(payment_method).to receive(:external_gateway?).and_return(true) - expect(payment_method).to receive(:external_payment_url).and_return("test_path") - - spree_post :update, - order: { payments_attributes: [{ payment_method_id: payment_method.id }] } - - expect(response.body).to eq({ path: "test_path" }.to_json) - end - end - end - - describe "#action_failed" do - let(:restart_checkout) { instance_double(OrderCheckoutRestart, call: true) } - - before do - controller.instance_variable_set(:@order, order) - allow(OrderCheckoutRestart).to receive(:new) { restart_checkout } - allow(controller).to receive(:current_order) { order } - end - - it "set shipping_address_from_distributor and restarts the checkout" do - expect(order.updater).to receive(:shipping_address_from_distributor) - expect(restart_checkout).to receive(:call) - expect(controller).to receive(:respond_to) - - controller.send(:action_failed) - end - end -end From 907c65d98ce3cd8e11676156f4055b79cb77c470 Mon Sep 17 00:00:00 2001 From: Mohamed ABDELLANI Date: Fri, 2 Jun 2023 09:33:32 +0100 Subject: [PATCH 03/16] run create_tax_charge! after transition to payment state --- app/models/spree/order/checkout.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/spree/order/checkout.rb b/app/models/spree/order/checkout.rb index 618cc6db27b..b5950a747ed 100644 --- a/app/models/spree/order/checkout.rb +++ b/app/models/spree/order/checkout.rb @@ -75,9 +75,9 @@ def self.define_state_machine! before_transition to: :delivery, do: :create_proposed_shipments before_transition to: :delivery, do: :ensure_available_shipping_rates - before_transition to: :payment, do: :create_tax_charge! before_transition to: :confirmation, do: :validate_payment_method! + after_transition to: :payment, do: :create_tax_charge! after_transition to: :complete, do: :finalize! after_transition to: :resumed, do: :after_resume after_transition to: :canceled, do: :after_cancel From bd0e7cdfc88ba858a29b6b42af56aa2f6a3da83e Mon Sep 17 00:00:00 2001 From: Mohamed ABDELLANI Date: Thu, 1 Jun 2023 05:51:32 +0100 Subject: [PATCH 04/16] remove legacy checkout tests --- .../admin/bulk_line_items_controller_spec.rb | 1 + .../stripe_controller_spec.rb | 2 - .../split_checkout_controller_spec.rb | 2 - spec/helpers/injection_helper_spec.rb | 4 - .../accordion_controller_spec.js.coffee | 24 -- .../checkout_controller_spec.js.coffee | 100 -------- .../details_controller_spec.js.coffee | 37 --- .../payment_controller_spec.js.coffee | 17 -- .../shop_variant_controller_spec.js.coffee | 164 ------------- spec/models/spree/adjustment_spec.rb | 6 +- spec/models/spree/order/checkout_spec.rb | 13 +- spec/models/spree/order/state_machine_spec.rb | 6 + spec/models/spree/order/tax_spec.rb | 4 + spec/models/spree/order_spec.rb | 7 +- spec/requests/checkout/routes_spec.rb | 27 +- spec/requests/voucher_adjustments_spec.rb | 2 - .../checkout/form_data_adapter_spec.rb | 85 ------- spec/system/admin/reports_spec.rb | 2 +- spec/system/consumer/shopping/cart_spec.rb | 12 - .../consumer/shopping/checkout_auth_spec.rb | 98 +++----- spec/system/consumer/split_checkout_spec.rb | 2 - .../consumer/split_checkout_tax_incl_spec.rb | 171 ++++--------- .../split_checkout_tax_not_incl_spec.rb | 230 +++++++----------- spec/system/consumer/white_label_spec.rb | 14 +- 24 files changed, 198 insertions(+), 832 deletions(-) delete mode 100644 spec/javascripts/unit/darkswarm/controllers/checkout/accordion_controller_spec.js.coffee delete mode 100644 spec/javascripts/unit/darkswarm/controllers/checkout/checkout_controller_spec.js.coffee delete mode 100644 spec/javascripts/unit/darkswarm/controllers/checkout/details_controller_spec.js.coffee delete mode 100644 spec/javascripts/unit/darkswarm/controllers/checkout/payment_controller_spec.js.coffee delete mode 100644 spec/javascripts/unit/darkswarm/controllers/checkout/shop_variant_controller_spec.js.coffee delete mode 100644 spec/services/checkout/form_data_adapter_spec.rb diff --git a/spec/controllers/admin/bulk_line_items_controller_spec.rb b/spec/controllers/admin/bulk_line_items_controller_spec.rb index 851e102a7c8..c5e6e49977f 100644 --- a/spec/controllers/admin/bulk_line_items_controller_spec.rb +++ b/spec/controllers/admin/bulk_line_items_controller_spec.rb @@ -379,6 +379,7 @@ order.shipments.map(&:refresh_rates) order.select_shipping_method(shipping_method.id) + OrderWorkflow.new(order).advance_to_payment order.finalize! order.recreate_all_fees! order.create_tax_charge! diff --git a/spec/controllers/payment_gateways/stripe_controller_spec.rb b/spec/controllers/payment_gateways/stripe_controller_spec.rb index 36095c9f74c..3c611df9087 100644 --- a/spec/controllers/payment_gateways/stripe_controller_spec.rb +++ b/spec/controllers/payment_gateways/stripe_controller_spec.rb @@ -74,8 +74,6 @@ module PaymentGateways context "using split checkout" do before do - Flipper.enable(:split_checkout) - order.update_attribute :state, "confirmation" end diff --git a/spec/controllers/split_checkout_controller_spec.rb b/spec/controllers/split_checkout_controller_spec.rb index c57710a2bbe..114a947c395 100644 --- a/spec/controllers/split_checkout_controller_spec.rb +++ b/spec/controllers/split_checkout_controller_spec.rb @@ -16,8 +16,6 @@ let(:shipping_method) { distributor.shipping_methods.first } before do - Flipper.enable(:split_checkout) - exchange.variants << order.line_items.first.variant allow(controller).to receive(:current_order) { order } allow(controller).to receive(:spree_current_user) { user } diff --git a/spec/helpers/injection_helper_spec.rb b/spec/helpers/injection_helper_spec.rb index c4abbdbf17f..06319fa87bf 100644 --- a/spec/helpers/injection_helper_spec.rb +++ b/spec/helpers/injection_helper_spec.rb @@ -37,8 +37,6 @@ order = create(:order, distributor: current_distributor) allow(helper).to receive(:current_order) { order } allow(helper).to receive(:spree_current_user) { nil } - expect(helper.inject_available_shipping_methods).to match sm.id.to_s - expect(helper.inject_available_shipping_methods).to match sm.compute_amount(order).to_s end it "injects payment methods" do @@ -47,8 +45,6 @@ order = create(:order, distributor: current_distributor) allow(helper).to receive(:current_order) { order } allow(helper).to receive(:spree_current_user) { nil } - expect(helper.inject_available_payment_methods).to match pm.id.to_s - expect(helper.inject_available_payment_methods).to match pm.name end it "injects current order" do diff --git a/spec/javascripts/unit/darkswarm/controllers/checkout/accordion_controller_spec.js.coffee b/spec/javascripts/unit/darkswarm/controllers/checkout/accordion_controller_spec.js.coffee deleted file mode 100644 index 3858f2a922c..00000000000 --- a/spec/javascripts/unit/darkswarm/controllers/checkout/accordion_controller_spec.js.coffee +++ /dev/null @@ -1,24 +0,0 @@ -describe "AccordionCtrl", -> - ctrl = null - scope = null - CurrentHubMock = - hub: - id: 1 - - beforeEach -> - module "Darkswarm" - module ($provide)-> - $provide.value "CurrentHub", CurrentHubMock - null - inject ($controller, $rootScope) -> - scope = $rootScope.$new() - scope.order = - id: 129 - ctrl = $controller 'AccordionCtrl', {$scope: scope} - - it "defaults the details accordion to visible", -> - expect(scope.accordion.details).toEqual true - - it "changes accordion", -> - scope.show "shipping" - expect(scope.accordion["shipping"]).toEqual true diff --git a/spec/javascripts/unit/darkswarm/controllers/checkout/checkout_controller_spec.js.coffee b/spec/javascripts/unit/darkswarm/controllers/checkout/checkout_controller_spec.js.coffee deleted file mode 100644 index 75d6fd8d36a..00000000000 --- a/spec/javascripts/unit/darkswarm/controllers/checkout/checkout_controller_spec.js.coffee +++ /dev/null @@ -1,100 +0,0 @@ -describe "CheckoutCtrl", -> - ctrl = null - scope = null - Checkout = null - CurrentUser = null - CurrentHubMock = - hub: - id: 1 - localStorageService = null - - beforeEach -> - module("Darkswarm") - angular.module('Darkswarm').value('user', {}) - angular.module('Darkswarm').value('currentHub', {id: 1}) - module ($provide)-> - $provide.value "CurrentHub", CurrentHubMock - null - Checkout = - purchase: -> - submit: -> - navigate: -> - bindFieldsToLocalStorage: -> - order: - id: 1 - email: "public" - user_id: 1 - bill_address: 'bill_address' - ship_address: 'ship address' - secrets: - card_number: "this is a secret" - - describe "with user", -> - beforeEach -> - inject ($controller, $rootScope, _localStorageService_) -> - localStorageService = _localStorageService_ - spyOn(localStorageService, "bind").and.callThrough() - scope = $rootScope.$new() - CurrentUser = { id: 1 } - ctrl = $controller 'CheckoutCtrl', {$scope: scope, Checkout: Checkout, CurrentUser: CurrentUser } - - describe "submitting", -> - event = - preventDefault: -> - - beforeEach -> - spyOn(Checkout, "purchase") - scope.submitted = false - - it "delegates to the service when valid", -> - scope.purchase(event, {$valid: true}) - expect(Checkout.purchase).toHaveBeenCalled() - expect(scope.submitted).toBe(true) - - it "does nothing when invalid", -> - scope.purchase(event, {$valid: false}) - expect(Checkout.purchase).not.toHaveBeenCalled() - expect(scope.submitted).toBe(true) - - it "is enabled", -> - expect(scope.enabled).toEqual true - - describe "Local storage", -> - it "binds to localStorage when given a scope", inject ($timeout) -> - prefix = "order_#{scope.order.id}#{CurrentUser.id or ""}#{CurrentHubMock.hub.id}" - - field = scope.fieldsToBind[0] - expect(localStorageService.bind).toHaveBeenCalledWith(scope, "Checkout.order.#{field}", Checkout.order[field], "#{prefix}_#{field}") - expect(localStorageService.bind).toHaveBeenCalledWith(scope, "Checkout.ship_address_same_as_billing", true, "#{prefix}_sameasbilling") - expect(localStorageService.bind).toHaveBeenCalledWith(scope, "Checkout.default_bill_address", false, "#{prefix}_defaultasbilladdress") - expect(localStorageService.bind).toHaveBeenCalledWith(scope, "Checkout.default_ship_address", false, "#{prefix}_defaultasshipaddress") - - it "it can retrieve data from localstorage", -> - prefix = "order_#{scope.order.id}#{CurrentUser.id or ""}#{CurrentHubMock.hub.id}" - scope.$digest() - expect(localStorage.getItem("ls.#{prefix}_email")).toMatch "public" - - it "does not store secrets in local storage", -> - Checkout.secrets = - card_number: "superfuckingsecret" - scope.$digest() - keys = (localStorage.key(i) for i in [0..localStorage.length]) - for key in keys - expect(localStorage.getItem(key)).not.toMatch Checkout.secrets.card_number - - describe "without user", -> - beforeEach -> - inject ($controller, $rootScope) -> - scope = $rootScope.$new() - ctrl = $controller 'CheckoutCtrl', {$scope: scope, Checkout: Checkout, CurrentUser: {}} - - it "is disabled", -> - expect(scope.enabled).toEqual false - - it "does not store secrets in local storage", -> - Checkout.secrets = - card_number: "superfuckingsecret" - scope.$digest() - keys = (localStorage.key(i) for i in [0..localStorage.length]) - for key in keys - expect(localStorage.getItem(key)).not.toMatch Checkout.secrets.card_number diff --git a/spec/javascripts/unit/darkswarm/controllers/checkout/details_controller_spec.js.coffee b/spec/javascripts/unit/darkswarm/controllers/checkout/details_controller_spec.js.coffee deleted file mode 100644 index 163a6c0f0b7..00000000000 --- a/spec/javascripts/unit/darkswarm/controllers/checkout/details_controller_spec.js.coffee +++ /dev/null @@ -1,37 +0,0 @@ -describe "DetailsCtrl", -> - ctrl = null - scope = null - order = null - CurrentUser = null - - beforeEach -> - module("Darkswarm") - inject ($controller, $rootScope) -> - scope = $rootScope.$new() - CurrentUser = { id: 1 } - ctrl = $controller 'DetailsCtrl', { $scope: scope, CurrentUser: CurrentUser } - - - it "finds a field by path", -> - scope.details = - path: "test" - expect(scope.field('path')).toEqual "test" - - it "tests validity", -> - scope.details = - path: - $dirty: true - $invalid: true - expect(scope.fieldValid('path')).toEqual false - - it "returns errors by path", -> - scope.Order = - errors: -> - scope.details = - path: - $error: - email: true - required: true - expect(scope.fieldErrors('path')).toEqual ["must be email address", "can't be blank"].join ", " - - diff --git a/spec/javascripts/unit/darkswarm/controllers/checkout/payment_controller_spec.js.coffee b/spec/javascripts/unit/darkswarm/controllers/checkout/payment_controller_spec.js.coffee deleted file mode 100644 index 46b152b00a0..00000000000 --- a/spec/javascripts/unit/darkswarm/controllers/checkout/payment_controller_spec.js.coffee +++ /dev/null @@ -1,17 +0,0 @@ -describe "PaymentCtrl", -> - ctrl = null - scope = null - card1 = { id: 1, is_default: false } - card2 = { id: 3, is_default: true } - cards = [card1, card2] - - beforeEach -> - module("Darkswarm") - angular.module('Darkswarm').value('savedCreditCards', cards) - inject ($controller, $rootScope) -> - scope = $rootScope.$new() - scope.secrets = {} - ctrl = $controller 'PaymentCtrl', {$scope: scope} - - it "sets the default card id as the selected_card", -> - expect(scope.secrets.selected_card).toEqual card2.id diff --git a/spec/javascripts/unit/darkswarm/controllers/checkout/shop_variant_controller_spec.js.coffee b/spec/javascripts/unit/darkswarm/controllers/checkout/shop_variant_controller_spec.js.coffee deleted file mode 100644 index c1e780e7834..00000000000 --- a/spec/javascripts/unit/darkswarm/controllers/checkout/shop_variant_controller_spec.js.coffee +++ /dev/null @@ -1,164 +0,0 @@ -describe "ShopVariantCtrl", -> - ctrl = null - scope = null - CartMock = null - - beforeEach -> - module 'Darkswarm' - - inject ($rootScope, $controller, $modal)-> - scope = $rootScope.$new() - scope.$watchGroup = -> - scope.variant = { - on_demand: true - product: {group_buy: true} - line_item: { - quantity: undefined - max_quantity: undefined - } - } - CartMock = - adjust: -> - true - ctrl = $controller 'ShopVariantCtrl', {$scope: scope, $modal: $modal, Cart: CartMock, Shopfront: {}} - - it "initializes the quantity for shop display", -> - expect(scope.variant.line_item.quantity).toEqual 0 - - it "adds an item to the cart", -> - scope.add 1 - expect(scope.variant.line_item.quantity).toEqual 1 - - it "adds to the existing quantity", -> - scope.add 1 - scope.add 5 - expect(scope.variant.line_item.quantity).toEqual 6 - - it "adds to an invalid quantity", -> - scope.$apply -> - scope.variant.line_item.quantity = -5 - scope.add 1 - expect(scope.variant.line_item.quantity).toEqual 1 - - it "adds to an undefined quantity", -> - scope.$apply -> - scope.variant.line_item.quantity = undefined - scope.add 1 - expect(scope.variant.line_item.quantity).toEqual 1 - - it "adds to the max quantity", -> - scope.addMax 5 - expect(scope.variant.line_item.quantity).toEqual 0 - expect(scope.variant.line_item.max_quantity).toEqual 5 - - it "adds to an undefined max quantity", -> - scope.variant.line_item.quantity = 3 - scope.variant.line_item.max_quantity = undefined - scope.addMax 1 - expect(scope.variant.line_item.max_quantity).toEqual 4 - - it "adds to the max quantity to be at least min quantity", -> - scope.$apply -> - scope.variant.line_item.max_quantity = 2 - - scope.$apply -> - scope.add 3 - - expect(scope.variant.line_item.quantity).toEqual 3 - expect(scope.variant.line_item.max_quantity).toEqual 3 - - it "decreases the min quantity to not exceed max quantity", -> - scope.$apply -> - scope.variant.line_item.quantity = 3 - scope.variant.line_item.max_quantity = 5 - - scope.$apply -> - scope.addMax -3 - - expect(scope.variant.line_item.quantity).toEqual 2 - expect(scope.variant.line_item.max_quantity).toEqual 2 - - it "caps at the available quantity", -> - scope.$apply -> - scope.variant.on_demand = false - scope.variant.on_hand = 3 - scope.variant.line_item.quantity = 5 - scope.variant.line_item.max_quantity = 7 - - expect(scope.variant.line_item.quantity).toEqual 3 - expect(scope.variant.line_item.max_quantity).toEqual 3 - - it "allows adding when variant is on demand", -> - expect(scope.canAdd(5000)).toEqual true - - it "denies adding if variant is out of stock", -> - scope.variant.on_demand = false - scope.variant.on_hand = 0 - - expect(scope.canAdd(1)).toEqual false - - it "denies adding if stock is limitted", -> - scope.variant.on_demand = false - scope.variant.on_hand = 5 - - expect(scope.canAdd(4)).toEqual true - expect(scope.canAdd(5)).toEqual true - expect(scope.canAdd(6)).toEqual false - - scope.add 3 - expect(scope.canAdd(2)).toEqual true - expect(scope.canAdd(3)).toEqual false - - it "denies adding if quantity is too high", -> - scope.variant.on_demand = false - scope.variant.on_hand = 5 - scope.variant.line_item.quantity = 7 - scope.variant.line_item.max_quantity = 7 - - expect(scope.canAdd(1)).toEqual false - expect(scope.canAddMax(1)).toEqual false - - it "allows decrease when quantity is too high", -> - scope.variant.on_demand = false - scope.variant.on_hand = 5 - scope.variant.line_item.quantity = 7 - scope.variant.line_item.max_quantity = 7 - expect(scope.canAdd(-1)).toEqual true - expect(scope.canAddMax(-1)).toEqual true - - it "allows increase when quantity is negative", -> - scope.variant.on_demand = false - scope.variant.on_hand = 5 - scope.variant.line_item.quantity = -3 - scope.variant.line_item.max_quantity = -3 - expect(scope.canAdd(1)).toEqual true - expect(scope.canAddMax(1)).toEqual false - - scope.variant.line_item.quantity = 1 - expect(scope.canAddMax(1)).toEqual true - - it "denies decrease when quantity is negative", -> - scope.variant.on_demand = false - scope.variant.on_hand = 5 - scope.variant.line_item.quantity = -3 - scope.variant.line_item.max_quantity = -3 - expect(scope.canAdd(-1)).toEqual false - expect(scope.canAddMax(-1)).toEqual false - - it "denies declaring max quantity before item is in cart", -> - expect(scope.canAddMax(1)).toEqual false - - it "allows declaring max quantity when item is in cart", -> - scope.add 1 - expect(scope.canAddMax(1)).toEqual true - - it "denies adding if stock is limitted", -> - scope.variant.on_demand = false - scope.variant.on_hand = 5 - scope.variant.line_item.quantity = 1 - scope.variant.line_item.max_quantity = 1 - - expect(scope.canAddMax(3)).toEqual true - expect(scope.canAddMax(4)).toEqual true - expect(scope.canAddMax(5)).toEqual false - expect(scope.canAddMax(6)).toEqual false diff --git a/spec/models/spree/adjustment_spec.rb b/spec/models/spree/adjustment_spec.rb index 9bb4baa06cf..35a6ba5779a 100644 --- a/spec/models/spree/adjustment_spec.rb +++ b/spec/models/spree/adjustment_spec.rb @@ -224,7 +224,7 @@ module Spree } let(:tax_category) { create(:tax_category, name: "Shipping", tax_rates: [tax_rate] ) } let(:hub) { create(:distributor_enterprise, charges_sales_tax: true) } - let(:order) { create(:order, distributor: hub) } + let(:order) { create(:order, distributor: hub, state: 'payment') } let(:line_item) { create(:line_item, order: order) } let(:shipping_method) { @@ -348,7 +348,7 @@ module Spree let(:line_item) { create(:line_item, variant: variant) } let(:order) { create(:order, line_items: [line_item], order_cycle: order_cycle, - distributor: coordinator) + distributor: coordinator, state: 'payment') } let(:fee) { order.all_adjustments.reload.enterprise_fee.first } let(:fee_tax) { fee.adjustments.tax.first } @@ -508,7 +508,7 @@ module Spree let!(:zone) { create(:zone_with_member) } let!(:tax_category) { create(:tax_category, name: "Tax Test") } let(:distributor) { create(:distributor_enterprise, charges_sales_tax: true) } - let(:order) { create(:order, distributor: distributor) } + let(:order) { create(:order, distributor: distributor, state: "payment") } let(:included_in_price) { true } let(:tax_rate) { create(:tax_rate, included_in_price: included_in_price, zone: zone, diff --git a/spec/models/spree/order/checkout_spec.rb b/spec/models/spree/order/checkout_spec.rb index 76912a62e5a..69d46c1e4e7 100644 --- a/spec/models/spree/order/checkout_spec.rb +++ b/spec/models/spree/order/checkout_spec.rb @@ -10,8 +10,9 @@ [ { address: :delivery }, { delivery: :payment }, - { payment: :complete }, - { delivery: :complete } + { delivery: :confirmation }, + { payment: :confirmation }, + { confirmation: :complete } ] end @@ -36,14 +37,14 @@ context "when payment not required" do before { allow(order).to receive_messages payment_required?: false } specify do - expect(order.checkout_steps).to eq %w(address delivery complete) + expect(order.checkout_steps).to eq %w(address delivery confirmation complete) end end context "when payment required" do before { allow(order).to receive_messages payment_required?: true } specify do - expect(order.checkout_steps).to eq %w(address delivery payment complete) + expect(order.checkout_steps).to eq %w(address delivery payment confirmation complete) end end end @@ -112,9 +113,9 @@ allow(order).to receive_messages payment_required?: false end - it "transitions to complete" do + it "transitions to confirmation" do order.next! - expect(order.state).to eq "complete" + expect(order.state).to eq 'confirmation' end end end diff --git a/spec/models/spree/order/state_machine_spec.rb b/spec/models/spree/order/state_machine_spec.rb index dc4b767ce70..3426532cb11 100644 --- a/spec/models/spree/order/state_machine_spec.rb +++ b/spec/models/spree/order/state_machine_spec.rb @@ -24,6 +24,8 @@ before { allow(order).to receive_messages process_payments!: true } it "should finalize order when transitioning to complete state" do + order.next + expect(order.state).to eq "confirmation" expect(order).to receive(:finalize!) order.next! end @@ -32,6 +34,8 @@ before { allow(order).to receive_messages process_payments!: false } it "should still complete the order" do + order.next + expect(order.state).to eq "confirmation" order.next expect(order.state).to eq "complete" end @@ -42,6 +46,8 @@ before { allow(order).to receive_messages process_payments!: false } it "can transition to complete" do + order.next + expect(order.state).to eq "confirmation" order.next expect(order.state).to eq "complete" end diff --git a/spec/models/spree/order/tax_spec.rb b/spec/models/spree/order/tax_spec.rb index 072e8999cd4..900720aa8c9 100644 --- a/spec/models/spree/order/tax_spec.rb +++ b/spec/models/spree/order/tax_spec.rb @@ -152,6 +152,10 @@ module Spree label: "legacy", originator_type: "Spree::TaxRate") } + before do + order.update(state: "payment") + end + it "removes any legacy tax adjustments on order" do order.create_tax_charge! diff --git a/spec/models/spree/order_spec.rb b/spec/models/spree/order_spec.rb index 97204b6db97..adaaf97f4ec 100644 --- a/spec/models/spree/order_spec.rb +++ b/spec/models/spree/order_spec.rb @@ -690,6 +690,7 @@ before do allow(order).to receive(:tax_zone) { shipping_tax_rate.zone } + order.update_attribute(:state, 'payment') order.reload order.create_tax_charge! end @@ -1269,7 +1270,8 @@ order.next! order.payments << create(:payment, order: order) - expect { order.next! }.to change { order.state }.from("payment").to("complete") + expect { order.next! }.to change { order.state }.from("payment").to("confirmation") + expect { order.next! }.to change { order.state }.from("confirmation").to("complete") end end @@ -1303,7 +1305,8 @@ it "skips the payment state" do advance_to_delivery_state(order) - expect { order.next! }.to change { order.state }.from("delivery").to("complete") + expect { order.next! }.to change { order.state }.from("delivery").to("confirmation") + expect { order.next! }.to change { order.state }.from("confirmation").to("complete") end end end diff --git a/spec/requests/checkout/routes_spec.rb b/spec/requests/checkout/routes_spec.rb index d0f37c5b6a7..d328542ae25 100644 --- a/spec/requests/checkout/routes_spec.rb +++ b/spec/requests/checkout/routes_spec.rb @@ -37,28 +37,13 @@ context "when getting the cart `/checkout/cart`" do let(:path) { "/checkout/cart" } - context "using the legacy checkout" do - it "do not redirect" do - get path - puts response.redirect_url - expect(response.status).to eq(200) - end - end - - context "using the split checkout" do - before do - # feature toggle is enabled - Flipper.enable(:split_checkout) - end - - it "redirect to the split checkout" do - get path - expect(response.status).to redirect_to("/checkout") + it "redirect to the split checkout" do + get path + expect(response.status).to redirect_to("/checkout") - # follow the redirect - get response.redirect_url - expect(response.status).to redirect_to("/checkout/details") - end + # follow the redirect + get response.redirect_url + expect(response.status).to redirect_to("/checkout/details") end end end diff --git a/spec/requests/voucher_adjustments_spec.rb b/spec/requests/voucher_adjustments_spec.rb index e663c1a6a9d..9154f7ea327 100644 --- a/spec/requests/voucher_adjustments_spec.rb +++ b/spec/requests/voucher_adjustments_spec.rb @@ -10,8 +10,6 @@ let!(:adjustment) { voucher.create_adjustment(voucher.code, order) } before do - Flipper.enable(:split_checkout) - # Make sure the order is created by the order user, the factory doesn't set ip properly order.created_by = user order.save! diff --git a/spec/services/checkout/form_data_adapter_spec.rb b/spec/services/checkout/form_data_adapter_spec.rb deleted file mode 100644 index 30aaab21384..00000000000 --- a/spec/services/checkout/form_data_adapter_spec.rb +++ /dev/null @@ -1,85 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -describe Checkout::FormDataAdapter do - describe '#params' do - let(:params) { { "order" => { "order_id" => "123" } } } - let(:order) { create(:order) } - let(:user) { create(:user) } - - let(:adapter) { Checkout::FormDataAdapter.new(params, order, user) } - - it "returns the :order item in the params provided" do - expect(adapter.params[:order]).to eq params["order"] - end - - describe "when payment_attributes are provided" do - before { params["order"]["payments_attributes"] = [{ "payment_method_id" => "123" }] } - - describe "and source attributes are provided" do - let(:source_attributes) { { "payment_method_name" => "Pay at the farm" } } - - before { params["payment_source"] = { "123" => source_attributes } } - - it "moves payment source attributes to the order payment attributes" do - expect(adapter.params[:order][:payments_attributes]. - first[:source_attributes]).to eq source_attributes - end - end - - describe "and order total is not zero" do - before { order.total = "50.0" } - - it "sets the payment attributes amount to the order total" do - expect(adapter.params[:order][:payments_attributes].first[:amount]).to eq order.total - end - end - - describe "and a credit card is provided" do - before do - params["order"]["payments_attributes"].first["source_attributes"] = - { "number" => "4444333322221111" } - end - - it "fills in missing credit card brand" do - expect(adapter.params[:order][:payments_attributes].first[:source_attributes][:cc_type]).to eq "visa" - end - - it "leaves an existing credit card brand" do - params["order"]["payments_attributes"].first["source_attributes"]["cc_type"] = "test" - expect(adapter.params[:order][:payments_attributes].first[:source_attributes][:cc_type]).to eq "test" - end - - it "doesn't touch the credit card brand without a number" do - params["order"]["payments_attributes"].first["source_attributes"]["number"] = "" - expect(adapter.params[:order][:payments_attributes].first[:source_attributes].key?(:cc_type)).to eq false - end - end - - describe "and existing credit card is provided" do - before { params["order"]["existing_card_id"] = credit_card.id } - - describe "and credit card is owned by current user" do - let(:credit_card) { create(:credit_card, user_id: user.id) } - - before { params["order"]["existing_card_id"] = credit_card.id } - - it "adds card details to payment attributes" do - expect(adapter.params[:order][:payments_attributes].first[:source][:id]).to eq credit_card.id - expect(adapter.params[:order][:payments_attributes]. - first[:source][:last_digits]).to eq credit_card.last_digits - end - end - - describe "and credit card is not owned by current user" do - let(:credit_card) { create(:credit_card) } - - it "raises exception if credit card provided doesnt belong to the current user" do - expect { adapter.params[:order] }.to raise_error Spree::Core::GatewayError - end - end - end - end - end -end diff --git a/spec/system/admin/reports_spec.rb b/spec/system/admin/reports_spec.rb index edde70b1e19..93e1eb4273f 100644 --- a/spec/system/admin/reports_spec.rb +++ b/spec/system/admin/reports_spec.rb @@ -578,7 +578,7 @@ } let(:order1) { create(:order, order_cycle: order_cycle, distributor: user1.enterprises.first, - shipments: [shipment], bill_address: bill_address) + shipments: [shipment], bill_address: bill_address, state: 'payment') } let(:product1) { create(:taxed_product, zone: zone, price: 12.54, tax_rate_amount: 0, sku: 'sku1') diff --git a/spec/system/consumer/shopping/cart_spec.rb b/spec/system/consumer/shopping/cart_spec.rb index 116041fe18b..270b84d728d 100644 --- a/spec/system/consumer/shopping/cart_spec.rb +++ b/spec/system/consumer/shopping/cart_spec.rb @@ -174,18 +174,6 @@ end end - describe "tax" do - before do - add_enterprise_fee enterprise_fee - add_product_to_cart order, product_with_tax - visit main_app.cart_path - end - - it "shows the total tax for the order, including product tax and tax on fees" do - expect(page).to have_selector '.tax-total', text: '11.00' # 10 + 1 - end - end - describe "updating quantities" do let(:li) { order.line_items.reload.last } let(:variant) { product_with_tax.variants.first } diff --git a/spec/system/consumer/shopping/checkout_auth_spec.rb b/spec/system/consumer/shopping/checkout_auth_spec.rb index 2808bb00984..b44deee4810 100644 --- a/spec/system/consumer/shopping/checkout_auth_spec.rb +++ b/spec/system/consumer/shopping/checkout_auth_spec.rb @@ -29,93 +29,51 @@ add_product_to_cart order, product end - shared_examples "with different checkout types" do |checkout_type| - context "on #{checkout_type}" do - it "does not render the login form when logged in" do - login_as user - visit checkout_path - within "section[role='main']" do - expect(page).to have_no_content "Login" - expect(page).to have_checkout_details - end + context "on split_checkout" do + it "does not render the login form when logged in" do + login_as user + visit checkout_path + within "section[role='main']" do + expect(page).to have_no_content "Login" + expect(page).to have_checkout_details + end + end + + it "renders the login buttons when logged out" do + visit checkout_path + within "section[role='main']" do + expect(page).to have_content "Login" + click_button "Login" end + expect(page).to have_login_modal + end - it "renders the login buttons when logged out" do + describe "logging in" do + before do visit checkout_path - within "section[role='main']" do - expect(page).to have_content "Login" - click_button "Login" - end + within("section[role='main']") { click_button "Login" } expect(page).to have_login_modal + fill_in "Email", with: user.email + fill_in "Password", with: user.password + within(".login-modal") { click_button 'Login' } end - describe "logging in" do - before do - visit checkout_path - within("section[role='main']") { click_button "Login" } - expect(page).to have_login_modal - fill_in "Email", with: user.email - fill_in "Password", with: user.password - within(".login-modal") { click_button 'Login' } - end - - context "and populating user details on (#{checkout_type})", - if: checkout_type.eql?("legacy_checkout") do - it "toggles the Details section" do - expect(page).to have_content "Your details" - page.find(:css, "i.ofn-i_052-point-down").click - end - end - - context "and populating user details on (#{checkout_type})", - if: checkout_type.eql?("split_checkout") do - it "should allow proceeding to the next step" do - expect(page).to have_content("Logged in successfully") - click_button "Next - Payment method" - expect(page).to have_button("Next - Order summary") - end + context "and populating user details on (split_checkout)" do + it "should allow proceeding to the next step" do + expect(page).to have_content("Logged in successfully") + click_button "Next - Payment method" + expect(page).to have_button("Next - Order summary") end end end end - describe "shared examples" do - context "legacy checkout" do - it_behaves_like "with different checkout types", "legacy_checkout" - end - - context "split checkout" do - before do - Flipper.enable(:split_checkout) - end - include_examples "with different checkout types", "split_checkout" - end - end - context "using the guest checkout" do it "allows user to checkout as guest" do visit checkout_path checkout_as_guest expect(page).to have_checkout_details end - - it "asks the user to log in if they are using a registered email" do - visit checkout_path - checkout_as_guest - - fill_in 'First Name', with: 'Not' - fill_in 'Last Name', with: 'Guest' - fill_in 'Email', with: user.email - fill_in 'Phone', with: '098712736' - - within '#details' do - click_button 'Next' - end - - expect(page).to have_selector 'div.login-modal' - expect(page).to have_content 'This email address is already registered. Please log in '\ - 'to continue, or go back and use another email address.' - end end end end diff --git a/spec/system/consumer/split_checkout_spec.rb b/spec/system/consumer/split_checkout_spec.rb index 59e428f2ded..f2939bb53e7 100644 --- a/spec/system/consumer/split_checkout_spec.rb +++ b/spec/system/consumer/split_checkout_spec.rb @@ -70,8 +70,6 @@ } before do - Flipper.enable(:split_checkout) - add_enterprise_fee enterprise_fee set_order order diff --git a/spec/system/consumer/split_checkout_tax_incl_spec.rb b/spec/system/consumer/split_checkout_tax_incl_spec.rb index b4935aca7c6..66edeff0080 100644 --- a/spec/system/consumer/split_checkout_tax_incl_spec.rb +++ b/spec/system/consumer/split_checkout_tax_incl_spec.rb @@ -82,158 +82,95 @@ end describe "for a customer with shipping address within the tax zone" do - context "on legacy checkout" do - before do - set_order order_within_zone - login_as(user_within_zone) - end - - it "will be charged tax on the order" do - visit checkout_path + before do + set_order order_within_zone + login_as(user_within_zone) + end - find(:xpath, '//*[@id="shipping"]/ng-form/dd').click - choose free_shipping.name.to_s + it "will be charged tax on the order" do + visit checkout_step_path(:details) - within "#payment" do - choose free_payment.name.to_s - end + choose "Delivery" - click_on "Place order now" + click_button "Next - Payment method" + click_on "Next - Order summary" + click_on "Complete order" - # UI checks - expect(page).to have_selector('#order_total', text: with_currency(10.00)) - expect(page).to have_selector('#tax-row', text: with_currency(1.15)) + # UI checks + expect(page).to have_content("Confirmed") + expect(page).to have_selector('#order_total', text: with_currency(10.00)) + expect(page).to have_selector('#tax-row', text: with_currency(1.15)) - # DB checks - assert_db_tax_incl - end + # DB checks + assert_db_tax_incl end - context "on split-checkout" do - before do - Flipper.enable(:split_checkout) - - set_order order_within_zone - login_as(user_within_zone) + context "when using a voucher" do + let!(:voucher) do + create(:voucher, code: 'some_code', enterprise: distributor, amount: 10) end - it "will be charged tax on the order" do + it "will include a tax included amount on the voucher adjustment" do visit checkout_step_path(:details) choose "Delivery" click_button "Next - Payment method" + + # add Voucher + fill_in "Enter voucher code", with: voucher.code + click_button("Apply") + + # Choose payment click_on "Next - Order summary" click_on "Complete order" # UI checks expect(page).to have_content("Confirmed") - expect(page).to have_selector('#order_total', text: with_currency(10.00)) + expect(page).to have_selector('#order_total', text: with_currency(0.00)) expect(page).to have_selector('#tax-row', text: with_currency(1.15)) - # DB checks - assert_db_tax_incl - end - - context "when using a voucher" do - let!(:voucher) do - create(:voucher, code: 'some_code', enterprise: distributor, amount: 10) + # Voucher + within "#line-items" do + expect(page).to have_content(voucher.code) + expect(page).to have_content(with_currency(-10.00)) end - it "will include a tax included amount on the voucher adjustment" do - visit checkout_step_path(:details) - - choose "Delivery" - - click_button "Next - Payment method" - - # add Voucher - fill_in "Enter voucher code", with: voucher.code - click_button("Apply") - - # Choose payment - click_on "Next - Order summary" - click_on "Complete order" + # DB check + order_within_zone.reload + voucher_adjustment = order_within_zone.voucher_adjustments.first - # UI checks - expect(page).to have_content("Confirmed") - expect(page).to have_selector('#order_total', text: with_currency(0.00)) - expect(page).to have_selector('#tax-row', text: with_currency(1.15)) - - # Voucher - within "#line-items" do - expect(page).to have_content(voucher.code) - expect(page).to have_content(with_currency(-10.00)) - end - - # DB check - order_within_zone.reload - voucher_adjustment = order_within_zone.voucher_adjustments.first - - expect(voucher_adjustment.amount.to_f).to eq(-10) - expect(voucher_adjustment.included_tax.to_f).to eq(-1.15) - end + expect(voucher_adjustment.amount.to_f).to eq(-10) + expect(voucher_adjustment.included_tax.to_f).to eq(-1.15) end end end describe "for a customer with shipping address outside the tax zone" do - context "on legacy checkout" do - before do - set_order order_outside_zone - login_as(user_outside_zone) - end - - it "will not be charged tax on the order" do - pending("#7540") - visit checkout_path - - find(:xpath, '//*[@id="shipping"]/ng-form/dd').click - choose free_shipping.name.to_s - - within "#payment" do - choose free_payment.name.to_s - end - - click_on "Place order now" - - # UI checks - expect(page).to have_selector('#order_total', text: with_currency(10.00)) - expect(page).not_to have_content("includes tax") - - # DB checks - assert_db_no_tax_incl - end + before do + set_order order_outside_zone + login_as(user_outside_zone) end - context "on split-checkout" do - before do - Flipper.enable(:split_checkout) - - set_order order_outside_zone - login_as(user_outside_zone) - end + it "will not be charged tax on the order" do + pending("#7540") + visit checkout_step_path(:details) - it "will not be charged tax on the order" do - pending("#7540") - visit checkout_step_path(:details) + choose "Delivery" + check "order_save_bill_address" + check "ship_address_same_as_billing" - choose "Delivery" - check "order_save_bill_address" - check "ship_address_same_as_billing" - - click_button "Next - Payment method" - click_on "Next - Order summary" - click_on "Complete order" + click_button "Next - Payment method" + click_on "Next - Order summary" + click_on "Complete order" - # UI checks - expect(page).to have_content("Confirmed") - expect(page).to have_selector('#order_total', text: with_currency(10.00)) - expect(page).not_to have_content("includes tax") + # UI checks + expect(page).to have_content("Confirmed") + expect(page).to have_selector('#order_total', text: with_currency(10.00)) + expect(page).not_to have_content("includes tax") - # DB checks - assert_db_no_tax_incl - end + # DB checks + assert_db_no_tax_incl end end end diff --git a/spec/system/consumer/split_checkout_tax_not_incl_spec.rb b/spec/system/consumer/split_checkout_tax_not_incl_spec.rb index 2b734adfe42..c7b0de4b614 100644 --- a/spec/system/consumer/split_checkout_tax_not_incl_spec.rb +++ b/spec/system/consumer/split_checkout_tax_not_incl_spec.rb @@ -88,207 +88,141 @@ end describe "for a customer with shipping address within the tax zone" do - context "on legacy checkout" do - before do - set_order order_within_zone - login_as(user_within_zone) - end + before do + set_order order_within_zone + login_as(user_within_zone) + end - it "will be charged tax on the order" do - visit checkout_path + it "will be charged tax on the order" do + visit checkout_step_path(:details) - find(:xpath, '//*[@id="shipping"]/ng-form/dd').click - choose free_shipping.name.to_s + choose "Delivery" - within "#payment" do - choose free_payment.name.to_s - end + click_button "Next - Payment method" + click_on "Next - Order summary" + click_on "Complete order" - click_on "Place order now" + # DB checks + order_within_zone.reload + expect(order_within_zone.additional_tax_total).to eq(1.3) - # DB checks - order_within_zone.reload - expect(order_within_zone.additional_tax_total).to eq(1.3) - - # UI checks - expect(page).to have_selector('#order_total', text: with_currency(11.30)) - expect(page).to have_selector('#tax-row', text: with_currency(1.30)) - end + # UI checks + expect(page).to have_content("Confirmed") + expect(page).to have_selector('#order_total', text: with_currency(11.30)) + expect(page).to have_selector('#tax-row', text: with_currency(1.30)) end - context "on split-checkout" do - before do - Flipper.enable(:split_checkout) - - set_order order_within_zone - login_as(user_within_zone) + context "when using a voucher" do + let!(:voucher) do + create(:voucher, code: 'some_code', enterprise: distributor, amount: 10) end - it "will be charged tax on the order" do + it "will include a tax included amount on the voucher adjustment" do visit checkout_step_path(:details) choose "Delivery" click_button "Next - Payment method" + # add Voucher + fill_in "Enter voucher code", with: voucher.code + click_button("Apply") + click_on "Next - Order summary" click_on "Complete order" - # DB checks - order_within_zone.reload - expect(order_within_zone.additional_tax_total).to eq(1.3) - # UI checks expect(page).to have_content("Confirmed") - expect(page).to have_selector('#order_total', text: with_currency(11.30)) + expect(page).to have_selector('#order_total', text: with_currency(1.30)) expect(page).to have_selector('#tax-row', text: with_currency(1.30)) - end - - context "when using a voucher" do - let!(:voucher) do - create(:voucher, code: 'some_code', enterprise: distributor, amount: 10) - end - - it "will include a tax included amount on the voucher adjustment" do - visit checkout_step_path(:details) - - choose "Delivery" - click_button "Next - Payment method" - # add Voucher - fill_in "Enter voucher code", with: voucher.code - click_button("Apply") + # Voucher + within "#line-items" do + expect(page).to have_content(voucher.code) + expect(page).to have_content(with_currency(-8.85)) - click_on "Next - Order summary" - click_on "Complete order" - - # UI checks - expect(page).to have_content("Confirmed") - expect(page).to have_selector('#order_total', text: with_currency(1.30)) - expect(page).to have_selector('#tax-row', text: with_currency(1.30)) - - # Voucher - within "#line-items" do - expect(page).to have_content(voucher.code) - expect(page).to have_content(with_currency(-8.85)) - - expect(page).to have_content("Tax #{voucher.code}") - expect(page).to have_content(with_currency(-1.15)) - end + expect(page).to have_content("Tax #{voucher.code}") + expect(page).to have_content(with_currency(-1.15)) + end - # DB check - order_within_zone.reload - voucher_adjustment = order_within_zone.voucher_adjustments.first - voucher_tax_adjustment = order_within_zone.voucher_adjustments.second + # DB check + order_within_zone.reload + voucher_adjustment = order_within_zone.voucher_adjustments.first + voucher_tax_adjustment = order_within_zone.voucher_adjustments.second - expect(voucher_adjustment.amount.to_f).to eq(-8.85) - expect(voucher_tax_adjustment.amount.to_f).to eq(-1.15) - end + expect(voucher_adjustment.amount.to_f).to eq(-8.85) + expect(voucher_tax_adjustment.amount.to_f).to eq(-1.15) end end end describe "for a customer with shipping address outside the tax zone" do - context "on legacy checkout" do - before do - set_order order_outside_zone - login_as(user_outside_zone) - end + before do + set_order order_outside_zone + login_as(user_outside_zone) + end - it "will not be charged tax on the order" do - visit checkout_path + it "will not be charged tax on the order" do + visit checkout_step_path(:details) - find(:xpath, '//*[@id="shipping"]/ng-form/dd').click - choose free_shipping.name.to_s + choose "Delivery" - within "#payment" do - choose free_payment.name.to_s - end + click_button "Next - Payment method" + click_on "Next - Order summary" + click_on "Complete order" - click_on "Place order now" + # DB checks + order_outside_zone.reload + expect(order_outside_zone.included_tax_total).to eq(0.0) + expect(order_outside_zone.additional_tax_total).to eq(0.0) - # DB checks - order_outside_zone.reload - expect(order_outside_zone.included_tax_total).to eq(0.0) - expect(order_outside_zone.additional_tax_total).to eq(0.0) - - # UI checks - expect(page).to have_content("Confirmed") - expect(page).to have_selector('#order_total', text: with_currency(10.00)) - expect(page).not_to have_content("includes tax") - end + # UI checks + expect(page).to have_content("Confirmed") + expect(page).to have_selector('#order_total', text: with_currency(10.00)) + expect(page).not_to have_content("includes tax") end - context "on split-checkout" do + # reproducing bug #9153 + context "changing the address on the /details step" do before do - Flipper.enable(:split_checkout) - - set_order order_outside_zone - login_as(user_outside_zone) - end - - it "will not be charged tax on the order" do visit checkout_step_path(:details) - choose "Delivery" click_button "Next - Payment method" click_on "Next - Order summary" - click_on "Complete order" - - # DB checks - order_outside_zone.reload - expect(order_outside_zone.included_tax_total).to eq(0.0) - expect(order_outside_zone.additional_tax_total).to eq(0.0) - # UI checks - expect(page).to have_content("Confirmed") expect(page).to have_selector('#order_total', text: with_currency(10.00)) - expect(page).not_to have_content("includes tax") - end - - # reproducing bug #9153 - context "changing the address on the /details step" do - before do - visit checkout_step_path(:details) - choose "Delivery" - click_button "Next - Payment method" - click_on "Next - Order summary" - - expect(page).to have_selector('#order_total', text: with_currency(10.00)) - - # customer goes back from Summary to Details step, to change Delivery - click_on "Your details" - end + # customer goes back from Summary to Details step, to change Delivery + click_on "Your details" + end - it "should re-calculate the tax accordingly" do - select "Victoria", from: "order_bill_address_attributes_state_id" + it "should re-calculate the tax accordingly" do + select "Victoria", from: "order_bill_address_attributes_state_id" - # it should not be necessary to save as new default bill address - check "order_save_bill_address" - check "ship_address_same_as_billing" + # it should not be necessary to save as new default bill address + check "order_save_bill_address" + check "ship_address_same_as_billing" - choose "Delivery" - click_button "Next - Payment method" + choose "Delivery" + click_button "Next - Payment method" - click_on "Next - Order summary" + click_on "Next - Order summary" - # Summary step should reflect changes - expect(page).to have_selector('#order_total', text: with_currency(11.30)) - expect(page).to have_selector('#tax-row', text: with_currency(1.30)) + # Summary step should reflect changes + expect(page).to have_selector('#order_total', text: with_currency(11.30)) + expect(page).to have_selector('#tax-row', text: with_currency(1.30)) - click_on "Complete order" + click_on "Complete order" - # DB checks - order_outside_zone.reload - expect(order_outside_zone.included_tax_total).to eq(0.0) - expect(order_outside_zone.additional_tax_total).to eq(1.3) + # DB checks + order_outside_zone.reload + expect(order_outside_zone.included_tax_total).to eq(0.0) + expect(order_outside_zone.additional_tax_total).to eq(1.3) - # UI checks - Order confirmation page should reflect changes - expect(page).to have_content("Confirmed") - expect(page).to have_selector('#order_total', text: with_currency(11.30)) - expect(page).to have_selector('#tax-row', text: with_currency(1.30)) - end + # UI checks - Order confirmation page should reflect changes + expect(page).to have_content("Confirmed") + expect(page).to have_selector('#order_total', text: with_currency(11.30)) + expect(page).to have_selector('#tax-row', text: with_currency(1.30)) end end end diff --git a/spec/system/consumer/white_label_spec.rb b/spec/system/consumer/white_label_spec.rb index 0597ff5d684..712f3db3027 100644 --- a/spec/system/consumer/white_label_spec.rb +++ b/spec/system/consumer/white_label_spec.rb @@ -145,7 +145,7 @@ set_order(order) end - shared_examples "hides the OFN navigation when needed only for the checkout" do + context "when the split checkout is enabled" do it_behaves_like "hides the OFN navigation when needed only" context "for cart path" do @@ -174,18 +174,6 @@ it_behaves_like "hides the OFN navigation for mobile view as well" end end - - context "when the split checkout is disabled" do - it_behaves_like "hides the OFN navigation when needed only for the checkout" - end - - context "when the split checkout is enabled" do - before do - Flipper.enable(:split_checkout) - end - - it_behaves_like "hides the OFN navigation when needed only for the checkout" - end end context "when the user has a complete order" do From 7e84579aa37954a9528c15ee35a4505cf27db7b0 Mon Sep 17 00:00:00 2001 From: Mohamed ABDELLANI Date: Fri, 2 Jun 2023 15:00:23 +0100 Subject: [PATCH 05/16] spec/system/consumer/shopping/checkout_stripe_spec these tests are using the legacy checkout --- spec/support/request/stripe_helper.rb | 13 - .../consumer/shopping/checkout_stripe_spec.rb | 222 ------------------ 2 files changed, 235 deletions(-) delete mode 100644 spec/system/consumer/shopping/checkout_stripe_spec.rb diff --git a/spec/support/request/stripe_helper.rb b/spec/support/request/stripe_helper.rb index 3aeef17e43e..b8827efcaaa 100644 --- a/spec/support/request/stripe_helper.rb +++ b/spec/support/request/stripe_helper.rb @@ -1,19 +1,6 @@ # frozen_string_literal: true module StripeHelper - def checkout_with_stripe(guest_checkout: true, remember_card: false) - visit checkout_path - checkout_as_guest if guest_checkout - fill_out_form( - free_shipping.name, - stripe_sca_payment_method.name, - save_default_addresses: false - ) - fill_out_card_details - check "Remember this card?" if remember_card - place_order - end - def fill_out_card_details fill_in "stripe-cardnumber", with: '4242424242424242' fill_in "exp-date", with: "01/#{DateTime.now.year + 1}" diff --git a/spec/system/consumer/shopping/checkout_stripe_spec.rb b/spec/system/consumer/shopping/checkout_stripe_spec.rb deleted file mode 100644 index c46a0c86376..00000000000 --- a/spec/system/consumer/shopping/checkout_stripe_spec.rb +++ /dev/null @@ -1,222 +0,0 @@ -# frozen_string_literal: true - -require 'system_helper' - -describe "Check out with Stripe" do - include AuthenticationHelper - include ShopWorkflow - include CheckoutRequestsHelper - include StripeHelper - include StripeStubs - - let(:distributor) { create(:distributor_enterprise) } - let!(:order_cycle) { - create(:simple_order_cycle, distributors: [distributor], variants: [variant]) - } - let(:product) { create(:product, price: 10) } - let(:variant) { product.variants.first } - let(:order) { - create(:order, order_cycle: order_cycle, distributor: distributor, bill_address_id: nil, - ship_address_id: nil) - } - - let(:shipping_with_fee) { - create(:shipping_method, require_ship_address: false, name: "Donkeys", - calculator: Calculator::FlatRate.new(preferred_amount: 4.56)) - } - let(:free_shipping) { create(:shipping_method) } - let!(:check_with_fee) { - create(:payment_method, distributors: [distributor], - calculator: Calculator::FlatRate.new(preferred_amount: 5.67)) - } - - around do |example| - with_stripe_setup { example.run } - end - - before do - stripe_enable - set_order order - add_product_to_cart order, product - distributor.shipping_methods << [shipping_with_fee, free_shipping] - end - - describe "using Stripe SCA" do - let!(:stripe_account) { create(:stripe_account, enterprise: distributor) } - let!(:stripe_sca_payment_method) { - create(:stripe_sca_payment_method, distributors: [distributor]) - } - let!(:shipping_method) { create(:shipping_method) } - let(:error_message) { "Card was declined: insufficient funds." } - - before do - stub_payment_intent_get_request - stub_payment_methods_post_request - end - - context "with guest checkout" do - before do - stub_retrieve_payment_method_request("pm_123") - stub_list_customers_request(email: order.user.email, response: {}) - stub_get_customer_payment_methods_request(customer: "cus_A456", response: {}) - end - - context "when the card is accepted" do - before do - stub_payment_intents_post_request order: order - stub_successful_capture_request order: order - end - - it "completes checkout successfully" do - checkout_with_stripe - - expect(page).to have_content "Confirmed" - expect(order.reload.completed?).to eq true - expect(order.payments.first.state).to eq "completed" - end - end - - context "when the card is rejected" do - before do - stub_payment_intents_post_request order: order - stub_failed_capture_request order: order, response: { message: error_message } - end - - it "shows an error message from the Stripe response" do - checkout_with_stripe - - expect(page).to have_content error_message - expect(order.reload.state).to eq "cart" - expect(order.payments.first.state).to eq "failed" - end - end - - context "when the card needs extra SCA authorization" do - before do - stripe_redirect_url = checkout_path(payment_intent: "pi_123") - stub_payment_intents_post_request_with_redirect order: order, - redirect_url: stripe_redirect_url - end - - describe "and the authorization succeeds" do - before do - stub_successful_capture_request order: order - end - - it "completes checkout successfully" do - checkout_with_stripe - - # We make stripe return stripe_redirect_url (which is already sending the user back - # to the checkout) as if the authorization was done. We can then control the actual - # authorization or failure of the payment through the mock - # stub_successful_capture_request - - expect(page).to have_content "Confirmed" - expect(order.reload.completed?).to eq true - expect(order.payments.first.state).to eq "completed" - end - end - - describe "and the authorization fails" do - before do - stub_failed_capture_request order: order, response: { message: error_message } - end - - it "shows an error message from the Stripe response" do - checkout_with_stripe - - # We make stripe return stripe_redirect_url (which is already sending the user back to - # the checkout) as if the authorization was done. We can then control the actual - # authorization or failure of the payment through the mock stub_failed_capture_request - expect(page).to have_content error_message - expect(order.reload.state).to eq "cart" - expect(order.payments.first.state).to eq "failed" - end - end - end - - context "with multiple payment attempts; one failed and one succeeded" do - before do - stub_payment_intents_post_request order: order - end - - it "records failed payment attempt and allows order completion" do - # First payment attempt is rejected - stub_failed_capture_request(order: order, response: { message: error_message }) - checkout_with_stripe - expect(page).to have_content error_message - - expect(order.reload.payments.count).to eq 1 - expect(order.state).to eq "cart" - expect(order.payments.first.state).to eq "failed" - - # Second payment attempt is accepted - stub_successful_capture_request order: order - place_order - expect(page).to have_content "Confirmed" - - expect(order.reload.payments.count).to eq 2 - expect(order.state).to eq "complete" - expect(order.payments.last.state).to eq "completed" - end - end - end - - context "with a logged in user" do - let(:user) { order.user } - - before do - login_as user - end - - context "saving a card and re-using it" do - before do - stub_retrieve_payment_method_request("pm_123") - stub_list_customers_request(email: order.user.email, response: {}) - stub_get_customer_payment_methods_request(customer: "cus_A456", response: {}) - stub_get_customer_payment_methods_request(customer: "cus_A123", response: {}) - stub_payment_methods_post_request( - request: { payment_method: "pm_123", customer: "cus_A123" }, - response: { pm_id: "pm_123" } - ) - stub_add_metadata_request(payment_method: "pm_123", response: {}) - stub_payment_intents_post_request order: order - stub_successful_capture_request order: order - stub_customers_post_request email: "test@test.com" # First checkout with default details - stub_customers_post_request email: user.email # Second checkout with saved user details - stub_payment_method_attach_request - end - - it "allows saving a card and re-using it" do - checkout_with_stripe guest_checkout: false, remember_card: true - - expect(page).to have_content "Confirmed" - expect(order.reload.completed?).to eq true - expect(order.payments.first.state).to eq "completed" - - # Verify card has been saved with correct stripe IDs - user_credit_card = order.reload.user.credit_cards.first - expect(user_credit_card.gateway_payment_profile_id).to eq "pm_123" - expect(user_credit_card.gateway_customer_profile_id).to eq "cus_A123" - - # Prepare a second order - new_order = create(:order, user: user, order_cycle: order_cycle, - distributor: distributor, bill_address_id: nil, - ship_address_id: nil) - set_order(new_order) - add_product_to_cart(new_order, product, quantity: 10) - stub_payment_intents_post_request order: new_order - stub_successful_capture_request order: new_order - - # Checkout with saved card - visit checkout_path - choose free_shipping.name - choose stripe_sca_payment_method.name - expect(page).to have_content "Use a saved card" - expect(page).to have_select 'selected_card', selected: "Visa x-4242 Exp:10/2050" - place_order - end - end - end - end -end From 905187f3ce7127e41fa3ea7a08dd8847f152f3e0 Mon Sep 17 00:00:00 2001 From: Mohamed ABDELLANI Date: Fri, 2 Jun 2023 15:03:28 +0100 Subject: [PATCH 06/16] fix ./spec/services/order_tax_adjustments_fetcher_spec.rb:100 --- spec/services/order_tax_adjustments_fetcher_spec.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/spec/services/order_tax_adjustments_fetcher_spec.rb b/spec/services/order_tax_adjustments_fetcher_spec.rb index b8e9bb74700..7b91f4ee1dc 100644 --- a/spec/services/order_tax_adjustments_fetcher_spec.rb +++ b/spec/services/order_tax_adjustments_fetcher_spec.rb @@ -72,7 +72,8 @@ line_items: [line_item1, line_item2], bill_address: create(:address), order_cycle: order_cycle, - distributor: coordinator + distributor: coordinator, + state: 'payment' ) end let(:shipping_method) do From 56204b2315533b739e8eab476050803448488e58 Mon Sep 17 00:00:00 2001 From: Mohamed ABDELLANI Date: Fri, 2 Jun 2023 15:19:49 +0100 Subject: [PATCH 07/16] fix ./spec/routing/stripe_spec.rb --- spec/routing/stripe_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/routing/stripe_spec.rb b/spec/routing/stripe_spec.rb index b4f5c4b7d75..31eddad5534 100644 --- a/spec/routing/stripe_spec.rb +++ b/spec/routing/stripe_spec.rb @@ -6,12 +6,12 @@ context "checkout return URLs" do it "routes /checkout to checkout#edit" do expect(get: "checkout"). - to route_to("checkout#edit") + to route_to("split_checkout#edit") end it "routes /checkout?test=123 to checkout#edit" do expect(get: "/checkout?test=123"). - to route_to(controller: "checkout", action: "edit", test: "123") + to route_to(controller: "split_checkout", action: "edit", test: "123") end it "routes /checkout?payment_intent=pm_123 to payment_gateways/stripe#confirm" do From 78617905c62d7542a3ddf6f477c84569d426f4bd Mon Sep 17 00:00:00 2001 From: Mohamed ABDELLANI Date: Fri, 2 Jun 2023 16:34:02 +0100 Subject: [PATCH 08/16] remove spec/requests/checkout/concurrency_spec.rb --- spec/requests/checkout/concurrency_spec.rb | 99 ---------------------- 1 file changed, 99 deletions(-) delete mode 100644 spec/requests/checkout/concurrency_spec.rb diff --git a/spec/requests/checkout/concurrency_spec.rb b/spec/requests/checkout/concurrency_spec.rb deleted file mode 100644 index a087aed67b9..00000000000 --- a/spec/requests/checkout/concurrency_spec.rb +++ /dev/null @@ -1,99 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -# This is the first example of testing concurrency in the Open Food Network. -# If we want to do this more often, we should look at: -# -# https://github.com/forkbreak/fork_break -# -# The concurrency flag enables multiple threads to see the same database -# without isolated transactions. -describe "Concurrent checkouts", concurrency: true, type: :request do - include AuthenticationHelper - include ShopWorkflow - - let(:order_cycle) { create(:order_cycle) } - let(:distributor) { order_cycle.distributors.first } - let(:order) { create(:order, order_cycle: order_cycle, distributor: distributor) } - let(:address) { create(:address) } - let(:payment_method) { create(:payment_method, distributors: [distributor]) } - let(:breakpoint) { Mutex.new } - - let(:address_params) { address.attributes.except("id") } - let(:order_params) { - { - "payments_attributes" => [ - { - "payment_method_id" => payment_method.id, - "amount" => order.total - } - ], - "bill_address_attributes" => address_params, - "ship_address_attributes" => address_params, - } - } - let(:params) { { format: :json, order: order_params } } - - before do - # Create a valid order ready for checkout: - create(:shipping_method, distributors: [distributor]) - variant = order_cycle.variants_distributed_by(distributor).first - order.line_items << create(:line_item, variant: variant) - - set_order(order) - login_as(order.user) - end - - it "handles two concurrent orders successfully" do - breakpoint.lock - breakpoint_reached_counter = 0 - - # Set a breakpoint after loading the order and before advancing the order's - # state and making payments. If two requests reach this breakpoint at the - # same time, they are in a race condition and bad things can happen. - # Examples are processing payments twice or selling more than we have. - allow_any_instance_of(CheckoutController). - to receive(:checkout_workflow). - and_wrap_original do |method, *args| - - breakpoint_reached_counter += 1 - breakpoint.synchronize {} - method.call(*args) - end - - # Starting two checkout threads. The controller code will determine if - # these two threads are synchronised correctly or run into a race condition. - # - # 1. If the controller synchronises correctly: - # The first thread locks required resources and then waits at the - # breakpoint. The second thread waits for the first one. - # 2. If the controller fails to prevent the race condition: - # Both threads load required resources and wait at the breakpoint to do - # the same checkout action. - threads = [ - Thread.new { put update_checkout_path, params: params }, - Thread.new { put update_checkout_path, params: params }, - ] - - # Wait for the first thread to reach the breakpoint: - Timeout.timeout(1) do - sleep 0.1 while breakpoint_reached_counter < 1 - end - - # Give the second thread a chance to reach the breakpoint, too. - # But we hope that it waits for the first thread earlier and doesn't - # reach the breakpoint yet. - sleep 1 - expect(breakpoint_reached_counter).to eq 1 - - # Let the requests continue and finish. - breakpoint.unlock - threads.each(&:join) - - # Verify that the checkout happened once. - order.reload - expect(order.completed?).to be true - expect(order.payments.count).to eq 1 - end -end From 345f54072374854273393d6e3b45e965f78f3f37 Mon Sep 17 00:00:00 2001 From: Mohamed ABDELLANI Date: Fri, 2 Jun 2023 16:41:21 +0100 Subject: [PATCH 09/16] fix spec/models/spree/tax_rate_spec.rb --- spec/models/spree/tax_rate_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/models/spree/tax_rate_spec.rb b/spec/models/spree/tax_rate_spec.rb index 60766a42845..a9daf8b683a 100644 --- a/spec/models/spree/tax_rate_spec.rb +++ b/spec/models/spree/tax_rate_spec.rb @@ -301,7 +301,7 @@ module Spree tax_category: @category, zone: @zone ) - @order = Spree::Order.create! + @order = Spree::Order.create!(state: 'payment') @taxable = create(:product, tax_category: @category) @nontaxable = create(:product, tax_category: @category2) end From 5487aa19fcfefb92a3bd60eaf48fa989e97c627e Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Fri, 2 Jun 2023 14:22:18 +0100 Subject: [PATCH 10/16] Fix missing checkout_state_path --- app/controllers/payment_gateways/paypal_controller.rb | 4 ++-- app/controllers/spree/orders_controller.rb | 2 +- .../payment_gateways/paypal_controller_spec.rb | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/app/controllers/payment_gateways/paypal_controller.rb b/app/controllers/payment_gateways/paypal_controller.rb index c0c41fd77de..ab5ed51a428 100644 --- a/app/controllers/payment_gateways/paypal_controller.rb +++ b/app/controllers/payment_gateways/paypal_controller.rb @@ -29,11 +29,11 @@ def express flash[:error] = Spree.t('flash.generic_error', scope: 'paypal', reasons: pp_response.errors.map(&:long_message).join(" ")) - redirect_to main_app.checkout_state_path(:payment) + redirect_to main_app.checkout_step_path(:payment) end rescue SocketError flash[:error] = Spree.t('flash.connection_failed', scope: 'paypal') - redirect_to main_app.checkout_state_path(:payment) + redirect_to main_app.checkout_step_path(:payment) end end diff --git a/app/controllers/spree/orders_controller.rb b/app/controllers/spree/orders_controller.rb index ded1115e754..01779e11cbc 100644 --- a/app/controllers/spree/orders_controller.rb +++ b/app/controllers/spree/orders_controller.rb @@ -78,7 +78,7 @@ def update format.html do if params.key?(:checkout) @order.next_transition.run_callbacks if @order.cart? - redirect_to main_app.checkout_state_path(@order.checkout_steps.first) + redirect_to main_app.checkout_step_path(@order.checkout_steps.first) elsif @order.complete? redirect_to main_app.order_path(@order) else diff --git a/spec/controllers/payment_gateways/paypal_controller_spec.rb b/spec/controllers/payment_gateways/paypal_controller_spec.rb index 79b26849e0a..25152eb2b99 100644 --- a/spec/controllers/payment_gateways/paypal_controller_spec.rb +++ b/spec/controllers/payment_gateways/paypal_controller_spec.rb @@ -88,8 +88,8 @@ module PaymentGateways context "when processing fails" do let(:response) { false } - it "redirects to checkout_state_path with a flash error" do - expect(post(:express)).to redirect_to checkout_state_path(:payment) + it "redirects to checkout_step_path with a flash error" do + expect(post(:express)).to redirect_to checkout_step_path(:payment) expect(flash[:error]).to eq "PayPal failed. " end end @@ -99,8 +99,8 @@ module PaymentGateways allow(response_mock).to receive(:success?).and_raise(SocketError) end - it "redirects to checkout_state_path with a flash error" do - expect(post(:express)).to redirect_to checkout_state_path(:payment) + it "redirects to checkout_step_path with a flash error" do + expect(post(:express)).to redirect_to checkout_step_path(:payment) expect(flash[:error]).to eq "Could not connect to PayPal." end end From 0e289a23c1d90f274cd7d6b5eb4ccfd31c8d758f Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Sat, 3 Jun 2023 11:41:05 +0100 Subject: [PATCH 11/16] Set some legacy checkout specs that we might want to rewrite later to pending --- .../requests/checkout/failed_checkout_spec.rb | 2 +- spec/requests/checkout/stripe_sca_spec.rb | 4 +- spec/system/consumer/multilingual_spec.rb | 7 - .../consumer/shopping/checkout_paypal_spec.rb | 6 +- .../system/consumer/shopping/checkout_spec.rb | 6 +- .../consumer/shopping/checkout_stripe_spec.rb | 222 ++++++++++++++++++ .../shopping/variant_overrides_spec.rb | 18 +- 7 files changed, 241 insertions(+), 24 deletions(-) create mode 100644 spec/system/consumer/shopping/checkout_stripe_spec.rb diff --git a/spec/requests/checkout/failed_checkout_spec.rb b/spec/requests/checkout/failed_checkout_spec.rb index 28516596050..25c98f7bcd5 100644 --- a/spec/requests/checkout/failed_checkout_spec.rb +++ b/spec/requests/checkout/failed_checkout_spec.rb @@ -44,7 +44,7 @@ set_order order end - context "when shipping and payment fees apply" do + pending "when shipping and payment fees apply" do let(:calculator) { Calculator::FlatPercentItemTotal.new(preferred_flat_percent: 10) } before do diff --git a/spec/requests/checkout/stripe_sca_spec.rb b/spec/requests/checkout/stripe_sca_spec.rb index 4bae1defa6d..517fec564f5 100644 --- a/spec/requests/checkout/stripe_sca_spec.rb +++ b/spec/requests/checkout/stripe_sca_spec.rb @@ -114,7 +114,7 @@ stub_add_metadata_request(payment_method: "pm_456", response: {}) end - context "when the user submits a new card and doesn't request that the card is saved for later" do + pending "when the user submits a new card and doesn't request that the card is saved for later" do let(:hubs_payment_method_response_mock) do { status: 200, body: JSON.generate(id: hubs_stripe_payment_method) } end @@ -161,7 +161,7 @@ end end - context "when saving a card or using a stored card is involved" do + pending "when saving a card or using a stored card is involved" do let(:hubs_payment_method_response_mock) do { status: 200, diff --git a/spec/system/consumer/multilingual_spec.rb b/spec/system/consumer/multilingual_spec.rb index 66a94431fcc..1ce556a2f2e 100644 --- a/spec/system/consumer/multilingual_spec.rb +++ b/spec/system/consumer/multilingual_spec.rb @@ -61,13 +61,6 @@ expect_menu_and_cookie_in_es expect(page).to have_content 'Precio' end - - it "in the checkout page" do - visit checkout_path(locale: 'es') - - expect_menu_and_cookie_in_es - expect(page).to have_content 'Total del carrito' - end end end diff --git a/spec/system/consumer/shopping/checkout_paypal_spec.rb b/spec/system/consumer/shopping/checkout_paypal_spec.rb index 8cc040d337f..8a5e232cb8f 100644 --- a/spec/system/consumer/shopping/checkout_paypal_spec.rb +++ b/spec/system/consumer/shopping/checkout_paypal_spec.rb @@ -47,7 +47,7 @@ end shared_examples "checking out with paypal" do |user_type| - context user_type.to_s do + pending user_type.to_s do before do fill_out_details fill_out_form(free_shipping.name, paypal.name, save_default_addresses: false) @@ -82,7 +82,7 @@ end describe "shared_examples" do - context "as a guest user" do + pending "as a guest user" do before do visit checkout_path checkout_as_guest @@ -90,7 +90,7 @@ it_behaves_like "checking out with paypal", "as guest" end - context "as a logged in user" do + pending "as a logged in user" do before do login_as user visit checkout_path diff --git a/spec/system/consumer/shopping/checkout_spec.rb b/spec/system/consumer/shopping/checkout_spec.rb index 077ad9d51d0..6de138b04d6 100644 --- a/spec/system/consumer/shopping/checkout_spec.rb +++ b/spec/system/consumer/shopping/checkout_spec.rb @@ -71,7 +71,7 @@ distributor.shipping_methods << tagged_shipping end - describe "when I have an out of stock product in my cart" do + pending "when I have an out of stock product in my cart" do before do variant.on_demand = false variant.on_hand = 0 @@ -87,7 +87,7 @@ end end - context 'login in as user' do + pending 'login in as user' do let(:user) { create(:user) } let(:pdf_upload) { Rack::Test::UploadedFile.new( @@ -335,7 +335,7 @@ end end - context "guest checkout" do + pending "guest checkout" do before do visit checkout_path checkout_as_guest diff --git a/spec/system/consumer/shopping/checkout_stripe_spec.rb b/spec/system/consumer/shopping/checkout_stripe_spec.rb new file mode 100644 index 00000000000..ae62de53ae4 --- /dev/null +++ b/spec/system/consumer/shopping/checkout_stripe_spec.rb @@ -0,0 +1,222 @@ +# frozen_string_literal: true + +require 'system_helper' + +describe "Check out with Stripe" do + include AuthenticationHelper + include ShopWorkflow + include CheckoutRequestsHelper + include StripeHelper + include StripeStubs + + let(:distributor) { create(:distributor_enterprise) } + let!(:order_cycle) { + create(:simple_order_cycle, distributors: [distributor], variants: [variant]) + } + let(:product) { create(:product, price: 10) } + let(:variant) { product.variants.first } + let(:order) { + create(:order, order_cycle: order_cycle, distributor: distributor, bill_address_id: nil, + ship_address_id: nil) + } + + let(:shipping_with_fee) { + create(:shipping_method, require_ship_address: false, name: "Donkeys", + calculator: Calculator::FlatRate.new(preferred_amount: 4.56)) + } + let(:free_shipping) { create(:shipping_method) } + let!(:check_with_fee) { + create(:payment_method, distributors: [distributor], + calculator: Calculator::FlatRate.new(preferred_amount: 5.67)) + } + + around do |example| + with_stripe_setup { example.run } + end + + before do + stripe_enable + set_order order + add_product_to_cart order, product + distributor.shipping_methods << [shipping_with_fee, free_shipping] + end + + pending "using Stripe SCA" do + let!(:stripe_account) { create(:stripe_account, enterprise: distributor) } + let!(:stripe_sca_payment_method) { + create(:stripe_sca_payment_method, distributors: [distributor]) + } + let!(:shipping_method) { create(:shipping_method) } + let(:error_message) { "Card was declined: insufficient funds." } + + before do + stub_payment_intent_get_request + stub_payment_methods_post_request + end + + context "with guest checkout" do + before do + stub_retrieve_payment_method_request("pm_123") + stub_list_customers_request(email: order.user.email, response: {}) + stub_get_customer_payment_methods_request(customer: "cus_A456", response: {}) + end + + context "when the card is accepted" do + before do + stub_payment_intents_post_request order: order + stub_successful_capture_request order: order + end + + it "completes checkout successfully" do + checkout_with_stripe + + expect(page).to have_content "Confirmed" + expect(order.reload.completed?).to eq true + expect(order.payments.first.state).to eq "completed" + end + end + + context "when the card is rejected" do + before do + stub_payment_intents_post_request order: order + stub_failed_capture_request order: order, response: { message: error_message } + end + + it "shows an error message from the Stripe response" do + checkout_with_stripe + + expect(page).to have_content error_message + expect(order.reload.state).to eq "cart" + expect(order.payments.first.state).to eq "failed" + end + end + + context "when the card needs extra SCA authorization" do + before do + stripe_redirect_url = checkout_path(payment_intent: "pi_123") + stub_payment_intents_post_request_with_redirect order: order, + redirect_url: stripe_redirect_url + end + + describe "and the authorization succeeds" do + before do + stub_successful_capture_request order: order + end + + it "completes checkout successfully" do + checkout_with_stripe + + # We make stripe return stripe_redirect_url (which is already sending the user back + # to the checkout) as if the authorization was done. We can then control the actual + # authorization or failure of the payment through the mock + # stub_successful_capture_request + + expect(page).to have_content "Confirmed" + expect(order.reload.completed?).to eq true + expect(order.payments.first.state).to eq "completed" + end + end + + describe "and the authorization fails" do + before do + stub_failed_capture_request order: order, response: { message: error_message } + end + + it "shows an error message from the Stripe response" do + checkout_with_stripe + + # We make stripe return stripe_redirect_url (which is already sending the user back to + # the checkout) as if the authorization was done. We can then control the actual + # authorization or failure of the payment through the mock stub_failed_capture_request + expect(page).to have_content error_message + expect(order.reload.state).to eq "cart" + expect(order.payments.first.state).to eq "failed" + end + end + end + + context "with multiple payment attempts; one failed and one succeeded" do + before do + stub_payment_intents_post_request order: order + end + + it "records failed payment attempt and allows order completion" do + # First payment attempt is rejected + stub_failed_capture_request(order: order, response: { message: error_message }) + checkout_with_stripe + expect(page).to have_content error_message + + expect(order.reload.payments.count).to eq 1 + expect(order.state).to eq "cart" + expect(order.payments.first.state).to eq "failed" + + # Second payment attempt is accepted + stub_successful_capture_request order: order + place_order + expect(page).to have_content "Confirmed" + + expect(order.reload.payments.count).to eq 2 + expect(order.state).to eq "complete" + expect(order.payments.last.state).to eq "completed" + end + end + end + + context "with a logged in user" do + let(:user) { order.user } + + before do + login_as user + end + + context "saving a card and re-using it" do + before do + stub_retrieve_payment_method_request("pm_123") + stub_list_customers_request(email: order.user.email, response: {}) + stub_get_customer_payment_methods_request(customer: "cus_A456", response: {}) + stub_get_customer_payment_methods_request(customer: "cus_A123", response: {}) + stub_payment_methods_post_request( + request: { payment_method: "pm_123", customer: "cus_A123" }, + response: { pm_id: "pm_123" } + ) + stub_add_metadata_request(payment_method: "pm_123", response: {}) + stub_payment_intents_post_request order: order + stub_successful_capture_request order: order + stub_customers_post_request email: "test@test.com" # First checkout with default details + stub_customers_post_request email: user.email # Second checkout with saved user details + stub_payment_method_attach_request + end + + it "allows saving a card and re-using it" do + checkout_with_stripe guest_checkout: false, remember_card: true + + expect(page).to have_content "Confirmed" + expect(order.reload.completed?).to eq true + expect(order.payments.first.state).to eq "completed" + + # Verify card has been saved with correct stripe IDs + user_credit_card = order.reload.user.credit_cards.first + expect(user_credit_card.gateway_payment_profile_id).to eq "pm_123" + expect(user_credit_card.gateway_customer_profile_id).to eq "cus_A123" + + # Prepare a second order + new_order = create(:order, user: user, order_cycle: order_cycle, + distributor: distributor, bill_address_id: nil, + ship_address_id: nil) + set_order(new_order) + add_product_to_cart(new_order, product, quantity: 10) + stub_payment_intents_post_request order: new_order + stub_successful_capture_request order: new_order + + # Checkout with saved card + visit checkout_path + choose free_shipping.name + choose stripe_sca_payment_method.name + expect(page).to have_content "Use a saved card" + expect(page).to have_select 'selected_card', selected: "Visa x-4242 Exp:10/2050" + place_order + end + end + end + end +end diff --git a/spec/system/consumer/shopping/variant_overrides_spec.rb b/spec/system/consumer/shopping/variant_overrides_spec.rb index 05f89716f1a..a0512ef3b23 100644 --- a/spec/system/consumer/shopping/variant_overrides_spec.rb +++ b/spec/system/consumer/shopping/variant_overrides_spec.rb @@ -150,17 +150,19 @@ expect(page).to have_selector "#edit-cart .grand-total", text: with_currency(122.22) end - it "shows the correct prices in the checkout" do - click_add_to_cart product1_variant1, 2 - click_checkout - - expect(page).to have_selector 'form.edit_order .cart-total', text: with_currency(122.22) - expect(page).to have_selector 'form.edit_order .shipping', text: with_currency(0.00) - expect(page).to have_selector 'form.edit_order .total', text: with_currency(122.22) + pending "prices in the checkout" do + it "shows the correct prices" do + click_add_to_cart product1_variant1, 2 + click_checkout + + expect(page).to have_selector 'form.edit_order .cart-total', text: with_currency(122.22) + expect(page).to have_selector 'form.edit_order .shipping', text: with_currency(0.00) + expect(page).to have_selector 'form.edit_order .total', text: with_currency(122.22) + end end end - describe "creating orders" do + pending "creating orders" do it "creates the order with the correct prices" do click_add_to_cart product1_variant1, 2 click_checkout From d5a625bdeb32089863dbd007f4d57f1a9ff1347d Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Sat, 3 Jun 2023 11:41:56 +0100 Subject: [PATCH 12/16] Fix Paypal spec --- spec/requests/checkout/paypal_spec.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/spec/requests/checkout/paypal_spec.rb b/spec/requests/checkout/paypal_spec.rb index 682a27e57fc..33f4cbf27a6 100644 --- a/spec/requests/checkout/paypal_spec.rb +++ b/spec/requests/checkout/paypal_spec.rb @@ -46,6 +46,7 @@ payment_method.calculator = calculator payment_method.save! order.payments.create!(payment_method_id: payment_method.id, amount: order.total) + order.next end it "destroys the old payment and processes the order" do From 8d633234f4efa1f92a1ec1249fb311eb69ab9bbf Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Sat, 3 Jun 2023 11:47:34 +0100 Subject: [PATCH 13/16] Set voucher specs to pending temporarily --- spec/system/consumer/split_checkout_tax_not_incl_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/system/consumer/split_checkout_tax_not_incl_spec.rb b/spec/system/consumer/split_checkout_tax_not_incl_spec.rb index c7b0de4b614..b899f5d01de 100644 --- a/spec/system/consumer/split_checkout_tax_not_incl_spec.rb +++ b/spec/system/consumer/split_checkout_tax_not_incl_spec.rb @@ -62,7 +62,7 @@ Spree::Config.set(tax_using_ship_address: true) end - describe "a not-included tax" do + pending "a not-included tax" do before do zone.update!(default_tax: false) tax_rate.update!(included_in_price: false) From 4e7fab691449ea9fdd98833aa4d69f00418a6a98 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Fri, 2 Jun 2023 22:09:01 +0100 Subject: [PATCH 14/16] Delete dead code Checkout#find_transition This method is only called from tests and nowhere else in the codebase. We may as well remove it. --- app/models/spree/order/checkout.rb | 8 ------- spec/models/spree/order/checkout_spec.rb | 27 ------------------------ 2 files changed, 35 deletions(-) diff --git a/app/models/spree/order/checkout.rb b/app/models/spree/order/checkout.rb index b5950a747ed..9d0bc4c54cf 100644 --- a/app/models/spree/order/checkout.rb +++ b/app/models/spree/order/checkout.rb @@ -96,14 +96,6 @@ def self.go_to_state(name, options = {}) end end - def self.find_transition(options = {}) - return nil if options.nil? || !options.include?(:from) || !options.include?(:to) - - next_event_transitions.detect do |transition| - transition[options[:from].to_sym] == options[:to].to_sym - end - end - def self.next_event_transitions @next_event_transitions ||= [] end diff --git a/spec/models/spree/order/checkout_spec.rb b/spec/models/spree/order/checkout_spec.rb index 69d46c1e4e7..02847257ea1 100644 --- a/spec/models/spree/order/checkout_spec.rb +++ b/spec/models/spree/order/checkout_spec.rb @@ -6,33 +6,6 @@ let(:order) { Spree::Order.new } context "with default state machine" do - let(:transitions) do - [ - { address: :delivery }, - { delivery: :payment }, - { delivery: :confirmation }, - { payment: :confirmation }, - { confirmation: :complete } - ] - end - - it "has the following transitions" do - transitions.each do |transition| - transition = Spree::Order.find_transition(from: transition.keys.first, - to: transition.values.first) - expect(transition).to_not be_nil - end - end - - it "does not have a transition from delivery to confirm" do - transition = Spree::Order.find_transition(from: :delivery, to: :confirm) - expect(transition).to be_nil - end - - it '.find_transition when contract was broken' do - expect(Spree::Order.find_transition({ foo: :bar, baz: :dog })).to be_falsy - end - context "#checkout_steps" do context "when payment not required" do before { allow(order).to receive_messages payment_required?: false } From 5fa81d1333e88c2910c06311efcb37a8c4c37dd2 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Sat, 3 Jun 2023 16:06:25 +0100 Subject: [PATCH 15/16] Fix invalid test setup in old tax tests --- spec/models/spree/tax_rate_spec.rb | 126 +++++++++++++++-------------- 1 file changed, 65 insertions(+), 61 deletions(-) diff --git a/spec/models/spree/tax_rate_spec.rb b/spec/models/spree/tax_rate_spec.rb index a9daf8b683a..6c0267dad3a 100644 --- a/spec/models/spree/tax_rate_spec.rb +++ b/spec/models/spree/tax_rate_spec.rb @@ -282,61 +282,64 @@ module Spree end end - context "#adjust" do + describe "#adjust" do + let!(:country) { create(:country, name: "Default Country") } + let!(:state) { create(:state, name: "Default State", country: country) } + let!(:zone) { create(:zone_with_member, default_tax: true, member: country ) } + let!(:category) { create(:tax_category, name: "Taxable Foo") } + let!(:category2) { create(:tax_category, name: "Non Taxable") } + let!(:rate1) { + create(:tax_rate, amount: 0.10, zone: zone, tax_category: category) + } + let!(:rate2) { + create(:tax_rate, amount: 0.05, zone: zone, tax_category: category) + } + let(:hub) { create(:distributor_enterprise, charges_sales_tax: true) } + let(:address) { create(:address, state: country.states.first, country: country) } + let!(:order) { + create(:order_with_line_items, line_items_count: 2, distributor: hub, + ship_address: address) + } + let!(:taxable) { order.line_items.first.variant.product } + let!(:nontaxable) { order.line_items.last.variant.product } + before do - @country = create(:country) - @zone = create(:zone, name: "Country Zone", default_tax: true, zone_members: []) - @zone.zone_members.create(zoneable: @country) - @category = Spree::TaxCategory.create(name: "Taxable Foo") - @category2 = Spree::TaxCategory.create(name: "Non Taxable") - @rate1 = Spree::TaxRate.create( - amount: 0.10, - calculator: ::Calculator::DefaultTax.new, - tax_category: @category, - zone: @zone - ) - @rate2 = Spree::TaxRate.create( - amount: 0.05, - calculator: ::Calculator::DefaultTax.new, - tax_category: @category, - zone: @zone - ) - @order = Spree::Order.create!(state: 'payment') - @taxable = create(:product, tax_category: @category) - @nontaxable = create(:product, tax_category: @category2) + taxable.update(tax_category: category) + nontaxable.update(tax_category: category2) + order.line_items.delete_all end context "not taxable line item " do - let!(:line_item) { @order.contents.add(@nontaxable.variants.first, 1) } + let!(:line_item) { order.contents.add(nontaxable.variants.first, 1) } it "should not create a tax adjustment" do - Spree::TaxRate.adjust(@order, @order.line_items) + Spree::TaxRate.adjust(order, order.line_items) expect(line_item.adjustments.tax.charge.count).to eq 0 end it "should not create a refund" do - Spree::TaxRate.adjust(@order, @order.line_items) + Spree::TaxRate.adjust(order, order.line_items) expect(line_item.adjustments.credit.count).to eq 0 end end context "taxable line item" do - let!(:line_item) { @order.contents.add(@taxable.variants.first, 1) } + let!(:line_item) { order.contents.add(taxable.variants.first, 1) } before do - @rate1.update_column(:included_in_price, true) - @rate2.update_column(:included_in_price, true) + rate1.update_column(:included_in_price, true) + rate2.update_column(:included_in_price, true) end context "when price includes tax" do context "when zone is contained by default tax zone" do it "should create two adjustments, one for each tax rate" do - Spree::TaxRate.adjust(@order, @order.line_items) + Spree::TaxRate.adjust(order, order.line_items) expect(line_item.adjustments.count).to eq 2 end it "should not create a tax refund" do - Spree::TaxRate.adjust(@order, @order.line_items) + Spree::TaxRate.adjust(order, order.line_items) expect(line_item.adjustments.credit.count).to eq 0 end end @@ -344,57 +347,59 @@ module Spree context "when order's zone is neither the default zone, or included in the default zone, but matches the rate's zone" do before do # With no zone members, this zone will not contain anything - @zone.zone_members.delete_all + zone.zone_members.delete_all end it "should create an adjustment" do - Spree::TaxRate.adjust(@order, @order.line_items) + Spree::TaxRate.adjust(order, order.line_items) expect(line_item.adjustments.charge.count).to eq 2 end it "should not create a tax refund for each tax rate" do - Spree::TaxRate.adjust(@order, @order.line_items) + Spree::TaxRate.adjust(order, order.line_items) expect(line_item.adjustments.credit.count).to eq 0 end end - end - context "when order's zone does not match default zone, is not included in the default zone, AND does not match the rate's zone" do - before do - @new_zone = create(:zone, name: "New Zone", default_tax: false) - @new_country = create(:country, name: "New Country") - @new_zone.zone_members.create(zoneable: @new_country) - @new_state = create(:state, country: @new_country) - @order.ship_address = create(:address, country: @new_country, state: @new_state) - @order.save - end + context "when order's zone does not match default zone, is not included in the default zone, AND does not match the rate's zone" do + let!(:other_country) { create(:country, name: "Other Country") } + let!(:other_state) { create(:state, name: "Other State", country: other_country) } + let!(:other_address) { create(:address, state: other_state, country: other_country) } + let!(:other_zone) { + create(:zone_with_member, name: "Other Zone", default_tax: false, + member: other_country) + } - it "should not create positive adjustments" do - Spree::TaxRate.adjust(@order, @order.line_items) - expect(line_item.adjustments.charge.count).to eq 0 - end + before do + order.update(ship_address: other_address) + order.all_adjustments.delete_all + end + + it "should not create positive adjustments" do + Spree::TaxRate.adjust(order, order.line_items) + expect(line_item.adjustments.charge.count).to eq 0 + end - it "should create a tax refund for each tax rate" do - Spree::TaxRate.adjust(@order, @order.line_items) - expect(line_item.adjustments.credit.count).to eq 2 + it "should create a tax refund for each tax rate" do + Spree::TaxRate.adjust(order, order.line_items) + expect(line_item.adjustments.credit.count).to eq 2 + end end end context "when price does not include tax" do before do - allow(@order).to receive(:tax_zone) { @zone } - - [@rate1, @rate2].each do |rate| - rate.included_in_price = false - rate.zone = @zone - rate.save + allow(order).to receive(:tax_zone) { zone } + [rate1, rate2].each do |rate| + rate.update(included_in_price: false, zone: zone) end + + Spree::TaxRate.adjust(order, order.line_items) end it "should not delete adjustments for complete order when taxrate is deleted" do - @order.update_column :completed_at, Time.now - @rate1.destroy! - @rate2.destroy! + rate1.destroy! + rate2.destroy! expect(line_item.adjustments.count).to eq 2 end @@ -407,10 +412,9 @@ module Spree end it "should remove adjustments when tax_zone is removed" do - Spree::TaxRate.adjust(@order, @order.line_items) expect(line_item.adjustments.count).to eq 2 - allow(@order).to receive(:tax_zone) { nil } - Spree::TaxRate.adjust(@order, @order.line_items) + allow(order).to receive(:tax_zone) { nil } + Spree::TaxRate.adjust(order, order.line_items) expect(line_item.adjustments.count).to eq 0 end end From 2654d3b86674f29ced23efd7c2d00bb74956a173 Mon Sep 17 00:00:00 2001 From: Mohamed ABDELLANI Date: Mon, 5 Jun 2023 09:58:14 +0100 Subject: [PATCH 16/16] update the rubocop_todo list --- .rubocop_todo.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 97b697bed6c..6eb6712ccec 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -628,11 +628,16 @@ Metrics/BlockLength: - 'spec/factories/user_factory.rb' - 'spec/factories/variant_factory.rb' - 'spec/requests/api/orders_spec.rb' + - 'spec/requests/checkout/failed_checkout_spec.rb' + - 'spec/requests/checkout/stripe_sca_spec.rb' - 'spec/support/cancan_helper.rb' - 'spec/support/matchers/select2_matchers.rb' - 'spec/support/matchers/table_matchers.rb' - 'spec/swagger_helper.rb' - 'spec/system/consumer/shopping/checkout_spec.rb' + - 'spec/system/consumer/shopping/checkout_stripe_spec.rb' + - 'spec/system/consumer/shopping/variant_overrides_spec.rb' + - 'spec/system/consumer/split_checkout_tax_not_incl_spec.rb' # Offense count: 1 # Configuration parameters: CountBlocks, Max.