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.

DefaultProjectBindingsControllerTest.java 9.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. /*
  2. * SonarQube
  3. * Copyright (C) 2009-2024 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.v2.api.projectbindings.controller;
  21. import java.util.List;
  22. import java.util.Optional;
  23. import org.junit.Rule;
  24. import org.junit.jupiter.api.Test;
  25. import org.mockito.ArgumentCaptor;
  26. import org.sonar.db.alm.setting.ProjectAlmSettingDto;
  27. import org.sonar.db.project.ProjectDto;
  28. import org.sonar.server.common.SearchResults;
  29. import org.sonar.server.common.projectbindings.service.ProjectBindingInformation;
  30. import org.sonar.server.common.projectbindings.service.ProjectBindingsSearchRequest;
  31. import org.sonar.server.common.projectbindings.service.ProjectBindingsService;
  32. import org.sonar.server.tester.UserSessionRule;
  33. import org.sonar.server.v2.api.ControllerTester;
  34. import org.springframework.test.web.servlet.MockMvc;
  35. import static org.assertj.core.api.Assertions.assertThat;
  36. import static org.mockito.ArgumentMatchers.any;
  37. import static org.mockito.Mockito.mock;
  38. import static org.mockito.Mockito.verify;
  39. import static org.mockito.Mockito.when;
  40. import static org.sonar.api.web.UserRole.ADMIN;
  41. import static org.sonar.db.permission.GlobalPermission.PROVISION_PROJECTS;
  42. import static org.sonar.server.v2.WebApiEndpoints.PROJECT_BINDINGS_ENDPOINT;
  43. import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
  44. import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
  45. import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
  46. class DefaultProjectBindingsControllerTest {
  47. public static final String UUID = "uuid";
  48. private static final String PROJECT_UUID = "projectUuid";
  49. @Rule
  50. public UserSessionRule userSession = UserSessionRule.standalone();
  51. private final ProjectBindingsService projectBindingsService = mock();
  52. private final MockMvc mockMvc = ControllerTester.getMockMvc(new DefaultProjectBindingsController(userSession, projectBindingsService));
  53. @Test
  54. void getProjectBinding_whenNoProjectBinding_returnsNotFound() throws Exception {
  55. userSession.logIn();
  56. when(projectBindingsService.findProjectBindingByUuid(UUID)).thenReturn(Optional.empty());
  57. mockMvc
  58. .perform(get(PROJECT_BINDINGS_ENDPOINT + "/uuid"))
  59. .andExpectAll(
  60. status().isNotFound(),
  61. content().json("""
  62. {
  63. "message": "Project binding 'uuid' not found"
  64. }
  65. """));
  66. }
  67. @Test
  68. void getProjectBinding_whenNoProject_returnsServerError() throws Exception {
  69. userSession.logIn();
  70. ProjectAlmSettingDto projectAlmSettingDto = mock();
  71. when(projectAlmSettingDto.getProjectUuid()).thenReturn(PROJECT_UUID);
  72. when(projectBindingsService.findProjectBindingByUuid(UUID)).thenReturn(Optional.of(projectAlmSettingDto));
  73. when(projectBindingsService.findProjectFromBinding(projectAlmSettingDto)).thenReturn(Optional.empty());
  74. mockMvc
  75. .perform(get(PROJECT_BINDINGS_ENDPOINT + "/uuid"))
  76. .andExpectAll(
  77. status().isInternalServerError(),
  78. content().json("""
  79. {
  80. "message": "Project (uuid 'projectUuid') not found for binding 'uuid'"
  81. }
  82. """));
  83. }
  84. @Test
  85. void getProjectBinding_whenUserDoesntHaveProjectAdminPermissions_returnsForbidden() throws Exception {
  86. userSession.logIn();
  87. ProjectAlmSettingDto projectAlmSettingDto = mock();
  88. when(projectBindingsService.findProjectBindingByUuid(UUID)).thenReturn(Optional.of(projectAlmSettingDto));
  89. when(projectBindingsService.findProjectFromBinding(projectAlmSettingDto)).thenReturn(Optional.ofNullable(mock(ProjectDto.class)));
  90. mockMvc
  91. .perform(get(PROJECT_BINDINGS_ENDPOINT + "/uuid"))
  92. .andExpectAll(
  93. status().isForbidden(),
  94. content().json("""
  95. {
  96. "message": "Insufficient privileges"
  97. }
  98. """));
  99. }
  100. @Test
  101. void getProjectBinding_whenProjectBindingAndPermissions_returnsIt() throws Exception {
  102. ProjectAlmSettingDto projectAlmSettingDto = mockProjectAlmSettingDto("1");
  103. ProjectDto projectDto = mock();
  104. when(projectDto.getKey()).thenReturn("projectKey_1");
  105. userSession.logIn().addProjectPermission(ADMIN, projectDto);
  106. when(projectBindingsService.findProjectBindingByUuid(UUID)).thenReturn(Optional.of(projectAlmSettingDto));
  107. when(projectBindingsService.findProjectFromBinding(projectAlmSettingDto)).thenReturn(Optional.ofNullable(projectDto));
  108. mockMvc
  109. .perform(get(PROJECT_BINDINGS_ENDPOINT + "/uuid"))
  110. .andExpectAll(
  111. status().isOk(),
  112. content().json("""
  113. {
  114. "id": "uuid_1",
  115. "devOpsPlatformSettingId": "almSettingUuid_1",
  116. "projectId": "projectUuid_1",
  117. "projectKey": "projectKey_1",
  118. "repository": "almRepo_1",
  119. "slug": "almSlug_1"
  120. }
  121. """));
  122. }
  123. @Test
  124. void searchProjectBindings_whenUserDoesntHaveProjectProvisionPermission_returnsForbidden() throws Exception {
  125. userSession.logIn();
  126. mockMvc
  127. .perform(get(PROJECT_BINDINGS_ENDPOINT)
  128. .param("repository", "repo")
  129. .param("dopSettingId", "id"))
  130. .andExpectAll(
  131. status().isForbidden(),
  132. content().json("""
  133. {
  134. "message": "Insufficient privileges"
  135. }
  136. """));
  137. }
  138. @Test
  139. void searchProjectBindings_whenParametersUsed_shouldForwardWithParameters() throws Exception {
  140. userSession.logIn().addPermission(PROVISION_PROJECTS);
  141. when(projectBindingsService.findProjectBindingsByRequest(any())).thenReturn(new SearchResults<>(List.of(), 0));
  142. mockMvc
  143. .perform(get(PROJECT_BINDINGS_ENDPOINT)
  144. .param("repository", "repo")
  145. .param("dopSettingId", "id")
  146. .param("pageIndex", "12")
  147. .param("pageSize", "42"))
  148. .andExpect(status().isOk());
  149. ArgumentCaptor<ProjectBindingsSearchRequest> requestCaptor = ArgumentCaptor.forClass(ProjectBindingsSearchRequest.class);
  150. verify(projectBindingsService).findProjectBindingsByRequest(requestCaptor.capture());
  151. assertThat(requestCaptor.getValue().repository()).isEqualTo("repo");
  152. assertThat(requestCaptor.getValue().dopSettingId()).isEqualTo("id");
  153. assertThat(requestCaptor.getValue().page()).isEqualTo(12);
  154. assertThat(requestCaptor.getValue().pageSize()).isEqualTo(42);
  155. }
  156. @Test
  157. void searchProjectBindings_whenResultsFound_shouldReturnsThem() throws Exception {
  158. userSession.logIn().addPermission(PROVISION_PROJECTS);
  159. ProjectBindingInformation dto1 = projectBindingInformation("1");
  160. ProjectBindingInformation dto2 = projectBindingInformation("2");
  161. List<ProjectBindingInformation> expectedResults = List.of(dto1, dto2);
  162. when(projectBindingsService.findProjectBindingsByRequest(any())).thenReturn(new SearchResults<>(expectedResults, expectedResults.size()));
  163. mockMvc
  164. .perform(get(PROJECT_BINDINGS_ENDPOINT)
  165. .param("repository", "whatever")
  166. .param("dopSettingId", "doesntmatter")
  167. .param("pageIndex", "1")
  168. .param("pageSize", "100"))
  169. .andExpectAll(
  170. status().isOk(),
  171. content().json("""
  172. {
  173. "projectBindings": [
  174. {
  175. "id": "uuid_1",
  176. "devOpsPlatformSettingId": "almSettingUuid_1",
  177. "projectId": "projectUuid_1",
  178. "projectKey": "projectKey_1",
  179. "repository": "almRepo_1",
  180. "slug": "almSlug_1"
  181. },
  182. {
  183. "id": "uuid_2",
  184. "devOpsPlatformSettingId": "almSettingUuid_2",
  185. "projectId": "projectUuid_2",
  186. "projectKey": "projectKey_2",
  187. "repository": "almRepo_2",
  188. "slug": "almSlug_2"
  189. }
  190. ],
  191. "page": {
  192. "pageIndex": 1,
  193. "pageSize": 100,
  194. "total": 2
  195. }
  196. }
  197. """));
  198. }
  199. private static ProjectAlmSettingDto mockProjectAlmSettingDto(String i) {
  200. ProjectAlmSettingDto dto = mock();
  201. when(dto.getUuid()).thenReturn("uuid_" + i);
  202. when(dto.getAlmSettingUuid()).thenReturn("almSettingUuid_" + i);
  203. when(dto.getProjectUuid()).thenReturn("projectUuid_" + i);
  204. when(dto.getAlmRepo()).thenReturn("almRepo_" + i);
  205. when(dto.getAlmSlug()).thenReturn("almSlug_" + i);
  206. return dto;
  207. }
  208. private static ProjectBindingInformation projectBindingInformation(String i) {
  209. return new ProjectBindingInformation("uuid_" + i,
  210. "almSettingUuid_" + i,
  211. "projectUuid_" + i,
  212. "projectKey_" + i,
  213. "almRepo_" + i,
  214. "almSlug_" + i);
  215. }
  216. }