]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-4764 Restore default profiles from ui
authorJulien Lancelot <julien.lancelot@sonarsource.com>
Fri, 25 Apr 2014 08:43:02 +0000 (10:43 +0200)
committerJulien Lancelot <julien.lancelot@sonarsource.com>
Fri, 25 Apr 2014 08:43:11 +0000 (10:43 +0200)
sonar-core/src/main/resources/org/sonar/l10n/core.properties
sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileBackup.java
sonar-server/src/main/webapp/WEB-INF/app/controllers/profiles_controller.rb
sonar-server/src/main/webapp/WEB-INF/app/views/profiles/_restore_default_form.html.erb [new file with mode: 0644]
sonar-server/src/main/webapp/WEB-INF/app/views/profiles/index.html.erb
sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileBackupTest.java
sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfilesMediumTest.java

index e9f2973f509cd347501c2a90f0495b35a5ef760a..6353deb89908aa79d9372fc81c5d4bd2881fd962 100644 (file)
@@ -116,6 +116,7 @@ rename=Rename
 reporter=Reporter
 reset_verb=Reset
 resolution=Resolution
+restore=Restore
 result=Result
 results=Results
 x_results={0} results
@@ -1628,6 +1629,10 @@ quality_profiles.remove_projects_confirm_message=Are you sure that you want to d
 quality_profiles.remove_projects_confirm_button=Remove All
 quality_profiles.copy_x_title=Copy Profile {0}
 quality_profiles.copy_new_name=New name
+quality_profiles.restore_default_profiles=Restore Default Profiles
+quality_profiles.restore_default_profiles_x_language=Restore default profiles for language '{0}'
+quality_profiles.restore_default_profiles_confirmation=Are you sure you want to restore '{0}' profile(s) for '{1}' ?
+quality_profiles.restore_default_profiles_warning=Before restoring default profiles for '{0}', you have to rename or delete profile(s) '{1}'.
 
 #------------------------------------------------------------------------------
 #
index 93f2afe8a17cc7bd4f55992e39ecd0ea3ea2e1cf..b7276ac7c752e364c32afe6902184dbd00041065 100644 (file)
@@ -43,12 +43,10 @@ import org.sonar.server.user.UserSession;
 import java.io.StringReader;
 import java.io.StringWriter;
 import java.io.Writer;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 
 import static com.google.common.collect.Lists.newArrayList;
+import static com.google.common.collect.Sets.newHashSet;
 
 /**
  * Used through ruby code <pre>Internal.profile_backup</pre>
@@ -188,20 +186,32 @@ public class QProfileBackup implements ServerComponent {
   }
 
   /**
-   * Return the list of existing profiles that match the provided ones for a given language
+   * Return the list of existing profile names that match the provided ones for a given language
    */
