import it.analysisExclusion.FileExclusionsTest;
import it.analysisExclusion.IssueExclusionsTest;
import it.component.ComponentsWsTest;
-import it.component.ProjectSearchTest;
+import it.component.ProjectsWsTest;
import it.dbCleaner.PurgeTest;
import it.duplication.CrossProjectDuplicationsOnRemoveFileTest;
import it.duplication.CrossProjectDuplicationsTest;
BaseIdentityProviderTest.class,
OAuth2IdentityProviderTest.class,
// component search
- ProjectSearchTest.class,
+ ProjectsWsTest.class,
ComponentsWsTest.class,
// analysis exclusion
FileExclusionsTest.class,
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.sonarqube.ws.WsComponents;
-import org.sonarqube.ws.WsComponents.BulkUpdateKeyWsResponse.Key;
import org.sonarqube.ws.client.WsClient;
-import org.sonarqube.ws.client.component.BulkUpdateWsRequest;
import org.sonarqube.ws.client.component.SearchWsRequest;
import org.sonarqube.ws.client.component.ShowWsRequest;
-import org.sonarqube.ws.client.component.UpdateWsRequest;
import util.ItUtils;
import static java.util.Collections.singletonList;
@ClassRule
public static final Orchestrator orchestrator = Category4Suite.ORCHESTRATOR;
private static final String FILE_KEY = "sample:src/main/xoo/sample/Sample.xoo";
- private static final String PROJECT_KEY = "sample";
@Rule
public ExpectedException expectedException = ExpectedException.none();
assertThat(response).isNotNull();
assertThat(response.getComponents(0).getKey()).isEqualTo(FILE_KEY);
}
-
- @Test
- public void update_key() {
- String newProjectKey = "another_project_key";
- WsComponents.Component project = wsClient.components().show(new ShowWsRequest().setKey(PROJECT_KEY)).getComponent();
- assertThat(project.getKey()).isEqualTo(PROJECT_KEY);
-
- wsClient.components().updateKey(UpdateWsRequest.builder()
- .setKey(PROJECT_KEY)
- .setNewKey(newProjectKey)
- .build());
-
- assertThat(wsClient.components().show(new ShowWsRequest().setId(project.getId())).getComponent().getKey()).isEqualTo(newProjectKey);
- }
-
- @Test
- public void bulk_update_key() {
- String newProjectKey = "another_project_key";
- WsComponents.Component project = wsClient.components().show(new ShowWsRequest().setKey(PROJECT_KEY)).getComponent();
- assertThat(project.getKey()).isEqualTo(PROJECT_KEY);
-
- WsComponents.BulkUpdateKeyWsResponse result = wsClient.components().bulkUpdateKey(BulkUpdateWsRequest.builder()
- .setKey(PROJECT_KEY)
- .setFrom(PROJECT_KEY)
- .setTo(newProjectKey)
- .build());
-
- assertThat(wsClient.components().show(new ShowWsRequest().setId(project.getId())).getComponent().getKey()).isEqualTo(newProjectKey);
- assertThat(result.getKeysCount()).isEqualTo(1);
- assertThat(result.getKeys(0))
- .extracting(Key::getKey, Key::getNewKey, Key::getDuplicate)
- .containsOnlyOnce(PROJECT_KEY, newProjectKey, false);
- }
}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2017 SonarSource SA
- * mailto:info 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 it.component;
-
-import com.sonar.orchestrator.Orchestrator;
-import com.sonar.orchestrator.build.SonarScanner;
-import it.Category4Suite;
-import java.io.IOException;
-import org.apache.commons.io.IOUtils;
-import org.apache.http.HttpResponse;
-import org.apache.http.client.HttpClient;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.impl.client.DefaultHttpClient;
-import org.apache.http.util.EntityUtils;
-import org.junit.Before;
-import org.junit.ClassRule;
-import org.junit.Test;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static util.ItUtils.projectDir;
-
-public class ProjectSearchTest {
-
- @ClassRule
- public static final Orchestrator orchestrator = Category4Suite.ORCHESTRATOR;
-
- @Before
- public void inspectProject() {
- orchestrator.resetData();
- orchestrator.executeBuild(SonarScanner.create(projectDir("shared/xoo-sample")));
- }
-
- /**
- * SONAR-3105
- */
- @Test
- public void projects_web_service() throws IOException {
- SonarScanner build = SonarScanner.create(projectDir("shared/xoo-sample"));
- orchestrator.executeBuild(build);
-
- String url = orchestrator.getServer().getUrl() + "/api/projects/index?key=sample&versions=true";
- HttpClient httpclient = new DefaultHttpClient();
- try {
- HttpGet get = new HttpGet(url);
- HttpResponse response = httpclient.execute(get);
-
- assertThat(response.getStatusLine().getStatusCode()).isEqualTo(200);
- String content = IOUtils.toString(response.getEntity().getContent());
- assertThat(content).doesNotContain("error");
- assertThat(content).contains("sample");
- EntityUtils.consume(response.getEntity());
-
- } finally {
- httpclient.getConnectionManager().shutdown();
- }
- }
-}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info 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 it.component;
+
+import com.sonar.orchestrator.Orchestrator;
+import com.sonar.orchestrator.build.SonarScanner;
+import it.Category4Suite;
+import java.io.IOException;
+import org.apache.commons.io.IOUtils;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.util.EntityUtils;
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonarqube.ws.WsComponents;
+import org.sonarqube.ws.WsProjects.BulkUpdateKeyWsResponse;
+import org.sonarqube.ws.WsProjects.BulkUpdateKeyWsResponse.Key;
+import org.sonarqube.ws.client.WsClient;
+import org.sonarqube.ws.client.component.ShowWsRequest;
+import org.sonarqube.ws.client.project.BulkUpdateKeyWsRequest;
+import org.sonarqube.ws.client.project.UpdateKeyWsRequest;
+import util.ItUtils;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static util.ItUtils.projectDir;
+
+public class ProjectsWsTest {
+
+ @ClassRule
+ public static final Orchestrator orchestrator = Category4Suite.ORCHESTRATOR;
+ private static final String PROJECT_KEY = "sample";
+
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+
+ private WsClient wsClient;
+
+ @Before
+ public void inspectProject() {
+ orchestrator.resetData();
+ orchestrator.executeBuild(SonarScanner.create(projectDir("shared/xoo-sample")));
+
+ wsClient = ItUtils.newAdminWsClient(orchestrator);
+ }
+
+ /**
+ * SONAR-3105
+ */
+ @Test
+ public void projects_web_service() throws IOException {
+ SonarScanner build = SonarScanner.create(projectDir("shared/xoo-sample"));
+ orchestrator.executeBuild(build);
+
+ String url = orchestrator.getServer().getUrl() + "/api/projects/index?key=sample&versions=true";
+ HttpClient httpclient = new DefaultHttpClient();
+ try {
+ HttpGet get = new HttpGet(url);
+ HttpResponse response = httpclient.execute(get);
+
+ assertThat(response.getStatusLine().getStatusCode()).isEqualTo(200);
+ String content = IOUtils.toString(response.getEntity().getContent());
+ assertThat(content).doesNotContain("error");
+ assertThat(content).contains("sample");
+ EntityUtils.consume(response.getEntity());
+
+ } finally {
+ httpclient.getConnectionManager().shutdown();
+ }
+ }
+
+ @Test
+ public void update_key() {
+ String newProjectKey = "another_project_key";
+ WsComponents.Component project = wsClient.components().show(new ShowWsRequest().setKey(PROJECT_KEY)).getComponent();
+ assertThat(project.getKey()).isEqualTo(PROJECT_KEY);
+
+ wsClient.projects().updateKey(UpdateKeyWsRequest.builder()
+ .setKey(PROJECT_KEY)
+ .setNewKey(newProjectKey)
+ .build());
+
+ assertThat(wsClient.components().show(new ShowWsRequest().setId(project.getId())).getComponent().getKey()).isEqualTo(newProjectKey);
+ }
+
+ @Test
+ public void bulk_update_key() {
+ String newProjectKey = "another_project_key";
+ WsComponents.Component project = wsClient.components().show(new ShowWsRequest().setKey(PROJECT_KEY)).getComponent();
+ assertThat(project.getKey()).isEqualTo(PROJECT_KEY);
+
+ BulkUpdateKeyWsResponse result = wsClient.projects().bulkUpdateKey(BulkUpdateKeyWsRequest.builder()
+ .setKey(PROJECT_KEY)
+ .setFrom(PROJECT_KEY)
+ .setTo(newProjectKey)
+ .build());
+
+ assertThat(wsClient.components().show(new ShowWsRequest().setId(project.getId())).getComponent().getKey()).isEqualTo(newProjectKey);
+ assertThat(result.getKeysCount()).isEqualTo(1);
+ assertThat(result.getKeys(0))
+ .extracting(Key::getKey, Key::getNewKey, Key::getDuplicate)
+ .containsOnlyOnce(PROJECT_KEY, newProjectKey, false);
+ }
+}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2017 SonarSource SA
- * mailto:info 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.component.ws;
-
-import com.google.common.collect.ImmutableList;
-import java.util.Map;
-import org.sonar.api.server.ws.Request;
-import org.sonar.api.server.ws.Response;
-import org.sonar.api.server.ws.WebService;
-import org.sonar.api.web.UserRole;
-import org.sonar.db.DbClient;
-import org.sonar.db.DbSession;
-import org.sonar.db.component.ComponentDto;
-import org.sonar.db.component.ComponentKeyUpdaterDao;
-import org.sonar.server.component.ComponentFinder;
-import org.sonar.server.component.ComponentFinder.ParamNames;
-import org.sonar.server.component.ComponentService;
-import org.sonar.server.user.UserSession;
-import org.sonarqube.ws.WsComponents;
-import org.sonarqube.ws.WsComponents.BulkUpdateKeyWsResponse;
-import org.sonarqube.ws.client.component.BulkUpdateWsRequest;
-
-import static org.sonar.core.util.Uuids.UUID_EXAMPLE_01;
-import static org.sonar.db.component.ComponentKeyUpdaterDao.checkIsProjectOrModule;
-import static org.sonar.server.ws.WsUtils.checkRequest;
-import static org.sonar.server.ws.WsUtils.writeProtobuf;
-import static org.sonarqube.ws.client.component.ComponentsWsParameters.ACTION_BULK_UPDATE_KEY;
-import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_DRY_RUN;
-import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_FROM;
-import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_PROJECT;
-import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_PROJECT_ID;
-import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_TO;
-
-public class BulkUpdateKeyAction implements ComponentsWsAction {
- private final DbClient dbClient;
- private final ComponentFinder componentFinder;
- private final ComponentKeyUpdaterDao componentKeyUpdater;
- private final ComponentService componentService;
- private final UserSession userSession;
-
- public BulkUpdateKeyAction(DbClient dbClient, ComponentFinder componentFinder, ComponentService componentService, UserSession userSession) {
- this.dbClient = dbClient;
- this.componentKeyUpdater = dbClient.componentKeyUpdaterDao();
- this.componentFinder = componentFinder;
- this.componentService = componentService;
- this.userSession = userSession;
- }
-
- @Override
- public void define(WebService.NewController context) {
- WebService.NewAction action = context.createAction(ACTION_BULK_UPDATE_KEY)
- .setDescription("Bulk update a project or module key and all its sub-components keys. " +
- "The bulk update allows to replace a part of the current key by another string on the current project and all its sub-modules.<br>" +
- "It's possible to simulate the bulk update by setting the parameter '%s' at true. No key is updated with a dry run.<br>" +
- "Ex: to rename a project with key 'my_project' to 'my_new_project' and all its sub-components keys, call the WS with parameters:" +
- "<ul>" +
- " <li>%s: my_project</li>" +
- " <li>%s: my_</li>" +
- " <li>%s: my_new_</li>" +
- "</ul>" +
- "Either '%s' or '%s' must be provided, not both.<br> " +
- "Requires one of the following permissions: " +
- "<ul>" +
- "<li>'Administer System'</li>" +
- "<li>'Administer' rights on the specified project</li>" +
- "</ul>",
- PARAM_DRY_RUN,
- PARAM_PROJECT, PARAM_FROM, PARAM_TO,
- PARAM_PROJECT_ID, PARAM_PROJECT)
- .setSince("6.1")
- .setPost(true)
- .setResponseExample(getClass().getResource("bulk_update_key-example.json"))
- .setHandler(this);
-
- action.createParam(PARAM_PROJECT_ID)
- .setDescription("Project or module ID")
- .setDeprecatedKey("id", "6.4")
- .setExampleValue(UUID_EXAMPLE_01);
-
- action.createParam(PARAM_PROJECT)
- .setDescription("Project or module key")
- .setDeprecatedKey("key", "6.4")
- .setExampleValue("my_old_project");
-
- action.createParam(PARAM_FROM)
- .setDescription("String to match in components keys")
- .setRequired(true)
- .setExampleValue("_old");
-
- action.createParam(PARAM_TO)
- .setDescription("String replacement in components keys")
- .setRequired(true)
- .setExampleValue("_new");
-
- action.createParam(PARAM_DRY_RUN)
- .setDescription("Simulate bulk update. No component key is updated.")
- .setBooleanPossibleValues()
- .setDefaultValue(false);
- }
-
- @Override
- public void handle(Request request, Response response) throws Exception {
- writeProtobuf(doHandle(toWsRequest(request)), request, response);
- }
-
- private BulkUpdateKeyWsResponse doHandle(BulkUpdateWsRequest request) {
- DbSession dbSession = dbClient.openSession(false);
- try {
- ComponentDto projectOrModule = componentFinder.getByUuidOrKey(dbSession, request.getId(), request.getKey(), ParamNames.ID_AND_KEY);
- checkIsProjectOrModule(projectOrModule);
- userSession.checkComponentPermission(UserRole.ADMIN, projectOrModule);
-
- Map<String, String> newKeysByOldKeys = componentKeyUpdater.simulateBulkUpdateKey(dbSession, projectOrModule.uuid(), request.getFrom(), request.getTo());
- Map<String, Boolean> newKeysWithDuplicateMap = componentKeyUpdater.checkComponentKeys(dbSession, ImmutableList.copyOf(newKeysByOldKeys.values()));
-
- if (!request.isDryRun()) {
- checkNoDuplicate(newKeysWithDuplicateMap);
- bulkUpdateKey(dbSession, request, projectOrModule);
- }
-
- return buildResponse(newKeysByOldKeys, newKeysWithDuplicateMap);
- } finally {
- dbClient.closeSession(dbSession);
- }
- }
-
- private static void checkNoDuplicate(Map<String, Boolean> newKeysWithDuplicateMap) {
- newKeysWithDuplicateMap.entrySet().forEach(entry -> checkRequest(!entry.getValue(), "Impossible to update key: a component with key \"%s\" already exists.", entry.getKey()));
- }
-
- private void bulkUpdateKey(DbSession dbSession, BulkUpdateWsRequest request, ComponentDto projectOrModule) {
- componentService.bulkUpdateKey(dbSession, projectOrModule.uuid(), request.getFrom(), request.getTo());
- dbSession.commit();
- }
-
- private static BulkUpdateKeyWsResponse buildResponse(Map<String, String> newKeysByOldKeys, Map<String, Boolean> newKeysWithDuplicateMap) {
- WsComponents.BulkUpdateKeyWsResponse.Builder response = WsComponents.BulkUpdateKeyWsResponse.newBuilder();
-
- newKeysByOldKeys.entrySet().stream()
- // sort by old key
- .sorted((e1, e2) -> e1.getKey().compareTo(e2.getKey()))
- .forEach(
- entry -> {
- String newKey = entry.getValue();
- response.addKeysBuilder()
- .setKey(entry.getKey())
- .setNewKey(newKey)
- .setDuplicate(newKeysWithDuplicateMap.getOrDefault(newKey, false));
- });
-
- return response.build();
- }
-
- private static BulkUpdateWsRequest toWsRequest(Request request) {
- return BulkUpdateWsRequest.builder()
- .setId(request.param(PARAM_PROJECT_ID))
- .setKey(request.param(PARAM_PROJECT))
- .setFrom(request.mandatoryParam(PARAM_FROM))
- .setTo(request.mandatoryParam(PARAM_TO))
- .setDryRun(request.mandatoryParamAsBoolean(PARAM_DRY_RUN))
- .build();
- }
-}
SuggestionsAction.class,
TreeAction.class,
ShowAction.class,
- UpdateKeyAction.class,
- BulkUpdateKeyAction.class,
SearchProjectsAction.class,
ProjectMeasuresQueryValidator.class);
}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2017 SonarSource SA
- * mailto:info 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.component.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.ComponentFinder;
-import org.sonar.server.component.ComponentFinder.ParamNames;
-import org.sonar.server.component.ComponentService;
-import org.sonarqube.ws.client.component.UpdateWsRequest;
-
-import static org.sonar.core.util.Uuids.UUID_EXAMPLE_01;
-import static org.sonarqube.ws.client.component.ComponentsWsParameters.ACTION_UPDATE_KEY;
-import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_NEW_PROJECT;
-import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_PROJECT;
-import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_PROJECT_ID;
-
-public class UpdateKeyAction implements ComponentsWsAction {
- private final DbClient dbClient;
- private final ComponentFinder componentFinder;
- private final ComponentService componentService;
-
- public UpdateKeyAction(DbClient dbClient, ComponentFinder componentFinder, ComponentService componentService) {
- this.dbClient = dbClient;
- this.componentFinder = componentFinder;
- this.componentService = componentService;
- }
-
- @Override
- public void define(WebService.NewController context) {
- WebService.NewAction action = context.createAction(ACTION_UPDATE_KEY)
- .setDescription("Update a project or module key and all its sub-components keys.<br>" +
- "Either '%s' or '%s' must be provided, not both.<br> " +
- "Requires one of the following permissions: " +
- "<ul>" +
- "<li>'Administer System'</li>" +
- "<li>'Administer' rights on the specified project</li>" +
- "</ul>",
- PARAM_PROJECT, PARAM_PROJECT_ID)
- .setSince("6.1")
- .setPost(true)
- .setHandler(this);
-
- action.createParam(PARAM_PROJECT_ID)
- .setDescription("Project or module id")
- .setDeprecatedKey("id", "6.4")
- .setExampleValue(UUID_EXAMPLE_01);
-
- action.createParam(PARAM_PROJECT)
- .setDescription("Project or module key")
- .setDeprecatedKey("key", "6.4")
- .setExampleValue("my_old_project");
-
- action.createParam(PARAM_NEW_PROJECT)
- .setDescription("New component key")
- .setRequired(true)
- .setDeprecatedKey("newKey", "6.4")
- .setExampleValue("my_new_project");
- }
-
- @Override
- public void handle(Request request, Response response) throws Exception {
- doHandle(toWsRequest(request));
- response.noContent();
- }
-
- private void doHandle(UpdateWsRequest request) {
- DbSession dbSession = dbClient.openSession(false);
- try {
- ComponentDto projectOrModule = componentFinder.getByUuidOrKey(dbSession, request.getId(), request.getKey(), ParamNames.PROJECT_ID_AND_PROJECT);
- componentService.updateKey(dbSession, projectOrModule, request.getNewKey());
- dbSession.commit();
- } finally {
- dbClient.closeSession(dbSession);
- }
- }
-
- private static UpdateWsRequest toWsRequest(Request request) {
- return UpdateWsRequest.builder()
- .setId(request.param(PARAM_PROJECT_ID))
- .setKey(request.param(PARAM_PROJECT))
- .setNewKey(request.mandatoryParam(PARAM_NEW_PROJECT))
- .build();
- }
-}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info 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.collect.ImmutableList;
+import java.util.Comparator;
+import java.util.Map;
+import org.sonar.api.server.ws.Change;
+import org.sonar.api.server.ws.Request;
+import org.sonar.api.server.ws.Response;
+import org.sonar.api.server.ws.WebService;
+import org.sonar.api.web.UserRole;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
+import org.sonar.db.component.ComponentDto;
+import org.sonar.db.component.ComponentKeyUpdaterDao;
+import org.sonar.server.component.ComponentFinder;
+import org.sonar.server.component.ComponentFinder.ParamNames;
+import org.sonar.server.component.ComponentService;
+import org.sonar.server.user.UserSession;
+import org.sonarqube.ws.WsProjects.BulkUpdateKeyWsResponse;
+import org.sonarqube.ws.client.project.BulkUpdateKeyWsRequest;
+
+import static org.sonar.core.util.Uuids.UUID_EXAMPLE_01;
+import static org.sonar.db.component.ComponentKeyUpdaterDao.checkIsProjectOrModule;
+import static org.sonar.server.ws.WsUtils.checkRequest;
+import static org.sonar.server.ws.WsUtils.writeProtobuf;
+import static org.sonarqube.ws.client.project.ProjectsWsParameters.ACTION_BULK_UPDATE_KEY;
+import static org.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_DRY_RUN;
+import static org.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_FROM;
+import static org.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_PROJECT;
+import static org.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_PROJECT_ID;
+import static org.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_TO;
+
+public class BulkUpdateKeyAction implements ProjectsWsAction {
+ private final DbClient dbClient;
+ private final ComponentFinder componentFinder;
+ private final ComponentKeyUpdaterDao componentKeyUpdater;
+ private final ComponentService componentService;
+ private final UserSession userSession;
+
+ public BulkUpdateKeyAction(DbClient dbClient, ComponentFinder componentFinder, ComponentService componentService, UserSession userSession) {
+ this.dbClient = dbClient;
+ this.componentKeyUpdater = dbClient.componentKeyUpdaterDao();
+ this.componentFinder = componentFinder;
+ this.componentService = componentService;
+ this.userSession = userSession;
+ }
+
+ @Override
+ public void define(WebService.NewController context) {
+ doDefine(context);
+ }
+
+ public WebService.NewAction doDefine(WebService.NewController context) {
+ WebService.NewAction action = context.createAction(ACTION_BULK_UPDATE_KEY)
+ .setDescription("Bulk update a project or module key and all its sub-components keys. " +
+ "The bulk update allows to replace a part of the current key by another string on the current project and all its sub-modules.<br>" +
+ "It's possible to simulate the bulk update by setting the parameter '%s' at true. No key is updated with a dry run.<br>" +
+ "Ex: to rename a project with key 'my_project' to 'my_new_project' and all its sub-components keys, call the WS with parameters:" +
+ "<ul>" +
+ " <li>%s: my_project</li>" +
+ " <li>%s: my_</li>" +
+ " <li>%s: my_new_</li>" +
+ "</ul>" +
+ "Either '%s' or '%s' must be provided, not both.<br> " +
+ "Requires one of the following permissions: " +
+ "<ul>" +
+ "<li>'Administer System'</li>" +
+ "<li>'Administer' rights on the specified project</li>" +
+ "</ul>",
+ PARAM_DRY_RUN,
+ PARAM_PROJECT, PARAM_FROM, PARAM_TO,
+ PARAM_PROJECT_ID, PARAM_PROJECT)
+ .setSince("6.1")
+ .setPost(true)
+ .setResponseExample(getClass().getResource("bulk_update_key-example.json"))
+ .setHandler(this);
+
+ action.setChangelog(
+ new Change("6.4", "Moved from api/components/bulk_update_key to api/projects/bulk_update_key"));
+
+ action.createParam(PARAM_PROJECT_ID)
+ .setDescription("Project or module ID")
+ .setDeprecatedKey("id", "6.4")
+ .setExampleValue(UUID_EXAMPLE_01);
+
+ action.createParam(PARAM_PROJECT)
+ .setDescription("Project or module key")
+ .setDeprecatedKey("key", "6.4")
+ .setExampleValue("my_old_project");
+
+ action.createParam(PARAM_FROM)
+ .setDescription("String to match in components keys")
+ .setRequired(true)
+ .setExampleValue("_old");
+
+ action.createParam(PARAM_TO)
+ .setDescription("String replacement in components keys")
+ .setRequired(true)
+ .setExampleValue("_new");
+
+ action.createParam(PARAM_DRY_RUN)
+ .setDescription("Simulate bulk update. No component key is updated.")
+ .setBooleanPossibleValues()
+ .setDefaultValue(false);
+
+ return action;
+ }
+
+ @Override
+ public void handle(Request request, Response response) throws Exception {
+ writeProtobuf(doHandle(toWsRequest(request)), request, response);
+ }
+
+ private BulkUpdateKeyWsResponse doHandle(BulkUpdateKeyWsRequest request) {
+ DbSession dbSession = dbClient.openSession(false);
+ try {
+ ComponentDto projectOrModule = componentFinder.getByUuidOrKey(dbSession, request.getId(), request.getKey(), ParamNames.ID_AND_KEY);
+ checkIsProjectOrModule(projectOrModule);
+ userSession.checkComponentPermission(UserRole.ADMIN, projectOrModule);
+
+ Map<String, String> newKeysByOldKeys = componentKeyUpdater.simulateBulkUpdateKey(dbSession, projectOrModule.uuid(), request.getFrom(), request.getTo());
+ Map<String, Boolean> newKeysWithDuplicateMap = componentKeyUpdater.checkComponentKeys(dbSession, ImmutableList.copyOf(newKeysByOldKeys.values()));
+
+ if (!request.isDryRun()) {
+ checkNoDuplicate(newKeysWithDuplicateMap);
+ bulkUpdateKey(dbSession, request, projectOrModule);
+ }
+
+ return buildResponse(newKeysByOldKeys, newKeysWithDuplicateMap);
+ } finally {
+ dbClient.closeSession(dbSession);
+ }
+ }
+
+ private static void checkNoDuplicate(Map<String, Boolean> newKeysWithDuplicateMap) {
+ newKeysWithDuplicateMap.entrySet().forEach(entry -> checkRequest(!entry.getValue(), "Impossible to update key: a component with key \"%s\" already exists.", entry.getKey()));
+ }
+
+ private void bulkUpdateKey(DbSession dbSession, BulkUpdateKeyWsRequest request, ComponentDto projectOrModule) {
+ componentService.bulkUpdateKey(dbSession, projectOrModule.uuid(), request.getFrom(), request.getTo());
+ dbSession.commit();
+ }
+
+ private static BulkUpdateKeyWsResponse buildResponse(Map<String, String> newKeysByOldKeys, Map<String, Boolean> newKeysWithDuplicateMap) {
+ BulkUpdateKeyWsResponse.Builder response = BulkUpdateKeyWsResponse.newBuilder();
+
+ newKeysByOldKeys.entrySet().stream()
+ // sort by old key
+ .sorted(Comparator.comparing(Map.Entry::getKey))
+ .forEach(
+ entry -> {
+ String newKey = entry.getValue();
+ response.addKeysBuilder()
+ .setKey(entry.getKey())
+ .setNewKey(newKey)
+ .setDuplicate(newKeysWithDuplicateMap.getOrDefault(newKey, false));
+ });
+
+ return response.build();
+ }
+
+ private static BulkUpdateKeyWsRequest toWsRequest(Request request) {
+ return BulkUpdateKeyWsRequest.builder()
+ .setId(request.param(PARAM_PROJECT_ID))
+ .setKey(request.param(PARAM_PROJECT))
+ .setFrom(request.mandatoryParam(PARAM_FROM))
+ .setTo(request.mandatoryParam(PARAM_TO))
+ .setDryRun(request.mandatoryParamAsBoolean(PARAM_DRY_RUN))
+ .build();
+ }
+}
IndexAction.class,
BulkDeleteAction.class,
DeleteAction.class,
+ UpdateKeyAction.class,
+ BulkUpdateKeyAction.class,
GhostsAction.class,
ProvisionedAction.class,
SearchMyProjectsAction.class,
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info 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.Change;
+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.ComponentFinder;
+import org.sonar.server.component.ComponentFinder.ParamNames;
+import org.sonar.server.component.ComponentService;
+import org.sonarqube.ws.client.project.UpdateKeyWsRequest;
+
+import static org.sonar.core.util.Uuids.UUID_EXAMPLE_01;
+import static org.sonarqube.ws.client.project.ProjectsWsParameters.ACTION_UPDATE_KEY;
+import static org.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_NEW_PROJECT;
+import static org.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_PROJECT;
+import static org.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_PROJECT_ID;
+
+public class UpdateKeyAction implements ProjectsWsAction {
+ private final DbClient dbClient;
+ private final ComponentFinder componentFinder;
+ private final ComponentService componentService;
+
+ public UpdateKeyAction(DbClient dbClient, ComponentFinder componentFinder, ComponentService componentService) {
+ this.dbClient = dbClient;
+ this.componentFinder = componentFinder;
+ this.componentService = componentService;
+ }
+
+ @Override
+ public void define(WebService.NewController context) {
+ doDefine(context);
+ }
+
+ public WebService.NewAction doDefine(WebService.NewController context) {
+ WebService.NewAction action = context.createAction(ACTION_UPDATE_KEY)
+ .setDescription("Update a project or module key and all its sub-components keys.<br>" +
+ "Either '%s' or '%s' must be provided, not both.<br> " +
+ "Requires one of the following permissions: " +
+ "<ul>" +
+ "<li>'Administer System'</li>" +
+ "<li>'Administer' rights on the specified project</li>" +
+ "</ul>",
+ PARAM_PROJECT, PARAM_PROJECT_ID)
+ .setSince("6.1")
+ .setPost(true)
+ .setHandler(this);
+
+ action.setChangelog(
+ new Change("6.4", "Move from api/components/update_key to api/projects/update_key"));
+
+ action.createParam(PARAM_PROJECT_ID)
+ .setDescription("Project or module id")
+ .setDeprecatedKey("id", "6.4")
+ .setExampleValue(UUID_EXAMPLE_01);
+
+ action.createParam(PARAM_PROJECT)
+ .setDescription("Project or module key")
+ .setDeprecatedKey("key", "6.4")
+ .setExampleValue("my_old_project");
+
+ action.createParam(PARAM_NEW_PROJECT)
+ .setDescription("New component key")
+ .setRequired(true)
+ .setDeprecatedKey("newKey", "6.4")
+ .setExampleValue("my_new_project");
+
+ return action;
+ }
+
+ @Override
+ public void handle(Request request, Response response) throws Exception {
+ doHandle(toWsRequest(request));
+ response.noContent();
+ }
+
+ private void doHandle(UpdateKeyWsRequest request) {
+ DbSession dbSession = dbClient.openSession(false);
+ try {
+ ComponentDto projectOrModule = componentFinder.getByUuidOrKey(dbSession, request.getId(), request.getKey(), ParamNames.PROJECT_ID_AND_PROJECT);
+ componentService.updateKey(dbSession, projectOrModule, request.getNewKey());
+ dbSession.commit();
+ } finally {
+ dbClient.closeSession(dbSession);
+ }
+ }
+
+ private static UpdateKeyWsRequest toWsRequest(Request request) {
+ return UpdateKeyWsRequest.builder()
+ .setId(request.param(PARAM_PROJECT_ID))
+ .setKey(request.param(PARAM_PROJECT))
+ .setNewKey(request.mandatoryParam(PARAM_NEW_PROJECT))
+ .build();
+ }
+}
+++ /dev/null
-{
- "keys": [
- {
- "key": "my_project",
- "newKey": "my_new_project",
- "duplicate": false
- },
- {
- "key": "my_project:module_1",
- "newKey": "my_new_project:module_1",
- "duplicate": true
- },
- {
- "key": "my_project:module_2",
- "newKey": "my_new_project:module_2",
- "duplicate": false
- }
- ]
-}
--- /dev/null
+{
+ "keys": [
+ {
+ "key": "my_project",
+ "newKey": "my_new_project",
+ "duplicate": false
+ },
+ {
+ "key": "my_project:module_1",
+ "newKey": "my_new_project:module_1",
+ "duplicate": true
+ },
+ {
+ "key": "my_project:module_2",
+ "newKey": "my_new_project:module_2",
+ "duplicate": false
+ }
+ ]
+}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2017 SonarSource SA
- * mailto:info 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.component.ws;
-
-import com.google.common.base.Throwables;
-import java.io.IOException;
-import javax.annotation.Nullable;
-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.server.ws.WebService;
-import org.sonar.api.utils.System2;
-import org.sonar.db.DbClient;
-import org.sonar.db.DbSession;
-import org.sonar.db.DbTester;
-import org.sonar.db.component.ComponentDbTester;
-import org.sonar.db.component.ComponentDto;
-import org.sonar.db.organization.OrganizationDto;
-import org.sonar.server.component.ComponentFinder;
-import org.sonar.server.component.ComponentService;
-import org.sonar.server.component.index.ComponentIndexDefinition;
-import org.sonar.server.es.EsTester;
-import org.sonar.server.exceptions.BadRequestException;
-import org.sonar.server.exceptions.ForbiddenException;
-import org.sonar.server.exceptions.NotFoundException;
-import org.sonar.server.measure.index.ProjectMeasuresIndexDefinition;
-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.WsComponents;
-import org.sonarqube.ws.WsComponents.BulkUpdateKeyWsResponse;
-import org.sonarqube.ws.WsComponents.BulkUpdateKeyWsResponse.Key;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.tuple;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.sonar.db.component.ComponentTesting.newFileDto;
-import static org.sonar.db.component.ComponentTesting.newModuleDto;
-import static org.sonar.db.component.ComponentTesting.newProjectDto;
-import static org.sonar.test.JsonAssert.assertJson;
-import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_DRY_RUN;
-import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_FROM;
-import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_PROJECT;
-import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_PROJECT_ID;
-import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_TO;
-
-public class BulkUpdateKeyActionTest {
- private static final String MY_PROJECT_KEY = "my_project";
- private static final String FROM = "my_";
- private static final String TO = "your_";
-
- private System2 system2 = System2.INSTANCE;
-
- @Rule
- public ExpectedException expectedException = ExpectedException.none();
- @Rule
- public UserSessionRule userSession = UserSessionRule.standalone();
- @Rule
- public EsTester es = new EsTester(new ProjectMeasuresIndexDefinition(new MapSettings()),
- new ComponentIndexDefinition(new MapSettings()));
- @Rule
- public DbTester db = DbTester.create(system2);
-
- private ComponentDbTester componentDb = new ComponentDbTester(db);
- private DbClient dbClient = db.getDbClient();
- private ComponentFinder componentFinder = new ComponentFinder(dbClient);
- private ComponentService componentService = mock(ComponentService.class);
- private WsActionTester ws = new WsActionTester(
- new BulkUpdateKeyAction(dbClient, componentFinder, componentService, userSession));
-
- @Before
- public void setUp() {
- userSession.logIn().setRoot();
- }
-
- @Test
- public void json_example() {
- OrganizationDto organizationDto = db.organizations().insert();
- ComponentDto project = componentDb.insertComponent(newProjectDto(organizationDto).setKey("my_project"));
- componentDb.insertComponent(newModuleDto(project).setKey("my_project:module_1"));
- ComponentDto anotherProject = componentDb.insertComponent(newProjectDto(organizationDto).setKey("another_project"));
- componentDb.insertComponent(newModuleDto(anotherProject).setKey("my_new_project:module_1"));
- ComponentDto module2 = componentDb.insertComponent(newModuleDto(project).setKey("my_project:module_2"));
- componentDb.insertComponent(newFileDto(module2, null));
-
- String result = ws.newRequest()
- .setParam(PARAM_PROJECT, "my_project")
- .setParam(PARAM_FROM, "my_")
- .setParam(PARAM_TO, "my_new_")
- .setParam(PARAM_DRY_RUN, String.valueOf(true))
- .execute().getInput();
-
- assertJson(result).withStrictArrayOrder().isSimilarTo(getClass().getResource("bulk_update_key-example.json"));
- }
-
- @Test
- public void dry_run_by_key() {
- insertMyProject();
-
- BulkUpdateKeyWsResponse result = callDryRunByKey(MY_PROJECT_KEY, FROM, TO);
-
- assertThat(result.getKeysCount()).isEqualTo(1);
- assertThat(result.getKeys(0).getNewKey()).isEqualTo("your_project");
- }
-
- @Test
- public void bulk_update_project_key() {
- ComponentDto project = insertMyProject();
- ComponentDto module = componentDb.insertComponent(newModuleDto(project).setKey("my_project:root:module"));
- ComponentDto inactiveModule = componentDb.insertComponent(newModuleDto(project).setKey("my_project:root:inactive_module").setEnabled(false));
- ComponentDto file = componentDb.insertComponent(newFileDto(module, null).setKey("my_project:root:module:src/File.xoo"));
- ComponentDto inactiveFile = componentDb.insertComponent(newFileDto(module, null).setKey("my_project:root:module:src/InactiveFile.xoo").setEnabled(false));
-
- BulkUpdateKeyWsResponse result = callByUuid(project.uuid(), FROM, TO);
-
- assertThat(result.getKeysCount()).isEqualTo(2);
- assertThat(result.getKeysList()).extracting(Key::getKey, Key::getNewKey, Key::getDuplicate)
- .containsExactly(
- tuple(project.key(), "your_project", false),
- tuple(module.key(), "your_project:root:module", false));
-
- verify(componentService).bulkUpdateKey(any(DbSession.class), eq(project.uuid()), eq(FROM), eq(TO));
- }
-
- @Test
- public void bulk_update_provisioned_project_key() {
- String newKey = "provisionedProject2";
- ComponentDto provisionedProject = componentDb.insertProject();
-
- callByKey(provisionedProject.key(), provisionedProject.getKey(), newKey);
-
- verify(componentService).bulkUpdateKey(any(DbSession.class), eq(provisionedProject.uuid()), eq(provisionedProject.getKey()), eq(newKey));
- }
-
- @Test
- public void fail_to_bulk_if_a_component_already_exists_with_the_same_key() {
- componentDb.insertComponent(newProjectDto(db.getDefaultOrganization()).setKey("my_project"));
- componentDb.insertComponent(newProjectDto(db.getDefaultOrganization()).setKey("your_project"));
-
- expectedException.expect(BadRequestException.class);
- expectedException.expectMessage("Impossible to update key: a component with key \"your_project\" already exists.");
-
- callByKey("my_project", "my_", "your_");
- }
-
- @Test
- public void fail_to_bulk_update_with_invalid_new_key() {
- insertMyProject();
-
- expectedException.expect(IllegalArgumentException.class);
- expectedException.expectMessage("Malformed key for 'my?project'. Allowed characters are alphanumeric, '-', '_', '.' and ':', with at least one non-digit.");
-
- callByKey(MY_PROJECT_KEY, FROM, "my?");
- }
-
- @Test
- public void fail_to_dry_bulk_update_with_invalid_new_key() {
- insertMyProject();
-
- expectedException.expect(IllegalArgumentException.class);
- expectedException.expectMessage("Malformed key for 'my?project'. Allowed characters are alphanumeric, '-', '_', '.' and ':', with at least one non-digit.");
-
- callDryRunByKey(MY_PROJECT_KEY, FROM, "my?");
- }
-
- @Test
- public void fail_to_bulk_update_if_not_project_or_module() {
- ComponentDto project = insertMyProject();
- ComponentDto file = componentDb.insertComponent(newFileDto(project, null));
-
- expectedException.expect(IllegalArgumentException.class);
- expectedException.expectMessage("Component updated must be a module or a key");
-
- callByKey(file.key(), FROM, TO);
- }
-
- @Test
- public void fail_if_from_string_is_not_provided() {
- expectedException.expect(IllegalArgumentException.class);
-
- ComponentDto project = insertMyProject();
-
- callDryRunByKey(project.key(), null, TO);
- }
-
- @Test
- public void fail_if_to_string_is_not_provided() {
- expectedException.expect(IllegalArgumentException.class);
-
- ComponentDto project = insertMyProject();
-
- callDryRunByKey(project.key(), FROM, null);
- }
-
- @Test
- public void fail_if_uuid_nor_key_provided() {
- expectedException.expect(IllegalArgumentException.class);
-
- call(null, null, FROM, TO, false);
- }
-
- @Test
- public void fail_if_uuid_and_key_provided() {
- expectedException.expect(IllegalArgumentException.class);
-
- ComponentDto project = insertMyProject();
-
- call(project.uuid(), project.key(), FROM, TO, false);
- }
-
- @Test
- public void fail_if_project_does_not_exist() {
- expectedException.expect(NotFoundException.class);
-
- callDryRunByUuid("UNKNOWN_UUID", FROM, TO);
- }
-
- @Test
- public void throw_ForbiddenException_if_not_project_administrator() {
- userSession.logIn();
- ComponentDto project = insertMyProject();
-
- expectedException.expect(ForbiddenException.class);
-
- callDryRunByUuid(project.uuid(), FROM, TO);
- }
-
- @Test
- public void api_definition() {
- WebService.Action definition = ws.getDef();
-
- assertThat(definition.isPost()).isTrue();
- assertThat(definition.since()).isEqualTo("6.1");
- assertThat(definition.key()).isEqualTo("bulk_update_key");
- assertThat(definition.params())
- .hasSize(5)
- .extracting(WebService.Param::key)
- .containsOnlyOnce("projectId", "project", "from", "to", "dryRun");
- }
-
- private ComponentDto insertMyProject() {
- return componentDb.insertComponent(newProjectDto(db.organizations().insert()).setKey(MY_PROJECT_KEY));
- }
-
- private WsComponents.BulkUpdateKeyWsResponse callDryRunByUuid(@Nullable String uuid, @Nullable String from, @Nullable String to) {
- return call(uuid, null, from, to, true);
- }
-
- private BulkUpdateKeyWsResponse callDryRunByKey(@Nullable String key, @Nullable String from, @Nullable String to) {
- return call(null, key, from, to, true);
- }
-
- private WsComponents.BulkUpdateKeyWsResponse callByUuid(@Nullable String uuid, @Nullable String from, @Nullable String to) {
- return call(uuid, null, from, to, false);
- }
-
- private BulkUpdateKeyWsResponse callByKey(@Nullable String key, @Nullable String from, @Nullable String to) {
- return call(null, key, from, to, false);
- }
-
- private BulkUpdateKeyWsResponse call(@Nullable String uuid, @Nullable String key, @Nullable String from, @Nullable String to, @Nullable Boolean dryRun) {
- TestRequest request = ws.newRequest()
- .setMediaType(MediaTypes.PROTOBUF);
-
- if (uuid != null) {
- request.setParam(PARAM_PROJECT_ID, uuid);
- }
- if (key != null) {
- request.setParam(PARAM_PROJECT, key);
- }
- if (from != null) {
- request.setParam(PARAM_FROM, from);
- }
- if (to != null) {
- request.setParam(PARAM_TO, to);
- }
- if (dryRun != null) {
- request.setParam(PARAM_DRY_RUN, String.valueOf(dryRun));
- }
-
- try {
- return WsComponents.BulkUpdateKeyWsResponse.parseFrom(request.execute().getInputStream());
- } catch (IOException e) {
- throw Throwables.propagate(e);
- }
- }
-}
public void verify_count_of_added_components() {
ComponentContainer container = new ComponentContainer();
new ComponentsWsModule().configure(container);
- assertThat(container.size()).isEqualTo(11 + COMPONENTS_IN_EMPTY_COMPONENT_CONTAINER);
+ assertThat(container.size()).isEqualTo(COMPONENTS_IN_EMPTY_COMPONENT_CONTAINER + 9);
}
}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2017 SonarSource SA
- * mailto:info 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.component.ws;
-
-import javax.annotation.Nullable;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-import org.sonar.api.server.ws.WebService;
-import org.sonar.api.server.ws.WebService.Param;
-import org.sonar.api.utils.System2;
-import org.sonar.db.DbClient;
-import org.sonar.db.DbSession;
-import org.sonar.db.DbTester;
-import org.sonar.db.component.ComponentDbTester;
-import org.sonar.db.component.ComponentDto;
-import org.sonar.server.component.ComponentFinder;
-import org.sonar.server.component.ComponentService;
-import org.sonar.server.exceptions.NotFoundException;
-import org.sonar.server.ws.TestRequest;
-import org.sonar.server.ws.WsActionTester;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.sonar.db.component.ComponentTesting.newProjectDto;
-import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_NEW_PROJECT;
-import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_PROJECT;
-import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_PROJECT_ID;
-
-public class UpdateKeyActionTest {
- private static final String ANOTHER_KEY = "another_key";
- @Rule
- public ExpectedException expectedException = ExpectedException.none();
- @Rule
- public DbTester db = DbTester.create(System2.INSTANCE);
- ComponentDbTester componentDb = new ComponentDbTester(db);
- DbClient dbClient = db.getDbClient();
-
- ComponentService componentService = mock(ComponentService.class);
-
- WsActionTester ws = new WsActionTester(new UpdateKeyAction(dbClient, new ComponentFinder(dbClient), componentService));
-
- @Test
- public void call_by_key() {
- ComponentDto project = insertProject();
-
- callByKey(project.key(), ANOTHER_KEY);
-
- assertCallComponentService(ANOTHER_KEY);
- }
-
- @Test
- public void call_by_uuid() {
- ComponentDto project = insertProject();
-
- callByUuid(project.uuid(), ANOTHER_KEY);
-
- assertCallComponentService(ANOTHER_KEY);
- }
-
- @Test
- public void fail_if_new_key_is_not_provided() {
- expectedException.expect(IllegalArgumentException.class);
-
- ComponentDto project = insertProject();
-
- callByKey(project.key(), null);
- }
-
- @Test
- public void fail_if_uuid_nor_key_provided() {
- expectedException.expect(IllegalArgumentException.class);
-
- call(null, null, ANOTHER_KEY);
- }
-
- @Test
- public void fail_if_uuid_and_key_provided() {
- expectedException.expect(IllegalArgumentException.class);
-
- ComponentDto project = insertProject();
-
- call(project.uuid(), project.key(), ANOTHER_KEY);
- }
-
- @Test
- public void fail_if_project_does_not_exist() {
- expectedException.expect(NotFoundException.class);
-
- callByUuid("UNKNOWN_UUID", ANOTHER_KEY);
- }
-
- @Test
- public void api_definition() {
- WebService.Action definition = ws.getDef();
-
- assertThat(definition.since()).isEqualTo("6.1");
- assertThat(definition.isPost()).isTrue();
- assertThat(definition.key()).isEqualTo("update_key");
- assertThat(definition.params())
- .hasSize(3)
- .extracting(Param::key)
- .containsOnlyOnce("projectId", "project", "newProject");
- }
-
- private void assertCallComponentService(@Nullable String newKey) {
- verify(componentService).updateKey(any(DbSession.class), any(ComponentDto.class), eq(newKey));
- }
-
- private ComponentDto insertProject() {
- return componentDb.insertComponent(newProjectDto(db.organizations().insert()));
- }
-
- private String callByUuid(@Nullable String uuid, @Nullable String newKey) {
- return call(uuid, null, newKey);
- }
-
- private String callByKey(@Nullable String key, @Nullable String newKey) {
- return call(null, key, newKey);
- }
-
- private String call(@Nullable String uuid, @Nullable String key, @Nullable String newKey) {
- TestRequest request = ws.newRequest();
-
- if (uuid != null) {
- request.setParam(PARAM_PROJECT_ID, uuid);
- }
- if (key != null) {
- request.setParam(PARAM_PROJECT, key);
- }
- if (newKey != null) {
- request.setParam(PARAM_NEW_PROJECT, newKey);
- }
-
- return request.execute().getInput();
- }
-}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info 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 javax.annotation.Nullable;
+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.server.ws.WebService;
+import org.sonar.api.utils.System2;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
+import org.sonar.db.DbTester;
+import org.sonar.db.component.ComponentDbTester;
+import org.sonar.db.component.ComponentDto;
+import org.sonar.db.organization.OrganizationDto;
+import org.sonar.server.component.ComponentFinder;
+import org.sonar.server.component.ComponentService;
+import org.sonar.server.component.index.ComponentIndexDefinition;
+import org.sonar.server.es.EsTester;
+import org.sonar.server.exceptions.BadRequestException;
+import org.sonar.server.exceptions.ForbiddenException;
+import org.sonar.server.exceptions.NotFoundException;
+import org.sonar.server.measure.index.ProjectMeasuresIndexDefinition;
+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.BulkUpdateKeyWsResponse;
+import org.sonarqube.ws.WsProjects.BulkUpdateKeyWsResponse.Key;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.tuple;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.sonar.db.component.ComponentTesting.newFileDto;
+import static org.sonar.db.component.ComponentTesting.newModuleDto;
+import static org.sonar.db.component.ComponentTesting.newProjectDto;
+import static org.sonar.test.JsonAssert.assertJson;
+import static org.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_DRY_RUN;
+import static org.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_FROM;
+import static org.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_PROJECT;
+import static org.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_PROJECT_ID;
+import static org.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_TO;
+
+public class BulkUpdateKeyActionTest {
+ private static final String MY_PROJECT_KEY = "my_project";
+ private static final String FROM = "my_";
+ private static final String TO = "your_";
+
+ private System2 system2 = System2.INSTANCE;
+
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+ @Rule
+ public UserSessionRule userSession = UserSessionRule.standalone();
+ @Rule
+ public EsTester es = new EsTester(new ProjectMeasuresIndexDefinition(new MapSettings()),
+ new ComponentIndexDefinition(new MapSettings()));
+ @Rule
+ public DbTester db = DbTester.create(system2);
+
+ private ComponentDbTester componentDb = new ComponentDbTester(db);
+ private DbClient dbClient = db.getDbClient();
+ private ComponentFinder componentFinder = new ComponentFinder(dbClient);
+ private ComponentService componentService = mock(ComponentService.class);
+ private WsActionTester ws = new WsActionTester(
+ new BulkUpdateKeyAction(dbClient, componentFinder, componentService, userSession));
+
+ @Before
+ public void setUp() {
+ userSession.logIn().setRoot();
+ }
+
+ @Test
+ public void json_example() {
+ OrganizationDto organizationDto = db.organizations().insert();
+ ComponentDto project = componentDb.insertComponent(newProjectDto(organizationDto).setKey("my_project"));
+ componentDb.insertComponent(newModuleDto(project).setKey("my_project:module_1"));
+ ComponentDto anotherProject = componentDb.insertComponent(newProjectDto(organizationDto).setKey("another_project"));
+ componentDb.insertComponent(newModuleDto(anotherProject).setKey("my_new_project:module_1"));
+ ComponentDto module2 = componentDb.insertComponent(newModuleDto(project).setKey("my_project:module_2"));
+ componentDb.insertComponent(newFileDto(module2, null));
+
+ String result = ws.newRequest()
+ .setParam(PARAM_PROJECT, "my_project")
+ .setParam(PARAM_FROM, "my_")
+ .setParam(PARAM_TO, "my_new_")
+ .setParam(PARAM_DRY_RUN, String.valueOf(true))
+ .execute().getInput();
+
+ assertJson(result).withStrictArrayOrder().isSimilarTo(getClass().getResource("bulk_update_key-example.json"));
+ }
+
+ @Test
+ public void dry_run_by_key() {
+ insertMyProject();
+
+ BulkUpdateKeyWsResponse result = callDryRunByKey(MY_PROJECT_KEY, FROM, TO);
+
+ assertThat(result.getKeysCount()).isEqualTo(1);
+ assertThat(result.getKeys(0).getNewKey()).isEqualTo("your_project");
+ }
+
+ @Test
+ public void bulk_update_project_key() {
+ ComponentDto project = insertMyProject();
+ ComponentDto module = componentDb.insertComponent(newModuleDto(project).setKey("my_project:root:module"));
+ ComponentDto inactiveModule = componentDb.insertComponent(newModuleDto(project).setKey("my_project:root:inactive_module").setEnabled(false));
+ ComponentDto file = componentDb.insertComponent(newFileDto(module, null).setKey("my_project:root:module:src/File.xoo"));
+ ComponentDto inactiveFile = componentDb.insertComponent(newFileDto(module, null).setKey("my_project:root:module:src/InactiveFile.xoo").setEnabled(false));
+
+ BulkUpdateKeyWsResponse result = callByUuid(project.uuid(), FROM, TO);
+
+ assertThat(result.getKeysCount()).isEqualTo(2);
+ assertThat(result.getKeysList()).extracting(Key::getKey, Key::getNewKey, Key::getDuplicate)
+ .containsExactly(
+ tuple(project.key(), "your_project", false),
+ tuple(module.key(), "your_project:root:module", false));
+
+ verify(componentService).bulkUpdateKey(any(DbSession.class), eq(project.uuid()), eq(FROM), eq(TO));
+ }
+
+ @Test
+ public void bulk_update_provisioned_project_key() {
+ String newKey = "provisionedProject2";
+ ComponentDto provisionedProject = componentDb.insertProject();
+
+ callByKey(provisionedProject.key(), provisionedProject.getKey(), newKey);
+
+ verify(componentService).bulkUpdateKey(any(DbSession.class), eq(provisionedProject.uuid()), eq(provisionedProject.getKey()), eq(newKey));
+ }
+
+ @Test
+ public void fail_to_bulk_if_a_component_already_exists_with_the_same_key() {
+ componentDb.insertComponent(newProjectDto(db.getDefaultOrganization()).setKey("my_project"));
+ componentDb.insertComponent(newProjectDto(db.getDefaultOrganization()).setKey("your_project"));
+
+ expectedException.expect(BadRequestException.class);
+ expectedException.expectMessage("Impossible to update key: a component with key \"your_project\" already exists.");
+
+ callByKey("my_project", "my_", "your_");
+ }
+
+ @Test
+ public void fail_to_bulk_update_with_invalid_new_key() {
+ insertMyProject();
+
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("Malformed key for 'my?project'. Allowed characters are alphanumeric, '-', '_', '.' and ':', with at least one non-digit.");
+
+ callByKey(MY_PROJECT_KEY, FROM, "my?");
+ }
+
+ @Test
+ public void fail_to_dry_bulk_update_with_invalid_new_key() {
+ insertMyProject();
+
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("Malformed key for 'my?project'. Allowed characters are alphanumeric, '-', '_', '.' and ':', with at least one non-digit.");
+
+ callDryRunByKey(MY_PROJECT_KEY, FROM, "my?");
+ }
+
+ @Test
+ public void fail_to_bulk_update_if_not_project_or_module() {
+ ComponentDto project = insertMyProject();
+ ComponentDto file = componentDb.insertComponent(newFileDto(project, null));
+
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("Component updated must be a module or a key");
+
+ callByKey(file.key(), FROM, TO);
+ }
+
+ @Test
+ public void fail_if_from_string_is_not_provided() {
+ expectedException.expect(IllegalArgumentException.class);
+
+ ComponentDto project = insertMyProject();
+
+ callDryRunByKey(project.key(), null, TO);
+ }
+
+ @Test
+ public void fail_if_to_string_is_not_provided() {
+ expectedException.expect(IllegalArgumentException.class);
+
+ ComponentDto project = insertMyProject();
+
+ callDryRunByKey(project.key(), FROM, null);
+ }
+
+ @Test
+ public void fail_if_uuid_nor_key_provided() {
+ expectedException.expect(IllegalArgumentException.class);
+
+ call(null, null, FROM, TO, false);
+ }
+
+ @Test
+ public void fail_if_uuid_and_key_provided() {
+ expectedException.expect(IllegalArgumentException.class);
+
+ ComponentDto project = insertMyProject();
+
+ call(project.uuid(), project.key(), FROM, TO, false);
+ }
+
+ @Test
+ public void fail_if_project_does_not_exist() {
+ expectedException.expect(NotFoundException.class);
+
+ callDryRunByUuid("UNKNOWN_UUID", FROM, TO);
+ }
+
+ @Test
+ public void throw_ForbiddenException_if_not_project_administrator() {
+ userSession.logIn();
+ ComponentDto project = insertMyProject();
+
+ expectedException.expect(ForbiddenException.class);
+
+ callDryRunByUuid(project.uuid(), FROM, TO);
+ }
+
+ @Test
+ public void api_definition() {
+ WebService.Action definition = ws.getDef();
+
+ assertThat(definition.isPost()).isTrue();
+ assertThat(definition.since()).isEqualTo("6.1");
+ assertThat(definition.key()).isEqualTo("bulk_update_key");
+ assertThat(definition.params())
+ .hasSize(5)
+ .extracting(WebService.Param::key)
+ .containsOnlyOnce("projectId", "project", "from", "to", "dryRun");
+ }
+
+ private ComponentDto insertMyProject() {
+ return componentDb.insertComponent(newProjectDto(db.organizations().insert()).setKey(MY_PROJECT_KEY));
+ }
+
+ private BulkUpdateKeyWsResponse callDryRunByUuid(@Nullable String uuid, @Nullable String from, @Nullable String to) {
+ return call(uuid, null, from, to, true);
+ }
+
+ private BulkUpdateKeyWsResponse callDryRunByKey(@Nullable String key, @Nullable String from, @Nullable String to) {
+ return call(null, key, from, to, true);
+ }
+
+ private BulkUpdateKeyWsResponse callByUuid(@Nullable String uuid, @Nullable String from, @Nullable String to) {
+ return call(uuid, null, from, to, false);
+ }
+
+ private BulkUpdateKeyWsResponse callByKey(@Nullable String key, @Nullable String from, @Nullable String to) {
+ return call(null, key, from, to, false);
+ }
+
+ private BulkUpdateKeyWsResponse call(@Nullable String uuid, @Nullable String key, @Nullable String from, @Nullable String to, @Nullable Boolean dryRun) {
+ TestRequest request = ws.newRequest()
+ .setMediaType(MediaTypes.PROTOBUF);
+
+ if (uuid != null) {
+ request.setParam(PARAM_PROJECT_ID, uuid);
+ }
+ if (key != null) {
+ request.setParam(PARAM_PROJECT, key);
+ }
+ if (from != null) {
+ request.setParam(PARAM_FROM, from);
+ }
+ if (to != null) {
+ request.setParam(PARAM_TO, to);
+ }
+ if (dryRun != null) {
+ request.setParam(PARAM_DRY_RUN, String.valueOf(dryRun));
+ }
+
+ try {
+ return BulkUpdateKeyWsResponse.parseFrom(request.execute().getInputStream());
+ } catch (IOException e) {
+ throw Throwables.propagate(e);
+ }
+ }
+}
public void verify_count_of_added_components() {
ComponentContainer container = new ComponentContainer();
new ProjectsWsModule().configure(container);
- assertThat(container.size()).isEqualTo(COMPONENTS_IN_EMPTY_COMPONENT_CONTAINER + 11);
+ assertThat(container.size()).isEqualTo(COMPONENTS_IN_EMPTY_COMPONENT_CONTAINER + 13);
}
}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info 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 javax.annotation.Nullable;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.api.server.ws.WebService;
+import org.sonar.api.server.ws.WebService.Param;
+import org.sonar.api.utils.System2;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
+import org.sonar.db.DbTester;
+import org.sonar.db.component.ComponentDbTester;
+import org.sonar.db.component.ComponentDto;
+import org.sonar.server.component.ComponentFinder;
+import org.sonar.server.component.ComponentService;
+import org.sonar.server.exceptions.NotFoundException;
+import org.sonar.server.ws.TestRequest;
+import org.sonar.server.ws.WsActionTester;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.sonar.db.component.ComponentTesting.newProjectDto;
+import static org.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_NEW_PROJECT;
+import static org.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_PROJECT;
+import static org.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_PROJECT_ID;
+
+public class UpdateKeyActionTest {
+ private static final String ANOTHER_KEY = "another_key";
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+ @Rule
+ public DbTester db = DbTester.create(System2.INSTANCE);
+ ComponentDbTester componentDb = new ComponentDbTester(db);
+ DbClient dbClient = db.getDbClient();
+
+ ComponentService componentService = mock(ComponentService.class);
+
+ WsActionTester ws = new WsActionTester(new org.sonar.server.project.ws.UpdateKeyAction(dbClient, new ComponentFinder(dbClient), componentService));
+
+ @Test
+ public void call_by_key() {
+ ComponentDto project = insertProject();
+
+ callByKey(project.key(), ANOTHER_KEY);
+
+ assertCallComponentService(ANOTHER_KEY);
+ }
+
+ @Test
+ public void call_by_uuid() {
+ ComponentDto project = insertProject();
+
+ callByUuid(project.uuid(), ANOTHER_KEY);
+
+ assertCallComponentService(ANOTHER_KEY);
+ }
+
+ @Test
+ public void fail_if_new_key_is_not_provided() {
+ expectedException.expect(IllegalArgumentException.class);
+
+ ComponentDto project = insertProject();
+
+ callByKey(project.key(), null);
+ }
+
+ @Test
+ public void fail_if_uuid_nor_key_provided() {
+ expectedException.expect(IllegalArgumentException.class);
+
+ call(null, null, ANOTHER_KEY);
+ }
+
+ @Test
+ public void fail_if_uuid_and_key_provided() {
+ expectedException.expect(IllegalArgumentException.class);
+
+ ComponentDto project = insertProject();
+
+ call(project.uuid(), project.key(), ANOTHER_KEY);
+ }
+
+ @Test
+ public void fail_if_project_does_not_exist() {
+ expectedException.expect(NotFoundException.class);
+
+ callByUuid("UNKNOWN_UUID", ANOTHER_KEY);
+ }
+
+ @Test
+ public void api_definition() {
+ WebService.Action definition = ws.getDef();
+
+ assertThat(definition.since()).isEqualTo("6.1");
+ assertThat(definition.isPost()).isTrue();
+ assertThat(definition.key()).isEqualTo("update_key");
+ assertThat(definition.params())
+ .hasSize(3)
+ .extracting(Param::key)
+ .containsOnlyOnce("projectId", "project", "newProject");
+ }
+
+ private void assertCallComponentService(@Nullable String newKey) {
+ verify(componentService).updateKey(any(DbSession.class), any(ComponentDto.class), eq(newKey));
+ }
+
+ private ComponentDto insertProject() {
+ return componentDb.insertComponent(newProjectDto(db.organizations().insert()));
+ }
+
+ private String callByUuid(@Nullable String uuid, @Nullable String newKey) {
+ return call(uuid, null, newKey);
+ }
+
+ private String callByKey(@Nullable String key, @Nullable String newKey) {
+ return call(null, key, newKey);
+ }
+
+ private String call(@Nullable String uuid, @Nullable String key, @Nullable String newKey) {
+ TestRequest request = ws.newRequest();
+
+ if (uuid != null) {
+ request.setParam(PARAM_PROJECT_ID, uuid);
+ }
+ if (key != null) {
+ request.setParam(PARAM_PROJECT, key);
+ }
+ if (newKey != null) {
+ request.setParam(PARAM_NEW_PROJECT, newKey);
+ }
+
+ return request.execute().getInput();
+ }
+}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2017 SonarSource SA
- * mailto:info 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.sonarqube.ws.client.component;
-
-import javax.annotation.CheckForNull;
-import javax.annotation.Nullable;
-import javax.annotation.concurrent.Immutable;
-
-import static com.google.common.base.Preconditions.checkArgument;
-
-@Immutable
-public class BulkUpdateWsRequest {
- private final String id;
- private final String key;
- private final String from;
- private final String to;
- private final boolean dryRun;
-
- public BulkUpdateWsRequest(Builder builder) {
- this.id = builder.id;
- this.key = builder.key;
- this.from = builder.from;
- this.to = builder.to;
- this.dryRun = builder.dryRun;
- }
-
- @CheckForNull
- public String getId() {
- return id;
- }
-
- @CheckForNull
- public String getKey() {
- return key;
- }
-
- public String getFrom() {
- return from;
- }
-
- public String getTo() {
- return to;
- }
-
- public boolean isDryRun() {
- return dryRun;
- }
-
- public static Builder builder() {
- return new Builder();
- }
-
- public static class Builder {
- private String id;
- private String key;
- private String from;
- private String to;
- private boolean dryRun;
-
- private Builder() {
- // enforce method constructor
- }
-
- public Builder setId(@Nullable String id) {
- this.id = id;
- return this;
- }
-
- public Builder setKey(@Nullable String key) {
- this.key = key;
- return this;
- }
-
- public Builder setFrom(String from) {
- this.from = from;
- return this;
- }
-
- public Builder setTo(String to) {
- this.to = to;
- return this;
- }
-
- public Builder setDryRun(boolean dryRun) {
- this.dryRun = dryRun;
- return this;
- }
-
- public BulkUpdateWsRequest build() {
- checkArgument(from != null && !from.isEmpty(), "The string to match must not be empty");
- checkArgument(to != null && !to.isEmpty(), "The string replacement must not be empty");
- return new BulkUpdateWsRequest(this);
- }
- }
-}
import com.google.common.base.Joiner;
import java.util.List;
-import org.sonarqube.ws.WsComponents.BulkUpdateKeyWsResponse;
import org.sonarqube.ws.WsComponents.SearchProjectsWsResponse;
import org.sonarqube.ws.WsComponents.SearchWsResponse;
import org.sonarqube.ws.WsComponents.ShowWsResponse;
import org.sonarqube.ws.WsComponents.TreeWsResponse;
import org.sonarqube.ws.client.BaseService;
import org.sonarqube.ws.client.GetRequest;
-import org.sonarqube.ws.client.PostRequest;
import org.sonarqube.ws.client.WsConnector;
import static org.sonar.api.server.ws.WebService.Param;
-import static org.sonarqube.ws.client.component.ComponentsWsParameters.ACTION_BULK_UPDATE_KEY;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.ACTION_SEARCH;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.ACTION_SEARCH_PROJECTS;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.ACTION_SHOW;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.ACTION_TREE;
-import static org.sonarqube.ws.client.component.ComponentsWsParameters.ACTION_UPDATE_KEY;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.CONTROLLER_COMPONENTS;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_COMPONENT;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_COMPONENT_ID;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_FILTER;
-import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_FROM;
-import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_NEW_PROJECT;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_ORGANIZATION;
-import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_PROJECT;
-import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_PROJECT_ID;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_QUALIFIERS;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_STRATEGY;
-import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_TO;
public class ComponentsService extends BaseService {
return call(get, ShowWsResponse.parser());
}
- public void updateKey(UpdateWsRequest request) {
- PostRequest post = new PostRequest(path(ACTION_UPDATE_KEY))
- .setParam(PARAM_PROJECT_ID, request.getId())
- .setParam(PARAM_PROJECT, request.getKey())
- .setParam(PARAM_NEW_PROJECT, request.getNewKey());
-
- call(post);
- }
-
- public BulkUpdateKeyWsResponse bulkUpdateKey(BulkUpdateWsRequest request) {
- PostRequest post = new PostRequest(path(ACTION_BULK_UPDATE_KEY))
- .setParam(PARAM_PROJECT_ID, request.getId())
- .setParam(PARAM_PROJECT, request.getKey())
- .setParam(PARAM_FROM, request.getFrom())
- .setParam(PARAM_TO, request.getTo());
-
- return call(post, BulkUpdateKeyWsResponse.parser());
- }
-
public SearchProjectsWsResponse searchProjects(SearchProjectsRequest request) {
List<String> additionalFields = request.getAdditionalFields();
GetRequest get = new GetRequest(path(ACTION_SEARCH_PROJECTS))
// actions
public static final String ACTION_SEARCH = "search";
- public static final String ACTION_UPDATE_KEY = "update_key";
public static final String ACTION_TREE = "tree";
public static final String ACTION_SHOW = "show";
- public static final String ACTION_BULK_UPDATE_KEY = "bulk_update_key";
public static final String ACTION_SEARCH_PROJECTS = "search_projects";
public static final String ACTION_SUGGESTIONS = "suggestions";
public static final String PARAM_QUALIFIERS = "qualifiers";
public static final String PARAM_LANGUAGE = "language";
public static final String PARAM_STRATEGY = "strategy";
- public static final String PARAM_FROM = "from";
- public static final String PARAM_TO = "to";
- public static final String PARAM_DRY_RUN = "dryRun";
public static final String PARAM_FILTER = "filter";
- public static final String PARAM_PROJECT_ID = "projectId";
- public static final String PARAM_PROJECT = "project";
public static final String PARAM_COMPONENT_ID = "componentId";
public static final String PARAM_COMPONENT = "component";
- public static final String PARAM_NEW_PROJECT = "newProject";
private ComponentsWsParameters() {
// static utility class
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2017 SonarSource SA
- * mailto:info 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.sonarqube.ws.client.component;
-
-import javax.annotation.CheckForNull;
-import javax.annotation.Nullable;
-import javax.annotation.concurrent.Immutable;
-
-import static com.google.common.base.Preconditions.checkArgument;
-
-@Immutable
-public class UpdateWsRequest {
- private final String id;
- private final String key;
- private final String newKey;
-
- public UpdateWsRequest(Builder builder) {
- this.id = builder.id;
- this.key = builder.key;
- this.newKey = builder.newKey;
- }
-
- @CheckForNull
- public String getId() {
- return id;
- }
-
- @CheckForNull
- public String getKey() {
- return key;
- }
-
- public String getNewKey() {
- return newKey;
- }
-
- public static Builder builder() {
- return new Builder();
- }
-
- public static class Builder {
- private String id;
- private String key;
- private String newKey;
-
- private Builder() {
- // enforce method constructor
- }
-
- public Builder setId(@Nullable String id) {
- this.id = id;
- return this;
- }
-
- public Builder setKey(@Nullable String key) {
- this.key = key;
- return this;
- }
-
- public Builder setNewKey(String newKey) {
- this.newKey = newKey;
- return this;
- }
-
- public UpdateWsRequest build() {
- checkArgument(newKey != null && !newKey.isEmpty(), "The new key must not be empty");
- return new UpdateWsRequest(this);
- }
- }
-}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info 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.sonarqube.ws.client.project;
+
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
+import javax.annotation.concurrent.Immutable;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+@Immutable
+public class BulkUpdateKeyWsRequest {
+ private final String id;
+ private final String key;
+ private final String from;
+ private final String to;
+ private final boolean dryRun;
+
+ public BulkUpdateKeyWsRequest(Builder builder) {
+ this.id = builder.id;
+ this.key = builder.key;
+ this.from = builder.from;
+ this.to = builder.to;
+ this.dryRun = builder.dryRun;
+ }
+
+ @CheckForNull
+ public String getId() {
+ return id;
+ }
+
+ @CheckForNull
+ public String getKey() {
+ return key;
+ }
+
+ public String getFrom() {
+ return from;
+ }
+
+ public String getTo() {
+ return to;
+ }
+
+ public boolean isDryRun() {
+ return dryRun;
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ public static class Builder {
+ private String id;
+ private String key;
+ private String from;
+ private String to;
+ private boolean dryRun;
+
+ private Builder() {
+ // enforce method constructor
+ }
+
+ public Builder setId(@Nullable String id) {
+ this.id = id;
+ return this;
+ }
+
+ public Builder setKey(@Nullable String key) {
+ this.key = key;
+ return this;
+ }
+
+ public Builder setFrom(String from) {
+ this.from = from;
+ return this;
+ }
+
+ public Builder setTo(String to) {
+ this.to = to;
+ return this;
+ }
+
+ public Builder setDryRun(boolean dryRun) {
+ this.dryRun = dryRun;
+ return this;
+ }
+
+ public BulkUpdateKeyWsRequest build() {
+ checkArgument(from != null && !from.isEmpty(), "The string to match must not be empty");
+ checkArgument(to != null && !to.isEmpty(), "The string replacement must not be empty");
+ return new BulkUpdateKeyWsRequest(this);
+ }
+ }
+}
package org.sonarqube.ws.client.project;
import com.google.common.base.Joiner;
-import org.sonarqube.ws.WsProjects;
+import org.sonarqube.ws.WsProjects.BulkUpdateKeyWsResponse;
import org.sonarqube.ws.WsProjects.CreateWsResponse;
+import org.sonarqube.ws.WsProjects.SearchWsResponse;
import org.sonarqube.ws.client.BaseService;
import org.sonarqube.ws.client.GetRequest;
import org.sonarqube.ws.client.PostRequest;
import org.sonarqube.ws.client.WsConnector;
-import static org.sonar.api.server.ws.WebService.Param.*;
+import static org.sonar.api.server.ws.WebService.Param.PAGE;
+import static org.sonar.api.server.ws.WebService.Param.PAGE_SIZE;
+import static org.sonar.api.server.ws.WebService.Param.TEXT_QUERY;
+import static org.sonarqube.ws.client.project.ProjectsWsParameters.ACTION_BULK_UPDATE_KEY;
import static org.sonarqube.ws.client.project.ProjectsWsParameters.ACTION_CREATE;
import static org.sonarqube.ws.client.project.ProjectsWsParameters.ACTION_SEARCH;
+import static org.sonarqube.ws.client.project.ProjectsWsParameters.ACTION_UPDATE_KEY;
import static org.sonarqube.ws.client.project.ProjectsWsParameters.CONTROLLER;
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_NEW_PROJECT;
import static org.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_ORGANIZATION;
import static org.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_PROJECT;
+import static org.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_PROJECT_ID;
import static org.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_QUALIFIERS;
/**
.setParam("key", request.getKey()));
}
- public WsProjects.SearchWsResponse search(SearchWsRequest request) {
+ public void updateKey(UpdateKeyWsRequest request) {
+ PostRequest post = new PostRequest(path(ACTION_UPDATE_KEY))
+ .setParam(PARAM_PROJECT_ID, request.getId())
+ .setParam(PARAM_PROJECT, request.getKey())
+ .setParam(PARAM_NEW_PROJECT, request.getNewKey());
+
+ call(post);
+ }
+
+ public BulkUpdateKeyWsResponse bulkUpdateKey(BulkUpdateKeyWsRequest request) {
+ PostRequest post = new PostRequest(path(ACTION_BULK_UPDATE_KEY))
+ .setParam(PARAM_PROJECT_ID, request.getId())
+ .setParam(PARAM_PROJECT, request.getKey())
+ .setParam(ProjectsWsParameters.PARAM_FROM, request.getFrom())
+ .setParam(ProjectsWsParameters.PARAM_TO, request.getTo());
+
+ return call(post, BulkUpdateKeyWsResponse.parser());
+ }
+
+ public SearchWsResponse search(SearchWsRequest request) {
GetRequest get = new GetRequest(path(ACTION_SEARCH))
.setParam(PARAM_ORGANIZATION, request.getOrganization())
.setParam(PARAM_QUALIFIERS, Joiner.on(",").join(request.getQualifiers()))
.setParam(TEXT_QUERY, request.getQuery())
.setParam(PAGE, request.getPage())
.setParam(PAGE_SIZE, request.getPageSize());
- return call(get, WsProjects.SearchWsResponse.parser());
+ return call(get, SearchWsResponse.parser());
}
}
public static final String ACTION_CREATE = "create";
public static final String ACTION_INDEX = "index";
public static final String ACTION_SEARCH = "search";
+ public static final String ACTION_UPDATE_KEY = "update_key";
+ public static final String ACTION_BULK_UPDATE_KEY = "bulk_update_key";
public static final String PARAM_PROJECT = "project";
public static final String PARAM_PROJECT_ID = "projectId";
+ public static final String PARAM_NEW_PROJECT = "newProject";
public static final String PARAM_NAME = "name";
public static final String PARAM_BRANCH = "branch";
public static final String PARAM_ORGANIZATION = "organization";
public static final String PARAM_QUALIFIERS = "qualifiers";
+ public static final String PARAM_FROM = "from";
+ public static final String PARAM_TO = "to";
+ public static final String PARAM_DRY_RUN = "dryRun";
+
public static final String FILTER_LANGUAGE = "language";
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info 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.sonarqube.ws.client.project;
+
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
+import javax.annotation.concurrent.Immutable;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+@Immutable
+public class UpdateKeyWsRequest {
+ private final String id;
+ private final String key;
+ private final String newKey;
+
+ public UpdateKeyWsRequest(Builder builder) {
+ this.id = builder.id;
+ this.key = builder.key;
+ this.newKey = builder.newKey;
+ }
+
+ @CheckForNull
+ public String getId() {
+ return id;
+ }
+
+ @CheckForNull
+ public String getKey() {
+ return key;
+ }
+
+ public String getNewKey() {
+ return newKey;
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ public static class Builder {
+ private String id;
+ private String key;
+ private String newKey;
+
+ private Builder() {
+ // enforce method constructor
+ }
+
+ public Builder setId(@Nullable String id) {
+ this.id = id;
+ return this;
+ }
+
+ public Builder setKey(@Nullable String key) {
+ this.key = key;
+ return this;
+ }
+
+ public Builder setNewKey(String newKey) {
+ this.newKey = newKey;
+ return this;
+ }
+
+ public UpdateKeyWsRequest build() {
+ checkArgument(newKey != null && !newKey.isEmpty(), "The new key must not be empty");
+ return new UpdateKeyWsRequest(this);
+ }
+ }
+}
}
}
-// WS api/components/prepare_bulk_update_key
-message BulkUpdateKeyWsResponse {
- repeated Key keys = 1;
-
- message Key {
- optional string key = 1;
- optional string newKey = 2;
- optional bool duplicate = 3;
- }
-}
-
// WS api/components/search_projects
message SearchProjectsWsResponse {
optional sonarqube.ws.commons.Paging paging = 1;
}
}
+// WS api/projects/prepare_bulk_update_key
+message BulkUpdateKeyWsResponse {
+ repeated Key keys = 1;
+
+ message Key {
+ optional string key = 1;
+ optional string newKey = 2;
+ optional bool duplicate = 3;
+ }
+}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2017 SonarSource SA
- * mailto:info 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.sonarqube.ws.client.component;
-
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-
-public class UpdateWsRequestTest {
-
- @Rule
- public ExpectedException expectedException = ExpectedException.none();
-
- UpdateWsRequest.Builder underTest = UpdateWsRequest.builder();
-
- @Test
- public void fail_if_new_key_is_null() {
- expectedException.expect(IllegalArgumentException.class);
- expectedException.expectMessage("The new key must not be empty");
-
- underTest.setNewKey(null).build();
- }
-
- @Test
- public void fail_if_new_key_is_empty() {
- expectedException.expect(IllegalArgumentException.class);
- expectedException.expectMessage("The new key must not be empty");
-
- underTest.setNewKey("").build();
- }
-}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info 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.sonarqube.ws.client.project;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+public class UpdateKeyWsRequestTest {
+
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+
+ UpdateKeyWsRequest.Builder underTest = UpdateKeyWsRequest.builder();
+
+ @Test
+ public void fail_if_new_key_is_null() {
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("The new key must not be empty");
+
+ underTest.setNewKey(null).build();
+ }
+
+ @Test
+ public void fail_if_new_key_is_empty() {
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("The new key must not be empty");
+
+ underTest.setNewKey("").build();
+ }
+}