aboutsummaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
authorJulien Lancelot <julien.lancelot@sonarsource.com>2017-01-19 13:19:25 +0100
committerJulien Lancelot <julien.lancelot@sonarsource.com>2017-01-24 18:36:49 +0100
commit528c2312512686dba2dd9cf4dda4d38a184c56a2 (patch)
tree7e0482f4225311b1327cb14b1b13d2cd7242e273 /server
parent4795b2a1d9de7ac2b5e010565928000a45bad32e (diff)
downloadsonarqube-528c2312512686dba2dd9cf4dda4d38a184c56a2.tar.gz
sonarqube-528c2312512686dba2dd9cf4dda4d38a184c56a2.zip
SONAR-7299 Replace Ruby WS api/projects/create by java
Diffstat (limited to 'server')
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/component/ComponentService.java2
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/computation/queue/ReportSubmitter.java3
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/project/ws/CreateAction.java141
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/project/ws/ProjectsWs.java33
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/project/ws/ProjectsWsModule.java1
-rw-r--r--server/sonar-server/src/main/resources/org/sonar/server/project/ws/create-example.json7
-rw-r--r--server/sonar-server/src/main/resources/org/sonar/server/project/ws/projects-example-create.json8
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/i18n/I18nRule.java20
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/project/ws/CreateActionTest.java322
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/project/ws/ProjectsWsModuleTest.java2
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/project/ws/ProjectsWsTest.java13
11 files changed, 497 insertions, 55 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/component/ComponentService.java b/server/sonar-server/src/main/java/org/sonar/server/component/ComponentService.java
index 2fb921e6525..f525fb70326 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/component/ComponentService.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/component/ComponentService.java
@@ -35,7 +35,6 @@ import org.sonar.api.server.ServerSide;
import org.sonar.api.utils.System2;
import org.sonar.api.web.UserRole;
import org.sonar.core.component.ComponentKeys;
-import org.sonar.core.permission.GlobalPermissions;
import org.sonar.core.util.Uuids;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
@@ -89,7 +88,6 @@ public class ComponentService {
// Used by SQ and Governance
public ComponentDto create(DbSession session, NewComponent newComponent) {
- userSession.checkPermission(GlobalPermissions.PROVISIONING);
checkKeyFormat(newComponent.qualifier(), newComponent.key());
ComponentDto rootComponent = createRootComponent(session, newComponent);
removeDuplicatedProjects(session, rootComponent.getKey());
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/queue/ReportSubmitter.java b/server/sonar-server/src/main/java/org/sonar/server/computation/queue/ReportSubmitter.java
index 9adc1b4d766..e5660d58d88 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/computation/queue/ReportSubmitter.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/computation/queue/ReportSubmitter.java
@@ -43,6 +43,7 @@ import org.sonar.server.user.UserSession;
import static com.google.common.base.Preconditions.checkArgument;
import static java.lang.String.format;
+import static org.sonar.core.permission.GlobalPermissions.PROVISIONING;
import static org.sonar.core.permission.GlobalPermissions.SCAN_EXECUTION;
import static org.sonar.server.component.NewComponent.newComponentBuilder;
import static org.sonar.server.user.AbstractUserSession.insufficientPrivilegesException;
@@ -97,6 +98,7 @@ public class ReportSubmitter {
}
private ComponentDto createProject(DbSession dbSession, String organizationUuid, String projectKey, @Nullable String projectBranch, @Nullable String projectName) {
+ userSession.checkPermission(PROVISIONING);
Integer userId = userSession.getUserId();
Long projectCreatorUserId = userId == null ? null : userId.longValue();
@@ -113,7 +115,6 @@ public class ReportSubmitter {
.setBranch(projectBranch)
.setQualifier(Qualifiers.PROJECT)
.build();
- // "provisioning" permission is check in ComponentService
ComponentDto project = componentService.create(dbSession, newProject);
if (permissionTemplateService.hasDefaultTemplateWithPermissionOnProjectCreator(dbSession, organizationUuid, project)) {
favoriteUpdater.add(dbSession, project);
diff --git a/server/sonar-server/src/main/java/org/sonar/server/project/ws/CreateAction.java b/server/sonar-server/src/main/java/org/sonar/server/project/ws/CreateAction.java
new file mode 100644
index 00000000000..6ec82adcc0f
--- /dev/null
+++ b/server/sonar-server/src/main/java/org/sonar/server/project/ws/CreateAction.java
@@ -0,0 +1,141 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.project.ws;
+
+import org.sonar.api.server.ws.Request;
+import org.sonar.api.server.ws.Response;
+import org.sonar.api.server.ws.WebService;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
+import org.sonar.db.component.ComponentDto;
+import org.sonar.server.component.ComponentService;
+import org.sonar.server.favorite.FavoriteUpdater;
+import org.sonar.server.organization.DefaultOrganizationProvider;
+import org.sonar.server.permission.PermissionTemplateService;
+import org.sonar.server.user.UserSession;
+import org.sonarqube.ws.WsProjects.CreateWsResponse;
+import org.sonarqube.ws.client.project.CreateRequest;
+
+import static org.sonar.api.resources.Qualifiers.PROJECT;
+import static org.sonar.core.permission.GlobalPermissions.PROVISIONING;
+import static org.sonar.server.component.NewComponent.newComponentBuilder;
+import static org.sonar.server.ws.KeyExamples.KEY_PROJECT_EXAMPLE_001;
+import static org.sonar.server.ws.WsUtils.writeProtobuf;
+import static org.sonarqube.ws.client.project.ProjectsWsParameters.ACTION_CREATE;
+import static org.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_BRANCH;
+import static org.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_NAME;
+import static org.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_PROJECT;
+
+public class CreateAction implements ProjectsWsAction {
+
+ public static final String DEPRECATED_PARAM_KEY = "key";
+
+ private final DbClient dbClient;
+ private final UserSession userSession;
+ private final ComponentService componentService;
+ private final DefaultOrganizationProvider defaultOrganizationProvider;
+ private final PermissionTemplateService permissionTemplateService;
+ private final FavoriteUpdater favoriteUpdater;
+
+ public CreateAction(DbClient dbClient, UserSession userSession, ComponentService componentService, PermissionTemplateService permissionTemplateService,
+ FavoriteUpdater favoriteUpdater, DefaultOrganizationProvider defaultOrganizationProvider) {
+ this.dbClient = dbClient;
+ this.userSession = userSession;
+ this.componentService = componentService;
+ this.permissionTemplateService = permissionTemplateService;
+ this.favoriteUpdater = favoriteUpdater;
+ this.defaultOrganizationProvider = defaultOrganizationProvider;
+ }
+
+ @Override
+ public void define(WebService.NewController context) {
+ WebService.NewAction action = context.createAction(ACTION_CREATE)
+ .setDescription("Create a project.<br/>" +
+ "Requires 'Create Projects' permission<br/>" +
+ "Since 6.3, the response has been updated and does not contain the database ID anymore")
+ .setSince("4.0")
+ .setPost(true)
+ .setResponseExample(getClass().getResource("create-example.json"))
+ .setHandler(this);
+
+ action.createParam(PARAM_PROJECT)
+ .setDescription("Key of the project")
+ .setDeprecatedKey(DEPRECATED_PARAM_KEY)
+ .setRequired(true)
+ .setExampleValue(KEY_PROJECT_EXAMPLE_001);
+
+ action.createParam(PARAM_NAME)
+ .setDescription("Name of the project")
+ .setRequired(true)
+ .setExampleValue("SonarQube");
+
+ action.createParam(PARAM_BRANCH)
+ .setDescription("SCM Branch of the project. The key of the project will become key:branch, for instance 'SonarQube:branch-5.0'")
+ .setExampleValue("branch-5.0");
+ }
+
+ @Override
+ public void handle(Request request, Response response) throws Exception {
+ userSession.checkPermission(PROVISIONING);
+ CreateRequest createRequest = toCreateRequest(request);
+ writeProtobuf(doHandle(createRequest), request, response);
+ }
+
+ private CreateWsResponse doHandle(CreateRequest request) {
+ String organizationUuid = defaultOrganizationProvider.get().getUuid();
+ try (DbSession dbSession = dbClient.openSession(false)) {
+ ComponentDto componentDto = componentService.create(dbSession, newComponentBuilder()
+ .setOrganizationUuid(organizationUuid)
+ .setKey(request.getKey())
+ .setName(request.getName())
+ .setBranch(request.getBranch())
+ .setQualifier(PROJECT)
+ .build());
+ handlePermissionTemplate(dbSession, componentDto, organizationUuid);
+ return toCreateResponse(componentDto);
+ }
+ }
+
+ private void handlePermissionTemplate(DbSession dbSession, ComponentDto componentDto, String organizationUuid) {
+ permissionTemplateService.applyDefault(dbSession, organizationUuid, componentDto, userSession.isLoggedIn() ? userSession.getUserId().longValue() : null);
+ if (permissionTemplateService.hasDefaultTemplateWithPermissionOnProjectCreator(dbSession, organizationUuid, componentDto)) {
+ favoriteUpdater.add(dbSession, componentDto);
+ dbSession.commit();
+ }
+ }
+
+ private static CreateRequest toCreateRequest(Request request) {
+ return CreateRequest.builder()
+ .setKey(request.mandatoryParam(PARAM_PROJECT))
+ .setName(request.mandatoryParam(PARAM_NAME))
+ .setBranch(request.param(PARAM_BRANCH))
+ .build();
+ }
+
+ private static CreateWsResponse toCreateResponse(ComponentDto componentDto) {
+ return CreateWsResponse.newBuilder()
+ .setProject(CreateWsResponse.Project.newBuilder()
+ .setKey(componentDto.key())
+ .setName(componentDto.name())
+ .setQualifier(componentDto.qualifier()))
+ .build();
+ }
+
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/project/ws/ProjectsWs.java b/server/sonar-server/src/main/java/org/sonar/server/project/ws/ProjectsWs.java
index 8a06da7d277..e6a42102996 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/project/ws/ProjectsWs.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/project/ws/ProjectsWs.java
@@ -20,6 +20,7 @@
package org.sonar.server.project.ws;
import com.google.common.io.Resources;
+import java.util.Arrays;
import org.sonar.api.server.ws.RailsHandler;
import org.sonar.api.server.ws.WebService;
@@ -43,12 +44,7 @@ public class ProjectsWs implements WebService {
.setDescription("Manage project existence.");
defineIndexAction(controller);
- defineCreateAction(controller);
-
- for (ProjectsWsAction action : actions) {
- action.define(controller);
- }
-
+ Arrays.stream(actions).forEach(action -> action.define(controller));
controller.done();
}
@@ -95,29 +91,4 @@ public class ProjectsWs implements WebService {
RailsHandler.addFormatParam(action);
}
- private void defineCreateAction(NewController controller) {
- WebService.NewAction action = controller.createAction("create")
- .setDescription("Create a project. Requires Create Projects permission")
- .setSince("4.0")
- .setPost(true)
- .setHandler(RailsHandler.INSTANCE)
- .setResponseExample(Resources.getResource(this.getClass(), "projects-example-create.json"));
-
- action.createParam("key")
- .setDescription("Key of the project")
- .setRequired(true)
- .setExampleValue(KEY_PROJECT_EXAMPLE_001);
-
- action.createParam("name")
- .setDescription("Name of the project")
- .setRequired(true)
- .setExampleValue("SonarQube");
-
- action.createParam("branch")
- .setDescription("SCM Branch of the project. The key of the project will become key:branch, for instance 'SonarQube:branch-5.0'")
- .setRequired(false)
- .setExampleValue("branch-5.0");
-
- RailsHandler.addFormatParam(action);
- }
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/project/ws/ProjectsWsModule.java b/server/sonar-server/src/main/java/org/sonar/server/project/ws/ProjectsWsModule.java
index 782b619bd9a..e3e5138bf55 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/project/ws/ProjectsWsModule.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/project/ws/ProjectsWsModule.java
@@ -26,6 +26,7 @@ public class ProjectsWsModule extends Module {
protected void configureModule() {
add(
ProjectsWs.class,
+ CreateAction.class,
BulkDeleteAction.class,
DeleteAction.class,
GhostsAction.class,
diff --git a/server/sonar-server/src/main/resources/org/sonar/server/project/ws/create-example.json b/server/sonar-server/src/main/resources/org/sonar/server/project/ws/create-example.json
new file mode 100644
index 00000000000..077da7925c5
--- /dev/null
+++ b/server/sonar-server/src/main/resources/org/sonar/server/project/ws/create-example.json
@@ -0,0 +1,7 @@
+{
+ "project": {
+ "key": "project-key",
+ "name": "project-name",
+ "qualifier": "TRK"
+ }
+}
diff --git a/server/sonar-server/src/main/resources/org/sonar/server/project/ws/projects-example-create.json b/server/sonar-server/src/main/resources/org/sonar/server/project/ws/projects-example-create.json
deleted file mode 100644
index 043c4bb391d..00000000000
--- a/server/sonar-server/src/main/resources/org/sonar/server/project/ws/projects-example-create.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "id": "30057",
- "k": "org.jenkins-ci.plugins:sonar",
- "nm": "Jenkins Sonar Plugin",
- "sc": "PRJ",
- "qu": "TRK"
-}
-
diff --git a/server/sonar-server/src/test/java/org/sonar/server/i18n/I18nRule.java b/server/sonar-server/src/test/java/org/sonar/server/i18n/I18nRule.java
index 5d2218620e2..eb6c4c01fbb 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/i18n/I18nRule.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/i18n/I18nRule.java
@@ -26,9 +26,12 @@ import java.util.Locale;
import java.util.Map;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
import org.sonar.api.i18n.I18n;
-public class I18nRule implements I18n {
+public class I18nRule implements TestRule, I18n {
private final Map<String, String> messages = new HashMap<>();
public I18nRule put(String key, String value) {
@@ -36,6 +39,20 @@ public class I18nRule implements I18n {
return this;
}
+ @Override
+ public Statement apply(final Statement statement, Description description) {
+ return new Statement() {
+ @Override
+ public void evaluate() throws Throwable {
+ try {
+ statement.evaluate();
+ } finally {
+ messages.clear();
+ }
+ }
+ };
+ }
+
public void setProjectPermissions() {
put("projects_role.admin", "Administer");
put("projects_role.admin.desc", "Ability to access project settings and perform administration tasks. " +
@@ -101,4 +118,5 @@ public class I18nRule implements I18n {
public String formatInteger(Locale locale, Integer value) {
return String.valueOf(value);
}
+
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/project/ws/CreateActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/project/ws/CreateActionTest.java
index e69de29bb2d..541ad2afdb3 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/project/ws/CreateActionTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/project/ws/CreateActionTest.java
@@ -0,0 +1,322 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonar.server.project.ws;
+
+import com.google.common.base.Throwables;
+import java.io.IOException;
+import org.assertj.core.api.Assertions;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.api.config.MapSettings;
+import org.sonar.api.config.Settings;
+import org.sonar.api.server.ws.WebService;
+import org.sonar.api.utils.System2;
+import org.sonar.db.DbTester;
+import org.sonar.db.component.ComponentDto;
+import org.sonar.db.component.ComponentTesting;
+import org.sonar.db.permission.template.PermissionTemplateDto;
+import org.sonar.db.user.UserDto;
+import org.sonar.server.component.ComponentService;
+import org.sonar.server.component.index.ComponentIndexDefinition;
+import org.sonar.server.component.index.ComponentIndexer;
+import org.sonar.server.es.EsTester;
+import org.sonar.server.exceptions.BadRequestException;
+import org.sonar.server.exceptions.ForbiddenException;
+import org.sonar.server.favorite.FavoriteUpdater;
+import org.sonar.server.i18n.I18nRule;
+import org.sonar.server.measure.index.ProjectMeasuresIndexDefinition;
+import org.sonar.server.measure.index.ProjectMeasuresIndexer;
+import org.sonar.server.organization.DefaultOrganizationProvider;
+import org.sonar.server.organization.TestDefaultOrganizationProvider;
+import org.sonar.server.permission.PermissionTemplateService;
+import org.sonar.server.permission.index.PermissionIndexer;
+import org.sonar.server.tester.UserSessionRule;
+import org.sonar.server.ws.TestRequest;
+import org.sonar.server.ws.WsActionTester;
+import org.sonarqube.ws.MediaTypes;
+import org.sonarqube.ws.WsProjects.CreateWsResponse;
+import org.sonarqube.ws.client.project.CreateRequest;
+
+import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat;
+import static org.sonar.api.web.UserRole.USER;
+import static org.sonar.core.permission.GlobalPermissions.PROVISIONING;
+import static org.sonar.core.permission.GlobalPermissions.QUALITY_GATE_ADMIN;
+import static org.sonar.core.util.Protobuf.setNullable;
+import static org.sonar.server.component.index.ComponentIndexDefinition.INDEX_COMPONENTS;
+import static org.sonar.server.component.index.ComponentIndexDefinition.TYPE_COMPONENT;
+import static org.sonar.server.measure.index.ProjectMeasuresIndexDefinition.INDEX_PROJECT_MEASURES;
+import static org.sonar.server.measure.index.ProjectMeasuresIndexDefinition.TYPE_PROJECT_MEASURE;
+import static org.sonar.test.JsonAssert.assertJson;
+import static org.sonarqube.ws.client.WsRequest.Method.POST;
+import static org.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_NAME;
+
+public class CreateActionTest {
+
+ private static final String DEFAULT_PROJECT_KEY = "project-key";
+ private static final String DEFAULT_PROJECT_NAME = "project-name";
+
+ private System2 system2 = System2.INSTANCE;
+
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+
+ @Rule
+ public DbTester db = DbTester.create(system2);
+
+ @Rule
+ public EsTester es = new EsTester(new ComponentIndexDefinition(new MapSettings()), new ProjectMeasuresIndexDefinition(new MapSettings()));
+
+ @Rule
+ public UserSessionRule userSession = UserSessionRule.standalone();
+
+ @Rule
+ public I18nRule i18n = new I18nRule().put("qualifier.TRK", "Project");
+
+ private Settings settings = new MapSettings();
+
+ private DefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(db);
+
+ private PermissionTemplateDto permissionTemplateDto;
+
+ private WsActionTester ws = new WsActionTester(
+ new CreateAction(
+ db.getDbClient(), userSession,
+ new ComponentService(db.getDbClient(), i18n, userSession, system2,
+ new ProjectMeasuresIndexer(system2, db.getDbClient(), es.client()),
+ new ComponentIndexer(db.getDbClient(), es.client())),
+ new PermissionTemplateService(db.getDbClient(), settings, new PermissionIndexer(db.getDbClient(), es.client()), userSession),
+ new FavoriteUpdater(db.getDbClient(), userSession),
+ defaultOrganizationProvider));
+
+ @Before
+ public void setUp() throws Exception {
+ permissionTemplateDto = db.permissionTemplates().insertTemplate();
+ setTemplateAsDefault(permissionTemplateDto);
+ }
+
+ @Test
+ public void create_project() throws Exception {
+ userSession.setGlobalPermissions(PROVISIONING);
+
+ CreateWsResponse response = call(CreateRequest.builder()
+ .setKey(DEFAULT_PROJECT_KEY)
+ .setName(DEFAULT_PROJECT_NAME)
+ .build());
+
+ assertThat(response.getProject().getKey()).isEqualTo(DEFAULT_PROJECT_KEY);
+ assertThat(response.getProject().getName()).isEqualTo(DEFAULT_PROJECT_NAME);
+ assertThat(response.getProject().getQualifier()).isEqualTo("TRK");
+ ComponentDto project = db.getDbClient().componentDao().selectOrFailByKey(db.getSession(), DEFAULT_PROJECT_KEY);
+ assertThat(project.getKey()).isEqualTo(DEFAULT_PROJECT_KEY);
+ assertThat(project.name()).isEqualTo(DEFAULT_PROJECT_NAME);
+ assertThat(project.qualifier()).isEqualTo("TRK");
+ }
+
+ @Test
+ public void create_project_with_branch() throws Exception {
+ userSession.setGlobalPermissions(PROVISIONING);
+
+ CreateWsResponse response = call(CreateRequest.builder()
+ .setKey(DEFAULT_PROJECT_KEY)
+ .setName(DEFAULT_PROJECT_NAME)
+ .setBranch("origin/master")
+ .build());
+
+ assertThat(response.getProject().getKey()).isEqualTo("project-key:origin/master");
+ }
+
+ @Test
+ public void verify_permission_template_is_applied() throws Exception {
+ UserDto userDto = db.users().insertUser();
+ userSession.login(userDto).setGlobalPermissions(PROVISIONING);
+ db.permissionTemplates().addUserToTemplate(permissionTemplateDto.getId(), userDto.getId(), USER);
+
+ call(CreateRequest.builder()
+ .setKey(DEFAULT_PROJECT_KEY)
+ .setName(DEFAULT_PROJECT_NAME)
+ .build());
+
+ ComponentDto project = db.getDbClient().componentDao().selectOrFailByKey(db.getSession(), DEFAULT_PROJECT_KEY);
+ assertThat(db.users().selectProjectPermissionsOfUser(userDto, project)).containsOnly(USER);
+ }
+
+ @Test
+ public void add_project_to_favorite_when_logged() throws Exception {
+ UserDto userDto = db.users().insertUser();
+ userSession.login(userDto).setGlobalPermissions(PROVISIONING);
+ db.permissionTemplates().addProjectCreatorToTemplate(permissionTemplateDto.getId(), USER);
+
+ call(CreateRequest.builder()
+ .setKey(DEFAULT_PROJECT_KEY)
+ .setName(DEFAULT_PROJECT_NAME)
+ .build());
+
+ ComponentDto project = db.getDbClient().componentDao().selectOrFailByKey(db.getSession(), DEFAULT_PROJECT_KEY);
+ assertThat(db.favorites().hasFavorite(project, userDto.getId())).isTrue();
+ }
+
+ @Test
+ public void does_not_add_project_to_favorite_when_not_logged() throws Exception {
+ userSession.setGlobalPermissions(PROVISIONING);
+ db.permissionTemplates().addProjectCreatorToTemplate(permissionTemplateDto.getId(), USER);
+
+ call(CreateRequest.builder()
+ .setKey(DEFAULT_PROJECT_KEY)
+ .setName(DEFAULT_PROJECT_NAME)
+ .build());
+
+ ComponentDto project = db.getDbClient().componentDao().selectOrFailByKey(db.getSession(), DEFAULT_PROJECT_KEY);
+ assertThat(db.favorites().hasNoFavorite(project)).isTrue();
+ }
+
+ @Test
+ public void does_not_add_project_to_favorite_when_project_create_has_no_permission_on_template() throws Exception {
+ UserDto userDto = db.users().insertUser();
+ userSession.login(userDto).setGlobalPermissions(PROVISIONING);
+
+ call(CreateRequest.builder()
+ .setKey(DEFAULT_PROJECT_KEY)
+ .setName(DEFAULT_PROJECT_NAME)
+ .build());
+
+ ComponentDto project = db.getDbClient().componentDao().selectOrFailByKey(db.getSession(), DEFAULT_PROJECT_KEY);
+ assertThat(db.favorites().hasNoFavorite(project)).isTrue();
+ }
+
+ @Test
+ public void verify_project_exists_in_es_indexes() throws Exception {
+ userSession.setGlobalPermissions(PROVISIONING);
+
+ call(CreateRequest.builder()
+ .setKey(DEFAULT_PROJECT_KEY)
+ .setName(DEFAULT_PROJECT_NAME)
+ .build());
+
+ ComponentDto project = db.getDbClient().componentDao().selectOrFailByKey(db.getSession(), DEFAULT_PROJECT_KEY);
+ assertThat(es.getIds(INDEX_COMPONENTS, TYPE_COMPONENT)).containsOnly(project.uuid());
+ assertThat(es.getIds(INDEX_PROJECT_MEASURES, TYPE_PROJECT_MEASURE)).containsOnly(project.uuid());
+ }
+
+ @Test
+ public void create_project_with_deprecated_parameter() throws Exception {
+ userSession.setGlobalPermissions(PROVISIONING);
+
+ ws.newRequest()
+ .setMethod(POST.name())
+ .setParam("key", DEFAULT_PROJECT_KEY)
+ .setParam(PARAM_NAME, DEFAULT_PROJECT_NAME)
+ .execute();
+
+ assertThat(db.getDbClient().componentDao().selectByKey(db.getSession(), DEFAULT_PROJECT_KEY).isPresent()).isTrue();
+ }
+
+ @Test
+ public void fail_when_project_already_exists() throws Exception {
+ userSession.setGlobalPermissions(PROVISIONING);
+ db.components().insertComponent(ComponentTesting.newProjectDto(db.getDefaultOrganization()).setKey(DEFAULT_PROJECT_KEY));
+ expectedException.expect(BadRequestException.class);
+ expectedException.expectMessage("Could not create Project, key already exists: project-key");
+
+ call(CreateRequest.builder()
+ .setKey(DEFAULT_PROJECT_KEY)
+ .setName(DEFAULT_PROJECT_NAME)
+ .build());
+ }
+
+ @Test
+ public void fail_when_missing_project_parameter() throws Exception {
+ userSession.setGlobalPermissions(PROVISIONING);
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("The 'project' parameter is missing");
+
+ call(CreateRequest.builder().setName(DEFAULT_PROJECT_NAME).build());
+ }
+
+ @Test
+ public void fail_when_missing_name_parameter() throws Exception {
+ userSession.setGlobalPermissions(PROVISIONING);
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("The 'name' parameter is missing");
+
+ call(CreateRequest.builder().setKey(DEFAULT_PROJECT_KEY).build());
+ }
+
+ @Test
+ public void fail_when_key_has_bad_format() throws Exception {
+ userSession.setGlobalPermissions(PROVISIONING);
+ expectedException.expect(BadRequestException.class);
+ expectedException.expectMessage("Malformed key for Project: 1234");
+
+ call(CreateRequest.builder().setKey("1234").setName(DEFAULT_PROJECT_NAME).build());
+ }
+
+ @Test
+ public void fail_when_missing_create_project_permission() throws Exception {
+ userSession.setGlobalPermissions(QUALITY_GATE_ADMIN);
+ expectedException.expect(ForbiddenException.class);
+
+ call(CreateRequest.builder().setKey(DEFAULT_PROJECT_KEY).setName(DEFAULT_PROJECT_NAME).build());
+ }
+
+ @Test
+ public void test_example() {
+ userSession.setGlobalPermissions(PROVISIONING);
+
+ String result = ws.newRequest()
+ .setParam("key", DEFAULT_PROJECT_KEY)
+ .setParam("name", DEFAULT_PROJECT_NAME)
+ .execute().getInput();
+
+ assertJson(result).isSimilarTo(getClass().getResource("create-example.json"));
+ }
+
+ @Test
+ public void definition() {
+ WebService.Action definition = ws.getDef();
+
+ Assertions.assertThat(definition.key()).isEqualTo("create");
+ Assertions.assertThat(definition.since()).isEqualTo("4.0");
+ Assertions.assertThat(definition.isInternal()).isFalse();
+ Assertions.assertThat(definition.responseExampleAsString()).isNotEmpty();
+ Assertions.assertThat(definition.params()).hasSize(3);
+ }
+
+ private CreateWsResponse call(CreateRequest request) {
+ TestRequest httpRequest = ws.newRequest()
+ .setMethod(POST.name())
+ .setMediaType(MediaTypes.PROTOBUF);
+ setNullable(request.getKey(), e -> httpRequest.setParam("project", e));
+ setNullable(request.getName(), e -> httpRequest.setParam("name", e));
+ setNullable(request.getBranch(), e -> httpRequest.setParam("branch", e));
+ try {
+ return CreateWsResponse.parseFrom(httpRequest.execute().getInputStream());
+ } catch (IOException e) {
+ throw Throwables.propagate(e);
+ }
+ }
+
+ private void setTemplateAsDefault(PermissionTemplateDto permissionTemplateDto) {
+ settings.appendProperty("sonar.permission.template.default", permissionTemplateDto.getUuid());
+ }
+
+}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/project/ws/ProjectsWsModuleTest.java b/server/sonar-server/src/test/java/org/sonar/server/project/ws/ProjectsWsModuleTest.java
index f2cbc94baf4..c2a2dab4b74 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/project/ws/ProjectsWsModuleTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/project/ws/ProjectsWsModuleTest.java
@@ -29,6 +29,6 @@ public class ProjectsWsModuleTest {
public void verify_count_of_added_components() {
ComponentContainer container = new ComponentContainer();
new ProjectsWsModule().configure(container);
- assertThat(container.size()).isEqualTo(2 + 7);
+ assertThat(container.size()).isEqualTo(2 + 8);
}
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/project/ws/ProjectsWsTest.java b/server/sonar-server/src/test/java/org/sonar/server/project/ws/ProjectsWsTest.java
index fe2701d163b..214e9f176e4 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/project/ws/ProjectsWsTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/project/ws/ProjectsWsTest.java
@@ -41,8 +41,7 @@ public class ProjectsWsTest {
ws = new WsTester(new ProjectsWs(
new BulkDeleteAction(mock(ComponentCleanerService.class), mock(DbClient.class), mock(UserSession.class)),
new GhostsAction(mock(DbClient.class), mock(UserSession.class)),
- new ProvisionedAction(mock(DbClient.class), mock(UserSession.class))
- ));
+ new ProvisionedAction(mock(DbClient.class), mock(UserSession.class))));
controller = ws.controller("api/projects");
}
@@ -51,7 +50,7 @@ public class ProjectsWsTest {
assertThat(controller).isNotNull();
assertThat(controller.description()).isNotEmpty();
assertThat(controller.since()).isEqualTo("2.10");
- assertThat(controller.actions()).hasSize(5);
+ assertThat(controller.actions()).hasSize(4);
}
@Test
@@ -63,12 +62,4 @@ public class ProjectsWsTest {
assertThat(action.params()).hasSize(8);
}
- @Test
- public void define_create_action() {
- WebService.Action action = controller.action("create");
- assertThat(action).isNotNull();
- assertThat(action.handler()).isInstanceOf(RailsHandler.class);
- assertThat(action.responseExampleAsString()).isNotEmpty();
- assertThat(action.params()).hasSize(4);
- }
}