Files
openfoodnetwork/spec/javascripts/unit/darkswarm/services/cart_spec.js.coffee
Pau Perez c224df9b6a Do not trigger an orderChanged with null quantity
When loading the page $watchGroup calls the listener function for every
listed line item but with a set variant and null quantity and
max_quantity. There's no point on computing an order change when there
was none.

This saves an empty request on the second most used endpoint of the app,
specially busy when users are placing orders.
2020-04-24 15:54:46 +02:00

233 lines
8.2 KiB
CoffeeScript

describe 'Cart service', ->
Cart = null
Variants = null
variant = null
order = null
$httpBackend = null
$timeout = null
beforeEach ->
module 'Darkswarm'
variant =
id: 1
name_to_display: 'name'
product_name: 'name'
order = {
line_items: [
variant: variant
]
}
angular.module('Darkswarm').value('currentOrder', order)
inject ($injector, _$httpBackend_, _$timeout_)->
Variants = $injector.get("Variants")
Cart = $injector.get("Cart")
$httpBackend = _$httpBackend_
$timeout = _$timeout_
it "backreferences line items", ->
expect(Cart.line_items[0].variant.line_item).toBe Cart.line_items[0]
it "registers variants with the Variants service", ->
expect(Variants.variants[1]).toBe variant
it "generates extended variant names", ->
expect(Cart.line_items[0].variant.extended_name).toEqual "name"
it "adds item to and removes items from the cart", ->
Cart.line_items = []
expect(Cart.line_items.length).toEqual 0
order.line_items[0].quantity = 1
expect(Cart.line_items.length).toEqual 0
Cart.adjust(order.line_items[0])
expect(Cart.line_items.length).toEqual 1
order.line_items[0].quantity = 0
expect(Cart.line_items.length).toEqual 1
Cart.adjust(order.line_items[0])
expect(Cart.line_items.length).toEqual 0
it "does not add an item in the cart without quantity", ->
Cart.line_items = []
spyOn(Cart, 'orderChanged')
order.line_items[0].max_quantity = 0
expect(Cart.orderChanged).not.toHaveBeenCalled()
it "sums the quantity of each line item for cart total", ->
order.line_items[0].quantity = 2
expect(Cart.total_item_count()).toEqual 2
describe "triggering cart updates", ->
it "schedules an update when there's no update running", ->
Cart.update_running = false
Cart.update_enqueued = false
spyOn(Cart, 'scheduleUpdate')
spyOn(Cart, 'unsaved')
Cart.orderChanged()
expect(Cart.scheduleUpdate).toHaveBeenCalled()
it "enqueues an update when there's already an update running", ->
Cart.update_running = true
Cart.update_enqueued = false
spyOn(Cart, 'scheduleUpdate')
spyOn(Cart, 'unsaved')
Cart.orderChanged()
expect(Cart.scheduleUpdate).not.toHaveBeenCalled()
expect(Cart.update_enqueued).toBe(true)
it "does nothing when there's already an update enqueued", ->
Cart.update_running = true
Cart.update_enqueued = true
spyOn(Cart, 'scheduleUpdate')
spyOn(Cart, 'unsaved')
Cart.orderChanged()
expect(Cart.scheduleUpdate).not.toHaveBeenCalled()
expect(Cart.update_enqueued).toBe(true)
describe "updating the cart", ->
data = {variants: {}}
it "sets update_running during the update, and clears it on success", ->
$httpBackend.expectPOST("/cart/populate", data).respond 200, {}
expect(Cart.update_running).toBe(false)
Cart.update()
expect(Cart.update_running).toBe(true)
$httpBackend.flush()
expect(Cart.update_running).toBe(false)
it "sets update_running during the update, and clears it on failure", ->
$httpBackend.expectPOST("/cart/populate", data).respond 404, {}
expect(Cart.update_running).toBe(false)
Cart.update()
expect(Cart.update_running).toBe(true)
$httpBackend.flush()
expect(Cart.update_running).toBe(false)
it "marks the form as saved on success", ->
spyOn(Cart, 'saved')
$httpBackend.expectPOST("/cart/populate", data).respond 200, {}
Cart.update()
$httpBackend.flush()
expect(Cart.saved).toHaveBeenCalled()
it "runs enqueued updates after success", ->
Cart.update_enqueued = true
spyOn(Cart, 'saved')
spyOn(Cart, 'popQueue')
$httpBackend.expectPOST("/cart/populate", data).respond 200, {}
Cart.update()
$httpBackend.flush()
expect(Cart.popQueue).toHaveBeenCalled()
it "doesn't run an update if it's not enqueued", ->
Cart.update_enqueued = false
spyOn(Cart, 'saved')
spyOn(Cart, 'popQueue')
$httpBackend.expectPOST("/cart/populate", data).respond 200, {}
Cart.update()
$httpBackend.flush()
expect(Cart.popQueue).not.toHaveBeenCalled()
it "retries the update on failure", ->
spyOn(Cart, 'scheduleRetry')
$httpBackend.expectPOST("/cart/populate", data).respond 404, {}
Cart.update()
$httpBackend.flush()
expect(Cart.scheduleRetry).toHaveBeenCalled()
describe "verifying stock levels after update", ->
describe "when an item is out of stock", ->
it "reduces the quantity in the cart", ->
li = {variant: {id: 1}, quantity: 5}
Cart.line_items = [li]
stockLevels = {1: {quantity: 0, max_quantity: 0, on_hand: 0}}
Cart.compareAndNotifyStockLevels stockLevels
expect(li.quantity).toEqual 0
expect(li.max_quantity).toBeUndefined()
it "reduces the max_quantity in the cart", ->
li = {variant: {id: 1}, quantity: 5, max_quantity: 6}
Cart.line_items = [li]
stockLevels = {1: {quantity: 0, max_quantity: 0, on_hand: 0}}
Cart.compareAndNotifyStockLevels stockLevels
expect(li.max_quantity).toEqual 0
it "resets the count on hand available", ->
li = {variant: {id: 1, on_hand: 10}, quantity: 5}
Cart.line_items = [li]
stockLevels = {1: {quantity: 0, max_quantity: 0, on_hand: 0}}
Cart.compareAndNotifyStockLevels stockLevels
expect(li.variant.on_hand).toEqual 0
describe "when the quantity available is less than that requested", ->
it "reduces the quantity in the cart", ->
li = {variant: {id: 1}, quantity: 6}
Cart.line_items = [li]
stockLevels = {1: {quantity: 5, on_hand: 5}}
Cart.compareAndNotifyStockLevels stockLevels
expect(li.quantity).toEqual 5
expect(li.max_quantity).toBeUndefined()
it "does not reduce the max_quantity in the cart", ->
li = {variant: {id: 1}, quantity: 6, max_quantity: 7}
Cart.line_items = [li]
stockLevels = {1: {quantity: 5, max_quantity: 5, on_hand: 5}}
Cart.compareAndNotifyStockLevels stockLevels
expect(li.max_quantity).toEqual 7
it "resets the count on hand available", ->
li = {variant: {id: 1}, quantity: 6}
Cart.line_items = [li]
stockLevels = {1: {quantity: 5, on_hand: 6}}
Cart.compareAndNotifyStockLevels stockLevels
expect(li.variant.on_hand).toEqual 6
describe "when the client-side quantity has been increased during the request", ->
it "does not reset the quantity", ->
li = {variant: {id: 1}, quantity: 6}
Cart.line_items = [li]
stockLevels = {1: {quantity: 5, on_hand: 6}}
Cart.compareAndNotifyStockLevels stockLevels
expect(li.quantity).toEqual 6
expect(li.max_quantity).toBeUndefined()
it "does not reset the max_quantity", ->
li = {variant: {id: 1}, quantity: 5, max_quantity: 7}
Cart.line_items = [li]
stockLevels = {1: {quantity: 5, max_quantity: 6, on_hand: 7}}
Cart.compareAndNotifyStockLevels stockLevels
expect(li.quantity).toEqual 5
expect(li.max_quantity).toEqual 7
describe "when the client-side quantity has been changed from 0 to 1 during the request", ->
it "does not reset the quantity", ->
li = {variant: {id: 1}, quantity: 1}
Cart.line_items = [li]
Cart.compareAndNotifyStockLevels {}
expect(li.quantity).toEqual 1
expect(li.max_quantity).toBeUndefined()
it "does not reset the max_quantity", ->
li = {variant: {id: 1}, quantity: 1, max_quantity: 1}
Cart.line_items = [li]
Cart.compareAndNotifyStockLevels {}
expect(li.quantity).toEqual 1
expect(li.max_quantity).toEqual 1
it "pops the queue", ->
Cart.update_enqueued = true
spyOn(Cart, 'scheduleUpdate')
Cart.popQueue()
expect(Cart.update_enqueued).toBe(false)
expect(Cart.scheduleUpdate).toHaveBeenCalled()
it "schedules retries of updates", ->
spyOn(Cart, 'orderChanged')
Cart.scheduleRetry()
$timeout.flush()
expect(Cart.orderChanged).toHaveBeenCalled()
it "clears the cart", ->
expect(Cart.line_items).not.toEqual []
Cart.clear()
expect(Cart.line_items).toEqual []