From: Simon Brandhof Date: Mon, 13 Mar 2017 14:34:56 +0000 (+0100) Subject: SONAR-8857 support organizations in QProfileReference X-Git-Tag: 6.4-RC1~668 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=0ac69a06b1bad1ad68484205bef10c1cfaa8c602;p=sonarqube.git SONAR-8857 support organizations in QProfileReference + new method QProfileWsSupport#getProfile(DbSession,QProfileRef) --- diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileFactory.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileFactory.java index 0faeb66e105..73ec2fc3e6c 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileFactory.java +++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileFactory.java @@ -37,6 +37,7 @@ import org.sonar.db.qualityprofile.ActiveRuleDto; import org.sonar.db.qualityprofile.QualityProfileDto; import org.sonar.server.exceptions.BadRequestException; import org.sonar.server.exceptions.NotFoundException; +import org.sonar.server.qualityprofile.ws.QProfileReference; import static org.sonar.server.qualityprofile.ActiveRuleChange.Type.DEACTIVATED; import static org.sonar.server.ws.WsUtils.checkFound; @@ -160,6 +161,10 @@ public class QProfileFactory { db.qualityProfileDao().update(session, profile.setDefault(true)); } + /** + * @deprecated replaced by {@link org.sonar.server.qualityprofile.ws.QProfileWsSupport#getProfile(DbSession, QProfileReference)} + */ + @Deprecated public QualityProfileDto find(DbSession dbSession, QProfileRef ref) { if (ref.hasKey()) { return findByKey(dbSession, ref.getKey()); diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileRef.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileRef.java index 150fed7ad29..098b02da4d8 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileRef.java +++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileRef.java @@ -23,6 +23,7 @@ import javax.annotation.Nullable; import org.sonar.api.resources.Languages; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.WebService; +import org.sonar.server.qualityprofile.ws.QProfileReference; import org.sonar.server.util.LanguageParamUtils; import static com.google.common.base.Preconditions.checkArgument; @@ -36,7 +37,10 @@ import static org.apache.commons.lang.StringUtils.isEmpty; *
  • by its key
  • *
  • by the couple {language, name}
  • * + * + * @deprecated replaced by {@link QProfileReference} */ +@Deprecated public class QProfileRef { public static final String PARAM_LANGUAGE = "language"; diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileReference.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileReference.java new file mode 100644 index 00000000000..2a531054853 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileReference.java @@ -0,0 +1,187 @@ +/* + * 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.qualityprofile.ws; + +import java.util.Optional; +import javax.annotation.Nullable; +import org.sonar.api.resources.Languages; +import org.sonar.api.server.ws.Request; +import org.sonar.api.server.ws.WebService; +import org.sonar.server.util.LanguageParamUtils; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkState; +import static java.util.Objects.requireNonNull; +import static org.apache.commons.lang.StringUtils.isEmpty; +import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_ORGANIZATION; + +/** + * Reference to a Quality profile as defined by requests to web services api/qualityprofiles. + * The two exclusive options to reference a profile are: + * + */ +public class QProfileReference { + + public static final String DEFAULT_PARAM_PROFILE_KEY = "profileKey"; + public static final String DEFAULT_PARAM_LANGUAGE = "language"; + public static final String DEFAULT_PARAM_PROFILE_NAME = "profileName"; + + private enum Type { + KEY, NAME + } + + private final Type type; + private final String key; + private final String organizationKey; + private final String language; + private final String name; + + private QProfileReference(Type type, @Nullable String key, @Nullable String organizationKey, @Nullable String language, @Nullable String name) { + this.type = type; + if (type == Type.KEY) { + this.key = requireNonNull(key); + this.organizationKey = null; + this.language = null; + this.name = null; + } else { + this.key = null; + this.organizationKey = organizationKey; + this.language = requireNonNull(language); + this.name = requireNonNull(name); + } + } + + /** + * @return {@code true} if key is defined and {@link #getKey()} can be called. If {@code false}, then + * the couple {language, name} is defined and the methods {@link #getLanguage()}/{@link #getName()} + * can be called. + */ + public boolean hasKey() { + return type == Type.KEY; + } + + /** + * @return non-null key + * @throws IllegalStateException if {@link #hasKey()} does not return {@code true} + */ + public String getKey() { + checkState(key != null, "Key is not defined. Please call hasKey()."); + return key; + } + + /** + * @return key of organization. It is empty when {@link #hasKey()} is {@code true} or if {@link #hasKey()} is + * {@code false} and the default organization must be used. + */ + public Optional getOrganizationKey() { + checkState(type == Type.NAME, "Organization is not defined. Please call hasKey()."); + return Optional.ofNullable(organizationKey); + } + + /** + * @return non-null language + * @throws IllegalStateException if {@link #hasKey()} does not return {@code false} + */ + public String getLanguage() { + checkState(type == Type.NAME, "Language is not defined. Please call hasKey()."); + return language; + } + + /** + * @return non-null name + * @throws IllegalStateException if {@link #hasKey()} does not return {@code false} + */ + public String getName() { + checkState(type == Type.NAME, "Name is not defined. Please call hasKey()."); + return name; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + QProfileReference that = (QProfileReference) o; + if (key != null ? !key.equals(that.key) : (that.key != null)) { + return false; + } + if (organizationKey != null ? !organizationKey.equals(that.organizationKey) : (that.organizationKey != null)) { + return false; + } + if (language != null ? !language.equals(that.language) : (that.language != null)) { + return false; + } + return name != null ? name.equals(that.name) : (that.name == null); + + } + + @Override + public int hashCode() { + int result = key != null ? key.hashCode() : 0; + result = 31 * result + (organizationKey != null ? organizationKey.hashCode() : 0); + result = 31 * result + (language != null ? language.hashCode() : 0); + result = 31 * result + (name != null ? name.hashCode() : 0); + return result; + } + + public static QProfileReference from(Request request) { + String key = request.param(DEFAULT_PARAM_PROFILE_KEY); + String organizationKey = request.param(PARAM_ORGANIZATION); + String lang = request.param(DEFAULT_PARAM_LANGUAGE); + String name = request.param(DEFAULT_PARAM_PROFILE_NAME); + return from(key, organizationKey, lang, name); + } + + public static QProfileReference from(@Nullable String key, @Nullable String organizationKey, @Nullable String lang, @Nullable String name) { + if (key != null) { + checkArgument(isEmpty(organizationKey) && isEmpty(lang) && isEmpty(name), "Either key or tuple organization/language/name must be set"); + return fromKey(key); + } + checkArgument(!isEmpty(lang) && !isEmpty(name), "Both profile language and name must be set"); + return fromName(organizationKey, lang, name); + } + + public static QProfileReference fromKey(String key) { + return new QProfileReference(Type.KEY, key, null, null, null); + } + + public static QProfileReference fromName(@Nullable String organizationKey, String lang, String name) { + return new QProfileReference(Type.NAME, null, organizationKey, requireNonNull(lang), requireNonNull(name)); + } + + public static void defineParams(WebService.NewAction action, Languages languages) { + action.createParam(DEFAULT_PARAM_PROFILE_KEY) + .setDescription("A quality profile key. Either this parameter, or a combination of profileName + language must be set.") + .setExampleValue("sonar-way-java-12345"); + action.createParam(DEFAULT_PARAM_PROFILE_NAME) + .setDescription("A quality profile name. If this parameter is set, profileKey must not be set and language must be set to disambiguate.") + .setExampleValue("Sonar way"); + action.createParam(DEFAULT_PARAM_LANGUAGE) + .setDescription("A quality profile language. If this parameter is set, profileKey must not be set and profileName must be set to disambiguate.") + .setPossibleValues(LanguageParamUtils.getLanguageKeys(languages)) + .setExampleValue("js"); + } +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileWsSupport.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileWsSupport.java index 98cebdae6a8..17afb81bc91 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileWsSupport.java +++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileWsSupport.java @@ -33,6 +33,7 @@ import org.sonar.server.user.UserSession; import org.sonar.server.ws.WsUtils; import static org.sonar.db.permission.OrganizationPermission.ADMINISTER_QUALITY_PROFILES; +import static org.sonar.server.ws.WsUtils.checkFound; import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_ORGANIZATION; @ServerSide @@ -60,7 +61,7 @@ public class QProfileWsSupport { .orElseGet(defaultOrganizationProvider.get()::getKey); return WsUtils.checkFoundWithOptional( dbClient.organizationDao().selectByKey(dbSession, organizationOrDefaultKey), - "No organizationDto with key '%s'", organizationOrDefaultKey); + "No organization with key '%s'", organizationOrDefaultKey); } /** @@ -83,11 +84,11 @@ public class QProfileWsSupport { public NewParam createOrganizationParam(NewAction create) { return create - .createParam(PARAM_ORGANIZATION) - .setDescription("Organization key") - .setRequired(false) - .setInternal(true) - .setExampleValue("my-org"); + .createParam(PARAM_ORGANIZATION) + .setDescription("Organization key") + .setRequired(false) + .setInternal(true) + .setExampleValue("my-org"); } /** @@ -98,4 +99,20 @@ public class QProfileWsSupport { return dbClient.organizationDao().selectByKey(dbSession, defaultOrganizationProvider.get().getKey()) .orElseThrow(() -> new IllegalStateException("Could not find default organization")); } + + /** + * Get the Quality profile specified by the reference {@code ref}. + * + * @throws org.sonar.server.exceptions.NotFoundException if the specified organization or profile do not exist + */ + public QualityProfileDto getProfile(DbSession dbSession, QProfileReference ref) { + QualityProfileDto profile; + if (ref.hasKey()) { + profile = dbClient.qualityProfileDao().selectByKey(dbSession, ref.getKey()); + } else { + OrganizationDto org = getOrganizationByKey(dbSession, ref.getOrganizationKey().orElse(null)); + profile = dbClient.qualityProfileDao().selectByNameAndLanguage(org, ref.getName(), ref.getLanguage(), dbSession); + } + return checkFound(profile, "Quality Profile does not exist"); + } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileRefTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileRefTest.java new file mode 100644 index 00000000000..1e9bbb4bf02 --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileRefTest.java @@ -0,0 +1,189 @@ +/* + * 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.qualityprofile; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.sonar.api.resources.Language; +import org.sonar.api.resources.Languages; +import org.sonar.api.server.ws.WebService; +import org.sonar.api.server.ws.internal.SimpleGetRequest; +import org.sonar.server.ws.WsTester; + +import static org.assertj.core.api.Assertions.assertThat; + +public class QProfileRefTest { + + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + @Test + public void create_ref_by_key() { + QProfileRef ref = QProfileRef.fromKey("foo"); + assertThat(ref.hasKey()).isTrue(); + assertThat(ref.getKey()).isEqualTo("foo"); + } + + @Test + public void getLanguage_throws_ISE_if_key_ref() { + QProfileRef ref = QProfileRef.fromKey("foo"); + + expectedException.expect(IllegalStateException.class); + ref.getLanguage(); + } + + @Test + public void getName_throws_ISE_if_key_ref() { + QProfileRef ref = QProfileRef.fromKey("foo"); + + expectedException.expect(IllegalStateException.class); + ref.getName(); + } + + @Test + public void create_ref_by_name() { + QProfileRef ref = QProfileRef.fromName("js", "Sonar way"); + assertThat(ref.hasKey()).isFalse(); + assertThat(ref.getLanguage()).isEqualTo("js"); + assertThat(ref.getName()).isEqualTo("Sonar way"); + } + + @Test + public void getKey_throws_ISE_if_name_ref() { + QProfileRef ref = QProfileRef.fromName("js", "Sonar way"); + + expectedException.expect(IllegalStateException.class); + ref.getKey(); + } + + @Test + public void create_key_ref_from_ws_request() { + SimpleGetRequest req = new SimpleGetRequest(); + req.setParam("profileKey", "foo"); + + QProfileRef ref = QProfileRef.from(req); + assertThat(ref.getKey()).isEqualTo("foo"); + } + + @Test + public void create_name_ref_from_ws_request() { + SimpleGetRequest req = new SimpleGetRequest(); + req.setParam("language", "js"); + req.setParam("profileName", "Sonar way"); + + QProfileRef ref = QProfileRef.from(req); + assertThat(ref.getLanguage()).isEqualTo("js"); + assertThat(ref.getName()).isEqualTo("Sonar way"); + } + + @Test + public void create_name_ref_throws_IAE_if_language_is_missing() { + SimpleGetRequest req = new SimpleGetRequest(); + req.setParam(QProfileRef.PARAM_PROFILE_KEY, "the key"); + req.setParam(QProfileRef.PARAM_PROFILE_NAME, "the name"); + + expectedException.expect(IllegalArgumentException.class); + QProfileRef.from(req); + } + + @Test + public void throw_IAE_if_request_does_not_define_ref() { + SimpleGetRequest req = new SimpleGetRequest(); + + expectedException.expect(IllegalArgumentException.class); + QProfileRef.from(req); + } + + @Test + public void define_ws_parameters() { + WsTester wsTester = new WsTester(); + WebService.NewController controller = wsTester.context().createController("api/qualityprofiles"); + WebService.NewAction newAction = controller.createAction("do").setHandler((request, response) -> { + }); + + Languages languages = new Languages(new FakeLanguage("java"), new FakeLanguage("js")); + QProfileRef.defineParams(newAction, languages); + + controller.done(); + WebService.Action action = wsTester.controller("api/qualityprofiles").action("do"); + assertThat(action.param("language")).isNotNull(); + assertThat(action.param("language").possibleValues()).containsOnly("java", "js"); + assertThat(action.param("profileKey")).isNotNull(); + assertThat(action.param("profileName")).isNotNull(); + } + + @Test + public void test_equals_and_hashCode_of_key_ref() { + QProfileRef key1 = QProfileRef.fromKey("one"); + QProfileRef key1bis = QProfileRef.fromKey("one"); + QProfileRef key2 = QProfileRef.fromKey("two"); + QProfileRef name = QProfileRef.fromName("js", "one"); + + assertThat(key1.equals(key1)).isTrue(); + assertThat(key1.equals(key1bis)).isTrue(); + assertThat(key1.equals(key2)).isFalse(); + assertThat(key1.equals(name)).isFalse(); + + assertThat(key1.hashCode()).isEqualTo(key1.hashCode()); + assertThat(key1.hashCode()).isEqualTo(key1bis.hashCode()); + } + + @Test + public void test_equals_and_hashCode_of_name_ref() { + QProfileRef name1 = QProfileRef.fromName("js", "one"); + QProfileRef name1bis = QProfileRef.fromName("js", "one"); + QProfileRef name2 = QProfileRef.fromName("js", "two"); + QProfileRef name1OtherLang = QProfileRef.fromName("java", "one"); + QProfileRef key = QProfileRef.fromKey("one"); + + assertThat(name1.equals(name1)).isTrue(); + assertThat(name1.equals(name1bis)).isTrue(); + assertThat(name1.equals(name2)).isFalse(); + assertThat(name1.equals(name1OtherLang)).isFalse(); + assertThat(name1.equals(key)).isFalse(); + + assertThat(name1.hashCode()).isEqualTo(name1.hashCode()); + assertThat(name1.hashCode()).isEqualTo(name1bis.hashCode()); + } + + private static class FakeLanguage implements Language { + private final String key; + + public FakeLanguage(String key) { + this.key = key; + } + + @Override + public String getKey() { + return key; + } + + @Override + public String getName() { + return key; + } + + @Override + public String[] getFileSuffixes() { + throw new UnsupportedOperationException(); + } + } +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileRefTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileRefTest.java deleted file mode 100644 index 6db5c4305b3..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileRefTest.java +++ /dev/null @@ -1,192 +0,0 @@ -/* - * 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.qualityprofile.ws; - -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.sonar.api.resources.Language; -import org.sonar.api.resources.Languages; -import org.sonar.api.server.ws.WebService; -import org.sonar.api.server.ws.internal.SimpleGetRequest; -import org.sonar.server.qualityprofile.QProfileRef; -import org.sonar.server.ws.WsTester; - -import static org.assertj.core.api.Assertions.assertThat; - - -public class QProfileRefTest { - - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - @Test - public void create_ref_by_key() { - QProfileRef ref = QProfileRef.fromKey("foo"); - assertThat(ref.hasKey()).isTrue(); - assertThat(ref.getKey()).isEqualTo("foo"); - } - - @Test - public void getLanguage_throws_ISE_if_key_ref() { - QProfileRef ref = QProfileRef.fromKey("foo"); - - expectedException.expect(IllegalStateException.class); - ref.getLanguage(); - } - - @Test - public void getName_throws_ISE_if_key_ref() { - QProfileRef ref = QProfileRef.fromKey("foo"); - - expectedException.expect(IllegalStateException.class); - ref.getName(); - } - - @Test - public void create_ref_by_name() { - QProfileRef ref = QProfileRef.fromName("js", "Sonar way"); - assertThat(ref.hasKey()).isFalse(); - assertThat(ref.getLanguage()).isEqualTo("js"); - assertThat(ref.getName()).isEqualTo("Sonar way"); - } - - @Test - public void getKey_throws_ISE_if_name_ref() { - QProfileRef ref = QProfileRef.fromName("js", "Sonar way"); - - expectedException.expect(IllegalStateException.class); - ref.getKey(); - } - - - @Test - public void create_key_ref_from_ws_request() { - SimpleGetRequest req = new SimpleGetRequest(); - req.setParam("profileKey", "foo"); - - QProfileRef ref = QProfileRef.from(req); - assertThat(ref.getKey()).isEqualTo("foo"); - } - - @Test - public void create_name_ref_from_ws_request() { - SimpleGetRequest req = new SimpleGetRequest(); - req.setParam("language", "js"); - req.setParam("profileName", "Sonar way"); - - QProfileRef ref = QProfileRef.from(req); - assertThat(ref.getLanguage()).isEqualTo("js"); - assertThat(ref.getName()).isEqualTo("Sonar way"); - } - - @Test - public void create_name_ref_throws_IAE_if_language_is_missing() { - SimpleGetRequest req = new SimpleGetRequest(); - req.setParam(QProfileRef.PARAM_PROFILE_KEY, "the key"); - req.setParam(QProfileRef.PARAM_PROFILE_NAME, "the name"); - - expectedException.expect(IllegalArgumentException.class); - QProfileRef.from(req); - } - - @Test - public void throw_IAE_if_request_does_not_define_ref() { - SimpleGetRequest req = new SimpleGetRequest(); - - expectedException.expect(IllegalArgumentException.class); - QProfileRef.from(req); - } - - @Test - public void define_ws_parameters() { - WsTester wsTester = new WsTester(); - WebService.NewController controller = wsTester.context().createController("api/qualityprofiles"); - WebService.NewAction newAction = controller.createAction("do").setHandler((request, response) -> { - }); - - Languages languages = new Languages(new FakeLanguage("java"), new FakeLanguage("js")); - QProfileRef.defineParams(newAction, languages); - - controller.done(); - WebService.Action action = wsTester.controller("api/qualityprofiles").action("do"); - assertThat(action.param("language")).isNotNull(); - assertThat(action.param("language").possibleValues()).containsOnly("java", "js"); - assertThat(action.param("profileKey")).isNotNull(); - assertThat(action.param("profileName")).isNotNull(); - } - - @Test - public void test_equals_and_hashCode_of_key_ref() { - QProfileRef key1 = QProfileRef.fromKey("one"); - QProfileRef key1bis = QProfileRef.fromKey("one"); - QProfileRef key2 = QProfileRef.fromKey("two"); - QProfileRef name = QProfileRef.fromName("js", "one"); - - assertThat(key1.equals(key1)).isTrue(); - assertThat(key1.equals(key1bis)).isTrue(); - assertThat(key1.equals(key2)).isFalse(); - assertThat(key1.equals(name)).isFalse(); - - assertThat(key1.hashCode()).isEqualTo(key1.hashCode()); - assertThat(key1.hashCode()).isEqualTo(key1bis.hashCode()); - } - - @Test - public void test_equals_and_hashCode_of_name_ref() { - QProfileRef name1 = QProfileRef.fromName("js", "one"); - QProfileRef name1bis = QProfileRef.fromName("js", "one"); - QProfileRef name2 = QProfileRef.fromName("js", "two"); - QProfileRef name1OtherLang = QProfileRef.fromName("java", "one"); - QProfileRef key = QProfileRef.fromKey("one"); - - assertThat(name1.equals(name1)).isTrue(); - assertThat(name1.equals(name1bis)).isTrue(); - assertThat(name1.equals(name2)).isFalse(); - assertThat(name1.equals(name1OtherLang)).isFalse(); - assertThat(name1.equals(key)).isFalse(); - - assertThat(name1.hashCode()).isEqualTo(name1.hashCode()); - assertThat(name1.hashCode()).isEqualTo(name1bis.hashCode()); - } - - private static class FakeLanguage implements Language { - private final String key; - - public FakeLanguage(String key) { - this.key = key; - } - - @Override - public String getKey() { - return key; - } - - @Override - public String getName() { - return key; - } - - @Override - public String[] getFileSuffixes() { - throw new UnsupportedOperationException(); - } - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileReferenceTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileReferenceTest.java new file mode 100644 index 00000000000..fd4b0c13675 --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileReferenceTest.java @@ -0,0 +1,206 @@ +/* + * 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.qualityprofile.ws; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.sonar.api.resources.Languages; +import org.sonar.api.server.ws.WebService; +import org.sonar.api.server.ws.internal.SimpleGetRequest; +import org.sonar.server.ws.WsTester; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.sonar.server.language.LanguageTesting.newLanguage; + +public class QProfileReferenceTest { + + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + @Test + public void fromKey_creates_reference_by_key() { + QProfileReference ref = QProfileReference.fromKey("foo"); + assertThat(ref.hasKey()).isTrue(); + assertThat(ref.getKey()).isEqualTo("foo"); + } + + @Test + public void getLanguage_throws_ISE_on_reference_by_key() { + QProfileReference ref = QProfileReference.fromKey("foo"); + + expectedException.expect(IllegalStateException.class); + expectedException.expectMessage("Language is not defined. Please call hasKey()."); + ref.getLanguage(); + } + + @Test + public void getName_throws_ISE_on_reference_by_key() { + QProfileReference ref = QProfileReference.fromKey("foo"); + + expectedException.expect(IllegalStateException.class); + expectedException.expectMessage("Name is not defined. Please call hasKey()."); + ref.getName(); + } + + @Test + public void fromName_creates_reference_by_name_on_default_organization() { + QProfileReference ref = QProfileReference.fromName(null, "js", "Sonar way"); + assertThat(ref.hasKey()).isFalse(); + assertThat(ref.getOrganizationKey()).isEmpty(); + assertThat(ref.getLanguage()).isEqualTo("js"); + assertThat(ref.getName()).isEqualTo("Sonar way"); + } + + @Test + public void fromName_creates_reference_by_name_on_specified_organization() { + QProfileReference ref = QProfileReference.fromName("my-org", "js", "Sonar way"); + assertThat(ref.hasKey()).isFalse(); + assertThat(ref.getOrganizationKey()).hasValue("my-org"); + assertThat(ref.getLanguage()).isEqualTo("js"); + assertThat(ref.getName()).isEqualTo("Sonar way"); + } + + @Test + public void getKey_throws_ISE_on_reference_by_name() { + QProfileReference ref = QProfileReference.fromName(null, "js", "Sonar way"); + + expectedException.expect(IllegalStateException.class); + expectedException.expectMessage("Key is not defined. Please call hasKey()."); + + ref.getKey(); + } + + @Test + public void getOrganization_throws_ISE_on_reference_by_key() { + QProfileReference ref = QProfileReference.fromKey("foo"); + + expectedException.expect(IllegalStateException.class); + expectedException.expectMessage("Organization is not defined. Please call hasKey()."); + + ref.getOrganizationKey(); + } + + @Test + public void from_reads_request_parameters_and_creates_reference_by_key() { + SimpleGetRequest req = new SimpleGetRequest(); + req.setParam("profileKey", "foo"); + + QProfileReference ref = QProfileReference.from(req); + assertThat(ref.getKey()).isEqualTo("foo"); + } + + @Test + public void from_reads_request_parameters_and_creates_reference_by_name_on_default_organization() { + SimpleGetRequest req = new SimpleGetRequest(); + req.setParam("language", "js"); + req.setParam("profileName", "Sonar way"); + + QProfileReference ref = QProfileReference.from(req); + assertThat(ref.getOrganizationKey()).isEmpty(); + assertThat(ref.getLanguage()).isEqualTo("js"); + assertThat(ref.getName()).isEqualTo("Sonar way"); + } + + @Test + public void from_reads_request_parameters_and_creates_reference_by_name_on_specified_organization() { + SimpleGetRequest req = new SimpleGetRequest(); + req.setParam("organization", "my-org"); + req.setParam("language", "js"); + req.setParam("profileName", "Sonar way"); + + QProfileReference ref = QProfileReference.from(req); + assertThat(ref.getOrganizationKey()).hasValue("my-org"); + assertThat(ref.getLanguage()).isEqualTo("js"); + assertThat(ref.getName()).isEqualTo("Sonar way"); + } + + @Test + public void from_reads_request_parameters_and_throws_IAE_if_language_is_missing() { + SimpleGetRequest req = new SimpleGetRequest(); + req.setParam("profileName", "the name"); + + expectedException.expect(IllegalArgumentException.class); + expectedException.expectMessage("Both profile language and name must be set"); + + QProfileReference.from(req); + } + + @Test + public void throw_IAE_if_request_does_not_define_ref() { + SimpleGetRequest req = new SimpleGetRequest(); + + expectedException.expect(IllegalArgumentException.class); + QProfileReference.from(req); + } + + @Test + public void define_ws_parameters() { + WsTester wsTester = new WsTester(); + WebService.NewController controller = wsTester.context().createController("api/qualityprofiles"); + WebService.NewAction newAction = controller.createAction("do").setHandler((request, response) -> { + }); + + Languages languages = new Languages(newLanguage("java"), newLanguage("js")); + QProfileReference.defineParams(newAction, languages); + + controller.done(); + WebService.Action action = wsTester.controller("api/qualityprofiles").action("do"); + assertThat(action.param("language")).isNotNull(); + assertThat(action.param("language").possibleValues()).containsOnly("java", "js"); + assertThat(action.param("profileKey")).isNotNull(); + assertThat(action.param("profileName")).isNotNull(); + } + + @Test + public void test_equals_and_hashCode_of_key_ref() { + QProfileReference key1 = QProfileReference.fromKey("one"); + QProfileReference key1bis = QProfileReference.fromKey("one"); + QProfileReference key2 = QProfileReference.fromKey("two"); + QProfileReference name = QProfileReference.fromName("my-org", "js", "one"); + + assertThat(key1.equals(key1)).isTrue(); + assertThat(key1.equals(key1bis)).isTrue(); + assertThat(key1.equals(key2)).isFalse(); + assertThat(key1.equals(name)).isFalse(); + + assertThat(key1.hashCode()).isEqualTo(key1.hashCode()); + assertThat(key1.hashCode()).isEqualTo(key1bis.hashCode()); + } + + @Test + public void test_equals_and_hashCode_of_name_ref() { + QProfileReference name1 = QProfileReference.fromName("org1", "js", "one"); + QProfileReference name1bis = QProfileReference.fromName("org1", "js", "one"); + QProfileReference name2 = QProfileReference.fromName("org1", "js", "two"); + QProfileReference name1OtherLang = QProfileReference.fromName("org1", "java", "one"); + QProfileReference key = QProfileReference.fromKey("one"); + + assertThat(name1.equals(name1)).isTrue(); + assertThat(name1.equals(name1bis)).isTrue(); + assertThat(name1.equals(name2)).isFalse(); + assertThat(name1.equals(name1OtherLang)).isFalse(); + assertThat(name1.equals(key)).isFalse(); + + assertThat(name1.hashCode()).isEqualTo(name1.hashCode()); + assertThat(name1.hashCode()).isEqualTo(name1bis.hashCode()); + } + +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileWsSupportTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileWsSupportTest.java new file mode 100644 index 00000000000..12ca0caca23 --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileWsSupportTest.java @@ -0,0 +1,112 @@ +/* + * 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.qualityprofile.ws; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.sonar.db.DbTester; +import org.sonar.db.organization.OrganizationDto; +import org.sonar.db.qualityprofile.QualityProfileDto; +import org.sonar.db.qualityprofile.QualityProfileTesting; +import org.sonar.server.exceptions.NotFoundException; +import org.sonar.server.organization.DefaultOrganizationProvider; +import org.sonar.server.organization.TestDefaultOrganizationProvider; +import org.sonar.server.tester.UserSessionRule; + +import static org.assertj.core.api.Assertions.assertThat; + +public class QProfileWsSupportTest { + + @Rule + public ExpectedException expectedException = ExpectedException.none(); + @Rule + public DbTester db = DbTester.create(); + @Rule + public UserSessionRule userSession = UserSessionRule.standalone(); + + private DefaultOrganizationProvider defaultOrgProvider = TestDefaultOrganizationProvider.from(db); + private QProfileWsSupport underTest = new QProfileWsSupport(db.getDbClient(), userSession, defaultOrgProvider); + + @Test + public void getProfile_returns_the_profile_specified_by_key() { + QualityProfileDto profile = db.qualityProfiles().insertQualityProfile(QualityProfileTesting.newQualityProfileDto()); + + QualityProfileDto loaded = underTest.getProfile(db.getSession(), QProfileReference.fromKey(profile.getKey())); + + assertThat(loaded.getKey()).isEqualTo(profile.getKey()); + assertThat(loaded.getOrganizationUuid()).isEqualTo(profile.getOrganizationUuid()); + assertThat(loaded.getLanguage()).isEqualTo(profile.getLanguage()); + assertThat(loaded.getName()).isEqualTo(profile.getName()); + } + + @Test + public void getProfile_throws_NotFoundException_if_specified_key_does_not_exist() { + expectedException.expect(NotFoundException.class); + expectedException.expectMessage("Quality Profile does not exist"); + + underTest.getProfile(db.getSession(), QProfileReference.fromKey("missing")); + } + + @Test + public void getProfile_returns_the_profile_specified_by_name_and_default_organization() { + QualityProfileDto profile = QualityProfileTesting.newQualityProfileDto().setOrganizationUuid(db.getDefaultOrganization().getUuid()); + db.qualityProfiles().insertQualityProfile(profile); + + QualityProfileDto loaded = underTest.getProfile(db.getSession(), QProfileReference.fromName(null, profile.getLanguage(), profile.getName())); + + assertThat(loaded.getKey()).isEqualTo(profile.getKey()); + assertThat(loaded.getOrganizationUuid()).isEqualTo(profile.getOrganizationUuid()); + assertThat(loaded.getLanguage()).isEqualTo(profile.getLanguage()); + assertThat(loaded.getName()).isEqualTo(profile.getName()); + } + + @Test + public void getProfile_throws_NotFoundException_if_specified_name_does_not_exist_on_default_organization() { + QualityProfileDto profile = QualityProfileTesting.newQualityProfileDto().setOrganizationUuid(db.getDefaultOrganization().getUuid()); + db.qualityProfiles().insertQualityProfile(profile); + + expectedException.expect(NotFoundException.class); + expectedException.expectMessage("Quality Profile does not exist"); + + underTest.getProfile(db.getSession(), QProfileReference.fromName(null, "java", "missing")); + } + + @Test + public void getProfile_throws_NotFoundException_if_specified_name_does_not_exist_on_specified_organization() { + OrganizationDto org1 = db.organizations().insert(); + QualityProfileDto profile = QualityProfileTesting.newQualityProfileDto().setOrganizationUuid(org1.getUuid()); + db.qualityProfiles().insertQualityProfile(profile); + OrganizationDto org2 = db.organizations().insert(); + + expectedException.expect(NotFoundException.class); + expectedException.expectMessage("Quality Profile does not exist"); + + underTest.getProfile(db.getSession(), QProfileReference.fromName(org2.getKey(), profile.getLanguage(), profile.getName())); + } + + @Test + public void getProfile_throws_NotFoundException_if_specified_organization_does_not_exist() { + expectedException.expect(NotFoundException.class); + expectedException.expectMessage("No organization with key 'the-org'"); + + underTest.getProfile(db.getSession(), QProfileReference.fromName("the-org", "java", "the-name")); + } +}