From: Teryk Bellahsene Date: Tue, 19 May 2015 15:32:19 +0000 (+0200) Subject: consistent methods names for all WsAction classes X-Git-Tag: 5.2-RC1~1913 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=8d82c9cf9ba88c1517604b4063ad0fc2a9a1bb9a;p=sonarqube.git consistent methods names for all WsAction classes --- diff --git a/server/sonar-server/src/main/java/org/sonar/server/batch/GlobalAction.java b/server/sonar-server/src/main/java/org/sonar/server/batch/GlobalAction.java new file mode 100644 index 00000000000..84529cae0b7 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/batch/GlobalAction.java @@ -0,0 +1,113 @@ +/* + * 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.batch; + +import org.apache.commons.io.IOUtils; +import org.sonar.api.server.ws.Request; +import org.sonar.api.server.ws.Response; +import org.sonar.api.server.ws.WebService; +import org.sonar.batch.protocol.input.GlobalRepositories; +import org.sonar.core.measure.db.MetricDto; +import org.sonar.core.permission.GlobalPermissions; +import org.sonar.core.persistence.DbSession; +import org.sonar.core.persistence.MyBatis; +import org.sonar.core.properties.PropertiesDao; +import org.sonar.core.properties.PropertyDto; +import org.sonar.server.db.DbClient; +import org.sonar.server.exceptions.ForbiddenException; +import org.sonar.server.plugins.MimeTypes; +import org.sonar.server.user.UserSession; + +public class GlobalAction implements BatchWsAction { + + private final DbClient dbClient; + private final PropertiesDao propertiesDao; + private final UserSession userSession; + + public GlobalAction(DbClient dbClient, PropertiesDao propertiesDao, UserSession userSession) { + this.dbClient = dbClient; + this.propertiesDao = propertiesDao; + this.userSession = userSession; + } + + @Override + public void define(WebService.NewController controller) { + controller.createAction("global") + .setDescription("Return metrics and global properties") + .setSince("4.5") + .setInternal(true) + .setHandler(this); + } + + @Override + public void handle(Request request, Response response) throws Exception { + boolean hasScanPerm = userSession.hasGlobalPermission(GlobalPermissions.SCAN_EXECUTION); + boolean hasPreviewPerm = userSession.hasGlobalPermission(GlobalPermissions.PREVIEW_EXECUTION); + if (!hasPreviewPerm && !hasScanPerm) { + throw new ForbiddenException(Messages.NO_PERMISSION); + } + + DbSession session = dbClient.openSession(false); + try { + GlobalRepositories ref = new GlobalRepositories(); + addMetrics(ref, session); + addSettings(ref, hasScanPerm, hasPreviewPerm, session); + + response.stream().setMediaType(MimeTypes.JSON); + IOUtils.write(ref.toJson(), response.stream().output()); + } finally { + MyBatis.closeQuietly(session); + } + } + + private void addMetrics(GlobalRepositories ref, DbSession session) { + for (MetricDto metric : dbClient.metricDao().selectEnabled(session)) { + Boolean optimizedBestValue = metric.isOptimizedBestValue(); + ref.addMetric( + new org.sonar.batch.protocol.input.Metric(metric.getId(), metric.getKey(), + metric.getValueType(), + metric.getDescription(), + metric.getDirection(), + metric.getKey(), + metric.isQualitative(), + metric.isUserManaged(), + metric.getWorstValue(), + metric.getBestValue(), + optimizedBestValue != null ? optimizedBestValue : false)); + } + } + + private void addSettings(GlobalRepositories ref, boolean hasScanPerm, boolean hasPreviewPerm, DbSession session) { + for (PropertyDto propertyDto : propertiesDao.selectGlobalProperties(session)) { + String key = propertyDto.getKey(); + String value = propertyDto.getValue(); + + if (isPropertyAllowed(key, hasScanPerm, hasPreviewPerm)) { + ref.addGlobalSetting(key, value); + } + } + } + + private static boolean isPropertyAllowed(String key, boolean hasScanPerm, boolean hasPreviewPerm) { + return !key.contains(".secured") || hasScanPerm || (key.contains(".license") && hasPreviewPerm); + } + +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/batch/GlobalRepositoryAction.java b/server/sonar-server/src/main/java/org/sonar/server/batch/GlobalRepositoryAction.java deleted file mode 100644 index 92ca5e923b3..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/batch/GlobalRepositoryAction.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * 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.batch; - -import org.apache.commons.io.IOUtils; -import org.sonar.api.server.ws.Request; -import org.sonar.api.server.ws.Response; -import org.sonar.api.server.ws.WebService; -import org.sonar.batch.protocol.input.GlobalRepositories; -import org.sonar.core.measure.db.MetricDto; -import org.sonar.core.permission.GlobalPermissions; -import org.sonar.core.persistence.DbSession; -import org.sonar.core.persistence.MyBatis; -import org.sonar.core.properties.PropertiesDao; -import org.sonar.core.properties.PropertyDto; -import org.sonar.server.db.DbClient; -import org.sonar.server.exceptions.ForbiddenException; -import org.sonar.server.plugins.MimeTypes; -import org.sonar.server.user.UserSession; - -public class GlobalRepositoryAction implements BatchWsAction { - - private final DbClient dbClient; - private final PropertiesDao propertiesDao; - private final UserSession userSession; - - public GlobalRepositoryAction(DbClient dbClient, PropertiesDao propertiesDao, UserSession userSession) { - this.dbClient = dbClient; - this.propertiesDao = propertiesDao; - this.userSession = userSession; - } - - @Override - public void define(WebService.NewController controller) { - controller.createAction("global") - .setDescription("Return metrics and global properties") - .setSince("4.5") - .setInternal(true) - .setHandler(this); - } - - @Override - public void handle(Request request, Response response) throws Exception { - boolean hasScanPerm = userSession.hasGlobalPermission(GlobalPermissions.SCAN_EXECUTION); - boolean hasPreviewPerm = userSession.hasGlobalPermission(GlobalPermissions.PREVIEW_EXECUTION); - if (!hasPreviewPerm && !hasScanPerm) { - throw new ForbiddenException(Messages.NO_PERMISSION); - } - - DbSession session = dbClient.openSession(false); - try { - GlobalRepositories ref = new GlobalRepositories(); - addMetrics(ref, session); - addSettings(ref, hasScanPerm, hasPreviewPerm, session); - - response.stream().setMediaType(MimeTypes.JSON); - IOUtils.write(ref.toJson(), response.stream().output()); - } finally { - MyBatis.closeQuietly(session); - } - } - - private void addMetrics(GlobalRepositories ref, DbSession session) { - for (MetricDto metric : dbClient.metricDao().selectEnabled(session)) { - Boolean optimizedBestValue = metric.isOptimizedBestValue(); - ref.addMetric( - new org.sonar.batch.protocol.input.Metric(metric.getId(), metric.getKey(), - metric.getValueType(), - metric.getDescription(), - metric.getDirection(), - metric.getKey(), - metric.isQualitative(), - metric.isUserManaged(), - metric.getWorstValue(), - metric.getBestValue(), - optimizedBestValue != null ? optimizedBestValue : false)); - } - } - - private void addSettings(GlobalRepositories ref, boolean hasScanPerm, boolean hasPreviewPerm, DbSession session) { - for (PropertyDto propertyDto : propertiesDao.selectGlobalProperties(session)) { - String key = propertyDto.getKey(); - String value = propertyDto.getValue(); - - if (isPropertyAllowed(key, hasScanPerm, hasPreviewPerm)) { - ref.addGlobalSetting(key, value); - } - } - } - - private static boolean isPropertyAllowed(String key, boolean hasScanPerm, boolean hasPreviewPerm) { - return !key.contains(".secured") || hasScanPerm || (key.contains(".license") && hasPreviewPerm); - } - -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/batch/ProjectAction.java b/server/sonar-server/src/main/java/org/sonar/server/batch/ProjectAction.java new file mode 100644 index 00000000000..77d98330d15 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/batch/ProjectAction.java @@ -0,0 +1,78 @@ +/* + * 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.batch; + +import org.apache.commons.io.IOUtils; +import org.sonar.api.server.ws.Request; +import org.sonar.api.server.ws.Response; +import org.sonar.api.server.ws.WebService; +import org.sonar.batch.protocol.input.ProjectRepositories; +import org.sonar.server.plugins.MimeTypes; + +public class ProjectAction implements BatchWsAction { + + private static final String PARAM_KEY = "key"; + private static final String PARAM_PROFILE = "profile"; + private static final String PARAM_PREVIEW = "preview"; + + private final ProjectRepositoryLoader projectReferentialsLoader; + + public ProjectAction(ProjectRepositoryLoader projectReferentialsLoader) { + this.projectReferentialsLoader = projectReferentialsLoader; + } + + @Override + public void define(WebService.NewController controller) { + WebService.NewAction action = controller.createAction("project") + .setDescription("Return project repository") + .setSince("4.5") + .setInternal(true) + .setHandler(this); + + action + .createParam(PARAM_KEY) + .setRequired(true) + .setDescription("Project or module key") + .setExampleValue("org.codehaus.sonar:sonar"); + + action + .createParam(PARAM_PROFILE) + .setDescription("Profile name") + .setExampleValue("SonarQube Way"); + + action + .createParam(PARAM_PREVIEW) + .setDescription("Preview mode or not") + .setDefaultValue(false) + .setBooleanPossibleValues(); + } + + @Override + public void handle(Request request, Response response) throws Exception { + ProjectRepositories ref = projectReferentialsLoader.load(ProjectRepositoryQuery.create() + .setModuleKey(request.mandatoryParam(PARAM_KEY)) + .setProfileName(request.param(PARAM_PROFILE)) + .setPreview(request.mandatoryParamAsBoolean(PARAM_PREVIEW))); + response.stream().setMediaType(MimeTypes.JSON); + IOUtils.write(ref.toJson(), response.stream().output()); + } + +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/batch/ProjectRepositoryAction.java b/server/sonar-server/src/main/java/org/sonar/server/batch/ProjectRepositoryAction.java deleted file mode 100644 index 9a1369f590e..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/batch/ProjectRepositoryAction.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * 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.batch; - -import org.apache.commons.io.IOUtils; -import org.sonar.api.server.ws.Request; -import org.sonar.api.server.ws.Response; -import org.sonar.api.server.ws.WebService; -import org.sonar.batch.protocol.input.ProjectRepositories; -import org.sonar.server.plugins.MimeTypes; - -public class ProjectRepositoryAction implements BatchWsAction { - - private static final String PARAM_KEY = "key"; - private static final String PARAM_PROFILE = "profile"; - private static final String PARAM_PREVIEW = "preview"; - - private final ProjectRepositoryLoader projectReferentialsLoader; - - public ProjectRepositoryAction(ProjectRepositoryLoader projectReferentialsLoader) { - this.projectReferentialsLoader = projectReferentialsLoader; - } - - @Override - public void define(WebService.NewController controller) { - WebService.NewAction action = controller.createAction("project") - .setDescription("Return project repository") - .setSince("4.5") - .setInternal(true) - .setHandler(this); - - action - .createParam(PARAM_KEY) - .setRequired(true) - .setDescription("Project or module key") - .setExampleValue("org.codehaus.sonar:sonar"); - - action - .createParam(PARAM_PROFILE) - .setDescription("Profile name") - .setExampleValue("SonarQube Way"); - - action - .createParam(PARAM_PREVIEW) - .setDescription("Preview mode or not") - .setDefaultValue(false) - .setBooleanPossibleValues(); - } - - @Override - public void handle(Request request, Response response) throws Exception { - ProjectRepositories ref = projectReferentialsLoader.load(ProjectRepositoryQuery.create() - .setModuleKey(request.mandatoryParam(PARAM_KEY)) - .setProfileName(request.param(PARAM_PROFILE)) - .setPreview(request.mandatoryParamAsBoolean(PARAM_PREVIEW))); - response.stream().setMediaType(MimeTypes.JSON); - IOUtils.write(ref.toJson(), response.stream().output()); - } - -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/component/ws/AppAction.java b/server/sonar-server/src/main/java/org/sonar/server/component/ws/AppAction.java new file mode 100644 index 00000000000..6a09d72477e --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/component/ws/AppAction.java @@ -0,0 +1,230 @@ +/* + * 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.component.ws; + +import org.apache.commons.lang.BooleanUtils; +import org.sonar.api.i18n.I18n; +import org.sonar.api.measures.CoreMetrics; +import org.sonar.api.measures.Metric; +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.Durations; +import org.sonar.api.utils.text.JsonWriter; +import org.sonar.api.web.UserRole; +import org.sonar.core.component.ComponentDto; +import org.sonar.core.measure.db.MeasureDto; +import org.sonar.core.persistence.DbSession; +import org.sonar.core.persistence.MyBatis; +import org.sonar.core.properties.PropertyDto; +import org.sonar.core.properties.PropertyQuery; +import org.sonar.server.db.DbClient; +import org.sonar.server.exceptions.NotFoundException; +import org.sonar.server.user.UserSession; + +import javax.annotation.CheckForNull; +import javax.annotation.Nullable; +import java.util.List; +import java.util.Map; + +import static com.google.common.collect.Lists.newArrayList; +import static com.google.common.collect.Maps.newHashMap; + +public class AppAction implements RequestHandler { + + private static final String PARAM_UUID = "uuid"; + private static final String PARAM_PERIOD = "period"; + private static final List METRIC_KEYS = newArrayList(CoreMetrics.LINES_KEY, CoreMetrics.VIOLATIONS_KEY, + CoreMetrics.COVERAGE_KEY, CoreMetrics.IT_COVERAGE_KEY, CoreMetrics.OVERALL_COVERAGE_KEY, + CoreMetrics.DUPLICATED_LINES_DENSITY_KEY, CoreMetrics.TESTS_KEY, + CoreMetrics.TECHNICAL_DEBT_KEY, CoreMetrics.SQALE_RATING_KEY, CoreMetrics.SQALE_DEBT_RATIO_KEY); + + private final DbClient dbClient; + + private final Durations durations; + private final I18n i18n; + private final UserSession userSession; + + public AppAction(DbClient dbClient, Durations durations, I18n i18n, UserSession userSession) { + this.dbClient = dbClient; + this.durations = durations; + this.i18n = i18n; + this.userSession = userSession; + } + + void define(WebService.NewController controller) { + WebService.NewAction action = controller.createAction("app") + .setDescription("Coverage data required for rendering the component viewer") + .setSince("4.4") + .setInternal(true) + .setHandler(this); + + action + .createParam(PARAM_UUID) + .setRequired(true) + .setDescription("Component UUID") + .setExampleValue("d6d9e1e5-5e13-44fa-ab82-3ec29efa8935"); + + action + .createParam(PARAM_PERIOD) + .setDescription("Period index in order to get differential measures") + .setPossibleValues(1, 2, 3, 4, 5); + } + + @Override + public void handle(Request request, Response response) { + String componentUuid = request.mandatoryParam(PARAM_UUID); + + JsonWriter json = response.newJsonWriter(); + json.beginObject(); + + DbSession session = dbClient.openSession(false); + try { + ComponentDto component = dbClient.componentDao().selectNullableByUuid(session, componentUuid); + if (component == null) { + throw new NotFoundException(String.format("Component '%s' does not exist", componentUuid)); + } + userSession.checkComponentPermission(UserRole.USER, component.getKey()); + + Map measuresByMetricKey = measuresByMetricKey(component, session); + appendComponent(json, component, userSession, session); + appendPermissions(json, component, userSession); + appendMeasures(json, measuresByMetricKey); + + } finally { + MyBatis.closeQuietly(session); + } + + json.endObject(); + json.close(); + } + + private void appendComponent(JsonWriter json, ComponentDto component, UserSession userSession, DbSession session) { + List propertyDtos = dbClient.propertiesDao().selectByQuery(PropertyQuery.builder() + .setKey("favourite") + .setComponentId(component.getId()) + .setUserId(userSession.getUserId()) + .build(), + session + ); + boolean isFavourite = propertyDtos.size() == 1; + + json.prop("key", component.key()); + json.prop("uuid", component.uuid()); + json.prop("path", component.path()); + json.prop("name", component.name()); + json.prop("longName", component.longName()); + json.prop("q", component.qualifier()); + + ComponentDto parentProject = nullableComponentById(component.parentProjectId(), session); + ComponentDto project = dbClient.componentDao().selectByUuid(session, component.projectUuid()); + + // Do not display parent project if parent project and project are the same + boolean displayParentProject = parentProject != null && !parentProject.getId().equals(project.getId()); + json.prop("subProject", displayParentProject ? parentProject.key() : null); + json.prop("subProjectName", displayParentProject ? parentProject.longName() : null); + json.prop("project", project.key()); + json.prop("projectName", project.longName()); + + json.prop("fav", isFavourite); + } + + private void appendPermissions(JsonWriter json, ComponentDto component, UserSession userSession) { + boolean hasBrowsePermission = userSession.hasComponentPermission(UserRole.USER, component.key()); + json.prop("canMarkAsFavourite", userSession.isLoggedIn() && hasBrowsePermission); + json.prop("canCreateManualIssue", userSession.isLoggedIn() && hasBrowsePermission); + } + + private void appendMeasures(JsonWriter json, Map measuresByMetricKey) { + json.name("measures").beginObject(); + json.prop("lines", formatMeasure(measuresByMetricKey.get(CoreMetrics.LINES_KEY))); + json.prop("coverage", formatMeasure(coverageMeasure(measuresByMetricKey))); + json.prop("duplicationDensity", formatMeasure(measuresByMetricKey.get(CoreMetrics.DUPLICATED_LINES_DENSITY_KEY))); + json.prop("issues", formatMeasure(measuresByMetricKey.get(CoreMetrics.VIOLATIONS_KEY))); + json.prop("tests", formatMeasure(measuresByMetricKey.get(CoreMetrics.TESTS_KEY))); + json.prop("debt", formatMeasure(measuresByMetricKey.get(CoreMetrics.TECHNICAL_DEBT_KEY))); + json.prop("sqaleRating", formatMeasure(measuresByMetricKey.get(CoreMetrics.SQALE_RATING_KEY))); + json.prop("debtRatio", formatMeasure(measuresByMetricKey.get(CoreMetrics.SQALE_DEBT_RATIO_KEY))); + json.endObject(); + } + + private MeasureDto coverageMeasure(Map measuresByMetricKey) { + MeasureDto overallCoverage = measuresByMetricKey.get(CoreMetrics.OVERALL_COVERAGE_KEY); + MeasureDto itCoverage = measuresByMetricKey.get(CoreMetrics.IT_COVERAGE_KEY); + MeasureDto utCoverage = measuresByMetricKey.get(CoreMetrics.COVERAGE_KEY); + if (overallCoverage != null) { + return overallCoverage; + } else if (utCoverage != null) { + return utCoverage; + } else { + return itCoverage; + } + } + + private Map measuresByMetricKey(ComponentDto component, DbSession session) { + Map measuresByMetricKey = newHashMap(); + String fileKey = component.getKey(); + for (MeasureDto measureDto : dbClient.measureDao().findByComponentKeyAndMetricKeys(session, fileKey, METRIC_KEYS)) { + measuresByMetricKey.put(measureDto.getMetricKey(), measureDto); + } + return measuresByMetricKey; + } + + @CheckForNull + private ComponentDto nullableComponentById(@Nullable Long componentId, DbSession session) { + if (componentId != null) { + return dbClient.componentDao().selectById(componentId, session); + } + return null; + } + + @CheckForNull + private String formatMeasure(@Nullable MeasureDto measure) { + if (measure == null) { + return null; + } + + Metric metric = CoreMetrics.getMetric(measure.getMetricKey()); + Metric.ValueType metricType = metric.getType(); + Double value = measure.getValue(); + String data = measure.getData(); + if (BooleanUtils.isTrue(metric.isOptimizedBestValue()) && value == null) { + value = metric.getBestValue(); + } + if (metricType.equals(Metric.ValueType.FLOAT) && value != null) { + return i18n.formatDouble(userSession.locale(), value); + } + if (metricType.equals(Metric.ValueType.INT) && value != null) { + return i18n.formatInteger(userSession.locale(), value.intValue()); + } + if (metricType.equals(Metric.ValueType.PERCENT) && value != null) { + return i18n.formatDouble(userSession.locale(), value) + "%"; + } + if (metricType.equals(Metric.ValueType.WORK_DUR) && value != null) { + return durations.format(userSession.locale(), durations.create(value.longValue()), Durations.DurationFormat.SHORT); + } + if ((metricType.equals(Metric.ValueType.STRING) || metricType.equals(Metric.ValueType.RATING)) && data != null) { + return data; + } + return null; + } +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/component/ws/ComponentAppAction.java b/server/sonar-server/src/main/java/org/sonar/server/component/ws/ComponentAppAction.java deleted file mode 100644 index 85c835d9cdb..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/component/ws/ComponentAppAction.java +++ /dev/null @@ -1,229 +0,0 @@ -/* - * 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.component.ws; - -import java.util.List; -import java.util.Map; -import javax.annotation.CheckForNull; -import javax.annotation.Nullable; -import org.apache.commons.lang.BooleanUtils; -import org.sonar.api.i18n.I18n; -import org.sonar.api.measures.CoreMetrics; -import org.sonar.api.measures.Metric; -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.Durations; -import org.sonar.api.utils.text.JsonWriter; -import org.sonar.api.web.UserRole; -import org.sonar.core.component.ComponentDto; -import org.sonar.core.measure.db.MeasureDto; -import org.sonar.core.persistence.DbSession; -import org.sonar.core.persistence.MyBatis; -import org.sonar.core.properties.PropertyDto; -import org.sonar.core.properties.PropertyQuery; -import org.sonar.server.db.DbClient; -import org.sonar.server.exceptions.NotFoundException; -import org.sonar.server.user.UserSession; - -import static com.google.common.collect.Lists.newArrayList; -import static com.google.common.collect.Maps.newHashMap; - -public class ComponentAppAction implements RequestHandler { - - private static final String PARAM_UUID = "uuid"; - private static final String PARAM_PERIOD = "period"; - private static final List METRIC_KEYS = newArrayList(CoreMetrics.LINES_KEY, CoreMetrics.VIOLATIONS_KEY, - CoreMetrics.COVERAGE_KEY, CoreMetrics.IT_COVERAGE_KEY, CoreMetrics.OVERALL_COVERAGE_KEY, - CoreMetrics.DUPLICATED_LINES_DENSITY_KEY, CoreMetrics.TESTS_KEY, - CoreMetrics.TECHNICAL_DEBT_KEY, CoreMetrics.SQALE_RATING_KEY, CoreMetrics.SQALE_DEBT_RATIO_KEY); - - private final DbClient dbClient; - - private final Durations durations; - private final I18n i18n; - private final UserSession userSession; - - public ComponentAppAction(DbClient dbClient, Durations durations, I18n i18n, UserSession userSession) { - this.dbClient = dbClient; - this.durations = durations; - this.i18n = i18n; - this.userSession = userSession; - } - - void define(WebService.NewController controller) { - WebService.NewAction action = controller.createAction("app") - .setDescription("Coverage data required for rendering the component viewer") - .setSince("4.4") - .setInternal(true) - .setHandler(this); - - action - .createParam(PARAM_UUID) - .setRequired(true) - .setDescription("Component UUID") - .setExampleValue("d6d9e1e5-5e13-44fa-ab82-3ec29efa8935"); - - action - .createParam(PARAM_PERIOD) - .setDescription("Period index in order to get differential measures") - .setPossibleValues(1, 2, 3, 4, 5); - } - - @Override - public void handle(Request request, Response response) { - String componentUuid = request.mandatoryParam(PARAM_UUID); - - JsonWriter json = response.newJsonWriter(); - json.beginObject(); - - DbSession session = dbClient.openSession(false); - try { - ComponentDto component = dbClient.componentDao().selectNullableByUuid(session, componentUuid); - if (component == null) { - throw new NotFoundException(String.format("Component '%s' does not exist", componentUuid)); - } - userSession.checkComponentPermission(UserRole.USER, component.getKey()); - - Map measuresByMetricKey = measuresByMetricKey(component, session); - appendComponent(json, component, userSession, session); - appendPermissions(json, component, userSession); - appendMeasures(json, measuresByMetricKey); - - } finally { - MyBatis.closeQuietly(session); - } - - json.endObject(); - json.close(); - } - - private void appendComponent(JsonWriter json, ComponentDto component, UserSession userSession, DbSession session) { - List propertyDtos = dbClient.propertiesDao().selectByQuery(PropertyQuery.builder() - .setKey("favourite") - .setComponentId(component.getId()) - .setUserId(userSession.getUserId()) - .build(), - session - ); - boolean isFavourite = propertyDtos.size() == 1; - - json.prop("key", component.key()); - json.prop("uuid", component.uuid()); - json.prop("path", component.path()); - json.prop("name", component.name()); - json.prop("longName", component.longName()); - json.prop("q", component.qualifier()); - - ComponentDto parentProject = nullableComponentById(component.parentProjectId(), session); - ComponentDto project = dbClient.componentDao().selectByUuid(session, component.projectUuid()); - - // Do not display parent project if parent project and project are the same - boolean displayParentProject = parentProject != null && !parentProject.getId().equals(project.getId()); - json.prop("subProject", displayParentProject ? parentProject.key() : null); - json.prop("subProjectName", displayParentProject ? parentProject.longName() : null); - json.prop("project", project.key()); - json.prop("projectName", project.longName()); - - json.prop("fav", isFavourite); - } - - private void appendPermissions(JsonWriter json, ComponentDto component, UserSession userSession) { - boolean hasBrowsePermission = userSession.hasComponentPermission(UserRole.USER, component.key()); - json.prop("canMarkAsFavourite", userSession.isLoggedIn() && hasBrowsePermission); - json.prop("canCreateManualIssue", userSession.isLoggedIn() && hasBrowsePermission); - } - - private void appendMeasures(JsonWriter json, Map measuresByMetricKey) { - json.name("measures").beginObject(); - json.prop("lines", formatMeasure(measuresByMetricKey.get(CoreMetrics.LINES_KEY))); - json.prop("coverage", formatMeasure(coverageMeasure(measuresByMetricKey))); - json.prop("duplicationDensity", formatMeasure(measuresByMetricKey.get(CoreMetrics.DUPLICATED_LINES_DENSITY_KEY))); - json.prop("issues", formatMeasure(measuresByMetricKey.get(CoreMetrics.VIOLATIONS_KEY))); - json.prop("tests", formatMeasure(measuresByMetricKey.get(CoreMetrics.TESTS_KEY))); - json.prop("debt", formatMeasure(measuresByMetricKey.get(CoreMetrics.TECHNICAL_DEBT_KEY))); - json.prop("sqaleRating", formatMeasure(measuresByMetricKey.get(CoreMetrics.SQALE_RATING_KEY))); - json.prop("debtRatio", formatMeasure(measuresByMetricKey.get(CoreMetrics.SQALE_DEBT_RATIO_KEY))); - json.endObject(); - } - - private MeasureDto coverageMeasure(Map measuresByMetricKey) { - MeasureDto overallCoverage = measuresByMetricKey.get(CoreMetrics.OVERALL_COVERAGE_KEY); - MeasureDto itCoverage = measuresByMetricKey.get(CoreMetrics.IT_COVERAGE_KEY); - MeasureDto utCoverage = measuresByMetricKey.get(CoreMetrics.COVERAGE_KEY); - if (overallCoverage != null) { - return overallCoverage; - } else if (utCoverage != null) { - return utCoverage; - } else { - return itCoverage; - } - } - - private Map measuresByMetricKey(ComponentDto component, DbSession session) { - Map measuresByMetricKey = newHashMap(); - String fileKey = component.getKey(); - for (MeasureDto measureDto : dbClient.measureDao().findByComponentKeyAndMetricKeys(session, fileKey, METRIC_KEYS)) { - measuresByMetricKey.put(measureDto.getMetricKey(), measureDto); - } - return measuresByMetricKey; - } - - @CheckForNull - private ComponentDto nullableComponentById(@Nullable Long componentId, DbSession session) { - if (componentId != null) { - return dbClient.componentDao().selectById(componentId, session); - } - return null; - } - - @CheckForNull - private String formatMeasure(@Nullable MeasureDto measure) { - if (measure == null) { - return null; - } - - Metric metric = CoreMetrics.getMetric(measure.getMetricKey()); - Metric.ValueType metricType = metric.getType(); - Double value = measure.getValue(); - String data = measure.getData(); - if (BooleanUtils.isTrue(metric.isOptimizedBestValue()) && value == null) { - value = metric.getBestValue(); - } - if (metricType.equals(Metric.ValueType.FLOAT) && value != null) { - return i18n.formatDouble(userSession.locale(), value); - } - if (metricType.equals(Metric.ValueType.INT) && value != null) { - return i18n.formatInteger(userSession.locale(), value.intValue()); - } - if (metricType.equals(Metric.ValueType.PERCENT) && value != null) { - return i18n.formatDouble(userSession.locale(), value) + "%"; - } - if (metricType.equals(Metric.ValueType.WORK_DUR) && value != null) { - return durations.format(userSession.locale(), durations.create(value.longValue()), Durations.DurationFormat.SHORT); - } - if ((metricType.equals(Metric.ValueType.STRING) || metricType.equals(Metric.ValueType.RATING)) && data != null) { - return data; - } - return null; - } -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/component/ws/ComponentsWs.java b/server/sonar-server/src/main/java/org/sonar/server/component/ws/ComponentsWs.java index 94cadaa25f7..aba52c5b1bb 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/component/ws/ComponentsWs.java +++ b/server/sonar-server/src/main/java/org/sonar/server/component/ws/ComponentsWs.java @@ -26,10 +26,10 @@ import org.sonar.api.server.ws.WebService; public class ComponentsWs implements WebService { - private final ComponentAppAction appAction; + private final AppAction appAction; private final SearchAction searchAction; - public ComponentsWs(ComponentAppAction appAction, SearchAction searchAction) { + public ComponentsWs(AppAction appAction, SearchAction searchAction) { this.appAction = appAction; this.searchAction = searchAction; } diff --git a/server/sonar-server/src/main/java/org/sonar/server/component/ws/ProjectsDeleteAction.java b/server/sonar-server/src/main/java/org/sonar/server/component/ws/ProjectsDeleteAction.java deleted file mode 100644 index 179a24d741b..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/component/ws/ProjectsDeleteAction.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * 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.component.ws; - -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.web.UserRole; -import org.sonar.core.component.ComponentDto; -import org.sonar.core.persistence.DbSession; -import org.sonar.core.persistence.MyBatis; -import org.sonar.server.component.ComponentCleanerService; -import org.sonar.server.db.DbClient; -import org.sonar.server.user.UserSession; - -import javax.annotation.Nullable; - -import java.util.List; - -public class ProjectsDeleteAction implements ProjectsWsAction { - private static final String ACTION = "delete"; - private static final String PARAM_UUIDS = "uuids"; - private static final String PARAM_KEYS = "keys"; - - private final ComponentCleanerService componentCleanerService; - private final DbClient dbClient; - private final UserSession userSession; - - public ProjectsDeleteAction(ComponentCleanerService componentCleanerService, DbClient dbClient, UserSession userSession) { - this.componentCleanerService = componentCleanerService; - this.dbClient = dbClient; - this.userSession = userSession; - } - - @Override - public void define(WebService.NewController context) { - WebService.NewAction action = context - .createAction(ACTION) - .setDescription("Delete one or several projects.
Requires Admin permission.") - .setSince("5.2") - .setHandler(this); - - action - .createParam(PARAM_UUIDS) - .setDescription("List of project UUIDs to delete") - .setExampleValue("ce4c03d6-430f-40a9-b777-ad877c00aa4d,c526ef20-131b-4486-9357-063fa64b5079"); - - action - .createParam(PARAM_KEYS) - .setDescription("List of project keys to delete") - .setExampleValue("org.apache.hbas:hbase,com.microsoft.roslyn:roslyn"); - } - - @Override - public void handle(Request request, Response response) throws Exception { - userSession.checkGlobalPermission(UserRole.ADMIN); - List uuids = request.paramAsStrings(PARAM_UUIDS); - List keys = request.paramAsStrings(PARAM_KEYS); - - DbSession dbSession = dbClient.openSession(false); - try { - List projects = searchProjects(dbSession, uuids, keys); - componentCleanerService.delete(dbSession, projects); - } finally { - MyBatis.closeQuietly(dbSession); - } - - response.noContent(); - } - - private List searchProjects(DbSession dbSession, @Nullable List uuids, @Nullable List keys) { - if (uuids != null) { - return dbClient.componentDao().selectByUuids(dbSession, uuids); - } - if (keys != null) { - return dbClient.componentDao().selectByKeys(dbSession, keys); - } - - throw new IllegalArgumentException("UUIDs or keys must be provided"); - } -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/component/ws/ProjectsGhostsAction.java b/server/sonar-server/src/main/java/org/sonar/server/component/ws/ProjectsGhostsAction.java deleted file mode 100644 index d230af26050..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/component/ws/ProjectsGhostsAction.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * 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.component.ws; - -import com.google.common.io.Resources; -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.server.ws.WebService.Param; -import org.sonar.api.utils.text.JsonWriter; -import org.sonar.api.web.UserRole; -import org.sonar.core.component.ComponentDto; -import org.sonar.core.persistence.DbSession; -import org.sonar.core.persistence.MyBatis; -import org.sonar.server.db.DbClient; -import org.sonar.server.es.SearchOptions; -import org.sonar.server.user.UserSession; - -import javax.annotation.Nullable; - -import java.util.Date; -import java.util.List; -import java.util.Set; - -import static com.google.common.collect.Sets.newHashSet; - -public class ProjectsGhostsAction implements ProjectsWsAction { - public static final String ACTION = "ghosts"; - private static final Set POSSIBLE_FIELDS = newHashSet("uuid", "key", "name", "creationDate"); - - private final DbClient dbClient; - private final UserSession userSession; - - public ProjectsGhostsAction(DbClient dbClient, UserSession userSession) { - this.dbClient = dbClient; - this.userSession = userSession; - } - - @Override - public void define(WebService.NewController context) { - context - .createAction(ACTION) - .setDescription("List ghost projects.
Requires 'Administer System' permission.") - .setResponseExample(Resources.getResource(getClass(), "projects-example-ghosts.json")) - .setSince("5.2") - .addPagingParams(100) - .addFieldsParam(POSSIBLE_FIELDS) - .addSearchQuery("sonar", "names", "keys") - .setHandler(this); - } - - @Override - public void handle(Request request, Response response) throws Exception { - userSession.checkGlobalPermission(UserRole.ADMIN); - DbSession dbSession = dbClient.openSession(false); - SearchOptions searchOptions = new SearchOptions() - .setPage(request.mandatoryParamAsInt(Param.PAGE), - request.mandatoryParamAsInt(Param.PAGE_SIZE)); - Set desiredFields = fieldsToReturn(request.paramAsStrings(Param.FIELDS)); - String query = request.param(Param.TEXT_QUERY); - - try { - long nbOfProjects = dbClient.componentDao().countGhostProjects(dbSession, query); - List projects = dbClient.componentDao().selectGhostProjects(dbSession, query, searchOptions); - JsonWriter json = response.newJsonWriter().beginObject(); - writeProjects(json, projects, desiredFields); - searchOptions.writeJson(json, nbOfProjects); - json.endObject().close(); - } finally { - MyBatis.closeQuietly(dbSession); - } - } - - private void writeProjects(JsonWriter json, List projects, Set fieldsToReturn) { - json.name("projects"); - json.beginArray(); - for (ComponentDto project : projects) { - json.beginObject(); - json.prop("uuid", project.uuid()); - writeIfWished(json, "key", project.key(), fieldsToReturn); - writeIfWished(json, "name", project.name(), fieldsToReturn); - writeIfWished(json, "creationDate", project.getCreatedAt(), fieldsToReturn); - json.endObject(); - } - json.endArray(); - } - - private void writeIfWished(JsonWriter json, String key, String value, Set fieldsToReturn) { - if (fieldsToReturn.contains(key)) { - json.prop(key, value); - } - } - - private void writeIfWished(JsonWriter json, String key, Date value, Set desiredFields) { - if (desiredFields.contains(key)) { - json.propDateTime(key, value); - } - } - - private Set fieldsToReturn(@Nullable List desiredFieldsFromRequest) { - if (desiredFieldsFromRequest == null) { - return POSSIBLE_FIELDS; - } - - return newHashSet(desiredFieldsFromRequest); - } -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/component/ws/ProjectsProvisionedAction.java b/server/sonar-server/src/main/java/org/sonar/server/component/ws/ProjectsProvisionedAction.java deleted file mode 100644 index 90d2b8cad37..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/component/ws/ProjectsProvisionedAction.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * 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.component.ws; - -import com.google.common.io.Resources; -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.server.ws.WebService.Param; -import org.sonar.api.utils.text.JsonWriter; -import org.sonar.core.component.ComponentDto; -import org.sonar.core.permission.GlobalPermissions; -import org.sonar.core.persistence.DbSession; -import org.sonar.core.persistence.MyBatis; -import org.sonar.server.db.DbClient; -import org.sonar.server.es.SearchOptions; -import org.sonar.server.user.UserSession; - -import java.util.Date; -import java.util.List; -import java.util.Set; - -import static com.google.common.collect.Sets.newHashSet; - -public class ProjectsProvisionedAction implements ProjectsWsAction { - private static final Set POSSIBLE_FIELDS = newHashSet("uuid", "key", "name", "creationDate"); - - private final DbClient dbClient; - private final UserSession userSession; - - public ProjectsProvisionedAction(DbClient dbClient, UserSession userSession) { - this.dbClient = dbClient; - this.userSession = userSession; - } - - @Override - public void define(WebService.NewController controller) { - controller - .createAction("provisioned") - .setDescription( - "Get the list of provisioned projects.
" + - "Require 'Provision Projects' permission.") - .setSince("5.2") - .setResponseExample(Resources.getResource(getClass(), "projects-example-provisioned.json")) - .setHandler(this) - .addPagingParams(100) - .addSearchQuery("sonar", "names", "keys") - .addFieldsParam(POSSIBLE_FIELDS); - } - - @Override - public void handle(Request request, Response response) throws Exception { - userSession.checkGlobalPermission(GlobalPermissions.PROVISIONING); - SearchOptions options = new SearchOptions().setPage( - request.mandatoryParamAsInt(Param.PAGE), - request.mandatoryParamAsInt(Param.PAGE_SIZE) - ); - Set desiredFields = desiredFields(request); - String query = request.param(Param.TEXT_QUERY); - - DbSession dbSession = dbClient.openSession(false); - try { - List projects = dbClient.componentDao().selectProvisionedProjects(dbSession, options, query); - int nbOfProjects = dbClient.componentDao().countProvisionedProjects(dbSession, query); - JsonWriter json = response.newJsonWriter().beginObject(); - writeProjects(projects, json, desiredFields); - options.writeJson(json, nbOfProjects); - json.endObject().close(); - } finally { - MyBatis.closeQuietly(dbSession); - } - } - - private void writeProjects(List projects, JsonWriter json, Set desiredFields) { - json.name("projects"); - json.beginArray(); - for (ComponentDto project : projects) { - json.beginObject(); - json.prop("uuid", project.uuid()); - writeIfNeeded(json, "key", project.key(), desiredFields); - writeIfNeeded(json, "name", project.name(), desiredFields); - writeIfNeeded(json, "creationDate", project.getCreatedAt(), desiredFields); - json.endObject(); - } - json.endArray(); - } - - private void writeIfNeeded(JsonWriter json, String fieldName, String value, Set desiredFields) { - if (desiredFields.contains(fieldName)) { - json.prop(fieldName, value); - } - } - - private void writeIfNeeded(JsonWriter json, String fieldName, Date date, Set desiredFields) { - if (desiredFields.contains(fieldName)) { - json.propDateTime(fieldName, date); - } - } - - private Set desiredFields(Request request) { - List desiredFields = request.paramAsStrings(Param.FIELDS); - if (desiredFields == null) { - return POSSIBLE_FIELDS; - } - - return newHashSet(desiredFields); - } -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/component/ws/ProjectsWs.java b/server/sonar-server/src/main/java/org/sonar/server/component/ws/ProjectsWs.java deleted file mode 100644 index 4b6e9e10501..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/component/ws/ProjectsWs.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * 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.component.ws; - -import com.google.common.io.Resources; -import org.sonar.api.server.ws.RailsHandler; -import org.sonar.api.server.ws.WebService; - -public class ProjectsWs implements WebService { - private static final String ENDPOINT = "api/projects"; - - private final ProjectsWsAction[] actions; - - public ProjectsWs(ProjectsWsAction... actions) { - this.actions = actions; - } - - @Override - public void define(Context context) { - NewController controller = context.createController(ENDPOINT) - .setSince("2.10") - .setDescription("Projects management"); - - defineIndexAction(controller); - defineCreateAction(controller); - defineDestroyAction(controller); - - for (ProjectsWsAction action : actions) { - action.define(controller); - } - - controller.done(); - } - - private void defineIndexAction(NewController controller) { - WebService.NewAction action = controller.createAction("index") - .setDescription("Search for projects") - .setSince("2.10") - .setHandler(RailsHandler.INSTANCE) - .setResponseExample(Resources.getResource(this.getClass(), "projects-example-index.json")); - - action.createParam("key") - .setDescription("id or key of the project") - .setExampleValue("org.codehaus.sonar:sonar"); - - action.createParam("search") - .setDescription("Substring of project name, case insensitive") - .setExampleValue("Sonar"); - - action.createParam("desc") - .setDescription("Load project description") - .setDefaultValue("true") - .setPossibleValues("true", "false"); - - action.createParam("subprojects") - .setDescription("Load sub-projects. Ignored if the parameter key is set") - .setDefaultValue("false") - .setPossibleValues("true", "false"); - - action.createParam("views") - .setDescription("Load views and sub-views. Ignored if the parameter key is set") - .setDefaultValue("false") - .setPossibleValues("true", "false"); - - action.createParam("libs") - .setDescription("Load libraries. Ignored if the parameter key is set") - .setDefaultValue("false") - .setPossibleValues("true", "false"); - - action.createParam("versions") - .setDescription("Load version") - .setDefaultValue("false") - .setPossibleValues("true", "false", "last"); - - RailsHandler.addFormatParam(action); - } - - private void defineCreateAction(NewController controller) { - WebService.NewAction action = controller.createAction("create") - .setDescription("Provision a project. Requires Provision Projects permission") - .setSince("4.0") - .setPost(true) - .setHandler(RailsHandler.INSTANCE) - .setResponseExample(Resources.getResource(this.getClass(), "projects-example-create.json")); - - action.createParam("key") - .setDescription("Key of the project") - .setRequired(true) - .setExampleValue("org.codehaus.sonar:sonar"); - - action.createParam("name") - .setDescription("Name of the project") - .setRequired(true) - .setExampleValue("SonarQube"); - - action.createParam("branch") - .setDescription("SCM Branch of the project. The key of the project will become key:branch, for instance 'SonarQube:branch-5.0'") - .setRequired(false) - .setExampleValue("branch-5.0"); - - RailsHandler.addFormatParam(action); - } - - private void defineDestroyAction(NewController controller) { - WebService.NewAction action = controller.createAction("destroy") - .setDescription("Delete a project. Requires Administer System permission") - .setSince("2.11") - .setPost(true) - .setHandler(RailsHandler.INSTANCE); - - action.createParam("id") - .setDescription("id or key of the resource (ie: component)") - .setRequired(true) - .setExampleValue("org.codehaus.sonar:sonar"); - } - -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/component/ws/ProjectsWsAction.java b/server/sonar-server/src/main/java/org/sonar/server/component/ws/ProjectsWsAction.java deleted file mode 100644 index 6423e0c011c..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/component/ws/ProjectsWsAction.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * 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.component.ws; - -import org.sonar.server.ws.WsAction; - -public interface ProjectsWsAction extends WsAction { - // marker interface -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/ws/ComputationWsAction.java b/server/sonar-server/src/main/java/org/sonar/server/computation/ws/ComputationWsAction.java index a4a9dd772c1..10ea28e79a9 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/ws/ComputationWsAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/ws/ComputationWsAction.java @@ -20,11 +20,12 @@ package org.sonar.server.computation.ws; import org.sonar.api.server.ws.WebService; +import org.sonar.server.ws.WsAction; /** * Used by {@link ComputationWs} to * loop over all its actions */ -interface ComputationWsAction { +interface ComputationWsAction extends WsAction{ void define(WebService.NewController controller); } diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/ws/HistoryAction.java b/server/sonar-server/src/main/java/org/sonar/server/computation/ws/HistoryAction.java new file mode 100644 index 00000000000..0320fcdefdf --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/ws/HistoryAction.java @@ -0,0 +1,90 @@ +/* + * 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.computation.ws; + +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.core.permission.GlobalPermissions; +import org.sonar.server.activity.Activity; +import org.sonar.server.activity.index.ActivityDoc; +import org.sonar.server.activity.index.ActivityIndex; +import org.sonar.server.activity.index.ActivityQuery; +import org.sonar.server.es.SearchOptions; +import org.sonar.server.es.SearchResult; +import org.sonar.server.issue.ws.IssuesWs; +import org.sonar.server.user.UserSession; + +import java.util.Arrays; +import java.util.Map; + +// FIXME replace by api/activities/search +public class HistoryAction implements ComputationWsAction { + private final ActivityIndex activityIndex; + private final UserSession userSession; + + public HistoryAction(ActivityIndex activityIndex, UserSession userSession) { + this.activityIndex = activityIndex; + this.userSession = userSession; + } + + @Override + public void define(WebService.NewController controller) { + WebService.NewAction action = controller + .createAction("history") + .setDescription("Past integrations of analysis reports") + .setSince("5.0") + .setInternal(true) + .setHandler(this); + + action.addPagingParams(10); + } + + @Override + public void handle(Request request, Response response) { + userSession.checkGlobalPermission(GlobalPermissions.SYSTEM_ADMIN); + + ActivityQuery query = new ActivityQuery(); + query.setTypes(Arrays.asList(Activity.Type.ANALYSIS_REPORT.name())); + + SearchOptions options = new SearchOptions(); + options.setPage(request.mandatoryParamAsInt(IssuesWs.Param.PAGE), request.mandatoryParamAsInt(IssuesWs.Param.PAGE_SIZE)); + SearchResult results = activityIndex.search(query, options); + + JsonWriter json = response.newJsonWriter().beginObject(); + options.writeJson(json, results.getTotal()); + writeReports(results, json); + json.endObject().close(); + } + + private void writeReports(SearchResult result, JsonWriter json) { + json.name("reports").beginArray(); + for (ActivityDoc doc : result.getDocs()) { + json.beginObject(); + for (Map.Entry detail : doc.getDetails().entrySet()) { + json.prop(detail.getKey(), detail.getValue()); + } + json.endObject(); + } + json.endArray(); + } +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/ws/HistoryWsAction.java b/server/sonar-server/src/main/java/org/sonar/server/computation/ws/HistoryWsAction.java deleted file mode 100644 index 0bb4d2b1155..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/ws/HistoryWsAction.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * 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.computation.ws; - -import java.util.Arrays; -import java.util.Map; -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.permission.GlobalPermissions; -import org.sonar.server.activity.Activity; -import org.sonar.server.activity.index.ActivityDoc; -import org.sonar.server.activity.index.ActivityIndex; -import org.sonar.server.activity.index.ActivityQuery; -import org.sonar.server.es.SearchOptions; -import org.sonar.server.es.SearchResult; -import org.sonar.server.issue.ws.IssuesWs; -import org.sonar.server.user.UserSession; - -// FIXME replace by api/activities/search -public class HistoryWsAction implements ComputationWsAction, RequestHandler { - - public static final String PARAM_TYPE = "type"; - - private final ActivityIndex activityIndex; - private final UserSession userSession; - - public HistoryWsAction(ActivityIndex activityIndex, UserSession userSession) { - this.activityIndex = activityIndex; - this.userSession = userSession; - } - - @Override - public void define(WebService.NewController controller) { - WebService.NewAction action = controller - .createAction("history") - .setDescription("Past integrations of analysis reports") - .setSince("5.0") - .setInternal(true) - .setHandler(this); - - action.addPagingParams(10); - } - - @Override - public void handle(Request request, Response response) { - userSession.checkGlobalPermission(GlobalPermissions.SYSTEM_ADMIN); - - ActivityQuery query = new ActivityQuery(); - query.setTypes(Arrays.asList(Activity.Type.ANALYSIS_REPORT.name())); - - SearchOptions options = new SearchOptions(); - options.setPage(request.mandatoryParamAsInt(IssuesWs.Param.PAGE), request.mandatoryParamAsInt(IssuesWs.Param.PAGE_SIZE)); - SearchResult results = activityIndex.search(query, options); - - JsonWriter json = response.newJsonWriter().beginObject(); - options.writeJson(json, results.getTotal()); - writeReports(results, json); - json.endObject().close(); - } - - private void writeReports(SearchResult result, JsonWriter json) { - json.name("reports").beginArray(); - for (ActivityDoc doc : result.getDocs()) { - json.beginObject(); - for (Map.Entry detail : doc.getDetails().entrySet()) { - json.prop(detail.getKey(), detail.getValue()); - } - json.endObject(); - } - json.endArray(); - } -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/ws/IsQueueEmptyWs.java b/server/sonar-server/src/main/java/org/sonar/server/computation/ws/IsQueueEmptyWs.java index d9c83b0fff1..ab580c50a98 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/ws/IsQueueEmptyWs.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/ws/IsQueueEmptyWs.java @@ -36,10 +36,10 @@ import java.util.List; public class IsQueueEmptyWs implements WebService { public static final String API_ENDPOINT = "api/analysis_reports"; - private final IsQueueEmptyWsAction action; + private final IsQueueEmptyAction action; public IsQueueEmptyWs(ReportQueue queue) { - this.action = new IsQueueEmptyWsAction(queue); + this.action = new IsQueueEmptyAction(queue); } @Override @@ -51,10 +51,10 @@ public class IsQueueEmptyWs implements WebService { controller.done(); } - static class IsQueueEmptyWsAction implements RequestHandler { + static class IsQueueEmptyAction implements RequestHandler { private final ReportQueue queue; - public IsQueueEmptyWsAction(ReportQueue queue) { + public IsQueueEmptyAction(ReportQueue queue) { this.queue = queue; } diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/ws/QueueAction.java b/server/sonar-server/src/main/java/org/sonar/server/computation/ws/QueueAction.java new file mode 100644 index 00000000000..fd20ecf2977 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/ws/QueueAction.java @@ -0,0 +1,80 @@ +/* + * 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.computation.ws; + +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.core.computation.db.AnalysisReportDto; +import org.sonar.server.computation.ReportQueue; + +import java.util.List; + +import static org.sonar.api.utils.DateUtils.longToDate; + +/** + * @since 5.0 + */ +public class QueueAction implements ComputationWsAction { + private final ReportQueue queue; + + public QueueAction(ReportQueue queue) { + this.queue = queue; + } + + @Override + public void define(WebService.NewController controller) { + controller + .createAction("queue") + .setDescription("List all the active analysis reports") + .setSince("5.0") + .setInternal(true) + .setHandler(this); + } + + @Override + public void handle(Request request, Response response) throws Exception { + List reports = queue.all(); + + JsonWriter json = response.newJsonWriter().beginObject(); + writeReports(reports, json); + json.endObject(); + json.close(); + } + + private void writeReports(List reports, JsonWriter json) { + json.name("reports").beginArray(); + for (AnalysisReportDto report : reports) { + json.beginObject(); + json.prop("key", report.getId()); + json.prop("projectKey", report.getProjectKey()); + json.prop("projectName", report.getProjectKey()); + json.propDateTime("startedAt", longToDate(report.getStartedAt())); + json.propDateTime("finishedAt", longToDate(report.getFinishedAt())); + json.propDateTime("submittedAt", longToDate(report.getCreatedAt())); + json.prop("status", report.getStatus().toString()); + json.endObject(); + } + json.endArray(); + } + +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/ws/QueueWsAction.java b/server/sonar-server/src/main/java/org/sonar/server/computation/ws/QueueWsAction.java deleted file mode 100644 index 39e6d3dcff4..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/ws/QueueWsAction.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * 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.computation.ws; - -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.computation.db.AnalysisReportDto; -import org.sonar.server.computation.ReportQueue; - -import java.util.List; - -import static org.sonar.api.utils.DateUtils.longToDate; - -/** - * @since 5.0 - */ -public class QueueWsAction implements ComputationWsAction, RequestHandler { - private final ReportQueue queue; - - public QueueWsAction(ReportQueue queue) { - this.queue = queue; - } - - @Override - public void define(WebService.NewController controller) { - controller - .createAction("queue") - .setDescription("List all the active analysis reports") - .setSince("5.0") - .setInternal(true) - .setHandler(this); - } - - @Override - public void handle(Request request, Response response) throws Exception { - List reports = queue.all(); - - JsonWriter json = response.newJsonWriter().beginObject(); - writeReports(reports, json); - json.endObject(); - json.close(); - } - - private void writeReports(List reports, JsonWriter json) { - json.name("reports").beginArray(); - for (AnalysisReportDto report : reports) { - json.beginObject(); - json.prop("key", report.getId()); - json.prop("projectKey", report.getProjectKey()); - json.prop("projectName", report.getProjectKey()); - json.propDateTime("startedAt", longToDate(report.getStartedAt())); - json.propDateTime("finishedAt", longToDate(report.getFinishedAt())); - json.propDateTime("submittedAt", longToDate(report.getCreatedAt())); - json.prop("status", report.getStatus().toString()); - json.endObject(); - } - json.endArray(); - } - -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/ws/SubmitReportAction.java b/server/sonar-server/src/main/java/org/sonar/server/computation/ws/SubmitReportAction.java new file mode 100644 index 00000000000..86f290b1f7d --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/ws/SubmitReportAction.java @@ -0,0 +1,89 @@ +/* + * 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.computation.ws; + +import org.apache.commons.io.IOUtils; +import org.sonar.api.server.ws.Request; +import org.sonar.api.server.ws.Response; +import org.sonar.api.server.ws.WebService; +import org.sonar.core.permission.GlobalPermissions; +import org.sonar.server.computation.ComputationThreadLauncher; +import org.sonar.server.computation.ReportQueue; +import org.sonar.server.user.UserSession; + +import java.io.InputStream; + +public class SubmitReportAction implements ComputationWsAction { + + public static final String ACTION = "submit_report"; + public static final String PARAM_PROJECT_KEY = "projectKey"; + public static final String PARAM_REPORT_DATA = "report"; + + private final ReportQueue queue; + private final ComputationThreadLauncher workerLauncher; + private final UserSession userSession; + + public SubmitReportAction(ReportQueue queue, ComputationThreadLauncher workerLauncher, UserSession userSession) { + this.queue = queue; + this.workerLauncher = workerLauncher; + this.userSession = userSession; + } + + @Override + public void define(WebService.NewController controller) { + WebService.NewAction action = controller.createAction(ACTION) + .setDescription("Submit an analysis report to the queue. Report is integrated asynchronously.") + .setPost(true) + .setInternal(true) + .setHandler(this); + + action + .createParam(PARAM_PROJECT_KEY) + .setRequired(true) + .setDescription("Project key") + .setExampleValue("org.codehaus.sonar:sonar"); + + action + .createParam(PARAM_REPORT_DATA) + .setRequired(true) + .setDescription("Report file. Format is not an API, it changes among SonarQube versions."); + } + + @Override + public void handle(Request request, Response response) throws Exception { + userSession.checkGlobalPermission(GlobalPermissions.SCAN_EXECUTION); + String projectKey = request.mandatoryParam(PARAM_PROJECT_KEY); + InputStream reportData = request.paramAsInputStream(PARAM_REPORT_DATA); + try { + ReportQueue.Item item = queue.add(projectKey, reportData); + workerLauncher.startAnalysisTaskNow(); + response.newJsonWriter() + .beginObject() + // do not write integer for forward-compatibility, for example + // if we want to write UUID later + .prop("key", String.valueOf(item.dto.getId())) + .endObject() + .close(); + } finally { + IOUtils.closeQuietly(reportData); + } + } +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/ws/SubmitReportWsAction.java b/server/sonar-server/src/main/java/org/sonar/server/computation/ws/SubmitReportWsAction.java deleted file mode 100644 index 2c1347e956f..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/ws/SubmitReportWsAction.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * 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.computation.ws; - -import java.io.InputStream; -import org.apache.commons.io.IOUtils; -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.core.permission.GlobalPermissions; -import org.sonar.server.computation.ComputationThreadLauncher; -import org.sonar.server.computation.ReportQueue; -import org.sonar.server.user.UserSession; - -public class SubmitReportWsAction implements ComputationWsAction, RequestHandler { - - public static final String ACTION = "submit_report"; - public static final String PARAM_PROJECT_KEY = "projectKey"; - public static final String PARAM_REPORT_DATA = "report"; - - private final ReportQueue queue; - private final ComputationThreadLauncher workerLauncher; - private final UserSession userSession; - - public SubmitReportWsAction(ReportQueue queue, ComputationThreadLauncher workerLauncher, UserSession userSession) { - this.queue = queue; - this.workerLauncher = workerLauncher; - this.userSession = userSession; - } - - @Override - public void define(WebService.NewController controller) { - WebService.NewAction action = controller.createAction(ACTION) - .setDescription("Submit an analysis report to the queue. Report is integrated asynchronously.") - .setPost(true) - .setInternal(true) - .setHandler(this); - - action - .createParam(PARAM_PROJECT_KEY) - .setRequired(true) - .setDescription("Project key") - .setExampleValue("org.codehaus.sonar:sonar"); - - action - .createParam(PARAM_REPORT_DATA) - .setRequired(true) - .setDescription("Report file. Format is not an API, it changes among SonarQube versions."); - } - - @Override - public void handle(Request request, Response response) throws Exception { - userSession.checkGlobalPermission(GlobalPermissions.SCAN_EXECUTION); - String projectKey = request.mandatoryParam(PARAM_PROJECT_KEY); - InputStream reportData = request.paramAsInputStream(PARAM_REPORT_DATA); - try { - ReportQueue.Item item = queue.add(projectKey, reportData); - workerLauncher.startAnalysisTaskNow(); - response.newJsonWriter() - .beginObject() - // do not write integer for forward-compatibility, for example - // if we want to write UUID later - .prop("key", String.valueOf(item.dto.getId())) - .endObject() - .close(); - } finally { - IOUtils.closeQuietly(reportData); - } - } -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/dashboard/ws/DashboardsShowAction.java b/server/sonar-server/src/main/java/org/sonar/server/dashboard/ws/DashboardsShowAction.java deleted file mode 100644 index b70211d339e..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/dashboard/ws/DashboardsShowAction.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * 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.dashboard.ws; - -import com.google.common.collect.ListMultimap; -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.core.dashboard.DashboardDto; -import org.sonar.core.dashboard.WidgetDto; -import org.sonar.core.dashboard.WidgetPropertyDto; -import org.sonar.core.persistence.DbSession; -import org.sonar.core.user.UserDto; -import org.sonar.server.db.DbClient; -import org.sonar.server.exceptions.NotFoundException; -import org.sonar.server.user.UserSession; - -import java.util.Collection; - -public class DashboardsShowAction implements DashboardsWsAction { - - private static final String PARAM_KEY = "key"; - - private final DbClient dbClient; - private final UserSession userSession; - - public DashboardsShowAction(DbClient dbClient, UserSession userSession) { - this.dbClient = dbClient; - this.userSession = userSession; - } - - @Override - public void define(WebService.NewController newController) { - WebService.NewAction action = newController.createAction("show"); - action.setDescription("Detail of a dashboard (name, description, layout and widgets)"); - action.setInternal(true); - action.setHandler(this); - action.createParam(PARAM_KEY) - .setDescription("Dashboard key") - .setExampleValue("12345") - .setRequired(true); - } - - @Override - public void handle(Request request, Response response) throws Exception { - DbSession dbSession = dbClient.openSession(false); - try { - Integer userId = userSession.getUserId(); - DashboardDto dashboard = dbClient.dashboardDao().getAllowedByKey(dbSession, request.mandatoryParamAsLong(PARAM_KEY), - userId != null ? userId.longValue() : null); - if (dashboard == null) { - throw new NotFoundException(); - } - - JsonWriter json = response.newJsonWriter(); - json.beginObject(); - json.prop("key", dashboard.getKey()); - json.prop("name", dashboard.getName()); - json.prop("layout", dashboard.getColumnLayout()); - json.prop("desc", dashboard.getDescription()); - json.prop("global", dashboard.getGlobal()); - json.prop("shared", dashboard.getShared()); - if (dashboard.getUserId() != null) { - UserDto user = dbClient.userDao().getUser(dashboard.getUserId()); - if (user != null) { - json.name("owner").beginObject(); - // TODO to be shared and extracted from here - json.prop("login", user.getLogin()); - json.prop("name", user.getName()); - json.endObject(); - } - } - // load widgets and related properties - json.name("widgets").beginArray(); - Collection widgets = dbClient.widgetDao().findByDashboard(dbSession, dashboard.getKey()); - ListMultimap propertiesByWidget = WidgetPropertyDto.groupByWidgetId( - dbClient.widgetPropertyDao().findByDashboard(dbSession, dashboard.getKey())); - for (WidgetDto widget : widgets) { - json.beginObject(); - json.prop("id", widget.getId()); - json.prop("key", widget.getWidgetKey()); - json.prop("name", widget.getName()); - json.prop("desc", widget.getDescription()); - json.prop("col", widget.getColumnIndex()); - json.prop("row", widget.getRowIndex()); - json.prop("configured", widget.getConfigured()); - json.prop("componentId", widget.getResourceId()); - json.name("props").beginArray(); - for (WidgetPropertyDto prop : propertiesByWidget.get(widget.getId())) { - json.beginObject(); - json.prop("key", prop.getPropertyKey()); - json.prop("val", prop.getTextValue()); - json.endObject(); - } - json.endArray().endObject(); - } - - json.endArray(); - json.endObject(); - json.close(); - } finally { - dbSession.close(); - } - } -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/dashboard/ws/ShowAction.java b/server/sonar-server/src/main/java/org/sonar/server/dashboard/ws/ShowAction.java new file mode 100644 index 00000000000..354239cf756 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/dashboard/ws/ShowAction.java @@ -0,0 +1,123 @@ +/* + * 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.dashboard.ws; + +import com.google.common.collect.ListMultimap; +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.core.dashboard.DashboardDto; +import org.sonar.core.dashboard.WidgetDto; +import org.sonar.core.dashboard.WidgetPropertyDto; +import org.sonar.core.persistence.DbSession; +import org.sonar.core.user.UserDto; +import org.sonar.server.db.DbClient; +import org.sonar.server.exceptions.NotFoundException; +import org.sonar.server.user.UserSession; + +import java.util.Collection; + +public class ShowAction implements DashboardsWsAction { + + private static final String PARAM_KEY = "key"; + + private final DbClient dbClient; + private final UserSession userSession; + + public ShowAction(DbClient dbClient, UserSession userSession) { + this.dbClient = dbClient; + this.userSession = userSession; + } + + @Override + public void define(WebService.NewController newController) { + WebService.NewAction action = newController.createAction("show"); + action.setDescription("Detail of a dashboard (name, description, layout and widgets)"); + action.setInternal(true); + action.setHandler(this); + action.createParam(PARAM_KEY) + .setDescription("Dashboard key") + .setExampleValue("12345") + .setRequired(true); + } + + @Override + public void handle(Request request, Response response) throws Exception { + DbSession dbSession = dbClient.openSession(false); + try { + Integer userId = userSession.getUserId(); + DashboardDto dashboard = dbClient.dashboardDao().getAllowedByKey(dbSession, request.mandatoryParamAsLong(PARAM_KEY), + userId != null ? userId.longValue() : null); + if (dashboard == null) { + throw new NotFoundException(); + } + + JsonWriter json = response.newJsonWriter(); + json.beginObject(); + json.prop("key", dashboard.getKey()); + json.prop("name", dashboard.getName()); + json.prop("layout", dashboard.getColumnLayout()); + json.prop("desc", dashboard.getDescription()); + json.prop("global", dashboard.getGlobal()); + json.prop("shared", dashboard.getShared()); + if (dashboard.getUserId() != null) { + UserDto user = dbClient.userDao().getUser(dashboard.getUserId()); + if (user != null) { + json.name("owner").beginObject(); + // TODO to be shared and extracted from here + json.prop("login", user.getLogin()); + json.prop("name", user.getName()); + json.endObject(); + } + } + // load widgets and related properties + json.name("widgets").beginArray(); + Collection widgets = dbClient.widgetDao().findByDashboard(dbSession, dashboard.getKey()); + ListMultimap propertiesByWidget = WidgetPropertyDto.groupByWidgetId( + dbClient.widgetPropertyDao().findByDashboard(dbSession, dashboard.getKey())); + for (WidgetDto widget : widgets) { + json.beginObject(); + json.prop("id", widget.getId()); + json.prop("key", widget.getWidgetKey()); + json.prop("name", widget.getName()); + json.prop("desc", widget.getDescription()); + json.prop("col", widget.getColumnIndex()); + json.prop("row", widget.getRowIndex()); + json.prop("configured", widget.getConfigured()); + json.prop("componentId", widget.getResourceId()); + json.name("props").beginArray(); + for (WidgetPropertyDto prop : propertiesByWidget.get(widget.getId())) { + json.beginObject(); + json.prop("key", prop.getPropertyKey()); + json.prop("val", prop.getTextValue()); + json.endObject(); + } + json.endArray().endObject(); + } + + json.endArray(); + json.endObject(); + json.close(); + } finally { + dbSession.close(); + } + } +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/issue/ws/IssueShowAction.java b/server/sonar-server/src/main/java/org/sonar/server/issue/ws/IssueShowAction.java deleted file mode 100644 index 2e730160aa4..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/issue/ws/IssueShowAction.java +++ /dev/null @@ -1,305 +0,0 @@ -/* - * 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.issue.ws; - -import com.google.common.io.Resources; -import java.util.Date; -import java.util.List; -import java.util.Map; -import javax.annotation.CheckForNull; -import javax.annotation.Nullable; -import org.sonar.api.i18n.I18n; -import org.sonar.api.issue.ActionPlan; -import org.sonar.api.issue.Issue; -import org.sonar.api.issue.IssueComment; -import org.sonar.api.issue.internal.DefaultIssueComment; -import org.sonar.api.issue.internal.FieldDiffs; -import org.sonar.api.server.debt.DebtCharacteristic; -import org.sonar.api.server.debt.internal.DefaultDebtCharacteristic; -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.user.User; -import org.sonar.api.user.UserFinder; -import org.sonar.api.utils.DateUtils; -import org.sonar.api.utils.Duration; -import org.sonar.api.utils.Durations; -import org.sonar.api.utils.text.JsonWriter; -import org.sonar.core.component.ComponentDto; -import org.sonar.core.persistence.DbSession; -import org.sonar.markdown.Markdown; -import org.sonar.server.db.DbClient; -import org.sonar.server.debt.DebtModelService; -import org.sonar.server.issue.IssueChangelog; -import org.sonar.server.issue.IssueChangelogService; -import org.sonar.server.issue.IssueCommentService; -import org.sonar.server.issue.IssueService; -import org.sonar.server.issue.actionplan.ActionPlanService; -import org.sonar.server.rule.Rule; -import org.sonar.server.rule.RuleService; -import org.sonar.server.user.UserSession; - -import static com.google.common.collect.Maps.newHashMap; - -public class IssueShowAction implements IssuesWsAction { - - public static final String SHOW_ACTION = "show"; - - private final DbClient dbClient; - - private final IssueService issueService; - private final IssueChangelogService issueChangelogService; - private final IssueCommentService commentService; - private final IssueActionsWriter actionsWriter; - private final ActionPlanService actionPlanService; - private final UserFinder userFinder; - private final DebtModelService debtModel; - private final RuleService ruleService; - private final I18n i18n; - private final Durations durations; - private final UserSession userSession; - - public IssueShowAction(DbClient dbClient, IssueService issueService, IssueChangelogService issueChangelogService, IssueCommentService commentService, - IssueActionsWriter actionsWriter, ActionPlanService actionPlanService, UserFinder userFinder, DebtModelService debtModel, RuleService ruleService, - I18n i18n, Durations durations, UserSession userSession) { - this.dbClient = dbClient; - this.issueService = issueService; - this.issueChangelogService = issueChangelogService; - this.commentService = commentService; - this.actionsWriter = actionsWriter; - this.actionPlanService = actionPlanService; - this.userFinder = userFinder; - this.debtModel = debtModel; - this.ruleService = ruleService; - this.i18n = i18n; - this.durations = durations; - this.userSession = userSession; - } - - @Override - public void define(WebService.NewController controller) { - WebService.NewAction action = controller.createAction(SHOW_ACTION) - .setDescription("Detail of issue") - .setSince("4.2") - .setInternal(true) - .setHandler(this) - .setResponseExample(Resources.getResource(this.getClass(), "example-show.json")); - action.createParam("key") - .setDescription("Issue key") - .setExampleValue("5bccd6e8-f525-43a2-8d76-fcb13dde79ef"); - } - - @Override - public void handle(Request request, Response response) { - String issueKey = request.mandatoryParam("key"); - - JsonWriter json = response.newJsonWriter(); - json.beginObject().name("issue").beginObject(); - - DbSession session = dbClient.openSession(false); - try { - Issue issue = issueService.getByKey(issueKey); - - writeIssue(session, issue, json); - actionsWriter.writeActions(issue, json); - actionsWriter.writeTransitions(issue, json); - writeComments(issue, json); - writeChangelog(issue, json); - - } finally { - session.close(); - } - - json.endObject().endObject().close(); - } - - private void writeIssue(DbSession session, Issue issue, JsonWriter json) { - String actionPlanKey = issue.actionPlanKey(); - ActionPlan actionPlan = actionPlanKey == null ? null : actionPlanService.findByKey(actionPlanKey, userSession); - Duration debt = issue.debt(); - Rule rule = ruleService.getNonNullByKey(issue.ruleKey()); - Date updateDate = issue.updateDate(); - Date closeDate = issue.closeDate(); - - json - .prop("key", issue.key()) - .prop("rule", issue.ruleKey().toString()) - .prop("ruleName", rule.name()) - .prop("line", issue.line()) - .prop("message", issue.message()) - .prop("resolution", issue.resolution()) - .prop("status", issue.status()) - .prop("severity", issue.severity()) - .prop("author", issue.authorLogin()) - .prop("actionPlan", actionPlanKey) - .prop("actionPlanName", actionPlan != null ? actionPlan.name() : null) - .prop("debt", debt != null ? durations.encode(debt) : null) - .prop("creationDate", DateUtils.formatDateTime(issue.creationDate())) - .prop("fCreationDate", formatDate(issue.creationDate())) - .prop("updateDate", updateDate != null ? DateUtils.formatDateTime(updateDate) : null) - .prop("fUpdateDate", formatDate(updateDate)) - .prop("fUpdateAge", formatAgeDate(updateDate)) - .prop("closeDate", closeDate != null ? DateUtils.formatDateTime(closeDate) : null) - .prop("fCloseDate", formatDate(issue.closeDate())); - - addComponents(session, issue, json); - addUserWithLabel(issue.assignee(), "assignee", json); - addUserWithLabel(issue.reporter(), "reporter", json); - addCharacteristics(rule, json); - } - - private void addComponents(DbSession session, Issue issue, JsonWriter json) { - ComponentDto component = dbClient.componentDao().selectByUuid(session, issue.componentUuid()); - Long parentProjectId = component.parentProjectId(); - ComponentDto parentProject = parentProjectId != null ? dbClient.componentDao().selectNullableById(parentProjectId, session) : null; - ComponentDto project = dbClient.componentDao().selectByUuid(session, component.projectUuid()); - - String projectName = project.longName() != null ? project.longName() : project.name(); - // Do not display sub project long name if sub project and project are the same - boolean displayParentProjectLongName = parentProject != null && !parentProject.getId().equals(project.getId()); - String parentProjectKey = displayParentProjectLongName ? parentProject.key() : null; - String parentProjectName = displayParentProjectLongName ? parentProject.longName() != null ? parentProject.longName() : parentProject.name() : null; - - json - .prop("component", component.key()) - .prop("componentLongName", component.longName()) - .prop("componentQualifier", component.qualifier()) - .prop("componentEnabled", component.isEnabled()) - .prop("project", project.key()) - .prop("projectName", projectName) - // TODO replace subProject names by parentProject - .prop("subProject", parentProjectKey) - .prop("subProjectName", parentProjectName); - } - - private void writeComments(Issue issue, JsonWriter json) { - json.name("comments").beginArray(); - String login = userSession.getLogin(); - - Map usersByLogin = newHashMap(); - List comments = commentService.findComments(issue.key()); - for (IssueComment comment : comments) { - String userLogin = comment.userLogin(); - User user = usersByLogin.get(userLogin); - if (user == null) { - user = userFinder.findByLogin(userLogin); - if (user != null) { - usersByLogin.put(userLogin, user); - } - } - } - - for (IssueComment comment : comments) { - String userLogin = comment.userLogin(); - User user = usersByLogin.get(userLogin); - json - .beginObject() - .prop("key", comment.key()) - .prop("userName", user != null ? user.name() : null) - .prop("raw", comment.markdownText()) - .prop("html", Markdown.convertToHtml(comment.markdownText())) - .prop("createdAt", DateUtils.formatDateTime(comment.createdAt())) - .prop("fCreatedAge", formatAgeDate(comment.createdAt())) - .prop("updatable", login != null && login.equals(userLogin)) - .endObject(); - } - json.endArray(); - } - - private void writeChangelog(Issue issue, JsonWriter json) { - json.name("changelog").beginArray() - .beginObject() - .prop("creationDate", DateUtils.formatDateTime(issue.creationDate())) - .prop("fCreationDate", formatDate(issue.creationDate())) - .name("diffs").beginArray() - .value(i18n.message(userSession.locale(), "created", null)) - .endArray() - .endObject(); - - IssueChangelog changelog = issueChangelogService.changelog(issue); - for (FieldDiffs diffs : changelog.changes()) { - User user = changelog.user(diffs); - json - .beginObject() - .prop("userName", user != null ? user.name() : null) - .prop("creationDate", DateUtils.formatDateTime(diffs.creationDate())) - .prop("fCreationDate", formatDate(diffs.creationDate())); - json.name("diffs").beginArray(); - List diffsFormatted = issueChangelogService.formatDiffs(diffs); - for (String diff : diffsFormatted) { - json.value(diff); - } - json.endArray(); - json.endObject(); - } - json.endArray(); - } - - private void addUserWithLabel(@Nullable String value, String field, JsonWriter json) { - if (value != null) { - User user = userFinder.findByLogin(value); - json - .prop(field, value) - .prop(field + "Name", user != null ? user.name() : null); - } - } - - @CheckForNull - private String formatDate(@Nullable Date date) { - if (date != null) { - return i18n.formatDateTime(userSession.locale(), date); - } - return null; - } - - @CheckForNull - private String formatAgeDate(@Nullable Date date) { - if (date != null) { - return i18n.ageFromNow(userSession.locale(), date); - } - return null; - } - - private void addCharacteristics(Rule rule, JsonWriter json) { - String subCharacteristicKey = rule.debtCharacteristicKey(); - DebtCharacteristic subCharacteristic = characteristicByKey(subCharacteristicKey); - if (subCharacteristic != null) { - json.prop("subCharacteristic", subCharacteristic.name()); - DebtCharacteristic characteristic = characteristicById(((DefaultDebtCharacteristic) subCharacteristic).parentId()); - json.prop("characteristic", characteristic != null ? characteristic.name() : null); - } - } - - @CheckForNull - private DebtCharacteristic characteristicById(@Nullable Integer id) { - if (id != null) { - return debtModel.characteristicById(id); - } - return null; - } - - @CheckForNull - private DebtCharacteristic characteristicByKey(@Nullable String key) { - if (key != null) { - return debtModel.characteristicByKey(key); - } - return null; - } -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/issue/ws/ShowAction.java b/server/sonar-server/src/main/java/org/sonar/server/issue/ws/ShowAction.java new file mode 100644 index 00000000000..bafc9544aea --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/issue/ws/ShowAction.java @@ -0,0 +1,306 @@ +/* + * 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.issue.ws; + +import com.google.common.io.Resources; +import org.sonar.api.i18n.I18n; +import org.sonar.api.issue.ActionPlan; +import org.sonar.api.issue.Issue; +import org.sonar.api.issue.IssueComment; +import org.sonar.api.issue.internal.DefaultIssueComment; +import org.sonar.api.issue.internal.FieldDiffs; +import org.sonar.api.server.debt.DebtCharacteristic; +import org.sonar.api.server.debt.internal.DefaultDebtCharacteristic; +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.user.User; +import org.sonar.api.user.UserFinder; +import org.sonar.api.utils.DateUtils; +import org.sonar.api.utils.Duration; +import org.sonar.api.utils.Durations; +import org.sonar.api.utils.text.JsonWriter; +import org.sonar.core.component.ComponentDto; +import org.sonar.core.persistence.DbSession; +import org.sonar.markdown.Markdown; +import org.sonar.server.db.DbClient; +import org.sonar.server.debt.DebtModelService; +import org.sonar.server.issue.IssueChangelog; +import org.sonar.server.issue.IssueChangelogService; +import org.sonar.server.issue.IssueCommentService; +import org.sonar.server.issue.IssueService; +import org.sonar.server.issue.actionplan.ActionPlanService; +import org.sonar.server.rule.Rule; +import org.sonar.server.rule.RuleService; +import org.sonar.server.user.UserSession; + +import javax.annotation.CheckForNull; +import javax.annotation.Nullable; +import java.util.Date; +import java.util.List; +import java.util.Map; + +import static com.google.common.collect.Maps.newHashMap; + +public class ShowAction implements IssuesWsAction { + + public static final String SHOW_ACTION = "show"; + + private final DbClient dbClient; + + private final IssueService issueService; + private final IssueChangelogService issueChangelogService; + private final IssueCommentService commentService; + private final IssueActionsWriter actionsWriter; + private final ActionPlanService actionPlanService; + private final UserFinder userFinder; + private final DebtModelService debtModel; + private final RuleService ruleService; + private final I18n i18n; + private final Durations durations; + private final UserSession userSession; + + public ShowAction(DbClient dbClient, IssueService issueService, IssueChangelogService issueChangelogService, IssueCommentService commentService, + IssueActionsWriter actionsWriter, ActionPlanService actionPlanService, UserFinder userFinder, DebtModelService debtModel, RuleService ruleService, + I18n i18n, Durations durations, UserSession userSession) { + this.dbClient = dbClient; + this.issueService = issueService; + this.issueChangelogService = issueChangelogService; + this.commentService = commentService; + this.actionsWriter = actionsWriter; + this.actionPlanService = actionPlanService; + this.userFinder = userFinder; + this.debtModel = debtModel; + this.ruleService = ruleService; + this.i18n = i18n; + this.durations = durations; + this.userSession = userSession; + } + + @Override + public void define(WebService.NewController controller) { + WebService.NewAction action = controller.createAction(SHOW_ACTION) + .setDescription("Detail of issue") + .setSince("4.2") + .setInternal(true) + .setHandler(this) + .setResponseExample(Resources.getResource(this.getClass(), "example-show.json")); + action.createParam("key") + .setDescription("Issue key") + .setExampleValue("5bccd6e8-f525-43a2-8d76-fcb13dde79ef"); + } + + @Override + public void handle(Request request, Response response) { + String issueKey = request.mandatoryParam("key"); + + JsonWriter json = response.newJsonWriter(); + json.beginObject().name("issue").beginObject(); + + DbSession session = dbClient.openSession(false); + try { + Issue issue = issueService.getByKey(issueKey); + + writeIssue(session, issue, json); + actionsWriter.writeActions(issue, json); + actionsWriter.writeTransitions(issue, json); + writeComments(issue, json); + writeChangelog(issue, json); + + } finally { + session.close(); + } + + json.endObject().endObject().close(); + } + + private void writeIssue(DbSession session, Issue issue, JsonWriter json) { + String actionPlanKey = issue.actionPlanKey(); + ActionPlan actionPlan = actionPlanKey == null ? null : actionPlanService.findByKey(actionPlanKey, userSession); + Duration debt = issue.debt(); + Rule rule = ruleService.getNonNullByKey(issue.ruleKey()); + Date updateDate = issue.updateDate(); + Date closeDate = issue.closeDate(); + + json + .prop("key", issue.key()) + .prop("rule", issue.ruleKey().toString()) + .prop("ruleName", rule.name()) + .prop("line", issue.line()) + .prop("message", issue.message()) + .prop("resolution", issue.resolution()) + .prop("status", issue.status()) + .prop("severity", issue.severity()) + .prop("author", issue.authorLogin()) + .prop("actionPlan", actionPlanKey) + .prop("actionPlanName", actionPlan != null ? actionPlan.name() : null) + .prop("debt", debt != null ? durations.encode(debt) : null) + .prop("creationDate", DateUtils.formatDateTime(issue.creationDate())) + .prop("fCreationDate", formatDate(issue.creationDate())) + .prop("updateDate", updateDate != null ? DateUtils.formatDateTime(updateDate) : null) + .prop("fUpdateDate", formatDate(updateDate)) + .prop("fUpdateAge", formatAgeDate(updateDate)) + .prop("closeDate", closeDate != null ? DateUtils.formatDateTime(closeDate) : null) + .prop("fCloseDate", formatDate(issue.closeDate())); + + addComponents(session, issue, json); + addUserWithLabel(issue.assignee(), "assignee", json); + addUserWithLabel(issue.reporter(), "reporter", json); + addCharacteristics(rule, json); + } + + private void addComponents(DbSession session, Issue issue, JsonWriter json) { + ComponentDto component = dbClient.componentDao().selectByUuid(session, issue.componentUuid()); + Long parentProjectId = component.parentProjectId(); + ComponentDto parentProject = parentProjectId != null ? dbClient.componentDao().selectNullableById(parentProjectId, session) : null; + ComponentDto project = dbClient.componentDao().selectByUuid(session, component.projectUuid()); + + String projectName = project.longName() != null ? project.longName() : project.name(); + // Do not display sub project long name if sub project and project are the same + boolean displayParentProjectLongName = parentProject != null && !parentProject.getId().equals(project.getId()); + String parentProjectKey = displayParentProjectLongName ? parentProject.key() : null; + String parentProjectName = displayParentProjectLongName ? parentProject.longName() != null ? parentProject.longName() : parentProject.name() : null; + + json + .prop("component", component.key()) + .prop("componentLongName", component.longName()) + .prop("componentQualifier", component.qualifier()) + .prop("componentEnabled", component.isEnabled()) + .prop("project", project.key()) + .prop("projectName", projectName) + // TODO replace subProject names by parentProject + .prop("subProject", parentProjectKey) + .prop("subProjectName", parentProjectName); + } + + private void writeComments(Issue issue, JsonWriter json) { + json.name("comments").beginArray(); + String login = userSession.getLogin(); + + Map usersByLogin = newHashMap(); + List comments = commentService.findComments(issue.key()); + for (IssueComment comment : comments) { + String userLogin = comment.userLogin(); + User user = usersByLogin.get(userLogin); + if (user == null) { + user = userFinder.findByLogin(userLogin); + if (user != null) { + usersByLogin.put(userLogin, user); + } + } + } + + for (IssueComment comment : comments) { + String userLogin = comment.userLogin(); + User user = usersByLogin.get(userLogin); + json + .beginObject() + .prop("key", comment.key()) + .prop("userName", user != null ? user.name() : null) + .prop("raw", comment.markdownText()) + .prop("html", Markdown.convertToHtml(comment.markdownText())) + .prop("createdAt", DateUtils.formatDateTime(comment.createdAt())) + .prop("fCreatedAge", formatAgeDate(comment.createdAt())) + .prop("updatable", login != null && login.equals(userLogin)) + .endObject(); + } + json.endArray(); + } + + private void writeChangelog(Issue issue, JsonWriter json) { + json.name("changelog").beginArray() + .beginObject() + .prop("creationDate", DateUtils.formatDateTime(issue.creationDate())) + .prop("fCreationDate", formatDate(issue.creationDate())) + .name("diffs").beginArray() + .value(i18n.message(userSession.locale(), "created", null)) + .endArray() + .endObject(); + + IssueChangelog changelog = issueChangelogService.changelog(issue); + for (FieldDiffs diffs : changelog.changes()) { + User user = changelog.user(diffs); + json + .beginObject() + .prop("userName", user != null ? user.name() : null) + .prop("creationDate", DateUtils.formatDateTime(diffs.creationDate())) + .prop("fCreationDate", formatDate(diffs.creationDate())); + json.name("diffs").beginArray(); + List diffsFormatted = issueChangelogService.formatDiffs(diffs); + for (String diff : diffsFormatted) { + json.value(diff); + } + json.endArray(); + json.endObject(); + } + json.endArray(); + } + + private void addUserWithLabel(@Nullable String value, String field, JsonWriter json) { + if (value != null) { + User user = userFinder.findByLogin(value); + json + .prop(field, value) + .prop(field + "Name", user != null ? user.name() : null); + } + } + + @CheckForNull + private String formatDate(@Nullable Date date) { + if (date != null) { + return i18n.formatDateTime(userSession.locale(), date); + } + return null; + } + + @CheckForNull + private String formatAgeDate(@Nullable Date date) { + if (date != null) { + return i18n.ageFromNow(userSession.locale(), date); + } + return null; + } + + private void addCharacteristics(Rule rule, JsonWriter json) { + String subCharacteristicKey = rule.debtCharacteristicKey(); + DebtCharacteristic subCharacteristic = characteristicByKey(subCharacteristicKey); + if (subCharacteristic != null) { + json.prop("subCharacteristic", subCharacteristic.name()); + DebtCharacteristic characteristic = characteristicById(((DefaultDebtCharacteristic) subCharacteristic).parentId()); + json.prop("characteristic", characteristic != null ? characteristic.name() : null); + } + } + + @CheckForNull + private DebtCharacteristic characteristicById(@Nullable Integer id) { + if (id != null) { + return debtModel.characteristicById(id); + } + return null; + } + + @CheckForNull + private DebtCharacteristic characteristicByKey(@Nullable String key) { + if (key != null) { + return debtModel.characteristicByKey(key); + } + return null; + } +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java b/server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java index 02ccd463bef..8350f83f0a7 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java +++ b/server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java @@ -92,9 +92,9 @@ import org.sonar.server.activity.ws.ActivityMapping; import org.sonar.server.authentication.ws.AuthenticationWs; import org.sonar.server.batch.BatchIndex; import org.sonar.server.batch.BatchWs; -import org.sonar.server.batch.GlobalRepositoryAction; +import org.sonar.server.batch.GlobalAction; import org.sonar.server.batch.IssuesAction; -import org.sonar.server.batch.ProjectRepositoryAction; +import org.sonar.server.batch.ProjectAction; import org.sonar.server.batch.ProjectRepositoryLoader; import org.sonar.server.batch.UsersAction; import org.sonar.server.charts.ChartFactory; @@ -106,27 +106,25 @@ import org.sonar.server.component.db.ComponentDao; import org.sonar.server.component.db.ComponentIndexDao; import org.sonar.server.component.db.ComponentLinkDao; import org.sonar.server.component.db.SnapshotDao; -import org.sonar.server.component.ws.ComponentAppAction; import org.sonar.server.component.ws.ComponentsWs; import org.sonar.server.component.ws.EventsWs; -import org.sonar.server.component.ws.ProjectsGhostsAction; -import org.sonar.server.component.ws.ProjectsWs; -import org.sonar.server.component.ws.ProjectsProvisionedAction; +import org.sonar.server.project.ws.GhostsAction; +import org.sonar.server.project.ws.ProjectsWs; +import org.sonar.server.project.ws.ProvisionedAction; import org.sonar.server.component.ws.ResourcesWs; import org.sonar.server.computation.ComputationThreadLauncher; import org.sonar.server.computation.ReportQueue; import org.sonar.server.computation.ReportQueueCleaner; import org.sonar.server.computation.db.AnalysisReportDao; import org.sonar.server.computation.ws.ComputationWs; -import org.sonar.server.computation.ws.HistoryWsAction; +import org.sonar.server.computation.ws.HistoryAction; import org.sonar.server.computation.ws.IsQueueEmptyWs; -import org.sonar.server.computation.ws.QueueWsAction; -import org.sonar.server.computation.ws.SubmitReportWsAction; +import org.sonar.server.computation.ws.QueueAction; +import org.sonar.server.computation.ws.SubmitReportAction; import org.sonar.server.config.ws.PropertiesWs; import org.sonar.server.dashboard.db.DashboardDao; import org.sonar.server.dashboard.db.WidgetDao; import org.sonar.server.dashboard.db.WidgetPropertyDao; -import org.sonar.server.dashboard.ws.DashboardsShowAction; import org.sonar.server.dashboard.ws.DashboardsWs; import org.sonar.server.db.DatabaseChecker; import org.sonar.server.db.DbClient; @@ -189,11 +187,9 @@ import org.sonar.server.issue.notification.NewIssuesNotificationDispatcher; import org.sonar.server.issue.notification.NewIssuesNotificationFactory; import org.sonar.server.issue.ws.ComponentTagsAction; import org.sonar.server.issue.ws.IssueActionsWriter; -import org.sonar.server.issue.ws.IssueShowAction; import org.sonar.server.issue.ws.IssuesWs; import org.sonar.server.issue.ws.SetTagsAction; import org.sonar.server.language.ws.LanguageWs; -import org.sonar.server.language.ws.ListAction; import org.sonar.server.measure.MeasureFilterEngine; import org.sonar.server.measure.MeasureFilterExecutor; import org.sonar.server.measure.MeasureFilterFactory; @@ -215,13 +211,13 @@ import org.sonar.server.platform.monitoring.PluginsMonitor; import org.sonar.server.platform.monitoring.SonarQubeMonitor; import org.sonar.server.platform.monitoring.SystemMonitor; import org.sonar.server.platform.ws.L10nWs; -import org.sonar.server.platform.ws.MigrateDbSystemWsAction; +import org.sonar.server.platform.ws.MigrateDbSystemAction; import org.sonar.server.platform.ws.ServerWs; -import org.sonar.server.platform.ws.SystemInfoWsAction; -import org.sonar.server.platform.ws.SystemRestartWsAction; -import org.sonar.server.platform.ws.SystemStatusWsAction; +import org.sonar.server.platform.ws.InfoAction; +import org.sonar.server.platform.ws.RestartAction; +import org.sonar.server.platform.ws.StatusAction; import org.sonar.server.platform.ws.SystemWs; -import org.sonar.server.platform.ws.UpgradesSystemWsAction; +import org.sonar.server.platform.ws.UpgradesAction; import org.sonar.server.plugins.InstalledPluginReferentialFactory; import org.sonar.server.plugins.PluginDownloader; import org.sonar.server.plugins.ServerExtensionInstaller; @@ -229,36 +225,31 @@ import org.sonar.server.plugins.ServerPluginRepository; import org.sonar.server.plugins.ServerPluginExploder; import org.sonar.server.plugins.UpdateCenterClient; import org.sonar.server.plugins.UpdateCenterMatrixFactory; -import org.sonar.server.plugins.ws.AvailablePluginsWsAction; -import org.sonar.server.plugins.ws.CancelAllPluginsWsAction; -import org.sonar.server.plugins.ws.InstallPluginsWsAction; -import org.sonar.server.plugins.ws.InstalledPluginsWsAction; -import org.sonar.server.plugins.ws.PendingPluginsWsAction; +import org.sonar.server.plugins.ws.AvailableAction; +import org.sonar.server.plugins.ws.CancelAllAction; +import org.sonar.server.plugins.ws.InstallAction; +import org.sonar.server.plugins.ws.InstalledAction; +import org.sonar.server.plugins.ws.PendingAction; import org.sonar.server.plugins.ws.PluginUpdateAggregator; import org.sonar.server.plugins.ws.PluginWSCommons; import org.sonar.server.plugins.ws.PluginsWs; -import org.sonar.server.plugins.ws.UninstallPluginsWsAction; -import org.sonar.server.plugins.ws.UpdatePluginsWsAction; -import org.sonar.server.plugins.ws.UpdatesPluginsWsAction; +import org.sonar.server.plugins.ws.UninstallAction; +import org.sonar.server.plugins.ws.UpdateAction; +import org.sonar.server.plugins.ws.UpdatesAction; import org.sonar.server.properties.ProjectSettingsFactory; import org.sonar.server.qualitygate.QgateProjectFinder; import org.sonar.server.qualitygate.QualityGates; import org.sonar.server.qualitygate.RegisterQualityGates; -import org.sonar.server.qualitygate.ws.QGatesAppAction; -import org.sonar.server.qualitygate.ws.QGatesCopyAction; -import org.sonar.server.qualitygate.ws.QGatesCreateAction; -import org.sonar.server.qualitygate.ws.QGatesCreateConditionAction; -import org.sonar.server.qualitygate.ws.QGatesDeleteConditionAction; -import org.sonar.server.qualitygate.ws.QGatesDeselectAction; -import org.sonar.server.qualitygate.ws.QGatesDestroyAction; -import org.sonar.server.qualitygate.ws.QGatesListAction; -import org.sonar.server.qualitygate.ws.QGatesRenameAction; -import org.sonar.server.qualitygate.ws.QGatesSearchAction; -import org.sonar.server.qualitygate.ws.QGatesSelectAction; -import org.sonar.server.qualitygate.ws.QGatesSetAsDefaultAction; -import org.sonar.server.qualitygate.ws.QGatesShowAction; -import org.sonar.server.qualitygate.ws.QGatesUnsetDefaultAction; -import org.sonar.server.qualitygate.ws.QGatesUpdateConditionAction; +import org.sonar.server.qualitygate.ws.AppAction; +import org.sonar.server.qualitygate.ws.CreateConditionAction; +import org.sonar.server.qualitygate.ws.DeleteConditionAction; +import org.sonar.server.qualitygate.ws.DeselectAction; +import org.sonar.server.qualitygate.ws.DestroyAction; +import org.sonar.server.qualitygate.ws.SelectAction; +import org.sonar.server.qualitygate.ws.SetAsDefaultAction; +import org.sonar.server.qualitygate.ws.ShowAction; +import org.sonar.server.qualitygate.ws.UnsetDefaultAction; +import org.sonar.server.qualitygate.ws.UpdateConditionAction; import org.sonar.server.qualitygate.ws.QGatesWs; import org.sonar.server.qualityprofile.BuiltInProfiles; import org.sonar.server.qualityprofile.QProfileBackuper; @@ -282,23 +273,23 @@ import org.sonar.server.qualityprofile.index.ActiveRuleNormalizer; import org.sonar.server.qualityprofile.ws.BulkRuleActivationActions; import org.sonar.server.qualityprofile.ws.ProfilesWs; import org.sonar.server.qualityprofile.ws.ProjectAssociationActions; -import org.sonar.server.qualityprofile.ws.QProfileBackupAction; -import org.sonar.server.qualityprofile.ws.QProfileChangeParentAction; -import org.sonar.server.qualityprofile.ws.QProfileChangelogAction; -import org.sonar.server.qualityprofile.ws.QProfileCompareAction; -import org.sonar.server.qualityprofile.ws.QProfileCopyAction; -import org.sonar.server.qualityprofile.ws.QProfileCreateAction; -import org.sonar.server.qualityprofile.ws.QProfileDeleteAction; -import org.sonar.server.qualityprofile.ws.QProfileExportAction; -import org.sonar.server.qualityprofile.ws.QProfileExportersAction; -import org.sonar.server.qualityprofile.ws.QProfileImportersAction; -import org.sonar.server.qualityprofile.ws.QProfileInheritanceAction; -import org.sonar.server.qualityprofile.ws.QProfileProjectsAction; -import org.sonar.server.qualityprofile.ws.QProfileRenameAction; -import org.sonar.server.qualityprofile.ws.QProfileRestoreAction; -import org.sonar.server.qualityprofile.ws.QProfileRestoreBuiltInAction; -import org.sonar.server.qualityprofile.ws.QProfileSearchAction; -import org.sonar.server.qualityprofile.ws.QProfileSetDefaultAction; +import org.sonar.server.qualityprofile.ws.BackupAction; +import org.sonar.server.qualityprofile.ws.ChangeParentAction; +import org.sonar.server.qualityprofile.ws.ChangelogAction; +import org.sonar.server.qualityprofile.ws.CompareAction; +import org.sonar.server.qualityprofile.ws.CopyAction; +import org.sonar.server.qualityprofile.ws.CreateAction; +import org.sonar.server.qualityprofile.ws.DeleteAction; +import org.sonar.server.qualityprofile.ws.ExportAction; +import org.sonar.server.qualityprofile.ws.ExportersAction; +import org.sonar.server.qualityprofile.ws.ImportersAction; +import org.sonar.server.qualityprofile.ws.InheritanceAction; +import org.sonar.server.qualityprofile.ws.ProjectsAction; +import org.sonar.server.qualityprofile.ws.RenameAction; +import org.sonar.server.qualityprofile.ws.RestoreAction; +import org.sonar.server.qualityprofile.ws.RestoreBuiltInAction; +import org.sonar.server.qualityprofile.ws.SearchAction; +import org.sonar.server.qualityprofile.ws.SetDefaultAction; import org.sonar.server.qualityprofile.ws.QProfilesWs; import org.sonar.server.qualityprofile.ws.RuleActivationActions; import org.sonar.server.ruby.PlatformRackBridge; @@ -318,14 +309,10 @@ import org.sonar.server.rule.db.RuleDao; import org.sonar.server.rule.index.RuleIndex; import org.sonar.server.rule.index.RuleNormalizer; import org.sonar.server.rule.ws.ActiveRuleCompleter; -import org.sonar.server.rule.ws.AppAction; -import org.sonar.server.rule.ws.DeleteAction; import org.sonar.server.rule.ws.RepositoriesAction; import org.sonar.server.rule.ws.RuleMapping; import org.sonar.server.rule.ws.RulesWs; -import org.sonar.server.rule.ws.SearchAction; import org.sonar.server.rule.ws.TagsAction; -import org.sonar.server.rule.ws.UpdateAction; import org.sonar.server.search.IndexClient; import org.sonar.server.search.IndexQueue; import org.sonar.server.search.IndexSynchronizer; @@ -341,7 +328,6 @@ import org.sonar.server.source.ws.IndexAction; import org.sonar.server.source.ws.LinesAction; import org.sonar.server.source.ws.RawAction; import org.sonar.server.source.ws.ScmAction; -import org.sonar.server.source.ws.ShowAction; import org.sonar.server.source.ws.SourcesWs; import org.sonar.server.startup.CopyRequirementsFromCharacteristicsToRules; import org.sonar.server.startup.GeneratePluginIndex; @@ -360,8 +346,8 @@ import org.sonar.server.test.CoverageService; import org.sonar.server.test.index.TestIndex; import org.sonar.server.test.index.TestIndexDefinition; import org.sonar.server.test.index.TestIndexer; -import org.sonar.server.test.ws.TestsCoveredFilesAction; -import org.sonar.server.test.ws.TestsListAction; +import org.sonar.server.test.ws.CoveredFilesAction; +import org.sonar.server.test.ws.ListAction; import org.sonar.server.test.ws.TestsWs; import org.sonar.server.text.MacroInterpreter; import org.sonar.server.text.RubyTextService; @@ -387,6 +373,7 @@ import org.sonar.server.user.db.UserGroupDao; import org.sonar.server.user.index.UserIndex; import org.sonar.server.user.index.UserIndexDefinition; import org.sonar.server.user.index.UserIndexer; +import org.sonar.server.user.ws.CurrentAction; import org.sonar.server.user.ws.FavoritesWs; import org.sonar.server.user.ws.UserPropertiesWs; import org.sonar.server.user.ws.UsersWs; @@ -565,8 +552,8 @@ class ServerComponents { ThreadLocalDatabaseSessionFactory.class, // Server WS - SystemStatusWsAction.class, - MigrateDbSystemWsAction.class, + StatusAction.class, + MigrateDbSystemAction.class, SystemWs.class, // Listing WS @@ -616,17 +603,17 @@ class ServerComponents { // batch pico.addSingleton(BatchIndex.class); - pico.addSingleton(GlobalRepositoryAction.class); - pico.addSingleton(ProjectRepositoryAction.class); + pico.addSingleton(GlobalAction.class); + pico.addSingleton(ProjectAction.class); pico.addSingleton(ProjectRepositoryLoader.class); - pico.addSingleton(SubmitReportWsAction.class); + pico.addSingleton(SubmitReportAction.class); pico.addSingleton(IssuesAction.class); pico.addSingleton(UsersAction.class); pico.addSingleton(BatchWs.class); // Dashboard pico.addSingleton(DashboardsWs.class); - pico.addSingleton(DashboardsShowAction.class); + pico.addSingleton(org.sonar.server.dashboard.ws.ShowAction.class); // update center pico.addSingleton(UpdateCenterClient.class); @@ -643,23 +630,23 @@ class ServerComponents { pico.addSingleton(QProfileProjectLookup.class); pico.addSingleton(QProfileComparison.class); pico.addSingleton(BuiltInProfiles.class); - pico.addSingleton(QProfileRestoreBuiltInAction.class); - pico.addSingleton(QProfileSearchAction.class); - pico.addSingleton(QProfileSetDefaultAction.class); - pico.addSingleton(QProfileProjectsAction.class); - pico.addSingleton(QProfileDeleteAction.class); - pico.addSingleton(QProfileRenameAction.class); - pico.addSingleton(QProfileCopyAction.class); - pico.addSingleton(QProfileBackupAction.class); - pico.addSingleton(QProfileRestoreAction.class); - pico.addSingleton(QProfileCreateAction.class); - pico.addSingleton(QProfileImportersAction.class); - pico.addSingleton(QProfileInheritanceAction.class); - pico.addSingleton(QProfileChangeParentAction.class); - pico.addSingleton(QProfileChangelogAction.class); - pico.addSingleton(QProfileCompareAction.class); - pico.addSingleton(QProfileExportAction.class); - pico.addSingleton(QProfileExportersAction.class); + pico.addSingleton(RestoreBuiltInAction.class); + pico.addSingleton(SearchAction.class); + pico.addSingleton(SetDefaultAction.class); + pico.addSingleton(ProjectsAction.class); + pico.addSingleton(DeleteAction.class); + pico.addSingleton(RenameAction.class); + pico.addSingleton(CopyAction.class); + pico.addSingleton(BackupAction.class); + pico.addSingleton(RestoreAction.class); + pico.addSingleton(CreateAction.class); + pico.addSingleton(ImportersAction.class); + pico.addSingleton(InheritanceAction.class); + pico.addSingleton(ChangeParentAction.class); + pico.addSingleton(ChangelogAction.class); + pico.addSingleton(CompareAction.class); + pico.addSingleton(ExportAction.class); + pico.addSingleton(ExportersAction.class); pico.addSingleton(QProfilesWs.class); pico.addSingleton(ProfilesWs.class); pico.addSingleton(RuleActivationActions.class); @@ -690,22 +677,22 @@ class ServerComponents { pico.addSingleton(RuleUpdater.class); pico.addSingleton(RuleCreator.class); pico.addSingleton(RuleDeleter.class); - pico.addSingleton(UpdateAction.class); + pico.addSingleton(org.sonar.server.rule.ws.UpdateAction.class); pico.addSingleton(RulesWs.class); - pico.addSingleton(SearchAction.class); + pico.addSingleton(org.sonar.server.rule.ws.SearchAction.class); pico.addSingleton(org.sonar.server.rule.ws.ShowAction.class); pico.addSingleton(org.sonar.server.rule.ws.CreateAction.class); - pico.addSingleton(DeleteAction.class); + pico.addSingleton(org.sonar.server.rule.ws.DeleteAction.class); pico.addSingleton(TagsAction.class); pico.addSingleton(RuleMapping.class); pico.addSingleton(ActiveRuleCompleter.class); pico.addSingleton(RepositoriesAction.class); - pico.addSingleton(AppAction.class); + pico.addSingleton(org.sonar.server.rule.ws.AppAction.class); // languages pico.addSingleton(Languages.class); pico.addSingleton(LanguageWs.class); - pico.addSingleton(ListAction.class); + pico.addSingleton(org.sonar.server.language.ws.ListAction.class); // activity pico.addSingleton(ActivitiesWs.class); @@ -730,21 +717,21 @@ class ServerComponents { pico.addSingleton(ProjectQgateAssociationDao.class); pico.addSingleton(QgateProjectFinder.class); - pico.addSingleton(QGatesListAction.class); - pico.addSingleton(QGatesSearchAction.class); - pico.addSingleton(QGatesShowAction.class); - pico.addSingleton(QGatesCreateAction.class); - pico.addSingleton(QGatesRenameAction.class); - pico.addSingleton(QGatesCopyAction.class); - pico.addSingleton(QGatesDestroyAction.class); - pico.addSingleton(QGatesSetAsDefaultAction.class); - pico.addSingleton(QGatesUnsetDefaultAction.class); - pico.addSingleton(QGatesSelectAction.class); - pico.addSingleton(QGatesDeselectAction.class); - pico.addSingleton(QGatesCreateConditionAction.class); - pico.addSingleton(QGatesDeleteConditionAction.class); - pico.addSingleton(QGatesUpdateConditionAction.class); - pico.addSingleton(QGatesAppAction.class); + pico.addSingleton(org.sonar.server.qualitygate.ws.ListAction.class); + pico.addSingleton(org.sonar.server.qualitygate.ws.SearchAction.class); + pico.addSingleton(ShowAction.class); + pico.addSingleton(org.sonar.server.qualitygate.ws.CreateAction.class); + pico.addSingleton(org.sonar.server.qualitygate.ws.RenameAction.class); + pico.addSingleton(org.sonar.server.qualitygate.ws.CopyAction.class); + pico.addSingleton(DestroyAction.class); + pico.addSingleton(SetAsDefaultAction.class); + pico.addSingleton(UnsetDefaultAction.class); + pico.addSingleton(SelectAction.class); + pico.addSingleton(DeselectAction.class); + pico.addSingleton(CreateConditionAction.class); + pico.addSingleton(DeleteConditionAction.class); + pico.addSingleton(UpdateConditionAction.class); + pico.addSingleton(AppAction.class); pico.addSingleton(QGatesWs.class); // web services @@ -768,7 +755,7 @@ class ServerComponents { pico.addSingleton(org.sonar.server.user.ws.UpdateAction.class); pico.addSingleton(org.sonar.server.user.ws.DeactivateAction.class); pico.addSingleton(org.sonar.server.user.ws.ChangePasswordAction.class); - pico.addSingleton(org.sonar.server.user.ws.CurrentUserAction.class); + pico.addSingleton(CurrentAction.class); pico.addSingleton(org.sonar.server.user.ws.SearchAction.class); pico.addSingleton(org.sonar.server.user.ws.GroupsAction.class); pico.addSingleton(org.sonar.server.issue.ws.AuthorsAction.class); @@ -797,12 +784,12 @@ class ServerComponents { pico.addSingleton(ResourcesWs.class); pico.addSingleton(ComponentsWs.class); pico.addSingleton(ProjectsWs.class); - pico.addSingleton(ComponentAppAction.class); + pico.addSingleton(org.sonar.server.component.ws.AppAction.class); pico.addSingleton(org.sonar.server.component.ws.SearchAction.class); pico.addSingleton(EventsWs.class); pico.addSingleton(ComponentCleanerService.class); - pico.addSingleton(ProjectsProvisionedAction.class); - pico.addSingleton(ProjectsGhostsAction.class); + pico.addSingleton(ProvisionedAction.class); + pico.addSingleton(GhostsAction.class); // views pico.addSingleton(ViewIndexDefinition.class); @@ -825,7 +812,7 @@ class ServerComponents { pico.addSingleton(IssueBulkChangeService.class); pico.addSingleton(IssueChangelogFormatter.class); pico.addSingleton(IssuesWs.class); - pico.addSingleton(IssueShowAction.class); + pico.addSingleton(org.sonar.server.issue.ws.ShowAction.class); pico.addSingleton(org.sonar.server.issue.ws.SearchAction.class); pico.addSingleton(org.sonar.server.issue.ws.TagsAction.class); pico.addSingleton(SetTagsAction.class); @@ -882,7 +869,7 @@ class ServerComponents { pico.addSingleton(HtmlSourceDecorator.class); pico.addSingleton(SourceService.class); pico.addSingleton(SourcesWs.class); - pico.addSingleton(ShowAction.class); + pico.addSingleton(org.sonar.server.source.ws.ShowAction.class); pico.addSingleton(LinesAction.class); pico.addSingleton(HashAction.class); pico.addSingleton(RawAction.class); @@ -911,8 +898,8 @@ class ServerComponents { // Tests pico.addSingleton(CoverageService.class); pico.addSingleton(TestsWs.class); - pico.addSingleton(TestsCoveredFilesAction.class); - pico.addSingleton(TestsListAction.class); + pico.addSingleton(CoveredFilesAction.class); + pico.addSingleton(ListAction.class); pico.addSingleton(TestIndexDefinition.class); pico.addSingleton(TestIndex.class); pico.addSingleton(TestIndexer.class); @@ -940,11 +927,11 @@ class ServerComponents { // System pico.addSingletons(Arrays.asList( - SystemRestartWsAction.class, - SystemInfoWsAction.class, - UpgradesSystemWsAction.class, - MigrateDbSystemWsAction.class, - SystemStatusWsAction.class, + RestartAction.class, + InfoAction.class, + UpgradesAction.class, + MigrateDbSystemAction.class, + StatusAction.class, SystemWs.class, SystemMonitor.class, SonarQubeMonitor.class, @@ -957,14 +944,14 @@ class ServerComponents { // Plugins WS pico.addSingleton(PluginWSCommons.class); pico.addSingleton(PluginUpdateAggregator.class); - pico.addSingleton(InstalledPluginsWsAction.class); - pico.addSingleton(AvailablePluginsWsAction.class); - pico.addSingleton(UpdatesPluginsWsAction.class); - pico.addSingleton(PendingPluginsWsAction.class); - pico.addSingleton(InstallPluginsWsAction.class); - pico.addSingleton(UpdatePluginsWsAction.class); - pico.addSingleton(UninstallPluginsWsAction.class); - pico.addSingleton(CancelAllPluginsWsAction.class); + pico.addSingleton(InstalledAction.class); + pico.addSingleton(AvailableAction.class); + pico.addSingleton(UpdatesAction.class); + pico.addSingleton(PendingAction.class); + pico.addSingleton(InstallAction.class); + pico.addSingleton(UpdateAction.class); + pico.addSingleton(UninstallAction.class); + pico.addSingleton(CancelAllAction.class); pico.addSingleton(PluginsWs.class); // Compute engine @@ -972,8 +959,8 @@ class ServerComponents { pico.addSingleton(ComputationThreadLauncher.class); pico.addSingleton(ComputationWs.class); pico.addSingleton(IsQueueEmptyWs.class); - pico.addSingleton(QueueWsAction.class); - pico.addSingleton(HistoryWsAction.class); + pico.addSingleton(QueueAction.class); + pico.addSingleton(HistoryAction.class); pico.addSingleton(DefaultPeriodCleaner.class); pico.addSingleton(DefaultPurgeTask.class); pico.addSingleton(ProjectCleaner.class); diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/monitoring/Monitor.java b/server/sonar-server/src/main/java/org/sonar/server/platform/monitoring/Monitor.java index d451ca17306..b647c6c35eb 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/platform/monitoring/Monitor.java +++ b/server/sonar-server/src/main/java/org/sonar/server/platform/monitoring/Monitor.java @@ -20,6 +20,7 @@ package org.sonar.server.platform.monitoring; import org.sonar.api.ServerSide; +import org.sonar.server.platform.ws.InfoAction; import java.util.LinkedHashMap; @@ -35,7 +36,7 @@ public interface Monitor { /** * Type of attribute values must be supported by {@link org.sonar.api.utils.text.JsonWriter#valueObject(Object)} - * because of JSON export by {@link org.sonar.server.platform.ws.SystemInfoWsAction} + * because of JSON export by {@link InfoAction} */ LinkedHashMap attributes(); } diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/ws/InfoAction.java b/server/sonar-server/src/main/java/org/sonar/server/platform/ws/InfoAction.java new file mode 100644 index 00000000000..2507352e5bd --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/platform/ws/InfoAction.java @@ -0,0 +1,77 @@ +/* + * 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.platform.ws; + +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.core.permission.GlobalPermissions; +import org.sonar.server.platform.monitoring.Monitor; +import org.sonar.server.user.UserSession; + +import java.util.Map; + +/** + * Implementation of the {@code info} action for the System WebService. + */ +public class InfoAction implements SystemWsAction { + + private final Monitor[] monitors; + private final UserSession userSession; + + public InfoAction(UserSession userSession, Monitor... monitors) { + this.userSession = userSession; + this.monitors = monitors; + } + + @Override + public void define(WebService.NewController controller) { + controller.createAction("info") + .setDescription("Detailed information about system configuration." + + "
" + + "Requires user to be authenticated with Administer System permissions.") + .setSince("5.1") + .setResponseExample(getClass().getResource("/org/sonar/server/platform/ws/example-system-info.json")) + .setHandler(this); + } + + @Override + public void handle(Request request, Response response) { + userSession.checkGlobalPermission(GlobalPermissions.SYSTEM_ADMIN); + JsonWriter json = response.newJsonWriter(); + writeJson(json); + json.close(); + } + + private void writeJson(JsonWriter json) { + json.beginObject(); + for (Monitor monitor : monitors) { + json.name(monitor.name()); + json.beginObject(); + for (Map.Entry attribute : monitor.attributes().entrySet()) { + json.name(attribute.getKey()).valueObject(attribute.getValue()); + } + json.endObject(); + } + json.endObject(); + } +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/ws/MigrateDbSystemAction.java b/server/sonar-server/src/main/java/org/sonar/server/platform/ws/MigrateDbSystemAction.java new file mode 100644 index 00000000000..d2dddb36110 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/platform/ws/MigrateDbSystemAction.java @@ -0,0 +1,185 @@ +/* + * 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.platform.ws; + +import com.google.common.io.Resources; +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.core.persistence.Database; +import org.sonar.core.persistence.DatabaseVersion; +import org.sonar.server.db.migrations.DatabaseMigration; + +import static org.sonar.server.db.migrations.DatabaseMigration.Status.RUNNING; + +/** + * Implementation of the {@code migrate_db} action for the System WebService. + */ +public class MigrateDbSystemAction implements SystemWsAction { + + private static final String UNSUPPORTED_DATABASE_MIGRATION_STATUS = "Unsupported DatabaseMigration status"; + private static final String MESSAGE_STATUS_NONE = "Database is up-to-date, no migration needed."; + private static final String MESSAGE_STATUS_RUNNING = "Database migration is running."; + private static final String MESSAGE_STATUS_SUCCEEDED = "Migration succeeded."; + private static final String MESSAGE_STATUS_FAILED = "Migration failed: %s.
Please check logs."; + + private static final String STATUS_NO_MIGRATION = "NO_MIGRATION"; + private static final String STATUS_NOT_SUPPORTED = "NOT_SUPPORTED"; + private static final String STATUS_MIGRATION_RUNNING = "MIGRATION_RUNNING"; + private static final String STATUS_MIGRATION_FAILED = "MIGRATION_FAILED"; + private static final String STATUS_MIGRATION_SUCCEEDED = "MIGRATION_SUCCEEDED"; + + private static final String PROPERTY_STATE = "state"; + private static final String PROPERTY_MESSAGE = "message"; + private static final String PROPERTY_STARTED_AT = "startedAt"; + + private final DatabaseVersion databaseVersion; + private final DatabaseMigration databaseMigration; + private final Database database; + + public MigrateDbSystemAction(DatabaseVersion databaseVersion, + Database database, + DatabaseMigration databaseMigration) { + this.databaseVersion = databaseVersion; + this.database = database; + this.databaseMigration = databaseMigration; + } + + @Override + public void define(WebService.NewController controller) { + controller.createAction("migrate_db") + .setDescription("Migrate the database to match the current version of SonarQube." + + "
" + + "Sending a POST request to this URL starts the DB migration. " + + "It is strongly advised to make a database backup before invoking this WS." + + "
" + + "State values are:" + + "
    " + + "
  • NO_MIGRATION: DB is up to date with current version of SonarQube.
  • " + + "
  • NOT_SUPPORTED: Migration is not supported on embedded databases.
  • " + + "
  • MIGRATION_RUNNING: DB migration is under go.
  • " + + "
  • MIGRATION_SUCCEEDED: DB migration has run and has been successful.
  • " + + "
  • MIGRATION_FAILED: DB migration has run and failed. SonarQube must be restarted in order to retry a " + + "DB migration (optionally after DB has been restored from backup).
  • " + + "
") + .setSince("5.2") + .setPost(true) + .setHandler(this) + .setResponseExample(Resources.getResource(this.getClass(), "example-migrate_db.json")); + } + + @Override + public void handle(Request request, Response response) throws Exception { + Integer currentVersion = databaseVersion.getVersion(); + if (currentVersion == null) { + throw new IllegalStateException("Version can not be retrieved from Database. Database is either blank or corrupted"); + } + + if (currentVersion >= DatabaseVersion.LAST_VERSION) { + writeResponse(response, databaseMigration); + } else if (!database.getDialect().supportsMigration()) { + writeNotSupportedResponse(response); + } else { + switch (databaseMigration.status()) { + case RUNNING: + case FAILED: + case SUCCEEDED: + writeResponse(response, databaseMigration); + break; + case NONE: + databaseMigration.startIt(); + writeNoneResponse(response, databaseMigration); + break; + default: + throw new IllegalArgumentException(UNSUPPORTED_DATABASE_MIGRATION_STATUS); + } + } + } + + private void writeNotSupportedResponse(Response response) { + JsonWriter jsonWriter = response.newJsonWriter(); + jsonWriter.beginObject() + .prop(PROPERTY_STATE, STATUS_NOT_SUPPORTED) + .prop(PROPERTY_MESSAGE, "Upgrade is not supported on embedded database.") + .endObject(); + jsonWriter.close(); + } + + private void writeNoneResponse(Response response, DatabaseMigration databaseMigration) { + JsonWriter jsonWriter = response.newJsonWriter(); + jsonWriter.beginObject() + .prop(PROPERTY_STATE, statusToJson(RUNNING)) + .prop(PROPERTY_MESSAGE, MESSAGE_STATUS_RUNNING) + .propDateTime(PROPERTY_STARTED_AT, databaseMigration.startedAt()) + .endObject(); + jsonWriter.close(); + } + + private void writeResponse(Response response, DatabaseMigration databaseMigration) { + JsonWriter jsonWriter = response.newJsonWriter(); + jsonWriter.beginObject() + .prop(PROPERTY_STATE, statusToJson(databaseMigration.status())) + .prop(PROPERTY_MESSAGE, buildMessage(databaseMigration)) + .propDateTime(PROPERTY_STARTED_AT, databaseMigration.startedAt()) + .endObject(); + jsonWriter.close(); + } + + private String statusToJson(DatabaseMigration.Status status) { + switch (status) { + case NONE: + return STATUS_NO_MIGRATION; + case RUNNING: + return STATUS_MIGRATION_RUNNING; + case FAILED: + return STATUS_MIGRATION_FAILED; + case SUCCEEDED: + return STATUS_MIGRATION_SUCCEEDED; + default: + throw new IllegalArgumentException( + "Unsupported DatabaseMigration.Status " + status + " can not be converted to JSON value"); + } + } + + private static String buildMessage(DatabaseMigration databaseMigration) { + switch (databaseMigration.status()) { + case NONE: + return MESSAGE_STATUS_NONE; + case RUNNING: + return MESSAGE_STATUS_RUNNING; + case SUCCEEDED: + return MESSAGE_STATUS_SUCCEEDED; + case FAILED: + return String.format(MESSAGE_STATUS_FAILED, failureMessage(databaseMigration)); + default: + return UNSUPPORTED_DATABASE_MIGRATION_STATUS; + } + } + + private static String failureMessage(DatabaseMigration databaseMigration) { + Throwable failureError = databaseMigration.failureError(); + if (failureError == null) { + return "No failure error"; + } + return failureError.getMessage(); + } + +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/ws/MigrateDbSystemWsAction.java b/server/sonar-server/src/main/java/org/sonar/server/platform/ws/MigrateDbSystemWsAction.java deleted file mode 100644 index 97601e57f91..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/platform/ws/MigrateDbSystemWsAction.java +++ /dev/null @@ -1,185 +0,0 @@ -/* - * 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.platform.ws; - -import com.google.common.io.Resources; -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.core.persistence.Database; -import org.sonar.core.persistence.DatabaseVersion; -import org.sonar.server.db.migrations.DatabaseMigration; - -import static org.sonar.server.db.migrations.DatabaseMigration.Status.RUNNING; - -/** - * Implementation of the {@code migrate_db} action for the System WebService. - */ -public class MigrateDbSystemWsAction implements SystemWsAction { - - private static final String UNSUPPORTED_DATABASE_MIGRATION_STATUS = "Unsupported DatabaseMigration status"; - private static final String MESSAGE_STATUS_NONE = "Database is up-to-date, no migration needed."; - private static final String MESSAGE_STATUS_RUNNING = "Database migration is running."; - private static final String MESSAGE_STATUS_SUCCEEDED = "Migration succeeded."; - private static final String MESSAGE_STATUS_FAILED = "Migration failed: %s.
Please check logs."; - - private static final String STATUS_NO_MIGRATION = "NO_MIGRATION"; - private static final String STATUS_NOT_SUPPORTED = "NOT_SUPPORTED"; - private static final String STATUS_MIGRATION_RUNNING = "MIGRATION_RUNNING"; - private static final String STATUS_MIGRATION_FAILED = "MIGRATION_FAILED"; - private static final String STATUS_MIGRATION_SUCCEEDED = "MIGRATION_SUCCEEDED"; - - private static final String PROPERTY_STATE = "state"; - private static final String PROPERTY_MESSAGE = "message"; - private static final String PROPERTY_STARTED_AT = "startedAt"; - - private final DatabaseVersion databaseVersion; - private final DatabaseMigration databaseMigration; - private final Database database; - - public MigrateDbSystemWsAction(DatabaseVersion databaseVersion, - Database database, - DatabaseMigration databaseMigration) { - this.databaseVersion = databaseVersion; - this.database = database; - this.databaseMigration = databaseMigration; - } - - @Override - public void define(WebService.NewController controller) { - controller.createAction("migrate_db") - .setDescription("Migrate the database to match the current version of SonarQube." + - "
" + - "Sending a POST request to this URL starts the DB migration. " + - "It is strongly advised to make a database backup before invoking this WS." + - "
" + - "State values are:" + - "
    " + - "
  • NO_MIGRATION: DB is up to date with current version of SonarQube.
  • " + - "
  • NOT_SUPPORTED: Migration is not supported on embedded databases.
  • " + - "
  • MIGRATION_RUNNING: DB migration is under go.
  • " + - "
  • MIGRATION_SUCCEEDED: DB migration has run and has been successful.
  • " + - "
  • MIGRATION_FAILED: DB migration has run and failed. SonarQube must be restarted in order to retry a " + - "DB migration (optionally after DB has been restored from backup).
  • " + - "
") - .setSince("5.2") - .setPost(true) - .setHandler(this) - .setResponseExample(Resources.getResource(this.getClass(), "example-migrate_db.json")); - } - - @Override - public void handle(Request request, Response response) throws Exception { - Integer currentVersion = databaseVersion.getVersion(); - if (currentVersion == null) { - throw new IllegalStateException("Version can not be retrieved from Database. Database is either blank or corrupted"); - } - - if (currentVersion >= DatabaseVersion.LAST_VERSION) { - writeResponse(response, databaseMigration); - } else if (!database.getDialect().supportsMigration()) { - writeNotSupportedResponse(response); - } else { - switch (databaseMigration.status()) { - case RUNNING: - case FAILED: - case SUCCEEDED: - writeResponse(response, databaseMigration); - break; - case NONE: - databaseMigration.startIt(); - writeNoneResponse(response, databaseMigration); - break; - default: - throw new IllegalArgumentException(UNSUPPORTED_DATABASE_MIGRATION_STATUS); - } - } - } - - private void writeNotSupportedResponse(Response response) { - JsonWriter jsonWriter = response.newJsonWriter(); - jsonWriter.beginObject() - .prop(PROPERTY_STATE, STATUS_NOT_SUPPORTED) - .prop(PROPERTY_MESSAGE, "Upgrade is not supported on embedded database.") - .endObject(); - jsonWriter.close(); - } - - private void writeNoneResponse(Response response, DatabaseMigration databaseMigration) { - JsonWriter jsonWriter = response.newJsonWriter(); - jsonWriter.beginObject() - .prop(PROPERTY_STATE, statusToJson(RUNNING)) - .prop(PROPERTY_MESSAGE, MESSAGE_STATUS_RUNNING) - .propDateTime(PROPERTY_STARTED_AT, databaseMigration.startedAt()) - .endObject(); - jsonWriter.close(); - } - - private void writeResponse(Response response, DatabaseMigration databaseMigration) { - JsonWriter jsonWriter = response.newJsonWriter(); - jsonWriter.beginObject() - .prop(PROPERTY_STATE, statusToJson(databaseMigration.status())) - .prop(PROPERTY_MESSAGE, buildMessage(databaseMigration)) - .propDateTime(PROPERTY_STARTED_AT, databaseMigration.startedAt()) - .endObject(); - jsonWriter.close(); - } - - private String statusToJson(DatabaseMigration.Status status) { - switch (status) { - case NONE: - return STATUS_NO_MIGRATION; - case RUNNING: - return STATUS_MIGRATION_RUNNING; - case FAILED: - return STATUS_MIGRATION_FAILED; - case SUCCEEDED: - return STATUS_MIGRATION_SUCCEEDED; - default: - throw new IllegalArgumentException( - "Unsupported DatabaseMigration.Status " + status + " can not be converted to JSON value"); - } - } - - private static String buildMessage(DatabaseMigration databaseMigration) { - switch (databaseMigration.status()) { - case NONE: - return MESSAGE_STATUS_NONE; - case RUNNING: - return MESSAGE_STATUS_RUNNING; - case SUCCEEDED: - return MESSAGE_STATUS_SUCCEEDED; - case FAILED: - return String.format(MESSAGE_STATUS_FAILED, failureMessage(databaseMigration)); - default: - return UNSUPPORTED_DATABASE_MIGRATION_STATUS; - } - } - - private static String failureMessage(DatabaseMigration databaseMigration) { - Throwable failureError = databaseMigration.failureError(); - if (failureError == null) { - return "No failure error"; - } - return failureError.getMessage(); - } - -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/ws/RestartAction.java b/server/sonar-server/src/main/java/org/sonar/server/platform/ws/RestartAction.java new file mode 100644 index 00000000000..f4204520fcf --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/platform/ws/RestartAction.java @@ -0,0 +1,68 @@ +/* + * 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.platform.ws; + +import org.sonar.api.config.Settings; +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.log.Logger; +import org.sonar.api.utils.log.Loggers; +import org.sonar.server.exceptions.ForbiddenException; +import org.sonar.server.platform.Platform; + +/** + * Implementation of the {@code restart} action for the System WebService. + */ +public class RestartAction implements SystemWsAction { + + private static final Logger LOGGER = Loggers.get(RestartAction.class); + + private final Settings settings; + private final Platform platform; + + public RestartAction(Settings settings, Platform platform) { + this.settings = settings; + this.platform = platform; + } + + @Override + public void define(WebService.NewController controller) { + controller.createAction("restart") + .setDescription("Restart server. Available only on development mode (sonar.web.dev=true). " + + "Ruby on Rails extensions are not reloaded.") + .setSince("4.3") + .setPost(true) + .setHandler(this); + } + + @Override + public void handle(Request request, Response response) { + if (!settings.getBoolean("sonar.web.dev")) { + throw new ForbiddenException("Webservice available only in dev mode"); + } + + LOGGER.info("Restart server"); + platform.restart(); + LOGGER.info("Server restarted"); + response.noContent(); + } + +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/ws/ServerWsAction.java b/server/sonar-server/src/main/java/org/sonar/server/platform/ws/ServerWsAction.java deleted file mode 100644 index 2e22c06bde2..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/platform/ws/ServerWsAction.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * 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.platform.ws; - -import org.sonar.server.ws.WsAction; - -/** - * Marker interface for actions of the WS on URL api/server. - */ -public interface ServerWsAction extends WsAction { - -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/ws/StatusAction.java b/server/sonar-server/src/main/java/org/sonar/server/platform/ws/StatusAction.java new file mode 100644 index 00000000000..cbead05cc15 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/platform/ws/StatusAction.java @@ -0,0 +1,140 @@ +/* + * 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.platform.ws; + +import org.sonar.api.platform.Server; +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.log.Logger; +import org.sonar.api.utils.log.Loggers; +import org.sonar.api.utils.text.JsonWriter; +import org.sonar.core.persistence.DbSession; +import org.sonar.core.persistence.IsAliveMapper; +import org.sonar.server.db.DbClient; +import org.sonar.server.db.migrations.DatabaseMigration; +import org.sonar.server.platform.Platform; + +import com.google.common.io.Resources; + +/** + * Implementation of the {@code status} action for the System WebService. + */ +public class StatusAction implements SystemWsAction { + + private static final Logger LOGGER = Loggers.get(StatusAction.class); + + private final Server server; + private final DatabaseMigration databaseMigration; + private final Platform platform; + private final DbClient dbClient; + + public StatusAction(Server server, DatabaseMigration databaseMigration, Platform platform, DbClient dbClient) { + this.server = server; + this.databaseMigration = databaseMigration; + this.platform = platform; + this.dbClient = dbClient; + } + + @Override + public void define(WebService.NewController controller) { + controller.createAction("status") + .setDescription("Get the server status:" + + "
    " + + "
  • UP: SonarQube instance is up and running
  • " + + "
  • DOWN: SonarQube instance is up but not running because SQ can not connect to database or " + + "migration has failed (refer to WS /api/system/migrate_db for details) or some other reason (check logs).
  • " + + "
  • DB_MIGRATION_NEEDED: database migration is required. DB migration can be started using WS /api/system/migrate_db.
  • " + + "
  • DB_MIGRATION_RUNNING: DB migration is running (refer to WS /api/system/migrate_db for details)
  • " + + "
") + .setSince("5.2") + .setResponseExample(Resources.getResource(this.getClass(), "example-status.json")) + .setHandler(this); + } + + @Override + public void handle(Request request, Response response) throws Exception { + JsonWriter json = response.newJsonWriter(); + writeJson(json); + json.close(); + } + + private void writeJson(JsonWriter json) { + Status status = computeStatus(); + + json.beginObject(); + json.prop("id", server.getId()); + json.prop("version", server.getVersion()); + json.prop("status", status.toString()); + json.endObject(); + } + + private Status computeStatus() { + if (!isConnectedToDB()) { + return Status.DOWN; + } + + Platform.Status platformStatus = platform.status(); + switch (platformStatus) { + case BOOTING: + // can not happen since there can not even exist an instance of the current class + // unless the Platform's status is UP or SAFEMODE + return Status.DOWN; + case UP: + return Status.UP; + case SAFEMODE: + return computeFromDbMigrationStatus(); + default: + throw new IllegalArgumentException("Unsupported Platform.Status " + platformStatus); + } + } + + private boolean isConnectedToDB() { + try (DbSession dbSession = dbClient.openSession(false)) { + return dbSession.getMapper(IsAliveMapper.class).isAlive() == IsAliveMapper.IS_ALIVE_RETURNED_VALUE; + } catch (RuntimeException e) { + LOGGER.error("DB connection is down", e); + return false; + } + } + + private Status computeFromDbMigrationStatus() { + DatabaseMigration.Status databaseMigrationStatus = databaseMigration.status(); + switch (databaseMigrationStatus) { + case NONE: + return Status.DB_MIGRATION_NEEDED; + case RUNNING: + return Status.DB_MIGRATION_RUNNING; + case FAILED: + return Status.DOWN; + case SUCCEEDED: + // status of Platform is supposed to be UP _before_ DatabaseMigration status becomes UP too + // so, in theory, this case can not happen + return Status.UP; + default: + throw new IllegalArgumentException("Unsupported DatabaseMigration.Status " + databaseMigrationStatus); + } + } + + private enum Status { + UP, DOWN, DB_MIGRATION_NEEDED, DB_MIGRATION_RUNNING + } + +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/ws/SystemInfoWsAction.java b/server/sonar-server/src/main/java/org/sonar/server/platform/ws/SystemInfoWsAction.java deleted file mode 100644 index a90d17112ac..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/platform/ws/SystemInfoWsAction.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * 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.platform.ws; - -import java.util.Map; -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.core.permission.GlobalPermissions; -import org.sonar.server.platform.monitoring.Monitor; -import org.sonar.server.user.UserSession; - -/** - * Implementation of the {@code info} action for the System WebService. - */ -public class SystemInfoWsAction implements SystemWsAction { - - private final Monitor[] monitors; - private final UserSession userSession; - - public SystemInfoWsAction(UserSession userSession, Monitor... monitors) { - this.userSession = userSession; - this.monitors = monitors; - } - - @Override - public void define(WebService.NewController controller) { - controller.createAction("info") - .setDescription("Detailed information about system configuration." + - "
" + - "Requires user to be authenticated with Administer System permissions.") - .setSince("5.1") - .setResponseExample(getClass().getResource("/org/sonar/server/platform/ws/example-system-info.json")) - .setHandler(this); - } - - @Override - public void handle(Request request, Response response) { - userSession.checkGlobalPermission(GlobalPermissions.SYSTEM_ADMIN); - JsonWriter json = response.newJsonWriter(); - writeJson(json); - json.close(); - } - - private void writeJson(JsonWriter json) { - json.beginObject(); - for (Monitor monitor : monitors) { - json.name(monitor.name()); - json.beginObject(); - for (Map.Entry attribute : monitor.attributes().entrySet()) { - json.name(attribute.getKey()).valueObject(attribute.getValue()); - } - json.endObject(); - } - json.endObject(); - } -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/ws/SystemRestartWsAction.java b/server/sonar-server/src/main/java/org/sonar/server/platform/ws/SystemRestartWsAction.java deleted file mode 100644 index 92665be650e..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/platform/ws/SystemRestartWsAction.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * 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.platform.ws; - -import org.sonar.api.config.Settings; -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.log.Logger; -import org.sonar.api.utils.log.Loggers; -import org.sonar.server.exceptions.ForbiddenException; -import org.sonar.server.platform.Platform; - -/** - * Implementation of the {@code restart} action for the System WebService. - */ -public class SystemRestartWsAction implements SystemWsAction { - - private static final Logger LOGGER = Loggers.get(SystemRestartWsAction.class); - - private final Settings settings; - private final Platform platform; - - public SystemRestartWsAction(Settings settings, Platform platform) { - this.settings = settings; - this.platform = platform; - } - - @Override - public void define(WebService.NewController controller) { - controller.createAction("restart") - .setDescription("Restart server. Available only on development mode (sonar.web.dev=true). " + - "Ruby on Rails extensions are not reloaded.") - .setSince("4.3") - .setPost(true) - .setHandler(this); - } - - @Override - public void handle(Request request, Response response) { - if (!settings.getBoolean("sonar.web.dev")) { - throw new ForbiddenException("Webservice available only in dev mode"); - } - - LOGGER.info("Restart server"); - platform.restart(); - LOGGER.info("Server restarted"); - response.noContent(); - } - -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/ws/SystemStatusWsAction.java b/server/sonar-server/src/main/java/org/sonar/server/platform/ws/SystemStatusWsAction.java deleted file mode 100644 index 89e08b4dce5..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/platform/ws/SystemStatusWsAction.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * 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.platform.ws; - -import org.sonar.api.platform.Server; -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.log.Logger; -import org.sonar.api.utils.log.Loggers; -import org.sonar.api.utils.text.JsonWriter; -import org.sonar.core.persistence.DbSession; -import org.sonar.core.persistence.IsAliveMapper; -import org.sonar.server.db.DbClient; -import org.sonar.server.db.migrations.DatabaseMigration; -import org.sonar.server.platform.Platform; - -import com.google.common.io.Resources; - -/** - * Implementation of the {@code status} action for the System WebService. - */ -public class SystemStatusWsAction implements SystemWsAction { - - private static final Logger LOGGER = Loggers.get(SystemStatusWsAction.class); - - private final Server server; - private final DatabaseMigration databaseMigration; - private final Platform platform; - private final DbClient dbClient; - - public SystemStatusWsAction(Server server, DatabaseMigration databaseMigration, Platform platform, DbClient dbClient) { - this.server = server; - this.databaseMigration = databaseMigration; - this.platform = platform; - this.dbClient = dbClient; - } - - @Override - public void define(WebService.NewController controller) { - controller.createAction("status") - .setDescription("Get the server status:" + - "
    " + - "
  • UP: SonarQube instance is up and running
  • " + - "
  • DOWN: SonarQube instance is up but not running because SQ can not connect to database or " + - "migration has failed (refer to WS /api/system/migrate_db for details) or some other reason (check logs).
  • " + - "
  • DB_MIGRATION_NEEDED: database migration is required. DB migration can be started using WS /api/system/migrate_db.
  • " + - "
  • DB_MIGRATION_RUNNING: DB migration is running (refer to WS /api/system/migrate_db for details)
  • " + - "
") - .setSince("5.2") - .setResponseExample(Resources.getResource(this.getClass(), "example-status.json")) - .setHandler(this); - } - - @Override - public void handle(Request request, Response response) throws Exception { - JsonWriter json = response.newJsonWriter(); - writeJson(json); - json.close(); - } - - private void writeJson(JsonWriter json) { - Status status = computeStatus(); - - json.beginObject(); - json.prop("id", server.getId()); - json.prop("version", server.getVersion()); - json.prop("status", status.toString()); - json.endObject(); - } - - private Status computeStatus() { - if (!isConnectedToDB()) { - return Status.DOWN; - } - - Platform.Status platformStatus = platform.status(); - switch (platformStatus) { - case BOOTING: - // can not happen since there can not even exist an instance of the current class - // unless the Platform's status is UP or SAFEMODE - return Status.DOWN; - case UP: - return Status.UP; - case SAFEMODE: - return computeFromDbMigrationStatus(); - default: - throw new IllegalArgumentException("Unsupported Platform.Status " + platformStatus); - } - } - - private boolean isConnectedToDB() { - try (DbSession dbSession = dbClient.openSession(false)) { - return dbSession.getMapper(IsAliveMapper.class).isAlive() == IsAliveMapper.IS_ALIVE_RETURNED_VALUE; - } catch (RuntimeException e) { - LOGGER.error("DB connection is down", e); - return false; - } - } - - private Status computeFromDbMigrationStatus() { - DatabaseMigration.Status databaseMigrationStatus = databaseMigration.status(); - switch (databaseMigrationStatus) { - case NONE: - return Status.DB_MIGRATION_NEEDED; - case RUNNING: - return Status.DB_MIGRATION_RUNNING; - case FAILED: - return Status.DOWN; - case SUCCEEDED: - // status of Platform is supposed to be UP _before_ DatabaseMigration status becomes UP too - // so, in theory, this case can not happen - return Status.UP; - default: - throw new IllegalArgumentException("Unsupported DatabaseMigration.Status " + databaseMigrationStatus); - } - } - - private enum Status { - UP, DOWN, DB_MIGRATION_NEEDED, DB_MIGRATION_RUNNING - } - -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/ws/UpgradesAction.java b/server/sonar-server/src/main/java/org/sonar/server/platform/ws/UpgradesAction.java new file mode 100644 index 00000000000..3b7c0a88426 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/platform/ws/UpgradesAction.java @@ -0,0 +1,158 @@ +/* + * 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.platform.ws; + +import com.google.common.io.Resources; +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.plugins.UpdateCenterMatrixFactory; +import org.sonar.server.plugins.ws.PluginWSCommons; +import org.sonar.updatecenter.common.Plugin; +import org.sonar.updatecenter.common.Release; +import org.sonar.updatecenter.common.SonarUpdate; +import org.sonar.updatecenter.common.UpdateCenter; + +import java.util.List; + +/** + * Implementation of the {@code upgrades} action for the System WebService. + */ +public class UpgradesAction implements SystemWsAction { + + private static final boolean DO_NOT_FORCE_REFRESH = false; + + private static final String ARRAY_UPGRADES = "upgrades"; + private static final String PROPERTY_UPDATE_CENTER_REFRESH = "updateCenterRefresh"; + private static final String PROPERTY_VERSION = "version"; + private static final String PROPERTY_DESCRIPTION = "description"; + private static final String PROPERTY_RELEASE_DATE = "releaseDate"; + private static final String PROPERTY_CHANGE_LOG_URL = "changeLogUrl"; + private static final String PROPERTY_DOWNLOAD_URL = "downloadUrl"; + private static final String OBJECT_PLUGINS = "plugins"; + private static final String ARRAY_REQUIRE_UPDATE = "requireUpdate"; + private static final String ARRAY_INCOMPATIBLE = "incompatible"; + + private final UpdateCenterMatrixFactory updateCenterFactory; + private final PluginWSCommons pluginWSCommons; + + public UpgradesAction(UpdateCenterMatrixFactory updateCenterFactory, PluginWSCommons pluginWSCommons) { + this.updateCenterFactory = updateCenterFactory; + this.pluginWSCommons = pluginWSCommons; + } + + @Override + public void define(WebService.NewController controller) { + controller.createAction("upgrades") + .setDescription("Lists available upgrades for the SonarQube instance (if any) and for each one, " + + "lists incompatible plugins and plugins requiring upgrade." + + "
" + + "Plugin information is retrieved from Update Center. Date and time at which Update Center was last refreshed " + + "is provided in the response.") + .setHandler(this) + .setResponseExample(Resources.getResource(this.getClass(), "example-upgrades_plugins.json")); + } + + @Override + public void handle(Request request, Response response) throws Exception { + JsonWriter jsonWriter = response.newJsonWriter().setSerializeEmptys(false); + + writeResponse(jsonWriter); + + jsonWriter.close(); + } + + private void writeResponse(JsonWriter jsonWriter) { + jsonWriter.beginObject(); + + UpdateCenter updateCenter = updateCenterFactory.getUpdateCenter(DO_NOT_FORCE_REFRESH); + writeUpgrades(jsonWriter, updateCenter); + jsonWriter.propDateTime(PROPERTY_UPDATE_CENTER_REFRESH, updateCenter.getDate()); + + jsonWriter.endObject(); + } + + private void writeUpgrades(JsonWriter jsonWriter, UpdateCenter updateCenter) { + jsonWriter.name(ARRAY_UPGRADES).beginArray(); + + for (SonarUpdate sonarUpdate : updateCenter.findSonarUpdates()) { + writeUpgrade(jsonWriter, sonarUpdate); + } + + jsonWriter.endArray(); + } + + private void writeUpgrade(JsonWriter jsonWriter, SonarUpdate sonarUpdate) { + jsonWriter.beginObject(); + + writeMetadata(jsonWriter, sonarUpdate.getRelease()); + + writePlugins(jsonWriter, sonarUpdate); + + jsonWriter.endObject(); + } + + private void writeMetadata(JsonWriter jsonWriter, Release release) { + jsonWriter.prop(PROPERTY_VERSION, release.getVersion().getName()); + jsonWriter.prop(PROPERTY_DESCRIPTION, release.getDescription()); + jsonWriter.propDate(PROPERTY_RELEASE_DATE, release.getDate()); + jsonWriter.prop(PROPERTY_CHANGE_LOG_URL, release.getChangelogUrl()); + jsonWriter.prop(PROPERTY_DOWNLOAD_URL, release.getDownloadUrl()); + } + + private void writePlugins(JsonWriter jsonWriter, SonarUpdate sonarUpdate) { + jsonWriter.name(OBJECT_PLUGINS).beginObject(); + + writePluginsToUpdate(jsonWriter, sonarUpdate.getPluginsToUpgrade()); + + writeIncompatiblePlugins(jsonWriter, sonarUpdate.getIncompatiblePlugins()); + + jsonWriter.endObject(); + } + + private void writePluginsToUpdate(JsonWriter jsonWriter, List pluginsToUpgrade) { + jsonWriter.name(ARRAY_REQUIRE_UPDATE).beginArray(); + for (Release release : pluginsToUpgrade) { + jsonWriter.beginObject(); + + pluginWSCommons.writeMetadata(jsonWriter, (Plugin) release.getArtifact()); + jsonWriter.prop(PROPERTY_VERSION, release.getVersion().toString()); + + jsonWriter.endObject(); + } + + jsonWriter.endArray(); + } + + private void writeIncompatiblePlugins(JsonWriter jsonWriter, List incompatiblePlugins) { + jsonWriter.name(ARRAY_INCOMPATIBLE).beginArray(); + + for (Plugin incompatiblePlugin : incompatiblePlugins) { + jsonWriter.beginObject(); + + pluginWSCommons.writeMetadata(jsonWriter, incompatiblePlugin); + + jsonWriter.endObject(); + } + + jsonWriter.endArray(); + } +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/ws/UpgradesSystemWsAction.java b/server/sonar-server/src/main/java/org/sonar/server/platform/ws/UpgradesSystemWsAction.java deleted file mode 100644 index 5e845559201..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/platform/ws/UpgradesSystemWsAction.java +++ /dev/null @@ -1,159 +0,0 @@ -/* - * 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.platform.ws; - -import java.util.List; - -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.plugins.UpdateCenterMatrixFactory; -import org.sonar.server.plugins.ws.PluginWSCommons; -import org.sonar.updatecenter.common.Plugin; -import org.sonar.updatecenter.common.Release; -import org.sonar.updatecenter.common.SonarUpdate; -import org.sonar.updatecenter.common.UpdateCenter; - -import com.google.common.io.Resources; - -/** - * Implementation of the {@code upgrades} action for the System WebService. - */ -public class UpgradesSystemWsAction implements SystemWsAction { - - private static final boolean DO_NOT_FORCE_REFRESH = false; - - private static final String ARRAY_UPGRADES = "upgrades"; - private static final String PROPERTY_UPDATE_CENTER_REFRESH = "updateCenterRefresh"; - private static final String PROPERTY_VERSION = "version"; - private static final String PROPERTY_DESCRIPTION = "description"; - private static final String PROPERTY_RELEASE_DATE = "releaseDate"; - private static final String PROPERTY_CHANGE_LOG_URL = "changeLogUrl"; - private static final String PROPERTY_DOWNLOAD_URL = "downloadUrl"; - private static final String OBJECT_PLUGINS = "plugins"; - private static final String ARRAY_REQUIRE_UPDATE = "requireUpdate"; - private static final String ARRAY_INCOMPATIBLE = "incompatible"; - - private final UpdateCenterMatrixFactory updateCenterFactory; - private final PluginWSCommons pluginWSCommons; - - public UpgradesSystemWsAction(UpdateCenterMatrixFactory updateCenterFactory, PluginWSCommons pluginWSCommons) { - this.updateCenterFactory = updateCenterFactory; - this.pluginWSCommons = pluginWSCommons; - } - - @Override - public void define(WebService.NewController controller) { - controller.createAction("upgrades") - .setDescription("Lists available upgrades for the SonarQube instance (if any) and for each one, " + - "lists incompatible plugins and plugins requiring upgrade." + - "
" + - "Plugin information is retrieved from Update Center. Date and time at which Update Center was last refreshed " + - "is provided in the response.") - .setHandler(this) - .setResponseExample(Resources.getResource(this.getClass(), "example-upgrades_plugins.json")); - } - - @Override - public void handle(Request request, Response response) throws Exception { - JsonWriter jsonWriter = response.newJsonWriter().setSerializeEmptys(false); - - writeResponse(jsonWriter); - - jsonWriter.close(); - } - - private void writeResponse(JsonWriter jsonWriter) { - jsonWriter.beginObject(); - - UpdateCenter updateCenter = updateCenterFactory.getUpdateCenter(DO_NOT_FORCE_REFRESH); - writeUpgrades(jsonWriter, updateCenter); - jsonWriter.propDateTime(PROPERTY_UPDATE_CENTER_REFRESH, updateCenter.getDate()); - - jsonWriter.endObject(); - } - - private void writeUpgrades(JsonWriter jsonWriter, UpdateCenter updateCenter) { - jsonWriter.name(ARRAY_UPGRADES).beginArray(); - - for (SonarUpdate sonarUpdate : updateCenter.findSonarUpdates()) { - writeUpgrade(jsonWriter, sonarUpdate); - } - - jsonWriter.endArray(); - } - - private void writeUpgrade(JsonWriter jsonWriter, SonarUpdate sonarUpdate) { - jsonWriter.beginObject(); - - writeMetadata(jsonWriter, sonarUpdate.getRelease()); - - writePlugins(jsonWriter, sonarUpdate); - - jsonWriter.endObject(); - } - - private void writeMetadata(JsonWriter jsonWriter, Release release) { - jsonWriter.prop(PROPERTY_VERSION, release.getVersion().getName()); - jsonWriter.prop(PROPERTY_DESCRIPTION, release.getDescription()); - jsonWriter.propDate(PROPERTY_RELEASE_DATE, release.getDate()); - jsonWriter.prop(PROPERTY_CHANGE_LOG_URL, release.getChangelogUrl()); - jsonWriter.prop(PROPERTY_DOWNLOAD_URL, release.getDownloadUrl()); - } - - private void writePlugins(JsonWriter jsonWriter, SonarUpdate sonarUpdate) { - jsonWriter.name(OBJECT_PLUGINS).beginObject(); - - writePluginsToUpdate(jsonWriter, sonarUpdate.getPluginsToUpgrade()); - - writeIncompatiblePlugins(jsonWriter, sonarUpdate.getIncompatiblePlugins()); - - jsonWriter.endObject(); - } - - private void writePluginsToUpdate(JsonWriter jsonWriter, List pluginsToUpgrade) { - jsonWriter.name(ARRAY_REQUIRE_UPDATE).beginArray(); - for (Release release : pluginsToUpgrade) { - jsonWriter.beginObject(); - - pluginWSCommons.writeMetadata(jsonWriter, (Plugin) release.getArtifact()); - jsonWriter.prop(PROPERTY_VERSION, release.getVersion().toString()); - - jsonWriter.endObject(); - } - - jsonWriter.endArray(); - } - - private void writeIncompatiblePlugins(JsonWriter jsonWriter, List incompatiblePlugins) { - jsonWriter.name(ARRAY_INCOMPATIBLE).beginArray(); - - for (Plugin incompatiblePlugin : incompatiblePlugins) { - jsonWriter.beginObject(); - - pluginWSCommons.writeMetadata(jsonWriter, incompatiblePlugin); - - jsonWriter.endObject(); - } - - jsonWriter.endArray(); - } -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/AvailableAction.java b/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/AvailableAction.java new file mode 100644 index 00000000000..4bb68ba25d8 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/AvailableAction.java @@ -0,0 +1,98 @@ +/* + * 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.plugins.ws; + +import com.google.common.collect.ImmutableSortedSet; +import com.google.common.io.Resources; +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.plugins.UpdateCenterMatrixFactory; +import org.sonar.updatecenter.common.PluginUpdate; +import org.sonar.updatecenter.common.UpdateCenter; + +import java.util.Collection; + +import static org.sonar.server.plugins.ws.PluginWSCommons.NAME_KEY_PLUGIN_UPDATE_ORDERING; + +public class AvailableAction implements PluginsWsAction { + + private static final boolean DO_NOT_FORCE_REFRESH = false; + private static final String ARRAY_PLUGINS = "plugins"; + + private final UpdateCenterMatrixFactory updateCenterFactory; + private final PluginWSCommons pluginWSCommons; + + public AvailableAction(UpdateCenterMatrixFactory updateCenterFactory, PluginWSCommons pluginWSCommons) { + this.updateCenterFactory = updateCenterFactory; + this.pluginWSCommons = pluginWSCommons; + } + + @Override + public void define(WebService.NewController controller) { + controller.createAction("available") + .setDescription("Get the list of all the plugins available for installation on the SonarQube instance, sorted by plugin name." + + "
" + + "Plugin information is retrieved from Update Center. Date and time at which Update Center was last refreshed is provided in the response." + + "
" + + "Update status values are: " + + "
    " + + "
  • COMPATIBLE: plugin is compatible with current SonarQube instance.
  • " + + "
  • INCOMPATIBLE: plugin is not compatible with current SonarQube instance.
  • " + + "
  • REQUIRES_SYSTEM_UPGRADE: plugin requires SonarQube to be upgraded before being installed.
  • " + + "
  • DEPS_REQUIRE_SYSTEM_UPGRADE: at least one plugin on which the plugin is dependent requires SonarQube to be upgraded.
  • " + + "
") + .setSince("5.2") + .setHandler(this) + .setResponseExample(Resources.getResource(this.getClass(), "example-available_plugins.json")); + } + + @Override + public void handle(Request request, Response response) throws Exception { + JsonWriter jsonWriter = response.newJsonWriter(); + jsonWriter.beginObject(); + + UpdateCenter updateCenter = updateCenterFactory.getUpdateCenter(DO_NOT_FORCE_REFRESH); + + writePlugins(jsonWriter, updateCenter); + + pluginWSCommons.writeUpdateCenterProperties(jsonWriter, updateCenter); + + jsonWriter.endObject(); + jsonWriter.close(); + } + + private void writePlugins(JsonWriter jsonWriter, UpdateCenter updateCenter) { + jsonWriter.name(ARRAY_PLUGINS).beginArray(); + for (PluginUpdate pluginUpdate : retrieveAvailablePlugins(updateCenter)) { + pluginWSCommons.writePluginUpdate(jsonWriter, pluginUpdate); + } + jsonWriter.endArray(); + } + + private Collection retrieveAvailablePlugins(UpdateCenter updateCenter) { + return ImmutableSortedSet.copyOf( + NAME_KEY_PLUGIN_UPDATE_ORDERING, + updateCenter.findAvailablePlugins() + ); + } + +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/AvailablePluginsWsAction.java b/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/AvailablePluginsWsAction.java deleted file mode 100644 index bb0d0ea3313..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/AvailablePluginsWsAction.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * 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.plugins.ws; - -import com.google.common.collect.ImmutableSortedSet; -import com.google.common.io.Resources; -import java.util.Collection; -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.plugins.UpdateCenterMatrixFactory; -import org.sonar.updatecenter.common.PluginUpdate; -import org.sonar.updatecenter.common.UpdateCenter; - -import static org.sonar.server.plugins.ws.PluginWSCommons.NAME_KEY_PLUGIN_UPDATE_ORDERING; - -public class AvailablePluginsWsAction implements PluginsWsAction { - - private static final boolean DO_NOT_FORCE_REFRESH = false; - private static final String ARRAY_PLUGINS = "plugins"; - - private final UpdateCenterMatrixFactory updateCenterFactory; - private final PluginWSCommons pluginWSCommons; - - public AvailablePluginsWsAction(UpdateCenterMatrixFactory updateCenterFactory, PluginWSCommons pluginWSCommons) { - this.updateCenterFactory = updateCenterFactory; - this.pluginWSCommons = pluginWSCommons; - } - - @Override - public void define(WebService.NewController controller) { - controller.createAction("available") - .setDescription("Get the list of all the plugins available for installation on the SonarQube instance, sorted by plugin name." + - "
" + - "Plugin information is retrieved from Update Center. Date and time at which Update Center was last refreshed is provided in the response." + - "
" + - "Update status values are: " + - "
    " + - "
  • COMPATIBLE: plugin is compatible with current SonarQube instance.
  • " + - "
  • INCOMPATIBLE: plugin is not compatible with current SonarQube instance.
  • " + - "
  • REQUIRES_SYSTEM_UPGRADE: plugin requires SonarQube to be upgraded before being installed.
  • " + - "
  • DEPS_REQUIRE_SYSTEM_UPGRADE: at least one plugin on which the plugin is dependent requires SonarQube to be upgraded.
  • " + - "
") - .setSince("5.2") - .setHandler(this) - .setResponseExample(Resources.getResource(this.getClass(), "example-available_plugins.json")); - } - - @Override - public void handle(Request request, Response response) throws Exception { - JsonWriter jsonWriter = response.newJsonWriter(); - jsonWriter.beginObject(); - - UpdateCenter updateCenter = updateCenterFactory.getUpdateCenter(DO_NOT_FORCE_REFRESH); - - writePlugins(jsonWriter, updateCenter); - - pluginWSCommons.writeUpdateCenterProperties(jsonWriter, updateCenter); - - jsonWriter.endObject(); - jsonWriter.close(); - } - - private void writePlugins(JsonWriter jsonWriter, UpdateCenter updateCenter) { - jsonWriter.name(ARRAY_PLUGINS).beginArray(); - for (PluginUpdate pluginUpdate : retrieveAvailablePlugins(updateCenter)) { - pluginWSCommons.writePluginUpdate(jsonWriter, pluginUpdate); - } - jsonWriter.endArray(); - } - - private Collection retrieveAvailablePlugins(UpdateCenter updateCenter) { - return ImmutableSortedSet.copyOf( - NAME_KEY_PLUGIN_UPDATE_ORDERING, - updateCenter.findAvailablePlugins() - ); - } - -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/CancelAllAction.java b/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/CancelAllAction.java new file mode 100644 index 00000000000..2d10ce1070c --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/CancelAllAction.java @@ -0,0 +1,61 @@ +/* + * 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.plugins.ws; + +import org.sonar.api.server.ws.Request; +import org.sonar.api.server.ws.Response; +import org.sonar.api.server.ws.WebService; +import org.sonar.core.permission.GlobalPermissions; +import org.sonar.server.plugins.PluginDownloader; +import org.sonar.server.plugins.ServerPluginRepository; +import org.sonar.server.user.UserSession; + +public class CancelAllAction implements PluginsWsAction { + + private final PluginDownloader pluginDownloader; + private final ServerPluginRepository pluginRepository; + private final UserSession userSession; + + public CancelAllAction(PluginDownloader pluginDownloader, ServerPluginRepository pluginRepository, UserSession userSession) { + this.pluginDownloader = pluginDownloader; + this.pluginRepository = pluginRepository; + this.userSession = userSession; + } + + @Override + public void define(WebService.NewController controller) { + controller.createAction("cancel_all") + .setPost(true) + .setDescription("Cancels any operation pending on any plugin (install, update or uninstall)" + + "
" + + "Requires user to be authenticated with Administer System permissions") + .setHandler(this); + } + + @Override + public void handle(Request request, Response response) throws Exception { + userSession.checkGlobalPermission(GlobalPermissions.SYSTEM_ADMIN); + + pluginDownloader.cancelDownloads(); + pluginRepository.cancelUninstalls(); + + response.noContent(); + } +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/CancelAllPluginsWsAction.java b/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/CancelAllPluginsWsAction.java deleted file mode 100644 index 1812db27095..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/CancelAllPluginsWsAction.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * 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.plugins.ws; - -import org.sonar.api.server.ws.Request; -import org.sonar.api.server.ws.Response; -import org.sonar.api.server.ws.WebService; -import org.sonar.core.permission.GlobalPermissions; -import org.sonar.server.plugins.PluginDownloader; -import org.sonar.server.plugins.ServerPluginRepository; -import org.sonar.server.user.UserSession; - -public class CancelAllPluginsWsAction implements PluginsWsAction { - - private final PluginDownloader pluginDownloader; - private final ServerPluginRepository pluginRepository; - private final UserSession userSession; - - public CancelAllPluginsWsAction(PluginDownloader pluginDownloader, ServerPluginRepository pluginRepository, UserSession userSession) { - this.pluginDownloader = pluginDownloader; - this.pluginRepository = pluginRepository; - this.userSession = userSession; - } - - @Override - public void define(WebService.NewController controller) { - controller.createAction("cancel_all") - .setPost(true) - .setDescription("Cancels any operation pending on any plugin (install, update or uninstall)" + - "
" + - "Requires user to be authenticated with Administer System permissions") - .setHandler(this); - } - - @Override - public void handle(Request request, Response response) throws Exception { - userSession.checkGlobalPermission(GlobalPermissions.SYSTEM_ADMIN); - - pluginDownloader.cancelDownloads(); - pluginRepository.cancelUninstalls(); - - response.noContent(); - } -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/InstallAction.java b/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/InstallAction.java new file mode 100644 index 00000000000..e69f4d61b1c --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/InstallAction.java @@ -0,0 +1,109 @@ +/* + * 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.plugins.ws; + +import com.google.common.base.Predicate; +import com.google.common.collect.Iterables; +import org.sonar.api.server.ws.Request; +import org.sonar.api.server.ws.Response; +import org.sonar.api.server.ws.WebService; +import org.sonar.core.permission.GlobalPermissions; +import org.sonar.server.plugins.PluginDownloader; +import org.sonar.server.plugins.UpdateCenterMatrixFactory; +import org.sonar.server.user.UserSession; +import org.sonar.updatecenter.common.PluginUpdate; + +import javax.annotation.Nullable; + +import static java.lang.String.format; + +/** + * Implementation of the {@code install} action for the Plugins WebService. + */ +public class InstallAction implements PluginsWsAction { + + private static final String PARAM_KEY = "key"; + private static final PluginUpdate MISSING_PLUGIN = null; + + private final UpdateCenterMatrixFactory updateCenterFactory; + private final PluginDownloader pluginDownloader; + private final UserSession userSession; + + public InstallAction(UpdateCenterMatrixFactory updateCenterFactory, + PluginDownloader pluginDownloader, UserSession userSession) { + this.updateCenterFactory = updateCenterFactory; + this.pluginDownloader = pluginDownloader; + this.userSession = userSession; + } + + @Override + public void define(WebService.NewController controller) { + WebService.NewAction action = controller.createAction("install") + .setPost(true) + .setDescription("Installs the latest version of a plugin specified by its key." + + "
" + + "Plugin information is retrieved from Update Center." + + "
" + + "Requires user to be authenticated with Administer System permissions") + .setHandler(this); + + action.createParam(PARAM_KEY).setRequired(true) + .setDescription("The key identifying the plugin to install"); + } + + @Override + public void handle(Request request, Response response) throws Exception { + userSession.checkGlobalPermission(GlobalPermissions.SYSTEM_ADMIN); + String key = request.mandatoryParam(PARAM_KEY); + PluginUpdate pluginUpdate = findAvailablePluginByKey(key); + pluginDownloader.download(key, pluginUpdate.getRelease().getVersion()); + response.noContent(); + } + + private PluginUpdate findAvailablePluginByKey(String key) { + PluginUpdate pluginUpdate = Iterables.find( + updateCenterFactory.getUpdateCenter(false).findAvailablePlugins(), + hasKey(key), + MISSING_PLUGIN + ); + if (pluginUpdate == MISSING_PLUGIN) { + throw new IllegalArgumentException( + format("No plugin with key '%s' or plugin '%s' is already installed in latest version", key, key)); + } + return pluginUpdate; + } + + private static PluginKeyPredicate hasKey(String key) { + return new PluginKeyPredicate(key); + } + + private static class PluginKeyPredicate implements Predicate { + private final String key; + + public PluginKeyPredicate(String key) { + this.key = key; + } + + @Override + public boolean apply(@Nullable PluginUpdate input) { + return input != null && key.equals(input.getPlugin().getKey()); + } + } +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/InstallPluginsWsAction.java b/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/InstallPluginsWsAction.java deleted file mode 100644 index 3a55f4a3140..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/InstallPluginsWsAction.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * 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.plugins.ws; - -import com.google.common.base.Predicate; -import com.google.common.collect.Iterables; -import javax.annotation.Nullable; -import org.sonar.api.server.ws.Request; -import org.sonar.api.server.ws.Response; -import org.sonar.api.server.ws.WebService; -import org.sonar.core.permission.GlobalPermissions; -import org.sonar.server.plugins.PluginDownloader; -import org.sonar.server.plugins.UpdateCenterMatrixFactory; -import org.sonar.server.user.UserSession; -import org.sonar.updatecenter.common.PluginUpdate; - -import static java.lang.String.format; - -/** - * Implementation of the {@code install} action for the Plugins WebService. - */ -public class InstallPluginsWsAction implements PluginsWsAction { - - private static final String PARAM_KEY = "key"; - private static final PluginUpdate MISSING_PLUGIN = null; - - private final UpdateCenterMatrixFactory updateCenterFactory; - private final PluginDownloader pluginDownloader; - private final UserSession userSession; - - public InstallPluginsWsAction(UpdateCenterMatrixFactory updateCenterFactory, - PluginDownloader pluginDownloader, UserSession userSession) { - this.updateCenterFactory = updateCenterFactory; - this.pluginDownloader = pluginDownloader; - this.userSession = userSession; - } - - @Override - public void define(WebService.NewController controller) { - WebService.NewAction action = controller.createAction("install") - .setPost(true) - .setDescription("Installs the latest version of a plugin specified by its key." + - "
" + - "Plugin information is retrieved from Update Center." + - "
" + - "Requires user to be authenticated with Administer System permissions") - .setHandler(this); - - action.createParam(PARAM_KEY).setRequired(true) - .setDescription("The key identifying the plugin to install"); - } - - @Override - public void handle(Request request, Response response) throws Exception { - userSession.checkGlobalPermission(GlobalPermissions.SYSTEM_ADMIN); - String key = request.mandatoryParam(PARAM_KEY); - PluginUpdate pluginUpdate = findAvailablePluginByKey(key); - pluginDownloader.download(key, pluginUpdate.getRelease().getVersion()); - response.noContent(); - } - - private PluginUpdate findAvailablePluginByKey(String key) { - PluginUpdate pluginUpdate = Iterables.find( - updateCenterFactory.getUpdateCenter(false).findAvailablePlugins(), - hasKey(key), - MISSING_PLUGIN - ); - if (pluginUpdate == MISSING_PLUGIN) { - throw new IllegalArgumentException( - format("No plugin with key '%s' or plugin '%s' is already installed in latest version", key, key)); - } - return pluginUpdate; - } - - private static PluginKeyPredicate hasKey(String key) { - return new PluginKeyPredicate(key); - } - - private static class PluginKeyPredicate implements Predicate { - private final String key; - - public PluginKeyPredicate(String key) { - this.key = key; - } - - @Override - public boolean apply(@Nullable PluginUpdate input) { - return input != null && key.equals(input.getPlugin().getKey()); - } - } -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/InstalledAction.java b/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/InstalledAction.java new file mode 100644 index 00000000000..bd0addab688 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/InstalledAction.java @@ -0,0 +1,102 @@ +/* + * 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.plugins.ws; + +import com.google.common.base.Predicate; +import com.google.common.collect.ImmutableSortedSet; +import com.google.common.io.Resources; +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.core.platform.PluginInfo; +import org.sonar.server.plugins.ServerPluginRepository; + +import javax.annotation.Nullable; + +import java.util.Collection; +import java.util.SortedSet; + +import static com.google.common.collect.Iterables.filter; +import static org.sonar.server.plugins.ws.PluginWSCommons.NAME_KEY_PLUGIN_METADATA_COMPARATOR; + +/** + * Implementation of the {@code installed} action for the Plugins WebService. + */ +public class InstalledAction implements PluginsWsAction { + private static final String ARRAY_PLUGINS = "plugins"; + + private final ServerPluginRepository pluginRepository; + private final PluginWSCommons pluginWSCommons; + + public InstalledAction(ServerPluginRepository pluginRepository, + PluginWSCommons pluginWSCommons) { + this.pluginRepository = pluginRepository; + this.pluginWSCommons = pluginWSCommons; + } + + @Override + public void define(WebService.NewController controller) { + controller.createAction("installed") + .setDescription("Get the list of all the plugins installed on the SonarQube instance, sorted by plugin name") + .setSince("5.2") + .setHandler(this) + .setResponseExample(Resources.getResource(this.getClass(), "example-installed_plugins.json")); + } + + @Override + public void handle(Request request, Response response) throws Exception { + Collection infos = retrieveAndSortPluginMetadata(); + + JsonWriter jsonWriter = response.newJsonWriter(); + jsonWriter.setSerializeEmptys(false); + jsonWriter.beginObject(); + + writeMetadataList(jsonWriter, infos); + + jsonWriter.endObject(); + jsonWriter.close(); + } + + private SortedSet retrieveAndSortPluginMetadata() { + return ImmutableSortedSet.copyOf( + NAME_KEY_PLUGIN_METADATA_COMPARATOR, + filter(pluginRepository.getPluginInfos(), NotCorePluginsPredicate.INSTANCE) + ); + } + + private void writeMetadataList(JsonWriter jsonWriter, Collection pluginMetadatas) { + jsonWriter.name(ARRAY_PLUGINS); + jsonWriter.beginArray(); + for (PluginInfo pluginMetadata : pluginMetadatas) { + pluginWSCommons.writePluginMetadata(jsonWriter, pluginMetadata); + } + jsonWriter.endArray(); + } + + private enum NotCorePluginsPredicate implements Predicate { + INSTANCE; + + @Override + public boolean apply(@Nullable PluginInfo input) { + return input != null && !input.isCore(); + } + } +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/InstalledPluginsWsAction.java b/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/InstalledPluginsWsAction.java deleted file mode 100644 index dc2f3ff4be7..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/InstalledPluginsWsAction.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * 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.plugins.ws; - -import com.google.common.base.Predicate; -import com.google.common.collect.ImmutableSortedSet; -import com.google.common.io.Resources; -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.core.platform.PluginInfo; -import org.sonar.server.plugins.ServerPluginRepository; - -import javax.annotation.Nullable; - -import java.util.Collection; -import java.util.SortedSet; - -import static com.google.common.collect.Iterables.filter; -import static org.sonar.server.plugins.ws.PluginWSCommons.NAME_KEY_PLUGIN_METADATA_COMPARATOR; - -/** - * Implementation of the {@code installed} action for the Plugins WebService. - */ -public class InstalledPluginsWsAction implements PluginsWsAction { - private static final String ARRAY_PLUGINS = "plugins"; - - private final ServerPluginRepository pluginRepository; - private final PluginWSCommons pluginWSCommons; - - public InstalledPluginsWsAction(ServerPluginRepository pluginRepository, - PluginWSCommons pluginWSCommons) { - this.pluginRepository = pluginRepository; - this.pluginWSCommons = pluginWSCommons; - } - - @Override - public void define(WebService.NewController controller) { - controller.createAction("installed") - .setDescription("Get the list of all the plugins installed on the SonarQube instance, sorted by plugin name") - .setSince("5.2") - .setHandler(this) - .setResponseExample(Resources.getResource(this.getClass(), "example-installed_plugins.json")); - } - - @Override - public void handle(Request request, Response response) throws Exception { - Collection infos = retrieveAndSortPluginMetadata(); - - JsonWriter jsonWriter = response.newJsonWriter(); - jsonWriter.setSerializeEmptys(false); - jsonWriter.beginObject(); - - writeMetadataList(jsonWriter, infos); - - jsonWriter.endObject(); - jsonWriter.close(); - } - - private SortedSet retrieveAndSortPluginMetadata() { - return ImmutableSortedSet.copyOf( - NAME_KEY_PLUGIN_METADATA_COMPARATOR, - filter(pluginRepository.getPluginInfos(), NotCorePluginsPredicate.INSTANCE) - ); - } - - private void writeMetadataList(JsonWriter jsonWriter, Collection pluginMetadatas) { - jsonWriter.name(ARRAY_PLUGINS); - jsonWriter.beginArray(); - for (PluginInfo pluginMetadata : pluginMetadatas) { - pluginWSCommons.writePluginMetadata(jsonWriter, pluginMetadata); - } - jsonWriter.endArray(); - } - - private enum NotCorePluginsPredicate implements Predicate { - INSTANCE; - - @Override - public boolean apply(@Nullable PluginInfo input) { - return input != null && !input.isCore(); - } - } -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/PendingAction.java b/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/PendingAction.java new file mode 100644 index 00000000000..86293e731d5 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/PendingAction.java @@ -0,0 +1,99 @@ +/* + * 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.plugins.ws; + +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.core.platform.PluginInfo; +import org.sonar.server.plugins.PluginDownloader; +import org.sonar.server.plugins.ServerPluginRepository; + +import java.util.Collection; + +import static com.google.common.collect.ImmutableSortedSet.copyOf; +import static com.google.common.io.Resources.getResource; +import static org.sonar.server.plugins.ws.PluginWSCommons.NAME_KEY_PLUGIN_METADATA_COMPARATOR; + +/** + * Implementation of the {@code pending} action for the Plugins WebService. + */ +public class PendingAction implements PluginsWsAction { + + private static final String ARRAY_INSTALLING = "installing"; + private static final String ARRAY_REMOVING = "removing"; + + private final PluginDownloader pluginDownloader; + private final ServerPluginRepository installer; + private final PluginWSCommons pluginWSCommons; + + public PendingAction(PluginDownloader pluginDownloader, + ServerPluginRepository installer, + PluginWSCommons pluginWSCommons) { + this.pluginDownloader = pluginDownloader; + this.installer = installer; + this.pluginWSCommons = pluginWSCommons; + } + + @Override + public void define(WebService.NewController controller) { + controller.createAction("pending") + .setDescription("Get the list of plugins which will either be installed or removed at the next startup of the SonarQube instance, sorted by plugin name") + .setSince("5.2") + .setHandler(this) + .setResponseExample(getResource(this.getClass(), "example-pending_plugins.json")); + } + + @Override + public void handle(Request request, Response response) throws Exception { + JsonWriter jsonWriter = response.newJsonWriter(); + + jsonWriter.beginObject(); + + writeInstalling(jsonWriter); + + writeRemoving(jsonWriter); + + jsonWriter.endObject(); + jsonWriter.close(); + } + + private void writeInstalling(JsonWriter jsonWriter) { + jsonWriter.name(ARRAY_INSTALLING); + jsonWriter.beginArray(); + Collection plugins = pluginDownloader.getDownloadedPlugins(); + for (PluginInfo pluginMetadata : copyOf(NAME_KEY_PLUGIN_METADATA_COMPARATOR, plugins)) { + pluginWSCommons.writePluginMetadata(jsonWriter, pluginMetadata); + } + jsonWriter.endArray(); + } + + private void writeRemoving(JsonWriter jsonWriter) { + jsonWriter.name(ARRAY_REMOVING); + jsonWriter.beginArray(); + Collection plugins = installer.getUninstalledPlugins(); + for (PluginInfo pluginMetadata : copyOf(NAME_KEY_PLUGIN_METADATA_COMPARATOR, plugins)) { + pluginWSCommons.writePluginMetadata(jsonWriter, pluginMetadata); + } + jsonWriter.endArray(); + } + +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/PendingPluginsWsAction.java b/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/PendingPluginsWsAction.java deleted file mode 100644 index 29eb3cc9b53..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/PendingPluginsWsAction.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * 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.plugins.ws; - -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.core.platform.PluginInfo; -import org.sonar.server.plugins.PluginDownloader; -import org.sonar.server.plugins.ServerPluginRepository; - -import java.util.Collection; - -import static com.google.common.collect.ImmutableSortedSet.copyOf; -import static com.google.common.io.Resources.getResource; -import static org.sonar.server.plugins.ws.PluginWSCommons.NAME_KEY_PLUGIN_METADATA_COMPARATOR; - -/** - * Implementation of the {@code pending} action for the Plugins WebService. - */ -public class PendingPluginsWsAction implements PluginsWsAction { - - private static final String ARRAY_INSTALLING = "installing"; - private static final String ARRAY_REMOVING = "removing"; - - private final PluginDownloader pluginDownloader; - private final ServerPluginRepository installer; - private final PluginWSCommons pluginWSCommons; - - public PendingPluginsWsAction(PluginDownloader pluginDownloader, - ServerPluginRepository installer, - PluginWSCommons pluginWSCommons) { - this.pluginDownloader = pluginDownloader; - this.installer = installer; - this.pluginWSCommons = pluginWSCommons; - } - - @Override - public void define(WebService.NewController controller) { - controller.createAction("pending") - .setDescription("Get the list of plugins which will either be installed or removed at the next startup of the SonarQube instance, sorted by plugin name") - .setSince("5.2") - .setHandler(this) - .setResponseExample(getResource(this.getClass(), "example-pending_plugins.json")); - } - - @Override - public void handle(Request request, Response response) throws Exception { - JsonWriter jsonWriter = response.newJsonWriter(); - - jsonWriter.beginObject(); - - writeInstalling(jsonWriter); - - writeRemoving(jsonWriter); - - jsonWriter.endObject(); - jsonWriter.close(); - } - - private void writeInstalling(JsonWriter jsonWriter) { - jsonWriter.name(ARRAY_INSTALLING); - jsonWriter.beginArray(); - Collection plugins = pluginDownloader.getDownloadedPlugins(); - for (PluginInfo pluginMetadata : copyOf(NAME_KEY_PLUGIN_METADATA_COMPARATOR, plugins)) { - pluginWSCommons.writePluginMetadata(jsonWriter, pluginMetadata); - } - jsonWriter.endArray(); - } - - private void writeRemoving(JsonWriter jsonWriter) { - jsonWriter.name(ARRAY_REMOVING); - jsonWriter.beginArray(); - Collection plugins = installer.getUninstalledPlugins(); - for (PluginInfo pluginMetadata : copyOf(NAME_KEY_PLUGIN_METADATA_COMPARATOR, plugins)) { - pluginWSCommons.writePluginMetadata(jsonWriter, pluginMetadata); - } - jsonWriter.endArray(); - } - -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/UninstallAction.java b/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/UninstallAction.java new file mode 100644 index 00000000000..5e465fc2a89 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/UninstallAction.java @@ -0,0 +1,74 @@ +/* + * 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.plugins.ws; + +import org.sonar.api.server.ws.Request; +import org.sonar.api.server.ws.Response; +import org.sonar.api.server.ws.WebService; +import org.sonar.core.permission.GlobalPermissions; +import org.sonar.server.plugins.ServerPluginRepository; +import org.sonar.server.user.UserSession; + +import static java.lang.String.format; + +/** + * Implementation of the {@code uninstall} action for the Plugins WebService. + */ +public class UninstallAction implements PluginsWsAction { + private static final String PARAM_KEY = "key"; + + private final ServerPluginRepository pluginRepository; + private final UserSession userSession; + + public UninstallAction(ServerPluginRepository pluginRepository, UserSession userSession) { + this.pluginRepository = pluginRepository; + this.userSession = userSession; + } + + @Override + public void define(WebService.NewController controller) { + WebService.NewAction action = controller.createAction("uninstall") + .setPost(true) + .setDescription("Uninstalls the plugin specified by its key." + + "
" + + "Requires user to be authenticated with Administer System permissions.") + .setHandler(this); + + action.createParam(PARAM_KEY) + .setDescription("The key identifying the plugin to uninstall") + .setRequired(true); + } + + @Override + public void handle(Request request, Response response) throws Exception { + userSession.checkGlobalPermission(GlobalPermissions.SYSTEM_ADMIN); + String key = request.mandatoryParam(PARAM_KEY); + ensurePluginIsInstalled(key); + pluginRepository.uninstall(key); + response.noContent(); + } + + // FIXME should be moved to ServerPluginRepository#uninstall(String) + private void ensurePluginIsInstalled(String key) { + if (!pluginRepository.hasPlugin(key)) { + throw new IllegalArgumentException(format("Plugin [%s] is not installed", key)); + } + } +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/UninstallPluginsWsAction.java b/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/UninstallPluginsWsAction.java deleted file mode 100644 index a4583e35b64..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/UninstallPluginsWsAction.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * 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.plugins.ws; - -import org.sonar.api.server.ws.Request; -import org.sonar.api.server.ws.Response; -import org.sonar.api.server.ws.WebService; -import org.sonar.core.permission.GlobalPermissions; -import org.sonar.server.plugins.ServerPluginRepository; -import org.sonar.server.user.UserSession; - -import static java.lang.String.format; - -/** - * Implementation of the {@code uninstall} action for the Plugins WebService. - */ -public class UninstallPluginsWsAction implements PluginsWsAction { - private static final String PARAM_KEY = "key"; - - private final ServerPluginRepository pluginRepository; - private final UserSession userSession; - - public UninstallPluginsWsAction(ServerPluginRepository pluginRepository, UserSession userSession) { - this.pluginRepository = pluginRepository; - this.userSession = userSession; - } - - @Override - public void define(WebService.NewController controller) { - WebService.NewAction action = controller.createAction("uninstall") - .setPost(true) - .setDescription("Uninstalls the plugin specified by its key." + - "
" + - "Requires user to be authenticated with Administer System permissions.") - .setHandler(this); - - action.createParam(PARAM_KEY) - .setDescription("The key identifying the plugin to uninstall") - .setRequired(true); - } - - @Override - public void handle(Request request, Response response) throws Exception { - userSession.checkGlobalPermission(GlobalPermissions.SYSTEM_ADMIN); - String key = request.mandatoryParam(PARAM_KEY); - ensurePluginIsInstalled(key); - pluginRepository.uninstall(key); - response.noContent(); - } - - // FIXME should be moved to ServerPluginRepository#uninstall(String) - private void ensurePluginIsInstalled(String key) { - if (!pluginRepository.hasPlugin(key)) { - throw new IllegalArgumentException(format("Plugin [%s] is not installed", key)); - } - } -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/UpdateAction.java b/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/UpdateAction.java new file mode 100644 index 00000000000..1a8a3bc78e5 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/UpdateAction.java @@ -0,0 +1,107 @@ +/* + * 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.plugins.ws; + +import com.google.common.base.Predicate; +import com.google.common.collect.Iterables; +import org.sonar.api.server.ws.Request; +import org.sonar.api.server.ws.Response; +import org.sonar.api.server.ws.WebService; +import org.sonar.core.permission.GlobalPermissions; +import org.sonar.server.plugins.PluginDownloader; +import org.sonar.server.plugins.UpdateCenterMatrixFactory; +import org.sonar.server.user.UserSession; +import org.sonar.updatecenter.common.PluginUpdate; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +import static java.lang.String.format; + +/** + * Implementation of the {@code update} action for the Plugins WebService. + */ +public class UpdateAction implements PluginsWsAction { + + public static final String PARAM_KEY = "key"; + public static final PluginUpdate MISSING_PLUGIN = null; + + private final UpdateCenterMatrixFactory updateCenterFactory; + private final PluginDownloader pluginDownloader; + private final UserSession userSession; + + public UpdateAction(UpdateCenterMatrixFactory updateCenterFactory, PluginDownloader pluginDownloader, UserSession userSession) { + this.updateCenterFactory = updateCenterFactory; + this.pluginDownloader = pluginDownloader; + this.userSession = userSession; + } + + @Override + public void define(WebService.NewController controller) { + WebService.NewAction action = controller.createAction("update") + .setPost(true) + .setDescription("Updates a plugin specified by its key to the latest version compatible with the SonarQube instance." + + "
" + + "Plugin information is retrieved from Update Center." + + "
" + + "Requires user to be authenticated with Administer System permissions") + .setHandler(this); + + action.createParam(PARAM_KEY) + .setRequired(true) + .setDescription("The key identifying the plugin to update"); + } + + @Override + public void handle(Request request, Response response) throws Exception { + userSession.checkGlobalPermission(GlobalPermissions.SYSTEM_ADMIN); + String key = request.mandatoryParam(PARAM_KEY); + PluginUpdate pluginUpdate = findPluginUpdateByKey(key); + pluginDownloader.download(key, pluginUpdate.getRelease().getVersion()); + response.noContent(); + } + + @Nonnull + private PluginUpdate findPluginUpdateByKey(String key) { + PluginUpdate pluginUpdate = Iterables.find( + updateCenterFactory.getUpdateCenter(false).findPluginUpdates(), + new PluginKeyPredicate(key), + MISSING_PLUGIN + ); + if (pluginUpdate == MISSING_PLUGIN) { + throw new IllegalArgumentException( + format("No plugin with key '%s' or plugin '%s' is already in latest compatible version", key, key)); + } + return pluginUpdate; + } + + private static class PluginKeyPredicate implements Predicate { + private final String key; + + public PluginKeyPredicate(String key) { + this.key = key; + } + + @Override + public boolean apply(@Nullable PluginUpdate input) { + return input != null && key.equals(input.getPlugin().getKey()); + } + } +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/UpdatePluginsWsAction.java b/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/UpdatePluginsWsAction.java deleted file mode 100644 index 37382736ed9..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/UpdatePluginsWsAction.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * 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.plugins.ws; - -import com.google.common.base.Predicate; -import com.google.common.collect.Iterables; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import org.sonar.api.server.ws.Request; -import org.sonar.api.server.ws.Response; -import org.sonar.api.server.ws.WebService; -import org.sonar.core.permission.GlobalPermissions; -import org.sonar.server.plugins.PluginDownloader; -import org.sonar.server.plugins.UpdateCenterMatrixFactory; -import org.sonar.server.user.UserSession; -import org.sonar.updatecenter.common.PluginUpdate; - -import static java.lang.String.format; - -/** - * Implementation of the {@code update} action for the Plugins WebService. - */ -public class UpdatePluginsWsAction implements PluginsWsAction { - - public static final String PARAM_KEY = "key"; - public static final PluginUpdate MISSING_PLUGIN = null; - - private final UpdateCenterMatrixFactory updateCenterFactory; - private final PluginDownloader pluginDownloader; - private final UserSession userSession; - - public UpdatePluginsWsAction(UpdateCenterMatrixFactory updateCenterFactory, PluginDownloader pluginDownloader, UserSession userSession) { - this.updateCenterFactory = updateCenterFactory; - this.pluginDownloader = pluginDownloader; - this.userSession = userSession; - } - - @Override - public void define(WebService.NewController controller) { - WebService.NewAction action = controller.createAction("update") - .setPost(true) - .setDescription("Updates a plugin specified by its key to the latest version compatible with the SonarQube instance." + - "
" + - "Plugin information is retrieved from Update Center." + - "
" + - "Requires user to be authenticated with Administer System permissions") - .setHandler(this); - - action.createParam(PARAM_KEY) - .setRequired(true) - .setDescription("The key identifying the plugin to update"); - } - - @Override - public void handle(Request request, Response response) throws Exception { - userSession.checkGlobalPermission(GlobalPermissions.SYSTEM_ADMIN); - String key = request.mandatoryParam(PARAM_KEY); - PluginUpdate pluginUpdate = findPluginUpdateByKey(key); - pluginDownloader.download(key, pluginUpdate.getRelease().getVersion()); - response.noContent(); - } - - @Nonnull - private PluginUpdate findPluginUpdateByKey(String key) { - PluginUpdate pluginUpdate = Iterables.find( - updateCenterFactory.getUpdateCenter(false).findPluginUpdates(), - new PluginKeyPredicate(key), - MISSING_PLUGIN - ); - if (pluginUpdate == MISSING_PLUGIN) { - throw new IllegalArgumentException( - format("No plugin with key '%s' or plugin '%s' is already in latest compatible version", key, key)); - } - return pluginUpdate; - } - - private static class PluginKeyPredicate implements Predicate { - private final String key; - - public PluginKeyPredicate(String key) { - this.key = key; - } - - @Override - public boolean apply(@Nullable PluginUpdate input) { - return input != null && key.equals(input.getPlugin().getKey()); - } - } -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/UpdatesAction.java b/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/UpdatesAction.java new file mode 100644 index 00000000000..1e6014366bd --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/UpdatesAction.java @@ -0,0 +1,148 @@ +/* + * 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.plugins.ws; + +import com.google.common.base.Function; +import com.google.common.collect.ImmutableSortedSet; +import com.google.common.collect.Ordering; +import com.google.common.io.Resources; +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.plugins.UpdateCenterMatrixFactory; +import org.sonar.server.plugins.ws.PluginUpdateAggregator.PluginUpdateAggregate; +import org.sonar.updatecenter.common.Plugin; +import org.sonar.updatecenter.common.PluginUpdate; +import org.sonar.updatecenter.common.UpdateCenter; + +import javax.annotation.Nonnull; +import java.util.Collection; +import java.util.List; + +/** + * Implementation of the {@code updates} action for the Plugins WebService. + */ +public class UpdatesAction implements PluginsWsAction { + + private static final boolean DO_NOT_FORCE_REFRESH = false; + private static final String ARRAY_PLUGINS = "plugins"; + private static final String ARRAY_UPDATES = "updates"; + + private static final Ordering NAME_KEY_PLUGIN_UPGRADE_AGGREGATE_ORDERING = + Ordering.from(PluginWSCommons.NAME_KEY_PLUGIN_ORDERING).onResultOf(PluginUpdateAggregateToPlugin.INSTANCE); + private static final Ordering PLUGIN_UPDATE_BY_VERSION_ORDERING = Ordering.natural().onResultOf(new Function() { + @Override + public String apply(@Nonnull PluginUpdate input) { + return input.getRelease().getVersion().toString(); + } + }); + + private final UpdateCenterMatrixFactory updateCenterMatrixFactory; + private final PluginWSCommons pluginWSCommons; + private final PluginUpdateAggregator aggregator; + + public UpdatesAction(UpdateCenterMatrixFactory updateCenterMatrixFactory, + PluginWSCommons pluginWSCommons, + PluginUpdateAggregator aggregator) { + this.updateCenterMatrixFactory = updateCenterMatrixFactory; + this.pluginWSCommons = pluginWSCommons; + this.aggregator = aggregator; + } + + @Override + public void define(WebService.NewController controller) { + controller.createAction("updates") + .setDescription("Lists plugins installed on the SonarQube instance for which at least one newer version is available, sorted by plugin name." + + "
" + + "Each newer version is listed, ordered from the oldest to the newest, with its own update/compatibility status." + + "
" + + "Plugin information is retrieved from Update Center. Date and time at which Update Center was last refreshed is provided in the response." + + "
" + + "Update status values are: [COMPATIBLE, INCOMPATIBLE, REQUIRES_UPGRADE, DEPS_REQUIRE_UPGRADE]") + .setSince("5.2") + .setHandler(this) + .setResponseExample(Resources.getResource(this.getClass(), "example-updates_plugins.json")); + } + + @Override + public void handle(Request request, Response response) throws Exception { + JsonWriter jsonWriter = response.newJsonWriter(); + jsonWriter.beginObject(); + + UpdateCenter updateCenter = updateCenterMatrixFactory.getUpdateCenter(DO_NOT_FORCE_REFRESH); + + writePlugins(jsonWriter, updateCenter); + + pluginWSCommons.writeUpdateCenterProperties(jsonWriter, updateCenter); + + jsonWriter.endObject(); + jsonWriter.close(); + } + + private void writePlugins(JsonWriter jsonWriter, UpdateCenter updateCenter) { + jsonWriter.name(ARRAY_PLUGINS); + jsonWriter.beginArray(); + for (PluginUpdateAggregate aggregate : retrieveUpdatablePlugins(updateCenter)) { + writePluginUpdateAggregate(jsonWriter, aggregate); + } + jsonWriter.endArray(); + } + + private void writePluginUpdateAggregate(JsonWriter jsonWriter, PluginUpdateAggregate aggregate) { + jsonWriter.beginObject(); + Plugin plugin = aggregate.getPlugin(); + + pluginWSCommons.writeMetadata(jsonWriter, plugin); + + writeUpdates(jsonWriter, aggregate.getUpdates()); + + jsonWriter.endObject(); + } + + private void writeUpdates(JsonWriter jsonWriter, Collection pluginUpdates) { + jsonWriter.name(ARRAY_UPDATES).beginArray(); + for (PluginUpdate pluginUpdate : ImmutableSortedSet.copyOf(PLUGIN_UPDATE_BY_VERSION_ORDERING, pluginUpdates)) { + jsonWriter.beginObject(); + pluginWSCommons.writeRelease(jsonWriter, pluginUpdate.getRelease()); + pluginWSCommons.writeUpdateProperties(jsonWriter, pluginUpdate); + jsonWriter.endObject(); + } + jsonWriter.endArray(); + } + + private Collection retrieveUpdatablePlugins(UpdateCenter updateCenter) { + List pluginUpdates = updateCenter.findPluginUpdates(); + // aggregates updates of the same plugin to a single object and sort these objects by plugin name then key + return ImmutableSortedSet.copyOf( + NAME_KEY_PLUGIN_UPGRADE_AGGREGATE_ORDERING, + aggregator.aggregate(pluginUpdates) + ); + } + + private enum PluginUpdateAggregateToPlugin implements Function { + INSTANCE; + + @Override + public Plugin apply(@Nonnull PluginUpdateAggregate input) { + return input.getPlugin(); + } + } +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/UpdatesPluginsWsAction.java b/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/UpdatesPluginsWsAction.java deleted file mode 100644 index 0aedfd319fe..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/UpdatesPluginsWsAction.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * 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.plugins.ws; - -import java.util.Collection; -import java.util.List; - -import javax.annotation.Nonnull; - -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.plugins.UpdateCenterMatrixFactory; -import org.sonar.server.plugins.ws.PluginUpdateAggregator.PluginUpdateAggregate; -import org.sonar.updatecenter.common.Plugin; -import org.sonar.updatecenter.common.PluginUpdate; -import org.sonar.updatecenter.common.UpdateCenter; - -import com.google.common.base.Function; -import com.google.common.collect.ImmutableSortedSet; -import com.google.common.collect.Ordering; -import com.google.common.io.Resources; - -/** - * Implementation of the {@code updates} action for the Plugins WebService. - */ -public class UpdatesPluginsWsAction implements PluginsWsAction { - - private static final boolean DO_NOT_FORCE_REFRESH = false; - private static final String ARRAY_PLUGINS = "plugins"; - private static final String ARRAY_UPDATES = "updates"; - - private static final Ordering NAME_KEY_PLUGIN_UPGRADE_AGGREGATE_ORDERING = - Ordering.from(PluginWSCommons.NAME_KEY_PLUGIN_ORDERING).onResultOf(PluginUpdateAggregateToPlugin.INSTANCE); - private static final Ordering PLUGIN_UPDATE_BY_VERSION_ORDERING = Ordering.natural().onResultOf(new Function() { - @Override - public String apply(@Nonnull PluginUpdate input) { - return input.getRelease().getVersion().toString(); - } - }); - - private final UpdateCenterMatrixFactory updateCenterMatrixFactory; - private final PluginWSCommons pluginWSCommons; - private final PluginUpdateAggregator aggregator; - - public UpdatesPluginsWsAction(UpdateCenterMatrixFactory updateCenterMatrixFactory, - PluginWSCommons pluginWSCommons, - PluginUpdateAggregator aggregator) { - this.updateCenterMatrixFactory = updateCenterMatrixFactory; - this.pluginWSCommons = pluginWSCommons; - this.aggregator = aggregator; - } - - @Override - public void define(WebService.NewController controller) { - controller.createAction("updates") - .setDescription("Lists plugins installed on the SonarQube instance for which at least one newer version is available, sorted by plugin name." + - "
" + - "Each newer version is listed, ordered from the oldest to the newest, with its own update/compatibility status." + - "
" + - "Plugin information is retrieved from Update Center. Date and time at which Update Center was last refreshed is provided in the response." + - "
" + - "Update status values are: [COMPATIBLE, INCOMPATIBLE, REQUIRES_UPGRADE, DEPS_REQUIRE_UPGRADE]") - .setSince("5.2") - .setHandler(this) - .setResponseExample(Resources.getResource(this.getClass(), "example-updates_plugins.json")); - } - - @Override - public void handle(Request request, Response response) throws Exception { - JsonWriter jsonWriter = response.newJsonWriter(); - jsonWriter.beginObject(); - - UpdateCenter updateCenter = updateCenterMatrixFactory.getUpdateCenter(DO_NOT_FORCE_REFRESH); - - writePlugins(jsonWriter, updateCenter); - - pluginWSCommons.writeUpdateCenterProperties(jsonWriter, updateCenter); - - jsonWriter.endObject(); - jsonWriter.close(); - } - - private void writePlugins(JsonWriter jsonWriter, UpdateCenter updateCenter) { - jsonWriter.name(ARRAY_PLUGINS); - jsonWriter.beginArray(); - for (PluginUpdateAggregate aggregate : retrieveUpdatablePlugins(updateCenter)) { - writePluginUpdateAggregate(jsonWriter, aggregate); - } - jsonWriter.endArray(); - } - - private void writePluginUpdateAggregate(JsonWriter jsonWriter, PluginUpdateAggregate aggregate) { - jsonWriter.beginObject(); - Plugin plugin = aggregate.getPlugin(); - - pluginWSCommons.writeMetadata(jsonWriter, plugin); - - writeUpdates(jsonWriter, aggregate.getUpdates()); - - jsonWriter.endObject(); - } - - private void writeUpdates(JsonWriter jsonWriter, Collection pluginUpdates) { - jsonWriter.name(ARRAY_UPDATES).beginArray(); - for (PluginUpdate pluginUpdate : ImmutableSortedSet.copyOf(PLUGIN_UPDATE_BY_VERSION_ORDERING, pluginUpdates)) { - jsonWriter.beginObject(); - pluginWSCommons.writeRelease(jsonWriter, pluginUpdate.getRelease()); - pluginWSCommons.writeUpdateProperties(jsonWriter, pluginUpdate); - jsonWriter.endObject(); - } - jsonWriter.endArray(); - } - - private Collection retrieveUpdatablePlugins(UpdateCenter updateCenter) { - List pluginUpdates = updateCenter.findPluginUpdates(); - // aggregates updates of the same plugin to a single object and sort these objects by plugin name then key - return ImmutableSortedSet.copyOf( - NAME_KEY_PLUGIN_UPGRADE_AGGREGATE_ORDERING, - aggregator.aggregate(pluginUpdates) - ); - } - - private enum PluginUpdateAggregateToPlugin implements Function { - INSTANCE; - - @Override - public Plugin apply(@Nonnull PluginUpdateAggregate input) { - return input.getPlugin(); - } - } -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/project/ws/DeleteAction.java b/server/sonar-server/src/main/java/org/sonar/server/project/ws/DeleteAction.java new file mode 100644 index 00000000000..9596c367d5b --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/project/ws/DeleteAction.java @@ -0,0 +1,99 @@ +/* + * 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.project.ws; + +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.web.UserRole; +import org.sonar.core.component.ComponentDto; +import org.sonar.core.persistence.DbSession; +import org.sonar.core.persistence.MyBatis; +import org.sonar.server.component.ComponentCleanerService; +import org.sonar.server.db.DbClient; +import org.sonar.server.user.UserSession; + +import javax.annotation.Nullable; + +import java.util.List; + +public class DeleteAction implements ProjectsWsAction { + private static final String ACTION = "delete"; + private static final String PARAM_UUIDS = "uuids"; + private static final String PARAM_KEYS = "keys"; + + private final ComponentCleanerService componentCleanerService; + private final DbClient dbClient; + private final UserSession userSession; + + public DeleteAction(ComponentCleanerService componentCleanerService, DbClient dbClient, UserSession userSession) { + this.componentCleanerService = componentCleanerService; + this.dbClient = dbClient; + this.userSession = userSession; + } + + @Override + public void define(WebService.NewController context) { + WebService.NewAction action = context + .createAction(ACTION) + .setDescription("Delete one or several projects.
Requires Admin permission.") + .setSince("5.2") + .setHandler(this); + + action + .createParam(PARAM_UUIDS) + .setDescription("List of project UUIDs to delete") + .setExampleValue("ce4c03d6-430f-40a9-b777-ad877c00aa4d,c526ef20-131b-4486-9357-063fa64b5079"); + + action + .createParam(PARAM_KEYS) + .setDescription("List of project keys to delete") + .setExampleValue("org.apache.hbas:hbase,com.microsoft.roslyn:roslyn"); + } + + @Override + public void handle(Request request, Response response) throws Exception { + userSession.checkGlobalPermission(UserRole.ADMIN); + List uuids = request.paramAsStrings(PARAM_UUIDS); + List keys = request.paramAsStrings(PARAM_KEYS); + + DbSession dbSession = dbClient.openSession(false); + try { + List projects = searchProjects(dbSession, uuids, keys); + componentCleanerService.delete(dbSession, projects); + } finally { + MyBatis.closeQuietly(dbSession); + } + + response.noContent(); + } + + private List searchProjects(DbSession dbSession, @Nullable List uuids, @Nullable List keys) { + if (uuids != null) { + return dbClient.componentDao().selectByUuids(dbSession, uuids); + } + if (keys != null) { + return dbClient.componentDao().selectByKeys(dbSession, keys); + } + + throw new IllegalArgumentException("UUIDs or keys must be provided"); + } +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/project/ws/GhostsAction.java b/server/sonar-server/src/main/java/org/sonar/server/project/ws/GhostsAction.java new file mode 100644 index 00000000000..b80814de3d4 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/project/ws/GhostsAction.java @@ -0,0 +1,125 @@ +/* + * 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.project.ws; + +import com.google.common.io.Resources; +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.server.ws.WebService.Param; +import org.sonar.api.utils.text.JsonWriter; +import org.sonar.api.web.UserRole; +import org.sonar.core.component.ComponentDto; +import org.sonar.core.persistence.DbSession; +import org.sonar.core.persistence.MyBatis; +import org.sonar.server.db.DbClient; +import org.sonar.server.es.SearchOptions; +import org.sonar.server.user.UserSession; + +import javax.annotation.Nullable; + +import java.util.Date; +import java.util.List; +import java.util.Set; + +import static com.google.common.collect.Sets.newHashSet; + +public class GhostsAction implements ProjectsWsAction { + public static final String ACTION = "ghosts"; + private static final Set POSSIBLE_FIELDS = newHashSet("uuid", "key", "name", "creationDate"); + + private final DbClient dbClient; + private final UserSession userSession; + + public GhostsAction(DbClient dbClient, UserSession userSession) { + this.dbClient = dbClient; + this.userSession = userSession; + } + + @Override + public void define(WebService.NewController context) { + context + .createAction(ACTION) + .setDescription("List ghost projects.
Requires 'Administer System' permission.") + .setResponseExample(Resources.getResource(getClass(), "projects-example-ghosts.json")) + .setSince("5.2") + .addPagingParams(100) + .addFieldsParam(POSSIBLE_FIELDS) + .addSearchQuery("sonar", "names", "keys") + .setHandler(this); + } + + @Override + public void handle(Request request, Response response) throws Exception { + userSession.checkGlobalPermission(UserRole.ADMIN); + DbSession dbSession = dbClient.openSession(false); + SearchOptions searchOptions = new SearchOptions() + .setPage(request.mandatoryParamAsInt(Param.PAGE), + request.mandatoryParamAsInt(Param.PAGE_SIZE)); + Set desiredFields = fieldsToReturn(request.paramAsStrings(Param.FIELDS)); + String query = request.param(Param.TEXT_QUERY); + + try { + long nbOfProjects = dbClient.componentDao().countGhostProjects(dbSession, query); + List projects = dbClient.componentDao().selectGhostProjects(dbSession, query, searchOptions); + JsonWriter json = response.newJsonWriter().beginObject(); + writeProjects(json, projects, desiredFields); + searchOptions.writeJson(json, nbOfProjects); + json.endObject().close(); + } finally { + MyBatis.closeQuietly(dbSession); + } + } + + private void writeProjects(JsonWriter json, List projects, Set fieldsToReturn) { + json.name("projects"); + json.beginArray(); + for (ComponentDto project : projects) { + json.beginObject(); + json.prop("uuid", project.uuid()); + writeIfWished(json, "key", project.key(), fieldsToReturn); + writeIfWished(json, "name", project.name(), fieldsToReturn); + writeIfWished(json, "creationDate", project.getCreatedAt(), fieldsToReturn); + json.endObject(); + } + json.endArray(); + } + + private void writeIfWished(JsonWriter json, String key, String value, Set fieldsToReturn) { + if (fieldsToReturn.contains(key)) { + json.prop(key, value); + } + } + + private void writeIfWished(JsonWriter json, String key, Date value, Set desiredFields) { + if (desiredFields.contains(key)) { + json.propDateTime(key, value); + } + } + + private Set fieldsToReturn(@Nullable List desiredFieldsFromRequest) { + if (desiredFieldsFromRequest == null) { + return POSSIBLE_FIELDS; + } + + return newHashSet(desiredFieldsFromRequest); + } +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/project/ws/ProjectsWs.java b/server/sonar-server/src/main/java/org/sonar/server/project/ws/ProjectsWs.java new file mode 100644 index 00000000000..8c70d269a6b --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/project/ws/ProjectsWs.java @@ -0,0 +1,135 @@ +/* + * 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.project.ws; + +import com.google.common.io.Resources; +import org.sonar.api.server.ws.RailsHandler; +import org.sonar.api.server.ws.WebService; + +public class ProjectsWs implements WebService { + private static final String ENDPOINT = "api/projects"; + + private final ProjectsWsAction[] actions; + + public ProjectsWs(ProjectsWsAction... actions) { + this.actions = actions; + } + + @Override + public void define(Context context) { + NewController controller = context.createController(ENDPOINT) + .setSince("2.10") + .setDescription("Projects management"); + + defineIndexAction(controller); + defineCreateAction(controller); + defineDestroyAction(controller); + + for (ProjectsWsAction action : actions) { + action.define(controller); + } + + controller.done(); + } + + private void defineIndexAction(NewController controller) { + WebService.NewAction action = controller.createAction("index") + .setDescription("Search for projects") + .setSince("2.10") + .setHandler(RailsHandler.INSTANCE) + .setResponseExample(Resources.getResource(this.getClass(), "projects-example-index.json")); + + action.createParam("key") + .setDescription("id or key of the project") + .setExampleValue("org.codehaus.sonar:sonar"); + + action.createParam("search") + .setDescription("Substring of project name, case insensitive") + .setExampleValue("Sonar"); + + action.createParam("desc") + .setDescription("Load project description") + .setDefaultValue("true") + .setPossibleValues("true", "false"); + + action.createParam("subprojects") + .setDescription("Load sub-projects. Ignored if the parameter key is set") + .setDefaultValue("false") + .setPossibleValues("true", "false"); + + action.createParam("views") + .setDescription("Load views and sub-views. Ignored if the parameter key is set") + .setDefaultValue("false") + .setPossibleValues("true", "false"); + + action.createParam("libs") + .setDescription("Load libraries. Ignored if the parameter key is set") + .setDefaultValue("false") + .setPossibleValues("true", "false"); + + action.createParam("versions") + .setDescription("Load version") + .setDefaultValue("false") + .setPossibleValues("true", "false", "last"); + + RailsHandler.addFormatParam(action); + } + + private void defineCreateAction(NewController controller) { + WebService.NewAction action = controller.createAction("create") + .setDescription("Provision a project. Requires Provision Projects permission") + .setSince("4.0") + .setPost(true) + .setHandler(RailsHandler.INSTANCE) + .setResponseExample(Resources.getResource(this.getClass(), "projects-example-create.json")); + + action.createParam("key") + .setDescription("Key of the project") + .setRequired(true) + .setExampleValue("org.codehaus.sonar:sonar"); + + action.createParam("name") + .setDescription("Name of the project") + .setRequired(true) + .setExampleValue("SonarQube"); + + action.createParam("branch") + .setDescription("SCM Branch of the project. The key of the project will become key:branch, for instance 'SonarQube:branch-5.0'") + .setRequired(false) + .setExampleValue("branch-5.0"); + + RailsHandler.addFormatParam(action); + } + + private void defineDestroyAction(NewController controller) { + WebService.NewAction action = controller.createAction("destroy") + .setDescription("Delete a project. Requires Administer System permission") + .setSince("2.11") + .setPost(true) + .setHandler(RailsHandler.INSTANCE); + + action.createParam("id") + .setDescription("id or key of the resource (ie: component)") + .setRequired(true) + .setExampleValue("org.codehaus.sonar:sonar"); + } + +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/project/ws/ProjectsWsAction.java b/server/sonar-server/src/main/java/org/sonar/server/project/ws/ProjectsWsAction.java new file mode 100644 index 00000000000..5792d51ddaf --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/project/ws/ProjectsWsAction.java @@ -0,0 +1,27 @@ +/* + * 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.project.ws; + +import org.sonar.server.ws.WsAction; + +public interface ProjectsWsAction extends WsAction { + // marker interface +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/project/ws/ProvisionedAction.java b/server/sonar-server/src/main/java/org/sonar/server/project/ws/ProvisionedAction.java new file mode 100644 index 00000000000..8825707c1fc --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/project/ws/ProvisionedAction.java @@ -0,0 +1,126 @@ +/* + * 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.project.ws; + +import com.google.common.io.Resources; +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.server.ws.WebService.Param; +import org.sonar.api.utils.text.JsonWriter; +import org.sonar.core.component.ComponentDto; +import org.sonar.core.permission.GlobalPermissions; +import org.sonar.core.persistence.DbSession; +import org.sonar.core.persistence.MyBatis; +import org.sonar.server.db.DbClient; +import org.sonar.server.es.SearchOptions; +import org.sonar.server.user.UserSession; + +import java.util.Date; +import java.util.List; +import java.util.Set; + +import static com.google.common.collect.Sets.newHashSet; + +public class ProvisionedAction implements ProjectsWsAction { + private static final Set POSSIBLE_FIELDS = newHashSet("uuid", "key", "name", "creationDate"); + + private final DbClient dbClient; + private final UserSession userSession; + + public ProvisionedAction(DbClient dbClient, UserSession userSession) { + this.dbClient = dbClient; + this.userSession = userSession; + } + + @Override + public void define(WebService.NewController controller) { + controller + .createAction("provisioned") + .setDescription( + "Get the list of provisioned projects.
" + + "Require 'Provision Projects' permission.") + .setSince("5.2") + .setResponseExample(Resources.getResource(getClass(), "projects-example-provisioned.json")) + .setHandler(this) + .addPagingParams(100) + .addSearchQuery("sonar", "names", "keys") + .addFieldsParam(POSSIBLE_FIELDS); + } + + @Override + public void handle(Request request, Response response) throws Exception { + userSession.checkGlobalPermission(GlobalPermissions.PROVISIONING); + SearchOptions options = new SearchOptions().setPage( + request.mandatoryParamAsInt(Param.PAGE), + request.mandatoryParamAsInt(Param.PAGE_SIZE) + ); + Set desiredFields = desiredFields(request); + String query = request.param(Param.TEXT_QUERY); + + DbSession dbSession = dbClient.openSession(false); + try { + List projects = dbClient.componentDao().selectProvisionedProjects(dbSession, options, query); + int nbOfProjects = dbClient.componentDao().countProvisionedProjects(dbSession, query); + JsonWriter json = response.newJsonWriter().beginObject(); + writeProjects(projects, json, desiredFields); + options.writeJson(json, nbOfProjects); + json.endObject().close(); + } finally { + MyBatis.closeQuietly(dbSession); + } + } + + private void writeProjects(List projects, JsonWriter json, Set desiredFields) { + json.name("projects"); + json.beginArray(); + for (ComponentDto project : projects) { + json.beginObject(); + json.prop("uuid", project.uuid()); + writeIfNeeded(json, "key", project.key(), desiredFields); + writeIfNeeded(json, "name", project.name(), desiredFields); + writeIfNeeded(json, "creationDate", project.getCreatedAt(), desiredFields); + json.endObject(); + } + json.endArray(); + } + + private void writeIfNeeded(JsonWriter json, String fieldName, String value, Set desiredFields) { + if (desiredFields.contains(fieldName)) { + json.prop(fieldName, value); + } + } + + private void writeIfNeeded(JsonWriter json, String fieldName, Date date, Set desiredFields) { + if (desiredFields.contains(fieldName)) { + json.propDateTime(fieldName, date); + } + } + + private Set desiredFields(Request request) { + List desiredFields = request.paramAsStrings(Param.FIELDS); + if (desiredFields == null) { + return POSSIBLE_FIELDS; + } + + return newHashSet(desiredFields); + } +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/project/ws/package-info.java b/server/sonar-server/src/main/java/org/sonar/server/project/ws/package-info.java new file mode 100644 index 00000000000..b02c9e3b15a --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/project/ws/package-info.java @@ -0,0 +1,24 @@ +/* + * 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. + */ + +@ParametersAreNonnullByDefault +package org.sonar.server.project.ws; + +import javax.annotation.ParametersAreNonnullByDefault; diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/AppAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/AppAction.java new file mode 100644 index 00000000000..a0e0c409003 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/AppAction.java @@ -0,0 +1,101 @@ +/* + * 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.qualitygate.ws; + +import org.apache.commons.lang.BooleanUtils; +import org.sonar.api.i18n.I18n; +import org.sonar.api.measures.Metric; +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.core.timemachine.Periods; +import org.sonar.server.qualitygate.QualityGates; + +import java.util.Locale; + +public class AppAction implements QGateWsAction { + + private final QualityGates qualityGates; + + private final Periods periods; + + private final I18n i18n; + + public AppAction(QualityGates qualityGates, Periods periods, I18n i18n) { + this.qualityGates = qualityGates; + this.periods = periods; + this.i18n = i18n; + } + + @Override + public void define(WebService.NewController controller) { + controller.createAction("app") + .setInternal(true) + .setDescription("Get initialization items for the admin UI. For internal use") + .setSince("4.3") + .setHandler(this); + } + + @Override + public void handle(Request request, Response response) { + JsonWriter writer = response.newJsonWriter().beginObject(); + addPermissions(writer); + addPeriods(writer); + addMetrics(writer); + writer.endObject().close(); + } + + private void addPermissions(JsonWriter writer) { + writer.prop("edit", qualityGates.currentUserHasWritePermission()); + } + + private void addPeriods(JsonWriter writer) { + writer.name("periods").beginArray(); + for (int i = 0; i < 3; i++) { + writer.beginObject().prop("key", (long) i + 1).prop("text", periods.label(i + 1)).endObject(); + } + addProjectPeriod(4, writer); + addProjectPeriod(5, writer); + writer.endArray(); + } + + private void addProjectPeriod(int periodIndex, JsonWriter writer) { + writer.beginObject().prop("key", periodIndex).prop("text", + i18n.message(Locale.getDefault(), "quality_gates.project_period", "Period " + periodIndex, periodIndex) + ).endObject(); + } + + private void addMetrics(JsonWriter writer) { + writer.name("metrics").beginArray(); + for (Metric metric : qualityGates.gateMetrics()) { + writer.beginObject() + .prop("id", metric.getId()) + .prop("key", metric.getKey()) + .prop("name", metric.getName()) + .prop("type", metric.getType().toString()) + .prop("domain", metric.getDomain()) + .prop("hidden", BooleanUtils.isNotFalse(metric.isHidden())) + .endObject(); + } + writer.endArray(); + } + +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/CopyAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/CopyAction.java new file mode 100644 index 00000000000..8c930728782 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/CopyAction.java @@ -0,0 +1,64 @@ +/* + * 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.qualitygate.ws; + +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.core.qualitygate.db.QualityGateDto; +import org.sonar.server.qualitygate.QualityGates; + +public class CopyAction implements QGateWsAction { + + private final QualityGates qualityGates; + + public CopyAction(QualityGates qualityGates) { + this.qualityGates = qualityGates; + } + + @Override + public void define(WebService.NewController controller) { + WebService.NewAction action = controller.createAction("copy") + .setDescription("Copy a Quality Gate. Require Administer Quality Profiles and Gates permission") + .setPost(true) + .setSince("4.3") + .setHandler(this); + + action.createParam(QGatesWs.PARAM_ID) + .setDescription("The ID of the source quality gate") + .setRequired(true) + .setExampleValue("1"); + + action.createParam(QGatesWs.PARAM_NAME) + .setDescription("The name of the quality gate to create") + .setRequired(true) + .setExampleValue("My Quality Gate"); + } + + @Override + public void handle(Request request, Response response) { + QualityGateDto newQualityGate = qualityGates.copy(QGatesWs.parseId(request, QGatesWs.PARAM_ID), request.mandatoryParam(QGatesWs.PARAM_NAME)); + JsonWriter writer = response.newJsonWriter(); + QGatesWs.writeQualityGate(newQualityGate, writer).close(); + } + +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/CreateAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/CreateAction.java new file mode 100644 index 00000000000..d83aae3fc5f --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/CreateAction.java @@ -0,0 +1,59 @@ +/* + * 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.qualitygate.ws; + +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.core.qualitygate.db.QualityGateDto; +import org.sonar.server.qualitygate.QualityGates; + +public class CreateAction implements QGateWsAction { + + private final QualityGates qualityGates; + + public CreateAction(QualityGates qualityGates) { + this.qualityGates = qualityGates; + } + + @Override + public void define(WebService.NewController controller) { + WebService.NewAction action = controller.createAction("create") + .setDescription("Create a Quality Gate. Require Administer Quality Profiles and Gates permission") + .setSince("4.3") + .setPost(true) + .setHandler(this); + + action.createParam(QGatesWs.PARAM_NAME) + .setDescription("The name of the quality gate to create") + .setRequired(true) + .setExampleValue("My Quality Gate"); + } + + @Override + public void handle(Request request, Response response) { + QualityGateDto newQualityGate = qualityGates.create(request.mandatoryParam(QGatesWs.PARAM_NAME)); + JsonWriter writer = response.newJsonWriter(); + QGatesWs.writeQualityGate(newQualityGate, writer).close(); + } + +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/CreateConditionAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/CreateConditionAction.java new file mode 100644 index 00000000000..69a796d3d2a --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/CreateConditionAction.java @@ -0,0 +1,67 @@ +/* + * 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.qualitygate.ws; + +import org.sonar.api.server.ws.Request; +import org.sonar.api.server.ws.Response; +import org.sonar.api.server.ws.WebService; +import org.sonar.server.qualitygate.QualityGates; + +public class CreateConditionAction implements QGateWsAction { + + private final QualityGates qualityGates; + + public CreateConditionAction(QualityGates qualityGates) { + this.qualityGates = qualityGates; + } + + @Override + public void define(WebService.NewController controller) { + WebService.NewAction createCondition = controller.createAction("create_condition") + .setDescription("Add a new condition to a quality gate. Require Administer Quality Profiles and Gates permission") + .setPost(true) + .setSince("4.3") + .setHandler(this); + + createCondition + .createParam(QGatesWs.PARAM_GATE_ID) + .setDescription("ID of the quality gate") + .setRequired(true) + .setExampleValue("1"); + + QGatesWs.addConditionParams(createCondition); + } + + @Override + public void handle(Request request, Response response) { + QGatesWs.writeQualityGateCondition( + qualityGates.createCondition( + QGatesWs.parseId(request, QGatesWs.PARAM_GATE_ID), + request.mandatoryParam(QGatesWs.PARAM_METRIC), + request.mandatoryParam(QGatesWs.PARAM_OPERATOR), + request.param(QGatesWs.PARAM_WARNING), + request.param(QGatesWs.PARAM_ERROR), + request.paramAsInt(QGatesWs.PARAM_PERIOD) + ), response.newJsonWriter() + ).close(); + } + +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/DeleteConditionAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/DeleteConditionAction.java new file mode 100644 index 00000000000..f7d1d075af5 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/DeleteConditionAction.java @@ -0,0 +1,57 @@ +/* + * 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.qualitygate.ws; + +import org.sonar.api.server.ws.Request; +import org.sonar.api.server.ws.Response; +import org.sonar.api.server.ws.WebService; +import org.sonar.server.qualitygate.QualityGates; + +public class DeleteConditionAction implements QGateWsAction { + + private final QualityGates qualityGates; + + public DeleteConditionAction(QualityGates qualityGates) { + this.qualityGates = qualityGates; + } + + @Override + public void define(WebService.NewController controller) { + WebService.NewAction createCondition = controller.createAction("delete_condition") + .setDescription("Delete a condition from a quality gate. Require Administer Quality Profiles and Gates permission") + .setPost(true) + .setSince("4.3") + .setHandler(this); + + createCondition + .createParam(QGatesWs.PARAM_ID) + .setRequired(true) + .setDescription("Condition ID") + .setExampleValue("2"); + } + + @Override + public void handle(Request request, Response response) { + qualityGates.deleteCondition(QGatesWs.parseId(request, QGatesWs.PARAM_ID)); + response.noContent(); + } + +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/DeselectAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/DeselectAction.java new file mode 100644 index 00000000000..941efa19ffc --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/DeselectAction.java @@ -0,0 +1,61 @@ +/* + * 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.qualitygate.ws; + +import org.sonar.api.server.ws.Request; +import org.sonar.api.server.ws.Response; +import org.sonar.api.server.ws.WebService; +import org.sonar.server.qualitygate.QualityGates; + +public class DeselectAction implements QGateWsAction { + + private final QualityGates qualityGates; + + public DeselectAction(QualityGates qualityGates) { + this.qualityGates = qualityGates; + } + + @Override + public void define(WebService.NewController controller) { + WebService.NewAction action = controller.createAction("deselect") + .setDescription("Remove the association of a project from a quality gate. Require Administer Quality Profiles and Gates permission") + .setPost(true) + .setSince("4.3") + .setHandler(this); + + action.createParam(QGatesWs.PARAM_GATE_ID) + .setDescription("Quality Gate ID") + .setRequired(true) + .setExampleValue("1"); + + action.createParam(QGatesWs.PARAM_PROJECT_ID) + .setDescription("Project ID") + .setRequired(true) + .setExampleValue("12"); + } + + @Override + public void handle(Request request, Response response) { + qualityGates.dissociateProject(QGatesWs.parseId(request, QGatesWs.PARAM_GATE_ID), QGatesWs.parseId(request, QGatesWs.PARAM_PROJECT_ID)); + response.noContent(); + } + +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/DestroyAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/DestroyAction.java new file mode 100644 index 00000000000..85b706c0df9 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/DestroyAction.java @@ -0,0 +1,56 @@ +/* + * 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.qualitygate.ws; + +import org.sonar.api.server.ws.Request; +import org.sonar.api.server.ws.Response; +import org.sonar.api.server.ws.WebService; +import org.sonar.server.qualitygate.QualityGates; + +public class DestroyAction implements QGateWsAction { + + private final QualityGates qualityGates; + + public DestroyAction(QualityGates qualityGates) { + this.qualityGates = qualityGates; + } + + @Override + public void define(WebService.NewController controller) { + WebService.NewAction action = controller.createAction("destroy") + .setDescription("Delete a Quality Gate. Require Administer Quality Profiles and Gates permission") + .setSince("4.3") + .setPost(true) + .setHandler(this); + + action.createParam(QGatesWs.PARAM_ID) + .setDescription("ID of the quality gate to delete") + .setRequired(true) + .setExampleValue("1"); + } + + @Override + public void handle(Request request, Response response) { + qualityGates.delete(QGatesWs.parseId(request, QGatesWs.PARAM_ID)); + response.noContent(); + } + +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/ListAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/ListAction.java new file mode 100644 index 00000000000..a18562154b7 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/ListAction.java @@ -0,0 +1,62 @@ +/* + * 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.qualitygate.ws; + +import com.google.common.io.Resources; +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.core.qualitygate.db.QualityGateDto; +import org.sonar.server.qualitygate.QualityGates; + +public class ListAction implements QGateWsAction { + + private final QualityGates qualityGates; + + public ListAction(QualityGates qualityGates) { + this.qualityGates = qualityGates; + } + + @Override + public void define(WebService.NewController controller) { + controller.createAction("list") + .setDescription("Get a list of quality gates") + .setSince("4.3") + .setResponseExample(Resources.getResource(this.getClass(), "example-list.json")) + .setHandler(this); + } + + @Override + public void handle(Request request, Response response) { + JsonWriter writer = response.newJsonWriter().beginObject().name("qualitygates").beginArray(); + for (QualityGateDto qgate : qualityGates.list()) { + QGatesWs.writeQualityGate(qgate, writer); + } + writer.endArray(); + QualityGateDto defaultQgate = qualityGates.getDefault(); + if (defaultQgate != null) { + writer.prop("default", defaultQgate.getId()); + } + writer.endObject().close(); + } + +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesAppAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesAppAction.java deleted file mode 100644 index 1996e96462a..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesAppAction.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * 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.qualitygate.ws; - -import org.apache.commons.lang.BooleanUtils; -import org.sonar.api.i18n.I18n; -import org.sonar.api.measures.Metric; -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.core.timemachine.Periods; -import org.sonar.server.qualitygate.QualityGates; - -import java.util.Locale; - -public class QGatesAppAction implements QGateWsAction { - - private final QualityGates qualityGates; - - private final Periods periods; - - private final I18n i18n; - - public QGatesAppAction(QualityGates qualityGates, Periods periods, I18n i18n) { - this.qualityGates = qualityGates; - this.periods = periods; - this.i18n = i18n; - } - - @Override - public void define(WebService.NewController controller) { - controller.createAction("app") - .setInternal(true) - .setDescription("Get initialization items for the admin UI. For internal use") - .setSince("4.3") - .setHandler(this); - } - - @Override - public void handle(Request request, Response response) { - JsonWriter writer = response.newJsonWriter().beginObject(); - addPermissions(writer); - addPeriods(writer); - addMetrics(writer); - writer.endObject().close(); - } - - private void addPermissions(JsonWriter writer) { - writer.prop("edit", qualityGates.currentUserHasWritePermission()); - } - - private void addPeriods(JsonWriter writer) { - writer.name("periods").beginArray(); - for (int i = 0; i < 3; i++) { - writer.beginObject().prop("key", (long) i + 1).prop("text", periods.label(i + 1)).endObject(); - } - addProjectPeriod(4, writer); - addProjectPeriod(5, writer); - writer.endArray(); - } - - private void addProjectPeriod(int periodIndex, JsonWriter writer) { - writer.beginObject().prop("key", periodIndex).prop("text", - i18n.message(Locale.getDefault(), "quality_gates.project_period", "Period " + periodIndex, periodIndex) - ).endObject(); - } - - private void addMetrics(JsonWriter writer) { - writer.name("metrics").beginArray(); - for (Metric metric : qualityGates.gateMetrics()) { - writer.beginObject() - .prop("id", metric.getId()) - .prop("key", metric.getKey()) - .prop("name", metric.getName()) - .prop("type", metric.getType().toString()) - .prop("domain", metric.getDomain()) - .prop("hidden", BooleanUtils.isNotFalse(metric.isHidden())) - .endObject(); - } - writer.endArray(); - } - -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesCopyAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesCopyAction.java deleted file mode 100644 index c61f2a27838..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesCopyAction.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * 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.qualitygate.ws; - -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.core.qualitygate.db.QualityGateDto; -import org.sonar.server.qualitygate.QualityGates; - -public class QGatesCopyAction implements QGateWsAction { - - private final QualityGates qualityGates; - - public QGatesCopyAction(QualityGates qualityGates) { - this.qualityGates = qualityGates; - } - - @Override - public void define(WebService.NewController controller) { - WebService.NewAction action = controller.createAction("copy") - .setDescription("Copy a Quality Gate. Require Administer Quality Profiles and Gates permission") - .setPost(true) - .setSince("4.3") - .setHandler(this); - - action.createParam(QGatesWs.PARAM_ID) - .setDescription("The ID of the source quality gate") - .setRequired(true) - .setExampleValue("1"); - - action.createParam(QGatesWs.PARAM_NAME) - .setDescription("The name of the quality gate to create") - .setRequired(true) - .setExampleValue("My Quality Gate"); - } - - @Override - public void handle(Request request, Response response) { - QualityGateDto newQualityGate = qualityGates.copy(QGatesWs.parseId(request, QGatesWs.PARAM_ID), request.mandatoryParam(QGatesWs.PARAM_NAME)); - JsonWriter writer = response.newJsonWriter(); - QGatesWs.writeQualityGate(newQualityGate, writer).close(); - } - -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesCreateAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesCreateAction.java deleted file mode 100644 index d3114898a62..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesCreateAction.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * 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.qualitygate.ws; - -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.core.qualitygate.db.QualityGateDto; -import org.sonar.server.qualitygate.QualityGates; - -public class QGatesCreateAction implements QGateWsAction { - - private final QualityGates qualityGates; - - public QGatesCreateAction(QualityGates qualityGates) { - this.qualityGates = qualityGates; - } - - @Override - public void define(WebService.NewController controller) { - WebService.NewAction action = controller.createAction("create") - .setDescription("Create a Quality Gate. Require Administer Quality Profiles and Gates permission") - .setSince("4.3") - .setPost(true) - .setHandler(this); - - action.createParam(QGatesWs.PARAM_NAME) - .setDescription("The name of the quality gate to create") - .setRequired(true) - .setExampleValue("My Quality Gate"); - } - - @Override - public void handle(Request request, Response response) { - QualityGateDto newQualityGate = qualityGates.create(request.mandatoryParam(QGatesWs.PARAM_NAME)); - JsonWriter writer = response.newJsonWriter(); - QGatesWs.writeQualityGate(newQualityGate, writer).close(); - } - -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesCreateConditionAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesCreateConditionAction.java deleted file mode 100644 index 927622e4924..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesCreateConditionAction.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * 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.qualitygate.ws; - -import org.sonar.api.server.ws.Request; -import org.sonar.api.server.ws.Response; -import org.sonar.api.server.ws.WebService; -import org.sonar.server.qualitygate.QualityGates; - -public class QGatesCreateConditionAction implements QGateWsAction { - - private final QualityGates qualityGates; - - public QGatesCreateConditionAction(QualityGates qualityGates) { - this.qualityGates = qualityGates; - } - - @Override - public void define(WebService.NewController controller) { - WebService.NewAction createCondition = controller.createAction("create_condition") - .setDescription("Add a new condition to a quality gate. Require Administer Quality Profiles and Gates permission") - .setPost(true) - .setSince("4.3") - .setHandler(this); - - createCondition - .createParam(QGatesWs.PARAM_GATE_ID) - .setDescription("ID of the quality gate") - .setRequired(true) - .setExampleValue("1"); - - QGatesWs.addConditionParams(createCondition); - } - - @Override - public void handle(Request request, Response response) { - QGatesWs.writeQualityGateCondition( - qualityGates.createCondition( - QGatesWs.parseId(request, QGatesWs.PARAM_GATE_ID), - request.mandatoryParam(QGatesWs.PARAM_METRIC), - request.mandatoryParam(QGatesWs.PARAM_OPERATOR), - request.param(QGatesWs.PARAM_WARNING), - request.param(QGatesWs.PARAM_ERROR), - request.paramAsInt(QGatesWs.PARAM_PERIOD) - ), response.newJsonWriter() - ).close(); - } - -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesDeleteConditionAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesDeleteConditionAction.java deleted file mode 100644 index 2edfc8da679..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesDeleteConditionAction.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * 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.qualitygate.ws; - -import org.sonar.api.server.ws.Request; -import org.sonar.api.server.ws.Response; -import org.sonar.api.server.ws.WebService; -import org.sonar.server.qualitygate.QualityGates; - -public class QGatesDeleteConditionAction implements QGateWsAction { - - private final QualityGates qualityGates; - - public QGatesDeleteConditionAction(QualityGates qualityGates) { - this.qualityGates = qualityGates; - } - - @Override - public void define(WebService.NewController controller) { - WebService.NewAction createCondition = controller.createAction("delete_condition") - .setDescription("Delete a condition from a quality gate. Require Administer Quality Profiles and Gates permission") - .setPost(true) - .setSince("4.3") - .setHandler(this); - - createCondition - .createParam(QGatesWs.PARAM_ID) - .setRequired(true) - .setDescription("Condition ID") - .setExampleValue("2"); - } - - @Override - public void handle(Request request, Response response) { - qualityGates.deleteCondition(QGatesWs.parseId(request, QGatesWs.PARAM_ID)); - response.noContent(); - } - -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesDeselectAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesDeselectAction.java deleted file mode 100644 index 8bdcb84dc88..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesDeselectAction.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * 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.qualitygate.ws; - -import org.sonar.api.server.ws.Request; -import org.sonar.api.server.ws.Response; -import org.sonar.api.server.ws.WebService; -import org.sonar.server.qualitygate.QualityGates; - -public class QGatesDeselectAction implements QGateWsAction { - - private final QualityGates qualityGates; - - public QGatesDeselectAction(QualityGates qualityGates) { - this.qualityGates = qualityGates; - } - - @Override - public void define(WebService.NewController controller) { - WebService.NewAction action = controller.createAction("deselect") - .setDescription("Remove the association of a project from a quality gate. Require Administer Quality Profiles and Gates permission") - .setPost(true) - .setSince("4.3") - .setHandler(this); - - action.createParam(QGatesWs.PARAM_GATE_ID) - .setDescription("Quality Gate ID") - .setRequired(true) - .setExampleValue("1"); - - action.createParam(QGatesWs.PARAM_PROJECT_ID) - .setDescription("Project ID") - .setRequired(true) - .setExampleValue("12"); - } - - @Override - public void handle(Request request, Response response) { - qualityGates.dissociateProject(QGatesWs.parseId(request, QGatesWs.PARAM_GATE_ID), QGatesWs.parseId(request, QGatesWs.PARAM_PROJECT_ID)); - response.noContent(); - } - -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesDestroyAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesDestroyAction.java deleted file mode 100644 index e8aa7871747..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesDestroyAction.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * 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.qualitygate.ws; - -import org.sonar.api.server.ws.Request; -import org.sonar.api.server.ws.Response; -import org.sonar.api.server.ws.WebService; -import org.sonar.server.qualitygate.QualityGates; - -public class QGatesDestroyAction implements QGateWsAction { - - private final QualityGates qualityGates; - - public QGatesDestroyAction(QualityGates qualityGates) { - this.qualityGates = qualityGates; - } - - @Override - public void define(WebService.NewController controller) { - WebService.NewAction action = controller.createAction("destroy") - .setDescription("Delete a Quality Gate. Require Administer Quality Profiles and Gates permission") - .setSince("4.3") - .setPost(true) - .setHandler(this); - - action.createParam(QGatesWs.PARAM_ID) - .setDescription("ID of the quality gate to delete") - .setRequired(true) - .setExampleValue("1"); - } - - @Override - public void handle(Request request, Response response) { - qualityGates.delete(QGatesWs.parseId(request, QGatesWs.PARAM_ID)); - response.noContent(); - } - -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesListAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesListAction.java deleted file mode 100644 index d7f5d370566..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesListAction.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * 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.qualitygate.ws; - -import com.google.common.io.Resources; -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.core.qualitygate.db.QualityGateDto; -import org.sonar.server.qualitygate.QualityGates; - -public class QGatesListAction implements QGateWsAction { - - private final QualityGates qualityGates; - - public QGatesListAction(QualityGates qualityGates) { - this.qualityGates = qualityGates; - } - - @Override - public void define(WebService.NewController controller) { - controller.createAction("list") - .setDescription("Get a list of quality gates") - .setSince("4.3") - .setResponseExample(Resources.getResource(this.getClass(), "example-list.json")) - .setHandler(this); - } - - @Override - public void handle(Request request, Response response) { - JsonWriter writer = response.newJsonWriter().beginObject().name("qualitygates").beginArray(); - for (QualityGateDto qgate : qualityGates.list()) { - QGatesWs.writeQualityGate(qgate, writer); - } - writer.endArray(); - QualityGateDto defaultQgate = qualityGates.getDefault(); - if (defaultQgate != null) { - writer.prop("default", defaultQgate.getId()); - } - writer.endObject().close(); - } - -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesRenameAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesRenameAction.java deleted file mode 100644 index 8491c29ff8b..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesRenameAction.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * 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.qualitygate.ws; - -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.core.qualitygate.db.QualityGateDto; -import org.sonar.server.qualitygate.QualityGates; - -public class QGatesRenameAction implements QGateWsAction { - - private final QualityGates qualityGates; - - public QGatesRenameAction(QualityGates qualityGates) { - this.qualityGates = qualityGates; - } - - @Override - public void define(WebService.NewController controller) { - WebService.NewAction action = controller.createAction("rename") - .setDescription("Rename a Quality Gate. Require Administer Quality Profiles and Gates permission") - .setPost(true) - .setHandler(this); - - action.createParam(QGatesWs.PARAM_ID) - .setDescription("ID of the quality gate to rename") - .setRequired(true) - .setExampleValue("1"); - - action.createParam(QGatesWs.PARAM_NAME) - .setDescription("New name of the quality gate") - .setRequired(true) - .setExampleValue("My Quality Gate"); - } - - @Override - public void handle(Request request, Response response) { - long idToRename = QGatesWs.parseId(request, QGatesWs.PARAM_ID); - QualityGateDto renamedQualityGate = qualityGates.rename(idToRename, request.mandatoryParam(QGatesWs.PARAM_NAME)); - JsonWriter writer = response.newJsonWriter(); - QGatesWs.writeQualityGate(renamedQualityGate, writer).close(); - } - -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesSearchAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesSearchAction.java deleted file mode 100644 index e21973ceb65..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesSearchAction.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * 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.qualitygate.ws; - -import com.google.common.io.Resources; -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.core.qualitygate.db.ProjectQgateAssociation; -import org.sonar.core.qualitygate.db.ProjectQgateAssociationQuery; -import org.sonar.server.qualitygate.QgateProjectFinder; - -public class QGatesSearchAction implements QGateWsAction { - - private final QgateProjectFinder projectFinder; - - public QGatesSearchAction(QgateProjectFinder projectFinder) { - this.projectFinder = projectFinder; - } - - @Override - public void define(WebService.NewController controller) { - WebService.NewAction action = controller.createAction("search") - .setDescription("Search for projects associated (or not) to a quality gate") - .setSince("4.3") - .setResponseExample(Resources.getResource(this.getClass(), "example-search.json")) - .setHandler(this); - - action.createParam(QGatesWs.PARAM_GATE_ID) - .setDescription("Quality Gate ID") - .setRequired(true) - .setExampleValue("1"); - - action.createParam(QGatesWs.PARAM_QUERY) - .setDescription("To search for projects containing this string. If this parameter is set, \"selected\" is set to \"all\".") - .setExampleValue("abc"); - - action.createParam(QGatesWs.PARAM_SELECTED) - .setDescription("If \"selected\", search for projects associated to the quality gate") - .setDefaultValue(ProjectQgateAssociationQuery.IN) - .setPossibleValues(ProjectQgateAssociationQuery.AVAILABLE_MEMBERSHIP) - .setExampleValue(ProjectQgateAssociationQuery.OUT); - - action.createParam(QGatesWs.PARAM_PAGE) - .setDescription("Page number") - .setDefaultValue("1") - .setExampleValue("2"); - - action.createParam(QGatesWs.PARAM_PAGE_SIZE) - .setDescription("Page size") - .setExampleValue("10"); - } - - @Override - public void handle(Request request, Response response) { - QgateProjectFinder.Association associations = projectFinder.find(ProjectQgateAssociationQuery.builder() - .gateId(request.mandatoryParam(QGatesWs.PARAM_GATE_ID)) - .membership(request.param(QGatesWs.PARAM_QUERY) == null ? request.param(QGatesWs.PARAM_SELECTED) : ProjectQgateAssociationQuery.ANY) - .projectSearch(request.param(QGatesWs.PARAM_QUERY)) - .pageIndex(request.paramAsInt(QGatesWs.PARAM_PAGE)) - .pageSize(request.paramAsInt(QGatesWs.PARAM_PAGE_SIZE)) - .build()); - JsonWriter writer = response.newJsonWriter(); - writer.beginObject().prop("more", associations.hasMoreResults()); - writer.name("results").beginArray(); - for (ProjectQgateAssociation project : associations.projects()) { - writer.beginObject().prop("id", project.id()).prop("name", project.name()).prop(QGatesWs.PARAM_SELECTED, project.isMember()).endObject(); - } - writer.endArray().endObject().close(); - } - -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesSelectAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesSelectAction.java deleted file mode 100644 index ce760117cbc..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesSelectAction.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * 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.qualitygate.ws; - -import org.sonar.api.server.ws.Request; -import org.sonar.api.server.ws.Response; -import org.sonar.api.server.ws.WebService; -import org.sonar.server.qualitygate.QualityGates; - -public class QGatesSelectAction implements QGateWsAction { - - private final QualityGates qualityGates; - - public QGatesSelectAction(QualityGates qualityGates) { - this.qualityGates = qualityGates; - } - - @Override - public void define(WebService.NewController controller) { - WebService.NewAction action = controller.createAction("select") - .setDescription("Associate a project to a quality gate. Require Administer Quality Profiles and Gates permission") - .setPost(true) - .setSince("4.3") - .setHandler(this); - - action.createParam(QGatesWs.PARAM_GATE_ID) - .setDescription("Quality Gate ID") - .setRequired(true) - .setExampleValue("1"); - - action.createParam(QGatesWs.PARAM_PROJECT_ID) - .setDescription("Project ID") - .setRequired(true) - .setExampleValue("12"); - } - - @Override - public void handle(Request request, Response response) { - qualityGates.associateProject(QGatesWs.parseId(request, QGatesWs.PARAM_GATE_ID), QGatesWs.parseId(request, QGatesWs.PARAM_PROJECT_ID)); - response.noContent(); - } - -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesSetAsDefaultAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesSetAsDefaultAction.java deleted file mode 100644 index 18fc05e019a..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesSetAsDefaultAction.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * 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.qualitygate.ws; - -import org.sonar.api.server.ws.Request; -import org.sonar.api.server.ws.Response; -import org.sonar.api.server.ws.WebService; -import org.sonar.server.qualitygate.QualityGates; - -public class QGatesSetAsDefaultAction implements QGateWsAction { - - private final QualityGates qualityGates; - - public QGatesSetAsDefaultAction(QualityGates qualityGates) { - this.qualityGates = qualityGates; - } - - @Override - public void define(WebService.NewController controller) { - WebService.NewAction action = controller.createAction("set_as_default") - .setDescription("Set a quality gate as the default quality gate. Require Administer Quality Profiles and Gates permission") - .setSince("4.3") - .setPost(true) - .setHandler(this); - - action.createParam(QGatesWs.PARAM_ID) - .setDescription("ID of the quality gate to set as default") - .setRequired(true) - .setExampleValue("1"); - } - - @Override - public void handle(Request request, Response response) { - qualityGates.setDefault(QGatesWs.parseId(request, QGatesWs.PARAM_ID)); - response.noContent(); - } - -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesShowAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesShowAction.java deleted file mode 100644 index 74710fa0f75..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesShowAction.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * 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.qualitygate.ws; - -import com.google.common.io.Resources; -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.core.qualitygate.db.QualityGateConditionDto; -import org.sonar.core.qualitygate.db.QualityGateDto; -import org.sonar.server.exceptions.BadRequestException; -import org.sonar.server.qualitygate.QualityGates; - -import javax.annotation.Nullable; - -import java.util.Collection; - -public class QGatesShowAction implements QGateWsAction { - - private final QualityGates qualityGates; - - public QGatesShowAction(QualityGates qualityGates) { - this.qualityGates = qualityGates; - } - - @Override - public void define(WebService.NewController controller) { - WebService.NewAction action = controller.createAction("show") - .setDescription("Display the details of a quality gate") - .setSince("4.3") - .setResponseExample(Resources.getResource(this.getClass(), "example-show.json")) - .setHandler(this); - - action.createParam(QGatesWs.PARAM_ID) - .setDescription("ID of the quality gate. Either id or name must be set") - .setExampleValue("1"); - - action.createParam(QGatesWs.PARAM_NAME) - .setDescription("Name of the quality gate. Either id or name must be set") - .setExampleValue("My Quality Gate"); - } - - @Override - public void handle(Request request, Response response) { - Long qGateId = request.paramAsLong(QGatesWs.PARAM_ID); - String qGateName = request.param(QGatesWs.PARAM_NAME); - checkOneOfIdOrNamePresent(qGateId, qGateName); - - QualityGateDto qGate = qGateId == null ? qualityGates.get(qGateName) : qualityGates.get(qGateId); - qGateId = qGate.getId(); - - JsonWriter writer = response.newJsonWriter().beginObject() - .prop(QGatesWs.PARAM_ID, qGate.getId()) - .prop(QGatesWs.PARAM_NAME, qGate.getName()); - Collection conditions = qualityGates.listConditions(qGateId); - if (!conditions.isEmpty()) { - writer.name("conditions").beginArray(); - for (QualityGateConditionDto condition : conditions) { - QGatesWs.writeQualityGateCondition(condition, writer); - } - writer.endArray(); - } - writer.endObject().close(); - } - - private void checkOneOfIdOrNamePresent(@Nullable Long qGateId, @Nullable String qGateName) { - if (qGateId == null && qGateName == null) { - throw new BadRequestException("Either one of 'id' or 'name' is required."); - } else if (qGateId != null && qGateName != null) { - throw new BadRequestException("Only one of 'id' or 'name' must be provided."); - } - } - -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesUnsetDefaultAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesUnsetDefaultAction.java deleted file mode 100644 index ab76b7ec755..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesUnsetDefaultAction.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * 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.qualitygate.ws; - -import org.sonar.api.server.ws.Request; -import org.sonar.api.server.ws.Response; -import org.sonar.api.server.ws.WebService; -import org.sonar.server.qualitygate.QualityGates; - -public class QGatesUnsetDefaultAction implements QGateWsAction { - - private final QualityGates qualityGates; - - public QGatesUnsetDefaultAction(QualityGates qualityGates) { - this.qualityGates = qualityGates; - } - - @Override - public void define(WebService.NewController controller) { - WebService.NewAction action = controller.createAction("unset_default") - .setDescription("Unset a quality gate as the default quality gate. Require Administer Quality Profiles and Gates permission") - .setSince("4.3") - .setPost(true) - .setHandler(this); - - action.createParam(QGatesWs.PARAM_ID) - .setDescription("ID of the quality gate to unset as default") - .setRequired(true) - .setExampleValue("1"); - } - - @Override - public void handle(Request request, Response response) { - qualityGates.setDefault(null); - response.noContent(); - } - -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesUpdateConditionAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesUpdateConditionAction.java deleted file mode 100644 index 1a5d8bf596c..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesUpdateConditionAction.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * 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.qualitygate.ws; - -import org.sonar.api.server.ws.Request; -import org.sonar.api.server.ws.Response; -import org.sonar.api.server.ws.WebService; -import org.sonar.server.qualitygate.QualityGates; - -public class QGatesUpdateConditionAction implements QGateWsAction { - - private final QualityGates qualityGates; - - public QGatesUpdateConditionAction(QualityGates qualityGates) { - this.qualityGates = qualityGates; - } - - @Override - public void define(WebService.NewController controller) { - WebService.NewAction createCondition = controller.createAction("update_condition") - .setDescription("Update a condition attached to a quality gate. Require Administer Quality Profiles and Gates permission") - .setPost(true) - .setSince("4.3") - .setHandler(this); - - createCondition - .createParam(QGatesWs.PARAM_ID) - .setDescription("Condition ID") - .setRequired(true) - .setExampleValue("10"); - - QGatesWs.addConditionParams(createCondition); - } - - @Override - public void handle(Request request, Response response) { - QGatesWs.writeQualityGateCondition( - qualityGates.updateCondition( - QGatesWs.parseId(request, QGatesWs.PARAM_ID), - request.mandatoryParam(QGatesWs.PARAM_METRIC), - request.mandatoryParam(QGatesWs.PARAM_OPERATOR), - request.param(QGatesWs.PARAM_WARNING), - request.param(QGatesWs.PARAM_ERROR), - request.paramAsInt(QGatesWs.PARAM_PERIOD) - ), response.newJsonWriter() - ).close(); - } - -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/RenameAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/RenameAction.java new file mode 100644 index 00000000000..42901fad207 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/RenameAction.java @@ -0,0 +1,64 @@ +/* + * 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.qualitygate.ws; + +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.core.qualitygate.db.QualityGateDto; +import org.sonar.server.qualitygate.QualityGates; + +public class RenameAction implements QGateWsAction { + + private final QualityGates qualityGates; + + public RenameAction(QualityGates qualityGates) { + this.qualityGates = qualityGates; + } + + @Override + public void define(WebService.NewController controller) { + WebService.NewAction action = controller.createAction("rename") + .setDescription("Rename a Quality Gate. Require Administer Quality Profiles and Gates permission") + .setPost(true) + .setHandler(this); + + action.createParam(QGatesWs.PARAM_ID) + .setDescription("ID of the quality gate to rename") + .setRequired(true) + .setExampleValue("1"); + + action.createParam(QGatesWs.PARAM_NAME) + .setDescription("New name of the quality gate") + .setRequired(true) + .setExampleValue("My Quality Gate"); + } + + @Override + public void handle(Request request, Response response) { + long idToRename = QGatesWs.parseId(request, QGatesWs.PARAM_ID); + QualityGateDto renamedQualityGate = qualityGates.rename(idToRename, request.mandatoryParam(QGatesWs.PARAM_NAME)); + JsonWriter writer = response.newJsonWriter(); + QGatesWs.writeQualityGate(renamedQualityGate, writer).close(); + } + +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/SearchAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/SearchAction.java new file mode 100644 index 00000000000..24ccf061c53 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/SearchAction.java @@ -0,0 +1,91 @@ +/* + * 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.qualitygate.ws; + +import com.google.common.io.Resources; +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.core.qualitygate.db.ProjectQgateAssociation; +import org.sonar.core.qualitygate.db.ProjectQgateAssociationQuery; +import org.sonar.server.qualitygate.QgateProjectFinder; + +public class SearchAction implements QGateWsAction { + + private final QgateProjectFinder projectFinder; + + public SearchAction(QgateProjectFinder projectFinder) { + this.projectFinder = projectFinder; + } + + @Override + public void define(WebService.NewController controller) { + WebService.NewAction action = controller.createAction("search") + .setDescription("Search for projects associated (or not) to a quality gate") + .setSince("4.3") + .setResponseExample(Resources.getResource(this.getClass(), "example-search.json")) + .setHandler(this); + + action.createParam(QGatesWs.PARAM_GATE_ID) + .setDescription("Quality Gate ID") + .setRequired(true) + .setExampleValue("1"); + + action.createParam(QGatesWs.PARAM_QUERY) + .setDescription("To search for projects containing this string. If this parameter is set, \"selected\" is set to \"all\".") + .setExampleValue("abc"); + + action.createParam(QGatesWs.PARAM_SELECTED) + .setDescription("If \"selected\", search for projects associated to the quality gate") + .setDefaultValue(ProjectQgateAssociationQuery.IN) + .setPossibleValues(ProjectQgateAssociationQuery.AVAILABLE_MEMBERSHIP) + .setExampleValue(ProjectQgateAssociationQuery.OUT); + + action.createParam(QGatesWs.PARAM_PAGE) + .setDescription("Page number") + .setDefaultValue("1") + .setExampleValue("2"); + + action.createParam(QGatesWs.PARAM_PAGE_SIZE) + .setDescription("Page size") + .setExampleValue("10"); + } + + @Override + public void handle(Request request, Response response) { + QgateProjectFinder.Association associations = projectFinder.find(ProjectQgateAssociationQuery.builder() + .gateId(request.mandatoryParam(QGatesWs.PARAM_GATE_ID)) + .membership(request.param(QGatesWs.PARAM_QUERY) == null ? request.param(QGatesWs.PARAM_SELECTED) : ProjectQgateAssociationQuery.ANY) + .projectSearch(request.param(QGatesWs.PARAM_QUERY)) + .pageIndex(request.paramAsInt(QGatesWs.PARAM_PAGE)) + .pageSize(request.paramAsInt(QGatesWs.PARAM_PAGE_SIZE)) + .build()); + JsonWriter writer = response.newJsonWriter(); + writer.beginObject().prop("more", associations.hasMoreResults()); + writer.name("results").beginArray(); + for (ProjectQgateAssociation project : associations.projects()) { + writer.beginObject().prop("id", project.id()).prop("name", project.name()).prop(QGatesWs.PARAM_SELECTED, project.isMember()).endObject(); + } + writer.endArray().endObject().close(); + } + +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/SelectAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/SelectAction.java new file mode 100644 index 00000000000..f2f2b5bf622 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/SelectAction.java @@ -0,0 +1,61 @@ +/* + * 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.qualitygate.ws; + +import org.sonar.api.server.ws.Request; +import org.sonar.api.server.ws.Response; +import org.sonar.api.server.ws.WebService; +import org.sonar.server.qualitygate.QualityGates; + +public class SelectAction implements QGateWsAction { + + private final QualityGates qualityGates; + + public SelectAction(QualityGates qualityGates) { + this.qualityGates = qualityGates; + } + + @Override + public void define(WebService.NewController controller) { + WebService.NewAction action = controller.createAction("select") + .setDescription("Associate a project to a quality gate. Require Administer Quality Profiles and Gates permission") + .setPost(true) + .setSince("4.3") + .setHandler(this); + + action.createParam(QGatesWs.PARAM_GATE_ID) + .setDescription("Quality Gate ID") + .setRequired(true) + .setExampleValue("1"); + + action.createParam(QGatesWs.PARAM_PROJECT_ID) + .setDescription("Project ID") + .setRequired(true) + .setExampleValue("12"); + } + + @Override + public void handle(Request request, Response response) { + qualityGates.associateProject(QGatesWs.parseId(request, QGatesWs.PARAM_GATE_ID), QGatesWs.parseId(request, QGatesWs.PARAM_PROJECT_ID)); + response.noContent(); + } + +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/SetAsDefaultAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/SetAsDefaultAction.java new file mode 100644 index 00000000000..828186cdb5e --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/SetAsDefaultAction.java @@ -0,0 +1,56 @@ +/* + * 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.qualitygate.ws; + +import org.sonar.api.server.ws.Request; +import org.sonar.api.server.ws.Response; +import org.sonar.api.server.ws.WebService; +import org.sonar.server.qualitygate.QualityGates; + +public class SetAsDefaultAction implements QGateWsAction { + + private final QualityGates qualityGates; + + public SetAsDefaultAction(QualityGates qualityGates) { + this.qualityGates = qualityGates; + } + + @Override + public void define(WebService.NewController controller) { + WebService.NewAction action = controller.createAction("set_as_default") + .setDescription("Set a quality gate as the default quality gate. Require Administer Quality Profiles and Gates permission") + .setSince("4.3") + .setPost(true) + .setHandler(this); + + action.createParam(QGatesWs.PARAM_ID) + .setDescription("ID of the quality gate to set as default") + .setRequired(true) + .setExampleValue("1"); + } + + @Override + public void handle(Request request, Response response) { + qualityGates.setDefault(QGatesWs.parseId(request, QGatesWs.PARAM_ID)); + response.noContent(); + } + +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/ShowAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/ShowAction.java new file mode 100644 index 00000000000..9b53247017f --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/ShowAction.java @@ -0,0 +1,93 @@ +/* + * 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.qualitygate.ws; + +import com.google.common.io.Resources; +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.core.qualitygate.db.QualityGateConditionDto; +import org.sonar.core.qualitygate.db.QualityGateDto; +import org.sonar.server.exceptions.BadRequestException; +import org.sonar.server.qualitygate.QualityGates; + +import javax.annotation.Nullable; + +import java.util.Collection; + +public class ShowAction implements QGateWsAction { + + private final QualityGates qualityGates; + + public ShowAction(QualityGates qualityGates) { + this.qualityGates = qualityGates; + } + + @Override + public void define(WebService.NewController controller) { + WebService.NewAction action = controller.createAction("show") + .setDescription("Display the details of a quality gate") + .setSince("4.3") + .setResponseExample(Resources.getResource(this.getClass(), "example-show.json")) + .setHandler(this); + + action.createParam(QGatesWs.PARAM_ID) + .setDescription("ID of the quality gate. Either id or name must be set") + .setExampleValue("1"); + + action.createParam(QGatesWs.PARAM_NAME) + .setDescription("Name of the quality gate. Either id or name must be set") + .setExampleValue("My Quality Gate"); + } + + @Override + public void handle(Request request, Response response) { + Long qGateId = request.paramAsLong(QGatesWs.PARAM_ID); + String qGateName = request.param(QGatesWs.PARAM_NAME); + checkOneOfIdOrNamePresent(qGateId, qGateName); + + QualityGateDto qGate = qGateId == null ? qualityGates.get(qGateName) : qualityGates.get(qGateId); + qGateId = qGate.getId(); + + JsonWriter writer = response.newJsonWriter().beginObject() + .prop(QGatesWs.PARAM_ID, qGate.getId()) + .prop(QGatesWs.PARAM_NAME, qGate.getName()); + Collection conditions = qualityGates.listConditions(qGateId); + if (!conditions.isEmpty()) { + writer.name("conditions").beginArray(); + for (QualityGateConditionDto condition : conditions) { + QGatesWs.writeQualityGateCondition(condition, writer); + } + writer.endArray(); + } + writer.endObject().close(); + } + + private void checkOneOfIdOrNamePresent(@Nullable Long qGateId, @Nullable String qGateName) { + if (qGateId == null && qGateName == null) { + throw new BadRequestException("Either one of 'id' or 'name' is required."); + } else if (qGateId != null && qGateName != null) { + throw new BadRequestException("Only one of 'id' or 'name' must be provided."); + } + } + +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/UnsetDefaultAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/UnsetDefaultAction.java new file mode 100644 index 00000000000..b2210aded5e --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/UnsetDefaultAction.java @@ -0,0 +1,56 @@ +/* + * 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.qualitygate.ws; + +import org.sonar.api.server.ws.Request; +import org.sonar.api.server.ws.Response; +import org.sonar.api.server.ws.WebService; +import org.sonar.server.qualitygate.QualityGates; + +public class UnsetDefaultAction implements QGateWsAction { + + private final QualityGates qualityGates; + + public UnsetDefaultAction(QualityGates qualityGates) { + this.qualityGates = qualityGates; + } + + @Override + public void define(WebService.NewController controller) { + WebService.NewAction action = controller.createAction("unset_default") + .setDescription("Unset a quality gate as the default quality gate. Require Administer Quality Profiles and Gates permission") + .setSince("4.3") + .setPost(true) + .setHandler(this); + + action.createParam(QGatesWs.PARAM_ID) + .setDescription("ID of the quality gate to unset as default") + .setRequired(true) + .setExampleValue("1"); + } + + @Override + public void handle(Request request, Response response) { + qualityGates.setDefault(null); + response.noContent(); + } + +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/UpdateConditionAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/UpdateConditionAction.java new file mode 100644 index 00000000000..cb844e05861 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/UpdateConditionAction.java @@ -0,0 +1,67 @@ +/* + * 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.qualitygate.ws; + +import org.sonar.api.server.ws.Request; +import org.sonar.api.server.ws.Response; +import org.sonar.api.server.ws.WebService; +import org.sonar.server.qualitygate.QualityGates; + +public class UpdateConditionAction implements QGateWsAction { + + private final QualityGates qualityGates; + + public UpdateConditionAction(QualityGates qualityGates) { + this.qualityGates = qualityGates; + } + + @Override + public void define(WebService.NewController controller) { + WebService.NewAction createCondition = controller.createAction("update_condition") + .setDescription("Update a condition attached to a quality gate. Require Administer Quality Profiles and Gates permission") + .setPost(true) + .setSince("4.3") + .setHandler(this); + + createCondition + .createParam(QGatesWs.PARAM_ID) + .setDescription("Condition ID") + .setRequired(true) + .setExampleValue("10"); + + QGatesWs.addConditionParams(createCondition); + } + + @Override + public void handle(Request request, Response response) { + QGatesWs.writeQualityGateCondition( + qualityGates.updateCondition( + QGatesWs.parseId(request, QGatesWs.PARAM_ID), + request.mandatoryParam(QGatesWs.PARAM_METRIC), + request.mandatoryParam(QGatesWs.PARAM_OPERATOR), + request.param(QGatesWs.PARAM_WARNING), + request.param(QGatesWs.PARAM_ERROR), + request.paramAsInt(QGatesWs.PARAM_PERIOD) + ), response.newJsonWriter() + ).close(); + } + +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/BackupAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/BackupAction.java new file mode 100644 index 00000000000..69e320da5b0 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/BackupAction.java @@ -0,0 +1,80 @@ +/* + * 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.qualityprofile.ws; + +import org.apache.commons.io.IOUtils; +import org.sonar.api.resources.Languages; +import org.sonar.api.server.ws.Request; +import org.sonar.api.server.ws.Response; +import org.sonar.api.server.ws.Response.Stream; +import org.sonar.api.server.ws.WebService; +import org.sonar.api.server.ws.WebService.NewAction; +import org.sonar.core.persistence.DbSession; +import org.sonar.server.db.DbClient; +import org.sonar.server.plugins.MimeTypes; +import org.sonar.server.qualityprofile.QProfileBackuper; +import org.sonar.server.qualityprofile.QProfileFactory; + +import java.io.OutputStreamWriter; +import java.nio.charset.StandardCharsets; + +public class BackupAction implements QProfileWsAction { + + private final QProfileBackuper backuper; + + private final DbClient dbClient; + + private QProfileFactory profileFactory; + + private final Languages languages; + + public BackupAction(QProfileBackuper backuper, DbClient dbClient, QProfileFactory profileFactory, Languages languages) { + this.backuper = backuper; + this.dbClient = dbClient; + this.profileFactory = profileFactory; + this.languages = languages; + } + + @Override + public void define(WebService.NewController controller) { + NewAction backup = controller.createAction("backup") + .setSince("5.2") + .setDescription("Backup a quality profile in XML form. The exported profile can be restored through api/qualityprofiles/restore.") + .setHandler(this); + + QProfileIdentificationParamUtils.defineProfileParams(backup, languages); + } + + @Override + public void handle(Request request, Response response) throws Exception { + Stream stream = response.stream(); + stream.setMediaType(MimeTypes.XML); + OutputStreamWriter writer = new OutputStreamWriter(stream.output(), StandardCharsets.UTF_8); + DbSession session = dbClient.openSession(false); + try { + String profileKey = QProfileIdentificationParamUtils.getProfileKeyFromParameters(request, profileFactory, session); + backuper.backup(profileKey, writer); + } finally { + session.close(); + IOUtils.closeQuietly(writer); + } + } + +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/ChangeParentAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/ChangeParentAction.java new file mode 100644 index 00000000000..002ac94362e --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/ChangeParentAction.java @@ -0,0 +1,117 @@ +/* + * 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.qualityprofile.ws; + +import com.google.common.base.Preconditions; +import org.sonar.api.resources.Languages; +import org.sonar.api.server.ws.Request; +import org.sonar.api.server.ws.Response; +import org.sonar.api.server.ws.WebService.NewAction; +import org.sonar.api.server.ws.WebService.NewController; +import org.sonar.core.permission.GlobalPermissions; +import org.sonar.core.persistence.DbSession; +import org.sonar.server.db.DbClient; +import org.sonar.server.qualityprofile.QProfileFactory; +import org.sonar.server.qualityprofile.RuleActivator; +import org.sonar.server.user.UserSession; + +import static org.apache.commons.lang.StringUtils.isEmpty; + +public class ChangeParentAction implements QProfileWsAction { + + private static final String PARAM_PARENT_KEY = "parentKey"; + + private static final String PARAM_PARENT_NAME = "parentName"; + + private final DbClient dbClient; + + private final RuleActivator ruleActivator; + + private final QProfileFactory profileFactory; + + private final Languages languages; + private final UserSession userSession; + + public ChangeParentAction(DbClient dbClient, RuleActivator ruleActivator, QProfileFactory profileFactory, Languages languages, UserSession userSession) { + this.dbClient = dbClient; + this.ruleActivator = ruleActivator; + this.profileFactory = profileFactory; + this.languages = languages; + this.userSession = userSession; + } + + @Override + public void define(NewController context) { + NewAction inheritance = context.createAction("change_parent") + .setSince("5.2") + .setPost(true) + .setDescription("Change a quality profile's parent.") + .setHandler(this); + + QProfileIdentificationParamUtils.defineProfileParams(inheritance, languages); + + inheritance.createParam(PARAM_PARENT_KEY) + .setDescription("The key of the new parent profile. If this parameter is set, parentName must not be set. " + + "If both are left empty, the inheritance link with current parent profile (if any) is broken, which deactivates all rules " + + "which come from the parent and are not overridden.") + .setExampleValue("sonar-way-java-12345"); + inheritance.createParam(PARAM_PARENT_NAME) + .setDescription("A quality profile name. If this parameter is set, profileKey must not be set and language must be set to disambiguate.") + .setExampleValue("Sonar way"); + + } + + @Override + public void handle(Request request, Response response) throws Exception { + userSession.checkLoggedIn().checkGlobalPermission(GlobalPermissions.QUALITY_PROFILE_ADMIN); + + DbSession session = dbClient.openSession(false); + try { + String profileKey = QProfileIdentificationParamUtils.getProfileKeyFromParameters(request, profileFactory, session); + String parentKey = getParentKeyFromParameters(request, profileFactory, session); + + ruleActivator.setParent(profileKey, parentKey); + + response.noContent(); + } finally { + session.close(); + } + } + + private static String getParentKeyFromParameters(Request request, QProfileFactory profileFactory, DbSession session) { + String language = request.param(QProfileIdentificationParamUtils.PARAM_LANGUAGE); + String parentName = request.param(PARAM_PARENT_NAME); + String parentKey = request.param(PARAM_PARENT_KEY); + + Preconditions.checkArgument( + isEmpty(parentName) || isEmpty(parentKey), "parentKey and parentName cannot be used simultaneously"); + + if (isEmpty(parentKey)) { + if (!isEmpty(parentName)) { + parentKey = QProfileIdentificationParamUtils.getProfileKeyFromLanguageAndName(language, parentName, profileFactory, session); + } else { + // Empty parent key is treated as "no more parent" + parentKey = null; + } + } + + return parentKey; + } +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/ChangelogAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/ChangelogAction.java new file mode 100644 index 00000000000..af462f70cd5 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/ChangelogAction.java @@ -0,0 +1,169 @@ +/* + * 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.qualityprofile.ws; + +import org.elasticsearch.action.search.SearchResponse; +import org.elasticsearch.search.SearchHit; +import org.sonar.api.resources.Languages; +import org.sonar.api.server.ws.*; +import org.sonar.api.server.ws.WebService.NewAction; +import org.sonar.api.server.ws.WebService.NewController; +import org.sonar.api.server.ws.WebService.Param; +import org.sonar.api.utils.DateUtils; +import org.sonar.api.utils.Paging; +import org.sonar.api.utils.text.JsonWriter; +import org.sonar.core.persistence.DbSession; +import org.sonar.core.rule.RuleDto; +import org.sonar.core.user.UserDto; +import org.sonar.server.activity.index.ActivityIndex; +import org.sonar.server.db.DbClient; +import org.sonar.server.es.SearchOptions; +import org.sonar.server.exceptions.NotFoundException; +import org.sonar.server.qualityprofile.QProfileActivity; +import org.sonar.server.qualityprofile.QProfileActivityQuery; +import org.sonar.server.qualityprofile.QProfileFactory; +import org.sonar.server.search.Result; + +import java.util.Date; +import java.util.Map.Entry; + +public class ChangelogAction implements QProfileWsAction { + + private static final String PARAM_SINCE = "since"; + private static final String PARAM_TO = "to"; + + private DbClient dbClient; + private ActivityIndex activityIndex; + private QProfileFactory profileFactory; + private Languages languages; + + public ChangelogAction(DbClient dbClient, ActivityIndex activityIndex, QProfileFactory profileFactory, Languages languages) { + this.dbClient = dbClient; + this.activityIndex = activityIndex; + this.profileFactory = profileFactory; + this.languages = languages; + } + + @Override + public void define(NewController context) { + NewAction changelog = context.createAction("changelog") + .setSince("5.2") + .setDescription("Get the history of changes on a quality profile: rule activation/deactivation, change in parameters/severity. " + + "Events are ordered by date in descending order (most recent first).") + .setHandler(this) + .setResponseExample(getClass().getResource("example-changelog.json")); + + QProfileIdentificationParamUtils.defineProfileParams(changelog, languages); + + changelog.addPagingParams(50); + + changelog.createParam(PARAM_SINCE) + .setDescription("Start date for the changelog.") + .setExampleValue("2011-04-25T01:15:42+0100"); + + changelog.createParam(PARAM_TO) + .setDescription("End date for the changelog.") + .setExampleValue("2013-07-25T07:35:42+0200"); + } + + @Override + public void handle(Request request, Response response) throws Exception { + DbSession session = dbClient.openSession(false); + try { + String profileKey = QProfileIdentificationParamUtils.getProfileKeyFromParameters(request, profileFactory, session); + if (dbClient.qualityProfileDao().getByKey(session, profileKey) == null) { + throw new NotFoundException(String.format("Could not find a profile with key '%s'", profileKey)); + } + + QProfileActivityQuery query = new QProfileActivityQuery().setQprofileKey(profileKey); + Date since = request.paramAsDateTime(PARAM_SINCE); + if (since != null) { + query.setSince(since); + } + Date to = request.paramAsDateTime(PARAM_TO); + if (to != null) { + query.setTo(to); + } + SearchOptions options = new SearchOptions(); + + int page = request.mandatoryParamAsInt(Param.PAGE); + options.setPage(page, request.mandatoryParamAsInt(Param.PAGE_SIZE)); + + Result result = searchActivities(query, options); + writeResponse(response.newJsonWriter(), result, Paging.create(options.getLimit(), page, (int) result.getTotal())); + } finally { + session.close(); + } + } + + private Result searchActivities(QProfileActivityQuery query, SearchOptions options) { + DbSession session = dbClient.openSession(false); + try { + SearchResponse response = activityIndex.doSearch(query, options); + Result result = new Result<>(response); + for (SearchHit hit : response.getHits().getHits()) { + QProfileActivity profileActivity = new QProfileActivity(hit.getSource()); + RuleDto ruleDto = dbClient.ruleDao().getNullableByKey(session, profileActivity.ruleKey()); + profileActivity.ruleName(ruleDto != null ? ruleDto.getName() : null); + + String login = profileActivity.getLogin(); + if (login != null) { + UserDto user = dbClient.userDao().selectActiveUserByLogin(session, login); + profileActivity.authorName(user != null ? user.getName() : null); + } + result.getHits().add(profileActivity); + } + return result; + } finally { + session.close(); + } + } + + private void writeResponse(JsonWriter json, Result result, Paging paging) { + json.beginObject(); + json.prop("total", result.getTotal()); + json.prop(Param.PAGE, paging.pageIndex()); + json.prop(Param.PAGE_SIZE, paging.pageSize()); + json.name("events").beginArray(); + for (QProfileActivity event : result.getHits()) { + json.beginObject() + .prop("date", DateUtils.formatDateTime(event.getCreatedAt())) + .prop("authorLogin", event.getLogin()) + .prop("authorName", event.authorName()) + .prop("action", event.getAction()) + .prop("ruleKey", event.ruleKey().toString()) + .prop("ruleName", event.ruleName()); + writeParameters(json, event); + json.endObject(); + } + json.endArray(); + json.endObject().close(); + } + + private void writeParameters(JsonWriter json, QProfileActivity event) { + json.name("params").beginObject() + .prop("severity", event.severity()); + for (Entry param : event.parameters().entrySet()) { + json.prop(param.getKey(), param.getValue()); + } + json.endObject(); + } + +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/CompareAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/CompareAction.java new file mode 100644 index 00000000000..6659583cf6a --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/CompareAction.java @@ -0,0 +1,221 @@ +/* + * 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.qualityprofile.ws; + +import com.google.common.collect.MapDifference.ValueDifference; +import com.google.common.collect.Maps; +import org.sonar.api.resources.Language; +import org.sonar.api.resources.Languages; +import org.sonar.api.rule.RuleKey; +import org.sonar.api.server.ws.Request; +import org.sonar.api.server.ws.Response; +import org.sonar.api.server.ws.WebService.NewAction; +import org.sonar.api.server.ws.WebService.NewController; +import org.sonar.api.utils.text.JsonWriter; +import org.sonar.core.qualityprofile.db.QualityProfileDto; +import org.sonar.core.util.NonNullInputFunction; +import org.sonar.server.qualityprofile.ActiveRule; +import org.sonar.server.qualityprofile.QProfileComparison; +import org.sonar.server.qualityprofile.QProfileComparison.ActiveRuleDiff; +import org.sonar.server.qualityprofile.QProfileComparison.QProfileComparisonResult; +import org.sonar.server.rule.Rule; +import org.sonar.server.rule.RuleRepositories; +import org.sonar.server.rule.RuleRepositories.Repository; +import org.sonar.server.rule.RuleService; + +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +public class CompareAction implements QProfileWsAction { + + private static final String ATTRIBUTE_LEFT = "left"; + private static final String ATTRIBUTE_RIGHT = "right"; + private static final String ATTRIBUTE_IN_LEFT = "inLeft"; + private static final String ATTRIBUTE_IN_RIGHT = "inRight"; + private static final String ATTRIBUTE_MODIFIED = "modified"; + private static final String ATTRIBUTE_SAME = "same"; + private static final String ATTRIBUTE_KEY = "key"; + private static final String ATTRIBUTE_NAME = "name"; + private static final String ATTRIBUTE_SEVERITY = "severity"; + private static final String ATTRIBUTE_PLUGIN_KEY = "pluginKey"; + private static final String ATTRIBUTE_PLUGIN_NAME = "pluginName"; + private static final String ATTRIBUTE_LANGUAGE_KEY = "languageKey"; + private static final String ATTRIBUTE_LANGUAGE_NAME = "languageName"; + private static final String ATTRIBUTE_PARAMS = "params"; + + private static final String PARAM_LEFT_KEY = "leftKey"; + private static final String PARAM_RIGHT_KEY = "rightKey"; + + private final QProfileComparison comparator; + private final RuleService ruleService; + private final RuleRepositories ruleRepositories; + private final Languages languages; + + public CompareAction(QProfileComparison comparator, RuleService ruleService, RuleRepositories ruleRepositories, Languages languages) { + this.comparator = comparator; + this.ruleService = ruleService; + this.ruleRepositories = ruleRepositories; + this.languages = languages; + } + + @Override + public void define(NewController context) { + NewAction compare = context.createAction("compare") + .setDescription("Compare two quality profiles.") + .setHandler(this) + .setInternal(true) + .setResponseExample(getClass().getResource("example-compare.json")) + .setSince("5.2"); + + compare.createParam(PARAM_LEFT_KEY) + .setDescription("A profile key.") + .setExampleValue("java-sonar-way-12345") + .setRequired(true); + + compare.createParam(PARAM_RIGHT_KEY) + .setDescription("Another profile key.") + .setExampleValue("java-sonar-way-with-findbugs-23456") + .setRequired(true); + } + + @Override + public void handle(Request request, Response response) throws Exception { + String leftKey = request.mandatoryParam(PARAM_LEFT_KEY); + String rightKey = request.mandatoryParam(PARAM_RIGHT_KEY); + + QProfileComparisonResult result = comparator.compare(leftKey, rightKey); + + List referencedRules = ruleService.getByKeys(result.collectRuleKeys()); + Map rulesByKey = Maps.uniqueIndex(referencedRules, new NonNullInputFunction() { + @Override + protected RuleKey doApply(Rule input) { + return input.key(); + } + }); + + writeResult(response.newJsonWriter(), result, rulesByKey); + } + + private void writeResult(JsonWriter json, QProfileComparisonResult result, Map rulesByKey) { + json.beginObject(); + + json.name(ATTRIBUTE_LEFT).beginObject(); + writeProfile(json, result.left()); + json.endObject(); + + json.name(ATTRIBUTE_RIGHT).beginObject(); + writeProfile(json, result.right()); + json.endObject(); + + json.name(ATTRIBUTE_IN_LEFT); + writeRules(json, result.inLeft(), rulesByKey); + + json.name(ATTRIBUTE_IN_RIGHT); + writeRules(json, result.inRight(), rulesByKey); + + json.name(ATTRIBUTE_MODIFIED); + writeDifferences(json, result.modified(), rulesByKey); + + json.name(ATTRIBUTE_SAME); + writeRules(json, result.same(), rulesByKey); + + json.endObject().close(); + } + + private void writeProfile(JsonWriter json, QualityProfileDto profile) { + json.prop(ATTRIBUTE_KEY, profile.getKey()) + .prop(ATTRIBUTE_NAME, profile.getName()); + } + + private void writeRules(JsonWriter json, Map activeRules, Map rulesByKey) { + json.beginArray(); + for (Entry activeRule : activeRules.entrySet()) { + RuleKey key = activeRule.getKey(); + ActiveRule value = activeRule.getValue(); + + json.beginObject(); + writeRule(json, key, rulesByKey); + json.prop(ATTRIBUTE_SEVERITY, value.severity()); + json.endObject(); + } + json.endArray(); + } + + private void writeRule(JsonWriter json, RuleKey key, Map rulesByKey) { + String repositoryKey = key.repository(); + json.prop(ATTRIBUTE_KEY, key.toString()) + .prop(ATTRIBUTE_NAME, rulesByKey.get(key).name()) + .prop(ATTRIBUTE_PLUGIN_KEY, repositoryKey); + + Repository repo = ruleRepositories.repository(repositoryKey); + if (repo != null) { + String languageKey = repo.getLanguage(); + Language language = languages.get(languageKey); + + json.prop(ATTRIBUTE_PLUGIN_NAME, repo.getName()); + json.prop(ATTRIBUTE_LANGUAGE_KEY, languageKey); + json.prop(ATTRIBUTE_LANGUAGE_NAME, language == null ? null : language.getName()); + } + } + + private void writeDifferences(JsonWriter json, Map modified, Map rulesByKey) { + json.beginArray(); + for (Entry diffEntry : modified.entrySet()) { + RuleKey key = diffEntry.getKey(); + ActiveRuleDiff value = diffEntry.getValue(); + json.beginObject(); + writeRule(json, key, rulesByKey); + + json.name(ATTRIBUTE_LEFT).beginObject(); + json.prop(ATTRIBUTE_SEVERITY, value.leftSeverity()); + json.name(ATTRIBUTE_PARAMS).beginObject(); + for (Entry> valueDiff : value.paramDifference().entriesDiffering().entrySet()) { + json.prop(valueDiff.getKey(), valueDiff.getValue().leftValue()); + } + for (Entry valueDiff : value.paramDifference().entriesOnlyOnLeft().entrySet()) { + json.prop(valueDiff.getKey(), valueDiff.getValue()); + } + // params + json.endObject(); + // left + json.endObject(); + + json.name(ATTRIBUTE_RIGHT).beginObject(); + json.prop(ATTRIBUTE_SEVERITY, value.rightSeverity()); + json.name(ATTRIBUTE_PARAMS).beginObject(); + for (Entry> valueDiff : value.paramDifference().entriesDiffering().entrySet()) { + json.prop(valueDiff.getKey(), valueDiff.getValue().rightValue()); + } + for (Entry valueDiff : value.paramDifference().entriesOnlyOnRight().entrySet()) { + json.prop(valueDiff.getKey(), valueDiff.getValue()); + } + // params + json.endObject(); + // right + json.endObject(); + + // rule + json.endObject(); + } + json.endArray(); + } + +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/CopyAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/CopyAction.java new file mode 100644 index 00000000000..f02a071c2c0 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/CopyAction.java @@ -0,0 +1,90 @@ +/* + * 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.qualityprofile.ws; + +import org.sonar.api.resources.Language; +import org.sonar.api.resources.Languages; +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.server.ws.WebService.NewAction; +import org.sonar.core.permission.GlobalPermissions; +import org.sonar.core.qualityprofile.db.QualityProfileDto; +import org.sonar.server.qualityprofile.QProfileCopier; +import org.sonar.server.user.UserSession; + +public class CopyAction implements QProfileWsAction { + + private static final String PARAM_PROFILE_NAME = "toName"; + private static final String PARAM_PROFILE_KEY = "fromKey"; + + private final QProfileCopier profileCopier; + private final Languages languages; + private final UserSession userSession; + + public CopyAction(QProfileCopier profileCopier, Languages languages, UserSession userSession) { + this.profileCopier = profileCopier; + this.languages = languages; + this.userSession = userSession; + } + + @Override + public void define(WebService.NewController controller) { + NewAction setDefault = controller.createAction("copy") + .setSince("5.2") + .setDescription("Copy a quality profile.") + .setPost(true) + .setHandler(this); + + setDefault.createParam(PARAM_PROFILE_NAME) + .setDescription("The name for the new quality profile.") + .setExampleValue("My Sonar way") + .setRequired(true); + + setDefault.createParam(PARAM_PROFILE_KEY) + .setDescription("The key of a quality profile.") + .setExampleValue("sonar-way-js-12345") + .setRequired(true); + } + + @Override + public void handle(Request request, Response response) throws Exception { + userSession.checkLoggedIn().checkGlobalPermission(GlobalPermissions.QUALITY_PROFILE_ADMIN); + + String newName = request.mandatoryParam(PARAM_PROFILE_NAME); + String profileKey = request.mandatoryParam(PARAM_PROFILE_KEY); + + QualityProfileDto copiedProfile = profileCopier.copyToName(profileKey, newName); + + String languageKey = copiedProfile.getLanguage(); + Language language = languages.get(copiedProfile.getLanguage()); + String parentKey = copiedProfile.getParentKee(); + response.newJsonWriter() + .beginObject() + .prop("key", copiedProfile.getKey()) + .prop("name", copiedProfile.getName()) + .prop("language", languageKey) + .prop("languageName", language == null ? null : language.getName()) + .prop("isDefault", copiedProfile.isDefault()) + .prop("isInherited", parentKey != null) + .prop("parentKey", parentKey) + .endObject().close(); + } +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/CreateAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/CreateAction.java new file mode 100644 index 00000000000..b41ab309535 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/CreateAction.java @@ -0,0 +1,157 @@ +/* + * 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.qualityprofile.ws; + +import org.sonar.api.profiles.ProfileImporter; +import org.sonar.api.resources.Languages; +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.server.ws.WebService.NewAction; +import org.sonar.api.utils.text.JsonWriter; +import org.sonar.core.permission.GlobalPermissions; +import org.sonar.core.persistence.DbSession; +import org.sonar.core.qualityprofile.db.QualityProfileDto; +import org.sonar.server.db.DbClient; +import org.sonar.server.qualityprofile.QProfileExporters; +import org.sonar.server.qualityprofile.QProfileFactory; +import org.sonar.server.qualityprofile.QProfileName; +import org.sonar.server.qualityprofile.QProfileResult; +import org.sonar.server.user.UserSession; + +import java.io.InputStream; + +public class CreateAction implements QProfileWsAction { + + private static final String PARAM_PROFILE_NAME = "name"; + private static final String PARAM_LANGUAGE = "language"; + private static final String PARAM_BACKUP_FORMAT = "backup_%s"; + + private final DbClient dbClient; + + private final QProfileFactory profileFactory; + + private final QProfileExporters exporters; + + private final Languages languages; + + private final ProfileImporter[] importers; + private final UserSession userSession; + + public CreateAction(DbClient dbClient, QProfileFactory profileFactory, QProfileExporters exporters, + Languages languages, ProfileImporter[] importers, UserSession userSession) { + this.dbClient = dbClient; + this.profileFactory = profileFactory; + this.exporters = exporters; + this.languages = languages; + this.importers = importers; + this.userSession = userSession; + } + + public CreateAction(DbClient dbClient, QProfileFactory profileFactory, QProfileExporters exporters, Languages languages, UserSession userSession) { + this(dbClient, profileFactory, exporters, languages, new ProfileImporter[0], userSession); + } + + @Override + public void define(WebService.NewController controller) { + NewAction create = controller.createAction("create") + .setSince("5.2") + .setDescription("Create a quality profile.") + .setPost(true) + .setResponseExample(getClass().getResource("example-create.json")) + .setHandler(this); + + create.createParam(PARAM_PROFILE_NAME) + .setDescription("The name for the new quality profile.") + .setExampleValue("My Sonar way") + .setRequired(true); + + create.createParam(PARAM_LANGUAGE) + .setDescription("The language for the quality profile.") + .setExampleValue("js") + .setPossibleValues(LanguageParamUtils.getLanguageKeys(languages)) + .setRequired(true); + + for (ProfileImporter importer : importers) { + create.createParam(getBackupParamName(importer.getKey())) + .setDescription(String.format("A configuration file for %s.", importer.getName())); + } + } + + @Override + public void handle(Request request, Response response) throws Exception { + userSession.checkLoggedIn().checkGlobalPermission(GlobalPermissions.QUALITY_PROFILE_ADMIN); + + String name = request.mandatoryParam(PARAM_PROFILE_NAME); + String language = request.mandatoryParam(PARAM_LANGUAGE); + + DbSession dbSession = dbClient.openSession(false); + + try { + QProfileResult result = new QProfileResult(); + QualityProfileDto profile = profileFactory.create(dbSession, QProfileName.createFor(language, name)); + result.setProfile(profile); + for (ProfileImporter importer : importers) { + InputStream contentToImport = request.paramAsInputStream(getBackupParamName(importer.getKey())); + if (contentToImport != null) { + result.add(exporters.importXml(profile, importer.getKey(), contentToImport, dbSession)); + } + } + dbSession.commit(); + writeResult(response.newJsonWriter(), result); + } finally { + dbSession.close(); + } + } + + private void writeResult(JsonWriter json, QProfileResult result) { + String language = result.profile().getLanguage(); + json.beginObject().name("profile").beginObject() + .prop("key", result.profile().getKey()) + .prop("name", result.profile().getName()) + .prop("language", language) + .prop("languageName", languages.get(result.profile().getLanguage()).getName()) + .prop("isDefault", false) + .prop("isInherited", false) + .endObject(); + + if (!result.infos().isEmpty()) { + json.name("infos").beginArray(); + for (String info : result.infos()) { + json.value(info); + } + json.endArray(); + } + + if (!result.warnings().isEmpty()) { + json.name("warnings").beginArray(); + for (String warning : result.warnings()) { + json.value(warning); + } + json.endArray(); + } + + json.endObject().close(); + } + + private String getBackupParamName(String importerKey) { + return String.format(PARAM_BACKUP_FORMAT, importerKey); + } +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/DeleteAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/DeleteAction.java new file mode 100644 index 00000000000..0af30ba17cb --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/DeleteAction.java @@ -0,0 +1,77 @@ +/* + * 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.qualityprofile.ws; + +import org.sonar.api.resources.Languages; +import org.sonar.api.server.ws.Request; +import org.sonar.api.server.ws.Response; +import org.sonar.api.server.ws.WebService.NewAction; +import org.sonar.api.server.ws.WebService.NewController; +import org.sonar.core.permission.GlobalPermissions; +import org.sonar.core.persistence.DbSession; +import org.sonar.server.db.DbClient; +import org.sonar.server.qualityprofile.QProfileFactory; +import org.sonar.server.user.UserSession; + +public class DeleteAction implements QProfileWsAction { + + private final Languages languages; + private final QProfileFactory profileFactory; + private final DbClient dbClient; + private final UserSession userSession; + + public DeleteAction(Languages languages, QProfileFactory profileFactory, DbClient dbClient, UserSession userSession) { + this.languages = languages; + this.profileFactory = profileFactory; + this.dbClient = dbClient; + this.userSession = userSession; + } + + @Override + public void define(NewController controller) { + NewAction action = controller.createAction("delete") + .setDescription("Delete a quality profile and all its descendants. The default quality profile cannot be deleted.") + .setSince("5.2") + .setPost(true) + .setHandler(this); + + QProfileIdentificationParamUtils.defineProfileParams(action, languages); + } + + + @Override + public void handle(Request request, Response response) throws Exception { + userSession.checkLoggedIn(); + userSession.checkGlobalPermission(GlobalPermissions.QUALITY_PROFILE_ADMIN); + + + DbSession session = dbClient.openSession(false); + try { + String profileKey = QProfileIdentificationParamUtils.getProfileKeyFromParameters(request, profileFactory, session); + profileFactory.delete(session, profileKey, false); + + session.commit(); + } finally { + session.close(); + } + + response.noContent(); + } +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/ExportAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/ExportAction.java new file mode 100644 index 00000000000..38f97c7e593 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/ExportAction.java @@ -0,0 +1,141 @@ +/* + * 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.qualityprofile.ws; + +import com.google.common.collect.Lists; +import org.apache.commons.io.IOUtils; +import org.sonar.api.profiles.ProfileExporter; +import org.sonar.api.resources.Language; +import org.sonar.api.resources.Languages; +import org.sonar.api.server.ws.Request; +import org.sonar.api.server.ws.Response; +import org.sonar.api.server.ws.Response.Stream; +import org.sonar.api.server.ws.WebService; +import org.sonar.api.server.ws.WebService.NewAction; +import org.sonar.core.persistence.DbSession; +import org.sonar.core.qualityprofile.db.QualityProfileDto; +import org.sonar.server.db.DbClient; +import org.sonar.server.exceptions.NotFoundException; +import org.sonar.server.plugins.MimeTypes; +import org.sonar.server.qualityprofile.QProfileBackuper; +import org.sonar.server.qualityprofile.QProfileExporters; +import org.sonar.server.qualityprofile.QProfileFactory; + +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.Writer; +import java.nio.charset.StandardCharsets; +import java.util.List; + +public class ExportAction implements QProfileWsAction { + + private static final String PARAM_PROFILE_NAME = "name"; + private static final String PARAM_LANGUAGE = "language"; + private static final String PARAM_FORMAT = "exporterKey"; + + private final DbClient dbClient; + + private final QProfileFactory profileFactory; + + private final QProfileBackuper backuper; + + private final QProfileExporters exporters; + + private final Languages languages; + + public ExportAction(DbClient dbClient, QProfileFactory profileFactory, QProfileBackuper backuper, QProfileExporters exporters, Languages languages) { + this.dbClient = dbClient; + this.profileFactory = profileFactory; + this.backuper = backuper; + this.exporters = exporters; + this.languages = languages; + } + + @Override + public void define(WebService.NewController controller) { + NewAction create = controller.createAction("export") + .setSince("5.2") + .setDescription("Export a quality profile.") + .setHandler(this); + + create.createParam(PARAM_PROFILE_NAME) + .setDescription("The name of the quality profile to export. If left empty, will export the default profile for the language.") + .setExampleValue("My Sonar way"); + + create.createParam(PARAM_LANGUAGE) + .setDescription("The language for the quality profile.") + .setExampleValue(LanguageParamUtils.getExampleValue(languages)) + .setPossibleValues(LanguageParamUtils.getLanguageKeys(languages)) + .setRequired(true); + + List exporterKeys = Lists.newArrayList(); + for (Language lang : languages.all()) { + for (ProfileExporter exporter : exporters.exportersForLanguage(lang.getKey())) { + exporterKeys.add(exporter.getKey()); + } + } + if (!exporterKeys.isEmpty()) { + create.createParam(PARAM_FORMAT) + .setDescription("Output format. If left empty, the same format as api/qualityprofiles/backup is used. " + + "Possible values are described by api/qualityprofiles/exporters.") + .setPossibleValues(exporterKeys); + } + } + + @Override + public void handle(Request request, Response response) throws Exception { + String name = request.param(PARAM_PROFILE_NAME); + String language = request.mandatoryParam(PARAM_LANGUAGE); + String format = null; + if (!exporters.exportersForLanguage(language).isEmpty()) { + format = request.param(PARAM_FORMAT); + } + + DbSession dbSession = dbClient.openSession(false); + Stream stream = response.stream(); + OutputStream output = stream.output(); + Writer writer = new OutputStreamWriter(output, StandardCharsets.UTF_8); + + try { + QualityProfileDto profile; + if (name == null) { + profile = profileFactory.getDefault(dbSession, language); + } else { + profile = profileFactory.getByNameAndLanguage(dbSession, name, language); + } + if (profile == null) { + throw new NotFoundException(String.format("Could not find profile with name '%s' for language '%s'", name, language)); + } + + String profileKey = profile.getKey(); + if (format == null) { + stream.setMediaType(MimeTypes.XML); + backuper.backup(profileKey, writer); + } else { + stream.setMediaType(exporters.mimeType(format)); + exporters.export(profileKey, format, writer); + } + } finally { + IOUtils.closeQuietly(writer); + IOUtils.closeQuietly(output); + dbSession.close(); + } + } +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/ExportersAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/ExportersAction.java new file mode 100644 index 00000000000..0196729e592 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/ExportersAction.java @@ -0,0 +1,65 @@ +/* + * 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.qualityprofile.ws; + +import org.sonar.api.profiles.ProfileExporter; +import org.sonar.api.server.ws.Request; +import org.sonar.api.server.ws.Response; +import org.sonar.api.server.ws.WebService.NewController; +import org.sonar.api.utils.text.JsonWriter; + +public class ExportersAction implements QProfileWsAction { + + private ProfileExporter[] exporters; + + public ExportersAction(ProfileExporter[] exporters) { + this.exporters = exporters; + } + + public ExportersAction() { + this(new ProfileExporter[0]); + } + + @Override + public void define(NewController context) { + context.createAction("exporters") + .setDescription("Lists available profile export formats.") + .setHandler(this) + .setResponseExample(getClass().getResource("example-exporters.json")) + .setSince("5.2"); + } + + @Override + public void handle(Request request, Response response) throws Exception { + JsonWriter json = response.newJsonWriter().beginObject().name("exporters").beginArray(); + for (ProfileExporter exporter : exporters) { + json.beginObject() + .prop("key", exporter.getKey()) + .prop("name", exporter.getName()); + json.name("languages").beginArray(); + for (String language : exporter.getSupportedLanguages()) { + json.value(language); + } + json.endArray().endObject(); + } + json.endArray().endObject().close(); + } + +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/ImportersAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/ImportersAction.java new file mode 100644 index 00000000000..6911be1242e --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/ImportersAction.java @@ -0,0 +1,64 @@ +/* + * 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.qualityprofile.ws; + +import org.sonar.api.profiles.ProfileImporter; +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; + +public class ImportersAction implements QProfileWsAction { + + private final ProfileImporter[] importers; + + public ImportersAction(ProfileImporter[] importers) { + this.importers = importers; + } + + public ImportersAction() { + this(new ProfileImporter[0]); + } + + @Override + public void define(WebService.NewController controller) { + controller.createAction("importers") + .setSince("5.2") + .setDescription("List supported importers.") + .setResponseExample(getClass().getResource("example-importers.json")) + .setHandler(this); + } + + @Override + public void handle(Request request, Response response) throws Exception { + JsonWriter json = response.newJsonWriter().beginObject().name("importers").beginArray(); + for (ProfileImporter importer : importers) { + json.beginObject() + .prop("key", importer.getKey()) + .prop("name", importer.getName()) + .name("languages").beginArray(); + for (String languageKey : importer.getSupportedLanguages()) { + json.value(languageKey); + } + json.endArray().endObject(); + } + json.endArray().endObject().close(); + } +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/InheritanceAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/InheritanceAction.java new file mode 100644 index 00000000000..5cf4062409d --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/InheritanceAction.java @@ -0,0 +1,169 @@ +/* + * 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.qualityprofile.ws; + +import com.google.common.collect.Multimap; +import org.sonar.api.resources.Languages; +import org.sonar.api.server.ws.Request; +import org.sonar.api.server.ws.Response; +import org.sonar.api.server.ws.WebService.NewAction; +import org.sonar.api.server.ws.WebService.NewController; +import org.sonar.api.utils.text.JsonWriter; +import org.sonar.core.persistence.DbSession; +import org.sonar.core.qualityprofile.db.QualityProfileDto; +import org.sonar.server.db.DbClient; +import org.sonar.server.exceptions.NotFoundException; +import org.sonar.server.qualityprofile.QProfile; +import org.sonar.server.qualityprofile.QProfileFactory; +import org.sonar.server.qualityprofile.QProfileLoader; +import org.sonar.server.qualityprofile.QProfileLookup; +import org.sonar.server.qualityprofile.index.ActiveRuleIndex; +import org.sonar.server.qualityprofile.index.ActiveRuleNormalizer; +import org.sonar.server.search.FacetValue; + +import javax.annotation.Nullable; + +import java.util.List; +import java.util.Map; + +public class InheritanceAction implements QProfileWsAction { + + private final DbClient dbClient; + + private final QProfileLookup profileLookup; + + private final QProfileLoader profileLoader; + + private final QProfileFactory profileFactory; + + private final Languages languages; + + public InheritanceAction(DbClient dbClient, QProfileLookup profileLookup, QProfileLoader profileLoader, QProfileFactory profileFactory, Languages languages) { + this.dbClient = dbClient; + this.profileLookup = profileLookup; + this.profileLoader = profileLoader; + this.profileFactory = profileFactory; + this.languages = languages; + } + + @Override + public void define(NewController context) { + NewAction inheritance = context.createAction("inheritance") + .setSince("5.2") + .setDescription("Show a quality profile's ancestors and children.") + .setHandler(this) + .setResponseExample(getClass().getResource("example-inheritance.json")); + + QProfileIdentificationParamUtils.defineProfileParams(inheritance, languages); + } + + @Override + public void handle(Request request, Response response) throws Exception { + DbSession session = dbClient.openSession(false); + try { + String profileKey = QProfileIdentificationParamUtils.getProfileKeyFromParameters(request, profileFactory, session); + QualityProfileDto profile = dbClient.qualityProfileDao().getByKey(session, profileKey); + if (profile == null) { + throw new NotFoundException(String.format("Could not find a quality profile with key %s", profileKey)); + } + + List ancestors = profileLookup.ancestors(profile, session); + List children = dbClient.qualityProfileDao().findChildren(session, profileKey); + Map> profileStats = profileLoader.getAllProfileStats(); + + writeResponse(response.newJsonWriter(), profile, ancestors, children, profileStats); + } finally { + session.close(); + } + } + + private void writeResponse(JsonWriter json, QualityProfileDto profile, List ancestors, List children, + Map> profileStats) { + json.beginObject(); + writeProfile(json, profile, profileStats); + writeAncestors(json, ancestors, profileStats); + writeChildren(json, children, profileStats); + json.endObject().close(); + } + + private void writeProfile(JsonWriter json, QualityProfileDto profile, Map> profileStats) { + String profileKey = profile.getKey(); + json.name("profile"); + writeProfileAttributes(json, profileKey, profile.getName(), profile.getParentKee(), profileStats); + } + + private void writeAncestors(JsonWriter json, List ancestors, Map> profileStats) { + json.name("ancestors").beginArray(); + for (QProfile ancestor : ancestors) { + String ancestorKey = ancestor.key(); + writeProfileAttributes(json, ancestorKey, ancestor.name(), ancestor.parent(), profileStats); + } + json.endArray(); + } + + private void writeChildren(JsonWriter json, List children, Map> profileStats) { + json.name("children").beginArray(); + for (QualityProfileDto child : children) { + String childKey = child.getKey(); + writeProfileAttributes(json, childKey, child.getName(), null, profileStats); + } + json.endArray(); + } + + private void writeProfileAttributes(JsonWriter json, String key, String name, @Nullable String parentKey, Map> profileStats) { + json.beginObject(); + json.prop("key", key) + .prop("name", name) + .prop("parent", parentKey); + writeStats(json, key, profileStats); + json.endObject(); + } + + private void writeStats(JsonWriter json, String profileKey, Map> profileStats) { + if (profileStats.containsKey(profileKey)) { + Multimap ancestorStats = profileStats.get(profileKey); + json.prop("activeRuleCount", getActiveRuleCount(ancestorStats)); + json.prop("overridingRuleCount", getOverridingRuleCount(ancestorStats)); + } else { + json.prop("activeRuleCount", 0); + } + } + + private Long getActiveRuleCount(Multimap profileStats) { + Long result = null; + if (profileStats.containsKey(ActiveRuleIndex.COUNT_ACTIVE_RULES)) { + result = profileStats.get(ActiveRuleIndex.COUNT_ACTIVE_RULES).iterator().next().getValue(); + } + return result; + } + + private Long getOverridingRuleCount(Multimap profileStats) { + Long result = null; + if (profileStats.containsKey(ActiveRuleNormalizer.ActiveRuleField.INHERITANCE.field())) { + for (FacetValue value : profileStats.get(ActiveRuleNormalizer.ActiveRuleField.INHERITANCE.field())) { + if ("OVERRIDES".equals(value.getKey())) { + result = value.getValue(); + } + } + } + return result; + } + +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/ProjectsAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/ProjectsAction.java new file mode 100644 index 00000000000..f4b3bc9658f --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/ProjectsAction.java @@ -0,0 +1,178 @@ +/* + * 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.qualityprofile.ws; + +import com.google.common.base.Predicate; +import com.google.common.collect.Collections2; +import com.google.common.collect.Iterables; +import com.google.common.collect.Lists; +import org.apache.commons.lang.builder.CompareToBuilder; +import org.sonar.api.server.ws.Request; +import org.sonar.api.server.ws.Response; +import org.sonar.api.server.ws.WebService.NewAction; +import org.sonar.api.server.ws.WebService.NewController; +import org.sonar.api.utils.Paging; +import org.sonar.api.utils.text.JsonWriter; +import org.sonar.api.web.UserRole; +import org.sonar.core.persistence.DbSession; +import org.sonar.core.qualityprofile.db.ProjectQprofileAssociationDto; +import org.sonar.core.util.NonNullInputFunction; +import org.sonar.server.db.DbClient; +import org.sonar.server.exceptions.NotFoundException; +import org.sonar.server.user.UserSession; + +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +public class ProjectsAction implements QProfileWsAction { + + private static final String PARAM_KEY = "key"; + private static final String PARAM_SELECTED = "selected"; + private static final String PARAM_QUERY = "query"; + private static final String PARAM_PAGE_SIZE = "pageSize"; + private static final String PARAM_PAGE = "page"; + + private static final String SELECTION_ALL = "all"; + private static final String SELECTION_SELECTED = "selected"; + private static final String SELECTION_DESELECTED = "deselected"; + + private final DbClient dbClient; + private final UserSession userSession; + + public ProjectsAction(DbClient dbClient, UserSession userSession) { + this.dbClient = dbClient; + this.userSession = userSession; + } + + @Override + public void define(NewController controller) { + NewAction projects = controller.createAction("projects") + .setSince("5.2") + .setHandler(this) + .setDescription("List projects with their association status regarding a quality profile.") + .setResponseExample(getClass().getResource("example-projects.json")); + projects.createParam(PARAM_KEY) + .setDescription("A quality profile key.") + .setRequired(true) + .setExampleValue("sonar-way-java-12345"); + projects.createParam(PARAM_SELECTED) + .setDescription("If specified, return only selected or deselected projects.") + .setPossibleValues(SELECTION_SELECTED, SELECTION_DESELECTED, SELECTION_ALL) + .setDefaultValue(SELECTION_ALL); + projects.createParam(PARAM_QUERY) + .setDescription("If specified, return only projects whose name match the query."); + projects.createParam(PARAM_PAGE_SIZE) + .setDescription("Size for the paging to apply.").setDefaultValue(100); + projects.createParam(PARAM_PAGE) + .setDescription("Index of the page to display.").setDefaultValue(1); + } + + @Override + public void handle(Request request, Response response) throws Exception { + String profileKey = request.mandatoryParam(PARAM_KEY); + + DbSession session = dbClient.openSession(false); + + try { + checkProfileExists(profileKey, session); + String selected = request.param(PARAM_SELECTED); + String query = request.param(PARAM_QUERY); + int pageSize = request.mandatoryParamAsInt(PARAM_PAGE_SIZE); + int page = request.mandatoryParamAsInt(PARAM_PAGE); + + List projects = loadProjects(profileKey, session, selected, query); + Collections.sort(projects, new Comparator() { + @Override + public int compare(ProjectQprofileAssociationDto o1, ProjectQprofileAssociationDto o2) { + return new CompareToBuilder() + // First, sort by name + .append(o1.getProjectName(), o2.getProjectName()) + // Then by UUID to disambiguate + .append(o1.getProjectUuid(), o2.getProjectUuid()) + .toComparison(); + } + }); + + Collection projectIds = Collections2.transform(projects, new NonNullInputFunction() { + @Override + protected Long doApply(ProjectQprofileAssociationDto input) { + return input.getProjectId(); + } + }); + + final Collection authorizedProjectIds = dbClient.authorizationDao().keepAuthorizedProjectIds(session, projectIds, userSession.getUserId(), UserRole.USER); + Iterable authorizedProjects = Iterables.filter(projects, new Predicate() { + @Override + public boolean apply(ProjectQprofileAssociationDto input) { + return authorizedProjectIds.contains(input.getProjectId()); + } + }); + + Paging paging = Paging.create(pageSize, page, authorizedProjectIds.size()); + + List pagedAuthorizedProjects = Lists.newArrayList(authorizedProjects); + if (pagedAuthorizedProjects.size() <= paging.offset()) { + pagedAuthorizedProjects = Lists.newArrayList(); + } else if (pagedAuthorizedProjects.size() > paging.pageSize()) { + int endIndex = Math.min(paging.offset() + pageSize, pagedAuthorizedProjects.size()); + pagedAuthorizedProjects = pagedAuthorizedProjects.subList(paging.offset(), endIndex); + } + + writeProjects(response.newJsonWriter(), pagedAuthorizedProjects, paging); + } finally { + session.close(); + } + } + + private void checkProfileExists(String profileKey, DbSession session) { + if (dbClient.qualityProfileDao().getByKey(session, profileKey) == null) { + throw new NotFoundException(String.format("Could not find a quality profile with key '%s'", profileKey)); + } + } + + private List loadProjects(String profileKey, DbSession session, String selected, String query) { + List projects = Lists.newArrayList(); + if (SELECTION_SELECTED.equals(selected)) { + projects.addAll(dbClient.qualityProfileDao().selectSelectedProjects(profileKey, query, session)); + } else if (SELECTION_DESELECTED.equals(selected)) { + projects.addAll(dbClient.qualityProfileDao().selectDeselectedProjects(profileKey, query, session)); + } else { + projects.addAll(dbClient.qualityProfileDao().selectProjectAssociations(profileKey, query, session)); + } + return projects; + } + + private void writeProjects(JsonWriter json, List projects, Paging paging) { + json.beginObject(); + json.name("results").beginArray(); + for (ProjectQprofileAssociationDto project : projects) { + json.beginObject() + .prop("uuid", project.getProjectUuid()) + .prop("name", project.getProjectName()) + .prop("selected", project.isAssociated()) + .endObject(); + } + json.endArray(); + json.prop("more", paging.hasNextPage()); + json.endObject().close(); + } +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileBackupAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileBackupAction.java deleted file mode 100644 index 0bca14c941d..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileBackupAction.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * 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.qualityprofile.ws; - -import org.apache.commons.io.IOUtils; -import org.sonar.api.resources.Languages; -import org.sonar.api.server.ws.Request; -import org.sonar.api.server.ws.Response; -import org.sonar.api.server.ws.Response.Stream; -import org.sonar.api.server.ws.WebService; -import org.sonar.api.server.ws.WebService.NewAction; -import org.sonar.core.persistence.DbSession; -import org.sonar.server.db.DbClient; -import org.sonar.server.plugins.MimeTypes; -import org.sonar.server.qualityprofile.QProfileBackuper; -import org.sonar.server.qualityprofile.QProfileFactory; - -import java.io.OutputStreamWriter; -import java.nio.charset.StandardCharsets; - -public class QProfileBackupAction implements QProfileWsAction { - - private final QProfileBackuper backuper; - - private final DbClient dbClient; - - private QProfileFactory profileFactory; - - private final Languages languages; - - public QProfileBackupAction(QProfileBackuper backuper, DbClient dbClient, QProfileFactory profileFactory, Languages languages) { - this.backuper = backuper; - this.dbClient = dbClient; - this.profileFactory = profileFactory; - this.languages = languages; - } - - @Override - public void define(WebService.NewController controller) { - NewAction backup = controller.createAction("backup") - .setSince("5.2") - .setDescription("Backup a quality profile in XML form. The exported profile can be restored through api/qualityprofiles/restore.") - .setHandler(this); - - QProfileIdentificationParamUtils.defineProfileParams(backup, languages); - } - - @Override - public void handle(Request request, Response response) throws Exception { - Stream stream = response.stream(); - stream.setMediaType(MimeTypes.XML); - OutputStreamWriter writer = new OutputStreamWriter(stream.output(), StandardCharsets.UTF_8); - DbSession session = dbClient.openSession(false); - try { - String profileKey = QProfileIdentificationParamUtils.getProfileKeyFromParameters(request, profileFactory, session); - backuper.backup(profileKey, writer); - } finally { - session.close(); - IOUtils.closeQuietly(writer); - } - } - -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileChangeParentAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileChangeParentAction.java deleted file mode 100644 index 034cddd6346..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileChangeParentAction.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * 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.qualityprofile.ws; - -import com.google.common.base.Preconditions; -import org.sonar.api.resources.Languages; -import org.sonar.api.server.ws.Request; -import org.sonar.api.server.ws.Response; -import org.sonar.api.server.ws.WebService.NewAction; -import org.sonar.api.server.ws.WebService.NewController; -import org.sonar.core.permission.GlobalPermissions; -import org.sonar.core.persistence.DbSession; -import org.sonar.server.db.DbClient; -import org.sonar.server.qualityprofile.QProfileFactory; -import org.sonar.server.qualityprofile.RuleActivator; -import org.sonar.server.user.UserSession; - -import static org.apache.commons.lang.StringUtils.isEmpty; - -public class QProfileChangeParentAction implements QProfileWsAction { - - private static final String PARAM_PARENT_KEY = "parentKey"; - - private static final String PARAM_PARENT_NAME = "parentName"; - - private final DbClient dbClient; - - private final RuleActivator ruleActivator; - - private final QProfileFactory profileFactory; - - private final Languages languages; - private final UserSession userSession; - - public QProfileChangeParentAction(DbClient dbClient, RuleActivator ruleActivator, QProfileFactory profileFactory, Languages languages, UserSession userSession) { - this.dbClient = dbClient; - this.ruleActivator = ruleActivator; - this.profileFactory = profileFactory; - this.languages = languages; - this.userSession = userSession; - } - - @Override - public void define(NewController context) { - NewAction inheritance = context.createAction("change_parent") - .setSince("5.2") - .setPost(true) - .setDescription("Change a quality profile's parent.") - .setHandler(this); - - QProfileIdentificationParamUtils.defineProfileParams(inheritance, languages); - - inheritance.createParam(PARAM_PARENT_KEY) - .setDescription("The key of the new parent profile. If this parameter is set, parentName must not be set. " + - "If both are left empty, the inheritance link with current parent profile (if any) is broken, which deactivates all rules " + - "which come from the parent and are not overridden.") - .setExampleValue("sonar-way-java-12345"); - inheritance.createParam(PARAM_PARENT_NAME) - .setDescription("A quality profile name. If this parameter is set, profileKey must not be set and language must be set to disambiguate.") - .setExampleValue("Sonar way"); - - } - - @Override - public void handle(Request request, Response response) throws Exception { - userSession.checkLoggedIn().checkGlobalPermission(GlobalPermissions.QUALITY_PROFILE_ADMIN); - - DbSession session = dbClient.openSession(false); - try { - String profileKey = QProfileIdentificationParamUtils.getProfileKeyFromParameters(request, profileFactory, session); - String parentKey = getParentKeyFromParameters(request, profileFactory, session); - - ruleActivator.setParent(profileKey, parentKey); - - response.noContent(); - } finally { - session.close(); - } - } - - private static String getParentKeyFromParameters(Request request, QProfileFactory profileFactory, DbSession session) { - String language = request.param(QProfileIdentificationParamUtils.PARAM_LANGUAGE); - String parentName = request.param(PARAM_PARENT_NAME); - String parentKey = request.param(PARAM_PARENT_KEY); - - Preconditions.checkArgument( - isEmpty(parentName) || isEmpty(parentKey), "parentKey and parentName cannot be used simultaneously"); - - if (isEmpty(parentKey)) { - if (!isEmpty(parentName)) { - parentKey = QProfileIdentificationParamUtils.getProfileKeyFromLanguageAndName(language, parentName, profileFactory, session); - } else { - // Empty parent key is treated as "no more parent" - parentKey = null; - } - } - - return parentKey; - } -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileChangelogAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileChangelogAction.java deleted file mode 100644 index 6ad199294d5..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileChangelogAction.java +++ /dev/null @@ -1,169 +0,0 @@ -/* - * 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.qualityprofile.ws; - -import org.elasticsearch.action.search.SearchResponse; -import org.elasticsearch.search.SearchHit; -import org.sonar.api.resources.Languages; -import org.sonar.api.server.ws.*; -import org.sonar.api.server.ws.WebService.NewAction; -import org.sonar.api.server.ws.WebService.NewController; -import org.sonar.api.server.ws.WebService.Param; -import org.sonar.api.utils.DateUtils; -import org.sonar.api.utils.Paging; -import org.sonar.api.utils.text.JsonWriter; -import org.sonar.core.persistence.DbSession; -import org.sonar.core.rule.RuleDto; -import org.sonar.core.user.UserDto; -import org.sonar.server.activity.index.ActivityIndex; -import org.sonar.server.db.DbClient; -import org.sonar.server.es.SearchOptions; -import org.sonar.server.exceptions.NotFoundException; -import org.sonar.server.qualityprofile.QProfileActivity; -import org.sonar.server.qualityprofile.QProfileActivityQuery; -import org.sonar.server.qualityprofile.QProfileFactory; -import org.sonar.server.search.Result; - -import java.util.Date; -import java.util.Map.Entry; - -public class QProfileChangelogAction implements QProfileWsAction { - - private static final String PARAM_SINCE = "since"; - private static final String PARAM_TO = "to"; - - private DbClient dbClient; - private ActivityIndex activityIndex; - private QProfileFactory profileFactory; - private Languages languages; - - public QProfileChangelogAction(DbClient dbClient, ActivityIndex activityIndex, QProfileFactory profileFactory, Languages languages) { - this.dbClient = dbClient; - this.activityIndex = activityIndex; - this.profileFactory = profileFactory; - this.languages = languages; - } - - @Override - public void define(NewController context) { - NewAction changelog = context.createAction("changelog") - .setSince("5.2") - .setDescription("Get the history of changes on a quality profile: rule activation/deactivation, change in parameters/severity. " + - "Events are ordered by date in descending order (most recent first).") - .setHandler(this) - .setResponseExample(getClass().getResource("example-changelog.json")); - - QProfileIdentificationParamUtils.defineProfileParams(changelog, languages); - - changelog.addPagingParams(50); - - changelog.createParam(PARAM_SINCE) - .setDescription("Start date for the changelog.") - .setExampleValue("2011-04-25T01:15:42+0100"); - - changelog.createParam(PARAM_TO) - .setDescription("End date for the changelog.") - .setExampleValue("2013-07-25T07:35:42+0200"); - } - - @Override - public void handle(Request request, Response response) throws Exception { - DbSession session = dbClient.openSession(false); - try { - String profileKey = QProfileIdentificationParamUtils.getProfileKeyFromParameters(request, profileFactory, session); - if (dbClient.qualityProfileDao().getByKey(session, profileKey) == null) { - throw new NotFoundException(String.format("Could not find a profile with key '%s'", profileKey)); - } - - QProfileActivityQuery query = new QProfileActivityQuery().setQprofileKey(profileKey); - Date since = request.paramAsDateTime(PARAM_SINCE); - if (since != null) { - query.setSince(since); - } - Date to = request.paramAsDateTime(PARAM_TO); - if (to != null) { - query.setTo(to); - } - SearchOptions options = new SearchOptions(); - - int page = request.mandatoryParamAsInt(Param.PAGE); - options.setPage(page, request.mandatoryParamAsInt(Param.PAGE_SIZE)); - - Result result = searchActivities(query, options); - writeResponse(response.newJsonWriter(), result, Paging.create(options.getLimit(), page, (int) result.getTotal())); - } finally { - session.close(); - } - } - - private Result searchActivities(QProfileActivityQuery query, SearchOptions options) { - DbSession session = dbClient.openSession(false); - try { - SearchResponse response = activityIndex.doSearch(query, options); - Result result = new Result<>(response); - for (SearchHit hit : response.getHits().getHits()) { - QProfileActivity profileActivity = new QProfileActivity(hit.getSource()); - RuleDto ruleDto = dbClient.ruleDao().getNullableByKey(session, profileActivity.ruleKey()); - profileActivity.ruleName(ruleDto != null ? ruleDto.getName() : null); - - String login = profileActivity.getLogin(); - if (login != null) { - UserDto user = dbClient.userDao().selectActiveUserByLogin(session, login); - profileActivity.authorName(user != null ? user.getName() : null); - } - result.getHits().add(profileActivity); - } - return result; - } finally { - session.close(); - } - } - - private void writeResponse(JsonWriter json, Result result, Paging paging) { - json.beginObject(); - json.prop("total", result.getTotal()); - json.prop(Param.PAGE, paging.pageIndex()); - json.prop(Param.PAGE_SIZE, paging.pageSize()); - json.name("events").beginArray(); - for (QProfileActivity event : result.getHits()) { - json.beginObject() - .prop("date", DateUtils.formatDateTime(event.getCreatedAt())) - .prop("authorLogin", event.getLogin()) - .prop("authorName", event.authorName()) - .prop("action", event.getAction()) - .prop("ruleKey", event.ruleKey().toString()) - .prop("ruleName", event.ruleName()); - writeParameters(json, event); - json.endObject(); - } - json.endArray(); - json.endObject().close(); - } - - private void writeParameters(JsonWriter json, QProfileActivity event) { - json.name("params").beginObject() - .prop("severity", event.severity()); - for (Entry param : event.parameters().entrySet()) { - json.prop(param.getKey(), param.getValue()); - } - json.endObject(); - } - -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileCompareAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileCompareAction.java deleted file mode 100644 index b455ab57d9c..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileCompareAction.java +++ /dev/null @@ -1,221 +0,0 @@ -/* - * 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.qualityprofile.ws; - -import com.google.common.collect.MapDifference.ValueDifference; -import com.google.common.collect.Maps; -import org.sonar.api.resources.Language; -import org.sonar.api.resources.Languages; -import org.sonar.api.rule.RuleKey; -import org.sonar.api.server.ws.Request; -import org.sonar.api.server.ws.Response; -import org.sonar.api.server.ws.WebService.NewAction; -import org.sonar.api.server.ws.WebService.NewController; -import org.sonar.api.utils.text.JsonWriter; -import org.sonar.core.qualityprofile.db.QualityProfileDto; -import org.sonar.core.util.NonNullInputFunction; -import org.sonar.server.qualityprofile.ActiveRule; -import org.sonar.server.qualityprofile.QProfileComparison; -import org.sonar.server.qualityprofile.QProfileComparison.ActiveRuleDiff; -import org.sonar.server.qualityprofile.QProfileComparison.QProfileComparisonResult; -import org.sonar.server.rule.Rule; -import org.sonar.server.rule.RuleRepositories; -import org.sonar.server.rule.RuleRepositories.Repository; -import org.sonar.server.rule.RuleService; - -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; - -public class QProfileCompareAction implements QProfileWsAction { - - private static final String ATTRIBUTE_LEFT = "left"; - private static final String ATTRIBUTE_RIGHT = "right"; - private static final String ATTRIBUTE_IN_LEFT = "inLeft"; - private static final String ATTRIBUTE_IN_RIGHT = "inRight"; - private static final String ATTRIBUTE_MODIFIED = "modified"; - private static final String ATTRIBUTE_SAME = "same"; - private static final String ATTRIBUTE_KEY = "key"; - private static final String ATTRIBUTE_NAME = "name"; - private static final String ATTRIBUTE_SEVERITY = "severity"; - private static final String ATTRIBUTE_PLUGIN_KEY = "pluginKey"; - private static final String ATTRIBUTE_PLUGIN_NAME = "pluginName"; - private static final String ATTRIBUTE_LANGUAGE_KEY = "languageKey"; - private static final String ATTRIBUTE_LANGUAGE_NAME = "languageName"; - private static final String ATTRIBUTE_PARAMS = "params"; - - private static final String PARAM_LEFT_KEY = "leftKey"; - private static final String PARAM_RIGHT_KEY = "rightKey"; - - private final QProfileComparison comparator; - private final RuleService ruleService; - private final RuleRepositories ruleRepositories; - private final Languages languages; - - public QProfileCompareAction(QProfileComparison comparator, RuleService ruleService, RuleRepositories ruleRepositories, Languages languages) { - this.comparator = comparator; - this.ruleService = ruleService; - this.ruleRepositories = ruleRepositories; - this.languages = languages; - } - - @Override - public void define(NewController context) { - NewAction compare = context.createAction("compare") - .setDescription("Compare two quality profiles.") - .setHandler(this) - .setInternal(true) - .setResponseExample(getClass().getResource("example-compare.json")) - .setSince("5.2"); - - compare.createParam(PARAM_LEFT_KEY) - .setDescription("A profile key.") - .setExampleValue("java-sonar-way-12345") - .setRequired(true); - - compare.createParam(PARAM_RIGHT_KEY) - .setDescription("Another profile key.") - .setExampleValue("java-sonar-way-with-findbugs-23456") - .setRequired(true); - } - - @Override - public void handle(Request request, Response response) throws Exception { - String leftKey = request.mandatoryParam(PARAM_LEFT_KEY); - String rightKey = request.mandatoryParam(PARAM_RIGHT_KEY); - - QProfileComparisonResult result = comparator.compare(leftKey, rightKey); - - List referencedRules = ruleService.getByKeys(result.collectRuleKeys()); - Map rulesByKey = Maps.uniqueIndex(referencedRules, new NonNullInputFunction() { - @Override - protected RuleKey doApply(Rule input) { - return input.key(); - } - }); - - writeResult(response.newJsonWriter(), result, rulesByKey); - } - - private void writeResult(JsonWriter json, QProfileComparisonResult result, Map rulesByKey) { - json.beginObject(); - - json.name(ATTRIBUTE_LEFT).beginObject(); - writeProfile(json, result.left()); - json.endObject(); - - json.name(ATTRIBUTE_RIGHT).beginObject(); - writeProfile(json, result.right()); - json.endObject(); - - json.name(ATTRIBUTE_IN_LEFT); - writeRules(json, result.inLeft(), rulesByKey); - - json.name(ATTRIBUTE_IN_RIGHT); - writeRules(json, result.inRight(), rulesByKey); - - json.name(ATTRIBUTE_MODIFIED); - writeDifferences(json, result.modified(), rulesByKey); - - json.name(ATTRIBUTE_SAME); - writeRules(json, result.same(), rulesByKey); - - json.endObject().close(); - } - - private void writeProfile(JsonWriter json, QualityProfileDto profile) { - json.prop(ATTRIBUTE_KEY, profile.getKey()) - .prop(ATTRIBUTE_NAME, profile.getName()); - } - - private void writeRules(JsonWriter json, Map activeRules, Map rulesByKey) { - json.beginArray(); - for (Entry activeRule : activeRules.entrySet()) { - RuleKey key = activeRule.getKey(); - ActiveRule value = activeRule.getValue(); - - json.beginObject(); - writeRule(json, key, rulesByKey); - json.prop(ATTRIBUTE_SEVERITY, value.severity()); - json.endObject(); - } - json.endArray(); - } - - private void writeRule(JsonWriter json, RuleKey key, Map rulesByKey) { - String repositoryKey = key.repository(); - json.prop(ATTRIBUTE_KEY, key.toString()) - .prop(ATTRIBUTE_NAME, rulesByKey.get(key).name()) - .prop(ATTRIBUTE_PLUGIN_KEY, repositoryKey); - - Repository repo = ruleRepositories.repository(repositoryKey); - if (repo != null) { - String languageKey = repo.getLanguage(); - Language language = languages.get(languageKey); - - json.prop(ATTRIBUTE_PLUGIN_NAME, repo.getName()); - json.prop(ATTRIBUTE_LANGUAGE_KEY, languageKey); - json.prop(ATTRIBUTE_LANGUAGE_NAME, language == null ? null : language.getName()); - } - } - - private void writeDifferences(JsonWriter json, Map modified, Map rulesByKey) { - json.beginArray(); - for (Entry diffEntry : modified.entrySet()) { - RuleKey key = diffEntry.getKey(); - ActiveRuleDiff value = diffEntry.getValue(); - json.beginObject(); - writeRule(json, key, rulesByKey); - - json.name(ATTRIBUTE_LEFT).beginObject(); - json.prop(ATTRIBUTE_SEVERITY, value.leftSeverity()); - json.name(ATTRIBUTE_PARAMS).beginObject(); - for (Entry> valueDiff : value.paramDifference().entriesDiffering().entrySet()) { - json.prop(valueDiff.getKey(), valueDiff.getValue().leftValue()); - } - for (Entry valueDiff : value.paramDifference().entriesOnlyOnLeft().entrySet()) { - json.prop(valueDiff.getKey(), valueDiff.getValue()); - } - // params - json.endObject(); - // left - json.endObject(); - - json.name(ATTRIBUTE_RIGHT).beginObject(); - json.prop(ATTRIBUTE_SEVERITY, value.rightSeverity()); - json.name(ATTRIBUTE_PARAMS).beginObject(); - for (Entry> valueDiff : value.paramDifference().entriesDiffering().entrySet()) { - json.prop(valueDiff.getKey(), valueDiff.getValue().rightValue()); - } - for (Entry valueDiff : value.paramDifference().entriesOnlyOnRight().entrySet()) { - json.prop(valueDiff.getKey(), valueDiff.getValue()); - } - // params - json.endObject(); - // right - json.endObject(); - - // rule - json.endObject(); - } - json.endArray(); - } - -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileCopyAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileCopyAction.java deleted file mode 100644 index 99b0a5c862f..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileCopyAction.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * 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.qualityprofile.ws; - -import org.sonar.api.resources.Language; -import org.sonar.api.resources.Languages; -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.server.ws.WebService.NewAction; -import org.sonar.core.permission.GlobalPermissions; -import org.sonar.core.qualityprofile.db.QualityProfileDto; -import org.sonar.server.qualityprofile.QProfileCopier; -import org.sonar.server.user.UserSession; - -public class QProfileCopyAction implements QProfileWsAction { - - private static final String PARAM_PROFILE_NAME = "toName"; - private static final String PARAM_PROFILE_KEY = "fromKey"; - - private final QProfileCopier profileCopier; - private final Languages languages; - private final UserSession userSession; - - public QProfileCopyAction(QProfileCopier profileCopier, Languages languages, UserSession userSession) { - this.profileCopier = profileCopier; - this.languages = languages; - this.userSession = userSession; - } - - @Override - public void define(WebService.NewController controller) { - NewAction setDefault = controller.createAction("copy") - .setSince("5.2") - .setDescription("Copy a quality profile.") - .setPost(true) - .setHandler(this); - - setDefault.createParam(PARAM_PROFILE_NAME) - .setDescription("The name for the new quality profile.") - .setExampleValue("My Sonar way") - .setRequired(true); - - setDefault.createParam(PARAM_PROFILE_KEY) - .setDescription("The key of a quality profile.") - .setExampleValue("sonar-way-js-12345") - .setRequired(true); - } - - @Override - public void handle(Request request, Response response) throws Exception { - userSession.checkLoggedIn().checkGlobalPermission(GlobalPermissions.QUALITY_PROFILE_ADMIN); - - String newName = request.mandatoryParam(PARAM_PROFILE_NAME); - String profileKey = request.mandatoryParam(PARAM_PROFILE_KEY); - - QualityProfileDto copiedProfile = profileCopier.copyToName(profileKey, newName); - - String languageKey = copiedProfile.getLanguage(); - Language language = languages.get(copiedProfile.getLanguage()); - String parentKey = copiedProfile.getParentKee(); - response.newJsonWriter() - .beginObject() - .prop("key", copiedProfile.getKey()) - .prop("name", copiedProfile.getName()) - .prop("language", languageKey) - .prop("languageName", language == null ? null : language.getName()) - .prop("isDefault", copiedProfile.isDefault()) - .prop("isInherited", parentKey != null) - .prop("parentKey", parentKey) - .endObject().close(); - } -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileCreateAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileCreateAction.java deleted file mode 100644 index 18b7b821f28..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileCreateAction.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * 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.qualityprofile.ws; - -import org.sonar.api.profiles.ProfileImporter; -import org.sonar.api.resources.Languages; -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.server.ws.WebService.NewAction; -import org.sonar.api.utils.text.JsonWriter; -import org.sonar.core.permission.GlobalPermissions; -import org.sonar.core.persistence.DbSession; -import org.sonar.core.qualityprofile.db.QualityProfileDto; -import org.sonar.server.db.DbClient; -import org.sonar.server.qualityprofile.QProfileExporters; -import org.sonar.server.qualityprofile.QProfileFactory; -import org.sonar.server.qualityprofile.QProfileName; -import org.sonar.server.qualityprofile.QProfileResult; - -import java.io.InputStream; -import org.sonar.server.user.UserSession; - -public class QProfileCreateAction implements QProfileWsAction { - - private static final String PARAM_PROFILE_NAME = "name"; - private static final String PARAM_LANGUAGE = "language"; - private static final String PARAM_BACKUP_FORMAT = "backup_%s"; - - private final DbClient dbClient; - - private final QProfileFactory profileFactory; - - private final QProfileExporters exporters; - - private final Languages languages; - - private final ProfileImporter[] importers; - private final UserSession userSession; - - public QProfileCreateAction(DbClient dbClient, QProfileFactory profileFactory, QProfileExporters exporters, - Languages languages, ProfileImporter[] importers, UserSession userSession) { - this.dbClient = dbClient; - this.profileFactory = profileFactory; - this.exporters = exporters; - this.languages = languages; - this.importers = importers; - this.userSession = userSession; - } - - public QProfileCreateAction(DbClient dbClient, QProfileFactory profileFactory, QProfileExporters exporters, Languages languages, UserSession userSession) { - this(dbClient, profileFactory, exporters, languages, new ProfileImporter[0], userSession); - } - - @Override - public void define(WebService.NewController controller) { - NewAction create = controller.createAction("create") - .setSince("5.2") - .setDescription("Create a quality profile.") - .setPost(true) - .setResponseExample(getClass().getResource("example-create.json")) - .setHandler(this); - - create.createParam(PARAM_PROFILE_NAME) - .setDescription("The name for the new quality profile.") - .setExampleValue("My Sonar way") - .setRequired(true); - - create.createParam(PARAM_LANGUAGE) - .setDescription("The language for the quality profile.") - .setExampleValue("js") - .setPossibleValues(LanguageParamUtils.getLanguageKeys(languages)) - .setRequired(true); - - for (ProfileImporter importer : importers) { - create.createParam(getBackupParamName(importer.getKey())) - .setDescription(String.format("A configuration file for %s.", importer.getName())); - } - } - - @Override - public void handle(Request request, Response response) throws Exception { - userSession.checkLoggedIn().checkGlobalPermission(GlobalPermissions.QUALITY_PROFILE_ADMIN); - - String name = request.mandatoryParam(PARAM_PROFILE_NAME); - String language = request.mandatoryParam(PARAM_LANGUAGE); - - DbSession dbSession = dbClient.openSession(false); - - try { - QProfileResult result = new QProfileResult(); - QualityProfileDto profile = profileFactory.create(dbSession, QProfileName.createFor(language, name)); - result.setProfile(profile); - for (ProfileImporter importer : importers) { - InputStream contentToImport = request.paramAsInputStream(getBackupParamName(importer.getKey())); - if (contentToImport != null) { - result.add(exporters.importXml(profile, importer.getKey(), contentToImport, dbSession)); - } - } - dbSession.commit(); - writeResult(response.newJsonWriter(), result); - } finally { - dbSession.close(); - } - } - - private void writeResult(JsonWriter json, QProfileResult result) { - String language = result.profile().getLanguage(); - json.beginObject().name("profile").beginObject() - .prop("key", result.profile().getKey()) - .prop("name", result.profile().getName()) - .prop("language", language) - .prop("languageName", languages.get(result.profile().getLanguage()).getName()) - .prop("isDefault", false) - .prop("isInherited", false) - .endObject(); - - if (!result.infos().isEmpty()) { - json.name("infos").beginArray(); - for (String info : result.infos()) { - json.value(info); - } - json.endArray(); - } - - if (!result.warnings().isEmpty()) { - json.name("warnings").beginArray(); - for (String warning : result.warnings()) { - json.value(warning); - } - json.endArray(); - } - - json.endObject().close(); - } - - private String getBackupParamName(String importerKey) { - return String.format(PARAM_BACKUP_FORMAT, importerKey); - } -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileDeleteAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileDeleteAction.java deleted file mode 100644 index 800031e6780..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileDeleteAction.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * 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.qualityprofile.ws; - -import org.sonar.api.resources.Languages; -import org.sonar.api.server.ws.Request; -import org.sonar.api.server.ws.Response; -import org.sonar.api.server.ws.WebService.NewAction; -import org.sonar.api.server.ws.WebService.NewController; -import org.sonar.core.permission.GlobalPermissions; -import org.sonar.core.persistence.DbSession; -import org.sonar.server.db.DbClient; -import org.sonar.server.qualityprofile.QProfileFactory; -import org.sonar.server.user.UserSession; - -public class QProfileDeleteAction implements QProfileWsAction { - - private final Languages languages; - private final QProfileFactory profileFactory; - private final DbClient dbClient; - private final UserSession userSession; - - public QProfileDeleteAction(Languages languages, QProfileFactory profileFactory, DbClient dbClient, UserSession userSession) { - this.languages = languages; - this.profileFactory = profileFactory; - this.dbClient = dbClient; - this.userSession = userSession; - } - - @Override - public void define(NewController controller) { - NewAction action = controller.createAction("delete") - .setDescription("Delete a quality profile and all its descendants. The default quality profile cannot be deleted.") - .setSince("5.2") - .setPost(true) - .setHandler(this); - - QProfileIdentificationParamUtils.defineProfileParams(action, languages); - } - - - @Override - public void handle(Request request, Response response) throws Exception { - userSession.checkLoggedIn(); - userSession.checkGlobalPermission(GlobalPermissions.QUALITY_PROFILE_ADMIN); - - - DbSession session = dbClient.openSession(false); - try { - String profileKey = QProfileIdentificationParamUtils.getProfileKeyFromParameters(request, profileFactory, session); - profileFactory.delete(session, profileKey, false); - - session.commit(); - } finally { - session.close(); - } - - response.noContent(); - } -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileExportAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileExportAction.java deleted file mode 100644 index 1750393c147..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileExportAction.java +++ /dev/null @@ -1,141 +0,0 @@ -/* - * 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.qualityprofile.ws; - -import com.google.common.collect.Lists; -import org.apache.commons.io.IOUtils; -import org.sonar.api.profiles.ProfileExporter; -import org.sonar.api.resources.Language; -import org.sonar.api.resources.Languages; -import org.sonar.api.server.ws.Request; -import org.sonar.api.server.ws.Response; -import org.sonar.api.server.ws.Response.Stream; -import org.sonar.api.server.ws.WebService; -import org.sonar.api.server.ws.WebService.NewAction; -import org.sonar.core.persistence.DbSession; -import org.sonar.core.qualityprofile.db.QualityProfileDto; -import org.sonar.server.db.DbClient; -import org.sonar.server.exceptions.NotFoundException; -import org.sonar.server.plugins.MimeTypes; -import org.sonar.server.qualityprofile.QProfileBackuper; -import org.sonar.server.qualityprofile.QProfileExporters; -import org.sonar.server.qualityprofile.QProfileFactory; - -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.Writer; -import java.nio.charset.StandardCharsets; -import java.util.List; - -public class QProfileExportAction implements QProfileWsAction { - - private static final String PARAM_PROFILE_NAME = "name"; - private static final String PARAM_LANGUAGE = "language"; - private static final String PARAM_FORMAT = "exporterKey"; - - private final DbClient dbClient; - - private final QProfileFactory profileFactory; - - private final QProfileBackuper backuper; - - private final QProfileExporters exporters; - - private final Languages languages; - - public QProfileExportAction(DbClient dbClient, QProfileFactory profileFactory, QProfileBackuper backuper, QProfileExporters exporters, Languages languages) { - this.dbClient = dbClient; - this.profileFactory = profileFactory; - this.backuper = backuper; - this.exporters = exporters; - this.languages = languages; - } - - @Override - public void define(WebService.NewController controller) { - NewAction create = controller.createAction("export") - .setSince("5.2") - .setDescription("Export a quality profile.") - .setHandler(this); - - create.createParam(PARAM_PROFILE_NAME) - .setDescription("The name of the quality profile to export. If left empty, will export the default profile for the language.") - .setExampleValue("My Sonar way"); - - create.createParam(PARAM_LANGUAGE) - .setDescription("The language for the quality profile.") - .setExampleValue(LanguageParamUtils.getExampleValue(languages)) - .setPossibleValues(LanguageParamUtils.getLanguageKeys(languages)) - .setRequired(true); - - List exporterKeys = Lists.newArrayList(); - for (Language lang : languages.all()) { - for (ProfileExporter exporter : exporters.exportersForLanguage(lang.getKey())) { - exporterKeys.add(exporter.getKey()); - } - } - if (!exporterKeys.isEmpty()) { - create.createParam(PARAM_FORMAT) - .setDescription("Output format. If left empty, the same format as api/qualityprofiles/backup is used. " + - "Possible values are described by api/qualityprofiles/exporters.") - .setPossibleValues(exporterKeys); - } - } - - @Override - public void handle(Request request, Response response) throws Exception { - String name = request.param(PARAM_PROFILE_NAME); - String language = request.mandatoryParam(PARAM_LANGUAGE); - String format = null; - if (!exporters.exportersForLanguage(language).isEmpty()) { - format = request.param(PARAM_FORMAT); - } - - DbSession dbSession = dbClient.openSession(false); - Stream stream = response.stream(); - OutputStream output = stream.output(); - Writer writer = new OutputStreamWriter(output, StandardCharsets.UTF_8); - - try { - QualityProfileDto profile; - if (name == null) { - profile = profileFactory.getDefault(dbSession, language); - } else { - profile = profileFactory.getByNameAndLanguage(dbSession, name, language); - } - if (profile == null) { - throw new NotFoundException(String.format("Could not find profile with name '%s' for language '%s'", name, language)); - } - - String profileKey = profile.getKey(); - if (format == null) { - stream.setMediaType(MimeTypes.XML); - backuper.backup(profileKey, writer); - } else { - stream.setMediaType(exporters.mimeType(format)); - exporters.export(profileKey, format, writer); - } - } finally { - IOUtils.closeQuietly(writer); - IOUtils.closeQuietly(output); - dbSession.close(); - } - } -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileExportersAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileExportersAction.java deleted file mode 100644 index fff90fc19c0..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileExportersAction.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * 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.qualityprofile.ws; - -import org.sonar.api.profiles.ProfileExporter; -import org.sonar.api.server.ws.Request; -import org.sonar.api.server.ws.Response; -import org.sonar.api.server.ws.WebService.NewController; -import org.sonar.api.utils.text.JsonWriter; - -public class QProfileExportersAction implements QProfileWsAction { - - private ProfileExporter[] exporters; - - public QProfileExportersAction(ProfileExporter[] exporters) { - this.exporters = exporters; - } - - public QProfileExportersAction() { - this(new ProfileExporter[0]); - } - - @Override - public void define(NewController context) { - context.createAction("exporters") - .setDescription("Lists available profile export formats.") - .setHandler(this) - .setResponseExample(getClass().getResource("example-exporters.json")) - .setSince("5.2"); - } - - @Override - public void handle(Request request, Response response) throws Exception { - JsonWriter json = response.newJsonWriter().beginObject().name("exporters").beginArray(); - for (ProfileExporter exporter : exporters) { - json.beginObject() - .prop("key", exporter.getKey()) - .prop("name", exporter.getName()); - json.name("languages").beginArray(); - for (String language : exporter.getSupportedLanguages()) { - json.value(language); - } - json.endArray().endObject(); - } - json.endArray().endObject().close(); - } - -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileImportersAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileImportersAction.java deleted file mode 100644 index dba30bfb00f..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileImportersAction.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * 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.qualityprofile.ws; - -import org.sonar.api.profiles.ProfileImporter; -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; - -public class QProfileImportersAction implements QProfileWsAction { - - private final ProfileImporter[] importers; - - public QProfileImportersAction(ProfileImporter[] importers) { - this.importers = importers; - } - - public QProfileImportersAction() { - this(new ProfileImporter[0]); - } - - @Override - public void define(WebService.NewController controller) { - controller.createAction("importers") - .setSince("5.2") - .setDescription("List supported importers.") - .setResponseExample(getClass().getResource("example-importers.json")) - .setHandler(this); - } - - @Override - public void handle(Request request, Response response) throws Exception { - JsonWriter json = response.newJsonWriter().beginObject().name("importers").beginArray(); - for (ProfileImporter importer : importers) { - json.beginObject() - .prop("key", importer.getKey()) - .prop("name", importer.getName()) - .name("languages").beginArray(); - for (String languageKey : importer.getSupportedLanguages()) { - json.value(languageKey); - } - json.endArray().endObject(); - } - json.endArray().endObject().close(); - } -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileInheritanceAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileInheritanceAction.java deleted file mode 100644 index fd1790e2fe8..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileInheritanceAction.java +++ /dev/null @@ -1,169 +0,0 @@ -/* - * 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.qualityprofile.ws; - -import com.google.common.collect.Multimap; -import org.sonar.api.resources.Languages; -import org.sonar.api.server.ws.Request; -import org.sonar.api.server.ws.Response; -import org.sonar.api.server.ws.WebService.NewAction; -import org.sonar.api.server.ws.WebService.NewController; -import org.sonar.api.utils.text.JsonWriter; -import org.sonar.core.persistence.DbSession; -import org.sonar.core.qualityprofile.db.QualityProfileDto; -import org.sonar.server.db.DbClient; -import org.sonar.server.exceptions.NotFoundException; -import org.sonar.server.qualityprofile.QProfile; -import org.sonar.server.qualityprofile.QProfileFactory; -import org.sonar.server.qualityprofile.QProfileLoader; -import org.sonar.server.qualityprofile.QProfileLookup; -import org.sonar.server.qualityprofile.index.ActiveRuleIndex; -import org.sonar.server.qualityprofile.index.ActiveRuleNormalizer; -import org.sonar.server.search.FacetValue; - -import javax.annotation.Nullable; - -import java.util.List; -import java.util.Map; - -public class QProfileInheritanceAction implements QProfileWsAction { - - private final DbClient dbClient; - - private final QProfileLookup profileLookup; - - private final QProfileLoader profileLoader; - - private final QProfileFactory profileFactory; - - private final Languages languages; - - public QProfileInheritanceAction(DbClient dbClient, QProfileLookup profileLookup, QProfileLoader profileLoader, QProfileFactory profileFactory, Languages languages) { - this.dbClient = dbClient; - this.profileLookup = profileLookup; - this.profileLoader = profileLoader; - this.profileFactory = profileFactory; - this.languages = languages; - } - - @Override - public void define(NewController context) { - NewAction inheritance = context.createAction("inheritance") - .setSince("5.2") - .setDescription("Show a quality profile's ancestors and children.") - .setHandler(this) - .setResponseExample(getClass().getResource("example-inheritance.json")); - - QProfileIdentificationParamUtils.defineProfileParams(inheritance, languages); - } - - @Override - public void handle(Request request, Response response) throws Exception { - DbSession session = dbClient.openSession(false); - try { - String profileKey = QProfileIdentificationParamUtils.getProfileKeyFromParameters(request, profileFactory, session); - QualityProfileDto profile = dbClient.qualityProfileDao().getByKey(session, profileKey); - if (profile == null) { - throw new NotFoundException(String.format("Could not find a quality profile with key %s", profileKey)); - } - - List ancestors = profileLookup.ancestors(profile, session); - List children = dbClient.qualityProfileDao().findChildren(session, profileKey); - Map> profileStats = profileLoader.getAllProfileStats(); - - writeResponse(response.newJsonWriter(), profile, ancestors, children, profileStats); - } finally { - session.close(); - } - } - - private void writeResponse(JsonWriter json, QualityProfileDto profile, List ancestors, List children, - Map> profileStats) { - json.beginObject(); - writeProfile(json, profile, profileStats); - writeAncestors(json, ancestors, profileStats); - writeChildren(json, children, profileStats); - json.endObject().close(); - } - - private void writeProfile(JsonWriter json, QualityProfileDto profile, Map> profileStats) { - String profileKey = profile.getKey(); - json.name("profile"); - writeProfileAttributes(json, profileKey, profile.getName(), profile.getParentKee(), profileStats); - } - - private void writeAncestors(JsonWriter json, List ancestors, Map> profileStats) { - json.name("ancestors").beginArray(); - for (QProfile ancestor : ancestors) { - String ancestorKey = ancestor.key(); - writeProfileAttributes(json, ancestorKey, ancestor.name(), ancestor.parent(), profileStats); - } - json.endArray(); - } - - private void writeChildren(JsonWriter json, List children, Map> profileStats) { - json.name("children").beginArray(); - for (QualityProfileDto child : children) { - String childKey = child.getKey(); - writeProfileAttributes(json, childKey, child.getName(), null, profileStats); - } - json.endArray(); - } - - private void writeProfileAttributes(JsonWriter json, String key, String name, @Nullable String parentKey, Map> profileStats) { - json.beginObject(); - json.prop("key", key) - .prop("name", name) - .prop("parent", parentKey); - writeStats(json, key, profileStats); - json.endObject(); - } - - private void writeStats(JsonWriter json, String profileKey, Map> profileStats) { - if (profileStats.containsKey(profileKey)) { - Multimap ancestorStats = profileStats.get(profileKey); - json.prop("activeRuleCount", getActiveRuleCount(ancestorStats)); - json.prop("overridingRuleCount", getOverridingRuleCount(ancestorStats)); - } else { - json.prop("activeRuleCount", 0); - } - } - - private Long getActiveRuleCount(Multimap profileStats) { - Long result = null; - if (profileStats.containsKey(ActiveRuleIndex.COUNT_ACTIVE_RULES)) { - result = profileStats.get(ActiveRuleIndex.COUNT_ACTIVE_RULES).iterator().next().getValue(); - } - return result; - } - - private Long getOverridingRuleCount(Multimap profileStats) { - Long result = null; - if (profileStats.containsKey(ActiveRuleNormalizer.ActiveRuleField.INHERITANCE.field())) { - for (FacetValue value : profileStats.get(ActiveRuleNormalizer.ActiveRuleField.INHERITANCE.field())) { - if ("OVERRIDES".equals(value.getKey())) { - result = value.getValue(); - } - } - } - return result; - } - -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileProjectsAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileProjectsAction.java deleted file mode 100644 index c36b90a3e77..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileProjectsAction.java +++ /dev/null @@ -1,177 +0,0 @@ -/* - * 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.qualityprofile.ws; - -import com.google.common.base.Predicate; -import com.google.common.collect.Collections2; -import com.google.common.collect.Iterables; -import com.google.common.collect.Lists; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; -import org.apache.commons.lang.builder.CompareToBuilder; -import org.sonar.api.server.ws.Request; -import org.sonar.api.server.ws.Response; -import org.sonar.api.server.ws.WebService.NewAction; -import org.sonar.api.server.ws.WebService.NewController; -import org.sonar.api.utils.Paging; -import org.sonar.api.utils.text.JsonWriter; -import org.sonar.api.web.UserRole; -import org.sonar.core.persistence.DbSession; -import org.sonar.core.qualityprofile.db.ProjectQprofileAssociationDto; -import org.sonar.core.util.NonNullInputFunction; -import org.sonar.server.db.DbClient; -import org.sonar.server.exceptions.NotFoundException; -import org.sonar.server.user.UserSession; - -public class QProfileProjectsAction implements QProfileWsAction { - - private static final String PARAM_KEY = "key"; - private static final String PARAM_SELECTED = "selected"; - private static final String PARAM_QUERY = "query"; - private static final String PARAM_PAGE_SIZE = "pageSize"; - private static final String PARAM_PAGE = "page"; - - private static final String SELECTION_ALL = "all"; - private static final String SELECTION_SELECTED = "selected"; - private static final String SELECTION_DESELECTED = "deselected"; - - private final DbClient dbClient; - private final UserSession userSession; - - public QProfileProjectsAction(DbClient dbClient, UserSession userSession) { - this.dbClient = dbClient; - this.userSession = userSession; - } - - @Override - public void define(NewController controller) { - NewAction projects = controller.createAction("projects") - .setSince("5.2") - .setHandler(this) - .setDescription("List projects with their association status regarding a quality profile.") - .setResponseExample(getClass().getResource("example-projects.json")); - projects.createParam(PARAM_KEY) - .setDescription("A quality profile key.") - .setRequired(true) - .setExampleValue("sonar-way-java-12345"); - projects.createParam(PARAM_SELECTED) - .setDescription("If specified, return only selected or deselected projects.") - .setPossibleValues(SELECTION_SELECTED, SELECTION_DESELECTED, SELECTION_ALL) - .setDefaultValue(SELECTION_ALL); - projects.createParam(PARAM_QUERY) - .setDescription("If specified, return only projects whose name match the query."); - projects.createParam(PARAM_PAGE_SIZE) - .setDescription("Size for the paging to apply.").setDefaultValue(100); - projects.createParam(PARAM_PAGE) - .setDescription("Index of the page to display.").setDefaultValue(1); - } - - @Override - public void handle(Request request, Response response) throws Exception { - String profileKey = request.mandatoryParam(PARAM_KEY); - - DbSession session = dbClient.openSession(false); - - try { - checkProfileExists(profileKey, session); - String selected = request.param(PARAM_SELECTED); - String query = request.param(PARAM_QUERY); - int pageSize = request.mandatoryParamAsInt(PARAM_PAGE_SIZE); - int page = request.mandatoryParamAsInt(PARAM_PAGE); - - List projects = loadProjects(profileKey, session, selected, query); - Collections.sort(projects, new Comparator() { - @Override - public int compare(ProjectQprofileAssociationDto o1, ProjectQprofileAssociationDto o2) { - return new CompareToBuilder() - // First, sort by name - .append(o1.getProjectName(), o2.getProjectName()) - // Then by UUID to disambiguate - .append(o1.getProjectUuid(), o2.getProjectUuid()) - .toComparison(); - } - }); - - Collection projectIds = Collections2.transform(projects, new NonNullInputFunction() { - @Override - protected Long doApply(ProjectQprofileAssociationDto input) { - return input.getProjectId(); - } - }); - - final Collection authorizedProjectIds = dbClient.authorizationDao().keepAuthorizedProjectIds(session, projectIds, userSession.getUserId(), UserRole.USER); - Iterable authorizedProjects = Iterables.filter(projects, new Predicate() { - @Override - public boolean apply(ProjectQprofileAssociationDto input) { - return authorizedProjectIds.contains(input.getProjectId()); - } - }); - - Paging paging = Paging.create(pageSize, page, authorizedProjectIds.size()); - - List pagedAuthorizedProjects = Lists.newArrayList(authorizedProjects); - if (pagedAuthorizedProjects.size() <= paging.offset()) { - pagedAuthorizedProjects = Lists.newArrayList(); - } else if (pagedAuthorizedProjects.size() > paging.pageSize()) { - int endIndex = Math.min(paging.offset() + pageSize, pagedAuthorizedProjects.size()); - pagedAuthorizedProjects = pagedAuthorizedProjects.subList(paging.offset(), endIndex); - } - - writeProjects(response.newJsonWriter(), pagedAuthorizedProjects, paging); - } finally { - session.close(); - } - } - - private void checkProfileExists(String profileKey, DbSession session) { - if (dbClient.qualityProfileDao().getByKey(session, profileKey) == null) { - throw new NotFoundException(String.format("Could not find a quality profile with key '%s'", profileKey)); - } - } - - private List loadProjects(String profileKey, DbSession session, String selected, String query) { - List projects = Lists.newArrayList(); - if (SELECTION_SELECTED.equals(selected)) { - projects.addAll(dbClient.qualityProfileDao().selectSelectedProjects(profileKey, query, session)); - } else if (SELECTION_DESELECTED.equals(selected)) { - projects.addAll(dbClient.qualityProfileDao().selectDeselectedProjects(profileKey, query, session)); - } else { - projects.addAll(dbClient.qualityProfileDao().selectProjectAssociations(profileKey, query, session)); - } - return projects; - } - - private void writeProjects(JsonWriter json, List projects, Paging paging) { - json.beginObject(); - json.name("results").beginArray(); - for (ProjectQprofileAssociationDto project : projects) { - json.beginObject() - .prop("uuid", project.getProjectUuid()) - .prop("name", project.getProjectName()) - .prop("selected", project.isAssociated()) - .endObject(); - } - json.endArray(); - json.prop("more", paging.hasNextPage()); - json.endObject().close(); - } -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileRenameAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileRenameAction.java deleted file mode 100644 index 65ef7a3b8d1..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileRenameAction.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * 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.qualityprofile.ws; - -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.server.ws.WebService.NewAction; -import org.sonar.core.permission.GlobalPermissions; -import org.sonar.server.qualityprofile.QProfileFactory; -import org.sonar.server.user.UserSession; - -public class QProfileRenameAction implements QProfileWsAction { - - private static final String PARAM_PROFILE_NAME = "name"; - private static final String PARAM_PROFILE_KEY = "key"; - - private final QProfileFactory profileFactory; - private final UserSession userSession; - - public QProfileRenameAction(QProfileFactory profileFactory, UserSession userSession) { - this.profileFactory = profileFactory; - this.userSession = userSession; - } - - @Override - public void define(WebService.NewController controller) { - NewAction setDefault = controller.createAction("rename") - .setSince("5.2") - .setDescription("Rename a quality profile.") - .setPost(true) - .setHandler(this); - - setDefault.createParam(PARAM_PROFILE_NAME) - .setDescription("The new name for the quality profile.") - .setExampleValue("My Sonar way") - .setRequired(true); - - setDefault.createParam(PARAM_PROFILE_KEY) - .setDescription("The key of a quality profile.") - .setExampleValue("sonar-way-js-12345") - .setRequired(true); - } - - @Override - public void handle(Request request, Response response) throws Exception { - userSession.checkLoggedIn().checkGlobalPermission(GlobalPermissions.QUALITY_PROFILE_ADMIN); - - String newName = request.mandatoryParam(PARAM_PROFILE_NAME); - String profileKey = request.mandatoryParam(PARAM_PROFILE_KEY); - - profileFactory.rename(profileKey, newName); - - response.noContent(); - } -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileRestoreAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileRestoreAction.java deleted file mode 100644 index 621bf9473f0..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileRestoreAction.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * 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.qualityprofile.ws; - -import com.google.common.base.Preconditions; -import org.apache.commons.io.IOUtils; -import org.sonar.api.resources.Languages; -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.core.permission.GlobalPermissions; -import org.sonar.core.qualityprofile.db.QualityProfileDto; -import org.sonar.server.qualityprofile.BulkChangeResult; -import org.sonar.server.qualityprofile.QProfileBackuper; -import org.sonar.server.user.UserSession; - -import java.io.InputStream; -import java.io.InputStreamReader; -import java.nio.charset.StandardCharsets; - -public class QProfileRestoreAction implements QProfileWsAction { - - private static final String PARAM_BACKUP = "backup"; - private final QProfileBackuper backuper; - private final Languages languages; - private final UserSession userSession; - - public QProfileRestoreAction(QProfileBackuper backuper, Languages languages, UserSession userSession) { - this.backuper = backuper; - this.languages = languages; - this.userSession = userSession; - } - - @Override - public void define(WebService.NewController controller) { - controller.createAction("restore") - .setSince("5.2") - .setDescription("Restore a quality profile using an XML file. The restored profile name is taken from the backup file, " - + "so if a profile with the same name and language already exists, it will be overwritten.") - .setPost(true) - .setHandler(this) - .createParam(PARAM_BACKUP) - .setDescription("A profile backup file in XML format, as generated by api/qualityprofiles/backup " + - "or the former api/profiles/backup.") - .setRequired(true); - } - - @Override - public void handle(Request request, Response response) throws Exception { - userSession.checkLoggedIn().checkGlobalPermission(GlobalPermissions.QUALITY_PROFILE_ADMIN); - InputStream backup = request.paramAsInputStream(PARAM_BACKUP); - InputStreamReader reader = null; - - try { - Preconditions.checkArgument(backup != null, "A backup file must be provided"); - reader = new InputStreamReader(backup, StandardCharsets.UTF_8); - BulkChangeResult result = backuper.restore(reader, null); - writeResponse(response.newJsonWriter(), result); - } finally { - IOUtils.closeQuietly(reader); - IOUtils.closeQuietly(backup); - } - } - - private void writeResponse(JsonWriter json, BulkChangeResult result) { - QualityProfileDto profile = result.profile(); - if (profile != null) { - String language = profile.getLanguage(); - json.beginObject().name("profile").beginObject() - .prop("key", profile.getKey()) - .prop("name", profile.getName()) - .prop("language", language) - .prop("languageName", languages.get(profile.getLanguage()).getName()) - .prop("isDefault", false) - .prop("isInherited", false) - .endObject(); - } - json.prop("ruleSuccesses", result.countSucceeded()); - json.prop("ruleFailures", result.countFailed()); - json.endObject().close(); - } -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileRestoreBuiltInAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileRestoreBuiltInAction.java deleted file mode 100644 index 9127ebefd45..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileRestoreBuiltInAction.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * 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.qualityprofile.ws; - -import org.sonar.api.server.ws.Request; -import org.sonar.api.server.ws.Response; -import org.sonar.api.server.ws.WebService; -import org.sonar.server.qualityprofile.QProfileService; - -public class QProfileRestoreBuiltInAction implements QProfileWsAction { - - private final QProfileService service; - - public QProfileRestoreBuiltInAction(QProfileService service) { - this.service = service; - } - - @Override - public void define(WebService.NewController controller) { - WebService.NewAction restoreDefault = controller.createAction("restore_built_in") - .setDescription("Restore built-in profiles from the definitions declared by plugins. " + - "Missing profiles are created, existing ones are updated.") - .setSince("4.4") - .setPost(true) - .setHandler(this); - restoreDefault.createParam("language") - .setDescription("Restore the built-in profiles defined for this language") - .setExampleValue("java") - .setRequired(true); - } - - @Override - public void handle(Request request, Response response) { - String language = request.mandatoryParam("language"); - service.restoreBuiltInProfilesForLanguage(language); - response.noContent(); - } - -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileSearchAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileSearchAction.java deleted file mode 100644 index 7a2580ec02f..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileSearchAction.java +++ /dev/null @@ -1,192 +0,0 @@ -/* - * 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.qualityprofile.ws; - -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Maps; -import org.apache.commons.lang.builder.CompareToBuilder; -import org.sonar.api.resources.Languages; -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.server.ws.WebService.NewAction; -import org.sonar.api.server.ws.WebService.Param; -import org.sonar.api.utils.text.JsonWriter; -import org.sonar.core.qualityprofile.db.QualityProfileDao; -import org.sonar.core.util.NonNullInputFunction; -import org.sonar.server.qualityprofile.QProfile; -import org.sonar.server.qualityprofile.QProfileLoader; -import org.sonar.server.qualityprofile.QProfileLookup; - -import javax.annotation.CheckForNull; -import javax.annotation.Nullable; - -import java.util.Collections; -import java.util.Comparator; -import java.util.List; -import java.util.Map; -import java.util.Set; - -public class QProfileSearchAction implements QProfileWsAction { - - private static final String FIELD_KEY = "key"; - private static final String FIELD_NAME = "name"; - private static final String FIELD_LANGUAGE = "language"; - private static final String FIELD_LANGUAGE_NAME = "languageName"; - private static final String FIELD_IS_INHERITED = "isInherited"; - private static final String FIELD_IS_DEFAULT = "isDefault"; - private static final String FIELD_PARENT_KEY = "parentKey"; - private static final String FIELD_PARENT_NAME = "parentName"; - private static final String FIELD_ACTIVE_RULE_COUNT = "activeRuleCount"; - private static final String FIELD_PROJECT_COUNT = "projectCount"; - - private static final Set ALL_FIELDS = ImmutableSet.of( - FIELD_KEY, FIELD_NAME, FIELD_LANGUAGE, FIELD_LANGUAGE_NAME, FIELD_IS_INHERITED, FIELD_PARENT_KEY, FIELD_PARENT_NAME, FIELD_IS_DEFAULT, FIELD_ACTIVE_RULE_COUNT, - FIELD_PROJECT_COUNT); - - private static final String PARAM_LANGUAGE = FIELD_LANGUAGE; - - private final Languages languages; - - private final QProfileLookup profileLookup; - - private final QProfileLoader profileLoader; - - private final QualityProfileDao qualityProfileDao; - - public QProfileSearchAction(Languages languages, QProfileLookup profileLookup, QProfileLoader profileLoader, QualityProfileDao qualityProfileDao) { - this.languages = languages; - this.profileLookup = profileLookup; - this.profileLoader = profileLoader; - this.qualityProfileDao = qualityProfileDao; - } - - @Override - public void define(WebService.NewController controller) { - NewAction search = controller.createAction("search") - .setSince("5.2") - .setDescription("List quality profiles.") - .setHandler(this) - .setResponseExample(getClass().getResource("example-search.json")); - - search.createParam(PARAM_LANGUAGE) - .setDescription("The key of a language supported by the platform. If specified, only profiles for the given language are returned.") - .setExampleValue("js") - .setPossibleValues(LanguageParamUtils.getLanguageKeys(languages)); - - search.createParam(Param.FIELDS) - .setDescription("Use to restrict returned fields.") - .setExampleValue("key,language") - .setPossibleValues(ALL_FIELDS); - } - - @Override - public void handle(Request request, Response response) throws Exception { - List fields = request.paramAsStrings(Param.FIELDS); - - String language = request.param(PARAM_LANGUAGE); - - List profiles = null; - if (language == null) { - profiles = profileLookup.allProfiles(); - } else { - profiles = profileLookup.profiles(language); - } - - Collections.sort(profiles, new Comparator() { - @Override - public int compare(QProfile o1, QProfile o2) { - return new CompareToBuilder() - .append(o1.language(), o2.language()) - .append(o1.name(), o2.name()) - .toComparison(); - } - }); - - JsonWriter json = response.newJsonWriter().beginObject(); - writeProfiles(json, profiles, fields); - json.endObject().close(); - } - - private void writeProfiles(JsonWriter json, List profiles, List fields) { - Map profilesByKey = Maps.uniqueIndex(profiles, new NonNullInputFunction() { - @Override - protected String doApply(QProfile input) { - return input.key(); - } - }); - Map activeRuleCountByKey = profileLoader.countAllActiveRules(); - Map projectCountByKey = qualityProfileDao.countProjectsByProfileKey(); - - json.name("profiles") - .beginArray(); - for (QProfile profile : profiles) { - if (languages.get(profile.language()) == null) { - // Hide profiles on an unsupported language - continue; - } - - String key = profile.key(); - Long activeRuleCount = activeRuleCountByKey.containsKey(key) ? activeRuleCountByKey.get(key) : 0L; - Long projectCount = projectCountByKey.containsKey(key) ? projectCountByKey.get(key) : 0L; - json.beginObject() - .prop(FIELD_KEY, nullUnlessNeeded(FIELD_KEY, key, fields)) - .prop(FIELD_NAME, nullUnlessNeeded(FIELD_NAME, profile.name(), fields)) - .prop(FIELD_ACTIVE_RULE_COUNT, nullUnlessNeeded(FIELD_ACTIVE_RULE_COUNT, activeRuleCount, fields)); - - if (!profile.isDefault()) { - json.prop(FIELD_PROJECT_COUNT, nullUnlessNeeded(FIELD_PROJECT_COUNT, projectCount, fields)); - } - writeLanguageFields(json, profile, fields); - writeParentFields(json, profile, fields, profilesByKey); - // Special case for booleans - if (fieldIsNeeded(FIELD_IS_INHERITED, fields)) { - json.prop(FIELD_IS_INHERITED, profile.isInherited()); - } - if (fieldIsNeeded(FIELD_IS_DEFAULT, fields)) { - json.prop(FIELD_IS_DEFAULT, profile.isDefault()); - } - json.endObject(); - } - json.endArray(); - } - - private void writeLanguageFields(JsonWriter json, QProfile profile, List fields) { - String languageKey = profile.language(); - json.prop(FIELD_LANGUAGE, nullUnlessNeeded(FIELD_LANGUAGE, languageKey, fields)) - .prop(FIELD_LANGUAGE_NAME, nullUnlessNeeded(FIELD_LANGUAGE_NAME, languages.get(languageKey).getName(), fields)); - } - - private void writeParentFields(JsonWriter json, QProfile profile, List fields, Map profilesByKey) { - String parentKey = profile.parent(); - QProfile parent = parentKey == null ? null : profilesByKey.get(parentKey); - json.prop(FIELD_PARENT_KEY, nullUnlessNeeded(FIELD_PARENT_KEY, parentKey, fields)) - .prop(FIELD_PARENT_NAME, nullUnlessNeeded(FIELD_PARENT_NAME, parent == null ? parentKey : parent.name(), fields)); - } - - @CheckForNull - private T nullUnlessNeeded(String field, T value, @Nullable List fields) { - return fieldIsNeeded(field, fields) ? value : null; - } - - private boolean fieldIsNeeded(String field, @Nullable List fields) { - return fields == null || fields.contains(field); - } -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileSetDefaultAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileSetDefaultAction.java deleted file mode 100644 index 0d1f0484277..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileSetDefaultAction.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * 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.qualityprofile.ws; - -import com.google.common.base.Preconditions; -import org.sonar.api.resources.Languages; -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.server.ws.WebService.NewAction; -import org.sonar.core.permission.GlobalPermissions; -import org.sonar.server.exceptions.NotFoundException; -import org.sonar.server.qualityprofile.QProfile; -import org.sonar.server.qualityprofile.QProfileFactory; -import org.sonar.server.qualityprofile.QProfileLookup; -import org.sonar.server.user.UserSession; - -import static org.apache.commons.lang.StringUtils.isEmpty; - -public class QProfileSetDefaultAction implements QProfileWsAction { - - private static final String PARAM_LANGUAGE = "language"; - private static final String PARAM_PROFILE_NAME = "profileName"; - private static final String PARAM_PROFILE_KEY = "profileKey"; - - private final Languages languages; - - private final QProfileLookup profileLookup; - - private final QProfileFactory profileFactory; - private final UserSession userSession; - - public QProfileSetDefaultAction(Languages languages, QProfileLookup profileLookup, QProfileFactory profileFactory, UserSession userSession) { - this.languages = languages; - this.profileLookup = profileLookup; - this.profileFactory = profileFactory; - this.userSession = userSession; - } - - @Override - public void define(WebService.NewController controller) { - NewAction setDefault = controller.createAction("set_default") - .setSince("5.2") - .setDescription("Select the default profile for a given language.") - .setPost(true) - .setHandler(this); - - setDefault.createParam(PARAM_LANGUAGE) - .setDescription("The key of a language supported by the platform. If specified, profileName must be set to select the default profile for the selected language.") - .setExampleValue("js") - .setPossibleValues(LanguageParamUtils.getLanguageKeys(languages)); - - setDefault.createParam(PARAM_PROFILE_NAME) - .setDescription("The name of a quality profile. If specified, language must be set. The matching profile will be used as default for the selected language.") - .setExampleValue("Sonar way"); - - setDefault.createParam(PARAM_PROFILE_KEY) - .setDescription("The key of a quality profile. If specified, language and profileName must not be set. The matching profile will be used as default for its language.") - .setExampleValue("sonar-way-js-12345"); - } - - @Override - public void handle(Request request, Response response) throws Exception { - userSession.checkLoggedIn().checkGlobalPermission(GlobalPermissions.QUALITY_PROFILE_ADMIN); - - String language = request.param(PARAM_LANGUAGE); - String profileName = request.param(PARAM_PROFILE_NAME); - String profileKey = request.param(PARAM_PROFILE_KEY); - - Preconditions.checkArgument( - (!isEmpty(language) && !isEmpty(profileName)) ^ !isEmpty(profileKey), "Either profileKey or profileName + language must be set"); - - if(profileKey == null) { - profileKey = getProfileKeyFromLanguageAndName(language, profileName); - } - - profileFactory.setDefault(profileKey); - - response.noContent(); - } - - private String getProfileKeyFromLanguageAndName(String language, String profileName) { - QProfile profile = profileLookup.profile(profileName, language); - if (profile == null) { - throw new NotFoundException(String.format("Unable to find a profile for language '%s' with name '%s'", language, profileName)); - } - return profile.key(); - } -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/RenameAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/RenameAction.java new file mode 100644 index 00000000000..e8202c64b02 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/RenameAction.java @@ -0,0 +1,73 @@ +/* + * 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.qualityprofile.ws; + +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.server.ws.WebService.NewAction; +import org.sonar.core.permission.GlobalPermissions; +import org.sonar.server.qualityprofile.QProfileFactory; +import org.sonar.server.user.UserSession; + +public class RenameAction implements QProfileWsAction { + + private static final String PARAM_PROFILE_NAME = "name"; + private static final String PARAM_PROFILE_KEY = "key"; + + private final QProfileFactory profileFactory; + private final UserSession userSession; + + public RenameAction(QProfileFactory profileFactory, UserSession userSession) { + this.profileFactory = profileFactory; + this.userSession = userSession; + } + + @Override + public void define(WebService.NewController controller) { + NewAction setDefault = controller.createAction("rename") + .setSince("5.2") + .setDescription("Rename a quality profile.") + .setPost(true) + .setHandler(this); + + setDefault.createParam(PARAM_PROFILE_NAME) + .setDescription("The new name for the quality profile.") + .setExampleValue("My Sonar way") + .setRequired(true); + + setDefault.createParam(PARAM_PROFILE_KEY) + .setDescription("The key of a quality profile.") + .setExampleValue("sonar-way-js-12345") + .setRequired(true); + } + + @Override + public void handle(Request request, Response response) throws Exception { + userSession.checkLoggedIn().checkGlobalPermission(GlobalPermissions.QUALITY_PROFILE_ADMIN); + + String newName = request.mandatoryParam(PARAM_PROFILE_NAME); + String profileKey = request.mandatoryParam(PARAM_PROFILE_KEY); + + profileFactory.rename(profileKey, newName); + + response.noContent(); + } +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/RestoreAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/RestoreAction.java new file mode 100644 index 00000000000..c94625c0635 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/RestoreAction.java @@ -0,0 +1,100 @@ +/* + * 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.qualityprofile.ws; + +import com.google.common.base.Preconditions; +import org.apache.commons.io.IOUtils; +import org.sonar.api.resources.Languages; +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.core.permission.GlobalPermissions; +import org.sonar.core.qualityprofile.db.QualityProfileDto; +import org.sonar.server.qualityprofile.BulkChangeResult; +import org.sonar.server.qualityprofile.QProfileBackuper; +import org.sonar.server.user.UserSession; + +import java.io.InputStream; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; + +public class RestoreAction implements QProfileWsAction { + + private static final String PARAM_BACKUP = "backup"; + private final QProfileBackuper backuper; + private final Languages languages; + private final UserSession userSession; + + public RestoreAction(QProfileBackuper backuper, Languages languages, UserSession userSession) { + this.backuper = backuper; + this.languages = languages; + this.userSession = userSession; + } + + @Override + public void define(WebService.NewController controller) { + controller.createAction("restore") + .setSince("5.2") + .setDescription("Restore a quality profile using an XML file. The restored profile name is taken from the backup file, " + + "so if a profile with the same name and language already exists, it will be overwritten.") + .setPost(true) + .setHandler(this) + .createParam(PARAM_BACKUP) + .setDescription("A profile backup file in XML format, as generated by api/qualityprofiles/backup " + + "or the former api/profiles/backup.") + .setRequired(true); + } + + @Override + public void handle(Request request, Response response) throws Exception { + userSession.checkLoggedIn().checkGlobalPermission(GlobalPermissions.QUALITY_PROFILE_ADMIN); + InputStream backup = request.paramAsInputStream(PARAM_BACKUP); + InputStreamReader reader = null; + + try { + Preconditions.checkArgument(backup != null, "A backup file must be provided"); + reader = new InputStreamReader(backup, StandardCharsets.UTF_8); + BulkChangeResult result = backuper.restore(reader, null); + writeResponse(response.newJsonWriter(), result); + } finally { + IOUtils.closeQuietly(reader); + IOUtils.closeQuietly(backup); + } + } + + private void writeResponse(JsonWriter json, BulkChangeResult result) { + QualityProfileDto profile = result.profile(); + if (profile != null) { + String language = profile.getLanguage(); + json.beginObject().name("profile").beginObject() + .prop("key", profile.getKey()) + .prop("name", profile.getName()) + .prop("language", language) + .prop("languageName", languages.get(profile.getLanguage()).getName()) + .prop("isDefault", false) + .prop("isInherited", false) + .endObject(); + } + json.prop("ruleSuccesses", result.countSucceeded()); + json.prop("ruleFailures", result.countFailed()); + json.endObject().close(); + } +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/RestoreBuiltInAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/RestoreBuiltInAction.java new file mode 100644 index 00000000000..8d421a78012 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/RestoreBuiltInAction.java @@ -0,0 +1,57 @@ +/* + * 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.qualityprofile.ws; + +import org.sonar.api.server.ws.Request; +import org.sonar.api.server.ws.Response; +import org.sonar.api.server.ws.WebService; +import org.sonar.server.qualityprofile.QProfileService; + +public class RestoreBuiltInAction implements QProfileWsAction { + + private final QProfileService service; + + public RestoreBuiltInAction(QProfileService service) { + this.service = service; + } + + @Override + public void define(WebService.NewController controller) { + WebService.NewAction restoreDefault = controller.createAction("restore_built_in") + .setDescription("Restore built-in profiles from the definitions declared by plugins. " + + "Missing profiles are created, existing ones are updated.") + .setSince("4.4") + .setPost(true) + .setHandler(this); + restoreDefault.createParam("language") + .setDescription("Restore the built-in profiles defined for this language") + .setExampleValue("java") + .setRequired(true); + } + + @Override + public void handle(Request request, Response response) { + String language = request.mandatoryParam("language"); + service.restoreBuiltInProfilesForLanguage(language); + response.noContent(); + } + +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/SearchAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/SearchAction.java new file mode 100644 index 00000000000..ecdbbf53efb --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/SearchAction.java @@ -0,0 +1,192 @@ +/* + * 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.qualityprofile.ws; + +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Maps; +import org.apache.commons.lang.builder.CompareToBuilder; +import org.sonar.api.resources.Languages; +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.server.ws.WebService.NewAction; +import org.sonar.api.server.ws.WebService.Param; +import org.sonar.api.utils.text.JsonWriter; +import org.sonar.core.qualityprofile.db.QualityProfileDao; +import org.sonar.core.util.NonNullInputFunction; +import org.sonar.server.qualityprofile.QProfile; +import org.sonar.server.qualityprofile.QProfileLoader; +import org.sonar.server.qualityprofile.QProfileLookup; + +import javax.annotation.CheckForNull; +import javax.annotation.Nullable; + +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +public class SearchAction implements QProfileWsAction { + + private static final String FIELD_KEY = "key"; + private static final String FIELD_NAME = "name"; + private static final String FIELD_LANGUAGE = "language"; + private static final String FIELD_LANGUAGE_NAME = "languageName"; + private static final String FIELD_IS_INHERITED = "isInherited"; + private static final String FIELD_IS_DEFAULT = "isDefault"; + private static final String FIELD_PARENT_KEY = "parentKey"; + private static final String FIELD_PARENT_NAME = "parentName"; + private static final String FIELD_ACTIVE_RULE_COUNT = "activeRuleCount"; + private static final String FIELD_PROJECT_COUNT = "projectCount"; + + private static final Set ALL_FIELDS = ImmutableSet.of( + FIELD_KEY, FIELD_NAME, FIELD_LANGUAGE, FIELD_LANGUAGE_NAME, FIELD_IS_INHERITED, FIELD_PARENT_KEY, FIELD_PARENT_NAME, FIELD_IS_DEFAULT, FIELD_ACTIVE_RULE_COUNT, + FIELD_PROJECT_COUNT); + + private static final String PARAM_LANGUAGE = FIELD_LANGUAGE; + + private final Languages languages; + + private final QProfileLookup profileLookup; + + private final QProfileLoader profileLoader; + + private final QualityProfileDao qualityProfileDao; + + public SearchAction(Languages languages, QProfileLookup profileLookup, QProfileLoader profileLoader, QualityProfileDao qualityProfileDao) { + this.languages = languages; + this.profileLookup = profileLookup; + this.profileLoader = profileLoader; + this.qualityProfileDao = qualityProfileDao; + } + + @Override + public void define(WebService.NewController controller) { + NewAction search = controller.createAction("search") + .setSince("5.2") + .setDescription("List quality profiles.") + .setHandler(this) + .setResponseExample(getClass().getResource("example-search.json")); + + search.createParam(PARAM_LANGUAGE) + .setDescription("The key of a language supported by the platform. If specified, only profiles for the given language are returned.") + .setExampleValue("js") + .setPossibleValues(LanguageParamUtils.getLanguageKeys(languages)); + + search.createParam(Param.FIELDS) + .setDescription("Use to restrict returned fields.") + .setExampleValue("key,language") + .setPossibleValues(ALL_FIELDS); + } + + @Override + public void handle(Request request, Response response) throws Exception { + List fields = request.paramAsStrings(Param.FIELDS); + + String language = request.param(PARAM_LANGUAGE); + + List profiles = null; + if (language == null) { + profiles = profileLookup.allProfiles(); + } else { + profiles = profileLookup.profiles(language); + } + + Collections.sort(profiles, new Comparator() { + @Override + public int compare(QProfile o1, QProfile o2) { + return new CompareToBuilder() + .append(o1.language(), o2.language()) + .append(o1.name(), o2.name()) + .toComparison(); + } + }); + + JsonWriter json = response.newJsonWriter().beginObject(); + writeProfiles(json, profiles, fields); + json.endObject().close(); + } + + private void writeProfiles(JsonWriter json, List profiles, List fields) { + Map profilesByKey = Maps.uniqueIndex(profiles, new NonNullInputFunction() { + @Override + protected String doApply(QProfile input) { + return input.key(); + } + }); + Map activeRuleCountByKey = profileLoader.countAllActiveRules(); + Map projectCountByKey = qualityProfileDao.countProjectsByProfileKey(); + + json.name("profiles") + .beginArray(); + for (QProfile profile : profiles) { + if (languages.get(profile.language()) == null) { + // Hide profiles on an unsupported language + continue; + } + + String key = profile.key(); + Long activeRuleCount = activeRuleCountByKey.containsKey(key) ? activeRuleCountByKey.get(key) : 0L; + Long projectCount = projectCountByKey.containsKey(key) ? projectCountByKey.get(key) : 0L; + json.beginObject() + .prop(FIELD_KEY, nullUnlessNeeded(FIELD_KEY, key, fields)) + .prop(FIELD_NAME, nullUnlessNeeded(FIELD_NAME, profile.name(), fields)) + .prop(FIELD_ACTIVE_RULE_COUNT, nullUnlessNeeded(FIELD_ACTIVE_RULE_COUNT, activeRuleCount, fields)); + + if (!profile.isDefault()) { + json.prop(FIELD_PROJECT_COUNT, nullUnlessNeeded(FIELD_PROJECT_COUNT, projectCount, fields)); + } + writeLanguageFields(json, profile, fields); + writeParentFields(json, profile, fields, profilesByKey); + // Special case for booleans + if (fieldIsNeeded(FIELD_IS_INHERITED, fields)) { + json.prop(FIELD_IS_INHERITED, profile.isInherited()); + } + if (fieldIsNeeded(FIELD_IS_DEFAULT, fields)) { + json.prop(FIELD_IS_DEFAULT, profile.isDefault()); + } + json.endObject(); + } + json.endArray(); + } + + private void writeLanguageFields(JsonWriter json, QProfile profile, List fields) { + String languageKey = profile.language(); + json.prop(FIELD_LANGUAGE, nullUnlessNeeded(FIELD_LANGUAGE, languageKey, fields)) + .prop(FIELD_LANGUAGE_NAME, nullUnlessNeeded(FIELD_LANGUAGE_NAME, languages.get(languageKey).getName(), fields)); + } + + private void writeParentFields(JsonWriter json, QProfile profile, List fields, Map profilesByKey) { + String parentKey = profile.parent(); + QProfile parent = parentKey == null ? null : profilesByKey.get(parentKey); + json.prop(FIELD_PARENT_KEY, nullUnlessNeeded(FIELD_PARENT_KEY, parentKey, fields)) + .prop(FIELD_PARENT_NAME, nullUnlessNeeded(FIELD_PARENT_NAME, parent == null ? parentKey : parent.name(), fields)); + } + + @CheckForNull + private T nullUnlessNeeded(String field, T value, @Nullable List fields) { + return fieldIsNeeded(field, fields) ? value : null; + } + + private boolean fieldIsNeeded(String field, @Nullable List fields) { + return fields == null || fields.contains(field); + } +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/SetDefaultAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/SetDefaultAction.java new file mode 100644 index 00000000000..e0032982045 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/SetDefaultAction.java @@ -0,0 +1,106 @@ +/* + * 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.qualityprofile.ws; + +import com.google.common.base.Preconditions; +import org.sonar.api.resources.Languages; +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.server.ws.WebService.NewAction; +import org.sonar.core.permission.GlobalPermissions; +import org.sonar.server.exceptions.NotFoundException; +import org.sonar.server.qualityprofile.QProfile; +import org.sonar.server.qualityprofile.QProfileFactory; +import org.sonar.server.qualityprofile.QProfileLookup; +import org.sonar.server.user.UserSession; + +import static org.apache.commons.lang.StringUtils.isEmpty; + +public class SetDefaultAction implements QProfileWsAction { + + private static final String PARAM_LANGUAGE = "language"; + private static final String PARAM_PROFILE_NAME = "profileName"; + private static final String PARAM_PROFILE_KEY = "profileKey"; + + private final Languages languages; + + private final QProfileLookup profileLookup; + + private final QProfileFactory profileFactory; + private final UserSession userSession; + + public SetDefaultAction(Languages languages, QProfileLookup profileLookup, QProfileFactory profileFactory, UserSession userSession) { + this.languages = languages; + this.profileLookup = profileLookup; + this.profileFactory = profileFactory; + this.userSession = userSession; + } + + @Override + public void define(WebService.NewController controller) { + NewAction setDefault = controller.createAction("set_default") + .setSince("5.2") + .setDescription("Select the default profile for a given language.") + .setPost(true) + .setHandler(this); + + setDefault.createParam(PARAM_LANGUAGE) + .setDescription("The key of a language supported by the platform. If specified, profileName must be set to select the default profile for the selected language.") + .setExampleValue("js") + .setPossibleValues(LanguageParamUtils.getLanguageKeys(languages)); + + setDefault.createParam(PARAM_PROFILE_NAME) + .setDescription("The name of a quality profile. If specified, language must be set. The matching profile will be used as default for the selected language.") + .setExampleValue("Sonar way"); + + setDefault.createParam(PARAM_PROFILE_KEY) + .setDescription("The key of a quality profile. If specified, language and profileName must not be set. The matching profile will be used as default for its language.") + .setExampleValue("sonar-way-js-12345"); + } + + @Override + public void handle(Request request, Response response) throws Exception { + userSession.checkLoggedIn().checkGlobalPermission(GlobalPermissions.QUALITY_PROFILE_ADMIN); + + String language = request.param(PARAM_LANGUAGE); + String profileName = request.param(PARAM_PROFILE_NAME); + String profileKey = request.param(PARAM_PROFILE_KEY); + + Preconditions.checkArgument( + (!isEmpty(language) && !isEmpty(profileName)) ^ !isEmpty(profileKey), "Either profileKey or profileName + language must be set"); + + if(profileKey == null) { + profileKey = getProfileKeyFromLanguageAndName(language, profileName); + } + + profileFactory.setDefault(profileKey); + + response.noContent(); + } + + private String getProfileKeyFromLanguageAndName(String language, String profileName) { + QProfile profile = profileLookup.profile(profileName, language); + if (profile == null) { + throw new NotFoundException(String.format("Unable to find a profile for language '%s' with name '%s'", language, profileName)); + } + return profile.key(); + } +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/test/ws/CoveredFilesAction.java b/server/sonar-server/src/main/java/org/sonar/server/test/ws/CoveredFilesAction.java new file mode 100644 index 00000000000..e09b0c34a1b --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/test/ws/CoveredFilesAction.java @@ -0,0 +1,121 @@ +/* + * 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.test.ws; + +import com.google.common.base.Function; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.io.Resources; +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.api.web.UserRole; +import org.sonar.core.component.ComponentDto; +import org.sonar.core.persistence.DbSession; +import org.sonar.core.persistence.MyBatis; +import org.sonar.server.db.DbClient; +import org.sonar.server.test.index.CoveredFileDoc; +import org.sonar.server.test.index.TestIndex; +import org.sonar.server.user.UserSession; + +import java.util.List; +import java.util.Map; + +public class CoveredFilesAction implements TestsWsAction { + + public static final String TEST_UUID = "testUuid"; + + private final DbClient dbClient; + private final TestIndex index; + private final UserSession userSession; + + public CoveredFilesAction(DbClient dbClient, TestIndex index, UserSession userSession) { + this.dbClient = dbClient; + this.index = index; + this.userSession = userSession; + } + + @Override + public void define(WebService.NewController controller) { + WebService.NewAction action = controller.createAction("covered_files") + .setDescription("Get the list of source files covered by a test. Require Browse permission on test file's project") + .setSince("4.4") + .setResponseExample(Resources.getResource(getClass(), "tests-example-covered-files.json")) + .setHandler(this) + .addPagingParams(100); + + action + .createParam(TEST_UUID) + .setRequired(true) + .setDescription("Test uuid") + .setExampleValue("ce4c03d6-430f-40a9-b777-ad877c00aa4d"); + } + + @Override + public void handle(Request request, Response response) { + String testUuid = request.mandatoryParam(TEST_UUID); + userSession.checkComponentUuidPermission(UserRole.CODEVIEWER, index.searchByTestUuid(testUuid).fileUuid()); + + List coveredFiles = index.coveredFiles(testUuid); + Map componentsByUuid = buildComponentsByUuid(coveredFiles); + JsonWriter json = response.newJsonWriter().beginObject(); + if (!coveredFiles.isEmpty()) { + writeTests(coveredFiles, componentsByUuid, json); + } + json.endObject().close(); + } + + private void writeTests(List coveredFiles, Map componentsByUuid, JsonWriter json) { + json.name("files").beginArray(); + for (CoveredFileDoc coveredFile : coveredFiles) { + json.beginObject(); + json.prop("key", componentsByUuid.get(coveredFile.fileUuid()).key()); + json.prop("longName", componentsByUuid.get(coveredFile.fileUuid()).longName()); + json.prop("coveredLines", coveredFile.coveredLines().size()); + json.endObject(); + } + json.endArray(); + } + + private Map buildComponentsByUuid(List coveredFiles) { + List sourceFileUuids = Lists.transform(coveredFiles, new Function() { + @Override + public String apply(CoveredFileDoc coveredFile) { + return coveredFile.fileUuid(); + } + }); + DbSession dbSession = dbClient.openSession(false); + List components; + try { + components = dbClient.componentDao().selectByUuids(dbSession, sourceFileUuids); + } finally { + MyBatis.closeQuietly(dbSession); + } + return Maps.uniqueIndex(components, new Function() { + @Override + public String apply(ComponentDto component) { + return component.uuid(); + } + }); + } + +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/test/ws/ListAction.java b/server/sonar-server/src/main/java/org/sonar/server/test/ws/ListAction.java new file mode 100644 index 00000000000..d757bc46c25 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/test/ws/ListAction.java @@ -0,0 +1,229 @@ +/* + * 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.test.ws; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.io.Resources; +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.api.web.UserRole; +import org.sonar.core.component.ComponentDto; +import org.sonar.core.persistence.DbSession; +import org.sonar.core.persistence.MyBatis; +import org.sonar.core.util.NonNullInputFunction; +import org.sonar.server.db.DbClient; +import org.sonar.server.es.SearchOptions; +import org.sonar.server.es.SearchResult; +import org.sonar.server.test.index.CoveredFileDoc; +import org.sonar.server.test.index.TestDoc; +import org.sonar.server.test.index.TestIndex; +import org.sonar.server.user.UserSession; + +import javax.annotation.Nullable; + +import java.util.List; +import java.util.Map; + +public class ListAction implements TestsWsAction { + public static final String TEST_UUID = "testUuid"; + public static final String TEST_FILE_UUID = "testFileUuid"; + public static final String TEST_FILE_KEY = "testFileKey"; + public static final String SOURCE_FILE_UUID = "sourceFileUuid"; + public static final String SOURCE_FILE_LINE_NUMBER = "sourceFileLineNumber"; + + private final DbClient dbClient; + private final TestIndex testIndex; + private final UserSession userSession; + + public ListAction(DbClient dbClient, TestIndex testIndex, UserSession userSession) { + this.dbClient = dbClient; + this.testIndex = testIndex; + this.userSession = userSession; + } + + @Override + public void define(WebService.NewController controller) { + WebService.NewAction action = controller + .createAction("list") + .setDescription( + "Get the list of tests.
" + + "Require Browse permission on file's project.
" + + "One (and only one) of the following combination of parameters must be provided: " + + "
    " + + "
  • Test file UUID
  • " + + "
  • Test UUID
  • " + + "
  • Source file UUID and Source file line number
  • " + + "
") + .setSince("5.2") + .setResponseExample(Resources.getResource(getClass(), "tests-example-list.json")) + .setHandler(this) + .addPagingParams(100); + + action + .createParam(TEST_FILE_UUID) + .setDescription("Test file UUID") + .setExampleValue("ce4c03d6-430f-40a9-b777-ad877c00aa4d"); + + action + .createParam(TEST_FILE_KEY) + .setDescription("Test file key") + .setExampleValue("org.codehaus.sonar:sonar-server:src/test/java/org/sonar/server/rule/RubyRuleServiceTest.java"); + + action + .createParam(TEST_UUID) + .setDescription("Test UUID") + .setExampleValue("c526ef20-131b-4486-9357-063fa64b5079"); + + action + .createParam(SOURCE_FILE_UUID) + .setDescription("Source file UUID. Must be provided with the source file line number.") + .setExampleValue("584a89f2-8037-4f7b-b82c-8b45d2d63fb2"); + + action + .createParam(SOURCE_FILE_LINE_NUMBER) + .setDescription("Source file line number. Must be provided with the source file UUID.") + .setExampleValue("10"); + } + + @Override + public void handle(Request request, Response response) { + String testUuid = request.param(TEST_UUID); + String testFileUuid = request.param(TEST_FILE_UUID); + String testFileKey = request.param(TEST_FILE_KEY); + String sourceFileUuid = request.param(SOURCE_FILE_UUID); + Integer sourceFileLineNumber = request.paramAsInt(SOURCE_FILE_LINE_NUMBER); + SearchOptions searchOptions = new SearchOptions().setPage( + request.mandatoryParamAsInt(WebService.Param.PAGE), + request.mandatoryParamAsInt(WebService.Param.PAGE_SIZE) + ); + + DbSession dbSession = dbClient.openSession(false); + SearchResult tests; + Map componentsByTestFileUuid; + try { + tests = searchTests(dbSession, testUuid, testFileUuid, testFileKey, sourceFileUuid, sourceFileLineNumber, searchOptions); + componentsByTestFileUuid = buildComponentsByTestFileUuid(dbSession, tests.getDocs()); + } finally { + MyBatis.closeQuietly(dbSession); + } + + JsonWriter json = response.newJsonWriter().beginObject(); + writeTests(tests.getDocs(), componentsByTestFileUuid, json); + searchOptions.writeJson(json, tests.getTotal()); + json.endObject().close(); + } + + private void writeTests(List tests, Map componentsByTestFileUuid, JsonWriter json) { + json.name("tests").beginArray(); + for (TestDoc test : tests) { + String fileUuid = test.fileUuid(); + json.beginObject(); + json.prop("testUuid", test.testUuid()); + json.prop("fileUuid", fileUuid); + json.prop("name", test.name()); + json.prop("status", test.status()); + json.prop("durationInMs", test.durationInMs()); + json.prop("message", test.message()); + json.prop("stacktrace", test.stackTrace()); + json.prop("coveredLines", coveredLines(test.coveredFiles())); + json.prop("fileKey", componentsByTestFileUuid.get(fileUuid).key()); + json.prop("fileLongName", componentsByTestFileUuid.get(fileUuid).longName()); + json.endObject(); + } + json.endArray(); + } + + private long coveredLines(List coveredFiles) { + long numberOfLinesCovered = 0L; + for (CoveredFileDoc coveredFile : coveredFiles) { + numberOfLinesCovered += coveredFile.coveredLines().size(); + } + + return numberOfLinesCovered; + } + + private Map buildComponentsByTestFileUuid(DbSession dbSession, List tests) { + List fileUuids = Lists.transform(tests, new NonNullInputFunction() { + @Override + protected String doApply(TestDoc testDoc) { + return testDoc.fileUuid(); + } + }); + List components = dbClient.componentDao().selectByUuids(dbSession, fileUuids); + + return Maps.uniqueIndex(components, new NonNullInputFunction() { + @Override + public String doApply(ComponentDto componentDto) { + return componentDto.uuid(); + } + }); + } + + private SearchResult searchTests(DbSession dbSession, @Nullable String testUuid, @Nullable String testFileUuid, @Nullable String testFileKey, + @Nullable String sourceFileUuid, @Nullable Integer sourceFileLineNumber, SearchOptions searchOptions) { + if (testUuid != null) { + return searchTestsByTestUuid(dbSession, testUuid, searchOptions); + } + if (testFileUuid != null) { + return searchTestsByTestFileUuid(dbSession, testFileUuid, searchOptions); + } + if (testFileKey != null) { + return searchTestsByTestFileKey(dbSession, testFileKey, searchOptions); + } + if (sourceFileUuid != null && sourceFileLineNumber != null) { + return searchTestsBySourceFileUuidAndLineNumber(dbSession, sourceFileUuid, sourceFileLineNumber, searchOptions); + } + + throw new IllegalArgumentException( + "One (and only one) of the following combination of parameters must be provided: 1) test UUID. 2) test file UUID. " + + "3) test file key. 4) source file UUID and source file line number."); + } + + private SearchResult searchTestsBySourceFileUuidAndLineNumber(DbSession dbSession, String sourceFileUuid, Integer sourceFileLineNumber, SearchOptions searchOptions) { + checkComponentUuidPermission(dbSession, sourceFileUuid); + return testIndex.searchBySourceFileUuidAndLineNumber(sourceFileUuid, sourceFileLineNumber, searchOptions); + } + + private SearchResult searchTestsByTestFileKey(DbSession dbSession, String testFileKey, SearchOptions searchOptions) { + userSession.checkComponentPermission(UserRole.CODEVIEWER, testFileKey); + ComponentDto testFile = dbClient.componentDao().selectByKey(dbSession, testFileKey); + + return testIndex.searchByTestFileUuid(testFile.uuid(), searchOptions); + } + + private SearchResult searchTestsByTestFileUuid(DbSession dbSession, String testFileUuid, SearchOptions searchOptions) { + checkComponentUuidPermission(dbSession, testFileUuid); + return testIndex.searchByTestFileUuid(testFileUuid, searchOptions); + } + + private SearchResult searchTestsByTestUuid(DbSession dbSession, String testUuid, SearchOptions searchOptions) { + checkComponentUuidPermission(dbSession, testIndex.searchByTestUuid(testUuid).fileUuid()); + return testIndex.searchByTestUuid(testUuid, searchOptions); + } + + private void checkComponentUuidPermission(DbSession dbSession, String componentUuid) { + ComponentDto component = dbClient.componentDao().selectByUuid(dbSession, componentUuid); + userSession.checkProjectUuidPermission(UserRole.CODEVIEWER, component.projectUuid()); + } +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/test/ws/TestsCoveredFilesAction.java b/server/sonar-server/src/main/java/org/sonar/server/test/ws/TestsCoveredFilesAction.java deleted file mode 100644 index 50c87eaaf51..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/test/ws/TestsCoveredFilesAction.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * 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.test.ws; - -import com.google.common.base.Function; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.google.common.io.Resources; -import java.util.List; -import java.util.Map; -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.api.web.UserRole; -import org.sonar.core.component.ComponentDto; -import org.sonar.core.persistence.DbSession; -import org.sonar.core.persistence.MyBatis; -import org.sonar.server.db.DbClient; -import org.sonar.server.test.index.CoveredFileDoc; -import org.sonar.server.test.index.TestIndex; -import org.sonar.server.user.UserSession; - -public class TestsCoveredFilesAction implements TestsWsAction { - - public static final String TEST_UUID = "testUuid"; - - private final DbClient dbClient; - private final TestIndex index; - private final UserSession userSession; - - public TestsCoveredFilesAction(DbClient dbClient, TestIndex index, UserSession userSession) { - this.dbClient = dbClient; - this.index = index; - this.userSession = userSession; - } - - @Override - public void define(WebService.NewController controller) { - WebService.NewAction action = controller.createAction("covered_files") - .setDescription("Get the list of source files covered by a test. Require Browse permission on test file's project") - .setSince("4.4") - .setResponseExample(Resources.getResource(getClass(), "tests-example-covered-files.json")) - .setHandler(this) - .addPagingParams(100); - - action - .createParam(TEST_UUID) - .setRequired(true) - .setDescription("Test uuid") - .setExampleValue("ce4c03d6-430f-40a9-b777-ad877c00aa4d"); - } - - @Override - public void handle(Request request, Response response) { - String testUuid = request.mandatoryParam(TEST_UUID); - userSession.checkComponentUuidPermission(UserRole.CODEVIEWER, index.searchByTestUuid(testUuid).fileUuid()); - - List coveredFiles = index.coveredFiles(testUuid); - Map componentsByUuid = buildComponentsByUuid(coveredFiles); - JsonWriter json = response.newJsonWriter().beginObject(); - if (!coveredFiles.isEmpty()) { - writeTests(coveredFiles, componentsByUuid, json); - } - json.endObject().close(); - } - - private void writeTests(List coveredFiles, Map componentsByUuid, JsonWriter json) { - json.name("files").beginArray(); - for (CoveredFileDoc coveredFile : coveredFiles) { - json.beginObject(); - json.prop("key", componentsByUuid.get(coveredFile.fileUuid()).key()); - json.prop("longName", componentsByUuid.get(coveredFile.fileUuid()).longName()); - json.prop("coveredLines", coveredFile.coveredLines().size()); - json.endObject(); - } - json.endArray(); - } - - private Map buildComponentsByUuid(List coveredFiles) { - List sourceFileUuids = Lists.transform(coveredFiles, new Function() { - @Override - public String apply(CoveredFileDoc coveredFile) { - return coveredFile.fileUuid(); - } - }); - DbSession dbSession = dbClient.openSession(false); - List components; - try { - components = dbClient.componentDao().selectByUuids(dbSession, sourceFileUuids); - } finally { - MyBatis.closeQuietly(dbSession); - } - return Maps.uniqueIndex(components, new Function() { - @Override - public String apply(ComponentDto component) { - return component.uuid(); - } - }); - } - -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/test/ws/TestsListAction.java b/server/sonar-server/src/main/java/org/sonar/server/test/ws/TestsListAction.java deleted file mode 100644 index f74b34f87c5..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/test/ws/TestsListAction.java +++ /dev/null @@ -1,229 +0,0 @@ -/* - * 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.test.ws; - -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.google.common.io.Resources; -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.api.web.UserRole; -import org.sonar.core.component.ComponentDto; -import org.sonar.core.persistence.DbSession; -import org.sonar.core.persistence.MyBatis; -import org.sonar.core.util.NonNullInputFunction; -import org.sonar.server.db.DbClient; -import org.sonar.server.es.SearchOptions; -import org.sonar.server.es.SearchResult; -import org.sonar.server.test.index.CoveredFileDoc; -import org.sonar.server.test.index.TestDoc; -import org.sonar.server.test.index.TestIndex; -import org.sonar.server.user.UserSession; - -import javax.annotation.Nullable; - -import java.util.List; -import java.util.Map; - -public class TestsListAction implements TestsWsAction { - public static final String TEST_UUID = "testUuid"; - public static final String TEST_FILE_UUID = "testFileUuid"; - public static final String TEST_FILE_KEY = "testFileKey"; - public static final String SOURCE_FILE_UUID = "sourceFileUuid"; - public static final String SOURCE_FILE_LINE_NUMBER = "sourceFileLineNumber"; - - private final DbClient dbClient; - private final TestIndex testIndex; - private final UserSession userSession; - - public TestsListAction(DbClient dbClient, TestIndex testIndex, UserSession userSession) { - this.dbClient = dbClient; - this.testIndex = testIndex; - this.userSession = userSession; - } - - @Override - public void define(WebService.NewController controller) { - WebService.NewAction action = controller - .createAction("list") - .setDescription( - "Get the list of tests.
" + - "Require Browse permission on file's project.
" + - "One (and only one) of the following combination of parameters must be provided: " + - "
    " + - "
  • Test file UUID
  • " + - "
  • Test UUID
  • " + - "
  • Source file UUID and Source file line number
  • " + - "
") - .setSince("5.2") - .setResponseExample(Resources.getResource(getClass(), "tests-example-list.json")) - .setHandler(this) - .addPagingParams(100); - - action - .createParam(TEST_FILE_UUID) - .setDescription("Test file UUID") - .setExampleValue("ce4c03d6-430f-40a9-b777-ad877c00aa4d"); - - action - .createParam(TEST_FILE_KEY) - .setDescription("Test file key") - .setExampleValue("org.codehaus.sonar:sonar-server:src/test/java/org/sonar/server/rule/RubyRuleServiceTest.java"); - - action - .createParam(TEST_UUID) - .setDescription("Test UUID") - .setExampleValue("c526ef20-131b-4486-9357-063fa64b5079"); - - action - .createParam(SOURCE_FILE_UUID) - .setDescription("Source file UUID. Must be provided with the source file line number.") - .setExampleValue("584a89f2-8037-4f7b-b82c-8b45d2d63fb2"); - - action - .createParam(SOURCE_FILE_LINE_NUMBER) - .setDescription("Source file line number. Must be provided with the source file UUID.") - .setExampleValue("10"); - } - - @Override - public void handle(Request request, Response response) { - String testUuid = request.param(TEST_UUID); - String testFileUuid = request.param(TEST_FILE_UUID); - String testFileKey = request.param(TEST_FILE_KEY); - String sourceFileUuid = request.param(SOURCE_FILE_UUID); - Integer sourceFileLineNumber = request.paramAsInt(SOURCE_FILE_LINE_NUMBER); - SearchOptions searchOptions = new SearchOptions().setPage( - request.mandatoryParamAsInt(WebService.Param.PAGE), - request.mandatoryParamAsInt(WebService.Param.PAGE_SIZE) - ); - - DbSession dbSession = dbClient.openSession(false); - SearchResult tests; - Map componentsByTestFileUuid; - try { - tests = searchTests(dbSession, testUuid, testFileUuid, testFileKey, sourceFileUuid, sourceFileLineNumber, searchOptions); - componentsByTestFileUuid = buildComponentsByTestFileUuid(dbSession, tests.getDocs()); - } finally { - MyBatis.closeQuietly(dbSession); - } - - JsonWriter json = response.newJsonWriter().beginObject(); - writeTests(tests.getDocs(), componentsByTestFileUuid, json); - searchOptions.writeJson(json, tests.getTotal()); - json.endObject().close(); - } - - private void writeTests(List tests, Map componentsByTestFileUuid, JsonWriter json) { - json.name("tests").beginArray(); - for (TestDoc test : tests) { - String fileUuid = test.fileUuid(); - json.beginObject(); - json.prop("testUuid", test.testUuid()); - json.prop("fileUuid", fileUuid); - json.prop("name", test.name()); - json.prop("status", test.status()); - json.prop("durationInMs", test.durationInMs()); - json.prop("message", test.message()); - json.prop("stacktrace", test.stackTrace()); - json.prop("coveredLines", coveredLines(test.coveredFiles())); - json.prop("fileKey", componentsByTestFileUuid.get(fileUuid).key()); - json.prop("fileLongName", componentsByTestFileUuid.get(fileUuid).longName()); - json.endObject(); - } - json.endArray(); - } - - private long coveredLines(List coveredFiles) { - long numberOfLinesCovered = 0L; - for (CoveredFileDoc coveredFile : coveredFiles) { - numberOfLinesCovered += coveredFile.coveredLines().size(); - } - - return numberOfLinesCovered; - } - - private Map buildComponentsByTestFileUuid(DbSession dbSession, List tests) { - List fileUuids = Lists.transform(tests, new NonNullInputFunction() { - @Override - protected String doApply(TestDoc testDoc) { - return testDoc.fileUuid(); - } - }); - List components = dbClient.componentDao().selectByUuids(dbSession, fileUuids); - - return Maps.uniqueIndex(components, new NonNullInputFunction() { - @Override - public String doApply(ComponentDto componentDto) { - return componentDto.uuid(); - } - }); - } - - private SearchResult searchTests(DbSession dbSession, @Nullable String testUuid, @Nullable String testFileUuid, @Nullable String testFileKey, - @Nullable String sourceFileUuid, @Nullable Integer sourceFileLineNumber, SearchOptions searchOptions) { - if (testUuid != null) { - return searchTestsByTestUuid(dbSession, testUuid, searchOptions); - } - if (testFileUuid != null) { - return searchTestsByTestFileUuid(dbSession, testFileUuid, searchOptions); - } - if (testFileKey != null) { - return searchTestsByTestFileKey(dbSession, testFileKey, searchOptions); - } - if (sourceFileUuid != null && sourceFileLineNumber != null) { - return searchTestsBySourceFileUuidAndLineNumber(dbSession, sourceFileUuid, sourceFileLineNumber, searchOptions); - } - - throw new IllegalArgumentException( - "One (and only one) of the following combination of parameters must be provided: 1) test UUID. 2) test file UUID. " + - "3) test file key. 4) source file UUID and source file line number."); - } - - private SearchResult searchTestsBySourceFileUuidAndLineNumber(DbSession dbSession, String sourceFileUuid, Integer sourceFileLineNumber, SearchOptions searchOptions) { - checkComponentUuidPermission(dbSession, sourceFileUuid); - return testIndex.searchBySourceFileUuidAndLineNumber(sourceFileUuid, sourceFileLineNumber, searchOptions); - } - - private SearchResult searchTestsByTestFileKey(DbSession dbSession, String testFileKey, SearchOptions searchOptions) { - userSession.checkComponentPermission(UserRole.CODEVIEWER, testFileKey); - ComponentDto testFile = dbClient.componentDao().selectByKey(dbSession, testFileKey); - - return testIndex.searchByTestFileUuid(testFile.uuid(), searchOptions); - } - - private SearchResult searchTestsByTestFileUuid(DbSession dbSession, String testFileUuid, SearchOptions searchOptions) { - checkComponentUuidPermission(dbSession, testFileUuid); - return testIndex.searchByTestFileUuid(testFileUuid, searchOptions); - } - - private SearchResult searchTestsByTestUuid(DbSession dbSession, String testUuid, SearchOptions searchOptions) { - checkComponentUuidPermission(dbSession, testIndex.searchByTestUuid(testUuid).fileUuid()); - return testIndex.searchByTestUuid(testUuid, searchOptions); - } - - private void checkComponentUuidPermission(DbSession dbSession, String componentUuid) { - ComponentDto component = dbClient.componentDao().selectByUuid(dbSession, componentUuid); - userSession.checkProjectUuidPermission(UserRole.CODEVIEWER, component.projectUuid()); - } -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java b/server/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java index 71a39f1e1f9..5e08f594cc9 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java +++ b/server/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java @@ -58,6 +58,7 @@ import org.sonar.server.platform.Platform; import org.sonar.server.platform.ServerIdGenerator; import org.sonar.server.platform.ServerSettings; import org.sonar.server.platform.SettingsChangeNotifier; +import org.sonar.server.platform.ws.UpgradesAction; import org.sonar.server.plugins.InstalledPluginReferentialFactory; import org.sonar.server.plugins.PluginDownloader; import org.sonar.server.plugins.ServerPluginRepository; @@ -382,9 +383,9 @@ public final class JRubyFacade { /** * Checks whether the SQ instance is up and running (ie. not in safemode and with an up-to-date database). *

- * This method duplicates most of the logic code written in {@link org.sonar.server.platform.ws.UpgradesSystemWsAction} + * This method duplicates most of the logic code written in {@link UpgradesAction} * class. There is no need to refactor code to avoid this duplication since this method is only used by RoR code - * which will soon be replaced by pure JS code based on the {@link org.sonar.server.platform.ws.UpgradesSystemWsAction} + * which will soon be replaced by pure JS code based on the {@link UpgradesAction} * WebService. *

*/ diff --git a/server/sonar-server/src/main/java/org/sonar/server/user/ws/CurrentAction.java b/server/sonar-server/src/main/java/org/sonar/server/user/ws/CurrentAction.java new file mode 100644 index 00000000000..f3784f06c26 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/user/ws/CurrentAction.java @@ -0,0 +1,76 @@ +/* + * 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.user.ws; + +import org.sonar.api.server.ws.Request; +import org.sonar.api.server.ws.Response; +import org.sonar.api.server.ws.WebService.NewController; +import org.sonar.api.utils.text.JsonWriter; +import org.sonar.server.user.UserSession; + +public class CurrentAction implements UsersWsAction { + private final UserSession userSession; + + public CurrentAction(UserSession userSession) { + this.userSession = userSession; + } + + + @Override + public void define(NewController context) { + context.createAction("current") + .setDescription("Get the details of the current authenticated user.") + .setHandler(this) + .setInternal(true) + .setResponseExample(getClass().getResource("example-current.json")) + .setSince("5.2"); + } + + @Override + public void handle(Request request, Response response) throws Exception { + JsonWriter json = response.newJsonWriter().beginObject(); + + writeUserDetails(json, userSession); + + json.endObject().close(); + } + + private void writeUserDetails(JsonWriter json, UserSession session) { + json.prop("isLoggedIn", session.isLoggedIn()) + .prop("login", session.getLogin()) + .prop("name", session.getName()); + writePermissions(json, session); + } + + private void writePermissions(JsonWriter json, UserSession session) { + json.name("permissions").beginObject(); + writeGlobalPermissions(json, session); + json.endObject(); + } + + private void writeGlobalPermissions(JsonWriter json, UserSession session) { + json.name("global").beginArray(); + for (String permission : session.globalPermissions()) { + json.value(permission); + } + json.endArray(); + } + +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/user/ws/CurrentUserAction.java b/server/sonar-server/src/main/java/org/sonar/server/user/ws/CurrentUserAction.java deleted file mode 100644 index 422d4539d71..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/user/ws/CurrentUserAction.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * 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.user.ws; - -import org.sonar.api.server.ws.Request; -import org.sonar.api.server.ws.Response; -import org.sonar.api.server.ws.WebService.NewController; -import org.sonar.api.utils.text.JsonWriter; -import org.sonar.server.user.UserSession; - -public class CurrentUserAction implements UsersWsAction { - private final UserSession userSession; - - public CurrentUserAction(UserSession userSession) { - this.userSession = userSession; - } - - - @Override - public void define(NewController context) { - context.createAction("current") - .setDescription("Get the details of the current authenticated user.") - .setHandler(this) - .setInternal(true) - .setResponseExample(getClass().getResource("example-current.json")) - .setSince("5.2"); - } - - @Override - public void handle(Request request, Response response) throws Exception { - JsonWriter json = response.newJsonWriter().beginObject(); - - writeUserDetails(json, userSession); - - json.endObject().close(); - } - - private void writeUserDetails(JsonWriter json, UserSession session) { - json.prop("isLoggedIn", session.isLoggedIn()) - .prop("login", session.getLogin()) - .prop("name", session.getName()); - writePermissions(json, session); - } - - private void writePermissions(JsonWriter json, UserSession session) { - json.name("permissions").beginObject(); - writeGlobalPermissions(json, session); - json.endObject(); - } - - private void writeGlobalPermissions(JsonWriter json, UserSession session) { - json.name("global").beginArray(); - for (String permission : session.globalPermissions()) { - json.value(permission); - } - json.endArray(); - } - -} diff --git a/server/sonar-server/src/main/resources/org/sonar/server/component/ws/projects-example-create.json b/server/sonar-server/src/main/resources/org/sonar/server/component/ws/projects-example-create.json deleted file mode 100644 index 043c4bb391d..00000000000 --- a/server/sonar-server/src/main/resources/org/sonar/server/component/ws/projects-example-create.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "id": "30057", - "k": "org.jenkins-ci.plugins:sonar", - "nm": "Jenkins Sonar Plugin", - "sc": "PRJ", - "qu": "TRK" -} - diff --git a/server/sonar-server/src/main/resources/org/sonar/server/component/ws/projects-example-ghosts.json b/server/sonar-server/src/main/resources/org/sonar/server/component/ws/projects-example-ghosts.json deleted file mode 100644 index 4bb9f843654..00000000000 --- a/server/sonar-server/src/main/resources/org/sonar/server/component/ws/projects-example-ghosts.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "projects": [ - { - "uuid": "ce4c03d6-430f-40a9-b777-ad877c00aa4d", - "key": "org.apache.hbas:hbase", - "name": "HBase", - "creationDate": "2015-03-04T23:03:44+0100" - }, - { - "uuid": "c526ef20-131b-4486-9357-063fa64b5079", - "key": "com.microsoft.roslyn:roslyn", - "name": "Roslyn", - "creationDate": "2013-03-04T23:03:44+0100" - } - ], - "total": 2, - "p": 1, - "ps": 100 -} diff --git a/server/sonar-server/src/main/resources/org/sonar/server/component/ws/projects-example-index.json b/server/sonar-server/src/main/resources/org/sonar/server/component/ws/projects-example-index.json deleted file mode 100644 index a5d82ab23c3..00000000000 --- a/server/sonar-server/src/main/resources/org/sonar/server/component/ws/projects-example-index.json +++ /dev/null @@ -1,23 +0,0 @@ -[ - { - "id": "5035", - "k": "org.jenkins-ci.plugins:sonar", - "nm": "Jenkins Sonar Plugin", - "sc": "PRJ", - "qu": "TRK" - }, - { - "id": "5146", - "k": "org.codehaus.sonar-plugins:sonar-ant-task", - "nm": "Sonar Ant Task", - "sc": "PRJ", - "qu": "TRK" - }, - { - "id": "15964", - "k": "org.codehaus.sonar-plugins:sonar-build-breaker-plugin", - "nm": "Sonar Build Breaker Plugin", - "sc": "PRJ", - "qu": "TRK" - } -] diff --git a/server/sonar-server/src/main/resources/org/sonar/server/component/ws/projects-example-provisioned.json b/server/sonar-server/src/main/resources/org/sonar/server/component/ws/projects-example-provisioned.json deleted file mode 100644 index 4bb9f843654..00000000000 --- a/server/sonar-server/src/main/resources/org/sonar/server/component/ws/projects-example-provisioned.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "projects": [ - { - "uuid": "ce4c03d6-430f-40a9-b777-ad877c00aa4d", - "key": "org.apache.hbas:hbase", - "name": "HBase", - "creationDate": "2015-03-04T23:03:44+0100" - }, - { - "uuid": "c526ef20-131b-4486-9357-063fa64b5079", - "key": "com.microsoft.roslyn:roslyn", - "name": "Roslyn", - "creationDate": "2013-03-04T23:03:44+0100" - } - ], - "total": 2, - "p": 1, - "ps": 100 -} diff --git a/server/sonar-server/src/main/resources/org/sonar/server/project/ws/projects-example-create.json b/server/sonar-server/src/main/resources/org/sonar/server/project/ws/projects-example-create.json new file mode 100644 index 00000000000..043c4bb391d --- /dev/null +++ b/server/sonar-server/src/main/resources/org/sonar/server/project/ws/projects-example-create.json @@ -0,0 +1,8 @@ +{ + "id": "30057", + "k": "org.jenkins-ci.plugins:sonar", + "nm": "Jenkins Sonar Plugin", + "sc": "PRJ", + "qu": "TRK" +} + diff --git a/server/sonar-server/src/main/resources/org/sonar/server/project/ws/projects-example-ghosts.json b/server/sonar-server/src/main/resources/org/sonar/server/project/ws/projects-example-ghosts.json new file mode 100644 index 00000000000..4bb9f843654 --- /dev/null +++ b/server/sonar-server/src/main/resources/org/sonar/server/project/ws/projects-example-ghosts.json @@ -0,0 +1,19 @@ +{ + "projects": [ + { + "uuid": "ce4c03d6-430f-40a9-b777-ad877c00aa4d", + "key": "org.apache.hbas:hbase", + "name": "HBase", + "creationDate": "2015-03-04T23:03:44+0100" + }, + { + "uuid": "c526ef20-131b-4486-9357-063fa64b5079", + "key": "com.microsoft.roslyn:roslyn", + "name": "Roslyn", + "creationDate": "2013-03-04T23:03:44+0100" + } + ], + "total": 2, + "p": 1, + "ps": 100 +} diff --git a/server/sonar-server/src/main/resources/org/sonar/server/project/ws/projects-example-index.json b/server/sonar-server/src/main/resources/org/sonar/server/project/ws/projects-example-index.json new file mode 100644 index 00000000000..a5d82ab23c3 --- /dev/null +++ b/server/sonar-server/src/main/resources/org/sonar/server/project/ws/projects-example-index.json @@ -0,0 +1,23 @@ +[ + { + "id": "5035", + "k": "org.jenkins-ci.plugins:sonar", + "nm": "Jenkins Sonar Plugin", + "sc": "PRJ", + "qu": "TRK" + }, + { + "id": "5146", + "k": "org.codehaus.sonar-plugins:sonar-ant-task", + "nm": "Sonar Ant Task", + "sc": "PRJ", + "qu": "TRK" + }, + { + "id": "15964", + "k": "org.codehaus.sonar-plugins:sonar-build-breaker-plugin", + "nm": "Sonar Build Breaker Plugin", + "sc": "PRJ", + "qu": "TRK" + } +] diff --git a/server/sonar-server/src/main/resources/org/sonar/server/project/ws/projects-example-provisioned.json b/server/sonar-server/src/main/resources/org/sonar/server/project/ws/projects-example-provisioned.json new file mode 100644 index 00000000000..4bb9f843654 --- /dev/null +++ b/server/sonar-server/src/main/resources/org/sonar/server/project/ws/projects-example-provisioned.json @@ -0,0 +1,19 @@ +{ + "projects": [ + { + "uuid": "ce4c03d6-430f-40a9-b777-ad877c00aa4d", + "key": "org.apache.hbas:hbase", + "name": "HBase", + "creationDate": "2015-03-04T23:03:44+0100" + }, + { + "uuid": "c526ef20-131b-4486-9357-063fa64b5079", + "key": "com.microsoft.roslyn:roslyn", + "name": "Roslyn", + "creationDate": "2013-03-04T23:03:44+0100" + } + ], + "total": 2, + "p": 1, + "ps": 100 +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/batch/BatchWsTest.java b/server/sonar-server/src/test/java/org/sonar/server/batch/BatchWsTest.java index 3dee07e1a02..f0778ab7da0 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/batch/BatchWsTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/batch/BatchWsTest.java @@ -58,8 +58,8 @@ public class BatchWsTest { @Before public void before() { tester = new WsTester(new BatchWs(batchIndex, - new GlobalRepositoryAction(mock(DbClient.class), mock(PropertiesDao.class), userSessionRule), - new ProjectRepositoryAction(mock(ProjectRepositoryLoader.class)), + new GlobalAction(mock(DbClient.class), mock(PropertiesDao.class), userSessionRule), + new ProjectAction(mock(ProjectRepositoryLoader.class)), new IssuesAction(mock(DbClient.class), mock(IssueIndex.class), userSessionRule))); } diff --git a/server/sonar-server/src/test/java/org/sonar/server/batch/GlobalActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/batch/GlobalActionTest.java new file mode 100644 index 00000000000..b9ffed89f19 --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/batch/GlobalActionTest.java @@ -0,0 +1,127 @@ +/* + * 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.batch; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; +import org.sonar.core.measure.db.MetricDto; +import org.sonar.core.permission.GlobalPermissions; +import org.sonar.core.persistence.DbSession; +import org.sonar.core.properties.PropertiesDao; +import org.sonar.core.properties.PropertyDto; +import org.sonar.server.db.DbClient; +import org.sonar.server.exceptions.ForbiddenException; +import org.sonar.server.measure.persistence.MetricDao; +import org.sonar.server.tester.UserSessionRule; +import org.sonar.server.ws.WsTester; + +import static com.google.common.collect.Lists.newArrayList; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class GlobalActionTest { + @Rule + public UserSessionRule userSessionRule = UserSessionRule.standalone(); + @Rule + public ExpectedException thrown = ExpectedException.none(); + + @Mock + DbSession session; + + @Mock + MetricDao metricDao; + + @Mock + PropertiesDao propertiesDao; + + WsTester tester; + + @Before + public void setUp() { + DbClient dbClient = mock(DbClient.class); + when(dbClient.openSession(false)).thenReturn(session); + when(dbClient.metricDao()).thenReturn(metricDao); + + tester = new WsTester(new BatchWs(mock(BatchIndex.class), new GlobalAction(dbClient, propertiesDao, userSessionRule))); + } + + @Test + public void return_metrics() throws Exception { + userSessionRule.setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION, GlobalPermissions.PREVIEW_EXECUTION); + + when(metricDao.selectEnabled(session)).thenReturn(newArrayList( + new MetricDto().setId(1).setKey("coverage").setDescription("Coverage by unit tests").setValueType("PERCENT").setQualitative(true) + .setWorstValue(0d).setBestValue(100d).setOptimizedBestValue(false).setDirection(1).setEnabled(true) + )); + + WsTester.TestRequest request = tester.newGetRequest("batch", "global"); + request.execute().assertJson(getClass(), "return_global_referentials.json"); + } + + @Test + public void return_global_settings() throws Exception { + userSessionRule.setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION, GlobalPermissions.PREVIEW_EXECUTION); + + when(propertiesDao.selectGlobalProperties(session)).thenReturn(newArrayList( + new PropertyDto().setKey("foo").setValue("bar"), + new PropertyDto().setKey("foo.secured").setValue("1234"), + new PropertyDto().setKey("foo.license.secured").setValue("5678") + )); + + WsTester.TestRequest request = tester.newGetRequest("batch", "global"); + request.execute().assertJson(getClass(), "return_global_settings.json"); + } + + @Test + public void return_only_license_settings_without_scan_but_with_preview_permission() throws Exception { + userSessionRule.setGlobalPermissions(GlobalPermissions.PREVIEW_EXECUTION); + + when(propertiesDao.selectGlobalProperties(session)).thenReturn(newArrayList( + new PropertyDto().setKey("foo").setValue("bar"), + new PropertyDto().setKey("foo.secured").setValue("1234"), + new PropertyDto().setKey("foo.license.secured").setValue("5678") + )); + + WsTester.TestRequest request = tester.newGetRequest("batch", "global"); + request.execute().assertJson(getClass(), "return_only_license_settings_without_scan_but_with_preview_permission.json"); + } + + @Test + public void access_forbidden_without_scan_and_preview_permission() throws Exception { + userSessionRule.setGlobalPermissions(); + + when(propertiesDao.selectGlobalProperties(session)).thenReturn(newArrayList( + new PropertyDto().setKey("foo").setValue("bar"), + new PropertyDto().setKey("foo.secured").setValue("1234"), + new PropertyDto().setKey("foo.license.secured").setValue("5678") + )); + + thrown.expect(ForbiddenException.class); + + tester.newGetRequest("batch", "global").execute(); + } +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/batch/GlobalRepositoryActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/batch/GlobalRepositoryActionTest.java deleted file mode 100644 index b6944c77738..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/batch/GlobalRepositoryActionTest.java +++ /dev/null @@ -1,127 +0,0 @@ -/* - * 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.batch; - -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; -import org.sonar.core.measure.db.MetricDto; -import org.sonar.core.permission.GlobalPermissions; -import org.sonar.core.persistence.DbSession; -import org.sonar.core.properties.PropertiesDao; -import org.sonar.core.properties.PropertyDto; -import org.sonar.server.db.DbClient; -import org.sonar.server.exceptions.ForbiddenException; -import org.sonar.server.measure.persistence.MetricDao; -import org.sonar.server.tester.UserSessionRule; -import org.sonar.server.ws.WsTester; - -import static com.google.common.collect.Lists.newArrayList; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -@RunWith(MockitoJUnitRunner.class) -public class GlobalRepositoryActionTest { - @Rule - public UserSessionRule userSessionRule = UserSessionRule.standalone(); - @Rule - public ExpectedException thrown = ExpectedException.none(); - - @Mock - DbSession session; - - @Mock - MetricDao metricDao; - - @Mock - PropertiesDao propertiesDao; - - WsTester tester; - - @Before - public void setUp() { - DbClient dbClient = mock(DbClient.class); - when(dbClient.openSession(false)).thenReturn(session); - when(dbClient.metricDao()).thenReturn(metricDao); - - tester = new WsTester(new BatchWs(mock(BatchIndex.class), new GlobalRepositoryAction(dbClient, propertiesDao, userSessionRule))); - } - - @Test - public void return_metrics() throws Exception { - userSessionRule.setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION, GlobalPermissions.PREVIEW_EXECUTION); - - when(metricDao.selectEnabled(session)).thenReturn(newArrayList( - new MetricDto().setId(1).setKey("coverage").setDescription("Coverage by unit tests").setValueType("PERCENT").setQualitative(true) - .setWorstValue(0d).setBestValue(100d).setOptimizedBestValue(false).setDirection(1).setEnabled(true) - )); - - WsTester.TestRequest request = tester.newGetRequest("batch", "global"); - request.execute().assertJson(getClass(), "return_global_referentials.json"); - } - - @Test - public void return_global_settings() throws Exception { - userSessionRule.setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION, GlobalPermissions.PREVIEW_EXECUTION); - - when(propertiesDao.selectGlobalProperties(session)).thenReturn(newArrayList( - new PropertyDto().setKey("foo").setValue("bar"), - new PropertyDto().setKey("foo.secured").setValue("1234"), - new PropertyDto().setKey("foo.license.secured").setValue("5678") - )); - - WsTester.TestRequest request = tester.newGetRequest("batch", "global"); - request.execute().assertJson(getClass(), "return_global_settings.json"); - } - - @Test - public void return_only_license_settings_without_scan_but_with_preview_permission() throws Exception { - userSessionRule.setGlobalPermissions(GlobalPermissions.PREVIEW_EXECUTION); - - when(propertiesDao.selectGlobalProperties(session)).thenReturn(newArrayList( - new PropertyDto().setKey("foo").setValue("bar"), - new PropertyDto().setKey("foo.secured").setValue("1234"), - new PropertyDto().setKey("foo.license.secured").setValue("5678") - )); - - WsTester.TestRequest request = tester.newGetRequest("batch", "global"); - request.execute().assertJson(getClass(), "return_only_license_settings_without_scan_but_with_preview_permission.json"); - } - - @Test - public void access_forbidden_without_scan_and_preview_permission() throws Exception { - userSessionRule.setGlobalPermissions(); - - when(propertiesDao.selectGlobalProperties(session)).thenReturn(newArrayList( - new PropertyDto().setKey("foo").setValue("bar"), - new PropertyDto().setKey("foo.secured").setValue("1234"), - new PropertyDto().setKey("foo.license.secured").setValue("5678") - )); - - thrown.expect(ForbiddenException.class); - - tester.newGetRequest("batch", "global").execute(); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/batch/ProjectActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/batch/ProjectActionTest.java new file mode 100644 index 00000000000..dc70a1eae9d --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/batch/ProjectActionTest.java @@ -0,0 +1,70 @@ +/* + * 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.batch; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; +import org.sonar.batch.protocol.input.ProjectRepositories; +import org.sonar.server.ws.WsTester; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class ProjectActionTest { + + @Mock + ProjectRepositoryLoader projectRepositoryLoader; + + WsTester tester; + + @Before + public void setUp() { + tester = new WsTester(new BatchWs(mock(BatchIndex.class), new ProjectAction(projectRepositoryLoader))); + } + + @Test + public void project_referentials() throws Exception { + String projectKey = "org.codehaus.sonar:sonar"; + + ProjectRepositories projectReferentials = mock(ProjectRepositories.class); + when(projectReferentials.toJson()).thenReturn("{\"settingsByModule\": {}}"); + + ArgumentCaptor queryArgumentCaptor = ArgumentCaptor.forClass(ProjectRepositoryQuery.class); + when(projectRepositoryLoader.load(queryArgumentCaptor.capture())).thenReturn(projectReferentials); + + WsTester.TestRequest request = tester.newGetRequest("batch", "project") + .setParam("key", projectKey) + .setParam("profile", "Default") + .setParam("preview", "false"); + request.execute().assertJson("{\"settingsByModule\": {}}"); + + assertThat(queryArgumentCaptor.getValue().getModuleKey()).isEqualTo(projectKey); + assertThat(queryArgumentCaptor.getValue().getProfileName()).isEqualTo("Default"); + assertThat(queryArgumentCaptor.getValue().isPreview()).isFalse(); + } + +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/batch/ProjectRepositoryActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/batch/ProjectRepositoryActionTest.java deleted file mode 100644 index 161d65ce6d9..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/batch/ProjectRepositoryActionTest.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * 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.batch; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; -import org.sonar.batch.protocol.input.ProjectRepositories; -import org.sonar.server.ws.WsTester; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -@RunWith(MockitoJUnitRunner.class) -public class ProjectRepositoryActionTest { - - @Mock - ProjectRepositoryLoader projectRepositoryLoader; - - WsTester tester; - - @Before - public void setUp() { - tester = new WsTester(new BatchWs(mock(BatchIndex.class), new ProjectRepositoryAction(projectRepositoryLoader))); - } - - @Test - public void project_referentials() throws Exception { - String projectKey = "org.codehaus.sonar:sonar"; - - ProjectRepositories projectReferentials = mock(ProjectRepositories.class); - when(projectReferentials.toJson()).thenReturn("{\"settingsByModule\": {}}"); - - ArgumentCaptor queryArgumentCaptor = ArgumentCaptor.forClass(ProjectRepositoryQuery.class); - when(projectRepositoryLoader.load(queryArgumentCaptor.capture())).thenReturn(projectReferentials); - - WsTester.TestRequest request = tester.newGetRequest("batch", "project") - .setParam("key", projectKey) - .setParam("profile", "Default") - .setParam("preview", "false"); - request.execute().assertJson("{\"settingsByModule\": {}}"); - - assertThat(queryArgumentCaptor.getValue().getModuleKey()).isEqualTo(projectKey); - assertThat(queryArgumentCaptor.getValue().getProfileName()).isEqualTo("Default"); - assertThat(queryArgumentCaptor.getValue().isPreview()).isFalse(); - } - -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/component/ws/AppActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/component/ws/AppActionTest.java new file mode 100644 index 00000000000..c29c021743b --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/component/ws/AppActionTest.java @@ -0,0 +1,248 @@ +/* + * 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.component.ws; + +import java.util.List; +import java.util.Locale; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; +import org.sonar.api.i18n.I18n; +import org.sonar.api.measures.CoreMetrics; +import org.sonar.api.utils.Duration; +import org.sonar.api.utils.Durations; +import org.sonar.api.web.UserRole; +import org.sonar.core.component.ComponentDto; +import org.sonar.core.measure.db.MeasureDto; +import org.sonar.core.persistence.DbSession; +import org.sonar.core.properties.PropertiesDao; +import org.sonar.core.properties.PropertyDto; +import org.sonar.core.properties.PropertyQuery; +import org.sonar.server.component.ComponentTesting; +import org.sonar.server.component.db.ComponentDao; +import org.sonar.server.db.DbClient; +import org.sonar.server.exceptions.NotFoundException; +import org.sonar.server.measure.persistence.MeasureDao; +import org.sonar.server.tester.UserSessionRule; +import org.sonar.server.ws.WsTester; + +import static com.google.common.collect.Lists.newArrayList; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.fail; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyListOf; +import static org.mockito.Matchers.anyString; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class AppActionTest { + @Rule + public UserSessionRule userSessionRule = UserSessionRule.standalone(); + + static final String SUB_PROJECT_KEY = "org.codehaus.sonar:sonar-plugin-api"; + static final String COMPONENT_KEY = "org.codehaus.sonar:sonar-plugin-api:src/main/java/org/sonar/api/Plugin.java"; + static final String COMPONENT_UUID = "ABCDE"; + static final String PROJECT_UUID = "THE_PROJECT"; + + @Mock + DbSession session; + + @Mock + ComponentDao componentDao; + + @Mock + PropertiesDao propertiesDao; + + @Mock + MeasureDao measureDao; + @Mock + Durations durations; + + @Mock + I18n i18n; + + @Captor + ArgumentCaptor> measureKeysCaptor; + + List measures = newArrayList(); + + WsTester tester; + + @Before + public void setUp() { + DbClient dbClient = mock(DbClient.class); + when(dbClient.openSession(false)).thenReturn(session); + when(dbClient.componentDao()).thenReturn(componentDao); + when(dbClient.propertiesDao()).thenReturn(propertiesDao); + when(dbClient.measureDao()).thenReturn(measureDao); + + when(measureDao.findByComponentKeyAndMetricKeys(eq(session), anyString(), anyListOf(String.class))).thenReturn(measures); + + tester = new WsTester(new ComponentsWs(new AppAction(dbClient, durations, i18n, userSessionRule), mock(SearchAction.class))); + } + + @Test + public void app() throws Exception { + userSessionRule.login("john").addComponentPermission(UserRole.USER, SUB_PROJECT_KEY, COMPONENT_KEY); + ComponentDto project = newProject(); + + ComponentDto file = ComponentTesting.newFileDto(project) + .setId(10L) + .setKey(COMPONENT_KEY) + .setUuid(COMPONENT_UUID) + .setName("Plugin.java") + .setProjectUuid("THE_PROJECT") + .setLongName("src/main/java/org/sonar/api/Plugin.java") + .setPath("src/main/java/org/sonar/api/Plugin.java") + .setParentProjectId(5L); + when(componentDao.selectNullableByUuid(session, COMPONENT_UUID)).thenReturn(file); + when(componentDao.selectById(5L, session)).thenReturn(new ComponentDto().setId(5L).setLongName("SonarQube :: Plugin API").setKey(SUB_PROJECT_KEY)); + when(componentDao.selectByUuid(session, project.uuid())).thenReturn(project); + when(propertiesDao.selectByQuery(any(PropertyQuery.class), eq(session))).thenReturn(newArrayList(new PropertyDto())); + + WsTester.TestRequest request = tester.newGetRequest("api/components", "app").setParam("uuid", COMPONENT_UUID); + request.execute().assertJson(getClass(), "app.json"); + } + + @Test + public void app_with_measures() throws Exception { + userSessionRule.addComponentPermission(UserRole.USER, SUB_PROJECT_KEY, COMPONENT_KEY); + ComponentDto project = newProject(); + newComponent(project); + + addMeasure(CoreMetrics.LINES_KEY, 200); + addMeasure(CoreMetrics.COVERAGE_KEY, 95.4); + addMeasure(CoreMetrics.DUPLICATED_LINES_DENSITY_KEY, 7.4); + addMeasure(CoreMetrics.SQALE_RATING_KEY, "C"); + addMeasure(CoreMetrics.SQALE_DEBT_RATIO_KEY, 35d); + + measures.add(new MeasureDto().setComponentKey(COMPONENT_KEY).setMetricKey(CoreMetrics.TECHNICAL_DEBT_KEY).setValue(182.0)); + when(durations.format(any(Locale.class), any(Duration.class), eq(Durations.DurationFormat.SHORT))).thenReturn("3h 2min"); + + WsTester.TestRequest request = tester.newGetRequest("api/components", "app").setParam("uuid", COMPONENT_UUID); + request.execute().assertJson(getClass(), "app_with_measures.json"); + + verify(measureDao).findByComponentKeyAndMetricKeys(eq(session), eq(COMPONENT_KEY), measureKeysCaptor.capture()); + assertThat(measureKeysCaptor.getValue()).contains(CoreMetrics.LINES_KEY, CoreMetrics.COVERAGE_KEY, CoreMetrics.DUPLICATED_LINES_DENSITY_KEY, + CoreMetrics.TECHNICAL_DEBT_KEY); + } + + @Test + public void app_with_overall_measure() throws Exception { + userSessionRule.addComponentPermission(UserRole.USER, SUB_PROJECT_KEY, COMPONENT_KEY); + ComponentDto project = newProject(); + newComponent(project); + + addMeasure(CoreMetrics.OVERALL_COVERAGE_KEY, 90.1); + addMeasure(CoreMetrics.COVERAGE_KEY, 95.4); + addMeasure(CoreMetrics.IT_COVERAGE_KEY, 85.2); + + WsTester.TestRequest request = tester.newGetRequest("api/components", "app").setParam("uuid", COMPONENT_UUID); + request.execute().assertJson(getClass(), "app_with_overall_measure.json"); + } + + @Test + public void app_with_ut_measure() throws Exception { + userSessionRule.addComponentPermission(UserRole.USER, SUB_PROJECT_KEY, COMPONENT_KEY); + ComponentDto project = newProject(); + newComponent(project); + + addMeasure(CoreMetrics.COVERAGE_KEY, 95.4); + addMeasure(CoreMetrics.IT_COVERAGE_KEY, 85.2); + + WsTester.TestRequest request = tester.newGetRequest("api/components", "app").setParam("uuid", COMPONENT_UUID); + request.execute().assertJson(getClass(), "app_with_ut_measure.json"); + } + + @Test + public void app_with_it_measure() throws Exception { + userSessionRule.addComponentPermission(UserRole.USER, SUB_PROJECT_KEY, COMPONENT_KEY); + ComponentDto project = newProject(); + newComponent(project); + + addMeasure(CoreMetrics.IT_COVERAGE_KEY, 85.2); + + WsTester.TestRequest request = tester.newGetRequest("api/components", "app").setParam("uuid", COMPONENT_UUID); + request.execute().assertJson(getClass(), "app_with_it_measure.json"); + } + + @Test + public void fail_on_unknown_component() { + userSessionRule.login("john").addComponentPermission(UserRole.USER, SUB_PROJECT_KEY, COMPONENT_KEY); + when(componentDao.selectNullableByUuid(session, COMPONENT_UUID)).thenReturn(null); + + try { + tester.newGetRequest("api/components", "app").setParam("uuid", COMPONENT_UUID).execute(); + fail(); + } catch (Exception e) { + assertThat(e).isInstanceOf(NotFoundException.class).hasMessage("Component 'ABCDE' does not exist"); + } + } + + private ComponentDto newProject() { + return ComponentTesting.newProjectDto() + .setId(1L) + .setName("SonarQube") + .setUuid(PROJECT_UUID) + .setLongName("SonarQube") + .setKey("org.codehaus.sonar:sonar"); + } + + private ComponentDto newComponent(ComponentDto project) { + ComponentDto file = ComponentTesting.newFileDto(project) + .setId(10L) + .setQualifier("FIL") + .setKey(COMPONENT_KEY) + .setUuid(COMPONENT_UUID) + .setProjectUuid(PROJECT_UUID) + .setName("Plugin.java") + .setLongName("src/main/java/org/sonar/api/Plugin.java") + .setPath("src/main/java/org/sonar/api/Plugin.java") + .setParentProjectId(5L); + when(componentDao.selectNullableByUuid(session, COMPONENT_UUID)).thenReturn(file); + when(componentDao.selectById(5L, session)).thenReturn(new ComponentDto().setId(5L).setLongName("SonarQube :: Plugin API").setKey(SUB_PROJECT_KEY)); + when(componentDao.selectByUuid(session, project.uuid())).thenReturn(project); + return file; + } + + private void addMeasure(String metricKey, Integer value) { + measures.add(new MeasureDto().setComponentKey(COMPONENT_KEY).setMetricKey(metricKey).setValue(value.doubleValue())); + when(i18n.formatInteger(any(Locale.class), eq(value.intValue()))).thenReturn(Integer.toString(value)); + } + + private void addMeasure(String metricKey, Double value) { + measures.add(new MeasureDto().setComponentKey(COMPONENT_KEY).setMetricKey(metricKey).setValue(value)); + when(i18n.formatDouble(any(Locale.class), eq(value))).thenReturn(Double.toString(value)); + } + + private void addMeasure(String metricKey, String value) { + measures.add(new MeasureDto().setComponentKey(COMPONENT_KEY).setMetricKey(metricKey).setData(value)); + } + +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/component/ws/ComponentAppActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/component/ws/ComponentAppActionTest.java deleted file mode 100644 index 5089d87590c..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/component/ws/ComponentAppActionTest.java +++ /dev/null @@ -1,248 +0,0 @@ -/* - * 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.component.ws; - -import java.util.List; -import java.util.Locale; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Captor; -import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; -import org.sonar.api.i18n.I18n; -import org.sonar.api.measures.CoreMetrics; -import org.sonar.api.utils.Duration; -import org.sonar.api.utils.Durations; -import org.sonar.api.web.UserRole; -import org.sonar.core.component.ComponentDto; -import org.sonar.core.measure.db.MeasureDto; -import org.sonar.core.persistence.DbSession; -import org.sonar.core.properties.PropertiesDao; -import org.sonar.core.properties.PropertyDto; -import org.sonar.core.properties.PropertyQuery; -import org.sonar.server.component.ComponentTesting; -import org.sonar.server.component.db.ComponentDao; -import org.sonar.server.db.DbClient; -import org.sonar.server.exceptions.NotFoundException; -import org.sonar.server.measure.persistence.MeasureDao; -import org.sonar.server.tester.UserSessionRule; -import org.sonar.server.ws.WsTester; - -import static com.google.common.collect.Lists.newArrayList; -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.fail; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyListOf; -import static org.mockito.Matchers.anyString; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -@RunWith(MockitoJUnitRunner.class) -public class ComponentAppActionTest { - @Rule - public UserSessionRule userSessionRule = UserSessionRule.standalone(); - - static final String SUB_PROJECT_KEY = "org.codehaus.sonar:sonar-plugin-api"; - static final String COMPONENT_KEY = "org.codehaus.sonar:sonar-plugin-api:src/main/java/org/sonar/api/Plugin.java"; - static final String COMPONENT_UUID = "ABCDE"; - static final String PROJECT_UUID = "THE_PROJECT"; - - @Mock - DbSession session; - - @Mock - ComponentDao componentDao; - - @Mock - PropertiesDao propertiesDao; - - @Mock - MeasureDao measureDao; - @Mock - Durations durations; - - @Mock - I18n i18n; - - @Captor - ArgumentCaptor> measureKeysCaptor; - - List measures = newArrayList(); - - WsTester tester; - - @Before - public void setUp() { - DbClient dbClient = mock(DbClient.class); - when(dbClient.openSession(false)).thenReturn(session); - when(dbClient.componentDao()).thenReturn(componentDao); - when(dbClient.propertiesDao()).thenReturn(propertiesDao); - when(dbClient.measureDao()).thenReturn(measureDao); - - when(measureDao.findByComponentKeyAndMetricKeys(eq(session), anyString(), anyListOf(String.class))).thenReturn(measures); - - tester = new WsTester(new ComponentsWs(new ComponentAppAction(dbClient, durations, i18n, userSessionRule), mock(SearchAction.class))); - } - - @Test - public void app() throws Exception { - userSessionRule.login("john").addComponentPermission(UserRole.USER, SUB_PROJECT_KEY, COMPONENT_KEY); - ComponentDto project = newProject(); - - ComponentDto file = ComponentTesting.newFileDto(project) - .setId(10L) - .setKey(COMPONENT_KEY) - .setUuid(COMPONENT_UUID) - .setName("Plugin.java") - .setProjectUuid("THE_PROJECT") - .setLongName("src/main/java/org/sonar/api/Plugin.java") - .setPath("src/main/java/org/sonar/api/Plugin.java") - .setParentProjectId(5L); - when(componentDao.selectNullableByUuid(session, COMPONENT_UUID)).thenReturn(file); - when(componentDao.selectById(5L, session)).thenReturn(new ComponentDto().setId(5L).setLongName("SonarQube :: Plugin API").setKey(SUB_PROJECT_KEY)); - when(componentDao.selectByUuid(session, project.uuid())).thenReturn(project); - when(propertiesDao.selectByQuery(any(PropertyQuery.class), eq(session))).thenReturn(newArrayList(new PropertyDto())); - - WsTester.TestRequest request = tester.newGetRequest("api/components", "app").setParam("uuid", COMPONENT_UUID); - request.execute().assertJson(getClass(), "app.json"); - } - - @Test - public void app_with_measures() throws Exception { - userSessionRule.addComponentPermission(UserRole.USER, SUB_PROJECT_KEY, COMPONENT_KEY); - ComponentDto project = newProject(); - newComponent(project); - - addMeasure(CoreMetrics.LINES_KEY, 200); - addMeasure(CoreMetrics.COVERAGE_KEY, 95.4); - addMeasure(CoreMetrics.DUPLICATED_LINES_DENSITY_KEY, 7.4); - addMeasure(CoreMetrics.SQALE_RATING_KEY, "C"); - addMeasure(CoreMetrics.SQALE_DEBT_RATIO_KEY, 35d); - - measures.add(new MeasureDto().setComponentKey(COMPONENT_KEY).setMetricKey(CoreMetrics.TECHNICAL_DEBT_KEY).setValue(182.0)); - when(durations.format(any(Locale.class), any(Duration.class), eq(Durations.DurationFormat.SHORT))).thenReturn("3h 2min"); - - WsTester.TestRequest request = tester.newGetRequest("api/components", "app").setParam("uuid", COMPONENT_UUID); - request.execute().assertJson(getClass(), "app_with_measures.json"); - - verify(measureDao).findByComponentKeyAndMetricKeys(eq(session), eq(COMPONENT_KEY), measureKeysCaptor.capture()); - assertThat(measureKeysCaptor.getValue()).contains(CoreMetrics.LINES_KEY, CoreMetrics.COVERAGE_KEY, CoreMetrics.DUPLICATED_LINES_DENSITY_KEY, - CoreMetrics.TECHNICAL_DEBT_KEY); - } - - @Test - public void app_with_overall_measure() throws Exception { - userSessionRule.addComponentPermission(UserRole.USER, SUB_PROJECT_KEY, COMPONENT_KEY); - ComponentDto project = newProject(); - newComponent(project); - - addMeasure(CoreMetrics.OVERALL_COVERAGE_KEY, 90.1); - addMeasure(CoreMetrics.COVERAGE_KEY, 95.4); - addMeasure(CoreMetrics.IT_COVERAGE_KEY, 85.2); - - WsTester.TestRequest request = tester.newGetRequest("api/components", "app").setParam("uuid", COMPONENT_UUID); - request.execute().assertJson(getClass(), "app_with_overall_measure.json"); - } - - @Test - public void app_with_ut_measure() throws Exception { - userSessionRule.addComponentPermission(UserRole.USER, SUB_PROJECT_KEY, COMPONENT_KEY); - ComponentDto project = newProject(); - newComponent(project); - - addMeasure(CoreMetrics.COVERAGE_KEY, 95.4); - addMeasure(CoreMetrics.IT_COVERAGE_KEY, 85.2); - - WsTester.TestRequest request = tester.newGetRequest("api/components", "app").setParam("uuid", COMPONENT_UUID); - request.execute().assertJson(getClass(), "app_with_ut_measure.json"); - } - - @Test - public void app_with_it_measure() throws Exception { - userSessionRule.addComponentPermission(UserRole.USER, SUB_PROJECT_KEY, COMPONENT_KEY); - ComponentDto project = newProject(); - newComponent(project); - - addMeasure(CoreMetrics.IT_COVERAGE_KEY, 85.2); - - WsTester.TestRequest request = tester.newGetRequest("api/components", "app").setParam("uuid", COMPONENT_UUID); - request.execute().assertJson(getClass(), "app_with_it_measure.json"); - } - - @Test - public void fail_on_unknown_component() { - userSessionRule.login("john").addComponentPermission(UserRole.USER, SUB_PROJECT_KEY, COMPONENT_KEY); - when(componentDao.selectNullableByUuid(session, COMPONENT_UUID)).thenReturn(null); - - try { - tester.newGetRequest("api/components", "app").setParam("uuid", COMPONENT_UUID).execute(); - fail(); - } catch (Exception e) { - assertThat(e).isInstanceOf(NotFoundException.class).hasMessage("Component 'ABCDE' does not exist"); - } - } - - private ComponentDto newProject() { - return ComponentTesting.newProjectDto() - .setId(1L) - .setName("SonarQube") - .setUuid(PROJECT_UUID) - .setLongName("SonarQube") - .setKey("org.codehaus.sonar:sonar"); - } - - private ComponentDto newComponent(ComponentDto project) { - ComponentDto file = ComponentTesting.newFileDto(project) - .setId(10L) - .setQualifier("FIL") - .setKey(COMPONENT_KEY) - .setUuid(COMPONENT_UUID) - .setProjectUuid(PROJECT_UUID) - .setName("Plugin.java") - .setLongName("src/main/java/org/sonar/api/Plugin.java") - .setPath("src/main/java/org/sonar/api/Plugin.java") - .setParentProjectId(5L); - when(componentDao.selectNullableByUuid(session, COMPONENT_UUID)).thenReturn(file); - when(componentDao.selectById(5L, session)).thenReturn(new ComponentDto().setId(5L).setLongName("SonarQube :: Plugin API").setKey(SUB_PROJECT_KEY)); - when(componentDao.selectByUuid(session, project.uuid())).thenReturn(project); - return file; - } - - private void addMeasure(String metricKey, Integer value) { - measures.add(new MeasureDto().setComponentKey(COMPONENT_KEY).setMetricKey(metricKey).setValue(value.doubleValue())); - when(i18n.formatInteger(any(Locale.class), eq(value.intValue()))).thenReturn(Integer.toString(value)); - } - - private void addMeasure(String metricKey, Double value) { - measures.add(new MeasureDto().setComponentKey(COMPONENT_KEY).setMetricKey(metricKey).setValue(value)); - when(i18n.formatDouble(any(Locale.class), eq(value))).thenReturn(Double.toString(value)); - } - - private void addMeasure(String metricKey, String value) { - measures.add(new MeasureDto().setComponentKey(COMPONENT_KEY).setMetricKey(metricKey).setData(value)); - } - -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/component/ws/ComponentsWsTest.java b/server/sonar-server/src/test/java/org/sonar/server/component/ws/ComponentsWsTest.java index 486e5b33741..94baa386fc6 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/component/ws/ComponentsWsTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/component/ws/ComponentsWsTest.java @@ -42,7 +42,7 @@ public class ComponentsWsTest { @Before public void setUp() { - WsTester tester = new WsTester(new ComponentsWs(new ComponentAppAction(mock(DbClient.class), mock(Durations.class), mock(I18n.class), userSessionRule), new SearchAction(mock(DbClient.class), userSessionRule))); + WsTester tester = new WsTester(new ComponentsWs(new AppAction(mock(DbClient.class), mock(Durations.class), mock(I18n.class), userSessionRule), new SearchAction(mock(DbClient.class), userSessionRule))); controller = tester.controller("api/components"); } diff --git a/server/sonar-server/src/test/java/org/sonar/server/component/ws/ProjectsDeleteActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/component/ws/ProjectsDeleteActionTest.java deleted file mode 100644 index b21454b0980..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/component/ws/ProjectsDeleteActionTest.java +++ /dev/null @@ -1,252 +0,0 @@ -/* - * 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.component.ws; - -import com.google.common.collect.ImmutableMap; -import org.junit.After; -import org.junit.Before; -import org.junit.ClassRule; -import org.junit.Rule; -import org.junit.Test; -import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; -import org.sonar.api.config.Settings; -import org.sonar.api.resources.Qualifiers; -import org.sonar.api.resources.ResourceType; -import org.sonar.api.resources.ResourceTypes; -import org.sonar.api.rule.RuleKey; -import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; -import org.sonar.core.component.ComponentDto; -import org.sonar.core.component.SnapshotDto; -import org.sonar.core.issue.db.IssueDto; -import org.sonar.core.persistence.DbSession; -import org.sonar.core.persistence.DbTester; -import org.sonar.core.purge.PurgeDao; -import org.sonar.core.purge.PurgeProfiler; -import org.sonar.core.resource.ResourceDao; -import org.sonar.core.rule.RuleDto; -import org.sonar.server.component.ComponentCleanerService; -import org.sonar.server.component.ComponentTesting; -import org.sonar.server.component.SnapshotTesting; -import org.sonar.server.component.db.ComponentDao; -import org.sonar.server.component.db.SnapshotDao; -import org.sonar.server.db.DbClient; -import org.sonar.server.es.EsTester; -import org.sonar.server.exceptions.ForbiddenException; -import org.sonar.server.issue.IssueTesting; -import org.sonar.server.issue.db.IssueDao; -import org.sonar.server.issue.index.IssueAuthorizationIndexer; -import org.sonar.server.issue.index.IssueIndexDefinition; -import org.sonar.server.issue.index.IssueIndexer; -import org.sonar.server.rule.RuleTesting; -import org.sonar.server.rule.db.RuleDao; -import org.sonar.server.source.index.SourceLineDoc; -import org.sonar.server.source.index.SourceLineIndexDefinition; -import org.sonar.server.source.index.SourceLineIndexer; -import org.sonar.server.test.index.TestDoc; -import org.sonar.server.test.index.TestIndexDefinition; -import org.sonar.server.test.index.TestIndexer; -import org.sonar.server.tester.UserSessionRule; -import org.sonar.server.ws.WsTester; -import org.sonar.test.DbTests; - -import java.util.Arrays; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Matchers.anyString; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -@Category(DbTests.class) -public class ProjectsDeleteActionTest { - - @ClassRule - public static DbTester db = new DbTester(); - @ClassRule - public static EsTester es = new EsTester().addDefinitions(new IssueIndexDefinition(new Settings()), new SourceLineIndexDefinition(new Settings()), - new TestIndexDefinition(new Settings())); - @Rule - public UserSessionRule userSessionRule = UserSessionRule.standalone(); - @Rule - public ExpectedException expectedException = ExpectedException.none(); - WsTester ws; - DbClient dbClient; - DbSession dbSession; - ResourceType resourceType; - - @Before - public void setUp() throws Exception { - ComponentDao componentDao = new ComponentDao(); - ResourceDao resourceDao = new ResourceDao(db.myBatis(), System2.INSTANCE); - PurgeDao purgeDao = new PurgeDao(db.myBatis(), resourceDao, new PurgeProfiler(), System2.INSTANCE); - dbClient = new DbClient(db.database(), db.myBatis(), componentDao, purgeDao, new RuleDao(System2.INSTANCE), new IssueDao(db.myBatis()), new SnapshotDao(System2.INSTANCE)); - dbSession = dbClient.openSession(false); - resourceType = mock(ResourceType.class); - when(resourceType.getBooleanProperty(anyString())).thenReturn(true); - ResourceTypes mockResourceTypes = mock(ResourceTypes.class); - when(mockResourceTypes.get(anyString())).thenReturn(resourceType); - ws = new WsTester(new ProjectsWs(new ProjectsDeleteAction(new ComponentCleanerService(dbClient, new IssueAuthorizationIndexer(dbClient, es.client()), new IssueIndexer( - dbClient, es.client()), new SourceLineIndexer(dbClient, es.client()), new TestIndexer(dbClient, es.client()), mockResourceTypes), dbClient, userSessionRule))); - db.truncateTables(); - es.truncateIndices(); - } - - @After - public void tearDown() throws Exception { - dbSession.close(); - } - - @Test - public void delete_projects_and_data_in_db_by_uuids() throws Exception { - userSessionRule.setGlobalPermissions(UserRole.ADMIN); - long snapshotId1 = insertNewProjectInDbAndReturnSnapshotId(1); - long snapshotId2 = insertNewProjectInDbAndReturnSnapshotId(2); - long snapshotId3 = insertNewProjectInDbAndReturnSnapshotId(3); - long snapshotId4 = insertNewProjectInDbAndReturnSnapshotId(4); - - ws.newGetRequest("api/projects", "delete") - .setParam("uuids", "project-uuid-1, project-uuid-3, project-uuid-4").execute(); - dbSession.commit(); - - assertThat(dbClient.componentDao().selectByUuids(dbSession, Arrays.asList("project-uuid-1", "project-uuid-3", "project-uuid-4"))).isEmpty(); - assertThat(dbClient.componentDao().selectByUuid(dbSession, "project-uuid-2")).isNotNull(); - assertThat(dbClient.snapshotDao().getNullableByKey(dbSession, snapshotId1)).isNull(); - assertThat(dbClient.snapshotDao().getNullableByKey(dbSession, snapshotId3)).isNull(); - assertThat(dbClient.snapshotDao().getNullableByKey(dbSession, snapshotId4)).isNull(); - assertThat(dbClient.snapshotDao().getNullableByKey(dbSession, snapshotId2)).isNotNull(); - assertThat(dbClient.issueDao().selectByKeys(dbSession, Arrays.asList("issue-key-1", "issue-key-3", "issue-key-4"))).isEmpty(); - assertThat(dbClient.issueDao().selectByKey(dbSession, "issue-key-2")).isNotNull(); - } - - @Test - public void delete_projects_and_data_in_db_by_keys() throws Exception { - userSessionRule.setGlobalPermissions(UserRole.ADMIN); - insertNewProjectInDbAndReturnSnapshotId(1); - insertNewProjectInDbAndReturnSnapshotId(2); - insertNewProjectInDbAndReturnSnapshotId(3); - insertNewProjectInDbAndReturnSnapshotId(4); - - ws.newGetRequest("api/projects", "delete") - .setParam("keys", "project-key-1, project-key-3, project-key-4").execute(); - dbSession.commit(); - - assertThat(dbClient.componentDao().selectByUuids(dbSession, Arrays.asList("project-uuid-1", "project-uuid-3", "project-uuid-4"))).isEmpty(); - assertThat(dbClient.componentDao().selectByUuid(dbSession, "project-uuid-2")).isNotNull(); - } - - @Test - public void delete_documents_indexes() throws Exception { - userSessionRule.setGlobalPermissions(UserRole.ADMIN); - insertNewProjectInIndexes(1); - insertNewProjectInIndexes(2); - insertNewProjectInIndexes(3); - insertNewProjectInIndexes(4); - - ws.newGetRequest("api/projects", "delete") - .setParam("keys", "project-key-1, project-key-3, project-key-4").execute(); - - String remainingProjectUuid = "project-uuid-2"; - assertThat(es.getDocumentFieldValues(IssueIndexDefinition.INDEX, IssueIndexDefinition.TYPE_ISSUE, IssueIndexDefinition.FIELD_ISSUE_PROJECT_UUID)) - .containsOnly(remainingProjectUuid); - assertThat(es.getDocumentFieldValues(IssueIndexDefinition.INDEX, IssueIndexDefinition.TYPE_AUTHORIZATION, IssueIndexDefinition.FIELD_AUTHORIZATION_PROJECT_UUID)) - .containsOnly(remainingProjectUuid); - assertThat(es.getDocumentFieldValues(SourceLineIndexDefinition.INDEX, SourceLineIndexDefinition.TYPE, SourceLineIndexDefinition.FIELD_PROJECT_UUID)) - .containsOnly(remainingProjectUuid); - assertThat(es.getDocumentFieldValues(TestIndexDefinition.INDEX, TestIndexDefinition.TYPE, TestIndexDefinition.FIELD_PROJECT_UUID)) - .containsOnly(remainingProjectUuid); - } - - @Test - public void web_service_returns_204() throws Exception { - userSessionRule.setGlobalPermissions(UserRole.ADMIN); - insertNewProjectInDbAndReturnSnapshotId(1); - - WsTester.Result result = ws.newGetRequest("api/projects", "delete").setParam("uuids", "project-uuid-1").execute(); - - result.assertNoContent(); - } - - @Test - public void fail_if_insufficient_privileges() throws Exception { - userSessionRule.setGlobalPermissions(UserRole.CODEVIEWER, UserRole.ISSUE_ADMIN, UserRole.USER); - expectedException.expect(ForbiddenException.class); - - ws.newGetRequest("api/projects", "delete").setParam("uuids", "whatever-the-uuid").execute(); - } - - @Test - public void fail_if_scope_is_not_project() throws Exception { - userSessionRule.setGlobalPermissions(UserRole.ADMIN); - expectedException.expect(IllegalArgumentException.class); - dbClient.componentDao().insert(dbSession, ComponentTesting.newFileDto(ComponentTesting.newProjectDto(), "file-uuid")); - dbSession.commit(); - - ws.newGetRequest("api/projects", "delete").setParam("uuids", "file-uuid").execute(); - } - - @Test - public void fail_if_qualifier_is_not_deletable() throws Exception { - userSessionRule.setGlobalPermissions(UserRole.ADMIN); - expectedException.expect(IllegalArgumentException.class); - dbClient.componentDao().insert(dbSession, ComponentTesting.newProjectDto("project-uuid").setQualifier(Qualifiers.FILE)); - dbSession.commit(); - when(resourceType.getBooleanProperty(anyString())).thenReturn(false); - - ws.newGetRequest("api/projects", "delete").setParam("uuids", "project-uuid").execute(); - } - - private long insertNewProjectInDbAndReturnSnapshotId(int id) { - String suffix = String.valueOf(id); - ComponentDto project = ComponentTesting - .newProjectDto("project-uuid-" + suffix) - .setKey("project-key-" + suffix); - RuleDto rule = RuleTesting.newDto(RuleKey.of("sonarqube", "rule-" + suffix)); - dbClient.ruleDao().insert(dbSession, rule); - IssueDto issue = IssueTesting.newDto(rule, project, project).setKee("issue-key-" + suffix); - dbClient.componentDao().insert(dbSession, project); - SnapshotDto snapshot = dbClient.snapshotDao().insert(dbSession, SnapshotTesting.createForProject(project)); - dbClient.issueDao().insert(dbSession, issue); - dbSession.commit(); - - return snapshot.getId(); - } - - private void insertNewProjectInIndexes(int id) throws Exception { - String suffix = String.valueOf(id); - ComponentDto project = ComponentTesting - .newProjectDto("project-uuid-" + suffix) - .setKey("project-key-" + suffix); - dbClient.componentDao().insert(dbSession, project); - dbSession.commit(); - - es.putDocuments(IssueIndexDefinition.INDEX, IssueIndexDefinition.TYPE_ISSUE, IssueTesting.newDoc("issue-key-" + suffix, project)); - SourceLineDoc sourceLineDoc = new SourceLineDoc() - .setProjectUuid(project.uuid()) - .setFileUuid(project.uuid()); - es.putDocuments(IssueIndexDefinition.INDEX, IssueIndexDefinition.TYPE_AUTHORIZATION, - ImmutableMap.of(IssueIndexDefinition.FIELD_AUTHORIZATION_PROJECT_UUID, project.uuid())); - - es.putDocuments(SourceLineIndexDefinition.INDEX, SourceLineIndexDefinition.TYPE, sourceLineDoc); - TestDoc testDoc = new TestDoc().setUuid("test-uuid-" + suffix).setProjectUuid(project.uuid()).setFileUuid(project.uuid()); - es.putDocuments(TestIndexDefinition.INDEX, TestIndexDefinition.TYPE, testDoc); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/component/ws/ProjectsGhostsActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/component/ws/ProjectsGhostsActionTest.java deleted file mode 100644 index 1cd6a645b01..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/component/ws/ProjectsGhostsActionTest.java +++ /dev/null @@ -1,202 +0,0 @@ -/* - * 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.component.ws; - -import com.google.common.io.Resources; -import org.apache.commons.lang.StringUtils; -import org.junit.After; -import org.junit.Before; -import org.junit.ClassRule; -import org.junit.Rule; -import org.junit.Test; -import org.junit.experimental.categories.Category; -import org.sonar.api.server.ws.WebService.Param; -import org.sonar.api.utils.DateUtils; -import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; -import org.sonar.core.component.ComponentDto; -import org.sonar.core.component.SnapshotDto; -import org.sonar.core.persistence.DbSession; -import org.sonar.core.persistence.DbTester; -import org.sonar.server.component.ComponentTesting; -import org.sonar.server.component.SnapshotTesting; -import org.sonar.server.component.db.ComponentDao; -import org.sonar.server.component.db.SnapshotDao; -import org.sonar.server.db.DbClient; -import org.sonar.server.exceptions.ForbiddenException; -import org.sonar.server.tester.UserSessionRule; -import org.sonar.server.ws.WsTester; -import org.sonar.test.DbTests; -import org.sonar.test.JsonAssert; - -import static org.assertj.core.api.Assertions.assertThat; - -@Category(DbTests.class) -public class ProjectsGhostsActionTest { - - @ClassRule - public static DbTester db = new DbTester(); - @Rule - public UserSessionRule userSessionRule = UserSessionRule.standalone(); - WsTester ws; - - DbClient dbClient; - DbSession dbSession; - - @Before - public void setUp() { - dbClient = new DbClient(db.database(), db.myBatis(), new ComponentDao(), new SnapshotDao(System2.INSTANCE)); - dbSession = dbClient.openSession(false); - ws = new WsTester(new ProjectsWs(new ProjectsGhostsAction(dbClient, userSessionRule))); - db.truncateTables(); - } - - @After - public void tearDown() throws Exception { - dbSession.close(); - } - - @Test - public void ghost_projects_without_analyzed_projects() throws Exception { - userSessionRule.setGlobalPermissions(UserRole.ADMIN); - insertNewGhostProject("1"); - insertNewGhostProject("2"); - insertNewActiveProject("3"); - - WsTester.Result result = ws.newGetRequest("api/projects", "ghosts").execute(); - - result.assertJson(getClass(), "all-projects.json"); - assertThat(result.outputAsString()).doesNotContain("analyzed-uuid-3"); - } - - @Test - public void ghost_projects_with_correct_pagination() throws Exception { - userSessionRule.setGlobalPermissions(UserRole.ADMIN); - for (int i = 1; i <= 10; i++) { - insertNewGhostProject(String.valueOf(i)); - } - - WsTester.Result result = ws.newGetRequest("api/projects", "ghosts") - .setParam(Param.PAGE, "3") - .setParam(Param.PAGE_SIZE, "4") - .execute(); - - result.assertJson(getClass(), "pagination.json"); - assertThat(StringUtils.countMatches(result.outputAsString(), "ghost-uuid-")).isEqualTo(2); - } - - @Test - public void ghost_projects_with_chosen_fields() throws Exception { - userSessionRule.setGlobalPermissions(UserRole.ADMIN); - insertNewGhostProject("1"); - - WsTester.Result result = ws.newGetRequest("api/projects", "ghosts") - .setParam(Param.FIELDS, "name") - .execute(); - - assertThat(result.outputAsString()).contains("uuid", "name") - .doesNotContain("key") - .doesNotContain("creationDate"); - } - - @Test - public void ghost_projects_with_partial_query_on_name() throws Exception { - userSessionRule.setGlobalPermissions(UserRole.ADMIN); - - insertNewGhostProject("10"); - insertNewGhostProject("11"); - insertNewGhostProject("2"); - - WsTester.Result result = ws.newGetRequest("api/projects", "ghosts") - .setParam(Param.TEXT_QUERY, "name-1") - .execute(); - - assertThat(result.outputAsString()).contains("ghost-name-10", "ghost-name-11") - .doesNotContain("ghost-name-2"); - } - - @Test - public void ghost_projects_with_partial_query_on_key() throws Exception { - userSessionRule.setGlobalPermissions(UserRole.ADMIN); - - insertNewGhostProject("1"); - - WsTester.Result result = ws.newGetRequest("api/projects", "ghosts") - .setParam(Param.TEXT_QUERY, "GHOST-key") - .execute(); - - assertThat(result.outputAsString()).contains("ghost-key-1"); - } - - @Test - public void ghost_projects_base_on_json_example() throws Exception { - userSessionRule.setGlobalPermissions(UserRole.ADMIN); - ComponentDto hBaseProject = ComponentTesting.newProjectDto("ce4c03d6-430f-40a9-b777-ad877c00aa4d") - .setKey("org.apache.hbas:hbase") - .setName("HBase") - .setCreatedAt(DateUtils.parseDateTime("2015-03-04T23:03:44+0100")); - dbClient.componentDao().insert(dbSession, hBaseProject); - dbClient.snapshotDao().insert(dbSession, SnapshotTesting.createForProject(hBaseProject) - .setStatus(SnapshotDto.STATUS_UNPROCESSED)); - ComponentDto roslynProject = ComponentTesting.newProjectDto("c526ef20-131b-4486-9357-063fa64b5079") - .setKey("com.microsoft.roslyn:roslyn") - .setName("Roslyn") - .setCreatedAt(DateUtils.parseDateTime("2013-03-04T23:03:44+0100")); - dbClient.componentDao().insert(dbSession, roslynProject); - dbClient.snapshotDao().insert(dbSession, SnapshotTesting.createForProject(roslynProject) - .setStatus(SnapshotDto.STATUS_UNPROCESSED)); - dbSession.commit(); - - WsTester.Result result = ws.newGetRequest("api/projects", "ghosts").execute(); - - JsonAssert.assertJson(result.outputAsString()).isSimilarTo(Resources.getResource(getClass(), "projects-example-ghosts.json")); - } - - @Test(expected = ForbiddenException.class) - public void fail_if_does_not_have_sufficient_rights() throws Exception { - userSessionRule.setGlobalPermissions(UserRole.USER, UserRole.ISSUE_ADMIN, UserRole.CODEVIEWER); - - ws.newGetRequest("api/projects", "ghosts").execute(); - } - - private void insertNewGhostProject(String id) { - ComponentDto project = ComponentTesting - .newProjectDto("ghost-uuid-" + id) - .setName("ghost-name-" + id) - .setKey("ghost-key-" + id); - dbClient.componentDao().insert(dbSession, project); - SnapshotDto snapshot = SnapshotTesting.createForProject(project) - .setStatus(SnapshotDto.STATUS_UNPROCESSED); - dbClient.snapshotDao().insert(dbSession, snapshot); - dbSession.commit(); - } - - private void insertNewActiveProject(String id) { - ComponentDto project = ComponentTesting - .newProjectDto("analyzed-uuid-" + id) - .setName("analyzed-name-" + id) - .setKey("analyzed-key-" + id); - dbClient.componentDao().insert(dbSession, project); - SnapshotDto snapshot = SnapshotTesting.createForProject(project); - dbClient.snapshotDao().insert(dbSession, snapshot); - dbSession.commit(); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/component/ws/ProjectsProvisionedActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/component/ws/ProjectsProvisionedActionTest.java deleted file mode 100644 index 2abe36c9447..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/component/ws/ProjectsProvisionedActionTest.java +++ /dev/null @@ -1,181 +0,0 @@ -/* - * 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.component.ws; - -import com.google.common.io.Resources; -import org.apache.commons.lang.StringUtils; -import org.junit.After; -import org.junit.Before; -import org.junit.ClassRule; -import org.junit.Rule; -import org.junit.Test; -import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; -import org.sonar.api.server.ws.WebService.Param; -import org.sonar.api.utils.DateUtils; -import org.sonar.api.utils.System2; -import org.sonar.core.component.ComponentDto; -import org.sonar.core.component.SnapshotDto; -import org.sonar.core.permission.GlobalPermissions; -import org.sonar.core.persistence.DbSession; -import org.sonar.core.persistence.DbTester; -import org.sonar.server.component.ComponentTesting; -import org.sonar.server.component.SnapshotTesting; -import org.sonar.server.component.db.ComponentDao; -import org.sonar.server.component.db.SnapshotDao; -import org.sonar.server.db.DbClient; -import org.sonar.server.exceptions.ForbiddenException; -import org.sonar.server.tester.UserSessionRule; -import org.sonar.server.ws.WsTester; -import org.sonar.test.DbTests; -import org.sonar.test.JsonAssert; - -import static org.assertj.core.api.Assertions.assertThat; - -@Category(DbTests.class) -public class ProjectsProvisionedActionTest { - - @ClassRule - public static DbTester db = new DbTester(); - @Rule - public UserSessionRule userSessionRule = UserSessionRule.standalone(); - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - WsTester ws; - DbClient dbClient; - DbSession dbSession; - ComponentDao componentDao; - - @After - public void tearDown() { - dbSession.close(); - } - - @Before - public void setUp() { - dbClient = new DbClient(db.database(), db.myBatis(), new ComponentDao(), new SnapshotDao(System2.INSTANCE)); - dbSession = dbClient.openSession(false); - componentDao = dbClient.componentDao(); - db.truncateTables(); - ws = new WsTester(new ProjectsWs(new ProjectsProvisionedAction(dbClient, userSessionRule))); - } - - @Test - public void all_provisioned_projects_without_analyzed_projects() throws Exception { - userSessionRule.setGlobalPermissions(GlobalPermissions.PROVISIONING); - ComponentDto analyzedProject = ComponentTesting.newProjectDto("analyzed-uuid-1"); - componentDao.insert(dbSession, newProvisionedProject("1"), newProvisionedProject("2"), analyzedProject); - SnapshotDto snapshot = SnapshotTesting.createForProject(analyzedProject); - dbClient.snapshotDao().insert(dbSession, snapshot); - dbSession.commit(); - - WsTester.Result result = ws.newGetRequest("api/projects", "provisioned").execute(); - - result.assertJson(getClass(), "all-projects.json"); - assertThat(result.outputAsString()).doesNotContain("analyzed-uuid-1"); - } - - @Test - public void provisioned_projects_with_correct_pagination() throws Exception { - userSessionRule.setGlobalPermissions(GlobalPermissions.PROVISIONING); - for (int i = 1; i <= 10; i++) { - componentDao.insert(dbSession, newProvisionedProject(String.valueOf(i))); - } - dbSession.commit(); - - WsTester.TestRequest request = ws.newGetRequest("api/projects", "provisioned") - .setParam(Param.PAGE, "3") - .setParam(Param.PAGE_SIZE, "4"); - - String jsonOutput = request.execute().outputAsString(); - - assertThat(StringUtils.countMatches(jsonOutput, "provisioned-uuid-")).isEqualTo(2); - } - - @Test - public void provisioned_projects_with_desired_fields() throws Exception { - userSessionRule.setGlobalPermissions(GlobalPermissions.PROVISIONING); - componentDao.insert(dbSession, newProvisionedProject("1")); - dbSession.commit(); - - String jsonOutput = ws.newGetRequest("api/projects", "provisioned") - .setParam(Param.FIELDS, "key") - .execute().outputAsString(); - - assertThat(jsonOutput).contains("uuid", "key") - .doesNotContain("name") - .doesNotContain("creationDate"); - } - - @Test - public void provisioned_projects_with_query() throws Exception { - userSessionRule.setGlobalPermissions(GlobalPermissions.PROVISIONING); - componentDao.insert(dbSession, newProvisionedProject("1"), newProvisionedProject("2")); - dbSession.commit(); - - String jsonOutput = ws.newGetRequest("api/projects", "provisioned") - .setParam(Param.TEXT_QUERY, "PROVISIONED-name-2") - .execute().outputAsString(); - - assertThat(jsonOutput) - .contains("provisioned-name-2", "provisioned-uuid-2") - .doesNotContain("provisioned-uuid-1"); - assertThat(componentDao.countProvisionedProjects(dbSession, "name-2")).isEqualTo(1); - assertThat(componentDao.countProvisionedProjects(dbSession, "key-2")).isEqualTo(1); - assertThat(componentDao.countProvisionedProjects(dbSession, "visioned-name-")).isEqualTo(2); - } - - @Test - public void provisioned_projects_as_defined_in_the_example() throws Exception { - userSessionRule.setGlobalPermissions(GlobalPermissions.PROVISIONING); - ComponentDto hBaseProject = ComponentTesting.newProjectDto("ce4c03d6-430f-40a9-b777-ad877c00aa4d") - .setKey("org.apache.hbas:hbase") - .setName("HBase") - .setCreatedAt(DateUtils.parseDateTime("2015-03-04T23:03:44+0100")); - ComponentDto roslynProject = ComponentTesting.newProjectDto("c526ef20-131b-4486-9357-063fa64b5079") - .setKey("com.microsoft.roslyn:roslyn") - .setName("Roslyn") - .setCreatedAt(DateUtils.parseDateTime("2013-03-04T23:03:44+0100")); - componentDao.insert(dbSession, hBaseProject, roslynProject); - dbSession.commit(); - - WsTester.Result result = ws.newGetRequest("api/projects", "provisioned").execute(); - - JsonAssert.assertJson(result.outputAsString()).isSimilarTo(Resources.getResource(getClass(), "projects-example-provisioned.json")); - } - - @Test - public void fail_when_not_enough_privileges() throws Exception { - expectedException.expect(ForbiddenException.class); - userSessionRule.setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION); - componentDao.insert(dbSession, newProvisionedProject("1")); - - ws.newGetRequest("api/projects", "provisioned").execute(); - } - - private static ComponentDto newProvisionedProject(String uuid) { - return ComponentTesting - .newProjectDto("provisioned-uuid-" + uuid) - .setName("provisioned-name-" + uuid) - .setKey("provisioned-key-" + uuid); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/component/ws/ProjectsWsTest.java b/server/sonar-server/src/test/java/org/sonar/server/component/ws/ProjectsWsTest.java deleted file mode 100644 index 003bb4fa72a..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/component/ws/ProjectsWsTest.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * 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.component.ws; - -import org.junit.Before; -import org.junit.Test; -import org.sonar.api.server.ws.RailsHandler; -import org.sonar.api.server.ws.WebService; -import org.sonar.server.ws.WsTester; - -import static org.assertj.core.api.Assertions.assertThat; - -public class ProjectsWsTest { - - WebService.Controller controller; - WsTester ws; - - @Before - public void setUp() { - ws = new WsTester(new ProjectsWs()); - controller = ws.controller("api/projects"); - } - - @Test - public void define_controller() { - assertThat(controller).isNotNull(); - assertThat(controller.description()).isNotEmpty(); - assertThat(controller.since()).isEqualTo("2.10"); - assertThat(controller.actions()).hasSize(3); - } - - @Test - public void define_index_action() { - WebService.Action action = controller.action("index"); - assertThat(action).isNotNull(); - assertThat(action.handler()).isInstanceOf(RailsHandler.class); - assertThat(action.responseExampleAsString()).isNotEmpty(); - assertThat(action.params()).hasSize(8); - } - - @Test - public void define_create_action() { - WebService.Action action = controller.action("create"); - assertThat(action).isNotNull(); - assertThat(action.handler()).isInstanceOf(RailsHandler.class); - assertThat(action.responseExampleAsString()).isNotEmpty(); - assertThat(action.params()).hasSize(4); - } - - @Test - public void define_destroy_action() { - WebService.Action action = controller.action("destroy"); - assertThat(action).isNotNull(); - assertThat(action.handler()).isInstanceOf(RailsHandler.class); - assertThat(action.params()).hasSize(1); - } - -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/component/ws/SearchActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/component/ws/SearchActionTest.java index c63ff362391..7e3a0766895 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/component/ws/SearchActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/component/ws/SearchActionTest.java @@ -55,7 +55,7 @@ public class SearchActionTest { DbClient dbClient = new DbClient(dbTester.database(), dbTester.myBatis(), new ComponentDao(), new AuthorizationDao(dbTester.myBatis()), new ComponentIndexDao() ); - tester = new WsTester(new ComponentsWs(mock(ComponentAppAction.class), new SearchAction(dbClient, userSessionRule))); + tester = new WsTester(new ComponentsWs(mock(AppAction.class), new SearchAction(dbClient, userSessionRule))); } @Test diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/ws/ComputationWsTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/ws/ComputationWsTest.java index 8da36798f95..742afbf0d27 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/ws/ComputationWsTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/ws/ComputationWsTest.java @@ -21,29 +21,29 @@ package org.sonar.server.computation.ws; import org.junit.Test; -import org.sonar.api.server.ws.RequestHandler; import org.sonar.api.server.ws.WebService; +import org.sonar.server.activity.index.ActivityIndex; +import org.sonar.server.computation.ComputationThreadLauncher; +import org.sonar.server.computation.ReportQueue; +import org.sonar.server.user.UserSession; +import org.sonar.server.ws.WsTester; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; public class ComputationWsTest { + WsTester ws = new WsTester(new ComputationWs( + new QueueAction(mock(ReportQueue.class)), + new SubmitReportAction(mock(ReportQueue.class), mock(ComputationThreadLauncher.class), mock(UserSession.class)), + new HistoryAction(mock(ActivityIndex.class), mock(UserSession.class)))); + @Test public void define() { - ComputationWs ws = new ComputationWs(new ComputationWsAction() { - @Override - public void define(WebService.NewController controller) { - WebService.NewAction upload = controller.createAction("upload"); - upload.setHandler(mock(RequestHandler.class)); - } - }); - WebService.Context context = new WebService.Context(); - ws.define(context); + WebService.Controller controller = ws.controller("api/computation"); - WebService.Controller controller = context.controller("api/computation"); assertThat(controller).isNotNull(); assertThat(controller.description()).isNotEmpty(); - assertThat(controller.actions()).hasSize(1); + assertThat(controller.actions()).hasSize(3); } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/ws/HistoryActionMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/ws/HistoryActionMediumTest.java new file mode 100644 index 00000000000..21bd5520948 --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/ws/HistoryActionMediumTest.java @@ -0,0 +1,91 @@ +/* + * 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.computation.ws; + +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Rule; +import org.junit.Test; +import org.sonar.core.computation.db.AnalysisReportDto; +import org.sonar.core.permission.GlobalPermissions; +import org.sonar.server.activity.Activity; +import org.sonar.server.activity.ActivityService; +import org.sonar.server.exceptions.ForbiddenException; +import org.sonar.server.tester.ServerTester; +import org.sonar.server.tester.UserSessionRule; +import org.sonar.server.ws.WsTester; + +import java.util.Date; + +/** + * TODO replace this medium test by a small test + */ +public class HistoryActionMediumTest { + + @ClassRule + public static ServerTester tester = new ServerTester(); + @Rule + public UserSessionRule userSessionRule = UserSessionRule.forServerTester(tester); + + HistoryAction sut; + ActivityService activityService; + + @Before + public void setUp() { + tester.clearDbAndIndexes(); + sut = tester.get(HistoryAction.class); + activityService = tester.get(ActivityService.class); + } + + @Test + public void search() throws Exception { + Activity activity1 = new Activity(); + activity1.setType(Activity.Type.ANALYSIS_REPORT); + activity1.setAction("LOG_ANALYSIS_REPORT"); + activity1.setData("projectKey", "P1"); + activity1.setData("projectName", "POne"); + activity1.setData("projectUuid", "U1"); + activity1.setData("status", AnalysisReportDto.Status.SUCCESS); + activity1.setData("submittedAt", new Date()); + activityService.save(activity1); + + Activity activity2 = new Activity(); + activity2.setType(Activity.Type.ANALYSIS_REPORT); + activity2.setAction("LOG_ANALYSIS_REPORT"); + activity2.setData("projectKey", "P2"); + activity2.setData("projectName", "PTwo"); + activity2.setData("projectUuid", "U2"); + activity2.setData("status", AnalysisReportDto.Status.FAILED); + activity2.setData("submittedAt", new Date()); + activityService.save(activity2); + + userSessionRule.setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN); + + WsTester.TestRequest request = tester.wsTester().newGetRequest("api/computation", "history"); + request.execute().assertJson(getClass(), "list_history_reports.json"); + } + + @Test(expected = ForbiddenException.class) + public void requires_admin_right() throws Exception { + WsTester.TestRequest request = tester.wsTester().newGetRequest("api/computation", "history"); + request.execute(); + } +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/ws/HistoryWsActionMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/ws/HistoryWsActionMediumTest.java deleted file mode 100644 index 82da6149876..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/ws/HistoryWsActionMediumTest.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * 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.computation.ws; - -import java.util.Date; -import org.junit.Before; -import org.junit.ClassRule; -import org.junit.Rule; -import org.junit.Test; -import org.sonar.core.computation.db.AnalysisReportDto; -import org.sonar.core.permission.GlobalPermissions; -import org.sonar.server.activity.Activity; -import org.sonar.server.activity.ActivityService; -import org.sonar.server.exceptions.ForbiddenException; -import org.sonar.server.tester.ServerTester; -import org.sonar.server.tester.UserSessionRule; -import org.sonar.server.ws.WsTester; - -/** - * TODO replace this medium test by a small test - */ -public class HistoryWsActionMediumTest { - - @ClassRule - public static ServerTester tester = new ServerTester(); - @Rule - public UserSessionRule userSessionRule = UserSessionRule.forServerTester(tester); - - HistoryWsAction sut; - ActivityService activityService; - - @Before - public void setUp() { - tester.clearDbAndIndexes(); - sut = tester.get(HistoryWsAction.class); - activityService = tester.get(ActivityService.class); - } - - @Test - public void search() throws Exception { - Activity activity1 = new Activity(); - activity1.setType(Activity.Type.ANALYSIS_REPORT); - activity1.setAction("LOG_ANALYSIS_REPORT"); - activity1.setData("projectKey", "P1"); - activity1.setData("projectName", "POne"); - activity1.setData("projectUuid", "U1"); - activity1.setData("status", AnalysisReportDto.Status.SUCCESS); - activity1.setData("submittedAt", new Date()); - activityService.save(activity1); - - Activity activity2 = new Activity(); - activity2.setType(Activity.Type.ANALYSIS_REPORT); - activity2.setAction("LOG_ANALYSIS_REPORT"); - activity2.setData("projectKey", "P2"); - activity2.setData("projectName", "PTwo"); - activity2.setData("projectUuid", "U2"); - activity2.setData("status", AnalysisReportDto.Status.FAILED); - activity2.setData("submittedAt", new Date()); - activityService.save(activity2); - - userSessionRule.setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN); - - WsTester.TestRequest request = tester.wsTester().newGetRequest("api/computation", "history"); - request.execute().assertJson(getClass(), "list_history_reports.json"); - } - - @Test(expected = ForbiddenException.class) - public void requires_admin_right() throws Exception { - WsTester.TestRequest request = tester.wsTester().newGetRequest("api/computation", "history"); - request.execute(); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/ws/IsQueueEmptyWsTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/ws/IsQueueEmptyWsTest.java index 32c9e9432d9..e88401ec61a 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/ws/IsQueueEmptyWsTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/ws/IsQueueEmptyWsTest.java @@ -38,14 +38,14 @@ import static org.mockito.Mockito.when; public class IsQueueEmptyWsTest { - IsQueueEmptyWs.IsQueueEmptyWsAction sut; + IsQueueEmptyWs.IsQueueEmptyAction sut; ReportQueue queue; Response response; @Before public void before() { queue = mock(ReportQueue.class); - sut = new IsQueueEmptyWs.IsQueueEmptyWsAction(queue); + sut = new IsQueueEmptyWs.IsQueueEmptyAction(queue); response = mock(Response.class); when(response.stream()).thenReturn(new FakeStream()); diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/ws/QueueActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/ws/QueueActionTest.java new file mode 100644 index 00000000000..86e27721204 --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/ws/QueueActionTest.java @@ -0,0 +1,70 @@ +/* + * 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.computation.ws; + +import com.google.common.collect.Lists; +import org.junit.Before; +import org.junit.Test; +import org.sonar.api.utils.DateUtils; +import org.sonar.core.computation.db.AnalysisReportDto; +import org.sonar.server.computation.ReportQueue; +import org.sonar.server.ws.WsTester; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.sonar.core.computation.db.AnalysisReportDto.Status.PENDING; + +public class QueueActionTest { + + WsTester tester; + private ReportQueue queue; + + @Before + public void setup() { + queue = mock(ReportQueue.class); + tester = new WsTester(new ComputationWs(new QueueAction(queue))); + } + + @Test + public void list_active_reports() throws Exception { + AnalysisReportDto report = AnalysisReportDto + .newForTests(1L) + .setProjectKey("project-key") + .setStatus(PENDING) + .setUuid("PROJECT_UUID") + .setCreatedAt(DateUtils.parseDateTime("2014-10-13T00:00:00+0200").getTime()) + .setStartedAt(DateUtils.parseDateTime("2014-10-13T00:00:00+0200").getTime()) + .setFinishedAt(DateUtils.parseDateTime("2014-10-13T00:00:00+0200").getTime()); + List reports = Lists.newArrayList(report); + when(queue.all()).thenReturn(reports); + + WsTester.TestRequest request = tester.newGetRequest(ComputationWs.ENDPOINT, "queue"); + request.execute().assertJson(getClass(), "list_queue_reports.json"); + } + + @Test + public void define() { + assertThat(tester.controller(ComputationWs.ENDPOINT).action("queue")).isNotNull(); + } +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/ws/QueueWsActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/ws/QueueWsActionTest.java deleted file mode 100644 index 42f6f11a075..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/ws/QueueWsActionTest.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * 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.computation.ws; - -import com.google.common.collect.Lists; -import org.junit.Before; -import org.junit.Test; -import org.sonar.api.utils.DateUtils; -import org.sonar.core.computation.db.AnalysisReportDto; -import org.sonar.server.computation.ReportQueue; -import org.sonar.server.ws.WsTester; - -import java.util.List; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; -import static org.sonar.core.computation.db.AnalysisReportDto.Status.PENDING; - -public class QueueWsActionTest { - - WsTester tester; - private ReportQueue queue; - - @Before - public void setup() { - queue = mock(ReportQueue.class); - tester = new WsTester(new ComputationWs(new QueueWsAction(queue))); - } - - @Test - public void list_active_reports() throws Exception { - AnalysisReportDto report = AnalysisReportDto - .newForTests(1L) - .setProjectKey("project-key") - .setStatus(PENDING) - .setUuid("PROJECT_UUID") - .setCreatedAt(DateUtils.parseDateTime("2014-10-13T00:00:00+0200").getTime()) - .setStartedAt(DateUtils.parseDateTime("2014-10-13T00:00:00+0200").getTime()) - .setFinishedAt(DateUtils.parseDateTime("2014-10-13T00:00:00+0200").getTime()); - List reports = Lists.newArrayList(report); - when(queue.all()).thenReturn(reports); - - WsTester.TestRequest request = tester.newGetRequest(ComputationWs.ENDPOINT, "queue"); - request.execute().assertJson(getClass(), "list_queue_reports.json"); - } - - @Test - public void define() { - assertThat(tester.controller(ComputationWs.ENDPOINT).action("queue")).isNotNull(); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/ws/SubmitReportActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/ws/SubmitReportActionTest.java new file mode 100644 index 00000000000..4998ab619d7 --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/ws/SubmitReportActionTest.java @@ -0,0 +1,99 @@ +/* + * 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.computation.ws; + +import java.io.InputStream; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.sonar.api.server.ws.WebService; +import org.sonar.core.computation.db.AnalysisReportDto; +import org.sonar.core.permission.GlobalPermissions; +import org.sonar.server.computation.ComputationThreadLauncher; +import org.sonar.server.computation.ReportQueue; +import org.sonar.server.exceptions.ForbiddenException; +import org.sonar.server.tester.UserSessionRule; +import org.sonar.server.ws.WsTester; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +public class SubmitReportActionTest { + @Rule + public UserSessionRule userSessionRule = UserSessionRule.standalone(); + + ComputationThreadLauncher workerLauncher = mock(ComputationThreadLauncher.class); + ReportQueue queue = mock(ReportQueue.class); + WsTester wsTester; + SubmitReportAction sut; + + @Before + public void before() { + sut = new SubmitReportAction(queue, workerLauncher, userSessionRule); + wsTester = new WsTester(new ComputationWs(sut)); + } + + @Test + public void define_metadata() { + WebService.Context context = new WebService.Context(); + WebService.NewController controller = context.createController("api/computation"); + sut.define(controller); + controller.done(); + + WebService.Action action = context.controller("api/computation").action("submit_report"); + assertThat(action).isNotNull(); + assertThat(action.params()).hasSize(2); + } + + @Test + public void add_element_to_queue_and_launch_analysis_task() throws Exception { + userSessionRule.setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION); + AnalysisReportDto dto = mock(AnalysisReportDto.class); + when(dto.getId()).thenReturn(42L); + when(queue.add(any(String.class), any(InputStream.class))).thenReturn(new ReportQueue.Item(dto, null)); + + WsTester.TestRequest request = wsTester + .newGetRequest(ComputationWs.ENDPOINT, "submit_report") + .setParam(SubmitReportAction.PARAM_PROJECT_KEY, "P1") + .setParam(SubmitReportAction.PARAM_REPORT_DATA, null); + WsTester.Result response = request.execute(); + + verify(queue).add(eq("P1"), any(InputStream.class)); + verify(workerLauncher).startAnalysisTaskNow(); + assertThat(response.outputAsString()).isEqualTo("{\"key\":\"42\"}"); + } + + @Test(expected = ForbiddenException.class) + public void requires_scan_permission() throws Exception { + userSessionRule.setGlobalPermissions(GlobalPermissions.DASHBOARD_SHARING); + + WsTester.TestRequest request = wsTester + .newGetRequest(ComputationWs.ENDPOINT, "submit_report") + .setParam(SubmitReportAction.PARAM_PROJECT_KEY, "P1") + .setParam(SubmitReportAction.PARAM_REPORT_DATA, null); + request.execute(); + + } +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/ws/SubmitReportWsActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/ws/SubmitReportWsActionTest.java deleted file mode 100644 index 95910bcfdc0..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/ws/SubmitReportWsActionTest.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * 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.computation.ws; - -import java.io.InputStream; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.sonar.api.server.ws.WebService; -import org.sonar.core.computation.db.AnalysisReportDto; -import org.sonar.core.permission.GlobalPermissions; -import org.sonar.server.computation.ComputationThreadLauncher; -import org.sonar.server.computation.ReportQueue; -import org.sonar.server.exceptions.ForbiddenException; -import org.sonar.server.tester.UserSessionRule; -import org.sonar.server.ws.WsTester; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.any; -import static org.mockito.Mockito.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class SubmitReportWsActionTest { - @Rule - public UserSessionRule userSessionRule = UserSessionRule.standalone(); - - ComputationThreadLauncher workerLauncher = mock(ComputationThreadLauncher.class); - ReportQueue queue = mock(ReportQueue.class); - WsTester wsTester; - SubmitReportWsAction sut; - - @Before - public void before() { - sut = new SubmitReportWsAction(queue, workerLauncher, userSessionRule); - wsTester = new WsTester(new ComputationWs(sut)); - } - - @Test - public void define_metadata() { - WebService.Context context = new WebService.Context(); - WebService.NewController controller = context.createController("api/computation"); - sut.define(controller); - controller.done(); - - WebService.Action action = context.controller("api/computation").action("submit_report"); - assertThat(action).isNotNull(); - assertThat(action.params()).hasSize(2); - } - - @Test - public void add_element_to_queue_and_launch_analysis_task() throws Exception { - userSessionRule.setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION); - AnalysisReportDto dto = mock(AnalysisReportDto.class); - when(dto.getId()).thenReturn(42L); - when(queue.add(any(String.class), any(InputStream.class))).thenReturn(new ReportQueue.Item(dto, null)); - - WsTester.TestRequest request = wsTester - .newGetRequest(ComputationWs.ENDPOINT, "submit_report") - .setParam(SubmitReportWsAction.PARAM_PROJECT_KEY, "P1") - .setParam(SubmitReportWsAction.PARAM_REPORT_DATA, null); - WsTester.Result response = request.execute(); - - verify(queue).add(eq("P1"), any(InputStream.class)); - verify(workerLauncher).startAnalysisTaskNow(); - assertThat(response.outputAsString()).isEqualTo("{\"key\":\"42\"}"); - } - - @Test(expected = ForbiddenException.class) - public void requires_scan_permission() throws Exception { - userSessionRule.setGlobalPermissions(GlobalPermissions.DASHBOARD_SHARING); - - WsTester.TestRequest request = wsTester - .newGetRequest(ComputationWs.ENDPOINT, "submit_report") - .setParam(SubmitReportWsAction.PARAM_PROJECT_KEY, "P1") - .setParam(SubmitReportWsAction.PARAM_REPORT_DATA, null); - request.execute(); - - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/ws/IssueShowActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/ws/IssueShowActionTest.java deleted file mode 100644 index ab039a878d2..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/issue/ws/IssueShowActionTest.java +++ /dev/null @@ -1,528 +0,0 @@ -/* - * 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.issue.ws; - -import com.google.common.collect.Lists; -import java.util.Date; -import java.util.List; -import java.util.Locale; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; -import org.sonar.api.i18n.I18n; -import org.sonar.api.issue.Issue; -import org.sonar.api.issue.internal.DefaultIssue; -import org.sonar.api.issue.internal.DefaultIssueComment; -import org.sonar.api.issue.internal.FieldDiffs; -import org.sonar.api.rule.RuleKey; -import org.sonar.api.server.debt.internal.DefaultDebtCharacteristic; -import org.sonar.api.user.User; -import org.sonar.api.user.UserFinder; -import org.sonar.api.utils.DateUtils; -import org.sonar.api.utils.Duration; -import org.sonar.api.utils.Durations; -import org.sonar.core.component.ComponentDto; -import org.sonar.core.issue.DefaultActionPlan; -import org.sonar.core.issue.workflow.Transition; -import org.sonar.core.persistence.DbSession; -import org.sonar.core.user.DefaultUser; -import org.sonar.server.component.ComponentTesting; -import org.sonar.server.component.db.ComponentDao; -import org.sonar.server.db.DbClient; -import org.sonar.server.debt.DebtModelService; -import org.sonar.server.issue.ActionService; -import org.sonar.server.issue.IssueChangelog; -import org.sonar.server.issue.IssueChangelogService; -import org.sonar.server.issue.IssueCommentService; -import org.sonar.server.issue.IssueService; -import org.sonar.server.issue.actionplan.ActionPlanService; -import org.sonar.server.rule.Rule; -import org.sonar.server.rule.RuleService; -import org.sonar.server.source.SourceService; -import org.sonar.server.tester.UserSessionRule; -import org.sonar.server.user.ThreadLocalUserSession; -import org.sonar.server.ws.WsTester; - -import static com.google.common.collect.Lists.newArrayList; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -/** - * TODO Should be replaced by medium tests, as there are too many dependencies - */ -@RunWith(MockitoJUnitRunner.class) -public class IssueShowActionTest { - - @org.junit.Rule - public UserSessionRule userSessionRule = UserSessionRule.standalone(); - - @Mock - DbClient dbClient; - - @Mock - DbSession session; - - @Mock - ComponentDao componentDao; - - @Mock - IssueService issueService; - - @Mock - IssueChangelogService issueChangelogService; - - @Mock - IssueCommentService commentService; - - @Mock - ActionPlanService actionPlanService; - - @Mock - ActionService actionService; - - @Mock - UserFinder userFinder; - - @Mock - DebtModelService debtModel; - - @Mock - RuleService ruleService; - - @Mock - I18n i18n; - - @Mock - Durations durations; - - @Mock - SourceService sourceService; - - Date issueCreationDate; - - Rule rule; - - WsTester tester; - - @Before - public void setUp() { - when(dbClient.openSession(false)).thenReturn(session); - when(dbClient.componentDao()).thenReturn(componentDao); - - rule = mock(Rule.class); - when(rule.key()).thenReturn(RuleKey.of("squid", "AvoidCycle")); - when(rule.name()).thenReturn("Avoid cycle"); - when(ruleService.getNonNullByKey(rule.key())).thenReturn(rule); - - when(issueChangelogService.changelog(any(Issue.class))).thenReturn(mock(IssueChangelog.class)); - - issueCreationDate = DateUtils.parseDateTime("2014-01-22T19:10:03+0100"); - when(i18n.formatDateTime(any(Locale.class), eq(issueCreationDate))).thenReturn("Jan 22, 2014 10:03 AM"); - - when(i18n.message(any(Locale.class), eq("created"), eq((String) null))).thenReturn("Created"); - - tester = new WsTester(new IssuesWs( - new IssueShowAction( - dbClient, issueService, issueChangelogService, commentService, - new IssueActionsWriter(issueService, actionService, userSessionRule), - actionPlanService, userFinder, debtModel, ruleService, i18n, durations, userSessionRule) - )); - } - - @Test - public void show_issue() throws Exception { - String issueKey = "ABCD"; - - ComponentDto project = ComponentTesting.newProjectDto() - .setId(1L) - .setKey("org.sonar.Sonar") - .setLongName("SonarQube") - .setName("SonarQube"); - when(componentDao.selectByUuid(session, project.uuid())).thenReturn(project); - - ComponentDto file = ComponentTesting.newFileDto(project) - .setId(10L) - .setKey("org.sonar.server.issue.IssueClient") - .setLongName("SonarQube :: Issue Client") - .setName("SonarQube :: Issue Client") - .setQualifier("FIL") - .setParentProjectId(1L); - when(componentDao.selectByUuid(session, file.uuid())).thenReturn(file); - - DefaultIssue issue = new DefaultIssue() - .setKey(issueKey) - .setComponentKey("org.sonar.server.issue.IssueClient") - .setComponentUuid(file.uuid()) - .setProjectKey("org.sonar.Sonar") - .setProjectUuid(project.uuid()) - .setRuleKey(RuleKey.of("squid", "AvoidCycle")) - .setLine(12) - .setMessage("Fix it") - .setResolution("FIXED") - .setStatus("CLOSED") - .setSeverity("MAJOR") - .setCreationDate(issueCreationDate); - when(issueService.getByKey(issueKey)).thenReturn(issue); - - WsTester.TestRequest request = tester.newGetRequest("api/issues", "show").setParam("key", issueKey); - request.execute().assertJson(getClass(), "show_issue.json"); - } - - @Test - public void show_issue_with_sub_project() throws Exception { - String issueKey = "ABCD"; - - // Project - ComponentDto project = ComponentTesting.newProjectDto() - .setId(1L) - .setKey("org.sonar.Sonar") - .setLongName("SonarQube"); - when(componentDao.selectByUuid(session, project.uuid())).thenReturn(project); - - // Module - ComponentDto module = ComponentTesting.newModuleDto(project) - .setId(2L) - .setKey("org.sonar.server.Server") - .setLongName("SonarQube :: Server") - .setQualifier("BRC") - .setParentProjectId(1L); - when(componentDao.selectNullableById(module.getId(), session)).thenReturn(module); - - // File - ComponentDto file = ComponentTesting.newFileDto(module) - .setId(10L) - .setKey("org.sonar.server.issue.IssueClient") - .setLongName("SonarQube :: Issue Client") - .setQualifier("FIL") - .setParentProjectId(2L); - when(componentDao.selectByUuid(session, file.uuid())).thenReturn(file); - - DefaultIssue issue = new DefaultIssue() - .setKey(issueKey) - .setComponentKey("org.sonar.server.issue.IssueClient") - .setComponentUuid(file.uuid()) - .setProjectKey("org.sonar.Sonar") - .setProjectUuid(project.uuid()) - .setModuleUuid(module.uuid()) - .setRuleKey(RuleKey.of("squid", "AvoidCycle")) - .setLine(12) - .setMessage("Fix it") - .setResolution("FIXED") - .setStatus("CLOSED") - .setSeverity("MAJOR") - .setCreationDate(issueCreationDate); - when(issueService.getByKey(issueKey)).thenReturn(issue); - - WsTester.TestRequest request = tester.newGetRequest("api/issues", "show").setParam("key", issueKey); - request.execute().assertJson(getClass(), "show_issue_with_sub_project.json"); - } - - @Test - public void use_project_and_sub_project_names_if_no_long_name() throws Exception { - String issueKey = "ABCD"; - - // Project - ComponentDto project = ComponentTesting.newProjectDto() - .setId(1L) - .setKey("org.sonar.Sonar") - .setName("SonarQube") - .setLongName(null); - when(componentDao.selectByUuid(session, project.uuid())).thenReturn(project); - - // Module - ComponentDto module = ComponentTesting.newModuleDto(project) - .setId(2L) - .setKey("org.sonar.server.Server") - .setName("SonarQube :: Server") - .setLongName(null) - .setQualifier("BRC") - .setParentProjectId(1L); - when(componentDao.selectNullableById(module.getId(), session)).thenReturn(module); - - // File - ComponentDto file = ComponentTesting.newFileDto(module) - .setId(10L) - .setKey("org.sonar.server.issue.IssueClient") - .setLongName("SonarQube :: Issue Client") - .setQualifier("FIL") - .setParentProjectId(2L); - when(componentDao.selectByUuid(session, file.uuid())).thenReturn(file); - - DefaultIssue issue = new DefaultIssue() - .setKey(issueKey) - .setComponentKey("org.sonar.server.issue.IssueClient") - .setComponentUuid(file.uuid()) - .setProjectKey("org.sonar.Sonar") - .setProjectUuid(project.uuid()) - .setModuleUuid(module.uuid()) - .setRuleKey(RuleKey.of("squid", "AvoidCycle")) - .setLine(12) - .setEffortToFix(2.0) - .setMessage("Fix it") - .setResolution("FIXED") - .setStatus("CLOSED") - .setSeverity("MAJOR") - .setCreationDate(issueCreationDate); - when(issueService.getByKey(issueKey)).thenReturn(issue); - - WsTester.TestRequest request = tester.newGetRequest("api/issues", "show").setParam("key", issueKey); - request.execute().assertJson(getClass(), "show_issue_with_sub_project.json"); - } - - @Test - public void show_issue_on_removed_component() throws Exception { - String issueKey = "ABCD"; - - ComponentDto project = ComponentTesting.newProjectDto() - .setId(1L) - .setKey("org.sonar.Sonar") - .setLongName("SonarQube") - .setName("SonarQube"); - when(componentDao.selectByUuid(session, project.uuid())).thenReturn(project); - - ComponentDto file = ComponentTesting.newFileDto(project) - .setId(10L) - .setEnabled(false) - .setKey("org.sonar.server.issue.IssueClient") - .setLongName("SonarQube :: Issue Client") - .setName("SonarQube :: Issue Client") - .setQualifier("FIL") - .setParentProjectId(1L); - when(componentDao.selectByUuid(session, file.uuid())).thenReturn(file); - - DefaultIssue issue = createIssue() - .setComponentUuid(file.uuid()) - .setProjectUuid(project.uuid()); - when(issueService.getByKey(issueKey)).thenReturn(issue); - - WsTester.TestRequest request = tester.newGetRequest("api/issues", "show").setParam("key", issueKey); - request.execute().assertJson(getClass(), "show_issue_on_removed_component.json"); - } - - @Test - public void show_issue_with_action_plan() throws Exception { - DefaultIssue issue = createStandardIssue() - .setActionPlanKey("AP-ABCD"); - when(issueService.getByKey(issue.key())).thenReturn(issue); - - when(actionPlanService.findByKey(eq(issue.actionPlanKey()), any(ThreadLocalUserSession.class))).thenReturn(new DefaultActionPlan().setKey("AP-ABCD").setName("Version 4.2")); - - WsTester.TestRequest request = tester.newGetRequest("api/issues", "show").setParam("key", issue.key()); - request.execute().assertJson(getClass(), "show_issue_with_action_plan.json"); - } - - @Test - public void show_issue_with_users() throws Exception { - DefaultIssue issue = createStandardIssue() - .setAssignee("john") - .setReporter("steven") - .setAuthorLogin("Henry"); - when(issueService.getByKey(issue.key())).thenReturn(issue); - - when(userFinder.findByLogin("john")).thenReturn(new DefaultUser().setLogin("john").setName("John")); - when(userFinder.findByLogin("steven")).thenReturn(new DefaultUser().setLogin("steven").setName("Steven")); - - WsTester.TestRequest request = tester.newGetRequest("api/issues", "show").setParam("key", issue.key()); - request.execute().assertJson(getClass(), "show_issue_with_users.json"); - } - - @Test - public void show_issue_with_technical_debt() throws Exception { - Duration debt = (Duration.create(7260L)); - DefaultIssue issue = createStandardIssue().setDebt(debt); - when(issueService.getByKey(issue.key())).thenReturn(issue); - - when(durations.encode(debt)).thenReturn("2h1min"); - - WsTester.TestRequest request = tester.newGetRequest("api/issues", "show").setParam("key", issue.key()); - request.execute().assertJson(getClass(), "show_issue_with_technical_debt.json"); - } - - @Test - public void show_issue_with_user_characteristics() throws Exception { - DefaultIssue issue = createStandardIssue().setDebt(Duration.create(7260L)); - when(issueService.getByKey(issue.key())).thenReturn(issue); - - when(rule.debtCharacteristicKey()).thenReturn("K2"); - when(debtModel.characteristicById(1)).thenReturn(new DefaultDebtCharacteristic().setKey("K1").setId(1).setName("Maintainability")); - when(debtModel.characteristicById(2)).thenReturn(new DefaultDebtCharacteristic().setKey("K2").setId(2).setName("Readability").setParentId(1)); - when(debtModel.characteristicByKey("K2")).thenReturn(new DefaultDebtCharacteristic().setKey("K2").setId(2).setName("Readability").setParentId(1)); - - WsTester.TestRequest request = tester.newGetRequest("api/issues", "show").setParam("key", issue.key()); - request.execute().assertJson(getClass(), "show_issue_with_characteristics.json"); - } - - @Test - public void show_issue_with_default_characteristics() throws Exception { - DefaultIssue issue = createStandardIssue().setDebt(Duration.create(7260L)); - when(issueService.getByKey(issue.key())).thenReturn(issue); - - when(rule.debtCharacteristicKey()).thenReturn("K2"); - when(debtModel.characteristicById(1)).thenReturn(new DefaultDebtCharacteristic().setKey("K1").setId(1).setName("Maintainability")); - when(debtModel.characteristicById(2)).thenReturn(new DefaultDebtCharacteristic().setKey("K2").setId(2).setName("Readability").setParentId(1)); - when(debtModel.characteristicByKey("K2")).thenReturn(new DefaultDebtCharacteristic().setKey("K2").setId(2).setName("Readability").setParentId(1)); - - WsTester.TestRequest request = tester.newGetRequest("api/issues", "show").setParam("key", issue.key()); - request.execute().assertJson(getClass(), "show_issue_with_characteristics.json"); - } - - @Test - public void show_issue_with_dates() throws Exception { - Date creationDate = DateUtils.parseDateTime("2014-01-22T19:10:03+0100"); - Date updateDate = DateUtils.parseDateTime("2014-01-23T19:10:03+0100"); - Date closedDate = DateUtils.parseDateTime("2014-01-24T19:10:03+0100"); - - DefaultIssue issue = createStandardIssue() - .setCreationDate(creationDate) - .setUpdateDate(updateDate) - .setCloseDate(closedDate); - when(issueService.getByKey(issue.key())).thenReturn(issue); - - when(i18n.formatDateTime(any(Locale.class), eq(creationDate))).thenReturn("Jan 22, 2014 10:03 AM"); - when(i18n.formatDateTime(any(Locale.class), eq(updateDate))).thenReturn("Jan 23, 2014 10:03 AM"); - when(i18n.ageFromNow(any(Locale.class), eq(updateDate))).thenReturn("9 days"); - when(i18n.formatDateTime(any(Locale.class), eq(closedDate))).thenReturn("Jan 24, 2014 10:03 AM"); - - WsTester.TestRequest request = tester.newGetRequest("api/issues", "show").setParam("key", issue.key()); - request.execute().assertJson(getClass(), "show_issue_with_dates.json"); - } - - @Test - public void show_issue_with_comments() throws Exception { - Date date1 = DateUtils.parseDateTime("2014-02-22T19:10:03+0100"); - Date date2 = DateUtils.parseDateTime("2014-02-23T19:10:03+0100"); - - DefaultIssue issue = createStandardIssue(); - when(issueService.getByKey(issue.key())).thenReturn(issue); - - when(commentService.findComments(issue.key())).thenReturn(newArrayList( - new DefaultIssueComment() - .setKey("COMMENT-ABCD") - .setMarkdownText("*My comment*") - .setUserLogin("john") - .setCreatedAt(date1), - new DefaultIssueComment() - .setKey("COMMENT-ABCE") - .setMarkdownText("Another comment") - .setUserLogin("arthur") - .setCreatedAt(date2) - )); - - when(userFinder.findByLogin("john")).thenReturn(new DefaultUser().setLogin("john").setName("John")); - when(userFinder.findByLogin("arthur")).thenReturn(new DefaultUser().setLogin("arthur").setName("Arthur")); - - when(i18n.ageFromNow(any(Locale.class), eq(date1))).thenReturn("9 days"); - when(i18n.ageFromNow(any(Locale.class), eq(date2))).thenReturn("10 days"); - - userSessionRule.login("arthur"); - WsTester.TestRequest request = tester.newGetRequest("api/issues", "show").setParam("key", issue.key()); - request.execute().assertJson(getClass(), "show_issue_with_comments.json"); - } - - @Test - public void show_issue_with_transitions() throws Exception { - DefaultIssue issue = createStandardIssue() - .setStatus("RESOLVED") - .setResolution("FIXED"); - when(issueService.getByKey(issue.key())).thenReturn(issue); - - when(issueService.listTransitions(eq(issue))).thenReturn(newArrayList(Transition.create("reopen", "RESOLVED", "REOPEN"))); - - userSessionRule.login("john"); - WsTester.TestRequest request = tester.newGetRequest("api/issues", "show").setParam("key", issue.key()); - request.execute().assertJson(getClass(), "show_issue_with_transitions.json"); - } - - @Test - public void show_issue_with_actions() throws Exception { - DefaultIssue issue = createStandardIssue() - .setStatus("OPEN"); - when(issueService.getByKey(issue.key())).thenReturn(issue); - - userSessionRule.login("john"); - WsTester.TestRequest request = tester.newGetRequest("api/issues", "show").setParam("key", issue.key()); - request.execute().assertJson(getClass(), "show_issue_with_actions.json"); - } - - @Test - public void show_issue_with_changelog() throws Exception { - DefaultIssue issue = createStandardIssue(); - when(issueService.getByKey(issue.key())).thenReturn(issue); - - Date date1 = DateUtils.parseDateTime("2014-02-22T19:10:03+0100"); - Date date2 = DateUtils.parseDateTime("2014-02-23T19:10:03+0100"); - - List users = Lists.newArrayList(new DefaultUser().setLogin("john").setName("John")); - FieldDiffs userChange = new FieldDiffs() - .setUserLogin("john") - .setDiff("actionPlan", null, "1.0") - .setCreationDate(date1); - FieldDiffs scanChange = new FieldDiffs() - .setDiff("severity", "INFO", "BLOCKER") - .setDiff("status", "REOPEN", "RESOLVED") - .setCreationDate(date2); - when(issueChangelogService.changelog(issue)).thenReturn(new IssueChangelog(newArrayList(userChange, scanChange), users)); - when(issueChangelogService.formatDiffs(userChange)).thenReturn(newArrayList("Action plan updated to 1.0")); - when(issueChangelogService.formatDiffs(scanChange)).thenReturn(newArrayList("Severity updated from Info to Blocker", "Status updated from Reopen to Resolved")); - - when(i18n.formatDateTime(any(Locale.class), eq(date1))).thenReturn("Fev 22, 2014 10:03 AM"); - when(i18n.formatDateTime(any(Locale.class), eq(date2))).thenReturn("Fev 23, 2014 10:03 AM"); - - WsTester.TestRequest request = tester.newGetRequest("api/issues", "show").setParam("key", issue.key()); - request.execute().assertJson(getClass(), "show_issue_with_changelog.json"); - } - - private DefaultIssue createStandardIssue() { - ComponentDto project = ComponentTesting.newProjectDto() - .setId(1L) - .setKey("org.sonar.Sonar") - .setLongName("SonarQube") - .setName("SonarQube"); - when(componentDao.selectByUuid(session, project.uuid())).thenReturn(project); - - ComponentDto file = ComponentTesting.newFileDto(project) - .setId(10L) - .setKey("org.sonar.server.issue.IssueClient") - .setLongName("SonarQube :: Issue Client") - .setName("SonarQube :: Issue Client") - .setQualifier("FIL") - .setParentProjectId(1L); - when(componentDao.selectByUuid(session, file.uuid())).thenReturn(file); - - return createIssue() - .setComponentUuid(file.uuid()) - .setProjectUuid(project.uuid()); - } - - private DefaultIssue createIssue() { - return new DefaultIssue() - .setKey("ABCD") - .setComponentKey("org.sonar.server.issue.IssueClient") - .setProjectKey("org.sonar.Sonar") - .setRuleKey(RuleKey.of("squid", "AvoidCycle")) - .setCreationDate(issueCreationDate); - } - -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/ws/ShowActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/ws/ShowActionTest.java new file mode 100644 index 00000000000..61e7a768110 --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/issue/ws/ShowActionTest.java @@ -0,0 +1,528 @@ +/* + * 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.issue.ws; + +import com.google.common.collect.Lists; +import java.util.Date; +import java.util.List; +import java.util.Locale; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; +import org.sonar.api.i18n.I18n; +import org.sonar.api.issue.Issue; +import org.sonar.api.issue.internal.DefaultIssue; +import org.sonar.api.issue.internal.DefaultIssueComment; +import org.sonar.api.issue.internal.FieldDiffs; +import org.sonar.api.rule.RuleKey; +import org.sonar.api.server.debt.internal.DefaultDebtCharacteristic; +import org.sonar.api.user.User; +import org.sonar.api.user.UserFinder; +import org.sonar.api.utils.DateUtils; +import org.sonar.api.utils.Duration; +import org.sonar.api.utils.Durations; +import org.sonar.core.component.ComponentDto; +import org.sonar.core.issue.DefaultActionPlan; +import org.sonar.core.issue.workflow.Transition; +import org.sonar.core.persistence.DbSession; +import org.sonar.core.user.DefaultUser; +import org.sonar.server.component.ComponentTesting; +import org.sonar.server.component.db.ComponentDao; +import org.sonar.server.db.DbClient; +import org.sonar.server.debt.DebtModelService; +import org.sonar.server.issue.ActionService; +import org.sonar.server.issue.IssueChangelog; +import org.sonar.server.issue.IssueChangelogService; +import org.sonar.server.issue.IssueCommentService; +import org.sonar.server.issue.IssueService; +import org.sonar.server.issue.actionplan.ActionPlanService; +import org.sonar.server.rule.Rule; +import org.sonar.server.rule.RuleService; +import org.sonar.server.source.SourceService; +import org.sonar.server.tester.UserSessionRule; +import org.sonar.server.user.ThreadLocalUserSession; +import org.sonar.server.ws.WsTester; + +import static com.google.common.collect.Lists.newArrayList; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +/** + * TODO Should be replaced by medium tests, as there are too many dependencies + */ +@RunWith(MockitoJUnitRunner.class) +public class ShowActionTest { + + @org.junit.Rule + public UserSessionRule userSessionRule = UserSessionRule.standalone(); + + @Mock + DbClient dbClient; + + @Mock + DbSession session; + + @Mock + ComponentDao componentDao; + + @Mock + IssueService issueService; + + @Mock + IssueChangelogService issueChangelogService; + + @Mock + IssueCommentService commentService; + + @Mock + ActionPlanService actionPlanService; + + @Mock + ActionService actionService; + + @Mock + UserFinder userFinder; + + @Mock + DebtModelService debtModel; + + @Mock + RuleService ruleService; + + @Mock + I18n i18n; + + @Mock + Durations durations; + + @Mock + SourceService sourceService; + + Date issueCreationDate; + + Rule rule; + + WsTester tester; + + @Before + public void setUp() { + when(dbClient.openSession(false)).thenReturn(session); + when(dbClient.componentDao()).thenReturn(componentDao); + + rule = mock(Rule.class); + when(rule.key()).thenReturn(RuleKey.of("squid", "AvoidCycle")); + when(rule.name()).thenReturn("Avoid cycle"); + when(ruleService.getNonNullByKey(rule.key())).thenReturn(rule); + + when(issueChangelogService.changelog(any(Issue.class))).thenReturn(mock(IssueChangelog.class)); + + issueCreationDate = DateUtils.parseDateTime("2014-01-22T19:10:03+0100"); + when(i18n.formatDateTime(any(Locale.class), eq(issueCreationDate))).thenReturn("Jan 22, 2014 10:03 AM"); + + when(i18n.message(any(Locale.class), eq("created"), eq((String) null))).thenReturn("Created"); + + tester = new WsTester(new IssuesWs( + new ShowAction( + dbClient, issueService, issueChangelogService, commentService, + new IssueActionsWriter(issueService, actionService, userSessionRule), + actionPlanService, userFinder, debtModel, ruleService, i18n, durations, userSessionRule) + )); + } + + @Test + public void show_issue() throws Exception { + String issueKey = "ABCD"; + + ComponentDto project = ComponentTesting.newProjectDto() + .setId(1L) + .setKey("org.sonar.Sonar") + .setLongName("SonarQube") + .setName("SonarQube"); + when(componentDao.selectByUuid(session, project.uuid())).thenReturn(project); + + ComponentDto file = ComponentTesting.newFileDto(project) + .setId(10L) + .setKey("org.sonar.server.issue.IssueClient") + .setLongName("SonarQube :: Issue Client") + .setName("SonarQube :: Issue Client") + .setQualifier("FIL") + .setParentProjectId(1L); + when(componentDao.selectByUuid(session, file.uuid())).thenReturn(file); + + DefaultIssue issue = new DefaultIssue() + .setKey(issueKey) + .setComponentKey("org.sonar.server.issue.IssueClient") + .setComponentUuid(file.uuid()) + .setProjectKey("org.sonar.Sonar") + .setProjectUuid(project.uuid()) + .setRuleKey(RuleKey.of("squid", "AvoidCycle")) + .setLine(12) + .setMessage("Fix it") + .setResolution("FIXED") + .setStatus("CLOSED") + .setSeverity("MAJOR") + .setCreationDate(issueCreationDate); + when(issueService.getByKey(issueKey)).thenReturn(issue); + + WsTester.TestRequest request = tester.newGetRequest("api/issues", "show").setParam("key", issueKey); + request.execute().assertJson(getClass(), "show_issue.json"); + } + + @Test + public void show_issue_with_sub_project() throws Exception { + String issueKey = "ABCD"; + + // Project + ComponentDto project = ComponentTesting.newProjectDto() + .setId(1L) + .setKey("org.sonar.Sonar") + .setLongName("SonarQube"); + when(componentDao.selectByUuid(session, project.uuid())).thenReturn(project); + + // Module + ComponentDto module = ComponentTesting.newModuleDto(project) + .setId(2L) + .setKey("org.sonar.server.Server") + .setLongName("SonarQube :: Server") + .setQualifier("BRC") + .setParentProjectId(1L); + when(componentDao.selectNullableById(module.getId(), session)).thenReturn(module); + + // File + ComponentDto file = ComponentTesting.newFileDto(module) + .setId(10L) + .setKey("org.sonar.server.issue.IssueClient") + .setLongName("SonarQube :: Issue Client") + .setQualifier("FIL") + .setParentProjectId(2L); + when(componentDao.selectByUuid(session, file.uuid())).thenReturn(file); + + DefaultIssue issue = new DefaultIssue() + .setKey(issueKey) + .setComponentKey("org.sonar.server.issue.IssueClient") + .setComponentUuid(file.uuid()) + .setProjectKey("org.sonar.Sonar") + .setProjectUuid(project.uuid()) + .setModuleUuid(module.uuid()) + .setRuleKey(RuleKey.of("squid", "AvoidCycle")) + .setLine(12) + .setMessage("Fix it") + .setResolution("FIXED") + .setStatus("CLOSED") + .setSeverity("MAJOR") + .setCreationDate(issueCreationDate); + when(issueService.getByKey(issueKey)).thenReturn(issue); + + WsTester.TestRequest request = tester.newGetRequest("api/issues", "show").setParam("key", issueKey); + request.execute().assertJson(getClass(), "show_issue_with_sub_project.json"); + } + + @Test + public void use_project_and_sub_project_names_if_no_long_name() throws Exception { + String issueKey = "ABCD"; + + // Project + ComponentDto project = ComponentTesting.newProjectDto() + .setId(1L) + .setKey("org.sonar.Sonar") + .setName("SonarQube") + .setLongName(null); + when(componentDao.selectByUuid(session, project.uuid())).thenReturn(project); + + // Module + ComponentDto module = ComponentTesting.newModuleDto(project) + .setId(2L) + .setKey("org.sonar.server.Server") + .setName("SonarQube :: Server") + .setLongName(null) + .setQualifier("BRC") + .setParentProjectId(1L); + when(componentDao.selectNullableById(module.getId(), session)).thenReturn(module); + + // File + ComponentDto file = ComponentTesting.newFileDto(module) + .setId(10L) + .setKey("org.sonar.server.issue.IssueClient") + .setLongName("SonarQube :: Issue Client") + .setQualifier("FIL") + .setParentProjectId(2L); + when(componentDao.selectByUuid(session, file.uuid())).thenReturn(file); + + DefaultIssue issue = new DefaultIssue() + .setKey(issueKey) + .setComponentKey("org.sonar.server.issue.IssueClient") + .setComponentUuid(file.uuid()) + .setProjectKey("org.sonar.Sonar") + .setProjectUuid(project.uuid()) + .setModuleUuid(module.uuid()) + .setRuleKey(RuleKey.of("squid", "AvoidCycle")) + .setLine(12) + .setEffortToFix(2.0) + .setMessage("Fix it") + .setResolution("FIXED") + .setStatus("CLOSED") + .setSeverity("MAJOR") + .setCreationDate(issueCreationDate); + when(issueService.getByKey(issueKey)).thenReturn(issue); + + WsTester.TestRequest request = tester.newGetRequest("api/issues", "show").setParam("key", issueKey); + request.execute().assertJson(getClass(), "show_issue_with_sub_project.json"); + } + + @Test + public void show_issue_on_removed_component() throws Exception { + String issueKey = "ABCD"; + + ComponentDto project = ComponentTesting.newProjectDto() + .setId(1L) + .setKey("org.sonar.Sonar") + .setLongName("SonarQube") + .setName("SonarQube"); + when(componentDao.selectByUuid(session, project.uuid())).thenReturn(project); + + ComponentDto file = ComponentTesting.newFileDto(project) + .setId(10L) + .setEnabled(false) + .setKey("org.sonar.server.issue.IssueClient") + .setLongName("SonarQube :: Issue Client") + .setName("SonarQube :: Issue Client") + .setQualifier("FIL") + .setParentProjectId(1L); + when(componentDao.selectByUuid(session, file.uuid())).thenReturn(file); + + DefaultIssue issue = createIssue() + .setComponentUuid(file.uuid()) + .setProjectUuid(project.uuid()); + when(issueService.getByKey(issueKey)).thenReturn(issue); + + WsTester.TestRequest request = tester.newGetRequest("api/issues", "show").setParam("key", issueKey); + request.execute().assertJson(getClass(), "show_issue_on_removed_component.json"); + } + + @Test + public void show_issue_with_action_plan() throws Exception { + DefaultIssue issue = createStandardIssue() + .setActionPlanKey("AP-ABCD"); + when(issueService.getByKey(issue.key())).thenReturn(issue); + + when(actionPlanService.findByKey(eq(issue.actionPlanKey()), any(ThreadLocalUserSession.class))).thenReturn(new DefaultActionPlan().setKey("AP-ABCD").setName("Version 4.2")); + + WsTester.TestRequest request = tester.newGetRequest("api/issues", "show").setParam("key", issue.key()); + request.execute().assertJson(getClass(), "show_issue_with_action_plan.json"); + } + + @Test + public void show_issue_with_users() throws Exception { + DefaultIssue issue = createStandardIssue() + .setAssignee("john") + .setReporter("steven") + .setAuthorLogin("Henry"); + when(issueService.getByKey(issue.key())).thenReturn(issue); + + when(userFinder.findByLogin("john")).thenReturn(new DefaultUser().setLogin("john").setName("John")); + when(userFinder.findByLogin("steven")).thenReturn(new DefaultUser().setLogin("steven").setName("Steven")); + + WsTester.TestRequest request = tester.newGetRequest("api/issues", "show").setParam("key", issue.key()); + request.execute().assertJson(getClass(), "show_issue_with_users.json"); + } + + @Test + public void show_issue_with_technical_debt() throws Exception { + Duration debt = (Duration.create(7260L)); + DefaultIssue issue = createStandardIssue().setDebt(debt); + when(issueService.getByKey(issue.key())).thenReturn(issue); + + when(durations.encode(debt)).thenReturn("2h1min"); + + WsTester.TestRequest request = tester.newGetRequest("api/issues", "show").setParam("key", issue.key()); + request.execute().assertJson(getClass(), "show_issue_with_technical_debt.json"); + } + + @Test + public void show_issue_with_user_characteristics() throws Exception { + DefaultIssue issue = createStandardIssue().setDebt(Duration.create(7260L)); + when(issueService.getByKey(issue.key())).thenReturn(issue); + + when(rule.debtCharacteristicKey()).thenReturn("K2"); + when(debtModel.characteristicById(1)).thenReturn(new DefaultDebtCharacteristic().setKey("K1").setId(1).setName("Maintainability")); + when(debtModel.characteristicById(2)).thenReturn(new DefaultDebtCharacteristic().setKey("K2").setId(2).setName("Readability").setParentId(1)); + when(debtModel.characteristicByKey("K2")).thenReturn(new DefaultDebtCharacteristic().setKey("K2").setId(2).setName("Readability").setParentId(1)); + + WsTester.TestRequest request = tester.newGetRequest("api/issues", "show").setParam("key", issue.key()); + request.execute().assertJson(getClass(), "show_issue_with_characteristics.json"); + } + + @Test + public void show_issue_with_default_characteristics() throws Exception { + DefaultIssue issue = createStandardIssue().setDebt(Duration.create(7260L)); + when(issueService.getByKey(issue.key())).thenReturn(issue); + + when(rule.debtCharacteristicKey()).thenReturn("K2"); + when(debtModel.characteristicById(1)).thenReturn(new DefaultDebtCharacteristic().setKey("K1").setId(1).setName("Maintainability")); + when(debtModel.characteristicById(2)).thenReturn(new DefaultDebtCharacteristic().setKey("K2").setId(2).setName("Readability").setParentId(1)); + when(debtModel.characteristicByKey("K2")).thenReturn(new DefaultDebtCharacteristic().setKey("K2").setId(2).setName("Readability").setParentId(1)); + + WsTester.TestRequest request = tester.newGetRequest("api/issues", "show").setParam("key", issue.key()); + request.execute().assertJson(getClass(), "show_issue_with_characteristics.json"); + } + + @Test + public void show_issue_with_dates() throws Exception { + Date creationDate = DateUtils.parseDateTime("2014-01-22T19:10:03+0100"); + Date updateDate = DateUtils.parseDateTime("2014-01-23T19:10:03+0100"); + Date closedDate = DateUtils.parseDateTime("2014-01-24T19:10:03+0100"); + + DefaultIssue issue = createStandardIssue() + .setCreationDate(creationDate) + .setUpdateDate(updateDate) + .setCloseDate(closedDate); + when(issueService.getByKey(issue.key())).thenReturn(issue); + + when(i18n.formatDateTime(any(Locale.class), eq(creationDate))).thenReturn("Jan 22, 2014 10:03 AM"); + when(i18n.formatDateTime(any(Locale.class), eq(updateDate))).thenReturn("Jan 23, 2014 10:03 AM"); + when(i18n.ageFromNow(any(Locale.class), eq(updateDate))).thenReturn("9 days"); + when(i18n.formatDateTime(any(Locale.class), eq(closedDate))).thenReturn("Jan 24, 2014 10:03 AM"); + + WsTester.TestRequest request = tester.newGetRequest("api/issues", "show").setParam("key", issue.key()); + request.execute().assertJson(getClass(), "show_issue_with_dates.json"); + } + + @Test + public void show_issue_with_comments() throws Exception { + Date date1 = DateUtils.parseDateTime("2014-02-22T19:10:03+0100"); + Date date2 = DateUtils.parseDateTime("2014-02-23T19:10:03+0100"); + + DefaultIssue issue = createStandardIssue(); + when(issueService.getByKey(issue.key())).thenReturn(issue); + + when(commentService.findComments(issue.key())).thenReturn(newArrayList( + new DefaultIssueComment() + .setKey("COMMENT-ABCD") + .setMarkdownText("*My comment*") + .setUserLogin("john") + .setCreatedAt(date1), + new DefaultIssueComment() + .setKey("COMMENT-ABCE") + .setMarkdownText("Another comment") + .setUserLogin("arthur") + .setCreatedAt(date2) + )); + + when(userFinder.findByLogin("john")).thenReturn(new DefaultUser().setLogin("john").setName("John")); + when(userFinder.findByLogin("arthur")).thenReturn(new DefaultUser().setLogin("arthur").setName("Arthur")); + + when(i18n.ageFromNow(any(Locale.class), eq(date1))).thenReturn("9 days"); + when(i18n.ageFromNow(any(Locale.class), eq(date2))).thenReturn("10 days"); + + userSessionRule.login("arthur"); + WsTester.TestRequest request = tester.newGetRequest("api/issues", "show").setParam("key", issue.key()); + request.execute().assertJson(getClass(), "show_issue_with_comments.json"); + } + + @Test + public void show_issue_with_transitions() throws Exception { + DefaultIssue issue = createStandardIssue() + .setStatus("RESOLVED") + .setResolution("FIXED"); + when(issueService.getByKey(issue.key())).thenReturn(issue); + + when(issueService.listTransitions(eq(issue))).thenReturn(newArrayList(Transition.create("reopen", "RESOLVED", "REOPEN"))); + + userSessionRule.login("john"); + WsTester.TestRequest request = tester.newGetRequest("api/issues", "show").setParam("key", issue.key()); + request.execute().assertJson(getClass(), "show_issue_with_transitions.json"); + } + + @Test + public void show_issue_with_actions() throws Exception { + DefaultIssue issue = createStandardIssue() + .setStatus("OPEN"); + when(issueService.getByKey(issue.key())).thenReturn(issue); + + userSessionRule.login("john"); + WsTester.TestRequest request = tester.newGetRequest("api/issues", "show").setParam("key", issue.key()); + request.execute().assertJson(getClass(), "show_issue_with_actions.json"); + } + + @Test + public void show_issue_with_changelog() throws Exception { + DefaultIssue issue = createStandardIssue(); + when(issueService.getByKey(issue.key())).thenReturn(issue); + + Date date1 = DateUtils.parseDateTime("2014-02-22T19:10:03+0100"); + Date date2 = DateUtils.parseDateTime("2014-02-23T19:10:03+0100"); + + List users = Lists.newArrayList(new DefaultUser().setLogin("john").setName("John")); + FieldDiffs userChange = new FieldDiffs() + .setUserLogin("john") + .setDiff("actionPlan", null, "1.0") + .setCreationDate(date1); + FieldDiffs scanChange = new FieldDiffs() + .setDiff("severity", "INFO", "BLOCKER") + .setDiff("status", "REOPEN", "RESOLVED") + .setCreationDate(date2); + when(issueChangelogService.changelog(issue)).thenReturn(new IssueChangelog(newArrayList(userChange, scanChange), users)); + when(issueChangelogService.formatDiffs(userChange)).thenReturn(newArrayList("Action plan updated to 1.0")); + when(issueChangelogService.formatDiffs(scanChange)).thenReturn(newArrayList("Severity updated from Info to Blocker", "Status updated from Reopen to Resolved")); + + when(i18n.formatDateTime(any(Locale.class), eq(date1))).thenReturn("Fev 22, 2014 10:03 AM"); + when(i18n.formatDateTime(any(Locale.class), eq(date2))).thenReturn("Fev 23, 2014 10:03 AM"); + + WsTester.TestRequest request = tester.newGetRequest("api/issues", "show").setParam("key", issue.key()); + request.execute().assertJson(getClass(), "show_issue_with_changelog.json"); + } + + private DefaultIssue createStandardIssue() { + ComponentDto project = ComponentTesting.newProjectDto() + .setId(1L) + .setKey("org.sonar.Sonar") + .setLongName("SonarQube") + .setName("SonarQube"); + when(componentDao.selectByUuid(session, project.uuid())).thenReturn(project); + + ComponentDto file = ComponentTesting.newFileDto(project) + .setId(10L) + .setKey("org.sonar.server.issue.IssueClient") + .setLongName("SonarQube :: Issue Client") + .setName("SonarQube :: Issue Client") + .setQualifier("FIL") + .setParentProjectId(1L); + when(componentDao.selectByUuid(session, file.uuid())).thenReturn(file); + + return createIssue() + .setComponentUuid(file.uuid()) + .setProjectUuid(project.uuid()); + } + + private DefaultIssue createIssue() { + return new DefaultIssue() + .setKey("ABCD") + .setComponentKey("org.sonar.server.issue.IssueClient") + .setProjectKey("org.sonar.Sonar") + .setRuleKey(RuleKey.of("squid", "AvoidCycle")) + .setCreationDate(issueCreationDate); + } + +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/platform/ws/InfoActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/platform/ws/InfoActionTest.java new file mode 100644 index 00000000000..74cf84b130f --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/platform/ws/InfoActionTest.java @@ -0,0 +1,73 @@ +/* + * 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.platform.ws; + +import java.util.LinkedHashMap; +import org.junit.Rule; +import org.junit.Test; +import org.sonar.api.server.ws.Request; +import org.sonar.api.server.ws.Response; +import org.sonar.api.server.ws.internal.SimpleGetRequest; +import org.sonar.core.permission.GlobalPermissions; +import org.sonar.server.exceptions.ForbiddenException; +import org.sonar.server.platform.monitoring.Monitor; +import org.sonar.server.tester.UserSessionRule; +import org.sonar.server.ws.WsTester; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class InfoActionTest { + @Rule + public UserSessionRule userSessionRule = UserSessionRule.standalone().login("login") + .setName("name"); + + Monitor monitor1 = mock(Monitor.class); + Monitor monitor2 = mock(Monitor.class); + InfoAction sut = new InfoAction(userSessionRule, monitor1, monitor2); + + @Test(expected = ForbiddenException.class) + public void should_fail_when_does_not_have_admin_right() { + userSessionRule.setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION); + + sut.handle(mock(Request.class), mock(Response.class)); + } + + @Test + public void write_json() { + userSessionRule.setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN); + + LinkedHashMap attributes1 = new LinkedHashMap<>(); + attributes1.put("foo", "bar"); + LinkedHashMap attributes2 = new LinkedHashMap<>(); + attributes2.put("one", 1); + attributes2.put("two", 2); + when(monitor1.name()).thenReturn("Monitor One"); + when(monitor1.attributes()).thenReturn(attributes1); + when(monitor2.name()).thenReturn("Monitor Two"); + when(monitor2.attributes()).thenReturn(attributes2); + + WsTester.TestResponse response = new WsTester.TestResponse(); + sut.handle(new SimpleGetRequest(), response); + assertThat(response.outputAsString()).isEqualTo("{\"Monitor One\":{\"foo\":\"bar\"},\"Monitor Two\":{\"one\":1,\"two\":2}}"); + } +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/platform/ws/MigrateDbSystemActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/platform/ws/MigrateDbSystemActionTest.java new file mode 100644 index 00000000000..8cbee38474f --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/platform/ws/MigrateDbSystemActionTest.java @@ -0,0 +1,221 @@ +/* + * 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.platform.ws; + +import com.google.common.collect.ImmutableList; +import java.util.Arrays; +import java.util.Date; +import javax.annotation.Nullable; +import org.junit.Before; +import org.junit.Test; +import org.sonar.api.server.ws.Request; +import org.sonar.api.utils.DateUtils; +import org.sonar.core.persistence.Database; +import org.sonar.core.persistence.DatabaseVersion; +import org.sonar.core.persistence.dialect.Dialect; +import org.sonar.server.db.migrations.DatabaseMigration; +import org.sonar.server.db.migrations.DatabaseMigration.Status; +import org.sonar.server.ws.WsTester; + +import static com.google.common.base.Predicates.in; +import static com.google.common.base.Predicates.not; +import static com.google.common.collect.Iterables.filter; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.sonar.server.db.migrations.DatabaseMigration.Status.FAILED; +import static org.sonar.server.db.migrations.DatabaseMigration.Status.NONE; +import static org.sonar.server.db.migrations.DatabaseMigration.Status.RUNNING; +import static org.sonar.server.db.migrations.DatabaseMigration.Status.SUCCEEDED; +import static org.sonar.test.JsonAssert.assertJson; + +public class MigrateDbSystemActionTest { + + private static final String UPTODATE_MSG = "Database is up-to-date, no migration needed."; + private static final String MIG_NOT_SUPPORTED_MSG = "Upgrade is not supported on embedded database."; + private static final String RUNNING_MSG = "Database migration is running."; + private static final Date SOME_DATE = new Date(); + private static final String SOME_THROWABLE_MSG = "blablabla pop !"; + private static final String DEFAULT_ERROR_MSG = "No failure error"; + private static final String MIG_SUCCESS_MSG = "Migration succeeded."; + private static final int CURRENT_VERSION = DatabaseVersion.LAST_VERSION; + private static final int OLD_VERSION = CURRENT_VERSION - 1; + private static final int NEWER_VERSION = CURRENT_VERSION + 1; + private static final String STATUS_NONE = "NO_MIGRATION"; + private static final String STATUS_NOT_SUPPORTED = "NOT_SUPPORTED"; + private static final String STATUS_RUNNING = "MIGRATION_RUNNING"; + private static final String STATUS_SUCCEEDED = "MIGRATION_SUCCEEDED"; + private static final String STATUS_FAILED = "MIGRATION_FAILED"; + + DatabaseVersion databaseVersion = mock(DatabaseVersion.class); + Database database = mock(Database.class); + Dialect dialect = mock(Dialect.class); + DatabaseMigration databaseMigration = mock(DatabaseMigration.class); + MigrateDbSystemAction underTest = new MigrateDbSystemAction(databaseVersion, database, databaseMigration); + + Request request = mock(Request.class); + WsTester.TestResponse response = new WsTester.TestResponse(); + + @Before + public void wireMocksTogether() { + when(database.getDialect()).thenReturn(dialect); + } + + @Test(expected = IllegalStateException.class) + public void ISE_is_thrown_when_version_can_not_be_retrieved_from_database() throws Exception { + when(databaseVersion.getVersion()).thenReturn(null); + + underTest.handle(request, response); + } + + @Test + public void verify_example() throws Exception { + when(databaseVersion.getVersion()).thenReturn(OLD_VERSION); + when(dialect.supportsMigration()).thenReturn(true); + when(databaseMigration.status()).thenReturn(RUNNING); + when(databaseMigration.startedAt()).thenReturn(DateUtils.parseDateTime("2015-02-23T18:54:23+0100")); + underTest.handle(request, response); + + assertJson(response.outputAsString()).isSimilarTo(getClass().getResource("example-migrate_db.json")); + } + + @Test + public void msg_is_operational_and_state_from_databasemigration_when_databaseversion_is_equal_to_currentversion() throws Exception { + when(databaseVersion.getVersion()).thenReturn(CURRENT_VERSION); + when(databaseMigration.status()).thenReturn(NONE); + + underTest.handle(request, response); + + assertJson(response.outputAsString()).isSimilarTo(expectedResponse(STATUS_NONE, UPTODATE_MSG)); + } + + // this test will raise a IllegalArgumentException when an unsupported value is added to the Status enum + @Test + public void defensive_test_all_values_of_Status_must_be_supported() throws Exception { + for (Status status : filter(Arrays.asList(Status.values()), not(in(ImmutableList.of(NONE, RUNNING, FAILED, SUCCEEDED))))) { + when(databaseVersion.getVersion()).thenReturn(CURRENT_VERSION); + when(databaseMigration.status()).thenReturn(status); + + underTest.handle(request, response); + } + } + + @Test + public void state_from_databasemigration_when_databaseversion_greater_than_currentversion() throws Exception { + when(databaseVersion.getVersion()).thenReturn(NEWER_VERSION); + when(databaseMigration.status()).thenReturn(NONE); + + underTest.handle(request, response); + + assertJson(response.outputAsString()).isSimilarTo(expectedResponse(STATUS_NONE, UPTODATE_MSG)); + } + + @Test + public void state_is_NONE_with_specific_msg_when_version_is_less_than_current_version_and_dialect_does_not_support_migration() throws Exception { + when(databaseVersion.getVersion()).thenReturn(OLD_VERSION); + when(dialect.supportsMigration()).thenReturn(false); + + underTest.handle(request, response); + + assertJson(response.outputAsString()).isSimilarTo(expectedResponse(STATUS_NOT_SUPPORTED, MIG_NOT_SUPPORTED_MSG)); + } + + @Test + public void state_from_databasemigration_when_dbmigration_status_is_RUNNING() throws Exception { + when(databaseVersion.getVersion()).thenReturn(OLD_VERSION); + when(dialect.supportsMigration()).thenReturn(true); + when(databaseMigration.status()).thenReturn(RUNNING); + when(databaseMigration.startedAt()).thenReturn(SOME_DATE); + + underTest.handle(request, response); + + assertJson(response.outputAsString()).isSimilarTo(expectedResponse(STATUS_RUNNING, RUNNING_MSG, SOME_DATE)); + } + + @Test + public void state_from_databasemigration_and_msg_includes_error_when_dbmigration_status_is_FAILED() throws Exception { + when(databaseVersion.getVersion()).thenReturn(OLD_VERSION); + when(dialect.supportsMigration()).thenReturn(true); + when(databaseMigration.status()).thenReturn(FAILED); + when(databaseMigration.startedAt()).thenReturn(SOME_DATE); + when(databaseMigration.failureError()).thenReturn(new UnsupportedOperationException(SOME_THROWABLE_MSG)); + + underTest.handle(request, response); + + assertJson(response.outputAsString()).isSimilarTo(expectedResponse(STATUS_FAILED, failedMsg(SOME_THROWABLE_MSG), SOME_DATE)); + } + + @Test + public void state_from_databasemigration_and_msg_has_default_msg_when_dbmigration_status_is_FAILED() throws Exception { + when(databaseVersion.getVersion()).thenReturn(OLD_VERSION); + when(dialect.supportsMigration()).thenReturn(true); + when(databaseMigration.status()).thenReturn(FAILED); + when(databaseMigration.startedAt()).thenReturn(SOME_DATE); + when(databaseMigration.failureError()).thenReturn(null); // no failure throwable caught + + underTest.handle(request, response); + + assertJson(response.outputAsString()).isSimilarTo(expectedResponse(STATUS_FAILED, failedMsg(DEFAULT_ERROR_MSG), SOME_DATE)); + } + + @Test + public void state_from_databasemigration_and_msg_has_default_msg_when_dbmigration_status_is_SUCCEEDED() throws Exception { + when(databaseVersion.getVersion()).thenReturn(OLD_VERSION); + when(dialect.supportsMigration()).thenReturn(true); + when(databaseMigration.status()).thenReturn(SUCCEEDED); + when(databaseMigration.startedAt()).thenReturn(SOME_DATE); + + underTest.handle(request, response); + + assertJson(response.outputAsString()).isSimilarTo(expectedResponse(STATUS_SUCCEEDED, MIG_SUCCESS_MSG, SOME_DATE)); + } + + @Test + public void start_migration_and_return_state_from_databasemigration_when_dbmigration_status_is_NONE() throws Exception { + when(databaseVersion.getVersion()).thenReturn(OLD_VERSION); + when(dialect.supportsMigration()).thenReturn(true); + when(databaseMigration.status()).thenReturn(NONE); + when(databaseMigration.startedAt()).thenReturn(SOME_DATE); + + underTest.handle(request, response); + + verify(databaseMigration).startIt(); + assertJson(response.outputAsString()).isSimilarTo(expectedResponse(STATUS_RUNNING, RUNNING_MSG, SOME_DATE)); + } + + private static String failedMsg(@Nullable String t) { + return "Migration failed: " + t + ".
Please check logs."; + } + + private static String expectedResponse(String status, String msg) { + return "{" + + "\"state\":\"" + status + "\"," + + "\"message\":\"" + msg + "\"" + + "}"; + } + + private static String expectedResponse(String status, String msg, Date date) { + return "{" + + "\"state\":\"" + status + "\"," + + "\"message\":\"" + msg + "\"," + + "\"startedAt\":\"" + DateUtils.formatDateTime(date) + "\"" + + "}"; + } +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/platform/ws/MigrateDbSystemWsActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/platform/ws/MigrateDbSystemWsActionTest.java deleted file mode 100644 index 1090640f063..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/platform/ws/MigrateDbSystemWsActionTest.java +++ /dev/null @@ -1,221 +0,0 @@ -/* - * 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.platform.ws; - -import com.google.common.collect.ImmutableList; -import java.util.Arrays; -import java.util.Date; -import javax.annotation.Nullable; -import org.junit.Before; -import org.junit.Test; -import org.sonar.api.server.ws.Request; -import org.sonar.api.utils.DateUtils; -import org.sonar.core.persistence.Database; -import org.sonar.core.persistence.DatabaseVersion; -import org.sonar.core.persistence.dialect.Dialect; -import org.sonar.server.db.migrations.DatabaseMigration; -import org.sonar.server.db.migrations.DatabaseMigration.Status; -import org.sonar.server.ws.WsTester; - -import static com.google.common.base.Predicates.in; -import static com.google.common.base.Predicates.not; -import static com.google.common.collect.Iterables.filter; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; -import static org.sonar.server.db.migrations.DatabaseMigration.Status.FAILED; -import static org.sonar.server.db.migrations.DatabaseMigration.Status.NONE; -import static org.sonar.server.db.migrations.DatabaseMigration.Status.RUNNING; -import static org.sonar.server.db.migrations.DatabaseMigration.Status.SUCCEEDED; -import static org.sonar.test.JsonAssert.assertJson; - -public class MigrateDbSystemWsActionTest { - - private static final String UPTODATE_MSG = "Database is up-to-date, no migration needed."; - private static final String MIG_NOT_SUPPORTED_MSG = "Upgrade is not supported on embedded database."; - private static final String RUNNING_MSG = "Database migration is running."; - private static final Date SOME_DATE = new Date(); - private static final String SOME_THROWABLE_MSG = "blablabla pop !"; - private static final String DEFAULT_ERROR_MSG = "No failure error"; - private static final String MIG_SUCCESS_MSG = "Migration succeeded."; - private static final int CURRENT_VERSION = DatabaseVersion.LAST_VERSION; - private static final int OLD_VERSION = CURRENT_VERSION - 1; - private static final int NEWER_VERSION = CURRENT_VERSION + 1; - private static final String STATUS_NONE = "NO_MIGRATION"; - private static final String STATUS_NOT_SUPPORTED = "NOT_SUPPORTED"; - private static final String STATUS_RUNNING = "MIGRATION_RUNNING"; - private static final String STATUS_SUCCEEDED = "MIGRATION_SUCCEEDED"; - private static final String STATUS_FAILED = "MIGRATION_FAILED"; - - DatabaseVersion databaseVersion = mock(DatabaseVersion.class); - Database database = mock(Database.class); - Dialect dialect = mock(Dialect.class); - DatabaseMigration databaseMigration = mock(DatabaseMigration.class); - MigrateDbSystemWsAction underTest = new MigrateDbSystemWsAction(databaseVersion, database, databaseMigration); - - Request request = mock(Request.class); - WsTester.TestResponse response = new WsTester.TestResponse(); - - @Before - public void wireMocksTogether() { - when(database.getDialect()).thenReturn(dialect); - } - - @Test(expected = IllegalStateException.class) - public void ISE_is_thrown_when_version_can_not_be_retrieved_from_database() throws Exception { - when(databaseVersion.getVersion()).thenReturn(null); - - underTest.handle(request, response); - } - - @Test - public void verify_example() throws Exception { - when(databaseVersion.getVersion()).thenReturn(OLD_VERSION); - when(dialect.supportsMigration()).thenReturn(true); - when(databaseMigration.status()).thenReturn(RUNNING); - when(databaseMigration.startedAt()).thenReturn(DateUtils.parseDateTime("2015-02-23T18:54:23+0100")); - underTest.handle(request, response); - - assertJson(response.outputAsString()).isSimilarTo(getClass().getResource("example-migrate_db.json")); - } - - @Test - public void msg_is_operational_and_state_from_databasemigration_when_databaseversion_is_equal_to_currentversion() throws Exception { - when(databaseVersion.getVersion()).thenReturn(CURRENT_VERSION); - when(databaseMigration.status()).thenReturn(NONE); - - underTest.handle(request, response); - - assertJson(response.outputAsString()).isSimilarTo(expectedResponse(STATUS_NONE, UPTODATE_MSG)); - } - - // this test will raise a IllegalArgumentException when an unsupported value is added to the Status enum - @Test - public void defensive_test_all_values_of_Status_must_be_supported() throws Exception { - for (Status status : filter(Arrays.asList(Status.values()), not(in(ImmutableList.of(NONE, RUNNING, FAILED, SUCCEEDED))))) { - when(databaseVersion.getVersion()).thenReturn(CURRENT_VERSION); - when(databaseMigration.status()).thenReturn(status); - - underTest.handle(request, response); - } - } - - @Test - public void state_from_databasemigration_when_databaseversion_greater_than_currentversion() throws Exception { - when(databaseVersion.getVersion()).thenReturn(NEWER_VERSION); - when(databaseMigration.status()).thenReturn(NONE); - - underTest.handle(request, response); - - assertJson(response.outputAsString()).isSimilarTo(expectedResponse(STATUS_NONE, UPTODATE_MSG)); - } - - @Test - public void state_is_NONE_with_specific_msg_when_version_is_less_than_current_version_and_dialect_does_not_support_migration() throws Exception { - when(databaseVersion.getVersion()).thenReturn(OLD_VERSION); - when(dialect.supportsMigration()).thenReturn(false); - - underTest.handle(request, response); - - assertJson(response.outputAsString()).isSimilarTo(expectedResponse(STATUS_NOT_SUPPORTED, MIG_NOT_SUPPORTED_MSG)); - } - - @Test - public void state_from_databasemigration_when_dbmigration_status_is_RUNNING() throws Exception { - when(databaseVersion.getVersion()).thenReturn(OLD_VERSION); - when(dialect.supportsMigration()).thenReturn(true); - when(databaseMigration.status()).thenReturn(RUNNING); - when(databaseMigration.startedAt()).thenReturn(SOME_DATE); - - underTest.handle(request, response); - - assertJson(response.outputAsString()).isSimilarTo(expectedResponse(STATUS_RUNNING, RUNNING_MSG, SOME_DATE)); - } - - @Test - public void state_from_databasemigration_and_msg_includes_error_when_dbmigration_status_is_FAILED() throws Exception { - when(databaseVersion.getVersion()).thenReturn(OLD_VERSION); - when(dialect.supportsMigration()).thenReturn(true); - when(databaseMigration.status()).thenReturn(FAILED); - when(databaseMigration.startedAt()).thenReturn(SOME_DATE); - when(databaseMigration.failureError()).thenReturn(new UnsupportedOperationException(SOME_THROWABLE_MSG)); - - underTest.handle(request, response); - - assertJson(response.outputAsString()).isSimilarTo(expectedResponse(STATUS_FAILED, failedMsg(SOME_THROWABLE_MSG), SOME_DATE)); - } - - @Test - public void state_from_databasemigration_and_msg_has_default_msg_when_dbmigration_status_is_FAILED() throws Exception { - when(databaseVersion.getVersion()).thenReturn(OLD_VERSION); - when(dialect.supportsMigration()).thenReturn(true); - when(databaseMigration.status()).thenReturn(FAILED); - when(databaseMigration.startedAt()).thenReturn(SOME_DATE); - when(databaseMigration.failureError()).thenReturn(null); // no failure throwable caught - - underTest.handle(request, response); - - assertJson(response.outputAsString()).isSimilarTo(expectedResponse(STATUS_FAILED, failedMsg(DEFAULT_ERROR_MSG), SOME_DATE)); - } - - @Test - public void state_from_databasemigration_and_msg_has_default_msg_when_dbmigration_status_is_SUCCEEDED() throws Exception { - when(databaseVersion.getVersion()).thenReturn(OLD_VERSION); - when(dialect.supportsMigration()).thenReturn(true); - when(databaseMigration.status()).thenReturn(SUCCEEDED); - when(databaseMigration.startedAt()).thenReturn(SOME_DATE); - - underTest.handle(request, response); - - assertJson(response.outputAsString()).isSimilarTo(expectedResponse(STATUS_SUCCEEDED, MIG_SUCCESS_MSG, SOME_DATE)); - } - - @Test - public void start_migration_and_return_state_from_databasemigration_when_dbmigration_status_is_NONE() throws Exception { - when(databaseVersion.getVersion()).thenReturn(OLD_VERSION); - when(dialect.supportsMigration()).thenReturn(true); - when(databaseMigration.status()).thenReturn(NONE); - when(databaseMigration.startedAt()).thenReturn(SOME_DATE); - - underTest.handle(request, response); - - verify(databaseMigration).startIt(); - assertJson(response.outputAsString()).isSimilarTo(expectedResponse(STATUS_RUNNING, RUNNING_MSG, SOME_DATE)); - } - - private static String failedMsg(@Nullable String t) { - return "Migration failed: " + t + ".
Please check logs."; - } - - private static String expectedResponse(String status, String msg) { - return "{" + - "\"state\":\"" + status + "\"," + - "\"message\":\"" + msg + "\"" + - "}"; - } - - private static String expectedResponse(String status, String msg, Date date) { - return "{" + - "\"state\":\"" + status + "\"," + - "\"message\":\"" + msg + "\"," + - "\"startedAt\":\"" + DateUtils.formatDateTime(date) + "\"" + - "}"; - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/platform/ws/RestartActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/platform/ws/RestartActionTest.java new file mode 100644 index 00000000000..34db99aa9a8 --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/platform/ws/RestartActionTest.java @@ -0,0 +1,60 @@ +/* + * 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.platform.ws; + +import org.junit.Test; +import org.sonar.api.config.Settings; +import org.sonar.server.exceptions.ForbiddenException; +import org.sonar.server.platform.Platform; +import org.sonar.server.ws.WsTester; + +import static org.junit.Assert.fail; +import static org.mockito.Mockito.*; + +public class RestartActionTest { + + Settings settings = new Settings(); + Platform platform = mock(Platform.class); + RestartAction sut = new RestartAction(settings, platform); + + @Test + public void restart_if_dev_mode() throws Exception { + settings.setProperty("sonar.web.dev", true); + + SystemWs ws = new SystemWs(sut); + + WsTester tester = new WsTester(ws); + tester.newPostRequest("api/system", "restart").execute(); + verify(platform).restart(); + } + + @Test + public void fail_if_production_mode() throws Exception { + SystemWs ws = new SystemWs(sut); + + WsTester tester = new WsTester(ws); + try { + tester.newPostRequest("api/system", "restart").execute(); + fail(); + } catch (ForbiddenException e) { + verifyZeroInteractions(platform); + } + } +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/platform/ws/StatusActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/platform/ws/StatusActionTest.java new file mode 100644 index 00000000000..26f3c2dc54a --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/platform/ws/StatusActionTest.java @@ -0,0 +1,244 @@ +/* + * 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.platform.ws; + +import org.junit.Before; +import org.junit.Test; +import org.sonar.api.platform.Server; +import org.sonar.api.server.ws.Request; +import org.sonar.api.server.ws.WebService; +import org.sonar.core.persistence.DbSession; +import org.sonar.core.persistence.IsAliveMapper; +import org.sonar.server.db.DbClient; +import org.sonar.server.db.migrations.DatabaseMigration; +import org.sonar.server.platform.Platform; +import org.sonar.server.ws.WsTester; + +import java.io.File; +import java.util.Date; +import java.util.Set; + +import static com.google.common.base.Predicates.in; +import static com.google.common.base.Predicates.not; +import static com.google.common.collect.ImmutableSet.of; +import static com.google.common.collect.Iterables.filter; +import static java.util.Arrays.asList; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Matchers.anyBoolean; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.sonar.test.JsonAssert.assertJson; + +public class StatusActionTest { + private static final String DUMMY_CONTROLLER_KEY = "dummy"; + + private static final String SERVER_ID = "20150504120436"; + private static final String SERVER_VERSION = "5.1"; + private static final String STATUS_UP = "UP"; + private static final String STATUS_DOWN = "DOWN"; + private static final String STATUS_MIGRATION_NEEDED = "DB_MIGRATION_NEEDED"; + private static final String STATUS_MIGRATION_RUNNING = "DB_MIGRATION_RUNNING"; + private static final Set SUPPORTED_DATABASE_MIGRATION_STATUSES = of(DatabaseMigration.Status.FAILED, DatabaseMigration.Status.NONE, + DatabaseMigration.Status.SUCCEEDED, DatabaseMigration.Status.RUNNING); + private static final Set SUPPORTED_PLATFORM_STATUSES = of(Platform.Status.BOOTING, Platform.Status.SAFEMODE, Platform.Status.UP); + + private static Server server = new Dummy51Server(); + private DatabaseMigration databaseMigration = mock(DatabaseMigration.class); + private Platform platform = mock(Platform.class); + private DbClient dbClient = mock(DbClient.class); + private DbSession dbSession = mock(DbSession.class); + private IsAliveMapper isAliveMapper = mock(IsAliveMapper.class); + private StatusAction underTest = new StatusAction(server, databaseMigration, platform, dbClient); + + private Request request = mock(Request.class); + + @Before + public void wireMocks() { + when(dbClient.openSession(anyBoolean())).thenReturn(dbSession); + when(dbSession.getMapper(IsAliveMapper.class)).thenReturn(isAliveMapper); + } + + @Test + public void action_status_is_defined() { + WsTester wsTester = new WsTester(); + WebService.NewController newController = wsTester.context().createController(DUMMY_CONTROLLER_KEY); + + underTest.define(newController); + newController.done(); + + WebService.Controller controller = wsTester.controller(DUMMY_CONTROLLER_KEY); + assertThat(controller.actions()).extracting("key").containsExactly("status"); + + WebService.Action action = controller.actions().iterator().next(); + assertThat(action.isPost()).isFalse(); + assertThat(action.description()).isNotEmpty(); + assertThat(action.responseExample()).isNotNull(); + + assertThat(action.params()).isEmpty(); + } + + @Test + public void verify_example() throws Exception { + when(isAliveMapper.isAlive()).thenReturn(IsAliveMapper.IS_ALIVE_RETURNED_VALUE); + when(platform.status()).thenReturn(Platform.Status.UP); + + WsTester.TestResponse response = new WsTester.TestResponse(); + underTest.handle(request, response); + + assertJson(response.outputAsString()).isSimilarTo(getClass().getResource("example-status.json")); + } + + @Test + public void status_is_UP_if_platform_is_UP_whatever_databaseMigration_status_is() throws Exception { + for (DatabaseMigration.Status databaseMigrationStatus : DatabaseMigration.Status.values()) { + verifyStatus(Platform.Status.UP, databaseMigrationStatus, STATUS_UP); + } + } + + @Test + public void status_is_DOWN_if_platform_is_BOOTING_whatever_databaseMigration_status_is() throws Exception { + for (DatabaseMigration.Status databaseMigrationStatus : DatabaseMigration.Status.values()) { + verifyStatus(Platform.Status.BOOTING, databaseMigrationStatus, STATUS_DOWN); + } + } + + @Test + public void status_is_DB_MIGRATION_NEEDED_if_platform_is_SAFEMODE_and_databaseMigration_is_NONE() throws Exception { + verifyStatus(Platform.Status.SAFEMODE, DatabaseMigration.Status.NONE, STATUS_MIGRATION_NEEDED); + } + + @Test + public void status_is_DB_MIGRATION_RUNNING_if_platform_is_SAFEMODE_and_databaseMigration_is_RUNNING() throws Exception { + verifyStatus(Platform.Status.SAFEMODE, DatabaseMigration.Status.RUNNING, STATUS_MIGRATION_RUNNING); + } + + @Test + public void status_is_UP_if_platform_is_SAFEMODE_and_databaseMigration_is_SUCCEEDED() throws Exception { + verifyStatus(Platform.Status.SAFEMODE, DatabaseMigration.Status.SUCCEEDED, STATUS_UP); + } + + @Test + public void status_is_DOWN_if_platform_is_SAFEMODE_and_databaseMigration_is_FAILED() throws Exception { + verifyStatus(Platform.Status.SAFEMODE, DatabaseMigration.Status.FAILED, STATUS_DOWN); + } + + @Test + public void status_is_DOWN_if_any_error_occurs_when_checking_DB() throws Exception { + when(isAliveMapper.isAlive()).thenThrow(new RuntimeException("simulated runtime exception when querying DB")); + + WsTester.TestResponse response = new WsTester.TestResponse(); + underTest.handle(request, response); + + assertJson(response.outputAsString()).isSimilarTo("{" + + " \"status\": \"DOWN\"\n" + + "}"); + } + + /** + * By contract {@link IsAliveMapper#isAlive()} can not return anything but 1. Still we write this test as a + * protection against change in this contract. + */ + @Test + public void status_is_DOWN_if_isAlive_does_not_return_1() throws Exception { + when(isAliveMapper.isAlive()).thenReturn(12); + + WsTester.TestResponse response = new WsTester.TestResponse(); + underTest.handle(request, response); + + assertJson(response.outputAsString()).isSimilarTo("{" + + " \"status\": \"" + STATUS_DOWN + "\"\n" + + "}"); + } + + @Test + public void safety_test_for_new_platform_status() throws Exception { + for (Platform.Status platformStatus : filter(asList(Platform.Status.values()), not(in(SUPPORTED_PLATFORM_STATUSES)))) { + for (DatabaseMigration.Status databaseMigrationStatus : DatabaseMigration.Status.values()) { + verifyStatus(platformStatus, databaseMigrationStatus, STATUS_DOWN); + } + } + } + + @Test + public void safety_test_for_new_databaseMigration_status_when_platform_is_SAFEMODE() throws Exception { + for (DatabaseMigration.Status databaseMigrationStatus : filter(asList(DatabaseMigration.Status.values()), not(in(SUPPORTED_DATABASE_MIGRATION_STATUSES)))) { + when(platform.status()).thenReturn(Platform.Status.SAFEMODE); + when(databaseMigration.status()).thenReturn(databaseMigrationStatus); + + WsTester.TestResponse response = new WsTester.TestResponse(); + underTest.handle(request, response); + } + } + + private void verifyStatus(Platform.Status platformStatus, DatabaseMigration.Status databaseMigrationStatus, String expectedStatus) throws Exception { + when(isAliveMapper.isAlive()).thenReturn(IsAliveMapper.IS_ALIVE_RETURNED_VALUE); + when(platform.status()).thenReturn(platformStatus); + when(databaseMigration.status()).thenReturn(databaseMigrationStatus); + + WsTester.TestResponse response = new WsTester.TestResponse(); + underTest.handle(request, response); + + assertJson(response.outputAsString()).isSimilarTo("{" + + " \"status\": \"" + expectedStatus + "\"\n" + + "}"); + } + + private static class Dummy51Server extends Server { + @Override + public String getId() { + return SERVER_ID; + } + + @Override + public String getVersion() { + return SERVER_VERSION; + } + + @Override + public Date getStartedAt() { + throw new UnsupportedOperationException(); + } + + @Override + public File getRootDir() { + throw new UnsupportedOperationException(); + } + + @Override + public File getDeployDir() { + throw new UnsupportedOperationException(); + } + + @Override + public String getContextPath() { + throw new UnsupportedOperationException(); + } + + @Override + public String getURL() { + throw new UnsupportedOperationException(); + } + + @Override + public String getPermanentServerId() { + throw new UnsupportedOperationException(); + } + } +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/platform/ws/SystemInfoWsActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/platform/ws/SystemInfoWsActionTest.java deleted file mode 100644 index f93b1fd2992..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/platform/ws/SystemInfoWsActionTest.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * 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.platform.ws; - -import java.util.LinkedHashMap; -import org.junit.Rule; -import org.junit.Test; -import org.sonar.api.server.ws.Request; -import org.sonar.api.server.ws.Response; -import org.sonar.api.server.ws.internal.SimpleGetRequest; -import org.sonar.core.permission.GlobalPermissions; -import org.sonar.server.exceptions.ForbiddenException; -import org.sonar.server.platform.monitoring.Monitor; -import org.sonar.server.tester.UserSessionRule; -import org.sonar.server.ws.WsTester; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -public class SystemInfoWsActionTest { - @Rule - public UserSessionRule userSessionRule = UserSessionRule.standalone().login("login") - .setName("name"); - - Monitor monitor1 = mock(Monitor.class); - Monitor monitor2 = mock(Monitor.class); - SystemInfoWsAction sut = new SystemInfoWsAction(userSessionRule, monitor1, monitor2); - - @Test(expected = ForbiddenException.class) - public void should_fail_when_does_not_have_admin_right() { - userSessionRule.setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION); - - sut.handle(mock(Request.class), mock(Response.class)); - } - - @Test - public void write_json() { - userSessionRule.setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN); - - LinkedHashMap attributes1 = new LinkedHashMap<>(); - attributes1.put("foo", "bar"); - LinkedHashMap attributes2 = new LinkedHashMap<>(); - attributes2.put("one", 1); - attributes2.put("two", 2); - when(monitor1.name()).thenReturn("Monitor One"); - when(monitor1.attributes()).thenReturn(attributes1); - when(monitor2.name()).thenReturn("Monitor Two"); - when(monitor2.attributes()).thenReturn(attributes2); - - WsTester.TestResponse response = new WsTester.TestResponse(); - sut.handle(new SimpleGetRequest(), response); - assertThat(response.outputAsString()).isEqualTo("{\"Monitor One\":{\"foo\":\"bar\"},\"Monitor Two\":{\"one\":1,\"two\":2}}"); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/platform/ws/SystemRestartWsActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/platform/ws/SystemRestartWsActionTest.java deleted file mode 100644 index 4329ff9a5d5..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/platform/ws/SystemRestartWsActionTest.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * 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.platform.ws; - -import org.junit.Test; -import org.sonar.api.config.Settings; -import org.sonar.server.exceptions.ForbiddenException; -import org.sonar.server.platform.Platform; -import org.sonar.server.ws.WsTester; - -import static org.junit.Assert.fail; -import static org.mockito.Mockito.*; - -public class SystemRestartWsActionTest { - - Settings settings = new Settings(); - Platform platform = mock(Platform.class); - SystemRestartWsAction sut = new SystemRestartWsAction(settings, platform); - - @Test - public void restart_if_dev_mode() throws Exception { - settings.setProperty("sonar.web.dev", true); - - SystemWs ws = new SystemWs(sut); - - WsTester tester = new WsTester(ws); - tester.newPostRequest("api/system", "restart").execute(); - verify(platform).restart(); - } - - @Test - public void fail_if_production_mode() throws Exception { - SystemWs ws = new SystemWs(sut); - - WsTester tester = new WsTester(ws); - try { - tester.newPostRequest("api/system", "restart").execute(); - fail(); - } catch (ForbiddenException e) { - verifyZeroInteractions(platform); - } - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/platform/ws/SystemStatusWsActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/platform/ws/SystemStatusWsActionTest.java deleted file mode 100644 index a64e45a95b9..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/platform/ws/SystemStatusWsActionTest.java +++ /dev/null @@ -1,243 +0,0 @@ -/* - * 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.platform.ws; - -import java.io.File; -import java.util.Date; -import java.util.Set; -import org.junit.Before; -import org.junit.Test; -import org.sonar.api.platform.Server; -import org.sonar.api.server.ws.Request; -import org.sonar.api.server.ws.WebService; -import org.sonar.core.persistence.DbSession; -import org.sonar.core.persistence.IsAliveMapper; -import org.sonar.server.db.DbClient; -import org.sonar.server.db.migrations.DatabaseMigration; -import org.sonar.server.platform.Platform; -import org.sonar.server.ws.WsTester; - -import static com.google.common.base.Predicates.in; -import static com.google.common.base.Predicates.not; -import static com.google.common.collect.ImmutableSet.of; -import static com.google.common.collect.Iterables.filter; -import static java.util.Arrays.asList; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Matchers.anyBoolean; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; -import static org.sonar.test.JsonAssert.assertJson; - -public class SystemStatusWsActionTest { - private static final String DUMMY_CONTROLLER_KEY = "dummy"; - - private static final String SERVER_ID = "20150504120436"; - private static final String SERVER_VERSION = "5.1"; - private static final String STATUS_UP = "UP"; - private static final String STATUS_DOWN = "DOWN"; - private static final String STATUS_MIGRATION_NEEDED = "DB_MIGRATION_NEEDED"; - private static final String STATUS_MIGRATION_RUNNING = "DB_MIGRATION_RUNNING"; - private static final Set SUPPORTED_DATABASE_MIGRATION_STATUSES = of(DatabaseMigration.Status.FAILED, DatabaseMigration.Status.NONE, - DatabaseMigration.Status.SUCCEEDED, DatabaseMigration.Status.RUNNING); - private static final Set SUPPORTED_PLATFORM_STATUSES = of(Platform.Status.BOOTING, Platform.Status.SAFEMODE, Platform.Status.UP); - - private static Server server = new Dummy51Server(); - private DatabaseMigration databaseMigration = mock(DatabaseMigration.class); - private Platform platform = mock(Platform.class); - private DbClient dbClient = mock(DbClient.class); - private DbSession dbSession = mock(DbSession.class); - private IsAliveMapper isAliveMapper = mock(IsAliveMapper.class); - private SystemStatusWsAction underTest = new SystemStatusWsAction(server, databaseMigration, platform, dbClient); - - private Request request = mock(Request.class); - - @Before - public void wireMocks() { - when(dbClient.openSession(anyBoolean())).thenReturn(dbSession); - when(dbSession.getMapper(IsAliveMapper.class)).thenReturn(isAliveMapper); - } - - @Test - public void action_status_is_defined() { - WsTester wsTester = new WsTester(); - WebService.NewController newController = wsTester.context().createController(DUMMY_CONTROLLER_KEY); - - underTest.define(newController); - newController.done(); - - WebService.Controller controller = wsTester.controller(DUMMY_CONTROLLER_KEY); - assertThat(controller.actions()).extracting("key").containsExactly("status"); - - WebService.Action action = controller.actions().iterator().next(); - assertThat(action.isPost()).isFalse(); - assertThat(action.description()).isNotEmpty(); - assertThat(action.responseExample()).isNotNull(); - - assertThat(action.params()).isEmpty(); - } - - @Test - public void verify_example() throws Exception { - when(isAliveMapper.isAlive()).thenReturn(IsAliveMapper.IS_ALIVE_RETURNED_VALUE); - when(platform.status()).thenReturn(Platform.Status.UP); - - WsTester.TestResponse response = new WsTester.TestResponse(); - underTest.handle(request, response); - - assertJson(response.outputAsString()).isSimilarTo(getClass().getResource("example-status.json")); - } - - @Test - public void status_is_UP_if_platform_is_UP_whatever_databaseMigration_status_is() throws Exception { - for (DatabaseMigration.Status databaseMigrationStatus : DatabaseMigration.Status.values()) { - verifyStatus(Platform.Status.UP, databaseMigrationStatus, STATUS_UP); - } - } - - @Test - public void status_is_DOWN_if_platform_is_BOOTING_whatever_databaseMigration_status_is() throws Exception { - for (DatabaseMigration.Status databaseMigrationStatus : DatabaseMigration.Status.values()) { - verifyStatus(Platform.Status.BOOTING, databaseMigrationStatus, STATUS_DOWN); - } - } - - @Test - public void status_is_DB_MIGRATION_NEEDED_if_platform_is_SAFEMODE_and_databaseMigration_is_NONE() throws Exception { - verifyStatus(Platform.Status.SAFEMODE, DatabaseMigration.Status.NONE, STATUS_MIGRATION_NEEDED); - } - - @Test - public void status_is_DB_MIGRATION_RUNNING_if_platform_is_SAFEMODE_and_databaseMigration_is_RUNNING() throws Exception { - verifyStatus(Platform.Status.SAFEMODE, DatabaseMigration.Status.RUNNING, STATUS_MIGRATION_RUNNING); - } - - @Test - public void status_is_UP_if_platform_is_SAFEMODE_and_databaseMigration_is_SUCCEEDED() throws Exception { - verifyStatus(Platform.Status.SAFEMODE, DatabaseMigration.Status.SUCCEEDED, STATUS_UP); - } - - @Test - public void status_is_DOWN_if_platform_is_SAFEMODE_and_databaseMigration_is_FAILED() throws Exception { - verifyStatus(Platform.Status.SAFEMODE, DatabaseMigration.Status.FAILED, STATUS_DOWN); - } - - @Test - public void status_is_DOWN_if_any_error_occurs_when_checking_DB() throws Exception { - when(isAliveMapper.isAlive()).thenThrow(new RuntimeException("simulated runtime exception when querying DB")); - - WsTester.TestResponse response = new WsTester.TestResponse(); - underTest.handle(request, response); - - assertJson(response.outputAsString()).isSimilarTo("{" + - " \"status\": \"DOWN\"\n" + - "}"); - } - - /** - * By contract {@link IsAliveMapper#isAlive()} can not return anything but 1. Still we write this test as a - * protection against change in this contract. - */ - @Test - public void status_is_DOWN_if_isAlive_does_not_return_1() throws Exception { - when(isAliveMapper.isAlive()).thenReturn(12); - - WsTester.TestResponse response = new WsTester.TestResponse(); - underTest.handle(request, response); - - assertJson(response.outputAsString()).isSimilarTo("{" + - " \"status\": \"" + STATUS_DOWN + "\"\n" + - "}"); - } - - @Test - public void safety_test_for_new_platform_status() throws Exception { - for (Platform.Status platformStatus : filter(asList(Platform.Status.values()), not(in(SUPPORTED_PLATFORM_STATUSES)))) { - for (DatabaseMigration.Status databaseMigrationStatus : DatabaseMigration.Status.values()) { - verifyStatus(platformStatus, databaseMigrationStatus, STATUS_DOWN); - } - } - } - - @Test - public void safety_test_for_new_databaseMigration_status_when_platform_is_SAFEMODE() throws Exception { - for (DatabaseMigration.Status databaseMigrationStatus : filter(asList(DatabaseMigration.Status.values()), not(in(SUPPORTED_DATABASE_MIGRATION_STATUSES)))) { - when(platform.status()).thenReturn(Platform.Status.SAFEMODE); - when(databaseMigration.status()).thenReturn(databaseMigrationStatus); - - WsTester.TestResponse response = new WsTester.TestResponse(); - underTest.handle(request, response); - } - } - - private void verifyStatus(Platform.Status platformStatus, DatabaseMigration.Status databaseMigrationStatus, String expectedStatus) throws Exception { - when(isAliveMapper.isAlive()).thenReturn(IsAliveMapper.IS_ALIVE_RETURNED_VALUE); - when(platform.status()).thenReturn(platformStatus); - when(databaseMigration.status()).thenReturn(databaseMigrationStatus); - - WsTester.TestResponse response = new WsTester.TestResponse(); - underTest.handle(request, response); - - assertJson(response.outputAsString()).isSimilarTo("{" + - " \"status\": \"" + expectedStatus + "\"\n" + - "}"); - } - - private static class Dummy51Server extends Server { - @Override - public String getId() { - return SERVER_ID; - } - - @Override - public String getVersion() { - return SERVER_VERSION; - } - - @Override - public Date getStartedAt() { - throw new UnsupportedOperationException(); - } - - @Override - public File getRootDir() { - throw new UnsupportedOperationException(); - } - - @Override - public File getDeployDir() { - throw new UnsupportedOperationException(); - } - - @Override - public String getContextPath() { - throw new UnsupportedOperationException(); - } - - @Override - public String getURL() { - throw new UnsupportedOperationException(); - } - - @Override - public String getPermanentServerId() { - throw new UnsupportedOperationException(); - } - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/platform/ws/SystemWsTest.java b/server/sonar-server/src/test/java/org/sonar/server/platform/ws/SystemWsTest.java index a475adf91f7..a00bc635f87 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/platform/ws/SystemWsTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/platform/ws/SystemWsTest.java @@ -32,8 +32,8 @@ public class SystemWsTest { @Test public void define() { - SystemRestartWsAction action1 = new SystemRestartWsAction(mock(Settings.class), mock(Platform.class)); - SystemInfoWsAction action2 = new SystemInfoWsAction(new AnonymousMockUserSession()); + RestartAction action1 = new RestartAction(mock(Settings.class), mock(Platform.class)); + InfoAction action2 = new InfoAction(new AnonymousMockUserSession()); SystemWs ws = new SystemWs(action1, action2); WebService.Context context = new WebService.Context(); diff --git a/server/sonar-server/src/test/java/org/sonar/server/platform/ws/UpgradesActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/platform/ws/UpgradesActionTest.java new file mode 100644 index 00000000000..e5939d5a45d --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/platform/ws/UpgradesActionTest.java @@ -0,0 +1,136 @@ +/* + * 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.platform.ws; + +import org.junit.Before; +import org.junit.Test; +import org.sonar.api.server.ws.Request; +import org.sonar.api.server.ws.WebService; +import org.sonar.api.utils.DateUtils; +import org.sonar.server.plugins.UpdateCenterMatrixFactory; +import org.sonar.server.plugins.ws.PluginWSCommons; +import org.sonar.server.ws.WsTester; +import org.sonar.updatecenter.common.Plugin; +import org.sonar.updatecenter.common.Release; +import org.sonar.updatecenter.common.Sonar; +import org.sonar.updatecenter.common.SonarUpdate; +import org.sonar.updatecenter.common.UpdateCenter; +import org.sonar.updatecenter.common.Version; + +import static com.google.common.collect.ImmutableList.of; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Matchers.anyBoolean; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.sonar.test.JsonAssert.assertJson; + +public class UpgradesActionTest { + private static final String DUMMY_CONTROLLER_KEY = "dummy"; + private static final String JSON_EMPTY_UPGRADE_LIST = + "{" + + " \"upgrades\":" + "[]" + + "}"; + + private UpdateCenterMatrixFactory updateCenterFactory = mock(UpdateCenterMatrixFactory.class); + private UpdateCenter updateCenter = mock(UpdateCenter.class); + private UpgradesAction underTest = new UpgradesAction(updateCenterFactory, new PluginWSCommons()); + + private Request request = mock(Request.class); + private WsTester.TestResponse response = new WsTester.TestResponse(); + + @Before + public void wireMocks() { + when(updateCenterFactory.getUpdateCenter(anyBoolean())).thenReturn(updateCenter); + when(updateCenter.getDate()).thenReturn(DateUtils.parseDateTime("2015-04-24T16:08:36+0200")); + } + + @Test + public void action_updates_is_defined() { + WsTester wsTester = new WsTester(); + WebService.NewController newController = wsTester.context().createController(DUMMY_CONTROLLER_KEY); + + underTest.define(newController); + newController.done(); + + WebService.Controller controller = wsTester.controller(DUMMY_CONTROLLER_KEY); + assertThat(controller.actions()).extracting("key").containsExactly("upgrades"); + + WebService.Action action = controller.actions().iterator().next(); + assertThat(action.isPost()).isFalse(); + assertThat(action.description()).isNotEmpty(); + assertThat(action.responseExample()).isNotNull(); + + assertThat(action.params()).isEmpty(); + } + + @Test + public void empty_array_is_returned_when_there_is_no_upgrade_available() throws Exception { + underTest.handle(request, response); + + assertJson(response.outputAsString()).setStrictArrayOrder(true).isSimilarTo(JSON_EMPTY_UPGRADE_LIST); + } + + @Test + public void verify_JSON_response_against_example() throws Exception { + SonarUpdate sonarUpdate = createSonar_51_update(); + when(updateCenter.findSonarUpdates()).thenReturn(of(sonarUpdate)); + + underTest.handle(request, response); + + assertJson(response.outputAsString()).setStrictArrayOrder(true) + .isSimilarTo(getClass().getResource("example-upgrades_plugins.json")); + } + + private static SonarUpdate createSonar_51_update() { + Plugin brandingPlugin = new Plugin("branding") + .setCategory("Integration") + .setName("Branding") + .setDescription("Allows to add your own logo to the SonarQube UI.") + .setHomepageUrl("http://docs.codehaus.org/display/SONAR/Branding+Plugin") + .setLicense("GNU LGPL 3") + .setOrganization("SonarSource") + .setOrganizationUrl("http://www.sonarsource.com") + .setIssueTrackerUrl("http://jira.codehaus.org/browse/SONARPLUGINS/component/14663") + .setSourcesUrl("https://github.com/SonarCommunity/sonar-branding"); + Plugin viewsPlugin = new Plugin("views") + .setName("Views") + .setCategory("Governance") + .setDescription("Create aggregation trees to group projects. Projects can for instance be grouped by applications, applications by team, teams by department.") + .setHomepageUrl("http://redirect.sonarsource.com/plugins/views.html") + .setLicense("Commercial") + .setOrganization("SonarSource") + .setOrganizationUrl("http://www.sonarsource.com") + .setTermsConditionsUrl("http://dist.sonarsource.com/SonarSource_Terms_And_Conditions.pdf") + .setIssueTrackerUrl("http://jira.sonarsource.com/browse/VIEWS"); + + SonarUpdate sonarUpdate = new SonarUpdate( + new Release(new Sonar(), Version.create("5.1")) + .setDate(DateUtils.parseDate("2015-04-02")) + .setDescription("New overall layout, merge Issues Drilldown [...]") + .setDownloadUrl("http://dist.sonar.codehaus.org/sonarqube-5.1.zip") + .setChangelogUrl("http://jira.codehaus.org/secure/ReleaseNote.jspa?projectId=11694&version=20666") + ); + + sonarUpdate.addIncompatiblePlugin(brandingPlugin); + sonarUpdate.addPluginToUpgrade(new Release(viewsPlugin, Version.create("2.8"))); + + return sonarUpdate; + } +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/platform/ws/UpgradesSystemWsActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/platform/ws/UpgradesSystemWsActionTest.java deleted file mode 100644 index 24557f8b035..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/platform/ws/UpgradesSystemWsActionTest.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * 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.platform.ws; - -import org.junit.Before; -import org.junit.Test; -import org.sonar.api.server.ws.Request; -import org.sonar.api.server.ws.WebService; -import org.sonar.api.utils.DateUtils; -import org.sonar.server.plugins.UpdateCenterMatrixFactory; -import org.sonar.server.plugins.ws.PluginWSCommons; -import org.sonar.server.ws.WsTester; -import org.sonar.updatecenter.common.Plugin; -import org.sonar.updatecenter.common.Release; -import org.sonar.updatecenter.common.Sonar; -import org.sonar.updatecenter.common.SonarUpdate; -import org.sonar.updatecenter.common.UpdateCenter; -import org.sonar.updatecenter.common.Version; - -import static com.google.common.collect.ImmutableList.of; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Matchers.anyBoolean; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; -import static org.sonar.test.JsonAssert.assertJson; - -public class UpgradesSystemWsActionTest { - private static final String DUMMY_CONTROLLER_KEY = "dummy"; - private static final String JSON_EMPTY_UPGRADE_LIST = - "{" + - " \"upgrades\":" + "[]" + - "}"; - - private UpdateCenterMatrixFactory updateCenterFactory = mock(UpdateCenterMatrixFactory.class); - private UpdateCenter updateCenter = mock(UpdateCenter.class); - private UpgradesSystemWsAction underTest = new UpgradesSystemWsAction(updateCenterFactory, new PluginWSCommons()); - - private Request request = mock(Request.class); - private WsTester.TestResponse response = new WsTester.TestResponse(); - - @Before - public void wireMocks() { - when(updateCenterFactory.getUpdateCenter(anyBoolean())).thenReturn(updateCenter); - when(updateCenter.getDate()).thenReturn(DateUtils.parseDateTime("2015-04-24T16:08:36+0200")); - } - - @Test - public void action_updates_is_defined() { - WsTester wsTester = new WsTester(); - WebService.NewController newController = wsTester.context().createController(DUMMY_CONTROLLER_KEY); - - underTest.define(newController); - newController.done(); - - WebService.Controller controller = wsTester.controller(DUMMY_CONTROLLER_KEY); - assertThat(controller.actions()).extracting("key").containsExactly("upgrades"); - - WebService.Action action = controller.actions().iterator().next(); - assertThat(action.isPost()).isFalse(); - assertThat(action.description()).isNotEmpty(); - assertThat(action.responseExample()).isNotNull(); - - assertThat(action.params()).isEmpty(); - } - - @Test - public void empty_array_is_returned_when_there_is_no_upgrade_available() throws Exception { - underTest.handle(request, response); - - assertJson(response.outputAsString()).setStrictArrayOrder(true).isSimilarTo(JSON_EMPTY_UPGRADE_LIST); - } - - @Test - public void verify_JSON_response_against_example() throws Exception { - SonarUpdate sonarUpdate = createSonar_51_update(); - when(updateCenter.findSonarUpdates()).thenReturn(of(sonarUpdate)); - - underTest.handle(request, response); - - assertJson(response.outputAsString()).setStrictArrayOrder(true) - .isSimilarTo(getClass().getResource("example-upgrades_plugins.json")); - } - - private static SonarUpdate createSonar_51_update() { - Plugin brandingPlugin = new Plugin("branding") - .setCategory("Integration") - .setName("Branding") - .setDescription("Allows to add your own logo to the SonarQube UI.") - .setHomepageUrl("http://docs.codehaus.org/display/SONAR/Branding+Plugin") - .setLicense("GNU LGPL 3") - .setOrganization("SonarSource") - .setOrganizationUrl("http://www.sonarsource.com") - .setIssueTrackerUrl("http://jira.codehaus.org/browse/SONARPLUGINS/component/14663") - .setSourcesUrl("https://github.com/SonarCommunity/sonar-branding"); - Plugin viewsPlugin = new Plugin("views") - .setName("Views") - .setCategory("Governance") - .setDescription("Create aggregation trees to group projects. Projects can for instance be grouped by applications, applications by team, teams by department.") - .setHomepageUrl("http://redirect.sonarsource.com/plugins/views.html") - .setLicense("Commercial") - .setOrganization("SonarSource") - .setOrganizationUrl("http://www.sonarsource.com") - .setTermsConditionsUrl("http://dist.sonarsource.com/SonarSource_Terms_And_Conditions.pdf") - .setIssueTrackerUrl("http://jira.sonarsource.com/browse/VIEWS"); - - SonarUpdate sonarUpdate = new SonarUpdate( - new Release(new Sonar(), Version.create("5.1")) - .setDate(DateUtils.parseDate("2015-04-02")) - .setDescription("New overall layout, merge Issues Drilldown [...]") - .setDownloadUrl("http://dist.sonar.codehaus.org/sonarqube-5.1.zip") - .setChangelogUrl("http://jira.codehaus.org/secure/ReleaseNote.jspa?projectId=11694&version=20666") - ); - - sonarUpdate.addIncompatiblePlugin(brandingPlugin); - sonarUpdate.addPluginToUpgrade(new Release(viewsPlugin, Version.create("2.8"))); - - return sonarUpdate; - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/AbstractUpdateCenterBasedPluginsWsActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/AbstractUpdateCenterBasedPluginsWsActionTest.java index 92c7fbab55a..03682b2ffdb 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/AbstractUpdateCenterBasedPluginsWsActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/AbstractUpdateCenterBasedPluginsWsActionTest.java @@ -19,7 +19,6 @@ */ package org.sonar.server.plugins.ws; -import java.net.URL; import org.junit.Before; import org.sonar.api.server.ws.Request; import org.sonar.api.utils.DateUtils; @@ -31,6 +30,8 @@ import org.sonar.updatecenter.common.Release; import org.sonar.updatecenter.common.UpdateCenter; import org.sonar.updatecenter.common.Version; +import java.net.URL; + import static org.mockito.Matchers.anyBoolean; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -60,7 +61,7 @@ public class AbstractUpdateCenterBasedPluginsWsActionTest { } protected static URL resource(String s) { - Class clazz = AvailablePluginsWsActionTest.class; + Class clazz = AvailableActionTest.class; return clazz.getResource(clazz.getSimpleName() + "/" + s); } diff --git a/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/AvailableActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/AvailableActionTest.java new file mode 100644 index 00000000000..b6c59f1ab61 --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/AvailableActionTest.java @@ -0,0 +1,142 @@ +/* + * 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.plugins.ws; + +import org.junit.Test; +import org.sonar.api.server.ws.WebService; +import org.sonar.api.utils.DateUtils; +import org.sonar.server.ws.WsTester; +import org.sonar.updatecenter.common.Plugin; +import org.sonar.updatecenter.common.PluginUpdate; +import org.sonar.updatecenter.common.Release; + +import static com.google.common.collect.ImmutableList.of; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.when; +import static org.sonar.test.JsonAssert.assertJson; +import static org.sonar.updatecenter.common.PluginUpdate.Status.COMPATIBLE; +import static org.sonar.updatecenter.common.PluginUpdate.Status.DEPENDENCIES_REQUIRE_SONAR_UPGRADE; +import static org.sonar.updatecenter.common.PluginUpdate.Status.INCOMPATIBLE; +import static org.sonar.updatecenter.common.PluginUpdate.Status.REQUIRE_SONAR_UPGRADE; + +public class AvailableActionTest extends AbstractUpdateCenterBasedPluginsWsActionTest { + + private static final Plugin FULL_PROPERTIES_PLUGIN = new Plugin("p_key") + .setName("p_name") + .setCategory("p_category") + .setDescription("p_description") + .setLicense("p_license") + .setOrganization("p_orga_name") + .setOrganizationUrl("p_orga_url") + .setTermsConditionsUrl("p_t_and_c_url"); + private static final Release FULL_PROPERTIES_PLUGIN_RELEASE = release(FULL_PROPERTIES_PLUGIN, "1.12.1") + .setDate(DateUtils.parseDate("2015-04-16")) + .setDownloadUrl("http://p_file.jar") + .addOutgoingDependency(release(PLUGIN_1, "0.3.6")) + .addOutgoingDependency(release(PLUGIN_2, "1.0.0")); + + private AvailableAction underTest = new AvailableAction(updateCenterFactory, new PluginWSCommons()); + + @Test + public void action_available_is_defined() { + WsTester wsTester = new WsTester(); + WebService.NewController newController = wsTester.context().createController(DUMMY_CONTROLLER_KEY); + + underTest.define(newController); + newController.done(); + + WebService.Controller controller = wsTester.controller(DUMMY_CONTROLLER_KEY); + assertThat(controller.actions()).extracting("key").containsExactly("available"); + + WebService.Action action = controller.actions().iterator().next(); + assertThat(action.isPost()).isFalse(); + assertThat(action.description()).isNotEmpty(); + assertThat(action.responseExample()).isNotNull(); + } + + @Test + public void empty_array_is_returned_when_there_is_no_plugin_available() throws Exception { + underTest.handle(request, response); + + assertJson(response.outputAsString()).setStrictArrayOrder(true).isSimilarTo(JSON_EMPTY_PLUGIN_LIST); + } + + @Test + public void verify_properties_displayed_in_json_per_plugin() throws Exception { + when(updateCenter.findAvailablePlugins()).thenReturn(of( + pluginUpdate(FULL_PROPERTIES_PLUGIN_RELEASE, COMPATIBLE) + )); + + underTest.handle(request, response); + + assertJson(response.outputAsString()).isSimilarTo(resource("properties_per_plugin.json")); + } + + @Test + public void status_COMPATIBLE_is_displayed_COMPATIBLE_in_JSON() throws Exception { + checkStatusDisplayedInJson(COMPATIBLE, "COMPATIBLE"); + } + + @Test + public void status_INCOMPATIBLE_is_displayed_INCOMPATIBLE_in_JSON() throws Exception { + checkStatusDisplayedInJson(INCOMPATIBLE, "INCOMPATIBLE"); + } + + @Test + public void status_REQUIRE_SONAR_UPGRADE_is_displayed_REQUIRES_SYSTEM_UPGRADE_in_JSON() throws Exception { + checkStatusDisplayedInJson(REQUIRE_SONAR_UPGRADE, "REQUIRES_SYSTEM_UPGRADE"); + } + + @Test + public void status_DEPENDENCIES_REQUIRE_SONAR_UPGRADE_is_displayed_DEPS_REQUIRE_SYSTEM_UPGRADE_in_JSON() throws Exception { + checkStatusDisplayedInJson(DEPENDENCIES_REQUIRE_SONAR_UPGRADE, "DEPS_REQUIRE_SYSTEM_UPGRADE"); + } + + private void checkStatusDisplayedInJson(PluginUpdate.Status status, String expectedValue) throws Exception { + when(updateCenter.findAvailablePlugins()).thenReturn(of( + pluginUpdate(release(PLUGIN_1, "1.0.0"), status) + )); + + underTest.handle(request, response); + + assertJson(response.outputAsString()).isSimilarTo( + "{" + + " \"plugins\": [" + + " {" + + " \"update\": {" + + " \"status\": \"" + expectedValue + "\"" + + " }" + + " }" + + " ]" + + "}" + ); + } + + @Test + public void plugins_are_sorted_by_name_then_key_and_made_unique() { + when(updateCenter.findAvailablePlugins()).thenReturn(of( + pluginUpdate("key2", "name2"), + pluginUpdate("key1", "name2"), + pluginUpdate("key2", "name2"), + pluginUpdate("key0", "name0"), + pluginUpdate("key1", "name1") + )); + } +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/AvailablePluginsWsActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/AvailablePluginsWsActionTest.java deleted file mode 100644 index 220975fbfd5..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/AvailablePluginsWsActionTest.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * 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.plugins.ws; - -import org.junit.Test; -import org.sonar.api.server.ws.WebService; -import org.sonar.api.utils.DateUtils; -import org.sonar.server.ws.WsTester; -import org.sonar.updatecenter.common.Plugin; -import org.sonar.updatecenter.common.PluginUpdate; -import org.sonar.updatecenter.common.Release; - -import static com.google.common.collect.ImmutableList.of; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.when; -import static org.sonar.test.JsonAssert.assertJson; -import static org.sonar.updatecenter.common.PluginUpdate.Status.COMPATIBLE; -import static org.sonar.updatecenter.common.PluginUpdate.Status.DEPENDENCIES_REQUIRE_SONAR_UPGRADE; -import static org.sonar.updatecenter.common.PluginUpdate.Status.INCOMPATIBLE; -import static org.sonar.updatecenter.common.PluginUpdate.Status.REQUIRE_SONAR_UPGRADE; - -public class AvailablePluginsWsActionTest extends AbstractUpdateCenterBasedPluginsWsActionTest { - - private static final Plugin FULL_PROPERTIES_PLUGIN = new Plugin("p_key") - .setName("p_name") - .setCategory("p_category") - .setDescription("p_description") - .setLicense("p_license") - .setOrganization("p_orga_name") - .setOrganizationUrl("p_orga_url") - .setTermsConditionsUrl("p_t_and_c_url"); - private static final Release FULL_PROPERTIES_PLUGIN_RELEASE = release(FULL_PROPERTIES_PLUGIN, "1.12.1") - .setDate(DateUtils.parseDate("2015-04-16")) - .setDownloadUrl("http://p_file.jar") - .addOutgoingDependency(release(PLUGIN_1, "0.3.6")) - .addOutgoingDependency(release(PLUGIN_2, "1.0.0")); - - private AvailablePluginsWsAction underTest = new AvailablePluginsWsAction(updateCenterFactory, new PluginWSCommons()); - - @Test - public void action_available_is_defined() { - WsTester wsTester = new WsTester(); - WebService.NewController newController = wsTester.context().createController(DUMMY_CONTROLLER_KEY); - - underTest.define(newController); - newController.done(); - - WebService.Controller controller = wsTester.controller(DUMMY_CONTROLLER_KEY); - assertThat(controller.actions()).extracting("key").containsExactly("available"); - - WebService.Action action = controller.actions().iterator().next(); - assertThat(action.isPost()).isFalse(); - assertThat(action.description()).isNotEmpty(); - assertThat(action.responseExample()).isNotNull(); - } - - @Test - public void empty_array_is_returned_when_there_is_no_plugin_available() throws Exception { - underTest.handle(request, response); - - assertJson(response.outputAsString()).setStrictArrayOrder(true).isSimilarTo(JSON_EMPTY_PLUGIN_LIST); - } - - @Test - public void verify_properties_displayed_in_json_per_plugin() throws Exception { - when(updateCenter.findAvailablePlugins()).thenReturn(of( - pluginUpdate(FULL_PROPERTIES_PLUGIN_RELEASE, COMPATIBLE) - )); - - underTest.handle(request, response); - - assertJson(response.outputAsString()).isSimilarTo(resource("properties_per_plugin.json")); - } - - @Test - public void status_COMPATIBLE_is_displayed_COMPATIBLE_in_JSON() throws Exception { - checkStatusDisplayedInJson(COMPATIBLE, "COMPATIBLE"); - } - - @Test - public void status_INCOMPATIBLE_is_displayed_INCOMPATIBLE_in_JSON() throws Exception { - checkStatusDisplayedInJson(INCOMPATIBLE, "INCOMPATIBLE"); - } - - @Test - public void status_REQUIRE_SONAR_UPGRADE_is_displayed_REQUIRES_SYSTEM_UPGRADE_in_JSON() throws Exception { - checkStatusDisplayedInJson(REQUIRE_SONAR_UPGRADE, "REQUIRES_SYSTEM_UPGRADE"); - } - - @Test - public void status_DEPENDENCIES_REQUIRE_SONAR_UPGRADE_is_displayed_DEPS_REQUIRE_SYSTEM_UPGRADE_in_JSON() throws Exception { - checkStatusDisplayedInJson(DEPENDENCIES_REQUIRE_SONAR_UPGRADE, "DEPS_REQUIRE_SYSTEM_UPGRADE"); - } - - private void checkStatusDisplayedInJson(PluginUpdate.Status status, String expectedValue) throws Exception { - when(updateCenter.findAvailablePlugins()).thenReturn(of( - pluginUpdate(release(PLUGIN_1, "1.0.0"), status) - )); - - underTest.handle(request, response); - - assertJson(response.outputAsString()).isSimilarTo( - "{" + - " \"plugins\": [" + - " {" + - " \"update\": {" + - " \"status\": \"" + expectedValue + "\"" + - " }" + - " }" + - " ]" + - "}" - ); - } - - @Test - public void plugins_are_sorted_by_name_then_key_and_made_unique() { - when(updateCenter.findAvailablePlugins()).thenReturn(of( - pluginUpdate("key2", "name2"), - pluginUpdate("key1", "name2"), - pluginUpdate("key2", "name2"), - pluginUpdate("key0", "name0"), - pluginUpdate("key1", "name1") - )); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/CancelAllActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/CancelAllActionTest.java new file mode 100644 index 00000000000..26d06a8a233 --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/CancelAllActionTest.java @@ -0,0 +1,94 @@ +/* + * 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.plugins.ws; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.sonar.api.server.ws.Request; +import org.sonar.api.server.ws.WebService; +import org.sonar.core.permission.GlobalPermissions; +import org.sonar.server.exceptions.ForbiddenException; +import org.sonar.server.plugins.PluginDownloader; +import org.sonar.server.plugins.ServerPluginRepository; +import org.sonar.server.tester.UserSessionRule; +import org.sonar.server.ws.WsTester; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +public class CancelAllActionTest { + private static final String DUMMY_CONTROLLER_KEY = "dummy"; + + @Rule + public UserSessionRule userSessionRule = UserSessionRule.standalone().setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN); + + private PluginDownloader pluginDownloader = mock(PluginDownloader.class); + private ServerPluginRepository pluginRepository = mock(ServerPluginRepository.class); + private CancelAllAction underTest = new CancelAllAction(pluginDownloader, pluginRepository, userSessionRule); + + private Request request = mock(Request.class); + private WsTester.TestResponse response = new WsTester.TestResponse(); + + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + @Test + public void action_cancel_all_is_defined() { + WsTester wsTester = new WsTester(); + WebService.NewController newController = wsTester.context().createController(DUMMY_CONTROLLER_KEY); + + underTest.define(newController); + newController.done(); + + WebService.Controller controller = wsTester.controller(DUMMY_CONTROLLER_KEY); + assertThat(controller.actions()).extracting("key").containsExactly("cancel_all"); + + WebService.Action action = controller.actions().iterator().next(); + assertThat(action.isPost()).isTrue(); + assertThat(action.description()).isNotEmpty(); + assertThat(action.responseExample()).isNull(); + + assertThat(action.params()).isEmpty(); + } + + @Test + public void user_must_have_system_admin_permission() throws Exception { + expectedException.expect(ForbiddenException.class); + expectedException.expectMessage("Insufficient privileges"); + + // no permission on user + userSessionRule.setGlobalPermissions(); + + underTest.handle(request, response); + } + + @Test + public void triggers_cancel_for_downloads_and_uninstalls() throws Exception { + underTest.handle(request, response); + + verify(pluginDownloader, times(1)).cancelDownloads(); + verify(pluginRepository, times(1)).cancelUninstalls(); + assertThat(response.outputAsString()).isEmpty(); + } + +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/CancelAllPluginsWsActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/CancelAllPluginsWsActionTest.java deleted file mode 100644 index 11f91f15ef6..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/CancelAllPluginsWsActionTest.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * 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.plugins.ws; - -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.sonar.api.server.ws.Request; -import org.sonar.api.server.ws.WebService; -import org.sonar.core.permission.GlobalPermissions; -import org.sonar.server.exceptions.ForbiddenException; -import org.sonar.server.plugins.PluginDownloader; -import org.sonar.server.plugins.ServerPluginRepository; -import org.sonar.server.tester.UserSessionRule; -import org.sonar.server.ws.WsTester; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -public class CancelAllPluginsWsActionTest { - private static final String DUMMY_CONTROLLER_KEY = "dummy"; - - @Rule - public UserSessionRule userSessionRule = UserSessionRule.standalone().setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN); - - private PluginDownloader pluginDownloader = mock(PluginDownloader.class); - private ServerPluginRepository pluginRepository = mock(ServerPluginRepository.class); - private CancelAllPluginsWsAction underTest = new CancelAllPluginsWsAction(pluginDownloader, pluginRepository, userSessionRule); - - private Request request = mock(Request.class); - private WsTester.TestResponse response = new WsTester.TestResponse(); - - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - @Test - public void action_cancel_all_is_defined() { - WsTester wsTester = new WsTester(); - WebService.NewController newController = wsTester.context().createController(DUMMY_CONTROLLER_KEY); - - underTest.define(newController); - newController.done(); - - WebService.Controller controller = wsTester.controller(DUMMY_CONTROLLER_KEY); - assertThat(controller.actions()).extracting("key").containsExactly("cancel_all"); - - WebService.Action action = controller.actions().iterator().next(); - assertThat(action.isPost()).isTrue(); - assertThat(action.description()).isNotEmpty(); - assertThat(action.responseExample()).isNull(); - - assertThat(action.params()).isEmpty(); - } - - @Test - public void user_must_have_system_admin_permission() throws Exception { - expectedException.expect(ForbiddenException.class); - expectedException.expectMessage("Insufficient privileges"); - - // no permission on user - userSessionRule.setGlobalPermissions(); - - underTest.handle(request, response); - } - - @Test - public void triggers_cancel_for_downloads_and_uninstalls() throws Exception { - underTest.handle(request, response); - - verify(pluginDownloader, times(1)).cancelDownloads(); - verify(pluginRepository, times(1)).cancelUninstalls(); - assertThat(response.outputAsString()).isEmpty(); - } - -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/InstallActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/InstallActionTest.java new file mode 100644 index 00000000000..6cac3de746d --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/InstallActionTest.java @@ -0,0 +1,138 @@ +/* + * 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.plugins.ws; + +import com.google.common.collect.ImmutableList; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.sonar.api.server.ws.WebService; +import org.sonar.core.permission.GlobalPermissions; +import org.sonar.server.exceptions.ForbiddenException; +import org.sonar.server.plugins.PluginDownloader; +import org.sonar.server.plugins.UpdateCenterMatrixFactory; +import org.sonar.server.tester.UserSessionRule; +import org.sonar.server.ws.WsTester; +import org.sonar.updatecenter.common.Plugin; +import org.sonar.updatecenter.common.PluginUpdate; +import org.sonar.updatecenter.common.Release; +import org.sonar.updatecenter.common.UpdateCenter; +import org.sonar.updatecenter.common.Version; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Matchers.anyBoolean; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +public class InstallActionTest { + private static final String DUMMY_CONTROLLER_KEY = "dummy"; + private static final String CONTROLLER_KEY = "api/plugins"; + private static final String ACTION_KEY = "install"; + private static final String KEY_PARAM = "key"; + private static final String PLUGIN_KEY = "pluginKey"; + + @Rule + public UserSessionRule userSessionRule = UserSessionRule.standalone(); + + private UpdateCenterMatrixFactory updateCenterFactory = mock(UpdateCenterMatrixFactory.class); + private UpdateCenter updateCenter = mock(UpdateCenter.class); + private PluginDownloader pluginDownloader = mock(PluginDownloader.class); + private InstallAction underTest = new InstallAction(updateCenterFactory, pluginDownloader, userSessionRule); + + private WsTester wsTester = new WsTester(new PluginsWs(underTest)); + private WsTester.TestRequest invalidRequest = wsTester.newPostRequest(CONTROLLER_KEY, ACTION_KEY); + private WsTester.TestRequest validRequest = wsTester.newPostRequest(CONTROLLER_KEY, ACTION_KEY) + .setParam(KEY_PARAM, PLUGIN_KEY); + + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + @Before + public void wireMocks() { + when(updateCenterFactory.getUpdateCenter(anyBoolean())).thenReturn(updateCenter); + + userSessionRule.setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN); + } + + @Test + public void user_must_have_system_admin_permission() throws Exception { + expectedException.expect(ForbiddenException.class); + expectedException.expectMessage("Insufficient privileges"); + + // no permission on user + userSessionRule.setGlobalPermissions(); + + validRequest.execute(); + } + + @Test + public void action_install_is_defined() { + WsTester wsTester = new WsTester(); + WebService.NewController newController = wsTester.context().createController(DUMMY_CONTROLLER_KEY); + + underTest.define(newController); + newController.done(); + + WebService.Controller controller = wsTester.controller(DUMMY_CONTROLLER_KEY); + assertThat(controller.actions()).extracting("key").containsExactly(ACTION_KEY); + + WebService.Action action = controller.actions().iterator().next(); + assertThat(action.isPost()).isTrue(); + assertThat(action.description()).isNotEmpty(); + assertThat(action.responseExample()).isNull(); + + assertThat(action.params()).hasSize(1); + WebService.Param keyParam = action.param(KEY_PARAM); + assertThat(keyParam).isNotNull(); + assertThat(keyParam.isRequired()).isTrue(); + assertThat(keyParam.description()).isNotNull(); + } + + @Test + public void IAE_is_raised_when_key_param_is_not_provided() throws Exception { + expectedException.expect(IllegalArgumentException.class); + expectedException.expectMessage("Parameter 'key' is missing"); + + invalidRequest.execute(); + } + + @Test + public void IAE_is_raised_when_there_is_no_available_plugin_for_the_key() throws Exception { + expectedException.expect(IllegalArgumentException.class); + expectedException.expectMessage("No plugin with key 'pluginKey'"); + + validRequest.execute(); + } + + @Test + public void if_plugin_is_found_available_download_is_triggered_with_latest_version_from_updatecenter() throws Exception { + Version version = Version.create("1.0"); + when(updateCenter.findAvailablePlugins()).thenReturn(ImmutableList.of( + PluginUpdate.createWithStatus(new Release(new Plugin(PLUGIN_KEY), version), PluginUpdate.Status.COMPATIBLE) + )); + + WsTester.Result result = validRequest.execute(); + + verify(pluginDownloader).download(PLUGIN_KEY, version); + result.assertNoContent(); + } +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/InstallPluginsWsActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/InstallPluginsWsActionTest.java deleted file mode 100644 index 1be07a38451..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/InstallPluginsWsActionTest.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * 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.plugins.ws; - -import com.google.common.collect.ImmutableList; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.sonar.api.server.ws.WebService; -import org.sonar.core.permission.GlobalPermissions; -import org.sonar.server.exceptions.ForbiddenException; -import org.sonar.server.plugins.PluginDownloader; -import org.sonar.server.plugins.UpdateCenterMatrixFactory; -import org.sonar.server.tester.UserSessionRule; -import org.sonar.server.ws.WsTester; -import org.sonar.updatecenter.common.Plugin; -import org.sonar.updatecenter.common.PluginUpdate; -import org.sonar.updatecenter.common.Release; -import org.sonar.updatecenter.common.UpdateCenter; -import org.sonar.updatecenter.common.Version; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Matchers.anyBoolean; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class InstallPluginsWsActionTest { - private static final String DUMMY_CONTROLLER_KEY = "dummy"; - private static final String CONTROLLER_KEY = "api/plugins"; - private static final String ACTION_KEY = "install"; - private static final String KEY_PARAM = "key"; - private static final String PLUGIN_KEY = "pluginKey"; - - @Rule - public UserSessionRule userSessionRule = UserSessionRule.standalone(); - - private UpdateCenterMatrixFactory updateCenterFactory = mock(UpdateCenterMatrixFactory.class); - private UpdateCenter updateCenter = mock(UpdateCenter.class); - private PluginDownloader pluginDownloader = mock(PluginDownloader.class); - private InstallPluginsWsAction underTest = new InstallPluginsWsAction(updateCenterFactory, pluginDownloader, userSessionRule); - - private WsTester wsTester = new WsTester(new PluginsWs(underTest)); - private WsTester.TestRequest invalidRequest = wsTester.newPostRequest(CONTROLLER_KEY, ACTION_KEY); - private WsTester.TestRequest validRequest = wsTester.newPostRequest(CONTROLLER_KEY, ACTION_KEY) - .setParam(KEY_PARAM, PLUGIN_KEY); - - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - @Before - public void wireMocks() { - when(updateCenterFactory.getUpdateCenter(anyBoolean())).thenReturn(updateCenter); - - userSessionRule.setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN); - } - - @Test - public void user_must_have_system_admin_permission() throws Exception { - expectedException.expect(ForbiddenException.class); - expectedException.expectMessage("Insufficient privileges"); - - // no permission on user - userSessionRule.setGlobalPermissions(); - - validRequest.execute(); - } - - @Test - public void action_install_is_defined() { - WsTester wsTester = new WsTester(); - WebService.NewController newController = wsTester.context().createController(DUMMY_CONTROLLER_KEY); - - underTest.define(newController); - newController.done(); - - WebService.Controller controller = wsTester.controller(DUMMY_CONTROLLER_KEY); - assertThat(controller.actions()).extracting("key").containsExactly(ACTION_KEY); - - WebService.Action action = controller.actions().iterator().next(); - assertThat(action.isPost()).isTrue(); - assertThat(action.description()).isNotEmpty(); - assertThat(action.responseExample()).isNull(); - - assertThat(action.params()).hasSize(1); - WebService.Param keyParam = action.param(KEY_PARAM); - assertThat(keyParam).isNotNull(); - assertThat(keyParam.isRequired()).isTrue(); - assertThat(keyParam.description()).isNotNull(); - } - - @Test - public void IAE_is_raised_when_key_param_is_not_provided() throws Exception { - expectedException.expect(IllegalArgumentException.class); - expectedException.expectMessage("Parameter 'key' is missing"); - - invalidRequest.execute(); - } - - @Test - public void IAE_is_raised_when_there_is_no_available_plugin_for_the_key() throws Exception { - expectedException.expect(IllegalArgumentException.class); - expectedException.expectMessage("No plugin with key 'pluginKey'"); - - validRequest.execute(); - } - - @Test - public void if_plugin_is_found_available_download_is_triggered_with_latest_version_from_updatecenter() throws Exception { - Version version = Version.create("1.0"); - when(updateCenter.findAvailablePlugins()).thenReturn(ImmutableList.of( - PluginUpdate.createWithStatus(new Release(new Plugin(PLUGIN_KEY), version), PluginUpdate.Status.COMPATIBLE) - )); - - WsTester.Result result = validRequest.execute(); - - verify(pluginDownloader).download(PLUGIN_KEY, version); - result.assertNoContent(); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/InstalledActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/InstalledActionTest.java new file mode 100644 index 00000000000..15d405ccfa7 --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/InstalledActionTest.java @@ -0,0 +1,199 @@ +/* + * 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.plugins.ws; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.sonar.api.server.ws.Request; +import org.sonar.api.server.ws.WebService; +import org.sonar.core.platform.PluginInfo; +import org.sonar.server.plugins.ServerPluginRepository; +import org.sonar.server.ws.WsTester; +import org.sonar.updatecenter.common.Version; + +import java.io.File; + +import static com.google.common.collect.ImmutableList.of; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.sonar.test.JsonAssert.assertJson; + +public class InstalledActionTest { + private static final String DUMMY_CONTROLLER_KEY = "dummy"; + private static final String JSON_EMPTY_PLUGIN_LIST = + "{" + + " \"plugins\":" + "[]" + + "}"; + + @Rule + public TemporaryFolder temp = new TemporaryFolder(); + + private ServerPluginRepository pluginRepository = mock(ServerPluginRepository.class); + private InstalledAction underTest = new InstalledAction(pluginRepository, new PluginWSCommons()); + + private Request request = mock(Request.class); + private WsTester.TestResponse response = new WsTester.TestResponse(); + + @Test + public void action_installed_is_defined() { + WsTester wsTester = new WsTester(); + WebService.NewController newController = wsTester.context().createController(DUMMY_CONTROLLER_KEY); + + underTest.define(newController); + newController.done(); + + WebService.Controller controller = wsTester.controller(DUMMY_CONTROLLER_KEY); + assertThat(controller.actions()).extracting("key").containsExactly("installed"); + + WebService.Action action = controller.actions().iterator().next(); + assertThat(action.isPost()).isFalse(); + assertThat(action.description()).isNotEmpty(); + assertThat(action.responseExample()).isNotNull(); + } + + @Test + public void empty_array_is_returned_when_there_is_not_plugin_installed() throws Exception { + underTest.handle(request, response); + + assertJson(response.outputAsString()).setStrictArrayOrder(true).isSimilarTo(JSON_EMPTY_PLUGIN_LIST); + } + + @Test + public void core_plugin_are_not_returned() throws Exception { + when(pluginRepository.getPluginInfos()).thenReturn(of(corePlugin("core1", "1.0"))); + + underTest.handle(request, response); + + assertJson(response.outputAsString()).setStrictArrayOrder(true).isSimilarTo(JSON_EMPTY_PLUGIN_LIST); + } + + @Test + public void empty_fields_are_not_serialized_to_json() throws Exception { + when(pluginRepository.getPluginInfos()).thenReturn( + of( + new PluginInfo("").setName("").setCore(false) + ) + ); + + underTest.handle(request, response); + + assertThat(response.outputAsString()).doesNotContain("name").doesNotContain("key"); + } + + @Test + public void verify_properties_displayed_in_json_per_plugin() throws Exception { + String jarFilename = getClass().getSimpleName() + "/" + "some.jar"; + when(pluginRepository.getPluginInfos()).thenReturn(of( + new PluginInfo("plugKey") + .setName("plugName") + .setCore(false) + .setDescription("desc_it") + .setVersion(Version.create("1.0")) + .setLicense("license_hey") + .setOrganizationName("org_name") + .setOrganizationUrl("org_url") + .setHomepageUrl("homepage_url") + .setIssueTrackerUrl("issueTracker_url") + .setImplementationBuild("sou_rev_sha1") + .setJarFile(new File(getClass().getResource(jarFilename).toURI())) + ) + ); + + underTest.handle(request, response); + + assertJson(response.outputAsString()).isSimilarTo( + "{" + + " \"plugins\":" + + " [" + + " {" + + " \"key\": \"plugKey\"," + + " \"name\": \"plugName\"," + + " \"description\": \"desc_it\"," + + " \"version\": \"1.0\"," + + " \"license\": \"license_hey\"," + + " \"organizationName\": \"org_name\"," + + " \"organizationUrl\": \"org_url\"," + + " \"homepageUrl\": \"homepage_url\"," + + " \"issueTrackerUrl\": \"issueTracker_url\"," + + " \"implementationBuild\": \"sou_rev_sha1\"" + + " }" + + " ]" + + "}" + ); + } + + @Test + public void plugins_are_sorted_by_name_then_key_and_only_one_plugin_can_have_a_specific_name() throws Exception { + when(pluginRepository.getPluginInfos()).thenReturn( + of( + plugin("A", "name2"), + plugin("B", "name1"), + plugin("C", "name0"), + plugin("D", "name0") + ) + ); + + underTest.handle(request, response); + + assertJson(response.outputAsString()).setStrictArrayOrder(true).isSimilarTo( + "{" + + " \"plugins\":" + + " [" + + " {\"key\": \"C\"}" + "," + + " {\"key\": \"D\"}" + "," + + " {\"key\": \"B\"}" + "," + + " {\"key\": \"A\"}" + + " ]" + + "}" + ); + } + + @Test + public void only_one_plugin_can_have_a_specific_name_and_key() throws Exception { + when(pluginRepository.getPluginInfos()).thenReturn( + of( + plugin("A", "name2"), + plugin("A", "name2") + ) + ); + + underTest.handle(request, response); + + assertJson(response.outputAsString()).setStrictArrayOrder(true).isSimilarTo( + "{" + + " \"plugins\":" + + " [" + + " {\"key\": \"A\"}" + + " ]" + + "}" + ); + assertThat(response.outputAsString()).containsOnlyOnce("name2"); + } + + private PluginInfo corePlugin(String key, String version) { + return new PluginInfo(key).setName(key).setCore(true).setVersion(Version.create(version)); + } + + private PluginInfo plugin(String key, String name) { + return new PluginInfo(key).setName(name).setCore(false).setVersion(Version.create("1.0")); + } +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/InstalledPluginsWsActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/InstalledPluginsWsActionTest.java deleted file mode 100644 index ab79848ff97..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/InstalledPluginsWsActionTest.java +++ /dev/null @@ -1,199 +0,0 @@ -/* - * 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.plugins.ws; - -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TemporaryFolder; -import org.sonar.api.server.ws.Request; -import org.sonar.api.server.ws.WebService; -import org.sonar.core.platform.PluginInfo; -import org.sonar.server.plugins.ServerPluginRepository; -import org.sonar.server.ws.WsTester; -import org.sonar.updatecenter.common.Version; - -import java.io.File; - -import static com.google.common.collect.ImmutableList.of; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; -import static org.sonar.test.JsonAssert.assertJson; - -public class InstalledPluginsWsActionTest { - private static final String DUMMY_CONTROLLER_KEY = "dummy"; - private static final String JSON_EMPTY_PLUGIN_LIST = - "{" + - " \"plugins\":" + "[]" + - "}"; - - @Rule - public TemporaryFolder temp = new TemporaryFolder(); - - private ServerPluginRepository pluginRepository = mock(ServerPluginRepository.class); - private InstalledPluginsWsAction underTest = new InstalledPluginsWsAction(pluginRepository, new PluginWSCommons()); - - private Request request = mock(Request.class); - private WsTester.TestResponse response = new WsTester.TestResponse(); - - @Test - public void action_installed_is_defined() { - WsTester wsTester = new WsTester(); - WebService.NewController newController = wsTester.context().createController(DUMMY_CONTROLLER_KEY); - - underTest.define(newController); - newController.done(); - - WebService.Controller controller = wsTester.controller(DUMMY_CONTROLLER_KEY); - assertThat(controller.actions()).extracting("key").containsExactly("installed"); - - WebService.Action action = controller.actions().iterator().next(); - assertThat(action.isPost()).isFalse(); - assertThat(action.description()).isNotEmpty(); - assertThat(action.responseExample()).isNotNull(); - } - - @Test - public void empty_array_is_returned_when_there_is_not_plugin_installed() throws Exception { - underTest.handle(request, response); - - assertJson(response.outputAsString()).setStrictArrayOrder(true).isSimilarTo(JSON_EMPTY_PLUGIN_LIST); - } - - @Test - public void core_plugin_are_not_returned() throws Exception { - when(pluginRepository.getPluginInfos()).thenReturn(of(corePlugin("core1", "1.0"))); - - underTest.handle(request, response); - - assertJson(response.outputAsString()).setStrictArrayOrder(true).isSimilarTo(JSON_EMPTY_PLUGIN_LIST); - } - - @Test - public void empty_fields_are_not_serialized_to_json() throws Exception { - when(pluginRepository.getPluginInfos()).thenReturn( - of( - new PluginInfo("").setName("").setCore(false) - ) - ); - - underTest.handle(request, response); - - assertThat(response.outputAsString()).doesNotContain("name").doesNotContain("key"); - } - - @Test - public void verify_properties_displayed_in_json_per_plugin() throws Exception { - String jarFilename = getClass().getSimpleName() + "/" + "some.jar"; - when(pluginRepository.getPluginInfos()).thenReturn(of( - new PluginInfo("plugKey") - .setName("plugName") - .setCore(false) - .setDescription("desc_it") - .setVersion(Version.create("1.0")) - .setLicense("license_hey") - .setOrganizationName("org_name") - .setOrganizationUrl("org_url") - .setHomepageUrl("homepage_url") - .setIssueTrackerUrl("issueTracker_url") - .setImplementationBuild("sou_rev_sha1") - .setJarFile(new File(getClass().getResource(jarFilename).toURI())) - ) - ); - - underTest.handle(request, response); - - assertJson(response.outputAsString()).isSimilarTo( - "{" + - " \"plugins\":" + - " [" + - " {" + - " \"key\": \"plugKey\"," + - " \"name\": \"plugName\"," + - " \"description\": \"desc_it\"," + - " \"version\": \"1.0\"," + - " \"license\": \"license_hey\"," + - " \"organizationName\": \"org_name\"," + - " \"organizationUrl\": \"org_url\"," + - " \"homepageUrl\": \"homepage_url\"," + - " \"issueTrackerUrl\": \"issueTracker_url\"," + - " \"implementationBuild\": \"sou_rev_sha1\"" + - " }" + - " ]" + - "}" - ); - } - - @Test - public void plugins_are_sorted_by_name_then_key_and_only_one_plugin_can_have_a_specific_name() throws Exception { - when(pluginRepository.getPluginInfos()).thenReturn( - of( - plugin("A", "name2"), - plugin("B", "name1"), - plugin("C", "name0"), - plugin("D", "name0") - ) - ); - - underTest.handle(request, response); - - assertJson(response.outputAsString()).setStrictArrayOrder(true).isSimilarTo( - "{" + - " \"plugins\":" + - " [" + - " {\"key\": \"C\"}" + "," + - " {\"key\": \"D\"}" + "," + - " {\"key\": \"B\"}" + "," + - " {\"key\": \"A\"}" + - " ]" + - "}" - ); - } - - @Test - public void only_one_plugin_can_have_a_specific_name_and_key() throws Exception { - when(pluginRepository.getPluginInfos()).thenReturn( - of( - plugin("A", "name2"), - plugin("A", "name2") - ) - ); - - underTest.handle(request, response); - - assertJson(response.outputAsString()).setStrictArrayOrder(true).isSimilarTo( - "{" + - " \"plugins\":" + - " [" + - " {\"key\": \"A\"}" + - " ]" + - "}" - ); - assertThat(response.outputAsString()).containsOnlyOnce("name2"); - } - - private PluginInfo corePlugin(String key, String version) { - return new PluginInfo(key).setName(key).setCore(true).setVersion(Version.create(version)); - } - - private PluginInfo plugin(String key, String name) { - return new PluginInfo(key).setName(name).setCore(false).setVersion(Version.create("1.0")); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/PendingActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/PendingActionTest.java new file mode 100644 index 00000000000..a9620d490c6 --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/PendingActionTest.java @@ -0,0 +1,212 @@ +/* + * 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.plugins.ws; + +import org.junit.Test; +import org.sonar.api.server.ws.Request; +import org.sonar.api.server.ws.WebService; +import org.sonar.core.platform.PluginInfo; +import org.sonar.server.plugins.PluginDownloader; +import org.sonar.server.plugins.ServerPluginRepository; +import org.sonar.server.ws.WsTester; +import org.sonar.updatecenter.common.Version; + +import static com.google.common.collect.ImmutableList.of; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.sonar.test.JsonAssert.assertJson; + +public class PendingActionTest { + + private static final String DUMMY_CONTROLLER_KEY = "dummy"; + + PluginDownloader pluginDownloader = mock(PluginDownloader.class); + ServerPluginRepository serverPluginRepository = mock(ServerPluginRepository.class); + PendingAction underTest = new PendingAction(pluginDownloader, serverPluginRepository, new PluginWSCommons()); + Request request = mock(Request.class); + WsTester.TestResponse response = new WsTester.TestResponse(); + + @Test + public void action_pending_is_defined() { + WsTester wsTester = new WsTester(); + WebService.NewController newController = wsTester.context().createController(DUMMY_CONTROLLER_KEY); + + underTest.define(newController); + newController.done(); + + WebService.Controller controller = wsTester.controller(DUMMY_CONTROLLER_KEY); + assertThat(controller.actions()).extracting("key").containsExactly("pending"); + + WebService.Action action = controller.actions().iterator().next(); + assertThat(action.isPost()).isFalse(); + assertThat(action.description()).isNotEmpty(); + assertThat(action.responseExample()).isNotNull(); + } + + @Test + public void empty_arrays_are_returned_when_there_nothing_pending() throws Exception { + underTest.handle(request, response); + + assertJson(response.outputAsString()).setStrictArrayOrder(true).isSimilarTo( + "{" + + " \"installing\": []," + + " \"removing\": []" + + "}" + ); + } + + @Test + public void verify_properties_displayed_in_json_per_installing_plugin() throws Exception { + when(pluginDownloader.getDownloadedPlugins()).thenReturn(of(gitPluginInfo())); + + underTest.handle(request, response); + + assertJson(response.outputAsString()).isSimilarTo( + "{" + + " \"installing\": " + + " [" + + " {" + + " \"key\": \"scmgit\"," + + " \"name\": \"Git\"," + + " \"description\": \"Git SCM Provider.\"," + + " \"version\": \"1.0\"," + + " \"license\": \"GNU LGPL 3\"," + + " \"organizationName\": \"SonarSource\"," + + " \"organizationUrl\": \"http://www.sonarsource.com\"," + + " \"homepageUrl\": \"http://redirect.sonarsource.com/plugins/scmgit.html\"," + + " \"issueTrackerUrl\": \"http://jira.codehaus.org/browse/SONARSCGIT\"," + + " \"implementationBuild\": \"9ce9d330c313c296fab051317cc5ad4b26319e07\"" + + " }" + + " ]," + + " \"removing\": []" + + "}" + ); + } + + @Test + public void verify_properties_displayed_in_json_per_removing_plugin() throws Exception { + when(serverPluginRepository.getUninstalledPlugins()).thenReturn(of(gitPluginInfo())); + + underTest.handle(request, response); + + assertJson(response.outputAsString()).isSimilarTo( + "{" + + " \"installing\": []," + + " \"removing\": " + + " [" + + " {" + + " \"key\": \"scmgit\"," + + " \"name\": \"Git\"," + + " \"description\": \"Git SCM Provider.\"," + + " \"version\": \"1.0\"," + + " \"license\": \"GNU LGPL 3\"," + + " \"organizationName\": \"SonarSource\"," + + " \"organizationUrl\": \"http://www.sonarsource.com\"," + + " \"homepageUrl\": \"http://redirect.sonarsource.com/plugins/scmgit.html\"," + + " \"issueTrackerUrl\": \"http://jira.codehaus.org/browse/SONARSCGIT\"," + + " \"implementationBuild\": \"9ce9d330c313c296fab051317cc5ad4b26319e07\"" + + " }" + + " ]" + + "}" + ); + } + + @Test + public void installing_plugins_are_sorted_by_name_then_key_and_are_unique() throws Exception { + when(pluginDownloader.getDownloadedPlugins()).thenReturn(of( + newPluginInfo(0).setName("Foo"), + newPluginInfo(3).setName("Bar"), + newPluginInfo(2).setName("Bar") + )); + + underTest.handle(request, response); + + assertJson(response.outputAsString()).setStrictArrayOrder(true).isSimilarTo( + "{" + + " \"installing\": " + + " [" + + " {" + + " \"key\": \"key2\"," + + " \"name\": \"Bar\"," + + " }," + + " {" + + " \"key\": \"key3\"," + + " \"name\": \"Bar\"," + + " }," + + " {" + + " \"key\": \"key0\"," + + " \"name\": \"Foo\"," + + " }" + + " ]," + + " \"removing\": []" + + "}" + ); + } + + @Test + public void removing_plugins_are_sorted_and_unique() throws Exception { + when(serverPluginRepository.getUninstalledPlugins()).thenReturn(of( + newPluginInfo(0).setName("Foo"), + newPluginInfo(3).setName("Bar"), + newPluginInfo(2).setName("Bar") + )); + + underTest.handle(request, response); + + assertJson(response.outputAsString()).setStrictArrayOrder(true).isSimilarTo( + "{" + + " \"installing\": []," + + " \"removing\": " + + " [" + + " {" + + " \"key\": \"key2\"," + + " \"name\": \"Bar\"," + + " }," + + " {" + + " \"key\": \"key3\"," + + " \"name\": \"Bar\"," + + " }," + + " {" + + " \"key\": \"key0\"," + + " \"name\": \"Foo\"," + + " }" + + " ]" + + "}" + ); + } + + public PluginInfo gitPluginInfo() { + return new PluginInfo("scmgit") + .setName("Git") + .setDescription("Git SCM Provider.") + .setVersion(Version.create("1.0")) + .setLicense("GNU LGPL 3") + .setOrganizationName("SonarSource") + .setOrganizationUrl("http://www.sonarsource.com") + .setHomepageUrl("http://redirect.sonarsource.com/plugins/scmgit.html") + .setIssueTrackerUrl("http://jira.codehaus.org/browse/SONARSCGIT") + .setImplementationBuild("9ce9d330c313c296fab051317cc5ad4b26319e07"); + } + + public PluginInfo newPluginInfo(int id) { + return new PluginInfo("key" + id).setName("name" + id); + } +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/PendingPluginsWsActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/PendingPluginsWsActionTest.java deleted file mode 100644 index 56cd9e86cbf..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/PendingPluginsWsActionTest.java +++ /dev/null @@ -1,212 +0,0 @@ -/* - * 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.plugins.ws; - -import org.junit.Test; -import org.sonar.api.server.ws.Request; -import org.sonar.api.server.ws.WebService; -import org.sonar.core.platform.PluginInfo; -import org.sonar.server.plugins.PluginDownloader; -import org.sonar.server.plugins.ServerPluginRepository; -import org.sonar.server.ws.WsTester; -import org.sonar.updatecenter.common.Version; - -import static com.google.common.collect.ImmutableList.of; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; -import static org.sonar.test.JsonAssert.assertJson; - -public class PendingPluginsWsActionTest { - - private static final String DUMMY_CONTROLLER_KEY = "dummy"; - - PluginDownloader pluginDownloader = mock(PluginDownloader.class); - ServerPluginRepository serverPluginRepository = mock(ServerPluginRepository.class); - PendingPluginsWsAction underTest = new PendingPluginsWsAction(pluginDownloader, serverPluginRepository, new PluginWSCommons()); - Request request = mock(Request.class); - WsTester.TestResponse response = new WsTester.TestResponse(); - - @Test - public void action_pending_is_defined() { - WsTester wsTester = new WsTester(); - WebService.NewController newController = wsTester.context().createController(DUMMY_CONTROLLER_KEY); - - underTest.define(newController); - newController.done(); - - WebService.Controller controller = wsTester.controller(DUMMY_CONTROLLER_KEY); - assertThat(controller.actions()).extracting("key").containsExactly("pending"); - - WebService.Action action = controller.actions().iterator().next(); - assertThat(action.isPost()).isFalse(); - assertThat(action.description()).isNotEmpty(); - assertThat(action.responseExample()).isNotNull(); - } - - @Test - public void empty_arrays_are_returned_when_there_nothing_pending() throws Exception { - underTest.handle(request, response); - - assertJson(response.outputAsString()).setStrictArrayOrder(true).isSimilarTo( - "{" + - " \"installing\": []," + - " \"removing\": []" + - "}" - ); - } - - @Test - public void verify_properties_displayed_in_json_per_installing_plugin() throws Exception { - when(pluginDownloader.getDownloadedPlugins()).thenReturn(of(gitPluginInfo())); - - underTest.handle(request, response); - - assertJson(response.outputAsString()).isSimilarTo( - "{" + - " \"installing\": " + - " [" + - " {" + - " \"key\": \"scmgit\"," + - " \"name\": \"Git\"," + - " \"description\": \"Git SCM Provider.\"," + - " \"version\": \"1.0\"," + - " \"license\": \"GNU LGPL 3\"," + - " \"organizationName\": \"SonarSource\"," + - " \"organizationUrl\": \"http://www.sonarsource.com\"," + - " \"homepageUrl\": \"http://redirect.sonarsource.com/plugins/scmgit.html\"," + - " \"issueTrackerUrl\": \"http://jira.codehaus.org/browse/SONARSCGIT\"," + - " \"implementationBuild\": \"9ce9d330c313c296fab051317cc5ad4b26319e07\"" + - " }" + - " ]," + - " \"removing\": []" + - "}" - ); - } - - @Test - public void verify_properties_displayed_in_json_per_removing_plugin() throws Exception { - when(serverPluginRepository.getUninstalledPlugins()).thenReturn(of(gitPluginInfo())); - - underTest.handle(request, response); - - assertJson(response.outputAsString()).isSimilarTo( - "{" + - " \"installing\": []," + - " \"removing\": " + - " [" + - " {" + - " \"key\": \"scmgit\"," + - " \"name\": \"Git\"," + - " \"description\": \"Git SCM Provider.\"," + - " \"version\": \"1.0\"," + - " \"license\": \"GNU LGPL 3\"," + - " \"organizationName\": \"SonarSource\"," + - " \"organizationUrl\": \"http://www.sonarsource.com\"," + - " \"homepageUrl\": \"http://redirect.sonarsource.com/plugins/scmgit.html\"," + - " \"issueTrackerUrl\": \"http://jira.codehaus.org/browse/SONARSCGIT\"," + - " \"implementationBuild\": \"9ce9d330c313c296fab051317cc5ad4b26319e07\"" + - " }" + - " ]" + - "}" - ); - } - - @Test - public void installing_plugins_are_sorted_by_name_then_key_and_are_unique() throws Exception { - when(pluginDownloader.getDownloadedPlugins()).thenReturn(of( - newPluginInfo(0).setName("Foo"), - newPluginInfo(3).setName("Bar"), - newPluginInfo(2).setName("Bar") - )); - - underTest.handle(request, response); - - assertJson(response.outputAsString()).setStrictArrayOrder(true).isSimilarTo( - "{" + - " \"installing\": " + - " [" + - " {" + - " \"key\": \"key2\"," + - " \"name\": \"Bar\"," + - " }," + - " {" + - " \"key\": \"key3\"," + - " \"name\": \"Bar\"," + - " }," + - " {" + - " \"key\": \"key0\"," + - " \"name\": \"Foo\"," + - " }" + - " ]," + - " \"removing\": []" + - "}" - ); - } - - @Test - public void removing_plugins_are_sorted_and_unique() throws Exception { - when(serverPluginRepository.getUninstalledPlugins()).thenReturn(of( - newPluginInfo(0).setName("Foo"), - newPluginInfo(3).setName("Bar"), - newPluginInfo(2).setName("Bar") - )); - - underTest.handle(request, response); - - assertJson(response.outputAsString()).setStrictArrayOrder(true).isSimilarTo( - "{" + - " \"installing\": []," + - " \"removing\": " + - " [" + - " {" + - " \"key\": \"key2\"," + - " \"name\": \"Bar\"," + - " }," + - " {" + - " \"key\": \"key3\"," + - " \"name\": \"Bar\"," + - " }," + - " {" + - " \"key\": \"key0\"," + - " \"name\": \"Foo\"," + - " }" + - " ]" + - "}" - ); - } - - public PluginInfo gitPluginInfo() { - return new PluginInfo("scmgit") - .setName("Git") - .setDescription("Git SCM Provider.") - .setVersion(Version.create("1.0")) - .setLicense("GNU LGPL 3") - .setOrganizationName("SonarSource") - .setOrganizationUrl("http://www.sonarsource.com") - .setHomepageUrl("http://redirect.sonarsource.com/plugins/scmgit.html") - .setIssueTrackerUrl("http://jira.codehaus.org/browse/SONARSCGIT") - .setImplementationBuild("9ce9d330c313c296fab051317cc5ad4b26319e07"); - } - - public PluginInfo newPluginInfo(int id) { - return new PluginInfo("key" + id).setName("name" + id); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/UninstallActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/UninstallActionTest.java new file mode 100644 index 00000000000..4bf85e00f1b --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/UninstallActionTest.java @@ -0,0 +1,118 @@ +/* + * 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.plugins.ws; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.sonar.api.server.ws.Request; +import org.sonar.api.server.ws.WebService; +import org.sonar.core.permission.GlobalPermissions; +import org.sonar.server.exceptions.ForbiddenException; +import org.sonar.server.plugins.ServerPluginRepository; +import org.sonar.server.tester.UserSessionRule; +import org.sonar.server.ws.WsTester; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +public class UninstallActionTest { + private static final String DUMMY_CONTROLLER_KEY = "dummy"; + private static final String CONTROLLER_KEY = "api/plugins"; + private static final String ACTION_KEY = "uninstall"; + private static final String KEY_PARAM = "key"; + private static final String PLUGIN_KEY = "findbugs"; + + @Rule + public UserSessionRule userSessionRule = UserSessionRule.standalone().setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN); + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + private ServerPluginRepository pluginRepository = mock(ServerPluginRepository.class); + private UninstallAction underTest = new UninstallAction(pluginRepository, userSessionRule); + + private WsTester wsTester = new WsTester(new PluginsWs(underTest)); + private Request invalidRequest = wsTester.newGetRequest(CONTROLLER_KEY, ACTION_KEY); + private Request validRequest = wsTester.newGetRequest(CONTROLLER_KEY, ACTION_KEY).setParam(KEY_PARAM, PLUGIN_KEY); + private WsTester.TestResponse response = new WsTester.TestResponse(); + + @Test + public void user_must_have_system_admin_permission() throws Exception { + expectedException.expect(ForbiddenException.class); + expectedException.expectMessage("Insufficient privileges"); + + // no permission on user + userSessionRule.setGlobalPermissions(); + + underTest.handle(validRequest, response); + } + + @Test + public void action_uninstall_is_defined() { + WsTester wsTester = new WsTester(); + WebService.NewController newController = wsTester.context().createController(DUMMY_CONTROLLER_KEY); + + underTest.define(newController); + newController.done(); + + WebService.Controller controller = wsTester.controller(DUMMY_CONTROLLER_KEY); + assertThat(controller.actions()).extracting("key").containsExactly(ACTION_KEY); + + WebService.Action action = controller.actions().iterator().next(); + assertThat(action.isPost()).isTrue(); + assertThat(action.description()).isNotEmpty(); + assertThat(action.responseExample()).isNull(); + + assertThat(action.params()).hasSize(1); + WebService.Param keyParam = action.param(KEY_PARAM); + assertThat(keyParam).isNotNull(); + assertThat(keyParam.isRequired()).isTrue(); + assertThat(keyParam.description()).isNotNull(); + } + + @Test + public void IAE_is_raised_when_key_param_is_not_provided() throws Exception { + expectedException.expect(IllegalArgumentException.class); + expectedException.expectMessage("Parameter 'key' is missing"); + + underTest.handle(invalidRequest, response); + } + + @Test + public void IAE_is_raised_when_plugin_is_not_installed() throws Exception { + expectedException.expect(IllegalArgumentException.class); + expectedException.expectMessage("Plugin [findbugs] is not installed"); + + underTest.handle(validRequest, response); + } + + @Test + public void if_plugin_is_installed_uninstallation_is_triggered() throws Exception { + when(pluginRepository.hasPlugin(PLUGIN_KEY)).thenReturn(true); + + underTest.handle(validRequest, response); + + verify(pluginRepository).uninstall(PLUGIN_KEY); + assertThat(response.outputAsString()).isEmpty(); + } + +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/UninstallPluginsWsActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/UninstallPluginsWsActionTest.java deleted file mode 100644 index 42f42aab246..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/UninstallPluginsWsActionTest.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * 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.plugins.ws; - -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.sonar.api.server.ws.Request; -import org.sonar.api.server.ws.WebService; -import org.sonar.core.permission.GlobalPermissions; -import org.sonar.server.exceptions.ForbiddenException; -import org.sonar.server.plugins.ServerPluginRepository; -import org.sonar.server.tester.UserSessionRule; -import org.sonar.server.ws.WsTester; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class UninstallPluginsWsActionTest { - private static final String DUMMY_CONTROLLER_KEY = "dummy"; - private static final String CONTROLLER_KEY = "api/plugins"; - private static final String ACTION_KEY = "uninstall"; - private static final String KEY_PARAM = "key"; - private static final String PLUGIN_KEY = "findbugs"; - - @Rule - public UserSessionRule userSessionRule = UserSessionRule.standalone().setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN); - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - private ServerPluginRepository pluginRepository = mock(ServerPluginRepository.class); - private UninstallPluginsWsAction underTest = new UninstallPluginsWsAction(pluginRepository, userSessionRule); - - private WsTester wsTester = new WsTester(new PluginsWs(underTest)); - private Request invalidRequest = wsTester.newGetRequest(CONTROLLER_KEY, ACTION_KEY); - private Request validRequest = wsTester.newGetRequest(CONTROLLER_KEY, ACTION_KEY).setParam(KEY_PARAM, PLUGIN_KEY); - private WsTester.TestResponse response = new WsTester.TestResponse(); - - @Test - public void user_must_have_system_admin_permission() throws Exception { - expectedException.expect(ForbiddenException.class); - expectedException.expectMessage("Insufficient privileges"); - - // no permission on user - userSessionRule.setGlobalPermissions(); - - underTest.handle(validRequest, response); - } - - @Test - public void action_uninstall_is_defined() { - WsTester wsTester = new WsTester(); - WebService.NewController newController = wsTester.context().createController(DUMMY_CONTROLLER_KEY); - - underTest.define(newController); - newController.done(); - - WebService.Controller controller = wsTester.controller(DUMMY_CONTROLLER_KEY); - assertThat(controller.actions()).extracting("key").containsExactly(ACTION_KEY); - - WebService.Action action = controller.actions().iterator().next(); - assertThat(action.isPost()).isTrue(); - assertThat(action.description()).isNotEmpty(); - assertThat(action.responseExample()).isNull(); - - assertThat(action.params()).hasSize(1); - WebService.Param keyParam = action.param(KEY_PARAM); - assertThat(keyParam).isNotNull(); - assertThat(keyParam.isRequired()).isTrue(); - assertThat(keyParam.description()).isNotNull(); - } - - @Test - public void IAE_is_raised_when_key_param_is_not_provided() throws Exception { - expectedException.expect(IllegalArgumentException.class); - expectedException.expectMessage("Parameter 'key' is missing"); - - underTest.handle(invalidRequest, response); - } - - @Test - public void IAE_is_raised_when_plugin_is_not_installed() throws Exception { - expectedException.expect(IllegalArgumentException.class); - expectedException.expectMessage("Plugin [findbugs] is not installed"); - - underTest.handle(validRequest, response); - } - - @Test - public void if_plugin_is_installed_uninstallation_is_triggered() throws Exception { - when(pluginRepository.hasPlugin(PLUGIN_KEY)).thenReturn(true); - - underTest.handle(validRequest, response); - - verify(pluginRepository).uninstall(PLUGIN_KEY); - assertThat(response.outputAsString()).isEmpty(); - } - -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/UpdateActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/UpdateActionTest.java new file mode 100644 index 00000000000..22c8ac0fc05 --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/UpdateActionTest.java @@ -0,0 +1,141 @@ +/* + * 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.plugins.ws; + +import com.google.common.collect.ImmutableList; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.sonar.api.server.ws.Request; +import org.sonar.api.server.ws.WebService; +import org.sonar.core.permission.GlobalPermissions; +import org.sonar.server.exceptions.ForbiddenException; +import org.sonar.server.plugins.PluginDownloader; +import org.sonar.server.plugins.UpdateCenterMatrixFactory; +import org.sonar.server.tester.UserSessionRule; +import org.sonar.server.ws.WsTester; +import org.sonar.updatecenter.common.Plugin; +import org.sonar.updatecenter.common.PluginUpdate; +import org.sonar.updatecenter.common.PluginUpdate.Status; +import org.sonar.updatecenter.common.Release; +import org.sonar.updatecenter.common.UpdateCenter; +import org.sonar.updatecenter.common.Version; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Matchers.anyBoolean; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +public class UpdateActionTest { + private static final String DUMMY_CONTROLLER_KEY = "dummy"; + private static final String CONTROLLER_KEY = "api/plugins"; + private static final String ACTION_KEY = "update"; + private static final String KEY_PARAM = "key"; + private static final String PLUGIN_KEY = "pluginKey"; + + @Rule + public UserSessionRule userSessionRule = UserSessionRule.standalone(); + + private UpdateCenterMatrixFactory updateCenterFactory = mock(UpdateCenterMatrixFactory.class); + private UpdateCenter updateCenter = mock(UpdateCenter.class); + private PluginDownloader pluginDownloader = mock(PluginDownloader.class); + private UpdateAction underTest = new UpdateAction(updateCenterFactory, pluginDownloader, userSessionRule); + + private WsTester wsTester = new WsTester(new PluginsWs(underTest)); + private Request invalidRequest = wsTester.newGetRequest(CONTROLLER_KEY, ACTION_KEY); + private Request validRequest = wsTester.newGetRequest(CONTROLLER_KEY, ACTION_KEY).setParam(KEY_PARAM, PLUGIN_KEY); + private WsTester.TestResponse response = new WsTester.TestResponse(); + + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + @Before + public void setUp() { + when(updateCenterFactory.getUpdateCenter(anyBoolean())).thenReturn(updateCenter); + + userSessionRule.setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN); + } + + @Test + public void user_must_have_system_admin_permission() throws Exception { + expectedException.expect(ForbiddenException.class); + expectedException.expectMessage("Insufficient privileges"); + + // no permission on user + userSessionRule.setGlobalPermissions(); + + underTest.handle(validRequest, response); + } + + @Test + public void action_update_is_defined() { + WsTester wsTester = new WsTester(); + WebService.NewController newController = wsTester.context().createController(DUMMY_CONTROLLER_KEY); + + underTest.define(newController); + newController.done(); + + WebService.Controller controller = wsTester.controller(DUMMY_CONTROLLER_KEY); + assertThat(controller.actions()).extracting("key").containsExactly(ACTION_KEY); + + WebService.Action action = controller.actions().iterator().next(); + assertThat(action.isPost()).isTrue(); + assertThat(action.description()).isNotEmpty(); + assertThat(action.responseExample()).isNull(); + + assertThat(action.params()).hasSize(1); + WebService.Param key = action.param(KEY_PARAM); + assertThat(key).isNotNull(); + assertThat(key.isRequired()).isTrue(); + assertThat(key.description()).isNotNull(); + } + + @Test + public void IAE_is_raised_when_key_param_is_not_provided() throws Exception { + expectedException.expect(IllegalArgumentException.class); + expectedException.expectMessage("Parameter 'key' is missing"); + + underTest.handle(invalidRequest, response); + } + + @Test + public void IAE_is_raised_when_there_is_no_plugin_update_for_the_key() throws Exception { + expectedException.expect(IllegalArgumentException.class); + expectedException.expectMessage("No plugin with key 'pluginKey'"); + + underTest.handle(validRequest, response); + } + + @Test + public void if_plugin_has_an_update_download_is_triggered_with_latest_version_from_updatecenter() throws Exception { + Version version = Version.create("1.0"); + when(updateCenter.findPluginUpdates()).thenReturn(ImmutableList.of( + PluginUpdate.createWithStatus(new Release(new Plugin(PLUGIN_KEY), version), Status.COMPATIBLE) + )); + + underTest.handle(validRequest, response); + + verify(pluginDownloader).download(PLUGIN_KEY, version); + assertThat(response.outputAsString()).isEmpty(); + } + +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/UpdatePluginsWsActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/UpdatePluginsWsActionTest.java deleted file mode 100644 index 750dae46318..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/UpdatePluginsWsActionTest.java +++ /dev/null @@ -1,141 +0,0 @@ -/* - * 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.plugins.ws; - -import com.google.common.collect.ImmutableList; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.sonar.api.server.ws.Request; -import org.sonar.api.server.ws.WebService; -import org.sonar.core.permission.GlobalPermissions; -import org.sonar.server.exceptions.ForbiddenException; -import org.sonar.server.plugins.PluginDownloader; -import org.sonar.server.plugins.UpdateCenterMatrixFactory; -import org.sonar.server.tester.UserSessionRule; -import org.sonar.server.ws.WsTester; -import org.sonar.updatecenter.common.Plugin; -import org.sonar.updatecenter.common.PluginUpdate; -import org.sonar.updatecenter.common.PluginUpdate.Status; -import org.sonar.updatecenter.common.Release; -import org.sonar.updatecenter.common.UpdateCenter; -import org.sonar.updatecenter.common.Version; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Matchers.anyBoolean; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class UpdatePluginsWsActionTest { - private static final String DUMMY_CONTROLLER_KEY = "dummy"; - private static final String CONTROLLER_KEY = "api/plugins"; - private static final String ACTION_KEY = "update"; - private static final String KEY_PARAM = "key"; - private static final String PLUGIN_KEY = "pluginKey"; - - @Rule - public UserSessionRule userSessionRule = UserSessionRule.standalone(); - - private UpdateCenterMatrixFactory updateCenterFactory = mock(UpdateCenterMatrixFactory.class); - private UpdateCenter updateCenter = mock(UpdateCenter.class); - private PluginDownloader pluginDownloader = mock(PluginDownloader.class); - private UpdatePluginsWsAction underTest = new UpdatePluginsWsAction(updateCenterFactory, pluginDownloader, userSessionRule); - - private WsTester wsTester = new WsTester(new PluginsWs(underTest)); - private Request invalidRequest = wsTester.newGetRequest(CONTROLLER_KEY, ACTION_KEY); - private Request validRequest = wsTester.newGetRequest(CONTROLLER_KEY, ACTION_KEY).setParam(KEY_PARAM, PLUGIN_KEY); - private WsTester.TestResponse response = new WsTester.TestResponse(); - - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - @Before - public void setUp() { - when(updateCenterFactory.getUpdateCenter(anyBoolean())).thenReturn(updateCenter); - - userSessionRule.setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN); - } - - @Test - public void user_must_have_system_admin_permission() throws Exception { - expectedException.expect(ForbiddenException.class); - expectedException.expectMessage("Insufficient privileges"); - - // no permission on user - userSessionRule.setGlobalPermissions(); - - underTest.handle(validRequest, response); - } - - @Test - public void action_update_is_defined() { - WsTester wsTester = new WsTester(); - WebService.NewController newController = wsTester.context().createController(DUMMY_CONTROLLER_KEY); - - underTest.define(newController); - newController.done(); - - WebService.Controller controller = wsTester.controller(DUMMY_CONTROLLER_KEY); - assertThat(controller.actions()).extracting("key").containsExactly(ACTION_KEY); - - WebService.Action action = controller.actions().iterator().next(); - assertThat(action.isPost()).isTrue(); - assertThat(action.description()).isNotEmpty(); - assertThat(action.responseExample()).isNull(); - - assertThat(action.params()).hasSize(1); - WebService.Param key = action.param(KEY_PARAM); - assertThat(key).isNotNull(); - assertThat(key.isRequired()).isTrue(); - assertThat(key.description()).isNotNull(); - } - - @Test - public void IAE_is_raised_when_key_param_is_not_provided() throws Exception { - expectedException.expect(IllegalArgumentException.class); - expectedException.expectMessage("Parameter 'key' is missing"); - - underTest.handle(invalidRequest, response); - } - - @Test - public void IAE_is_raised_when_there_is_no_plugin_update_for_the_key() throws Exception { - expectedException.expect(IllegalArgumentException.class); - expectedException.expectMessage("No plugin with key 'pluginKey'"); - - underTest.handle(validRequest, response); - } - - @Test - public void if_plugin_has_an_update_download_is_triggered_with_latest_version_from_updatecenter() throws Exception { - Version version = Version.create("1.0"); - when(updateCenter.findPluginUpdates()).thenReturn(ImmutableList.of( - PluginUpdate.createWithStatus(new Release(new Plugin(PLUGIN_KEY), version), Status.COMPATIBLE) - )); - - underTest.handle(validRequest, response); - - verify(pluginDownloader).download(PLUGIN_KEY, version); - assertThat(response.outputAsString()).isEmpty(); - } - -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/UpdatesActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/UpdatesActionTest.java new file mode 100644 index 00000000000..54aeddee145 --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/UpdatesActionTest.java @@ -0,0 +1,167 @@ +/* + * 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.plugins.ws; + +import org.junit.Test; +import org.sonar.api.server.ws.WebService; +import org.sonar.api.utils.DateUtils; +import org.sonar.server.ws.WsTester; +import org.sonar.updatecenter.common.Plugin; +import org.sonar.updatecenter.common.Release; + +import static com.google.common.collect.ImmutableList.of; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.when; +import static org.sonar.test.JsonAssert.assertJson; +import static org.sonar.updatecenter.common.PluginUpdate.Status.COMPATIBLE; +import static org.sonar.updatecenter.common.PluginUpdate.Status.INCOMPATIBLE; + +public class UpdatesActionTest extends AbstractUpdateCenterBasedPluginsWsActionTest { + private static final Plugin JAVA_PLUGIN = new Plugin("java") + .setName("Java") + .setDescription("SonarQube rule engine."); + private static final Plugin ABAP_PLUGIN = new Plugin("abap") + .setName("ABAP") + .setCategory("Languages") + .setDescription("Enable analysis and reporting on ABAP projects") + .setLicense("Commercial") + .setOrganization("SonarSource") + .setOrganizationUrl("http://www.sonarsource.com") + .setTermsConditionsUrl("http://dist.sonarsource.com/SonarSource_Terms_And_Conditions.pdf"); + private static final Release ABAP_31 = release(ABAP_PLUGIN, "3.1") + .setDate(DateUtils.parseDate("2014-12-21")) + .setDescription("New rules, several improvements") + .setDownloadUrl("http://dist.sonarsource.com/abap/download/sonar-abap-plugin-3.1.jar") + .setChangelogUrl("http://jira.sonarsource.com/secure/ReleaseNote.jspa?projectId=10054&version=10552"); + private static final Release ABAP_32 = release(ABAP_PLUGIN, "3.2") + .setDate(DateUtils.parseDate("2015-03-10")) + .setDescription("14 new rules, most of them designed to detect potential performance hotspots.") + .setDownloadUrl("http://dist.sonarsource.com/abap/download/sonar-abap-plugin-3.2.jar") + .setChangelogUrl("http://jira.sonarsource.com/secure/ReleaseNote.jspa?projectId=10054&version=10575"); + private static final Plugin ANDROID_PLUGIN = new Plugin("android") + .setName("Android") + .setCategory("Languages") + .setDescription("Import Android Lint reports.") + .setLicense("GNU LGPL 3") + .setOrganization("SonarSource and Jerome Van Der Linden, Stephane Nicolas, Florian Roncari, Thomas Bores") + .setOrganizationUrl("http://www.sonarsource.com"); + private static final Release ANDROID_10 = release(ANDROID_PLUGIN, "1.0") + .setDate(DateUtils.parseDate("2014-03-31")) + .setDescription("Makes the plugin compatible with multi-language analysis introduced in SonarQube 4.2 and adds support of Emma 2.0 reports") + .setDownloadUrl("http://repository.codehaus.org/org/codehaus/sonar-plugins/android/sonar-android-plugin/1.0/sonar-android-plugin-1.0.jar") + .setChangelogUrl("http://jira.codehaus.org/secure/ReleaseNote.jspa?projectId=13235&version=20187") + + .addOutgoingDependency(release(JAVA_PLUGIN, "1.0")); + + private UpdatesAction underTest = new UpdatesAction(updateCenterFactory, + new PluginWSCommons(), new PluginUpdateAggregator() + ); + + @Test + public void action_updatable_is_defined() { + WsTester wsTester = new WsTester(); + WebService.NewController newController = wsTester.context().createController(DUMMY_CONTROLLER_KEY); + + underTest.define(newController); + newController.done(); + + WebService.Controller controller = wsTester.controller(DUMMY_CONTROLLER_KEY); + assertThat(controller.actions()).extracting("key").containsExactly("updates"); + + WebService.Action action = controller.actions().iterator().next(); + assertThat(action.isPost()).isFalse(); + assertThat(action.description()).isNotEmpty(); + assertThat(action.responseExample()).isNotNull(); + } + + @Test + public void empty_array_is_returned_when_there_is_no_plugin_available() throws Exception { + underTest.handle(request, response); + + assertJson(response.outputAsString()).setStrictArrayOrder(true).isSimilarTo(JSON_EMPTY_PLUGIN_LIST); + } + + @Test + public void verify_response_against_example() throws Exception { + when(updateCenter.findPluginUpdates()).thenReturn(of( + pluginUpdate(ABAP_32, COMPATIBLE), + pluginUpdate(ABAP_31, INCOMPATIBLE), + pluginUpdate(ANDROID_10, COMPATIBLE) + )); + + underTest.handle(request, response); + + assertJson(response.outputAsString()).isSimilarTo(getClass().getResource("example-updates_plugins.json")); + } + + @Test + public void status_COMPATIBLE_is_displayed_COMPATIBLE_in_JSON() throws Exception { + when(updateCenter.findPluginUpdates()).thenReturn(of( + pluginUpdate(release(PLUGIN_1, "1.0.0"), COMPATIBLE) + )); + + underTest.handle(request, response); + + assertJson(response.outputAsString()).isSimilarTo( + "{" + + " \"plugins\": [" + + " {" + + " \"updates\": [" + + " {" + + " \"status\": \"COMPATIBLE\"" + + " }" + + " ]" + + " }" + + " ]" + + "}" + ); + } + + @Test + public void plugins_are_sorted_by_name_and_made_unique() throws Exception { + when(updateCenter.findPluginUpdates()).thenReturn(of( + pluginUpdate("key2", "name2"), + pluginUpdate("key2", "name2"), + pluginUpdate("key0", "name0"), + pluginUpdate("key1", "name1") + )); + + underTest.handle(request, response); + + assertJson(response.outputAsString()).setStrictArrayOrder(true).isSimilarTo( + "{" + + " \"plugins\": [" + + " {" + + " \"key\": \"key0\"," + + " \"name\": \"name0\"" + + " }," + + " {" + + " \"key\": \"key1\"," + + " \"name\": \"name1\"" + + " }," + + " {" + + " \"key\": \"key2\"," + + " \"name\": \"name2\"" + + " }," + + " ]" + + "}" + ); + } +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/UpdatesPluginsWsActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/UpdatesPluginsWsActionTest.java deleted file mode 100644 index 4784b7cedae..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/UpdatesPluginsWsActionTest.java +++ /dev/null @@ -1,167 +0,0 @@ -/* - * 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.plugins.ws; - -import org.junit.Test; -import org.sonar.api.server.ws.WebService; -import org.sonar.api.utils.DateUtils; -import org.sonar.server.ws.WsTester; -import org.sonar.updatecenter.common.Plugin; -import org.sonar.updatecenter.common.Release; - -import static com.google.common.collect.ImmutableList.of; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.when; -import static org.sonar.test.JsonAssert.assertJson; -import static org.sonar.updatecenter.common.PluginUpdate.Status.COMPATIBLE; -import static org.sonar.updatecenter.common.PluginUpdate.Status.INCOMPATIBLE; - -public class UpdatesPluginsWsActionTest extends AbstractUpdateCenterBasedPluginsWsActionTest { - private static final Plugin JAVA_PLUGIN = new Plugin("java") - .setName("Java") - .setDescription("SonarQube rule engine."); - private static final Plugin ABAP_PLUGIN = new Plugin("abap") - .setName("ABAP") - .setCategory("Languages") - .setDescription("Enable analysis and reporting on ABAP projects") - .setLicense("Commercial") - .setOrganization("SonarSource") - .setOrganizationUrl("http://www.sonarsource.com") - .setTermsConditionsUrl("http://dist.sonarsource.com/SonarSource_Terms_And_Conditions.pdf"); - private static final Release ABAP_31 = release(ABAP_PLUGIN, "3.1") - .setDate(DateUtils.parseDate("2014-12-21")) - .setDescription("New rules, several improvements") - .setDownloadUrl("http://dist.sonarsource.com/abap/download/sonar-abap-plugin-3.1.jar") - .setChangelogUrl("http://jira.sonarsource.com/secure/ReleaseNote.jspa?projectId=10054&version=10552"); - private static final Release ABAP_32 = release(ABAP_PLUGIN, "3.2") - .setDate(DateUtils.parseDate("2015-03-10")) - .setDescription("14 new rules, most of them designed to detect potential performance hotspots.") - .setDownloadUrl("http://dist.sonarsource.com/abap/download/sonar-abap-plugin-3.2.jar") - .setChangelogUrl("http://jira.sonarsource.com/secure/ReleaseNote.jspa?projectId=10054&version=10575"); - private static final Plugin ANDROID_PLUGIN = new Plugin("android") - .setName("Android") - .setCategory("Languages") - .setDescription("Import Android Lint reports.") - .setLicense("GNU LGPL 3") - .setOrganization("SonarSource and Jerome Van Der Linden, Stephane Nicolas, Florian Roncari, Thomas Bores") - .setOrganizationUrl("http://www.sonarsource.com"); - private static final Release ANDROID_10 = release(ANDROID_PLUGIN, "1.0") - .setDate(DateUtils.parseDate("2014-03-31")) - .setDescription("Makes the plugin compatible with multi-language analysis introduced in SonarQube 4.2 and adds support of Emma 2.0 reports") - .setDownloadUrl("http://repository.codehaus.org/org/codehaus/sonar-plugins/android/sonar-android-plugin/1.0/sonar-android-plugin-1.0.jar") - .setChangelogUrl("http://jira.codehaus.org/secure/ReleaseNote.jspa?projectId=13235&version=20187") - - .addOutgoingDependency(release(JAVA_PLUGIN, "1.0")); - - private UpdatesPluginsWsAction underTest = new UpdatesPluginsWsAction(updateCenterFactory, - new PluginWSCommons(), new PluginUpdateAggregator() - ); - - @Test - public void action_updatable_is_defined() { - WsTester wsTester = new WsTester(); - WebService.NewController newController = wsTester.context().createController(DUMMY_CONTROLLER_KEY); - - underTest.define(newController); - newController.done(); - - WebService.Controller controller = wsTester.controller(DUMMY_CONTROLLER_KEY); - assertThat(controller.actions()).extracting("key").containsExactly("updates"); - - WebService.Action action = controller.actions().iterator().next(); - assertThat(action.isPost()).isFalse(); - assertThat(action.description()).isNotEmpty(); - assertThat(action.responseExample()).isNotNull(); - } - - @Test - public void empty_array_is_returned_when_there_is_no_plugin_available() throws Exception { - underTest.handle(request, response); - - assertJson(response.outputAsString()).setStrictArrayOrder(true).isSimilarTo(JSON_EMPTY_PLUGIN_LIST); - } - - @Test - public void verify_response_against_example() throws Exception { - when(updateCenter.findPluginUpdates()).thenReturn(of( - pluginUpdate(ABAP_32, COMPATIBLE), - pluginUpdate(ABAP_31, INCOMPATIBLE), - pluginUpdate(ANDROID_10, COMPATIBLE) - )); - - underTest.handle(request, response); - - assertJson(response.outputAsString()).isSimilarTo(getClass().getResource("example-updates_plugins.json")); - } - - @Test - public void status_COMPATIBLE_is_displayed_COMPATIBLE_in_JSON() throws Exception { - when(updateCenter.findPluginUpdates()).thenReturn(of( - pluginUpdate(release(PLUGIN_1, "1.0.0"), COMPATIBLE) - )); - - underTest.handle(request, response); - - assertJson(response.outputAsString()).isSimilarTo( - "{" + - " \"plugins\": [" + - " {" + - " \"updates\": [" + - " {" + - " \"status\": \"COMPATIBLE\"" + - " }" + - " ]" + - " }" + - " ]" + - "}" - ); - } - - @Test - public void plugins_are_sorted_by_name_and_made_unique() throws Exception { - when(updateCenter.findPluginUpdates()).thenReturn(of( - pluginUpdate("key2", "name2"), - pluginUpdate("key2", "name2"), - pluginUpdate("key0", "name0"), - pluginUpdate("key1", "name1") - )); - - underTest.handle(request, response); - - assertJson(response.outputAsString()).setStrictArrayOrder(true).isSimilarTo( - "{" + - " \"plugins\": [" + - " {" + - " \"key\": \"key0\"," + - " \"name\": \"name0\"" + - " }," + - " {" + - " \"key\": \"key1\"," + - " \"name\": \"name1\"" + - " }," + - " {" + - " \"key\": \"key2\"," + - " \"name\": \"name2\"" + - " }," + - " ]" + - "}" - ); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/project/ws/DeleteActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/project/ws/DeleteActionTest.java new file mode 100644 index 00000000000..38915debf48 --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/project/ws/DeleteActionTest.java @@ -0,0 +1,252 @@ +/* + * 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.project.ws; + +import com.google.common.collect.ImmutableMap; +import org.junit.After; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Rule; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.junit.rules.ExpectedException; +import org.sonar.api.config.Settings; +import org.sonar.api.resources.Qualifiers; +import org.sonar.api.resources.ResourceType; +import org.sonar.api.resources.ResourceTypes; +import org.sonar.api.rule.RuleKey; +import org.sonar.api.utils.System2; +import org.sonar.api.web.UserRole; +import org.sonar.core.component.ComponentDto; +import org.sonar.core.component.SnapshotDto; +import org.sonar.core.issue.db.IssueDto; +import org.sonar.core.persistence.DbSession; +import org.sonar.core.persistence.DbTester; +import org.sonar.core.purge.PurgeDao; +import org.sonar.core.purge.PurgeProfiler; +import org.sonar.core.resource.ResourceDao; +import org.sonar.core.rule.RuleDto; +import org.sonar.server.component.ComponentCleanerService; +import org.sonar.server.component.ComponentTesting; +import org.sonar.server.component.SnapshotTesting; +import org.sonar.server.component.db.ComponentDao; +import org.sonar.server.component.db.SnapshotDao; +import org.sonar.server.db.DbClient; +import org.sonar.server.es.EsTester; +import org.sonar.server.exceptions.ForbiddenException; +import org.sonar.server.issue.IssueTesting; +import org.sonar.server.issue.db.IssueDao; +import org.sonar.server.issue.index.IssueAuthorizationIndexer; +import org.sonar.server.issue.index.IssueIndexDefinition; +import org.sonar.server.issue.index.IssueIndexer; +import org.sonar.server.rule.RuleTesting; +import org.sonar.server.rule.db.RuleDao; +import org.sonar.server.source.index.SourceLineDoc; +import org.sonar.server.source.index.SourceLineIndexDefinition; +import org.sonar.server.source.index.SourceLineIndexer; +import org.sonar.server.test.index.TestDoc; +import org.sonar.server.test.index.TestIndexDefinition; +import org.sonar.server.test.index.TestIndexer; +import org.sonar.server.tester.UserSessionRule; +import org.sonar.server.ws.WsTester; +import org.sonar.test.DbTests; + +import java.util.Arrays; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +@Category(DbTests.class) +public class DeleteActionTest { + + @ClassRule + public static DbTester db = new DbTester(); + @ClassRule + public static EsTester es = new EsTester().addDefinitions(new IssueIndexDefinition(new Settings()), new SourceLineIndexDefinition(new Settings()), + new TestIndexDefinition(new Settings())); + @Rule + public UserSessionRule userSessionRule = UserSessionRule.standalone(); + @Rule + public ExpectedException expectedException = ExpectedException.none(); + WsTester ws; + DbClient dbClient; + DbSession dbSession; + ResourceType resourceType; + + @Before + public void setUp() throws Exception { + ComponentDao componentDao = new ComponentDao(); + ResourceDao resourceDao = new ResourceDao(db.myBatis(), System2.INSTANCE); + PurgeDao purgeDao = new PurgeDao(db.myBatis(), resourceDao, new PurgeProfiler(), System2.INSTANCE); + dbClient = new DbClient(db.database(), db.myBatis(), componentDao, purgeDao, new RuleDao(System2.INSTANCE), new IssueDao(db.myBatis()), new SnapshotDao(System2.INSTANCE)); + dbSession = dbClient.openSession(false); + resourceType = mock(ResourceType.class); + when(resourceType.getBooleanProperty(anyString())).thenReturn(true); + ResourceTypes mockResourceTypes = mock(ResourceTypes.class); + when(mockResourceTypes.get(anyString())).thenReturn(resourceType); + ws = new WsTester(new ProjectsWs(new DeleteAction(new ComponentCleanerService(dbClient, new IssueAuthorizationIndexer(dbClient, es.client()), new IssueIndexer( + dbClient, es.client()), new SourceLineIndexer(dbClient, es.client()), new TestIndexer(dbClient, es.client()), mockResourceTypes), dbClient, userSessionRule))); + db.truncateTables(); + es.truncateIndices(); + } + + @After + public void tearDown() throws Exception { + dbSession.close(); + } + + @Test + public void delete_projects_and_data_in_db_by_uuids() throws Exception { + userSessionRule.setGlobalPermissions(UserRole.ADMIN); + long snapshotId1 = insertNewProjectInDbAndReturnSnapshotId(1); + long snapshotId2 = insertNewProjectInDbAndReturnSnapshotId(2); + long snapshotId3 = insertNewProjectInDbAndReturnSnapshotId(3); + long snapshotId4 = insertNewProjectInDbAndReturnSnapshotId(4); + + ws.newGetRequest("api/projects", "delete") + .setParam("uuids", "project-uuid-1, project-uuid-3, project-uuid-4").execute(); + dbSession.commit(); + + assertThat(dbClient.componentDao().selectByUuids(dbSession, Arrays.asList("project-uuid-1", "project-uuid-3", "project-uuid-4"))).isEmpty(); + assertThat(dbClient.componentDao().selectByUuid(dbSession, "project-uuid-2")).isNotNull(); + assertThat(dbClient.snapshotDao().getNullableByKey(dbSession, snapshotId1)).isNull(); + assertThat(dbClient.snapshotDao().getNullableByKey(dbSession, snapshotId3)).isNull(); + assertThat(dbClient.snapshotDao().getNullableByKey(dbSession, snapshotId4)).isNull(); + assertThat(dbClient.snapshotDao().getNullableByKey(dbSession, snapshotId2)).isNotNull(); + assertThat(dbClient.issueDao().selectByKeys(dbSession, Arrays.asList("issue-key-1", "issue-key-3", "issue-key-4"))).isEmpty(); + assertThat(dbClient.issueDao().selectByKey(dbSession, "issue-key-2")).isNotNull(); + } + + @Test + public void delete_projects_and_data_in_db_by_keys() throws Exception { + userSessionRule.setGlobalPermissions(UserRole.ADMIN); + insertNewProjectInDbAndReturnSnapshotId(1); + insertNewProjectInDbAndReturnSnapshotId(2); + insertNewProjectInDbAndReturnSnapshotId(3); + insertNewProjectInDbAndReturnSnapshotId(4); + + ws.newGetRequest("api/projects", "delete") + .setParam("keys", "project-key-1, project-key-3, project-key-4").execute(); + dbSession.commit(); + + assertThat(dbClient.componentDao().selectByUuids(dbSession, Arrays.asList("project-uuid-1", "project-uuid-3", "project-uuid-4"))).isEmpty(); + assertThat(dbClient.componentDao().selectByUuid(dbSession, "project-uuid-2")).isNotNull(); + } + + @Test + public void delete_documents_indexes() throws Exception { + userSessionRule.setGlobalPermissions(UserRole.ADMIN); + insertNewProjectInIndexes(1); + insertNewProjectInIndexes(2); + insertNewProjectInIndexes(3); + insertNewProjectInIndexes(4); + + ws.newGetRequest("api/projects", "delete") + .setParam("keys", "project-key-1, project-key-3, project-key-4").execute(); + + String remainingProjectUuid = "project-uuid-2"; + assertThat(es.getDocumentFieldValues(IssueIndexDefinition.INDEX, IssueIndexDefinition.TYPE_ISSUE, IssueIndexDefinition.FIELD_ISSUE_PROJECT_UUID)) + .containsOnly(remainingProjectUuid); + assertThat(es.getDocumentFieldValues(IssueIndexDefinition.INDEX, IssueIndexDefinition.TYPE_AUTHORIZATION, IssueIndexDefinition.FIELD_AUTHORIZATION_PROJECT_UUID)) + .containsOnly(remainingProjectUuid); + assertThat(es.getDocumentFieldValues(SourceLineIndexDefinition.INDEX, SourceLineIndexDefinition.TYPE, SourceLineIndexDefinition.FIELD_PROJECT_UUID)) + .containsOnly(remainingProjectUuid); + assertThat(es.getDocumentFieldValues(TestIndexDefinition.INDEX, TestIndexDefinition.TYPE, TestIndexDefinition.FIELD_PROJECT_UUID)) + .containsOnly(remainingProjectUuid); + } + + @Test + public void web_service_returns_204() throws Exception { + userSessionRule.setGlobalPermissions(UserRole.ADMIN); + insertNewProjectInDbAndReturnSnapshotId(1); + + WsTester.Result result = ws.newGetRequest("api/projects", "delete").setParam("uuids", "project-uuid-1").execute(); + + result.assertNoContent(); + } + + @Test + public void fail_if_insufficient_privileges() throws Exception { + userSessionRule.setGlobalPermissions(UserRole.CODEVIEWER, UserRole.ISSUE_ADMIN, UserRole.USER); + expectedException.expect(ForbiddenException.class); + + ws.newGetRequest("api/projects", "delete").setParam("uuids", "whatever-the-uuid").execute(); + } + + @Test + public void fail_if_scope_is_not_project() throws Exception { + userSessionRule.setGlobalPermissions(UserRole.ADMIN); + expectedException.expect(IllegalArgumentException.class); + dbClient.componentDao().insert(dbSession, ComponentTesting.newFileDto(ComponentTesting.newProjectDto(), "file-uuid")); + dbSession.commit(); + + ws.newGetRequest("api/projects", "delete").setParam("uuids", "file-uuid").execute(); + } + + @Test + public void fail_if_qualifier_is_not_deletable() throws Exception { + userSessionRule.setGlobalPermissions(UserRole.ADMIN); + expectedException.expect(IllegalArgumentException.class); + dbClient.componentDao().insert(dbSession, ComponentTesting.newProjectDto("project-uuid").setQualifier(Qualifiers.FILE)); + dbSession.commit(); + when(resourceType.getBooleanProperty(anyString())).thenReturn(false); + + ws.newGetRequest("api/projects", "delete").setParam("uuids", "project-uuid").execute(); + } + + private long insertNewProjectInDbAndReturnSnapshotId(int id) { + String suffix = String.valueOf(id); + ComponentDto project = ComponentTesting + .newProjectDto("project-uuid-" + suffix) + .setKey("project-key-" + suffix); + RuleDto rule = RuleTesting.newDto(RuleKey.of("sonarqube", "rule-" + suffix)); + dbClient.ruleDao().insert(dbSession, rule); + IssueDto issue = IssueTesting.newDto(rule, project, project).setKee("issue-key-" + suffix); + dbClient.componentDao().insert(dbSession, project); + SnapshotDto snapshot = dbClient.snapshotDao().insert(dbSession, SnapshotTesting.createForProject(project)); + dbClient.issueDao().insert(dbSession, issue); + dbSession.commit(); + + return snapshot.getId(); + } + + private void insertNewProjectInIndexes(int id) throws Exception { + String suffix = String.valueOf(id); + ComponentDto project = ComponentTesting + .newProjectDto("project-uuid-" + suffix) + .setKey("project-key-" + suffix); + dbClient.componentDao().insert(dbSession, project); + dbSession.commit(); + + es.putDocuments(IssueIndexDefinition.INDEX, IssueIndexDefinition.TYPE_ISSUE, IssueTesting.newDoc("issue-key-" + suffix, project)); + SourceLineDoc sourceLineDoc = new SourceLineDoc() + .setProjectUuid(project.uuid()) + .setFileUuid(project.uuid()); + es.putDocuments(IssueIndexDefinition.INDEX, IssueIndexDefinition.TYPE_AUTHORIZATION, + ImmutableMap.of(IssueIndexDefinition.FIELD_AUTHORIZATION_PROJECT_UUID, project.uuid())); + + es.putDocuments(SourceLineIndexDefinition.INDEX, SourceLineIndexDefinition.TYPE, sourceLineDoc); + TestDoc testDoc = new TestDoc().setUuid("test-uuid-" + suffix).setProjectUuid(project.uuid()).setFileUuid(project.uuid()); + es.putDocuments(TestIndexDefinition.INDEX, TestIndexDefinition.TYPE, testDoc); + } +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/project/ws/GhostsActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/project/ws/GhostsActionTest.java new file mode 100644 index 00000000000..3b3535d2fb9 --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/project/ws/GhostsActionTest.java @@ -0,0 +1,202 @@ +/* + * 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.project.ws; + +import com.google.common.io.Resources; +import org.apache.commons.lang.StringUtils; +import org.junit.After; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Rule; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.sonar.api.server.ws.WebService.Param; +import org.sonar.api.utils.DateUtils; +import org.sonar.api.utils.System2; +import org.sonar.api.web.UserRole; +import org.sonar.core.component.ComponentDto; +import org.sonar.core.component.SnapshotDto; +import org.sonar.core.persistence.DbSession; +import org.sonar.core.persistence.DbTester; +import org.sonar.server.component.ComponentTesting; +import org.sonar.server.component.SnapshotTesting; +import org.sonar.server.component.db.ComponentDao; +import org.sonar.server.component.db.SnapshotDao; +import org.sonar.server.db.DbClient; +import org.sonar.server.exceptions.ForbiddenException; +import org.sonar.server.tester.UserSessionRule; +import org.sonar.server.ws.WsTester; +import org.sonar.test.DbTests; +import org.sonar.test.JsonAssert; + +import static org.assertj.core.api.Assertions.assertThat; + +@Category(DbTests.class) +public class GhostsActionTest { + + @ClassRule + public static DbTester db = new DbTester(); + @Rule + public UserSessionRule userSessionRule = UserSessionRule.standalone(); + WsTester ws; + + DbClient dbClient; + DbSession dbSession; + + @Before + public void setUp() { + dbClient = new DbClient(db.database(), db.myBatis(), new ComponentDao(), new SnapshotDao(System2.INSTANCE)); + dbSession = dbClient.openSession(false); + ws = new WsTester(new ProjectsWs(new GhostsAction(dbClient, userSessionRule))); + db.truncateTables(); + } + + @After + public void tearDown() throws Exception { + dbSession.close(); + } + + @Test + public void ghost_projects_without_analyzed_projects() throws Exception { + userSessionRule.setGlobalPermissions(UserRole.ADMIN); + insertNewGhostProject("1"); + insertNewGhostProject("2"); + insertNewActiveProject("3"); + + WsTester.Result result = ws.newGetRequest("api/projects", "ghosts").execute(); + + result.assertJson(getClass(), "all-projects.json"); + assertThat(result.outputAsString()).doesNotContain("analyzed-uuid-3"); + } + + @Test + public void ghost_projects_with_correct_pagination() throws Exception { + userSessionRule.setGlobalPermissions(UserRole.ADMIN); + for (int i = 1; i <= 10; i++) { + insertNewGhostProject(String.valueOf(i)); + } + + WsTester.Result result = ws.newGetRequest("api/projects", "ghosts") + .setParam(Param.PAGE, "3") + .setParam(Param.PAGE_SIZE, "4") + .execute(); + + result.assertJson(getClass(), "pagination.json"); + assertThat(StringUtils.countMatches(result.outputAsString(), "ghost-uuid-")).isEqualTo(2); + } + + @Test + public void ghost_projects_with_chosen_fields() throws Exception { + userSessionRule.setGlobalPermissions(UserRole.ADMIN); + insertNewGhostProject("1"); + + WsTester.Result result = ws.newGetRequest("api/projects", "ghosts") + .setParam(Param.FIELDS, "name") + .execute(); + + assertThat(result.outputAsString()).contains("uuid", "name") + .doesNotContain("key") + .doesNotContain("creationDate"); + } + + @Test + public void ghost_projects_with_partial_query_on_name() throws Exception { + userSessionRule.setGlobalPermissions(UserRole.ADMIN); + + insertNewGhostProject("10"); + insertNewGhostProject("11"); + insertNewGhostProject("2"); + + WsTester.Result result = ws.newGetRequest("api/projects", "ghosts") + .setParam(Param.TEXT_QUERY, "name-1") + .execute(); + + assertThat(result.outputAsString()).contains("ghost-name-10", "ghost-name-11") + .doesNotContain("ghost-name-2"); + } + + @Test + public void ghost_projects_with_partial_query_on_key() throws Exception { + userSessionRule.setGlobalPermissions(UserRole.ADMIN); + + insertNewGhostProject("1"); + + WsTester.Result result = ws.newGetRequest("api/projects", "ghosts") + .setParam(Param.TEXT_QUERY, "GHOST-key") + .execute(); + + assertThat(result.outputAsString()).contains("ghost-key-1"); + } + + @Test + public void ghost_projects_base_on_json_example() throws Exception { + userSessionRule.setGlobalPermissions(UserRole.ADMIN); + ComponentDto hBaseProject = ComponentTesting.newProjectDto("ce4c03d6-430f-40a9-b777-ad877c00aa4d") + .setKey("org.apache.hbas:hbase") + .setName("HBase") + .setCreatedAt(DateUtils.parseDateTime("2015-03-04T23:03:44+0100")); + dbClient.componentDao().insert(dbSession, hBaseProject); + dbClient.snapshotDao().insert(dbSession, SnapshotTesting.createForProject(hBaseProject) + .setStatus(SnapshotDto.STATUS_UNPROCESSED)); + ComponentDto roslynProject = ComponentTesting.newProjectDto("c526ef20-131b-4486-9357-063fa64b5079") + .setKey("com.microsoft.roslyn:roslyn") + .setName("Roslyn") + .setCreatedAt(DateUtils.parseDateTime("2013-03-04T23:03:44+0100")); + dbClient.componentDao().insert(dbSession, roslynProject); + dbClient.snapshotDao().insert(dbSession, SnapshotTesting.createForProject(roslynProject) + .setStatus(SnapshotDto.STATUS_UNPROCESSED)); + dbSession.commit(); + + WsTester.Result result = ws.newGetRequest("api/projects", "ghosts").execute(); + + JsonAssert.assertJson(result.outputAsString()).isSimilarTo(Resources.getResource(getClass(), "projects-example-ghosts.json")); + } + + @Test(expected = ForbiddenException.class) + public void fail_if_does_not_have_sufficient_rights() throws Exception { + userSessionRule.setGlobalPermissions(UserRole.USER, UserRole.ISSUE_ADMIN, UserRole.CODEVIEWER); + + ws.newGetRequest("api/projects", "ghosts").execute(); + } + + private void insertNewGhostProject(String id) { + ComponentDto project = ComponentTesting + .newProjectDto("ghost-uuid-" + id) + .setName("ghost-name-" + id) + .setKey("ghost-key-" + id); + dbClient.componentDao().insert(dbSession, project); + SnapshotDto snapshot = SnapshotTesting.createForProject(project) + .setStatus(SnapshotDto.STATUS_UNPROCESSED); + dbClient.snapshotDao().insert(dbSession, snapshot); + dbSession.commit(); + } + + private void insertNewActiveProject(String id) { + ComponentDto project = ComponentTesting + .newProjectDto("analyzed-uuid-" + id) + .setName("analyzed-name-" + id) + .setKey("analyzed-key-" + id); + dbClient.componentDao().insert(dbSession, project); + SnapshotDto snapshot = SnapshotTesting.createForProject(project); + dbClient.snapshotDao().insert(dbSession, snapshot); + dbSession.commit(); + } +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/project/ws/ProjectsWsTest.java b/server/sonar-server/src/test/java/org/sonar/server/project/ws/ProjectsWsTest.java new file mode 100644 index 00000000000..7bd3f1d0aa3 --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/project/ws/ProjectsWsTest.java @@ -0,0 +1,76 @@ +/* + * 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.project.ws; + +import org.junit.Before; +import org.junit.Test; +import org.sonar.api.server.ws.RailsHandler; +import org.sonar.api.server.ws.WebService; +import org.sonar.server.ws.WsTester; + +import static org.assertj.core.api.Assertions.assertThat; + +public class ProjectsWsTest { + + WebService.Controller controller; + WsTester ws; + + @Before + public void setUp() { + ws = new WsTester(new ProjectsWs()); + controller = ws.controller("api/projects"); + } + + @Test + public void define_controller() { + assertThat(controller).isNotNull(); + assertThat(controller.description()).isNotEmpty(); + assertThat(controller.since()).isEqualTo("2.10"); + assertThat(controller.actions()).hasSize(3); + } + + @Test + public void define_index_action() { + WebService.Action action = controller.action("index"); + assertThat(action).isNotNull(); + assertThat(action.handler()).isInstanceOf(RailsHandler.class); + assertThat(action.responseExampleAsString()).isNotEmpty(); + assertThat(action.params()).hasSize(8); + } + + @Test + public void define_create_action() { + WebService.Action action = controller.action("create"); + assertThat(action).isNotNull(); + assertThat(action.handler()).isInstanceOf(RailsHandler.class); + assertThat(action.responseExampleAsString()).isNotEmpty(); + assertThat(action.params()).hasSize(4); + } + + @Test + public void define_destroy_action() { + WebService.Action action = controller.action("destroy"); + assertThat(action).isNotNull(); + assertThat(action.handler()).isInstanceOf(RailsHandler.class); + assertThat(action.params()).hasSize(1); + } + +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/project/ws/ProvisionedActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/project/ws/ProvisionedActionTest.java new file mode 100644 index 00000000000..c96928f068c --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/project/ws/ProvisionedActionTest.java @@ -0,0 +1,181 @@ +/* + * 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.project.ws; + +import com.google.common.io.Resources; +import org.apache.commons.lang.StringUtils; +import org.junit.After; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Rule; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.junit.rules.ExpectedException; +import org.sonar.api.server.ws.WebService.Param; +import org.sonar.api.utils.DateUtils; +import org.sonar.api.utils.System2; +import org.sonar.core.component.ComponentDto; +import org.sonar.core.component.SnapshotDto; +import org.sonar.core.permission.GlobalPermissions; +import org.sonar.core.persistence.DbSession; +import org.sonar.core.persistence.DbTester; +import org.sonar.server.component.ComponentTesting; +import org.sonar.server.component.SnapshotTesting; +import org.sonar.server.component.db.ComponentDao; +import org.sonar.server.component.db.SnapshotDao; +import org.sonar.server.db.DbClient; +import org.sonar.server.exceptions.ForbiddenException; +import org.sonar.server.tester.UserSessionRule; +import org.sonar.server.ws.WsTester; +import org.sonar.test.DbTests; +import org.sonar.test.JsonAssert; + +import static org.assertj.core.api.Assertions.assertThat; + +@Category(DbTests.class) +public class ProvisionedActionTest { + + @ClassRule + public static DbTester db = new DbTester(); + @Rule + public UserSessionRule userSessionRule = UserSessionRule.standalone(); + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + WsTester ws; + DbClient dbClient; + DbSession dbSession; + ComponentDao componentDao; + + @After + public void tearDown() { + dbSession.close(); + } + + @Before + public void setUp() { + dbClient = new DbClient(db.database(), db.myBatis(), new ComponentDao(), new SnapshotDao(System2.INSTANCE)); + dbSession = dbClient.openSession(false); + componentDao = dbClient.componentDao(); + db.truncateTables(); + ws = new WsTester(new ProjectsWs(new ProvisionedAction(dbClient, userSessionRule))); + } + + @Test + public void all_provisioned_projects_without_analyzed_projects() throws Exception { + userSessionRule.setGlobalPermissions(GlobalPermissions.PROVISIONING); + ComponentDto analyzedProject = ComponentTesting.newProjectDto("analyzed-uuid-1"); + componentDao.insert(dbSession, newProvisionedProject("1"), newProvisionedProject("2"), analyzedProject); + SnapshotDto snapshot = SnapshotTesting.createForProject(analyzedProject); + dbClient.snapshotDao().insert(dbSession, snapshot); + dbSession.commit(); + + WsTester.Result result = ws.newGetRequest("api/projects", "provisioned").execute(); + + result.assertJson(getClass(), "all-projects.json"); + assertThat(result.outputAsString()).doesNotContain("analyzed-uuid-1"); + } + + @Test + public void provisioned_projects_with_correct_pagination() throws Exception { + userSessionRule.setGlobalPermissions(GlobalPermissions.PROVISIONING); + for (int i = 1; i <= 10; i++) { + componentDao.insert(dbSession, newProvisionedProject(String.valueOf(i))); + } + dbSession.commit(); + + WsTester.TestRequest request = ws.newGetRequest("api/projects", "provisioned") + .setParam(Param.PAGE, "3") + .setParam(Param.PAGE_SIZE, "4"); + + String jsonOutput = request.execute().outputAsString(); + + assertThat(StringUtils.countMatches(jsonOutput, "provisioned-uuid-")).isEqualTo(2); + } + + @Test + public void provisioned_projects_with_desired_fields() throws Exception { + userSessionRule.setGlobalPermissions(GlobalPermissions.PROVISIONING); + componentDao.insert(dbSession, newProvisionedProject("1")); + dbSession.commit(); + + String jsonOutput = ws.newGetRequest("api/projects", "provisioned") + .setParam(Param.FIELDS, "key") + .execute().outputAsString(); + + assertThat(jsonOutput).contains("uuid", "key") + .doesNotContain("name") + .doesNotContain("creationDate"); + } + + @Test + public void provisioned_projects_with_query() throws Exception { + userSessionRule.setGlobalPermissions(GlobalPermissions.PROVISIONING); + componentDao.insert(dbSession, newProvisionedProject("1"), newProvisionedProject("2")); + dbSession.commit(); + + String jsonOutput = ws.newGetRequest("api/projects", "provisioned") + .setParam(Param.TEXT_QUERY, "PROVISIONED-name-2") + .execute().outputAsString(); + + assertThat(jsonOutput) + .contains("provisioned-name-2", "provisioned-uuid-2") + .doesNotContain("provisioned-uuid-1"); + assertThat(componentDao.countProvisionedProjects(dbSession, "name-2")).isEqualTo(1); + assertThat(componentDao.countProvisionedProjects(dbSession, "key-2")).isEqualTo(1); + assertThat(componentDao.countProvisionedProjects(dbSession, "visioned-name-")).isEqualTo(2); + } + + @Test + public void provisioned_projects_as_defined_in_the_example() throws Exception { + userSessionRule.setGlobalPermissions(GlobalPermissions.PROVISIONING); + ComponentDto hBaseProject = ComponentTesting.newProjectDto("ce4c03d6-430f-40a9-b777-ad877c00aa4d") + .setKey("org.apache.hbas:hbase") + .setName("HBase") + .setCreatedAt(DateUtils.parseDateTime("2015-03-04T23:03:44+0100")); + ComponentDto roslynProject = ComponentTesting.newProjectDto("c526ef20-131b-4486-9357-063fa64b5079") + .setKey("com.microsoft.roslyn:roslyn") + .setName("Roslyn") + .setCreatedAt(DateUtils.parseDateTime("2013-03-04T23:03:44+0100")); + componentDao.insert(dbSession, hBaseProject, roslynProject); + dbSession.commit(); + + WsTester.Result result = ws.newGetRequest("api/projects", "provisioned").execute(); + + JsonAssert.assertJson(result.outputAsString()).isSimilarTo(Resources.getResource(getClass(), "projects-example-provisioned.json")); + } + + @Test + public void fail_when_not_enough_privileges() throws Exception { + expectedException.expect(ForbiddenException.class); + userSessionRule.setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION); + componentDao.insert(dbSession, newProvisionedProject("1")); + + ws.newGetRequest("api/projects", "provisioned").execute(); + } + + private static ComponentDto newProvisionedProject(String uuid) { + return ComponentTesting + .newProjectDto("provisioned-uuid-" + uuid) + .setName("provisioned-name-" + uuid) + .setKey("provisioned-key-" + uuid); + } +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/AppActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/AppActionTest.java new file mode 100644 index 00000000000..8da15e9fd29 --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/AppActionTest.java @@ -0,0 +1,108 @@ +/* + * 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.qualitygate.ws; + +import com.google.common.collect.ImmutableList; +import org.json.simple.JSONValue; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.stubbing.Answer; +import org.sonar.api.i18n.I18n; +import org.sonar.api.measures.Metric; +import org.sonar.api.measures.Metric.ValueType; +import org.sonar.core.timemachine.Periods; +import org.sonar.server.qualitygate.QgateProjectFinder; +import org.sonar.server.qualitygate.QualityGates; +import org.sonar.server.ws.WsTester; + +import java.util.Collection; +import java.util.Locale; +import java.util.Map; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class AppActionTest { + + @Mock + private QualityGates qGates; + + @Mock + private Periods periods; + + @Mock + private I18n i18n; + + WsTester tester; + + @Before + public void setUp() { + tester = new WsTester(new QGatesWs( + new ListAction(qGates), new ShowAction(qGates), new SearchAction(mock(QgateProjectFinder.class)), + new CreateAction(qGates), new CopyAction(qGates), new DestroyAction(qGates), new RenameAction(qGates), + new SetAsDefaultAction(qGates), new UnsetDefaultAction(qGates), + new CreateConditionAction(qGates), new UpdateConditionAction(qGates), new DeleteConditionAction(qGates), + new SelectAction(qGates), new DeselectAction(qGates), new AppAction(qGates, periods, i18n))); + } + + @Test + @SuppressWarnings({"unchecked", "rawtypes"}) + public void should_initialize_app() throws Exception { + doAnswer(new Answer() { + @Override + public String answer(InvocationOnMock invocation) throws Throwable { + return (String) invocation.getArguments()[1]; + } + }).when(i18n).message(any(Locale.class), any(String.class), any(String.class)); + + Metric metric = mock(Metric.class); + when(metric.getId()).thenReturn(42); + when(metric.getKey()).thenReturn("metric"); + when(metric.getName()).thenReturn("Metric"); + when(metric.getType()).thenReturn(ValueType.BOOL); + when(metric.getDomain()).thenReturn("General"); + when(metric.isHidden()).thenReturn(false); + when(qGates.gateMetrics()).thenReturn(ImmutableList.of(metric)); + + String json = tester.newGetRequest("api/qualitygates", "app").execute().outputAsString(); + + Map responseJson = (Map) JSONValue.parse(json); + assertThat((Boolean) responseJson.get("edit")).isFalse(); + Collection periods = (Collection) responseJson.get("periods"); + assertThat(periods).hasSize(5); + Collection metrics = (Collection) responseJson.get("metrics"); + assertThat(metrics).hasSize(1); + Map metricMap = metrics.iterator().next(); + assertThat(metricMap.get("id").toString()).isEqualTo("42"); + assertThat(metricMap.get("key")).isEqualTo("metric"); + assertThat(metricMap.get("name")).isEqualTo("Metric"); + assertThat(metricMap.get("type")).isEqualTo("BOOL"); + assertThat(metricMap.get("domain")).isEqualTo("General"); + assertThat(metricMap.get("hidden")).isEqualTo(false); + } +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/QGatesAppActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/QGatesAppActionTest.java deleted file mode 100644 index 7cbbb3db16d..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/QGatesAppActionTest.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * 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.qualitygate.ws; - -import com.google.common.collect.ImmutableList; -import org.json.simple.JSONValue; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.runners.MockitoJUnitRunner; -import org.mockito.stubbing.Answer; -import org.sonar.api.i18n.I18n; -import org.sonar.api.measures.Metric; -import org.sonar.api.measures.Metric.ValueType; -import org.sonar.core.timemachine.Periods; -import org.sonar.server.qualitygate.QgateProjectFinder; -import org.sonar.server.qualitygate.QualityGates; -import org.sonar.server.ws.WsTester; - -import java.util.Collection; -import java.util.Locale; -import java.util.Map; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -@RunWith(MockitoJUnitRunner.class) -public class QGatesAppActionTest { - - @Mock - private QualityGates qGates; - - @Mock - private Periods periods; - - @Mock - private I18n i18n; - - WsTester tester; - - @Before - public void setUp() { - tester = new WsTester(new QGatesWs( - new QGatesListAction(qGates), new QGatesShowAction(qGates), new QGatesSearchAction(mock(QgateProjectFinder.class)), - new QGatesCreateAction(qGates), new QGatesCopyAction(qGates), new QGatesDestroyAction(qGates), new QGatesRenameAction(qGates), - new QGatesSetAsDefaultAction(qGates), new QGatesUnsetDefaultAction(qGates), - new QGatesCreateConditionAction(qGates), new QGatesUpdateConditionAction(qGates), new QGatesDeleteConditionAction(qGates), - new QGatesSelectAction(qGates), new QGatesDeselectAction(qGates), new QGatesAppAction(qGates, periods, i18n))); - } - - @Test - @SuppressWarnings({"unchecked", "rawtypes"}) - public void should_initialize_app() throws Exception { - doAnswer(new Answer() { - @Override - public String answer(InvocationOnMock invocation) throws Throwable { - return (String) invocation.getArguments()[1]; - } - }).when(i18n).message(any(Locale.class), any(String.class), any(String.class)); - - Metric metric = mock(Metric.class); - when(metric.getId()).thenReturn(42); - when(metric.getKey()).thenReturn("metric"); - when(metric.getName()).thenReturn("Metric"); - when(metric.getType()).thenReturn(ValueType.BOOL); - when(metric.getDomain()).thenReturn("General"); - when(metric.isHidden()).thenReturn(false); - when(qGates.gateMetrics()).thenReturn(ImmutableList.of(metric)); - - String json = tester.newGetRequest("api/qualitygates", "app").execute().outputAsString(); - - Map responseJson = (Map) JSONValue.parse(json); - assertThat((Boolean) responseJson.get("edit")).isFalse(); - Collection periods = (Collection) responseJson.get("periods"); - assertThat(periods).hasSize(5); - Collection metrics = (Collection) responseJson.get("metrics"); - assertThat(metrics).hasSize(1); - Map metricMap = metrics.iterator().next(); - assertThat(metricMap.get("id").toString()).isEqualTo("42"); - assertThat(metricMap.get("key")).isEqualTo("metric"); - assertThat(metricMap.get("name")).isEqualTo("Metric"); - assertThat(metricMap.get("type")).isEqualTo("BOOL"); - assertThat(metricMap.get("domain")).isEqualTo("General"); - assertThat(metricMap.get("hidden")).isEqualTo(false); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/QGatesWsTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/QGatesWsTest.java index 0eea3c11b57..e912b781678 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/QGatesWsTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/QGatesWsTest.java @@ -60,18 +60,18 @@ public class QGatesWsTest { private QgateProjectFinder projectFinder; @Mock - private QGatesAppAction appHandler; + private AppAction appHandler; WsTester tester; @Before public void setUp() { tester = new WsTester(new QGatesWs( - new QGatesListAction(qGates), new QGatesShowAction(qGates), new QGatesSearchAction(projectFinder), - new QGatesCreateAction(qGates), new QGatesCopyAction(qGates), new QGatesDestroyAction(qGates), new QGatesRenameAction(qGates), - new QGatesSetAsDefaultAction(qGates), new QGatesUnsetDefaultAction(qGates), - new QGatesCreateConditionAction(qGates), new QGatesUpdateConditionAction(qGates), new QGatesDeleteConditionAction(qGates), - new QGatesSelectAction(qGates), new QGatesDeselectAction(qGates), new QGatesAppAction(qGates, mock(Periods.class), mock(I18n.class)))); + new ListAction(qGates), new ShowAction(qGates), new SearchAction(projectFinder), + new CreateAction(qGates), new CopyAction(qGates), new DestroyAction(qGates), new RenameAction(qGates), + new SetAsDefaultAction(qGates), new UnsetDefaultAction(qGates), + new CreateConditionAction(qGates), new UpdateConditionAction(qGates), new DeleteConditionAction(qGates), + new SelectAction(qGates), new DeselectAction(qGates), new AppAction(qGates, mock(Periods.class), mock(I18n.class)))); } @Test diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/BackupActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/BackupActionTest.java new file mode 100644 index 00000000000..37c920b63fa --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/BackupActionTest.java @@ -0,0 +1,93 @@ +/* + * 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.qualityprofile.ws; + +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.stubbing.Answer; +import org.sonar.core.persistence.DbTester; +import org.sonar.server.db.DbClient; +import org.sonar.server.language.LanguageTesting; +import org.sonar.server.qualityprofile.QProfileBackuper; +import org.sonar.server.qualityprofile.QProfileFactory; +import org.sonar.server.ws.WsTester; +import org.sonar.server.ws.WsTester.Result; + +import java.io.PrintWriter; +import java.io.Writer; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.mock; + +@RunWith(MockitoJUnitRunner.class) +public class BackupActionTest { + + @ClassRule + public static final DbTester db = new DbTester(); + + // TODO Replace with proper DbTester + EsTester medium test once DaoV2 is removed + @Mock + private QProfileBackuper backuper; + + private WsTester tester; + + @Before + public void setUp() { + DbClient dbClient = new DbClient(db.database(), db.myBatis()); + + tester = new WsTester(new QProfilesWs( + mock(RuleActivationActions.class), + mock(BulkRuleActivationActions.class), + mock(ProjectAssociationActions.class), + new BackupAction(backuper, dbClient, new QProfileFactory(dbClient), LanguageTesting.newLanguages("xoo")))); + } + + @Test + public void backup_profile() throws Exception { + String profileKey = "polop-palap-xoo-12345"; + + final String response = ""; + doAnswer(new Answer() { + @Override + public Void answer(InvocationOnMock invocation) throws Throwable { + Writer w = (Writer) invocation.getArguments()[1]; + new PrintWriter(w).print(response); + w.close(); + return null; + } + }).when(backuper).backup(eq(profileKey), any(Writer.class)); + + Result result = tester.newGetRequest("api/qualityprofiles", "backup").setParam("profileKey", profileKey).execute(); + assertThat(result.outputAsString()).isEqualTo(response); + } + + @Test(expected = IllegalArgumentException.class) + public void fail_on_missing_key() throws Exception { + tester.newGetRequest("api/qualityprofiles", "backup").execute(); + } +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/ChangeParentActionMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/ChangeParentActionMediumTest.java new file mode 100644 index 00000000000..52ead319c32 --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/ChangeParentActionMediumTest.java @@ -0,0 +1,290 @@ +/* + * 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.qualityprofile.ws; + +import java.util.List; +import org.junit.After; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Rule; +import org.junit.Test; +import org.sonar.api.rule.RuleKey; +import org.sonar.api.rule.RuleStatus; +import org.sonar.api.rule.Severity; +import org.sonar.core.permission.GlobalPermissions; +import org.sonar.core.persistence.DbSession; +import org.sonar.core.qualityprofile.db.ActiveRuleDto; +import org.sonar.core.qualityprofile.db.QualityProfileDto; +import org.sonar.core.rule.RuleDto; +import org.sonar.server.db.DbClient; +import org.sonar.server.exceptions.ForbiddenException; +import org.sonar.server.qualityprofile.QProfileName; +import org.sonar.server.qualityprofile.QProfileTesting; +import org.sonar.server.qualityprofile.RuleActivator; +import org.sonar.server.tester.ServerTester; +import org.sonar.server.tester.UserSessionRule; +import org.sonar.server.ws.WsTester; + +import static org.assertj.core.api.Assertions.assertThat; + +public class ChangeParentActionMediumTest { + + // TODO Replace with DbTester + EsTester once DaoV2 is removed + @ClassRule + public static ServerTester tester = new ServerTester(); + @Rule + public UserSessionRule userSessionRule = UserSessionRule.forServerTester(tester); + + QProfilesWs ws; + DbClient db; + DbSession session; + WsTester wsTester; + + @Before + public void setUp() { + tester.clearDbAndIndexes(); + db = tester.get(DbClient.class); + ws = tester.get(QProfilesWs.class); + wsTester = tester.get(WsTester.class); + session = db.openSession(false); + userSessionRule.login("gandalf").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); + } + + @After + public void after() { + session.close(); + } + + @Test + public void change_parent_with_no_parent_before() throws Exception { + QualityProfileDto parent1 = createProfile("xoo", "Parent 1"); + QualityProfileDto child = createProfile("xoo", "Child"); + + RuleDto rule1 = createRule("xoo", "rule1"); + createActiveRule(rule1, parent1); + session.commit(); + + assertThat(db.activeRuleDao().findByProfileKey(session, child.getKey())).isEmpty(); + + // Set parent + wsTester.newGetRequest(QProfilesWs.API_ENDPOINT, "change_parent") + .setParam(QProfileIdentificationParamUtils.PARAM_PROFILE_KEY, child.getKey()) + .setParam("parentKey", parent1.getKey().toString()) + .execute(); + session.clearCache(); + + // Check rule 1 enabled + List activeRules1 = db.activeRuleDao().findByProfileKey(session, child.getKey()); + assertThat(activeRules1).hasSize(1); + assertThat(activeRules1.get(0).getKey().ruleKey().rule()).isEqualTo("rule1"); + } + + @Test + public void replace_existing_parent() throws Exception { + QualityProfileDto parent1 = createProfile("xoo", "Parent 1"); + QualityProfileDto parent2 = createProfile("xoo", "Parent 2"); + QualityProfileDto child = createProfile("xoo", "Child"); + + RuleDto rule1 = createRule("xoo", "rule1"); + RuleDto rule2 = createRule("xoo", "rule2"); + createActiveRule(rule1, parent1); + createActiveRule(rule2, parent2); + session.commit(); + + // Set parent 1 + tester.get(RuleActivator.class).setParent(child.getKey(), parent1.getKey()); + session.clearCache(); + + // Set parent 2 through WS + wsTester.newGetRequest(QProfilesWs.API_ENDPOINT, "change_parent") + .setParam(QProfileIdentificationParamUtils.PARAM_PROFILE_KEY, child.getKey()) + .setParam("parentKey", parent2.getKey().toString()) + .execute(); + session.clearCache(); + + // Check rule 2 enabled + List activeRules2 = db.activeRuleDao().findByProfileKey(session, child.getKey()); + assertThat(activeRules2).hasSize(1); + assertThat(activeRules2.get(0).getKey().ruleKey().rule()).isEqualTo("rule2"); + } + + @Test + public void remove_parent() throws Exception { + QualityProfileDto parent = createProfile("xoo", "Parent 1"); + QualityProfileDto child = createProfile("xoo", "Child"); + + RuleDto rule1 = createRule("xoo", "rule1"); + createActiveRule(rule1, parent); + session.commit(); + + // Set parent + tester.get(RuleActivator.class).setParent(child.getKey(), parent.getKey()); + session.clearCache(); + + // Remove parent through WS + wsTester.newGetRequest(QProfilesWs.API_ENDPOINT, "change_parent") + .setParam(QProfileIdentificationParamUtils.PARAM_PROFILE_KEY, child.getKey()) + .execute(); + session.clearCache(); + + // Check no rule enabled + List activeRules = db.activeRuleDao().findByProfileKey(session, child.getKey()); + assertThat(activeRules).isEmpty(); + } + + @Test + public void change_parent_with_names() throws Exception { + QualityProfileDto parent1 = createProfile("xoo", "Parent 1"); + QualityProfileDto parent2 = createProfile("xoo", "Parent 2"); + QualityProfileDto child = createProfile("xoo", "Child"); + + RuleDto rule1 = createRule("xoo", "rule1"); + RuleDto rule2 = createRule("xoo", "rule2"); + createActiveRule(rule1, parent1); + createActiveRule(rule2, parent2); + session.commit(); + + assertThat(db.activeRuleDao().findByProfileKey(session, child.getKey())).isEmpty(); + + // 1. Set parent 1 + wsTester.newGetRequest(QProfilesWs.API_ENDPOINT, "change_parent") + .setParam(QProfileIdentificationParamUtils.PARAM_LANGUAGE, "xoo") + .setParam(QProfileIdentificationParamUtils.PARAM_PROFILE_NAME, child.getName()) + .setParam("parentName", parent1.getName()) + .execute(); + session.clearCache(); + + // 1. check rule 1 enabled + List activeRules1 = db.activeRuleDao().findByProfileKey(session, child.getKey()); + assertThat(activeRules1).hasSize(1); + assertThat(activeRules1.get(0).getKey().ruleKey().rule()).isEqualTo("rule1"); + + // 2. Set parent 2 + wsTester.newGetRequest(QProfilesWs.API_ENDPOINT, "change_parent") + .setParam(QProfileIdentificationParamUtils.PARAM_LANGUAGE, "xoo") + .setParam(QProfileIdentificationParamUtils.PARAM_PROFILE_NAME, child.getName()) + .setParam("parentName", parent2.getName()) + .execute(); + session.clearCache(); + + // 2. check rule 2 enabled + List activeRules2 = db.activeRuleDao().findByProfileKey(session, child.getKey()); + assertThat(activeRules2).hasSize(1); + assertThat(activeRules2.get(0).getKey().ruleKey().rule()).isEqualTo("rule2"); + + // 3. Remove parent + wsTester.newGetRequest(QProfilesWs.API_ENDPOINT, "change_parent") + .setParam(QProfileIdentificationParamUtils.PARAM_LANGUAGE, "xoo") + .setParam(QProfileIdentificationParamUtils.PARAM_PROFILE_NAME, child.getName()) + .setParam("parentName", "") + .execute(); + session.clearCache(); + + // 3. check no rule enabled + List activeRules = db.activeRuleDao().findByProfileKey(session, child.getKey()); + assertThat(activeRules).isEmpty(); + } + + @Test + public void remove_parent_with_empty_key() throws Exception { + QualityProfileDto parent = createProfile("xoo", "Parent 1"); + QualityProfileDto child = createProfile("xoo", "Child"); + + RuleDto rule1 = createRule("xoo", "rule1"); + createActiveRule(rule1, parent); + session.commit(); + + assertThat(db.activeRuleDao().findByProfileKey(session, child.getKey())).isEmpty(); + + // Set parent + tester.get(RuleActivator.class).setParent(child.getKey(), parent.getKey()); + session.clearCache(); + + // Remove parent + wsTester.newGetRequest(QProfilesWs.API_ENDPOINT, "change_parent") + .setParam(QProfileIdentificationParamUtils.PARAM_PROFILE_KEY, child.getKey()) + .setParam("parentKey", "") + .execute(); + session.clearCache(); + + // Check no rule enabled + List activeRules = db.activeRuleDao().findByProfileKey(session, child.getKey()); + assertThat(activeRules).isEmpty(); + } + + @Test(expected = IllegalArgumentException.class) + public void fail_if_parent_key_and_name_both_set() throws Exception { + QualityProfileDto child = createProfile("xoo", "Child"); + session.commit(); + + assertThat(db.activeRuleDao().findByProfileKey(session, child.getKey())).isEmpty(); + + wsTester.newGetRequest(QProfilesWs.API_ENDPOINT, "change_parent") + .setParam(QProfileIdentificationParamUtils.PARAM_PROFILE_KEY, child.getKee()) + .setParam("parentName", "polop") + .setParam("parentKey", "palap") + .execute(); + } + + @Test(expected = IllegalArgumentException.class) + public void fail_if_profile_key_and_name_both_set() throws Exception { + QualityProfileDto child = createProfile("xoo", "Child"); + session.commit(); + + assertThat(db.activeRuleDao().findByProfileKey(session, child.getKey())).isEmpty(); + + wsTester.newGetRequest(QProfilesWs.API_ENDPOINT, "change_parent") + .setParam(QProfileIdentificationParamUtils.PARAM_PROFILE_KEY, child.getKee()) + .setParam(QProfileIdentificationParamUtils.PARAM_PROFILE_NAME, child.getName()) + .setParam("parentKey", "palap") + .execute(); + } + + @Test(expected = ForbiddenException.class) + public void fail_if_missing_permission() throws Exception { + userSessionRule.login("anakin"); + wsTester.newGetRequest(QProfilesWs.API_ENDPOINT, "change_parent") + .setParam(QProfileIdentificationParamUtils.PARAM_PROFILE_KEY, "polop") + .setParam("parentKey", "pulup") + .execute(); + } + + private QualityProfileDto createProfile(String lang, String name) { + QualityProfileDto profile = QProfileTesting.newDto(new QProfileName(lang, name), "p" + lang + "-" + name.toLowerCase()); + db.qualityProfileDao().insert(session, profile); + return profile; + } + + private RuleDto createRule(String lang, String id) { + RuleDto rule = RuleDto.createFor(RuleKey.of("blah", id)) + .setLanguage(lang) + .setSeverity(Severity.BLOCKER) + .setStatus(RuleStatus.READY); + db.ruleDao().insert(session, rule); + return rule; + } + + private ActiveRuleDto createActiveRule(RuleDto rule, QualityProfileDto profile) { + ActiveRuleDto activeRule = ActiveRuleDto.createFor(profile, rule) + .setSeverity(rule.getSeverityString()); + db.activeRuleDao().insert(session, activeRule); + return activeRule; + } +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/ChangelogActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/ChangelogActionTest.java new file mode 100644 index 00000000000..3aaf7638a58 --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/ChangelogActionTest.java @@ -0,0 +1,207 @@ +/* + * 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.qualityprofile.ws; + +import com.google.common.collect.Maps; +import org.joda.time.DateTime; +import org.junit.After; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Test; +import org.sonar.api.config.Settings; +import org.sonar.api.rule.Severity; +import org.sonar.api.utils.DateUtils; +import org.sonar.api.utils.System2; +import org.sonar.api.utils.internal.Uuids; +import org.sonar.core.persistence.DbSession; +import org.sonar.core.persistence.DbTester; +import org.sonar.core.qualityprofile.db.ActiveRuleKey; +import org.sonar.core.qualityprofile.db.QualityProfileDao; +import org.sonar.core.rule.RuleDto; +import org.sonar.core.user.UserDto; +import org.sonar.server.activity.Activity; +import org.sonar.server.activity.index.ActivityDoc; +import org.sonar.server.activity.index.ActivityIndex; +import org.sonar.server.activity.index.ActivityIndexDefinition; +import org.sonar.server.db.DbClient; +import org.sonar.server.es.EsTester; +import org.sonar.server.exceptions.NotFoundException; +import org.sonar.server.language.LanguageTesting; +import org.sonar.server.qualityprofile.ActiveRuleChange; +import org.sonar.server.qualityprofile.ActiveRuleChange.Type; +import org.sonar.server.qualityprofile.QProfileFactory; +import org.sonar.server.qualityprofile.QProfileTesting; +import org.sonar.server.rule.RuleTesting; +import org.sonar.server.rule.db.RuleDao; +import org.sonar.server.user.db.UserDao; +import org.sonar.server.ws.WsTester; + +import java.util.Date; +import java.util.Map; + +import static org.mockito.Mockito.mock; +import static org.sonar.server.qualityprofile.QProfileTesting.XOO_P1_KEY; + +public class ChangelogActionTest { + + @ClassRule + public static DbTester dbTester = new DbTester(); + + @ClassRule + public static EsTester esTester = new EsTester().addDefinitions(new ActivityIndexDefinition(new Settings())); + + private DbClient db; + private DbSession dbSession; + private WsTester wsTester; + private String login; + + @Before + public void before() { + dbTester.truncateTables(); + esTester.truncateIndices(); + + System2 system = mock(System2.class); + + db = new DbClient(dbTester.database(), dbTester.myBatis(), new RuleDao(system), new QualityProfileDao(dbTester.myBatis(), system), new UserDao(dbTester.myBatis(), system)); + dbSession = db.openSession(false); + + // create pre-defined rules + RuleDto xooRule1 = RuleTesting.newXooX1().setSeverity("MINOR"); + db.ruleDao().insert(dbSession, xooRule1); + + // create pre-defined profiles P1 and P2 + db.qualityProfileDao().insert(dbSession, QProfileTesting.newXooP1(), QProfileTesting.newXooP2()); + + login = "david"; + UserDto user = new UserDto().setLogin(login).setName("David").setEmail("dav@id.com").setCreatedAt(System.currentTimeMillis()).setUpdatedAt(System.currentTimeMillis()); + db.userDao().insert(dbSession, user); + + dbSession.commit(); + dbSession.clearCache(); + + wsTester = new WsTester(new QProfilesWs(mock(RuleActivationActions.class), mock(BulkRuleActivationActions.class), mock(ProjectAssociationActions.class), + new ChangelogAction(db, new ActivityIndex(esTester.client()), new QProfileFactory(db), LanguageTesting.newLanguages("xoo")))); + } + + @After + public void after() { + dbSession.close(); + } + + @Test + public void changelog_empty() throws Exception { + wsTester.newGetRequest(QProfilesWs.API_ENDPOINT, "changelog").setParam("profileKey", XOO_P1_KEY) + .execute().assertJson(getClass(), "changelog_empty.json"); + } + + @Test + public void changelog_nominal() throws Exception { + createActivity(login, ActiveRuleChange.Type.ACTIVATED, ActiveRuleKey.of(XOO_P1_KEY, RuleTesting.XOO_X1), Severity.MAJOR, new Date(), "max", "10"); + + wsTester.newGetRequest(QProfilesWs.API_ENDPOINT, "changelog").setParam("profileKey", XOO_P1_KEY) + .execute().assertJson(getClass(), "changelog_nominal.json"); + } + + @Test + public void changelog_no_param() throws Exception { + createActivity(login, ActiveRuleChange.Type.ACTIVATED, ActiveRuleKey.of(XOO_P1_KEY, RuleTesting.XOO_X1), Severity.MAJOR, new Date()); + + wsTester.newGetRequest(QProfilesWs.API_ENDPOINT, "changelog").setParam("profileKey", XOO_P1_KEY) + .execute().assertJson(getClass(), "changelog_no_param.json"); + } + + @Test + public void changelog_system_user() throws Exception { + createActivity(null, ActiveRuleChange.Type.ACTIVATED, ActiveRuleKey.of(XOO_P1_KEY, RuleTesting.XOO_X1), Severity.MAJOR, new Date()); + + wsTester.newGetRequest(QProfilesWs.API_ENDPOINT, "changelog").setParam("profileKey", XOO_P1_KEY) + .execute().assertJson(getClass(), "changelog_no_login.json"); + } + + @Test + public void changelog_with_dates() throws Exception { + Date yesterday = DateTime.now().minusDays(1).toDate(); + Date tomorrow = DateTime.now().plusDays(1).toDate(); + + createActivity(login, ActiveRuleChange.Type.ACTIVATED, ActiveRuleKey.of(XOO_P1_KEY, RuleTesting.XOO_X1), Severity.MAJOR, new Date(), "max", "10"); + + // Tests with "since" + wsTester.newGetRequest(QProfilesWs.API_ENDPOINT, "changelog").setParam("profileKey", XOO_P1_KEY).setParam("since", + DateUtils.formatDateTime(yesterday)) + .execute().assertJson(getClass(), "changelog_nominal.json"); + wsTester.newGetRequest(QProfilesWs.API_ENDPOINT, "changelog").setParam("profileKey", XOO_P1_KEY).setParam("since", + DateUtils.formatDateTime(tomorrow)) + .execute().assertJson(getClass(), "changelog_empty.json"); + + // Tests with "to" + wsTester.newGetRequest(QProfilesWs.API_ENDPOINT, "changelog").setParam("profileKey", XOO_P1_KEY).setParam("to", + DateUtils.formatDateTime(yesterday)) + .execute().assertJson(getClass(), "changelog_empty.json"); + wsTester.newGetRequest(QProfilesWs.API_ENDPOINT, "changelog").setParam("profileKey", XOO_P1_KEY).setParam("to", + DateUtils.formatDateTime(tomorrow)) + .execute().assertJson(getClass(), "changelog_nominal.json"); + + // Test with both bounds set + wsTester.newGetRequest(QProfilesWs.API_ENDPOINT, "changelog").setParam("profileKey", XOO_P1_KEY) + .setParam("since", DateUtils.formatDateTime(yesterday)) + .setParam("to", DateUtils.formatDateTime(tomorrow)) + .execute().assertJson(getClass(), "changelog_nominal.json"); + } + + @Test + public void changelog_with_pagination() throws Exception { + Date farthest = new Date(1_500_000_000_000L); + createActivity(login, ActiveRuleChange.Type.ACTIVATED, ActiveRuleKey.of(XOO_P1_KEY, RuleTesting.XOO_X1), Severity.MAJOR, farthest, "max", "10"); + Date nearest = new Date(1_500_000_100_000L); + createActivity(login, ActiveRuleChange.Type.ACTIVATED, ActiveRuleKey.of(XOO_P1_KEY, RuleTesting.XOO_X1), Severity.CRITICAL, nearest, "max", "20"); + + wsTester.newGetRequest(QProfilesWs.API_ENDPOINT, "changelog").setParam("profileKey", XOO_P1_KEY).setParam("ps", "1") + .execute().assertJson(getClass(), "changelog_page1.json"); + wsTester.newGetRequest(QProfilesWs.API_ENDPOINT, "changelog").setParam("profileKey", XOO_P1_KEY).setParam("ps", "1").setParam("p", "2") + .execute().assertJson(getClass(), "changelog_page2.json"); + wsTester.newGetRequest(QProfilesWs.API_ENDPOINT, "changelog").setParam("profileKey", XOO_P1_KEY).setParam("ps", "1").setParam("p", "3") + .execute().assertJson(getClass(), "changelog_page3.json"); + } + + @Test(expected = NotFoundException.class) + public void fail_on_unknown_profile() throws Exception { + wsTester.newGetRequest(QProfilesWs.API_ENDPOINT, "changelog").setParam("profileKey", "unknown-profile").execute(); + } + + private void createActivity(String login, Type type, ActiveRuleKey activeRuleKey, String severity, Date createdAt, String... params) throws Exception { + Map details = Maps.newHashMap(); + details.put("key", activeRuleKey.toString()); + details.put("ruleKey", activeRuleKey.ruleKey().toString()); + details.put("profileKey", activeRuleKey.qProfile()); + details.put("severity", severity); + for (int i = 0; i < params.length; i += 2) { + details.put("param_" + params[i], params[i + 1]); + } + ActivityDoc doc = new ActivityDoc(Maps.newHashMap()); + doc.setAction(type.toString()); + doc.setCreatedAt(createdAt); + doc.setDetails(details); + doc.setKey(Uuids.create()); + doc.setLogin(login); + doc.setType(Activity.Type.QPROFILE.toString()); + + esTester.putDocuments(ActivityIndexDefinition.INDEX, ActivityIndexDefinition.TYPE, doc); + } +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/CompareActionMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/CompareActionMediumTest.java new file mode 100644 index 00000000000..d60550fb732 --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/CompareActionMediumTest.java @@ -0,0 +1,237 @@ +/* + * 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.qualityprofile.ws; + +import org.apache.commons.lang.StringUtils; +import org.junit.After; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Rule; +import org.junit.Test; +import org.sonar.api.rule.RuleKey; +import org.sonar.api.rule.RuleStatus; +import org.sonar.api.rule.Severity; +import org.sonar.api.server.rule.RuleParamType; +import org.sonar.api.server.rule.RulesDefinition; +import org.sonar.core.persistence.DbSession; +import org.sonar.core.qualityprofile.db.ActiveRuleDto; +import org.sonar.core.qualityprofile.db.ActiveRuleParamDto; +import org.sonar.core.qualityprofile.db.QualityProfileDto; +import org.sonar.core.rule.RuleDto; +import org.sonar.core.rule.RuleParamDto; +import org.sonar.server.db.DbClient; +import org.sonar.server.qualityprofile.QProfileName; +import org.sonar.server.qualityprofile.QProfileTesting; +import org.sonar.server.tester.ServerTester; +import org.sonar.server.tester.UserSessionRule; +import org.sonar.server.ws.WsTester; + +public class CompareActionMediumTest { + + @ClassRule + public static ServerTester tester = new ServerTester().addXoo() + .addComponents(new RulesDefinition() { + @Override + public void define(Context context) { + context.createRepository("blah", "xoo") + .setName("Blah") + .done(); + } + }); + @Rule + public UserSessionRule userSessionRule = UserSessionRule.forServerTester(tester); + + private DbClient db; + + private WsTester wsTester; + + private DbSession session; + + @Before + public void setUp() { + tester.clearDbAndIndexes(); + db = tester.get(DbClient.class); + session = db.openSession(false); + + wsTester = new WsTester(tester.get(QProfilesWs.class)); + } + + @After + public void tearDown() { + session.close(); + } + + @Test + public void compare_nominal() throws Exception { + RuleDto rule1 = createRule("xoo", "rule1"); + RuleDto rule2 = createRule("xoo", "rule2"); + RuleDto rule3 = createRule("xoo", "rule3"); + RuleDto rule4 = createRuleWithParam("xoo", "rule4"); + RuleDto rule5 = createRule("xoo", "rule5"); + + /* + * Profile 1: + * - rule 1 active (on both profiles) => "same" + * - rule 2 active (only in this profile) => "inLeft" + * - rule 4 active with different parameters => "modified" + * - rule 5 active with different severity => "modified" + */ + QualityProfileDto profile1 = createProfile("xoo", "Profile 1", "xoo-profile-1-01234"); + createActiveRule(rule1, profile1); + createActiveRule(rule2, profile1); + createActiveRuleWithParam(rule4, profile1, "polop"); + createActiveRuleWithSeverity(rule5, profile1, Severity.MINOR); + session.commit(); + + /* + * Profile 1: + * - rule 1 active (on both profiles) => "same" + * - rule 3 active (only in this profile) => "inRight" + * - rule 4 active with different parameters => "modified" + */ + QualityProfileDto profile2 = createProfile("xoo", "Profile 2", "xoo-profile-2-12345"); + createActiveRule(rule1, profile2); + createActiveRule(rule3, profile2); + createActiveRuleWithParam(rule4, profile2, "palap"); + createActiveRuleWithSeverity(rule5, profile2, Severity.MAJOR); + session.commit(); + + wsTester.newGetRequest("api/qualityprofiles", "compare") + .setParam("leftKey", profile1.getKey()) + .setParam("rightKey", profile2.getKey()) + .execute().assertJson(this.getClass(), "compare_nominal.json"); + } + + @Test + public void compare_param_on_left() throws Exception { + RuleDto rule1 = createRuleWithParam("xoo", "rule1"); + + QualityProfileDto profile1 = createProfile("xoo", "Profile 1", "xoo-profile-1-01234"); + createActiveRuleWithParam(rule1, profile1, "polop"); + session.commit(); + + QualityProfileDto profile2 = createProfile("xoo", "Profile 2", "xoo-profile-2-12345"); + createActiveRule(rule1, profile2); + session.commit(); + + wsTester.newGetRequest("api/qualityprofiles", "compare") + .setParam("leftKey", profile1.getKey()) + .setParam("rightKey", profile2.getKey()) + .execute().assertJson(this.getClass(), "compare_param_on_left.json"); + } + + @Test + public void compare_param_on_right() throws Exception { + RuleDto rule1 = createRuleWithParam("xoo", "rule1"); + + QualityProfileDto profile1 = createProfile("xoo", "Profile 1", "xoo-profile-1-01234"); + createActiveRule(rule1, profile1); + session.commit(); + + QualityProfileDto profile2 = createProfile("xoo", "Profile 2", "xoo-profile-2-12345"); + createActiveRuleWithParam(rule1, profile2, "polop"); + session.commit(); + + wsTester.newGetRequest("api/qualityprofiles", "compare") + .setParam("leftKey", profile1.getKey()) + .setParam("rightKey", profile2.getKey()) + .execute().assertJson(this.getClass(), "compare_param_on_right.json"); + } + + @Test(expected = IllegalArgumentException.class) + public void fail_on_missing_left_param() throws Exception { + wsTester.newGetRequest("api/qualityprofiles", "compare") + .setParam("rightKey", "polop") + .execute(); + } + + @Test(expected = IllegalArgumentException.class) + public void fail_on_missing_right_param() throws Exception { + wsTester.newGetRequest("api/qualityprofiles", "compare") + .setParam("leftKey", "polop") + .execute(); + } + + @Test(expected = IllegalArgumentException.class) + public void fail_on_left_profile_not_found() throws Exception { + createProfile("xoo", "Right", "xoo-right-12345"); + wsTester.newGetRequest("api/qualityprofiles", "compare") + .setParam("leftKey", "polop") + .setParam("rightKey", "xoo-right-12345") + .execute(); + } + + @Test(expected = IllegalArgumentException.class) + public void fail_on_right_profile_not_found() throws Exception { + createProfile("xoo", "Left", "xoo-left-12345"); + wsTester.newGetRequest("api/qualityprofiles", "compare") + .setParam("leftKey", "xoo-left-12345") + .setParam("rightKey", "polop") + .execute(); + } + + private QualityProfileDto createProfile(String lang, String name, String key) { + QualityProfileDto profile = QProfileTesting.newDto(new QProfileName(lang, name), key); + db.qualityProfileDao().insert(session, profile); + session.commit(); + return profile; + } + + private RuleDto createRule(String lang, String id) { + RuleDto rule = RuleDto.createFor(RuleKey.of("blah", id)) + .setName(StringUtils.capitalize(id)) + .setLanguage(lang) + .setSeverity(Severity.BLOCKER) + .setStatus(RuleStatus.READY); + db.ruleDao().insert(session, rule); + RuleParamDto param = RuleParamDto.createFor(rule).setName("param_" + id).setType(RuleParamType.STRING.toString()); + db.ruleDao().addRuleParam(session, rule, param); + return rule; + } + + private RuleDto createRuleWithParam(String lang, String id) { + RuleDto rule = createRule(lang, id); + RuleParamDto param = RuleParamDto.createFor(rule).setName("param_" + id).setType(RuleParamType.STRING.toString()); + db.ruleDao().addRuleParam(session, rule, param); + return rule; + } + + private ActiveRuleDto createActiveRule(RuleDto rule, QualityProfileDto profile) { + ActiveRuleDto activeRule = ActiveRuleDto.createFor(profile, rule) + .setSeverity(rule.getSeverityString()); + db.activeRuleDao().insert(session, activeRule); + return activeRule; + } + + private ActiveRuleDto createActiveRuleWithParam(RuleDto rule, QualityProfileDto profile, String value) { + ActiveRuleDto activeRule = createActiveRule(rule, profile); + RuleParamDto paramDto = db.ruleDao().findRuleParamsByRuleKey(session, rule.getKey()).get(0); + ActiveRuleParamDto activeRuleParam = ActiveRuleParamDto.createFor(paramDto).setValue(value); + db.activeRuleDao().addParam(session, activeRule, activeRuleParam); + return activeRule; + } + + private ActiveRuleDto createActiveRuleWithSeverity(RuleDto rule, QualityProfileDto profile, String severity) { + ActiveRuleDto activeRule = ActiveRuleDto.createFor(profile, rule) + .setSeverity(severity); + db.activeRuleDao().insert(session, activeRule); + return activeRule; + } +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/CopyActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/CopyActionTest.java new file mode 100644 index 00000000000..161132b851e --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/CopyActionTest.java @@ -0,0 +1,129 @@ +/* + * 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.qualityprofile.ws; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; +import org.sonar.core.permission.GlobalPermissions; +import org.sonar.core.qualityprofile.db.QualityProfileDto; +import org.sonar.server.exceptions.ForbiddenException; +import org.sonar.server.language.LanguageTesting; +import org.sonar.server.qualityprofile.QProfileCopier; +import org.sonar.server.tester.UserSessionRule; +import org.sonar.server.ws.WsTester; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class CopyActionTest { + + @Rule + public UserSessionRule userSessionRule = UserSessionRule.standalone(); + + private WsTester tester; + + // TODO Replace with proper DbTester + EsTester medium test during removal of DaoV2 + @Mock + private QProfileCopier qProfileCopier; + + @Before + public void setUp() { + tester = new WsTester(new QProfilesWs( + mock(RuleActivationActions.class), + mock(BulkRuleActivationActions.class), + mock(ProjectAssociationActions.class), + new CopyAction(qProfileCopier, LanguageTesting.newLanguages("xoo"), userSessionRule))); + } + + @Test + public void copy_nominal() throws Exception { + userSessionRule.login("obiwan").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); + + String fromProfileKey = "xoo-sonar-way-23456"; + String toName = "Other Sonar Way"; + + when(qProfileCopier.copyToName(fromProfileKey, toName)).thenReturn( + QualityProfileDto.createFor("xoo-other-sonar-way-12345") + .setName(toName) + .setLanguage("xoo")); + + tester.newPostRequest("api/qualityprofiles", "copy") + .setParam("fromKey", fromProfileKey) + .setParam("toName", toName) + .execute().assertJson(getClass(), "copy_nominal.json"); + + verify(qProfileCopier).copyToName(fromProfileKey, toName); + } + + @Test + public void copy_with_parent() throws Exception { + userSessionRule.login("obiwan").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); + + String fromProfileKey = "xoo-sonar-way-23456"; + String toName = "Other Sonar Way"; + + when(qProfileCopier.copyToName(fromProfileKey, toName)).thenReturn( + QualityProfileDto.createFor("xoo-other-sonar-way-12345") + .setName(toName) + .setLanguage("xoo") + .setParentKee("xoo-parent-profile-01324")); + + tester.newPostRequest("api/qualityprofiles", "copy") + .setParam("fromKey", fromProfileKey) + .setParam("toName", toName) + .execute().assertJson(getClass(), "copy_with_parent.json"); + + verify(qProfileCopier).copyToName(fromProfileKey, toName); + } + + @Test(expected = IllegalArgumentException.class) + public void fail_on_missing_key() throws Exception { + userSessionRule.login("obiwan").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); + + tester.newPostRequest("api/qualityprofiles", "copy") + .setParam("name", "Other Sonar Way") + .execute(); + } + + @Test(expected = IllegalArgumentException.class) + public void fail_on_missing_name() throws Exception { + userSessionRule.login("obiwan").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); + + tester.newPostRequest("api/qualityprofiles", "copy") + .setParam("key", "sonar-way-xoo1-13245") + .execute(); + } + + @Test(expected = ForbiddenException.class) + public void fail_on_missing_permission() throws Exception { + userSessionRule.login("obiwan"); + + tester.newPostRequest("api/qualityprofiles", "copy") + .setParam("key", "sonar-way-xoo1-13245") + .setParam("name", "Hey look I am not quality profile admin!") + .execute(); + } +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/CreateActionMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/CreateActionMediumTest.java new file mode 100644 index 00000000000..994cee4a07d --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/CreateActionMediumTest.java @@ -0,0 +1,109 @@ +/* + * 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.qualityprofile.ws; + +import org.junit.After; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Rule; +import org.junit.Test; +import org.sonar.core.permission.GlobalPermissions; +import org.sonar.core.persistence.DbSession; +import org.sonar.server.db.DbClient; +import org.sonar.server.exceptions.BadRequestException; +import org.sonar.server.qualityprofile.QProfileExporters; +import org.sonar.server.qualityprofile.QProfileExportersTest.StandardExporter; +import org.sonar.server.qualityprofile.QProfileExportersTest.XooExporter; +import org.sonar.server.qualityprofile.QProfileExportersTest.XooProfileDefinition; +import org.sonar.server.qualityprofile.QProfileExportersTest.XooProfileImporter; +import org.sonar.server.qualityprofile.QProfileExportersTest.XooProfileImporterWithError; +import org.sonar.server.qualityprofile.QProfileExportersTest.XooProfileImporterWithMessages; +import org.sonar.server.qualityprofile.QProfileExportersTest.XooRulesDefinition; +import org.sonar.server.qualityprofile.QProfileLoader; +import org.sonar.server.tester.ServerTester; +import org.sonar.server.tester.UserSessionRule; +import org.sonar.server.ws.WsTester; + +public class CreateActionMediumTest { + + // TODO Replace with simpler test with DbTester / EsTester after removal of DaoV2 + @ClassRule + public static ServerTester tester = new ServerTester().addXoo().addComponents( + XooRulesDefinition.class, XooProfileDefinition.class, + XooExporter.class, StandardExporter.class, + XooProfileImporter.class, XooProfileImporterWithMessages.class, XooProfileImporterWithError.class); + @Rule + public UserSessionRule userSessionRule = UserSessionRule.forServerTester(tester); + + DbClient db; + DbSession dbSession; + QProfileExporters exporters; + QProfileLoader loader; + WsTester wsTester; + + @Before + public void before() { + db = tester.get(DbClient.class); + dbSession = db.openSession(false); + exporters = tester.get(QProfileExporters.class); + loader = tester.get(QProfileLoader.class); + wsTester = new WsTester(tester.get(QProfilesWs.class)); + } + + @After + public void after() { + dbSession.close(); + } + + @Test + public void create_nominal() throws Exception { + userSessionRule.login("obiwan").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); + + wsTester.newPostRequest("api/qualityprofiles", "create") + .setParam("backup_XooProfileImporter", "a value for xoo importer") + .setParam("language", "xoo") + .setParam("name", "My New Profile") + .execute().assertJson(this.getClass(), "create-nominal.json"); + } + + @Test + public void create_with_messages() throws Exception { + userSessionRule.login("obiwan").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); + + wsTester.newPostRequest("api/qualityprofiles", "create") + .setParam("backup_XooProfileImporter", "a value for xoo importer") + .setParam("backup_XooProfileImporterWithMessages", "this will generate some messages") + .setParam("language", "xoo") + .setParam("name", "My Other Profile") + .execute().assertJson(this.getClass(), "create-with-messages.json"); + } + + @Test(expected = BadRequestException.class) + public void fail_on_error_from_importer() throws Exception { + userSessionRule.login("obiwan").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); + + wsTester.newPostRequest("api/qualityprofiles", "create") + .setParam("backup_XooProfileImporter", "a value for xoo importer") + .setParam("backup_XooProfileImporterWithError", "this will fail") + .setParam("language", "xoo") + .setParam("name", "Error In Importer") + .execute(); + } +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/CreateActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/CreateActionTest.java new file mode 100644 index 00000000000..1b6a67a9309 --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/CreateActionTest.java @@ -0,0 +1,64 @@ +/* + * 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.qualityprofile.ws; + +import org.junit.ClassRule; +import org.junit.Rule; +import org.junit.Test; +import org.sonar.api.server.ws.WebService.Action; +import org.sonar.api.utils.System2; +import org.sonar.core.permission.GlobalPermissions; +import org.sonar.core.persistence.DbTester; +import org.sonar.core.qualityprofile.db.QualityProfileDao; +import org.sonar.server.db.DbClient; +import org.sonar.server.language.LanguageTesting; +import org.sonar.server.qualityprofile.QProfileFactory; +import org.sonar.server.tester.UserSessionRule; +import org.sonar.server.ws.WsTester; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; + +public class CreateActionTest { + + @ClassRule + public static final DbTester db = new DbTester(); + @Rule + public UserSessionRule userSessionRule = UserSessionRule.standalone(); + + @Test + public void should_not_fail_on_no_importers() throws Exception { + QualityProfileDao profileDao = new QualityProfileDao(db.myBatis(), mock(System2.class)); + DbClient dbClient = new DbClient(db.database(), db.myBatis(), profileDao); + + String xooKey = "xoo"; + WsTester wsTester = new WsTester(new QProfilesWs( + mock(RuleActivationActions.class), mock(BulkRuleActivationActions.class), mock(ProjectAssociationActions.class), + new CreateAction(dbClient, new QProfileFactory(dbClient), null, LanguageTesting.newLanguages(xooKey), userSessionRule))); + + Action create = wsTester.controller("api/qualityprofiles").action("create"); + assertThat(create.params()).hasSize(2); + + userSessionRule.login("anakin").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); + + wsTester.newPostRequest("api/qualityprofiles", "create") + .setParam("language", xooKey).setParam("name", "Yeehaw!").execute().assertJson(getClass(), "create-no-importer.json"); + } +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/DeleteActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/DeleteActionTest.java new file mode 100644 index 00000000000..083e2034e28 --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/DeleteActionTest.java @@ -0,0 +1,167 @@ +/* + * 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.qualityprofile.ws; + +import org.junit.After; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Rule; +import org.junit.Test; +import org.sonar.api.resources.Language; +import org.sonar.api.resources.Languages; +import org.sonar.api.utils.System2; +import org.sonar.core.component.ComponentDto; +import org.sonar.core.permission.GlobalPermissions; +import org.sonar.core.persistence.DbSession; +import org.sonar.core.persistence.DbTester; +import org.sonar.core.qualityprofile.db.QualityProfileDao; +import org.sonar.core.qualityprofile.db.QualityProfileDto; +import org.sonar.server.component.ComponentTesting; +import org.sonar.server.component.db.ComponentDao; +import org.sonar.server.db.DbClient; +import org.sonar.server.exceptions.ForbiddenException; +import org.sonar.server.exceptions.NotFoundException; +import org.sonar.server.language.LanguageTesting; +import org.sonar.server.qualityprofile.QProfileFactory; +import org.sonar.server.qualityprofile.db.ActiveRuleDao; +import org.sonar.server.rule.db.RuleDao; +import org.sonar.server.tester.UserSessionRule; +import org.sonar.server.ws.WsTester; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; + +public class DeleteActionTest { + + @ClassRule + public static DbTester dbTester = new DbTester(); + @Rule + public UserSessionRule userSessionRule = UserSessionRule.standalone(); + + private DbClient dbClient; + + private QualityProfileDao qualityProfileDao; + + private ComponentDao componentDao; + + private Language xoo1, xoo2; + + private WsTester tester; + + private DbSession session; + + System2 system2 = mock(System2.class); + + @Before + public void setUp() { + dbTester.truncateTables(); + qualityProfileDao = new QualityProfileDao(dbTester.myBatis(), mock(System2.class)); + componentDao = new ComponentDao(); + + dbClient = new DbClient(dbTester.database(), dbTester.myBatis(), qualityProfileDao, new ActiveRuleDao(qualityProfileDao, new RuleDao(system2), system2)); + session = dbClient.openSession(false); + + xoo1 = LanguageTesting.newLanguage("xoo1"); + xoo2 = LanguageTesting.newLanguage("xoo2"); + + tester = new WsTester(new QProfilesWs( + mock(RuleActivationActions.class), + mock(BulkRuleActivationActions.class), + mock(ProjectAssociationActions.class), + new DeleteAction(new Languages(xoo1, xoo2), new QProfileFactory(dbClient), dbClient, userSessionRule))); + } + + @After + public void teadDown() { + session.close(); + } + + @Test + public void delete_nominal_with_key() throws Exception { + String profileKey = "sonar-way-xoo1-12345"; + + ComponentDto project = ComponentTesting.newProjectDto("polop"); + componentDao.insert(session, project); + qualityProfileDao.insert(session, QualityProfileDto.createFor(profileKey).setLanguage(xoo1.getKey()).setName("Sonar way")); + qualityProfileDao.insertProjectProfileAssociation(project.uuid(), profileKey, session); + session.commit(); + + userSessionRule.login("obiwan").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); + + tester.newPostRequest("api/qualityprofiles", "delete").setParam("profileKey", "sonar-way-xoo1-12345").execute().assertNoContent(); + + assertThat(qualityProfileDao.getByKey(session, "sonar-way-xoo1-12345")).isNull(); + assertThat(qualityProfileDao.selectProjects("Sonar way", xoo1.getName())).isEmpty(); + } + + @Test + public void delete_nominal_with_language_and_name() throws Exception { + String profileKey = "sonar-way-xoo1-12345"; + + ComponentDto project = ComponentTesting.newProjectDto("polop"); + componentDao.insert(session, project); + qualityProfileDao.insert(session, QualityProfileDto.createFor(profileKey).setLanguage(xoo1.getKey()).setName("Sonar way")); + qualityProfileDao.insertProjectProfileAssociation(project.uuid(), profileKey, session); + session.commit(); + + userSessionRule.login("obiwan").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); + + tester.newPostRequest("api/qualityprofiles", "delete").setParam("profileName", "Sonar way").setParam("language", xoo1.getKey()).execute().assertNoContent(); + + assertThat(qualityProfileDao.getByKey(session, "sonar-way-xoo1-12345")).isNull(); + assertThat(qualityProfileDao.selectProjects("Sonar way", xoo1.getName())).isEmpty(); + } + + @Test(expected = ForbiddenException.class) + public void fail_on_missing_permission() throws Exception { + userSessionRule.login("obiwan"); + tester.newPostRequest("api/qualityprofiles", "delete").execute(); + } + + @Test(expected = IllegalArgumentException.class) + public void fail_on_missing_arguments() throws Exception { + userSessionRule.login("obiwan").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); + tester.newPostRequest("api/qualityprofiles", "delete").execute(); + } + + @Test(expected = IllegalArgumentException.class) + public void fail_on_missing_language() throws Exception { + userSessionRule.login("obiwan").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); + tester.newPostRequest("api/qualityprofiles", "delete").setParam("profileName", "Polop").execute(); + } + + @Test(expected = IllegalArgumentException.class) + public void fail_on_missing_name() throws Exception { + userSessionRule.login("obiwan").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); + tester.newPostRequest("api/qualityprofiles", "delete").setParam("language", xoo1.getKey()).execute(); + } + + @Test(expected = IllegalArgumentException.class) + public void fail_on_too_many_arguments() throws Exception { + userSessionRule.login("obiwan").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); + tester.newPostRequest("api/qualityprofiles", "delete").setParam("profileName", "Polop").setParam("language", xoo1.getKey()).setParam("profileKey", "polop").execute(); + } + + @Test(expected = NotFoundException.class) + public void fail_on_unexisting_profile() throws Exception { + userSessionRule.login("obiwan").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); + tester.newPostRequest("api/qualityprofiles", "delete").setParam("profileName", "Polop").setParam("language", xoo1.getKey()).execute(); + } +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/ExportActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/ExportActionTest.java new file mode 100644 index 00000000000..d87d18ab36d --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/ExportActionTest.java @@ -0,0 +1,202 @@ +/* + * 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.qualityprofile.ws; + +import com.google.common.collect.Sets; +import org.apache.commons.lang.StringUtils; +import org.junit.After; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Rule; +import org.junit.Test; +import org.mockito.Matchers; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; +import org.sonar.api.profiles.ProfileExporter; +import org.sonar.api.profiles.RulesProfile; +import org.sonar.api.server.ws.WebService.Action; +import org.sonar.api.utils.System2; +import org.sonar.core.persistence.DbSession; +import org.sonar.core.persistence.DbTester; +import org.sonar.core.qualityprofile.db.QualityProfileDao; +import org.sonar.core.qualityprofile.db.QualityProfileDto; +import org.sonar.server.db.DbClient; +import org.sonar.server.exceptions.NotFoundException; +import org.sonar.server.language.LanguageTesting; +import org.sonar.server.qualityprofile.*; +import org.sonar.server.qualityprofile.index.ActiveRuleIndex; +import org.sonar.server.search.IndexClient; +import org.sonar.server.tester.UserSessionRule; +import org.sonar.server.ws.WsTester; +import org.sonar.server.ws.WsTester.Result; + +import java.io.IOException; +import java.io.Writer; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class ExportActionTest { + + @ClassRule + public static final DbTester db = new DbTester(); + @Rule + public UserSessionRule userSessionRule = UserSessionRule.standalone(); + + WsTester wsTester; + + QualityProfileDao qualityProfileDao; + + DbClient dbClient; + + DbSession session; + + QProfileBackuper backuper; + + QProfileExporters exporters; + + @Before + public void before() { + qualityProfileDao = new QualityProfileDao(db.myBatis(), mock(System2.class)); + dbClient = new DbClient(db.database(), db.myBatis(), qualityProfileDao); + session = dbClient.openSession(false); + backuper = mock(QProfileBackuper.class); + + db.truncateTables(); + + ProfileExporter exporter1 = newExporter("polop"); + ProfileExporter exporter2 = newExporter("palap"); + + IndexClient indexClient = mock(IndexClient.class); + ActiveRuleIndex activeRuleIndex = mock(ActiveRuleIndex.class); + when(activeRuleIndex.findByProfile(Matchers.anyString())).thenReturn(Sets.newHashSet().iterator()); + + when(indexClient.get(ActiveRuleIndex.class)).thenReturn(activeRuleIndex); + exporters = new QProfileExporters(new QProfileLoader(dbClient, indexClient, userSessionRule), null, null, new ProfileExporter[] {exporter1, exporter2}, null); + wsTester = new WsTester(new QProfilesWs(mock(RuleActivationActions.class), + mock(BulkRuleActivationActions.class), + mock(ProjectAssociationActions.class), + new ExportAction(dbClient, new QProfileFactory(dbClient), backuper, exporters, LanguageTesting.newLanguages("xoo")))); + } + + @After + public void after() { + session.close(); + } + + private ProfileExporter newExporter(final String key) { + return new ProfileExporter(key, StringUtils.capitalize(key)) { + @Override + public String getMimeType() { + return "text/plain+" + key; + } + + @Override + public void exportProfile(RulesProfile profile, Writer writer) { + try { + writer.write(String.format("Profile %s exported by %s", profile.getName(), key)); + } catch (IOException ioe) { + throw new RuntimeException(ioe); + } + } + }; + } + + @Test + public void export_without_format() throws Exception { + QualityProfileDto profile = QProfileTesting.newXooP1(); + qualityProfileDao.insert(session, profile); + session.commit(); + + doAnswer(new Answer() { + @Override + public Void answer(InvocationOnMock invocation) throws Throwable { + invocation.getArgumentAt(1, Writer.class).write("As exported by SQ !"); + return null; + } + }).when(backuper).backup(Matchers.eq(profile.getKey()), Matchers.any(Writer.class)); + + Result result = wsTester.newGetRequest("api/qualityprofiles", "export").setParam("language", profile.getLanguage()).setParam("name", profile.getName()).execute(); + + assertThat(result.outputAsString()).isEqualTo("As exported by SQ !"); + } + + @Test + public void export_with_format() throws Exception { + QualityProfileDto profile = QProfileTesting.newXooP1(); + qualityProfileDao.insert(session, profile); + session.commit(); + + Result result = wsTester.newGetRequest("api/qualityprofiles", "export") + .setParam("language", profile.getLanguage()).setParam("name", profile.getName()).setParam("exporterKey", "polop").execute(); + + assertThat(result.outputAsString()).isEqualTo("Profile " + profile.getName() + " exported by polop"); + } + + @Test + public void export_default_profile() throws Exception { + QualityProfileDto profile1 = QProfileTesting.newXooP1(); + QualityProfileDto profile2 = QProfileTesting.newXooP2().setDefault(true); + qualityProfileDao.insert(session, profile1, profile2); + session.commit(); + + Result result = wsTester.newGetRequest("api/qualityprofiles", "export") + .setParam("language", "xoo").setParam("exporterKey", "polop").execute(); + + assertThat(result.outputAsString()).isEqualTo("Profile " + profile2.getName() + " exported by polop"); + } + + @Test(expected = NotFoundException.class) + public void fail_on_unknown_profile() throws Exception { + wsTester.newGetRequest("api/qualityprofiles", "export") + .setParam("language", "xoo").setParam("exporterKey", "polop").execute(); + } + + @Test(expected = IllegalArgumentException.class) + public void fail_on_unknown_exporter() throws Exception { + QualityProfileDto profile = QProfileTesting.newXooP1(); + qualityProfileDao.insert(session, profile); + session.commit(); + + wsTester.newGetRequest("api/qualityprofiles", "export") + .setParam("language", "xoo").setParam("exporterKey", "unknown").execute(); + } + + @Test + public void do_not_fail_when_no_exporters() throws Exception { + QProfileExporters myExporters = new QProfileExporters(null, null, null, new ProfileExporter[0], null); + WsTester myWsTester = new WsTester(new QProfilesWs(mock(RuleActivationActions.class), + mock(BulkRuleActivationActions.class), + mock(ProjectAssociationActions.class), + new ExportAction(dbClient, new QProfileFactory(dbClient), backuper, myExporters, LanguageTesting.newLanguages("xoo")))); + + Action export = myWsTester.controller("api/qualityprofiles").action("export"); + assertThat(export.params()).hasSize(2); + + QualityProfileDto profile = QProfileTesting.newXooP1(); + qualityProfileDao.insert(session, profile); + session.commit(); + + myWsTester.newGetRequest("api/qualityprofiles", "export").setParam("language", "xoo").setParam("name", profile.getName()).execute(); + + } +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/ExportersActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/ExportersActionTest.java new file mode 100644 index 00000000000..fb84e89a46e --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/ExportersActionTest.java @@ -0,0 +1,61 @@ +/* + * 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.qualityprofile.ws; + +import org.junit.Test; +import org.sonar.api.profiles.ProfileExporter; +import org.sonar.api.profiles.RulesProfile; +import org.sonar.server.ws.WsTester; + +import java.io.Writer; + +import static org.mockito.Mockito.mock; + +public class ExportersActionTest { + + @Test + public void importers_nominal() throws Exception { + WsTester wsTester = new WsTester(new QProfilesWs( + mock(RuleActivationActions.class), mock(BulkRuleActivationActions.class), mock(ProjectAssociationActions.class), + new ExportersAction(createExporters()))); + + wsTester.newGetRequest("api/qualityprofiles", "exporters").execute().assertJson(getClass(), "exporters.json"); + } + + private ProfileExporter[] createExporters() { + class NoopImporter extends ProfileExporter { + private NoopImporter(String key, String name, String... languages) { + super(key, name); + setSupportedLanguages(languages); + } + + @Override + public void exportProfile(RulesProfile profile, Writer writer) { + // Nothing + } + + } + return new ProfileExporter[] { + new NoopImporter("findbugs", "FindBugs", "java"), + new NoopImporter("jslint", "JS Lint", "js"), + new NoopImporter("vaadin", "Vaadin", "java", "js") + }; + } +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/ImportersActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/ImportersActionTest.java new file mode 100644 index 00000000000..955d7447f2b --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/ImportersActionTest.java @@ -0,0 +1,62 @@ +/* + * 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.qualityprofile.ws; + +import org.junit.Test; +import org.sonar.api.profiles.ProfileImporter; +import org.sonar.api.profiles.RulesProfile; +import org.sonar.api.utils.ValidationMessages; +import org.sonar.server.ws.WsTester; + +import java.io.Reader; + +import static org.mockito.Mockito.mock; + +public class ImportersActionTest { + + @Test + public void importers_nominal() throws Exception { + WsTester wsTester = new WsTester(new QProfilesWs( + mock(RuleActivationActions.class), mock(BulkRuleActivationActions.class), mock(ProjectAssociationActions.class), + new ImportersAction(createImporters()))); + + wsTester.newGetRequest("api/qualityprofiles", "importers").execute().assertJson(getClass(), "importers.json"); + } + + private ProfileImporter[] createImporters() { + class NoopImporter extends ProfileImporter { + private NoopImporter(String key, String name, String... languages) { + super(key, name); + setSupportedLanguages(languages); + } + + @Override + public RulesProfile importProfile(Reader reader, ValidationMessages messages) { + return RulesProfile.create(); + } + + } + return new ProfileImporter[] { + new NoopImporter("findbugs", "FindBugs", "java"), + new NoopImporter("jslint", "JS Lint", "js"), + new NoopImporter("vaadin", "Vaadin", "java", "js") + }; + } +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/InheritanceActionMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/InheritanceActionMediumTest.java new file mode 100644 index 00000000000..6db05c6f350 --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/InheritanceActionMediumTest.java @@ -0,0 +1,148 @@ +/* + * 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.qualityprofile.ws; + +import org.junit.After; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Rule; +import org.junit.Test; +import org.sonar.api.rule.RuleKey; +import org.sonar.api.rule.RuleStatus; +import org.sonar.api.rule.Severity; +import org.sonar.core.persistence.DbSession; +import org.sonar.core.qualityprofile.db.ActiveRuleDto; +import org.sonar.core.qualityprofile.db.QualityProfileDto; +import org.sonar.core.rule.RuleDto; +import org.sonar.server.db.DbClient; +import org.sonar.server.exceptions.NotFoundException; +import org.sonar.server.qualityprofile.QProfileName; +import org.sonar.server.qualityprofile.QProfileTesting; +import org.sonar.server.qualityprofile.RuleActivation; +import org.sonar.server.qualityprofile.RuleActivator; +import org.sonar.server.tester.ServerTester; +import org.sonar.server.tester.UserSessionRule; +import org.sonar.server.ws.WsTester; + +public class InheritanceActionMediumTest { + + @ClassRule + public static final ServerTester tester = new ServerTester(); + @Rule + public UserSessionRule userSessionRule = UserSessionRule.forServerTester(tester); + + private WsTester wsTester; + + private DbClient db; + + private DbSession session; + + @Before + public void setUp() { + tester.clearDbAndIndexes(); + db = tester.get(DbClient.class); + session = db.openSession(false); + + wsTester = new WsTester(tester.get(QProfilesWs.class)); + } + + @After + public void tearDown() { + session.close(); + } + + @Test + public void inheritance_nominal() throws Exception { + RuleDto rule1 = createRule("xoo", "rule1"); + RuleDto rule2 = createRule("xoo", "rule2"); + RuleDto rule3 = createRule("xoo", "rule3"); + + /* + * groupWide (2) <- companyWide (2) <- buWide (2, 1 overriding) <- (forProject1 (2), forProject2 (2)) + */ + QualityProfileDto groupWide = createProfile("xoo", "My Group Profile", "xoo-my-group-profile-01234"); + createActiveRule(rule1, groupWide); + createActiveRule(rule2, groupWide); + session.commit(); + + QualityProfileDto companyWide = createProfile("xoo", "My Company Profile", "xoo-my-company-profile-12345"); + setParent(groupWide, companyWide); + + QualityProfileDto buWide = createProfile("xoo", "My BU Profile", "xoo-my-bu-profile-23456"); + setParent(companyWide, buWide); + overrideActiveRuleSeverity(rule1, buWide, Severity.CRITICAL); + + QualityProfileDto forProject1 = createProfile("xoo", "For Project One", "xoo-for-project-one-34567"); + setParent(buWide, forProject1); + createActiveRule(rule3, forProject1); + session.commit(); + + QualityProfileDto forProject2 = createProfile("xoo", "For Project Two", "xoo-for-project-two-45678"); + setParent(buWide, forProject2); + overrideActiveRuleSeverity(rule2, forProject2, Severity.CRITICAL); + + wsTester.newGetRequest("api/qualityprofiles", "inheritance").setParam("profileKey", buWide.getKee()).execute().assertJson(getClass(), "inheritance-buWide.json"); + } + + @Test + public void inheritance_no_family() throws Exception { + // Simple profile, no parent, no child + QualityProfileDto remi = createProfile("xoo", "Nobodys Boy", "xoo-nobody-s-boy-01234"); + + wsTester.newGetRequest("api/qualityprofiles", "inheritance").setParam("profileKey", remi.getKee()).execute().assertJson(getClass(), "inheritance-simple.json"); + } + + @Test(expected = NotFoundException.class) + public void fail_if_not_found() throws Exception { + wsTester.newGetRequest("api/qualityprofiles", "inheritance").setParam("profileKey", "polop").execute(); + } + + private QualityProfileDto createProfile(String lang, String name, String key) { + QualityProfileDto profile = QProfileTesting.newDto(new QProfileName(lang, name), key); + db.qualityProfileDao().insert(session, profile); + session.commit(); + return profile; + } + + private void setParent(QualityProfileDto profile, QualityProfileDto parent) { + tester.get(RuleActivator.class).setParent(parent.getKey(), profile.getKey()); + } + + private RuleDto createRule(String lang, String id) { + RuleDto rule = RuleDto.createFor(RuleKey.of("blah", id)) + .setLanguage(lang) + .setSeverity(Severity.BLOCKER) + .setStatus(RuleStatus.READY); + db.ruleDao().insert(session, rule); + return rule; + } + + private ActiveRuleDto createActiveRule(RuleDto rule, QualityProfileDto profile) { + ActiveRuleDto activeRule = ActiveRuleDto.createFor(profile, rule) + .setSeverity(rule.getSeverityString()); + db.activeRuleDao().insert(session, activeRule); + return activeRule; + } + + private void overrideActiveRuleSeverity(RuleDto rule, QualityProfileDto profile, String severity) { + tester.get(RuleActivator.class).activate(session, new RuleActivation(rule.getKey()).setSeverity(severity), profile.getKey()); + session.commit(); + } +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/ProjectsActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/ProjectsActionTest.java new file mode 100644 index 00000000000..097531c9741 --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/ProjectsActionTest.java @@ -0,0 +1,240 @@ +/* + * 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.qualityprofile.ws; + +import org.junit.After; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Rule; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.sonar.api.utils.System2; +import org.sonar.api.web.UserRole; +import org.sonar.core.component.ComponentDto; +import org.sonar.core.persistence.DbSession; +import org.sonar.core.persistence.DbTester; +import org.sonar.core.qualityprofile.db.QualityProfileDao; +import org.sonar.core.qualityprofile.db.QualityProfileDto; +import org.sonar.core.user.AuthorizationDao; +import org.sonar.core.user.GroupRoleDto; +import org.sonar.core.user.RoleDao; +import org.sonar.core.user.UserDto; +import org.sonar.core.user.UserRoleDto; +import org.sonar.server.component.ComponentTesting; +import org.sonar.server.component.db.ComponentDao; +import org.sonar.server.db.DbClient; +import org.sonar.server.exceptions.NotFoundException; +import org.sonar.server.qualityprofile.QProfileTesting; +import org.sonar.server.tester.UserSessionRule; +import org.sonar.server.user.db.UserDao; +import org.sonar.server.ws.WsTester; +import org.sonar.server.ws.WsTester.TestRequest; +import org.sonar.test.DbTests; + +import static org.mockito.Mockito.mock; + +@Category(DbTests.class) +public class ProjectsActionTest { + + @ClassRule + public static final DbTester dbTester = new DbTester(); + @Rule + public UserSessionRule userSessionRule = UserSessionRule.standalone(); + + private WsTester wsTester; + + private DbClient dbClient; + + private DbSession session; + + private QualityProfileDto xooP1, xooP2; + + private ComponentDto project1, project2, project3, project4; + + private Long userId = 42L; + + private RoleDao roleDao; + + System2 system2 = mock(System2.class); + + @Before + public void setUp() { + dbTester.truncateTables(); + dbClient = new DbClient(dbTester.database(), dbTester.myBatis(), + new QualityProfileDao(dbTester.myBatis(), system2), + new ComponentDao(), + new AuthorizationDao(dbTester.myBatis())); + roleDao = new RoleDao(); + session = dbClient.openSession(false); + + wsTester = new WsTester(new QProfilesWs( + mock(RuleActivationActions.class), + mock(BulkRuleActivationActions.class), + mock(ProjectAssociationActions.class), + new ProjectsAction(dbClient, userSessionRule))); + + userSessionRule.login("obiwan").setUserId(userId.intValue()); + new UserDao(dbTester.myBatis(), mock(System2.class)) + .insert(session, new UserDto() + .setActive(true) + .setId(userId) + .setLogin("obiwan")); + + createProfiles(); + + session.commit(); + } + + @After + public void tearDown() { + session.close(); + } + + @Test + public void should_list_authorized_projects_only() throws Exception { + project1 = newProject("ABCD", "Project One"); + project2 = newProject("BCDE", "Project Two"); + dbClient.componentDao().insert(session, project1, project2); + + // user only sees project1 + roleDao.insertUserRole(new UserRoleDto().setUserId(userId).setResourceId(project1.getId()).setRole(UserRole.USER), session); + + associateProjectsWithProfile(session, xooP1, project1, project2); + + session.commit(); + + newRequest().setParam("key", xooP1.getKey()).setParam("selected", "selected").execute().assertJson(this.getClass(), "authorized_selected.json"); + } + + @Test + public void should_paginate() throws Exception { + project1 = newProject("ABCD", "Project One"); + project2 = newProject("BCDE", "Project Two"); + project3 = newProject("CDEF", "Project Three"); + project4 = newProject("DEFA", "Project Four"); + dbClient.componentDao().insert(session, project1, project2, project3, project4); + + addBrowsePermissionToAnyone(session, project1, project2, project3, project4); + + associateProjectsWithProfile(session, xooP1, project1, project2, project3, project4); + + session.commit(); + + newRequest().setParam("key", xooP1.getKey()).setParam("selected", "selected").setParam("pageSize", "2") + .execute().assertJson(this.getClass(), "selected_page1.json"); + newRequest().setParam("key", xooP1.getKey()).setParam("selected", "selected").setParam("pageSize", "2").setParam("page", "2") + .execute().assertJson(this.getClass(), "selected_page2.json"); + newRequest().setParam("key", xooP1.getKey()).setParam("selected", "selected").setParam("pageSize", "2").setParam("page", "3") + .execute().assertJson(this.getClass(), "empty.json"); + newRequest().setParam("key", xooP1.getKey()).setParam("selected", "selected").setParam("pageSize", "2").setParam("page", "4") + .execute().assertJson(this.getClass(), "empty.json"); + + newRequest().setParam("key", xooP1.getKey()).setParam("selected", "selected").setParam("pageSize", "3").setParam("page", "1") + .execute().assertJson(this.getClass(), "selected_ps3_page1.json"); + newRequest().setParam("key", xooP1.getKey()).setParam("selected", "selected").setParam("pageSize", "3").setParam("page", "2") + .execute().assertJson(this.getClass(), "selected_ps3_page2.json"); + newRequest().setParam("key", xooP1.getKey()).setParam("selected", "selected").setParam("pageSize", "3").setParam("page", "3") + .execute().assertJson(this.getClass(), "empty.json"); + } + + @Test + public void should_show_unselected() throws Exception { + project1 = newProject("ABCD", "Project One"); + project2 = newProject("BCDE", "Project Two"); + project3 = newProject("CDEF", "Project Three"); + project4 = newProject("DEFA", "Project Four"); + dbClient.componentDao().insert(session, project1, project2, project3, project4); + + addBrowsePermissionToAnyone(session, project1, project2, project3, project4); + + associateProjectsWithProfile(session, xooP1, project1, project2); + + session.commit(); + + newRequest().setParam("key", xooP1.getKey()).setParam("selected", "deselected").execute().assertJson(this.getClass(), "deselected.json"); + } + + @Test + public void should_show_all() throws Exception { + project1 = newProject("ABCD", "Project One"); + project2 = newProject("BCDE", "Project Two"); + project3 = newProject("CDEF", "Project Three"); + project4 = newProject("DEFA", "Project Four"); + dbClient.componentDao().insert(session, project1, project2, project3, project4); + + addBrowsePermissionToAnyone(session, project1, project2, project3, project4); + + associateProjectsWithProfile(session, xooP1, project1, project2); + // project3 is associated with P2, must appear as not associated with xooP1 + associateProjectsWithProfile(session, xooP2, project3); + + session.commit(); + + newRequest().setParam("key", xooP1.getKey()).setParam("selected", "all").execute().assertJson(this.getClass(), "all.json"); + } + + @Test + public void should_filter_on_name() throws Exception { + project1 = newProject("ABCD", "Project One"); + project2 = newProject("BCDE", "Project Two"); + project3 = newProject("CDEF", "Project Three"); + project4 = newProject("DEFA", "Project Four"); + dbClient.componentDao().insert(session, project1, project2, project3, project4); + + addBrowsePermissionToAnyone(session, project1, project2, project3, project4); + + associateProjectsWithProfile(session, xooP1, project1, project2); + + session.commit(); + + newRequest().setParam("key", xooP1.getKey()).setParam("selected", "all").setParam("query", "project t").execute().assertJson(this.getClass(), "all_filtered.json"); + } + + @Test(expected = NotFoundException.class) + public void should_fail_on_nonexistent_profile() throws Exception { + newRequest().setParam("key", "unknown").setParam("selected", "all").execute(); + } + + private void createProfiles() { + xooP1 = QProfileTesting.newXooP1(); + xooP2 = QProfileTesting.newXooP2(); + dbClient.qualityProfileDao().insert(session, xooP1, xooP2); + } + + private TestRequest newRequest() { + return wsTester.newGetRequest("api/qualityprofiles", "projects"); + } + + private ComponentDto newProject(String uuid, String name) { + return ComponentTesting.newProjectDto(uuid).setName(name); + } + + private void addBrowsePermissionToAnyone(DbSession session, ComponentDto... projects) { + for (ComponentDto project : projects) { + roleDao.insertGroupRole(new GroupRoleDto().setGroupId(null).setResourceId(project.getId()).setRole(UserRole.USER), session); + } + } + + private void associateProjectsWithProfile(DbSession session, QualityProfileDto profile, ComponentDto... projects) { + for (ComponentDto project : projects) { + dbClient.qualityProfileDao().insertProjectProfileAssociation(project.uuid(), profile.getKey(), session); + } + } +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileBackupActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileBackupActionTest.java deleted file mode 100644 index b039d48813f..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileBackupActionTest.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * 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.qualityprofile.ws; - -import org.junit.Before; -import org.junit.ClassRule; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.runners.MockitoJUnitRunner; -import org.mockito.stubbing.Answer; -import org.sonar.core.persistence.DbTester; -import org.sonar.server.db.DbClient; -import org.sonar.server.language.LanguageTesting; -import org.sonar.server.qualityprofile.QProfileBackuper; -import org.sonar.server.qualityprofile.QProfileFactory; -import org.sonar.server.ws.WsTester; -import org.sonar.server.ws.WsTester.Result; - -import java.io.PrintWriter; -import java.io.Writer; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.mock; - -@RunWith(MockitoJUnitRunner.class) -public class QProfileBackupActionTest { - - @ClassRule - public static final DbTester db = new DbTester(); - - // TODO Replace with proper DbTester + EsTester medium test once DaoV2 is removed - @Mock - private QProfileBackuper backuper; - - private WsTester tester; - - @Before - public void setUp() { - DbClient dbClient = new DbClient(db.database(), db.myBatis()); - - tester = new WsTester(new QProfilesWs( - mock(RuleActivationActions.class), - mock(BulkRuleActivationActions.class), - mock(ProjectAssociationActions.class), - new QProfileBackupAction(backuper, dbClient, new QProfileFactory(dbClient), LanguageTesting.newLanguages("xoo")))); - } - - @Test - public void backup_profile() throws Exception { - String profileKey = "polop-palap-xoo-12345"; - - final String response = ""; - doAnswer(new Answer() { - @Override - public Void answer(InvocationOnMock invocation) throws Throwable { - Writer w = (Writer) invocation.getArguments()[1]; - new PrintWriter(w).print(response); - w.close(); - return null; - } - }).when(backuper).backup(eq(profileKey), any(Writer.class)); - - Result result = tester.newGetRequest("api/qualityprofiles", "backup").setParam("profileKey", profileKey).execute(); - assertThat(result.outputAsString()).isEqualTo(response); - } - - @Test(expected = IllegalArgumentException.class) - public void fail_on_missing_key() throws Exception { - tester.newGetRequest("api/qualityprofiles", "backup").execute(); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileChangeParentActionMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileChangeParentActionMediumTest.java deleted file mode 100644 index 14beeb84bc1..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileChangeParentActionMediumTest.java +++ /dev/null @@ -1,290 +0,0 @@ -/* - * 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.qualityprofile.ws; - -import java.util.List; -import org.junit.After; -import org.junit.Before; -import org.junit.ClassRule; -import org.junit.Rule; -import org.junit.Test; -import org.sonar.api.rule.RuleKey; -import org.sonar.api.rule.RuleStatus; -import org.sonar.api.rule.Severity; -import org.sonar.core.permission.GlobalPermissions; -import org.sonar.core.persistence.DbSession; -import org.sonar.core.qualityprofile.db.ActiveRuleDto; -import org.sonar.core.qualityprofile.db.QualityProfileDto; -import org.sonar.core.rule.RuleDto; -import org.sonar.server.db.DbClient; -import org.sonar.server.exceptions.ForbiddenException; -import org.sonar.server.qualityprofile.QProfileName; -import org.sonar.server.qualityprofile.QProfileTesting; -import org.sonar.server.qualityprofile.RuleActivator; -import org.sonar.server.tester.ServerTester; -import org.sonar.server.tester.UserSessionRule; -import org.sonar.server.ws.WsTester; - -import static org.assertj.core.api.Assertions.assertThat; - -public class QProfileChangeParentActionMediumTest { - - // TODO Replace with DbTester + EsTester once DaoV2 is removed - @ClassRule - public static ServerTester tester = new ServerTester(); - @Rule - public UserSessionRule userSessionRule = UserSessionRule.forServerTester(tester); - - QProfilesWs ws; - DbClient db; - DbSession session; - WsTester wsTester; - - @Before - public void setUp() { - tester.clearDbAndIndexes(); - db = tester.get(DbClient.class); - ws = tester.get(QProfilesWs.class); - wsTester = tester.get(WsTester.class); - session = db.openSession(false); - userSessionRule.login("gandalf").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); - } - - @After - public void after() { - session.close(); - } - - @Test - public void change_parent_with_no_parent_before() throws Exception { - QualityProfileDto parent1 = createProfile("xoo", "Parent 1"); - QualityProfileDto child = createProfile("xoo", "Child"); - - RuleDto rule1 = createRule("xoo", "rule1"); - createActiveRule(rule1, parent1); - session.commit(); - - assertThat(db.activeRuleDao().findByProfileKey(session, child.getKey())).isEmpty(); - - // Set parent - wsTester.newGetRequest(QProfilesWs.API_ENDPOINT, "change_parent") - .setParam(QProfileIdentificationParamUtils.PARAM_PROFILE_KEY, child.getKey()) - .setParam("parentKey", parent1.getKey().toString()) - .execute(); - session.clearCache(); - - // Check rule 1 enabled - List activeRules1 = db.activeRuleDao().findByProfileKey(session, child.getKey()); - assertThat(activeRules1).hasSize(1); - assertThat(activeRules1.get(0).getKey().ruleKey().rule()).isEqualTo("rule1"); - } - - @Test - public void replace_existing_parent() throws Exception { - QualityProfileDto parent1 = createProfile("xoo", "Parent 1"); - QualityProfileDto parent2 = createProfile("xoo", "Parent 2"); - QualityProfileDto child = createProfile("xoo", "Child"); - - RuleDto rule1 = createRule("xoo", "rule1"); - RuleDto rule2 = createRule("xoo", "rule2"); - createActiveRule(rule1, parent1); - createActiveRule(rule2, parent2); - session.commit(); - - // Set parent 1 - tester.get(RuleActivator.class).setParent(child.getKey(), parent1.getKey()); - session.clearCache(); - - // Set parent 2 through WS - wsTester.newGetRequest(QProfilesWs.API_ENDPOINT, "change_parent") - .setParam(QProfileIdentificationParamUtils.PARAM_PROFILE_KEY, child.getKey()) - .setParam("parentKey", parent2.getKey().toString()) - .execute(); - session.clearCache(); - - // Check rule 2 enabled - List activeRules2 = db.activeRuleDao().findByProfileKey(session, child.getKey()); - assertThat(activeRules2).hasSize(1); - assertThat(activeRules2.get(0).getKey().ruleKey().rule()).isEqualTo("rule2"); - } - - @Test - public void remove_parent() throws Exception { - QualityProfileDto parent = createProfile("xoo", "Parent 1"); - QualityProfileDto child = createProfile("xoo", "Child"); - - RuleDto rule1 = createRule("xoo", "rule1"); - createActiveRule(rule1, parent); - session.commit(); - - // Set parent - tester.get(RuleActivator.class).setParent(child.getKey(), parent.getKey()); - session.clearCache(); - - // Remove parent through WS - wsTester.newGetRequest(QProfilesWs.API_ENDPOINT, "change_parent") - .setParam(QProfileIdentificationParamUtils.PARAM_PROFILE_KEY, child.getKey()) - .execute(); - session.clearCache(); - - // Check no rule enabled - List activeRules = db.activeRuleDao().findByProfileKey(session, child.getKey()); - assertThat(activeRules).isEmpty(); - } - - @Test - public void change_parent_with_names() throws Exception { - QualityProfileDto parent1 = createProfile("xoo", "Parent 1"); - QualityProfileDto parent2 = createProfile("xoo", "Parent 2"); - QualityProfileDto child = createProfile("xoo", "Child"); - - RuleDto rule1 = createRule("xoo", "rule1"); - RuleDto rule2 = createRule("xoo", "rule2"); - createActiveRule(rule1, parent1); - createActiveRule(rule2, parent2); - session.commit(); - - assertThat(db.activeRuleDao().findByProfileKey(session, child.getKey())).isEmpty(); - - // 1. Set parent 1 - wsTester.newGetRequest(QProfilesWs.API_ENDPOINT, "change_parent") - .setParam(QProfileIdentificationParamUtils.PARAM_LANGUAGE, "xoo") - .setParam(QProfileIdentificationParamUtils.PARAM_PROFILE_NAME, child.getName()) - .setParam("parentName", parent1.getName()) - .execute(); - session.clearCache(); - - // 1. check rule 1 enabled - List activeRules1 = db.activeRuleDao().findByProfileKey(session, child.getKey()); - assertThat(activeRules1).hasSize(1); - assertThat(activeRules1.get(0).getKey().ruleKey().rule()).isEqualTo("rule1"); - - // 2. Set parent 2 - wsTester.newGetRequest(QProfilesWs.API_ENDPOINT, "change_parent") - .setParam(QProfileIdentificationParamUtils.PARAM_LANGUAGE, "xoo") - .setParam(QProfileIdentificationParamUtils.PARAM_PROFILE_NAME, child.getName()) - .setParam("parentName", parent2.getName()) - .execute(); - session.clearCache(); - - // 2. check rule 2 enabled - List activeRules2 = db.activeRuleDao().findByProfileKey(session, child.getKey()); - assertThat(activeRules2).hasSize(1); - assertThat(activeRules2.get(0).getKey().ruleKey().rule()).isEqualTo("rule2"); - - // 3. Remove parent - wsTester.newGetRequest(QProfilesWs.API_ENDPOINT, "change_parent") - .setParam(QProfileIdentificationParamUtils.PARAM_LANGUAGE, "xoo") - .setParam(QProfileIdentificationParamUtils.PARAM_PROFILE_NAME, child.getName()) - .setParam("parentName", "") - .execute(); - session.clearCache(); - - // 3. check no rule enabled - List activeRules = db.activeRuleDao().findByProfileKey(session, child.getKey()); - assertThat(activeRules).isEmpty(); - } - - @Test - public void remove_parent_with_empty_key() throws Exception { - QualityProfileDto parent = createProfile("xoo", "Parent 1"); - QualityProfileDto child = createProfile("xoo", "Child"); - - RuleDto rule1 = createRule("xoo", "rule1"); - createActiveRule(rule1, parent); - session.commit(); - - assertThat(db.activeRuleDao().findByProfileKey(session, child.getKey())).isEmpty(); - - // Set parent - tester.get(RuleActivator.class).setParent(child.getKey(), parent.getKey()); - session.clearCache(); - - // Remove parent - wsTester.newGetRequest(QProfilesWs.API_ENDPOINT, "change_parent") - .setParam(QProfileIdentificationParamUtils.PARAM_PROFILE_KEY, child.getKey()) - .setParam("parentKey", "") - .execute(); - session.clearCache(); - - // Check no rule enabled - List activeRules = db.activeRuleDao().findByProfileKey(session, child.getKey()); - assertThat(activeRules).isEmpty(); - } - - @Test(expected = IllegalArgumentException.class) - public void fail_if_parent_key_and_name_both_set() throws Exception { - QualityProfileDto child = createProfile("xoo", "Child"); - session.commit(); - - assertThat(db.activeRuleDao().findByProfileKey(session, child.getKey())).isEmpty(); - - wsTester.newGetRequest(QProfilesWs.API_ENDPOINT, "change_parent") - .setParam(QProfileIdentificationParamUtils.PARAM_PROFILE_KEY, child.getKee()) - .setParam("parentName", "polop") - .setParam("parentKey", "palap") - .execute(); - } - - @Test(expected = IllegalArgumentException.class) - public void fail_if_profile_key_and_name_both_set() throws Exception { - QualityProfileDto child = createProfile("xoo", "Child"); - session.commit(); - - assertThat(db.activeRuleDao().findByProfileKey(session, child.getKey())).isEmpty(); - - wsTester.newGetRequest(QProfilesWs.API_ENDPOINT, "change_parent") - .setParam(QProfileIdentificationParamUtils.PARAM_PROFILE_KEY, child.getKee()) - .setParam(QProfileIdentificationParamUtils.PARAM_PROFILE_NAME, child.getName()) - .setParam("parentKey", "palap") - .execute(); - } - - @Test(expected = ForbiddenException.class) - public void fail_if_missing_permission() throws Exception { - userSessionRule.login("anakin"); - wsTester.newGetRequest(QProfilesWs.API_ENDPOINT, "change_parent") - .setParam(QProfileIdentificationParamUtils.PARAM_PROFILE_KEY, "polop") - .setParam("parentKey", "pulup") - .execute(); - } - - private QualityProfileDto createProfile(String lang, String name) { - QualityProfileDto profile = QProfileTesting.newDto(new QProfileName(lang, name), "p" + lang + "-" + name.toLowerCase()); - db.qualityProfileDao().insert(session, profile); - return profile; - } - - private RuleDto createRule(String lang, String id) { - RuleDto rule = RuleDto.createFor(RuleKey.of("blah", id)) - .setLanguage(lang) - .setSeverity(Severity.BLOCKER) - .setStatus(RuleStatus.READY); - db.ruleDao().insert(session, rule); - return rule; - } - - private ActiveRuleDto createActiveRule(RuleDto rule, QualityProfileDto profile) { - ActiveRuleDto activeRule = ActiveRuleDto.createFor(profile, rule) - .setSeverity(rule.getSeverityString()); - db.activeRuleDao().insert(session, activeRule); - return activeRule; - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileChangelogActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileChangelogActionTest.java deleted file mode 100644 index 5a3aa537365..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileChangelogActionTest.java +++ /dev/null @@ -1,207 +0,0 @@ -/* - * 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.qualityprofile.ws; - -import com.google.common.collect.Maps; -import org.joda.time.DateTime; -import org.junit.After; -import org.junit.Before; -import org.junit.ClassRule; -import org.junit.Test; -import org.sonar.api.config.Settings; -import org.sonar.api.rule.Severity; -import org.sonar.api.utils.DateUtils; -import org.sonar.api.utils.System2; -import org.sonar.api.utils.internal.Uuids; -import org.sonar.core.persistence.DbSession; -import org.sonar.core.persistence.DbTester; -import org.sonar.core.qualityprofile.db.ActiveRuleKey; -import org.sonar.core.qualityprofile.db.QualityProfileDao; -import org.sonar.core.rule.RuleDto; -import org.sonar.core.user.UserDto; -import org.sonar.server.activity.Activity; -import org.sonar.server.activity.index.ActivityDoc; -import org.sonar.server.activity.index.ActivityIndex; -import org.sonar.server.activity.index.ActivityIndexDefinition; -import org.sonar.server.db.DbClient; -import org.sonar.server.es.EsTester; -import org.sonar.server.exceptions.NotFoundException; -import org.sonar.server.language.LanguageTesting; -import org.sonar.server.qualityprofile.ActiveRuleChange; -import org.sonar.server.qualityprofile.ActiveRuleChange.Type; -import org.sonar.server.qualityprofile.QProfileFactory; -import org.sonar.server.qualityprofile.QProfileTesting; -import org.sonar.server.rule.RuleTesting; -import org.sonar.server.rule.db.RuleDao; -import org.sonar.server.user.db.UserDao; -import org.sonar.server.ws.WsTester; - -import java.util.Date; -import java.util.Map; - -import static org.mockito.Mockito.mock; -import static org.sonar.server.qualityprofile.QProfileTesting.XOO_P1_KEY; - -public class QProfileChangelogActionTest { - - @ClassRule - public static DbTester dbTester = new DbTester(); - - @ClassRule - public static EsTester esTester = new EsTester().addDefinitions(new ActivityIndexDefinition(new Settings())); - - private DbClient db; - private DbSession dbSession; - private WsTester wsTester; - private String login; - - @Before - public void before() { - dbTester.truncateTables(); - esTester.truncateIndices(); - - System2 system = mock(System2.class); - - db = new DbClient(dbTester.database(), dbTester.myBatis(), new RuleDao(system), new QualityProfileDao(dbTester.myBatis(), system), new UserDao(dbTester.myBatis(), system)); - dbSession = db.openSession(false); - - // create pre-defined rules - RuleDto xooRule1 = RuleTesting.newXooX1().setSeverity("MINOR"); - db.ruleDao().insert(dbSession, xooRule1); - - // create pre-defined profiles P1 and P2 - db.qualityProfileDao().insert(dbSession, QProfileTesting.newXooP1(), QProfileTesting.newXooP2()); - - login = "david"; - UserDto user = new UserDto().setLogin(login).setName("David").setEmail("dav@id.com").setCreatedAt(System.currentTimeMillis()).setUpdatedAt(System.currentTimeMillis()); - db.userDao().insert(dbSession, user); - - dbSession.commit(); - dbSession.clearCache(); - - wsTester = new WsTester(new QProfilesWs(mock(RuleActivationActions.class), mock(BulkRuleActivationActions.class), mock(ProjectAssociationActions.class), - new QProfileChangelogAction(db, new ActivityIndex(esTester.client()), new QProfileFactory(db), LanguageTesting.newLanguages("xoo")))); - } - - @After - public void after() { - dbSession.close(); - } - - @Test - public void changelog_empty() throws Exception { - wsTester.newGetRequest(QProfilesWs.API_ENDPOINT, "changelog").setParam("profileKey", XOO_P1_KEY) - .execute().assertJson(getClass(), "changelog_empty.json"); - } - - @Test - public void changelog_nominal() throws Exception { - createActivity(login, ActiveRuleChange.Type.ACTIVATED, ActiveRuleKey.of(XOO_P1_KEY, RuleTesting.XOO_X1), Severity.MAJOR, new Date(), "max", "10"); - - wsTester.newGetRequest(QProfilesWs.API_ENDPOINT, "changelog").setParam("profileKey", XOO_P1_KEY) - .execute().assertJson(getClass(), "changelog_nominal.json"); - } - - @Test - public void changelog_no_param() throws Exception { - createActivity(login, ActiveRuleChange.Type.ACTIVATED, ActiveRuleKey.of(XOO_P1_KEY, RuleTesting.XOO_X1), Severity.MAJOR, new Date()); - - wsTester.newGetRequest(QProfilesWs.API_ENDPOINT, "changelog").setParam("profileKey", XOO_P1_KEY) - .execute().assertJson(getClass(), "changelog_no_param.json"); - } - - @Test - public void changelog_system_user() throws Exception { - createActivity(null, ActiveRuleChange.Type.ACTIVATED, ActiveRuleKey.of(XOO_P1_KEY, RuleTesting.XOO_X1), Severity.MAJOR, new Date()); - - wsTester.newGetRequest(QProfilesWs.API_ENDPOINT, "changelog").setParam("profileKey", XOO_P1_KEY) - .execute().assertJson(getClass(), "changelog_no_login.json"); - } - - @Test - public void changelog_with_dates() throws Exception { - Date yesterday = DateTime.now().minusDays(1).toDate(); - Date tomorrow = DateTime.now().plusDays(1).toDate(); - - createActivity(login, ActiveRuleChange.Type.ACTIVATED, ActiveRuleKey.of(XOO_P1_KEY, RuleTesting.XOO_X1), Severity.MAJOR, new Date(), "max", "10"); - - // Tests with "since" - wsTester.newGetRequest(QProfilesWs.API_ENDPOINT, "changelog").setParam("profileKey", XOO_P1_KEY).setParam("since", - DateUtils.formatDateTime(yesterday)) - .execute().assertJson(getClass(), "changelog_nominal.json"); - wsTester.newGetRequest(QProfilesWs.API_ENDPOINT, "changelog").setParam("profileKey", XOO_P1_KEY).setParam("since", - DateUtils.formatDateTime(tomorrow)) - .execute().assertJson(getClass(), "changelog_empty.json"); - - // Tests with "to" - wsTester.newGetRequest(QProfilesWs.API_ENDPOINT, "changelog").setParam("profileKey", XOO_P1_KEY).setParam("to", - DateUtils.formatDateTime(yesterday)) - .execute().assertJson(getClass(), "changelog_empty.json"); - wsTester.newGetRequest(QProfilesWs.API_ENDPOINT, "changelog").setParam("profileKey", XOO_P1_KEY).setParam("to", - DateUtils.formatDateTime(tomorrow)) - .execute().assertJson(getClass(), "changelog_nominal.json"); - - // Test with both bounds set - wsTester.newGetRequest(QProfilesWs.API_ENDPOINT, "changelog").setParam("profileKey", XOO_P1_KEY) - .setParam("since", DateUtils.formatDateTime(yesterday)) - .setParam("to", DateUtils.formatDateTime(tomorrow)) - .execute().assertJson(getClass(), "changelog_nominal.json"); - } - - @Test - public void changelog_with_pagination() throws Exception { - Date farthest = new Date(1_500_000_000_000L); - createActivity(login, ActiveRuleChange.Type.ACTIVATED, ActiveRuleKey.of(XOO_P1_KEY, RuleTesting.XOO_X1), Severity.MAJOR, farthest, "max", "10"); - Date nearest = new Date(1_500_000_100_000L); - createActivity(login, ActiveRuleChange.Type.ACTIVATED, ActiveRuleKey.of(XOO_P1_KEY, RuleTesting.XOO_X1), Severity.CRITICAL, nearest, "max", "20"); - - wsTester.newGetRequest(QProfilesWs.API_ENDPOINT, "changelog").setParam("profileKey", XOO_P1_KEY).setParam("ps", "1") - .execute().assertJson(getClass(), "changelog_page1.json"); - wsTester.newGetRequest(QProfilesWs.API_ENDPOINT, "changelog").setParam("profileKey", XOO_P1_KEY).setParam("ps", "1").setParam("p", "2") - .execute().assertJson(getClass(), "changelog_page2.json"); - wsTester.newGetRequest(QProfilesWs.API_ENDPOINT, "changelog").setParam("profileKey", XOO_P1_KEY).setParam("ps", "1").setParam("p", "3") - .execute().assertJson(getClass(), "changelog_page3.json"); - } - - @Test(expected = NotFoundException.class) - public void fail_on_unknown_profile() throws Exception { - wsTester.newGetRequest(QProfilesWs.API_ENDPOINT, "changelog").setParam("profileKey", "unknown-profile").execute(); - } - - private void createActivity(String login, Type type, ActiveRuleKey activeRuleKey, String severity, Date createdAt, String... params) throws Exception { - Map details = Maps.newHashMap(); - details.put("key", activeRuleKey.toString()); - details.put("ruleKey", activeRuleKey.ruleKey().toString()); - details.put("profileKey", activeRuleKey.qProfile()); - details.put("severity", severity); - for (int i = 0; i < params.length; i += 2) { - details.put("param_" + params[i], params[i + 1]); - } - ActivityDoc doc = new ActivityDoc(Maps.newHashMap()); - doc.setAction(type.toString()); - doc.setCreatedAt(createdAt); - doc.setDetails(details); - doc.setKey(Uuids.create()); - doc.setLogin(login); - doc.setType(Activity.Type.QPROFILE.toString()); - - esTester.putDocuments(ActivityIndexDefinition.INDEX, ActivityIndexDefinition.TYPE, doc); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileCompareActionMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileCompareActionMediumTest.java deleted file mode 100644 index 49447da2611..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileCompareActionMediumTest.java +++ /dev/null @@ -1,237 +0,0 @@ -/* - * 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.qualityprofile.ws; - -import org.apache.commons.lang.StringUtils; -import org.junit.After; -import org.junit.Before; -import org.junit.ClassRule; -import org.junit.Rule; -import org.junit.Test; -import org.sonar.api.rule.RuleKey; -import org.sonar.api.rule.RuleStatus; -import org.sonar.api.rule.Severity; -import org.sonar.api.server.rule.RuleParamType; -import org.sonar.api.server.rule.RulesDefinition; -import org.sonar.core.persistence.DbSession; -import org.sonar.core.qualityprofile.db.ActiveRuleDto; -import org.sonar.core.qualityprofile.db.ActiveRuleParamDto; -import org.sonar.core.qualityprofile.db.QualityProfileDto; -import org.sonar.core.rule.RuleDto; -import org.sonar.core.rule.RuleParamDto; -import org.sonar.server.db.DbClient; -import org.sonar.server.qualityprofile.QProfileName; -import org.sonar.server.qualityprofile.QProfileTesting; -import org.sonar.server.tester.ServerTester; -import org.sonar.server.tester.UserSessionRule; -import org.sonar.server.ws.WsTester; - -public class QProfileCompareActionMediumTest { - - @ClassRule - public static ServerTester tester = new ServerTester().addXoo() - .addComponents(new RulesDefinition() { - @Override - public void define(Context context) { - context.createRepository("blah", "xoo") - .setName("Blah") - .done(); - } - }); - @Rule - public UserSessionRule userSessionRule = UserSessionRule.forServerTester(tester); - - private DbClient db; - - private WsTester wsTester; - - private DbSession session; - - @Before - public void setUp() { - tester.clearDbAndIndexes(); - db = tester.get(DbClient.class); - session = db.openSession(false); - - wsTester = new WsTester(tester.get(QProfilesWs.class)); - } - - @After - public void tearDown() { - session.close(); - } - - @Test - public void compare_nominal() throws Exception { - RuleDto rule1 = createRule("xoo", "rule1"); - RuleDto rule2 = createRule("xoo", "rule2"); - RuleDto rule3 = createRule("xoo", "rule3"); - RuleDto rule4 = createRuleWithParam("xoo", "rule4"); - RuleDto rule5 = createRule("xoo", "rule5"); - - /* - * Profile 1: - * - rule 1 active (on both profiles) => "same" - * - rule 2 active (only in this profile) => "inLeft" - * - rule 4 active with different parameters => "modified" - * - rule 5 active with different severity => "modified" - */ - QualityProfileDto profile1 = createProfile("xoo", "Profile 1", "xoo-profile-1-01234"); - createActiveRule(rule1, profile1); - createActiveRule(rule2, profile1); - createActiveRuleWithParam(rule4, profile1, "polop"); - createActiveRuleWithSeverity(rule5, profile1, Severity.MINOR); - session.commit(); - - /* - * Profile 1: - * - rule 1 active (on both profiles) => "same" - * - rule 3 active (only in this profile) => "inRight" - * - rule 4 active with different parameters => "modified" - */ - QualityProfileDto profile2 = createProfile("xoo", "Profile 2", "xoo-profile-2-12345"); - createActiveRule(rule1, profile2); - createActiveRule(rule3, profile2); - createActiveRuleWithParam(rule4, profile2, "palap"); - createActiveRuleWithSeverity(rule5, profile2, Severity.MAJOR); - session.commit(); - - wsTester.newGetRequest("api/qualityprofiles", "compare") - .setParam("leftKey", profile1.getKey()) - .setParam("rightKey", profile2.getKey()) - .execute().assertJson(this.getClass(), "compare_nominal.json"); - } - - @Test - public void compare_param_on_left() throws Exception { - RuleDto rule1 = createRuleWithParam("xoo", "rule1"); - - QualityProfileDto profile1 = createProfile("xoo", "Profile 1", "xoo-profile-1-01234"); - createActiveRuleWithParam(rule1, profile1, "polop"); - session.commit(); - - QualityProfileDto profile2 = createProfile("xoo", "Profile 2", "xoo-profile-2-12345"); - createActiveRule(rule1, profile2); - session.commit(); - - wsTester.newGetRequest("api/qualityprofiles", "compare") - .setParam("leftKey", profile1.getKey()) - .setParam("rightKey", profile2.getKey()) - .execute().assertJson(this.getClass(), "compare_param_on_left.json"); - } - - @Test - public void compare_param_on_right() throws Exception { - RuleDto rule1 = createRuleWithParam("xoo", "rule1"); - - QualityProfileDto profile1 = createProfile("xoo", "Profile 1", "xoo-profile-1-01234"); - createActiveRule(rule1, profile1); - session.commit(); - - QualityProfileDto profile2 = createProfile("xoo", "Profile 2", "xoo-profile-2-12345"); - createActiveRuleWithParam(rule1, profile2, "polop"); - session.commit(); - - wsTester.newGetRequest("api/qualityprofiles", "compare") - .setParam("leftKey", profile1.getKey()) - .setParam("rightKey", profile2.getKey()) - .execute().assertJson(this.getClass(), "compare_param_on_right.json"); - } - - @Test(expected = IllegalArgumentException.class) - public void fail_on_missing_left_param() throws Exception { - wsTester.newGetRequest("api/qualityprofiles", "compare") - .setParam("rightKey", "polop") - .execute(); - } - - @Test(expected = IllegalArgumentException.class) - public void fail_on_missing_right_param() throws Exception { - wsTester.newGetRequest("api/qualityprofiles", "compare") - .setParam("leftKey", "polop") - .execute(); - } - - @Test(expected = IllegalArgumentException.class) - public void fail_on_left_profile_not_found() throws Exception { - createProfile("xoo", "Right", "xoo-right-12345"); - wsTester.newGetRequest("api/qualityprofiles", "compare") - .setParam("leftKey", "polop") - .setParam("rightKey", "xoo-right-12345") - .execute(); - } - - @Test(expected = IllegalArgumentException.class) - public void fail_on_right_profile_not_found() throws Exception { - createProfile("xoo", "Left", "xoo-left-12345"); - wsTester.newGetRequest("api/qualityprofiles", "compare") - .setParam("leftKey", "xoo-left-12345") - .setParam("rightKey", "polop") - .execute(); - } - - private QualityProfileDto createProfile(String lang, String name, String key) { - QualityProfileDto profile = QProfileTesting.newDto(new QProfileName(lang, name), key); - db.qualityProfileDao().insert(session, profile); - session.commit(); - return profile; - } - - private RuleDto createRule(String lang, String id) { - RuleDto rule = RuleDto.createFor(RuleKey.of("blah", id)) - .setName(StringUtils.capitalize(id)) - .setLanguage(lang) - .setSeverity(Severity.BLOCKER) - .setStatus(RuleStatus.READY); - db.ruleDao().insert(session, rule); - RuleParamDto param = RuleParamDto.createFor(rule).setName("param_" + id).setType(RuleParamType.STRING.toString()); - db.ruleDao().addRuleParam(session, rule, param); - return rule; - } - - private RuleDto createRuleWithParam(String lang, String id) { - RuleDto rule = createRule(lang, id); - RuleParamDto param = RuleParamDto.createFor(rule).setName("param_" + id).setType(RuleParamType.STRING.toString()); - db.ruleDao().addRuleParam(session, rule, param); - return rule; - } - - private ActiveRuleDto createActiveRule(RuleDto rule, QualityProfileDto profile) { - ActiveRuleDto activeRule = ActiveRuleDto.createFor(profile, rule) - .setSeverity(rule.getSeverityString()); - db.activeRuleDao().insert(session, activeRule); - return activeRule; - } - - private ActiveRuleDto createActiveRuleWithParam(RuleDto rule, QualityProfileDto profile, String value) { - ActiveRuleDto activeRule = createActiveRule(rule, profile); - RuleParamDto paramDto = db.ruleDao().findRuleParamsByRuleKey(session, rule.getKey()).get(0); - ActiveRuleParamDto activeRuleParam = ActiveRuleParamDto.createFor(paramDto).setValue(value); - db.activeRuleDao().addParam(session, activeRule, activeRuleParam); - return activeRule; - } - - private ActiveRuleDto createActiveRuleWithSeverity(RuleDto rule, QualityProfileDto profile, String severity) { - ActiveRuleDto activeRule = ActiveRuleDto.createFor(profile, rule) - .setSeverity(severity); - db.activeRuleDao().insert(session, activeRule); - return activeRule; - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileCopyActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileCopyActionTest.java deleted file mode 100644 index bf14f0935bb..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileCopyActionTest.java +++ /dev/null @@ -1,129 +0,0 @@ -/* - * 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.qualityprofile.ws; - -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; -import org.sonar.core.permission.GlobalPermissions; -import org.sonar.core.qualityprofile.db.QualityProfileDto; -import org.sonar.server.exceptions.ForbiddenException; -import org.sonar.server.language.LanguageTesting; -import org.sonar.server.qualityprofile.QProfileCopier; -import org.sonar.server.tester.UserSessionRule; -import org.sonar.server.ws.WsTester; - -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -@RunWith(MockitoJUnitRunner.class) -public class QProfileCopyActionTest { - - @Rule - public UserSessionRule userSessionRule = UserSessionRule.standalone(); - - private WsTester tester; - - // TODO Replace with proper DbTester + EsTester medium test during removal of DaoV2 - @Mock - private QProfileCopier qProfileCopier; - - @Before - public void setUp() { - tester = new WsTester(new QProfilesWs( - mock(RuleActivationActions.class), - mock(BulkRuleActivationActions.class), - mock(ProjectAssociationActions.class), - new QProfileCopyAction(qProfileCopier, LanguageTesting.newLanguages("xoo"), userSessionRule))); - } - - @Test - public void copy_nominal() throws Exception { - userSessionRule.login("obiwan").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); - - String fromProfileKey = "xoo-sonar-way-23456"; - String toName = "Other Sonar Way"; - - when(qProfileCopier.copyToName(fromProfileKey, toName)).thenReturn( - QualityProfileDto.createFor("xoo-other-sonar-way-12345") - .setName(toName) - .setLanguage("xoo")); - - tester.newPostRequest("api/qualityprofiles", "copy") - .setParam("fromKey", fromProfileKey) - .setParam("toName", toName) - .execute().assertJson(getClass(), "copy_nominal.json"); - - verify(qProfileCopier).copyToName(fromProfileKey, toName); - } - - @Test - public void copy_with_parent() throws Exception { - userSessionRule.login("obiwan").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); - - String fromProfileKey = "xoo-sonar-way-23456"; - String toName = "Other Sonar Way"; - - when(qProfileCopier.copyToName(fromProfileKey, toName)).thenReturn( - QualityProfileDto.createFor("xoo-other-sonar-way-12345") - .setName(toName) - .setLanguage("xoo") - .setParentKee("xoo-parent-profile-01324")); - - tester.newPostRequest("api/qualityprofiles", "copy") - .setParam("fromKey", fromProfileKey) - .setParam("toName", toName) - .execute().assertJson(getClass(), "copy_with_parent.json"); - - verify(qProfileCopier).copyToName(fromProfileKey, toName); - } - - @Test(expected = IllegalArgumentException.class) - public void fail_on_missing_key() throws Exception { - userSessionRule.login("obiwan").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); - - tester.newPostRequest("api/qualityprofiles", "copy") - .setParam("name", "Other Sonar Way") - .execute(); - } - - @Test(expected = IllegalArgumentException.class) - public void fail_on_missing_name() throws Exception { - userSessionRule.login("obiwan").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); - - tester.newPostRequest("api/qualityprofiles", "copy") - .setParam("key", "sonar-way-xoo1-13245") - .execute(); - } - - @Test(expected = ForbiddenException.class) - public void fail_on_missing_permission() throws Exception { - userSessionRule.login("obiwan"); - - tester.newPostRequest("api/qualityprofiles", "copy") - .setParam("key", "sonar-way-xoo1-13245") - .setParam("name", "Hey look I am not quality profile admin!") - .execute(); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileCreateActionMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileCreateActionMediumTest.java deleted file mode 100644 index d0c187dd61f..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileCreateActionMediumTest.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * 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.qualityprofile.ws; - -import org.junit.After; -import org.junit.Before; -import org.junit.ClassRule; -import org.junit.Rule; -import org.junit.Test; -import org.sonar.core.permission.GlobalPermissions; -import org.sonar.core.persistence.DbSession; -import org.sonar.server.db.DbClient; -import org.sonar.server.exceptions.BadRequestException; -import org.sonar.server.qualityprofile.QProfileExporters; -import org.sonar.server.qualityprofile.QProfileExportersTest.StandardExporter; -import org.sonar.server.qualityprofile.QProfileExportersTest.XooExporter; -import org.sonar.server.qualityprofile.QProfileExportersTest.XooProfileDefinition; -import org.sonar.server.qualityprofile.QProfileExportersTest.XooProfileImporter; -import org.sonar.server.qualityprofile.QProfileExportersTest.XooProfileImporterWithError; -import org.sonar.server.qualityprofile.QProfileExportersTest.XooProfileImporterWithMessages; -import org.sonar.server.qualityprofile.QProfileExportersTest.XooRulesDefinition; -import org.sonar.server.qualityprofile.QProfileLoader; -import org.sonar.server.tester.ServerTester; -import org.sonar.server.tester.UserSessionRule; -import org.sonar.server.ws.WsTester; - -public class QProfileCreateActionMediumTest { - - // TODO Replace with simpler test with DbTester / EsTester after removal of DaoV2 - @ClassRule - public static ServerTester tester = new ServerTester().addXoo().addComponents( - XooRulesDefinition.class, XooProfileDefinition.class, - XooExporter.class, StandardExporter.class, - XooProfileImporter.class, XooProfileImporterWithMessages.class, XooProfileImporterWithError.class); - @Rule - public UserSessionRule userSessionRule = UserSessionRule.forServerTester(tester); - - DbClient db; - DbSession dbSession; - QProfileExporters exporters; - QProfileLoader loader; - WsTester wsTester; - - @Before - public void before() { - db = tester.get(DbClient.class); - dbSession = db.openSession(false); - exporters = tester.get(QProfileExporters.class); - loader = tester.get(QProfileLoader.class); - wsTester = new WsTester(tester.get(QProfilesWs.class)); - } - - @After - public void after() { - dbSession.close(); - } - - @Test - public void create_nominal() throws Exception { - userSessionRule.login("obiwan").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); - - wsTester.newPostRequest("api/qualityprofiles", "create") - .setParam("backup_XooProfileImporter", "a value for xoo importer") - .setParam("language", "xoo") - .setParam("name", "My New Profile") - .execute().assertJson(this.getClass(), "create-nominal.json"); - } - - @Test - public void create_with_messages() throws Exception { - userSessionRule.login("obiwan").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); - - wsTester.newPostRequest("api/qualityprofiles", "create") - .setParam("backup_XooProfileImporter", "a value for xoo importer") - .setParam("backup_XooProfileImporterWithMessages", "this will generate some messages") - .setParam("language", "xoo") - .setParam("name", "My Other Profile") - .execute().assertJson(this.getClass(), "create-with-messages.json"); - } - - @Test(expected = BadRequestException.class) - public void fail_on_error_from_importer() throws Exception { - userSessionRule.login("obiwan").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); - - wsTester.newPostRequest("api/qualityprofiles", "create") - .setParam("backup_XooProfileImporter", "a value for xoo importer") - .setParam("backup_XooProfileImporterWithError", "this will fail") - .setParam("language", "xoo") - .setParam("name", "Error In Importer") - .execute(); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileCreateActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileCreateActionTest.java deleted file mode 100644 index d3085347f13..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileCreateActionTest.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * 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.qualityprofile.ws; - -import org.junit.ClassRule; -import org.junit.Rule; -import org.junit.Test; -import org.sonar.api.server.ws.WebService.Action; -import org.sonar.api.utils.System2; -import org.sonar.core.permission.GlobalPermissions; -import org.sonar.core.persistence.DbTester; -import org.sonar.core.qualityprofile.db.QualityProfileDao; -import org.sonar.server.db.DbClient; -import org.sonar.server.language.LanguageTesting; -import org.sonar.server.qualityprofile.QProfileFactory; -import org.sonar.server.tester.UserSessionRule; -import org.sonar.server.ws.WsTester; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; - -public class QProfileCreateActionTest { - - @ClassRule - public static final DbTester db = new DbTester(); - @Rule - public UserSessionRule userSessionRule = UserSessionRule.standalone(); - - @Test - public void should_not_fail_on_no_importers() throws Exception { - QualityProfileDao profileDao = new QualityProfileDao(db.myBatis(), mock(System2.class)); - DbClient dbClient = new DbClient(db.database(), db.myBatis(), profileDao); - - String xooKey = "xoo"; - WsTester wsTester = new WsTester(new QProfilesWs( - mock(RuleActivationActions.class), mock(BulkRuleActivationActions.class), mock(ProjectAssociationActions.class), - new QProfileCreateAction(dbClient, new QProfileFactory(dbClient), null, LanguageTesting.newLanguages(xooKey), userSessionRule))); - - Action create = wsTester.controller("api/qualityprofiles").action("create"); - assertThat(create.params()).hasSize(2); - - userSessionRule.login("anakin").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); - - wsTester.newPostRequest("api/qualityprofiles", "create") - .setParam("language", xooKey).setParam("name", "Yeehaw!").execute().assertJson(getClass(), "create-no-importer.json"); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileDeleteActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileDeleteActionTest.java deleted file mode 100644 index c7ac2685824..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileDeleteActionTest.java +++ /dev/null @@ -1,167 +0,0 @@ -/* - * 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.qualityprofile.ws; - -import org.junit.After; -import org.junit.Before; -import org.junit.ClassRule; -import org.junit.Rule; -import org.junit.Test; -import org.sonar.api.resources.Language; -import org.sonar.api.resources.Languages; -import org.sonar.api.utils.System2; -import org.sonar.core.component.ComponentDto; -import org.sonar.core.permission.GlobalPermissions; -import org.sonar.core.persistence.DbSession; -import org.sonar.core.persistence.DbTester; -import org.sonar.core.qualityprofile.db.QualityProfileDao; -import org.sonar.core.qualityprofile.db.QualityProfileDto; -import org.sonar.server.component.ComponentTesting; -import org.sonar.server.component.db.ComponentDao; -import org.sonar.server.db.DbClient; -import org.sonar.server.exceptions.ForbiddenException; -import org.sonar.server.exceptions.NotFoundException; -import org.sonar.server.language.LanguageTesting; -import org.sonar.server.qualityprofile.QProfileFactory; -import org.sonar.server.qualityprofile.db.ActiveRuleDao; -import org.sonar.server.rule.db.RuleDao; -import org.sonar.server.tester.UserSessionRule; -import org.sonar.server.ws.WsTester; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; - -public class QProfileDeleteActionTest { - - @ClassRule - public static DbTester dbTester = new DbTester(); - @Rule - public UserSessionRule userSessionRule = UserSessionRule.standalone(); - - private DbClient dbClient; - - private QualityProfileDao qualityProfileDao; - - private ComponentDao componentDao; - - private Language xoo1, xoo2; - - private WsTester tester; - - private DbSession session; - - System2 system2 = mock(System2.class); - - @Before - public void setUp() { - dbTester.truncateTables(); - qualityProfileDao = new QualityProfileDao(dbTester.myBatis(), mock(System2.class)); - componentDao = new ComponentDao(); - - dbClient = new DbClient(dbTester.database(), dbTester.myBatis(), qualityProfileDao, new ActiveRuleDao(qualityProfileDao, new RuleDao(system2), system2)); - session = dbClient.openSession(false); - - xoo1 = LanguageTesting.newLanguage("xoo1"); - xoo2 = LanguageTesting.newLanguage("xoo2"); - - tester = new WsTester(new QProfilesWs( - mock(RuleActivationActions.class), - mock(BulkRuleActivationActions.class), - mock(ProjectAssociationActions.class), - new QProfileDeleteAction(new Languages(xoo1, xoo2), new QProfileFactory(dbClient), dbClient, userSessionRule))); - } - - @After - public void teadDown() { - session.close(); - } - - @Test - public void delete_nominal_with_key() throws Exception { - String profileKey = "sonar-way-xoo1-12345"; - - ComponentDto project = ComponentTesting.newProjectDto("polop"); - componentDao.insert(session, project); - qualityProfileDao.insert(session, QualityProfileDto.createFor(profileKey).setLanguage(xoo1.getKey()).setName("Sonar way")); - qualityProfileDao.insertProjectProfileAssociation(project.uuid(), profileKey, session); - session.commit(); - - userSessionRule.login("obiwan").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); - - tester.newPostRequest("api/qualityprofiles", "delete").setParam("profileKey", "sonar-way-xoo1-12345").execute().assertNoContent(); - - assertThat(qualityProfileDao.getByKey(session, "sonar-way-xoo1-12345")).isNull(); - assertThat(qualityProfileDao.selectProjects("Sonar way", xoo1.getName())).isEmpty(); - } - - @Test - public void delete_nominal_with_language_and_name() throws Exception { - String profileKey = "sonar-way-xoo1-12345"; - - ComponentDto project = ComponentTesting.newProjectDto("polop"); - componentDao.insert(session, project); - qualityProfileDao.insert(session, QualityProfileDto.createFor(profileKey).setLanguage(xoo1.getKey()).setName("Sonar way")); - qualityProfileDao.insertProjectProfileAssociation(project.uuid(), profileKey, session); - session.commit(); - - userSessionRule.login("obiwan").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); - - tester.newPostRequest("api/qualityprofiles", "delete").setParam("profileName", "Sonar way").setParam("language", xoo1.getKey()).execute().assertNoContent(); - - assertThat(qualityProfileDao.getByKey(session, "sonar-way-xoo1-12345")).isNull(); - assertThat(qualityProfileDao.selectProjects("Sonar way", xoo1.getName())).isEmpty(); - } - - @Test(expected = ForbiddenException.class) - public void fail_on_missing_permission() throws Exception { - userSessionRule.login("obiwan"); - tester.newPostRequest("api/qualityprofiles", "delete").execute(); - } - - @Test(expected = IllegalArgumentException.class) - public void fail_on_missing_arguments() throws Exception { - userSessionRule.login("obiwan").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); - tester.newPostRequest("api/qualityprofiles", "delete").execute(); - } - - @Test(expected = IllegalArgumentException.class) - public void fail_on_missing_language() throws Exception { - userSessionRule.login("obiwan").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); - tester.newPostRequest("api/qualityprofiles", "delete").setParam("profileName", "Polop").execute(); - } - - @Test(expected = IllegalArgumentException.class) - public void fail_on_missing_name() throws Exception { - userSessionRule.login("obiwan").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); - tester.newPostRequest("api/qualityprofiles", "delete").setParam("language", xoo1.getKey()).execute(); - } - - @Test(expected = IllegalArgumentException.class) - public void fail_on_too_many_arguments() throws Exception { - userSessionRule.login("obiwan").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); - tester.newPostRequest("api/qualityprofiles", "delete").setParam("profileName", "Polop").setParam("language", xoo1.getKey()).setParam("profileKey", "polop").execute(); - } - - @Test(expected = NotFoundException.class) - public void fail_on_unexisting_profile() throws Exception { - userSessionRule.login("obiwan").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); - tester.newPostRequest("api/qualityprofiles", "delete").setParam("profileName", "Polop").setParam("language", xoo1.getKey()).execute(); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileExportActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileExportActionTest.java deleted file mode 100644 index d145d0f7421..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileExportActionTest.java +++ /dev/null @@ -1,202 +0,0 @@ -/* - * 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.qualityprofile.ws; - -import com.google.common.collect.Sets; -import org.apache.commons.lang.StringUtils; -import org.junit.After; -import org.junit.Before; -import org.junit.ClassRule; -import org.junit.Rule; -import org.junit.Test; -import org.mockito.Matchers; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; -import org.sonar.api.profiles.ProfileExporter; -import org.sonar.api.profiles.RulesProfile; -import org.sonar.api.server.ws.WebService.Action; -import org.sonar.api.utils.System2; -import org.sonar.core.persistence.DbSession; -import org.sonar.core.persistence.DbTester; -import org.sonar.core.qualityprofile.db.QualityProfileDao; -import org.sonar.core.qualityprofile.db.QualityProfileDto; -import org.sonar.server.db.DbClient; -import org.sonar.server.exceptions.NotFoundException; -import org.sonar.server.language.LanguageTesting; -import org.sonar.server.qualityprofile.*; -import org.sonar.server.qualityprofile.index.ActiveRuleIndex; -import org.sonar.server.search.IndexClient; -import org.sonar.server.tester.UserSessionRule; -import org.sonar.server.ws.WsTester; -import org.sonar.server.ws.WsTester.Result; - -import java.io.IOException; -import java.io.Writer; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -public class QProfileExportActionTest { - - @ClassRule - public static final DbTester db = new DbTester(); - @Rule - public UserSessionRule userSessionRule = UserSessionRule.standalone(); - - WsTester wsTester; - - QualityProfileDao qualityProfileDao; - - DbClient dbClient; - - DbSession session; - - QProfileBackuper backuper; - - QProfileExporters exporters; - - @Before - public void before() { - qualityProfileDao = new QualityProfileDao(db.myBatis(), mock(System2.class)); - dbClient = new DbClient(db.database(), db.myBatis(), qualityProfileDao); - session = dbClient.openSession(false); - backuper = mock(QProfileBackuper.class); - - db.truncateTables(); - - ProfileExporter exporter1 = newExporter("polop"); - ProfileExporter exporter2 = newExporter("palap"); - - IndexClient indexClient = mock(IndexClient.class); - ActiveRuleIndex activeRuleIndex = mock(ActiveRuleIndex.class); - when(activeRuleIndex.findByProfile(Matchers.anyString())).thenReturn(Sets.newHashSet().iterator()); - - when(indexClient.get(ActiveRuleIndex.class)).thenReturn(activeRuleIndex); - exporters = new QProfileExporters(new QProfileLoader(dbClient, indexClient, userSessionRule), null, null, new ProfileExporter[] {exporter1, exporter2}, null); - wsTester = new WsTester(new QProfilesWs(mock(RuleActivationActions.class), - mock(BulkRuleActivationActions.class), - mock(ProjectAssociationActions.class), - new QProfileExportAction(dbClient, new QProfileFactory(dbClient), backuper, exporters, LanguageTesting.newLanguages("xoo")))); - } - - @After - public void after() { - session.close(); - } - - private ProfileExporter newExporter(final String key) { - return new ProfileExporter(key, StringUtils.capitalize(key)) { - @Override - public String getMimeType() { - return "text/plain+" + key; - } - - @Override - public void exportProfile(RulesProfile profile, Writer writer) { - try { - writer.write(String.format("Profile %s exported by %s", profile.getName(), key)); - } catch (IOException ioe) { - throw new RuntimeException(ioe); - } - } - }; - } - - @Test - public void export_without_format() throws Exception { - QualityProfileDto profile = QProfileTesting.newXooP1(); - qualityProfileDao.insert(session, profile); - session.commit(); - - doAnswer(new Answer() { - @Override - public Void answer(InvocationOnMock invocation) throws Throwable { - invocation.getArgumentAt(1, Writer.class).write("As exported by SQ !"); - return null; - } - }).when(backuper).backup(Matchers.eq(profile.getKey()), Matchers.any(Writer.class)); - - Result result = wsTester.newGetRequest("api/qualityprofiles", "export").setParam("language", profile.getLanguage()).setParam("name", profile.getName()).execute(); - - assertThat(result.outputAsString()).isEqualTo("As exported by SQ !"); - } - - @Test - public void export_with_format() throws Exception { - QualityProfileDto profile = QProfileTesting.newXooP1(); - qualityProfileDao.insert(session, profile); - session.commit(); - - Result result = wsTester.newGetRequest("api/qualityprofiles", "export") - .setParam("language", profile.getLanguage()).setParam("name", profile.getName()).setParam("exporterKey", "polop").execute(); - - assertThat(result.outputAsString()).isEqualTo("Profile " + profile.getName() + " exported by polop"); - } - - @Test - public void export_default_profile() throws Exception { - QualityProfileDto profile1 = QProfileTesting.newXooP1(); - QualityProfileDto profile2 = QProfileTesting.newXooP2().setDefault(true); - qualityProfileDao.insert(session, profile1, profile2); - session.commit(); - - Result result = wsTester.newGetRequest("api/qualityprofiles", "export") - .setParam("language", "xoo").setParam("exporterKey", "polop").execute(); - - assertThat(result.outputAsString()).isEqualTo("Profile " + profile2.getName() + " exported by polop"); - } - - @Test(expected = NotFoundException.class) - public void fail_on_unknown_profile() throws Exception { - wsTester.newGetRequest("api/qualityprofiles", "export") - .setParam("language", "xoo").setParam("exporterKey", "polop").execute(); - } - - @Test(expected = IllegalArgumentException.class) - public void fail_on_unknown_exporter() throws Exception { - QualityProfileDto profile = QProfileTesting.newXooP1(); - qualityProfileDao.insert(session, profile); - session.commit(); - - wsTester.newGetRequest("api/qualityprofiles", "export") - .setParam("language", "xoo").setParam("exporterKey", "unknown").execute(); - } - - @Test - public void do_not_fail_when_no_exporters() throws Exception { - QProfileExporters myExporters = new QProfileExporters(null, null, null, new ProfileExporter[0], null); - WsTester myWsTester = new WsTester(new QProfilesWs(mock(RuleActivationActions.class), - mock(BulkRuleActivationActions.class), - mock(ProjectAssociationActions.class), - new QProfileExportAction(dbClient, new QProfileFactory(dbClient), backuper, myExporters, LanguageTesting.newLanguages("xoo")))); - - Action export = myWsTester.controller("api/qualityprofiles").action("export"); - assertThat(export.params()).hasSize(2); - - QualityProfileDto profile = QProfileTesting.newXooP1(); - qualityProfileDao.insert(session, profile); - session.commit(); - - myWsTester.newGetRequest("api/qualityprofiles", "export").setParam("language", "xoo").setParam("name", profile.getName()).execute(); - - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileExportersActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileExportersActionTest.java deleted file mode 100644 index 9e3c4d3190c..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileExportersActionTest.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * 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.qualityprofile.ws; - -import org.junit.Test; -import org.sonar.api.profiles.ProfileExporter; -import org.sonar.api.profiles.RulesProfile; -import org.sonar.server.ws.WsTester; - -import java.io.Writer; - -import static org.mockito.Mockito.mock; - -public class QProfileExportersActionTest { - - @Test - public void importers_nominal() throws Exception { - WsTester wsTester = new WsTester(new QProfilesWs( - mock(RuleActivationActions.class), mock(BulkRuleActivationActions.class), mock(ProjectAssociationActions.class), - new QProfileExportersAction(createExporters()))); - - wsTester.newGetRequest("api/qualityprofiles", "exporters").execute().assertJson(getClass(), "exporters.json"); - } - - private ProfileExporter[] createExporters() { - class NoopImporter extends ProfileExporter { - private NoopImporter(String key, String name, String... languages) { - super(key, name); - setSupportedLanguages(languages); - } - - @Override - public void exportProfile(RulesProfile profile, Writer writer) { - // Nothing - } - - } - return new ProfileExporter[] { - new NoopImporter("findbugs", "FindBugs", "java"), - new NoopImporter("jslint", "JS Lint", "js"), - new NoopImporter("vaadin", "Vaadin", "java", "js") - }; - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileImportersActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileImportersActionTest.java deleted file mode 100644 index dfd16c7d012..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileImportersActionTest.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * 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.qualityprofile.ws; - -import org.junit.Test; -import org.sonar.api.profiles.ProfileImporter; -import org.sonar.api.profiles.RulesProfile; -import org.sonar.api.utils.ValidationMessages; -import org.sonar.server.ws.WsTester; - -import java.io.Reader; - -import static org.mockito.Mockito.mock; - -public class QProfileImportersActionTest { - - @Test - public void importers_nominal() throws Exception { - WsTester wsTester = new WsTester(new QProfilesWs( - mock(RuleActivationActions.class), mock(BulkRuleActivationActions.class), mock(ProjectAssociationActions.class), - new QProfileImportersAction(createImporters()))); - - wsTester.newGetRequest("api/qualityprofiles", "importers").execute().assertJson(getClass(), "importers.json"); - } - - private ProfileImporter[] createImporters() { - class NoopImporter extends ProfileImporter { - private NoopImporter(String key, String name, String... languages) { - super(key, name); - setSupportedLanguages(languages); - } - - @Override - public RulesProfile importProfile(Reader reader, ValidationMessages messages) { - return RulesProfile.create(); - } - - } - return new ProfileImporter[] { - new NoopImporter("findbugs", "FindBugs", "java"), - new NoopImporter("jslint", "JS Lint", "js"), - new NoopImporter("vaadin", "Vaadin", "java", "js") - }; - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileInheritanceActionMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileInheritanceActionMediumTest.java deleted file mode 100644 index 58dcf278b0b..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileInheritanceActionMediumTest.java +++ /dev/null @@ -1,148 +0,0 @@ -/* - * 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.qualityprofile.ws; - -import org.junit.After; -import org.junit.Before; -import org.junit.ClassRule; -import org.junit.Rule; -import org.junit.Test; -import org.sonar.api.rule.RuleKey; -import org.sonar.api.rule.RuleStatus; -import org.sonar.api.rule.Severity; -import org.sonar.core.persistence.DbSession; -import org.sonar.core.qualityprofile.db.ActiveRuleDto; -import org.sonar.core.qualityprofile.db.QualityProfileDto; -import org.sonar.core.rule.RuleDto; -import org.sonar.server.db.DbClient; -import org.sonar.server.exceptions.NotFoundException; -import org.sonar.server.qualityprofile.QProfileName; -import org.sonar.server.qualityprofile.QProfileTesting; -import org.sonar.server.qualityprofile.RuleActivation; -import org.sonar.server.qualityprofile.RuleActivator; -import org.sonar.server.tester.ServerTester; -import org.sonar.server.tester.UserSessionRule; -import org.sonar.server.ws.WsTester; - -public class QProfileInheritanceActionMediumTest { - - @ClassRule - public static final ServerTester tester = new ServerTester(); - @Rule - public UserSessionRule userSessionRule = UserSessionRule.forServerTester(tester); - - private WsTester wsTester; - - private DbClient db; - - private DbSession session; - - @Before - public void setUp() { - tester.clearDbAndIndexes(); - db = tester.get(DbClient.class); - session = db.openSession(false); - - wsTester = new WsTester(tester.get(QProfilesWs.class)); - } - - @After - public void tearDown() { - session.close(); - } - - @Test - public void inheritance_nominal() throws Exception { - RuleDto rule1 = createRule("xoo", "rule1"); - RuleDto rule2 = createRule("xoo", "rule2"); - RuleDto rule3 = createRule("xoo", "rule3"); - - /* - * groupWide (2) <- companyWide (2) <- buWide (2, 1 overriding) <- (forProject1 (2), forProject2 (2)) - */ - QualityProfileDto groupWide = createProfile("xoo", "My Group Profile", "xoo-my-group-profile-01234"); - createActiveRule(rule1, groupWide); - createActiveRule(rule2, groupWide); - session.commit(); - - QualityProfileDto companyWide = createProfile("xoo", "My Company Profile", "xoo-my-company-profile-12345"); - setParent(groupWide, companyWide); - - QualityProfileDto buWide = createProfile("xoo", "My BU Profile", "xoo-my-bu-profile-23456"); - setParent(companyWide, buWide); - overrideActiveRuleSeverity(rule1, buWide, Severity.CRITICAL); - - QualityProfileDto forProject1 = createProfile("xoo", "For Project One", "xoo-for-project-one-34567"); - setParent(buWide, forProject1); - createActiveRule(rule3, forProject1); - session.commit(); - - QualityProfileDto forProject2 = createProfile("xoo", "For Project Two", "xoo-for-project-two-45678"); - setParent(buWide, forProject2); - overrideActiveRuleSeverity(rule2, forProject2, Severity.CRITICAL); - - wsTester.newGetRequest("api/qualityprofiles", "inheritance").setParam("profileKey", buWide.getKee()).execute().assertJson(getClass(), "inheritance-buWide.json"); - } - - @Test - public void inheritance_no_family() throws Exception { - // Simple profile, no parent, no child - QualityProfileDto remi = createProfile("xoo", "Nobodys Boy", "xoo-nobody-s-boy-01234"); - - wsTester.newGetRequest("api/qualityprofiles", "inheritance").setParam("profileKey", remi.getKee()).execute().assertJson(getClass(), "inheritance-simple.json"); - } - - @Test(expected = NotFoundException.class) - public void fail_if_not_found() throws Exception { - wsTester.newGetRequest("api/qualityprofiles", "inheritance").setParam("profileKey", "polop").execute(); - } - - private QualityProfileDto createProfile(String lang, String name, String key) { - QualityProfileDto profile = QProfileTesting.newDto(new QProfileName(lang, name), key); - db.qualityProfileDao().insert(session, profile); - session.commit(); - return profile; - } - - private void setParent(QualityProfileDto profile, QualityProfileDto parent) { - tester.get(RuleActivator.class).setParent(parent.getKey(), profile.getKey()); - } - - private RuleDto createRule(String lang, String id) { - RuleDto rule = RuleDto.createFor(RuleKey.of("blah", id)) - .setLanguage(lang) - .setSeverity(Severity.BLOCKER) - .setStatus(RuleStatus.READY); - db.ruleDao().insert(session, rule); - return rule; - } - - private ActiveRuleDto createActiveRule(RuleDto rule, QualityProfileDto profile) { - ActiveRuleDto activeRule = ActiveRuleDto.createFor(profile, rule) - .setSeverity(rule.getSeverityString()); - db.activeRuleDao().insert(session, activeRule); - return activeRule; - } - - private void overrideActiveRuleSeverity(RuleDto rule, QualityProfileDto profile, String severity) { - tester.get(RuleActivator.class).activate(session, new RuleActivation(rule.getKey()).setSeverity(severity), profile.getKey()); - session.commit(); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileProjectsActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileProjectsActionTest.java deleted file mode 100644 index fd05411c6a0..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileProjectsActionTest.java +++ /dev/null @@ -1,240 +0,0 @@ -/* - * 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.qualityprofile.ws; - -import org.junit.After; -import org.junit.Before; -import org.junit.ClassRule; -import org.junit.Rule; -import org.junit.Test; -import org.junit.experimental.categories.Category; -import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; -import org.sonar.core.component.ComponentDto; -import org.sonar.core.persistence.DbSession; -import org.sonar.core.persistence.DbTester; -import org.sonar.core.qualityprofile.db.QualityProfileDao; -import org.sonar.core.qualityprofile.db.QualityProfileDto; -import org.sonar.core.user.AuthorizationDao; -import org.sonar.core.user.GroupRoleDto; -import org.sonar.core.user.RoleDao; -import org.sonar.core.user.UserDto; -import org.sonar.core.user.UserRoleDto; -import org.sonar.server.component.ComponentTesting; -import org.sonar.server.component.db.ComponentDao; -import org.sonar.server.db.DbClient; -import org.sonar.server.exceptions.NotFoundException; -import org.sonar.server.qualityprofile.QProfileTesting; -import org.sonar.server.tester.UserSessionRule; -import org.sonar.server.user.db.UserDao; -import org.sonar.server.ws.WsTester; -import org.sonar.server.ws.WsTester.TestRequest; -import org.sonar.test.DbTests; - -import static org.mockito.Mockito.mock; - -@Category(DbTests.class) -public class QProfileProjectsActionTest { - - @ClassRule - public static final DbTester dbTester = new DbTester(); - @Rule - public UserSessionRule userSessionRule = UserSessionRule.standalone(); - - private WsTester wsTester; - - private DbClient dbClient; - - private DbSession session; - - private QualityProfileDto xooP1, xooP2; - - private ComponentDto project1, project2, project3, project4; - - private Long userId = 42L; - - private RoleDao roleDao; - - System2 system2 = mock(System2.class); - - @Before - public void setUp() { - dbTester.truncateTables(); - dbClient = new DbClient(dbTester.database(), dbTester.myBatis(), - new QualityProfileDao(dbTester.myBatis(), system2), - new ComponentDao(), - new AuthorizationDao(dbTester.myBatis())); - roleDao = new RoleDao(); - session = dbClient.openSession(false); - - wsTester = new WsTester(new QProfilesWs( - mock(RuleActivationActions.class), - mock(BulkRuleActivationActions.class), - mock(ProjectAssociationActions.class), - new QProfileProjectsAction(dbClient, userSessionRule))); - - userSessionRule.login("obiwan").setUserId(userId.intValue()); - new UserDao(dbTester.myBatis(), mock(System2.class)) - .insert(session, new UserDto() - .setActive(true) - .setId(userId) - .setLogin("obiwan")); - - createProfiles(); - - session.commit(); - } - - @After - public void tearDown() { - session.close(); - } - - @Test - public void should_list_authorized_projects_only() throws Exception { - project1 = newProject("ABCD", "Project One"); - project2 = newProject("BCDE", "Project Two"); - dbClient.componentDao().insert(session, project1, project2); - - // user only sees project1 - roleDao.insertUserRole(new UserRoleDto().setUserId(userId).setResourceId(project1.getId()).setRole(UserRole.USER), session); - - associateProjectsWithProfile(session, xooP1, project1, project2); - - session.commit(); - - newRequest().setParam("key", xooP1.getKey()).setParam("selected", "selected").execute().assertJson(this.getClass(), "authorized_selected.json"); - } - - @Test - public void should_paginate() throws Exception { - project1 = newProject("ABCD", "Project One"); - project2 = newProject("BCDE", "Project Two"); - project3 = newProject("CDEF", "Project Three"); - project4 = newProject("DEFA", "Project Four"); - dbClient.componentDao().insert(session, project1, project2, project3, project4); - - addBrowsePermissionToAnyone(session, project1, project2, project3, project4); - - associateProjectsWithProfile(session, xooP1, project1, project2, project3, project4); - - session.commit(); - - newRequest().setParam("key", xooP1.getKey()).setParam("selected", "selected").setParam("pageSize", "2") - .execute().assertJson(this.getClass(), "selected_page1.json"); - newRequest().setParam("key", xooP1.getKey()).setParam("selected", "selected").setParam("pageSize", "2").setParam("page", "2") - .execute().assertJson(this.getClass(), "selected_page2.json"); - newRequest().setParam("key", xooP1.getKey()).setParam("selected", "selected").setParam("pageSize", "2").setParam("page", "3") - .execute().assertJson(this.getClass(), "empty.json"); - newRequest().setParam("key", xooP1.getKey()).setParam("selected", "selected").setParam("pageSize", "2").setParam("page", "4") - .execute().assertJson(this.getClass(), "empty.json"); - - newRequest().setParam("key", xooP1.getKey()).setParam("selected", "selected").setParam("pageSize", "3").setParam("page", "1") - .execute().assertJson(this.getClass(), "selected_ps3_page1.json"); - newRequest().setParam("key", xooP1.getKey()).setParam("selected", "selected").setParam("pageSize", "3").setParam("page", "2") - .execute().assertJson(this.getClass(), "selected_ps3_page2.json"); - newRequest().setParam("key", xooP1.getKey()).setParam("selected", "selected").setParam("pageSize", "3").setParam("page", "3") - .execute().assertJson(this.getClass(), "empty.json"); - } - - @Test - public void should_show_unselected() throws Exception { - project1 = newProject("ABCD", "Project One"); - project2 = newProject("BCDE", "Project Two"); - project3 = newProject("CDEF", "Project Three"); - project4 = newProject("DEFA", "Project Four"); - dbClient.componentDao().insert(session, project1, project2, project3, project4); - - addBrowsePermissionToAnyone(session, project1, project2, project3, project4); - - associateProjectsWithProfile(session, xooP1, project1, project2); - - session.commit(); - - newRequest().setParam("key", xooP1.getKey()).setParam("selected", "deselected").execute().assertJson(this.getClass(), "deselected.json"); - } - - @Test - public void should_show_all() throws Exception { - project1 = newProject("ABCD", "Project One"); - project2 = newProject("BCDE", "Project Two"); - project3 = newProject("CDEF", "Project Three"); - project4 = newProject("DEFA", "Project Four"); - dbClient.componentDao().insert(session, project1, project2, project3, project4); - - addBrowsePermissionToAnyone(session, project1, project2, project3, project4); - - associateProjectsWithProfile(session, xooP1, project1, project2); - // project3 is associated with P2, must appear as not associated with xooP1 - associateProjectsWithProfile(session, xooP2, project3); - - session.commit(); - - newRequest().setParam("key", xooP1.getKey()).setParam("selected", "all").execute().assertJson(this.getClass(), "all.json"); - } - - @Test - public void should_filter_on_name() throws Exception { - project1 = newProject("ABCD", "Project One"); - project2 = newProject("BCDE", "Project Two"); - project3 = newProject("CDEF", "Project Three"); - project4 = newProject("DEFA", "Project Four"); - dbClient.componentDao().insert(session, project1, project2, project3, project4); - - addBrowsePermissionToAnyone(session, project1, project2, project3, project4); - - associateProjectsWithProfile(session, xooP1, project1, project2); - - session.commit(); - - newRequest().setParam("key", xooP1.getKey()).setParam("selected", "all").setParam("query", "project t").execute().assertJson(this.getClass(), "all_filtered.json"); - } - - @Test(expected = NotFoundException.class) - public void should_fail_on_nonexistent_profile() throws Exception { - newRequest().setParam("key", "unknown").setParam("selected", "all").execute(); - } - - private void createProfiles() { - xooP1 = QProfileTesting.newXooP1(); - xooP2 = QProfileTesting.newXooP2(); - dbClient.qualityProfileDao().insert(session, xooP1, xooP2); - } - - private TestRequest newRequest() { - return wsTester.newGetRequest("api/qualityprofiles", "projects"); - } - - private ComponentDto newProject(String uuid, String name) { - return ComponentTesting.newProjectDto(uuid).setName(name); - } - - private void addBrowsePermissionToAnyone(DbSession session, ComponentDto... projects) { - for (ComponentDto project : projects) { - roleDao.insertGroupRole(new GroupRoleDto().setGroupId(null).setResourceId(project.getId()).setRole(UserRole.USER), session); - } - } - - private void associateProjectsWithProfile(DbSession session, QualityProfileDto profile, ComponentDto... projects) { - for (ComponentDto project : projects) { - dbClient.qualityProfileDao().insertProjectProfileAssociation(project.uuid(), profile.getKey(), session); - } - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileRenameActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileRenameActionTest.java deleted file mode 100644 index fc6a0536b22..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileRenameActionTest.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * 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.qualityprofile.ws; - -import org.junit.After; -import org.junit.Before; -import org.junit.ClassRule; -import org.junit.Rule; -import org.junit.Test; -import org.sonar.api.utils.System2; -import org.sonar.core.permission.GlobalPermissions; -import org.sonar.core.persistence.DbSession; -import org.sonar.core.persistence.DbTester; -import org.sonar.core.qualityprofile.db.QualityProfileDao; -import org.sonar.core.qualityprofile.db.QualityProfileDto; -import org.sonar.server.db.DbClient; -import org.sonar.server.exceptions.BadRequestException; -import org.sonar.server.exceptions.ForbiddenException; -import org.sonar.server.qualityprofile.QProfileFactory; -import org.sonar.server.tester.UserSessionRule; -import org.sonar.server.ws.WsTester; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; - -public class QProfileRenameActionTest { - - @ClassRule - public static DbTester dbTester = new DbTester(); - @Rule - public UserSessionRule userSessionRule = UserSessionRule.standalone(); - - private DbClient dbClient; - - private QualityProfileDao qualityProfileDao; - - private String xoo1Key = "xoo1", xoo2Key = "xoo2"; - - private WsTester tester; - - private DbSession session; - - - @Before - public void setUp() { - dbTester.truncateTables(); - qualityProfileDao = new QualityProfileDao(dbTester.myBatis(), mock(System2.class)); - dbClient = new DbClient(dbTester.database(), dbTester.myBatis(), qualityProfileDao); - session = dbClient.openSession(false); - - createProfiles(); - - tester = new WsTester(new QProfilesWs( - mock(RuleActivationActions.class), - mock(BulkRuleActivationActions.class), - mock(ProjectAssociationActions.class), - new QProfileRenameAction(new QProfileFactory(dbClient), userSessionRule))); - } - - @After - public void tearDown() { - session.close(); - } - - @Test - public void rename_nominal() throws Exception { - userSessionRule.login("obiwan").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); - - tester.newPostRequest("api/qualityprofiles", "rename") - .setParam("key", "sonar-way-xoo2-23456") - .setParam("name", "Other Sonar Way") - .execute().assertNoContent(); - - assertThat(qualityProfileDao.getNonNullByKey(session, "sonar-way-xoo2-23456").getName()).isEqualTo("Other Sonar Way"); - } - - @Test(expected = BadRequestException.class) - public void do_nothing_on_conflict() throws Exception { - userSessionRule.login("obiwan").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); - - tester.newPostRequest("api/qualityprofiles", "rename") - .setParam("key", "sonar-way-xoo2-23456") - .setParam("name", "My Sonar way") - .execute(); - } - - @Test(expected = IllegalArgumentException.class) - public void fail_on_missing_key() throws Exception { - userSessionRule.login("obiwan").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); - - tester.newPostRequest("api/qualityprofiles", "rename") - .setParam("name", "Other Sonar Way") - .execute(); - } - - @Test(expected = IllegalArgumentException.class) - public void fail_on_missing_name() throws Exception { - userSessionRule.login("obiwan").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); - - tester.newPostRequest("api/qualityprofiles", "rename") - .setParam("key", "sonar-way-xoo1-13245") - .execute(); - } - - @Test(expected = ForbiddenException.class) - public void fail_on_missing_permission() throws Exception { - userSessionRule.login("obiwan"); - - tester.newPostRequest("api/qualityprofiles", "rename") - .setParam("key", "sonar-way-xoo1-13245") - .setParam("name", "Hey look I am not quality profile admin!") - .execute(); - } - - @Test(expected = IllegalArgumentException.class) - public void fail_on_unknown_profile() throws Exception { - userSessionRule.login("obiwan").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); - - tester.newPostRequest("api/qualityprofiles", "rename") - .setParam("key", "polop") - .setParam("name", "Uh oh, I don't know this profile") - .execute(); - } - - private void createProfiles() { - qualityProfileDao.insert(session, - QualityProfileDto.createFor("sonar-way-xoo1-12345").setLanguage(xoo1Key).setName("Sonar way").setDefault(true), - QualityProfileDto.createFor("sonar-way-xoo2-23456").setLanguage(xoo2Key).setName("Sonar way"), - QualityProfileDto.createFor("my-sonar-way-xoo2-34567").setLanguage(xoo2Key).setName("My Sonar way").setParentKee("sonar-way-xoo2-23456").setDefault(true) - ); - session.commit(); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileRestoreActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileRestoreActionTest.java deleted file mode 100644 index 4d538499782..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileRestoreActionTest.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * 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.qualityprofile.ws; - -import java.io.Reader; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; -import org.sonar.core.permission.GlobalPermissions; -import org.sonar.core.qualityprofile.db.QualityProfileDto; -import org.sonar.server.exceptions.ForbiddenException; -import org.sonar.server.language.LanguageTesting; -import org.sonar.server.qualityprofile.BulkChangeResult; -import org.sonar.server.qualityprofile.QProfileBackuper; -import org.sonar.server.qualityprofile.QProfileName; -import org.sonar.server.tester.UserSessionRule; -import org.sonar.server.ws.WsTester; - -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -@RunWith(MockitoJUnitRunner.class) -public class QProfileRestoreActionTest { - @Rule - public UserSessionRule userSessionRule = UserSessionRule.standalone(); - - // TODO Replace with proper DbTester + EsTester medium test once DaoV2 is removed - @Mock - private QProfileBackuper backuper; - - private WsTester tester; - - @Before - public void setUp() { - tester = new WsTester(new QProfilesWs( - mock(RuleActivationActions.class), - mock(BulkRuleActivationActions.class), - mock(ProjectAssociationActions.class), - new QProfileRestoreAction(backuper, LanguageTesting.newLanguages("xoo"), userSessionRule))); - } - - @Test - public void restore_profile() throws Exception { - userSessionRule.login("obiwan").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); - - QualityProfileDto profile = QualityProfileDto.createFor("xoo-sonar-way-12345") - .setDefault(false).setLanguage("xoo").setName("Sonar way"); - BulkChangeResult restoreResult = new BulkChangeResult(profile); - when(backuper.restore(any(Reader.class), (QProfileName) eq(null))).thenReturn(restoreResult); - - tester.newPostRequest("api/qualityprofiles", "restore").setParam("backup", "").execute() - .assertJson(getClass(), "restore_profile.json"); - verify(backuper).restore(any(Reader.class), (QProfileName) eq(null)); - } - - @Test(expected = IllegalArgumentException.class) - public void fail_on_missing_backup() throws Exception { - userSessionRule.login("obiwan").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); - - tester.newGetRequest("api/qualityprofiles", "restore").execute(); - } - - @Test(expected = ForbiddenException.class) - public void fail_on_misssing_permission() throws Exception { - userSessionRule.login("obiwan"); - - tester.newPostRequest("api/qualityprofiles", "restore").setParam("backup", "").execute(); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileRestoreBuiltInActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileRestoreBuiltInActionTest.java deleted file mode 100644 index 043a8b372c1..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileRestoreBuiltInActionTest.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * 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.qualityprofile.ws; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; -import org.sonar.api.i18n.I18n; -import org.sonar.server.qualityprofile.QProfileService; -import org.sonar.server.ws.WsTester; - -import static org.mockito.Mockito.mock; - -@RunWith(MockitoJUnitRunner.class) -public class QProfileRestoreBuiltInActionTest { - - @Mock - QProfileService profileService; - - @Mock - I18n i18n; - - WsTester tester; - - @Before - public void setUp() { - tester = new WsTester(new QProfilesWs( - mock(RuleActivationActions.class), - mock(BulkRuleActivationActions.class), - mock(ProjectAssociationActions.class), - new QProfileRestoreBuiltInAction(profileService))); - } - - @Test - public void return_empty_result_when_no_infos_or_warnings() throws Exception { - WsTester.TestRequest request = tester.newPostRequest("api/qualityprofiles", "restore_built_in").setParam("language", "java"); - request.execute().assertNoContent(); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileSearchActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileSearchActionTest.java deleted file mode 100644 index 4c13287ec35..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileSearchActionTest.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * 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.qualityprofile.ws; - -import com.google.common.collect.ImmutableMap; -import org.junit.After; -import org.junit.Before; -import org.junit.ClassRule; -import org.junit.Test; -import org.sonar.api.resources.Language; -import org.sonar.api.resources.Languages; -import org.sonar.api.utils.System2; -import org.sonar.core.persistence.DbSession; -import org.sonar.core.persistence.DbTester; -import org.sonar.core.qualityprofile.db.QualityProfileDao; -import org.sonar.core.qualityprofile.db.QualityProfileDto; -import org.sonar.server.component.ComponentTesting; -import org.sonar.server.component.db.ComponentDao; -import org.sonar.server.db.DbClient; -import org.sonar.server.language.LanguageTesting; -import org.sonar.server.qualityprofile.QProfileLoader; -import org.sonar.server.qualityprofile.QProfileLookup; -import org.sonar.server.ws.WsTester; - -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -public class QProfileSearchActionTest { - - @ClassRule - public static DbTester dbTester = new DbTester(); - - private DbClient dbClient; - - private QualityProfileDao qualityProfileDao; - - private Language xoo1, xoo2; - - private WsTester tester; - - private DbSession session; - - private QProfileLoader profileLoader; - - @Before - public void setUp() { - dbTester.truncateTables(); - qualityProfileDao = new QualityProfileDao(dbTester.myBatis(), mock(System2.class)); - dbClient = new DbClient(dbTester.database(), dbTester.myBatis(), qualityProfileDao); - session = dbClient.openSession(false); - - // TODO Replace with actual implementation after removal of DaoV2... - profileLoader = mock(QProfileLoader.class); - - xoo1 = LanguageTesting.newLanguage("xoo1"); - xoo2 = LanguageTesting.newLanguage("xoo2"); - - tester = new WsTester(new QProfilesWs( - mock(RuleActivationActions.class), - mock(BulkRuleActivationActions.class), - mock(ProjectAssociationActions.class), - new QProfileSearchAction(new Languages(xoo1, xoo2), new QProfileLookup(dbClient), profileLoader, qualityProfileDao))); - } - - @After - public void teadDown() { - session.close(); - } - - @Test - public void search_nominal() throws Exception { - when(profileLoader.countAllActiveRules()).thenReturn(ImmutableMap.of( - "sonar-way-xoo1-12345", 11L, - "my-sonar-way-xoo2-34567", 33L - )); - - qualityProfileDao.insert(session, - QualityProfileDto.createFor("sonar-way-xoo1-12345").setLanguage(xoo1.getKey()).setName("Sonar way").setDefault(true), - QualityProfileDto.createFor("sonar-way-xoo2-23456").setLanguage(xoo2.getKey()).setName("Sonar way"), - QualityProfileDto.createFor("my-sonar-way-xoo2-34567").setLanguage(xoo2.getKey()).setName("My Sonar way").setParentKee("sonar-way-xoo2-23456"), - QualityProfileDto.createFor("sonar-way-other-666").setLanguage("other").setName("Sonar way").setDefault(true) - ); - new ComponentDao().insert(session, - ComponentTesting.newProjectDto("project-uuid1"), - ComponentTesting.newProjectDto("project-uuid2")); - qualityProfileDao.insertProjectProfileAssociation("project-uuid1", "sonar-way-xoo2-23456", session); - qualityProfileDao.insertProjectProfileAssociation("project-uuid2", "sonar-way-xoo2-23456", session); - session.commit(); - - tester.newGetRequest("api/qualityprofiles", "search").execute().assertJson(this.getClass(), "search.json"); - } - - @Test - public void search_with_fields() throws Exception { - qualityProfileDao.insert(session, - QualityProfileDto.createFor("sonar-way-xoo1-12345").setLanguage(xoo1.getKey()).setName("Sonar way").setDefault(true), - QualityProfileDto.createFor("sonar-way-xoo2-23456").setLanguage(xoo2.getKey()).setName("Sonar way"), - QualityProfileDto.createFor("my-sonar-way-xoo2-34567").setLanguage(xoo2.getKey()).setName("My Sonar way").setParentKee("sonar-way-xoo2-23456") - ); - session.commit(); - - tester.newGetRequest("api/qualityprofiles", "search").setParam("f", "key,language").execute().assertJson(this.getClass(), "search_fields.json"); - } - - @Test(expected = IllegalArgumentException.class) - public void fail_on_unknown_fields() throws Exception { - tester.newGetRequest("api/qualityprofiles", "search").setParam("f", "polop").execute(); - } - - @Test - public void search_for_language() throws Exception { - qualityProfileDao.insert(session, - QualityProfileDto.createFor("sonar-way-xoo1-12345").setLanguage(xoo1.getKey()).setName("Sonar way") - ); - session.commit(); - - tester.newGetRequest("api/qualityprofiles", "search").setParam("language", xoo1.getKey()).execute().assertJson(this.getClass(), "search_xoo1.json"); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileSetDefaultActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileSetDefaultActionTest.java deleted file mode 100644 index e621bd0d0b5..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileSetDefaultActionTest.java +++ /dev/null @@ -1,170 +0,0 @@ -/* - * 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.qualityprofile.ws; - -import org.assertj.core.api.Fail; -import org.junit.After; -import org.junit.Before; -import org.junit.ClassRule; -import org.junit.Rule; -import org.junit.Test; -import org.sonar.api.utils.System2; -import org.sonar.core.permission.GlobalPermissions; -import org.sonar.core.persistence.DbSession; -import org.sonar.core.persistence.DbTester; -import org.sonar.core.qualityprofile.db.QualityProfileDao; -import org.sonar.core.qualityprofile.db.QualityProfileDto; -import org.sonar.server.db.DbClient; -import org.sonar.server.exceptions.ForbiddenException; -import org.sonar.server.exceptions.NotFoundException; -import org.sonar.server.language.LanguageTesting; -import org.sonar.server.qualityprofile.QProfileFactory; -import org.sonar.server.qualityprofile.QProfileLookup; -import org.sonar.server.tester.UserSessionRule; -import org.sonar.server.ws.WsTester; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; - -public class QProfileSetDefaultActionTest { - - @ClassRule - public static DbTester dbTester = new DbTester(); - @Rule - public UserSessionRule userSessionRule = UserSessionRule.standalone(); - - private DbClient dbClient; - - private QualityProfileDao qualityProfileDao; - - private String xoo1Key = "xoo1", xoo2Key = "xoo2"; - - private WsTester tester; - - private DbSession session; - - - @Before - public void setUp() { - dbTester.truncateTables(); - qualityProfileDao = new QualityProfileDao(dbTester.myBatis(), mock(System2.class)); - dbClient = new DbClient(dbTester.database(), dbTester.myBatis(), qualityProfileDao); - session = dbClient.openSession(false); - - createProfiles(); - - tester = new WsTester(new QProfilesWs( - mock(RuleActivationActions.class), - mock(BulkRuleActivationActions.class), - mock(ProjectAssociationActions.class), - new QProfileSetDefaultAction(LanguageTesting.newLanguages(xoo1Key, xoo2Key), new QProfileLookup(dbClient), new QProfileFactory(dbClient), userSessionRule))); - } - - @After - public void tearDown() { - session.close(); - } - - @Test - public void set_default_profile_using_key() throws Exception { - userSessionRule.login("obiwan").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); - - - checkDefaultProfile(xoo1Key, "sonar-way-xoo1-12345"); - checkDefaultProfile(xoo2Key, "my-sonar-way-xoo2-34567"); - - tester.newPostRequest("api/qualityprofiles", "set_default").setParam("profileKey", "sonar-way-xoo2-23456").execute().assertNoContent(); - - checkDefaultProfile(xoo1Key, "sonar-way-xoo1-12345"); - checkDefaultProfile(xoo2Key, "sonar-way-xoo2-23456"); - assertThat(dbClient.qualityProfileDao().getByKey(session, "sonar-way-xoo2-23456").isDefault()).isTrue(); - assertThat(dbClient.qualityProfileDao().getByKey(session, "my-sonar-way-xoo2-34567").isDefault()).isFalse(); - - // One more time! - tester.newPostRequest("api/qualityprofiles", "set_default").setParam("profileKey", "sonar-way-xoo2-23456").execute().assertNoContent(); - checkDefaultProfile(xoo1Key, "sonar-way-xoo1-12345"); - checkDefaultProfile(xoo2Key, "sonar-way-xoo2-23456"); - } - - @Test - public void set_default_profile_using_language_and_name() throws Exception { - userSessionRule.login("obiwan").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); - - tester.newPostRequest("api/qualityprofiles", "set_default").setParam("language", xoo2Key).setParam("profileName", "Sonar way").execute().assertNoContent(); - - checkDefaultProfile(xoo1Key, "sonar-way-xoo1-12345"); - checkDefaultProfile(xoo2Key, "sonar-way-xoo2-23456"); - } - - @Test - public void fail_to_set_default_profile_using_key() throws Exception { - userSessionRule.login("obiwan").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); - - try { - tester.newPostRequest("api/qualityprofiles", "set_default").setParam("profileKey", "unknown-profile-666").execute(); - Fail.failBecauseExceptionWasNotThrown(IllegalArgumentException.class); - } catch(IllegalArgumentException nfe) { - assertThat(nfe).hasMessage("Quality profile not found: unknown-profile-666"); - checkDefaultProfile(xoo1Key, "sonar-way-xoo1-12345"); - checkDefaultProfile(xoo2Key, "my-sonar-way-xoo2-34567"); - } - } - - - @Test - public void fail_to_set_default_profile_using_language_and_name() throws Exception { - userSessionRule.login("obiwan").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); - - try { - tester.newPostRequest("api/qualityprofiles", "set_default").setParam("language", xoo2Key).setParam("profileName", "Unknown").execute(); - Fail.failBecauseExceptionWasNotThrown(NotFoundException.class); - } catch(NotFoundException nfe) { - assertThat(nfe).hasMessage("Unable to find a profile for language 'xoo2' with name 'Unknown'"); - checkDefaultProfile(xoo1Key, "sonar-way-xoo1-12345"); - checkDefaultProfile(xoo2Key, "my-sonar-way-xoo2-34567"); - } - } - - @Test - public void fail_on_missing_permission() throws Exception { - userSessionRule.login("obiwan"); - - try { - tester.newPostRequest("api/qualityprofiles", "set_default").setParam("profileKey", "sonar-way-xoo2-23456").execute().assertNoContent(); - Fail.failBecauseExceptionWasNotThrown(ForbiddenException.class); - } catch(ForbiddenException forbidden) { - checkDefaultProfile(xoo1Key, "sonar-way-xoo1-12345"); - checkDefaultProfile(xoo2Key, "my-sonar-way-xoo2-34567"); - } - } - - private void createProfiles() { - qualityProfileDao.insert(session, - QualityProfileDto.createFor("sonar-way-xoo1-12345").setLanguage(xoo1Key).setName("Sonar way").setDefault(true), - QualityProfileDto.createFor("sonar-way-xoo2-23456").setLanguage(xoo2Key).setName("Sonar way"), - QualityProfileDto.createFor("my-sonar-way-xoo2-34567").setLanguage(xoo2Key).setName("My Sonar way").setParentKee("sonar-way-xoo2-23456").setDefault(true) - ); - session.commit(); - } - - private void checkDefaultProfile(String language, String key) { - assertThat(dbClient.qualityProfileDao().getDefaultProfile(language).getKey()).isEqualTo(key); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfilesWsTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfilesWsTest.java index 7f6dc975e6d..a27423428e0 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfilesWsTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfilesWsTest.java @@ -63,23 +63,23 @@ public class QProfilesWsTest { new RuleActivationActions(profileService), new BulkRuleActivationActions(profileService, ruleService, i18n, userSessionRule), new ProjectAssociationActions(null, null, null, languages, userSessionRule), - new QProfileCreateAction(null, null, null, languages, importers, userSessionRule), - new QProfileImportersAction(importers), - new QProfileRestoreBuiltInAction(null), - new QProfileSearchAction(languages, null, null, null), - new QProfileSetDefaultAction(languages, null, null, userSessionRule), - new QProfileProjectsAction(null, userSessionRule), - new QProfileBackupAction(null, null, null, languages), - new QProfileRestoreAction(null, languages, userSessionRule), - new QProfileChangelogAction(null, null, null, languages), - new QProfileChangeParentAction(null, null, null, languages, userSessionRule), - new QProfileCompareAction(null, null, null, languages), - new QProfileCopyAction(null, languages, userSessionRule), - new QProfileDeleteAction(languages, null, null, userSessionRule), - new QProfileExportAction(null, null, null, mock(QProfileExporters.class), languages), - new QProfileExportersAction(), - new QProfileInheritanceAction(null, null, null, null, languages), - new QProfileRenameAction(null, userSessionRule) + new CreateAction(null, null, null, languages, importers, userSessionRule), + new ImportersAction(importers), + new RestoreBuiltInAction(null), + new SearchAction(languages, null, null, null), + new SetDefaultAction(languages, null, null, userSessionRule), + new ProjectsAction(null, userSessionRule), + new BackupAction(null, null, null, languages), + new RestoreAction(null, languages, userSessionRule), + new ChangelogAction(null, null, null, languages), + new ChangeParentAction(null, null, null, languages, userSessionRule), + new CompareAction(null, null, null, languages), + new CopyAction(null, languages, userSessionRule), + new DeleteAction(languages, null, null, userSessionRule), + new ExportAction(null, null, null, mock(QProfileExporters.class), languages), + new ExportersAction(), + new InheritanceAction(null, null, null, null, languages), + new RenameAction(null, userSessionRule) )).controller(QProfilesWs.API_ENDPOINT); } diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/RenameActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/RenameActionTest.java new file mode 100644 index 00000000000..d5d70d40cb6 --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/RenameActionTest.java @@ -0,0 +1,150 @@ +/* + * 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.qualityprofile.ws; + +import org.junit.After; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Rule; +import org.junit.Test; +import org.sonar.api.utils.System2; +import org.sonar.core.permission.GlobalPermissions; +import org.sonar.core.persistence.DbSession; +import org.sonar.core.persistence.DbTester; +import org.sonar.core.qualityprofile.db.QualityProfileDao; +import org.sonar.core.qualityprofile.db.QualityProfileDto; +import org.sonar.server.db.DbClient; +import org.sonar.server.exceptions.BadRequestException; +import org.sonar.server.exceptions.ForbiddenException; +import org.sonar.server.qualityprofile.QProfileFactory; +import org.sonar.server.tester.UserSessionRule; +import org.sonar.server.ws.WsTester; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; + +public class RenameActionTest { + + @ClassRule + public static DbTester dbTester = new DbTester(); + @Rule + public UserSessionRule userSessionRule = UserSessionRule.standalone(); + + private DbClient dbClient; + + private QualityProfileDao qualityProfileDao; + + private String xoo1Key = "xoo1", xoo2Key = "xoo2"; + + private WsTester tester; + + private DbSession session; + + + @Before + public void setUp() { + dbTester.truncateTables(); + qualityProfileDao = new QualityProfileDao(dbTester.myBatis(), mock(System2.class)); + dbClient = new DbClient(dbTester.database(), dbTester.myBatis(), qualityProfileDao); + session = dbClient.openSession(false); + + createProfiles(); + + tester = new WsTester(new QProfilesWs( + mock(RuleActivationActions.class), + mock(BulkRuleActivationActions.class), + mock(ProjectAssociationActions.class), + new RenameAction(new QProfileFactory(dbClient), userSessionRule))); + } + + @After + public void tearDown() { + session.close(); + } + + @Test + public void rename_nominal() throws Exception { + userSessionRule.login("obiwan").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); + + tester.newPostRequest("api/qualityprofiles", "rename") + .setParam("key", "sonar-way-xoo2-23456") + .setParam("name", "Other Sonar Way") + .execute().assertNoContent(); + + assertThat(qualityProfileDao.getNonNullByKey(session, "sonar-way-xoo2-23456").getName()).isEqualTo("Other Sonar Way"); + } + + @Test(expected = BadRequestException.class) + public void do_nothing_on_conflict() throws Exception { + userSessionRule.login("obiwan").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); + + tester.newPostRequest("api/qualityprofiles", "rename") + .setParam("key", "sonar-way-xoo2-23456") + .setParam("name", "My Sonar way") + .execute(); + } + + @Test(expected = IllegalArgumentException.class) + public void fail_on_missing_key() throws Exception { + userSessionRule.login("obiwan").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); + + tester.newPostRequest("api/qualityprofiles", "rename") + .setParam("name", "Other Sonar Way") + .execute(); + } + + @Test(expected = IllegalArgumentException.class) + public void fail_on_missing_name() throws Exception { + userSessionRule.login("obiwan").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); + + tester.newPostRequest("api/qualityprofiles", "rename") + .setParam("key", "sonar-way-xoo1-13245") + .execute(); + } + + @Test(expected = ForbiddenException.class) + public void fail_on_missing_permission() throws Exception { + userSessionRule.login("obiwan"); + + tester.newPostRequest("api/qualityprofiles", "rename") + .setParam("key", "sonar-way-xoo1-13245") + .setParam("name", "Hey look I am not quality profile admin!") + .execute(); + } + + @Test(expected = IllegalArgumentException.class) + public void fail_on_unknown_profile() throws Exception { + userSessionRule.login("obiwan").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); + + tester.newPostRequest("api/qualityprofiles", "rename") + .setParam("key", "polop") + .setParam("name", "Uh oh, I don't know this profile") + .execute(); + } + + private void createProfiles() { + qualityProfileDao.insert(session, + QualityProfileDto.createFor("sonar-way-xoo1-12345").setLanguage(xoo1Key).setName("Sonar way").setDefault(true), + QualityProfileDto.createFor("sonar-way-xoo2-23456").setLanguage(xoo2Key).setName("Sonar way"), + QualityProfileDto.createFor("my-sonar-way-xoo2-34567").setLanguage(xoo2Key).setName("My Sonar way").setParentKee("sonar-way-xoo2-23456").setDefault(true) + ); + session.commit(); + } +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/RestoreActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/RestoreActionTest.java new file mode 100644 index 00000000000..7ad552f84b3 --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/RestoreActionTest.java @@ -0,0 +1,92 @@ +/* + * 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.qualityprofile.ws; + +import java.io.Reader; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; +import org.sonar.core.permission.GlobalPermissions; +import org.sonar.core.qualityprofile.db.QualityProfileDto; +import org.sonar.server.exceptions.ForbiddenException; +import org.sonar.server.language.LanguageTesting; +import org.sonar.server.qualityprofile.BulkChangeResult; +import org.sonar.server.qualityprofile.QProfileBackuper; +import org.sonar.server.qualityprofile.QProfileName; +import org.sonar.server.tester.UserSessionRule; +import org.sonar.server.ws.WsTester; + +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class RestoreActionTest { + @Rule + public UserSessionRule userSessionRule = UserSessionRule.standalone(); + + // TODO Replace with proper DbTester + EsTester medium test once DaoV2 is removed + @Mock + private QProfileBackuper backuper; + + private WsTester tester; + + @Before + public void setUp() { + tester = new WsTester(new QProfilesWs( + mock(RuleActivationActions.class), + mock(BulkRuleActivationActions.class), + mock(ProjectAssociationActions.class), + new RestoreAction(backuper, LanguageTesting.newLanguages("xoo"), userSessionRule))); + } + + @Test + public void restore_profile() throws Exception { + userSessionRule.login("obiwan").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); + + QualityProfileDto profile = QualityProfileDto.createFor("xoo-sonar-way-12345") + .setDefault(false).setLanguage("xoo").setName("Sonar way"); + BulkChangeResult restoreResult = new BulkChangeResult(profile); + when(backuper.restore(any(Reader.class), (QProfileName) eq(null))).thenReturn(restoreResult); + + tester.newPostRequest("api/qualityprofiles", "restore").setParam("backup", "").execute() + .assertJson(getClass(), "restore_profile.json"); + verify(backuper).restore(any(Reader.class), (QProfileName) eq(null)); + } + + @Test(expected = IllegalArgumentException.class) + public void fail_on_missing_backup() throws Exception { + userSessionRule.login("obiwan").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); + + tester.newGetRequest("api/qualityprofiles", "restore").execute(); + } + + @Test(expected = ForbiddenException.class) + public void fail_on_misssing_permission() throws Exception { + userSessionRule.login("obiwan"); + + tester.newPostRequest("api/qualityprofiles", "restore").setParam("backup", "").execute(); + } +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/RestoreBuiltInActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/RestoreBuiltInActionTest.java new file mode 100644 index 00000000000..1c433dd8ea9 --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/RestoreBuiltInActionTest.java @@ -0,0 +1,59 @@ +/* + * 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.qualityprofile.ws; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; +import org.sonar.api.i18n.I18n; +import org.sonar.server.qualityprofile.QProfileService; +import org.sonar.server.ws.WsTester; + +import static org.mockito.Mockito.mock; + +@RunWith(MockitoJUnitRunner.class) +public class RestoreBuiltInActionTest { + + @Mock + QProfileService profileService; + + @Mock + I18n i18n; + + WsTester tester; + + @Before + public void setUp() { + tester = new WsTester(new QProfilesWs( + mock(RuleActivationActions.class), + mock(BulkRuleActivationActions.class), + mock(ProjectAssociationActions.class), + new RestoreBuiltInAction(profileService))); + } + + @Test + public void return_empty_result_when_no_infos_or_warnings() throws Exception { + WsTester.TestRequest request = tester.newPostRequest("api/qualityprofiles", "restore_built_in").setParam("language", "java"); + request.execute().assertNoContent(); + } +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/SearchActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/SearchActionTest.java new file mode 100644 index 00000000000..28650acc86a --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/SearchActionTest.java @@ -0,0 +1,136 @@ +/* + * 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.qualityprofile.ws; + +import com.google.common.collect.ImmutableMap; +import org.junit.After; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Test; +import org.sonar.api.resources.Language; +import org.sonar.api.resources.Languages; +import org.sonar.api.utils.System2; +import org.sonar.core.persistence.DbSession; +import org.sonar.core.persistence.DbTester; +import org.sonar.core.qualityprofile.db.QualityProfileDao; +import org.sonar.core.qualityprofile.db.QualityProfileDto; +import org.sonar.server.component.ComponentTesting; +import org.sonar.server.component.db.ComponentDao; +import org.sonar.server.db.DbClient; +import org.sonar.server.language.LanguageTesting; +import org.sonar.server.qualityprofile.QProfileLoader; +import org.sonar.server.qualityprofile.QProfileLookup; +import org.sonar.server.ws.WsTester; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class SearchActionTest { + + @ClassRule + public static DbTester dbTester = new DbTester(); + + private DbClient dbClient; + + private QualityProfileDao qualityProfileDao; + + private Language xoo1, xoo2; + + private WsTester tester; + + private DbSession session; + + private QProfileLoader profileLoader; + + @Before + public void setUp() { + dbTester.truncateTables(); + qualityProfileDao = new QualityProfileDao(dbTester.myBatis(), mock(System2.class)); + dbClient = new DbClient(dbTester.database(), dbTester.myBatis(), qualityProfileDao); + session = dbClient.openSession(false); + + // TODO Replace with actual implementation after removal of DaoV2... + profileLoader = mock(QProfileLoader.class); + + xoo1 = LanguageTesting.newLanguage("xoo1"); + xoo2 = LanguageTesting.newLanguage("xoo2"); + + tester = new WsTester(new QProfilesWs( + mock(RuleActivationActions.class), + mock(BulkRuleActivationActions.class), + mock(ProjectAssociationActions.class), + new SearchAction(new Languages(xoo1, xoo2), new QProfileLookup(dbClient), profileLoader, qualityProfileDao))); + } + + @After + public void teadDown() { + session.close(); + } + + @Test + public void search_nominal() throws Exception { + when(profileLoader.countAllActiveRules()).thenReturn(ImmutableMap.of( + "sonar-way-xoo1-12345", 11L, + "my-sonar-way-xoo2-34567", 33L + )); + + qualityProfileDao.insert(session, + QualityProfileDto.createFor("sonar-way-xoo1-12345").setLanguage(xoo1.getKey()).setName("Sonar way").setDefault(true), + QualityProfileDto.createFor("sonar-way-xoo2-23456").setLanguage(xoo2.getKey()).setName("Sonar way"), + QualityProfileDto.createFor("my-sonar-way-xoo2-34567").setLanguage(xoo2.getKey()).setName("My Sonar way").setParentKee("sonar-way-xoo2-23456"), + QualityProfileDto.createFor("sonar-way-other-666").setLanguage("other").setName("Sonar way").setDefault(true) + ); + new ComponentDao().insert(session, + ComponentTesting.newProjectDto("project-uuid1"), + ComponentTesting.newProjectDto("project-uuid2")); + qualityProfileDao.insertProjectProfileAssociation("project-uuid1", "sonar-way-xoo2-23456", session); + qualityProfileDao.insertProjectProfileAssociation("project-uuid2", "sonar-way-xoo2-23456", session); + session.commit(); + + tester.newGetRequest("api/qualityprofiles", "search").execute().assertJson(this.getClass(), "search.json"); + } + + @Test + public void search_with_fields() throws Exception { + qualityProfileDao.insert(session, + QualityProfileDto.createFor("sonar-way-xoo1-12345").setLanguage(xoo1.getKey()).setName("Sonar way").setDefault(true), + QualityProfileDto.createFor("sonar-way-xoo2-23456").setLanguage(xoo2.getKey()).setName("Sonar way"), + QualityProfileDto.createFor("my-sonar-way-xoo2-34567").setLanguage(xoo2.getKey()).setName("My Sonar way").setParentKee("sonar-way-xoo2-23456") + ); + session.commit(); + + tester.newGetRequest("api/qualityprofiles", "search").setParam("f", "key,language").execute().assertJson(this.getClass(), "search_fields.json"); + } + + @Test(expected = IllegalArgumentException.class) + public void fail_on_unknown_fields() throws Exception { + tester.newGetRequest("api/qualityprofiles", "search").setParam("f", "polop").execute(); + } + + @Test + public void search_for_language() throws Exception { + qualityProfileDao.insert(session, + QualityProfileDto.createFor("sonar-way-xoo1-12345").setLanguage(xoo1.getKey()).setName("Sonar way") + ); + session.commit(); + + tester.newGetRequest("api/qualityprofiles", "search").setParam("language", xoo1.getKey()).execute().assertJson(this.getClass(), "search_xoo1.json"); + } +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/SetDefaultActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/SetDefaultActionTest.java new file mode 100644 index 00000000000..1c543a0a1b5 --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/SetDefaultActionTest.java @@ -0,0 +1,170 @@ +/* + * 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.qualityprofile.ws; + +import org.assertj.core.api.Fail; +import org.junit.After; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Rule; +import org.junit.Test; +import org.sonar.api.utils.System2; +import org.sonar.core.permission.GlobalPermissions; +import org.sonar.core.persistence.DbSession; +import org.sonar.core.persistence.DbTester; +import org.sonar.core.qualityprofile.db.QualityProfileDao; +import org.sonar.core.qualityprofile.db.QualityProfileDto; +import org.sonar.server.db.DbClient; +import org.sonar.server.exceptions.ForbiddenException; +import org.sonar.server.exceptions.NotFoundException; +import org.sonar.server.language.LanguageTesting; +import org.sonar.server.qualityprofile.QProfileFactory; +import org.sonar.server.qualityprofile.QProfileLookup; +import org.sonar.server.tester.UserSessionRule; +import org.sonar.server.ws.WsTester; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; + +public class SetDefaultActionTest { + + @ClassRule + public static DbTester dbTester = new DbTester(); + @Rule + public UserSessionRule userSessionRule = UserSessionRule.standalone(); + + private DbClient dbClient; + + private QualityProfileDao qualityProfileDao; + + private String xoo1Key = "xoo1", xoo2Key = "xoo2"; + + private WsTester tester; + + private DbSession session; + + + @Before + public void setUp() { + dbTester.truncateTables(); + qualityProfileDao = new QualityProfileDao(dbTester.myBatis(), mock(System2.class)); + dbClient = new DbClient(dbTester.database(), dbTester.myBatis(), qualityProfileDao); + session = dbClient.openSession(false); + + createProfiles(); + + tester = new WsTester(new QProfilesWs( + mock(RuleActivationActions.class), + mock(BulkRuleActivationActions.class), + mock(ProjectAssociationActions.class), + new SetDefaultAction(LanguageTesting.newLanguages(xoo1Key, xoo2Key), new QProfileLookup(dbClient), new QProfileFactory(dbClient), userSessionRule))); + } + + @After + public void tearDown() { + session.close(); + } + + @Test + public void set_default_profile_using_key() throws Exception { + userSessionRule.login("obiwan").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); + + + checkDefaultProfile(xoo1Key, "sonar-way-xoo1-12345"); + checkDefaultProfile(xoo2Key, "my-sonar-way-xoo2-34567"); + + tester.newPostRequest("api/qualityprofiles", "set_default").setParam("profileKey", "sonar-way-xoo2-23456").execute().assertNoContent(); + + checkDefaultProfile(xoo1Key, "sonar-way-xoo1-12345"); + checkDefaultProfile(xoo2Key, "sonar-way-xoo2-23456"); + assertThat(dbClient.qualityProfileDao().getByKey(session, "sonar-way-xoo2-23456").isDefault()).isTrue(); + assertThat(dbClient.qualityProfileDao().getByKey(session, "my-sonar-way-xoo2-34567").isDefault()).isFalse(); + + // One more time! + tester.newPostRequest("api/qualityprofiles", "set_default").setParam("profileKey", "sonar-way-xoo2-23456").execute().assertNoContent(); + checkDefaultProfile(xoo1Key, "sonar-way-xoo1-12345"); + checkDefaultProfile(xoo2Key, "sonar-way-xoo2-23456"); + } + + @Test + public void set_default_profile_using_language_and_name() throws Exception { + userSessionRule.login("obiwan").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); + + tester.newPostRequest("api/qualityprofiles", "set_default").setParam("language", xoo2Key).setParam("profileName", "Sonar way").execute().assertNoContent(); + + checkDefaultProfile(xoo1Key, "sonar-way-xoo1-12345"); + checkDefaultProfile(xoo2Key, "sonar-way-xoo2-23456"); + } + + @Test + public void fail_to_set_default_profile_using_key() throws Exception { + userSessionRule.login("obiwan").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); + + try { + tester.newPostRequest("api/qualityprofiles", "set_default").setParam("profileKey", "unknown-profile-666").execute(); + Fail.failBecauseExceptionWasNotThrown(IllegalArgumentException.class); + } catch(IllegalArgumentException nfe) { + assertThat(nfe).hasMessage("Quality profile not found: unknown-profile-666"); + checkDefaultProfile(xoo1Key, "sonar-way-xoo1-12345"); + checkDefaultProfile(xoo2Key, "my-sonar-way-xoo2-34567"); + } + } + + + @Test + public void fail_to_set_default_profile_using_language_and_name() throws Exception { + userSessionRule.login("obiwan").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); + + try { + tester.newPostRequest("api/qualityprofiles", "set_default").setParam("language", xoo2Key).setParam("profileName", "Unknown").execute(); + Fail.failBecauseExceptionWasNotThrown(NotFoundException.class); + } catch(NotFoundException nfe) { + assertThat(nfe).hasMessage("Unable to find a profile for language 'xoo2' with name 'Unknown'"); + checkDefaultProfile(xoo1Key, "sonar-way-xoo1-12345"); + checkDefaultProfile(xoo2Key, "my-sonar-way-xoo2-34567"); + } + } + + @Test + public void fail_on_missing_permission() throws Exception { + userSessionRule.login("obiwan"); + + try { + tester.newPostRequest("api/qualityprofiles", "set_default").setParam("profileKey", "sonar-way-xoo2-23456").execute().assertNoContent(); + Fail.failBecauseExceptionWasNotThrown(ForbiddenException.class); + } catch(ForbiddenException forbidden) { + checkDefaultProfile(xoo1Key, "sonar-way-xoo1-12345"); + checkDefaultProfile(xoo2Key, "my-sonar-way-xoo2-34567"); + } + } + + private void createProfiles() { + qualityProfileDao.insert(session, + QualityProfileDto.createFor("sonar-way-xoo1-12345").setLanguage(xoo1Key).setName("Sonar way").setDefault(true), + QualityProfileDto.createFor("sonar-way-xoo2-23456").setLanguage(xoo2Key).setName("Sonar way"), + QualityProfileDto.createFor("my-sonar-way-xoo2-34567").setLanguage(xoo2Key).setName("My Sonar way").setParentKee("sonar-way-xoo2-23456").setDefault(true) + ); + session.commit(); + } + + private void checkDefaultProfile(String language, String key) { + assertThat(dbClient.qualityProfileDao().getDefaultProfile(language).getKey()).isEqualTo(key); + } +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/test/ws/CoveredFilesActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/test/ws/CoveredFilesActionTest.java new file mode 100644 index 00000000000..d0c68a032de --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/test/ws/CoveredFilesActionTest.java @@ -0,0 +1,78 @@ +/* + * 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.test.ws; + +import java.util.Arrays; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.sonar.api.web.UserRole; +import org.sonar.core.persistence.DbSession; +import org.sonar.server.db.DbClient; +import org.sonar.server.test.index.CoveredFileDoc; +import org.sonar.server.test.index.TestIndex; +import org.sonar.server.tester.UserSessionRule; +import org.sonar.server.ws.WsTester; + +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyList; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.RETURNS_DEEP_STUBS; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.sonar.server.component.ComponentTesting.newFileDto; +import static org.sonar.server.component.ComponentTesting.newProjectDto; +import static org.sonar.server.test.ws.CoveredFilesAction.TEST_UUID; + +public class CoveredFilesActionTest { + @Rule + public UserSessionRule userSessionRule = UserSessionRule.standalone(); + + WsTester ws; + private DbClient dbClient; + private TestIndex testIndex; + + @Before + public void setUp() { + dbClient = mock(DbClient.class, RETURNS_DEEP_STUBS); + testIndex = mock(TestIndex.class, RETURNS_DEEP_STUBS); + ws = new WsTester(new TestsWs(new CoveredFilesAction(dbClient, testIndex, userSessionRule))); + } + + @Test + public void covered_files() throws Exception { + userSessionRule.addComponentUuidPermission(UserRole.CODEVIEWER, "SonarQube", "test-file-uuid"); + + when(testIndex.searchByTestUuid(anyString()).fileUuid()).thenReturn("test-file-uuid"); + when(testIndex.coveredFiles("test-uuid")).thenReturn(Arrays.asList( + new CoveredFileDoc().setFileUuid("bar-uuid").setCoveredLines(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)), + new CoveredFileDoc().setFileUuid("file-uuid").setCoveredLines(Arrays.asList(1, 2, 3)) + )); + when(dbClient.componentDao().selectByUuids(any(DbSession.class), anyList())).thenReturn( + Arrays.asList( + newFileDto(newProjectDto(), "bar-uuid").setKey("org.foo.Bar.java").setLongName("src/main/java/org/foo/Bar.java"), + newFileDto(newProjectDto(), "file-uuid").setKey("org.foo.File.java").setLongName("src/main/java/org/foo/File.java"))); + + WsTester.TestRequest request = ws.newGetRequest("api/tests", "covered_files").setParam(TEST_UUID, "test-uuid"); + + request.execute().assertJson(getClass(), "tests-covered-files.json"); + } +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/test/ws/ListActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/test/ws/ListActionTest.java new file mode 100644 index 00000000000..753687d911e --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/test/ws/ListActionTest.java @@ -0,0 +1,289 @@ +/* + * 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.test.ws; + +import org.junit.After; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Rule; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.sonar.api.config.Settings; +import org.sonar.api.web.UserRole; +import org.sonar.core.component.ComponentDto; +import org.sonar.core.persistence.DbSession; +import org.sonar.core.persistence.DbTester; +import org.sonar.server.component.db.ComponentDao; +import org.sonar.server.db.DbClient; +import org.sonar.server.es.EsTester; +import org.sonar.server.exceptions.ForbiddenException; +import org.sonar.server.test.index.CoveredFileDoc; +import org.sonar.server.test.index.TestDoc; +import org.sonar.server.test.index.TestIndex; +import org.sonar.server.test.index.TestIndexDefinition; +import org.sonar.server.tester.UserSessionRule; +import org.sonar.server.ws.WsTester; +import org.sonar.test.DbTests; + +import java.util.Arrays; +import java.util.List; + +@Category(DbTests.class) +public class ListActionTest { + DbClient dbClient; + DbSession dbSession; + TestIndex testIndex; + + WsTester ws; + + @ClassRule + public static DbTester db = new DbTester(); + @ClassRule + public static EsTester es = new EsTester().addDefinitions(new TestIndexDefinition(new Settings())); + @Rule + public UserSessionRule userSessionRule = UserSessionRule.standalone(); + + @Before + public void setUp() { + dbClient = new DbClient(db.database(), db.myBatis(), new ComponentDao()); + dbSession = dbClient.openSession(false); + db.truncateTables(); + es.truncateIndices(); + testIndex = new TestIndex(es.client()); + + ws = new WsTester(new TestsWs(new ListAction(dbClient, testIndex, userSessionRule))); + } + + @After + public void tearDown() { + dbSession.close(); + } + + @Test + public void list_based_on_test_uuid() throws Exception { + userSessionRule.addProjectUuidPermissions(UserRole.CODEVIEWER, TestFile1.PROJECT_UUID); + + dbClient.componentDao().insert(dbSession, TestFile1.newDto()); + dbSession.commit(); + + es.putDocuments(TestIndexDefinition.INDEX, TestIndexDefinition.TYPE, + new TestDoc() + .setUuid(TestFile1.UUID) + .setName(TestFile1.NAME) + .setFileUuid(TestFile1.FILE_UUID) + .setDurationInMs(TestFile1.DURATION_IN_MS) + .setStatus(TestFile1.STATUS) + .setMessage(TestFile1.MESSAGE) + .setCoveredFiles(TestFile1.COVERED_FILES) + .setStackTrace(TestFile1.STACKTRACE) + ); + + WsTester.TestRequest request = ws.newGetRequest("api/tests", "list").setParam(ListAction.TEST_UUID, TestFile1.UUID); + + request.execute().assertJson(getClass(), "list-test-uuid.json"); + } + + @Test + public void list_based_on_test_file_uuid() throws Exception { + userSessionRule.addProjectUuidPermissions(UserRole.CODEVIEWER, TestFile1.PROJECT_UUID); + dbClient.componentDao().insert(dbSession, TestFile1.newDto()); + dbSession.commit(); + + es.putDocuments(TestIndexDefinition.INDEX, TestIndexDefinition.TYPE, + new TestDoc() + .setUuid(TestFile1.UUID) + .setName(TestFile1.NAME) + .setFileUuid(TestFile1.FILE_UUID) + .setDurationInMs(TestFile1.DURATION_IN_MS) + .setCoveredFiles(TestFile1.COVERED_FILES) + .setStatus(TestFile1.STATUS) + .setMessage(TestFile1.MESSAGE) + .setStackTrace(TestFile1.STACKTRACE)); + + WsTester.TestRequest request = ws.newGetRequest("api/tests", "list").setParam(ListAction.TEST_FILE_UUID, TestFile1.FILE_UUID); + + request.execute().assertJson(getClass(), "list-test-uuid.json"); + } + + @Test + public void list_based_on_test_file_key() throws Exception { + userSessionRule.addComponentPermission(UserRole.CODEVIEWER, TestFile1.PROJECT_UUID, TestFile1.KEY); + dbClient.componentDao().insert(dbSession, TestFile1.newDto()); + dbSession.commit(); + + es.putDocuments(TestIndexDefinition.INDEX, TestIndexDefinition.TYPE, + new TestDoc() + .setUuid(TestFile1.UUID) + .setName(TestFile1.NAME) + .setFileUuid(TestFile1.FILE_UUID) + .setDurationInMs(TestFile1.DURATION_IN_MS) + .setCoveredFiles(TestFile1.COVERED_FILES) + .setStatus(TestFile1.STATUS) + .setMessage(TestFile1.MESSAGE) + .setStackTrace(TestFile1.STACKTRACE) + ); + + WsTester.TestRequest request = ws.newGetRequest("api/tests", "list").setParam(ListAction.TEST_FILE_KEY, TestFile1.KEY); + + request.execute().assertJson(getClass(), "list-test-uuid.json"); + } + + @Test + public void list_based_on_main_file_and_line_number() throws Exception { + String mainFileUuid = "MAIN-FILE-UUID"; + userSessionRule.addProjectUuidPermissions(UserRole.CODEVIEWER, TestFile1.PROJECT_UUID); + dbClient.componentDao().insert(dbSession, + new ComponentDto() + .setUuid(TestFile1.FILE_UUID) + .setLongName(TestFile1.LONG_NAME) + .setKey(TestFile1.KEY) + .setProjectUuid(TestFile1.PROJECT_UUID), + new ComponentDto() + .setUuid(TestFile2.FILE_UUID) + .setLongName(TestFile2.LONG_NAME) + .setProjectUuid(TestFile2.PROJECT_UUID) + .setKey(TestFile2.KEY), + new ComponentDto() + .setUuid(mainFileUuid) + .setProjectUuid(TestFile1.PROJECT_UUID) + ); + dbSession.commit(); + + es.putDocuments(TestIndexDefinition.INDEX, TestIndexDefinition.TYPE, + new TestDoc() + .setUuid(TestFile1.UUID) + .setName(TestFile1.NAME) + .setFileUuid(TestFile1.FILE_UUID) + .setDurationInMs(TestFile1.DURATION_IN_MS) + .setStatus(TestFile1.STATUS) + .setMessage(TestFile1.MESSAGE) + .setCoveredFiles(TestFile1.COVERED_FILES) + .setStackTrace(TestFile1.STACKTRACE), + new TestDoc() + .setUuid(TestFile2.UUID) + .setName(TestFile2.NAME) + .setFileUuid(TestFile2.FILE_UUID) + .setDurationInMs(TestFile2.DURATION_IN_MS) + .setStatus(TestFile2.STATUS) + .setStackTrace(TestFile2.STATUS) + .setMessage(TestFile2.MESSAGE) + .setCoveredFiles(TestFile2.COVERED_FILES) + .setStackTrace(TestFile2.STACKTRACE)); + + WsTester.TestRequest request = ws.newGetRequest("api/tests", "list") + .setParam(ListAction.SOURCE_FILE_UUID, mainFileUuid) + .setParam(ListAction.SOURCE_FILE_LINE_NUMBER, "10"); + + request.execute().assertJson(getClass(), "list-main-file.json"); + } + + @Test(expected = IllegalArgumentException.class) + public void fail_when_no_argument() throws Exception { + ws.newGetRequest("api/tests", "list").execute(); + } + + @Test(expected = IllegalArgumentException.class) + public void fail_when_main_file_uuid_without_line_number() throws Exception { + ws.newGetRequest("api/tests", "list").setParam(ListAction.SOURCE_FILE_UUID, "ANY-UUID").execute(); + } + + @Test(expected = ForbiddenException.class) + public void fail_when_no_sufficent_privilege_on_file_uuid() throws Exception { + userSessionRule.addProjectUuidPermissions(UserRole.USER, TestFile1.PROJECT_UUID); + dbClient.componentDao().insert(dbSession, TestFile1.newDto()); + dbSession.commit(); + ws.newGetRequest("api/tests", "list").setParam(ListAction.TEST_FILE_UUID, TestFile1.FILE_UUID).execute(); + } + + @Test(expected = ForbiddenException.class) + public void fail_when_no_sufficent_privilege_on_test_uuid() throws Exception { + userSessionRule.addProjectUuidPermissions(UserRole.USER, TestFile1.PROJECT_UUID); + dbClient.componentDao().insert(dbSession, TestFile1.newDto()); + dbSession.commit(); + ws.newGetRequest("api/tests", "list").setParam(ListAction.TEST_FILE_UUID, TestFile1.FILE_UUID).execute(); + } + + @Test(expected = ForbiddenException.class) + public void fail_when_no_sufficent_privilege_on_file_key() throws Exception { + userSessionRule.addProjectUuidPermissions(UserRole.USER, TestFile1.PROJECT_UUID); + dbClient.componentDao().insert(dbSession, TestFile1.newDto()); + dbSession.commit(); + ws.newGetRequest("api/tests", "list").setParam(ListAction.TEST_FILE_KEY, TestFile1.KEY).execute(); + } + + @Test(expected = ForbiddenException.class) + public void fail_when_no_sufficient_privilege_on_main_file_uuid() throws Exception { + userSessionRule.addProjectUuidPermissions(UserRole.USER, TestFile1.PROJECT_UUID); + String mainFileUuid = "MAIN-FILE-UUID"; + dbClient.componentDao().insert(dbSession, new ComponentDto().setUuid(mainFileUuid).setProjectUuid(TestFile1.PROJECT_UUID)); + dbSession.commit(); + + ws.newGetRequest("api/tests", "list") + .setParam(ListAction.SOURCE_FILE_UUID, mainFileUuid) + .setParam(ListAction.SOURCE_FILE_LINE_NUMBER, "10") + .execute(); + } + + private static final class TestFile1 { + public static final String UUID = "TEST-UUID-1"; + public static final String FILE_UUID = "ABCD"; + public static final String PROJECT_UUID = "PROJECT-UUID"; + public static final String NAME = "test1"; + public static final String STATUS = "OK"; + public static final long DURATION_IN_MS = 10; + public static final String MESSAGE = "MESSAGE-1"; + public static final String STACKTRACE = "STACKTRACE-1"; + public static final String KEY = "org.foo.BarTest.java"; + public static final String LONG_NAME = "src/test/java/org/foo/BarTest.java"; + public static final List COVERED_FILES = Arrays.asList(new CoveredFileDoc().setFileUuid("MAIN-FILE-UUID").setCoveredLines(Arrays.asList(1, 2, 3, 10))); + + public static ComponentDto newDto() { + return new ComponentDto() + .setUuid(TestFile1.FILE_UUID) + .setLongName(TestFile1.LONG_NAME) + .setProjectUuid(TestFile1.PROJECT_UUID) + .setKey(TestFile1.KEY); + } + + private TestFile1() { + // static stuff for test purposes + } + } + + private static final class TestFile2 { + public static final String UUID = "TEST-UUID-2"; + public static final String FILE_UUID = "BCDE"; + public static final String PROJECT_UUID = "PROJECT-UUID"; + public static final String NAME = "test2"; + public static final String STATUS = "ERROR"; + public static final long DURATION_IN_MS = 97; + public static final String MESSAGE = "MESSAGE-2"; + public static final String STACKTRACE = "STACKTRACE-2"; + public static final String KEY = "org.foo.FileTest.java"; + public static final String LONG_NAME = "src/test/java/org/foo/FileTest.java"; + public static final List COVERED_FILES = Arrays.asList(new CoveredFileDoc().setFileUuid("MAIN-FILE-UUID").setCoveredLines(Arrays.asList(11, 12, 13, 10))); + + private TestFile2() { + // static stuff for test purposes + } + } + +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/test/ws/TestsCoveredFilesActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/test/ws/TestsCoveredFilesActionTest.java deleted file mode 100644 index a0156dcbf70..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/test/ws/TestsCoveredFilesActionTest.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * 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.test.ws; - -import java.util.Arrays; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.sonar.api.web.UserRole; -import org.sonar.core.persistence.DbSession; -import org.sonar.server.db.DbClient; -import org.sonar.server.test.index.CoveredFileDoc; -import org.sonar.server.test.index.TestIndex; -import org.sonar.server.tester.UserSessionRule; -import org.sonar.server.ws.WsTester; - -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyList; -import static org.mockito.Matchers.anyString; -import static org.mockito.Mockito.RETURNS_DEEP_STUBS; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; -import static org.sonar.server.component.ComponentTesting.newFileDto; -import static org.sonar.server.component.ComponentTesting.newProjectDto; -import static org.sonar.server.test.ws.TestsCoveredFilesAction.TEST_UUID; - -public class TestsCoveredFilesActionTest { - @Rule - public UserSessionRule userSessionRule = UserSessionRule.standalone(); - - WsTester ws; - private DbClient dbClient; - private TestIndex testIndex; - - @Before - public void setUp() { - dbClient = mock(DbClient.class, RETURNS_DEEP_STUBS); - testIndex = mock(TestIndex.class, RETURNS_DEEP_STUBS); - ws = new WsTester(new TestsWs(new TestsCoveredFilesAction(dbClient, testIndex, userSessionRule))); - } - - @Test - public void covered_files() throws Exception { - userSessionRule.addComponentUuidPermission(UserRole.CODEVIEWER, "SonarQube", "test-file-uuid"); - - when(testIndex.searchByTestUuid(anyString()).fileUuid()).thenReturn("test-file-uuid"); - when(testIndex.coveredFiles("test-uuid")).thenReturn(Arrays.asList( - new CoveredFileDoc().setFileUuid("bar-uuid").setCoveredLines(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)), - new CoveredFileDoc().setFileUuid("file-uuid").setCoveredLines(Arrays.asList(1, 2, 3)) - )); - when(dbClient.componentDao().selectByUuids(any(DbSession.class), anyList())).thenReturn( - Arrays.asList( - newFileDto(newProjectDto(), "bar-uuid").setKey("org.foo.Bar.java").setLongName("src/main/java/org/foo/Bar.java"), - newFileDto(newProjectDto(), "file-uuid").setKey("org.foo.File.java").setLongName("src/main/java/org/foo/File.java"))); - - WsTester.TestRequest request = ws.newGetRequest("api/tests", "covered_files").setParam(TEST_UUID, "test-uuid"); - - request.execute().assertJson(getClass(), "tests-covered-files.json"); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/test/ws/TestsListActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/test/ws/TestsListActionTest.java deleted file mode 100644 index 3de460c906d..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/test/ws/TestsListActionTest.java +++ /dev/null @@ -1,289 +0,0 @@ -/* - * 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.test.ws; - -import org.junit.After; -import org.junit.Before; -import org.junit.ClassRule; -import org.junit.Rule; -import org.junit.Test; -import org.junit.experimental.categories.Category; -import org.sonar.api.config.Settings; -import org.sonar.api.web.UserRole; -import org.sonar.core.component.ComponentDto; -import org.sonar.core.persistence.DbSession; -import org.sonar.core.persistence.DbTester; -import org.sonar.server.component.db.ComponentDao; -import org.sonar.server.db.DbClient; -import org.sonar.server.es.EsTester; -import org.sonar.server.exceptions.ForbiddenException; -import org.sonar.server.test.index.CoveredFileDoc; -import org.sonar.server.test.index.TestDoc; -import org.sonar.server.test.index.TestIndex; -import org.sonar.server.test.index.TestIndexDefinition; -import org.sonar.server.tester.UserSessionRule; -import org.sonar.server.ws.WsTester; -import org.sonar.test.DbTests; - -import java.util.Arrays; -import java.util.List; - -@Category(DbTests.class) -public class TestsListActionTest { - DbClient dbClient; - DbSession dbSession; - TestIndex testIndex; - - WsTester ws; - - @ClassRule - public static DbTester db = new DbTester(); - @ClassRule - public static EsTester es = new EsTester().addDefinitions(new TestIndexDefinition(new Settings())); - @Rule - public UserSessionRule userSessionRule = UserSessionRule.standalone(); - - @Before - public void setUp() { - dbClient = new DbClient(db.database(), db.myBatis(), new ComponentDao()); - dbSession = dbClient.openSession(false); - db.truncateTables(); - es.truncateIndices(); - testIndex = new TestIndex(es.client()); - - ws = new WsTester(new TestsWs(new TestsListAction(dbClient, testIndex, userSessionRule))); - } - - @After - public void tearDown() { - dbSession.close(); - } - - @Test - public void list_based_on_test_uuid() throws Exception { - userSessionRule.addProjectUuidPermissions(UserRole.CODEVIEWER, TestFile1.PROJECT_UUID); - - dbClient.componentDao().insert(dbSession, TestFile1.newDto()); - dbSession.commit(); - - es.putDocuments(TestIndexDefinition.INDEX, TestIndexDefinition.TYPE, - new TestDoc() - .setUuid(TestFile1.UUID) - .setName(TestFile1.NAME) - .setFileUuid(TestFile1.FILE_UUID) - .setDurationInMs(TestFile1.DURATION_IN_MS) - .setStatus(TestFile1.STATUS) - .setMessage(TestFile1.MESSAGE) - .setCoveredFiles(TestFile1.COVERED_FILES) - .setStackTrace(TestFile1.STACKTRACE) - ); - - WsTester.TestRequest request = ws.newGetRequest("api/tests", "list").setParam(TestsListAction.TEST_UUID, TestFile1.UUID); - - request.execute().assertJson(getClass(), "list-test-uuid.json"); - } - - @Test - public void list_based_on_test_file_uuid() throws Exception { - userSessionRule.addProjectUuidPermissions(UserRole.CODEVIEWER, TestFile1.PROJECT_UUID); - dbClient.componentDao().insert(dbSession, TestFile1.newDto()); - dbSession.commit(); - - es.putDocuments(TestIndexDefinition.INDEX, TestIndexDefinition.TYPE, - new TestDoc() - .setUuid(TestFile1.UUID) - .setName(TestFile1.NAME) - .setFileUuid(TestFile1.FILE_UUID) - .setDurationInMs(TestFile1.DURATION_IN_MS) - .setCoveredFiles(TestFile1.COVERED_FILES) - .setStatus(TestFile1.STATUS) - .setMessage(TestFile1.MESSAGE) - .setStackTrace(TestFile1.STACKTRACE)); - - WsTester.TestRequest request = ws.newGetRequest("api/tests", "list").setParam(TestsListAction.TEST_FILE_UUID, TestFile1.FILE_UUID); - - request.execute().assertJson(getClass(), "list-test-uuid.json"); - } - - @Test - public void list_based_on_test_file_key() throws Exception { - userSessionRule.addComponentPermission(UserRole.CODEVIEWER, TestFile1.PROJECT_UUID, TestFile1.KEY); - dbClient.componentDao().insert(dbSession, TestFile1.newDto()); - dbSession.commit(); - - es.putDocuments(TestIndexDefinition.INDEX, TestIndexDefinition.TYPE, - new TestDoc() - .setUuid(TestFile1.UUID) - .setName(TestFile1.NAME) - .setFileUuid(TestFile1.FILE_UUID) - .setDurationInMs(TestFile1.DURATION_IN_MS) - .setCoveredFiles(TestFile1.COVERED_FILES) - .setStatus(TestFile1.STATUS) - .setMessage(TestFile1.MESSAGE) - .setStackTrace(TestFile1.STACKTRACE) - ); - - WsTester.TestRequest request = ws.newGetRequest("api/tests", "list").setParam(TestsListAction.TEST_FILE_KEY, TestFile1.KEY); - - request.execute().assertJson(getClass(), "list-test-uuid.json"); - } - - @Test - public void list_based_on_main_file_and_line_number() throws Exception { - String mainFileUuid = "MAIN-FILE-UUID"; - userSessionRule.addProjectUuidPermissions(UserRole.CODEVIEWER, TestFile1.PROJECT_UUID); - dbClient.componentDao().insert(dbSession, - new ComponentDto() - .setUuid(TestFile1.FILE_UUID) - .setLongName(TestFile1.LONG_NAME) - .setKey(TestFile1.KEY) - .setProjectUuid(TestFile1.PROJECT_UUID), - new ComponentDto() - .setUuid(TestFile2.FILE_UUID) - .setLongName(TestFile2.LONG_NAME) - .setProjectUuid(TestFile2.PROJECT_UUID) - .setKey(TestFile2.KEY), - new ComponentDto() - .setUuid(mainFileUuid) - .setProjectUuid(TestFile1.PROJECT_UUID) - ); - dbSession.commit(); - - es.putDocuments(TestIndexDefinition.INDEX, TestIndexDefinition.TYPE, - new TestDoc() - .setUuid(TestFile1.UUID) - .setName(TestFile1.NAME) - .setFileUuid(TestFile1.FILE_UUID) - .setDurationInMs(TestFile1.DURATION_IN_MS) - .setStatus(TestFile1.STATUS) - .setMessage(TestFile1.MESSAGE) - .setCoveredFiles(TestFile1.COVERED_FILES) - .setStackTrace(TestFile1.STACKTRACE), - new TestDoc() - .setUuid(TestFile2.UUID) - .setName(TestFile2.NAME) - .setFileUuid(TestFile2.FILE_UUID) - .setDurationInMs(TestFile2.DURATION_IN_MS) - .setStatus(TestFile2.STATUS) - .setStackTrace(TestFile2.STATUS) - .setMessage(TestFile2.MESSAGE) - .setCoveredFiles(TestFile2.COVERED_FILES) - .setStackTrace(TestFile2.STACKTRACE)); - - WsTester.TestRequest request = ws.newGetRequest("api/tests", "list") - .setParam(TestsListAction.SOURCE_FILE_UUID, mainFileUuid) - .setParam(TestsListAction.SOURCE_FILE_LINE_NUMBER, "10"); - - request.execute().assertJson(getClass(), "list-main-file.json"); - } - - @Test(expected = IllegalArgumentException.class) - public void fail_when_no_argument() throws Exception { - ws.newGetRequest("api/tests", "list").execute(); - } - - @Test(expected = IllegalArgumentException.class) - public void fail_when_main_file_uuid_without_line_number() throws Exception { - ws.newGetRequest("api/tests", "list").setParam(TestsListAction.SOURCE_FILE_UUID, "ANY-UUID").execute(); - } - - @Test(expected = ForbiddenException.class) - public void fail_when_no_sufficent_privilege_on_file_uuid() throws Exception { - userSessionRule.addProjectUuidPermissions(UserRole.USER, TestFile1.PROJECT_UUID); - dbClient.componentDao().insert(dbSession, TestFile1.newDto()); - dbSession.commit(); - ws.newGetRequest("api/tests", "list").setParam(TestsListAction.TEST_FILE_UUID, TestFile1.FILE_UUID).execute(); - } - - @Test(expected = ForbiddenException.class) - public void fail_when_no_sufficent_privilege_on_test_uuid() throws Exception { - userSessionRule.addProjectUuidPermissions(UserRole.USER, TestFile1.PROJECT_UUID); - dbClient.componentDao().insert(dbSession, TestFile1.newDto()); - dbSession.commit(); - ws.newGetRequest("api/tests", "list").setParam(TestsListAction.TEST_FILE_UUID, TestFile1.FILE_UUID).execute(); - } - - @Test(expected = ForbiddenException.class) - public void fail_when_no_sufficent_privilege_on_file_key() throws Exception { - userSessionRule.addProjectUuidPermissions(UserRole.USER, TestFile1.PROJECT_UUID); - dbClient.componentDao().insert(dbSession, TestFile1.newDto()); - dbSession.commit(); - ws.newGetRequest("api/tests", "list").setParam(TestsListAction.TEST_FILE_KEY, TestFile1.KEY).execute(); - } - - @Test(expected = ForbiddenException.class) - public void fail_when_no_sufficient_privilege_on_main_file_uuid() throws Exception { - userSessionRule.addProjectUuidPermissions(UserRole.USER, TestFile1.PROJECT_UUID); - String mainFileUuid = "MAIN-FILE-UUID"; - dbClient.componentDao().insert(dbSession, new ComponentDto().setUuid(mainFileUuid).setProjectUuid(TestFile1.PROJECT_UUID)); - dbSession.commit(); - - ws.newGetRequest("api/tests", "list") - .setParam(TestsListAction.SOURCE_FILE_UUID, mainFileUuid) - .setParam(TestsListAction.SOURCE_FILE_LINE_NUMBER, "10") - .execute(); - } - - private static final class TestFile1 { - public static final String UUID = "TEST-UUID-1"; - public static final String FILE_UUID = "ABCD"; - public static final String PROJECT_UUID = "PROJECT-UUID"; - public static final String NAME = "test1"; - public static final String STATUS = "OK"; - public static final long DURATION_IN_MS = 10; - public static final String MESSAGE = "MESSAGE-1"; - public static final String STACKTRACE = "STACKTRACE-1"; - public static final String KEY = "org.foo.BarTest.java"; - public static final String LONG_NAME = "src/test/java/org/foo/BarTest.java"; - public static final List COVERED_FILES = Arrays.asList(new CoveredFileDoc().setFileUuid("MAIN-FILE-UUID").setCoveredLines(Arrays.asList(1, 2, 3, 10))); - - public static ComponentDto newDto() { - return new ComponentDto() - .setUuid(TestFile1.FILE_UUID) - .setLongName(TestFile1.LONG_NAME) - .setProjectUuid(TestFile1.PROJECT_UUID) - .setKey(TestFile1.KEY); - } - - private TestFile1() { - // static stuff for test purposes - } - } - - private static final class TestFile2 { - public static final String UUID = "TEST-UUID-2"; - public static final String FILE_UUID = "BCDE"; - public static final String PROJECT_UUID = "PROJECT-UUID"; - public static final String NAME = "test2"; - public static final String STATUS = "ERROR"; - public static final long DURATION_IN_MS = 97; - public static final String MESSAGE = "MESSAGE-2"; - public static final String STACKTRACE = "STACKTRACE-2"; - public static final String KEY = "org.foo.FileTest.java"; - public static final String LONG_NAME = "src/test/java/org/foo/FileTest.java"; - public static final List COVERED_FILES = Arrays.asList(new CoveredFileDoc().setFileUuid("MAIN-FILE-UUID").setCoveredLines(Arrays.asList(11, 12, 13, 10))); - - private TestFile2() { - // static stuff for test purposes - } - } - -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/test/ws/TestsWsTest.java b/server/sonar-server/src/test/java/org/sonar/server/test/ws/TestsWsTest.java index c052d9c03bd..545c92fb4f7 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/test/ws/TestsWsTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/test/ws/TestsWsTest.java @@ -41,8 +41,8 @@ public class TestsWsTest { @Before public void setUp() { WsTester tester = new WsTester(new TestsWs( - new TestsListAction(mock(DbClient.class), mock(TestIndex.class), userSessionRule), - new TestsCoveredFilesAction(mock(DbClient.class), mock(TestIndex.class), userSessionRule))); + new ListAction(mock(DbClient.class), mock(TestIndex.class), userSessionRule), + new CoveredFilesAction(mock(DbClient.class), mock(TestIndex.class), userSessionRule))); controller = tester.controller("api/tests"); } diff --git a/server/sonar-server/src/test/java/org/sonar/server/user/ws/CurrentActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/user/ws/CurrentActionTest.java new file mode 100644 index 00000000000..7eba15eba16 --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/user/ws/CurrentActionTest.java @@ -0,0 +1,51 @@ +/* + * 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.user.ws; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.sonar.core.permission.GlobalPermissions; +import org.sonar.server.tester.UserSessionRule; +import org.sonar.server.ws.WsTester; + +public class CurrentActionTest { + @Rule + public UserSessionRule userSessionRule = UserSessionRule.standalone(); + + private WsTester tester; + + @Before + public void before() { + tester = new WsTester(new UsersWs(new CurrentAction(userSessionRule))); + } + + @Test + public void anonymous() throws Exception { + tester.newGetRequest("api/users", "current").execute().assertJson(getClass(), "anonymous.json"); + } + + @Test + public void authenticated() throws Exception { + userSessionRule.login("obiwan.kenobi").setName("Obiwan Kenobi") + .setGlobalPermissions(GlobalPermissions.ALL.toArray(new String[0])); + tester.newGetRequest("api/users", "current").execute().assertJson(getClass(), "authenticated.json"); + } +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/user/ws/CurrentUserActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/user/ws/CurrentUserActionTest.java deleted file mode 100644 index 3ee91682a3f..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/user/ws/CurrentUserActionTest.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * 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.user.ws; - -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.sonar.core.permission.GlobalPermissions; -import org.sonar.server.tester.UserSessionRule; -import org.sonar.server.ws.WsTester; - -public class CurrentUserActionTest { - @Rule - public UserSessionRule userSessionRule = UserSessionRule.standalone(); - - private WsTester tester; - - @Before - public void before() { - tester = new WsTester(new UsersWs(new CurrentUserAction(userSessionRule))); - } - - @Test - public void anonymous() throws Exception { - tester.newGetRequest("api/users", "current").execute().assertJson(getClass(), "anonymous.json"); - } - - @Test - public void authenticated() throws Exception { - userSessionRule.login("obiwan.kenobi").setName("Obiwan Kenobi") - .setGlobalPermissions(GlobalPermissions.ALL.toArray(new String[0])); - tester.newGetRequest("api/users", "current").execute().assertJson(getClass(), "authenticated.json"); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/user/ws/UsersWsTest.java b/server/sonar-server/src/test/java/org/sonar/server/user/ws/UsersWsTest.java index bb5fd484cc5..ccbb54a3830 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/user/ws/UsersWsTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/user/ws/UsersWsTest.java @@ -43,7 +43,7 @@ public class UsersWsTest { WsTester tester = new WsTester(new UsersWs( new CreateAction(mock(UserIndex.class), mock(UserUpdater.class), mock(I18n.class), userSessionRule), new UpdateAction(mock(UserIndex.class), mock(UserUpdater.class), userSessionRule), - new CurrentUserAction(userSessionRule), + new CurrentAction(userSessionRule), new DeactivateAction(mock(UserIndex.class), mock(UserUpdater.class), userSessionRule), new ChangePasswordAction(mock(UserUpdater.class), userSessionRule), new SearchAction(mock(UserIndex.class)))); diff --git a/server/sonar-server/src/test/resources/org/sonar/server/batch/GlobalActionTest/return_global_referentials.json b/server/sonar-server/src/test/resources/org/sonar/server/batch/GlobalActionTest/return_global_referentials.json new file mode 100644 index 00000000000..2e558edbbf6 --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/batch/GlobalActionTest/return_global_referentials.json @@ -0,0 +1,19 @@ +{ + "timestamp": 0, + "metrics": [ + { + "id": 1, + "key": "coverage", + "valueType": "PERCENT", + "description": "Coverage by unit tests", + "direction": 1, + "name": "coverage", + "qualitative": true, + "userManaged": false, + "worstValue": 0.0, + "bestValue": 100.0, + "optimizedBestValue": false + } + ], + "globalSettings": {} +} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/batch/GlobalActionTest/return_global_settings.json b/server/sonar-server/src/test/resources/org/sonar/server/batch/GlobalActionTest/return_global_settings.json new file mode 100644 index 00000000000..d6faa69622a --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/batch/GlobalActionTest/return_global_settings.json @@ -0,0 +1,9 @@ +{ + "timestamp": 0, + "metrics": [], + "globalSettings": { + "foo" : "bar", + "foo.secured" : "1234", + "foo.license.secured" : "5678" + } +} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/batch/GlobalActionTest/return_only_license_settings_without_scan_but_with_preview_permission.json b/server/sonar-server/src/test/resources/org/sonar/server/batch/GlobalActionTest/return_only_license_settings_without_scan_but_with_preview_permission.json new file mode 100644 index 00000000000..b0af2f8ca33 --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/batch/GlobalActionTest/return_only_license_settings_without_scan_but_with_preview_permission.json @@ -0,0 +1,8 @@ +{ + "timestamp": 0, + "metrics": [], + "globalSettings": { + "foo" : "bar", + "foo.license.secured" : "5678" + } +} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/batch/GlobalRepositoryActionTest/return_global_referentials.json b/server/sonar-server/src/test/resources/org/sonar/server/batch/GlobalRepositoryActionTest/return_global_referentials.json deleted file mode 100644 index 2e558edbbf6..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/batch/GlobalRepositoryActionTest/return_global_referentials.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "timestamp": 0, - "metrics": [ - { - "id": 1, - "key": "coverage", - "valueType": "PERCENT", - "description": "Coverage by unit tests", - "direction": 1, - "name": "coverage", - "qualitative": true, - "userManaged": false, - "worstValue": 0.0, - "bestValue": 100.0, - "optimizedBestValue": false - } - ], - "globalSettings": {} -} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/batch/GlobalRepositoryActionTest/return_global_settings.json b/server/sonar-server/src/test/resources/org/sonar/server/batch/GlobalRepositoryActionTest/return_global_settings.json deleted file mode 100644 index d6faa69622a..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/batch/GlobalRepositoryActionTest/return_global_settings.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "timestamp": 0, - "metrics": [], - "globalSettings": { - "foo" : "bar", - "foo.secured" : "1234", - "foo.license.secured" : "5678" - } -} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/batch/GlobalRepositoryActionTest/return_only_license_settings_without_scan_but_with_preview_permission.json b/server/sonar-server/src/test/resources/org/sonar/server/batch/GlobalRepositoryActionTest/return_only_license_settings_without_scan_but_with_preview_permission.json deleted file mode 100644 index b0af2f8ca33..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/batch/GlobalRepositoryActionTest/return_only_license_settings_without_scan_but_with_preview_permission.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "timestamp": 0, - "metrics": [], - "globalSettings": { - "foo" : "bar", - "foo.license.secured" : "5678" - } -} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectActionTest/project_referentials.json b/server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectActionTest/project_referentials.json new file mode 100644 index 00000000000..ff04061219e --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectActionTest/project_referentials.json @@ -0,0 +1,31 @@ +{ + "timestamp": 0, + "qprofilesByLanguage": { + "java": { + "key": "abcd", + "name": "Default", + "language": "java", + "rulesUpdatedAt": "2014-01-14T13:00:00+0100" + } + }, + "activeRules": [ + { + "repositoryKey": "squid", + "ruleKey": "AvoidCycle", + "name": "Avoid Cycle", + "severity": "MINOR", + "internalKey": "squid-1", + "language": "java", + "params": { + "max" : "2" + } + } + ], + "settingsByModule": { + "org.codehaus.sonar:sonar": { + "sonar.jira.project.key": "SONAR", + "sonar.jira.login.secured": "john" + } + }, + "fileDataByModuleAndPath": {} +} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectRepositoryActionTest/project_referentials.json b/server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectRepositoryActionTest/project_referentials.json deleted file mode 100644 index ff04061219e..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectRepositoryActionTest/project_referentials.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "timestamp": 0, - "qprofilesByLanguage": { - "java": { - "key": "abcd", - "name": "Default", - "language": "java", - "rulesUpdatedAt": "2014-01-14T13:00:00+0100" - } - }, - "activeRules": [ - { - "repositoryKey": "squid", - "ruleKey": "AvoidCycle", - "name": "Avoid Cycle", - "severity": "MINOR", - "internalKey": "squid-1", - "language": "java", - "params": { - "max" : "2" - } - } - ], - "settingsByModule": { - "org.codehaus.sonar:sonar": { - "sonar.jira.project.key": "SONAR", - "sonar.jira.login.secured": "john" - } - }, - "fileDataByModuleAndPath": {} -} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/component/ws/AppActionTest/app.json b/server/sonar-server/src/test/resources/org/sonar/server/component/ws/AppActionTest/app.json new file mode 100644 index 00000000000..201fc70537f --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/component/ws/AppActionTest/app.json @@ -0,0 +1,16 @@ +{ + "key": "org.codehaus.sonar:sonar-plugin-api:src/main/java/org/sonar/api/Plugin.java", + "uuid": "ABCDE", + "path": "src/main/java/org/sonar/api/Plugin.java", + "name": "Plugin.java", + "longName": "src/main/java/org/sonar/api/Plugin.java", + "q": "FIL", + "subProject": "org.codehaus.sonar:sonar-plugin-api", + "subProjectName": "SonarQube :: Plugin API", + "project": "org.codehaus.sonar:sonar", + "projectName": "SonarQube", + "fav": true, + "canMarkAsFavourite": true, + "canCreateManualIssue": true, + "measures": {} +} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/component/ws/AppActionTest/app_with_it_measure.json b/server/sonar-server/src/test/resources/org/sonar/server/component/ws/AppActionTest/app_with_it_measure.json new file mode 100644 index 00000000000..0b233ce08e2 --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/component/ws/AppActionTest/app_with_it_measure.json @@ -0,0 +1,16 @@ +{ + "key": "org.codehaus.sonar:sonar-plugin-api:src/main/java/org/sonar/api/Plugin.java", + "uuid": "ABCDE", + "path": "src/main/java/org/sonar/api/Plugin.java", + "name": "Plugin.java", + "longName": "src/main/java/org/sonar/api/Plugin.java", + "q": "FIL", + "subProject": "org.codehaus.sonar:sonar-plugin-api", + "subProjectName": "SonarQube :: Plugin API", + "project": "org.codehaus.sonar:sonar", + "projectName": "SonarQube", + "fav": false, + "canMarkAsFavourite": false, + "canCreateManualIssue": false, + "measures": {"coverage": "85.2%"} +} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/component/ws/AppActionTest/app_with_measures.json b/server/sonar-server/src/test/resources/org/sonar/server/component/ws/AppActionTest/app_with_measures.json new file mode 100644 index 00000000000..606f6594f53 --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/component/ws/AppActionTest/app_with_measures.json @@ -0,0 +1,23 @@ +{ + "key": "org.codehaus.sonar:sonar-plugin-api:src/main/java/org/sonar/api/Plugin.java", + "uuid": "ABCDE", + "path": "src/main/java/org/sonar/api/Plugin.java", + "name": "Plugin.java", + "longName": "src/main/java/org/sonar/api/Plugin.java", + "q": "FIL", + "subProject": "org.codehaus.sonar:sonar-plugin-api", + "subProjectName": "SonarQube :: Plugin API", + "project": "org.codehaus.sonar:sonar", + "projectName": "SonarQube", + "fav": false, + "canMarkAsFavourite": false, + "canCreateManualIssue": false, + "measures": { + "lines": "200", + "coverage": "95.4%", + "duplicationDensity": "7.4%", + "debt": "3h 2min", + "sqaleRating": "C", + "debtRatio": "35.0%" + } +} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/component/ws/AppActionTest/app_with_overall_measure.json b/server/sonar-server/src/test/resources/org/sonar/server/component/ws/AppActionTest/app_with_overall_measure.json new file mode 100644 index 00000000000..7cc5aedb715 --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/component/ws/AppActionTest/app_with_overall_measure.json @@ -0,0 +1,16 @@ +{ + "key": "org.codehaus.sonar:sonar-plugin-api:src/main/java/org/sonar/api/Plugin.java", + "uuid": "ABCDE", + "path": "src/main/java/org/sonar/api/Plugin.java", + "name": "Plugin.java", + "longName": "src/main/java/org/sonar/api/Plugin.java", + "q": "FIL", + "subProject": "org.codehaus.sonar:sonar-plugin-api", + "subProjectName": "SonarQube :: Plugin API", + "project": "org.codehaus.sonar:sonar", + "projectName": "SonarQube", + "fav": false, + "canMarkAsFavourite": false, + "canCreateManualIssue": false, + "measures": {"coverage": "90.1%"} +} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/component/ws/AppActionTest/app_with_ut_measure.json b/server/sonar-server/src/test/resources/org/sonar/server/component/ws/AppActionTest/app_with_ut_measure.json new file mode 100644 index 00000000000..c6ef590ad5d --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/component/ws/AppActionTest/app_with_ut_measure.json @@ -0,0 +1,16 @@ +{ + "key": "org.codehaus.sonar:sonar-plugin-api:src/main/java/org/sonar/api/Plugin.java", + "uuid": "ABCDE", + "path": "src/main/java/org/sonar/api/Plugin.java", + "name": "Plugin.java", + "longName": "src/main/java/org/sonar/api/Plugin.java", + "q": "FIL", + "subProject": "org.codehaus.sonar:sonar-plugin-api", + "subProjectName": "SonarQube :: Plugin API", + "project": "org.codehaus.sonar:sonar", + "projectName": "SonarQube", + "fav": false, + "canMarkAsFavourite": false, + "canCreateManualIssue": false, + "measures": {"coverage": "95.4%"} +} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/component/ws/ComponentAppActionTest/app.json b/server/sonar-server/src/test/resources/org/sonar/server/component/ws/ComponentAppActionTest/app.json deleted file mode 100644 index 201fc70537f..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/component/ws/ComponentAppActionTest/app.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "key": "org.codehaus.sonar:sonar-plugin-api:src/main/java/org/sonar/api/Plugin.java", - "uuid": "ABCDE", - "path": "src/main/java/org/sonar/api/Plugin.java", - "name": "Plugin.java", - "longName": "src/main/java/org/sonar/api/Plugin.java", - "q": "FIL", - "subProject": "org.codehaus.sonar:sonar-plugin-api", - "subProjectName": "SonarQube :: Plugin API", - "project": "org.codehaus.sonar:sonar", - "projectName": "SonarQube", - "fav": true, - "canMarkAsFavourite": true, - "canCreateManualIssue": true, - "measures": {} -} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/component/ws/ComponentAppActionTest/app_with_it_measure.json b/server/sonar-server/src/test/resources/org/sonar/server/component/ws/ComponentAppActionTest/app_with_it_measure.json deleted file mode 100644 index 0b233ce08e2..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/component/ws/ComponentAppActionTest/app_with_it_measure.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "key": "org.codehaus.sonar:sonar-plugin-api:src/main/java/org/sonar/api/Plugin.java", - "uuid": "ABCDE", - "path": "src/main/java/org/sonar/api/Plugin.java", - "name": "Plugin.java", - "longName": "src/main/java/org/sonar/api/Plugin.java", - "q": "FIL", - "subProject": "org.codehaus.sonar:sonar-plugin-api", - "subProjectName": "SonarQube :: Plugin API", - "project": "org.codehaus.sonar:sonar", - "projectName": "SonarQube", - "fav": false, - "canMarkAsFavourite": false, - "canCreateManualIssue": false, - "measures": {"coverage": "85.2%"} -} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/component/ws/ComponentAppActionTest/app_with_measures.json b/server/sonar-server/src/test/resources/org/sonar/server/component/ws/ComponentAppActionTest/app_with_measures.json deleted file mode 100644 index 606f6594f53..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/component/ws/ComponentAppActionTest/app_with_measures.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "key": "org.codehaus.sonar:sonar-plugin-api:src/main/java/org/sonar/api/Plugin.java", - "uuid": "ABCDE", - "path": "src/main/java/org/sonar/api/Plugin.java", - "name": "Plugin.java", - "longName": "src/main/java/org/sonar/api/Plugin.java", - "q": "FIL", - "subProject": "org.codehaus.sonar:sonar-plugin-api", - "subProjectName": "SonarQube :: Plugin API", - "project": "org.codehaus.sonar:sonar", - "projectName": "SonarQube", - "fav": false, - "canMarkAsFavourite": false, - "canCreateManualIssue": false, - "measures": { - "lines": "200", - "coverage": "95.4%", - "duplicationDensity": "7.4%", - "debt": "3h 2min", - "sqaleRating": "C", - "debtRatio": "35.0%" - } -} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/component/ws/ComponentAppActionTest/app_with_overall_measure.json b/server/sonar-server/src/test/resources/org/sonar/server/component/ws/ComponentAppActionTest/app_with_overall_measure.json deleted file mode 100644 index 7cc5aedb715..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/component/ws/ComponentAppActionTest/app_with_overall_measure.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "key": "org.codehaus.sonar:sonar-plugin-api:src/main/java/org/sonar/api/Plugin.java", - "uuid": "ABCDE", - "path": "src/main/java/org/sonar/api/Plugin.java", - "name": "Plugin.java", - "longName": "src/main/java/org/sonar/api/Plugin.java", - "q": "FIL", - "subProject": "org.codehaus.sonar:sonar-plugin-api", - "subProjectName": "SonarQube :: Plugin API", - "project": "org.codehaus.sonar:sonar", - "projectName": "SonarQube", - "fav": false, - "canMarkAsFavourite": false, - "canCreateManualIssue": false, - "measures": {"coverage": "90.1%"} -} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/component/ws/ComponentAppActionTest/app_with_ut_measure.json b/server/sonar-server/src/test/resources/org/sonar/server/component/ws/ComponentAppActionTest/app_with_ut_measure.json deleted file mode 100644 index c6ef590ad5d..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/component/ws/ComponentAppActionTest/app_with_ut_measure.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "key": "org.codehaus.sonar:sonar-plugin-api:src/main/java/org/sonar/api/Plugin.java", - "uuid": "ABCDE", - "path": "src/main/java/org/sonar/api/Plugin.java", - "name": "Plugin.java", - "longName": "src/main/java/org/sonar/api/Plugin.java", - "q": "FIL", - "subProject": "org.codehaus.sonar:sonar-plugin-api", - "subProjectName": "SonarQube :: Plugin API", - "project": "org.codehaus.sonar:sonar", - "projectName": "SonarQube", - "fav": false, - "canMarkAsFavourite": false, - "canCreateManualIssue": false, - "measures": {"coverage": "95.4%"} -} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/component/ws/ProjectsGhostsActionTest/all-projects.json b/server/sonar-server/src/test/resources/org/sonar/server/component/ws/ProjectsGhostsActionTest/all-projects.json deleted file mode 100644 index cd1aad1fa60..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/component/ws/ProjectsGhostsActionTest/all-projects.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "projects": [ - { - "uuid": "ghost-uuid-1", - "key": "ghost-key-1", - "name": "ghost-name-1" - }, - { - "uuid": "ghost-uuid-2", - "key": "ghost-key-2", - "name": "ghost-name-2" - } - ] -} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/component/ws/ProjectsGhostsActionTest/pagination.json b/server/sonar-server/src/test/resources/org/sonar/server/component/ws/ProjectsGhostsActionTest/pagination.json deleted file mode 100644 index 8967d5cb758..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/component/ws/ProjectsGhostsActionTest/pagination.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "p": 3, - "ps": 4, - "total": 10 -} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/component/ws/ProjectsProvisionedActionTest/all-projects.json b/server/sonar-server/src/test/resources/org/sonar/server/component/ws/ProjectsProvisionedActionTest/all-projects.json deleted file mode 100644 index 3fc3e56b540..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/component/ws/ProjectsProvisionedActionTest/all-projects.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "projects":[ - { - "uuid":"provisioned-uuid-1", - "key":"provisioned-key-1", - "name":"provisioned-name-1" - }, - { - "uuid":"provisioned-uuid-2", - "key":"provisioned-key-2", - "name":"provisioned-name-2" - } - ] -} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/computation/ws/HistoryActionMediumTest/list_history_reports.json b/server/sonar-server/src/test/resources/org/sonar/server/computation/ws/HistoryActionMediumTest/list_history_reports.json new file mode 100644 index 00000000000..caa180819a4 --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/computation/ws/HistoryActionMediumTest/list_history_reports.json @@ -0,0 +1,16 @@ +{ + "reports": [ + { + "status": "SUCCESS", + "projectName": "POne", + "projectKey": "P1", + "projectUuid": "U1" + }, + { + "status": "FAILED", + "projectName": "PTwo", + "projectKey": "P2", + "projectUuid": "U2" + } + ] +} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/computation/ws/HistoryWsActionMediumTest/list_history_reports.json b/server/sonar-server/src/test/resources/org/sonar/server/computation/ws/HistoryWsActionMediumTest/list_history_reports.json deleted file mode 100644 index caa180819a4..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/computation/ws/HistoryWsActionMediumTest/list_history_reports.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "reports": [ - { - "status": "SUCCESS", - "projectName": "POne", - "projectKey": "P1", - "projectUuid": "U1" - }, - { - "status": "FAILED", - "projectName": "PTwo", - "projectKey": "P2", - "projectUuid": "U2" - } - ] -} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/computation/ws/QueueActionTest/list_queue_reports.json b/server/sonar-server/src/test/resources/org/sonar/server/computation/ws/QueueActionTest/list_queue_reports.json new file mode 100644 index 00000000000..67f2234136f --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/computation/ws/QueueActionTest/list_queue_reports.json @@ -0,0 +1,13 @@ +{ + "reports": [ + { + "key": 1, + "status": "PENDING", + "projectName": "project-key", + "projectKey": "project-key", + "submittedAt": "2014-10-13T00:00:00+0200", + "startedAt": "2014-10-13T00:00:00+0200", + "finishedAt": "2014-10-13T00:00:00+0200" + } + ] +} \ No newline at end of file diff --git a/server/sonar-server/src/test/resources/org/sonar/server/computation/ws/QueueWsActionTest/list_queue_reports.json b/server/sonar-server/src/test/resources/org/sonar/server/computation/ws/QueueWsActionTest/list_queue_reports.json deleted file mode 100644 index 67f2234136f..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/computation/ws/QueueWsActionTest/list_queue_reports.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "reports": [ - { - "key": 1, - "status": "PENDING", - "projectName": "project-key", - "projectKey": "project-key", - "submittedAt": "2014-10-13T00:00:00+0200", - "startedAt": "2014-10-13T00:00:00+0200", - "finishedAt": "2014-10-13T00:00:00+0200" - } - ] -} \ No newline at end of file diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/IssueShowActionTest/show_issue.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/IssueShowActionTest/show_issue.json deleted file mode 100644 index e53e2b29fe6..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/IssueShowActionTest/show_issue.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "issue": { - "key": "ABCD", - "component": "org.sonar.server.issue.IssueClient", - "componentLongName": "SonarQube :: Issue Client", - "componentQualifier": "FIL", - "componentEnabled": true, - "project": "org.sonar.Sonar", - "projectName": "SonarQube", - "rule": "squid:AvoidCycle", - "ruleName": "Avoid cycle", - "line": 12, - "message": "Fix it", - "resolution": "FIXED", - "status": "CLOSED", - "severity": "MAJOR", - "creationDate": "2014-01-22T19:10:03+0100", - "fCreationDate": "Jan 22, 2014 10:03 AM", - "transitions": [], - "actions": [], - "comments": [], - "changelog": [ - { - "creationDate": "2014-01-22T19:10:03+0100", - "fCreationDate": "Jan 22, 2014 10:03 AM", - "diffs": ["Created"] - } - ] - } -} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/IssueShowActionTest/show_issue_on_removed_component.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/IssueShowActionTest/show_issue_on_removed_component.json deleted file mode 100644 index 33d376a5cc1..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/IssueShowActionTest/show_issue_on_removed_component.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "issue": { - "key": "ABCD", - "component": "org.sonar.server.issue.IssueClient", - "componentLongName": "SonarQube :: Issue Client", - "componentQualifier": "FIL", - "componentEnabled": false, - "project": "org.sonar.Sonar", - "projectName": "SonarQube", - "rule": "squid:AvoidCycle", - "ruleName": "Avoid cycle", - "creationDate": "2014-01-22T19:10:03+0100", - "fCreationDate": "Jan 22, 2014 10:03 AM", - "transitions": [], - "actions": [], - "comments": [], - "changelog": [ - { - "creationDate": "2014-01-22T19:10:03+0100", - "fCreationDate": "Jan 22, 2014 10:03 AM", - "diffs": ["Created"] - } - ] - } -} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/IssueShowActionTest/show_issue_with_action_plan.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/IssueShowActionTest/show_issue_with_action_plan.json deleted file mode 100644 index c03d5c8a8fa..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/IssueShowActionTest/show_issue_with_action_plan.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "issue": { - "key": "ABCD", - "component": "org.sonar.server.issue.IssueClient", - "componentLongName": "SonarQube :: Issue Client", - "componentQualifier": "FIL", - "componentEnabled": true, - "project": "org.sonar.Sonar", - "projectName": "SonarQube", - "rule": "squid:AvoidCycle", - "ruleName": "Avoid cycle", - "actionPlan" : "AP-ABCD", - "actionPlanName" : "Version 4.2", - "creationDate": "2014-01-22T19:10:03+0100", - "fCreationDate": "Jan 22, 2014 10:03 AM", - "transitions": [], - "actions": [], - "comments": [], - "changelog": [ - { - "creationDate": "2014-01-22T19:10:03+0100", - "fCreationDate": "Jan 22, 2014 10:03 AM", - "diffs": ["Created"] - } - ] - } -} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/IssueShowActionTest/show_issue_with_actions.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/IssueShowActionTest/show_issue_with_actions.json deleted file mode 100644 index 8cf6348c5fd..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/IssueShowActionTest/show_issue_with_actions.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "issue": { - "key": "ABCD", - "component": "org.sonar.server.issue.IssueClient", - "componentLongName": "SonarQube :: Issue Client", - "componentQualifier": "FIL", - "componentEnabled": true, - "project": "org.sonar.Sonar", - "projectName": "SonarQube", - "rule": "squid:AvoidCycle", - "ruleName": "Avoid cycle", - "status": "OPEN", - "creationDate": "2014-01-22T19:10:03+0100", - "fCreationDate": "Jan 22, 2014 10:03 AM", - "transitions": [], - "actions": [ - "comment", "assign", "set_tags", "assign_to_me", "plan" - ], - "comments": [], - "changelog": [ - { - "creationDate": "2014-01-22T19:10:03+0100", - "fCreationDate": "Jan 22, 2014 10:03 AM", - "diffs": ["Created"] - } - ] - } -} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/IssueShowActionTest/show_issue_with_changelog.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/IssueShowActionTest/show_issue_with_changelog.json deleted file mode 100644 index 4a1889d57ab..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/IssueShowActionTest/show_issue_with_changelog.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "issue": { - "key": "ABCD", - "component": "org.sonar.server.issue.IssueClient", - "componentLongName": "SonarQube :: Issue Client", - "componentQualifier": "FIL", - "componentEnabled": true, - "project": "org.sonar.Sonar", - "projectName": "SonarQube", - "rule": "squid:AvoidCycle", - "ruleName": "Avoid cycle", - "creationDate": "2014-01-22T19:10:03+0100", - "fCreationDate": "Jan 22, 2014 10:03 AM", - "transitions": [], - "actions": [], - "comments": [], - "changelog": [ - { - "creationDate": "2014-01-22T19:10:03+0100", - "fCreationDate": "Jan 22, 2014 10:03 AM", - "diffs": ["Created"] - }, - { - "userName": "John", - "creationDate": "2014-02-22T19:10:03+0100", - "fCreationDate": "Fev 22, 2014 10:03 AM", - "diffs": ["Action plan updated to 1.0"] - }, - { - "creationDate": "2014-02-23T19:10:03+0100", - "fCreationDate": "Fev 23, 2014 10:03 AM", - "diffs": ["Severity updated from Info to Blocker", "Status updated from Reopen to Resolved"] - } - ] - } -} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/IssueShowActionTest/show_issue_with_characteristics.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/IssueShowActionTest/show_issue_with_characteristics.json deleted file mode 100644 index b227aba9c71..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/IssueShowActionTest/show_issue_with_characteristics.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "issue": { - "key": "ABCD", - "component": "org.sonar.server.issue.IssueClient", - "componentLongName": "SonarQube :: Issue Client", - "componentQualifier": "FIL", - "componentEnabled": true, - "project": "org.sonar.Sonar", - "projectName": "SonarQube", - "rule": "squid:AvoidCycle", - "ruleName": "Avoid cycle", - "characteristic": "Maintainability", - "subCharacteristic": "Readability", - "creationDate": "2014-01-22T19:10:03+0100", - "fCreationDate": "Jan 22, 2014 10:03 AM", - "transitions": [], - "actions": [], - "comments": [], - "changelog": [ - { - "creationDate": "2014-01-22T19:10:03+0100", - "fCreationDate": "Jan 22, 2014 10:03 AM", - "diffs": ["Created"] - } - ] - } -} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/IssueShowActionTest/show_issue_with_comments.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/IssueShowActionTest/show_issue_with_comments.json deleted file mode 100644 index 0827d1f204e..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/IssueShowActionTest/show_issue_with_comments.json +++ /dev/null @@ -1,44 +0,0 @@ -{ - "issue": { - "key": "ABCD", - "component": "org.sonar.server.issue.IssueClient", - "componentLongName": "SonarQube :: Issue Client", - "componentQualifier": "FIL", - "componentEnabled": true, - "project": "org.sonar.Sonar", - "projectName": "SonarQube", - "rule": "squid:AvoidCycle", - "ruleName": "Avoid cycle", - "creationDate": "2014-01-22T19:10:03+0100", - "fCreationDate": "Jan 22, 2014 10:03 AM", - "transitions": [], - "actions": ["comment", "assign", "set_tags", "assign_to_me", "plan"], - "comments": [ - { - "key": "COMMENT-ABCD", - "userName": "John", - "raw": "*My comment*", - "html": "My comment", - "createdAt": "2014-02-22T19:10:03+0100", - "fCreatedAge": "9 days", - "updatable": false - }, - { - "key": "COMMENT-ABCE", - "userName": "Arthur", - "raw": "Another comment", - "html": "Another comment", - "createdAt": "2014-02-23T19:10:03+0100", - "fCreatedAge": "10 days", - "updatable": true - } - ], - "changelog": [ - { - "creationDate": "2014-01-22T19:10:03+0100", - "fCreationDate": "Jan 22, 2014 10:03 AM", - "diffs": ["Created"] - } - ] - } -} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/IssueShowActionTest/show_issue_with_dates.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/IssueShowActionTest/show_issue_with_dates.json deleted file mode 100644 index 5a7b591e687..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/IssueShowActionTest/show_issue_with_dates.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "issue": { - "key": "ABCD", - "component": "org.sonar.server.issue.IssueClient", - "componentLongName": "SonarQube :: Issue Client", - "componentQualifier": "FIL", - "componentEnabled": true, - "project": "org.sonar.Sonar", - "projectName": "SonarQube", - "rule": "squid:AvoidCycle", - "ruleName": "Avoid cycle", - "creationDate": "2014-01-22T19:10:03+0100", - "fCreationDate": "Jan 22, 2014 10:03 AM", - "updateDate": "2014-01-23T19:10:03+0100", - "fUpdateDate": "Jan 23, 2014 10:03 AM", - "fUpdateAge": "9 days", - "closeDate": "2014-01-24T19:10:03+0100", - "fCloseDate": "Jan 24, 2014 10:03 AM", - "transitions": [], - "actions": [], - "comments": [], - "changelog": [ - { - "creationDate": "2014-01-22T19:10:03+0100", - "fCreationDate": "Jan 22, 2014 10:03 AM", - "diffs": ["Created"] - } - ] - } -} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/IssueShowActionTest/show_issue_with_sub_project.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/IssueShowActionTest/show_issue_with_sub_project.json deleted file mode 100644 index 3222be95688..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/IssueShowActionTest/show_issue_with_sub_project.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "issue": { - "key": "ABCD", - "component": "org.sonar.server.issue.IssueClient", - "componentLongName": "SonarQube :: Issue Client", - "componentQualifier": "FIL", - "componentEnabled": true, - "project": "org.sonar.Sonar", - "projectName": "SonarQube", - "subProject": "org.sonar.server.Server", - "subProjectName": "SonarQube :: Server", - "rule": "squid:AvoidCycle", - "ruleName": "Avoid cycle", - "line": 12, - "message": "Fix it", - "resolution": "FIXED", - "status": "CLOSED", - "severity": "MAJOR", - "creationDate": "2014-01-22T19:10:03+0100", - "fCreationDate": "Jan 22, 2014 10:03 AM", - "transitions": [], - "actions": [], - "comments": [], - "changelog": [ - { - "creationDate": "2014-01-22T19:10:03+0100", - "fCreationDate": "Jan 22, 2014 10:03 AM", - "diffs": ["Created"] - } - ] - } -} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/IssueShowActionTest/show_issue_with_technical_debt.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/IssueShowActionTest/show_issue_with_technical_debt.json deleted file mode 100644 index ff29d2d2b49..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/IssueShowActionTest/show_issue_with_technical_debt.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "issue": { - "key": "ABCD", - "component": "org.sonar.server.issue.IssueClient", - "componentLongName": "SonarQube :: Issue Client", - "componentQualifier": "FIL", - "componentEnabled": true, - "project": "org.sonar.Sonar", - "projectName": "SonarQube", - "rule": "squid:AvoidCycle", - "ruleName": "Avoid cycle", - "debt": "2h1min", - "creationDate": "2014-01-22T19:10:03+0100", - "fCreationDate": "Jan 22, 2014 10:03 AM", - "transitions": [], - "actions": [], - "comments": [], - "changelog": [ - { - "creationDate": "2014-01-22T19:10:03+0100", - "fCreationDate": "Jan 22, 2014 10:03 AM", - "diffs": ["Created"] - } - ] - } -} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/IssueShowActionTest/show_issue_with_transitions.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/IssueShowActionTest/show_issue_with_transitions.json deleted file mode 100644 index 9d06cd9d942..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/IssueShowActionTest/show_issue_with_transitions.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "issue": { - "key": "ABCD", - "component": "org.sonar.server.issue.IssueClient", - "componentLongName": "SonarQube :: Issue Client", - "componentQualifier": "FIL", - "componentEnabled": true, - "project": "org.sonar.Sonar", - "projectName": "SonarQube", - "rule": "squid:AvoidCycle", - "ruleName": "Avoid cycle", - "status": "RESOLVED", - "resolution": "FIXED", - "creationDate": "2014-01-22T19:10:03+0100", - "fCreationDate": "Jan 22, 2014 10:03 AM", - "transitions": ["reopen"], - "actions": ["comment"], - "comments": [], - "changelog": [ - { - "creationDate": "2014-01-22T19:10:03+0100", - "fCreationDate": "Jan 22, 2014 10:03 AM", - "diffs": ["Created"] - } - ] - } -} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/IssueShowActionTest/show_issue_with_users.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/IssueShowActionTest/show_issue_with_users.json deleted file mode 100644 index eb96ea579a5..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/IssueShowActionTest/show_issue_with_users.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "issue": { - "key": "ABCD", - "component": "org.sonar.server.issue.IssueClient", - "componentLongName": "SonarQube :: Issue Client", - "componentQualifier": "FIL", - "componentEnabled": true, - "project": "org.sonar.Sonar", - "projectName": "SonarQube", - "rule": "squid:AvoidCycle", - "ruleName": "Avoid cycle", - "assignee": "john", - "assigneeName": "John", - "reporter": "steven", - "reporterName": "Steven", - "author": "Henry", - "creationDate": "2014-01-22T19:10:03+0100", - "fCreationDate": "Jan 22, 2014 10:03 AM", - "transitions": [], - "actions": [], - "comments": [], - "changelog": [ - { - "creationDate": "2014-01-22T19:10:03+0100", - "fCreationDate": "Jan 22, 2014 10:03 AM", - "diffs": ["Created"] - } - ] - } -} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/ShowActionTest/show_issue.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/ShowActionTest/show_issue.json new file mode 100644 index 00000000000..e53e2b29fe6 --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/ShowActionTest/show_issue.json @@ -0,0 +1,30 @@ +{ + "issue": { + "key": "ABCD", + "component": "org.sonar.server.issue.IssueClient", + "componentLongName": "SonarQube :: Issue Client", + "componentQualifier": "FIL", + "componentEnabled": true, + "project": "org.sonar.Sonar", + "projectName": "SonarQube", + "rule": "squid:AvoidCycle", + "ruleName": "Avoid cycle", + "line": 12, + "message": "Fix it", + "resolution": "FIXED", + "status": "CLOSED", + "severity": "MAJOR", + "creationDate": "2014-01-22T19:10:03+0100", + "fCreationDate": "Jan 22, 2014 10:03 AM", + "transitions": [], + "actions": [], + "comments": [], + "changelog": [ + { + "creationDate": "2014-01-22T19:10:03+0100", + "fCreationDate": "Jan 22, 2014 10:03 AM", + "diffs": ["Created"] + } + ] + } +} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/ShowActionTest/show_issue_on_removed_component.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/ShowActionTest/show_issue_on_removed_component.json new file mode 100644 index 00000000000..33d376a5cc1 --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/ShowActionTest/show_issue_on_removed_component.json @@ -0,0 +1,25 @@ +{ + "issue": { + "key": "ABCD", + "component": "org.sonar.server.issue.IssueClient", + "componentLongName": "SonarQube :: Issue Client", + "componentQualifier": "FIL", + "componentEnabled": false, + "project": "org.sonar.Sonar", + "projectName": "SonarQube", + "rule": "squid:AvoidCycle", + "ruleName": "Avoid cycle", + "creationDate": "2014-01-22T19:10:03+0100", + "fCreationDate": "Jan 22, 2014 10:03 AM", + "transitions": [], + "actions": [], + "comments": [], + "changelog": [ + { + "creationDate": "2014-01-22T19:10:03+0100", + "fCreationDate": "Jan 22, 2014 10:03 AM", + "diffs": ["Created"] + } + ] + } +} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/ShowActionTest/show_issue_with_action_plan.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/ShowActionTest/show_issue_with_action_plan.json new file mode 100644 index 00000000000..c03d5c8a8fa --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/ShowActionTest/show_issue_with_action_plan.json @@ -0,0 +1,27 @@ +{ + "issue": { + "key": "ABCD", + "component": "org.sonar.server.issue.IssueClient", + "componentLongName": "SonarQube :: Issue Client", + "componentQualifier": "FIL", + "componentEnabled": true, + "project": "org.sonar.Sonar", + "projectName": "SonarQube", + "rule": "squid:AvoidCycle", + "ruleName": "Avoid cycle", + "actionPlan" : "AP-ABCD", + "actionPlanName" : "Version 4.2", + "creationDate": "2014-01-22T19:10:03+0100", + "fCreationDate": "Jan 22, 2014 10:03 AM", + "transitions": [], + "actions": [], + "comments": [], + "changelog": [ + { + "creationDate": "2014-01-22T19:10:03+0100", + "fCreationDate": "Jan 22, 2014 10:03 AM", + "diffs": ["Created"] + } + ] + } +} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/ShowActionTest/show_issue_with_actions.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/ShowActionTest/show_issue_with_actions.json new file mode 100644 index 00000000000..8cf6348c5fd --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/ShowActionTest/show_issue_with_actions.json @@ -0,0 +1,28 @@ +{ + "issue": { + "key": "ABCD", + "component": "org.sonar.server.issue.IssueClient", + "componentLongName": "SonarQube :: Issue Client", + "componentQualifier": "FIL", + "componentEnabled": true, + "project": "org.sonar.Sonar", + "projectName": "SonarQube", + "rule": "squid:AvoidCycle", + "ruleName": "Avoid cycle", + "status": "OPEN", + "creationDate": "2014-01-22T19:10:03+0100", + "fCreationDate": "Jan 22, 2014 10:03 AM", + "transitions": [], + "actions": [ + "comment", "assign", "set_tags", "assign_to_me", "plan" + ], + "comments": [], + "changelog": [ + { + "creationDate": "2014-01-22T19:10:03+0100", + "fCreationDate": "Jan 22, 2014 10:03 AM", + "diffs": ["Created"] + } + ] + } +} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/ShowActionTest/show_issue_with_changelog.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/ShowActionTest/show_issue_with_changelog.json new file mode 100644 index 00000000000..4a1889d57ab --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/ShowActionTest/show_issue_with_changelog.json @@ -0,0 +1,36 @@ +{ + "issue": { + "key": "ABCD", + "component": "org.sonar.server.issue.IssueClient", + "componentLongName": "SonarQube :: Issue Client", + "componentQualifier": "FIL", + "componentEnabled": true, + "project": "org.sonar.Sonar", + "projectName": "SonarQube", + "rule": "squid:AvoidCycle", + "ruleName": "Avoid cycle", + "creationDate": "2014-01-22T19:10:03+0100", + "fCreationDate": "Jan 22, 2014 10:03 AM", + "transitions": [], + "actions": [], + "comments": [], + "changelog": [ + { + "creationDate": "2014-01-22T19:10:03+0100", + "fCreationDate": "Jan 22, 2014 10:03 AM", + "diffs": ["Created"] + }, + { + "userName": "John", + "creationDate": "2014-02-22T19:10:03+0100", + "fCreationDate": "Fev 22, 2014 10:03 AM", + "diffs": ["Action plan updated to 1.0"] + }, + { + "creationDate": "2014-02-23T19:10:03+0100", + "fCreationDate": "Fev 23, 2014 10:03 AM", + "diffs": ["Severity updated from Info to Blocker", "Status updated from Reopen to Resolved"] + } + ] + } +} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/ShowActionTest/show_issue_with_characteristics.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/ShowActionTest/show_issue_with_characteristics.json new file mode 100644 index 00000000000..b227aba9c71 --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/ShowActionTest/show_issue_with_characteristics.json @@ -0,0 +1,27 @@ +{ + "issue": { + "key": "ABCD", + "component": "org.sonar.server.issue.IssueClient", + "componentLongName": "SonarQube :: Issue Client", + "componentQualifier": "FIL", + "componentEnabled": true, + "project": "org.sonar.Sonar", + "projectName": "SonarQube", + "rule": "squid:AvoidCycle", + "ruleName": "Avoid cycle", + "characteristic": "Maintainability", + "subCharacteristic": "Readability", + "creationDate": "2014-01-22T19:10:03+0100", + "fCreationDate": "Jan 22, 2014 10:03 AM", + "transitions": [], + "actions": [], + "comments": [], + "changelog": [ + { + "creationDate": "2014-01-22T19:10:03+0100", + "fCreationDate": "Jan 22, 2014 10:03 AM", + "diffs": ["Created"] + } + ] + } +} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/ShowActionTest/show_issue_with_comments.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/ShowActionTest/show_issue_with_comments.json new file mode 100644 index 00000000000..0827d1f204e --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/ShowActionTest/show_issue_with_comments.json @@ -0,0 +1,44 @@ +{ + "issue": { + "key": "ABCD", + "component": "org.sonar.server.issue.IssueClient", + "componentLongName": "SonarQube :: Issue Client", + "componentQualifier": "FIL", + "componentEnabled": true, + "project": "org.sonar.Sonar", + "projectName": "SonarQube", + "rule": "squid:AvoidCycle", + "ruleName": "Avoid cycle", + "creationDate": "2014-01-22T19:10:03+0100", + "fCreationDate": "Jan 22, 2014 10:03 AM", + "transitions": [], + "actions": ["comment", "assign", "set_tags", "assign_to_me", "plan"], + "comments": [ + { + "key": "COMMENT-ABCD", + "userName": "John", + "raw": "*My comment*", + "html": "My comment", + "createdAt": "2014-02-22T19:10:03+0100", + "fCreatedAge": "9 days", + "updatable": false + }, + { + "key": "COMMENT-ABCE", + "userName": "Arthur", + "raw": "Another comment", + "html": "Another comment", + "createdAt": "2014-02-23T19:10:03+0100", + "fCreatedAge": "10 days", + "updatable": true + } + ], + "changelog": [ + { + "creationDate": "2014-01-22T19:10:03+0100", + "fCreationDate": "Jan 22, 2014 10:03 AM", + "diffs": ["Created"] + } + ] + } +} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/ShowActionTest/show_issue_with_dates.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/ShowActionTest/show_issue_with_dates.json new file mode 100644 index 00000000000..5a7b591e687 --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/ShowActionTest/show_issue_with_dates.json @@ -0,0 +1,30 @@ +{ + "issue": { + "key": "ABCD", + "component": "org.sonar.server.issue.IssueClient", + "componentLongName": "SonarQube :: Issue Client", + "componentQualifier": "FIL", + "componentEnabled": true, + "project": "org.sonar.Sonar", + "projectName": "SonarQube", + "rule": "squid:AvoidCycle", + "ruleName": "Avoid cycle", + "creationDate": "2014-01-22T19:10:03+0100", + "fCreationDate": "Jan 22, 2014 10:03 AM", + "updateDate": "2014-01-23T19:10:03+0100", + "fUpdateDate": "Jan 23, 2014 10:03 AM", + "fUpdateAge": "9 days", + "closeDate": "2014-01-24T19:10:03+0100", + "fCloseDate": "Jan 24, 2014 10:03 AM", + "transitions": [], + "actions": [], + "comments": [], + "changelog": [ + { + "creationDate": "2014-01-22T19:10:03+0100", + "fCreationDate": "Jan 22, 2014 10:03 AM", + "diffs": ["Created"] + } + ] + } +} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/ShowActionTest/show_issue_with_sub_project.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/ShowActionTest/show_issue_with_sub_project.json new file mode 100644 index 00000000000..3222be95688 --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/ShowActionTest/show_issue_with_sub_project.json @@ -0,0 +1,32 @@ +{ + "issue": { + "key": "ABCD", + "component": "org.sonar.server.issue.IssueClient", + "componentLongName": "SonarQube :: Issue Client", + "componentQualifier": "FIL", + "componentEnabled": true, + "project": "org.sonar.Sonar", + "projectName": "SonarQube", + "subProject": "org.sonar.server.Server", + "subProjectName": "SonarQube :: Server", + "rule": "squid:AvoidCycle", + "ruleName": "Avoid cycle", + "line": 12, + "message": "Fix it", + "resolution": "FIXED", + "status": "CLOSED", + "severity": "MAJOR", + "creationDate": "2014-01-22T19:10:03+0100", + "fCreationDate": "Jan 22, 2014 10:03 AM", + "transitions": [], + "actions": [], + "comments": [], + "changelog": [ + { + "creationDate": "2014-01-22T19:10:03+0100", + "fCreationDate": "Jan 22, 2014 10:03 AM", + "diffs": ["Created"] + } + ] + } +} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/ShowActionTest/show_issue_with_technical_debt.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/ShowActionTest/show_issue_with_technical_debt.json new file mode 100644 index 00000000000..ff29d2d2b49 --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/ShowActionTest/show_issue_with_technical_debt.json @@ -0,0 +1,26 @@ +{ + "issue": { + "key": "ABCD", + "component": "org.sonar.server.issue.IssueClient", + "componentLongName": "SonarQube :: Issue Client", + "componentQualifier": "FIL", + "componentEnabled": true, + "project": "org.sonar.Sonar", + "projectName": "SonarQube", + "rule": "squid:AvoidCycle", + "ruleName": "Avoid cycle", + "debt": "2h1min", + "creationDate": "2014-01-22T19:10:03+0100", + "fCreationDate": "Jan 22, 2014 10:03 AM", + "transitions": [], + "actions": [], + "comments": [], + "changelog": [ + { + "creationDate": "2014-01-22T19:10:03+0100", + "fCreationDate": "Jan 22, 2014 10:03 AM", + "diffs": ["Created"] + } + ] + } +} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/ShowActionTest/show_issue_with_transitions.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/ShowActionTest/show_issue_with_transitions.json new file mode 100644 index 00000000000..9d06cd9d942 --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/ShowActionTest/show_issue_with_transitions.json @@ -0,0 +1,27 @@ +{ + "issue": { + "key": "ABCD", + "component": "org.sonar.server.issue.IssueClient", + "componentLongName": "SonarQube :: Issue Client", + "componentQualifier": "FIL", + "componentEnabled": true, + "project": "org.sonar.Sonar", + "projectName": "SonarQube", + "rule": "squid:AvoidCycle", + "ruleName": "Avoid cycle", + "status": "RESOLVED", + "resolution": "FIXED", + "creationDate": "2014-01-22T19:10:03+0100", + "fCreationDate": "Jan 22, 2014 10:03 AM", + "transitions": ["reopen"], + "actions": ["comment"], + "comments": [], + "changelog": [ + { + "creationDate": "2014-01-22T19:10:03+0100", + "fCreationDate": "Jan 22, 2014 10:03 AM", + "diffs": ["Created"] + } + ] + } +} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/ShowActionTest/show_issue_with_users.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/ShowActionTest/show_issue_with_users.json new file mode 100644 index 00000000000..eb96ea579a5 --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/ShowActionTest/show_issue_with_users.json @@ -0,0 +1,30 @@ +{ + "issue": { + "key": "ABCD", + "component": "org.sonar.server.issue.IssueClient", + "componentLongName": "SonarQube :: Issue Client", + "componentQualifier": "FIL", + "componentEnabled": true, + "project": "org.sonar.Sonar", + "projectName": "SonarQube", + "rule": "squid:AvoidCycle", + "ruleName": "Avoid cycle", + "assignee": "john", + "assigneeName": "John", + "reporter": "steven", + "reporterName": "Steven", + "author": "Henry", + "creationDate": "2014-01-22T19:10:03+0100", + "fCreationDate": "Jan 22, 2014 10:03 AM", + "transitions": [], + "actions": [], + "comments": [], + "changelog": [ + { + "creationDate": "2014-01-22T19:10:03+0100", + "fCreationDate": "Jan 22, 2014 10:03 AM", + "diffs": ["Created"] + } + ] + } +} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/plugins/ws/AvailableActionTest/properties_per_plugin.json b/server/sonar-server/src/test/resources/org/sonar/server/plugins/ws/AvailableActionTest/properties_per_plugin.json new file mode 100644 index 00000000000..8c5ed3bf5aa --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/plugins/ws/AvailableActionTest/properties_per_plugin.json @@ -0,0 +1,33 @@ +{ + "plugins": [ + { + "key": "p_key", + "name": "p_name", + "category": "p_category", + "description": "p_description", + "license": "p_license", + "organizationName": "p_orga_name", + "organizationUrl": "p_orga_url", + "termsAndConditionsUrl": "p_t_and_c_url", + "release": { + "version": "1.12.1", + "date": "2015-04-16" + }, + "update": { + "status": "COMPATIBLE", + "requires": [ + { + "key": "p_key_1", + "name": "p_name_1" + }, + { + "key": "p_key_2", + "name": "p_name_2", + "description": "p_desc_2" + } + ] + } + } + ], + "updateCenterRefresh": "2015-04-24T16:08:36+0200" +} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/plugins/ws/AvailablePluginsWsActionTest/properties_per_plugin.json b/server/sonar-server/src/test/resources/org/sonar/server/plugins/ws/AvailablePluginsWsActionTest/properties_per_plugin.json deleted file mode 100644 index 8c5ed3bf5aa..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/plugins/ws/AvailablePluginsWsActionTest/properties_per_plugin.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "plugins": [ - { - "key": "p_key", - "name": "p_name", - "category": "p_category", - "description": "p_description", - "license": "p_license", - "organizationName": "p_orga_name", - "organizationUrl": "p_orga_url", - "termsAndConditionsUrl": "p_t_and_c_url", - "release": { - "version": "1.12.1", - "date": "2015-04-16" - }, - "update": { - "status": "COMPATIBLE", - "requires": [ - { - "key": "p_key_1", - "name": "p_name_1" - }, - { - "key": "p_key_2", - "name": "p_name_2", - "description": "p_desc_2" - } - ] - } - } - ], - "updateCenterRefresh": "2015-04-24T16:08:36+0200" -} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/plugins/ws/InstalledActionTest/some.jar b/server/sonar-server/src/test/resources/org/sonar/server/plugins/ws/InstalledActionTest/some.jar new file mode 100644 index 00000000000..e69de29bb2d diff --git a/server/sonar-server/src/test/resources/org/sonar/server/plugins/ws/InstalledPluginsWsActionTest/some.jar b/server/sonar-server/src/test/resources/org/sonar/server/plugins/ws/InstalledPluginsWsActionTest/some.jar deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/server/sonar-server/src/test/resources/org/sonar/server/plugins/ws/UpdatablePluginsWsActionTest/properties_per_plugin.json b/server/sonar-server/src/test/resources/org/sonar/server/plugins/ws/UpdatablePluginsWsActionTest/properties_per_plugin.json deleted file mode 100644 index 055feb3713b..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/plugins/ws/UpdatablePluginsWsActionTest/properties_per_plugin.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "plugins": [ - { - "key": "p_key", - "name": "p_name", - "category": "p_category", - "description": "p_description", - "license": "p_license", - "organizationName": "p_orga_name", - "organizationUrl": "p_orga_url", - "termsAndConditionsUrl": "p_t_and_c_url", - "release": { - "version": "1.12.1", - "date": "2015-04-16", - "artifact": { - "name": "p_file.jar", - "url": "http://p_file.jar" - } - }, - "update": { - "status": "COMPATIBLE", - "requires": [ - { - "key": "p_key_1", - "name": "p_name_1" - }, - { - "key": "p_key_2", - "name": "p_name_2", - "description": "p_desc_2" - } - ] - } - } - ] -} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/project/ws/GhostsActionTest/all-projects.json b/server/sonar-server/src/test/resources/org/sonar/server/project/ws/GhostsActionTest/all-projects.json new file mode 100644 index 00000000000..cd1aad1fa60 --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/project/ws/GhostsActionTest/all-projects.json @@ -0,0 +1,14 @@ +{ + "projects": [ + { + "uuid": "ghost-uuid-1", + "key": "ghost-key-1", + "name": "ghost-name-1" + }, + { + "uuid": "ghost-uuid-2", + "key": "ghost-key-2", + "name": "ghost-name-2" + } + ] +} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/project/ws/GhostsActionTest/pagination.json b/server/sonar-server/src/test/resources/org/sonar/server/project/ws/GhostsActionTest/pagination.json new file mode 100644 index 00000000000..8967d5cb758 --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/project/ws/GhostsActionTest/pagination.json @@ -0,0 +1,5 @@ +{ + "p": 3, + "ps": 4, + "total": 10 +} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/project/ws/ProvisionedActionTest/all-projects.json b/server/sonar-server/src/test/resources/org/sonar/server/project/ws/ProvisionedActionTest/all-projects.json new file mode 100644 index 00000000000..3fc3e56b540 --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/project/ws/ProvisionedActionTest/all-projects.json @@ -0,0 +1,14 @@ +{ + "projects":[ + { + "uuid":"provisioned-uuid-1", + "key":"provisioned-key-1", + "name":"provisioned-name-1" + }, + { + "uuid":"provisioned-uuid-2", + "key":"provisioned-key-2", + "name":"provisioned-name-2" + } + ] +} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ChangelogActionTest/changelog_empty.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ChangelogActionTest/changelog_empty.json new file mode 100644 index 00000000000..22d12b01f52 --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ChangelogActionTest/changelog_empty.json @@ -0,0 +1,6 @@ +{ + "total": 0, + "p": 1, + "ps": 50, + "events": [] +} \ No newline at end of file diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ChangelogActionTest/changelog_no_login.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ChangelogActionTest/changelog_no_login.json new file mode 100644 index 00000000000..eb0fe995d92 --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ChangelogActionTest/changelog_no_login.json @@ -0,0 +1,15 @@ +{ + "total": 1, + "p": 1, + "ps": 50, + "events": [ + { + "action" : "ACTIVATED", + "ruleKey" : "xoo:x1", + "ruleName" : "Rule x1", + "params" : { + "severity" : "MAJOR" + } + } + ] +} \ No newline at end of file diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ChangelogActionTest/changelog_no_param.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ChangelogActionTest/changelog_no_param.json new file mode 100644 index 00000000000..9ad8c7cd405 --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ChangelogActionTest/changelog_no_param.json @@ -0,0 +1,17 @@ +{ + "total": 1, + "p": 1, + "ps": 50, + "events": [ + { + "action" : "ACTIVATED", + "authorLogin" : "david", + "authorName" : "David", + "ruleKey" : "xoo:x1", + "ruleName" : "Rule x1", + "params" : { + "severity" : "MAJOR" + } + } + ] +} \ No newline at end of file diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ChangelogActionTest/changelog_nominal.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ChangelogActionTest/changelog_nominal.json new file mode 100644 index 00000000000..b0262c23911 --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ChangelogActionTest/changelog_nominal.json @@ -0,0 +1,18 @@ +{ + "total": 1, + "p": 1, + "ps": 50, + "events": [ + { + "action" : "ACTIVATED", + "authorLogin" : "david", + "authorName" : "David", + "ruleKey" : "xoo:x1", + "ruleName" : "Rule x1", + "params" : { + "severity" : "MAJOR", + "max" : "10" + } + } + ] +} \ No newline at end of file diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ChangelogActionTest/changelog_page1.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ChangelogActionTest/changelog_page1.json new file mode 100644 index 00000000000..adc40882c1b --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ChangelogActionTest/changelog_page1.json @@ -0,0 +1,18 @@ +{ + "total": 2, + "p": 1, + "ps": 1, + "events": [ + { + "action" : "ACTIVATED", + "authorLogin" : "david", + "authorName" : "David", + "ruleKey" : "xoo:x1", + "ruleName" : "Rule x1", + "params" : { + "severity" : "CRITICAL", + "max" : "20" + } + } + ] +} \ No newline at end of file diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ChangelogActionTest/changelog_page2.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ChangelogActionTest/changelog_page2.json new file mode 100644 index 00000000000..728705acc14 --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ChangelogActionTest/changelog_page2.json @@ -0,0 +1,18 @@ +{ + "total": 2, + "p": 2, + "ps": 1, + "events": [ + { + "action" : "ACTIVATED", + "authorLogin" : "david", + "authorName" : "David", + "ruleKey" : "xoo:x1", + "ruleName" : "Rule x1", + "params" : { + "severity" : "MAJOR", + "max" : "10" + } + } + ] +} \ No newline at end of file diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ChangelogActionTest/changelog_page3.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ChangelogActionTest/changelog_page3.json new file mode 100644 index 00000000000..06536dd3116 --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ChangelogActionTest/changelog_page3.json @@ -0,0 +1,6 @@ +{ + "total": 2, + "p": 3, + "ps": 1, + "events": [] +} \ No newline at end of file diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/CompareActionMediumTest/compare_nominal.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/CompareActionMediumTest/compare_nominal.json new file mode 100644 index 00000000000..1d0ef292292 --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/CompareActionMediumTest/compare_nominal.json @@ -0,0 +1,79 @@ +{ + "left" : { + "key" : "xoo-profile-1-01234", + "name" : "Profile 1" + }, + "right" : { + "key" : "xoo-profile-2-12345", + "name" : "Profile 2" + }, + "same" : [ + { + "key" : "blah:rule1", + "pluginKey" : "blah", + "pluginName" : "Blah", + "languageKey": "xoo", + "languageName": "Xoo", + "name" : "Rule1", + "severity" : "BLOCKER" + } + ], + "inLeft" : [ + { + "key" : "blah:rule2", + "pluginKey" : "blah", + "pluginName" : "Blah", + "languageKey": "xoo", + "languageName": "Xoo", + "name" : "Rule2", + "severity" : "BLOCKER" + } + ], + "inRight" : [ + { + "key" : "blah:rule3", + "pluginKey" : "blah", + "pluginName" : "Blah", + "languageKey": "xoo", + "languageName": "Xoo", + "name" : "Rule3", + "severity" : "BLOCKER" + } + ], + "modified" : [ + { + "key" : "blah:rule4", + "pluginKey" : "blah", + "pluginName" : "Blah", + "languageKey": "xoo", + "languageName": "Xoo", + "name" : "Rule4", + "left" : { + "severity" : "BLOCKER", + "params" : { + "param_rule4" : "polop" + } + }, + "right" : { + "severity" : "BLOCKER", + "params" : { + "param_rule4" : "palap" + } + } + }, + { + "key" : "blah:rule5", + "pluginKey" : "blah", + "pluginName" : "Blah", + "languageKey": "xoo", + "languageName": "Xoo", + "name" : "Rule5", + "left" : { + "severity" : "MINOR" + }, + "right" : { + "severity" : "MAJOR" + } + } + ] +} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/CompareActionMediumTest/compare_param_on_left.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/CompareActionMediumTest/compare_param_on_left.json new file mode 100644 index 00000000000..afe92f1d381 --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/CompareActionMediumTest/compare_param_on_left.json @@ -0,0 +1,32 @@ +{ + "left" : { + "key" : "xoo-profile-1-01234", + "name" : "Profile 1" + }, + "right" : { + "key" : "xoo-profile-2-12345", + "name" : "Profile 2" + }, + "same" : [], + "inLeft" : [], + "inRight" : [], + "modified" : [ + { + "key" : "blah:rule1", + "pluginKey" : "blah", + "pluginName" : "Blah", + "languageKey": "xoo", + "languageName": "Xoo", + "name" : "Rule1", + "left" : { + "severity" : "BLOCKER", + "params" : { + "param_rule1" : "polop" + } + }, + "right" : { + "severity" : "BLOCKER" + } + } + ] +} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/CompareActionMediumTest/compare_param_on_right.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/CompareActionMediumTest/compare_param_on_right.json new file mode 100644 index 00000000000..ec902279be3 --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/CompareActionMediumTest/compare_param_on_right.json @@ -0,0 +1,32 @@ +{ + "left" : { + "key" : "xoo-profile-1-01234", + "name" : "Profile 1" + }, + "right" : { + "key" : "xoo-profile-2-12345", + "name" : "Profile 2" + }, + "same" : [], + "inLeft" : [], + "inRight" : [], + "modified" : [ + { + "key" : "blah:rule1", + "pluginKey" : "blah", + "pluginName" : "Blah", + "languageKey": "xoo", + "languageName": "Xoo", + "name" : "Rule1", + "left" : { + "severity" : "BLOCKER" + }, + "right" : { + "severity" : "BLOCKER", + "params" : { + "param_rule1" : "polop" + } + } + } + ] +} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/CopyActionTest/copy_nominal.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/CopyActionTest/copy_nominal.json new file mode 100644 index 00000000000..bbf7ad61dc2 --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/CopyActionTest/copy_nominal.json @@ -0,0 +1,8 @@ +{ + "key": "xoo-other-sonar-way-12345", + "name": "Other Sonar Way", + "language": "xoo", + "languageName": "Xoo", + "isDefault": false, + "isInherited": false +} \ No newline at end of file diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/CopyActionTest/copy_with_parent.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/CopyActionTest/copy_with_parent.json new file mode 100644 index 00000000000..9fefdca7912 --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/CopyActionTest/copy_with_parent.json @@ -0,0 +1,9 @@ +{ + "key": "xoo-other-sonar-way-12345", + "name": "Other Sonar Way", + "language": "xoo", + "languageName": "Xoo", + "isDefault": false, + "isInherited": true, + "parentKey": "xoo-parent-profile-01324" +} \ No newline at end of file diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/CreateActionMediumTest/create-nominal.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/CreateActionMediumTest/create-nominal.json new file mode 100644 index 00000000000..a00e1eb1acc --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/CreateActionMediumTest/create-nominal.json @@ -0,0 +1,9 @@ +{ + "profile": { + "name": "My New Profile", + "language": "xoo", + "languageName": "Xoo", + "isDefault": false, + "isInherited": false + } +} \ No newline at end of file diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/CreateActionMediumTest/create-with-messages.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/CreateActionMediumTest/create-with-messages.json new file mode 100644 index 00000000000..aec5817ffb2 --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/CreateActionMediumTest/create-with-messages.json @@ -0,0 +1,15 @@ +{ + "profile": { + "name": "My Other Profile", + "language": "xoo", + "languageName": "Xoo", + "isDefault": false, + "isInherited": false + }, + "infos": [ + "an info" + ], + "warnings": [ + "a warning" + ] +} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/CreateActionTest/create-no-importer.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/CreateActionTest/create-no-importer.json new file mode 100644 index 00000000000..367abddd246 --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/CreateActionTest/create-no-importer.json @@ -0,0 +1,9 @@ +{ + "profile": { + "name": "Yeehaw!", + "language": "xoo", + "languageName": "Xoo", + "isDefault": false, + "isInherited": false + } +} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ExportersActionTest/exporters.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ExportersActionTest/exporters.json new file mode 100644 index 00000000000..cc0788d870d --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ExportersActionTest/exporters.json @@ -0,0 +1,7 @@ +{ + "exporters": [ + {"key": "findbugs", "name": "FindBugs", "languages": ["java"]}, + {"key": "jslint", "name": "JS Lint", "languages": ["js"]}, + {"key": "vaadin", "name": "Vaadin", "languages": ["java", "js"]} + ] +} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ImportersActionTest/importers.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ImportersActionTest/importers.json new file mode 100644 index 00000000000..2c180eec988 --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ImportersActionTest/importers.json @@ -0,0 +1,7 @@ +{ + "importers": [ + {"key": "findbugs", "name": "FindBugs", "languages": ["java"]}, + {"key": "jslint", "name": "JS Lint", "languages": ["js"]}, + {"key": "vaadin", "name": "Vaadin", "languages": ["java", "js"]} + ] +} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/InheritanceActionMediumTest/inheritance-buWide.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/InheritanceActionMediumTest/inheritance-buWide.json new file mode 100644 index 00000000000..9e3707e5d3f --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/InheritanceActionMediumTest/inheritance-buWide.json @@ -0,0 +1,14 @@ +{ + "profile": { + "key": "xoo-my-bu-profile-23456", "name": "My BU Profile", "parent": "xoo-my-company-profile-12345", + "activeRuleCount": 2, "overridingRuleCount": 1 + }, + "ancestors": [ + {"key": "xoo-my-company-profile-12345", "name": "My Company Profile", "parent": "xoo-my-group-profile-01234", "activeRuleCount": 2}, + {"key": "xoo-my-group-profile-01234", "name": "My Group Profile", "activeRuleCount": 2} + ], + "children": [ + {"key": "xoo-for-project-one-34567", "name": "For Project One", "activeRuleCount": 3}, + {"key": "xoo-for-project-two-45678", "name": "For Project Two", "activeRuleCount": 2, "overridingRuleCount": 1} + ] +} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/InheritanceActionMediumTest/inheritance-simple.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/InheritanceActionMediumTest/inheritance-simple.json new file mode 100644 index 00000000000..b5168de4671 --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/InheritanceActionMediumTest/inheritance-simple.json @@ -0,0 +1,7 @@ +{ + "profile": { + "key": "xoo-nobody-s-boy-01234", "name": "Nobodys Boy", "activeRuleCount": 0 + }, + "ancestors": [], + "children": [] +} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ProjectsActionTest/all.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ProjectsActionTest/all.json new file mode 100644 index 00000000000..186208afb24 --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ProjectsActionTest/all.json @@ -0,0 +1,27 @@ +{ + "results": + [ + { + "uuid": "DEFA", + "name": "Project Four", + "selected": false + }, + { + "uuid": "ABCD", + "name": "Project One", + "selected": true + }, + { + "uuid": "CDEF", + "name": "Project Three", + "selected": false + }, + { + "uuid": "BCDE", + "name": "Project Two", + "selected": true + } + ], + + "more": false +} \ No newline at end of file diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ProjectsActionTest/all_filtered.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ProjectsActionTest/all_filtered.json new file mode 100644 index 00000000000..06877249e6c --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ProjectsActionTest/all_filtered.json @@ -0,0 +1,17 @@ +{ + "results": + [ + { + "uuid": "CDEF", + "name": "Project Three", + "selected": false + }, + { + "uuid": "BCDE", + "name": "Project Two", + "selected": true + } + ], + + "more": false +} \ No newline at end of file diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ProjectsActionTest/authorized_selected.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ProjectsActionTest/authorized_selected.json new file mode 100644 index 00000000000..f5b73779077 --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ProjectsActionTest/authorized_selected.json @@ -0,0 +1,12 @@ +{ + "results": + [ + { + "uuid": "ABCD", + "name": "Project One", + "selected": true + } + ], + + "more": false +} \ No newline at end of file diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ProjectsActionTest/deselected.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ProjectsActionTest/deselected.json new file mode 100644 index 00000000000..2a0ecdb15c7 --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ProjectsActionTest/deselected.json @@ -0,0 +1,17 @@ +{ + "results": + [ + { + "uuid": "DEFA", + "name": "Project Four", + "selected": false + }, + { + "uuid": "CDEF", + "name": "Project Three", + "selected": false + } + ], + + "more": false +} \ No newline at end of file diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ProjectsActionTest/empty.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ProjectsActionTest/empty.json new file mode 100644 index 00000000000..cea4e2ee3c4 --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ProjectsActionTest/empty.json @@ -0,0 +1,6 @@ +{ + "results": + [], + + "more": false +} \ No newline at end of file diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ProjectsActionTest/selected_page1.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ProjectsActionTest/selected_page1.json new file mode 100644 index 00000000000..70668d5b7d5 --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ProjectsActionTest/selected_page1.json @@ -0,0 +1,17 @@ +{ + "results": + [ + { + "uuid": "DEFA", + "name": "Project Four", + "selected": true + }, + { + "uuid": "ABCD", + "name": "Project One", + "selected": true + } + ], + + "more": true +} \ No newline at end of file diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ProjectsActionTest/selected_page2.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ProjectsActionTest/selected_page2.json new file mode 100644 index 00000000000..6b6fd49358b --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ProjectsActionTest/selected_page2.json @@ -0,0 +1,17 @@ +{ + "results": + [ + { + "uuid": "CDEF", + "name": "Project Three", + "selected": true + }, + { + "uuid": "BCDE", + "name": "Project Two", + "selected": true + } + ], + + "more": false +} \ No newline at end of file diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ProjectsActionTest/selected_ps3_page1.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ProjectsActionTest/selected_ps3_page1.json new file mode 100644 index 00000000000..9c803fba2be --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ProjectsActionTest/selected_ps3_page1.json @@ -0,0 +1,22 @@ +{ + "results": + [ + { + "uuid": "DEFA", + "name": "Project Four", + "selected": true + }, + { + "uuid": "ABCD", + "name": "Project One", + "selected": true + }, + { + "uuid": "CDEF", + "name": "Project Three", + "selected": true + } + ], + + "more": true +} \ No newline at end of file diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ProjectsActionTest/selected_ps3_page2.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ProjectsActionTest/selected_ps3_page2.json new file mode 100644 index 00000000000..28f8cd7b86b --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ProjectsActionTest/selected_ps3_page2.json @@ -0,0 +1,12 @@ +{ + "results": + [ + { + "uuid": "BCDE", + "name": "Project Two", + "selected": true + } + ], + + "more": false +} \ No newline at end of file diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileChangelogActionTest/changelog_empty.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileChangelogActionTest/changelog_empty.json deleted file mode 100644 index 22d12b01f52..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileChangelogActionTest/changelog_empty.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "total": 0, - "p": 1, - "ps": 50, - "events": [] -} \ No newline at end of file diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileChangelogActionTest/changelog_no_login.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileChangelogActionTest/changelog_no_login.json deleted file mode 100644 index eb0fe995d92..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileChangelogActionTest/changelog_no_login.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "total": 1, - "p": 1, - "ps": 50, - "events": [ - { - "action" : "ACTIVATED", - "ruleKey" : "xoo:x1", - "ruleName" : "Rule x1", - "params" : { - "severity" : "MAJOR" - } - } - ] -} \ No newline at end of file diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileChangelogActionTest/changelog_no_param.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileChangelogActionTest/changelog_no_param.json deleted file mode 100644 index 9ad8c7cd405..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileChangelogActionTest/changelog_no_param.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "total": 1, - "p": 1, - "ps": 50, - "events": [ - { - "action" : "ACTIVATED", - "authorLogin" : "david", - "authorName" : "David", - "ruleKey" : "xoo:x1", - "ruleName" : "Rule x1", - "params" : { - "severity" : "MAJOR" - } - } - ] -} \ No newline at end of file diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileChangelogActionTest/changelog_nominal.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileChangelogActionTest/changelog_nominal.json deleted file mode 100644 index b0262c23911..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileChangelogActionTest/changelog_nominal.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "total": 1, - "p": 1, - "ps": 50, - "events": [ - { - "action" : "ACTIVATED", - "authorLogin" : "david", - "authorName" : "David", - "ruleKey" : "xoo:x1", - "ruleName" : "Rule x1", - "params" : { - "severity" : "MAJOR", - "max" : "10" - } - } - ] -} \ No newline at end of file diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileChangelogActionTest/changelog_page1.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileChangelogActionTest/changelog_page1.json deleted file mode 100644 index adc40882c1b..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileChangelogActionTest/changelog_page1.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "total": 2, - "p": 1, - "ps": 1, - "events": [ - { - "action" : "ACTIVATED", - "authorLogin" : "david", - "authorName" : "David", - "ruleKey" : "xoo:x1", - "ruleName" : "Rule x1", - "params" : { - "severity" : "CRITICAL", - "max" : "20" - } - } - ] -} \ No newline at end of file diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileChangelogActionTest/changelog_page2.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileChangelogActionTest/changelog_page2.json deleted file mode 100644 index 728705acc14..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileChangelogActionTest/changelog_page2.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "total": 2, - "p": 2, - "ps": 1, - "events": [ - { - "action" : "ACTIVATED", - "authorLogin" : "david", - "authorName" : "David", - "ruleKey" : "xoo:x1", - "ruleName" : "Rule x1", - "params" : { - "severity" : "MAJOR", - "max" : "10" - } - } - ] -} \ No newline at end of file diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileChangelogActionTest/changelog_page3.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileChangelogActionTest/changelog_page3.json deleted file mode 100644 index 06536dd3116..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileChangelogActionTest/changelog_page3.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "total": 2, - "p": 3, - "ps": 1, - "events": [] -} \ No newline at end of file diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileCompareActionMediumTest/compare_nominal.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileCompareActionMediumTest/compare_nominal.json deleted file mode 100644 index 1d0ef292292..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileCompareActionMediumTest/compare_nominal.json +++ /dev/null @@ -1,79 +0,0 @@ -{ - "left" : { - "key" : "xoo-profile-1-01234", - "name" : "Profile 1" - }, - "right" : { - "key" : "xoo-profile-2-12345", - "name" : "Profile 2" - }, - "same" : [ - { - "key" : "blah:rule1", - "pluginKey" : "blah", - "pluginName" : "Blah", - "languageKey": "xoo", - "languageName": "Xoo", - "name" : "Rule1", - "severity" : "BLOCKER" - } - ], - "inLeft" : [ - { - "key" : "blah:rule2", - "pluginKey" : "blah", - "pluginName" : "Blah", - "languageKey": "xoo", - "languageName": "Xoo", - "name" : "Rule2", - "severity" : "BLOCKER" - } - ], - "inRight" : [ - { - "key" : "blah:rule3", - "pluginKey" : "blah", - "pluginName" : "Blah", - "languageKey": "xoo", - "languageName": "Xoo", - "name" : "Rule3", - "severity" : "BLOCKER" - } - ], - "modified" : [ - { - "key" : "blah:rule4", - "pluginKey" : "blah", - "pluginName" : "Blah", - "languageKey": "xoo", - "languageName": "Xoo", - "name" : "Rule4", - "left" : { - "severity" : "BLOCKER", - "params" : { - "param_rule4" : "polop" - } - }, - "right" : { - "severity" : "BLOCKER", - "params" : { - "param_rule4" : "palap" - } - } - }, - { - "key" : "blah:rule5", - "pluginKey" : "blah", - "pluginName" : "Blah", - "languageKey": "xoo", - "languageName": "Xoo", - "name" : "Rule5", - "left" : { - "severity" : "MINOR" - }, - "right" : { - "severity" : "MAJOR" - } - } - ] -} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileCompareActionMediumTest/compare_param_on_left.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileCompareActionMediumTest/compare_param_on_left.json deleted file mode 100644 index afe92f1d381..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileCompareActionMediumTest/compare_param_on_left.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "left" : { - "key" : "xoo-profile-1-01234", - "name" : "Profile 1" - }, - "right" : { - "key" : "xoo-profile-2-12345", - "name" : "Profile 2" - }, - "same" : [], - "inLeft" : [], - "inRight" : [], - "modified" : [ - { - "key" : "blah:rule1", - "pluginKey" : "blah", - "pluginName" : "Blah", - "languageKey": "xoo", - "languageName": "Xoo", - "name" : "Rule1", - "left" : { - "severity" : "BLOCKER", - "params" : { - "param_rule1" : "polop" - } - }, - "right" : { - "severity" : "BLOCKER" - } - } - ] -} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileCompareActionMediumTest/compare_param_on_right.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileCompareActionMediumTest/compare_param_on_right.json deleted file mode 100644 index ec902279be3..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileCompareActionMediumTest/compare_param_on_right.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "left" : { - "key" : "xoo-profile-1-01234", - "name" : "Profile 1" - }, - "right" : { - "key" : "xoo-profile-2-12345", - "name" : "Profile 2" - }, - "same" : [], - "inLeft" : [], - "inRight" : [], - "modified" : [ - { - "key" : "blah:rule1", - "pluginKey" : "blah", - "pluginName" : "Blah", - "languageKey": "xoo", - "languageName": "Xoo", - "name" : "Rule1", - "left" : { - "severity" : "BLOCKER" - }, - "right" : { - "severity" : "BLOCKER", - "params" : { - "param_rule1" : "polop" - } - } - } - ] -} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileCopyActionTest/copy_nominal.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileCopyActionTest/copy_nominal.json deleted file mode 100644 index bbf7ad61dc2..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileCopyActionTest/copy_nominal.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "key": "xoo-other-sonar-way-12345", - "name": "Other Sonar Way", - "language": "xoo", - "languageName": "Xoo", - "isDefault": false, - "isInherited": false -} \ No newline at end of file diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileCopyActionTest/copy_with_parent.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileCopyActionTest/copy_with_parent.json deleted file mode 100644 index 9fefdca7912..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileCopyActionTest/copy_with_parent.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "key": "xoo-other-sonar-way-12345", - "name": "Other Sonar Way", - "language": "xoo", - "languageName": "Xoo", - "isDefault": false, - "isInherited": true, - "parentKey": "xoo-parent-profile-01324" -} \ No newline at end of file diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileCreateActionMediumTest/create-nominal.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileCreateActionMediumTest/create-nominal.json deleted file mode 100644 index a00e1eb1acc..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileCreateActionMediumTest/create-nominal.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "profile": { - "name": "My New Profile", - "language": "xoo", - "languageName": "Xoo", - "isDefault": false, - "isInherited": false - } -} \ No newline at end of file diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileCreateActionMediumTest/create-with-messages.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileCreateActionMediumTest/create-with-messages.json deleted file mode 100644 index aec5817ffb2..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileCreateActionMediumTest/create-with-messages.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "profile": { - "name": "My Other Profile", - "language": "xoo", - "languageName": "Xoo", - "isDefault": false, - "isInherited": false - }, - "infos": [ - "an info" - ], - "warnings": [ - "a warning" - ] -} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileCreateActionTest/create-no-importer.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileCreateActionTest/create-no-importer.json deleted file mode 100644 index 367abddd246..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileCreateActionTest/create-no-importer.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "profile": { - "name": "Yeehaw!", - "language": "xoo", - "languageName": "Xoo", - "isDefault": false, - "isInherited": false - } -} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileExportersActionTest/exporters.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileExportersActionTest/exporters.json deleted file mode 100644 index cc0788d870d..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileExportersActionTest/exporters.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "exporters": [ - {"key": "findbugs", "name": "FindBugs", "languages": ["java"]}, - {"key": "jslint", "name": "JS Lint", "languages": ["js"]}, - {"key": "vaadin", "name": "Vaadin", "languages": ["java", "js"]} - ] -} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileImportersActionTest/importers.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileImportersActionTest/importers.json deleted file mode 100644 index 2c180eec988..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileImportersActionTest/importers.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "importers": [ - {"key": "findbugs", "name": "FindBugs", "languages": ["java"]}, - {"key": "jslint", "name": "JS Lint", "languages": ["js"]}, - {"key": "vaadin", "name": "Vaadin", "languages": ["java", "js"]} - ] -} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileInheritanceActionMediumTest/inheritance-buWide.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileInheritanceActionMediumTest/inheritance-buWide.json deleted file mode 100644 index 9e3707e5d3f..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileInheritanceActionMediumTest/inheritance-buWide.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "profile": { - "key": "xoo-my-bu-profile-23456", "name": "My BU Profile", "parent": "xoo-my-company-profile-12345", - "activeRuleCount": 2, "overridingRuleCount": 1 - }, - "ancestors": [ - {"key": "xoo-my-company-profile-12345", "name": "My Company Profile", "parent": "xoo-my-group-profile-01234", "activeRuleCount": 2}, - {"key": "xoo-my-group-profile-01234", "name": "My Group Profile", "activeRuleCount": 2} - ], - "children": [ - {"key": "xoo-for-project-one-34567", "name": "For Project One", "activeRuleCount": 3}, - {"key": "xoo-for-project-two-45678", "name": "For Project Two", "activeRuleCount": 2, "overridingRuleCount": 1} - ] -} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileInheritanceActionMediumTest/inheritance-simple.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileInheritanceActionMediumTest/inheritance-simple.json deleted file mode 100644 index b5168de4671..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileInheritanceActionMediumTest/inheritance-simple.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "profile": { - "key": "xoo-nobody-s-boy-01234", "name": "Nobodys Boy", "activeRuleCount": 0 - }, - "ancestors": [], - "children": [] -} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileProjectsActionTest/all.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileProjectsActionTest/all.json deleted file mode 100644 index 186208afb24..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileProjectsActionTest/all.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "results": - [ - { - "uuid": "DEFA", - "name": "Project Four", - "selected": false - }, - { - "uuid": "ABCD", - "name": "Project One", - "selected": true - }, - { - "uuid": "CDEF", - "name": "Project Three", - "selected": false - }, - { - "uuid": "BCDE", - "name": "Project Two", - "selected": true - } - ], - - "more": false -} \ No newline at end of file diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileProjectsActionTest/all_filtered.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileProjectsActionTest/all_filtered.json deleted file mode 100644 index 06877249e6c..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileProjectsActionTest/all_filtered.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "results": - [ - { - "uuid": "CDEF", - "name": "Project Three", - "selected": false - }, - { - "uuid": "BCDE", - "name": "Project Two", - "selected": true - } - ], - - "more": false -} \ No newline at end of file diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileProjectsActionTest/authorized_selected.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileProjectsActionTest/authorized_selected.json deleted file mode 100644 index f5b73779077..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileProjectsActionTest/authorized_selected.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "results": - [ - { - "uuid": "ABCD", - "name": "Project One", - "selected": true - } - ], - - "more": false -} \ No newline at end of file diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileProjectsActionTest/deselected.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileProjectsActionTest/deselected.json deleted file mode 100644 index 2a0ecdb15c7..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileProjectsActionTest/deselected.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "results": - [ - { - "uuid": "DEFA", - "name": "Project Four", - "selected": false - }, - { - "uuid": "CDEF", - "name": "Project Three", - "selected": false - } - ], - - "more": false -} \ No newline at end of file diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileProjectsActionTest/empty.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileProjectsActionTest/empty.json deleted file mode 100644 index cea4e2ee3c4..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileProjectsActionTest/empty.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "results": - [], - - "more": false -} \ No newline at end of file diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileProjectsActionTest/selected_page1.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileProjectsActionTest/selected_page1.json deleted file mode 100644 index 70668d5b7d5..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileProjectsActionTest/selected_page1.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "results": - [ - { - "uuid": "DEFA", - "name": "Project Four", - "selected": true - }, - { - "uuid": "ABCD", - "name": "Project One", - "selected": true - } - ], - - "more": true -} \ No newline at end of file diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileProjectsActionTest/selected_page2.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileProjectsActionTest/selected_page2.json deleted file mode 100644 index 6b6fd49358b..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileProjectsActionTest/selected_page2.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "results": - [ - { - "uuid": "CDEF", - "name": "Project Three", - "selected": true - }, - { - "uuid": "BCDE", - "name": "Project Two", - "selected": true - } - ], - - "more": false -} \ No newline at end of file diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileProjectsActionTest/selected_ps3_page1.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileProjectsActionTest/selected_ps3_page1.json deleted file mode 100644 index 9c803fba2be..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileProjectsActionTest/selected_ps3_page1.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "results": - [ - { - "uuid": "DEFA", - "name": "Project Four", - "selected": true - }, - { - "uuid": "ABCD", - "name": "Project One", - "selected": true - }, - { - "uuid": "CDEF", - "name": "Project Three", - "selected": true - } - ], - - "more": true -} \ No newline at end of file diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileProjectsActionTest/selected_ps3_page2.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileProjectsActionTest/selected_ps3_page2.json deleted file mode 100644 index 28f8cd7b86b..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileProjectsActionTest/selected_ps3_page2.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "results": - [ - { - "uuid": "BCDE", - "name": "Project Two", - "selected": true - } - ], - - "more": false -} \ No newline at end of file diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileRestoreActionTest/restore_profile.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileRestoreActionTest/restore_profile.json deleted file mode 100644 index 9375056bade..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileRestoreActionTest/restore_profile.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "profile": { - "name": "Sonar way", - "language": "xoo", - "languageName": "Xoo", - "isDefault": false, - "isInherited": false - }, - "ruleSuccesses": 0, - "ruleFailures": 0 -} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileSearchActionTest/search.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileSearchActionTest/search.json deleted file mode 100644 index 6c051e7ac96..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileSearchActionTest/search.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "profiles": [ - { - "key": "sonar-way-xoo1-12345", - "name": "Sonar way", - "language": "xoo1", - "languageName": "Xoo1", - "isInherited": false, - "isDefault": true, - "activeRuleCount": 11 - }, - { - "key": "my-sonar-way-xoo2-34567", - "name": "My Sonar way", - "language": "xoo2", - "languageName": "Xoo2", - "isInherited": true, - "isDefault": false, - "parentKey": "sonar-way-xoo2-23456", - "parentName": "Sonar way", - "activeRuleCount": 33, - "projectCount": 0 - }, - { - "key": "sonar-way-xoo2-23456", - "name": "Sonar way", - "language": "xoo2", - "languageName": "Xoo2", - "isInherited": false, - "isDefault": false, - "activeRuleCount": 0, - "projectCount": 2 - } - ] -} \ No newline at end of file diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileSearchActionTest/search_fields.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileSearchActionTest/search_fields.json deleted file mode 100644 index 143625c201f..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileSearchActionTest/search_fields.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "profiles": [ - { - "key": "sonar-way-xoo1-12345", - "language": "xoo1" - }, - { - "key": "my-sonar-way-xoo2-34567", - "language": "xoo2" - }, - { - "key": "sonar-way-xoo2-23456", - "language": "xoo2" - } - ] -} \ No newline at end of file diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileSearchActionTest/search_xoo1.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileSearchActionTest/search_xoo1.json deleted file mode 100644 index fcff99ce520..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileSearchActionTest/search_xoo1.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "profiles": [ - { - "key": "sonar-way-xoo1-12345", - "name": "Sonar way", - "language": "xoo1", - "languageName": "Xoo1", - "isInherited": false - } - ] -} \ No newline at end of file diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/RestoreActionTest/restore_profile.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/RestoreActionTest/restore_profile.json new file mode 100644 index 00000000000..9375056bade --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/RestoreActionTest/restore_profile.json @@ -0,0 +1,11 @@ +{ + "profile": { + "name": "Sonar way", + "language": "xoo", + "languageName": "Xoo", + "isDefault": false, + "isInherited": false + }, + "ruleSuccesses": 0, + "ruleFailures": 0 +} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/SearchActionTest/search.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/SearchActionTest/search.json new file mode 100644 index 00000000000..6c051e7ac96 --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/SearchActionTest/search.json @@ -0,0 +1,35 @@ +{ + "profiles": [ + { + "key": "sonar-way-xoo1-12345", + "name": "Sonar way", + "language": "xoo1", + "languageName": "Xoo1", + "isInherited": false, + "isDefault": true, + "activeRuleCount": 11 + }, + { + "key": "my-sonar-way-xoo2-34567", + "name": "My Sonar way", + "language": "xoo2", + "languageName": "Xoo2", + "isInherited": true, + "isDefault": false, + "parentKey": "sonar-way-xoo2-23456", + "parentName": "Sonar way", + "activeRuleCount": 33, + "projectCount": 0 + }, + { + "key": "sonar-way-xoo2-23456", + "name": "Sonar way", + "language": "xoo2", + "languageName": "Xoo2", + "isInherited": false, + "isDefault": false, + "activeRuleCount": 0, + "projectCount": 2 + } + ] +} \ No newline at end of file diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/SearchActionTest/search_fields.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/SearchActionTest/search_fields.json new file mode 100644 index 00000000000..143625c201f --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/SearchActionTest/search_fields.json @@ -0,0 +1,16 @@ +{ + "profiles": [ + { + "key": "sonar-way-xoo1-12345", + "language": "xoo1" + }, + { + "key": "my-sonar-way-xoo2-34567", + "language": "xoo2" + }, + { + "key": "sonar-way-xoo2-23456", + "language": "xoo2" + } + ] +} \ No newline at end of file diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/SearchActionTest/search_xoo1.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/SearchActionTest/search_xoo1.json new file mode 100644 index 00000000000..fcff99ce520 --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/SearchActionTest/search_xoo1.json @@ -0,0 +1,11 @@ +{ + "profiles": [ + { + "key": "sonar-way-xoo1-12345", + "name": "Sonar way", + "language": "xoo1", + "languageName": "Xoo1", + "isInherited": false + } + ] +} \ No newline at end of file diff --git a/server/sonar-server/src/test/resources/org/sonar/server/test/ws/CoveredFilesActionTest/tests-covered-files.json b/server/sonar-server/src/test/resources/org/sonar/server/test/ws/CoveredFilesActionTest/tests-covered-files.json new file mode 100644 index 00000000000..7b37f47bd5d --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/test/ws/CoveredFilesActionTest/tests-covered-files.json @@ -0,0 +1,14 @@ +{ + "files": [ + { + "key": "org.foo.Bar.java", + "longName": "src/main/java/org/foo/Bar.java", + "coveredLines": 10 + }, + { + "key": "org.foo.File.java", + "longName": "src/main/java/org/foo/File.java", + "coveredLines": 3 + } + ] +} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/test/ws/ListActionTest/list-main-file.json b/server/sonar-server/src/test/resources/org/sonar/server/test/ws/ListActionTest/list-main-file.json new file mode 100644 index 00000000000..5a1e62547be --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/test/ws/ListActionTest/list-main-file.json @@ -0,0 +1,28 @@ +{ + "tests": [ + { + "testUuid": "TEST-UUID-1", + "fileUuid": "ABCD", + "name": "test1", + "status": "OK", + "durationInMs": 10, + "coveredLines": 4, + "message": "MESSAGE-1", + "stacktrace": "STACKTRACE-1", + "fileKey": "org.foo.BarTest.java", + "fileLongName": "src/test/java/org/foo/BarTest.java" + }, + { + "testUuid": "TEST-UUID-2", + "fileUuid": "BCDE", + "name": "test2", + "status": "ERROR", + "durationInMs": 97, + "coveredLines": 4, + "message": "MESSAGE-2", + "stacktrace": "STACKTRACE-2", + "fileKey": "org.foo.FileTest.java", + "fileLongName": "src/test/java/org/foo/FileTest.java" + } + ] +} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/test/ws/ListActionTest/list-test-uuid.json b/server/sonar-server/src/test/resources/org/sonar/server/test/ws/ListActionTest/list-test-uuid.json new file mode 100644 index 00000000000..de6d8d86fa2 --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/test/ws/ListActionTest/list-test-uuid.json @@ -0,0 +1,16 @@ +{ + "tests": [ + { + "testUuid": "TEST-UUID-1", + "fileUuid": "ABCD", + "name": "test1", + "status": "OK", + "durationInMs": 10, + "coveredLines": 4, + "message": "MESSAGE-1", + "stacktrace": "STACKTRACE-1", + "fileKey": "org.foo.BarTest.java", + "fileLongName": "src/test/java/org/foo/BarTest.java" + } + ] +} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/test/ws/TestsCoveredFilesActionTest/tests-covered-files.json b/server/sonar-server/src/test/resources/org/sonar/server/test/ws/TestsCoveredFilesActionTest/tests-covered-files.json deleted file mode 100644 index 7b37f47bd5d..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/test/ws/TestsCoveredFilesActionTest/tests-covered-files.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "files": [ - { - "key": "org.foo.Bar.java", - "longName": "src/main/java/org/foo/Bar.java", - "coveredLines": 10 - }, - { - "key": "org.foo.File.java", - "longName": "src/main/java/org/foo/File.java", - "coveredLines": 3 - } - ] -} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/test/ws/TestsListActionTest/list-main-file.json b/server/sonar-server/src/test/resources/org/sonar/server/test/ws/TestsListActionTest/list-main-file.json deleted file mode 100644 index 5a1e62547be..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/test/ws/TestsListActionTest/list-main-file.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "tests": [ - { - "testUuid": "TEST-UUID-1", - "fileUuid": "ABCD", - "name": "test1", - "status": "OK", - "durationInMs": 10, - "coveredLines": 4, - "message": "MESSAGE-1", - "stacktrace": "STACKTRACE-1", - "fileKey": "org.foo.BarTest.java", - "fileLongName": "src/test/java/org/foo/BarTest.java" - }, - { - "testUuid": "TEST-UUID-2", - "fileUuid": "BCDE", - "name": "test2", - "status": "ERROR", - "durationInMs": 97, - "coveredLines": 4, - "message": "MESSAGE-2", - "stacktrace": "STACKTRACE-2", - "fileKey": "org.foo.FileTest.java", - "fileLongName": "src/test/java/org/foo/FileTest.java" - } - ] -} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/test/ws/TestsListActionTest/list-test-uuid.json b/server/sonar-server/src/test/resources/org/sonar/server/test/ws/TestsListActionTest/list-test-uuid.json deleted file mode 100644 index de6d8d86fa2..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/test/ws/TestsListActionTest/list-test-uuid.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "tests": [ - { - "testUuid": "TEST-UUID-1", - "fileUuid": "ABCD", - "name": "test1", - "status": "OK", - "durationInMs": 10, - "coveredLines": 4, - "message": "MESSAGE-1", - "stacktrace": "STACKTRACE-1", - "fileKey": "org.foo.BarTest.java", - "fileLongName": "src/test/java/org/foo/BarTest.java" - } - ] -} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/test/ws/TestsShowActionTest/show.json b/server/sonar-server/src/test/resources/org/sonar/server/test/ws/TestsShowActionTest/show.json deleted file mode 100644 index f8832a0f01f..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/test/ws/TestsShowActionTest/show.json +++ /dev/null @@ -1,18 +0,0 @@ -{ -"tests": [ - { - "name": "test1", - "status": "OK", - "durationInMs": 10, - "coveredLines": 32 - }, - { - "name": "test2", - "status": "ERROR", - "durationInMs": 97, - "coveredLines": 21, - "message": "expected: but was:", - "stackTrace" : "java.lang.AssertionError: expected: but was:\n\tat org.junit.Assert.fail(Assert.java:91)\n\tat org.junit.Assert.failNotEquals(Assert.java:645)\n\tat org.junit.Assert.assertEquals(Assert.java:126)\n\tat org.junit.Assert.assertEquals(Assert.java:145)\n" - } - ] -} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/test/ws/TestsShowActionTest/show_from_test_data.json b/server/sonar-server/src/test/resources/org/sonar/server/test/ws/TestsShowActionTest/show_from_test_data.json deleted file mode 100644 index 97a9239999b..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/test/ws/TestsShowActionTest/show_from_test_data.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "tests": [ - { - "name": "test1", - "status": "OK", - "durationInMs": 10 - }, - { - "name": "test2", - "status": "ERROR", - "durationInMs": 97, - "message": "expected: but was:", - "stackTrace": "java.lang.AssertionError: expected: but was:\n\tat org.junit.Assert.fail(Assert.java:91)\n\tat org.junit.Assert.failNotEquals(Assert.java:645)\n\tat org.junit.Assert.assertEquals(Assert.java:126)\n\tat org.junit.Assert.assertEquals(Assert.java:145)\n" - } - ] -} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/test/ws/TestsShowActionTest/show_from_test_data_with_a_time_in_float.json b/server/sonar-server/src/test/resources/org/sonar/server/test/ws/TestsShowActionTest/show_from_test_data_with_a_time_in_float.json deleted file mode 100644 index 3f45bdbbe10..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/test/ws/TestsShowActionTest/show_from_test_data_with_a_time_in_float.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "tests": [ - { - "name": "test1", - "status": "OK", - "durationInMs": 12 - } - ] -} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/user/ws/CurrentActionTest/anonymous.json b/server/sonar-server/src/test/resources/org/sonar/server/user/ws/CurrentActionTest/anonymous.json new file mode 100644 index 00000000000..ba25670ea7d --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/user/ws/CurrentActionTest/anonymous.json @@ -0,0 +1,6 @@ +{ + "isLoggedIn": false, + "permissions": { + "global": [] + } +} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/user/ws/CurrentActionTest/authenticated.json b/server/sonar-server/src/test/resources/org/sonar/server/user/ws/CurrentActionTest/authenticated.json new file mode 100644 index 00000000000..ae2de7f3f69 --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/user/ws/CurrentActionTest/authenticated.json @@ -0,0 +1,8 @@ +{ + "isLoggedIn": true, + "login": "obiwan.kenobi", + "name": "Obiwan Kenobi", + "permissions": { + "global": ["admin", "profileadmin", "shareDashboard", "scan", "dryRunScan", "provisioning"] + } +} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/user/ws/CurrentUserActionTest/anonymous.json b/server/sonar-server/src/test/resources/org/sonar/server/user/ws/CurrentUserActionTest/anonymous.json deleted file mode 100644 index ba25670ea7d..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/user/ws/CurrentUserActionTest/anonymous.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "isLoggedIn": false, - "permissions": { - "global": [] - } -} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/user/ws/CurrentUserActionTest/authenticated.json b/server/sonar-server/src/test/resources/org/sonar/server/user/ws/CurrentUserActionTest/authenticated.json deleted file mode 100644 index ae2de7f3f69..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/user/ws/CurrentUserActionTest/authenticated.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "isLoggedIn": true, - "login": "obiwan.kenobi", - "name": "Obiwan Kenobi", - "permissions": { - "global": ["admin", "profileadmin", "shareDashboard", "scan", "dryRunScan", "provisioning"] - } -}