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 68ccb86..967a860 100644 --- a/src/main/java/com/epam/eighty/repository/TopicRepository.java +++ b/src/main/java/com/epam/eighty/repository/TopicRepository.java @@ -1,5 +1,7 @@ package com.epam.eighty.repository; +import org.springframework.data.domain.Slice; +import org.springframework.data.neo4j.annotation.Query; import org.springframework.stereotype.Repository; import com.epam.eighty.domain.Topic; @@ -10,4 +12,6 @@ @Repository("topicRepo") public interface TopicRepository extends BaseRepository { + @Query(value = "MATCH (root:`Topic`) WHERE ID(root) = {0} return root UNION ALL MATCH (root:`Topic`)-[:`contains`*]->(topic:`Topic`) WHERE ID(topic) = {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 11e6c45..88fd8a4 100644 --- a/src/main/java/com/epam/eighty/service/TopicService.java +++ b/src/main/java/com/epam/eighty/service/TopicService.java @@ -1,5 +1,6 @@ package com.epam.eighty.service; +import java.util.List; import java.util.Optional; import java.util.Set; @@ -16,4 +17,6 @@ public interface TopicService { void updateTopic(Topic topic); void deleteTopic(Long id); Topic createTopic(Topic topic, Long id); + Long getIdOfLastNotDeletedTopic(List topicIds); + 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 2ba1964..47b1a43 100644 --- a/src/main/java/com/epam/eighty/service/impl/TopicServiceImpl.java +++ b/src/main/java/com/epam/eighty/service/impl/TopicServiceImpl.java @@ -1,5 +1,6 @@ package com.epam.eighty.service.impl; +import java.util.List; import java.util.Optional; import java.util.Set; @@ -70,4 +71,33 @@ public Topic createTopic(final Topic topic, final Long id) { return topic; } + @Override + public Long getIdOfLastNotDeletedTopic(List topicIds) { + for(Long id: topicIds) { + Optional topic = topicRepo.findOne(id); + if(topic.isPresent()) { + return id; + } + } + return null; + } + + @Override + 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.get(); + } + + 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 0beffde..4497851 100644 --- a/src/main/java/com/epam/eighty/web/api/TopicController.java +++ b/src/main/java/com/epam/eighty/web/api/TopicController.java @@ -1,6 +1,7 @@ package com.epam.eighty.web.api; import java.io.IOException; +import java.util.List; import java.util.Optional; import javax.servlet.http.HttpServletResponse; @@ -101,6 +102,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"), @@ -115,4 +129,16 @@ public Topic updateTopic(@ApiParam(name = "topic", required = true, value = "top return topic; } + @ApiOperation(value = "Find path for topic by id", notes = "Get path for topic by id", httpMethod = "GET", response = Topic.class, produces = "application/json") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "application/json topic"), + @ApiResponse(code = 400, message = "Bad request"), + @ApiResponse(code = 404, message = "Not found") }) + @Timed + @RequestMapping(value = "/path/{id}", method = RequestMethod.GET) + @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); + } } 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/dataService/crud.factory.js b/src/main/webapp/js/dataService/crud.factory.js index 06e8bbe..2ded833 100644 --- a/src/main/webapp/js/dataService/crud.factory.js +++ b/src/main/webapp/js/dataService/crud.factory.js @@ -38,11 +38,13 @@ * - `{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'}}, + getLastNotRemoved: { method: 'POST', url: 'topics/notRemoved' }, update: { method: 'PUT', url: 'topics' }, - create: { method: 'POST', params: {id: '@id'}} + create: { method: 'POST', params: {id: '@id'}}, + getPath: { method: 'GET', url: 'topics/path/:id', params: {id: '@id'}} }); } 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..a85881e 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,74 @@ 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 { + var questionFromAllQuestions = allQuestions[getIndex(allQuestions, question)]; + if(questionFromAllQuestions !== question) { + vm.questionsForExport[i] = allQuestions[getIndex(allQuestions, question)]; + utility.updateInSet('exportSet', questionFromAllQuestions); + } + } + } + }); + } + 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 +206,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/topicTree/treeNavigation.controller.js b/src/main/webapp/js/topicTree/treeNavigation.controller.js index fef9730..370de2c 100644 --- a/src/main/webapp/js/topicTree/treeNavigation.controller.js +++ b/src/main/webapp/js/topicTree/treeNavigation.controller.js @@ -23,7 +23,7 @@ function activate() { crudFactory.topic().get({id: ''}).$promise.then(function(topic) { - vm.treedata = treeNavigationFactory.getTreeTopics(topic); + vm.treedata = treeNavigationFactory.getTreeTopics(topic); }, function(error) { printLog(error); }); @@ -39,13 +39,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/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/java/com/epam/eighty/repository/TopicRepositoryTest.java b/src/test/java/com/epam/eighty/repository/TopicRepositoryTest.java new file mode 100644 index 0000000..2451e9a --- /dev/null +++ b/src/test/java/com/epam/eighty/repository/TopicRepositoryTest.java @@ -0,0 +1,66 @@ +package com.epam.eighty.repository; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import java.io.IOException; +import java.util.List; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.neo4j.cypher.javacompat.ExecutionEngine; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.transaction.annotation.Transactional; + +import com.epam.eighty.domain.Topic; +import com.epam.eighty.resources.TestNeo4jConfig; + +/** + * @author Aliaksandr_Padalka + */ +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = TestNeo4jConfig.class) +@Transactional +public class TopicRepositoryTest { + + @Autowired + private TopicRepository topicRepo; + + @Autowired + private ExecutionEngine engine; + + @Autowired + private String createCypherScript; + + private String deleteScript = "START n=node(*) OPTIONAL MATCH (n)-[r]-() delete n,r;"; + + @Before + public void prepareTestDatabase() throws IOException { + engine.execute(createCypherScript); + } + + @After + public void cleanTestDatabase() { + engine.execute(deleteScript); + } + + @Test + public void test_getRootTopicsForTopic() { + Long topicId = topicRepo.findBySchemaPropertyValue("title", "Annotations").get().getId(); + + List result = topicRepo.getRootTopicsForTopic(topicId).getContent(); + + assertNotNull(result); + assertEquals(5, result.size()); + assertEquals("Annotations", result.get(0).getTitle()); + assertEquals("Language basics", result.get(1).getTitle()); + assertEquals("Java", result.get(2).getTitle()); + assertEquals("Programming Languages", result.get(3).getTitle()); + assertEquals("root", result.get(4).getTitle()); + + } +} diff --git a/src/test/java/com/epam/eighty/service/TopicServiceTest.java b/src/test/java/com/epam/eighty/service/TopicServiceTest.java index 6150a52..abcffc3 100644 --- a/src/test/java/com/epam/eighty/service/TopicServiceTest.java +++ b/src/test/java/com/epam/eighty/service/TopicServiceTest.java @@ -10,6 +10,8 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; +import org.springframework.data.domain.Slice; +import org.springframework.data.domain.SliceImpl; import org.springframework.data.neo4j.conversion.QueryResultBuilder; import org.springframework.data.neo4j.conversion.Result; import org.springframework.data.neo4j.template.Neo4jOperations; @@ -31,6 +33,7 @@ public class TopicServiceTest { private Optional root; private Result results; private Set fakes; + private Slice path; private List list; @Mock @@ -80,7 +83,7 @@ public void setUp() { list = new ArrayList<>(); list.add(fake0); list.add(fake1); - list.add(fake2); + path = new SliceImpl<>(list); } @Test @@ -128,4 +131,22 @@ public void test_getRoot() { 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 a7dbfae..415e6f6 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; @@ -106,4 +107,16 @@ 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 4287986..bb864d8 100644 --- a/src/test/javascript/unit/dataService/crud.factory.spec.js +++ b/src/test/javascript/unit/dataService/crud.factory.spec.js @@ -45,6 +45,15 @@ describe('service', function () { expectResponse(); }); + 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); service.topic().update(response).$promise.then(function (responseTopic) { @@ -60,6 +69,14 @@ describe('service', function () { }); expectResponse(); }); + + it('get path', function() { + $httpBackend.expectGET('topics/path/5').respond(fakeResponse); + service.topic().getPath({id: '5'}).$promise.then(function (responseTopic) { + response = responseTopic; + }); + expectResponse(); + }); it('get question by id', function () { $httpBackend.expectGET('questions/1').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..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); }); }); @@ -99,10 +104,36 @@ 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'); + 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(console.log).toHaveBeenCalled(); + + 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 () { @@ -153,6 +184,40 @@ describe('service', function () { expect(eightyStoreFactory.get('exportSet')[0].like).toBe(1); }); + it('get all questions with tag', function () { + var questionsSet = [ + {id: 1}, + {id: 2} + ]; + 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} + ]; + 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 = [ 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, ''); 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