From ed49a4f8f92de4bb34c89cbf79b608a852315c3b Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Lievremont Date: Thu, 2 Apr 2015 19:18:19 +0200 Subject: [PATCH] SONAR-6301 WS to copy a quality profile --- .../server/platform/ServerComponents.java | 1 + .../server/qualityprofile/QProfileCopier.java | 9 +- .../qualityprofile/ws/QProfileCopyAction.java | 71 ++++++++++++++ .../ws/QProfileCopyActionTest.java | 95 +++++++++++++++++++ 4 files changed, 169 insertions(+), 7 deletions(-) create mode 100644 server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileCopyAction.java create mode 100644 server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileCopyActionTest.java diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java b/server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java index 9981c9fc433..abb36161ba2 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java +++ b/server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java @@ -384,6 +384,7 @@ class ServerComponents { pico.addSingleton(QProfileProjectsAction.class); pico.addSingleton(QProfileDeleteAction.class); pico.addSingleton(QProfileRenameAction.class); + pico.addSingleton(QProfileCopyAction.class); pico.addSingleton(QProfilesWs.class); pico.addSingleton(ProfilesWs.class); pico.addSingleton(RuleActivationActions.class); diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileCopier.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileCopier.java index c92f17703b0..7265157d57a 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileCopier.java +++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileCopier.java @@ -29,12 +29,7 @@ import org.sonar.core.persistence.DbSession; import org.sonar.core.qualityprofile.db.QualityProfileDto; import org.sonar.server.db.DbClient; -import java.io.File; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.OutputStreamWriter; -import java.io.Reader; -import java.io.Writer; +import java.io.*; public class QProfileCopier implements ServerComponent { @@ -50,7 +45,7 @@ public class QProfileCopier implements ServerComponent { this.temp = temp; } - void copyToName(String fromProfileKey, String toName) { + public void copyToName(String fromProfileKey, String toName) { QProfileName to = prepareTarget(fromProfileKey, toName); File backupFile = temp.newFile(); backup(fromProfileKey, backupFile); diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileCopyAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileCopyAction.java new file mode 100644 index 00000000000..f1a3a4819d4 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileCopyAction.java @@ -0,0 +1,71 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.qualityprofile.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.api.server.ws.WebService.NewAction; +import org.sonar.core.permission.GlobalPermissions; +import org.sonar.server.qualityprofile.QProfileCopier; +import org.sonar.server.user.UserSession; + +public class QProfileCopyAction implements BaseQProfileWsAction { + + private static final String PARAM_PROFILE_NAME = "toName"; + private static final String PARAM_PROFILE_KEY = "fromKey"; + + private final QProfileCopier profileCopier; + + public QProfileCopyAction(QProfileCopier profileCopier) { + this.profileCopier = profileCopier; + } + + @Override + public void define(WebService.NewController controller) { + NewAction setDefault = controller.createAction("copy") + .setSince("5.2") + .setDescription("Copy a quality profile.") + .setPost(true) + .setHandler(this); + + setDefault.createParam(PARAM_PROFILE_NAME) + .setDescription("The name for the new quality profile.") + .setExampleValue("My Sonar way") + .setRequired(true); + + setDefault.createParam(PARAM_PROFILE_KEY) + .setDescription("The key of a quality profile.") + .setExampleValue("sonar-way-js-12345") + .setRequired(true); + } + + @Override + public void handle(Request request, Response response) throws Exception { + UserSession.get().checkLoggedIn().checkGlobalPermission(GlobalPermissions.QUALITY_PROFILE_ADMIN); + + String newName = request.mandatoryParam(PARAM_PROFILE_NAME); + String profileKey = request.mandatoryParam(PARAM_PROFILE_KEY); + + profileCopier.copyToName(profileKey, newName); + + response.noContent(); + } +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileCopyActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileCopyActionTest.java new file mode 100644 index 00000000000..500208c7528 --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileCopyActionTest.java @@ -0,0 +1,95 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.qualityprofile.ws; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; +import org.sonar.core.permission.GlobalPermissions; +import org.sonar.server.exceptions.ForbiddenException; +import org.sonar.server.qualityprofile.QProfileCopier; +import org.sonar.server.user.MockUserSession; +import org.sonar.server.ws.WsTester; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +@RunWith(MockitoJUnitRunner.class) +public class QProfileCopyActionTest { + + private WsTester tester; + + // TODO Replace with proper DbTester + EsTester medium test during removal of DaoV2 + @Mock + private QProfileCopier qProfileCopier; + + @Before + public void setUp() throws Exception { + tester = new WsTester(new QProfilesWs( + mock(RuleActivationActions.class), + mock(BulkRuleActivationActions.class), + mock(ProjectAssociationActions.class), + new QProfileCopyAction(qProfileCopier))); + } + + @Test + public void copy_nominal() throws Exception { + MockUserSession.set().setLogin("obiwan").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); + + String fromProfileKey = "sonar-way-xoo2-23456"; + String toName = "Other Sonar Way"; + tester.newPostRequest("api/qualityprofiles", "copy") + .setParam("fromKey", fromProfileKey) + .setParam("toName", toName) + .execute().assertNoContent(); + + verify(qProfileCopier).copyToName(fromProfileKey, toName); + } + + @Test(expected = IllegalArgumentException.class) + public void fail_on_missing_key() throws Exception { + MockUserSession.set().setLogin("obiwan").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); + + tester.newPostRequest("api/qualityprofiles", "copy") + .setParam("name", "Other Sonar Way") + .execute(); + } + + @Test(expected = IllegalArgumentException.class) + public void fail_on_missing_name() throws Exception { + MockUserSession.set().setLogin("obiwan").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); + + tester.newPostRequest("api/qualityprofiles", "copy") + .setParam("key", "sonar-way-xoo1-13245") + .execute(); + } + + @Test(expected = ForbiddenException.class) + public void fail_on_missing_permission() throws Exception { + MockUserSession.set().setLogin("obiwan"); + + tester.newPostRequest("api/qualityprofiles", "copy") + .setParam("key", "sonar-way-xoo1-13245") + .setParam("name", "Hey look I am not quality profile admin!") + .execute(); + } +} -- 2.39.5