-  public List<QProfile> findProvidedProfilesByLanguage(String language) {
-    List<QProfile> profiles = newArrayList();
+  public Collection<String> findExistingProvidedProfileNamesByLanguage(String language) {
+    Set<String> profiles = newHashSet();
     ListMultimap<String, RulesProfile> profilesByName = profilesByName(language, new QProfileResult());
     for (RulesProfile rulesProfile : profilesByName.values()) {
       QProfile profile = qProfileLookup.profile(rulesProfile.getName(), language);
       if (profile != null) {
-        profiles.add(profile);
+        profiles.add(profile.name());
       }
     }
     return profiles;
   }
 
+  /**
+   * Return the list of provided profile names for a given language
+   */
+  public Collection<String> findProvidedProfileNamesByLanguage(String language) {
+    Set<String> profiles = newHashSet();
+    ListMultimap<String, RulesProfile> profilesByName = profilesByName(language, new QProfileResult());
+    for (RulesProfile rulesProfile : profilesByName.values()) {
+      profiles.add(rulesProfile.getName());
+    }
+    return profiles;
+  }
+
   private void checkProfileDoesNotExists(RulesProfile importedProfile, boolean deleteExisting, DatabaseSession hibernateSession) {
     RulesProfile existingProfile = hibernateSession.getSingleResult(RulesProfile.class, "name", importedProfile.getName(), "language", importedProfile.getLanguage());
     if (existingProfile != null && !deleteExisting) {
index 404e89d1855bb5d50e1f378ea7372c8ede676726..a6b590acc3bf6709f5f9b321a65dc497df7cd0c4 100644 (file)
@@ -59,6 +59,29 @@ class ProfilesController < ApplicationController
     redirect_to :action => 'index'
   end
 
+  # Modal window to restore default profiles
+  # GET /profiles/restore_default_form/<profile id>
+  def restore_default_form
+    verify_ajax_request
+    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
+    end
+    render :partial => 'profiles/restore_default_form'
+  end
+
+  # POST /profiles/restore_default?language=<language>
+  def restore_default
+    require_parameters 'language'
+    call_backend do
+      @result = Internal.profile_backup.restoreProvidedProfilesFromLanguage(params[:language].to_s)
+      flash_result(@result)
+    end
+    redirect_to :action => 'index'
+  end
+
   # POST /profiles/delete/<id>
   def delete
     verify_post_request
diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/profiles/_restore_default_form.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/profiles/_restore_default_form.html.erb
new file mode 100644 (file)
index 0000000..f650cfb
--- /dev/null
@@ -0,0 +1,22 @@
+<form id="restore-default-profiles-form" action="profiles/restore_default" method="POST">
+  <fieldset>
+    <input type="hidden" name="language" value="<%= @language.getKey() -%>"/>
+
+    <div class="modal-head">
+      <h2><%= h message('quality_profiles.restore_default_profiles_x_language', :params => @language.getName()) -%></h2>
+    </div>
+
+    <div class="modal-body">
+      <% if @existing_default_profiles.empty? %>
+        <%= h message('quality_profiles.restore_default_profiles_confirmation', :params => [@default_profile_names.join('\', \''), @language.getName()]) -%>
+      <% else %>
+        <%= h message('quality_profiles.restore_default_profiles_warning', :params => [@language.getName(), @existing_default_profiles.join('\', \'')]) -%>
+      <% end %>
+    </div>
+
+    <div class="modal-foot">
+      <input type="submit" value="<%= h message('restore') -%>" id="restore-default-profiles-submit" <%= 'disabled=disabled' unless @existing_default_profiles.empty? -%>/>
+      <a href="#" onclick="return closeModalWindow()" id="restore-default-profiles-cancel"><%= h message('cancel') -%></a>
+    </div>
+  </fieldset>
+</form>
index 6b307cc7bd2b6a3a92377122e5723f61adcbce69..26cb167d7dd4faa4a4b8370b45c2b92cf2e2fcce 100644 (file)
              class="open-modal link-action"><%= message('create') -%></a>
         </li>
       </ul>
+      <ul style="float: right" class="horizontal">
+        <li class="marginleft10">
+          <i class="icon-plus"></i>
+          <a id="create-link-<%= language.getKey() -%>" href="<%= ApplicationController.root_context -%>/profiles/restore_default_form?language=<%= u language.getKey() -%>"
+             class="open-modal link-action"><%= message('quality_profiles.restore_default_profiles') -%></a>
+        </li>
+      </ul>
     <% end %>
     <h2><%= message('quality_profiles.x_language_profiles', :params => language.getName()) -%></h2>
   </div>
index dec4f775dd4a87ce3ac8913fb8a7b8ffd942b10f..ad3dfbd58306717f501d47b76505d5c30ca6fb7b 100644 (file)
@@ -50,6 +50,7 @@ import org.sonar.server.user.UserSession;
 
 import java.io.Reader;
 import java.io.Writer;
+import java.util.Collection;
 import java.util.List;
 
 import static com.google.common.collect.Lists.newArrayList;
@@ -369,21 +370,46 @@ public class QProfileBackupTest {
   }
 
   @Test
-  public void find_provided_profiles_by_language() throws Exception {
+  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("Default", "java");
+    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));
+    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 {
+    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("Default", "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);
 
-    List<QProfile> result = backup.findProvidedProfilesByLanguage("java");
-    assertThat(result).hasSize(1);
+    Collection<String> result = backup.findProvidedProfileNamesByLanguage("java");
+    assertThat(result).containsOnly("Basic", "Default");
   }
 }
index 26830e2e1f655762c85d60e4d9e41703aab2c6df..ea52ce51645bbfaff810ed8e34693a1b0d040576 100644 (file)
@@ -62,14 +62,21 @@ public class QProfilesMediumTest {
 
     assertThat(qProfiles.searchProfileRules(ProfileRuleQuery.create(profile.id()), Paging.create(10, 1)).rules()).hasSize(2);
 
-    QProfileRule qProfileRule = qProfiles.searchProfileRules(ProfileRuleQuery.create(profile.id()).setNameOrKey("x1"), Paging.create(10, 1)).rules().get(0);
-    assertThat(qProfileRule.key()).isEqualTo("x1");
-    assertThat(qProfileRule.severity()).isEqualTo("MAJOR");
-    assertThat(qProfileRule.params()).hasSize(1);
-
-    QProfileRuleParam qProfileRuleParam = qProfileRule.params().get(0);
-    assertThat(qProfileRuleParam.key()).isEqualTo("acceptWhitespace");
-    assertThat(qProfileRuleParam.value()).isEqualTo("true");
+    // Rule x1
+    QProfileRule qProfileRule1 = qProfiles.searchProfileRules(ProfileRuleQuery.create(profile.id()).setNameOrKey("x1"), Paging.create(10, 1)).rules().get(0);
+    assertThat(qProfileRule1.key()).isEqualTo("x1");
+    assertThat(qProfileRule1.severity()).isEqualTo("MAJOR");
+    assertThat(qProfileRule1.params()).hasSize(1);
+
+    QProfileRuleParam qProfileRule1Param = qProfileRule1.params().get(0);
+    assertThat(qProfileRule1Param.key()).isEqualTo("acceptWhitespace");
+    assertThat(qProfileRule1Param.value()).isEqualTo("true");
+
+    // Rule x2
+    QProfileRule qProfileRule2 = qProfiles.searchProfileRules(ProfileRuleQuery.create(profile.id()).setNameOrKey("x2"), Paging.create(10, 1)).rules().get(0);
+    assertThat(qProfileRule2.key()).isEqualTo("x2");
+    assertThat(qProfileRule2.severity()).isEqualTo("BLOCKER");
+    assertThat(qProfileRule2.params()).isEmpty();
   }
 
   @Test
@@ -91,12 +98,12 @@ 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.findProvidedProfilesByLanguage("xoo")).hasSize(1);
+    assertThat(qProfileBackup.findExistingProvidedProfileNamesByLanguage("xoo")).hasSize(1);
 
     // Renamed profile
     qProfiles.renameProfile(profile.id(), "Old Basic");
 
-    assertThat(qProfileBackup.findProvidedProfilesByLanguage("xoo")).isEmpty();
+    assertThat(qProfileBackup.findExistingProvidedProfileNamesByLanguage("xoo")).isEmpty();
 
     // Restore default profiles of xoo
     qProfileBackup.restoreProvidedProfilesFromLanguage("xoo");