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.

AppActionTest.java 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374
  1. /*
  2. * SonarQube
  3. * Copyright (C) 2009-2019 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.component.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;
  25. import org.sonar.db.DbTester;
  26. import org.sonar.db.component.ComponentDto;
  27. import org.sonar.db.metric.MetricDto;
  28. import org.sonar.server.component.TestComponentFinder;
  29. import org.sonar.server.exceptions.ForbiddenException;
  30. import org.sonar.server.exceptions.NotFoundException;
  31. import org.sonar.server.tester.UserSessionRule;
  32. import org.sonar.server.ws.WsActionTester;
  33. import static org.assertj.core.api.Assertions.assertThat;
  34. import static org.sonar.api.measures.CoreMetrics.COVERAGE_KEY;
  35. import static org.sonar.api.measures.CoreMetrics.DUPLICATED_LINES_DENSITY_KEY;
  36. import static org.sonar.api.measures.CoreMetrics.LINES_KEY;
  37. import static org.sonar.api.measures.CoreMetrics.TECHNICAL_DEBT_KEY;
  38. import static org.sonar.api.measures.CoreMetrics.TESTS_KEY;
  39. import static org.sonar.api.measures.CoreMetrics.VIOLATIONS_KEY;
  40. import static org.sonar.api.web.UserRole.USER;
  41. import static org.sonar.db.component.BranchType.PULL_REQUEST;
  42. import static org.sonar.db.component.ComponentTesting.newDirectory;
  43. import static org.sonar.db.component.ComponentTesting.newFileDto;
  44. import static org.sonar.db.component.ComponentTesting.newModuleDto;
  45. import static org.sonar.test.JsonAssert.assertJson;
  46. public class AppActionTest {
  47. @Rule
  48. public ExpectedException expectedException = ExpectedException.none();
  49. @Rule
  50. public UserSessionRule userSession = UserSessionRule.standalone();
  51. @Rule
  52. public DbTester db = DbTester.create();
  53. private WsActionTester ws = new WsActionTester(new AppAction(db.getDbClient(), userSession, TestComponentFinder.from(db)));
  54. @Test
  55. public void file_info() {
  56. ComponentDto project = db.components().insertPrivateProject();
  57. ComponentDto directory = db.components().insertComponent(newDirectory(project, "src"));
  58. ComponentDto file = db.components().insertComponent(newFileDto(project, directory));
  59. userSession.logIn("john").addProjectPermission(USER, project);
  60. String result = ws.newRequest()
  61. .setParam("component", file.getKey())
  62. .execute()
  63. .getInput();
  64. assertJson(result).isSimilarTo("{\n" +
  65. " \"key\": \"" + file.getKey() + "\",\n" +
  66. " \"uuid\": \"" + file.uuid() + "\",\n" +
  67. " \"path\": \"" + file.path() + "\",\n" +
  68. " \"name\": \"" + file.name() + "\",\n" +
  69. " \"longName\": \"" + file.longName() + "\",\n" +
  70. " \"q\": \"" + file.qualifier() + "\",\n" +
  71. " \"project\": \"" + project.getKey() + "\",\n" +
  72. " \"projectName\": \"" + project.longName() + "\",\n" +
  73. " \"fav\": false,\n" +
  74. " \"canMarkAsFavorite\": true,\n" +
  75. " \"measures\": {}\n" +
  76. "}\n");
  77. }
  78. @Test
  79. public void file_on_module() {
  80. ComponentDto project = db.components().insertPrivateProject();
  81. ComponentDto module = db.components().insertComponent(newModuleDto(project));
  82. ComponentDto directory = db.components().insertComponent(newDirectory(module, "src"));
  83. ComponentDto file = db.components().insertComponent(newFileDto(module, directory));
  84. userSession.logIn("john").addProjectPermission(USER, project);
  85. String result = ws.newRequest()
  86. .setParam("component", file.getKey())
  87. .execute()
  88. .getInput();
  89. assertJson(result).isSimilarTo("{\n" +
  90. " \"key\": \"" + file.getKey() + "\",\n" +
  91. " \"uuid\": \"" + file.uuid() + "\",\n" +
  92. " \"path\": \"" + file.path() + "\",\n" +
  93. " \"name\": \"" + file.name() + "\",\n" +
  94. " \"longName\": \"" + file.longName() + "\",\n" +
  95. " \"q\": \"" + file.qualifier() + "\",\n" +
  96. " \"subProject\": \"" + module.getKey() + "\",\n" +
  97. " \"subProjectName\": \"" + module.longName() + "\",\n" +
  98. " \"project\": \"" + project.getKey() + "\",\n" +
  99. " \"projectName\": \"" + project.longName() + "\",\n" +
  100. " \"fav\": false,\n" +
  101. " \"canMarkAsFavorite\": true,\n" +
  102. " \"measures\": {}\n" +
  103. "}\n");
  104. }
  105. @Test
  106. public void file_without_measures() {
  107. ComponentDto project = db.components().insertPrivateProject();
  108. ComponentDto file = db.components().insertComponent(newFileDto(project));
  109. userSession.logIn("john").addProjectPermission(USER, project);
  110. String result = ws.newRequest()
  111. .setParam("component", file.getKey())
  112. .execute()
  113. .getInput();
  114. assertJson(result).isSimilarTo("{\n" +
  115. " \"measures\": {}\n" +
  116. "}\n");
  117. }
  118. @Test
  119. public void file_with_measures() {
  120. ComponentDto project = db.components().insertPrivateProject();
  121. ComponentDto directory = db.components().insertComponent(newDirectory(project, "src"));
  122. ComponentDto file = db.components().insertComponent(newFileDto(project, directory));
  123. MetricDto lines = db.measures().insertMetric(m -> m.setKey(LINES_KEY));
  124. db.measures().insertLiveMeasure(file, lines, m -> m.setValue(200d));
  125. MetricDto duplicatedLines = db.measures().insertMetric(m -> m.setKey(DUPLICATED_LINES_DENSITY_KEY));
  126. db.measures().insertLiveMeasure(file, duplicatedLines, m -> m.setValue(7.4));
  127. MetricDto tests = db.measures().insertMetric(m -> m.setKey(TESTS_KEY));
  128. db.measures().insertLiveMeasure(file, tests, m -> m.setValue(3d));
  129. MetricDto technicalDebt = db.measures().insertMetric(m -> m.setKey(TECHNICAL_DEBT_KEY));
  130. db.measures().insertLiveMeasure(file, technicalDebt, m -> m.setValue(182d));
  131. MetricDto issues = db.measures().insertMetric(m -> m.setKey(VIOLATIONS_KEY));
  132. db.measures().insertLiveMeasure(file, issues, m -> m.setValue(231d));
  133. MetricDto coverage = db.measures().insertMetric(m -> m.setKey(COVERAGE_KEY));
  134. db.measures().insertLiveMeasure(file, coverage, m -> m.setValue(95.4d));
  135. userSession.logIn("john").addProjectPermission(USER, project);
  136. String result = ws.newRequest()
  137. .setParam("component", file.getKey())
  138. .execute()
  139. .getInput();
  140. assertJson(result).isSimilarTo("{\n" +
  141. " \"measures\": {\n" +
  142. " \"lines\": \"200.0\",\n" +
  143. " \"coverage\": \"95.4\",\n" +
  144. " \"duplicationDensity\": \"7.4\",\n" +
  145. " \"issues\": \"231.0\",\n" +
  146. " \"tests\": \"3.0\"\n" +
  147. " }" +
  148. "}\n");
  149. }
  150. @Test
  151. public void get_by_uuid() {
  152. ComponentDto project = db.components().insertPrivateProject();
  153. ComponentDto file = db.components().insertComponent(newFileDto(project, project));
  154. MetricDto coverage = db.measures().insertMetric(m -> m.setKey(COVERAGE_KEY));
  155. db.measures().insertLiveMeasure(file, coverage, m -> m.setValue(95.4d));
  156. userSession.logIn("john").addProjectPermission(USER, project);
  157. String result = ws.newRequest()
  158. .setParam("uuid", file.uuid())
  159. .execute()
  160. .getInput();
  161. assertJson(result).isSimilarTo("{\n" +
  162. " \"key\": \"" + file.getKey() + "\",\n" +
  163. " \"uuid\": \"" + file.uuid() + "\",\n" +
  164. " \"measures\": {\n" +
  165. " \"coverage\": \"95.4\"\n" +
  166. " }\n" +
  167. "}\n");
  168. }
  169. @Test
  170. public void canMarkAsFavorite_is_true_when_logged() {
  171. ComponentDto project = db.components().insertPrivateProject();
  172. userSession.logIn("john").addProjectPermission(USER, project);
  173. String result = ws.newRequest()
  174. .setParam("component", project.getKey())
  175. .execute()
  176. .getInput();
  177. assertJson(result).isSimilarTo("{\n" +
  178. " \"canMarkAsFavorite\": true,\n" +
  179. "}\n");
  180. }
  181. @Test
  182. public void canMarkAsFavorite_is_false_when_not_logged() {
  183. ComponentDto project = db.components().insertPrivateProject();
  184. userSession.addProjectPermission(USER, project);
  185. String result = ws.newRequest()
  186. .setParam("component", project.getKey())
  187. .execute()
  188. .getInput();
  189. assertJson(result).isSimilarTo("{\n" +
  190. " \"canMarkAsFavorite\": false,\n" +
  191. "}\n");
  192. }
  193. @Test
  194. public void component_is_favorite() {
  195. ComponentDto project = db.components().insertPrivateProject();
  196. userSession.logIn("john").addProjectPermission(USER, project);
  197. db.favorites().add(project, userSession.getUserId());
  198. String result = ws.newRequest()
  199. .setParam("component", project.getKey())
  200. .execute()
  201. .getInput();
  202. assertJson(result).isSimilarTo("{\n" +
  203. " \"fav\": true,\n" +
  204. "}\n");
  205. }
  206. @Test
  207. public void component_is_not_favorite() {
  208. ComponentDto project = db.components().insertPrivateProject();
  209. userSession.logIn("john").addProjectPermission(USER, project);
  210. String result = ws.newRequest()
  211. .setParam("component", project.getKey())
  212. .execute()
  213. .getInput();
  214. assertJson(result).isSimilarTo("{\n" +
  215. " \"fav\": false,\n" +
  216. "}\n");
  217. }
  218. @Test
  219. public void branch() {
  220. ComponentDto project = db.components().insertMainBranch();
  221. userSession.logIn("john").addProjectPermission(USER, project);
  222. ComponentDto branch = db.components().insertProjectBranch(project);
  223. ComponentDto module = db.components().insertComponent(newModuleDto(branch));
  224. ComponentDto directory = db.components().insertComponent(newDirectory(module, "src"));
  225. ComponentDto file = db.components().insertComponent(newFileDto(module, directory));
  226. MetricDto coverage = db.measures().insertMetric(m -> m.setKey(COVERAGE_KEY));
  227. db.measures().insertLiveMeasure(file, coverage, m -> m.setValue(95.4d));
  228. String result = ws.newRequest()
  229. .setParam("component", file.getKey())
  230. .setParam("branch", file.getBranch())
  231. .execute()
  232. .getInput();
  233. assertJson(result).isSimilarTo("{\n" +
  234. " \"key\": \"" + file.getKey() + "\",\n" +
  235. " \"branch\": \"" + file.getBranch() + "\",\n" +
  236. " \"uuid\": \"" + file.uuid() + "\",\n" +
  237. " \"path\": \"" + file.path() + "\",\n" +
  238. " \"name\": \"" + file.name() + "\",\n" +
  239. " \"longName\": \"" + file.longName() + "\",\n" +
  240. " \"q\": \"" + file.qualifier() + "\",\n" +
  241. " \"subProject\": \"" + module.getKey() + "\",\n" +
  242. " \"subProjectName\": \"" + module.longName() + "\",\n" +
  243. " \"project\": \"" + project.getKey() + "\",\n" +
  244. " \"projectName\": \"" + project.longName() + "\",\n" +
  245. " \"fav\": false,\n" +
  246. " \"canMarkAsFavorite\": true,\n" +
  247. " \"measures\": {\n" +
  248. " \"coverage\": \"95.4\"\n" +
  249. " }\n" +
  250. "}\n");
  251. }
  252. @Test
  253. public void fail_if_no_parameter_provided() {
  254. expectedException.expect(IllegalArgumentException.class);
  255. expectedException.expectMessage("Either 'componentId' or 'component' must be provided");
  256. ws.newRequest().execute();
  257. }
  258. @Test
  259. public void fail_if_both_componentId_and_branch_parameters_provided() {
  260. ComponentDto project = db.components().insertMainBranch();
  261. ComponentDto branch = db.components().insertProjectBranch(project);
  262. ComponentDto file = db.components().insertComponent(newFileDto(branch));
  263. expectedException.expect(IllegalArgumentException.class);
  264. expectedException.expectMessage("Parameter 'componentId' cannot be used at the same time as 'branch' or 'pullRequest'");
  265. ws.newRequest()
  266. .setParam("uuid", file.uuid())
  267. .setParam("branch", file.getBranch())
  268. .execute();
  269. }
  270. @Test
  271. public void fail_if_both_componentId_and_pull_request_parameters_provided() {
  272. ComponentDto project = db.components().insertMainBranch();
  273. ComponentDto branch = db.components().insertProjectBranch(project, b -> b.setBranchType(PULL_REQUEST));
  274. ComponentDto file = db.components().insertComponent(newFileDto(branch));
  275. expectedException.expect(IllegalArgumentException.class);
  276. expectedException.expectMessage("Parameter 'componentId' cannot be used at the same time as 'branch' or 'pullRequest'");
  277. ws.newRequest()
  278. .setParam("uuid", file.uuid())
  279. .setParam("pullRequest", file.getPullRequest())
  280. .execute();
  281. }
  282. @Test
  283. public void fail_when_component_not_found() {
  284. ComponentDto project = db.components().insertPrivateProject();
  285. ComponentDto file = db.components().insertComponent(newFileDto(project));
  286. expectedException.expect(NotFoundException.class);
  287. ws.newRequest()
  288. .setParam("component", "unknown")
  289. .execute();
  290. }
  291. @Test
  292. public void fail_when_branch_not_found() {
  293. ComponentDto project = db.components().insertPrivateProject();
  294. ComponentDto branch = db.components().insertProjectBranch(project);
  295. ComponentDto file = db.components().insertComponent(newFileDto(branch));
  296. expectedException.expect(NotFoundException.class);
  297. ws.newRequest()
  298. .setParam("component", file.getKey())
  299. .setParam("branch", "unknown")
  300. .execute();
  301. }
  302. @Test
  303. public void fail_when_missing_permission() {
  304. ComponentDto project = db.components().insertPrivateProject();
  305. ComponentDto file = db.components().insertComponent(newFileDto(project));
  306. expectedException.expect(ForbiddenException.class);
  307. ws.newRequest()
  308. .setParam("component", file.getKey())
  309. .execute();
  310. }
  311. @Test
  312. public void define_app_action() {
  313. WebService.Action action = ws.getDef();
  314. assertThat(action).isNotNull();
  315. assertThat(action.isInternal()).isTrue();
  316. assertThat(action.isPost()).isFalse();
  317. assertThat(action.handler()).isNotNull();
  318. assertThat(action.params()).hasSize(4);
  319. }
  320. }