Implement simple search queries for users, groups and repositories

This commit is contained in:
René Pfeuffer
2019-04-09 16:27:27 +02:00
parent fbd6f4f3c7
commit 4797967b0d
8 changed files with 144 additions and 31 deletions

View File

@@ -92,16 +92,13 @@ public final class SearchUtil
{ {
result = true; result = true;
if (Util.isNotEmpty(other)) for (String o : other)
{ {
for (String o : other) if ((o == null) ||!o.matches(query))
{ {
if ((o == null) ||!o.matches(query)) result = false;
{
result = false;
break; break;
}
} }
} }
} }
@@ -127,16 +124,13 @@ public final class SearchUtil
if (!value.matches(query)) if (!value.matches(query))
{ {
if (Util.isNotEmpty(other)) for (String o : other)
{ {
for (String o : other) if ((o != null) && o.matches(query))
{ {
if ((o != null) && o.matches(query)) result = true;
{
result = true;
break; break;
}
} }
} }
} }

View File

@@ -7,6 +7,8 @@ import com.webcohesion.enunciate.metadata.rs.StatusCodes;
import com.webcohesion.enunciate.metadata.rs.TypeHint; import com.webcohesion.enunciate.metadata.rs.TypeHint;
import sonia.scm.group.Group; import sonia.scm.group.Group;
import sonia.scm.group.GroupManager; import sonia.scm.group.GroupManager;
import sonia.scm.search.SearchRequest;
import sonia.scm.search.SearchUtil;
import sonia.scm.web.VndMediaType; import sonia.scm.web.VndMediaType;
import javax.inject.Inject; import javax.inject.Inject;
@@ -19,6 +21,9 @@ import javax.ws.rs.Path;
import javax.ws.rs.Produces; import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam; import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import java.util.function.Predicate;
import static com.google.common.base.Strings.isNullOrEmpty;
public class GroupCollectionResource { public class GroupCollectionResource {
@@ -63,8 +68,10 @@ public class GroupCollectionResource {
@DefaultValue("" + DEFAULT_PAGE_SIZE) @QueryParam("pageSize") int pageSize, @DefaultValue("" + DEFAULT_PAGE_SIZE) @QueryParam("pageSize") int pageSize,
@QueryParam("sortBy") String sortBy, @QueryParam("sortBy") String sortBy,
@DefaultValue("false") @DefaultValue("false")
@QueryParam("desc") boolean desc) { @QueryParam("desc") boolean desc,
return adapter.getAll(page, pageSize, sortBy, desc, @DefaultValue("") @QueryParam("q") String search
) {
return adapter.getAll(page, pageSize, createSearchPredicate(search), sortBy, desc,
pageResult -> groupCollectionToDtoMapper.map(page, pageSize, pageResult)); pageResult -> groupCollectionToDtoMapper.map(page, pageSize, pageResult));
} }
@@ -90,4 +97,12 @@ public class GroupCollectionResource {
() -> dtoToGroupMapper.map(group), () -> dtoToGroupMapper.map(group),
g -> resourceLinks.group().self(g.getName())); g -> resourceLinks.group().self(g.getName()));
} }
private Predicate<Group> createSearchPredicate(String search) {
if (isNullOrEmpty(search)) {
return group -> true;
}
SearchRequest searchRequest = new SearchRequest(search, true);
return group -> SearchUtil.matchesOne(searchRequest, group.getName(), group.getDescription());
}
} }

View File

