From e235239fdaf409edd18a0ee50bb1b697da8f3510 Mon Sep 17 00:00:00 2001 From: Kevin Day Date: Fri, 8 May 2020 18:30:08 -0500 Subject: [PATCH] Implement fetching on change and dimplify internal request service design I accidentally left an incomplete @todo that was intended to be implemented in the relevant card. Simplify the implementation and update the tests while I am at it. --- app/controllers/internalRequestController.js | 61 ++++++++++-- app/services/productsService.js | 70 +++++++++++--- .../remoteProductsByProductIdService.js | 66 ------------- .../modals/pushInternalRequestModal.html | 8 +- tests/mock/service/mockProductsService.js | 42 ++++++-- .../mockRemoteProductsByProductIdService.js | 36 ------- .../internalRequestControllerTest.js | 73 ++++++++++++-- .../services/internalRequestsServiceTest.js | 2 +- tests/unit/services/productsServiceTest.js | 28 +++++- .../remoteProductsByProductIdServiceTest.js | 96 ------------------- 10 files changed, 231 insertions(+), 251 deletions(-) delete mode 100644 app/services/remoteProductsByProductIdService.js delete mode 100644 tests/mock/service/mockRemoteProductsByProductIdService.js delete mode 100644 tests/unit/services/remoteProductsByProductIdServiceTest.js diff --git a/app/controllers/internalRequestController.js b/app/controllers/internalRequestController.js index 9ff4ea0..156a7be 100644 --- a/app/controllers/internalRequestController.js +++ b/app/controllers/internalRequestController.js @@ -1,4 +1,4 @@ -app.controller('InternalRequestController', function ($controller, $scope, ApiResponseActions, InternalRequestRepo, InternalRequestsService, ProductRepo, RemoteProductsByProductIdService, ProductsService) { +app.controller('InternalRequestController', function ($controller, $scope, ApiResponseActions, InternalRequestRepo, InternalRequestsService, ProductRepo, ProductsService, WsApi) { angular.extend(this, $controller('AbstractController', { $scope: $scope @@ -12,6 +12,10 @@ app.controller('InternalRequestController', function ($controller, $scope, ApiRe $scope.featureRequestToPush = {}; + $scope.products = []; + $scope.remoteProducts = {}; + $scope.remoteProductsLoading = false; + $scope.resetInternalRequestForms = function () { InternalRequestRepo.clearValidationResults(); @@ -27,11 +31,40 @@ app.controller('InternalRequestController', function ($controller, $scope, ApiRe $scope.resetInternalRequestForms(); if ($scope.isManager() || $scope.isAdmin()) { - $scope.remoteProductsByProduct = RemoteProductsByProductIdService.remoteProducts(); - $scope.products = ProductsService.getProducts(); + $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); + } + } + } + }; + + $scope.refreshRemoteProducts = function (productId) { + if ($scope.remoteProductsLoading === false) { + $scope.remoteProductsLoading = true; + $scope.remoteProducts = {}; + + ProductsService.refreshRemoteProducts(productId).then(null, null, function (res) { + remoteProducts = ProductsService.getRemoteProducts(); - $scope.refreshProductRemoteProducts = function () { - RemoteProductsByProductIdService.refreshRemoteProductsByProductId($scope.featureRequestToPush.productId); + if (angular.isDefined(remoteProducts[productId])) { + angular.extend($scope.remoteProducts, remoteProducts[productId]); + } + + $scope.remoteProductsLoading = false; + }).catch(function() { + $scope.remoteProductsLoading = false; + }); + } }; $scope.createInternalRequest = function () { @@ -123,13 +156,21 @@ app.controller('InternalRequestController', function ($controller, $scope, ApiRe }); }; - ProductRepo.listen([ApiResponseActions.CREATE, ApiResponseActions.DELETE, ApiResponseActions.UPDATE], function () { - var products = ProductRepo.getAll(); + ProductsService.ready.then(null, null, function () { + $scope.products = ProductsService.getProducts(); + }); - $scope.products.length = 0; + WsApi.listen(apiMapping.Product.listen).then(null, null, function (res) { + var productId = angular.isDefined($scope.featureRequestToPush.productId) ? $scope.featureRequestToPush.productId : null; - for (var i in products) { - $scope.products.push(products[i]); + ProductsService.refreshProducts(); + + if ($scope.remoteProductsLoading === false && productId !== null) { + var apiRes = angular.fromJson(res.body); + + if (apiRes.meta.status === 'SUCCESS') { + $scope.refreshRemoteProducts(productId); + } } }); } diff --git a/app/services/productsService.js b/app/services/productsService.js index ed48929..167f04a 100644 --- a/app/services/productsService.js +++ b/app/services/productsService.js @@ -1,39 +1,81 @@ app.service('ProductsService', function ($q, ProductRepo, WsApi) { - var productsService = this; + var service = this; - var products = {}; + var products = []; + var remoteProducts = {}; var defer = $q.defer(); var process = function (response) { var apiRes = angular.fromJson(response.body); + if (apiRes.meta.status === 'SUCCESS') { + products.length = 0; angular.extend(products, apiRes.payload['ArrayList']); - defer.resolve(); - ProductRepo.reset(); + defer.notify(); } else { console.error(apiRes.meta); throw "Unable to retrieve products"; } }; + var processRemoteProduct = function (response, productId, deferRefresh) { + var apiRes = angular.fromJson(response.body); + + if (apiRes.meta.status === 'SUCCESS') { + if (angular.isDefined(remoteProducts[productId])) { + for (var key in remoteProducts[productId]) { + remoteProducts[productId][key] = undefined; + } + } else { + remoteProducts[productId] = {}; + } + + angular.extend(remoteProducts[productId], apiRes.payload.HashMap); + deferRefresh.notify(); + } else { + throw "Unable to retrieve remote products for product " + productId; + } + }; + WsApi.listen(apiMapping.Product.listen).then(null, null, function (response) { process(response); }); - productsService.refreshProducts = function () { + service.refreshProducts = function () { WsApi.fetch(apiMapping.Product.all).then(function (response) { process(response); + + for (var productId in remoteProducts) { + service.refreshRemoteProducts(productId); + } }); }; - productsService.getProducts = function () { - return products; + service.refreshRemoteProducts = function (productId) { + var deferRefresh = $q.defer(); + var options = { + pathValues: { + productId: productId + } + }; + + WsApi.fetch(apiMapping.RemoteProducts.byProduct, options).then(function (response) { + processRemoteProduct(response, productId, deferRefresh); + }); + + return deferRefresh.promise; + }; + + service.getRemoteProducts = function () { + return remoteProducts; }; - productsService.getProductRemoteProducts = function (productId) { - var remoteProducts = {}; + service.getProducts = function () { + return products; + }; + service.getRemoteProductInfo = function (productId) { for (var i in products) { if (products[i].id == productId) { return products[i].remoteProducts; @@ -41,20 +83,20 @@ app.service('ProductsService', function ($q, ProductRepo, WsApi) { } }; - productsService.getById = function (id) { + service.getById = function (id) { return $q(function (resolve, reject) { - productsService.ready.then(function () { + service.ready.then(function () { for (var i in products) { if (products[i].id == id) { resolve(products[i]); } } }); - }.bind(productsService)); + }.bind(service)); }; - productsService.refreshProducts(); + service.refreshProducts(); - productsService.ready = defer.promise; + service.ready = defer.promise; }); diff --git a/app/services/remoteProductsByProductIdService.js b/app/services/remoteProductsByProductIdService.js deleted file mode 100644 index a17a434..0000000 --- a/app/services/remoteProductsByProductIdService.js +++ /dev/null @@ -1,66 +0,0 @@ -app.service('RemoteProductsByProductIdService', function ($q, WsApi) { - var service = this; - - var productId; - var remoteProducts = {}; - - var process = function (response) { - var apiRes = angular.fromJson(response.body); - - if (apiRes.meta.status === 'SUCCESS') { - if (productId) { - angular.extend(remoteProducts, apiRes.payload.HashMap); - } - } else { - console.error(apiRes.meta); - throw "Unable to retrieve remote products for product"; - } - }; - - WsApi.listen(apiMapping.Product.listen).then(null, null, function (response) { - if (productId === undefined) { - return; - } - - // @todo: walk through list of projects and only perform this if project for projectId is present. - - //service.fetchRemoteProductsByProductId(); - }); - - service.refreshRemoteProductsByProductId = function (id) { - if (productId == id) { - return; - } - - if (remoteProducts) { - for (var key in remoteProducts) { - remoteProducts[key] = undefined; - } - } - - if (!id) { - return; - } - - productId = id; - - var options = { - pathValues: { - productId: id - } - }; - - WsApi.fetch(apiMapping.RemoteProducts.byProduct, options).then(function (response) { - process(response); - }); - }; - - service.productId = function () { - return productId; - }; - - service.remoteProducts = function () { - return remoteProducts; - }; - -}); diff --git a/app/views/modals/pushInternalRequestModal.html b/app/views/modals/pushInternalRequestModal.html index cdd3f59..41ac52a 100644 --- a/app/views/modals/pushInternalRequestModal.html +++ b/app/views/modals/pushInternalRequestModal.html @@ -7,7 +7,7 @@
- +