]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-9976 add editionBundled flag to response of api/plugins/installed
authorSébastien Lesaint <sebastien.lesaint@sonarsource.com>
Mon, 16 Oct 2017 08:15:41 +0000 (10:15 +0200)
committerGrégoire Aubert <gregoire.aubert@sonarsource.com>
Mon, 23 Oct 2017 15:01:13 +0000 (08:01 -0700)
server/sonar-server/src/main/java/org/sonar/server/plugins/edition/EditionBundledPlugins.java
server/sonar-server/src/main/java/org/sonar/server/plugins/ws/PluginWSCommons.java
server/sonar-server/src/main/resources/org/sonar/server/plugins/ws/example-installed_plugins.json
server/sonar-server/src/test/java/org/sonar/server/plugins/edition/EditionBundledPluginsTest.java [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/plugins/ws/InstalledActionTest.java

index 362f027005b2925ff0e7a63eb97010943f93831b..058958958be1977e8df724109f4f95687f94eeaf 100644 (file)
@@ -20,6 +20,7 @@
 package org.sonar.server.plugins.edition;
 
 import java.util.Arrays;
+import org.sonar.core.platform.PluginInfo;
 import org.sonar.updatecenter.common.Plugin;
 
 public final class EditionBundledPlugins {
@@ -35,4 +36,9 @@ public final class EditionBundledPlugins {
     return SONARSOURCE_ORGANIZATION.equalsIgnoreCase(plugin.getOrganization())
       && Arrays.stream(SONARSOURCE_COMMERCIAL_LICENSES).anyMatch(s -> s.equalsIgnoreCase(plugin.getLicense()));
   }
+
+  public static boolean isEditionBundled(PluginInfo pluginInfo) {
+    return SONARSOURCE_ORGANIZATION.equalsIgnoreCase(pluginInfo.getOrganizationName())
+      && Arrays.stream(SONARSOURCE_COMMERCIAL_LICENSES).anyMatch(s -> s.equalsIgnoreCase(pluginInfo.getLicense()));
+  }
 }
index 82ee4b1a4728cf666334c3fd2604b7f100a66451..759d7a6f659e30bf617614db40dd058611d51be3 100644 (file)
@@ -37,6 +37,7 @@ import org.sonar.api.utils.text.JsonWriter;
 import org.sonar.core.platform.PluginInfo;
 import org.sonar.db.plugin.PluginDto;
 import org.sonar.server.plugins.UpdateCenterMatrixFactory;
+import org.sonar.server.plugins.edition.EditionBundledPlugins;
 import org.sonar.updatecenter.common.Artifact;
 import org.sonar.updatecenter.common.Plugin;
 import org.sonar.updatecenter.common.PluginUpdate;
@@ -110,6 +111,7 @@ public class PluginWSCommons {
     json.prop(PROPERTY_LICENSE, pluginInfo.getLicense());
     json.prop(PROPERTY_ORGANIZATION_NAME, pluginInfo.getOrganizationName());
     json.prop(PROPERTY_ORGANIZATION_URL, pluginInfo.getOrganizationUrl());
+    json.prop(PROPERTY_EDITION_BUNDLED, EditionBundledPlugins.isEditionBundled(pluginInfo));
     json.prop(PROPERTY_HOMEPAGE_URL, pluginInfo.getHomepageUrl());
     json.prop(PROPERTY_ISSUE_TRACKER_URL, pluginInfo.getIssueTrackerUrl());
     json.prop(PROPERTY_IMPLEMENTATION_BUILD, pluginInfo.getImplementationBuild());
index d88f50b376a980a31632e54fd4a09dff6c517e22..e961781b3ab091e5bbb3836bb6586b5edcd507a2 100644 (file)
@@ -8,6 +8,7 @@
       "license": "GNU LGPL 3",
       "organizationName": "SonarSource",
       "organizationUrl": "http://www.sonarsource.com",
+      "editionBundled": false,
       "homepageUrl": "https://redirect.sonarsource.com/plugins/scmgit.html",
       "issueTrackerUrl": "http://jira.sonarsource.com/browse/SONARSCGIT",
       "implementationBuild": "9ce9d330c313c296fab051317cc5ad4b26319e07",
@@ -24,6 +25,7 @@
       "license": "GNU LGPL 3",
       "organizationName": "SonarSource",
       "organizationUrl": "http://www.sonarsource.com",
+      "editionBundled": false,
       "homepageUrl": "https://redirect.sonarsource.com/plugins/java.html",
       "issueTrackerUrl": "http://jira.sonarsource.com/browse/SONARJAVA",
       "implementationBuild": "65396a609ddface8b311a6a665aca92a7da694f1",
@@ -40,6 +42,7 @@
       "license": "GNU LGPL 3",
       "organizationName": "SonarSource",
       "organizationUrl": "http://www.sonarsource.com",
+      "editionBundled": false,
       "homepageUrl": "https://redirect.sonarsource.com/plugins/scmsvn.html",
       "issueTrackerUrl": "http://jira.sonarsource.com/browse/SONARSCSVN",
       "implementationBuild": "213fc8a8b582ff530b12dd4a59a6512be1071234",
diff --git a/server/sonar-server/src/test/java/org/sonar/server/plugins/edition/EditionBundledPluginsTest.java b/server/sonar-server/src/test/java/org/sonar/server/plugins/edition/EditionBundledPluginsTest.java
new file mode 100644 (file)
index 0000000..2687d8f
--- /dev/null
@@ -0,0 +1,178 @@
+/*
+ * 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.plugins.edition;
+
+import java.util.Random;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.core.platform.PluginInfo;
+import org.sonar.updatecenter.common.Plugin;
+
+import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric;
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class EditionBundledPluginsTest {
+  @Rule
+  public ExpectedException expectedException = ExpectedException.none();
+
+  private final Random random = new Random();
+
+  @Test
+  public void isEditionBundled_on_Plugin_fails_with_NPE_if_arg_is_null() {
+    expectedException.expect(NullPointerException.class);
+
+    EditionBundledPlugins.isEditionBundled((Plugin) null);
+  }
+
+  @Test
+  public void isEditionBundled_on_Plugin_returns_false_for_SonarSource_and_non_commercial_license() {
+    Plugin plugin = newPlugin(randomizeCase("SonarSource"), randomAlphanumeric(3));
+
+    assertThat(EditionBundledPlugins.isEditionBundled(plugin)).isFalse();
+  }
+
+  @Test
+  public void isEditionBundled_on_Plugin_returns_false_for_license_SonarSource_and_non_SonarSource_organization() {
+    Plugin plugin = newPlugin(randomAlphanumeric(3), randomizeCase("SonarSource"));
+
+    assertThat(EditionBundledPlugins.isEditionBundled(plugin)).isFalse();
+  }
+
+  @Test
+  public void isEditionBundled_on_Plugin_returns_false_for_license_Commercial_and_non_SonarSource_organization() {
+    Plugin plugin = newPlugin(randomAlphanumeric(3), randomizeCase("Commercial"));
+
+    assertThat(EditionBundledPlugins.isEditionBundled(plugin)).isFalse();
+  }
+
+  @Test
+  public void isEditionBundled_on_Plugin_returns_true_for_organization_SonarSource_and_license_SonarSource_case_insensitive() {
+    Plugin plugin = newPlugin(randomizeCase("SonarSource"), randomizeCase("SonarSource"));
+
+    assertThat(EditionBundledPlugins.isEditionBundled(plugin)).isTrue();
+  }
+
+  @Test
+  public void isEditionBundled_on_Plugin_returns_true_for_organization_SonarSource_and_license_Commercial_case_insensitive() {
+    Plugin plugin = newPlugin(randomizeCase("SonarSource"), randomizeCase("Commercial"));
+
+    assertThat(EditionBundledPlugins.isEditionBundled(plugin)).isTrue();
+  }
+
+  @Test
+  public void isEditionBundled_on_PluginInfo_fails_with_NPE_if_arg_is_null() {
+    expectedException.expect(NullPointerException.class);
+
+    EditionBundledPlugins.isEditionBundled((PluginInfo) null);
+  }
+
+  @Test
+  public void isEditionBundled_on_PluginInfo_returns_false_for_SonarSource_and_non_commercial_license() {
+    PluginInfo pluginInfo = newPluginInfo(randomizeCase("SonarSource"), randomAlphanumeric(3));
+
+    assertThat(EditionBundledPlugins.isEditionBundled(pluginInfo)).isFalse();
+  }
+
+  @Test
+  public void isEditionBundled_on_PluginInfo_returns_false_for_license_SonarSource_and_non_SonarSource_organization() {
+    PluginInfo pluginInfo = newPluginInfo(randomAlphanumeric(3), randomizeCase("SonarSource"));
+
+    assertThat(EditionBundledPlugins.isEditionBundled(pluginInfo)).isFalse();
+  }
+
+  @Test
+  public void isEditionBundled_on_PluginInfo_returns_false_for_license_Commercial_and_non_SonarSource_organization() {
+    PluginInfo pluginInfo = newPluginInfo(randomAlphanumeric(3), randomizeCase("Commercial"));
+
+    assertThat(EditionBundledPlugins.isEditionBundled(pluginInfo)).isFalse();
+  }
+
+  @Test
+  public void isEditionBundled_on_PluginInfo_returns_true_for_organization_SonarSource_and_license_SonarSource_case_insensitive() {
+    PluginInfo pluginInfo = newPluginInfo(randomizeCase("SonarSource"), randomizeCase("SonarSource"));
+
+    assertThat(EditionBundledPlugins.isEditionBundled(pluginInfo)).isTrue();
+  }
+
+  @Test
+  public void isEditionBundled_on_PluginINfo_returns_true_for_organization_SonarSource_and_license_Commercial_case_insensitive() {
+    PluginInfo pluginInfo = newPluginInfo(randomizeCase("SonarSource"), randomizeCase("Commercial"));
+
+    assertThat(EditionBundledPlugins.isEditionBundled(pluginInfo)).isTrue();
+  }
+
+  private String randomizeCase(String s) {
+    return s.chars()
+      .map(c -> random.nextBoolean() ? Character.toUpperCase(c) : Character.toLowerCase(c))
+      .collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append)
+      .toString();
+  }
+
+  private PluginInfo newPluginInfo(String organization, String license) {
+    PluginInfo pluginInfo = new PluginInfo(randomAlphanumeric(2));
+    if (random.nextBoolean()) {
+      pluginInfo.setName(randomAlphanumeric(3));
+    }
+    if (random.nextBoolean()) {
+      pluginInfo.setOrganizationUrl(randomAlphanumeric(4));
+    }
+    if (random.nextBoolean()) {
+      pluginInfo.setIssueTrackerUrl(randomAlphanumeric(5));
+    }
+    if (random.nextBoolean()) {
+      pluginInfo.setIssueTrackerUrl(randomAlphanumeric(6));
+    }
+    if (random.nextBoolean()) {
+      pluginInfo.setBasePlugin(randomAlphanumeric(7));
+    }
+    if (random.nextBoolean()) {
+      pluginInfo.setHomepageUrl(randomAlphanumeric(8));
+    }
+    return pluginInfo
+      .setOrganizationName(organization)
+      .setLicense(license);
+  }
+
+  private Plugin newPlugin(String organization, String license) {
+    Plugin plugin = Plugin.factory(randomAlphanumeric(2));
+    if (random.nextBoolean()) {
+      plugin.setName(randomAlphanumeric(3));
+    }
+    if (random.nextBoolean()) {
+      plugin.setOrganizationUrl(randomAlphanumeric(4));
+    }
+    if (random.nextBoolean()) {
+      plugin.setTermsConditionsUrl(randomAlphanumeric(5));
+    }
+    if (random.nextBoolean()) {
+      plugin.setIssueTrackerUrl(randomAlphanumeric(6));
+    }
+    if (random.nextBoolean()) {
+      plugin.setCategory(randomAlphanumeric(7));
+    }
+    if (random.nextBoolean()) {
+      plugin.setHomepageUrl(randomAlphanumeric(8));
+    }
+    return plugin
+      .setLicense(license)
+      .setOrganization(organization);
+  }
+}
index 9e113765a43f747accba5b6f763089503b6dab02..7da28d8a859c746ad0860e96c60cbe9cdbed4b63 100644 (file)
 package org.sonar.server.plugins.ws;
 
 import com.google.common.base.Optional;
+import com.tngtech.java.junit.dataprovider.DataProvider;
+import com.tngtech.java.junit.dataprovider.DataProviderRunner;
+import com.tngtech.java.junit.dataprovider.UseDataProvider;
 import java.io.File;
 import java.util.Arrays;
+import java.util.Random;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
+import org.junit.runner.RunWith;
 import org.sonar.api.server.ws.Request;
 import org.sonar.api.server.ws.WebService;
 import org.sonar.api.server.ws.WebService.Param;
@@ -47,6 +52,7 @@ import static org.mockito.Mockito.verifyZeroInteractions;
 import static org.mockito.Mockito.when;
 import static org.sonar.test.JsonAssert.assertJson;
 
+@RunWith(DataProviderRunner.class)
 public class InstalledActionTest {
   private static final String DUMMY_CONTROLLER_KEY = "dummy";
   private static final String JSON_EMPTY_PLUGIN_LIST = "{" +
@@ -147,7 +153,8 @@ public class InstalledActionTest {
         "      \"version\": \"1.0\"," +
         "      \"license\": \"license_hey\"," +
         "      \"organizationName\": \"org_name\"," +
-        "      \"organizationUrl\": \"org_url\"," +
+        "      \"organizationUrl\": \"org_url\",\n" +
+        "      \"editionBundled\": false," +
         "      \"homepageUrl\": \"homepage_url\"," +
         "      \"issueTrackerUrl\": \"issueTracker_url\"," +
         "      \"implementationBuild\": \"sou_rev_sha1\"," +
@@ -203,7 +210,8 @@ public class InstalledActionTest {
         "      \"category\":\"cat_1\"," +
         "      \"license\": \"license_hey\"," +
         "      \"organizationName\": \"org_name\"," +
-        "      \"organizationUrl\": \"org_url\"," +
+        "      \"organizationUrl\": \"org_url\",\n" +
+        "      \"editionBundled\": false," +
         "      \"homepageUrl\": \"homepage_url\"," +
         "      \"issueTrackerUrl\": \"issueTracker_url\"," +
         "      \"implementationBuild\": \"sou_rev_sha1\"" +
@@ -252,6 +260,68 @@ public class InstalledActionTest {
         "}");
   }
 
+  @Test
+  @UseDataProvider("editionBundledLicenseValues")
+  public void commercial_plugins_from_SonarSource_has_flag_editionBundled_true_based_on_jar_info(String license) throws Exception {
+    String jarFilename = getClass().getSimpleName() + "/" + "some.jar";
+    Random random = new Random();
+    String organization = random.nextBoolean() ? "SonarSource" : "SONARSOURCE";
+    String pluginKey = "plugKey";
+    when(pluginRepository.getPluginInfos()).thenReturn(of(
+      new PluginInfo(pluginKey)
+        .setName("plugName")
+        .setVersion(Version.create("1.0"))
+        .setLicense(license)
+        .setOrganizationName(organization)
+        .setImplementationBuild("sou_rev_sha1")
+        .setJarFile(new File(getClass().getResource(jarFilename).toURI()))));
+    db.pluginDbTester().insertPlugin(
+      p -> p.setKee(pluginKey),
+      p -> p.setFileHash("abcdplugKey"),
+      p -> p.setUpdatedAt(111111L));
+    // ensure flag editionBundled is computed from jar info by enabling datacenter with other organization and license values
+    UpdateCenter updateCenter = mock(UpdateCenter.class);
+    when(updateCenterMatrixFactory.getUpdateCenter(false)).thenReturn(Optional.of(updateCenter));
+    when(updateCenter.findAllCompatiblePlugins()).thenReturn(
+        singletonList(
+            Plugin.factory(pluginKey)
+                .setOrganization("foo")
+                .setLicense("bar")
+                .setCategory("cat_1")));
+
+
+    underTest.handle(request, response);
+
+    verifyZeroInteractions(updateCenterMatrixFactory);
+    assertJson(response.outputAsString())
+      .isSimilarTo("{" +
+        "  \"plugins\":" +
+        "  [" +
+        "    {" +
+        "      \"key\": \"plugKey\"," +
+        "      \"name\": \"plugName\"," +
+        "      \"license\": \"" + license + "\"," +
+        "      \"organizationName\": \"" + organization + "\"," +
+        "      \"editionBundled\": true" +
+        "    }" +
+        "  ]" +
+        "}");
+  }
+
+  @DataProvider
+  public static Object[][] editionBundledLicenseValues() {
+    return new Object[][] {
+      {"sonarsource"},
+      {"SonarSource"},
+      {"SonaRSOUrce"},
+      {"SONARSOURCE"},
+      {"commercial"},
+      {"Commercial"},
+      {"COMMERCIAL"},
+      {"COmmERCiaL"},
+    };
+  }
+
   @Test
   public void only_one_plugin_can_have_a_specific_name_and_key() throws Exception {
     when(pluginRepository.getPluginInfos()).thenReturn(