From 7371f8580263541c0012c800b79ab45d39aca739 Mon Sep 17 00:00:00 2001 From: Simon Brandhof Date: Mon, 20 Jan 2014 23:23:34 +0100 Subject: [PATCH] SONAR-5010 refactor WebService framework --- .../org/sonar/api/server/ws/Response.java | 2 +- .../sonar/api/server/ws/SimpleRequest.java | 6 +- .../sonar/api/server/ws/SimpleResponse.java | 2 +- .../issue/InternalRubyIssueService.java | 3 + .../server/issue/PublicRubyIssueService.java | 1 + .../{ => filter}/IssueFilterParameters.java | 2 +- .../issue/{ => filter}/IssueFilterResult.java | 2 +- .../{ => filter}/IssueFilterService.java | 23 ++-- .../server/issue/filter/IssueFilterWs.java | 101 ++++++++++++++++++ .../server/issue/filter/package-info.java | 23 ++++ .../org/sonar/server/platform/Platform.java | 9 +- .../rule/{RuleWebService.java => RuleWs.java} | 2 +- ...{ListingWebService.java => ListingWs.java} | 2 +- .../org/sonar/server/ws/ServletResponse.java | 39 +++++-- .../org/sonar/server/ws/WebServiceEngine.java | 40 +++---- .../app/controllers/issues_controller.rb | 36 ------- .../issue/InternalRubyIssueServiceTest.java | 1 + .../{ => filter}/IssueFilterServiceTest.java | 50 +++------ .../issue/filter/IssueFilterWsTest.java | 96 +++++++++++++++++ ...uleWebServiceTest.java => RuleWsTest.java} | 27 ++--- ...WebServiceTest.java => ListingWsTest.java} | 16 +-- .../sonar/server/ws/WebServiceEngineTest.java | 23 +++- .../java/org/sonar/server/ws/WsTester.java | 93 ++++++++++++++++ .../IssueFilterWsTest/anonymous_page.json | 4 + .../IssueFilterWsTest/logged_in_page.json | 5 + .../logged_in_page_with_favorites.json | 14 +++ .../logged_in_page_with_selected_filter.json | 12 +++ .../search.json | 0 28 files changed, 478 insertions(+), 156 deletions(-) rename sonar-server/src/main/java/org/sonar/server/issue/{ => filter}/IssueFilterParameters.java (98%) rename sonar-server/src/main/java/org/sonar/server/issue/{ => filter}/IssueFilterResult.java (97%) rename sonar-server/src/main/java/org/sonar/server/issue/{ => filter}/IssueFilterService.java (96%) create mode 100644 sonar-server/src/main/java/org/sonar/server/issue/filter/IssueFilterWs.java create mode 100644 sonar-server/src/main/java/org/sonar/server/issue/filter/package-info.java rename sonar-server/src/main/java/org/sonar/server/rule/{RuleWebService.java => RuleWs.java} (97%) rename sonar-server/src/main/java/org/sonar/server/ws/{ListingWebService.java => ListingWs.java} (98%) rename sonar-server/src/test/java/org/sonar/server/issue/{ => filter}/IssueFilterServiceTest.java (95%) create mode 100644 sonar-server/src/test/java/org/sonar/server/issue/filter/IssueFilterWsTest.java rename sonar-server/src/test/java/org/sonar/server/rule/{RuleWebServiceTest.java => RuleWsTest.java} (67%) rename sonar-server/src/test/java/org/sonar/server/ws/{ListingWebServiceTest.java => ListingWsTest.java} (89%) create mode 100644 sonar-server/src/test/java/org/sonar/server/ws/WsTester.java create mode 100644 sonar-server/src/test/resources/org/sonar/server/issue/filter/IssueFilterWsTest/anonymous_page.json create mode 100644 sonar-server/src/test/resources/org/sonar/server/issue/filter/IssueFilterWsTest/logged_in_page.json create mode 100644 sonar-server/src/test/resources/org/sonar/server/issue/filter/IssueFilterWsTest/logged_in_page_with_favorites.json create mode 100644 sonar-server/src/test/resources/org/sonar/server/issue/filter/IssueFilterWsTest/logged_in_page_with_selected_filter.json rename sonar-server/src/test/resources/org/sonar/server/rule/{RuleWebServiceTest => RuleWsTest}/search.json (100%) diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/server/ws/Response.java b/sonar-plugin-api/src/main/java/org/sonar/api/server/ws/Response.java index 59209cbee40..fb22807ed67 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/server/ws/Response.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/server/ws/Response.java @@ -40,6 +40,6 @@ public interface Response { XmlWriter newXmlWriter(); - OutputStream output(); + OutputStream stream(); } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/server/ws/SimpleRequest.java b/sonar-plugin-api/src/main/java/org/sonar/api/server/ws/SimpleRequest.java index 9840b8abdcb..e24def28ec3 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/server/ws/SimpleRequest.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/server/ws/SimpleRequest.java @@ -38,8 +38,10 @@ public class SimpleRequest extends Request { return this; } - public SimpleRequest setParams(String key, String value) { - this.params.put(key, value); + public SimpleRequest setParam(String key, @CheckForNull String value) { + if (value != null) { + params.put(key, value); + } return this; } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/server/ws/SimpleResponse.java b/sonar-plugin-api/src/main/java/org/sonar/api/server/ws/SimpleResponse.java index c6ae01d17b9..d2de13b9f63 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/server/ws/SimpleResponse.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/server/ws/SimpleResponse.java @@ -42,7 +42,7 @@ public class SimpleResponse implements Response { } @Override - public OutputStream output() { + public OutputStream stream() { return output; } diff --git a/sonar-server/src/main/java/org/sonar/server/issue/InternalRubyIssueService.java b/sonar-server/src/main/java/org/sonar/server/issue/InternalRubyIssueService.java index cf7a8b6320f..3228d3c0475 100644 --- a/sonar-server/src/main/java/org/sonar/server/issue/InternalRubyIssueService.java +++ b/sonar-server/src/main/java/org/sonar/server/issue/InternalRubyIssueService.java @@ -45,6 +45,9 @@ import org.sonar.core.resource.ResourceDao; import org.sonar.core.resource.ResourceDto; import org.sonar.core.resource.ResourceQuery; import org.sonar.server.exceptions.BadRequestException; +import org.sonar.server.issue.filter.IssueFilterParameters; +import org.sonar.server.issue.filter.IssueFilterResult; +import org.sonar.server.issue.filter.IssueFilterService; import org.sonar.server.user.UserSession; import org.sonar.server.util.RubyUtils; import org.sonar.server.util.Validation; diff --git a/sonar-server/src/main/java/org/sonar/server/issue/PublicRubyIssueService.java b/sonar-server/src/main/java/org/sonar/server/issue/PublicRubyIssueService.java index 768ac484879..f288bbe227c 100644 --- a/sonar-server/src/main/java/org/sonar/server/issue/PublicRubyIssueService.java +++ b/sonar-server/src/main/java/org/sonar/server/issue/PublicRubyIssueService.java @@ -30,6 +30,7 @@ import org.sonar.api.issue.IssueQueryResult; import org.sonar.api.issue.RubyIssueService; import org.sonar.api.rule.RuleKey; import org.sonar.api.web.UserRole; +import org.sonar.server.issue.filter.IssueFilterParameters; import org.sonar.server.util.RubyUtils; import javax.annotation.Nullable; diff --git a/sonar-server/src/main/java/org/sonar/server/issue/IssueFilterParameters.java b/sonar-server/src/main/java/org/sonar/server/issue/filter/IssueFilterParameters.java similarity index 98% rename from sonar-server/src/main/java/org/sonar/server/issue/IssueFilterParameters.java rename to sonar-server/src/main/java/org/sonar/server/issue/filter/IssueFilterParameters.java index 12ec6819dad..a3078f75e36 100644 --- a/sonar-server/src/main/java/org/sonar/server/issue/IssueFilterParameters.java +++ b/sonar-server/src/main/java/org/sonar/server/issue/filter/IssueFilterParameters.java @@ -18,7 +18,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -package org.sonar.server.issue; +package org.sonar.server.issue.filter; import com.google.common.base.Predicate; import com.google.common.collect.ImmutableList; diff --git a/sonar-server/src/main/java/org/sonar/server/issue/IssueFilterResult.java b/sonar-server/src/main/java/org/sonar/server/issue/filter/IssueFilterResult.java similarity index 97% rename from sonar-server/src/main/java/org/sonar/server/issue/IssueFilterResult.java rename to sonar-server/src/main/java/org/sonar/server/issue/filter/IssueFilterResult.java index d1769f80350..90c0a465d30 100644 --- a/sonar-server/src/main/java/org/sonar/server/issue/IssueFilterResult.java +++ b/sonar-server/src/main/java/org/sonar/server/issue/filter/IssueFilterResult.java @@ -18,7 +18,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -package org.sonar.server.issue; +package org.sonar.server.issue.filter; import org.sonar.api.issue.IssueQuery; import org.sonar.api.issue.IssueQueryResult; diff --git a/sonar-server/src/main/java/org/sonar/server/issue/IssueFilterService.java b/sonar-server/src/main/java/org/sonar/server/issue/filter/IssueFilterService.java similarity index 96% rename from sonar-server/src/main/java/org/sonar/server/issue/IssueFilterService.java rename to sonar-server/src/main/java/org/sonar/server/issue/filter/IssueFilterService.java index 56d3e9c4227..1bff87a3378 100644 --- a/sonar-server/src/main/java/org/sonar/server/issue/IssueFilterService.java +++ b/sonar-server/src/main/java/org/sonar/server/issue/filter/IssueFilterService.java @@ -18,7 +18,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -package org.sonar.server.issue; +package org.sonar.server.issue.filter; import com.google.common.base.Function; import com.google.common.base.Predicate; @@ -43,15 +43,11 @@ import org.sonar.server.exceptions.UnauthorizedException; import org.sonar.server.user.UserSession; import javax.annotation.CheckForNull; - import java.util.List; import java.util.Map; import static com.google.common.collect.Lists.newArrayList; -/** - * @since 3.7 - */ public class IssueFilterService implements ServerComponent { private final IssueFilterDao filterDao; @@ -60,8 +56,9 @@ public class IssueFilterService implements ServerComponent { private final AuthorizationDao authorizationDao; private final IssueFilterSerializer serializer; - public IssueFilterService(IssueFilterDao filterDao, IssueFilterFavouriteDao favouriteDao, IssueFinder finder, AuthorizationDao authorizationDao, - IssueFilterSerializer serializer) { + public IssueFilterService(IssueFilterDao filterDao, IssueFilterFavouriteDao favouriteDao, + IssueFinder finder, AuthorizationDao authorizationDao, + IssueFilterSerializer serializer) { this.filterDao = filterDao; this.favouriteDao = favouriteDao; this.finder = finder; @@ -205,7 +202,7 @@ public class IssueFilterService implements ServerComponent { return issueFilterDto; } - public boolean canShareFilter(UserSession userSession){ + public boolean canShareFilter(UserSession userSession) { if (userSession.isLoggedIn()) { String user = userSession.login(); return hasUserSharingPermission(user); @@ -213,7 +210,7 @@ public class IssueFilterService implements ServerComponent { return false; } - String getLoggedLogin(UserSession userSession) { + public String getLoggedLogin(UserSession userSession) { String user = userSession.login(); if (!userSession.isLoggedIn()) { throw new UnauthorizedException("User is not logged in"); @@ -221,7 +218,7 @@ public class IssueFilterService implements ServerComponent { return user; } - void verifyCurrentUserCanReadFilter(DefaultIssueFilter issueFilter, String login) { + public void verifyCurrentUserCanReadFilter(DefaultIssueFilter issueFilter, String login) { if (!issueFilter.user().equals(login) && !issueFilter.shared()) { throw new ForbiddenException("User is not authorized to read this filter"); } @@ -301,8 +298,8 @@ public class IssueFilterService implements ServerComponent { private void addFavouriteIssueFilter(Long issueFilterId, String user) { IssueFilterFavouriteDto issueFilterFavouriteDto = new IssueFilterFavouriteDto() - .setIssueFilterId(issueFilterId) - .setUserLogin(user); + .setIssueFilterId(issueFilterId) + .setUserLogin(user); favouriteDao.insert(issueFilterFavouriteDto); } @@ -338,7 +335,7 @@ public class IssueFilterService implements ServerComponent { return new IssueFilterResult(issueQueryResult, issueQuery); } - private boolean hasUserSharingPermission(String user){ + private boolean hasUserSharingPermission(String user) { return authorizationDao.selectGlobalPermissions(user).contains(GlobalPermissions.DASHBOARD_SHARING); } diff --git a/sonar-server/src/main/java/org/sonar/server/issue/filter/IssueFilterWs.java b/sonar-server/src/main/java/org/sonar/server/issue/filter/IssueFilterWs.java new file mode 100644 index 00000000000..4326cc4319b --- /dev/null +++ b/sonar-server/src/main/java/org/sonar/server/issue/filter/IssueFilterWs.java @@ -0,0 +1,101 @@ +/* + * 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.issue.filter; + +import org.sonar.api.server.ws.Request; +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.utils.text.JsonWriter; +import org.sonar.core.issue.DefaultIssueFilter; +import org.sonar.server.user.UserSession; + +import java.util.List; + +public class IssueFilterWs implements WebService { + + private final IssueFilterService service; + + public IssueFilterWs(IssueFilterService service) { + this.service = service; + } + + @Override + public void define(Context context) { + NewController controller = context.newController("api/issue_filters") + .setSince("4.2") + .setDescription("Issue Filters"); + + NewAction search = controller.newAction("page"); + search + .setDescription("Data required for rendering page 'Issues'. Internal use only.") + .setPrivate(true) + .setHandler(new RequestHandler() { + @Override + public void handle(Request request, Response response) throws Exception { + page(request, response); + } + }); + + controller.done(); + } + + private void page(Request request, Response response) { + UserSession session = UserSession.get(); + + JsonWriter json = response.newJsonWriter(); + json.beginObject(); + + // Permissions + json.prop("canManageFilter", session.isLoggedIn()); + json.prop("canBulkChange", session.isLoggedIn()); + + // Current filter (optional) + int filterId = request.intParam("id", -1); + if (filterId >= 0) { + DefaultIssueFilter filter = service.find((long)filterId, session); + json.name("filter") + .beginObject() + .prop("id", filter.id()) + .prop("name", filter.name()) + .prop("user", filter.user()) + .prop("shared", filter.shared()) + .prop("query", filter.data()) + .endObject(); + } + + // Favorite filters, if logged in + if (session.isLoggedIn()) { + List favorites = service.findFavoriteFilters(session); + json.name("favorites").beginArray(); + for (DefaultIssueFilter favorite : favorites) { + json + .beginObject() + .prop("id", favorite.id()) + .prop("name", favorite.name()) + .endObject(); + } + json.endArray(); + } + + json.endObject(); + json.close(); + } +} diff --git a/sonar-server/src/main/java/org/sonar/server/issue/filter/package-info.java b/sonar-server/src/main/java/org/sonar/server/issue/filter/package-info.java new file mode 100644 index 00000000000..2d8d8cbd9ea --- /dev/null +++ b/sonar-server/src/main/java/org/sonar/server/issue/filter/package-info.java @@ -0,0 +1,23 @@ +/* + * 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. + */ +@ParametersAreNonnullByDefault +package org.sonar.server.issue.filter; + +import javax.annotation.ParametersAreNonnullByDefault; diff --git a/sonar-server/src/main/java/org/sonar/server/platform/Platform.java b/sonar-server/src/main/java/org/sonar/server/platform/Platform.java index 85eca5cf65b..bb1ed4c77e9 100644 --- a/sonar-server/src/main/java/org/sonar/server/platform/Platform.java +++ b/sonar-server/src/main/java/org/sonar/server/platform/Platform.java @@ -85,6 +85,8 @@ import org.sonar.server.es.ESNode; import org.sonar.server.group.GroupMembershipFinder; import org.sonar.server.group.InternalGroupMembershipService; import org.sonar.server.issue.*; +import org.sonar.server.issue.filter.IssueFilterService; +import org.sonar.server.issue.filter.IssueFilterWs; import org.sonar.server.notifications.NotificationCenter; import org.sonar.server.notifications.NotificationService; import org.sonar.server.permission.InternalPermissionService; @@ -102,7 +104,7 @@ import org.sonar.server.ui.*; import org.sonar.server.user.DefaultUserService; import org.sonar.server.user.NewUserNotifier; import org.sonar.server.util.*; -import org.sonar.server.ws.ListingWebService; +import org.sonar.server.ws.ListingWs; import org.sonar.server.ws.WebServiceEngine; import javax.annotation.Nullable; @@ -268,7 +270,7 @@ public final class Platform { // web services servicesContainer.addSingleton(WebServiceEngine.class); - servicesContainer.addSingleton(ListingWebService.class); + servicesContainer.addSingleton(ListingWs.class); // quality profiles servicesContainer.addSingleton(ProfileRules.class); @@ -322,6 +324,7 @@ public final class Platform { servicesContainer.addSingleton(IssueFilterService.class); servicesContainer.addSingleton(IssueBulkChangeService.class); servicesContainer.addSingleton(IssueChangelogFormatter.class); + servicesContainer.addSingleton(IssueFilterWs.class); // issues actions servicesContainer.addSingleton(AssignAction.class); servicesContainer.addSingleton(PlanAction.class); @@ -335,7 +338,7 @@ public final class Platform { servicesContainer.addSingleton(RuleTagLookup.class); servicesContainer.addSingleton(RubyRuleService.class); servicesContainer.addSingleton(RuleRepositories.class); - servicesContainer.addSingleton(RuleWebService.class); + servicesContainer.addSingleton(RuleWs.class); // technical debt servicesContainer.addSingleton(InternalRubyTechnicalDebtService.class); diff --git a/sonar-server/src/main/java/org/sonar/server/rule/RuleWebService.java b/sonar-server/src/main/java/org/sonar/server/rule/RuleWs.java similarity index 97% rename from sonar-server/src/main/java/org/sonar/server/rule/RuleWebService.java rename to sonar-server/src/main/java/org/sonar/server/rule/RuleWs.java index de35e668469..898cb4807a2 100644 --- a/sonar-server/src/main/java/org/sonar/server/rule/RuleWebService.java +++ b/sonar-server/src/main/java/org/sonar/server/rule/RuleWs.java @@ -24,7 +24,7 @@ import org.sonar.api.server.ws.RequestHandler; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; -public class RuleWebService implements WebService { +public class RuleWs implements WebService { @Override public void define(Context context) { diff --git a/sonar-server/src/main/java/org/sonar/server/ws/ListingWebService.java b/sonar-server/src/main/java/org/sonar/server/ws/ListingWs.java similarity index 98% rename from sonar-server/src/main/java/org/sonar/server/ws/ListingWebService.java rename to sonar-server/src/main/java/org/sonar/server/ws/ListingWs.java index b1ffa0a1bd7..54c55f874f1 100644 --- a/sonar-server/src/main/java/org/sonar/server/ws/ListingWebService.java +++ b/sonar-server/src/main/java/org/sonar/server/ws/ListingWs.java @@ -33,7 +33,7 @@ import java.util.List; * * @since 4.2 */ -public class ListingWebService implements WebService { +public class ListingWs implements WebService { @Override public void define(final Context context) { diff --git a/sonar-server/src/main/java/org/sonar/server/ws/ServletResponse.java b/sonar-server/src/main/java/org/sonar/server/ws/ServletResponse.java index 448bf213b6f..d5b001b2f57 100644 --- a/sonar-server/src/main/java/org/sonar/server/ws/ServletResponse.java +++ b/sonar-server/src/main/java/org/sonar/server/ws/ServletResponse.java @@ -19,13 +19,18 @@ */ package org.sonar.server.ws; +import org.apache.commons.io.Charsets; +import org.apache.commons.io.IOUtils; +import org.sonar.api.server.ws.Response; import org.sonar.api.utils.text.JsonWriter; import org.sonar.api.utils.text.XmlWriter; -import org.sonar.api.server.ws.Response; +import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletResponse; +import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.OutputStream; +import java.io.StringWriter; public class ServletResponse implements Response { @@ -37,11 +42,7 @@ public class ServletResponse implements Response { @Override public JsonWriter newJsonWriter() { - try { - return JsonWriter.of(source.getWriter()); - } catch (IOException e) { - throw new IllegalStateException(e); - } + return JsonWriter.of(new Buffer(source)); } @Override @@ -54,7 +55,7 @@ public class ServletResponse implements Response { } @Override - public OutputStream output() { + public OutputStream stream() { try { return source.getOutputStream(); } catch (IOException e) { @@ -72,4 +73,28 @@ public class ServletResponse implements Response { source.setStatus(httpStatus); return this; } + + private static class Buffer extends StringWriter { + private final HttpServletResponse httpResponse; + + public Buffer(HttpServletResponse httpResponse) { + this.httpResponse = httpResponse; + } + + @Override + public void close() throws IOException { + super.close(); + + ServletOutputStream stream = null; + try { + stream = httpResponse.getOutputStream(); + IOUtils.copy(new ByteArrayInputStream(toString().getBytes(Charsets.UTF_8)), stream); + stream.flush(); + } catch (IOException e) { + throw new IllegalStateException("Fail to flush buffer", e); + } finally { + IOUtils.closeQuietly(stream); + } + } + } } diff --git a/sonar-server/src/main/java/org/sonar/server/ws/WebServiceEngine.java b/sonar-server/src/main/java/org/sonar/server/ws/WebServiceEngine.java index b1556e57094..43f10176456 100644 --- a/sonar-server/src/main/java/org/sonar/server/ws/WebServiceEngine.java +++ b/sonar-server/src/main/java/org/sonar/server/ws/WebServiceEngine.java @@ -21,12 +21,15 @@ package org.sonar.server.ws; import org.picocontainer.Startable; import org.sonar.api.ServerComponent; -import org.sonar.api.utils.text.JsonWriter; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; +import org.sonar.api.utils.text.JsonWriter; +import org.sonar.server.exceptions.BadRequestException; +import org.sonar.server.exceptions.ServerException; import javax.servlet.http.HttpServletResponse; +import java.io.OutputStreamWriter; import java.util.List; /** @@ -34,15 +37,6 @@ import java.util.List; */ public class WebServiceEngine implements ServerComponent, Startable { - static class RequestException extends Exception { - private final int httpStatus; - - RequestException(int httpStatus, String message) { - super(message); - this.httpStatus = httpStatus; - } - } - private final WebService.Context context; public WebServiceEngine(WebService[] webServices) { @@ -52,10 +46,6 @@ public class WebServiceEngine implements ServerComponent, Startable { } } - public WebServiceEngine() { - this(new WebService[0]); - } - @Override public void start() { // Force execution of constructor to be sure that web services @@ -75,36 +65,36 @@ public class WebServiceEngine implements ServerComponent, Startable { } public void execute(Request request, Response response, - String controllerPath, String actionKey) { + String controllerPath, String actionKey) { try { WebService.Action action = getAction(controllerPath, actionKey); verifyRequest(action, request); action.handler().handle(request, response); - } catch (RequestException e) { - sendError(e.httpStatus, e.getMessage(), response); + } catch (ServerException e) { + // TODO support ServerException l10n messages + sendError(e.httpCode(), e.getMessage(), response); } catch (Exception e) { - // TODO support authentication exceptions and others... sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage(), response); } } - private WebService.Action getAction(String controllerPath, String actionKey) throws RequestException { + private WebService.Action getAction(String controllerPath, String actionKey) { WebService.Controller controller = context.controller(controllerPath); if (controller == null) { - throw new RequestException(HttpServletResponse.SC_BAD_REQUEST, String.format("Unknown web service: %s", controllerPath)); + throw new BadRequestException(String.format("Unknown web service: %s", controllerPath)); } WebService.Action action = controller.action(actionKey); if (action == null) { - throw new RequestException(HttpServletResponse.SC_BAD_REQUEST, String.format("Unknown action: %s/%s", controllerPath, actionKey)); + throw new BadRequestException(String.format("Unknown action: %s/%s", controllerPath, actionKey)); } return action; } - private void verifyRequest(WebService.Action action, Request request) throws RequestException { + private void verifyRequest(WebService.Action action, Request request) { if (request.isPost() != action.isPost()) { - throw new RequestException(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "Method POST is required"); + throw new ServerException(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "Method POST is required"); } // TODO verify required parameters } @@ -112,7 +102,9 @@ public class WebServiceEngine implements ServerComponent, Startable { private void sendError(int status, String message, Response response) { response.setStatus(status); - JsonWriter json = response.newJsonWriter(); + // Reset response by directly using the stream. Response#newJsonWriter() + // must not be used because it potentially contains some partial response + JsonWriter json = JsonWriter.of(new OutputStreamWriter(response.stream())); json.beginObject(); json.name("errors").beginArray(); json.beginObject().prop("msg", message).endObject(); diff --git a/sonar-server/src/main/webapp/WEB-INF/app/controllers/issues_controller.rb b/sonar-server/src/main/webapp/WEB-INF/app/controllers/issues_controller.rb index 99c91d1c19d..57485a69e83 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/controllers/issues_controller.rb +++ b/sonar-server/src/main/webapp/WEB-INF/app/controllers/issues_controller.rb @@ -60,42 +60,6 @@ class IssuesController < ApplicationController end end - # GET /issues/init?[id=] - def page_init - hash = {} - hash[:canBulkChange]=logged_in? - hash[:canManageFilter]=logged_in? - - if logged_in? - favorite_filters = Internal.issues.findFavouriteIssueFiltersForCurrentUser() - hash[:favorites] = favorite_filters.map do |filter| - { - :id => filter.id().to_i, - :name => filter.name(), - :user => filter.user(), - :shared => filter.shared() - # no need to export description and query fields - } - end - end - - if params[:id] - filter = Internal.issues.findIssueFilter(params[:id].to_i) - hash[:filter] = { - :id => filter.id().to_i, - :name => filter.name(), - :user => filter.user(), - :shared => filter.shared(), - :description => filter.description(), - :query => filter.data() - } - end - - respond_to do |format| - format.json { render :json => hash, :status => 200 } - end - end - # Load existing filter # GET /issues/filter/ def filter diff --git a/sonar-server/src/test/java/org/sonar/server/issue/InternalRubyIssueServiceTest.java b/sonar-server/src/test/java/org/sonar/server/issue/InternalRubyIssueServiceTest.java index 850d665e4b3..534283db21a 100644 --- a/sonar-server/src/test/java/org/sonar/server/issue/InternalRubyIssueServiceTest.java +++ b/sonar-server/src/test/java/org/sonar/server/issue/InternalRubyIssueServiceTest.java @@ -36,6 +36,7 @@ import org.sonar.core.resource.ResourceDao; import org.sonar.core.resource.ResourceDto; import org.sonar.core.resource.ResourceQuery; import org.sonar.server.exceptions.BadRequestException; +import org.sonar.server.issue.filter.IssueFilterService; import org.sonar.server.user.UserSession; import java.util.Collections; diff --git a/sonar-server/src/test/java/org/sonar/server/issue/IssueFilterServiceTest.java b/sonar-server/src/test/java/org/sonar/server/issue/filter/IssueFilterServiceTest.java similarity index 95% rename from sonar-server/src/test/java/org/sonar/server/issue/IssueFilterServiceTest.java rename to sonar-server/src/test/java/org/sonar/server/issue/filter/IssueFilterServiceTest.java index c915404efe9..6bfd5b873c9 100644 --- a/sonar-server/src/test/java/org/sonar/server/issue/IssueFilterServiceTest.java +++ b/sonar-server/src/test/java/org/sonar/server/issue/filter/IssueFilterServiceTest.java @@ -18,13 +18,12 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -package org.sonar.server.issue; +package org.sonar.server.issue.filter; import com.google.common.collect.Lists; import org.apache.commons.lang.ObjectUtils; import org.hamcrest.BaseMatcher; import org.hamcrest.Description; -import org.junit.Before; import org.junit.Test; import org.mockito.ArgumentCaptor; import org.sonar.api.issue.IssueFinder; @@ -62,33 +61,18 @@ import static org.mockito.Mockito.*; public class IssueFilterServiceTest { - private IssueFilterService service; - - private IssueFilterDao issueFilterDao; - private IssueFilterFavouriteDao issueFilterFavouriteDao; - private IssueFinder issueFinder; - private AuthorizationDao authorizationDao; - private IssueFilterSerializer issueFilterSerializer; - - private UserSession userSession; - - @Before - public void before() { - userSession = MockUserSession.create().setLogin("john"); - - issueFilterDao = mock(IssueFilterDao.class); - issueFilterFavouriteDao = mock(IssueFilterFavouriteDao.class); - issueFinder = mock(IssueFinder.class); - authorizationDao = mock(AuthorizationDao.class); - issueFilterSerializer = mock(IssueFilterSerializer.class); - - service = new IssueFilterService(issueFilterDao, issueFilterFavouriteDao, issueFinder, authorizationDao, issueFilterSerializer); - } + IssueFilterDao issueFilterDao = mock(IssueFilterDao.class); + IssueFilterFavouriteDao issueFilterFavouriteDao = mock(IssueFilterFavouriteDao.class); + IssueFinder issueFinder = mock(IssueFinder.class); + AuthorizationDao authorizationDao = mock(AuthorizationDao.class); + IssueFilterSerializer issueFilterSerializer = mock(IssueFilterSerializer.class); + UserSession userSession = MockUserSession.create().setLogin("john"); + IssueFilterService service = new IssueFilterService(issueFilterDao, issueFilterFavouriteDao, issueFinder, authorizationDao, issueFilterSerializer); @Test public void should_find_by_id() { - IssueFilterDto issueFilterDto = new IssueFilterDto().setId(1L).setName("My Issue").setUserLogin("john"); - when(issueFilterDao.selectById(1L)).thenReturn(issueFilterDto); + IssueFilterDto dto = new IssueFilterDto().setId(1L).setName("My Issue").setUserLogin("john"); + when(issueFilterDao.selectById(1L)).thenReturn(dto); DefaultIssueFilter issueFilter = service.findById(1L); assertThat(issueFilter).isNotNull(); @@ -218,7 +202,7 @@ public class IssueFilterServiceTest { @Test public void should_not_save_shared_filter_if_name_already_used_by_shared_filter() { - when(issueFilterDao.selectByUser(eq("john"))).thenReturn(Collections. emptyList()); + when(issueFilterDao.selectByUser(eq("john"))).thenReturn(Collections.emptyList()); when(issueFilterDao.selectSharedFilters()).thenReturn(newArrayList(new IssueFilterDto().setId(1L).setName("My Issue").setUserLogin("henry").setShared(true))); DefaultIssueFilter issueFilter = new DefaultIssueFilter().setName("My Issue").setShared(true); try { @@ -546,9 +530,9 @@ public class IssueFilterServiceTest { @Test public void should_find_shared_issue_filter() { when(issueFilterDao.selectSharedFilters()).thenReturn(newArrayList( - new IssueFilterDto().setId(1L).setName("My Issue").setUserLogin("john").setShared(true), - new IssueFilterDto().setId(2L).setName("Project Issues").setUserLogin("arthur").setShared(true) - )); + new IssueFilterDto().setId(1L).setName("My Issue").setUserLogin("john").setShared(true), + new IssueFilterDto().setId(2L).setName("Project Issues").setUserLogin("arthur").setShared(true) + )); List results = service.findSharedFiltersWithoutUserFilters(userSession); assertThat(results).hasSize(1); @@ -580,7 +564,7 @@ public class IssueFilterServiceTest { public void should_add_favourite_issue_filter_id() { when(issueFilterDao.selectById(1L)).thenReturn(new IssueFilterDto().setId(1L).setName("My Issues").setUserLogin("john").setData("componentRoots=struts")); // The filter is not in the favorite list --> add to favorite - when(issueFilterFavouriteDao.selectByFilterId(1L)).thenReturn(Collections. emptyList()); + when(issueFilterFavouriteDao.selectByFilterId(1L)).thenReturn(Collections.emptyList()); ArgumentCaptor issueFilterFavouriteDtoCaptor = ArgumentCaptor.forClass(IssueFilterFavouriteDto.class); boolean result = service.toggleFavouriteIssueFilter(1L, userSession); @@ -596,7 +580,7 @@ public class IssueFilterServiceTest { public void should_add_favourite_on_shared_filter() { when(issueFilterDao.selectById(1L)).thenReturn(new IssueFilterDto().setId(1L).setName("My Issues").setUserLogin("arthur").setShared(true)); // The filter is not in the favorite list --> add to favorite - when(issueFilterFavouriteDao.selectByFilterId(1L)).thenReturn(Collections. emptyList()); + when(issueFilterFavouriteDao.selectByFilterId(1L)).thenReturn(Collections.emptyList()); ArgumentCaptor issueFilterFavouriteDtoCaptor = ArgumentCaptor.forClass(IssueFilterFavouriteDto.class); boolean result = service.toggleFavouriteIssueFilter(1L, userSession); @@ -653,7 +637,7 @@ public class IssueFilterServiceTest { } @Test - public void user_can_share_filter_if_logged_and_own_sharing_permission(){ + public void user_can_share_filter_if_logged_and_own_sharing_permission() { when(authorizationDao.selectGlobalPermissions("john")).thenReturn(newArrayList(GlobalPermissions.DASHBOARD_SHARING)); UserSession userSession = MockUserSession.create().setLogin("john"); assertThat(service.canShareFilter(userSession)).isTrue(); diff --git a/sonar-server/src/test/java/org/sonar/server/issue/filter/IssueFilterWsTest.java b/sonar-server/src/test/java/org/sonar/server/issue/filter/IssueFilterWsTest.java new file mode 100644 index 00000000000..250a1009a73 --- /dev/null +++ b/sonar-server/src/test/java/org/sonar/server/issue/filter/IssueFilterWsTest.java @@ -0,0 +1,96 @@ +/* + * 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.issue.filter; + +import org.junit.Test; +import org.sonar.api.server.ws.SimpleRequest; +import org.sonar.api.server.ws.WebService; +import org.sonar.core.issue.DefaultIssueFilter; +import org.sonar.server.user.MockUserSession; +import org.sonar.server.ws.WsTester; + +import java.util.Arrays; + +import static org.fest.assertions.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class IssueFilterWsTest { + + IssueFilterService service = mock(IssueFilterService.class); + IssueFilterWs ws = new IssueFilterWs(service); + WsTester tester = new WsTester(ws); + + @Test + public void define_ws() throws Exception { + WebService.Controller controller = tester.controller("api/issue_filters"); + assertThat(controller).isNotNull(); + assertThat(controller.description()).isNotEmpty(); + assertThat(controller.since()).isEqualTo("4.2"); + + WebService.Action index = controller.action("page"); + assertThat(index).isNotNull(); + assertThat(index.handler()).isNotNull(); + assertThat(index.isPost()).isFalse(); + assertThat(index.isPrivate()).isTrue(); + } + + @Test + public void anonymous_page() throws Exception { + MockUserSession.set().setLogin(null); + SimpleRequest request = new SimpleRequest(); + tester.execute("page", request).assertJson(getClass(), "anonymous_page.json"); + } + + @Test + public void logged_in_page() throws Exception { + MockUserSession.set().setLogin("eric").setUserId(123); + SimpleRequest request = new SimpleRequest(); + tester.execute("page", request) + .assertHttpStatus(200) + .assertJson(getClass(), "logged_in_page.json"); + } + + @Test + public void logged_in_page_with_favorites() throws Exception { + MockUserSession session = MockUserSession.set().setLogin("eric").setUserId(123); + when(service.findFavoriteFilters(session)).thenReturn(Arrays.asList( + new DefaultIssueFilter().setId(6L).setName("My issues"), + new DefaultIssueFilter().setId(13L).setName("Blocker issues") + )); + SimpleRequest request = new SimpleRequest(); + tester.execute("page", request) + .assertHttpStatus(200) + .assertJson(getClass(), "logged_in_page_with_favorites.json"); + } + + @Test + public void logged_in_page_with_selected_filter() throws Exception { + MockUserSession session = MockUserSession.set().setLogin("eric").setUserId(123); + when(service.find(13L, session)).thenReturn( + new DefaultIssueFilter().setId(13L).setName("Blocker issues").setData("severity=BLOCKER") + ); + + SimpleRequest request = new SimpleRequest().setParam("id", "13"); + tester.execute("page", request) + .assertHttpStatus(200) + .assertJson(getClass(), "logged_in_page_with_selected_filter.json"); + } +} diff --git a/sonar-server/src/test/java/org/sonar/server/rule/RuleWebServiceTest.java b/sonar-server/src/test/java/org/sonar/server/rule/RuleWsTest.java similarity index 67% rename from sonar-server/src/test/java/org/sonar/server/rule/RuleWebServiceTest.java rename to sonar-server/src/test/java/org/sonar/server/rule/RuleWsTest.java index 69e9c4bdc5d..8778dfca58f 100644 --- a/sonar-server/src/test/java/org/sonar/server/rule/RuleWebServiceTest.java +++ b/sonar-server/src/test/java/org/sonar/server/rule/RuleWsTest.java @@ -19,26 +19,21 @@ */ package org.sonar.server.rule; -import org.apache.commons.io.IOUtils; import org.junit.Test; -import org.skyscreamer.jsonassert.JSONAssert; -import org.sonar.api.server.ws.RequestHandler; import org.sonar.api.server.ws.SimpleRequest; -import org.sonar.api.server.ws.SimpleResponse; import org.sonar.api.server.ws.WebService; +import org.sonar.server.ws.WsTester; import static org.fest.assertions.Assertions.assertThat; -public class RuleWebServiceTest { +public class RuleWsTest { - WebService.Context context = new WebService.Context(); - RuleWebService ws = new RuleWebService(); + RuleWs ws = new RuleWs(); + WsTester tester = new WsTester(ws); @Test public void define_ws() throws Exception { - ws.define(context); - - WebService.Controller controller = context.controller("api/rules"); + WebService.Controller controller = tester.controller("api/rules"); assertThat(controller).isNotNull(); assertThat(controller.path()).isEqualTo("api/rules"); assertThat(controller.description()).isNotEmpty(); @@ -53,17 +48,7 @@ public class RuleWebServiceTest { @Test public void search_for_rules() throws Exception { - ws.define(context); - RequestHandler handler = context.controller("api/rules").action("search").handler(); SimpleRequest request = new SimpleRequest(); - SimpleResponse response = new SimpleResponse(); - - handler.handle(request, response); - - String json = response.outputAsString(); - JSONAssert.assertEquals( - IOUtils.toString(getClass().getResource("/org/sonar/server/rule/RuleWebServiceTest/search.json")), - json, true - ); + tester.execute("search", request).assertJson(getClass(), "search.json"); } } diff --git a/sonar-server/src/test/java/org/sonar/server/ws/ListingWebServiceTest.java b/sonar-server/src/test/java/org/sonar/server/ws/ListingWsTest.java similarity index 89% rename from sonar-server/src/test/java/org/sonar/server/ws/ListingWebServiceTest.java rename to sonar-server/src/test/java/org/sonar/server/ws/ListingWsTest.java index 41aebdbf0b7..ce1388bd33e 100644 --- a/sonar-server/src/test/java/org/sonar/server/ws/ListingWebServiceTest.java +++ b/sonar-server/src/test/java/org/sonar/server/ws/ListingWsTest.java @@ -26,13 +26,14 @@ import org.sonar.api.server.ws.*; import static org.fest.assertions.Assertions.assertThat; -public class ListingWebServiceTest { +public class ListingWsTest { + + ListingWs ws = new ListingWs(); + WsTester tester = new WsTester(ws); + @Test public void define_ws() throws Exception { - WebService.Context context = new WebService.Context(); - new ListingWebService().define(context); - - WebService.Controller controller = context.controller("api/webservices"); + WebService.Controller controller = tester.controller("api/webservices"); assertThat(controller).isNotNull(); assertThat(controller.path()).isEqualTo("api/webservices"); assertThat(controller.description()).isNotEmpty(); @@ -52,12 +53,11 @@ public class ListingWebServiceTest { public void index() throws Exception { // register web services, including itself WebService.Context context = new WebService.Context(); - ListingWebService listingWs = new ListingWebService(); - listingWs.define(context); + ws.define(context); new MetricWebService().define(context); SimpleResponse response = new SimpleResponse(); - listingWs.list(context.controllers(), response); + ws.list(context.controllers(), response); JSONAssert.assertEquals( IOUtils.toString(getClass().getResource("/org/sonar/server/ws/ListingWebServiceTest/index.json")), diff --git a/sonar-server/src/test/java/org/sonar/server/ws/WebServiceEngineTest.java b/sonar-server/src/test/java/org/sonar/server/ws/WebServiceEngineTest.java index 727f07d2627..6893f691f58 100644 --- a/sonar-server/src/test/java/org/sonar/server/ws/WebServiceEngineTest.java +++ b/sonar-server/src/test/java/org/sonar/server/ws/WebServiceEngineTest.java @@ -82,8 +82,18 @@ public class WebServiceEngineTest { SimpleResponse response = new SimpleResponse(); engine.execute(request, response, "api/system", "ping"); - assertThat(response.outputAsString()).isEqualTo("{\"errors\":[{\"msg\":\"Method POST is required\"}]}"); assertThat(response.status()).isEqualTo(405); + assertThat(response.outputAsString()).isEqualTo("{\"errors\":[{\"msg\":\"Method POST is required\"}]}"); + } + + @Test + public void internal_error() throws Exception { + Request request = new SimpleRequest(); + SimpleResponse response = new SimpleResponse(); + engine.execute(request, response, "api/system", "fail"); + + assertThat(response.status()).isEqualTo(500); + assertThat(response.outputAsString()).isEqualTo("{\"errors\":[{\"msg\":\"Unexpected\"}]}"); } static class SystemWebService implements WebService { @@ -94,7 +104,7 @@ public class WebServiceEngineTest { .setHandler(new RequestHandler() { @Override public void handle(Request request, Response response) throws Exception { - response.output().write("good".getBytes()); + response.stream().write("good".getBytes()); } }); newController.newAction("ping") @@ -102,7 +112,14 @@ public class WebServiceEngineTest { .setHandler(new RequestHandler() { @Override public void handle(Request request, Response response) throws Exception { - response.output().write("pong".getBytes()); + response.stream().write("pong".getBytes()); + } + }); + newController.newAction("fail") + .setHandler(new RequestHandler() { + @Override + public void handle(Request request, Response response) throws Exception { + throw new IllegalStateException("Unexpected"); } }); newController.done(); diff --git a/sonar-server/src/test/java/org/sonar/server/ws/WsTester.java b/sonar-server/src/test/java/org/sonar/server/ws/WsTester.java new file mode 100644 index 00000000000..54afb95604f --- /dev/null +++ b/sonar-server/src/test/java/org/sonar/server/ws/WsTester.java @@ -0,0 +1,93 @@ +/* + * 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.ws; + +import org.apache.commons.io.IOUtils; +import org.skyscreamer.jsonassert.JSONAssert; +import org.sonar.api.server.ws.Request; +import org.sonar.api.server.ws.RequestHandler; +import org.sonar.api.server.ws.SimpleResponse; +import org.sonar.api.server.ws.WebService; + +import javax.annotation.CheckForNull; +import java.net.URL; + +import static org.junit.Assert.assertEquals; + +/** + * TODO move to sonar-plugin-api with type "test-jar" + */ +public class WsTester { + + private final WebService.Context context = new WebService.Context(); + private String wsPath = null; + + public WsTester(WebService ws) { + ws.define(context); + if (!context.controllers().isEmpty()) { + wsPath = context.controllers().get(0).path(); + } + } + + public WebService.Context context() { + return context; + } + + @CheckForNull + public WebService.Controller controller(String path) { + return context.controller(path); + } + + public Result execute(String actionKey, Request request) throws Exception { + if (wsPath == null) { + throw new IllegalStateException("Ws path is not defined"); + } + SimpleResponse response = new SimpleResponse(); + RequestHandler handler = context.controller(wsPath).action(actionKey).handler(); + handler.handle(request, response); + return new Result(response); + } + + public static class Result { + private final SimpleResponse response; + + private Result(SimpleResponse response) { + this.response = response; + } + + public Result assertHttpStatus(int httpStatus) { + assertEquals(httpStatus, response.status()); + return this; + } + + public Result assertJson(String expectedJson) throws Exception { + String json = response.outputAsString(); + JSONAssert.assertEquals(expectedJson, json, true); + return this; + } + + public Result assertJson(Class clazz, String jsonResourcePath) throws Exception { + String json = response.outputAsString(); + URL url = clazz.getResource(clazz.getSimpleName() + "/" + jsonResourcePath); + JSONAssert.assertEquals(IOUtils.toString(url), json, true); + return this; + } + } +} diff --git a/sonar-server/src/test/resources/org/sonar/server/issue/filter/IssueFilterWsTest/anonymous_page.json b/sonar-server/src/test/resources/org/sonar/server/issue/filter/IssueFilterWsTest/anonymous_page.json new file mode 100644 index 00000000000..7b3ea5bfb13 --- /dev/null +++ b/sonar-server/src/test/resources/org/sonar/server/issue/filter/IssueFilterWsTest/anonymous_page.json @@ -0,0 +1,4 @@ +{ + "canManageFilter": false, + "canBulkChange": false +} \ No newline at end of file diff --git a/sonar-server/src/test/resources/org/sonar/server/issue/filter/IssueFilterWsTest/logged_in_page.json b/sonar-server/src/test/resources/org/sonar/server/issue/filter/IssueFilterWsTest/logged_in_page.json new file mode 100644 index 00000000000..1db0d13a5f0 --- /dev/null +++ b/sonar-server/src/test/resources/org/sonar/server/issue/filter/IssueFilterWsTest/logged_in_page.json @@ -0,0 +1,5 @@ +{ + "canManageFilter": true, + "canBulkChange": true, + "favorites": [] +} \ No newline at end of file diff --git a/sonar-server/src/test/resources/org/sonar/server/issue/filter/IssueFilterWsTest/logged_in_page_with_favorites.json b/sonar-server/src/test/resources/org/sonar/server/issue/filter/IssueFilterWsTest/logged_in_page_with_favorites.json new file mode 100644 index 00000000000..4f4babeeea1 --- /dev/null +++ b/sonar-server/src/test/resources/org/sonar/server/issue/filter/IssueFilterWsTest/logged_in_page_with_favorites.json @@ -0,0 +1,14 @@ +{ + "canManageFilter": true, + "canBulkChange": true, + "favorites": [ + { + "id": 6, + "name": "My issues" + }, + { + "id": 13, + "name": "Blocker issues" + } + ] +} \ No newline at end of file diff --git a/sonar-server/src/test/resources/org/sonar/server/issue/filter/IssueFilterWsTest/logged_in_page_with_selected_filter.json b/sonar-server/src/test/resources/org/sonar/server/issue/filter/IssueFilterWsTest/logged_in_page_with_selected_filter.json new file mode 100644 index 00000000000..18b60b0ccbe --- /dev/null +++ b/sonar-server/src/test/resources/org/sonar/server/issue/filter/IssueFilterWsTest/logged_in_page_with_selected_filter.json @@ -0,0 +1,12 @@ +{ + "canManageFilter": true, + "canBulkChange": true, + "filter": { + "id": 13, + "name": "Blocker issues", + "shared": false, + "query": "severity=BLOCKER" + }, + "favorites": [ + ] +} diff --git a/sonar-server/src/test/resources/org/sonar/server/rule/RuleWebServiceTest/search.json b/sonar-server/src/test/resources/org/sonar/server/rule/RuleWsTest/search.json similarity index 100% rename from sonar-server/src/test/resources/org/sonar/server/rule/RuleWebServiceTest/search.json rename to sonar-server/src/test/resources/org/sonar/server/rule/RuleWsTest/search.json -- 2.39.5