diff --git a/app/controllers/internalRequestController.js b/app/controllers/internalRequestController.js index f39f7b0..88f1e18 100644 --- a/app/controllers/internalRequestController.js +++ b/app/controllers/internalRequestController.js @@ -4,66 +4,40 @@ app.controller('InternalRequestController', function ($controller, $scope, ApiRe $scope: $scope })); - $scope.internalRequests = InternalRequestRepo.getAll(); - - $scope.internalRequestToCreate = InternalRequestRepo.getScaffold(); - $scope.internalRequestToEdit = {}; - $scope.internalRequestToDelete = {}; + if ($scope.isManager() || $scope.isAdmin()) { + $scope.internalRequests = InternalRequestRepo.getAll(); - $scope.featureRequestToPush = {}; + $scope.internalRequestToCreate = InternalRequestRepo.getScaffold(); + $scope.internalRequestToEdit = {}; + $scope.internalRequestToDelete = {}; - $scope.products = []; - $scope.remoteProducts = {}; - $scope.remoteProductsLoading = false; + $scope.featureRequestToPush = {}; - $scope.resetInternalRequestForms = function () { - InternalRequestRepo.clearValidationResults(); + $scope.resetInternalRequestForms = function () { + InternalRequestRepo.clearValidationResults(); - for (var key in $scope.internalRequestForms) { - if ($scope.internalRequestForms[key] !== undefined && !$scope.internalRequestForms[key].$pristine && $scope.internalRequestForms[key].$setPristine) { - $scope.internalRequestForms[key].$setPristine(); + for (var key in $scope.internalRequestForms) { + if ($scope.internalRequestForms[key] !== undefined && !$scope.internalRequestForms[key].$pristine && $scope.internalRequestForms[key].$setPristine) { + $scope.internalRequestForms[key].$setPristine(); + } } - } - $scope.closeModal(); - }; + $scope.closeModal(); + }; - $scope.resetInternalRequestForms(); + $scope.resetInternalRequestForms(); - if ($scope.isManager() || $scope.isAdmin()) { $scope.selectRemoteProducts = function () { - if ($scope.remoteProductsLoading === false) { - $scope.remoteProducts = {}; - - if (angular.isDefined($scope.featureRequestToPush.productId) && $scope.featureRequestToPush.productId !== null) { - var productId = $scope.featureRequestToPush.productId; - var remoteProducts = ProductsService.getRemoteProducts(); - - if (angular.isDefined(remoteProducts[productId])) { - angular.extend($scope.remoteProducts, remoteProducts[productId]); - } else { - $scope.refreshRemoteProducts(productId); - } + if ($scope.featureRequestToPush.productId) { + if (!$scope.remoteProducts[$scope.featureRequestToPush.productId]) { + $scope.refreshRemoteProducts($scope.featureRequestToPush.productId); } } }; $scope.refreshRemoteProducts = function (productId) { - if ($scope.remoteProductsLoading === false) { - $scope.remoteProductsLoading = true; - $scope.remoteProducts = {}; - - ProductsService.refreshRemoteProducts(productId).then(null, null, function (res) { - remoteProducts = ProductsService.getRemoteProducts(); - - if (angular.isDefined(remoteProducts[productId])) { - angular.extend($scope.remoteProducts, remoteProducts[productId]); - } - - $scope.remoteProductsLoading = false; - }).catch(function() { - $scope.remoteProductsLoading = false; - }); + if (productId && !$scope.remoteProductsLoading[productId]) { + ProductsService.refreshRemoteProducts(productId); } }; @@ -92,7 +66,7 @@ app.controller('InternalRequestController', function ($controller, $scope, ApiRe scopeId: null }; - if ($scope.remoteProductsLoading !== true) { + if (!$scope.productsLoading) { ProductsService.refreshProducts(); } @@ -162,31 +136,18 @@ app.controller('InternalRequestController', function ($controller, $scope, ApiRe ProductsService.ready.then(null, null, function () { $scope.products = ProductsService.getProducts(); + $scope.productsLoading = ProductsService.getProductsLoading(); + $scope.remoteProducts = ProductsService.getRemoteProducts(); + $scope.remoteProductsLoading = ProductsService.getRemoteProductsLoading(); }); - WsApi.listen(apiMapping.Product.listen).then(null, null, function (res) { - var productId = angular.isDefined($scope.featureRequestToPush.productId) ? $scope.featureRequestToPush.productId : null; - - ProductsService.refreshProducts(); - - if ($scope.remoteProductsLoading === false && productId !== null) { - var apiRes = angular.fromJson(res.body); - - if (apiRes.meta.status === 'SUCCESS') { - $scope.refreshRemoteProducts(productId); + InternalRequestRepo.listen([ApiResponseActions.CREATE, ApiResponseActions.DELETE, ApiResponseActions.UPDATE], function () { + $scope.internalRequests.length = 0; + var internalRequests = InternalRequestRepo.getAll(); + for (var i in internalRequests) { + $scope.internalRequests.push(internalRequests[i]); } - } }); } - InternalRequestRepo.listen([ApiResponseActions.CREATE, ApiResponseActions.DELETE, ApiResponseActions.UPDATE], function () { - var internalRequests = InternalRequestRepo.getAll(); - - $scope.internalRequests.length = 0; - - for (var i in internalRequests) { - $scope.internalRequests.push(internalRequests[i]); - } - }); - }); diff --git a/app/services/productsService.js b/app/services/productsService.js index 99529e3..64bfc9c 100644 --- a/app/services/productsService.js +++ b/app/services/productsService.js @@ -2,25 +2,46 @@ app.service('ProductsService', function ($q, ProductRepo, WsApi) { var service = this; var products = []; + var productsLoading = false; var remoteProducts = {}; + var remoteProductsLoading = []; var defer = $q.defer(); - var process = function (response) { - var apiRes = angular.fromJson(response.body); + var process = function (res) { + var apiRes = angular.fromJson(res.body); if (apiRes.meta.status === 'SUCCESS') { products.length = 0; + angular.extend(products, apiRes.payload['ArrayList']); defer.notify(); + productsLoading = false; + + var toRemove = {}; + for (var productId in remoteProducts) { + toRemove[productId] = productId; + } + + for (var key in products) { + toRemove[products[key].id] = undefined; + + if (!remoteProductsLoading[products[key].id]) { + service.refreshRemoteProducts(products[key].id); + } + } + + for (var id in toRemove) { + remoteProducts[id] = undefined; + } } else { console.error(apiRes.meta); throw "Unable to retrieve products"; } }; - var processRemoteProduct = function (response, productId, deferRefresh) { - var apiRes = angular.fromJson(response.body); + var processRemoteProduct = function (res, productId) { + var apiRes = angular.fromJson(res.body); if (apiRes.meta.status === 'SUCCESS') { if (angular.isDefined(remoteProducts[productId])) { @@ -32,47 +53,66 @@ app.service('ProductsService', function ($q, ProductRepo, WsApi) { } angular.extend(remoteProducts[productId], apiRes.payload.HashMap); - deferRefresh.notify(); + remoteProductsLoading[productId] = false; } else { throw "Unable to retrieve remote products for product " + productId; } }; - WsApi.listen(apiMapping.Product.listen).then(null, null, function (response) { - process(response); + WsApi.listen(apiMapping.Product.listen).then(null, null, function (res) { + service.refreshProducts(); }); service.refreshProducts = function () { - WsApi.fetch(apiMapping.Product.all).then(function (response) { - process(response); + if (productsLoading === false) { + productsLoading = true; - for (var productId in remoteProducts) { - service.refreshRemoteProducts(productId); - } - }); + WsApi.fetch(apiMapping.Product.all).then(function (res) { + process(res); + }); + } }; service.refreshRemoteProducts = function (productId) { - var deferRefresh = $q.defer(); - var options = { - pathValues: { - productId: productId + if (productsLoading === false) { + var productFound = false; + for (var key in products) { + if (products[key].id === productId) { + productFound = true; + break; + } + } + + if (productFound) { + var options = { + pathValues: { + productId: productId + } + }; + + remoteProductsLoading[productId] = true; + + WsApi.fetch(apiMapping.RemoteProducts.byProduct, options).then(function (res) { + processRemoteProduct(res, productId); + }); } - }; + } + }; - WsApi.fetch(apiMapping.RemoteProducts.byProduct, options).then(function (response) { - processRemoteProduct(response, productId, deferRefresh); - }); + service.getProducts = function () { + return products; + }; - return deferRefresh.promise; + service.getProductsLoading = function () { + return productsLoading; }; service.getRemoteProducts = function () { return remoteProducts; }; - service.getProducts = function () { - return products; + service.getRemoteProductsLoading = function () { + return remoteProductsLoading; }; service.getRemoteProductInfo = function (productId) { diff --git a/app/views/modals/pushInternalRequestModal.html b/app/views/modals/pushInternalRequestModal.html index 2773c4e..f115ad2 100644 --- a/app/views/modals/pushInternalRequestModal.html +++ b/app/views/modals/pushInternalRequestModal.html @@ -38,14 +38,14 @@
-
-
diff --git a/tests/mock/service/mockProductsService.js b/tests/mock/service/mockProductsService.js index 05098e2..74c6ac7 100644 --- a/tests/mock/service/mockProductsService.js +++ b/tests/mock/service/mockProductsService.js @@ -1,30 +1,28 @@ var mockProductsService = function ($q, $timeout) { var service = mockService($q); - var products = {}; + var defer = $q.defer(); + var products = []; + var productsLoading = false; var remoteProducts = {}; + var remoteProductsLoading = []; - service.getProducts = function () { - return products; + service.mockProductsLoading = function (loading) { + productsLoading = loading ? true : false; }; - service.getRemoteProductInfo = function (productId) { - for (var i in products) { - if (products[i].id == productId) { - return products[i].remoteProductInfo; - } - } - }; - - service.getRemoteProducts = function () { - return remoteProducts; + service.remoteProductsLoading = function (productId, loading) { + remoteProductsLoading[productId] = loading ? true : false; }; service.refreshProducts = function () { + productsLoading = false; return messagePromise($q.defer()); }; service.refreshRemoteProducts = function (productId) { + remoteProductsLoading[productId] = false; + if (dataFeatureRequest1.id == productId) { return notifyPromise($timeout, $q.defer(), dataFeatureRequest1); } @@ -32,7 +30,28 @@ var mockProductsService = function ($q, $timeout) { return rejectPromise($q.defer()); }; - service.ready = $q.defer().promise; + service.getProductsLoading = function () { + return productsLoading; + }; + + service.getRemoteProducts = function () { + return remoteProducts; + }; + + service.getRemoteProductsLoading = function () { + return remoteProductsLoading; + }; + + service.getRemoteProductInfo = function (productId) { + for (var i in products) { + if (products[i].id == productId) { + return products[i].remoteProductInfo; + } + } + }; + + service.ready = defer.promise; + defer.notify(); return service; }; diff --git a/tests/mock/service/mockWsApi.js b/tests/mock/service/mockWsApi.js index 0b83c42..23ef92a 100644 --- a/tests/mock/service/mockWsApi.js +++ b/tests/mock/service/mockWsApi.js @@ -28,6 +28,10 @@ angular.module("mock.wsApi", []).service("WsApi", function ($q) { service.fetch = function (apiReq, options) { var payload = {}; + if (angular.isUndefined(apiReq)) { + return rejectPromise($q.defer()); + } + if (fetchResponse) { switch (fetchResponse.type) { case "message": diff --git a/tests/unit/controllers/internalRequestControllerTest.js b/tests/unit/controllers/internalRequestControllerTest.js index d1aac7f..f3a373c 100644 --- a/tests/unit/controllers/internalRequestControllerTest.js +++ b/tests/unit/controllers/internalRequestControllerTest.js @@ -1,12 +1,11 @@ describe("controller: InternalRequestController", function () { - var $q, $scope, $templateCache, $timeout, MockedInternalRequest, InternalRequestRepo, InternalRequestsService, ProductRepo, ProductsService, WsApi, controller; + var $q, $scope, $templateCache, MockedInternalRequest, InternalRequestRepo, InternalRequestsService, ProductRepo, ProductsService, WsApi, controller; var initializeVariables = function () { - inject(function (_$compile_, _$q_, _$templateCache_, _$timeout_, _InternalRequestRepo_, _InternalRequestsService_, _ProductRepo_, _ProductsService_, _RemoteProductManagerRepo_, _WsApi_) { + inject(function (_$compile_, _$q_, _$templateCache_, _InternalRequestRepo_, _InternalRequestsService_, _ProductRepo_, _ProductsService_, _RemoteProductManagerRepo_, _WsApi_) { $compile = _$compile_; $q = _$q_; $templateCache = _$templateCache_; - $timeout = _$timeout_; MockedInternalRequest = new mockInternalRequest($q); @@ -250,36 +249,43 @@ describe("controller: InternalRequestController", function () { expect($scope.openModal).toHaveBeenCalled(); }); - it("refreshRemoteProducts call refreshRemoteProducts() and toggle remoteProductsLoading", function () { + it("refreshRemoteProducts should call the service refresh for a given product id", function () { var featureRequest = new mockFeatureRequest($q); - $scope.remoteProductsLoading = false; - $scope.remoteProducts = { removeThis: "" }; + $scope.remoteProducts = {}; + $scope.remoteProducts[featureRequest.productId] = {}; + $scope.remoteProductsLoading = {}; + $scope.remoteProductsLoading[featureRequest.productId] = false; - spyOn(ProductsService, "refreshRemoteProducts").and.callThrough(); + spyOn(ProductsService, "refreshRemoteProducts"); $scope.refreshRemoteProducts(featureRequest.productId); + expect(ProductsService.refreshRemoteProducts).toHaveBeenCalledWith(featureRequest.productId); + }); - expect($scope.remoteProductsLoading).toBe(true); + it("refreshRemoteProducts should not call the service refresh for a given product id when remoteProductsLoading for that product id", function () { + var featureRequest = new mockFeatureRequest($q); + $scope.remoteProducts = {}; + $scope.remoteProducts[featureRequest.productId] = {}; + $scope.remoteProductsLoading = {}; + $scope.remoteProductsLoading[featureRequest.productId] = true; - $timeout.flush(); + spyOn(ProductsService, "refreshRemoteProducts"); - expect(ProductsService.refreshRemoteProducts).toHaveBeenCalledWith(featureRequest.productId); - expect($scope.remoteProducts.removeThis).not.toBeDefined(); - expect($scope.remoteProductsLoading).toBe(false); + $scope.refreshRemoteProducts(featureRequest.productId); + expect(ProductsService.refreshRemoteProducts).not.toHaveBeenCalled(); }); - it("refreshRemoteProducts should do nothing when remoteProductsLoading is true", function () { + it("refreshRemoteProducts should not call the service refresh when there is no given product id", function () { var featureRequest = new mockFeatureRequest($q); - $scope.featureRequestToPush = featureRequest; - $scope.remoteProductsLoading = true; - $scope.remoteProducts = { removeThis: "" }; + $scope.remoteProducts = {}; + $scope.remoteProducts[featureRequest.productId] = {}; + $scope.remoteProductsLoading = {}; + $scope.remoteProductsLoading[featureRequest.productId] = false; spyOn(ProductsService, "refreshRemoteProducts"); $scope.refreshRemoteProducts(); - expect(ProductsService.refreshRemoteProducts).not.toHaveBeenCalled(); - expect($scope.remoteProducts.removeThis).toBeDefined(); }); it("resetCreateInternalRequest call resetInternalRequestForms() and clear out the properties", function () { @@ -329,36 +335,35 @@ describe("controller: InternalRequestController", function () { expect($scope.closeModal).toHaveBeenCalled(); }); - it("selectRemoteProducts select a remote product, set loading boolean, and refresh if needed", function () { - var featureRequest = new mockFeatureRequest($q); - - $scope.remoteProducts = { removeThis: "" }; - - $scope.featureRequestToPush = featureRequest; - $scope.remoteProductsLoading = false; + it("selectRemoteProducts select should call refresh for a given product id", function () { + $scope.featureRequestToPush = new mockFeatureRequest($q); + $scope.remoteProducts = {}; spyOn($scope, "refreshRemoteProducts"); $scope.selectRemoteProducts(); - expect($scope.refreshRemoteProducts).toHaveBeenCalled(); - expect($scope.remoteProducts.removeThis).not.toBeDefined(); }); - it("selectRemoteProducts does nothing when remoteProductsLoading is true", function () { - var featureRequest = new mockFeatureRequest($q); + it("selectRemoteProducts select should not call refresh for a given product id if already loaded", function () { + $scope.featureRequestToPush = new mockFeatureRequest($q); + $scope.remoteProducts = {}; + $scope.remoteProducts[$scope.featureRequestToPush.productId] = {}; - $scope.remoteProducts = { removeThis: "" }; + spyOn($scope, "refreshRemoteProducts"); - $scope.featureRequestToPush = featureRequest; - $scope.remoteProductsLoading = true; + $scope.selectRemoteProducts(); + expect($scope.refreshRemoteProducts).not.toHaveBeenCalled(); + }); + + it("selectRemoteProducts should not call refresh if no product id is available", function () { + $scope.featureRequestToPush = {}; + $scope.remoteProducts = {}; spyOn($scope, "refreshRemoteProducts"); $scope.selectRemoteProducts(); - expect($scope.refreshRemoteProducts).not.toHaveBeenCalled(); - expect($scope.remoteProducts.removeThis).toBeDefined(); }); it("updateInternalRequest call dirty and save on the InternalRequest, and then call cancelEditInternalRequest", function () { diff --git a/tests/unit/services/productsServiceTest.js b/tests/unit/services/productsServiceTest.js index 6b618d0..d19acf7 100644 --- a/tests/unit/services/productsServiceTest.js +++ b/tests/unit/services/productsServiceTest.js @@ -43,8 +43,10 @@ describe("service: ProductsService", function () { describe("Is the service method", function () { var methods = [ "getProducts", + "getProductsLoading", "getRemoteProducts", "getRemoteProductInfo", + "getRemoteProductsLoading", "refreshProducts", "refreshRemoteProducts" ]; @@ -84,14 +86,20 @@ describe("service: ProductsService", function () { expect(response).toEqual(dataProductRepo1); }); - it("getRemoteProducts should return all remote products for a given product", function () { - var response; + it("getProductsLoading should return the current loading status for projects", function () { + var response = service.getProductsLoading(); + expect(response).toEqual(false); + }); - // @todo needs to be a test that checks when remote products has products assigned: - //service.refreshRemoteProducts(1); + it("getRemoteProducts should return all remote products for a given product", function () { + // @todo + //var response = service.getRemoteProducts(); + //expect(response).toEqual(dataRemoteProducts); + }); - response = service.getRemoteProducts(); - expect(response).toEqual({}); + it("getRemoteProductsLoading should return the current loading status for all remote products", function () { + var response = service.getRemoteProductsLoading(); + expect(response).toBeDefined(); }); it("getRemoteProductInfo should return all remote product info for a given product", function () {