diff --git a/app/assets/javascripts/darkswarm/controllers/checkout/checkout_controller.js.coffee b/app/assets/javascripts/darkswarm/controllers/checkout/checkout_controller.js.coffee index 64f0184e98..a8047d9199 100644 --- a/app/assets/javascripts/darkswarm/controllers/checkout/checkout_controller.js.coffee +++ b/app/assets/javascripts/darkswarm/controllers/checkout/checkout_controller.js.coffee @@ -2,6 +2,7 @@ Darkswarm.controller "CheckoutCtrl", ($scope, storage, CheckoutFormState, Order, $scope.Order = Order storage.bind $scope, "Order.order", {storeName: "order_#{Order.order.id}#{Order.order.user_id}"} $scope.order = Order.order # Ordering is important + $scope.secrets = Order.secrets $scope.enabled = if CurrentUser then true else false diff --git a/app/assets/javascripts/darkswarm/controllers/checkout/payment_controller.js.coffee b/app/assets/javascripts/darkswarm/controllers/checkout/payment_controller.js.coffee index ee5ff84b4a..adbe9bb8d6 100644 --- a/app/assets/javascripts/darkswarm/controllers/checkout/payment_controller.js.coffee +++ b/app/assets/javascripts/darkswarm/controllers/checkout/payment_controller.js.coffee @@ -1,3 +1,8 @@ Darkswarm.controller "PaymentCtrl", ($scope) -> angular.extend(this, new FieldsetMixin($scope)) $scope.name = "payment" + + $scope.months = {1: "January", 2: "February", 3: "March", 4: "April", 5: "May", 6: "June", 7: "July", 8: "August", 9: "September", 10: "October", 11: "November", 12: "December"} + $scope.years = [moment().year()..(moment().year()+15)] + $scope.secrets.card_month = "1" + $scope.secrets.card_year = moment().year() diff --git a/app/assets/javascripts/darkswarm/services/order.js.coffee b/app/assets/javascripts/darkswarm/services/order.js.coffee index 8078cf8fc3..06a2c8fadb 100644 --- a/app/assets/javascripts/darkswarm/services/order.js.coffee +++ b/app/assets/javascripts/darkswarm/services/order.js.coffee @@ -1,6 +1,7 @@ Darkswarm.factory 'Order', ($resource, order, $http, CheckoutFormState, flash, Navigation)-> new class Order errors: {} + secrets: {} constructor: -> @order = order @@ -30,6 +31,17 @@ Darkswarm.factory 'Order', ($resource, order, $http, CheckoutFormState, flash, N if CheckoutFormState.ship_address_same_as_billing munged_order.ship_address_attributes = munged_order.bill_address_attributes + + angular.extend munged_order.payments_attributes[0], { + source_attributes: + number: @secrets.card_number + month: @secrets.card_month + year: @secrets.card_year + verification_value: @secrets.card_verification_value + first_name: @order.bill_address.firstname + last_name: @order.bill_address.lastname + } + munged_order shippingMethod: -> diff --git a/app/views/spree/checkout/payment/_gateway.html.haml b/app/views/spree/checkout/payment/_gateway.html.haml new file mode 100644 index 0000000000..5cd25dafba --- /dev/null +++ b/app/views/spree/checkout/payment/_gateway.html.haml @@ -0,0 +1,8 @@ += validated_input "Card Number", "secrets.card_number", required: true, maxlength: 19, autocomplete: "off" + +%label{for: "secrets.card_month"} Expiry Date +%select{"ng-model" => "secrets.card_month", "ng-options" => "number as name for (number, name) in months", name: "secrets.card_month", required: true} + +%select{"ng-model" => "secrets.card_year", "ng-options" => "year for year in years", name: "secrets.card_year", required: true} + += validated_input "CVV", "secrets.card_verification_value", required: true diff --git a/spec/features/consumer/shopping/checkout_spec.rb b/spec/features/consumer/shopping/checkout_spec.rb index c24456b16a..dd84a1e8ca 100644 --- a/spec/features/consumer/shopping/checkout_spec.rb +++ b/spec/features/consumer/shopping/checkout_spec.rb @@ -96,37 +96,57 @@ feature "As a consumer I want to check out my cart", js: true do end place_order - page.should have_content "Your order has been processed successfully", wait: 10 + page.should have_content "Your order has been processed successfully" ActionMailer::Base.deliveries.length.should == 1 email = ActionMailer::Base.deliveries.last site_name = Spree::Config[:site_name] email.subject.should include "#{site_name} Order Confirmation" end - it "takes us to the order confirmation page when submitted with 'same as billing address' checked" do - toggle_shipping - choose sm1.name - toggle_payment - choose pm1.name - toggle_details - within "#details" do - fill_in "First Name", with: "Will" - fill_in "Last Name", with: "Marshall" - fill_in "Email", with: "test@test.com" - fill_in "Phone", with: "0468363090" + context "with basic details filled" do + before do + toggle_shipping + choose sm1.name + toggle_payment + choose pm1.name + toggle_details + within "#details" do + fill_in "First Name", with: "Will" + fill_in "Last Name", with: "Marshall" + fill_in "Email", with: "test@test.com" + fill_in "Phone", with: "0468363090" + end + toggle_billing + within "#billing" do + fill_in "City", with: "Melbourne" + fill_in "Postcode", with: "3066" + fill_in "Address", with: "123 Your Face" + select "Australia", from: "Country" + select "Victoria", from: "State" + end + toggle_shipping + check "Shipping address same as billing address?" end - toggle_billing - within "#billing" do - fill_in "City", with: "Melbourne" - fill_in "Postcode", with: "3066" - fill_in "Address", with: "123 Your Face" - select "Australia", from: "Country" - select "Victoria", from: "State" + + it "takes us to the order confirmation page when submitted with 'same as billing address' checked" do + place_order + page.should have_content "Your order has been processed successfully" + end + + context "with a credit card payment method" do + let!(:pm1) { create(:payment_method, distributors: [distributor], name: "Roger rabbit", type: "Spree::Gateway::Bogus") } + + it "takes us to the order confirmation page when submitted with a valid credit card" do + toggle_payment + fill_in 'Card Number', with: "4111111111111111" + select 'February', from: 'secrets.card_month' + select (Date.today.year+1).to_s, from: 'secrets.card_year' + fill_in 'CVV', with: '123' + + place_order + page.should have_content "Your order has been processed successfully" + end end - toggle_shipping - check "Shipping address same as billing address?" - place_order - page.should have_content "Your order has been processed successfully", wait: 10 end end end 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 index 8632cb49ec..ea9c28a82d 100644 --- a/spec/javascripts/unit/darkswarm/controllers/checkout/checkout_controller_spec.js.coffee +++ b/spec/javascripts/unit/darkswarm/controllers/checkout/checkout_controller_spec.js.coffee @@ -12,6 +12,9 @@ describe "CheckoutCtrl", -> navigate: -> order: id: 1 + public: "public" + secrets: + card_number: "this is a secret" describe "with user", -> beforeEach -> @@ -37,3 +40,11 @@ describe "CheckoutCtrl", -> it "is disabled", -> expect(scope.enabled).toEqual false + + it "binds order to local storage", -> + expect(localStorage.getItem("order_#{Order.order.id}#{Order.order.user_id}")).toMatch Order.order.public + + it "does not store secrets in local storage", -> + keys = (localStorage.key(i) for i in [0..localStorage.length]) + for key in keys + expect(localStorage.getItem(key)).not.toMatch Order.secrets.card_number diff --git a/spec/javascripts/unit/darkswarm/services/order_spec.js.coffee b/spec/javascripts/unit/darkswarm/services/order_spec.js.coffee index 4f6c711f99..a485e7b90d 100644 --- a/spec/javascripts/unit/darkswarm/services/order_spec.js.coffee +++ b/spec/javascripts/unit/darkswarm/services/order_spec.js.coffee @@ -7,10 +7,13 @@ describe 'Order service', -> flash = null beforeEach -> - orderData = { + orderData = id: 3102 payment_method_id: null - bill_address: {test: "foo"} + bill_address: + test: "foo" + firstname: "Robert" + lastname: "Harrington" ship_address: {test: "bar"} shipping_methods: 7: @@ -23,7 +26,7 @@ describe 'Order service', -> payment_methods: 99: test: "foo" - } + angular.module('Darkswarm').value('order', orderData) module 'Darkswarm' @@ -76,14 +79,34 @@ describe 'Order service', -> $httpBackend.flush() expect(Order.errors).toEqual {error: "frogs"} - it "Munges the order attributes to add _attributes as Rails needs", -> - expect(Order.preprocess().bill_address_attributes).not.toBe(undefined) - expect(Order.preprocess().bill_address).toBe(undefined) - expect(Order.preprocess().ship_address_attributes).not.toBe(undefined) - expect(Order.preprocess().ship_address).toBe(undefined) + describe "data preprocessing", -> + beforeEach -> + Order.order.payment_method_id = 99 - it "Munges the order attributes to clone ship address from bill address", -> - CheckoutFormState.ship_address_same_as_billing = false - expect(Order.preprocess().ship_address_attributes).toEqual(orderData.ship_address) - CheckoutFormState.ship_address_same_as_billing = true - expect(Order.preprocess().ship_address_attributes).toEqual(orderData.bill_address) + Order.secrets = + card_number: "1234567890123456" + card_month: "10" + card_year: "2015" + card_verification_value: "123" + + it "munges the order attributes to add _attributes as Rails needs", -> + expect(Order.preprocess().bill_address_attributes).not.toBe(undefined) + expect(Order.preprocess().bill_address).toBe(undefined) + expect(Order.preprocess().ship_address_attributes).not.toBe(undefined) + expect(Order.preprocess().ship_address).toBe(undefined) + + it "munges the order attributes to clone ship address from bill address", -> + CheckoutFormState.ship_address_same_as_billing = false + expect(Order.preprocess().ship_address_attributes).toEqual(orderData.ship_address) + CheckoutFormState.ship_address_same_as_billing = true + expect(Order.preprocess().ship_address_attributes).toEqual(orderData.bill_address) + + it "creates attributes for card fields", -> + source_attributes = Order.preprocess().payments_attributes[0].source_attributes + expect(source_attributes).toBeDefined() + expect(source_attributes.number).toBe Order.secrets.card_number + expect(source_attributes.month).toBe Order.secrets.card_month + expect(source_attributes.year).toBe Order.secrets.card_year + expect(source_attributes.verification_value).toBe Order.secrets.card_verification_value + expect(source_attributes.first_name).toBe Order.order.bill_address.firstname + expect(source_attributes.last_name).toBe Order.order.bill_address.lastname