3 * Copyright (C) 2009-2024 SonarSource SA
4 * mailto:info AT sonarsource DOT com
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.
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.
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.
20 package org.sonar.server.common.project;
22 import java.util.Optional;
23 import org.junit.Rule;
24 import org.junit.jupiter.api.Test;
25 import org.mockito.Answers;
26 import org.sonar.db.DbClient;
27 import org.sonar.db.DbSession;
28 import org.sonar.db.alm.setting.ALM;
29 import org.sonar.db.alm.setting.AlmSettingDto;
30 import org.sonar.db.alm.setting.ProjectAlmSettingDto;
31 import org.sonar.db.component.BranchDto;
32 import org.sonar.db.project.ProjectDto;
33 import org.sonar.server.common.almsettings.DevOpsProjectCreator;
34 import org.sonar.server.common.almsettings.DevOpsProjectCreatorFactory;
35 import org.sonar.server.common.almsettings.DevOpsProjectDescriptor;
36 import org.sonar.server.common.component.ComponentUpdater;
37 import org.sonar.server.common.newcodeperiod.NewCodeDefinitionResolver;
38 import org.sonar.server.component.ComponentCreationData;
39 import org.sonar.server.tester.UserSessionRule;
41 import static org.assertj.core.api.Assertions.assertThat;
42 import static org.assertj.core.api.Assertions.assertThatThrownBy;
43 import static org.mockito.ArgumentMatchers.any;
44 import static org.mockito.ArgumentMatchers.eq;
45 import static org.mockito.Mockito.lenient;
46 import static org.mockito.Mockito.mock;
47 import static org.mockito.Mockito.verify;
48 import static org.mockito.Mockito.when;
49 import static org.sonar.db.permission.GlobalPermission.PROVISION_PROJECTS;
51 class ImportProjectServiceTest {
53 private static final String API_URL = "https://api.com";
54 private static final String PROJECT_UUID = "project-uuid";
55 private static final String DOP_REPOSITORY_ID = "repository-id";
56 private static final String DOP_PROJECT_ID = "project-id";
57 private static final String PROJECT_KEY = "project-key";
58 private static final String PROJECT_NAME = "project-name";
59 private static final String MAIN_BRANCH_UUID = "main-branch-uuid";
60 private static final String MAIN_BRANCH_KEY = "main-branch-key";
61 private static final String ALM_SETTING_ID = "alm-setting-id";
64 public UserSessionRule userSession = UserSessionRule.standalone();
66 private final DevOpsProjectCreatorFactory devOpsProjectCreatorFactory = mock();
68 private final DbClient dbClient = mock(Answers.RETURNS_DEEP_STUBS);
69 private final NewCodeDefinitionResolver newCodeDefinitionResolver = mock();
70 private final ComponentUpdater componentUpdater = mock();
72 private final ImportProjectService importProjectService = new ImportProjectService(dbClient, devOpsProjectCreatorFactory, userSession, componentUpdater,
73 newCodeDefinitionResolver);;
76 void createdImportedProject_whenAlmSettingDoesntExist_throws() {
77 userSession.logIn().addPermission(PROVISION_PROJECTS);
78 DbSession dbSession = mockDbSession();
79 when(dbClient.almSettingDao().selectByUuid(dbSession, ALM_SETTING_ID)).thenReturn(Optional.empty());
81 ImportProjectRequest request = new ImportProjectRequest(PROJECT_KEY, PROJECT_NAME, ALM_SETTING_ID, DOP_REPOSITORY_ID, DOP_PROJECT_ID, null, null, true);
83 assertThatThrownBy(() -> importProjectService.importProject(request))
84 .isInstanceOf(IllegalArgumentException.class)
85 .hasMessage("ALM setting not found");
90 void createImportedProject_whenAlmIsNotSupported_throws() {
91 userSession.logIn().addPermission(PROVISION_PROJECTS);
93 DbSession dbSession = mockDbSession();
94 AlmSettingDto almSetting = mockAlmSetting(dbSession);
96 when(devOpsProjectCreatorFactory.getDevOpsProjectCreator(eq(almSetting), any()))
97 .thenReturn(Optional.empty());
99 ImportProjectRequest request = new ImportProjectRequest(PROJECT_KEY, PROJECT_NAME, ALM_SETTING_ID, DOP_REPOSITORY_ID, DOP_PROJECT_ID, null, null, true);
101 assertThatThrownBy(() -> importProjectService.importProject(request))
102 .isInstanceOf(IllegalArgumentException.class)
103 .hasMessage("Platform GITHUB not supported");
107 void createImportedProject_whenAlmIsSupportedAndNoNewCodeDefinitionDefined_shouldCreateProject() {
108 userSession.logIn().addPermission(PROVISION_PROJECTS);
109 DbSession dbSession = mockDbSession();
110 AlmSettingDto almSetting = mockAlmSetting(dbSession);
112 DevOpsProjectCreator devOpsProjectCreator = mockDevOpsProjectCreator(almSetting);
114 ComponentCreationData componentCreationData = mockProjectCreation(devOpsProjectCreator, dbSession);
116 ProjectDto projectDto = mockProjectDto(componentCreationData);
117 when(componentCreationData.mainBranchDto()).thenReturn(mock(BranchDto.class));
119 ProjectAlmSettingDto projectAlmSettingDto = mockProjectAlmSetting(dbSession, projectDto);
121 ImportProjectRequest request = new ImportProjectRequest(PROJECT_KEY, PROJECT_NAME, ALM_SETTING_ID, DOP_REPOSITORY_ID, DOP_PROJECT_ID, null, null, true);
123 ImportedProject importedProject = importProjectService.importProject(request);
125 assertThat(importedProject.projectDto()).isEqualTo(projectDto);
126 assertThat(importedProject.projectAlmSettingDto()).isEqualTo(projectAlmSettingDto);
128 verify(componentUpdater).commitAndIndex(dbSession, componentCreationData);
132 void createImportedProject_whenAlmIsSupportedAndNewCodeDefinitionDefined_shouldCreateProjectAndNewCodeDefinition() {
133 userSession.logIn().addPermission(PROVISION_PROJECTS);
134 DbSession dbSession = mockDbSession();
135 AlmSettingDto almSetting = mockAlmSetting(dbSession);
137 DevOpsProjectCreator devOpsProjectCreator = mockDevOpsProjectCreator(almSetting);
139 ComponentCreationData componentCreationData = mockProjectCreation(devOpsProjectCreator, dbSession);
141 ProjectDto projectDto = mockProjectDto(componentCreationData);
142 mockBranchDto(componentCreationData);
144 ProjectAlmSettingDto projectAlmSettingDto = mockProjectAlmSetting(dbSession, projectDto);
146 ImportProjectRequest request = new ImportProjectRequest(PROJECT_KEY, PROJECT_NAME, ALM_SETTING_ID, DOP_REPOSITORY_ID, DOP_PROJECT_ID, "NUMBER_OF_DAYS", "10", true);
148 ImportedProject importedProject = importProjectService.importProject(request);
150 assertThat(importedProject.projectDto()).isEqualTo(projectDto);
151 assertThat(importedProject.projectAlmSettingDto()).isEqualTo(projectAlmSettingDto);
153 verify(newCodeDefinitionResolver).createNewCodeDefinition(
160 verify(componentUpdater).commitAndIndex(dbSession, componentCreationData);
163 private DbSession mockDbSession() {
164 DbSession dbSession = mock(DbSession.class);
165 when(dbClient.openSession(false)).thenReturn(dbSession);
169 private AlmSettingDto mockAlmSetting(DbSession dbSession) {
170 AlmSettingDto almSetting = mock(AlmSettingDto.class);
171 when(almSetting.getAlm()).thenReturn(ALM.GITHUB);
172 when(almSetting.getUrl()).thenReturn(API_URL);
173 when(dbClient.almSettingDao().selectByUuid(dbSession, ALM_SETTING_ID)).thenReturn(Optional.of(almSetting));
177 private DevOpsProjectCreator mockDevOpsProjectCreator(AlmSettingDto almSetting) {
178 DevOpsProjectCreator devOpsProjectCreator = mock(DevOpsProjectCreator.class);
179 DevOpsProjectDescriptor projectDescriptor = new DevOpsProjectDescriptor(ALM.GITHUB, API_URL, DOP_REPOSITORY_ID, DOP_PROJECT_ID);
180 when(devOpsProjectCreatorFactory.getDevOpsProjectCreator(almSetting, projectDescriptor))
181 .thenReturn(Optional.of(devOpsProjectCreator));
182 return devOpsProjectCreator;
185 private static ComponentCreationData mockProjectCreation(DevOpsProjectCreator devOpsProjectCreator, DbSession dbSession) {
186 ComponentCreationData componentCreationData = mock(ComponentCreationData.class);
187 when(devOpsProjectCreator.createProjectAndBindToDevOpsPlatform(eq(dbSession), any(), eq(true), eq(PROJECT_KEY), eq(PROJECT_NAME)))
188 .thenReturn(componentCreationData);
189 return componentCreationData;
192 private static ProjectDto mockProjectDto(ComponentCreationData componentCreationData) {
193 ProjectDto projectDto = mock(ProjectDto.class);
194 lenient().when(projectDto.getUuid()).thenReturn(PROJECT_UUID);
195 when(componentCreationData.projectDto()).thenReturn(projectDto);
199 private static void mockBranchDto(ComponentCreationData componentCreationData) {
200 BranchDto mainBrainDto = mock(BranchDto.class);
201 when(mainBrainDto.getUuid()).thenReturn(MAIN_BRANCH_UUID);
202 when(mainBrainDto.getKey()).thenReturn(MAIN_BRANCH_KEY);
203 when(componentCreationData.mainBranchDto()).thenReturn(mainBrainDto);
206 private ProjectAlmSettingDto mockProjectAlmSetting(DbSession dbSession, ProjectDto projectDto) {
207 ProjectAlmSettingDto projectAlmSetting = mock(ProjectAlmSettingDto.class);
208 when(dbClient.projectAlmSettingDao().selectByProject(dbSession, projectDto))
209 .thenReturn(Optional.of(projectAlmSetting));
210 return projectAlmSetting;