]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-4923 Add rule parameter validation
authorJulien Lancelot <julien.lancelot@sonarsource.com>
Wed, 15 Jan 2014 10:35:51 +0000 (11:35 +0100)
committerJulien Lancelot <julien.lancelot@sonarsource.com>
Wed, 15 Jan 2014 10:36:00 +0000 (11:36 +0100)
15 files changed:
plugins/sonar-core-plugin/src/main/resources/org/sonar/l10n/core.properties
sonar-server/src/main/java/org/sonar/server/platform/Platform.java
sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileActiveRuleOperations.java
sonar-server/src/main/java/org/sonar/server/util/BooleanTypeValidation.java [new file with mode: 0644]
sonar-server/src/main/java/org/sonar/server/util/FloatTypeValidation.java [new file with mode: 0644]
sonar-server/src/main/java/org/sonar/server/util/IntegerTypeValidation.java [new file with mode: 0644]
sonar-server/src/main/java/org/sonar/server/util/StringListTypeValidation.java [new file with mode: 0644]
sonar-server/src/main/java/org/sonar/server/util/TypeValidation.java [new file with mode: 0644]
sonar-server/src/main/java/org/sonar/server/util/TypeValidations.java [new file with mode: 0644]
sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileActiveRuleOperationsTest.java
sonar-server/src/test/java/org/sonar/server/util/BooleanTypeValidationTest.java [new file with mode: 0644]
sonar-server/src/test/java/org/sonar/server/util/FloatTypeValidationTest.java [new file with mode: 0644]
sonar-server/src/test/java/org/sonar/server/util/IntegerTypeValidationTest.java [new file with mode: 0644]
sonar-server/src/test/java/org/sonar/server/util/StringListTypeValidationTest.java [new file with mode: 0644]
sonar-server/src/test/java/org/sonar/server/util/TypeValidationsTest.java [new file with mode: 0644]

index b52ecf15b52c7fc67fb12a6789449801847611af..d2e176d7992898ab14579bb0e7b01c20a5cb8450 100644 (file)
@@ -2499,6 +2499,11 @@ errors.is_already_used={0} has already been taken
 errors.cant_be_empty={0} can't be empty
 errors.is_not_valid={0} is not valid
 
+errors.type.notBoolean=Valid '{0}' must be one of "true" or "false".
+errors.type.notInteger=Value '{0}' must be an integer.
+errors.type.notFloat=Value '{0}' must be an floating point number.
+errors.type.notInOptions=Value '{0}' must be one of : {1}.
+
 
 #------------------------------------------------------------------------------
 #
index 4809f15692bb1af916adeec81e1a7f3be1f323e9..0603f1025fbe505db01098a4c90e8cae2de39729 100644 (file)
@@ -19,9 +19,6 @@
  */
 package org.sonar.server.platform;
 
-import org.sonar.server.es.ESIndex;
-import org.sonar.server.es.ESNode;
-
 import org.apache.commons.configuration.BaseConfiguration;
 import org.slf4j.LoggerFactory;
 import org.sonar.api.config.EmailSettings;
@@ -84,6 +81,8 @@ import org.sonar.server.db.EmbeddedDatabaseFactory;
 import org.sonar.server.db.migrations.DatabaseMigration;
 import org.sonar.server.db.migrations.DatabaseMigrations;
 import org.sonar.server.db.migrations.DatabaseMigrator;
+import org.sonar.server.es.ESIndex;
+import org.sonar.server.es.ESNode;
 import org.sonar.server.group.GroupMembershipFinder;
 import org.sonar.server.group.InternalGroupMembershipService;
 import org.sonar.server.issue.*;
@@ -108,6 +107,7 @@ import org.sonar.server.text.RubyTextService;
 import org.sonar.server.ui.*;
 import org.sonar.server.user.DefaultUserService;
 import org.sonar.server.user.NewUserNotifier;
+import org.sonar.server.util.*;
 
 import javax.annotation.Nullable;
 import javax.servlet.ServletContext;
