/**
* This file is part of lavagna.
*
* lavagna is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* lavagna is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with lavagna. If not, see <http://www.gnu.org/licenses/>.
*/
package io.lavagna.service;
import io.lavagna.common.LavagnaEnvironment;
import io.lavagna.config.PersistenceAndServiceConfig;
import io.lavagna.model.*;
import io.lavagna.model.BoardColumn.BoardColumnLocation;
import io.lavagna.service.PermissionService.ProjectRoleAndPermissionFullHolder;
import io.lavagna.service.SearchFilter.FilterType;
import io.lavagna.service.SearchFilter.SearchFilterValue;
import io.lavagna.service.SearchFilter.ValueType;
import io.lavagna.service.config.TestServiceConfig;
import org.apache.commons.lang3.time.DateUtils;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
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 java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import static java.util.Collections.singletonList;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { TestServiceConfig.class, PersistenceAndServiceConfig.class })
@Transactional
public class SearchServiceTest {
@Autowired
private LavagnaEnvironment env;
@Autowired
private SearchService searchService;
@Autowired
private UserRepository userRepository;
@Autowired
private PermissionService permissionService;
@Autowired
private ProjectService projectService;
@Autowired
private BoardRepository boardRepository;
@Autowired
private BoardColumnRepository boardColumnRepository;
@Autowired
private CardService cardService;
@Autowired
private MySqlFullTextSupportService mySqlFullTextSupportService;
private User user;
private User userWithNoAccess;
private UserWithPermission userWithPermissions;
private UserWithPermission userWithNoAccessPermission;
private final SearchFilter createdByMe = new SearchFilter(FilterType.CREATED_BY, null, new SearchFilterValue(
ValueType.CURRENT_USER, "me"));
private Project project;
private Board board;
private BoardColumn column;
private BoardColumn closedColumn;
@Before
public void prepare() {
userRepository.createUser("test", "test", null,null, null, true);
userRepository.createUser("test", "test-no-access", null,null, null, true);
user = userRepository.findUserByName("test", "test");
userWithNoAccess = userRepository.findUserByName("test", "test-no-access");
Role r = new Role("TEST");
permissionService.createRole(r);
permissionService.updatePermissionsToRole(r, EnumSet.of(Permission.READ));
permissionService.assignRolesToUsers(Collections.singletonMap(r, Collections.singleton(user.getId())));
userWithPermissions = new UserWithPermission(user, permissionService.findBasePermissionByUserId(user.getId()),
Collections.<String, Set<Permission>>emptyMap(), Collections.<Integer, Set<Permission>>emptyMap());
userWithNoAccessPermission = new UserWithPermission(userWithNoAccess,
permissionService.findBasePermissionByUserId(userWithNoAccess.getId()),
Collections.<String, Set<Permission>>emptyMap(), Collections.<Integer, Set<Permission>>emptyMap());
project = projectService.create("test search", "TEST-SRC", "desc");
board = boardRepository.createNewBoard("TEST-SEARCH", "TEST-SRC", "desc", project.getId());
List<BoardColumnDefinition> columnDefinitions = projectService
.findColumnDefinitionsByProjectId(project.getId());
for (BoardColumnDefinition bcd : columnDefinitions) {
if (bcd.getValue() == ColumnDefinition.OPEN) {
column = boardColumnRepository.addColumnToBoard("test", bcd.getId(), BoardColumnLocation.BOARD,
board.getId());
} else if (bcd.getValue() == ColumnDefinition.CLOSED) {
closedColumn = boardColumnRepository.addColumnToBoard("test", bcd.getId(), BoardColumnLocation.BOARD,
board.getId());
}
}
}
@Test
public void testNoReadPermission() {
SearchResults find = searchService.find(singletonList(createdByMe), null, null, userWithNoAccessPermission, 0);
Assert.assertEquals(0, find.getCount());
SearchResults find2 = searchService.find(singletonList(createdByMe), project.getId(), null,
userWithNoAccessPermission, 0);
Assert.assertEquals(0, find2.getCount());
}
@Test
public void testEmpty() {
SearchResults find = searchService.find(singletonList(createdByMe), null, null, userWithPermissions, 0);
Assert.assertEquals(0, find.getCount());
}
@Test
public void testFindCreatedByMe() {
cardService.createCard("test", column.getId(), new Date(), user);
SearchResults find = searchService.find(singletonList(createdByMe), null, null, userWithPermissions, 0);
Assert.assertEquals(1, find.getCount());
}
@Test
public void testFindByStatus() {
SearchFilter status = new SearchFilter(FilterType.STATUS, null,
new SearchFilterValue(ValueType.STRING, "OPEN"));
cardService.createCard("test", column.getId(), new Date(), user);
SearchResults find = searchService.find(singletonList(status), null, null, userWithPermissions, 0);
Assert.assertEquals(1, find.getCount());
}
@Test
public void testCreatedToday() {
SearchFilter today = new SearchFilter(FilterType.CREATED, null, new SearchFilterValue(
ValueType.DATE_IDENTIFIER, "today"));
SearchFilter thisWeek = new SearchFilter(FilterType.CREATED, null, new SearchFilterValue(
ValueType.DATE_IDENTIFIER, "this week"));
SearchFilter thisMonth = new SearchFilter(FilterType.CREATED, null, new SearchFilterValue(
ValueType.DATE_IDENTIFIER, "this month"));
SearchFilter lastWeek = new SearchFilter(FilterType.CREATED, null, new SearchFilterValue(
ValueType.DATE_IDENTIFIER, "last week"));
SearchFilter lastMonth = new SearchFilter(FilterType.CREATED, null, new SearchFilterValue(
ValueType.DATE_IDENTIFIER, "last month"));
Date now = new Date();
cardService.createCard("test", column.getId(), now, user);
SearchResults find = searchService.find(singletonList(today), null, null, userWithPermissions, 0);
Assert.assertEquals(1, find.getCount());
SimpleDateFormat formatter = new SimpleDateFormat("dd.MM.yyyy");
SearchFilter todayString = new SearchFilter(FilterType.CREATED, null, new SearchFilterValue(ValueType.STRING,
formatter.format(now)));
Assert.assertEquals(1,
searchService.find(singletonList(todayString), null, null, userWithPermissions, 0).getCount());
Assert.assertEquals(1,
searchService.find(singletonList(todayString), null, null, userWithPermissions, 0).getCount());
Assert.assertEquals(1,
searchService.find(singletonList(thisWeek), null, null, userWithPermissions, 0).getCount());
Assert.assertEquals(1,
searchService.find(singletonList(thisMonth), null, null, userWithPermissions, 0).getCount());
Assert.assertEquals(1,
searchService.find(singletonList(lastWeek), null, null, userWithPermissions, 0).getCount());
Assert.assertEquals(1,
searchService.find(singletonList(lastMonth), null, null, userWithPermissions, 0).getCount());
}
@Test
public void testSearchBoard() {
Date now = new Date();
cardService.createCard("test", column.getId(), now, user);
Board board2 = boardRepository.createNewBoard("TEST-SEARCH2", "TEST-SR2", "desc", project.getId());
SearchFilter thisWeek = new SearchFilter(FilterType.CREATED, null, new SearchFilterValue(
ValueType.DATE_IDENTIFIER, "this week"));
Assert.assertEquals(0,
searchService.find(singletonList(thisWeek), null, board.getId(), userWithPermissions, 0).getCount());
Assert.assertEquals(0,
searchService.find(singletonList(thisWeek), -5, board.getId(), userWithPermissions, 0).getCount());
Assert.assertEquals(1,
searchService.find(singletonList(thisWeek), project.getId(), board.getId(), userWithPermissions, 0)
.getCount());
Assert.assertEquals(0,
searchService.find(singletonList(thisWeek), project.getId(), board2.getId(), userWithPermissions, 0)
.getCount());
}
@Test
public void testUnassigned() {
SearchFilter unassigned = new SearchFilter(FilterType.ASSIGNED, null, new SearchFilterValue(
ValueType.UNASSIGNED, "unassigned"));
cardService.createCard("test", column.getId(), new Date(), user);
SearchResults find = searchService.find(singletonList(unassigned), null, null, userWithPermissions, 0);
Assert.assertEquals(1, find.getCount());
}
@Test
public void testCreatedThisYear() throws ParseException {
int year = Calendar.getInstance().get(Calendar.YEAR);
SearchFilter yearFilter = new SearchFilter(FilterType.CREATED, null, new SearchFilterValue(ValueType.STRING,
"01.01." + year + "..31.12." + year));
cardService.createCard("test", column.getId(), new Date(), user);
cardService.createCard("test", column.getId(), DateUtils.parseDate("01.01." + year, "dd.MM.yyyy"), user);
cardService.createCard("test", column.getId(), DateUtils.parseDate("31.12." + year, "dd.MM.yyyy"), user);
SearchResults find = searchService.find(singletonList(yearFilter), null, null, userWithPermissions, 0);
Assert.assertEquals(3, find.getCount());
}
@Test
public void testFTS() {
SearchFilter fts = new SearchFilter(FilterType.FREETEXT, null, new SearchFilterValue(ValueType.STRING, "test"));
syncMYSQLFTS();
SearchResults find = searchService.find(singletonList(fts), null, null, userWithPermissions, 0);
Assert.assertEquals(0, find.getCount());
cardService.createCard("test", column.getId(), new Date(), user);
syncMYSQLFTS();
SearchResults find2 = searchService.find(singletonList(fts), null, null, userWithPermissions, 0);
Assert.assertEquals(1, find2.getCount());
}
private void syncMYSQLFTS() {
if ("MYSQL".equals(env.getProperty("datasource.dialect"))) {
mySqlFullTextSupportService.syncNewCards();
mySqlFullTextSupportService.syncNewCardData();
mySqlFullTextSupportService.syncUpdatedCards();
mySqlFullTextSupportService.syncUpdatedCardData();
}
}
@Test
public void testInProject() {
cardService.createCard("test", column.getId(), new Date(), user);
SearchResults find = searchService
.find(Arrays.asList(createdByMe), project.getId(), null, userWithPermissions, 0);
Assert.assertEquals(1, find.getCount());
}
@Test
public void testWithoutPagination() {
for (int i = 0; i < 52; i++) {
cardService.createCard("test", column.getId(), new Date(), user);
}
SearchResults find = searchService.find(Arrays.asList(createdByMe), project.getId(), null, userWithPermissions);
Assert.assertEquals(52, find.getFound().size());
Assert.assertEquals(52, find.getCount());
Assert.assertEquals(0, find.getCurrentPage());
Assert.assertEquals(1, find.getTotalPages());
}
@Test
public void testPagination() {
for (int i = 0; i < 52; i++) {
cardService.createCard("test", column.getId(), new Date(), user);
}
SearchResults find = searchService
.find(Arrays.asList(createdByMe), project.getId(), null, userWithPermissions, 0);
Assert.assertEquals(51, find.getFound().size());
Assert.assertEquals(52, find.getCount());
Assert.assertEquals(0, find.getCurrentPage());
Assert.assertEquals(2, find.getTotalPages());
SearchResults find2 = searchService
.find(Arrays.asList(createdByMe), project.getId(), null, userWithPermissions, 1);
Assert.assertEquals(2, find2.getFound().size());
Assert.assertEquals(52, find2.getCount());
Assert.assertEquals(1, find2.getCurrentPage());
Assert.assertEquals(2, find2.getTotalPages());
}
@Test
public void testUserWithReadPermissionInProject() {
Role r = new Role("READ");
permissionService.createRoleInProjectId(r, project.getId());
permissionService.assignRoleToUsersInProjectId(r, Collections.singleton(userWithNoAccess.getId()),
project.getId());
permissionService.updatePermissionsToRoleInProjectId(r, EnumSet.of(Permission.READ), project.getId());
ProjectRoleAndPermissionFullHolder permissionsHolder = permissionService
.findPermissionsGroupedByProjectForUserId(userWithNoAccess.getId());
UserWithPermission uwp = new UserWithPermission(userWithNoAccess, EnumSet.noneOf(Permission.class),
permissionsHolder.getPermissionsByProject(), permissionsHolder.getPermissionsByProjectId());
cardService.createCard("test", column.getId(), new Date(), uwp);
SearchResults find = searchService.find(Arrays.asList(createdByMe), null, null, uwp, 0);
Assert.assertEquals(1, find.getCount());
}
@Test
public void testFindByStatusAndCreatedByMe() {
SearchFilter status = new SearchFilter(FilterType.STATUS, null,
new SearchFilterValue(ValueType.STRING, "OPEN"));
cardService.createCard("test", column.getId(), new Date(), user);
SearchResults find = searchService.find(Arrays.asList(createdByMe, status), null, null, userWithPermissions, 0);
Assert.assertEquals(1, find.getCount());
}
@Test
public void testFindTaksByColumnDefinition() {
cardService.createCard("test", column.getId(), new Date(), user);
Map<ColumnDefinition, Integer> tasks = searchService.findTaksByColumnDefinition(project.getId(), null, false,
userWithPermissions);
Assert.assertEquals(1, tasks.get(ColumnDefinition.OPEN).intValue());
Assert.assertEquals(0, tasks.get(ColumnDefinition.CLOSED).intValue());
Assert.assertEquals(0, tasks.get(ColumnDefinition.BACKLOG).intValue());
Assert.assertEquals(0, tasks.get(ColumnDefinition.DEFERRED).intValue());
}
@Test
public void testFindTaksByColumnDefinitionOnManyCards() {
int cardsToCreate = 100;
for (int i = 0; i < cardsToCreate; i++) {
cardService.createCard("test" + i, closedColumn.getId(), new Date(), user);
}
Map<ColumnDefinition, Integer> tasks = searchService.findTaksByColumnDefinition(project.getId(), null, false,
userWithPermissions);
Assert.assertEquals(0, tasks.get(ColumnDefinition.OPEN).intValue());
Assert.assertEquals(cardsToCreate, tasks.get(ColumnDefinition.CLOSED).intValue());
Assert.assertEquals(0, tasks.get(ColumnDefinition.BACKLOG).intValue());
Assert.assertEquals(0, tasks.get(ColumnDefinition.DEFERRED).intValue());
}
@Test
public void testFindTaksByColumnDefinitionAfterMove() {
Card card = cardService.createCard("test", column.getId(), new Date(), user);
cardService.moveCardToColumn(card.getId(), column.getId(), closedColumn.getId(), user.getId(), new Date());
Map<ColumnDefinition, Integer> tasks = searchService.findTaksByColumnDefinition(project.getId(), null, false,
userWithPermissions);
Assert.assertEquals(0, tasks.get(ColumnDefinition.OPEN).intValue());
Assert.assertEquals(1, tasks.get(ColumnDefinition.CLOSED).intValue());
Assert.assertEquals(0, tasks.get(ColumnDefinition.BACKLOG).intValue());
Assert.assertEquals(0, tasks.get(ColumnDefinition.DEFERRED).intValue());
}
}