import com.google.common.base.Splitter;
import com.google.common.collect.Lists;
import org.apache.commons.lang.StringUtils;
-import org.slf4j.LoggerFactory;
import javax.annotation.CheckForNull;
-import javax.annotation.Nullable;
import java.util.List;
-import java.util.Set;
/**
* @since 4.2
*/
public abstract class Request {
- private WebService.Action action;
-
- protected void setAction(WebService.Action action) {
- this.action = action;
- }
-
- public WebService.Action action() {
- return action;
- }
-
/**
* Returns the name of the HTTP method with which this request was made. Possible
* values are GET and POST. Others are not supported.
return values;
}
- @CheckForNull
- public String param(String key) {
- return param(key, true);
- }
-
- @CheckForNull
- String param(String key, boolean validateValue) {
- WebService.Param definition = action.param(key);
- String value = readParamOrDefaultValue(key, definition);
- if (value != null && validateValue) {
- validate(value, definition);
- }
- return value;
- }
-
- @CheckForNull
public List<String> paramAsStrings(String key) {
- WebService.Param definition = action.param(key);
- String value = readParamOrDefaultValue(key, definition);
- if (value == null) {
- return null;
- }
- List<String> values = Lists.newArrayList(Splitter.on(',').omitEmptyStrings().trimResults().split(value));
- for (String s : values) {
- validate(s, definition);
- }
- return values;
- }
-
- @CheckForNull
- public <E extends Enum<E>> List<E> paramAsEnums(String key, Class<E> enumClass) {
- WebService.Param definition = action.param(key);
- String value = readParamOrDefaultValue(key, definition);
- if (value == null) {
- return null;
- }
- Iterable<String> values = Splitter.on(',').omitEmptyStrings().trimResults().split(value);
- List<E> result = Lists.newArrayList();
- for (String s : values) {
- validate(s, definition);
- result.add(Enum.valueOf(enumClass, s));
- }
- return result;
- }
-
- @CheckForNull
- private String readParamOrDefaultValue(String key, @Nullable WebService.Param definition) {
- if (definition == null) {
- String message = String.format("BUG - parameter '%s' is undefined for action '%s'", key, action.key());
- LoggerFactory.getLogger(getClass()).error(message);
- throw new IllegalArgumentException(message);
- }
- String value = StringUtils.defaultString(readParam(key), definition.defaultValue());
+ String value = param(key);
if (value == null) {
return null;
}
- return value;
+ return Lists.newArrayList(Splitter.on(',').omitEmptyStrings().trimResults().split(value));
}
@CheckForNull
- protected abstract String readParam(String key);
-
- private void validate(String value, WebService.Param definition) {
- Set<String> possibleValues = definition.possibleValues();
- if (possibleValues != null && !possibleValues.contains(value)) {
- throw new IllegalArgumentException(String.format(
- "Value of parameter '%s' (%s) must be one of: %s", definition.key(), value, possibleValues));
- }
- }
+ public abstract String param(String key);
/**
* @deprecated to be dropped in 4.4. Default values are declared in ws metadata
String s = param(key);
return s == null ? null : Enum.valueOf(enumClass, s);
}
+
+ @CheckForNull
+ public <E extends Enum<E>> List<E> paramAsEnums(String key, Class<E> enumClass) {
+ String value = param(key);
+ if (value == null) {
+ return null;
+ }
+ Iterable<String> values = Splitter.on(',').omitEmptyStrings().trimResults().split(value);
+ List<E> result = Lists.newArrayList();
+ for (String s : values) {
+ result.add(Enum.valueOf(enumClass, s));
+ }
+ return result;
+ }
}
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
+
import java.io.IOException;
import java.net.URL;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
+import java.util.*;
/**
* Defines a web service. Note that contrary to the deprecated {@link org.sonar.api.web.Webservice}
/**
* Exhaustive list of possible values when it makes sense, for example
* list of severities.
- * <p/>
- * Note that the parameter supports values with type Iterable, for example :
- * <pre>
- * setPossibleValues(Arrays.asList("one", "two"), "three", "four");
- * </pre>
*
* @since 4.4
*/
public NewParam setPossibleValues(@Nullable Object... values) {
+ return setPossibleValues(values == null ? (Collection) null : Arrays.asList(values));
+ }
+
+ /**
+ * @since 4.4
+ */
+ public NewParam setBooleanPossibleValues() {
+ return setPossibleValues("true", "false");
+ }
+
+ /**
+ * Exhaustive list of possible values when it makes sense, for example
+ * list of severities.
+ *
+ * @since 4.4
+ */
+ public NewParam setPossibleValues(@Nullable Collection values) {
if (values == null) {
this.possibleValues = null;
} else {
this.possibleValues = Sets.newLinkedHashSet();
for (Object value : values) {
- if (value instanceof Iterable) {
- for (Object o : (Iterable) value) {
- this.possibleValues.add(o.toString());
- }
- } else {
- this.possibleValues.add(value.toString());
- }
+ this.possibleValues.add(value.toString());
}
}
return this;
}
- /**
- * @since 4.4
- */
- public NewParam setBooleanPossibleValues() {
- return setPossibleValues("true", "false");
- }
-
/**
* @since 4.4
*/
return this;
}
- @CheckForNull
- public String description() {
- return description;
- }
-
- @CheckForNull
- public String exampleValue() {
- return exampleValue;
- }
-
- @CheckForNull
- public String defaultValue() {
- return defaultValue;
- }
-
- @CheckForNull
- public boolean isRequired() {
- return required;
- }
-
- @CheckForNull
- public Set<String> possibleValues() {
- return possibleValues;
- }
-
@Override
public String toString() {
return key;
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.server.ws.internal;
+
+import com.google.common.collect.Maps;
+import org.sonar.api.server.ws.Request;
+
+import javax.annotation.Nullable;
+import java.util.Map;
+
+/**
+ * Fake implementation of {@link org.sonar.api.server.ws.Request} used
+ * for testing. Call the method {@link #setParam(String, String)} to
+ * emulate some parameter values.
+ */
+public class SimpleGetRequest extends Request {
+
+ private final Map<String, String> params = Maps.newHashMap();
+
+ @Override
+ public String method() {
+ return "GET";
+ }
+
+ @Override
+ public String param(String key) {
+ return params.get(key);
+ }
+
+ public SimpleGetRequest setParam(String key, @Nullable String value) {
+ if (value != null) {
+ params.put(key, value);
+ }
+ return this;
+ }
+
+}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.server.ws.internal;
+
+import com.google.common.base.Splitter;
+import com.google.common.collect.Lists;
+import org.apache.commons.lang.StringUtils;
+import org.slf4j.LoggerFactory;
+import org.sonar.api.server.ws.Request;
+import org.sonar.api.server.ws.WebService;
+
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * @since 4.2
+ */
+public abstract class ValidatingRequest extends Request {
+
+ private WebService.Action action;
+
+ public void setAction(WebService.Action action) {
+ this.action = action;
+ }
+
+ public WebService.Action action() {
+ return action;
+ }
+
+ @CheckForNull
+ public String param(String key) {
+ return param(key, true);
+ }
+
+ @CheckForNull
+ private String param(String key, boolean validateValue) {
+ WebService.Param definition = action.param(key);
+ String value = readParamOrDefaultValue(key, definition);
+ if (value != null && validateValue) {
+ validate(value, definition);
+ }
+ return value;
+ }
+
+ @CheckForNull
+ @Override
+ public List<String> paramAsStrings(String key) {
+ WebService.Param definition = action.param(key);
+ String value = readParamOrDefaultValue(key, definition);
+ if (value == null) {
+ return null;
+ }
+ List<String> values = Lists.newArrayList(Splitter.on(',').omitEmptyStrings().trimResults().split(value));
+ for (String s : values) {
+ validate(s, definition);
+ }
+ return values;
+ }
+
+ @CheckForNull
+ @Override
+ public <E extends Enum<E>> List<E> paramAsEnums(String key, Class<E> enumClass) {
+ WebService.Param definition = action.param(key);
+ String value = readParamOrDefaultValue(key, definition);
+ if (value == null) {
+ return null;
+ }
+ Iterable<String> values = Splitter.on(',').omitEmptyStrings().trimResults().split(value);
+ List<E> result = Lists.newArrayList();
+ for (String s : values) {
+ validate(s, definition);
+ result.add(Enum.valueOf(enumClass, s));
+ }
+ return result;
+ }
+
+ @CheckForNull
+ private String readParamOrDefaultValue(String key, @Nullable WebService.Param definition) {
+ if (definition == null) {
+ String message = String.format("BUG - parameter '%s' is undefined for action '%s'", key, action.key());
+ LoggerFactory.getLogger(getClass()).error(message);
+ throw new IllegalArgumentException(message);
+ }
+ String value = StringUtils.defaultString(readParam(key), definition.defaultValue());
+ if (value == null) {
+ return null;
+ }
+ return value;
+ }
+
+ @CheckForNull
+ protected abstract String readParam(String key);
+
+ private void validate(String value, WebService.Param definition) {
+ Set<String> possibleValues = definition.possibleValues();
+ if (possibleValues != null && !possibleValues.contains(value)) {
+ throw new IllegalArgumentException(String.format(
+ "Value of parameter '%s' (%s) must be one of: %s", definition.key(), value, possibleValues));
+ }
+ }
+}
import org.junit.Before;
import org.junit.Test;
import org.sonar.api.rule.RuleStatus;
+import org.sonar.api.server.ws.internal.ValidatingRequest;
import javax.annotation.Nullable;
import java.util.Map;
public class RequestTest {
- private static class SimpleRequest extends Request {
+ private static class SimpleRequest extends ValidatingRequest {
private final Map<String, String> params = Maps.newHashMap();
NewController newController = context.createController("api/rule");
NewAction create = newController.createAction("create").setHandler(mock(RequestHandler.class));
create.createParam("key").setDescription("Key of the new rule");
- create.createParam("severity").setDefaultValue("MAJOR");
+ create.createParam("severity").setDefaultValue("MAJOR").setPossibleValues("INFO", "MAJOR", "BLOCKER");
newController.done();
}
}.define(context);
assertThat(action.param("severity").key()).isEqualTo("severity");
assertThat(action.param("severity").description()).isNull();
assertThat(action.param("severity").defaultValue()).isEqualTo("MAJOR");
+ assertThat(action.param("severity").possibleValues()).containsOnly("INFO", "MAJOR", "BLOCKER");
}
@Test
}
});
rule.setTags(withoutSystemTags);
- return Sets.difference(initialTags, withoutSystemTags).size() > 0;
+ return withoutSystemTags.size()!=initialTags.size() || !withoutSystemTags.containsAll(initialTags);
}
}
import org.sonar.server.search.ws.BaseMapping;
import org.sonar.server.text.MacroInterpreter;
+/**
+ * Conversion between RuleDoc and WS JSON response
+ */
public class RuleMapping extends BaseMapping {
private final Languages languages;
*/
package org.sonar.server.rule2.ws;
+import com.google.common.collect.ImmutableList;
import com.google.common.io.Resources;
import org.sonar.api.rule.RuleStatus;
import org.sonar.api.rule.Severity;
.setSince("4.4")
.setHandler(this);
- SearchOptions.defineGenericParameters(action, mapping.supportedFields(), "actives");
+ SearchOptions.defineFieldsParam(action,
+ ImmutableList.<String>builder().addAll(mapping.supportedFields()).add("actives").build());
+ SearchOptions.definePageParams(action);
defineRuleSearchParameters(action);
}
import java.util.Set;
/**
- * Options about paging, sorting and fields to return
+ * Various Elasticsearch request options: paging, sorting, fields and facets
*
* @since 4.4
*/
public static final int DEFAULT_OFFSET = 0;
public static final int DEFAULT_LIMIT = 10;
- public static final boolean DEFAULT_FACET = true;
+ public static final boolean DEFAULT_FACET = false;
private int offset = DEFAULT_OFFSET;
private int limit = DEFAULT_LIMIT;
-
private boolean facet = DEFAULT_FACET;
-
private Set<String> fieldsToReturn = new HashSet<String>();
/**
* Set offset and limit according to page approach
*/
public QueryOptions setPage(int page, int pageSize) {
- Preconditions.checkArgument(page > 0, "Page must be positive");
- Preconditions.checkArgument(pageSize >= 0, "Page size must be positive or greater than 0");
- this.offset = (page * pageSize) - pageSize;
- this.limit = pageSize;
+ Preconditions.checkArgument(page >= 1, "Page must be greater or equal to 1 (got " + page + ")");
+ Preconditions.checkArgument(pageSize >= 0, "Page size must be greater or equal to 0 (got " + pageSize + ")");
+ setOffset((page * pageSize) - pageSize);
+ setLimit(pageSize);
return this;
}
fieldsToReturn.addAll(Arrays.asList(c));
return this;
}
-
- public boolean hasFieldToReturn(String key) {
- return fieldsToReturn.isEmpty() || fieldsToReturn.contains(key);
- }
}
private long total;
private long timeInMillis;
-
public Result(SearchResponse response) {
this.hits = new ArrayList<K>();
this.facets = new HashMap<String, Collection<FacetValue>>();
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
+import java.util.Collection;
import java.util.Iterator;
import java.util.List;
return options;
}
- public static void defineGenericParameters(WebService.NewAction action, Object... possibleValues) {
+ public static void defineFieldsParam(WebService.NewAction action, @Nullable Collection<String> possibleFields) {
WebService.NewParam newParam = action
.createParam(PARAM_FIELDS)
.setDescription("Comma-separated list of the fields to be returned in response. All the fields are returned by default.")
- .setPossibleValues(possibleValues);
- if (newParam.possibleValues() != null && newParam.possibleValues().size() > 1) {
- Iterator<String> it = newParam.possibleValues().iterator();
+ .setPossibleValues(possibleFields);
+ if (possibleFields != null && possibleFields.size() > 1) {
+ Iterator<String> it = possibleFields.iterator();
newParam.setExampleValue(String.format("%s,%s", it.next(), it.next()));
}
+ }
+ public static void definePageParams(WebService.NewAction action) {
action
.createParam(PARAM_PAGE)
.setDescription("1-based page number")
+++ /dev/null
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.server.ws;
-
-import org.sonar.api.server.ws.Request;
-import org.sonar.api.server.ws.WebService;
-
-public abstract class InternalRequest extends Request {
- @Override
- protected void setAction(WebService.Action action) {
- super.setAction(action);
- }
-}
*/
package org.sonar.server.ws;
+import org.sonar.api.server.ws.internal.ValidatingRequest;
+
import javax.servlet.http.HttpServletRequest;
import java.util.Map;
-public class ServletRequest extends InternalRequest {
+public class ServletRequest extends ValidatingRequest {
private final HttpServletRequest source;
private final Map<String, String> params;
import org.sonar.api.i18n.I18n;
import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.WebService;
+import org.sonar.api.server.ws.internal.ValidatingRequest;
import org.sonar.api.utils.text.JsonWriter;
import org.sonar.server.exceptions.BadRequestException;
import org.sonar.server.exceptions.BadRequestException.Message;
return context.controllers();
}
- public void execute(InternalRequest request, ServletResponse response,
+ public void execute(ValidatingRequest request, ServletResponse response,
String controllerPath, String actionKey) {
try {
WebService.Action action = getAction(controllerPath, actionKey);
@Test
public void applyTags() throws Exception {
RuleDto rule = new RuleDto().setTags(Sets.newHashSet("performance"));
- RuleTagHelper.applyTags(rule, Sets.newHashSet("java8", "security"));
+ boolean changed = RuleTagHelper.applyTags(rule, Sets.newHashSet("java8", "security"));
assertThat(rule.getTags()).containsOnly("java8", "security");
+ assertThat(changed).isTrue();
}
@Test
public void applyTags_remove_all_existing_tags() throws Exception {
RuleDto rule = new RuleDto().setTags(Sets.newHashSet("performance"));
- RuleTagHelper.applyTags(rule, Collections.<String>emptySet());
+ boolean changed = RuleTagHelper.applyTags(rule, Collections.<String>emptySet());
assertThat(rule.getTags()).isEmpty();
+ assertThat(changed).isTrue();
+ }
+
+ @Test
+ public void applyTags_no_changes() throws Exception {
+ RuleDto rule = new RuleDto().setTags(Sets.newHashSet("performance"));
+ boolean changed = RuleTagHelper.applyTags(rule, Sets.newHashSet("performance"));
+ assertThat(rule.getTags()).containsOnly("performance");
+ assertThat(changed).isFalse();
}
@Test
public void applyTags_validate_format() throws Exception {
RuleDto rule = new RuleDto();
- RuleTagHelper.applyTags(rule, Sets.newHashSet("java8", "security"));
+ boolean changed = RuleTagHelper.applyTags(rule, Sets.newHashSet("java8", "security"));
assertThat(rule.getTags()).containsOnly("java8", "security");
+ assertThat(changed).isTrue();
try {
RuleTagHelper.applyTags(rule, Sets.newHashSet("Java Eight"));
.setTags(Sets.newHashSet("performance"))
.setSystemTags(Sets.newHashSet("security"));
- RuleTagHelper.applyTags(rule, Sets.newHashSet("java8", "security"));
+ boolean changed = RuleTagHelper.applyTags(rule, Sets.newHashSet("java8", "security"));
+ assertThat(changed).isTrue();
assertThat(rule.getTags()).containsOnly("java8");
assertThat(rule.getSystemTags()).containsOnly("security");
}
import java.util.Arrays;
import static org.fest.assertions.Assertions.assertThat;
+import static org.fest.assertions.Fail.fail;
public class QueryOptionsTest {
+ QueryOptions options = new QueryOptions();
+
+ @Test
+ public void page_shortcut_for_limit_and_offset() throws Exception {
+ options.setPage(3, 10);
+
+ assertThat(options.getLimit()).isEqualTo(10);
+ assertThat(options.getOffset()).isEqualTo(20);
+ }
+
+ @Test
+ public void page_starts_at_one() throws Exception {
+ options.setPage(1, 10);
+ assertThat(options.getLimit()).isEqualTo(10);
+ assertThat(options.getOffset()).isEqualTo(0);
+ }
+
+ @Test
+ public void page_must_be_strictly_positive() throws Exception {
+ try {
+ options.setPage(0, 10);
+ fail();
+ } catch (IllegalArgumentException e) {
+ assertThat(e).hasMessage("Page must be greater or equal to 1 (got 0)");
+ }
+ }
+
+ @Test
+ public void page_size_must_be_positive() throws Exception {
+ try {
+ options.setPage(2, -1);
+ fail();
+ } catch (IllegalArgumentException e) {
+ assertThat(e).hasMessage("Page size must be greater or equal to 0 (got -1)");
+ }
+ }
+
@Test
public void fields_to_return() throws Exception {
- QueryOptions options = new QueryOptions();
assertThat(options.getFieldsToReturn()).isEmpty();
options.setFieldsToReturn(Arrays.asList("one", "two"));
@Test
public void support_immutable_fields() throws Exception {
- QueryOptions options = new QueryOptions();
-
options.setFieldsToReturn(ImmutableList.of("one", "two"));
assertThat(options.getFieldsToReturn()).containsOnly("one", "two");
options.addFieldsToReturn("four");
assertThat(options.getFieldsToReturn()).containsOnly("one", "two", "three", "four");
}
+
+ @Test
+ public void do_not_request_facets_by_default() throws Exception {
+ assertThat(options.isFacet()).isFalse();
+
+ options.setFacet(true);
+ assertThat(options.isFacet()).isTrue();
+ }
}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.search.ws;
+
+import com.google.common.collect.Lists;
+import org.junit.Test;
+import org.skyscreamer.jsonassert.JSONAssert;
+import org.sonar.api.server.ws.RequestHandler;
+import org.sonar.api.server.ws.WebService;
+import org.sonar.api.server.ws.internal.SimpleGetRequest;
+import org.sonar.api.utils.text.JsonWriter;
+import org.sonar.server.search.Result;
+
+import java.io.StringWriter;
+
+import static org.fest.assertions.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class SearchOptionsTest {
+
+ @Test
+ public void create_from_http_request() throws Exception {
+ SimpleGetRequest request = new SimpleGetRequest();
+ request.setParam("p", "3");
+ request.setParam("ps", "10");
+ request.setParam("f", "name,repo");
+ request.setParam("severities", "BLOCKER");
+
+ SearchOptions options = SearchOptions.create(request);
+
+ assertThat(options.fields()).containsOnly("name", "repo");
+ assertThat(options.page()).isEqualTo(3);
+ assertThat(options.pageSize()).isEqualTo(10);
+ }
+
+ @Test
+ public void hasField() throws Exception {
+ SimpleGetRequest request = new SimpleGetRequest();
+ request.setParam("p", "3");
+ request.setParam("ps", "10");
+ request.setParam("f", "name,repo");
+ SearchOptions options = SearchOptions.create(request);
+
+ assertThat(options.hasField("repo")).isTrue();
+ assertThat(options.hasField("severity")).isFalse();
+ }
+
+ @Test
+ public void hasField_always_true_by_default() throws Exception {
+ SimpleGetRequest request = new SimpleGetRequest();
+ request.setParam("p", "3");
+ request.setParam("ps", "10");
+ SearchOptions options = SearchOptions.create(request);
+
+ assertThat(options.hasField("repo")).isTrue();
+ }
+
+ @Test
+ public void hasField_no_if_empty_value() throws Exception {
+ SimpleGetRequest request = new SimpleGetRequest();
+ request.setParam("p", "3");
+ request.setParam("ps", "10");
+ request.setParam("f", "");
+ SearchOptions options = SearchOptions.create(request);
+
+ assertThat(options.hasField("repo")).isFalse();
+ }
+
+ @Test
+ public void write_statistics_to_json_response() throws Exception {
+ SimpleGetRequest request = new SimpleGetRequest();
+ request.setParam("p", "3");
+ request.setParam("ps", "10");
+ request.setParam("f", "name,repo");
+ request.setParam("severities", "BLOCKER");
+
+ SearchOptions options = SearchOptions.create(request);
+ StringWriter json = new StringWriter();
+ JsonWriter jsonWriter = JsonWriter.of(json).beginObject();
+ Result result = mock(Result.class);
+ when(result.getTotal()).thenReturn(42L);
+ options.writeStatistics(jsonWriter, result);
+ jsonWriter.endObject().close();
+
+ JSONAssert.assertEquals("{\"total\": 42, \"p\": 3, \"ps\": 10}", json.toString(), true);
+ }
+
+ @Test
+ public void defineFieldsParam() throws Exception {
+ WebService.Context context = new WebService.Context();
+ new WebService() {
+ @Override
+ public void define(Context context) {
+ NewController newController = context.createController("api/foo");
+ NewAction action = newController.createAction("search").setHandler(mock(RequestHandler.class));
+ SearchOptions.defineFieldsParam(action, Lists.newArrayList("name", "lang", "severity"));
+ newController.done();
+ }
+ }.define(context);
+
+ WebService.Action searchAction = context.controller("api/foo").action("search");
+ WebService.Param param = searchAction.param("f");
+ assertThat(param).isNotNull();
+ assertThat(param.possibleValues()).containsOnly("name", "lang", "severity");
+ assertThat(param.exampleValue()).isEqualTo("name,lang");
+ }
+
+ @Test
+ public void definePageParams() throws Exception {
+ WebService.Context context = new WebService.Context();
+ new WebService() {
+ @Override
+ public void define(Context context) {
+ NewController newController = context.createController("api/foo");
+ NewAction action = newController.createAction("search").setHandler(mock(RequestHandler.class));
+ SearchOptions.definePageParams(action);
+ newController.done();
+ }
+ }.define(context);
+
+ WebService.Action searchAction = context.controller("api/foo").action("search");
+ WebService.Param page = searchAction.param("p");
+ assertThat(page).isNotNull();
+ assertThat(page.defaultValue()).isEqualTo("1");
+ WebService.Param pageSize = searchAction.param("ps");
+ assertThat(pageSize).isNotNull();
+ assertThat(pageSize.defaultValue()).isEqualTo("25");
+
+ }
+}
import org.sonar.api.server.ws.RequestHandler;
import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService;
+import org.sonar.api.server.ws.internal.ValidatingRequest;
import org.sonar.server.exceptions.BadRequestException;
import org.sonar.server.exceptions.BadRequestException.Message;
import org.sonar.server.exceptions.ServerException;
public class WebServiceEngineTest {
- private static class SimpleRequest extends InternalRequest {
+ private static class SimpleRequest extends ValidatingRequest {
private final String method;
private Map<String, String> params = Maps.newHashMap();
@Test
public void execute_request() throws Exception {
- InternalRequest request = new SimpleRequest("GET");
+ ValidatingRequest request = new SimpleRequest("GET");
ServletResponse response = new ServletResponse();
engine.execute(request, response, "api/system", "health");
@Test
public void no_content() throws Exception {
- InternalRequest request = new SimpleRequest("GET");
+ ValidatingRequest request = new SimpleRequest("GET");
ServletResponse response = new ServletResponse();
engine.execute(request, response, "api/system", "alive");
@Test
public void bad_controller() throws Exception {
- InternalRequest request = new SimpleRequest("GET");
+ ValidatingRequest request = new SimpleRequest("GET");
ServletResponse response = new ServletResponse();
engine.execute(request, response, "api/xxx", "health");
@Test
public void bad_action() throws Exception {
- InternalRequest request = new SimpleRequest("GET");
+ ValidatingRequest request = new SimpleRequest("GET");
ServletResponse response = new ServletResponse();
engine.execute(request, response, "api/system", "xxx");
@Test
public void method_get_not_allowed() throws Exception {
- InternalRequest request = new SimpleRequest("GET");
+ ValidatingRequest request = new SimpleRequest("GET");
ServletResponse response = new ServletResponse();
engine.execute(request, response, "api/system", "ping");
@Test
public void method_post_required() throws Exception {
- InternalRequest request = new SimpleRequest("POST");
+ ValidatingRequest request = new SimpleRequest("POST");
ServletResponse response = new ServletResponse();
engine.execute(request, response, "api/system", "ping");
@Test
public void unknown_parameter_is_set() throws Exception {
- InternalRequest request = new SimpleRequest("GET").setParam("unknown", "Unknown");
+ ValidatingRequest request = new SimpleRequest("GET").setParam("unknown", "Unknown");
ServletResponse response = new ServletResponse();
engine.execute(request, response, "api/system", "fail_with_undeclared_parameter");
@Test
public void required_parameter_is_not_set() throws Exception {
- InternalRequest request = new SimpleRequest("GET");
+ ValidatingRequest request = new SimpleRequest("GET");
ServletResponse response = new ServletResponse();
engine.execute(request, response, "api/system", "print");
@Test
public void optional_parameter_is_not_set() throws Exception {
- InternalRequest request = new SimpleRequest("GET").setParam("message", "Hello World");
+ ValidatingRequest request = new SimpleRequest("GET").setParam("message", "Hello World");
ServletResponse response = new ServletResponse();
engine.execute(request, response, "api/system", "print");
@Test
public void optional_parameter_is_set() throws Exception {
- InternalRequest request = new SimpleRequest("GET")
+ ValidatingRequest request = new SimpleRequest("GET")
.setParam("message", "Hello World")
.setParam("author", "Marcel");
ServletResponse response = new ServletResponse();
@Test
public void param_value_is_in_possible_values() throws Exception {
- InternalRequest request = new SimpleRequest("GET")
+ ValidatingRequest request = new SimpleRequest("GET")
.setParam("message", "Hello World")
.setParam("format", "json");
ServletResponse response = new ServletResponse();
@Test
public void param_value_is_not_in_possible_values() throws Exception {
- InternalRequest request = new SimpleRequest("GET")
+ ValidatingRequest request = new SimpleRequest("GET")
.setParam("message", "Hello World")
.setParam("format", "html");
ServletResponse response = new ServletResponse();
@Test
public void internal_error() throws Exception {
- InternalRequest request = new SimpleRequest("GET");
+ ValidatingRequest request = new SimpleRequest("GET");
ServletResponse response = new ServletResponse();
engine.execute(request, response, "api/system", "fail");
@Test
public void bad_request_with_i18n_message() throws Exception {
- InternalRequest request = new SimpleRequest("GET").setParam("count", "3");
+ ValidatingRequest request = new SimpleRequest("GET").setParam("count", "3");
ServletResponse response = new ServletResponse();
when(i18n.message(eq(Locale.getDefault()), eq("bad.request.reason"), anyString(), eq(0))).thenReturn("Bad request reason #0");
@Test
public void bad_request_with_multiple_messages() throws Exception {
- InternalRequest request = new SimpleRequest("GET").setParam("count", "3");
+ ValidatingRequest request = new SimpleRequest("GET").setParam("count", "3");
ServletResponse response = new ServletResponse();
engine.execute(request, response, "api/system", "fail_with_multiple_messages");
@Test
public void bad_request_with_multiple_i18n_messages() throws Exception {
- InternalRequest request = new SimpleRequest("GET").setParam("count", "3");
+ ValidatingRequest request = new SimpleRequest("GET").setParam("count", "3");
ServletResponse response = new ServletResponse();
when(i18n.message(Locale.getDefault(), "bad.request.reason", null, 0)).thenReturn("Bad request reason #0");
when(i18n.message(Locale.getDefault(), "bad.request.reason", null, 1)).thenReturn("Bad request reason #1");
@Test
public void server_exception_with_i18n_message() throws Exception {
- InternalRequest request = new SimpleRequest("GET");
+ ValidatingRequest request = new SimpleRequest("GET");
ServletResponse response = new ServletResponse();
when(i18n.message(eq(Locale.getDefault()), eq("not.found"), anyString())).thenReturn("Element is not found");
import org.skyscreamer.jsonassert.JSONAssert;
import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService;
+import org.sonar.api.server.ws.internal.ValidatingRequest;
import org.sonar.api.utils.text.JsonWriter;
import org.sonar.api.utils.text.XmlWriter;
*/
public class WsTester {
- public static class TestRequest extends InternalRequest {
+ public static class TestRequest extends ValidatingRequest {
private final String method;
private Map<String, String> params = Maps.newHashMap();