@@ -360,6 +360,13 @@ public final class Platform {
     servicesContainer.addSingleton(SnapshotPerspectives.class);
     servicesContainer.addSingleton(HtmlSourceDecorator.class);
 
+    // Type validation
+    servicesContainer.addSingleton(TypeValidations.class);
+    servicesContainer.addSingleton(IntegerTypeValidation.class);
+    servicesContainer.addSingleton(FloatTypeValidation.class);
+    servicesContainer.addSingleton(BooleanTypeValidation.class);
+    servicesContainer.addSingleton(StringListTypeValidation.class);
+
     ServerExtensionInstaller extensionRegistrar = servicesContainer.getComponentByType(ServerExtensionInstaller.class);
     extensionRegistrar.registerExtensions(servicesContainer);
 
index 99124fedc79a66051e25d23a0b6329697261d02b..6296fb5d47875756ca2b0e8ffa1486f0c6181a38 100644 (file)
@@ -22,11 +22,9 @@ package org.sonar.server.qualityprofile;
 
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Strings;
-import org.apache.commons.lang.math.NumberUtils;
 import org.apache.ibatis.session.SqlSession;
 import org.elasticsearch.common.base.Predicate;
 import org.elasticsearch.common.collect.Iterables;
-import org.sonar.api.PropertyType;
 import org.sonar.api.ServerComponent;
 import org.sonar.api.rule.Severity;
 import org.sonar.api.rules.RulePriority;
@@ -41,6 +39,7 @@ import org.sonar.server.configuration.ProfilesManager;
 import org.sonar.server.exceptions.BadRequestException;
 import org.sonar.server.rule.RuleRegistry;
 import org.sonar.server.user.UserSession;
+import org.sonar.server.util.TypeValidations;
 
 import javax.annotation.CheckForNull;
 import javax.annotation.Nullable;
@@ -60,21 +59,23 @@ public class QProfileActiveRuleOperations implements ServerComponent {
   private final ProfilesManager profilesManager;
 
   private final System2 system;
+  private final TypeValidations typeValidations;
 
   public QProfileActiveRuleOperations(MyBatis myBatis, ActiveRuleDao activeRuleDao, RuleDao ruleDao, QualityProfileDao profileDao, RuleRegistry ruleRegistry,
-                                      ProfilesManager profilesManager) {
-    this(myBatis, activeRuleDao, ruleDao, profileDao, ruleRegistry, profilesManager, System2.INSTANCE);
+                                      ProfilesManager profilesManager, TypeValidations typeValidations) {
+    this(myBatis, activeRuleDao, ruleDao, profileDao, ruleRegistry, profilesManager, typeValidations, System2.INSTANCE);
   }
 
   @VisibleForTesting
   QProfileActiveRuleOperations(MyBatis myBatis, ActiveRuleDao activeRuleDao, RuleDao ruleDao, QualityProfileDao profileDao, RuleRegistry ruleRegistry,
-                               ProfilesManager profilesManager, System2 system) {
+                               ProfilesManager profilesManager, TypeValidations typeValidations, System2 system) {
     this.myBatis = myBatis;
     this.activeRuleDao = activeRuleDao;
     this.ruleDao = ruleDao;
     this.profileDao = profileDao;
     this.ruleRegistry = ruleRegistry;
     this.profilesManager = profilesManager;
+    this.typeValidations = typeValidations;
     this.system = system;
   }
 
@@ -415,13 +416,8 @@ public class QProfileActiveRuleOperations implements ServerComponent {
     }
   }
 
-  @VisibleForTesting
-  void validateParam(String type, String value) {
-    if (type.equals(PropertyType.INTEGER.name()) && !NumberUtils.isDigits(value)) {
-      throw new BadRequestException(String.format("Value '%s' must be an integer.", value));
-    } else if (type.equals(PropertyType.BOOLEAN.name()) && !Boolean.parseBoolean(value)) {
-      throw new BadRequestException(String.format("Value '%s' must be one of : true,false.", value));
-    }
+  private void validateParam(String type, String value) {
+    typeValidations.validate(value, type, null);
   }
 
   private String getLoggedName(UserSession userSession) {
diff --git a/sonar-server/src/main/java/org/sonar/server/util/BooleanTypeValidation.java b/sonar-server/src/main/java/org/sonar/server/util/BooleanTypeValidation.java
new file mode 100644 (file)
index 0000000..834214d
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 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.util;
+
+import org.apache.commons.lang.StringUtils;
+import org.sonar.api.PropertyType;
+import org.sonar.server.exceptions.BadRequestException;
+
+import java.util.List;
+
+public class BooleanTypeValidation implements TypeValidation {
+
+  @Override
+  public String key() {
+    return PropertyType.BOOLEAN.name();
+  }
+
+  @Override
+  public void validate(String value, List<String> options) {
+    if (!StringUtils.equalsIgnoreCase(value, "true") && !StringUtils.equalsIgnoreCase(value, "false")) {
+      throw BadRequestException.ofL10n("errors.type.notBoolean", value);
+    }
+  }
+
+}
diff --git a/sonar-server/src/main/java/org/sonar/server/util/FloatTypeValidation.java b/sonar-server/src/main/java/org/sonar/server/util/FloatTypeValidation.java
new file mode 100644 (file)
index 0000000..ed473db
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 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.util;
+
+import org.sonar.api.PropertyType;
+import org.sonar.server.exceptions.BadRequestException;
+
+import java.util.List;
+
+public class FloatTypeValidation implements TypeValidation {
+
+  @Override
+  public String key() {
+    return PropertyType.FLOAT.name();
+  }
+
+  @Override
+  public void validate(String value, List<String> options) {
+    try {
+      Double.parseDouble(value);
+    } catch (NumberFormatException e) {
+      throw BadRequestException.ofL10n("errors.type.notFloat", value);
+    }
+  }
+
+}
diff --git a/sonar-server/src/main/java/org/sonar/server/util/IntegerTypeValidation.java b/sonar-server/src/main/java/org/sonar/server/util/IntegerTypeValidation.java
new file mode 100644 (file)
index 0000000..e8532d1
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 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.util;
+
+import org.apache.commons.lang.math.NumberUtils;
+import org.sonar.api.PropertyType;
+import org.sonar.server.exceptions.BadRequestException;
+
+import java.util.List;
+
+public class IntegerTypeValidation implements TypeValidation {
+
+  @Override
+  public String key() {
+    return PropertyType.INTEGER.name();
+  }
+
+  @Override
+  public void validate(String value, List<String> options) {
+    if (!NumberUtils.isDigits(value)) {
+      throw BadRequestException.ofL10n("errors.type.notInteger", value);
+    }
+  }
+
+}
diff --git a/sonar-server/src/main/java/org/sonar/server/util/StringListTypeValidation.java b/sonar-server/src/main/java/org/sonar/server/util/StringListTypeValidation.java
new file mode 100644 (file)
index 0000000..bf9c900
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 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.util;
+
+import org.apache.commons.lang.StringUtils;
+import org.sonar.api.PropertyType;
+import org.sonar.server.exceptions.BadRequestException;
+
+import java.util.List;
+
+public class StringListTypeValidation implements TypeValidation {
+
+  @Override
+  public String key() {
+    return PropertyType.SINGLE_SELECT_LIST.name();
+  }
+
+  @Override
+  public void validate(String value, List<String> options) {
+    if (!options.contains(value)) {
+      String optionsAsString = StringUtils.join(options, ", ");
+      throw BadRequestException.ofL10n("errors.type.notInOptions", value, optionsAsString);
+    }
+  }
+
+}
diff --git a/sonar-server/src/main/java/org/sonar/server/util/TypeValidation.java b/sonar-server/src/main/java/org/sonar/server/util/TypeValidation.java
new file mode 100644 (file)
index 0000000..98f8278
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 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.util;
+
+import org.sonar.api.ServerComponent;
+
+import java.util.List;
+
+public interface TypeValidation extends ServerComponent {
+
+  String key();
+
+  void validate(String value, List<String> options);
+}
diff --git a/sonar-server/src/main/java/org/sonar/server/util/TypeValidations.java b/sonar-server/src/main/java/org/sonar/server/util/TypeValidations.java
new file mode 100644 (file)
index 0000000..5c28b42
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 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.util;
+
+import com.google.common.base.Predicate;
+import com.google.common.collect.Iterables;
+import org.sonar.api.ServerComponent;
+
+import java.util.List;
+
+public class TypeValidations implements ServerComponent {
+
+  private final List<TypeValidation> typeValidationList;
+
+  public TypeValidations(List<TypeValidation> typeValidationList) {
+    this.typeValidationList = typeValidationList;
+  }
+
+  public void validate(String value, String type, List<String> options) {
+    TypeValidation typeValidation = findByKey(type);
+    typeValidation.validate(value, options);
+  }
+
+  private TypeValidation findByKey(final String key) {
+    return Iterables.find(typeValidationList, new Predicate<TypeValidation>() {
+      @Override
+      public boolean apply(TypeValidation input) {
+        return input.key().equals(key);
+      }
+    });
+  }
+}
index bff47502361b3db59c812e98b2f0f296d2e10d3b..5622e2bfa9a96c6ec2e0deba7fe3c1c6a86bf71f 100644 (file)
@@ -46,6 +46,7 @@ import org.sonar.server.exceptions.ForbiddenException;
 import org.sonar.server.rule.RuleRegistry;
 import org.sonar.server.user.MockUserSession;
 import org.sonar.server.user.UserSession;
+import org.sonar.server.util.TypeValidations;
 
 import java.util.Date;
 import java.util.List;
@@ -83,6 +84,9 @@ public class QProfileActiveRuleOperationsTest {
   @Mock
   ProfilesManager profilesManager;
 
+  @Mock
+  TypeValidations typeValidations;
+
   @Mock
   System2 system;
 
@@ -107,7 +111,7 @@ public class QProfileActiveRuleOperationsTest {
       }
     }).when(activeRuleDao).insert(any(ActiveRuleDto.class), any(SqlSession.class));
 
-    operations = new QProfileActiveRuleOperations(myBatis, activeRuleDao, ruleDao, profileDao, ruleRegistry, profilesManager, system);
+    operations = new QProfileActiveRuleOperations(myBatis, activeRuleDao, ruleDao, profileDao, ruleRegistry, profilesManager, typeValidations, system);
   }
 
   @Test
@@ -292,6 +296,7 @@ public class QProfileActiveRuleOperationsTest {
     assertThat(argumentCaptor.getValue().getValue()).isEqualTo("30");
     assertThat(argumentCaptor.getValue().getActiveRuleId()).isEqualTo(5);
 
+    verify(typeValidations).validate("30", "INTEGER", null);
     verify(session).commit();
     verify(profilesManager).ruleParamChanged(eq(1), eq(5), eq("max"), eq((String) null), eq("30"), eq("Nicolas"));
     verify(ruleRegistry).deleteActiveRules(anyListOf(Integer.class));
@@ -314,23 +319,6 @@ public class QProfileActiveRuleOperationsTest {
     verifyZeroInteractions(profilesManager);
   }
 
-  @Test
-  public void fail_to_create_active_rule_if_type_is_invalid() throws Exception {
-    ActiveRuleDto activeRule = new ActiveRuleDto().setId(5).setProfileId(1).setRuleId(10).setSeverity(1);
-    when(activeRuleDao.selectById(5, session)).thenReturn(activeRule);
-    RuleParamDto ruleParam = new RuleParamDto().setRuleId(10).setName("max").setDefaultValue("20").setType(PropertyType.INTEGER.name());
-    when(ruleDao.selectParamByRuleAndKey(10, "max", session)).thenReturn(ruleParam);
-
-    try {
-      operations.updateActiveRuleParam(5, "max", "invalid integer", authorizedUserSession);
-      fail();
-    } catch (Exception e) {
-      assertThat(e).isInstanceOf(BadRequestException.class);
-    }
-    verify(activeRuleDao, never()).insert(any(ActiveRuleParamDto.class), eq(session));
-    verifyZeroInteractions(profilesManager);
-  }
-
   @Test
   public void update_active_rule_param() throws Exception {
     ActiveRuleDto activeRule = new ActiveRuleDto().setId(5).setProfileId(1).setRuleId(10).setSeverity(1);
@@ -349,6 +337,7 @@ public class QProfileActiveRuleOperationsTest {
     assertThat(argumentCaptor.getValue().getId()).isEqualTo(100);
     assertThat(argumentCaptor.getValue().getValue()).isEqualTo("30");
 
+    verify(typeValidations).validate("30", "INTEGER", null);
     verify(session).commit();
     verify(profilesManager).ruleParamChanged(eq(1), eq(5), eq("max"), eq("20"), eq("30"), eq("Nicolas"));
     verify(ruleRegistry).deleteActiveRules(anyListOf(Integer.class));
@@ -593,29 +582,4 @@ public class QProfileActiveRuleOperationsTest {
     verify(ruleRegistry).save(eq(activeRule), eq(activeRuleParams));
   }
 
-  @Test
-  public void validate_integer_type() throws Exception {
-    operations.validateParam(PropertyType.INTEGER.name(), "10");
-
-    try {
-      operations.validateParam(PropertyType.INTEGER.name(), "invalid integer");
-      fail();
-    } catch (Exception e) {
-      assertThat(e).isInstanceOf(BadRequestException.class).hasMessage("Value 'invalid integer' must be an integer.");
-    }
-  }
-
-  @Test
-  public void validate_boolean_type() throws Exception {
-    operations.validateParam(PropertyType.BOOLEAN.name(), "true");
-    operations.validateParam(PropertyType.BOOLEAN.name(), "True");
-
-    try {
-      operations.validateParam(PropertyType.BOOLEAN.name(), "invalid boolean");
-      fail();
-    } catch (Exception e) {
-      assertThat(e).isInstanceOf(BadRequestException.class).hasMessage("Value 'invalid boolean' must be one of : true,false.");
-    }
-  }
-
 }
diff --git a/sonar-server/src/test/java/org/sonar/server/util/BooleanTypeValidationTest.java b/sonar-server/src/test/java/org/sonar/server/util/BooleanTypeValidationTest.java
new file mode 100644 (file)
index 0000000..3ed8ad7
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 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.util;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.sonar.server.exceptions.BadRequestException;
+
+import static org.fest.assertions.Assertions.assertThat;
+import static org.junit.Assert.fail;
+
+public class BooleanTypeValidationTest {
+
+  BooleanTypeValidation validation;
+
+  @Before
+  public void setUp() throws Exception {
+    validation = new BooleanTypeValidation();
+  }
+
+  @Test
+  public void key() {
+    assertThat(validation.key()).isEqualTo("BOOLEAN");
+  }
+
+  @Test
+  public void not_fail_on_valid_boolean() {
+    validation.validate("true", null);
+    validation.validate("True", null);
+    validation.validate("false", null);
+    validation.validate("FALSE", null);
+  }
+
+  @Test
+  public void fail_on_invalid_boolean() {
+    try {
+      validation.validate("abc", null);
+      fail();
+    } catch (Exception e) {
+      assertThat(e).isInstanceOf(BadRequestException.class);
+      BadRequestException badRequestException = (BadRequestException) e;
+      assertThat(badRequestException.l10nParams().toArray()[0]).isEqualTo("abc");
+    }
+  }
+
+}
diff --git a/sonar-server/src/test/java/org/sonar/server/util/FloatTypeValidationTest.java b/sonar-server/src/test/java/org/sonar/server/util/FloatTypeValidationTest.java
new file mode 100644 (file)
index 0000000..ecce68e
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 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.util;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.sonar.server.exceptions.BadRequestException;
+
+import static org.fest.assertions.Assertions.assertThat;
+import static org.junit.Assert.fail;
+
+public class FloatTypeValidationTest {
+
+  FloatTypeValidation validation;
+
+  @Before
+  public void setUp() throws Exception {
+    validation = new FloatTypeValidation();
+  }
+
+  @Test
+  public void key() {
+    assertThat(validation.key()).isEqualTo("FLOAT");
+  }
+
+  @Test
+  public void not_fail_on_valid_float() {
+    validation.validate("10.2", null);
+    validation.validate("10", null);
+  }
+
+  @Test
+  public void fail_on_invalid_float() {
+    try {
+      validation.validate("abc", null);
+      fail();
+    } catch (Exception e) {
+      assertThat(e).isInstanceOf(BadRequestException.class);
+      BadRequestException badRequestException = (BadRequestException) e;
+      assertThat(badRequestException.l10nParams().toArray()[0]).isEqualTo("abc");
+    }
+  }
+
+}
diff --git a/sonar-server/src/test/java/org/sonar/server/util/IntegerTypeValidationTest.java b/sonar-server/src/test/java/org/sonar/server/util/IntegerTypeValidationTest.java
new file mode 100644 (file)
index 0000000..e8337d1
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 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.util;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.sonar.server.exceptions.BadRequestException;
+
+import static org.fest.assertions.Assertions.assertThat;
+import static org.junit.Assert.fail;
+
+public class IntegerTypeValidationTest {
+
+  IntegerTypeValidation validation;
+
+  @Before
+  public void setUp() throws Exception {
+    validation = new IntegerTypeValidation();
+  }
+
+  @Test
+  public void key() {
+    assertThat(validation.key()).isEqualTo("INTEGER");
+  }
+
+  @Test
+  public void not_fail_on_valid_integer() {
+    validation.validate("10", null);
+  }
+
+  @Test
+  public void fail_on_invalid_integer() {
+    try {
+      validation.validate("abc", null);
+      fail();
+    } catch (Exception e) {
+      assertThat(e).isInstanceOf(BadRequestException.class);
+      BadRequestException badRequestException = (BadRequestException) e;
+      assertThat(badRequestException.l10nParams().toArray()[0]).isEqualTo("abc");
+    }
+  }
+
+}
diff --git a/sonar-server/src/test/java/org/sonar/server/util/StringListTypeValidationTest.java b/sonar-server/src/test/java/org/sonar/server/util/StringListTypeValidationTest.java
new file mode 100644 (file)
index 0000000..389b39b
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 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.util;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.sonar.server.exceptions.BadRequestException;
+
+import static com.google.common.collect.Lists.newArrayList;
+import static org.fest.assertions.Assertions.assertThat;
+import static org.junit.Assert.fail;
+
+public class StringListTypeValidationTest {
+
+  StringListTypeValidation validation;
+
+  @Before
+  public void setUp() throws Exception {
+    validation = new StringListTypeValidation();
+  }
+
+  @Test
+  public void key() {
+    assertThat(validation.key()).isEqualTo("SINGLE_SELECT_LIST");
+  }
+
+  @Test
+  public void not_fail_on_valid_option() {
+    validation.validate("a", newArrayList("a", "b", "c"));
+  }
+
+  @Test
+  public void fail_on_invalid_option() {
+    try {
+      validation.validate("abc", newArrayList("a", "b", "c"));
+      fail();
+    } catch (Exception e) {
+      assertThat(e).isInstanceOf(BadRequestException.class);
+      BadRequestException badRequestException = (BadRequestException) e;
+      assertThat(badRequestException.l10nParams().toArray()[0]).isEqualTo("abc");
+      assertThat(badRequestException.l10nParams().toArray()[1]).isEqualTo("a, b, c");
+    }
+  }
+
+}
diff --git a/sonar-server/src/test/java/org/sonar/server/util/TypeValidationsTest.java b/sonar-server/src/test/java/org/sonar/server/util/TypeValidationsTest.java
new file mode 100644 (file)
index 0000000..9c0086c
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 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.util;
+
+import org.junit.Test;
+
+import java.util.NoSuchElementException;
+
+import static com.google.common.collect.Lists.newArrayList;
+import static org.fest.assertions.Assertions.assertThat;
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.*;
+
+public class TypeValidationsTest {
+
+  @Test
+  public void validate() throws Exception {
+    TypeValidation fakeTypeValidation = mock(TypeValidation.class);
+    when(fakeTypeValidation.key()).thenReturn("Fake");
+
+    TypeValidations typeValidations = new TypeValidations(newArrayList(fakeTypeValidation));
+    typeValidations.validate("10", "Fake", newArrayList("a"));
+
+    verify(fakeTypeValidation).validate("10", newArrayList("a"));
+  }
+
+  @Test
+  public void fail_on_unknown_type() throws Exception {
+    TypeValidation fakeTypeValidation = mock(TypeValidation.class);
+    when(fakeTypeValidation.key()).thenReturn("Fake");
+
+    try {
+      TypeValidations typeValidations = new TypeValidations(newArrayList(fakeTypeValidation));
+      typeValidations.validate("10", "Unknown", null);
+      fail();
+    } catch (Exception e) {
+      assertThat(e).isInstanceOf(NoSuchElementException.class);
+    }
+  }
+
+}