@@ -9,6 +9,8 @@ import org.apache.shiro.SecurityUtils;
import sonia.scm.repository.Repository; import sonia.scm.repository.Repository;
import sonia.scm.repository.RepositoryManager; import sonia.scm.repository.RepositoryManager;
import sonia.scm.repository.RepositoryPermission; import sonia.scm.repository.RepositoryPermission;
import sonia.scm.search.SearchRequest;
import sonia.scm.search.SearchUtil;
import sonia.scm.user.User; import sonia.scm.user.User;
import sonia.scm.web.VndMediaType; import sonia.scm.web.VndMediaType;
@@ -23,6 +25,9 @@ import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam; import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import java.util.function.Predicate;
import static com.google.common.base.Strings.isNullOrEmpty;
import static java.util.Collections.singletonList; import static java.util.Collections.singletonList;
public class RepositoryCollectionResource { public class RepositoryCollectionResource {
@@ -65,8 +70,10 @@ public class RepositoryCollectionResource {
public Response getAll(@DefaultValue("0") @QueryParam("page") int page, public Response getAll(@DefaultValue("0") @QueryParam("page") int page,
@DefaultValue("" + DEFAULT_PAGE_SIZE) @QueryParam("pageSize") int pageSize, @DefaultValue("" + DEFAULT_PAGE_SIZE) @QueryParam("pageSize") int pageSize,
@QueryParam("sortBy") String sortBy, @QueryParam("sortBy") String sortBy,
@DefaultValue("false") @QueryParam("desc") boolean desc) { @DefaultValue("false") @QueryParam("desc") boolean desc,
return adapter.getAll(page, pageSize, sortBy, desc, @DefaultValue("") @QueryParam("q") String search
) {
return adapter.getAll(page, pageSize, createSearchPredicate(search), sortBy, desc,
pageResult -> repositoryCollectionToDtoMapper.map(page, pageSize, pageResult)); pageResult -> repositoryCollectionToDtoMapper.map(page, pageSize, pageResult));
} }
@@ -106,4 +113,12 @@ public class RepositoryCollectionResource {
private String currentUser() { private String currentUser() {
return SecurityUtils.getSubject().getPrincipals().oneByType(User.class).getName(); return SecurityUtils.getSubject().getPrincipals().oneByType(User.class).getName();
} }
private Predicate<Repository> createSearchPredicate(String search) {
if (isNullOrEmpty(search)) {
return user -> true;
}
SearchRequest searchRequest = new SearchRequest(search, true);
return repository -> SearchUtil.matchesOne(searchRequest, repository.getName(), repository.getNamespace(), repository.getDescription());
}
} }

View File

@@ -6,6 +6,8 @@ import com.webcohesion.enunciate.metadata.rs.ResponseHeaders;
import com.webcohesion.enunciate.metadata.rs.StatusCodes; import com.webcohesion.enunciate.metadata.rs.StatusCodes;
import com.webcohesion.enunciate.metadata.rs.TypeHint; import com.webcohesion.enunciate.metadata.rs.TypeHint;
import org.apache.shiro.authc.credential.PasswordService; import org.apache.shiro.authc.credential.PasswordService;
import sonia.scm.search.SearchRequest;
import sonia.scm.search.SearchUtil;
import sonia.scm.user.User; import sonia.scm.user.User;
import sonia.scm.user.UserManager; import sonia.scm.user.UserManager;
import sonia.scm.web.VndMediaType; import sonia.scm.web.VndMediaType;
@@ -20,6 +22,9 @@ import javax.ws.rs.Path;
import javax.ws.rs.Produces; import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam; import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import java.util.function.Predicate;
import static com.google.common.base.Strings.isNullOrEmpty;
public class UserCollectionResource { public class UserCollectionResource {
@@ -65,8 +70,10 @@ public class UserCollectionResource {
public Response getAll(@DefaultValue("0") @QueryParam("page") int page, public Response getAll(@DefaultValue("0") @QueryParam("page") int page,
@DefaultValue("" + DEFAULT_PAGE_SIZE) @QueryParam("pageSize") int pageSize, @DefaultValue("" + DEFAULT_PAGE_SIZE) @QueryParam("pageSize") int pageSize,
@QueryParam("sortBy") String sortBy, @QueryParam("sortBy") String sortBy,
@DefaultValue("false") @QueryParam("desc") boolean desc) { @DefaultValue("false") @QueryParam("desc") boolean desc,
return adapter.getAll(page, pageSize, sortBy, desc, @DefaultValue("") @QueryParam("q") String search
) {
return adapter.getAll(page, pageSize, createSearchPredicate(search), sortBy, desc,
pageResult -> userCollectionToDtoMapper.map(page, pageSize, pageResult)); pageResult -> userCollectionToDtoMapper.map(page, pageSize, pageResult));
} }
@@ -93,4 +100,12 @@ public class UserCollectionResource {
public Response create(@Valid UserDto user) { public Response create(@Valid UserDto user) {
return adapter.create(user, () -> dtoToUserMapper.map(user, passwordService.encryptPassword(user.getPassword())), u -> resourceLinks.user().self(u.getName())); return adapter.create(user, () -> dtoToUserMapper.map(user, passwordService.encryptPassword(user.getPassword())), u -> resourceLinks.user().self(u.getName()));
} }
private Predicate<User> createSearchPredicate(String search) {
if (isNullOrEmpty(search)) {
return user -> true;
}
SearchRequest searchRequest = new SearchRequest(search, true);
return user -> SearchUtil.matchesOne(searchRequest, user.getName(), user.getDisplayName(), user.getMail());
}
} }

View File

@@ -12,6 +12,7 @@ import sonia.scm.Manager;
import sonia.scm.api.rest.resources.Simple; import sonia.scm.api.rest.resources.Simple;
import java.util.Comparator; import java.util.Comparator;
import java.util.function.Predicate;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.eq;
@@ -24,18 +25,20 @@ public class CollectionResourceManagerAdapterTest {
private Manager<Simple> manager; private Manager<Simple> manager;
@Captor @Captor
private ArgumentCaptor<Comparator<Simple>> comparatorCaptor; private ArgumentCaptor<Comparator<Simple>> comparatorCaptor;
@Captor
private ArgumentCaptor<Predicate<Simple>> filterCaptor;
private CollectionResourceManagerAdapter<Simple, HalRepresentation> abstractManagerResource; private CollectionResourceManagerAdapter<Simple, HalRepresentation> abstractManagerResource;
@Before @Before
public void captureComparator() { public void captureComparator() {
when(manager.getPage(comparatorCaptor.capture(), eq(0), eq(1))).thenReturn(null); when(manager.getPage(filterCaptor.capture(), comparatorCaptor.capture(), eq(0), eq(1))).thenReturn(null);
abstractManagerResource = new SimpleManagerResource(); abstractManagerResource = new SimpleManagerResource();
} }
@Test @Test
public void shouldAcceptDefaultSortByParameter() { public void shouldAcceptDefaultSortByParameter() {
abstractManagerResource.getAll(0, 1, null, true, r -> null); abstractManagerResource.getAll(0, 1, x -> true, null, true, r -> null);
Comparator<Simple> comparator = comparatorCaptor.getValue(); Comparator<Simple> comparator = comparatorCaptor.getValue();
assertTrue(comparator.compare(new Simple("1", null), new Simple("2", null)) > 0); assertTrue(comparator.compare(new Simple("1", null), new Simple("2", null)) > 0);
@@ -43,7 +46,7 @@ public class CollectionResourceManagerAdapterTest {
@Test @Test
public void shouldAcceptValidSortByParameter() { public void shouldAcceptValidSortByParameter() {
abstractManagerResource.getAll(0, 1, "data", true, r -> null); abstractManagerResource.getAll(0, 1, x -> true, "data", true, r -> null);
Comparator<Simple> comparator = comparatorCaptor.getValue(); Comparator<Simple> comparator = comparatorCaptor.getValue();
assertTrue(comparator.compare(new Simple("", "1"), new Simple("", "2")) > 0); assertTrue(comparator.compare(new Simple("", "1"), new Simple("", "2")) > 0);
@@ -51,7 +54,7 @@ public class CollectionResourceManagerAdapterTest {
@Test(expected = IllegalArgumentException.class) @Test(expected = IllegalArgumentException.class)
public void shouldFailForIllegalSortByParameter() { public void shouldFailForIllegalSortByParameter() {
abstractManagerResource.getAll(0, 1, "x", true, r -> null); abstractManagerResource.getAll(0, 1, x -> true, "x", true, r -> null);
} }
private class SimpleManagerResource extends CollectionResourceManagerAdapter<Simple, HalRepresentation> { private class SimpleManagerResource extends CollectionResourceManagerAdapter<Simple, HalRepresentation> {

View File

@@ -11,6 +11,7 @@ import org.junit.Before;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.mockito.ArgumentCaptor; import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.InjectMocks; import org.mockito.InjectMocks;
import org.mockito.Mock; import org.mockito.Mock;
import sonia.scm.PageResult; import sonia.scm.PageResult;
@@ -30,9 +31,11 @@ import java.net.URISyntaxException;
import java.net.URL; import java.net.URL;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.function.Predicate;
import static java.util.Collections.singletonList; import static java.util.Collections.singletonList;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.any;
@@ -67,8 +70,10 @@ public class GroupRootResourceTest {
@InjectMocks @InjectMocks
private PermissionCollectionToDtoMapper permissionCollectionToDtoMapper; private PermissionCollectionToDtoMapper permissionCollectionToDtoMapper;
@Captor
private ArgumentCaptor<Group> groupCaptor = ArgumentCaptor.forClass(Group.class); private ArgumentCaptor<Group> groupCaptor;
@Captor
private ArgumentCaptor<Predicate<Group>> filterCaptor;
@Before @Before
public void prepareEnvironment() { public void prepareEnvironment() {
@@ -77,7 +82,7 @@ public class GroupRootResourceTest {
doNothing().when(groupManager).modify(groupCaptor.capture()); doNothing().when(groupManager).modify(groupCaptor.capture());
Group group = createDummyGroup(); Group group = createDummyGroup();
when(groupManager.getPage(any(), eq(0), eq(10))).thenReturn(new PageResult<>(singletonList(group), 1)); when(groupManager.getPage(filterCaptor.capture(), any(), eq(0), eq(10))).thenReturn(new PageResult<>(singletonList(group), 1));
when(groupManager.get("admin")).thenReturn(group); when(groupManager.get("admin")).thenReturn(group);
GroupCollectionToDtoMapper groupCollectionToDtoMapper = new GroupCollectionToDtoMapper(groupToDtoMapper, resourceLinks); GroupCollectionToDtoMapper groupCollectionToDtoMapper = new GroupCollectionToDtoMapper(groupToDtoMapper, resourceLinks);
@@ -317,6 +322,23 @@ public class GroupRootResourceTest {
assertTrue(response.getContentAsString().contains("\"self\":{\"href\":\"/v2/groups/admin\"}")); assertTrue(response.getContentAsString().contains("\"self\":{\"href\":\"/v2/groups/admin\"}"));
} }
@Test
public void shouldCreateFilterForSearch() throws URISyntaxException {
MockHttpRequest request = MockHttpRequest.get("/" + GroupRootResource.GROUPS_PATH_V2 + "?q=One");
MockHttpResponse response = new MockHttpResponse();
dispatcher.invoke(request, response);
assertEquals(HttpServletResponse.SC_OK, response.getStatus());
Group group = new Group("xml", "someone");
assertTrue(filterCaptor.getValue().test(group));
group.setName("nothing");
group.setDescription("Someone");
assertTrue(filterCaptor.getValue().test(group));
group.setDescription("Nobody");
assertFalse(filterCaptor.getValue().test(group));
}
@Test @Test
public void shouldGetPermissionLink() throws URISyntaxException, UnsupportedEncodingException { public void shouldGetPermissionLink() throws URISyntaxException, UnsupportedEncodingException {
MockHttpRequest request = MockHttpRequest.get("/" + GroupRootResource.GROUPS_PATH_V2 + "admin"); MockHttpRequest request = MockHttpRequest.get("/" + GroupRootResource.GROUPS_PATH_V2 + "admin");

View File

@@ -13,6 +13,7 @@ import org.junit.Before;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.mockito.ArgumentCaptor; import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.InjectMocks; import org.mockito.InjectMocks;
import org.mockito.Mock; import org.mockito.Mock;
import sonia.scm.PageResult; import sonia.scm.PageResult;
@@ -31,6 +32,7 @@ import java.io.UnsupportedEncodingException;
import java.net.URI; import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.net.URL; import java.net.URL;
import java.util.function.Predicate;
import static java.util.Collections.singletonList; import static java.util.Collections.singletonList;
import static java.util.stream.Stream.of; import static java.util.stream.Stream.of;
@@ -42,6 +44,7 @@ import static javax.servlet.http.HttpServletResponse.SC_OK;
import static javax.servlet.http.HttpServletResponse.SC_PRECONDITION_FAILED; import static javax.servlet.http.HttpServletResponse.SC_PRECONDITION_FAILED;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyObject; import static org.mockito.ArgumentMatchers.anyObject;
@@ -78,6 +81,8 @@ public class RepositoryRootResourceTest extends RepositoryTestBase {
@Mock @Mock
private ScmPathInfo uriInfo; private ScmPathInfo uriInfo;
@Captor
private ArgumentCaptor<Predicate<Repository>> filterCaptor;
private final URI baseUri = URI.create("/"); private final URI baseUri = URI.create("/");
private final ResourceLinks resourceLinks = ResourceLinksMock.createMock(baseUri); private final ResourceLinks resourceLinks = ResourceLinksMock.createMock(baseUri);
@@ -150,7 +155,7 @@ public class RepositoryRootResourceTest extends RepositoryTestBase {
@Test @Test
public void shouldGetAll() throws URISyntaxException, UnsupportedEncodingException { public void shouldGetAll() throws URISyntaxException, UnsupportedEncodingException {
PageResult<Repository> singletonPageResult = createSingletonPageResult(mockRepository("space", "repo")); PageResult<Repository> singletonPageResult = createSingletonPageResult(mockRepository("space", "repo"));
when(repositoryManager.getPage(any(), eq(0), eq(10))).thenReturn(singletonPageResult); when(repositoryManager.getPage(any(), any(), eq(0), eq(10))).thenReturn(singletonPageResult);
MockHttpRequest request = MockHttpRequest.get("/" + RepositoryRootResource.REPOSITORIES_PATH_V2); MockHttpRequest request = MockHttpRequest.get("/" + RepositoryRootResource.REPOSITORIES_PATH_V2);
MockHttpResponse response = new MockHttpResponse(); MockHttpResponse response = new MockHttpResponse();
@@ -161,6 +166,22 @@ public class RepositoryRootResourceTest extends RepositoryTestBase {
assertTrue(response.getContentAsString().contains("\"name\":\"repo\"")); assertTrue(response.getContentAsString().contains("\"name\":\"repo\""));
} }
@Test
public void shouldCreateFilterForSearch() throws URISyntaxException {
PageResult<Repository> singletonPageResult = createSingletonPageResult(mockRepository("space", "repo"));
when(repositoryManager.getPage(filterCaptor.capture(), any(), eq(0), eq(10))).thenReturn(singletonPageResult);
MockHttpRequest request = MockHttpRequest.get("/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + "?q=Rep");
MockHttpResponse response = new MockHttpResponse();
dispatcher.invoke(request, response);
assertEquals(SC_OK, response.getStatus());
assertTrue(filterCaptor.getValue().test(new Repository("x", "git", "all_repos", "x")));
assertTrue(filterCaptor.getValue().test(new Repository("x", "git", "x", "repository")));
assertFalse(filterCaptor.getValue().test(new Repository("rep", "rep", "x", "x")));
}
@Test @Test
public void shouldHandleUpdateForNotExistingRepository() throws URISyntaxException, IOException { public void shouldHandleUpdateForNotExistingRepository() throws URISyntaxException, IOException {
URL url = Resources.getResource("sonia/scm/api/v2/repository-test-update.json"); URL url = Resources.getResource("sonia/scm/api/v2/repository-test-update.json");

View File

@@ -12,6 +12,7 @@ import org.junit.Before;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.mockito.ArgumentCaptor; import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.InjectMocks; import org.mockito.InjectMocks;
import org.mockito.Mock; import org.mockito.Mock;
import sonia.scm.ContextEntry; import sonia.scm.ContextEntry;
@@ -30,6 +31,7 @@ import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.net.URL; import java.net.URL;
import java.util.Collection; import java.util.Collection;
import java.util.function.Predicate;
import static java.util.Collections.singletonList; import static java.util.Collections.singletonList;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
@@ -72,7 +74,11 @@ public class UserRootResourceTest {
@InjectMocks @InjectMocks
private PermissionCollectionToDtoMapper permissionCollectionToDtoMapper; private PermissionCollectionToDtoMapper permissionCollectionToDtoMapper;
private ArgumentCaptor<User> userCaptor = ArgumentCaptor.forClass(User.class); @Captor
private ArgumentCaptor<User> userCaptor;
@Captor
private ArgumentCaptor<Predicate<User>> filterCaptor;
private User originalUser; private User originalUser;
@Before @Before
@@ -333,7 +339,7 @@ public class UserRootResourceTest {
@Test @Test
public void shouldCreatePageForOnePageOnly() throws URISyntaxException, UnsupportedEncodingException { public void shouldCreatePageForOnePageOnly() throws URISyntaxException, UnsupportedEncodingException {
PageResult<User> singletonPageResult = createSingletonPageResult(1); PageResult<User> singletonPageResult = createSingletonPageResult(1);
when(userManager.getPage(any(), eq(0), eq(10))).thenReturn(singletonPageResult); when(userManager.getPage(any(), any(), eq(0), eq(10))).thenReturn(singletonPageResult);
MockHttpRequest request = MockHttpRequest.get("/" + UserRootResource.USERS_PATH_V2); MockHttpRequest request = MockHttpRequest.get("/" + UserRootResource.USERS_PATH_V2);
MockHttpResponse response = new MockHttpResponse(); MockHttpResponse response = new MockHttpResponse();
@@ -349,7 +355,7 @@ public class UserRootResourceTest {
@Test @Test
public void shouldCreatePageForMultiplePages() throws URISyntaxException, UnsupportedEncodingException { public void shouldCreatePageForMultiplePages() throws URISyntaxException, UnsupportedEncodingException {
PageResult<User> singletonPageResult = createSingletonPageResult(3); PageResult<User> singletonPageResult = createSingletonPageResult(3);
when(userManager.getPage(any(), eq(1), eq(1))).thenReturn(singletonPageResult); when(userManager.getPage(any(), any(), eq(1), eq(1))).thenReturn(singletonPageResult);
MockHttpRequest request = MockHttpRequest.get("/" + UserRootResource.USERS_PATH_V2 + "?page=1&pageSize=1"); MockHttpRequest request = MockHttpRequest.get("/" + UserRootResource.USERS_PATH_V2 + "?page=1&pageSize=1");
MockHttpResponse response = new MockHttpResponse(); MockHttpResponse response = new MockHttpResponse();
@@ -364,6 +370,28 @@ public class UserRootResourceTest {
assertTrue(response.getContentAsString().contains("\"last\":{\"href\":\"/v2/users/?page=2")); assertTrue(response.getContentAsString().contains("\"last\":{\"href\":\"/v2/users/?page=2"));
} }
@Test
public void shouldCreateFilterForSearch() throws URISyntaxException {
PageResult<User> singletonPageResult = createSingletonPageResult(1);
when(userManager.getPage(filterCaptor.capture(), any(), eq(0), eq(10))).thenReturn(singletonPageResult);
MockHttpRequest request = MockHttpRequest.get("/" + UserRootResource.USERS_PATH_V2 + "?q=One");
MockHttpResponse response = new MockHttpResponse();
dispatcher.invoke(request, response);
assertEquals(HttpServletResponse.SC_OK, response.getStatus());
User user = new User("Someone I know");
assertTrue(filterCaptor.getValue().test(user));
user.setName("nobody");
user.setDisplayName("Someone I know");
assertTrue(filterCaptor.getValue().test(user));
user.setDisplayName("nobody");
user.setMail("me@someone.com");
assertTrue(filterCaptor.getValue().test(user));
user.setMail("me@nowhere.com");
assertFalse(filterCaptor.getValue().test(user));
}
@Test @Test
public void shouldGetPermissionLink() throws URISyntaxException, UnsupportedEncodingException { public void shouldGetPermissionLink() throws URISyntaxException, UnsupportedEncodingException {
MockHttpRequest request = MockHttpRequest.get("/" + UserRootResource.USERS_PATH_V2 + "Neo"); MockHttpRequest request = MockHttpRequest.get("/" + UserRootResource.USERS_PATH_V2 + "Neo");