diff --git a/app/assets/javascripts/admin/bulk_order_management.js.coffee b/app/assets/javascripts/admin/bulk_order_management.js.coffee index 62f7411ab8..dd4fa5c05a 100644 --- a/app/assets/javascripts/admin/bulk_order_management.js.coffee +++ b/app/assets/javascripts/admin/bulk_order_management.js.coffee @@ -9,12 +9,39 @@ orderManagementModule.config [ orderManagementModule.value "blankEnterprise", -> { id: "", name: "All" } +orderManagementModule.factory "pendingChanges",[ + "dataSubmitter" + (dataSubmitter) -> + pendingChanges: {} + + add: (id, attrName, changeObj) -> + this.pendingChanges["#{id}"] = {} unless this.pendingChanges.hasOwnProperty("#{id}") + this.pendingChanges["#{id}"]["#{attrName}"] = changeObj + + remove: (id, attrName) -> + if this.pendingChanges.hasOwnProperty("#{id}") + delete this.pendingChanges["#{id}"]["#{attrName}"] + delete this.pendingChanges["#{id}"] if this.changeCount( this.pendingChanges["#{id}"] ) < 1 + + submitAll: -> + for id,lineItem of this.pendingChanges + for attrName,changeObj of lineItem + this.submit id, attrName, changeObj + + submit: (id, attrName, change) -> + factory = this + dataSubmitter(change).then (data) -> + factory.remove id, attrName + change.element.dbValue = data["#{attrName}"] + + changeCount: (lineItem) -> + Object.keys(lineItem).length +] + + orderManagementModule.controller "AdminOrderMgmtCtrl", [ "$scope", "$http", "dataFetcher", "blankEnterprise" ($scope, $http, dataFetcher, blankEnterprise) -> - $scope.updateStatusMessage = - text: "" - style: {} $scope.lineItems = [] $scope.confirmDelete = true diff --git a/spec/javascripts/unit/bulk_order_management_spec.js.coffee b/spec/javascripts/unit/bulk_order_management_spec.js.coffee index a62a5afa8f..602ac64ce0 100644 --- a/spec/javascripts/unit/bulk_order_management_spec.js.coffee +++ b/spec/javascripts/unit/bulk_order_management_spec.js.coffee @@ -159,4 +159,106 @@ describe "AdminOrderMgmtCtrl", -> httpBackend.expectDELETE("/api/orders/#{line_item1.order.number}/line_items/#{line_item1.id}").respond 404, "NO CONTENT" scope.deleteLineItem line_item1 httpBackend.flush() - expect(order.line_items).toEqual [line_item1, line_item2] \ No newline at end of file + expect(order.line_items).toEqual [line_item1, line_item2] + +describe "managing pending changes", -> + dataSubmitter = pendingChangesService = null + + beforeEach -> + dataSubmitter = jasmine.createSpy('dataSubmitter').andReturn { + then: (thenFn) -> + thenFn({propertyName: "new_value"}) + } + + beforeEach -> + module "ofn.bulk_order_management", ($provide) -> + $provide.value 'dataSubmitter', dataSubmitter + return + + beforeEach inject (pendingChanges) -> + pendingChangesService = pendingChanges + + describe "adding a new change", -> + it "adds a new object with key of id if it does not already exist", -> + expect(pendingChangesService.pendingChanges).toEqual {} + expect(pendingChangesService.pendingChanges["1"]).not.toBeDefined() + pendingChangesService.add 1, "propertyName", { a: 1 } + expect(pendingChangesService.pendingChanges["1"]).toBeDefined() + + it "adds a new object with key of the altered attribute name if it does not already exist", -> + pendingChangesService.add 1, "propertyName", { a: 1 } + expect(pendingChangesService.pendingChanges["1"]).toBeDefined() + expect(pendingChangesService.pendingChanges["1"]["propertyName"]).toEqual { a: 1 } + + it "replaces the existing object when adding a change to an attribute which already exists", -> + pendingChangesService.add 1, "propertyName", { a: 1 } + expect(pendingChangesService.pendingChanges["1"]).toBeDefined() + expect(pendingChangesService.pendingChanges["1"]["propertyName"]).toEqual { a: 1 } + pendingChangesService.add 1, "propertyName", { b: 2 } + expect(pendingChangesService.pendingChanges["1"]["propertyName"]).toEqual { b: 2 } + + it "adds an attribute to key to a line item object when one already exists", -> + pendingChangesService.add 1, "propertyName1", { a: 1 } + pendingChangesService.add 1, "propertyName2", { b: 2 } + expect(pendingChangesService.pendingChanges["1"]).toEqual { propertyName1: { a: 1}, propertyName2: { b: 2 } } + + describe "removing an existing change", -> + it "deletes a change if it exists", -> + pendingChangesService.pendingChanges = { 1: { "propertyName1": { a: 1 }, "propertyName2": { b: 2 } } } + expect(pendingChangesService.pendingChanges["1"]["propertyName1"]).toBeDefined() + pendingChangesService.remove 1, "propertyName1" + expect(pendingChangesService.pendingChanges["1"]).toBeDefined() + expect(pendingChangesService.pendingChanges["1"]["propertyName1"]).not.toBeDefined() + + it "deletes a line item object if it is empty", -> + pendingChangesService.pendingChanges = { 1: { "propertyName1": { a: 1 } } } + expect(pendingChangesService.pendingChanges["1"]["propertyName1"]).toBeDefined() + pendingChangesService.remove 1, "propertyName1" + expect(pendingChangesService.pendingChanges["1"]).not.toBeDefined() + + it "does nothing if key with specified attribute does not exist", -> + pendingChangesService.pendingChanges = { 1: { "propertyName1": { a: 1 } } } + expect(pendingChangesService.pendingChanges["1"]["propertyName1"]).toBeDefined() + pendingChangesService.remove 1, "propertyName2" + expect(pendingChangesService.pendingChanges["1"]["propertyName1"]).toEqual { a: 1 } + + it "does nothing if key with specified id does not exist", -> + pendingChangesService.pendingChanges = { 1: { "propertyName1": { a: 1 } } } + expect(pendingChangesService.pendingChanges["1"]["propertyName1"]).toBeDefined() + pendingChangesService.remove 2, "propertyName1" + expect(pendingChangesService.pendingChanges["1"]).toEqual { "propertyName1": { a: 1 } } + + describe "submitting an individual change to the server", -> + it "sends the correct object to dataSubmitter", -> + changeObj = { element: {} } + pendingChangesService.submit 1, "propertyName", changeObj + expect(dataSubmitter.calls.length).toEqual 1 + expect(dataSubmitter).toHaveBeenCalledWith changeObj + + it "calls remove with id and attribute name", -> + changeObj = { element: {} } + spyOn(pendingChangesService, "remove").andCallFake(->) + pendingChangesService.submit 1, "propertyName", changeObj + expect(pendingChangesService.remove.calls.length).toEqual 1 + expect(pendingChangesService.remove).toHaveBeenCalledWith 1, "propertyName" + + it "resets the dbValue attribute of the element in question", -> + element = { dbValue: 2 } + changeObj = { element: element } + pendingChangesService.submit 1, "propertyName", changeObj + expect(element.dbValue).toEqual "new_value" + + describe "cycling through all changes to submit to server", -> + it "sends the correct object to dataSubmitter", -> + spyOn(pendingChangesService, "submit").andCallFake(->) + pendingChangesService.pendingChanges = + 1: { "prop1": 1, "prop2": 2 } + 2: { "prop1": 2, "prop2": 4 } + 7: { "prop2": 5 } + pendingChangesService.submitAll() + expect(pendingChangesService.submit.calls.length).toEqual 5 + expect(pendingChangesService.submit).toHaveBeenCalledWith '1', "prop1", 1 + expect(pendingChangesService.submit).toHaveBeenCalledWith '1', "prop2", 2 + expect(pendingChangesService.submit).toHaveBeenCalledWith '2', "prop1", 2 + expect(pendingChangesService.submit).toHaveBeenCalledWith '2', "prop2", 4 + expect(pendingChangesService.submit).toHaveBeenCalledWith '7', "prop2", 5 \ No newline at end of file