您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

GlobalActionTest.java 12KB

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