You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

TagsActionTest.java 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308
  1. /*
  2. * SonarQube
  3. * Copyright (C) 2009-2020 SonarSource SA
  4. * mailto:info AT sonarsource DOT com
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 3 of the License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public License
  17. * along with this program; if not, write to the Free Software Foundation,
  18. * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  19. */
  20. package org.sonar.server.issue.ws;
  21. import org.junit.Rule;
  22. import org.junit.Test;
  23. import org.junit.rules.ExpectedException;
  24. import org.sonar.api.server.ws.WebService.Action;
  25. import org.sonar.api.server.ws.WebService.Param;
  26. import org.sonar.api.utils.System2;
  27. import org.sonar.db.DbTester;
  28. import org.sonar.db.component.ComponentDto;
  29. import org.sonar.db.component.ResourceTypesRule;
  30. import org.sonar.db.organization.OrganizationDto;
  31. import org.sonar.db.rule.RuleDefinitionDto;
  32. import org.sonar.server.component.ComponentFinder;
  33. import org.sonar.server.es.EsTester;
  34. import org.sonar.server.issue.index.IssueIndex;
  35. import org.sonar.server.issue.index.IssueIndexer;
  36. import org.sonar.server.issue.index.IssueIteratorFactory;
  37. import org.sonar.server.permission.index.PermissionIndexerTester;
  38. import org.sonar.server.permission.index.WebAuthorizationTypeSupport;
  39. import org.sonar.server.tester.UserSessionRule;
  40. import org.sonar.server.view.index.ViewIndexer;
  41. import org.sonar.server.ws.WsActionTester;
  42. import org.sonarqube.ws.Issues.TagsResponse;
  43. import static java.lang.String.format;
  44. import static java.util.Arrays.asList;
  45. import static java.util.Collections.emptySet;
  46. import static java.util.Collections.singletonList;
  47. import static org.assertj.core.api.Assertions.assertThat;
  48. import static org.assertj.core.api.Assertions.tuple;
  49. import static org.sonar.api.resources.Qualifiers.PROJECT;
  50. import static org.sonar.db.component.ComponentTesting.newFileDto;
  51. import static org.sonar.db.component.ComponentTesting.newProjectCopy;
  52. import static org.sonar.test.JsonAssert.assertJson;
  53. public class TagsActionTest {
  54. @Rule
  55. public UserSessionRule userSession = UserSessionRule.standalone();
  56. @Rule
  57. public DbTester db = DbTester.create();
  58. @Rule
  59. public EsTester es = EsTester.create();
  60. @Rule
  61. public ExpectedException expectedException = ExpectedException.none();
  62. private IssueIndex issueIndex = new IssueIndex(es.client(), System2.INSTANCE, userSession, new WebAuthorizationTypeSupport(userSession));
  63. private IssueIndexer issueIndexer = new IssueIndexer(es.client(), db.getDbClient(), new IssueIteratorFactory(db.getDbClient()));
  64. private ViewIndexer viewIndexer = new ViewIndexer(db.getDbClient(), es.client());
  65. private PermissionIndexerTester permissionIndexer = new PermissionIndexerTester(es, issueIndexer);
  66. private ResourceTypesRule resourceTypes = new ResourceTypesRule().setRootQualifiers(PROJECT);
  67. private WsActionTester ws = new WsActionTester(new TagsAction(issueIndex, db.getDbClient(), new ComponentFinder(db.getDbClient(), resourceTypes)));
  68. @Test
  69. public void search_tags() {
  70. RuleDefinitionDto rule = db.rules().insertIssueRule();
  71. ComponentDto project = db.components().insertPrivateProject();
  72. db.issues().insertIssue(rule, project, project, issue -> issue.setTags(asList("tag1", "tag2")));
  73. db.issues().insertIssue(rule, project, project, issue -> issue.setTags(asList("tag3", "tag4", "tag5")));
  74. issueIndexer.indexOnStartup(emptySet());
  75. permissionIndexer.allowOnlyAnyone(project);
  76. TagsResponse result = ws.newRequest().executeProtobuf(TagsResponse.class);
  77. assertThat(result.getTagsList()).containsExactly("tag1", "tag2", "tag3", "tag4", "tag5");
  78. }
  79. @Test
  80. public void search_tags_by_query() {
  81. RuleDefinitionDto rule = db.rules().insertIssueRule();
  82. ComponentDto project = db.components().insertPrivateProject();
  83. db.issues().insertIssue(rule, project, project, issue -> issue.setTags(asList("tag1", "tag2")));
  84. db.issues().insertIssue(rule, project, project, issue -> issue.setTags(asList("tag12", "tag4", "tag5")));
  85. issueIndexer.indexOnStartup(emptySet());
  86. permissionIndexer.allowOnlyAnyone(project);
  87. TagsResponse result = ws.newRequest()
  88. .setParam("q", "ag1")
  89. .executeProtobuf(TagsResponse.class);
  90. assertThat(result.getTagsList()).containsExactly("tag1", "tag12");
  91. }
  92. @Test
  93. public void search_tags_by_organization() {
  94. RuleDefinitionDto rule = db.rules().insertIssueRule();
  95. // Tags on issues of organization 1
  96. OrganizationDto organization1 = db.organizations().insert();
  97. ComponentDto project1 = db.components().insertPrivateProject(organization1);
  98. db.issues().insertIssue(rule, project1, project1, issue -> issue.setTags(asList("tag1", "tag2")));
  99. // Tags on issues of organization 2
  100. OrganizationDto organization2 = db.organizations().insert();
  101. ComponentDto project2 = db.components().insertPrivateProject(organization2);
  102. db.issues().insertIssue(rule, project2, project2, issue -> issue.setTags(singletonList("tag3")));
  103. issueIndexer.indexOnStartup(emptySet());
  104. permissionIndexer.allowOnlyAnyone(project1, project2);
  105. TagsResponse result = ws.newRequest()
  106. .setParam("organization", organization1.getKey())
  107. .executeProtobuf(TagsResponse.class);
  108. assertThat(result.getTagsList()).containsExactly("tag1", "tag2");
  109. }
  110. @Test
  111. public void search_tags_by_project() {
  112. RuleDefinitionDto rule = db.rules().insertIssueRule();
  113. OrganizationDto organization = db.organizations().insert();
  114. ComponentDto project1 = db.components().insertPrivateProject(organization);
  115. ComponentDto project2 = db.components().insertPrivateProject(organization);
  116. db.issues().insertIssue(rule, project1, project1, issue -> issue.setTags(singletonList("tag1")));
  117. db.issues().insertIssue(rule, project2, project2, issue -> issue.setTags(singletonList("tag2")));
  118. issueIndexer.indexOnStartup(emptySet());
  119. permissionIndexer.allowOnlyAnyone(project1, project2);
  120. TagsResponse result = ws.newRequest()
  121. .setParam("organization", organization.getKey())
  122. .setParam("project", project1.getKey())
  123. .executeProtobuf(TagsResponse.class);
  124. assertThat(result.getTagsList()).containsExactly("tag1");
  125. }
  126. @Test
  127. public void search_tags_by_portfolio() {
  128. OrganizationDto organization = db.getDefaultOrganization();
  129. ComponentDto portfolio = db.components().insertPrivatePortfolio(organization);
  130. ComponentDto project = db.components().insertPrivateProject(organization);
  131. db.components().insertComponent(newProjectCopy(project, portfolio));
  132. permissionIndexer.allowOnlyAnyone(project);
  133. RuleDefinitionDto rule = db.rules().insertIssueRule();
  134. db.issues().insertIssue(rule, project, project, issue -> issue.setTags(singletonList("cwe")));
  135. issueIndexer.indexOnStartup(emptySet());
  136. viewIndexer.indexOnStartup(emptySet());
  137. userSession.logIn().addMembership(organization);
  138. TagsResponse result = ws.newRequest()
  139. .setParam("project", portfolio.getKey())
  140. .executeProtobuf(TagsResponse.class);
  141. assertThat(result.getTagsList()).containsExactly("cwe");
  142. }
  143. @Test
  144. public void search_tags_by_application() {
  145. OrganizationDto organization = db.getDefaultOrganization();
  146. ComponentDto application = db.components().insertPrivateApplication(organization);
  147. ComponentDto project = db.components().insertPrivateProject(organization);
  148. db.components().insertComponent(newProjectCopy(project, application));
  149. permissionIndexer.allowOnlyAnyone(project);
  150. RuleDefinitionDto rule = db.rules().insertIssueRule();
  151. db.issues().insertIssue(rule, project, project, issue -> issue.setTags(singletonList("cwe")));
  152. issueIndexer.indexOnStartup(emptySet());
  153. viewIndexer.indexOnStartup(emptySet());
  154. userSession.logIn().addMembership(organization);
  155. TagsResponse result = ws.newRequest()
  156. .setParam("project", application.getKey())
  157. .executeProtobuf(TagsResponse.class);
  158. assertThat(result.getTagsList()).containsExactly("cwe");
  159. }
  160. @Test
  161. public void return_limited_size() {
  162. RuleDefinitionDto rule = db.rules().insertIssueRule();
  163. ComponentDto project = db.components().insertPrivateProject();
  164. db.issues().insertIssue(rule, project, project, issue -> issue.setTags(asList("tag1", "tag2")));
  165. db.issues().insertIssue(rule, project, project, issue -> issue.setTags(asList("tag3", "tag4", "tag5")));
  166. issueIndexer.indexOnStartup(emptySet());
  167. permissionIndexer.allowOnlyAnyone(project);
  168. TagsResponse result = ws.newRequest()
  169. .setParam("ps", "2")
  170. .executeProtobuf(TagsResponse.class);
  171. assertThat(result.getTagsList()).containsExactly("tag1", "tag2");
  172. }
  173. @Test
  174. public void do_not_return_issues_without_permission() {
  175. RuleDefinitionDto rule = db.rules().insertIssueRule();
  176. ComponentDto project1 = db.components().insertPrivateProject();
  177. ComponentDto project2 = db.components().insertPrivateProject();
  178. db.issues().insertIssue(rule, project1, project1, issue -> issue.setTags(asList("tag1", "tag2")));
  179. db.issues().insertIssue(rule, project2, project2, issue -> issue.setTags(asList("tag3", "tag4", "tag5")));
  180. issueIndexer.indexOnStartup(emptySet());
  181. // Project 2 is not visible to current user
  182. permissionIndexer.allowOnlyAnyone(project1);
  183. TagsResponse result = ws.newRequest().executeProtobuf(TagsResponse.class);
  184. assertThat(result.getTagsList()).containsExactly("tag1", "tag2");
  185. }
  186. @Test
  187. public void without_organization_parameter_is_cross_organization() {
  188. RuleDefinitionDto rule = db.rules().insertIssueRule();
  189. // Tags on issues of organization 1
  190. OrganizationDto organization1 = db.organizations().insert();
  191. ComponentDto project1 = db.components().insertPrivateProject(organization1);
  192. db.issues().insertIssue(rule, project1, project1, issue -> issue.setTags(asList("tag1", "tag2")));
  193. // Tags on issues of organization 2
  194. OrganizationDto organization2 = db.organizations().insert();
  195. ComponentDto project2 = db.components().insertPrivateProject(organization2);
  196. db.issues().insertIssue(rule, project2, project2, issue -> issue.setTags(singletonList("tag3")));
  197. issueIndexer.indexOnStartup(emptySet());
  198. permissionIndexer.allowOnlyAnyone(project1, project2);
  199. TagsResponse result = ws.newRequest().executeProtobuf(TagsResponse.class);
  200. assertThat(result.getTagsList()).containsExactly("tag1", "tag2", "tag3");
  201. }
  202. @Test
  203. public void empty_list() {
  204. TagsResponse result = ws.newRequest().executeProtobuf(TagsResponse.class);
  205. assertThat(result.getTagsList()).isEmpty();
  206. }
  207. @Test
  208. public void fail_when_project_does_not_belong_to_organization() {
  209. OrganizationDto organization = db.organizations().insert();
  210. OrganizationDto otherOrganization = db.organizations().insert();
  211. ComponentDto project = db.components().insertPrivateProject(otherOrganization);
  212. issueIndexer.indexOnStartup(emptySet());
  213. permissionIndexer.allowOnlyAnyone(project, project);
  214. expectedException.expect(IllegalArgumentException.class);
  215. expectedException.expectMessage(format("Project '%s' is not part of the organization '%s'", project.getKey(), organization.getKey()));
  216. ws.newRequest()
  217. .setParam("organization", organization.getKey())
  218. .setParam("project", project.getKey())
  219. .execute();
  220. }
  221. @Test
  222. public void fail_when_project_parameter_does_not_match_a_project() {
  223. OrganizationDto organization = db.organizations().insert();
  224. ComponentDto project = db.components().insertPrivateProject(organization);
  225. ComponentDto file = db.components().insertComponent(newFileDto(project));
  226. issueIndexer.indexOnStartup(emptySet());
  227. permissionIndexer.allowOnlyAnyone(project, project);
  228. expectedException.expect(IllegalArgumentException.class);
  229. expectedException.expectMessage(format("Component '%s' must be a project", file.getKey()));
  230. ws.newRequest()
  231. .setParam("organization", organization.getKey())
  232. .setParam("project", file.getKey())
  233. .execute();
  234. }
  235. @Test
  236. public void json_example() {
  237. RuleDefinitionDto rule = db.rules().insertIssueRule();
  238. ComponentDto project = db.components().insertPrivateProject();
  239. db.issues().insertIssue(rule, project, project, issue -> issue.setTags(asList("convention", "security")));
  240. db.issues().insertIssue(rule, project, project, issue -> issue.setTags(singletonList("cwe")));
  241. issueIndexer.indexOnStartup(emptySet());
  242. permissionIndexer.allowOnlyAnyone(project);
  243. String result = ws.newRequest().execute().getInput();
  244. assertJson(result).isSimilarTo(ws.getDef().responseExampleAsString());
  245. }
  246. @Test
  247. public void definition() {
  248. userSession.logIn();
  249. Action action = ws.getDef();
  250. assertThat(action.description()).isNotEmpty();
  251. assertThat(action.responseExampleAsString()).isNotEmpty();
  252. assertThat(action.isPost()).isFalse();
  253. assertThat(action.isInternal()).isFalse();
  254. assertThat(action.params())
  255. .extracting(Param::key, Param::defaultValue, Param::since, Param::isRequired, Param::isInternal)
  256. .containsExactlyInAnyOrder(
  257. tuple("q", null, null, false, false),
  258. tuple("ps", "10", null, false, false),
  259. tuple("organization", null, "6.4", false, true),
  260. tuple("project", null, "7.4", false, false));
  261. }
  262. }