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.

GlobalActionTest.java 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  1. /*
  2. * SonarQube
  3. * Copyright (C) 2009-2018 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.ui.ws;
  21. import org.junit.Rule;
  22. import org.junit.Test;
  23. import org.sonar.api.config.internal.MapSettings;
  24. import org.sonar.api.platform.Server;
  25. import org.sonar.api.resources.ResourceType;
  26. import org.sonar.api.resources.ResourceTypeTree;
  27. import org.sonar.api.resources.ResourceTypes;
  28. import org.sonar.api.web.page.Page;
  29. import org.sonar.api.web.page.PageDefinition;
  30. import org.sonar.core.platform.PluginInfo;
  31. import org.sonar.core.platform.PluginRepository;
  32. import org.sonar.db.DbClient;
  33. import org.sonar.db.dialect.H2;
  34. import org.sonar.db.dialect.MySql;
  35. import org.sonar.server.branch.BranchFeatureRule;
  36. import org.sonar.core.extension.CoreExtensionRepository;
  37. import org.sonar.server.organization.DefaultOrganizationProvider;
  38. import org.sonar.server.organization.TestDefaultOrganizationProvider;
  39. import org.sonar.server.organization.TestOrganizationFlags;
  40. import org.sonar.server.platform.WebServer;
  41. import org.sonar.server.tester.UserSessionRule;
  42. import org.sonar.server.ui.PageRepository;
  43. import org.sonar.server.ws.WsActionTester;
  44. import org.sonar.updatecenter.common.Version;
  45. import static org.assertj.core.api.Assertions.assertThat;
  46. import static org.mockito.ArgumentMatchers.any;
  47. import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
  48. import static org.mockito.Mockito.mock;
  49. import static org.mockito.Mockito.when;
  50. import static org.sonar.test.JsonAssert.assertJson;
  51. public class GlobalActionTest {
  52. @Rule
  53. public UserSessionRule userSession = UserSessionRule.standalone();
  54. private MapSettings settings = new MapSettings();
  55. private Server server = mock(Server.class);
  56. private WebServer webServer = mock(WebServer.class);
  57. private DbClient dbClient = mock(DbClient.class, RETURNS_DEEP_STUBS);
  58. private TestOrganizationFlags organizationFlags = TestOrganizationFlags.standalone();
  59. private DefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.fromUuid("foo");
  60. private BranchFeatureRule branchFeature = new BranchFeatureRule();
  61. private WsActionTester ws;
  62. @Test
  63. public void empty_call() {
  64. init();
  65. assertJson(call()).isSimilarTo("{" +
  66. " \"globalPages\": []," +
  67. " \"settings\": {}," +
  68. " \"qualifiers\": []" +
  69. "}");
  70. }
  71. @Test
  72. public void return_qualifiers() {
  73. init(new Page[] {}, new ResourceTypeTree[] {
  74. ResourceTypeTree.builder()
  75. .addType(ResourceType.builder("POL").build())
  76. .addType(ResourceType.builder("LOP").build())
  77. .addRelations("POL", "LOP")
  78. .build(),
  79. ResourceTypeTree.builder()
  80. .addType(ResourceType.builder("PAL").build())
  81. .addType(ResourceType.builder("LAP").build())
  82. .addRelations("PAL", "LAP")
  83. .build()
  84. });
  85. assertJson(call()).isSimilarTo("{" +
  86. " \"qualifiers\": [\"POL\", \"PAL\"]" +
  87. "}");
  88. }
  89. @Test
  90. public void return_settings() {
  91. settings.setProperty("sonar.lf.logoUrl", "http://example.com/my-custom-logo.png");
  92. settings.setProperty("sonar.lf.logoWidthPx", 135);
  93. settings.setProperty("sonar.lf.gravatarServerUrl", "https://secure.gravatar.com/avatar/{EMAIL_MD5}.jpg?s={SIZE}&d=identicon");
  94. settings.setProperty("sonar.lf.enableGravatar", true);
  95. settings.setProperty("sonar.updatecenter.activate", false);
  96. settings.setProperty("sonar.technicalDebt.ratingGrid", "0.05,0.1,0.2,0.5");
  97. // This setting should be ignored as it's not needed
  98. settings.setProperty("sonar.defaultGroup", "sonar-users");
  99. init();
  100. assertJson(call()).isSimilarTo("{" +
  101. " \"settings\": {" +
  102. " \"sonar.lf.logoUrl\": \"http://example.com/my-custom-logo.png\"," +
  103. " \"sonar.lf.logoWidthPx\": \"135\"," +
  104. " \"sonar.lf.gravatarServerUrl\": \"https://secure.gravatar.com/avatar/{EMAIL_MD5}.jpg?s={SIZE}&d=identicon\"," +
  105. " \"sonar.lf.enableGravatar\": \"true\"," +
  106. " \"sonar.updatecenter.activate\": \"false\"," +
  107. " \"sonar.technicalDebt.ratingGrid\": \"0.05,0.1,0.2,0.5\"" +
  108. " }" +
  109. "}");
  110. }
  111. @Test
  112. public void return_deprecated_logo_settings() {
  113. init();
  114. settings.setProperty("sonar.lf.logoUrl", "http://example.com/my-custom-logo.png");
  115. settings.setProperty("sonar.lf.logoWidthPx", 135);
  116. assertJson(call()).isSimilarTo("{" +
  117. " \"settings\": {" +
  118. " \"sonar.lf.logoUrl\": \"http://example.com/my-custom-logo.png\"," +
  119. " \"sonar.lf.logoWidthPx\": \"135\"" +
  120. " }," +
  121. " \"logoUrl\": \"http://example.com/my-custom-logo.png\"," +
  122. " \"logoWidth\": \"135\"" +
  123. "}");
  124. }
  125. @Test
  126. public void the_returned_global_pages_do_not_include_administration_pages() {
  127. init(createPages(), new ResourceTypeTree[] {});
  128. assertJson(call()).isSimilarTo("{" +
  129. " \"globalPages\": [" +
  130. " {" +
  131. " \"key\": \"another_plugin/page\"," +
  132. " \"name\": \"My Another Page\"" +
  133. " }," +
  134. " {" +
  135. " \"key\": \"my_plugin/page\"," +
  136. " \"name\": \"My Plugin Page\"" +
  137. " }" +
  138. " ]" +
  139. "}");
  140. }
  141. @Test
  142. public void return_sonarqube_version() {
  143. init();
  144. when(server.getVersion()).thenReturn("6.2");
  145. assertJson(call()).isSimilarTo("{" +
  146. " \"version\": \"6.2\"" +
  147. "}");
  148. }
  149. @Test
  150. public void functional_version_when_4_digits() {
  151. init();
  152. when(server.getVersion()).thenReturn("6.3.1.1234");
  153. String result = call();
  154. assertThat(result).contains("6.3.1 (build 1234)");
  155. }
  156. @Test
  157. public void functional_version_when_third_digit_is_0() {
  158. init();
  159. when(server.getVersion()).thenReturn("6.3.0.1234");
  160. String result = call();
  161. assertThat(result).contains("6.3 (build 1234)");
  162. }
  163. @Test
  164. public void return_if_production_database_or_not() {
  165. init();
  166. when(dbClient.getDatabase().getDialect()).thenReturn(new MySql());
  167. assertJson(call()).isSimilarTo("{" +
  168. " \"productionDatabase\": true" +
  169. "}");
  170. }
  171. @Test
  172. public void organization_support() {
  173. init();
  174. organizationFlags.setEnabled(true);
  175. assertJson(call()).isSimilarTo("{" +
  176. " \"organizationsEnabled\": true," +
  177. " \"defaultOrganization\": \"key_foo\"" +
  178. "}");
  179. }
  180. @Test
  181. public void branch_support() {
  182. init();
  183. branchFeature.setEnabled(true);
  184. assertJson(call()).isSimilarTo("{\"branchesEnabled\":true}");
  185. branchFeature.setEnabled(false);
  186. assertJson(call()).isSimilarTo("{\"branchesEnabled\":false}");
  187. }
  188. @Test
  189. public void can_admin_on_global_level() {
  190. init();
  191. userSession.logIn().setRoot();
  192. assertJson(call()).isSimilarTo("{\"canAdmin\":true}");
  193. }
  194. @Test
  195. public void standalone_flag() {
  196. init();
  197. userSession.logIn().setRoot();
  198. when(webServer.isStandalone()).thenReturn(true);
  199. assertJson(call()).isSimilarTo("{\"standalone\":true}");
  200. }
  201. @Test
  202. public void not_standalone_flag() {
  203. init();
  204. userSession.logIn().setRoot();
  205. when(webServer.isStandalone()).thenReturn(false);
  206. assertJson(call()).isSimilarTo("{\"standalone\":false}");
  207. }
  208. @Test
  209. public void test_example_response() {
  210. settings.setProperty("sonar.lf.logoUrl", "http://example.com/my-custom-logo.png");
  211. settings.setProperty("sonar.lf.logoWidthPx", 135);
  212. settings.setProperty("sonar.lf.gravatarServerUrl", "http://some-server.tld/logo.png");
  213. settings.setProperty("sonar.lf.enableGravatar", true);
  214. settings.setProperty("sonar.updatecenter.activate", false);
  215. settings.setProperty("sonar.technicalDebt.ratingGrid", "0.05,0.1,0.2,0.5");
  216. init(createPages(), new ResourceTypeTree[] {
  217. ResourceTypeTree.builder()
  218. .addType(ResourceType.builder("POL").build())
  219. .addType(ResourceType.builder("LOP").build())
  220. .addRelations("POL", "LOP")
  221. .build(),
  222. ResourceTypeTree.builder()
  223. .addType(ResourceType.builder("PAL").build())
  224. .addType(ResourceType.builder("LAP").build())
  225. .addRelations("PAL", "LAP")
  226. .build()
  227. });
  228. when(server.getVersion()).thenReturn("6.2");
  229. when(dbClient.getDatabase().getDialect()).thenReturn(new MySql());
  230. when(webServer.isStandalone()).thenReturn(true);
  231. String result = call();
  232. assertJson(result).isSimilarTo(ws.getDef().responseExampleAsString());
  233. }
  234. private void init() {
  235. init(new org.sonar.api.web.page.Page[] {}, new ResourceTypeTree[] {});
  236. }
  237. private void init(org.sonar.api.web.page.Page[] pages, ResourceTypeTree[] resourceTypeTrees) {
  238. when(dbClient.getDatabase().getDialect()).thenReturn(new H2());
  239. when(server.getVersion()).thenReturn("6.42");
  240. PluginRepository pluginRepository = mock(PluginRepository.class);
  241. when(pluginRepository.hasPlugin(any())).thenReturn(true);
  242. when(pluginRepository.getPluginInfo(any())).thenReturn(new PluginInfo("unused").setVersion(Version.create("1.0")));
  243. CoreExtensionRepository coreExtensionRepository = mock(CoreExtensionRepository.class);
  244. when(coreExtensionRepository.isInstalled(any())).thenReturn(false);
  245. PageRepository pageRepository = new PageRepository(pluginRepository, coreExtensionRepository, new PageDefinition[] {context -> {
  246. for (Page page : pages) {
  247. context.addPage(page);
  248. }
  249. }});
  250. pageRepository.start();
  251. GlobalAction wsAction = new GlobalAction(pageRepository, settings.asConfig(), new ResourceTypes(resourceTypeTrees), server,
  252. webServer, dbClient, organizationFlags, defaultOrganizationProvider, branchFeature, userSession);
  253. ws = new WsActionTester(wsAction);
  254. wsAction.start();
  255. }
  256. private String call() {
  257. return ws.newRequest().execute().getInput();
  258. }
  259. private Page[] createPages() {
  260. Page page = Page.builder("my_plugin/page").setName("My Plugin Page").build();
  261. Page anotherPage = Page.builder("another_plugin/page").setName("My Another Page").build();
  262. Page adminPage = Page.builder("my_plugin/admin_page").setName("Admin Page").setAdmin(true).build();
  263. return new Page[] {page, anotherPage, adminPage};
  264. }
  265. }