/* * SonarQube * Copyright (C) 2009-2017 SonarSource SA * mailto:info AT sonarsource DOT com * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. * * This program 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ package org.sonar.server.favorite.ws; import java.util.stream.IntStream; import javax.annotation.Nullable; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.sonar.api.server.ws.WebService; import org.sonar.api.server.ws.WebService.Param; import org.sonar.api.web.UserRole; import org.sonar.db.DbClient; import org.sonar.db.DbTester; import org.sonar.db.component.ComponentDto; import org.sonar.db.component.ComponentTesting; import org.sonar.db.organization.OrganizationDto; import org.sonar.server.exceptions.UnauthorizedException; import org.sonar.server.favorite.FavoriteFinder; import org.sonar.server.tester.UserSessionRule; import org.sonar.server.ws.TestRequest; import org.sonar.server.ws.WsActionTester; import org.sonarqube.ws.Common.Paging; import org.sonarqube.ws.Favorites.Favorite; import org.sonarqube.ws.Favorites.SearchResponse; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.tuple; import static org.sonar.api.resources.Qualifiers.FILE; import static org.sonar.api.resources.Qualifiers.PROJECT; import static org.sonar.core.util.Protobuf.setNullable; import static org.sonar.db.component.ComponentTesting.newFileDto; import static org.sonar.db.component.ComponentTesting.newPrivateProjectDto; import static org.sonar.test.JsonAssert.assertJson; import static org.sonarqube.ws.client.WsRequest.Method.POST; public class SearchActionTest { private static final int USER_ID = 123; @Rule public ExpectedException expectedException = ExpectedException.none(); @Rule public UserSessionRule userSession = UserSessionRule.standalone().logIn().setUserId(USER_ID); @Rule public DbTester db = DbTester.create(); private DbClient dbClient = db.getDbClient(); private FavoriteFinder favoriteFinder = new FavoriteFinder(dbClient, userSession); private WsActionTester ws = new WsActionTester(new SearchAction(favoriteFinder, dbClient, userSession)); @Test public void return_favorites() { ComponentDto project = newPrivateProjectDto(db.getDefaultOrganization(), "P1").setKey("K1").setName("N1"); addComponent(project); addComponent(newFileDto(project).setKey("K11").setName("N11")); addComponent(newPrivateProjectDto(db.getDefaultOrganization(), "P2").setKey("K2").setName("N2")); SearchResponse result = call(); assertThat(result.getPaging()) .extracting(Paging::getPageIndex, Paging::getPageSize, Paging::getTotal) .containsExactly(1, 100, 3); assertThat(result.getFavoritesList()) .extracting(Favorite::getKey, Favorite::getName, Favorite::getQualifier) .containsOnly( tuple("K1", "N1", PROJECT), tuple("K11", "N11", FILE), tuple("K2", "N2", PROJECT)); } @Test public void empty_list() { SearchResponse result = call(); assertThat(result.getFavoritesCount()).isEqualTo(0); assertThat(result.getFavoritesList()).isEmpty(); } @Test public void filter_authorized_components() { OrganizationDto organizationDto = db.organizations().insert(); addComponent(ComponentTesting.newPrivateProjectDto(organizationDto).setKey("K1")); ComponentDto unauthorizedProject = db.components().insertComponent(ComponentTesting.newPrivateProjectDto(organizationDto)); db.favorites().add(unauthorizedProject, USER_ID); SearchResponse result = call(); assertThat(result.getFavoritesCount()).isEqualTo(1); assertThat(result.getFavorites(0).getKey()).isEqualTo("K1"); } @Test public void paginate_results() { IntStream.rangeClosed(1, 9) .forEach(i -> addComponent(ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization()).setKey("K" + i).setName("N" + i))); ComponentDto unauthorizedProject = db.components().insertComponent(ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization())); db.favorites().add(unauthorizedProject, USER_ID); SearchResponse result = call(2, 3); assertThat(result.getFavoritesCount()).isEqualTo(3); assertThat(result.getFavoritesList()) .extracting(Favorite::getKey) .containsExactly("K4", "K5", "K6"); } @Test public void return_only_users_favorite() { OrganizationDto organizationDto = db.organizations().insert(); addComponent(ComponentTesting.newPrivateProjectDto(organizationDto).setKey("K1")); ComponentDto otherUserFavorite = ComponentTesting.newPrivateProjectDto(organizationDto).setKey("K42"); db.components().insertComponent(otherUserFavorite); db.favorites().add(otherUserFavorite, 42); db.commit(); SearchResponse result = call(); assertThat(result.getFavoritesList()).extracting(Favorite::getKey).containsExactly("K1"); } @Test public void favorites_ordered_by_name() { OrganizationDto organizationDto = db.organizations().insert(); addComponent(ComponentTesting.newPrivateProjectDto(organizationDto).setName("N2")); addComponent(ComponentTesting.newPrivateProjectDto(organizationDto).setName("N3")); addComponent(ComponentTesting.newPrivateProjectDto(organizationDto).setName("N1")); SearchResponse result = call(); assertThat(result.getFavoritesList()).extracting(Favorite::getName) .containsExactly("N1", "N2", "N3"); } @Test public void json_example() { OrganizationDto organization1 = db.organizations().insertForKey("my-org"); OrganizationDto organization2 = db.organizations().insertForKey("openjdk"); addComponent(ComponentTesting.newPrivateProjectDto(organization1).setKey("K1").setName("Samba")); addComponent(ComponentTesting.newPrivateProjectDto(organization1).setKey("K2").setName("Apache HBase")); addComponent(ComponentTesting.newPrivateProjectDto(organization2).setKey("K3").setName("JDK9")); String result = ws.newRequest().execute().getInput(); assertJson(result).isSimilarTo(ws.getDef().responseExampleAsString()); } @Test public void definition() { WebService.Action definition = ws.getDef(); assertThat(definition.key()).isEqualTo("search"); assertThat(definition.responseExampleAsString()).isNotEmpty(); } @Test public void fail_if_not_authenticated() { userSession.anonymous(); expectedException.expect(UnauthorizedException.class); call(); } private void addComponent(ComponentDto component) { db.components().insertComponent(component); db.favorites().add(component, USER_ID); db.commit(); userSession.addProjectPermission(UserRole.USER, component); } private SearchResponse call(@Nullable Integer page, @Nullable Integer pageSize) { TestRequest request = ws.newRequest() .setMethod(POST.name()); setNullable(page, p -> request.setParam(Param.PAGE, p.toString())); setNullable(pageSize, ps -> request.setParam(Param.PAGE_SIZE, ps.toString())); return request.executeProtobuf(SearchResponse.class); } private SearchResponse call() { return call(null, null); } }