From 56b533be385366e4f9d232d9850aa6988f3111e3 Mon Sep 17 00:00:00 2001 From: SviatlanaHlukhava Date: Wed, 18 Mar 2015 06:15:32 +0000 Subject: [PATCH 1/5] Update removed question getting --- src/main/webapp/js/app.js | 12 +-- .../questions/filteredQuestions.controller.js | 2 +- .../js/questions/questions.controller.js | 2 +- .../webapp/js/questions/questions.factory.js | 78 +++++++++++++++++-- src/main/webapp/js/utility.js | 6 +- .../unit/dataService/crud.factory.spec.js | 4 +- .../exportQuestions.controller.spec.js | 2 +- .../unit/questions/questions.factory.spec.js | 6 +- src/test/javascript/unit/utility.spec.js | 5 ++ 9 files changed, 96 insertions(+), 21 deletions(-) diff --git a/src/main/webapp/js/app.js b/src/main/webapp/js/app.js index 1701f8b..79bef4d 100644 --- a/src/main/webapp/js/app.js +++ b/src/main/webapp/js/app.js @@ -103,18 +103,18 @@ angular.module('eightyControllers', ['ui.router', 'ui.bootstrap']); return customersFactory.getCustomers(); } - getAllQuestionsWithTag.$inject = ['$stateParams', 'crudFactory']; - function getAllQuestionsWithTag($stateParams, crudFactory) { - var questions = crudFactory.questions().allQuestionsWithTag({tagName: replaceDOT($stateParams.tagName)}).$promise; + getAllQuestionsWithTag.$inject = ['$stateParams', 'questionsFactory']; + function getAllQuestionsWithTag($stateParams, questionsFactory) { + var questions = questionsFactory.getAllQuestionsWithTag($stateParams); questions.then(undefined, function (error) { printLog(error); }); return questions; } - getAllQuestionsFromCustomer.$inject = ['$stateParams', 'crudFactory']; - function getAllQuestionsFromCustomer($stateParams, crudFactory) { - var questions = crudFactory.questions().allQuestionsFromCustomer({customerName: replaceDOT($stateParams.customerName)}).$promise; + getAllQuestionsFromCustomer.$inject = ['$stateParams', 'questionsFactory']; + function getAllQuestionsFromCustomer($stateParams, questionsFactory) { + var questions = questionsFactory.getAllQuestionsFromCustomer($stateParams); questions.then(undefined, function (error) { printLog(error); }); diff --git a/src/main/webapp/js/questions/filteredQuestions.controller.js b/src/main/webapp/js/questions/filteredQuestions.controller.js index 7766945..7e14f09 100644 --- a/src/main/webapp/js/questions/filteredQuestions.controller.js +++ b/src/main/webapp/js/questions/filteredQuestions.controller.js @@ -37,7 +37,7 @@ } function rateUp(questionUI) { - questionsFactory.rateUp(questionUI); + questionsFactory.rateUp(questionUI, vm); } function editQuestion(question) { diff --git a/src/main/webapp/js/questions/questions.controller.js b/src/main/webapp/js/questions/questions.controller.js index 302ddf3..94877e0 100644 --- a/src/main/webapp/js/questions/questions.controller.js +++ b/src/main/webapp/js/questions/questions.controller.js @@ -63,7 +63,7 @@ } function rateUp(questionUI) { - questionsFactory.rateUp(questionUI); + questionsFactory.rateUp(questionUI, vm); } function exportQuestion(question) { diff --git a/src/main/webapp/js/questions/questions.factory.js b/src/main/webapp/js/questions/questions.factory.js index 607686d..6099859 100644 --- a/src/main/webapp/js/questions/questions.factory.js +++ b/src/main/webapp/js/questions/questions.factory.js @@ -12,10 +12,9 @@ .module('eightyFactories') .factory('questionsFactory', questionsFactory); - questionsFactory.$inject = ['$modal', '$stateParams', '$rootScope', 'crudFactory', 'modalData', 'utility']; - - function questionsFactory($modal, $stateParams, $rootScope, crudFactory, modalData, utility) { + questionsFactory.$inject = ['$document', '$modal', '$stateParams', '$rootScope', 'crudFactory', 'modalData', 'utility']; + function questionsFactory($document, $modal, $stateParams, $rootScope, crudFactory, modalData, utility) { var publicMethods = { checkCollapsed: checkCollapsed, checkInSet: checkInSet, @@ -32,7 +31,9 @@ loadTagsAndCustomersByTopic: loadTagsAndCustomersByTopic, getTopic: getTopic, saveQuestionChanges: saveQuestionChanges, - deleteQuestion: deleteQuestion + deleteQuestion: deleteQuestion, + getAllQuestionsWithTag: getAllQuestionsWithTag, + getAllQuestionsFromCustomer: getAllQuestionsFromCustomer }; return publicMethods; @@ -47,7 +48,7 @@ function checkInSet(key, obj) { return utility.containsInSet(key, obj); } - function rateUp(questionUI) { + function rateUp(questionUI, vm) { if (questionUI.like === null) { questionUI.like = 0; } @@ -62,9 +63,73 @@ utility.updateInSet('exportSet', question); } }, function(error) { - printLog(error); + if (error.status === 404) { + errorAlert('Question is not found!', $modal); + reloadPageAfterQuestionWasRemoved(vm); + } }); } + + function reloadPageAfterQuestionWasRemoved(vm) { + $rootScope.$broadcast('topTags-update'); + var str_url = $document[0].URL; + var topics_url = '#/topics/'; + var tags_url = '#/questionsWithTag/'; + var customers_url = '#/questionsFromCustomer/'; + if(str_url.search(topics_url) !== -1) { + reloadQuestionsAndTopicTagsOnTopicsPage(vm, getUrlPath(str_url, topics_url)); + } + if(str_url.search(tags_url) !== -1) { + reloadQuestionsOnQuestionsWithTagPage(vm, getUrlPath(str_url, tags_url)); + } + if(str_url.search(customers_url) !== -1) { + reloadQuestionsOnQuestionsFromCustomerPage(vm, getUrlPath(str_url, customers_url)); + } + if(vm.questionsForExport) { + reloadQuestionsForExport(vm); + } + } + + function reloadQuestionsAndTopicTagsOnTopicsPage(vm, topicId) { + $rootScope.$broadcast('topicTags-update'); + $stateParams.id = topicId; + loadQuestions(vm, 0); + } + function reloadQuestionsOnQuestionsWithTagPage(vm, tagName) { + $stateParams.tagName = tagName; + getAllQuestionsWithTag($stateParams).then(function(set) { + vm.questions = set; + }); + } + function reloadQuestionsOnQuestionsFromCustomerPage(vm, customer) { + $stateParams.customerName = customer; + getAllQuestionsFromCustomer($stateParams).then(function(set) { + vm.questions = set; + }); + } + function reloadQuestionsForExport(vm) { + crudFactory.questions().query().$promise.then(function(allQuestions) { + for(var i = vm.questionsForExport.length - 1; i >= 0; i--) { + var question = vm.questionsForExport[i]; + if(!containsInSet(allQuestions, question)) { + vm.questionsForExport.splice(i, 1); + utility.removeFromSet('exportSet', question); + } else { + if(allQuestions[getIndex(allQuestions, question)] != question) { + vm.questionsForExport[i] = allQuestions[getIndex(allQuestions, question)]; + utility.updateInSet('exportSet', question); + } + } + } + }); + } + function getAllQuestionsWithTag($stateParams) { + return crudFactory.questions().allQuestionsWithTag({tagName: replaceDOT($stateParams.tagName)}).$promise; + } + function getAllQuestionsFromCustomer($stateParams) { + return crudFactory.questions().allQuestionsFromCustomer({customerName: replaceDOT($stateParams.customerName)}).$promise; + } + function editQuestion(question, vm) { modalData.setShouldBeOpen(true); @@ -140,6 +205,7 @@ if ($stateParams.id) { crudFactory.questions().allQuestions({id: $stateParams.id, page: page, size: scrollAddOption.count, sort: scrollAddOption.sort}) .$promise.then(function (set) { + scope.questions = []; if ((page === 0) && (set.length === 0)) { page = -1; scope.message = 'No questions'; diff --git a/src/main/webapp/js/utility.js b/src/main/webapp/js/utility.js index cf81289..c85c709 100644 --- a/src/main/webapp/js/utility.js +++ b/src/main/webapp/js/utility.js @@ -1,5 +1,5 @@ 'use strict'; -/*exported isPrintLog, getIndex, containsInSet, replaceDOT, printLog, errorAlert */ +/*exported isPrintLog, getIndex, containsInSet, replaceDOT, printLog, errorAlert, getUrlPath */ /** * Created by Aliaksandr_Padalka on 25/08/2014. */ @@ -46,3 +46,7 @@ function errorAlert(msg, $modal) { size: 'sm' }); } + +function getUrlPath(str_url, path) { + return str_url.substring(str_url.indexOf(path) + path.length); +} \ No newline at end of file diff --git a/src/test/javascript/unit/dataService/crud.factory.spec.js b/src/test/javascript/unit/dataService/crud.factory.spec.js index 5d6796a..f736560 100644 --- a/src/test/javascript/unit/dataService/crud.factory.spec.js +++ b/src/test/javascript/unit/dataService/crud.factory.spec.js @@ -45,13 +45,13 @@ describe('service', function () { expectResponse(); }); - it('get full topic by id', function () { + /*it('get full topic by id', function () { $httpBackend.expectGET('topics/full/1').respond(fakeResponse); service.topic().getFull({id: '1'}).$promise.then(function (responseTopic) { response = responseTopic; }); expectResponse(); - }); + });*/ it('update topic with id', function () { $httpBackend.expectPUT('topics').respond(fakeResponse); diff --git a/src/test/javascript/unit/questions/exportQuestions.controller.spec.js b/src/test/javascript/unit/questions/exportQuestions.controller.spec.js index a4405b5..b02c259 100644 --- a/src/test/javascript/unit/questions/exportQuestions.controller.spec.js +++ b/src/test/javascript/unit/questions/exportQuestions.controller.spec.js @@ -29,7 +29,7 @@ describe('exportCtrl', function() { })); it("check export", function () { - exportCtrl = controller('exportCtrl', {$document: document}); + exportCtrl = controller('exportCtrl', {$document: document}); expect(exportCtrl.checkExport(key)).toBe(true); expect(exportCtrl.exportLen).toBe(2); serviceUtility.eraseSet(key); diff --git a/src/test/javascript/unit/questions/questions.factory.spec.js b/src/test/javascript/unit/questions/questions.factory.spec.js index 1812b5f..7ec5b56 100644 --- a/src/test/javascript/unit/questions/questions.factory.spec.js +++ b/src/test/javascript/unit/questions/questions.factory.spec.js @@ -99,10 +99,10 @@ describe('service', function () { it('rateUp GET response with error', function () { $httpBackend.expectGET('questions/1').respond(404, ''); - spyOn(console, 'log'); - service.rateUp({id: 1}); + spyOn(window, 'errorAlert'); + service.rateUp({id: 1}, scope); $httpBackend.flush(); - expect(console.log).toHaveBeenCalled(); + expect(errorAlert).toHaveBeenCalled(); }); it('rateUp PUT response with error', function () { diff --git a/src/test/javascript/unit/utility.spec.js b/src/test/javascript/unit/utility.spec.js index e4fab26..fe1f215 100644 --- a/src/test/javascript/unit/utility.spec.js +++ b/src/test/javascript/unit/utility.spec.js @@ -46,4 +46,9 @@ describe('utility', function() { errorAlert('Bla-bla-bla', $modal); expect(errorAlert).toHaveBeenCalled(); }); + + it('get path of url', function() { + var id = getUrlPath('/topics/2', '/topics/'); + expect(id).toBe('2'); + }); }); \ No newline at end of file From 18daceecc04100fe3bf85897550a0ba371506043 Mon Sep 17 00:00:00 2001 From: SviatlanaHlukhava Date: Mon, 23 Mar 2015 11:47:41 +0000 Subject: [PATCH 2/5] update getting deleted topic --- .jshintrc | 1 + .../eighty/repository/TopicRepository.java | 2 +- .../com/epam/eighty/service/TopicService.java | 3 +- .../eighty/service/impl/TopicServiceImpl.java | 30 ++++++- .../epam/eighty/web/api/TopicController.java | 17 +++- .../webapp/js/dataService/crud.factory.js | 5 +- .../webapp/js/questions/questions.factory.js | 2 +- .../js/topicTree/treeNavigation.controller.js | 9 +- .../js/topicTree/treeNavigation.factory.js | 87 ++++++++++++++----- .../repository/TopicRepositoryTest.java | 3 +- .../epam/eighty/service/TopicServiceTest.java | 8 -- .../eighty/web/api/TopicControllerTest.java | 5 -- .../treeNavigation.controller.spec.js | 14 +-- .../topicTree/treeNavigation.factory.spec.js | 8 -- 14 files changed, 132 insertions(+), 62 deletions(-) diff --git a/.jshintrc b/.jshintrc index c6ad47d..ecae062 100644 --- a/.jshintrc +++ b/.jshintrc @@ -35,6 +35,7 @@ "getLength": true, "getExport": true, "isPrintLog": true, + "getUrlPath": true, "editQuestionInstanceCtrl": true } } \ No newline at end of file diff --git a/src/main/java/com/epam/eighty/repository/TopicRepository.java b/src/main/java/com/epam/eighty/repository/TopicRepository.java index 71a0529..26cb39a 100644 --- a/src/main/java/com/epam/eighty/repository/TopicRepository.java +++ b/src/main/java/com/epam/eighty/repository/TopicRepository.java @@ -11,6 +11,6 @@ */ @Repository("topicRepo") public interface TopicRepository extends BaseRepository { - @Query(value = "MATCH (root:`Topic`)-[:`contains`*]->(topic:`Topic`) WHERE ID(topic) = {0} RETURN root", elementClass = Topic.class) + @Query(value = "MATCH (root:`Topic`)-[:`contains`*]->(topic:`Topic`) WHERE ID(topic) = {0} RETURN root UNION ALL MATCH (root:`Topic`) WHERE ID(root) = {0} return root", elementClass = Topic.class) Slice getRootTopicsForTopic(Long id); } diff --git a/src/main/java/com/epam/eighty/service/TopicService.java b/src/main/java/com/epam/eighty/service/TopicService.java index baac21e..3444e92 100644 --- a/src/main/java/com/epam/eighty/service/TopicService.java +++ b/src/main/java/com/epam/eighty/service/TopicService.java @@ -18,5 +18,6 @@ public interface TopicService { void deleteTopic(Long id); Optional getFullTopicById(Long id); Topic createTopic(Topic topic, Long id); - List getRootTopicsForTopic(Long id); + Long getIdOfLastNotDeletedTopic(List topicIds); + Optional getTopicWithChildsTillTopicWithId(Long id); } diff --git a/src/main/java/com/epam/eighty/service/impl/TopicServiceImpl.java b/src/main/java/com/epam/eighty/service/impl/TopicServiceImpl.java index b88b98c..23380aa 100644 --- a/src/main/java/com/epam/eighty/service/impl/TopicServiceImpl.java +++ b/src/main/java/com/epam/eighty/service/impl/TopicServiceImpl.java @@ -45,6 +45,7 @@ public Optional getFullTopicById(final Long id) { return topic; } + @Override public Optional getTopicById(final Long id) { Optional topic = topicRepo.findOne(id); @@ -82,7 +83,32 @@ public Topic createTopic(final Topic topic, final Long id) { } @Override - public List getRootTopicsForTopic(final Long id) { - return topicRepo.getRootTopicsForTopic(id).getContent(); + public Long getIdOfLastNotDeletedTopic(List topicIds) { + for(Long id: topicIds) { + Optional topic = topicRepo.findOne(id); + if(topic.isPresent()) { + return id; + } + } + return null; + } + + @Override + public Optional getTopicWithChildsTillTopicWithId(Long id) { + Optional root = topicRepo.findBySchemaPropertyValue("title", "root"); + List path = topicRepo.getRootTopicsForTopic(id).getContent(); + root.ifPresent(r -> { + topicsFetchIfNeeded(r, path); + }); + return root; + } + + private void topicsFetchIfNeeded(Topic topic, List path) { + topic.getTopics().forEach(t -> { + template.fetch(t); + if(path.contains(t)) { + topicsFetchIfNeeded(t, path); + } + }); } } diff --git a/src/main/java/com/epam/eighty/web/api/TopicController.java b/src/main/java/com/epam/eighty/web/api/TopicController.java index 941399c..b303325 100644 --- a/src/main/java/com/epam/eighty/web/api/TopicController.java +++ b/src/main/java/com/epam/eighty/web/api/TopicController.java @@ -115,6 +115,19 @@ public Topic createTopic(@ApiParam(name = "topic", required = true, value = "top return topicService.createTopic(topic, id); } + @ApiOperation(value = "Create topic", notes = "Create topic", httpMethod = "POST", response = Topic.class, consumes = "application/json") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "application/json question"), + @ApiResponse(code = 400, message = "Bad request"), }) + @Timed + @RequestMapping(value = "/notRemoved", method = RequestMethod.POST) + @ResponseBody + @CacheEvict(value = "topic", allEntries = true) + public Long getIdOfLastNotDeletedTopic(@ApiParam(name = "topicIds", required = true, value = "topicIds") @RequestBody final List topicIds, + final HttpServletResponse response) { + return topicService.getIdOfLastNotDeletedTopic(topicIds); + } + @ApiOperation(value = "Update topic", notes = "Update topic", httpMethod = "PUT", response = Topic.class, consumes = "application/json") @ApiResponses(value = { @ApiResponse(code = 200, message = "application/json question"), @@ -138,7 +151,7 @@ public Topic updateTopic(@ApiParam(name = "topic", required = true, value = "top @RequestMapping(value = "/path/{id}", method = RequestMethod.GET) @ResponseBody @Cacheable(value = "topic", key = "'path.' + #id") - public List getPath(@ApiParam(name = "topicId", required = true, value = "topic id") @PathVariable("id") final Long id) { - return topicService.getRootTopicsForTopic(id); + public Topic getPath(@ApiParam(name = "topicId", required = true, value = "topic id") @PathVariable("id") final Long id) { + return topicService.getTopicWithChildsTillTopicWithId(id).orElseThrow(() -> new TopicNotFoundException(id)); } } diff --git a/src/main/webapp/js/dataService/crud.factory.js b/src/main/webapp/js/dataService/crud.factory.js index 9834233..4b904c7 100644 --- a/src/main/webapp/js/dataService/crud.factory.js +++ b/src/main/webapp/js/dataService/crud.factory.js @@ -39,13 +39,14 @@ * - `{object}` `get({Number} id)` — Request for topic with given id. * - `{object}` `update({object} topic)` — Request for update the given topic. */ - function topic () { + function topic() { return $resource('topics/:id', {}, { get: {method: 'GET', params: {id: '@id'}}, getFull: { method: 'GET', url: 'topics/full/:id', params: {id: '@id'} }, + getLastNotRemoved: { method: 'POST', url: 'topics/notRemoved' }, update: { method: 'PUT', url: 'topics' }, create: { method: 'POST', params: {id: '@id'}}, - getPath: { method: 'GET', url: 'topics/path/:id', params: {id: '@id'} } + getPath: { method: 'GET', url: 'topics/path/:id', params: {id: '@id'}} }); } diff --git a/src/main/webapp/js/questions/questions.factory.js b/src/main/webapp/js/questions/questions.factory.js index 6099859..d42075c 100644 --- a/src/main/webapp/js/questions/questions.factory.js +++ b/src/main/webapp/js/questions/questions.factory.js @@ -115,7 +115,7 @@ vm.questionsForExport.splice(i, 1); utility.removeFromSet('exportSet', question); } else { - if(allQuestions[getIndex(allQuestions, question)] != question) { + if(allQuestions[getIndex(allQuestions, question)] !== question) { vm.questionsForExport[i] = allQuestions[getIndex(allQuestions, question)]; utility.updateInSet('exportSet', question); } diff --git a/src/main/webapp/js/topicTree/treeNavigation.controller.js b/src/main/webapp/js/topicTree/treeNavigation.controller.js index fef9730..1ca22fc 100644 --- a/src/main/webapp/js/topicTree/treeNavigation.controller.js +++ b/src/main/webapp/js/topicTree/treeNavigation.controller.js @@ -23,13 +23,14 @@ function activate() { crudFactory.topic().get({id: ''}).$promise.then(function(topic) { - vm.treedata = treeNavigationFactory.getTreeTopics(topic); + vm.treedata = treeNavigationFactory.getTreeTopics(topic); }, function(error) { printLog(error); }); } function onTopicClick(node) { + console.log(vm.initialSelection); $state.go('topics', {id: node.data.id}); } @@ -39,13 +40,15 @@ treeNode.topics = treeNavigationFactory.getTreeTopics(topic); vm.treeControl.expand_branch(treeNode); }, function(error) { - printLog(error); + if (error.status === 404) { + treeNavigationFactory.reloadTopics(treeNode, vm); + } }); } function editTopic(node) { modalData.setShouldBeOpen(true); - treeNavigationFactory.editTopic(node); + treeNavigationFactory.editTopic(node, vm); } function addTopic(node) { diff --git a/src/main/webapp/js/topicTree/treeNavigation.factory.js b/src/main/webapp/js/topicTree/treeNavigation.factory.js index b822c26..3d535f8 100644 --- a/src/main/webapp/js/topicTree/treeNavigation.factory.js +++ b/src/main/webapp/js/topicTree/treeNavigation.factory.js @@ -20,33 +20,72 @@ getTreeTopics: getTreeTopics, editTopic: editTopic, addTopic: addTopic, - deleteTopic: deleteTopic + deleteTopic: deleteTopic, + reloadTopics: reloadTopics }; return publicMethods; - function getTreeTopics(topic) { - var result = []; - var firstSubtopics = topic.topics; - firstSubtopics.forEach(function(entry) { - var firstTreeTopic = {}; - firstTreeTopic.title = entry.title; - firstTreeTopic.data = {}; - firstTreeTopic.data.id = entry.id; - firstTreeTopic.topics = []; - var secondSubtopics = entry.topics; - secondSubtopics.forEach(function(subEntry) { - var secondTreeTopic = {}; - secondTreeTopic.title = subEntry.title; - secondTreeTopic.data = {}; - secondTreeTopic.data.id = subEntry.id; - firstTreeTopic.topics.push(secondTreeTopic); - }); - result.push(firstTreeTopic); - }); - return result; + function getTreeTopics(topic) { + return getTopicWithTopics(topic).topics; + } + + function getTopicWithTopics(topic) { + for(var i = 0; i < topic.topics.length; i++) { + topic.topics[i].data = {}; + topic.topics[i].data.id = topic.topics[i].id; + delete topic.topics[i].id; + delete topic.topics[i].questions; + getTopicWithTopics(topic.topics[i]); + if(topic.topics[i].topics.length === 0) { + delete topic.topics[i].topics; + } + } + return topic; } - function editTopic(node) { + function reloadTopics(treeNode, vm) { + errorAlert('Topic is not found!', $modal); + var treeNodesToTheRoot = getPathOfNodes(treeNode, vm); + crudFactory.topic().getLastNotRemoved(treeNodesToTheRoot).$promise.then(function(topicIdResource) { + var topicId = parseInt(topicIdResource[0]); + crudFactory.topic().getPath({id: topicId}).$promise.then(function(topic) { + vm.treedata = getTreeTopics(topic); + var node; + for(var i = treeNodesToTheRoot.length - 1; i >= treeNodesToTheRoot.indexOf(topicId); i--) { + if(node === undefined) { + node = getChildNode(vm.treedata, treeNodesToTheRoot[i]); + } else { + var childrenNodes = vm.treeControl.get_children(node); + node = getChildNode(childrenNodes, treeNodesToTheRoot[i]); + } + vm.treeControl.expand_branch(node); + } + }, function(error) { + printLog(error); + }); + }); + } + + function getPathOfNodes(treeNode, vm) { + var nodeIds = []; + while(vm.treeControl.get_parent_branch(treeNode) !== null && vm.treeControl.get_parent_branch(treeNode) !== undefined) { + nodeIds.push(vm.treeControl.get_parent_branch(treeNode).data.id); + treeNode = vm.treeControl.get_parent_branch(treeNode); + } + return nodeIds; + } + + function getChildNode(treeNode, id) { + var node; + for(var i = 0; i < treeNode.length; i++) { + if(treeNode[i].data.id === id) { + node = treeNode[i]; + } + } + return node; + } + + function editTopic(node, vm) { var modalInstance = $modal .open({ templateUrl: 'pages/edittopic.html', @@ -67,7 +106,9 @@ errorAlert('Cannot edit topic!', $modal); }); }, function(error) { - printLog(error); + if (error.status === 404) { + reloadTopics(node, vm); + } }); }); diff --git a/src/test/java/com/epam/eighty/repository/TopicRepositoryTest.java b/src/test/java/com/epam/eighty/repository/TopicRepositoryTest.java index e5f966a..724eada 100644 --- a/src/test/java/com/epam/eighty/repository/TopicRepositoryTest.java +++ b/src/test/java/com/epam/eighty/repository/TopicRepositoryTest.java @@ -158,8 +158,9 @@ public void test_getRootTopicsForTopic() { List result = topicRepo.getRootTopicsForTopic(topic.getId()).getContent(); assertNotNull(result); - assertEquals(result.size(), 2); + assertEquals(result.size(), 3); + topicRepo.delete(topic); topicRepo.delete(root3); topicRepo.delete(root2); topicRepo.delete(root1); diff --git a/src/test/java/com/epam/eighty/service/TopicServiceTest.java b/src/test/java/com/epam/eighty/service/TopicServiceTest.java index 95bc644..e66a233 100644 --- a/src/test/java/com/epam/eighty/service/TopicServiceTest.java +++ b/src/test/java/com/epam/eighty/service/TopicServiceTest.java @@ -139,12 +139,4 @@ public void test_getRoot() { assertNotNull(topic); assertEquals(topic, root.get()); } - - @Test - public void test_getRootTopicsForTopic() { - when(topicRepo.getRootTopicsForTopic(5L)).thenReturn(path); - List topics = topicService.getRootTopicsForTopic(5L); - assertNotNull(topics); - assertEquals(topics, list); - } } diff --git a/src/test/java/com/epam/eighty/web/api/TopicControllerTest.java b/src/test/java/com/epam/eighty/web/api/TopicControllerTest.java index d7cf211..e321930 100644 --- a/src/test/java/com/epam/eighty/web/api/TopicControllerTest.java +++ b/src/test/java/com/epam/eighty/web/api/TopicControllerTest.java @@ -120,9 +120,4 @@ public void test_createTopic() { verify(response, Mockito.times(1)).setStatus(HttpServletResponse.SC_OK); } - @Test - public void test_getPath() { - when(topicService.getRootTopicsForTopic(5L)).thenReturn(list); - assertTrue(topicController.getPath(5L).equals(list)); - } } diff --git a/src/test/javascript/unit/topicTree/treeNavigation.controller.spec.js b/src/test/javascript/unit/topicTree/treeNavigation.controller.spec.js index b2a1d03..cea7a8e 100644 --- a/src/test/javascript/unit/topicTree/treeNavigation.controller.spec.js +++ b/src/test/javascript/unit/topicTree/treeNavigation.controller.spec.js @@ -3,7 +3,7 @@ describe('treeNavigationCtrl', function () { var ctrl, $httpBackend, modalControllerMock, stateMock, treeNavigationFactoryMock; - var rootTopic = {"id": 0, "title": "root", "topics": [{"id": 1, "title": "Programming Languages", "topics": [{"id": 6, "title": "Java", "topics": [{"id": 7, "title": null, "topics": [], "questions": []}], "questions": []}], "questions": []},{"id": 2, "title": "Persistence", "topics": [{"id": 3, "title": "Query Lanquages", "topics": [{"id": 4, "title": null, "topics": [], "questions": []},{"id": 5, "title": null, "topics": [], "questions": []}], "questions": []}], "questions": []}], "questions": []}; + var rootTopic = {"id": 0, "title": "root", "topics": [{"id": 1, "title": "Programming Languages", "topics": [{"id": 6, "title": "Java", "topics": [], "questions": []}], "questions": []},{"id": 2, "title": "Persistence", "topics": [{"id": 3, "title": "Query Lanquages", "topics": [], "questions": []}], "questions": []}], "questions": []}; var topic1 = {"id": 1, "title": "Programming Languages", "topics": [{"id": 6, "title": "Java", "topics": [{"id": 7, "title": null, "topics": [], "questions": []}], "questions": []}], "questions": []}; var rootTree = [{"title": "Programming Languages", "data": {"id": 1}, "topics": [{"title": "Java", "data": {"id": 6}}]},{"title": "Persistence", "data": {"id": 2}, "topics": [{"title": "Query Lanquages", "data": {"id": 3}}]}]; var tree1 = [{"title": "Programming Languages", "data": {"id": 1}, "topics": [{"title": "Java", "data": {"id": 6}, "topics": [{"title": null, "data": {"id": 7}}]}]},{"title": "Persistence", "data": {"id": 2}, "topics": [{"title": "Query Lanquages", "data": {"id": 3}}]}]; @@ -38,6 +38,8 @@ describe('treeNavigationCtrl', function () { ctrl.treeControl = { expand_branch: function () { }, + get_parent_branch: function () { + }, }; })); @@ -61,10 +63,12 @@ describe('treeNavigationCtrl', function () { expect(ctrl.treedata).toEqualData([]); $httpBackend.flush(); $httpBackend.expectGET('topics/1').respond(404, ''); - spyOn(console, 'log'); + treeNavigationFactoryMock.addTopic = function(vm, node) { + }; + spyOn(treeNavigationFactoryMock, "reloadTopics"); ctrl.onFolderHeadClick(ctrl.treedata[0]); $httpBackend.flush(); - expect(console.log).toHaveBeenCalled(); + expect(treeNavigationFactoryMock.reloadTopics).toHaveBeenCalledWith(ctrl.treedata[0], ctrl); }); it('click on topic', function () { @@ -87,8 +91,8 @@ describe('treeNavigationCtrl', function () { treeNavigationFactoryMock.editTopic = function(node) { }; spyOn(treeNavigationFactoryMock, "editTopic"); - ctrl.editTopic(ctrl.treedata[0]); - expect(treeNavigationFactoryMock.editTopic).toHaveBeenCalledWith(ctrl.treedata[0]); + ctrl.editTopic(ctrl.treedata[0], ctrl); + expect(treeNavigationFactoryMock.editTopic).toHaveBeenCalledWith(ctrl.treedata[0], ctrl); }); it('delete topic', function () { diff --git a/src/test/javascript/unit/topicTree/treeNavigation.factory.spec.js b/src/test/javascript/unit/topicTree/treeNavigation.factory.spec.js index 4288ef5..b3759fc 100644 --- a/src/test/javascript/unit/topicTree/treeNavigation.factory.spec.js +++ b/src/test/javascript/unit/topicTree/treeNavigation.factory.spec.js @@ -95,14 +95,6 @@ describe('service', function () { expect(scope.treedata[0].topics[0].title).toEqualData(topic6.title); }); - it('edit topic with error while getting topic', function () { - $httpBackend.expectGET('topics/6').respond(404, ''); - spyOn(console, 'log'); - service.editTopic(scope.treedata[0].topics[0]); - $httpBackend.flush(); - expect(console.log).toHaveBeenCalled(); - }); - it('edit topic with error while updating topic', function () { $httpBackend.expectGET('topics/6').respond(topic6); $httpBackend.expectPUT('topics').respond(404, ''); From 6c8d4dc99eb819bbc1d53a31531ff84462b98620 Mon Sep 17 00:00:00 2001 From: SviatlanaHlukhava Date: Mon, 23 Mar 2015 11:59:42 +0000 Subject: [PATCH 3/5] Remove redundant console.log --- src/main/webapp/js/topicTree/treeNavigation.controller.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/webapp/js/topicTree/treeNavigation.controller.js b/src/main/webapp/js/topicTree/treeNavigation.controller.js index 1ca22fc..370de2c 100644 --- a/src/main/webapp/js/topicTree/treeNavigation.controller.js +++ b/src/main/webapp/js/topicTree/treeNavigation.controller.js @@ -30,7 +30,6 @@ } function onTopicClick(node) { - console.log(vm.initialSelection); $state.go('topics', {id: node.data.id}); } From c8f6c2b38d533f5742a038e292e7b01bdcb122fa Mon Sep 17 00:00:00 2001 From: SviatlanaHlukhava Date: Mon, 23 Mar 2015 14:04:59 +0000 Subject: [PATCH 4/5] Update getTopicWithChildsTillTopicWithId, add unit tests --- .../com/epam/eighty/service/TopicService.java | 2 +- .../eighty/service/impl/TopicServiceImpl.java | 4 +- .../epam/eighty/web/api/TopicController.java | 2 +- .../epam/eighty/service/TopicServiceTest.java | 20 +++++++++- .../eighty/web/api/TopicControllerTest.java | 14 +++++++ .../unit/dataService/crud.factory.spec.js | 8 ++-- .../unit/questions/questions.factory.spec.js | 38 +++++++++++++++++++ 7 files changed, 79 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/epam/eighty/service/TopicService.java b/src/main/java/com/epam/eighty/service/TopicService.java index 3444e92..dca90b5 100644 --- a/src/main/java/com/epam/eighty/service/TopicService.java +++ b/src/main/java/com/epam/eighty/service/TopicService.java @@ -19,5 +19,5 @@ public interface TopicService { Optional getFullTopicById(Long id); Topic createTopic(Topic topic, Long id); Long getIdOfLastNotDeletedTopic(List topicIds); - Optional getTopicWithChildsTillTopicWithId(Long id); + Topic getTopicWithChildsTillTopicWithId(Long id); } diff --git a/src/main/java/com/epam/eighty/service/impl/TopicServiceImpl.java b/src/main/java/com/epam/eighty/service/impl/TopicServiceImpl.java index 23380aa..c106e80 100644 --- a/src/main/java/com/epam/eighty/service/impl/TopicServiceImpl.java +++ b/src/main/java/com/epam/eighty/service/impl/TopicServiceImpl.java @@ -94,13 +94,13 @@ public Long getIdOfLastNotDeletedTopic(List topicIds) { } @Override - public Optional getTopicWithChildsTillTopicWithId(Long id) { + public Topic getTopicWithChildsTillTopicWithId(Long id) { Optional root = topicRepo.findBySchemaPropertyValue("title", "root"); List path = topicRepo.getRootTopicsForTopic(id).getContent(); root.ifPresent(r -> { topicsFetchIfNeeded(r, path); }); - return root; + return root.get(); } private void topicsFetchIfNeeded(Topic topic, List path) { diff --git a/src/main/java/com/epam/eighty/web/api/TopicController.java b/src/main/java/com/epam/eighty/web/api/TopicController.java index b303325..27182a4 100644 --- a/src/main/java/com/epam/eighty/web/api/TopicController.java +++ b/src/main/java/com/epam/eighty/web/api/TopicController.java @@ -152,6 +152,6 @@ public Topic updateTopic(@ApiParam(name = "topic", required = true, value = "top @ResponseBody @Cacheable(value = "topic", key = "'path.' + #id") public Topic getPath(@ApiParam(name = "topicId", required = true, value = "topic id") @PathVariable("id") final Long id) { - return topicService.getTopicWithChildsTillTopicWithId(id).orElseThrow(() -> new TopicNotFoundException(id)); + return topicService.getTopicWithChildsTillTopicWithId(id); } } diff --git a/src/test/java/com/epam/eighty/service/TopicServiceTest.java b/src/test/java/com/epam/eighty/service/TopicServiceTest.java index e66a233..9797457 100644 --- a/src/test/java/com/epam/eighty/service/TopicServiceTest.java +++ b/src/test/java/com/epam/eighty/service/TopicServiceTest.java @@ -83,7 +83,6 @@ public void setUp() { list = new ArrayList<>(); list.add(fake0); list.add(fake1); - list.add(fake2); path = new SliceImpl<>(list); } @@ -139,4 +138,23 @@ public void test_getRoot() { assertNotNull(topic); assertEquals(topic, root.get()); } + + @Test + public void test_getIdOfLastNotDeletedTopic() { + when(topicRepo.findOne(fake.get().getId())).thenReturn(fake); + when(topicRepo.findOne(100L)).thenReturn(Optional.empty()); + List topicIds = Arrays.asList(100L, fake.get().getId()); + Long id = topicService.getIdOfLastNotDeletedTopic(topicIds); + assertNotNull(id); + assertEquals(id, fake.get().getId()); + } + + @Test + public void test_getTopicWithChildsTillTopicWithId() { + when(topicRepo.findBySchemaPropertyValue("title", "root")).thenReturn(root); + when(topicRepo.getRootTopicsForTopic(10L)).thenReturn(path); + Topic topic = topicService.getTopicWithChildsTillTopicWithId(10L); + assertNotNull(topic); + assertEquals(topic, root.get()); + } } diff --git a/src/test/java/com/epam/eighty/web/api/TopicControllerTest.java b/src/test/java/com/epam/eighty/web/api/TopicControllerTest.java index e321930..fa5d777 100644 --- a/src/test/java/com/epam/eighty/web/api/TopicControllerTest.java +++ b/src/test/java/com/epam/eighty/web/api/TopicControllerTest.java @@ -17,6 +17,7 @@ import com.epam.eighty.exception.TopicNotFoundException; import java.io.IOException; +import java.util.Arrays; import java.util.List; import java.util.Optional; @@ -120,4 +121,17 @@ public void test_createTopic() { verify(response, Mockito.times(1)).setStatus(HttpServletResponse.SC_OK); } + @Test + public void test_getIdOfLastNotDeletedTopic() throws IOException { + List topics = Arrays.asList(1L, 2L, 3L); + when(topicService.getIdOfLastNotDeletedTopic(topics)).thenReturn(TEST_LONG); + assertTrue(topicController.getIdOfLastNotDeletedTopic(topics, response).equals(TEST_LONG)); + } + + @Test + public void test_getPath() throws IOException { + when(topicService.getTopicWithChildsTillTopicWithId(TEST_LONG)).thenReturn(topic); + assertTrue(topicController.getPath(TEST_LONG).equals(topic)); + } + } diff --git a/src/test/javascript/unit/dataService/crud.factory.spec.js b/src/test/javascript/unit/dataService/crud.factory.spec.js index f736560..e0d63d9 100644 --- a/src/test/javascript/unit/dataService/crud.factory.spec.js +++ b/src/test/javascript/unit/dataService/crud.factory.spec.js @@ -45,13 +45,13 @@ describe('service', function () { expectResponse(); }); - /*it('get full topic by id', function () { - $httpBackend.expectGET('topics/full/1').respond(fakeResponse); - service.topic().getFull({id: '1'}).$promise.then(function (responseTopic) { + it('get id of the last not removed topic', function () { + $httpBackend.expectPOST('topics/notRemoved').respond(fakeResponse); + service.topic().getLastNotRemoved([1, 2]).$promise.then(function (responseTopic) { response = responseTopic; }); expectResponse(); - });*/ + }); it('update topic with id', function () { $httpBackend.expectPUT('topics').respond(fakeResponse); diff --git a/src/test/javascript/unit/questions/questions.factory.spec.js b/src/test/javascript/unit/questions/questions.factory.spec.js index 7ec5b56..abb8ed8 100644 --- a/src/test/javascript/unit/questions/questions.factory.spec.js +++ b/src/test/javascript/unit/questions/questions.factory.spec.js @@ -153,6 +153,44 @@ describe('service', function () { expect(eightyStoreFactory.get('exportSet')[0].like).toBe(1); }); + it('get all questions with tag', function () { + var questionsSet = [ + {id: 1}, + {id: 2} + ]; + var $stateParams = { + tagName: "fakeTag" + }; + var responseArray = []; + $httpBackend.expectGET('questions/all/tag/fakeTag').respond(questionsSet); + service.getAllQuestionsWithTag($stateParams).then(function (responseQuestions) { + responseArray = responseQuestions; + }); + $httpBackend.flush(); + expect(responseArray.length).toBe(2); + expect(responseArray[0].id).toBe(1); + expect(responseArray[1].id).toEqual(2); + }); + + it('get all questions from customer', function () { + var questionsSet = [ + {id: 1}, + {id: 2} + ]; + var $stateParams = { + customerName: "fakeCustomer" + }; + var responseArray = []; + $httpBackend.expectGET('questions/all/customer/fakeCustomer').respond(questionsSet); + service.getAllQuestionsFromCustomer($stateParams).then(function (responseQuestions) { + responseArray = responseQuestions; + }); + $httpBackend.flush(); + expect(responseArray.length).toBe(2); + expect(responseArray[0].id).toBe(1); + expect(responseArray[1].id).toEqual(2); + }); + it('exportQuestion should add question to the exportSet', function () { var question = {id: 3}; var exportSet = [ From 3c6a1fc89084a945edac73aad713dd47d965d92c Mon Sep 17 00:00:00 2001 From: SviatlanaHlukhava Date: Mon, 23 Mar 2015 15:25:43 +0000 Subject: [PATCH 5/5] Fix reloadQuestionsForExport, add unit test --- .../webapp/js/questions/questions.factory.js | 5 ++- .../unit/questions/questions.factory.spec.js | 45 +++++++++++++++---- 2 files changed, 39 insertions(+), 11 deletions(-) diff --git a/src/main/webapp/js/questions/questions.factory.js b/src/main/webapp/js/questions/questions.factory.js index d42075c..a85881e 100644 --- a/src/main/webapp/js/questions/questions.factory.js +++ b/src/main/webapp/js/questions/questions.factory.js @@ -115,9 +115,10 @@ vm.questionsForExport.splice(i, 1); utility.removeFromSet('exportSet', question); } else { - if(allQuestions[getIndex(allQuestions, question)] !== question) { + var questionFromAllQuestions = allQuestions[getIndex(allQuestions, question)]; + if(questionFromAllQuestions !== question) { vm.questionsForExport[i] = allQuestions[getIndex(allQuestions, question)]; - utility.updateInSet('exportSet', question); + utility.updateInSet('exportSet', questionFromAllQuestions); } } } diff --git a/src/test/javascript/unit/questions/questions.factory.spec.js b/src/test/javascript/unit/questions/questions.factory.spec.js index abb8ed8..af79268 100644 --- a/src/test/javascript/unit/questions/questions.factory.spec.js +++ b/src/test/javascript/unit/questions/questions.factory.spec.js @@ -13,7 +13,7 @@ describe('service', function () { })); describe('questionsFactory', function () { - var $httpBackend, stateParams, rootScope; + var $httpBackend, stateParams, rootScope, $document, documentMock = []; var service, eightyStoreFactory, scope, modalInstanceMock; beforeEach(function() { @@ -31,8 +31,13 @@ describe('service', function () { spyOn(modalInstanceMock, "open") .andReturn({ result: modalResult }); + documentMock[0] = { + URL: '/#/topics/2' + }; + module(function($provide) { $provide.value('$modal', modalInstanceMock); + $provide.value('$document', documentMock); }); }); @@ -100,9 +105,35 @@ describe('service', function () { it('rateUp GET response with error', function () { $httpBackend.expectGET('questions/1').respond(404, ''); spyOn(window, 'errorAlert'); + var questionsSet = [ + {id: 1, question: "q1"}, + {id: 2}, + {id: 3} + ]; + $httpBackend.expectGET('questions/all/2?page=0&size=100&sort=a.question').respond(questionsSet); + spyOn(rootScope, '$broadcast'); + var exportSet = [ + {id: 1, question: "q2"}, + {id: 2}, + {id: 5} + ]; + eightyStoreFactory.set('exportSet', exportSet); + scope.questionsForExport = exportSet; + $httpBackend.expectGET('questions').respond(questionsSet); + service.rateUp({id: 1}, scope); $httpBackend.flush(); + expect(errorAlert).toHaveBeenCalled(); + expect(rootScope.$broadcast).toHaveBeenCalledWith('topicTags-update'); + expect(scope.questions.length).toBe(3); + expect(scope.questionsForExport.length).toBe(2); + expect(scope.questionsForExport[0].question).toBe("q1"); + expect(scope.questionsForExport[0].id).toBe(1); + expect(scope.questionsForExport[1].id).toBe(2); + expect(eightyStoreFactory.get('exportSet')[0].question).toBe("q1"); + expect(eightyStoreFactory.get('exportSet')[0].id).toBe(1); + expect(eightyStoreFactory.get('exportSet')[1].id).toBe(2); }); it('rateUp PUT response with error', function () { @@ -158,12 +189,10 @@ describe('service', function () { {id: 1}, {id: 2} ]; - var $stateParams = { - tagName: "fakeTag" - }; + stateParams.tagName = "fakeTag"; var responseArray = []; $httpBackend.expectGET('questions/all/tag/fakeTag').respond(questionsSet); - service.getAllQuestionsWithTag($stateParams).then(function (responseQuestions) { + service.getAllQuestionsWithTag(stateParams).then(function (responseQuestions) { responseArray = responseQuestions; }); $httpBackend.flush(); @@ -177,12 +206,10 @@ describe('service', function () { {id: 1}, {id: 2} ]; - var $stateParams = { - customerName: "fakeCustomer" - }; + stateParams.customerName = "fakeCustomer"; var responseArray = []; $httpBackend.expectGET('questions/all/customer/fakeCustomer').respond(questionsSet); - service.getAllQuestionsFromCustomer($stateParams).then(function (responseQuestions) { + service.getAllQuestionsFromCustomer(stateParams).then(function (responseQuestions) { responseArray = responseQuestions; }); $httpBackend.flush();