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 19d1810f38..a5966e503b 100644 --- a/app/assets/javascripts/darkswarm/controllers/checkout/checkout_controller.js.coffee +++ b/app/assets/javascripts/darkswarm/controllers/checkout/checkout_controller.js.coffee @@ -1,12 +1,22 @@ -Darkswarm.controller "CheckoutCtrl", ($scope, storage, Order, CurrentUser) -> - $scope.Order = Order - Order.bindFieldsToLocalStorage($scope) +Darkswarm.controller "CheckoutCtrl", ($scope, storage, Checkout, CurrentUser, CurrentHub) -> + $scope.Checkout = Checkout - $scope.order = Order.order # Ordering is important - $scope.secrets = Order.secrets + # Bind to local storage + $scope.fieldsToBind = ["bill_address", "email", "payment_method_id", "shipping_method_id", "ship_address"] + prefix = "order_#{Checkout.order.id}#{Checkout.order.user_id}#{CurrentHub.hub.id}" + + for field in $scope.fieldsToBind + storage.bind $scope, "Checkout.order.#{field}", + storeName: "#{prefix}_#{field}" + storage.bind $scope, "Checkout.ship_address_same_as_billing", + storeName: "#{prefix}_sameasbilling" + defaultValue: true + + $scope.order = Checkout.order # Ordering is important + $scope.secrets = Checkout.secrets $scope.enabled = if CurrentUser then true else false $scope.purchase = (event)-> event.preventDefault() - $scope.Order.submit() + $scope.Checkout.submit() diff --git a/app/assets/javascripts/darkswarm/controllers/order_cycle_controller.js.coffee b/app/assets/javascripts/darkswarm/controllers/order_cycle_controller.js.coffee index 555e49c539..5913ae4b03 100644 --- a/app/assets/javascripts/darkswarm/controllers/order_cycle_controller.js.coffee +++ b/app/assets/javascripts/darkswarm/controllers/order_cycle_controller.js.coffee @@ -1,3 +1,5 @@ +# TODO this SUCKS. Fix it + Darkswarm.controller "OrderCycleCtrl", ($scope, OrderCycle, $timeout) -> $scope.order_cycle = OrderCycle.order_cycle $scope.OrderCycle = OrderCycle diff --git a/app/assets/javascripts/darkswarm/services/cart.js.coffee b/app/assets/javascripts/darkswarm/services/cart.js.coffee new file mode 100644 index 0000000000..d02d2bf5c1 --- /dev/null +++ b/app/assets/javascripts/darkswarm/services/cart.js.coffee @@ -0,0 +1,5 @@ +Darkswarm.factory 'Cart', (Order)-> + # Handles syncing of current cart/order state to server + new class Cart + order: Order.order + diff --git a/app/assets/javascripts/darkswarm/services/checkout.js.coffee b/app/assets/javascripts/darkswarm/services/checkout.js.coffee new file mode 100644 index 0000000000..603230358b --- /dev/null +++ b/app/assets/javascripts/darkswarm/services/checkout.js.coffee @@ -0,0 +1,62 @@ +Darkswarm.factory 'Checkout', (Order, $http, Navigation, CurrentHub, RailsFlashLoader, Loading)-> + new class Checkout + errors: {} + secrets: {} + order: Order.order + ship_address_same_as_billing: true + + submit: -> + Loading.message = "Submitting your order: please wait" + $http.put('/checkout', {order: @preprocess()}).success (data, status)=> + Navigation.go data.pat + .error (response, status)=> + Loading.clear() + @errors = response.errors + RailsFlashLoader.loadFlash(response.flash) + + # Rails wants our Spree::Address data to be provided with _attributes + preprocess: -> + munged_order = {} + for name, value of @order # Clone all data from the order JSON object + switch name + when "bill_address" + munged_order["bill_address_attributes"] = value + when "ship_address" + munged_order["ship_address_attributes"] = value + when "payment_method_id" + munged_order["payments_attributes"] = [{payment_method_id: value}] + + when "form_state" # don't keep this shit + else + munged_order[name] = value + + if @ship_address_same_as_billing + munged_order.ship_address_attributes = munged_order.bill_address_attributes + + if @paymentMethod()?.method_type == 'gateway' + 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: -> + @order.shipping_methods[@order.shipping_method_id] if @order.shipping_method_id + + requireShipAddress: -> + @shippingMethod()?.require_ship_address + + shippingPrice: -> + @shippingMethod()?.price || 0.0 + + paymentMethod: -> + @order.payment_methods[@order.payment_method_id] + + cartTotal: -> + @shippingPrice() + @order.display_total diff --git a/app/assets/javascripts/darkswarm/services/order.js.coffee b/app/assets/javascripts/darkswarm/services/order.js.coffee index 479d21f90b..06472b07cc 100644 --- a/app/assets/javascripts/darkswarm/services/order.js.coffee +++ b/app/assets/javascripts/darkswarm/services/order.js.coffee @@ -1,77 +1,5 @@ -Darkswarm.factory 'Order', ($resource, order, $http, Navigation, storage, CurrentHub, RailsFlashLoader, Loading)-> +Darkswarm.factory 'Order', (order)-> new class Order errors: {} - secrets: {} order: order - ship_address_same_as_billing: true - #Whitelist of fields from Order.order to bind into localStorage - fieldsToBind: ["bill_address", "email", "payment_method_id", "shipping_method_id", "ship_address"] - - # Bind all the fields from fieldsToBind, + anything on the Order class - bindFieldsToLocalStorage: (scope)=> - prefix = "order_#{@order.id}#{@order.user_id}#{CurrentHub.hub.id}" - for field in @fieldsToBind - storage.bind scope, "Order.order.#{field}", - storeName: "#{prefix}_#{field}" - - storage.bind scope, "Order.ship_address_same_as_billing", - storeName: "#{prefix}_sameasbilling" - defaultValue: true - - submit: -> - Loading.message = "Submitting your order: please wait" - $http.put('/checkout', {order: @preprocess()}).success (data, status)=> - Navigation.go data.path - .error (response, status)=> - Loading.clear() - @errors = response.errors - RailsFlashLoader.loadFlash(response.flash) - - - # Rails wants our Spree::Address data to be provided with _attributes - preprocess: -> - munged_order = {} - for name, value of @order # Clone all data from the order JSON object - switch name - when "bill_address" - munged_order["bill_address_attributes"] = value - when "ship_address" - munged_order["ship_address_attributes"] = value - when "payment_method_id" - munged_order["payments_attributes"] = [{payment_method_id: value}] - - when "form_state" # don't keep this shit - else - munged_order[name] = value - - if @ship_address_same_as_billing - munged_order.ship_address_attributes = munged_order.bill_address_attributes - - if @paymentMethod()?.method_type == 'gateway' - 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: -> - @order.shipping_methods[@order.shipping_method_id] if @order.shipping_method_id - - requireShipAddress: -> - @shippingMethod()?.require_ship_address - - shippingPrice: -> - @shippingMethod()?.price || 0.0 - - paymentMethod: -> - @order.payment_methods[@order.payment_method_id] - - cartTotal: -> - @shippingPrice() + @order.display_total diff --git a/app/assets/javascripts/darkswarm/services/product.js.coffee b/app/assets/javascripts/darkswarm/services/product.js.coffee index 48cdd6ae33..63c9e7c0b0 100644 --- a/app/assets/javascripts/darkswarm/services/product.js.coffee +++ b/app/assets/javascripts/darkswarm/services/product.js.coffee @@ -23,8 +23,8 @@ Darkswarm.factory 'Product', ($resource, Enterprises, Dereferencer, Taxons) -> extend: -> for product in @products - if product.variants.length > 0 + if product.variants?.length > 0 prices = (v.price for v in product.variants) product.price = Math.min.apply(null, prices) - product.hasVariants = product.variants.length > 0 + product.hasVariants = product.variants?.length > 0 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 index 5e98318f4f..3858f2a922 100644 --- a/spec/javascripts/unit/darkswarm/controllers/checkout/accordion_controller_spec.js.coffee +++ b/spec/javascripts/unit/darkswarm/controllers/checkout/accordion_controller_spec.js.coffee @@ -10,29 +10,15 @@ describe "AccordionCtrl", -> module ($provide)-> $provide.value "CurrentHub", CurrentHubMock null - localStorage.clear() + inject ($controller, $rootScope) -> + scope = $rootScope.$new() + scope.order = + id: 129 + ctrl = $controller 'AccordionCtrl', {$scope: scope} - describe "loading incomplete form", -> - beforeEach -> - 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 "defaults the details accordion to visible", -> - expect(scope.accordion.details).toEqual true - - it "changes accordion", -> - scope.show "shipping" - expect(scope.accordion["shipping"]).toEqual true - - describe "loading complete form", -> - beforeEach -> - inject ($controller, $rootScope) -> - scope = $rootScope.$new() - scope.checkout = - $valid: true - scope.order = - id: 129 - ctrl = $controller 'AccordionCtrl', {$scope: scope} + 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 index edda65e0cf..ceebc55eab 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 @@ -1,47 +1,72 @@ describe "CheckoutCtrl", -> ctrl = null scope = null - Order = null + Checkout = null CurrentUser = null + CurrentHubMock = + hub: + id: 1 + storage = null beforeEach -> module("Darkswarm") angular.module('Darkswarm').value('user', {}) - Order = + angular.module('Darkswarm').value('currentHub', {id: 1}) + module ($provide)-> + $provide.value "CurrentHub", CurrentHubMock + null + Checkout = submit: -> navigate: -> bindFieldsToLocalStorage: -> order: id: 1 email: "public" + user_id: 1 secrets: card_number: "this is a secret" describe "with user", -> beforeEach -> - inject ($controller, $rootScope) -> + inject ($controller, $rootScope, _storage_) -> + storage = _storage_ + spyOn(storage, "bind").andCallThrough() scope = $rootScope.$new() - spyOn(Order, "bindFieldsToLocalStorage") - ctrl = $controller 'CheckoutCtrl', {$scope: scope, Order: Order, CurrentUser: {}} + ctrl = $controller 'CheckoutCtrl', {$scope: scope, Checkout: Checkout, CurrentUser: {}} it "delegates to the service on submit", -> event = preventDefault: -> - spyOn(Order, "submit") + spyOn(Checkout, "submit") scope.purchase(event) - expect(Order.submit).toHaveBeenCalled() + expect(Checkout.submit).toHaveBeenCalled() it "is enabled", -> expect(scope.enabled).toEqual true - it "triggers localStorage binding", -> - expect(Order.bindFieldsToLocalStorage).toHaveBeenCalled() + describe "Local storage", -> + it "binds to localStorage when given a scope", -> + prefix = "order_#{scope.order.id}#{scope.order.user_id}#{CurrentHubMock.hub.id}" + field = scope.fieldsToBind[0] + expect(storage.bind).toHaveBeenCalledWith(scope, "Checkout.order.#{field}", {storeName: "#{prefix}_#{field}"}) + expect(storage.bind).toHaveBeenCalledWith(scope, "Checkout.ship_address_same_as_billing", {storeName: "#{prefix}_sameasbilling", defaultValue: true}) + + it "it can retrieve data from localstorage", -> + prefix = "order_#{scope.order.id}#{scope.order.user_id}#{CurrentHubMock.hub.id}" + expect(localStorage.getItem("#{prefix}_email")).toMatch "public" + + it "does not store secrets in local storage", -> + Checkout.secrets = + card_number: "superfuckingsecret" + 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, Order: Order, CurrentUser: undefined} + ctrl = $controller 'CheckoutCtrl', {$scope: scope, Checkout: Checkout, CurrentUser: undefined} it "is disabled", -> expect(scope.enabled).toEqual false @@ -49,4 +74,4 @@ describe "CheckoutCtrl", -> 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 + expect(localStorage.getItem(key)).not.toMatch Checkout.secrets.card_number diff --git a/spec/javascripts/unit/darkswarm/controllers/ordercycle_controller_spec.js.coffee b/spec/javascripts/unit/darkswarm/controllers/order_cycle_controller_spec.js.coffee similarity index 79% rename from spec/javascripts/unit/darkswarm/controllers/ordercycle_controller_spec.js.coffee rename to spec/javascripts/unit/darkswarm/controllers/order_cycle_controller_spec.js.coffee index 0eec42671c..a9746f2d39 100644 --- a/spec/javascripts/unit/darkswarm/controllers/ordercycle_controller_spec.js.coffee +++ b/spec/javascripts/unit/darkswarm/controllers/order_cycle_controller_spec.js.coffee @@ -14,5 +14,6 @@ describe 'OrderCycleCtrl', -> scope = {} ctrl = $controller 'OrderCycleCtrl', {$scope: scope, OrderCycle: OrderCycle} - #it "puts the order cycle in scope", -> - #expect(scope.order_cycle).toEqual "test" + it "puts the order cycle in scope", -> + expect(scope.order_cycle).toEqual "test" + diff --git a/spec/javascripts/unit/darkswarm/controllers/products/product_node_controller_spec.js.coffee b/spec/javascripts/unit/darkswarm/controllers/products/product_node_controller_spec.js.coffee index 4b9e404b9e..fa99b2d1ec 100644 --- a/spec/javascripts/unit/darkswarm/controllers/products/product_node_controller_spec.js.coffee +++ b/spec/javascripts/unit/darkswarm/controllers/products/product_node_controller_spec.js.coffee @@ -5,6 +5,7 @@ describe "ProductNodeCtrl", -> id: 99 price: 10.00 variants: [] + supplier: {} beforeEach -> module('Darkswarm') @@ -13,12 +14,5 @@ describe "ProductNodeCtrl", -> product: product ctrl = $controller 'ProductNodeCtrl', {$scope: scope} - describe "determining the price to display for a product", -> - it "displays the product price when the product does not have variants", -> - expect(scope.price()).toEqual 10.00 - - it "displays the minimum variant price when the product has variants", -> - scope.product = - price: 11 - variants: [{price: 22}, {price: 33}] - expect(scope.price()).toEqual 22 + it "puts a reference to supplier in the scope", -> + expect(scope.enterprise).toBe product.supplier diff --git a/spec/javascripts/unit/darkswarm/controllers/products_controller_spec.js.coffee b/spec/javascripts/unit/darkswarm/controllers/products_controller_spec.js.coffee index 47ad0ccbd4..0aaf0eaaf3 100644 --- a/spec/javascripts/unit/darkswarm/controllers/products_controller_spec.js.coffee +++ b/spec/javascripts/unit/darkswarm/controllers/products_controller_spec.js.coffee @@ -9,7 +9,7 @@ describe 'ProductsCtrl', -> Product = all: -> update: -> - products: "testy mctest" + products: ["testy mctest"] OrderCycle = order_cycle: {} @@ -18,4 +18,19 @@ describe 'ProductsCtrl', -> ctrl = $controller 'ProductsCtrl', {$scope: scope, Product: Product, OrderCycle: OrderCycle} it 'fetches products from Product', -> - expect(scope.Product.products).toEqual 'testy mctest' + expect(scope.Product.products).toEqual ['testy mctest'] + + it "increments the limit up to the number of products", -> + scope.limit = 0 + scope.incrementLimit() + expect(scope.limit).toEqual 1 + scope.incrementLimit() + expect(scope.limit).toEqual 1 + + it "blocks keypresses on code 13", -> + event = + keyCode: 13 + preventDefault: -> + spyOn(event, 'preventDefault') + scope.searchKeypress(event) + expect(event.preventDefault).toHaveBeenCalled() diff --git a/spec/javascripts/unit/darkswarm/services/checkout_spec.js.coffee b/spec/javascripts/unit/darkswarm/services/checkout_spec.js.coffee new file mode 100644 index 0000000000..63e29d4ed2 --- /dev/null +++ b/spec/javascripts/unit/darkswarm/services/checkout_spec.js.coffee @@ -0,0 +1,133 @@ +describe 'Checkout service', -> + Checkout = null + orderData = null + $httpBackend = null + Navigation = null + flash = null + scope = null + FlashLoaderMock = + loadFlash: (arg)-> + + beforeEach -> + orderData = + id: 3102 + payment_method_id: null + email: "test@test.com" + bill_address: + test: "foo" + firstname: "Robert" + lastname: "Harrington" + ship_address: {test: "bar"} + user_id: 901 + shipping_methods: + 7: + require_ship_address: true + price: 0.0 + + 25: + require_ship_address: false + price: 13 + payment_methods: + 99: + test: "foo" + method_type: "gateway" + 123: + test: "bar" + method_type: "check" + + angular.module('Darkswarm').value('order', orderData) + module 'Darkswarm' + module ($provide)-> + $provide.value "RailsFlashLoader", FlashLoaderMock + null + + inject ($injector, _$httpBackend_, $rootScope)-> + $httpBackend = _$httpBackend_ + Checkout = $injector.get("Checkout") + scope = $rootScope.$new() + scope.Checkout = Checkout + Navigation = $injector.get("Navigation") + flash = $injector.get("flash") + spyOn(Navigation, "go") # Stubbing out writes to window.location + + it "defaults to no shipping method", -> + expect(Checkout.order.shipping_method_id).toEqual null + expect(Checkout.shippingMethod()).toEqual undefined + + it "has a shipping price of zero with no shipping method", -> + expect(Checkout.shippingPrice()).toEqual 0.0 + + describe "with shipping method", -> + beforeEach -> + Checkout.order.shipping_method_id = 7 + + it 'Tracks whether a ship address is required', -> + expect(Checkout.requireShipAddress()).toEqual true + Checkout.order.shipping_method_id = 25 + expect(Checkout.requireShipAddress()).toEqual false + + it 'Gets the current shipping price', -> + expect(Checkout.shippingPrice()).toEqual 0.0 + Checkout.order.shipping_method_id = 25 + expect(Checkout.shippingPrice()).toEqual 13 + + it 'Gets the current payment method', -> + expect(Checkout.paymentMethod()).toEqual null + Checkout.order.payment_method_id = 99 + expect(Checkout.paymentMethod()).toEqual {test: "foo", method_type: "gateway"} + + it "Posts the Checkout to the server", -> + $httpBackend.expectPUT("/checkout", {order: Checkout.preprocess()}).respond 200, {path: "test"} + Checkout.submit() + $httpBackend.flush() + + it "sends flash messages to the flash service", -> + spyOn(FlashLoaderMock, "loadFlash") # Stubbing out writes to window.location + $httpBackend.expectPUT("/checkout").respond 400, {flash: {error: "frogs"}} + Checkout.submit() + + $httpBackend.flush() + expect(FlashLoaderMock.loadFlash).toHaveBeenCalledWith {error: "frogs"} + + it "puts errors into the scope", -> + $httpBackend.expectPUT("/checkout").respond 400, {errors: {error: "frogs"}} + Checkout.submit() + $httpBackend.flush() + expect(Checkout.errors).toEqual {error: "frogs"} + + describe "data preprocessing", -> + beforeEach -> + Checkout.order.payment_method_id = 99 + + Checkout.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(Checkout.preprocess().bill_address_attributes).not.toBe(undefined) + expect(Checkout.preprocess().bill_address).toBe(undefined) + expect(Checkout.preprocess().ship_address_attributes).not.toBe(undefined) + expect(Checkout.preprocess().ship_address).toBe(undefined) + + it "munges the order attributes to clone ship address from bill address", -> + Checkout.ship_address_same_as_billing = false + expect(Checkout.preprocess().ship_address_attributes).toEqual(orderData.ship_address) + Checkout.ship_address_same_as_billing = true + expect(Checkout.preprocess().ship_address_attributes).toEqual(orderData.bill_address) + + it "creates attributes for card fields", -> + source_attributes = Checkout.preprocess().payments_attributes[0].source_attributes + expect(source_attributes).toBeDefined() + expect(source_attributes.number).toBe Checkout.secrets.card_number + expect(source_attributes.month).toBe Checkout.secrets.card_month + expect(source_attributes.year).toBe Checkout.secrets.card_year + expect(source_attributes.verification_value).toBe Checkout.secrets.card_verification_value + expect(source_attributes.first_name).toBe Checkout.order.bill_address.firstname + expect(source_attributes.last_name).toBe Checkout.order.bill_address.lastname + + it "does not create attributes for card fields when no card is supplied", -> + Checkout.order.payment_method_id = 123 + source_attributes = Checkout.preprocess().payments_attributes[0].source_attributes + expect(source_attributes).not.toBeDefined() diff --git a/spec/javascripts/unit/darkswarm/services/order_spec.js.coffee b/spec/javascripts/unit/darkswarm/services/order_spec.js.coffee deleted file mode 100644 index 7dfb9e25e6..0000000000 --- a/spec/javascripts/unit/darkswarm/services/order_spec.js.coffee +++ /dev/null @@ -1,159 +0,0 @@ -describe 'Order service', -> - Order = null - orderData = null - $httpBackend = null - Navigation = null - flash = null - storage = null - scope = null - CurrentHubMock = - hub: - id: 1 - FlashLoaderMock = - loadFlash: (arg)-> - - beforeEach -> - orderData = - id: 3102 - payment_method_id: null - email: "test@test.com" - bill_address: - test: "foo" - firstname: "Robert" - lastname: "Harrington" - ship_address: {test: "bar"} - user_id: 901 - shipping_methods: - 7: - require_ship_address: true - price: 0.0 - - 25: - require_ship_address: false - price: 13 - payment_methods: - 99: - test: "foo" - method_type: "gateway" - 123: - test: "bar" - method_type: "check" - - angular.module('Darkswarm').value('order', orderData) - module 'Darkswarm' - module ($provide)-> - $provide.value "CurrentHub", CurrentHubMock - $provide.value "RailsFlashLoader", FlashLoaderMock - null - - inject ($injector, _$httpBackend_, _storage_, $rootScope)-> - $httpBackend = _$httpBackend_ - storage = _storage_ - Order = $injector.get("Order") - scope = $rootScope.$new() - scope.Order = Order - Navigation = $injector.get("Navigation") - flash = $injector.get("flash") - spyOn(Navigation, "go") # Stubbing out writes to window.location - - it "defaults to no shipping method", -> - expect(Order.order.shipping_method_id).toEqual null - expect(Order.shippingMethod()).toEqual undefined - - it "has a shipping price of zero with no shipping method", -> - expect(Order.shippingPrice()).toEqual 0.0 - - it "binds to localStorage when given a scope", -> - spyOn(storage, "bind") - Order.fieldsToBind = ["testy"] - Order.bindFieldsToLocalStorage({}) - prefix = "order_#{Order.order.id}#{Order.order.user_id}#{CurrentHubMock.hub.id}" - expect(storage.bind).toHaveBeenCalledWith({}, "Order.order.testy", {storeName: "#{prefix}_testy"}) - expect(storage.bind).toHaveBeenCalledWith({}, "Order.ship_address_same_as_billing", {storeName: "#{prefix}_sameasbilling", defaultValue: true}) - - it "binds order to local storage", -> - Order.bindFieldsToLocalStorage(scope) - prefix = "order_#{Order.order.id}#{Order.order.user_id}#{CurrentHubMock.hub.id}" - expect(localStorage.getItem("#{prefix}_email")).toMatch "test@test.com" - - it "does not store secrets in local storage", -> - Order.secrets = - card_number: "superfuckingsecret" - Order.bindFieldsToLocalStorage(scope) - keys = (localStorage.key(i) for i in [0..localStorage.length]) - for key in keys - expect(localStorage.getItem(key)).not.toMatch Order.secrets.card_number - - describe "with shipping method", -> - beforeEach -> - Order.order.shipping_method_id = 7 - - it 'Tracks whether a ship address is required', -> - expect(Order.requireShipAddress()).toEqual true - Order.order.shipping_method_id = 25 - expect(Order.requireShipAddress()).toEqual false - - it 'Gets the current shipping price', -> - expect(Order.shippingPrice()).toEqual 0.0 - Order.order.shipping_method_id = 25 - expect(Order.shippingPrice()).toEqual 13 - - it 'Gets the current payment method', -> - expect(Order.paymentMethod()).toEqual null - Order.order.payment_method_id = 99 - expect(Order.paymentMethod()).toEqual {test: "foo", method_type: "gateway"} - - it "Posts the Order to the server", -> - $httpBackend.expectPUT("/checkout", {order: Order.preprocess()}).respond 200, {path: "test"} - Order.submit() - $httpBackend.flush() - - it "sends flash messages to the flash service", -> - spyOn(FlashLoaderMock, "loadFlash") # Stubbing out writes to window.location - $httpBackend.expectPUT("/checkout").respond 400, {flash: {error: "frogs"}} - Order.submit() - $httpBackend.flush() - expect(FlashLoaderMock.loadFlash).toHaveBeenCalledWith {error: "frogs"} - - it "puts errors into the scope", -> - $httpBackend.expectPUT("/checkout").respond 400, {errors: {error: "frogs"}} - Order.submit() - $httpBackend.flush() - expect(Order.errors).toEqual {error: "frogs"} - - describe "data preprocessing", -> - beforeEach -> - Order.order.payment_method_id = 99 - - 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", -> - Order.ship_address_same_as_billing = false - expect(Order.preprocess().ship_address_attributes).toEqual(orderData.ship_address) - Order.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 - - it "does not create attributes for card fields when no card is supplied", -> - Order.order.payment_method_id = 123 - source_attributes = Order.preprocess().payments_attributes[0].source_attributes - expect(source_attributes).not.toBeDefined() diff --git a/spec/javascripts/unit/darkswarm/services/product_spec.js.coffee b/spec/javascripts/unit/darkswarm/services/product_spec.js.coffee index 389c0696ae..50b4138b77 100644 --- a/spec/javascripts/unit/darkswarm/services/product_spec.js.coffee +++ b/spec/javascripts/unit/darkswarm/services/product_spec.js.coffee @@ -7,7 +7,8 @@ describe 'Product service', -> test: "cats" supplier: id: 9 - + price: 11 + variants: [] beforeEach -> module 'Darkswarm' module ($provide)-> @@ -29,3 +30,15 @@ describe 'Product service', -> $httpBackend.expectGET("/shop/products").respond([{supplier : {id: 9}}]) $httpBackend.flush() expect(Product.products[0].supplier).toBe Enterprises.enterprises_by_id["9"] + + describe "determining the price to display for a product", -> + it "displays the product price when the product does not have variants", -> + $httpBackend.expectGET("/shop/products").respond([product]) + $httpBackend.flush() + expect(Product.products[0].price).toEqual 11.00 + + it "displays the minimum variant price when the product has variants", -> + product.variants = [{price: 22}, {price: 33}] + $httpBackend.expectGET("/shop/products").respond([product]) + $httpBackend.flush() + expect(Product.products[0].price).toEqual 22