From bb373c4a41e454b376c4f6ffb2b7434d11dcc3d2 Mon Sep 17 00:00:00 2001 From: Julien Lancelot Date: Fri, 25 Apr 2014 12:33:53 +0200 Subject: [PATCH] SONAR-4764 Add WS to restore default profiles --- .../server/qualityprofile/QProfileBackup.java | 21 +---- .../ws/QProfileBackupWsHandler.java | 66 ++++++++++++++++ .../server/qualityprofile/ws/QProfilesWs.java | 45 +++++++++++ .../app/controllers/profiles_controller.rb | 8 +- .../qualityprofile/QProfileBackupTest.java | 39 ++------- .../qualityprofile/QProfilesMediumTest.java | 6 +- .../ws/QProfileBackupWsHandlerTest.java | 79 +++++++++++++++++++ .../qualityprofile/ws/QProfilesWsTest.java | 62 +++++++++++++++ .../show_infos.json | 1 + .../show_infos_and_warnings.json | 4 + .../show_warnings.json | 1 + 11 files changed, 276 insertions(+), 56 deletions(-) create mode 100644 sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileBackupWsHandler.java create mode 100644 sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfilesWs.java create mode 100644 sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileBackupWsHandlerTest.java create mode 100644 sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfilesWsTest.java create mode 100644 sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileBackupWsHandlerTest/show_infos.json create mode 100644 sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileBackupWsHandlerTest/show_infos_and_warnings.json create mode 100644 sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileBackupWsHandlerTest/show_warnings.json diff --git a/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileBackup.java b/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileBackup.java index b7276ac7c75..f3627c9de81 100644 --- a/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileBackup.java +++ b/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileBackup.java @@ -132,7 +132,7 @@ public class QProfileBackup implements ServerComponent { * Restore provided profile for a given language. * If a profile with same name than default profile already exists, an exception will be thrown. */ - public QProfileResult restoreProvidedProfilesFromLanguage(String language) { + public QProfileResult restoreDefaultProfilesByLanguage(String language) { checkPermission(UserSession.get()); QProfileResult result = new QProfileResult(); @@ -186,24 +186,9 @@ public class QProfileBackup implements ServerComponent { } /** - * Return the list of existing profile names that match the provided ones for a given language + * Return the list of default profile names for a given language */ - public Collection findExistingProvidedProfileNamesByLanguage(String language) { - Set profiles = newHashSet(); - ListMultimap profilesByName = profilesByName(language, new QProfileResult()); - for (RulesProfile rulesProfile : profilesByName.values()) { - QProfile profile = qProfileLookup.profile(rulesProfile.getName(), language); - if (profile != null) { - profiles.add(profile.name()); - } - } - return profiles; - } - - /** - * Return the list of provided profile names for a given language - */ - public Collection findProvidedProfileNamesByLanguage(String language) { + public Collection findDefaultProfileNamesByLanguage(String language) { Set profiles = newHashSet(); ListMultimap profilesByName = profilesByName(language, new QProfileResult()); for (RulesProfile rulesProfile : profilesByName.values()) { diff --git a/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileBackupWsHandler.java b/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileBackupWsHandler.java new file mode 100644 index 00000000000..5f40133c5a0 --- /dev/null +++ b/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileBackupWsHandler.java @@ -0,0 +1,66 @@ +/* + * 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.RequestHandler; +import org.sonar.api.server.ws.Response; +import org.sonar.api.utils.text.JsonWriter; +import org.sonar.server.qualityprofile.QProfileBackup; +import org.sonar.server.qualityprofile.QProfileResult; + +public class QProfileBackupWsHandler implements RequestHandler { + + private final QProfileBackup qProfileBackup; + + public QProfileBackupWsHandler(QProfileBackup qProfileBackup) { + this.qProfileBackup = qProfileBackup; + } + + @Override + public void handle(Request request, Response response) { + final String language = request.mandatoryParam("language"); + QProfileResult result = qProfileBackup.restoreDefaultProfilesByLanguage(language); + + if (!result.infos().isEmpty() || !result.warnings().isEmpty()) { + JsonWriter json = response.newJsonWriter(); + json.beginObject(); + if (!result.infos().isEmpty()) { + json.name("infos").beginArray(); + for (String info : result.infos()) { + json.value(info); + } + json.endArray(); + } + if (!result.warnings().isEmpty()) { + json.name("warnings").beginArray(); + for (String warning : result.warnings()) { + json.value(warning); + } + json.endArray(); + } + json.endObject().close(); + } else { + response.noContent(); + } + } + +} diff --git a/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfilesWs.java b/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfilesWs.java new file mode 100644 index 00000000000..f269509eafb --- /dev/null +++ b/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfilesWs.java @@ -0,0 +1,45 @@ +/* + * 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.WebService; + +public class QProfilesWs implements WebService { + + private final QProfileBackupWsHandler qProfileBackupWsHandler; + + public QProfilesWs(QProfileBackupWsHandler qProfileBackupWsHandler) { + this.qProfileBackupWsHandler = qProfileBackupWsHandler; + } + + @Override + public void define(Context context) { + NewController controller = context.createController("api/qprofiles") + .setDescription("Quality profiles"); + + controller.createAction("restore_default") + .setDescription("Restore default profiles") + .setSince("4.4") + .setHandler(qProfileBackupWsHandler) + .createParam("language", "Restore default profiles for this language"); + controller.done(); + } +} diff --git a/sonar-server/src/main/webapp/WEB-INF/app/controllers/profiles_controller.rb b/sonar-server/src/main/webapp/WEB-INF/app/controllers/profiles_controller.rb index a6b590acc3b..a6f64601464 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/controllers/profiles_controller.rb +++ b/sonar-server/src/main/webapp/WEB-INF/app/controllers/profiles_controller.rb @@ -66,17 +66,19 @@ class ProfilesController < ApplicationController require_parameters 'language' @language = java_facade.getLanguages().find { |l| l.getKey()==params[:language].to_s } call_backend do - @default_profile_names = Internal.profile_backup.findProvidedProfileNamesByLanguage(@language.getKey()).to_a - @existing_default_profiles = Internal.profile_backup.findExistingProvidedProfileNamesByLanguage(@language.getKey()).to_a + @default_profile_names = Internal.profile_backup.findDefaultProfileNamesByLanguage(@language.getKey()).to_a + profiles = Internal.quality_profiles.profilesByLanguage(@language.getKey()).to_a + @existing_default_profiles = profiles.select{|p| @default_profile_names.find{|default_profile| default_profile == p.name()}}.collect{|p| p.name()} end render :partial => 'profiles/restore_default_form' end # POST /profiles/restore_default?language= def restore_default + verify_post_request require_parameters 'language' call_backend do - @result = Internal.profile_backup.restoreProvidedProfilesFromLanguage(params[:language].to_s) + @result = Internal.profile_backup.restoreDefaultProfilesByLanguage(params[:language].to_s) flash_result(@result) end redirect_to :action => 'index' diff --git a/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileBackupTest.java b/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileBackupTest.java index ad3dfbd5830..a9cddcaebd1 100644 --- a/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileBackupTest.java +++ b/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileBackupTest.java @@ -298,7 +298,7 @@ public class QProfileBackupTest { } @Test - public void restore_provided_profiles_from_language() throws Exception { + public void restore_default_profiles_from_language() throws Exception { String name = "Default"; String language = "java"; @@ -315,7 +315,7 @@ public class QProfileBackupTest { when(qProfileOperations.newProfile(eq(name), eq(language), eq(true), any(UserSession.class), eq(session))).thenReturn(new QProfile().setId(1)); - backup.restoreProvidedProfilesFromLanguage(language); + backup.restoreDefaultProfilesByLanguage(language); verify(qProfileActiveRuleOperations).createActiveRule(eq(1), eq(RuleKey.of("pmd", "rule")), eq("BLOCKER"), eq(session)); verify(qProfileActiveRuleOperations).updateActiveRuleParam(any(ActiveRuleDto.class), eq("max"), eq("10"), eq(session)); @@ -327,7 +327,7 @@ public class QProfileBackupTest { } @Test - public void restore_provided_profiles_from_language_with_multiple_profiles_with_same_name_and_same_language() throws Exception { + public void restore_default_profiles_from_language_with_multiple_profiles_with_same_name_and_same_language() throws Exception { RulesProfile profile1 = RulesProfile.create("Default", "java"); profile1.activateRule(Rule.create("pmd", "rule").setSeverity(RulePriority.BLOCKER), null); ProfileDefinition profileDefinition1 = mock(ProfileDefinition.class); @@ -342,7 +342,7 @@ public class QProfileBackupTest { when(qProfileOperations.newProfile(eq("Default"), eq("java"), eq(true), any(UserSession.class), eq(session))).thenReturn(new QProfile().setId(1)); - backup.restoreProvidedProfilesFromLanguage("java"); + backup.restoreDefaultProfilesByLanguage("java"); verify(qProfileActiveRuleOperations).createActiveRule(eq(1), eq(RuleKey.of("pmd", "rule")), eq("BLOCKER"), eq(session)); verify(qProfileActiveRuleOperations).createActiveRule(eq(1), eq(RuleKey.of("checkstyle", "rule")), eq("MAJOR"), eq(session)); @@ -354,14 +354,14 @@ public class QProfileBackupTest { } @Test - public void not_restore_provided_profiles_from_another_language() throws Exception { + public void not_restore_default_profiles_from_another_language() throws Exception { RulesProfile profile = RulesProfile.create("Default", "java"); profile.activateRule(Rule.create("pmd", "rule").setSeverity(RulePriority.BLOCKER), null); ProfileDefinition profileDefinition = mock(ProfileDefinition.class); when(profileDefinition.createProfile(any(ValidationMessages.class))).thenReturn(profile); definitions.add(profileDefinition); - backup.restoreProvidedProfilesFromLanguage("js"); + backup.restoreDefaultProfilesByLanguage("js"); verifyZeroInteractions(qProfileOperations); verifyZeroInteractions(qProfileActiveRuleOperations); @@ -370,30 +370,7 @@ public class QProfileBackupTest { } @Test - public void find_existing_provided_profiles_by_language() throws Exception { - RulesProfile rulesProfile1 = RulesProfile.create("Basic", "java"); - ProfileDefinition profileDefinition1 = mock(ProfileDefinition.class); - when(profileDefinition1.createProfile(any(ValidationMessages.class))).thenReturn(rulesProfile1); - definitions.add(profileDefinition1); - - RulesProfile rulesProfile2 = RulesProfile.create("Basic", "java"); - ProfileDefinition profileDefinition2 = mock(ProfileDefinition.class); - when(profileDefinition2.createProfile(any(ValidationMessages.class))).thenReturn(rulesProfile2); - definitions.add(profileDefinition2); - - RulesProfile rulesProfile3 = RulesProfile.create("Default", "java"); - ProfileDefinition profileDefinition3 = mock(ProfileDefinition.class); - when(profileDefinition3.createProfile(any(ValidationMessages.class))).thenReturn(rulesProfile3); - definitions.add(profileDefinition3); - - // Only basic profile is existing - when(qProfileLookup.profile("Basic", "java")).thenReturn(new QProfile().setId(1).setName("Basic").setLanguage("java")); - - assertThat(backup.findExistingProvidedProfileNamesByLanguage("java")).containsOnly("Basic"); - } - - @Test - public void find_provided_profile_names_by_language() throws Exception { + public void find_default_profile_names_by_language() throws Exception { RulesProfile rulesProfile1 = RulesProfile.create("Basic", "java"); ProfileDefinition profileDefinition1 = mock(ProfileDefinition.class); when(profileDefinition1.createProfile(any(ValidationMessages.class))).thenReturn(rulesProfile1); @@ -409,7 +386,7 @@ public class QProfileBackupTest { when(profileDefinition3.createProfile(any(ValidationMessages.class))).thenReturn(rulesProfile3); definitions.add(profileDefinition3); - Collection result = backup.findProvidedProfileNamesByLanguage("java"); + Collection result = backup.findDefaultProfileNamesByLanguage("java"); assertThat(result).containsOnly("Basic", "Default"); } } diff --git a/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfilesMediumTest.java b/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfilesMediumTest.java index ea52ce51645..ecbf00a3cc8 100644 --- a/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfilesMediumTest.java +++ b/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfilesMediumTest.java @@ -98,15 +98,13 @@ public class QProfilesMediumTest { Rule rule2 = rules.find(RuleQuery.builder().searchQuery("x2").build()).results().iterator().next(); qProfiles.deactivateRule(qProfiles.profile("Basic", "xoo").id(), rule2.id()); - assertThat(qProfileBackup.findExistingProvidedProfileNamesByLanguage("xoo")).hasSize(1); + assertThat(qProfileBackup.findDefaultProfileNamesByLanguage("xoo")).hasSize(1); // Renamed profile qProfiles.renameProfile(profile.id(), "Old Basic"); - assertThat(qProfileBackup.findExistingProvidedProfileNamesByLanguage("xoo")).isEmpty(); - // Restore default profiles of xoo - qProfileBackup.restoreProvidedProfilesFromLanguage("xoo"); + qProfileBackup.restoreDefaultProfilesByLanguage("xoo"); // Reload profile profile = qProfiles.profile("Basic", "xoo"); diff --git a/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileBackupWsHandlerTest.java b/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileBackupWsHandlerTest.java new file mode 100644 index 00000000000..bd5e43be632 --- /dev/null +++ b/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileBackupWsHandlerTest.java @@ -0,0 +1,79 @@ +/* + * 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.api.server.ws.WsTester; +import org.sonar.server.qualityprofile.QProfileBackup; +import org.sonar.server.qualityprofile.QProfileResult; + +import static com.google.common.collect.Lists.newArrayList; +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class QProfileBackupWsHandlerTest { + + @Mock + QProfileBackup qProfileBackup; + + WsTester tester; + + @Before + public void setUp() throws Exception { + tester = new WsTester(new QProfilesWs(new QProfileBackupWsHandler(qProfileBackup))); + } + + @Test + public void return_empty_result_when_no_infos_or_warnings() throws Exception { + when(qProfileBackup.restoreDefaultProfilesByLanguage("java")).thenReturn(new QProfileResult()); + + WsTester.TestRequest request = tester.newRequest("restore_default").setParam("language", "java"); + request.execute().assertNoContent(); + } + + @Test + public void show_infos() throws Exception { + when(qProfileBackup.restoreDefaultProfilesByLanguage("java")).thenReturn(new QProfileResult().addInfos(newArrayList("Some info"))); + + WsTester.TestRequest request = tester.newRequest("restore_default").setParam("language", "java"); + request.execute().assertJson(getClass(), "show_infos.json"); + } + + @Test + public void show_warnings() throws Exception { + when(qProfileBackup.restoreDefaultProfilesByLanguage("java")).thenReturn(new QProfileResult().addWarnings(newArrayList("Some warning"))); + + WsTester.TestRequest request = tester.newRequest("restore_default").setParam("language", "java"); + request.execute().assertJson(getClass(), "show_warnings.json"); + } + + @Test + public void show_infos_and_warnings() throws Exception { + when(qProfileBackup.restoreDefaultProfilesByLanguage("java")).thenReturn(new QProfileResult().addInfos(newArrayList("Some info")).addWarnings(newArrayList("Some warning"))); + + WsTester.TestRequest request = tester.newRequest("restore_default").setParam("language", "java"); + request.execute().assertJson(getClass(), "show_infos_and_warnings.json"); + } +} diff --git a/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfilesWsTest.java b/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfilesWsTest.java new file mode 100644 index 00000000000..74501b9af40 --- /dev/null +++ b/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfilesWsTest.java @@ -0,0 +1,62 @@ +/* + * 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.api.server.ws.WebService; +import org.sonar.api.server.ws.WsTester; + +import static org.fest.assertions.Assertions.assertThat; + +@RunWith(MockitoJUnitRunner.class) +public class QProfilesWsTest { + + @Mock + QProfileBackupWsHandler qProfileBackupWsHandler; + + WsTester tester; + + @Before + public void setUp() { + tester = new WsTester(new QProfilesWs(qProfileBackupWsHandler)); + } + + @Test + public void define_ws() throws Exception { + WebService.Controller controller = tester.controller("api/qprofiles"); + assertThat(controller).isNotNull(); + assertThat(controller.path()).isEqualTo("api/qprofiles"); + assertThat(controller.description()).isNotEmpty(); + assertThat(controller.actions()).hasSize(1); + + WebService.Action restoreProfiles = controller.action("restore_default"); + assertThat(restoreProfiles).isNotNull(); + assertThat(restoreProfiles.handler()).isNotNull(); + assertThat(restoreProfiles.since()).isEqualTo("4.4"); + assertThat(restoreProfiles.isPost()).isFalse(); + assertThat(restoreProfiles.isInternal()).isFalse(); + assertThat(restoreProfiles.params()).hasSize(1); + } +} diff --git a/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileBackupWsHandlerTest/show_infos.json b/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileBackupWsHandlerTest/show_infos.json new file mode 100644 index 00000000000..b71854a2def --- /dev/null +++ b/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileBackupWsHandlerTest/show_infos.json @@ -0,0 +1 @@ +{"infos":["Some info"]} diff --git a/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileBackupWsHandlerTest/show_infos_and_warnings.json b/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileBackupWsHandlerTest/show_infos_and_warnings.json new file mode 100644 index 00000000000..49b287019d0 --- /dev/null +++ b/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileBackupWsHandlerTest/show_infos_and_warnings.json @@ -0,0 +1,4 @@ +{ + "infos": ["Some info"], + "warnings": ["Some warning"] +} diff --git a/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileBackupWsHandlerTest/show_warnings.json b/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileBackupWsHandlerTest/show_warnings.json new file mode 100644 index 00000000000..256ac20abf9 --- /dev/null +++ b/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileBackupWsHandlerTest/show_warnings.json @@ -0,0 +1 @@ +{"warnings":["Some warning"]} -- 2.39.5