package org.sonar.server.authentication.ws;
+import com.google.common.io.Resources;
import org.sonar.api.server.ws.RailsHandler;
import org.sonar.api.server.ws.WebService;
controller.createAction("validate")
.setDescription("Check credentials")
.setSince("3.3")
- .setHandler(RailsHandler.INSTANCE);
+ .setHandler(RailsHandler.INSTANCE)
+ .setResponseExample(Resources.getResource(this.getClass(), "example-validate.json"));
controller.done();
}
+++ /dev/null
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-package org.sonar.server.issue;
-
-import com.google.common.base.Function;
-import com.google.common.collect.Iterables;
-import org.sonar.api.ServerComponent;
-import org.sonar.api.issue.ActionPlan;
-import org.sonar.api.issue.IssueQuery;
-import org.sonar.api.issue.internal.DefaultIssue;
-import org.sonar.api.issue.internal.IssueChangeContext;
-import org.sonar.api.web.UserRole;
-import org.sonar.core.issue.ActionPlanDeadlineComparator;
-import org.sonar.core.issue.ActionPlanStats;
-import org.sonar.core.issue.DefaultActionPlan;
-import org.sonar.core.issue.IssueUpdater;
-import org.sonar.core.issue.db.*;
-import org.sonar.core.resource.ResourceDao;
-import org.sonar.core.resource.ResourceDto;
-import org.sonar.core.resource.ResourceQuery;
-import org.sonar.server.exceptions.NotFoundException;
-import org.sonar.server.user.UserSession;
-
-import javax.annotation.CheckForNull;
-
-import java.util.*;
-
-import static com.google.common.collect.Lists.newArrayList;
-
-/**
- * @since 3.6
- */
-public class ActionPlanService implements ServerComponent {
-
- private final ActionPlanDao actionPlanDao;
- private final ActionPlanStatsDao actionPlanStatsDao;
- private final ResourceDao resourceDao;
- private final IssueDao issueDao;
- private final IssueUpdater issueUpdater;
- private final IssueStorage issueStorage;
-
- public ActionPlanService(ActionPlanDao actionPlanDao, ActionPlanStatsDao actionPlanStatsDao, ResourceDao resourceDao,
- IssueDao issueDao, IssueUpdater issueUpdater, IssueStorage issueStorage) {
- this.actionPlanDao = actionPlanDao;
- this.actionPlanStatsDao = actionPlanStatsDao;
- this.resourceDao = resourceDao;
- this.issueDao = issueDao;
- this.issueUpdater = issueUpdater;
- this.issueStorage = issueStorage;
- }
-
- public ActionPlan create(ActionPlan actionPlan, UserSession userSession) {
- ResourceDto project = findProject(actionPlan.projectKey());
- checkUserIsProjectAdministrator(project.getKey(), userSession);
- actionPlanDao.save(ActionPlanDto.toActionDto(actionPlan, project.getId()));
- return actionPlan;
- }
-
- public ActionPlan update(ActionPlan actionPlan, UserSession userSession) {
- ResourceDto project = findProject(actionPlan.projectKey());
- checkUserIsProjectAdministrator(project.getKey(), userSession);
- actionPlanDao.update(ActionPlanDto.toActionDto(actionPlan, project.getId()));
- return actionPlan;
- }
-
- public void delete(String actionPlanKey, UserSession userSession) {
- ActionPlanDto dto = findActionPlanDto(actionPlanKey);
- checkUserIsProjectAdministrator(dto.getProjectKey(), userSession);
- unplanIssues(dto.toActionPlan(), userSession);
- actionPlanDao.delete(actionPlanKey);
- }
-
- /**
- * Unplan all issues linked to an action plan
- */
- private void unplanIssues(DefaultActionPlan actionPlan, UserSession userSession) {
- // Get all issues linked to this plan (need to disable pagination and authorization check)
- IssueQuery query = IssueQuery.builder().actionPlans(Arrays.asList(actionPlan.key())).requiredRole(null).build();
- List<IssueDto> dtos = issueDao.selectIssues(query);
- IssueChangeContext context = IssueChangeContext.createUser(new Date(), userSession.login());
- List<DefaultIssue> issues = newArrayList();
- for (IssueDto issueDto : dtos) {
- DefaultIssue issue = issueDto.toDefaultIssue();
- // Unplan issue
- if (issueUpdater.plan(issue, null, context)) {
- issues.add(issue);
- }
- }
- // Save all issues
- issueStorage.save(issues);
- }
-
- public ActionPlan setStatus(String actionPlanKey, String status, UserSession userSession) {
- ActionPlanDto actionPlanDto = findActionPlanDto(actionPlanKey);
- checkUserIsProjectAdministrator(actionPlanDto.getProjectKey(), userSession);
-
- actionPlanDto.setStatus(status);
- actionPlanDto.setCreatedAt(new Date());
- actionPlanDao.update(actionPlanDto);
- return actionPlanDto.toActionPlan();
- }
-
- @CheckForNull
- public ActionPlan findByKey(String key, UserSession userSession) {
- ActionPlanDto actionPlanDto = actionPlanDao.findByKey(key);
- if (actionPlanDto == null) {
- return null;
- }
- checkUserCanAccessProject(actionPlanDto.getProjectKey(), userSession);
- return actionPlanDto.toActionPlan();
- }
-
- public List<ActionPlan> findByKeys(Collection<String> keys) {
- List<ActionPlanDto> actionPlanDtos = actionPlanDao.findByKeys(keys);
- return toActionPlans(actionPlanDtos);
- }
-
- public Collection<ActionPlan> findOpenByProjectKey(String projectKey, UserSession userSession) {
- ResourceDto project = findProject(projectKey);
- checkUserCanAccessProject(project.getKey(), userSession);
-
- List<ActionPlanDto> dtos = actionPlanDao.findOpenByProjectId(project.getId());
- List<ActionPlan> plans = toActionPlans(dtos);
- Collections.sort(plans, new ActionPlanDeadlineComparator());
- return plans;
- }
-
- public List<ActionPlanStats> findActionPlanStats(String projectKey, UserSession userSession) {
- ResourceDto project = findProject(projectKey);
- checkUserCanAccessProject(project.getKey(), userSession);
-
- List<ActionPlanStatsDto> actionPlanStatsDtos = actionPlanStatsDao.findByProjectId(project.getId());
- List<ActionPlanStats> actionPlanStats = newArrayList(Iterables.transform(actionPlanStatsDtos, new Function<ActionPlanStatsDto, ActionPlanStats>() {
- @Override
- public ActionPlanStats apply(ActionPlanStatsDto actionPlanStatsDto) {
- return actionPlanStatsDto.toActionPlanStat();
- }
- }));
- Collections.sort(actionPlanStats, new ActionPlanDeadlineComparator());
- return actionPlanStats;
- }
-
- public boolean isNameAlreadyUsedForProject(String name, String projectKey) {
- return !actionPlanDao.findByNameAndProjectId(name, findProject(projectKey).getId()).isEmpty();
- }
-
- private List<ActionPlan> toActionPlans(List<ActionPlanDto> actionPlanDtos) {
- return newArrayList(Iterables.transform(actionPlanDtos, new Function<ActionPlanDto, ActionPlan>() {
- @Override
- public ActionPlan apply(ActionPlanDto actionPlanDto) {
- return actionPlanDto.toActionPlan();
- }
- }));
- }
-
- private ActionPlanDto findActionPlanDto(String actionPlanKey) {
- ActionPlanDto actionPlanDto = actionPlanDao.findByKey(actionPlanKey);
- if (actionPlanDto == null) {
- throw new NotFoundException("Action plan " + actionPlanKey + " has not been found.");
- }
- return actionPlanDto;
- }
-
- private ResourceDto findProject(String projectKey) {
- ResourceDto resourceDto = resourceDao.getResource(ResourceQuery.create().setKey(projectKey));
- if (resourceDto == null) {
- throw new NotFoundException("Project " + projectKey + " does not exists.");
- }
- return resourceDto;
- }
-
- private void checkUserCanAccessProject(String projectKey, UserSession userSession) {
- userSession.checkProjectPermission(UserRole.USER, projectKey);
- }
-
- private void checkUserIsProjectAdministrator(String projectKey, UserSession userSession) {
- userSession.checkProjectPermission(UserRole.ADMIN, projectKey);
- }
-
-}
import org.sonar.core.persistence.MyBatis;
import org.sonar.core.resource.ResourceDao;
import org.sonar.core.rule.DefaultRuleFinder;
+import org.sonar.server.issue.actionplan.ActionPlanService;
import org.sonar.server.user.UserSession;
import javax.annotation.CheckForNull;
import org.sonar.core.resource.ResourceDto;
import org.sonar.core.resource.ResourceQuery;
import org.sonar.server.exceptions.BadRequestException;
+import org.sonar.server.issue.actionplan.ActionPlanService;
import org.sonar.server.issue.filter.IssueFilterParameters;
import org.sonar.server.issue.filter.IssueFilterResult;
import org.sonar.server.issue.filter.IssueFilterService;
import org.sonar.core.resource.ResourceDto;
import org.sonar.core.resource.ResourceQuery;
import org.sonar.core.user.AuthorizationDao;
+import org.sonar.server.issue.actionplan.ActionPlanService;
import org.sonar.server.user.UserSession;
import javax.annotation.Nullable;
import org.sonar.api.issue.condition.IsUnResolved;
import org.sonar.api.issue.internal.DefaultIssue;
import org.sonar.core.issue.IssueUpdater;
+import org.sonar.server.issue.actionplan.ActionPlanService;
import org.sonar.server.user.UserSession;
import java.util.List;
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonar.server.issue.actionplan;
+
+import com.google.common.base.Function;
+import com.google.common.collect.Iterables;
+import org.sonar.api.ServerComponent;
+import org.sonar.api.issue.ActionPlan;
+import org.sonar.api.issue.IssueQuery;
+import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.api.issue.internal.IssueChangeContext;
+import org.sonar.api.web.UserRole;
+import org.sonar.core.issue.ActionPlanDeadlineComparator;
+import org.sonar.core.issue.ActionPlanStats;
+import org.sonar.core.issue.DefaultActionPlan;
+import org.sonar.core.issue.IssueUpdater;
+import org.sonar.core.issue.db.*;
+import org.sonar.core.resource.ResourceDao;
+import org.sonar.core.resource.ResourceDto;
+import org.sonar.core.resource.ResourceQuery;
+import org.sonar.server.exceptions.NotFoundException;
+import org.sonar.server.user.UserSession;
+
+import javax.annotation.CheckForNull;
+
+import java.util.*;
+
+import static com.google.common.collect.Lists.newArrayList;
+
+/**
+ * @since 3.6
+ */
+public class ActionPlanService implements ServerComponent {
+
+ private final ActionPlanDao actionPlanDao;
+ private final ActionPlanStatsDao actionPlanStatsDao;
+ private final ResourceDao resourceDao;
+ private final IssueDao issueDao;
+ private final IssueUpdater issueUpdater;
+ private final IssueStorage issueStorage;
+
+ public ActionPlanService(ActionPlanDao actionPlanDao, ActionPlanStatsDao actionPlanStatsDao, ResourceDao resourceDao,
+ IssueDao issueDao, IssueUpdater issueUpdater, IssueStorage issueStorage) {
+ this.actionPlanDao = actionPlanDao;
+ this.actionPlanStatsDao = actionPlanStatsDao;
+ this.resourceDao = resourceDao;
+ this.issueDao = issueDao;
+ this.issueUpdater = issueUpdater;
+ this.issueStorage = issueStorage;
+ }
+
+ public ActionPlan create(ActionPlan actionPlan, UserSession userSession) {
+ ResourceDto project = findProject(actionPlan.projectKey());
+ checkUserIsProjectAdministrator(project.getKey(), userSession);
+ actionPlanDao.save(ActionPlanDto.toActionDto(actionPlan, project.getId()));
+ return actionPlan;
+ }
+
+ public ActionPlan update(ActionPlan actionPlan, UserSession userSession) {
+ ResourceDto project = findProject(actionPlan.projectKey());
+ checkUserIsProjectAdministrator(project.getKey(), userSession);
+ actionPlanDao.update(ActionPlanDto.toActionDto(actionPlan, project.getId()));
+ return actionPlan;
+ }
+
+ public void delete(String actionPlanKey, UserSession userSession) {
+ ActionPlanDto dto = findActionPlanDto(actionPlanKey);
+ checkUserIsProjectAdministrator(dto.getProjectKey(), userSession);
+ unplanIssues(dto.toActionPlan(), userSession);
+ actionPlanDao.delete(actionPlanKey);
+ }
+
+ /**
+ * Unplan all issues linked to an action plan
+ */
+ private void unplanIssues(DefaultActionPlan actionPlan, UserSession userSession) {
+ // Get all issues linked to this plan (need to disable pagination and authorization check)
+ IssueQuery query = IssueQuery.builder().actionPlans(Arrays.asList(actionPlan.key())).requiredRole(null).build();
+ List<IssueDto> dtos = issueDao.selectIssues(query);
+ IssueChangeContext context = IssueChangeContext.createUser(new Date(), userSession.login());
+ List<DefaultIssue> issues = newArrayList();
+ for (IssueDto issueDto : dtos) {
+ DefaultIssue issue = issueDto.toDefaultIssue();
+ // Unplan issue
+ if (issueUpdater.plan(issue, null, context)) {
+ issues.add(issue);
+ }
+ }
+ // Save all issues
+ issueStorage.save(issues);
+ }
+
+ public ActionPlan setStatus(String actionPlanKey, String status, UserSession userSession) {
+ ActionPlanDto actionPlanDto = findActionPlanDto(actionPlanKey);
+ checkUserIsProjectAdministrator(actionPlanDto.getProjectKey(), userSession);
+
+ actionPlanDto.setStatus(status);
+ actionPlanDto.setCreatedAt(new Date());
+ actionPlanDao.update(actionPlanDto);
+ return actionPlanDto.toActionPlan();
+ }
+
+ @CheckForNull
+ public ActionPlan findByKey(String key, UserSession userSession) {
+ ActionPlanDto actionPlanDto = actionPlanDao.findByKey(key);
+ if (actionPlanDto == null) {
+ return null;
+ }
+ checkUserCanAccessProject(actionPlanDto.getProjectKey(), userSession);
+ return actionPlanDto.toActionPlan();
+ }
+
+ public List<ActionPlan> findByKeys(Collection<String> keys) {
+ List<ActionPlanDto> actionPlanDtos = actionPlanDao.findByKeys(keys);
+ return toActionPlans(actionPlanDtos);
+ }
+
+ public Collection<ActionPlan> findOpenByProjectKey(String projectKey, UserSession userSession) {
+ ResourceDto project = findProject(projectKey);
+ checkUserCanAccessProject(project.getKey(), userSession);
+
+ List<ActionPlanDto> dtos = actionPlanDao.findOpenByProjectId(project.getId());
+ List<ActionPlan> plans = toActionPlans(dtos);
+ Collections.sort(plans, new ActionPlanDeadlineComparator());
+ return plans;
+ }
+
+ public List<ActionPlanStats> findActionPlanStats(String projectKey, UserSession userSession) {
+ ResourceDto project = findProject(projectKey);
+ checkUserCanAccessProject(project.getKey(), userSession);
+
+ List<ActionPlanStatsDto> actionPlanStatsDtos = actionPlanStatsDao.findByProjectId(project.getId());
+ List<ActionPlanStats> actionPlanStats = newArrayList(Iterables.transform(actionPlanStatsDtos, new Function<ActionPlanStatsDto, ActionPlanStats>() {
+ @Override
+ public ActionPlanStats apply(ActionPlanStatsDto actionPlanStatsDto) {
+ return actionPlanStatsDto.toActionPlanStat();
+ }
+ }));
+ Collections.sort(actionPlanStats, new ActionPlanDeadlineComparator());
+ return actionPlanStats;
+ }
+
+ public boolean isNameAlreadyUsedForProject(String name, String projectKey) {
+ return !actionPlanDao.findByNameAndProjectId(name, findProject(projectKey).getId()).isEmpty();
+ }
+
+ private List<ActionPlan> toActionPlans(List<ActionPlanDto> actionPlanDtos) {
+ return newArrayList(Iterables.transform(actionPlanDtos, new Function<ActionPlanDto, ActionPlan>() {
+ @Override
+ public ActionPlan apply(ActionPlanDto actionPlanDto) {
+ return actionPlanDto.toActionPlan();
+ }
+ }));
+ }
+
+ private ActionPlanDto findActionPlanDto(String actionPlanKey) {
+ ActionPlanDto actionPlanDto = actionPlanDao.findByKey(actionPlanKey);
+ if (actionPlanDto == null) {
+ throw new NotFoundException("Action plan " + actionPlanKey + " has not been found.");
+ }
+ return actionPlanDto;
+ }
+
+ private ResourceDto findProject(String projectKey) {
+ ResourceDto resourceDto = resourceDao.getResource(ResourceQuery.create().setKey(projectKey));
+ if (resourceDto == null) {
+ throw new NotFoundException("Project " + projectKey + " does not exists.");
+ }
+ return resourceDto;
+ }
+
+ private void checkUserCanAccessProject(String projectKey, UserSession userSession) {
+ userSession.checkProjectPermission(UserRole.USER, projectKey);
+ }
+
+ private void checkUserIsProjectAdministrator(String projectKey, UserSession userSession) {
+ userSession.checkProjectPermission(UserRole.ADMIN, projectKey);
+ }
+
+}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonar.server.issue.actionplan;
+
+import com.google.common.io.Resources;
+import org.sonar.api.server.ws.RailsHandler;
+import org.sonar.api.server.ws.WebService;
+
+public class ActionPlanWs implements WebService {
+
+ @Override
+ public void define(Context context) {
+ NewController controller = context.createController("api/action_plans");
+ controller.setDescription("Action plans");
+
+ WebService.NewAction search = controller.createAction("search")
+ .setDescription("Get a list of action plans. Requires Browse permission on project")
+ .setSince("3.6")
+ .setHandler(RailsHandler.INSTANCE)
+ .setResponseExample(Resources.getResource(this.getClass(), "example-search.json"));
+ addProjectParam(search);
+
+ WebService.NewAction create = controller.createAction("create")
+ .setDescription("Create an action plan. Requires Administer permission on project")
+ .setSince("3.6")
+ .setPost(true)
+ .setHandler(RailsHandler.INSTANCE);
+ addNameParam(create);
+ addDescriptionParam(create);
+ addDeadLineParam(create);
+ addProjectParam(create);
+
+ WebService.NewAction update = controller.createAction("update")
+ .setDescription("Update an action plan. Requires Administer permission on project")
+ .setSince("3.6")
+ .setPost(true)
+ .setHandler(RailsHandler.INSTANCE);
+ addKeyParam(update);
+ addNameParam(update);
+ addDescriptionParam(update);
+ addDeadLineParam(update);
+
+ WebService.NewAction delete = controller.createAction("delete")
+ .setDescription("Delete an action plan. Requires Administer permission on project")
+ .setSince("3.6")
+ .setPost(true)
+ .setHandler(RailsHandler.INSTANCE);
+ addKeyParam(delete);
+
+ WebService.NewAction open = controller.createAction("open")
+ .setDescription("Open an action plan. Requires Administer permission on project")
+ .setSince("3.6")
+ .setPost(true)
+ .setHandler(RailsHandler.INSTANCE);
+ addKeyParam(open);
+
+ WebService.NewAction close = controller.createAction("close")
+ .setDescription("Close an action plan. Requires Administer permission on project")
+ .setSince("3.6")
+ .setPost(true)
+ .setHandler(RailsHandler.INSTANCE);
+ addKeyParam(close);
+
+ controller.done();
+ }
+
+ private static NewParam addKeyParam(WebService.NewAction action) {
+ return action.createParam("key")
+ .setDescription("Key of the action plan")
+ .setExampleValue("3f19de90-1521-4482-a737-a311758ff513")
+ .setRequired(true);
+ }
+
+ private static NewParam addNameParam(WebService.NewAction action) {
+ return action.createParam("name")
+ .setDescription("Name of the action plan")
+ .setExampleValue("Version 3.6")
+ .setRequired(true);
+ }
+
+ private static NewParam addDescriptionParam(WebService.NewAction action) {
+ return action.createParam("description")
+ .setDescription("Description of the action plan")
+ .setExampleValue("Version 3.6");
+ }
+
+ private static NewParam addDeadLineParam(WebService.NewAction action) {
+ return action.createParam("deadLine")
+ .setDescription("Due date of the action plan. Format: YYYY-MM-DD")
+ .setExampleValue("2013-12-31");
+ }
+
+ private static NewParam addProjectParam(WebService.NewAction action) {
+ return action.createParam("project")
+ .setDescription("Project key")
+ .setExampleValue("org.codehaus.sonar:sonar")
+ .setRequired(true);
+ }
+}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonar.server.issue.filter;
+
+import org.sonar.api.server.ws.Request;
+import org.sonar.api.server.ws.RequestHandler;
+import org.sonar.api.server.ws.Response;
+import org.sonar.api.server.ws.WebService;
+import org.sonar.api.utils.text.JsonWriter;
+import org.sonar.core.issue.DefaultIssueFilter;
+import org.sonar.server.user.UserSession;
+
+import java.util.List;
+
+public class AppAction implements RequestHandler {
+
+ private final IssueFilterService service;
+ private final IssueFilterWriter issueFilterWriter;
+
+ public AppAction(IssueFilterService service, IssueFilterWriter issueFilterWriter) {
+ this.service = service;
+ this.issueFilterWriter = issueFilterWriter;
+ }
+
+ void define(WebService.NewController controller) {
+ WebService.NewAction action = controller.createAction("app");
+ action
+ .setDescription("Data required for rendering the page 'Issues'")
+ .setInternal(true)
+ .setHandler(this);
+ action.createParam("id").setDescription("Optionally, the ID of the current filter");
+ }
+
+ @Override
+ public void handle(Request request, Response response) throws Exception {
+ UserSession session = UserSession.get();
+
+ JsonWriter json = response.newJsonWriter();
+ json.beginObject();
+
+ // Current filter (optional)
+ int filterId = request.paramAsInt("id", -1);
+ DefaultIssueFilter filter = null;
+ if (filterId >= 0) {
+ filter = service.find((long) filterId, session);
+ }
+
+ // Permissions
+ json.prop("canManageFilters", session.isLoggedIn());
+ json.prop("canBulkChange", session.isLoggedIn());
+
+ // Selected filter
+ if (filter != null) {
+ issueFilterWriter.write(session, filter, json);
+ }
+
+ // Favorite filters, if logged in
+ if (session.isLoggedIn()) {
+ List<DefaultIssueFilter> favorites = service.findFavoriteFilters(session);
+ json.name("favorites").beginArray();
+ for (DefaultIssueFilter favorite : favorites) {
+ json
+ .beginObject()
+ .prop("id", favorite.id())
+ .prop("name", favorite.name())
+ .endObject();
+ }
+ json.endArray();
+ }
+
+ json.endObject();
+ json.close();
+ }
+
+}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonar.server.issue.filter;
+
+import org.sonar.api.server.ws.Request;
+import org.sonar.api.server.ws.RequestHandler;
+import org.sonar.api.server.ws.Response;
+import org.sonar.api.server.ws.WebService;
+import org.sonar.api.utils.text.JsonWriter;
+import org.sonar.core.issue.DefaultIssueFilter;
+import org.sonar.server.user.UserSession;
+
+public class FavoritesAction implements RequestHandler {
+
+ private final IssueFilterService service;
+
+ public FavoritesAction(IssueFilterService service) {
+ this.service = service;
+ }
+
+ void define(WebService.NewController controller) {
+ WebService.NewAction action = controller.createAction("favorites");
+ action
+ .setDescription("The issue filters marked as favorite by request user")
+ .setSince("4.2")
+ .setHandler(this);
+ }
+
+ @Override
+ public void handle(Request request, Response response) throws Exception {
+ UserSession session = UserSession.get();
+ JsonWriter json = response.newJsonWriter();
+ json.beginObject().name("favoriteFilters").beginArray();
+ if (session.isLoggedIn()) {
+ for (DefaultIssueFilter favorite : service.findFavoriteFilters(session)) {
+ json.beginObject();
+ json.prop("id", favorite.id());
+ json.prop("name", favorite.name());
+ json.prop("user", favorite.user());
+ json.prop("shared", favorite.shared());
+ // no need to export description and query fields
+ json.endObject();
+ }
+ }
+ json.endArray().endObject().close();
+ }
+
+}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonar.server.issue.filter;
+
+import org.apache.commons.lang.StringUtils;
+import org.sonar.api.ServerComponent;
+import org.sonar.api.utils.text.JsonWriter;
+import org.sonar.core.issue.DefaultIssueFilter;
+import org.sonar.core.permission.GlobalPermissions;
+import org.sonar.server.user.UserSession;
+
+public class IssueFilterWriter implements ServerComponent {
+
+ void write(UserSession session, DefaultIssueFilter filter, JsonWriter json) {
+ json.name("filter").beginObject()
+ .prop("id", filter.id())
+ .prop("name", filter.name())
+ .prop("description", filter.description())
+ .prop("user", filter.user())
+ .prop("shared", filter.shared())
+ .prop("query", filter.data())
+ .prop("canModify", canModifyFilter(session, filter))
+ .endObject();
+ }
+
+ private boolean canModifyFilter(UserSession session, DefaultIssueFilter filter) {
+ return session.isLoggedIn() &&
+ (StringUtils.equals(filter.user(), session.login()) || session.hasGlobalPermission(GlobalPermissions.SYSTEM_ADMIN));
+ }
+
+}
*/
package org.sonar.server.issue.filter;
-import org.apache.commons.lang.StringUtils;
-import org.sonar.api.server.ws.Request;
-import org.sonar.api.server.ws.RequestHandler;
-import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService;
-import org.sonar.api.utils.text.JsonWriter;
-import org.sonar.core.issue.DefaultIssueFilter;
-import org.sonar.core.permission.GlobalPermissions;
-import org.sonar.server.user.UserSession;
-
-import java.util.List;
public class IssueFilterWs implements WebService {
- private static final String PARAM_ID = "id";
- private final IssueFilterService service;
+ private final AppAction appAction;
+ private final ShowAction showAction;
+ private final FavoritesAction favoritesAction;
- public IssueFilterWs(IssueFilterService service) {
- this.service = service;
+ public IssueFilterWs(AppAction appAction, ShowAction showAction, FavoritesAction favoritesAction) {
+ this.appAction = appAction;
+ this.showAction = showAction;
+ this.favoritesAction = favoritesAction;
}
@Override
NewController controller = context.createController("api/issue_filters")
.setSince("4.2")
.setDescription("Issue Filters");
-
- NewAction app = controller.createAction("app");
- app
- .setDescription("Data required for rendering the page 'Issues'")
- .setInternal(true)
- .setHandler(new RequestHandler() {
- @Override
- public void handle(Request request, Response response) {
- app(request, response);
- }
- });
- app.createParam(PARAM_ID).setDescription("Optionally, the ID of the current filter");
-
- NewAction show = controller.createAction("show");
- show
- .setDescription("Get detail of an issue filter. Requires to be authenticated")
- .setSince("4.2")
- .setHandler(new RequestHandler() {
- @Override
- public void handle(Request request, Response response) {
- show(request, response);
- }
- });
- show.createParam(PARAM_ID)
- .setDescription("ID of the issue filter")
- .setRequired(true);
-
- NewAction fav = controller.createAction("favorites");
- fav
- .setDescription("The issue filters marked as favorite by request user")
- .setSince("4.2")
- .setHandler(new RequestHandler() {
- @Override
- public void handle(Request request, Response response) {
- favorites(request, response);
- }
- });
-
+ appAction.define(controller);
+ showAction.define(controller);
+ favoritesAction.define(controller);
controller.done();
}
- private void app(Request request, Response response) {
- UserSession session = UserSession.get();
-
- JsonWriter json = response.newJsonWriter();
- json.beginObject();
-
- // Current filter (optional)
- int filterId = request.paramAsInt(PARAM_ID, -1);
- DefaultIssueFilter filter = null;
- if (filterId >= 0) {
- filter = service.find((long) filterId, session);
- }
-
- // Permissions
- json.prop("canManageFilters", session.isLoggedIn());
- json.prop("canBulkChange", session.isLoggedIn());
-
- // Selected filter
- if (filter != null) {
- json.name("filter");
- writeFilterJson(session, filter, json);
- }
-
- // Favorite filters, if logged in
- if (session.isLoggedIn()) {
- List<DefaultIssueFilter> favorites = service.findFavoriteFilters(session);
- json.name("favorites").beginArray();
- for (DefaultIssueFilter favorite : favorites) {
- json
- .beginObject()
- .prop(PARAM_ID, favorite.id())
- .prop("name", favorite.name())
- .endObject();
- }
- json.endArray();
- }
-
- json.endObject();
- json.close();
- }
-
- private void show(Request request, Response response) {
- UserSession session = UserSession.get();
- DefaultIssueFilter filter = service.find(Long.parseLong(request.mandatoryParam(PARAM_ID)), session);
-
- JsonWriter json = response.newJsonWriter();
- json.beginObject();
- json.name("filter");
- writeFilterJson(session, filter, json);
- json.endObject();
- json.close();
- }
-
- private void favorites(Request request, Response response) {
- UserSession session = UserSession.get();
- JsonWriter json = response.newJsonWriter();
- json.beginObject().name("favoriteFilters").beginArray();
- if (session.isLoggedIn()) {
- for (DefaultIssueFilter favorite : service.findFavoriteFilters(session)) {
- json.beginObject();
- json.prop(PARAM_ID, favorite.id());
- json.prop("name", favorite.name());
- json.prop("user", favorite.user());
- json.prop("shared", favorite.shared());
- // no need to export description and query fields
- json.endObject();
- }
- }
- json.endArray().endObject().close();
- }
-
- private JsonWriter writeFilterJson(UserSession session, DefaultIssueFilter filter, JsonWriter json) {
- return json.beginObject()
- .prop(PARAM_ID, filter.id())
- .prop("name", filter.name())
- .prop("description", filter.description())
- .prop("user", filter.user())
- .prop("shared", filter.shared())
- .prop("query", filter.data())
- .prop("canModify", canModifyFilter(session, filter))
- .endObject();
- }
-
- private boolean canModifyFilter(UserSession session, DefaultIssueFilter filter) {
- return session.isLoggedIn() &&
- (StringUtils.equals(filter.user(), session.login()) || session.hasGlobalPermission(GlobalPermissions.SYSTEM_ADMIN));
- }
}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonar.server.issue.filter;
+
+import com.google.common.io.Resources;
+import org.sonar.api.server.ws.Request;
+import org.sonar.api.server.ws.RequestHandler;
+import org.sonar.api.server.ws.Response;
+import org.sonar.api.server.ws.WebService;
+import org.sonar.api.utils.text.JsonWriter;
+import org.sonar.core.issue.DefaultIssueFilter;
+import org.sonar.server.user.UserSession;
+
+public class ShowAction implements RequestHandler {
+
+ private final IssueFilterService service;
+ private final IssueFilterWriter issueFilterWriter;
+
+ public ShowAction(IssueFilterService service, IssueFilterWriter issueFilterWriter) {
+ this.service = service;
+ this.issueFilterWriter = issueFilterWriter;
+ }
+
+ void define(WebService.NewController controller) {
+ WebService.NewAction action = controller.createAction("show");
+ action
+ .setDescription("Get detail of an issue filter. Requires to be authenticated")
+ .setSince("4.2")
+ .setHandler(this)
+ .setResponseExample(Resources.getResource(this.getClass(), "example-show.json"));
+ action.createParam("id")
+ .setDescription("ID of the issue filter")
+ .setRequired(true);
+ }
+
+ @Override
+ public void handle(Request request, Response response) throws Exception {
+ UserSession session = UserSession.get();
+ DefaultIssueFilter filter = service.find(Long.parseLong(request.mandatoryParam("id")), session);
+
+ JsonWriter json = response.newJsonWriter();
+ json.beginObject();
+ issueFilterWriter.write(session, filter, json);
+ json.endObject();
+ json.close();
+ }
+}
+++ /dev/null
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-package org.sonar.server.issue.ws;
-
-import org.sonar.api.server.ws.RailsHandler;
-import org.sonar.api.server.ws.WebService;
-
-public class ActionPlanWs implements WebService {
-
- @Override
- public void define(Context context) {
- NewController controller = context.createController("api/action_plans");
- controller.setDescription("Action plans");
-
- WebService.NewAction search = controller.createAction("search")
- .setDescription("Get a list of action plans. Requires Browse permission on project")
- .setSince("3.6")
- .setHandler(RailsHandler.INSTANCE);
- addProjectParam(search);
-
- WebService.NewAction create = controller.createAction("create")
- .setDescription("Create an action plan. Requires Administer permission on project")
- .setSince("3.6")
- .setPost(true)
- .setHandler(RailsHandler.INSTANCE);
- addNameParam(create);
- addDescriptionParam(create);
- addDeadLineParam(create);
- addProjectParam(create);
-
- WebService.NewAction update = controller.createAction("update")
- .setDescription("Update an action plan. Requires Administer permission on project")
- .setSince("3.6")
- .setPost(true)
- .setHandler(RailsHandler.INSTANCE);
- addKeyParam(update);
- addNameParam(update);
- addDescriptionParam(update);
- addDeadLineParam(update);
-
- WebService.NewAction delete = controller.createAction("delete")
- .setDescription("Delete an action plan. Requires Administer permission on project")
- .setSince("3.6")
- .setPost(true)
- .setHandler(RailsHandler.INSTANCE);
- addKeyParam(delete);
-
- WebService.NewAction open = controller.createAction("open")
- .setDescription("Open an action plan. Requires Administer permission on project")
- .setSince("3.6")
- .setPost(true)
- .setHandler(RailsHandler.INSTANCE);
- addKeyParam(open);
-
- WebService.NewAction close = controller.createAction("close")
- .setDescription("Close an action plan. Requires Administer permission on project")
- .setSince("3.6")
- .setPost(true)
- .setHandler(RailsHandler.INSTANCE);
- addKeyParam(close);
-
- controller.done();
- }
-
- private static NewParam addKeyParam(WebService.NewAction action) {
- return action.createParam("key")
- .setDescription("Key of the action plan")
- .setExampleValue("3f19de90-1521-4482-a737-a311758ff513")
- .setRequired(true);
- }
-
- private static NewParam addNameParam(WebService.NewAction action) {
- return action.createParam("name")
- .setDescription("Name of the action plan")
- .setExampleValue("Version 3.6")
- .setRequired(true);
- }
-
- private static NewParam addDescriptionParam(WebService.NewAction action) {
- return action.createParam("description")
- .setDescription("Description of the action plan")
- .setExampleValue("Version 3.6");
- }
-
- private static NewParam addDeadLineParam(WebService.NewAction action) {
- return action.createParam("deadLine")
- .setDescription("Due date of the action plan. Format: YYYY-MM-DD")
- .setExampleValue("2013-12-31");
- }
-
- private static NewParam addProjectParam(WebService.NewAction action) {
- return action.createParam("project")
- .setDescription("Project key")
- .setExampleValue("org.codehaus.sonar:sonar")
- .setRequired(true);
- }
-}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.issue.ws;
+
+import com.google.common.base.Predicate;
+import com.google.common.collect.Iterables;
+import org.sonar.api.component.Component;
+import org.sonar.api.i18n.I18n;
+import org.sonar.api.issue.*;
+import org.sonar.api.issue.action.Action;
+import org.sonar.api.issue.internal.DefaultIssue;
+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.RequestHandler;
+import org.sonar.api.server.ws.Response;
+import org.sonar.api.server.ws.WebService;
+import org.sonar.api.user.User;
+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.api.web.UserRole;
+import org.sonar.core.component.ComponentDto;
+import org.sonar.core.issue.workflow.Transition;
+import org.sonar.markdown.Markdown;
+import org.sonar.server.debt.DebtModelService;
+import org.sonar.server.exceptions.NotFoundException;
+import org.sonar.server.issue.ActionService;
+import org.sonar.server.issue.IssueChangelog;
+import org.sonar.server.issue.IssueChangelogService;
+import org.sonar.server.issue.IssueService;
+import org.sonar.server.user.UserSession;
+
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
+
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+
+import static com.google.common.collect.Lists.newArrayList;
+
+public class IssueShowAction implements RequestHandler {
+
+ private final IssueFinder issueFinder;
+ private final IssueService issueService;
+ private final IssueChangelogService issueChangelogService;
+ private final ActionService actionService;
+ private final DebtModelService debtModel;
+ private final I18n i18n;
+ private final Durations durations;
+
+ public IssueShowAction(IssueFinder issueFinder, IssueService issueService, IssueChangelogService issueChangelogService, ActionService actionService,
+ DebtModelService debtModel, I18n i18n, Durations durations) {
+ this.issueFinder = issueFinder;
+ this.issueService = issueService;
+ this.issueChangelogService = issueChangelogService;
+ this.actionService = actionService;
+ this.debtModel = debtModel;
+ this.i18n = i18n;
+ this.durations = durations;
+ }
+
+ void define (WebService.NewController controller) {
+ WebService.NewAction action = controller.createAction("show")
+ .setDescription("Detail of issue")
+ .setSince("4.2")
+ .setInternal(true)
+ .setHandler(this);
+ action.createParam("key")
+ .setDescription("Issue key");
+ }
+
+ @Override
+ public void handle(Request request, Response response) {
+ String issueKey = request.mandatoryParam("key");
+ IssueQueryResult queryResult = issueFinder.find(IssueQuery.builder().issueKeys(Arrays.asList(issueKey)).build());
+ if (queryResult.issues().size() != 1) {
+ throw new NotFoundException("Issue not found: " + issueKey);
+ }
+ DefaultIssue issue = (DefaultIssue) queryResult.first();
+
+ JsonWriter json = response.newJsonWriter();
+ json.beginObject().name("issue").beginObject();
+
+ writeIssue(queryResult, issue, json);
+ writeTransitions(issue, json);
+ writeActions(issue, json);
+ writeComments(queryResult, issue, json);
+ writeChangelog(issue, json);
+
+ json.endObject().endObject().close();
+ }
+
+ private void writeIssue(IssueQueryResult result, DefaultIssue issue, JsonWriter json) {
+ String actionPlanKey = issue.actionPlanKey();
+ ActionPlan actionPlan = result.actionPlan(issue);
+ Duration debt = issue.debt();
+ Date updateDate = issue.updateDate();
+ Date closeDate = issue.closeDate();
+
+ json
+ .prop("key", issue.key())
+ .prop("rule", issue.ruleKey().toString())
+ .prop("ruleName", result.rule(issue).getName())
+ .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.format(UserSession.get().locale(), debt, Durations.DurationFormat.SHORT) : 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(result, issue, json);
+ addUserWithLabel(result, issue.assignee(), "assignee", json);
+ addUserWithLabel(result, issue.reporter(), "reporter", json);
+ addCharacteristics(result, issue, json);
+ }
+
+ private void addComponents(IssueQueryResult result, DefaultIssue issue, JsonWriter json) {
+ // component, module and project can be null if they were removed
+ ComponentDto component = (ComponentDto) result.component(issue);
+ ComponentDto subProject = (ComponentDto) getSubProject(result, component);
+ ComponentDto project = (ComponentDto) geProject(result, component);
+
+ String projectName = project != null ? project.longName() != null ? project.longName() : project.name() : null;
+ // Do not display sub project long name if sub project and project are the same
+ boolean shoudDisplaySubProjectLongName = subProject != null && project != null && !subProject.getId().equals(project.getId());
+ String subProjectName = shoudDisplaySubProjectLongName ? subProject.longName() != null ? subProject.longName() : subProject.name() : null;
+
+ json
+ .prop("component", issue.componentKey())
+ .prop("componentLongName", component != null ? component.longName() : null)
+ .prop("componentQualifier", component != null ? component.qualifier() : null)
+ .prop("project", issue.projectKey())
+ .prop("projectName", projectName)
+ // Do not display sub project long name if sub project and project are the same
+ .prop("subProjectName", subProjectName)
+ ;
+ }
+
+ /**
+ * Can be null on project or on removed component
+ */
+ @CheckForNull
+ private Component getSubProject(IssueQueryResult result, @Nullable final ComponentDto component) {
+ if (component != null) {
+ return Iterables.find(result.components(), new Predicate<Component>() {
+ @Override
+ public boolean apply(Component input) {
+ Long groupId = component.subProjectId();
+ return groupId != null && groupId.equals(((ComponentDto) input).getId());
+ }
+ }, null);
+ }
+ return null;
+ }
+
+ /**
+ * Can be null on removed component
+ */
+ @CheckForNull
+ private Component geProject(IssueQueryResult result, @Nullable final ComponentDto component) {
+ if (component != null) {
+ return Iterables.find(result.components(), new Predicate<Component>() {
+ @Override
+ public boolean apply(Component input) {
+ return component.projectId().equals(((ComponentDto) input).getId());
+ }
+ }, null);
+ }
+ return null;
+ }
+
+ private void addCharacteristics(IssueQueryResult result, DefaultIssue issue, JsonWriter json) {
+ Integer subCharacteristicId = result.rule(issue).getCharacteristicId() != null ? result.rule(issue).getCharacteristicId() : result.rule(issue).getDefaultCharacteristicId();
+ DebtCharacteristic subCharacteristic = characteristicById(subCharacteristicId);
+ 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;
+ }
+
+ private void writeTransitions(Issue issue, JsonWriter json) {
+ json.name("transitions").beginArray();
+ if (UserSession.get().isLoggedIn()) {
+ List<Transition> transitions = issueService.listTransitions(issue, UserSession.get());
+ for (Transition transition : transitions) {
+ json.value(transition.key());
+ }
+ }
+ json.endArray();
+ }
+
+ private void writeActions(DefaultIssue issue, JsonWriter json) {
+ json.name("actions").beginArray();
+ for (String action : actions(issue)) {
+ json.value(action);
+ }
+ json.endArray();
+ }
+
+ // TODO all available actions should be returned by ActionService or another service
+ private List<String> actions(DefaultIssue issue) {
+ List<String> actions = newArrayList();
+ String login = UserSession.get().login();
+ if (login != null) {
+ actions.add("comment");
+ if (issue.resolution() == null) {
+ actions.add("assign");
+ if (!login.equals(issue.assignee())) {
+ actions.add("assign_to_me");
+ }
+ actions.add("plan");
+ String projectKey = issue.projectKey();
+ if (projectKey != null && UserSession.get().hasProjectPermission(UserRole.ISSUE_ADMIN, projectKey)) {
+ actions.add("set_severity");
+ }
+ for (Action action : actionService.listAvailableActions(issue)) {
+ actions.add(action.key());
+ }
+ }
+ }
+ return actions;
+ }
+
+ private void writeComments(IssueQueryResult queryResult, Issue issue, JsonWriter json) {
+ json.name("comments").beginArray();
+ String login = UserSession.get().login();
+ for (IssueComment comment : issue.comments()) {
+ String userLogin = comment.userLogin();
+ User user = userLogin != null ? queryResult.user(userLogin) : null;
+ 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.get().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<String> diffsFormatted = issueChangelogService.formatDiffs(diffs);
+ for (String diff : diffsFormatted) {
+ json.value(diff);
+ }
+ json.endArray();
+ json.endObject();
+ }
+ json.endArray();
+ }
+
+ private void addUserWithLabel(IssueQueryResult result, @Nullable String value, String field, JsonWriter json) {
+ if (value != null) {
+ User user = result.user(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.get().locale(), date);
+ }
+ return null;
+ }
+
+ @CheckForNull
+ private String formatAgeDate(@Nullable Date date) {
+ if (date != null) {
+ return i18n.ageFromNow(UserSession.get().locale(), date);
+ }
+ return null;
+ }
+}
+++ /dev/null
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.server.issue.ws;
-
-import com.google.common.base.Predicate;
-import com.google.common.collect.Iterables;
-import org.sonar.api.component.Component;
-import org.sonar.api.i18n.I18n;
-import org.sonar.api.issue.*;
-import org.sonar.api.issue.action.Action;
-import org.sonar.api.issue.internal.DefaultIssue;
-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.RequestHandler;
-import org.sonar.api.server.ws.Response;
-import org.sonar.api.user.User;
-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.api.web.UserRole;
-import org.sonar.core.component.ComponentDto;
-import org.sonar.core.issue.workflow.Transition;
-import org.sonar.markdown.Markdown;
-import org.sonar.server.debt.DebtModelService;
-import org.sonar.server.exceptions.NotFoundException;
-import org.sonar.server.issue.ActionService;
-import org.sonar.server.issue.IssueChangelog;
-import org.sonar.server.issue.IssueChangelogService;
-import org.sonar.server.issue.IssueService;
-import org.sonar.server.user.UserSession;
-
-import javax.annotation.CheckForNull;
-import javax.annotation.Nullable;
-
-import java.util.Arrays;
-import java.util.Date;
-import java.util.List;
-
-import static com.google.common.collect.Lists.newArrayList;
-
-public class IssueShowWsHandler implements RequestHandler {
-
- private final IssueFinder issueFinder;
- private final IssueService issueService;
- private final IssueChangelogService issueChangelogService;
- private final ActionService actionService;
- private final DebtModelService debtModel;
- private final I18n i18n;
- private final Durations durations;
-
- public IssueShowWsHandler(IssueFinder issueFinder, IssueService issueService, IssueChangelogService issueChangelogService, ActionService actionService,
- DebtModelService debtModel, I18n i18n, Durations durations) {
- this.issueFinder = issueFinder;
- this.issueService = issueService;
- this.issueChangelogService = issueChangelogService;
- this.actionService = actionService;
- this.debtModel = debtModel;
- this.i18n = i18n;
- this.durations = durations;
- }
-
- @Override
- public void handle(Request request, Response response) {
- String issueKey = request.mandatoryParam("key");
- IssueQueryResult queryResult = issueFinder.find(IssueQuery.builder().issueKeys(Arrays.asList(issueKey)).build());
- if (queryResult.issues().size() != 1) {
- throw new NotFoundException("Issue not found: " + issueKey);
- }
- DefaultIssue issue = (DefaultIssue) queryResult.first();
-
- JsonWriter json = response.newJsonWriter();
- json.beginObject().name("issue").beginObject();
-
- writeIssue(queryResult, issue, json);
- writeTransitions(issue, json);
- writeActions(issue, json);
- writeComments(queryResult, issue, json);
- writeChangelog(issue, json);
-
- json.endObject().endObject().close();
- }
-
- private void writeIssue(IssueQueryResult result, DefaultIssue issue, JsonWriter json) {
- String actionPlanKey = issue.actionPlanKey();
- ActionPlan actionPlan = result.actionPlan(issue);
- Duration debt = issue.debt();
- Date updateDate = issue.updateDate();
- Date closeDate = issue.closeDate();
-
- json
- .prop("key", issue.key())
- .prop("rule", issue.ruleKey().toString())
- .prop("ruleName", result.rule(issue).getName())
- .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.format(UserSession.get().locale(), debt, Durations.DurationFormat.SHORT) : 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(result, issue, json);
- addUserWithLabel(result, issue.assignee(), "assignee", json);
- addUserWithLabel(result, issue.reporter(), "reporter", json);
- addCharacteristics(result, issue, json);
- }
-
- private void addComponents(IssueQueryResult result, DefaultIssue issue, JsonWriter json) {
- // component, module and project can be null if they were removed
- ComponentDto component = (ComponentDto) result.component(issue);
- ComponentDto subProject = (ComponentDto) getSubProject(result, component);
- ComponentDto project = (ComponentDto) geProject(result, component);
-
- String projectName = project != null ? project.longName() != null ? project.longName() : project.name() : null;
- // Do not display sub project long name if sub project and project are the same
- boolean shoudDisplaySubProjectLongName = subProject != null && project != null && !subProject.getId().equals(project.getId());
- String subProjectName = shoudDisplaySubProjectLongName ? subProject.longName() != null ? subProject.longName() : subProject.name() : null;
-
- json
- .prop("component", issue.componentKey())
- .prop("componentLongName", component != null ? component.longName() : null)
- .prop("componentQualifier", component != null ? component.qualifier() : null)
- .prop("project", issue.projectKey())
- .prop("projectName", projectName)
- // Do not display sub project long name if sub project and project are the same
- .prop("subProjectName", subProjectName)
- ;
- }
-
- /**
- * Can be null on project or on removed component
- */
- @CheckForNull
- private Component getSubProject(IssueQueryResult result, @Nullable final ComponentDto component) {
- if (component != null) {
- return Iterables.find(result.components(), new Predicate<Component>() {
- @Override
- public boolean apply(Component input) {
- Long groupId = component.subProjectId();
- return groupId != null && groupId.equals(((ComponentDto) input).getId());
- }
- }, null);
- }
- return null;
- }
-
- /**
- * Can be null on removed component
- */
- @CheckForNull
- private Component geProject(IssueQueryResult result, @Nullable final ComponentDto component) {
- if (component != null) {
- return Iterables.find(result.components(), new Predicate<Component>() {
- @Override
- public boolean apply(Component input) {
- return component.projectId().equals(((ComponentDto) input).getId());
- }
- }, null);
- }
- return null;
- }
-
- private void addCharacteristics(IssueQueryResult result, DefaultIssue issue, JsonWriter json) {
- Integer subCharacteristicId = result.rule(issue).getCharacteristicId() != null ? result.rule(issue).getCharacteristicId() : result.rule(issue).getDefaultCharacteristicId();
- DebtCharacteristic subCharacteristic = characteristicById(subCharacteristicId);
- 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;
- }
-
- private void writeTransitions(Issue issue, JsonWriter json) {
- json.name("transitions").beginArray();
- if (UserSession.get().isLoggedIn()) {
- List<Transition> transitions = issueService.listTransitions(issue, UserSession.get());
- for (Transition transition : transitions) {
- json.value(transition.key());
- }
- }
- json.endArray();
- }
-
- private void writeActions(DefaultIssue issue, JsonWriter json) {
- json.name("actions").beginArray();
- for (String action : actions(issue)) {
- json.value(action);
- }
- json.endArray();
- }
-
- // TODO all available actions should be returned by ActionService or another service
- private List<String> actions(DefaultIssue issue) {
- List<String> actions = newArrayList();
- String login = UserSession.get().login();
- if (login != null) {
- actions.add("comment");
- if (issue.resolution() == null) {
- actions.add("assign");
- if (!login.equals(issue.assignee())) {
- actions.add("assign_to_me");
- }
- actions.add("plan");
- String projectKey = issue.projectKey();
- if (projectKey != null && UserSession.get().hasProjectPermission(UserRole.ISSUE_ADMIN, projectKey)) {
- actions.add("set_severity");
- }
- for (Action action : actionService.listAvailableActions(issue)) {
- actions.add(action.key());
- }
- }
- }
- return actions;
- }
-
- private void writeComments(IssueQueryResult queryResult, Issue issue, JsonWriter json) {
- json.name("comments").beginArray();
- String login = UserSession.get().login();
- for (IssueComment comment : issue.comments()) {
- String userLogin = comment.userLogin();
- User user = userLogin != null ? queryResult.user(userLogin) : null;
- 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.get().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<String> diffsFormatted = issueChangelogService.formatDiffs(diffs);
- for (String diff : diffsFormatted) {
- json.value(diff);
- }
- json.endArray();
- json.endObject();
- }
- json.endArray();
- }
-
- private void addUserWithLabel(IssueQueryResult result, @Nullable String value, String field, JsonWriter json) {
- if (value != null) {
- User user = result.user(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.get().locale(), date);
- }
- return null;
- }
-
- @CheckForNull
- private String formatAgeDate(@Nullable Date date) {
- if (date != null) {
- return i18n.ageFromNow(UserSession.get().locale(), date);
- }
- return null;
- }
-}
*/
package org.sonar.server.issue.ws;
+import org.sonar.api.rule.Severity;
+import org.sonar.api.server.ws.RailsHandler;
import org.sonar.api.server.ws.WebService;
public class IssuesWs implements WebService {
- private final IssueShowWsHandler showHandler;
+ private final IssueShowAction showHandler;
- public IssuesWs(IssueShowWsHandler showHandler) {
+ public IssuesWs(IssueShowAction showHandler) {
this.showHandler = showHandler;
}
public void define(Context context) {
NewController controller = context.createController("api/issues");
controller.setDescription("Coding rule issues");
+ controller.setSince("3.6");
+ showHandler.define(controller);
- controller.createAction("show")
- .setDescription("Detail of issue")
- .setSince("4.2")
- .setInternal(true)
- .setHandler(showHandler)
- .createParam("key", "Issue key");
+ WebService.NewAction search = controller.createAction("search")
+ .setDescription("Get a list of issues. If the number of issues is greater than 10,000, only the first 10,000 ones are returned by the web service. Requires Browse permission on project(s).")
+ .setSince("3.6")
+ .setHandler(RailsHandler.INSTANCE);
+ search.createParam("issues")
+ .setDescription("Comma-separated list of issue keys.")
+ .setExampleValue("5bccd6e8-f525-43a2-8d76-fcb13dde79ef");
+ search.createParam("severities")
+ .setDescription("Comma-separated list of severities.")
+ .setExampleValue("BLOCKER,CRITICAL")
+ .setPossibleValues(Severity.ALL.toArray(new String[Severity.ALL.size()]));
controller.done();
}
*/
package org.sonar.server.platform;
-import org.sonar.server.cluster.LocalNonBlockingWorkQueue;
-
-import org.sonar.server.rule2.RuleDao;
-import org.sonar.server.rule2.RuleService;
import com.google.common.collect.Lists;
import org.apache.commons.configuration.BaseConfiguration;
import org.sonar.api.config.EmailSettings;
import org.sonar.jpa.session.ThreadLocalDatabaseSessionFactory;
import org.sonar.server.authentication.ws.AuthenticationWs;
import org.sonar.server.charts.ChartFactory;
+import org.sonar.server.cluster.LocalNonBlockingWorkQueue;
import org.sonar.server.component.DefaultComponentFinder;
import org.sonar.server.component.DefaultRubyComponentService;
import org.sonar.server.db.EmbeddedDatabaseFactory;
import org.sonar.server.es.ESIndex;
import org.sonar.server.es.ESNode;
import org.sonar.server.issue.*;
+import org.sonar.server.issue.actionplan.ActionPlanService;
+import org.sonar.server.issue.actionplan.ActionPlanWs;
import org.sonar.server.issue.filter.IssueFilterService;
+import org.sonar.server.issue.filter.IssueFilterWriter;
import org.sonar.server.issue.filter.IssueFilterWs;
-import org.sonar.server.issue.ws.ActionPlanWs;
-import org.sonar.server.issue.ws.IssueShowWsHandler;
+import org.sonar.server.issue.ws.IssueShowAction;
import org.sonar.server.issue.ws.IssuesWs;
import org.sonar.server.notifications.NotificationCenter;
import org.sonar.server.notifications.NotificationService;
import org.sonar.server.qualityprofile.ws.QProfilesWs;
import org.sonar.server.rule.*;
import org.sonar.server.rule.ws.*;
+import org.sonar.server.rule2.RuleService;
import org.sonar.server.search.IndexUtils;
import org.sonar.server.source.CodeColorizers;
import org.sonar.server.source.DeprecatedSourceDecorator;
pico.addSingleton(IssueStatsFinder.class);
pico.addSingleton(PublicRubyIssueService.class);
pico.addSingleton(InternalRubyIssueService.class);
- pico.addSingleton(ActionPlanService.class);
pico.addSingleton(IssueChangelogService.class);
pico.addSingleton(IssueNotifications.class);
pico.addSingleton(ActionService.class);
pico.addSingleton(Actions.class);
- pico.addSingleton(IssueFilterSerializer.class);
- pico.addSingleton(IssueFilterService.class);
pico.addSingleton(IssueBulkChangeService.class);
pico.addSingleton(IssueChangelogFormatter.class);
- pico.addSingleton(IssueFilterWs.class);
- pico.addSingleton(IssueShowWsHandler.class);
+ pico.addSingleton(IssueShowAction.class);
pico.addSingleton(IssuesWs.class);
+
+ // issue filters
+ pico.addSingleton(IssueFilterService.class);
+ pico.addSingleton(IssueFilterSerializer.class);
+ pico.addSingleton(IssueFilterWs.class);
+ pico.addSingleton(IssueFilterWriter.class);
+ pico.addSingleton(org.sonar.server.issue.filter.AppAction.class);
+ pico.addSingleton(org.sonar.server.issue.filter.ShowAction.class);
+ pico.addSingleton(org.sonar.server.issue.filter.FavoritesAction.class);
+
+ // action plan
pico.addSingleton(ActionPlanWs.class);
+ pico.addSingleton(ActionPlanService.class);
// issues actions
pico.addSingleton(AssignAction.class);
--- /dev/null
+{"validate": true}
--- /dev/null
+{
+ "actionPlans": [
+ {
+ "key": "3f19de90-1521-4482-a737-a311758ff513",
+ "name": "Version 3.6",
+ "status": "OPEN",
+ "project": "java-sonar-runner-simple",
+ "userLogin": "admin",
+ "deadLine": "2013-12-31T00:00:00+0100",
+ "totalIssues": 1,
+ "unresolvedIssues": 0,
+ "createdAt": "2013-05-31T22:40:50+0200",
+ "updatedAt": "2013-05-31T22:40:50+0200"
+ },
+ {
+ "key": "8ab022c0-f0dc-41b7-a762-82502bda749f",
+ "name": "Version 3.5",
+ "status": "CLOSED",
+ "project": "java-sonar-runner-simple4",
+ "userLogin": "admin",
+ "totalIssues": 0,
+ "unresolvedIssues": 0,
+ "createdAt": "2013-05-31T22:40:30+0200",
+ "updatedAt": "2013-05-31T22:42:13+0200"
+ }
+ ]
+}
--- /dev/null
+{
+ "filter": {
+ "id": 1,
+ "name": "My Filter",
+ "user": "admin",
+ "shared": true,
+ "query": "statuses=OPEN,REOPENED|sort=UPDATE_DATE|asc=false",
+ "canModify": true
+ }
+}
require_parameters :issue
plan = nil
- plan = params[:plan] if params[:plan] && !params[:plan].blank?
+ plan = params[:actionplan] if params[:actionplan] && !params[:actionplan].blank?
result = Internal.issues.plan(params[:issue], plan)
render_result_issue(result)
end
elsif action_type=='severity'
issue_result = Internal.issues.setSeverity(issue_key, params[:severity])
elsif action_type=='plan'
- issue_result = Internal.issues.plan(issue_key, params[:plan])
+ issue_result = Internal.issues.plan(issue_key, params[:actionplan])
elsif action_type=='unplan'
issue_result = Internal.issues.plan(issue_key, nil)
else
WebService.Action validate = controller.action("validate");
assertThat(validate).isNotNull();
assertThat(validate.handler()).isInstanceOf(RailsHandler.class);
- assertThat(validate.since()).isEqualTo("3.3");
- assertThat(validate.isPost()).isFalse();
- assertThat(validate.isInternal()).isFalse();
+ assertThat(validate.responseExampleAsString()).isNotEmpty();
assertThat(validate.params()).isEmpty();
}
}
+++ /dev/null
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-package org.sonar.server.issue;
-
-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.api.issue.ActionPlan;
-import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.IssueQuery;
-import org.sonar.api.issue.internal.DefaultIssue;
-import org.sonar.api.issue.internal.IssueChangeContext;
-import org.sonar.api.web.UserRole;
-import org.sonar.core.issue.ActionPlanStats;
-import org.sonar.core.issue.DefaultActionPlan;
-import org.sonar.core.issue.IssueUpdater;
-import org.sonar.core.issue.db.*;
-import org.sonar.core.resource.ResourceDao;
-import org.sonar.core.resource.ResourceDto;
-import org.sonar.core.resource.ResourceQuery;
-import org.sonar.server.exceptions.ForbiddenException;
-import org.sonar.server.exceptions.NotFoundException;
-import org.sonar.server.user.MockUserSession;
-import org.sonar.server.user.UserSession;
-
-import java.util.Collection;
-
-import static com.google.common.collect.Lists.newArrayList;
-import static org.fest.assertions.Assertions.assertThat;
-import static org.fest.assertions.Fail.fail;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.*;
-
-@RunWith(MockitoJUnitRunner.class)
-public class ActionPlanServiceTest {
-
- @Mock
- ActionPlanDao actionPlanDao;
-
- @Mock
- ActionPlanStatsDao actionPlanStatsDao;
-
- @Mock
- ResourceDao resourceDao;
-
- @Mock
- IssueDao issueDao;
-
- @Mock
- IssueUpdater issueUpdater;
-
- @Mock
- IssueStorage issueStorage;
-
- String projectKey = "org.sonar.Sample";
-
- UserSession projectAdministratorUserSession = MockUserSession.create().setLogin("nicolas").setName("Nicolas").addProjectPermissions(UserRole.ADMIN, projectKey);
- UserSession projectUserSession = MockUserSession.create().setLogin("nicolas").setName("Nicolas").addProjectPermissions(UserRole.USER, projectKey);
- UserSession unauthorizedUserSession = MockUserSession.create().setLogin("nicolas").setName("Nicolas");
-
- private ActionPlanService actionPlanService;
-
- @Before
- public void before() {
- actionPlanService = new ActionPlanService(actionPlanDao, actionPlanStatsDao, resourceDao, issueDao, issueUpdater, issueStorage);
- }
-
- @Test
- public void create() {
- when(resourceDao.getResource(any(ResourceQuery.class))).thenReturn(new ResourceDto().setKey(projectKey).setId(1l));
- ActionPlan actionPlan = DefaultActionPlan.create("Long term");
-
- actionPlanService.create(actionPlan, projectAdministratorUserSession);
- verify(actionPlanDao).save(any(ActionPlanDto.class));
- }
-
- @Test
- public void create_required_admin_role() {
- when(resourceDao.getResource(any(ResourceQuery.class))).thenReturn(new ResourceDto().setKey(projectKey).setId(1l));
- ActionPlan actionPlan = DefaultActionPlan.create("Long term");
-
- try {
- actionPlanService.create(actionPlan, unauthorizedUserSession);
- fail();
- } catch (Exception e) {
- assertThat(e).isInstanceOf(ForbiddenException.class);
- }
- verifyZeroInteractions(actionPlanDao);
- }
-
- @Test
- public void set_status() {
- when(actionPlanDao.findByKey("ABCD")).thenReturn(new ActionPlanDto().setKey("ABCD").setProjectKey_unit_test_only(projectKey));
- when(resourceDao.getResource(any(ResourceQuery.class))).thenReturn(new ResourceDto().setKey(projectKey).setId(1l));
-
- ActionPlan result = actionPlanService.setStatus("ABCD", "CLOSED", projectAdministratorUserSession);
- verify(actionPlanDao).update(any(ActionPlanDto.class));
-
- assertThat(result).isNotNull();
- assertThat(result.status()).isEqualTo("CLOSED");
- }
-
- @Test
- public void update() {
- when(resourceDao.getResource(any(ResourceQuery.class))).thenReturn(new ResourceDto().setKey(projectKey).setId(1l));
- ActionPlan actionPlan = DefaultActionPlan.create("Long term");
-
- actionPlanService.update(actionPlan, projectAdministratorUserSession);
- verify(actionPlanDao).update(any(ActionPlanDto.class));
- }
-
- @Test
- public void delete() {
- when(actionPlanDao.findByKey("ABCD")).thenReturn(new ActionPlanDto().setKey("ABCD").setProjectKey_unit_test_only(projectKey));
- when(resourceDao.getResource(any(ResourceQuery.class))).thenReturn(new ResourceDto().setKey(projectKey).setId(1l));
- actionPlanService.delete("ABCD", projectAdministratorUserSession);
- verify(actionPlanDao).delete("ABCD");
- }
-
- @Test
- public void unplan_all_linked_issues_when_deleting_an_action_plan() {
- when(actionPlanDao.findByKey("ABCD")).thenReturn(new ActionPlanDto().setKey("ABCD").setProjectKey_unit_test_only(projectKey));
- when(resourceDao.getResource(any(ResourceQuery.class))).thenReturn(new ResourceDto().setKey(projectKey).setId(1l));
-
- IssueDto issueDto = new IssueDto().setId(100L).setStatus(Issue.STATUS_OPEN).setRuleKey_unit_test_only("squid", "s100");
- when(issueDao.selectIssues(any(IssueQuery.class))).thenReturn(newArrayList(issueDto));
- when(issueUpdater.plan(any(DefaultIssue.class), eq((ActionPlan) null), any(IssueChangeContext.class))).thenReturn(true);
-
- ArgumentCaptor<DefaultIssue> captor = ArgumentCaptor.forClass(DefaultIssue.class);
- actionPlanService.delete("ABCD", projectAdministratorUserSession);
- verify(actionPlanDao).delete("ABCD");
- verify(issueUpdater).plan(captor.capture(), eq((ActionPlan) null), any(IssueChangeContext.class));
- verify(issueStorage).save(newArrayList(captor.getAllValues()));
- }
-
- @Test
- public void find_by_key() {
- when(actionPlanDao.findByKey("ABCD")).thenReturn(new ActionPlanDto().setKey("ABCD").setProjectKey_unit_test_only(projectKey));
- when(resourceDao.getResource(any(ResourceQuery.class))).thenReturn(new ResourceDto().setKey(projectKey).setId(1l));
-
- ActionPlan result = actionPlanService.findByKey("ABCD", projectUserSession);
- assertThat(result).isNotNull();
- assertThat(result.key()).isEqualTo("ABCD");
- }
-
- @Test
- public void return_null_if_no_action_plan_when_find_by_key() {
- when(actionPlanDao.findByKey("ABCD")).thenReturn(null);
- assertThat(actionPlanService.findByKey("ABCD", projectUserSession)).isNull();
- }
-
- @Test
- public void find_by_keys() {
- when(actionPlanDao.findByKeys(newArrayList("ABCD"))).thenReturn(newArrayList(new ActionPlanDto().setKey("ABCD")));
- Collection<ActionPlan> results = actionPlanService.findByKeys(newArrayList("ABCD"));
- assertThat(results).hasSize(1);
- assertThat(results.iterator().next().key()).isEqualTo("ABCD");
- }
-
- @Test
- public void find_open_by_project_key() {
- when(resourceDao.getResource(any(ResourceQuery.class))).thenReturn(new ResourceDto().setKey(projectKey).setId(1l));
- when(actionPlanDao.findOpenByProjectId(1l)).thenReturn(newArrayList(new ActionPlanDto().setKey("ABCD")));
- Collection<ActionPlan> results = actionPlanService.findOpenByProjectKey(projectKey, projectUserSession);
- assertThat(results).hasSize(1);
- assertThat(results.iterator().next().key()).isEqualTo("ABCD");
- }
-
- @Test
- public void find_open_by_project_key_required_user_role() {
- when(resourceDao.getResource(any(ResourceQuery.class))).thenReturn(new ResourceDto().setKey(projectKey).setId(1l));
- when(actionPlanDao.findOpenByProjectId(1l)).thenReturn(newArrayList(new ActionPlanDto().setKey("ABCD")));
-
- try {
- actionPlanService.findOpenByProjectKey(projectKey, unauthorizedUserSession);
- fail();
- } catch (Exception e) {
- assertThat(e).isInstanceOf(ForbiddenException.class);
- }
- verifyZeroInteractions(actionPlanDao);
- }
-
- @Test(expected = NotFoundException.class)
- public void throw_exception_if_project_not_found_when_find_open_by_project_key() {
- when(resourceDao.getResource(any(ResourceQuery.class))).thenReturn(null);
- actionPlanService.findOpenByProjectKey("<Unkown>", projectUserSession);
- }
-
- @Test
- public void find_action_plan_stats() {
- when(resourceDao.getResource(any(ResourceQuery.class))).thenReturn(new ResourceDto().setId(1L).setKey(projectKey));
- when(actionPlanStatsDao.findByProjectId(1L)).thenReturn(newArrayList(new ActionPlanStatsDto()));
-
- Collection<ActionPlanStats> results = actionPlanService.findActionPlanStats(projectKey, projectUserSession);
- assertThat(results).hasSize(1);
- }
-
- @Test(expected = NotFoundException.class)
- public void throw_exception_if_project_not_found_when_find_open_action_plan_stats() {
- when(resourceDao.getResource(any(ResourceQuery.class))).thenReturn(null);
-
- actionPlanService.findActionPlanStats(projectKey, projectUserSession);
- }
-
-}
import org.sonar.core.resource.ResourceDao;
import org.sonar.core.rule.DefaultRuleFinder;
import org.sonar.core.user.DefaultUser;
+import org.sonar.server.issue.actionplan.ActionPlanService;
import java.util.Collections;
import java.util.List;
import org.sonar.core.resource.ResourceDto;
import org.sonar.core.resource.ResourceQuery;
import org.sonar.server.exceptions.BadRequestException;
+import org.sonar.server.issue.actionplan.ActionPlanService;
import org.sonar.server.issue.filter.IssueFilterService;
import org.sonar.server.user.UserSession;
import org.sonar.core.resource.ResourceQuery;
import org.sonar.core.user.AuthorizationDao;
import org.sonar.core.user.DefaultUser;
+import org.sonar.server.issue.actionplan.ActionPlanService;
import org.sonar.server.user.UserSession;
import java.util.Collections;
import org.sonar.api.issue.internal.IssueChangeContext;
import org.sonar.core.issue.DefaultActionPlan;
import org.sonar.core.issue.IssueUpdater;
+import org.sonar.server.issue.actionplan.ActionPlanService;
import org.sonar.server.user.UserSession;
import java.util.List;
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonar.server.issue.actionplan;
+
+import org.fest.assertions.Fail;
+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.api.issue.ActionPlan;
+import org.sonar.api.issue.Issue;
+import org.sonar.api.issue.IssueQuery;
+import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.api.issue.internal.IssueChangeContext;
+import org.sonar.api.web.UserRole;
+import org.sonar.core.issue.ActionPlanStats;
+import org.sonar.core.issue.DefaultActionPlan;
+import org.sonar.core.issue.IssueUpdater;
+import org.sonar.core.issue.db.*;
+import org.sonar.core.resource.ResourceDao;
+import org.sonar.core.resource.ResourceDto;
+import org.sonar.core.resource.ResourceQuery;
+import org.sonar.server.exceptions.ForbiddenException;
+import org.sonar.server.exceptions.NotFoundException;
+import org.sonar.server.user.MockUserSession;
+import org.sonar.server.user.UserSession;
+
+import java.util.Collection;
+
+import static com.google.common.collect.Lists.newArrayList;
+import static org.fest.assertions.Assertions.assertThat;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.*;
+
+@RunWith(MockitoJUnitRunner.class)
+public class ActionPlanServiceTest {
+
+ @Mock
+ ActionPlanDao actionPlanDao;
+
+ @Mock
+ ActionPlanStatsDao actionPlanStatsDao;
+
+ @Mock
+ ResourceDao resourceDao;
+
+ @Mock
+ IssueDao issueDao;
+
+ @Mock
+ IssueUpdater issueUpdater;
+
+ @Mock
+ IssueStorage issueStorage;
+
+ String projectKey = "org.sonar.Sample";
+
+ UserSession projectAdministratorUserSession = MockUserSession.create().setLogin("nicolas").setName("Nicolas").addProjectPermissions(UserRole.ADMIN, projectKey);
+ UserSession projectUserSession = MockUserSession.create().setLogin("nicolas").setName("Nicolas").addProjectPermissions(UserRole.USER, projectKey);
+ UserSession unauthorizedUserSession = MockUserSession.create().setLogin("nicolas").setName("Nicolas");
+
+ private ActionPlanService actionPlanService;
+
+ @Before
+ public void before() {
+ actionPlanService = new ActionPlanService(actionPlanDao, actionPlanStatsDao, resourceDao, issueDao, issueUpdater, issueStorage);
+ }
+
+ @Test
+ public void create() {
+ when(resourceDao.getResource(any(ResourceQuery.class))).thenReturn(new ResourceDto().setKey(projectKey).setId(1l));
+ ActionPlan actionPlan = DefaultActionPlan.create("Long term");
+
+ actionPlanService.create(actionPlan, projectAdministratorUserSession);
+ verify(actionPlanDao).save(any(ActionPlanDto.class));
+ }
+
+ @Test
+ public void create_required_admin_role() {
+ when(resourceDao.getResource(any(ResourceQuery.class))).thenReturn(new ResourceDto().setKey(projectKey).setId(1l));
+ ActionPlan actionPlan = DefaultActionPlan.create("Long term");
+
+ try {
+ actionPlanService.create(actionPlan, unauthorizedUserSession);
+ Fail.fail();
+ } catch (Exception e) {
+ assertThat(e).isInstanceOf(ForbiddenException.class);
+ }
+ verifyZeroInteractions(actionPlanDao);
+ }
+
+ @Test
+ public void set_status() {
+ when(actionPlanDao.findByKey("ABCD")).thenReturn(new ActionPlanDto().setKey("ABCD").setProjectKey_unit_test_only(projectKey));
+ when(resourceDao.getResource(any(ResourceQuery.class))).thenReturn(new ResourceDto().setKey(projectKey).setId(1l));
+
+ ActionPlan result = actionPlanService.setStatus("ABCD", "CLOSED", projectAdministratorUserSession);
+ verify(actionPlanDao).update(any(ActionPlanDto.class));
+
+ assertThat(result).isNotNull();
+ assertThat(result.status()).isEqualTo("CLOSED");
+ }
+
+ @Test
+ public void update() {
+ when(resourceDao.getResource(any(ResourceQuery.class))).thenReturn(new ResourceDto().setKey(projectKey).setId(1l));
+ ActionPlan actionPlan = DefaultActionPlan.create("Long term");
+
+ actionPlanService.update(actionPlan, projectAdministratorUserSession);
+ verify(actionPlanDao).update(any(ActionPlanDto.class));
+ }
+
+ @Test
+ public void delete() {
+ when(actionPlanDao.findByKey("ABCD")).thenReturn(new ActionPlanDto().setKey("ABCD").setProjectKey_unit_test_only(projectKey));
+ when(resourceDao.getResource(any(ResourceQuery.class))).thenReturn(new ResourceDto().setKey(projectKey).setId(1l));
+ actionPlanService.delete("ABCD", projectAdministratorUserSession);
+ verify(actionPlanDao).delete("ABCD");
+ }
+
+ @Test
+ public void unplan_all_linked_issues_when_deleting_an_action_plan() {
+ when(actionPlanDao.findByKey("ABCD")).thenReturn(new ActionPlanDto().setKey("ABCD").setProjectKey_unit_test_only(projectKey));
+ when(resourceDao.getResource(any(ResourceQuery.class))).thenReturn(new ResourceDto().setKey(projectKey).setId(1l));
+
+ IssueDto issueDto = new IssueDto().setId(100L).setStatus(Issue.STATUS_OPEN).setRuleKey_unit_test_only("squid", "s100");
+ when(issueDao.selectIssues(any(IssueQuery.class))).thenReturn(newArrayList(issueDto));
+ when(issueUpdater.plan(any(DefaultIssue.class), eq((ActionPlan) null), any(IssueChangeContext.class))).thenReturn(true);
+
+ ArgumentCaptor<DefaultIssue> captor = ArgumentCaptor.forClass(DefaultIssue.class);
+ actionPlanService.delete("ABCD", projectAdministratorUserSession);
+ verify(actionPlanDao).delete("ABCD");
+ verify(issueUpdater).plan(captor.capture(), eq((ActionPlan) null), any(IssueChangeContext.class));
+ verify(issueStorage).save(newArrayList(captor.getAllValues()));
+ }
+
+ @Test
+ public void find_by_key() {
+ when(actionPlanDao.findByKey("ABCD")).thenReturn(new ActionPlanDto().setKey("ABCD").setProjectKey_unit_test_only(projectKey));
+ when(resourceDao.getResource(any(ResourceQuery.class))).thenReturn(new ResourceDto().setKey(projectKey).setId(1l));
+
+ ActionPlan result = actionPlanService.findByKey("ABCD", projectUserSession);
+ assertThat(result).isNotNull();
+ assertThat(result.key()).isEqualTo("ABCD");
+ }
+
+ @Test
+ public void return_null_if_no_action_plan_when_find_by_key() {
+ when(actionPlanDao.findByKey("ABCD")).thenReturn(null);
+ assertThat(actionPlanService.findByKey("ABCD", projectUserSession)).isNull();
+ }
+
+ @Test
+ public void find_by_keys() {
+ when(actionPlanDao.findByKeys(newArrayList("ABCD"))).thenReturn(newArrayList(new ActionPlanDto().setKey("ABCD")));
+ Collection<ActionPlan> results = actionPlanService.findByKeys(newArrayList("ABCD"));
+ assertThat(results).hasSize(1);
+ assertThat(results.iterator().next().key()).isEqualTo("ABCD");
+ }
+
+ @Test
+ public void find_open_by_project_key() {
+ when(resourceDao.getResource(any(ResourceQuery.class))).thenReturn(new ResourceDto().setKey(projectKey).setId(1l));
+ when(actionPlanDao.findOpenByProjectId(1l)).thenReturn(newArrayList(new ActionPlanDto().setKey("ABCD")));
+ Collection<ActionPlan> results = actionPlanService.findOpenByProjectKey(projectKey, projectUserSession);
+ assertThat(results).hasSize(1);
+ assertThat(results.iterator().next().key()).isEqualTo("ABCD");
+ }
+
+ @Test
+ public void find_open_by_project_key_required_user_role() {
+ when(resourceDao.getResource(any(ResourceQuery.class))).thenReturn(new ResourceDto().setKey(projectKey).setId(1l));
+ when(actionPlanDao.findOpenByProjectId(1l)).thenReturn(newArrayList(new ActionPlanDto().setKey("ABCD")));
+
+ try {
+ actionPlanService.findOpenByProjectKey(projectKey, unauthorizedUserSession);
+ Fail.fail();
+ } catch (Exception e) {
+ assertThat(e).isInstanceOf(ForbiddenException.class);
+ }
+ verifyZeroInteractions(actionPlanDao);
+ }
+
+ @Test(expected = NotFoundException.class)
+ public void throw_exception_if_project_not_found_when_find_open_by_project_key() {
+ when(resourceDao.getResource(any(ResourceQuery.class))).thenReturn(null);
+ actionPlanService.findOpenByProjectKey("<Unkown>", projectUserSession);
+ }
+
+ @Test
+ public void find_action_plan_stats() {
+ when(resourceDao.getResource(any(ResourceQuery.class))).thenReturn(new ResourceDto().setId(1L).setKey(projectKey));
+ when(actionPlanStatsDao.findByProjectId(1L)).thenReturn(newArrayList(new ActionPlanStatsDto()));
+
+ Collection<ActionPlanStats> results = actionPlanService.findActionPlanStats(projectKey, projectUserSession);
+ assertThat(results).hasSize(1);
+ }
+
+ @Test(expected = NotFoundException.class)
+ public void throw_exception_if_project_not_found_when_find_open_action_plan_stats() {
+ when(resourceDao.getResource(any(ResourceQuery.class))).thenReturn(null);
+
+ actionPlanService.findActionPlanStats(projectKey, projectUserSession);
+ }
+
+}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonar.server.issue.actionplan;
+
+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.fest.assertions.Assertions.assertThat;
+
+public class ActionPlanWsTest {
+
+ WsTester tester = new WsTester(new ActionPlanWs());
+
+ @Test
+ public void define_controller() throws Exception {
+ WebService.Controller controller = tester.controller("api/action_plans");
+ assertThat(controller).isNotNull();
+ assertThat(controller.description()).isNotEmpty();
+ assertThat(controller.actions()).hasSize(6);
+ }
+
+ @Test
+ public void define_search_action() throws Exception {
+ WebService.Controller controller = tester.controller("api/action_plans");
+
+ WebService.Action action = controller.action("search");
+ assertThat(action).isNotNull();
+ assertThat(action.handler()).isInstanceOf(RailsHandler.class);
+ assertThat(action.responseExampleAsString()).isNotEmpty();
+ assertThat(action.params()).hasSize(1);
+ }
+
+ @Test
+ public void define_create_action() throws Exception {
+ WebService.Controller controller = tester.controller("api/action_plans");
+
+ WebService.Action action = controller.action("create");
+ assertThat(action).isNotNull();
+ assertThat(action.handler()).isInstanceOf(RailsHandler.class);
+ assertThat(action.params()).hasSize(4);
+ }
+
+ @Test
+ public void define_delete_action() throws Exception {
+ WebService.Controller controller = tester.controller("api/action_plans");
+
+ WebService.Action action = controller.action("delete");
+ assertThat(action).isNotNull();
+ assertThat(action.handler()).isInstanceOf(RailsHandler.class);
+ assertThat(action.params()).hasSize(1);
+ }
+
+ @Test
+ public void define_update_action() throws Exception {
+ WebService.Controller controller = tester.controller("api/action_plans");
+
+ WebService.Action action = controller.action("update");
+ assertThat(action).isNotNull();
+ assertThat(action.handler()).isInstanceOf(RailsHandler.class);
+ assertThat(action.params()).hasSize(4);
+ }
+
+ @Test
+ public void define_open_action() throws Exception {
+ WebService.Controller controller = tester.controller("api/action_plans");
+
+ WebService.Action action = controller.action("open");
+ assertThat(action).isNotNull();
+ assertThat(action.handler()).isInstanceOf(RailsHandler.class);
+ assertThat(action.params()).hasSize(1);
+ }
+
+ @Test
+ public void define_close_action() throws Exception {
+ WebService.Controller controller = tester.controller("api/action_plans");
+
+ WebService.Action action = controller.action("close");
+ assertThat(action).isNotNull();
+ assertThat(action.handler()).isInstanceOf(RailsHandler.class);
+ assertThat(action.params()).hasSize(1);
+ }
+}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonar.server.issue.filter;
+
+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.core.issue.DefaultIssueFilter;
+import org.sonar.server.user.MockUserSession;
+import org.sonar.server.ws.WsTester;
+
+import java.util.Arrays;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+@RunWith(MockitoJUnitRunner.class)
+public class AppActionTest {
+
+ @Mock
+ IssueFilterService service;
+
+ IssueFilterWriter writer = new IssueFilterWriter();
+
+ AppAction action;
+
+ WsTester tester;
+
+ @Before
+ public void setUp() throws Exception {
+ action = new AppAction(service, writer);
+ tester = new WsTester(new IssueFilterWs(action, mock(ShowAction.class), mock(FavoritesAction.class)));
+ }
+
+ @Test
+ public void anonymous_app() throws Exception {
+ MockUserSession.set().setLogin(null);
+ tester.newRequest("app").execute().assertJson(getClass(), "anonymous_page.json");
+ }
+
+ @Test
+ public void logged_in_app() throws Exception {
+ MockUserSession.set().setLogin("eric").setUserId(123);
+ tester.newRequest("app").execute()
+ .assertJson(getClass(), "logged_in_page.json");
+ }
+
+ @Test
+ public void logged_in_app_with_favorites() throws Exception {
+ MockUserSession session = MockUserSession.set().setLogin("eric").setUserId(123);
+ when(service.findFavoriteFilters(session)).thenReturn(Arrays.asList(
+ new DefaultIssueFilter().setId(6L).setName("My issues"),
+ new DefaultIssueFilter().setId(13L).setName("Blocker issues")
+ ));
+ tester.newRequest("app").execute()
+ .assertJson(getClass(), "logged_in_page_with_favorites.json");
+ }
+
+ @Test
+ public void logged_in_app_with_selected_filter() throws Exception {
+ MockUserSession session = MockUserSession.set().setLogin("eric").setUserId(123);
+ when(service.find(13L, session)).thenReturn(
+ new DefaultIssueFilter().setId(13L).setName("Blocker issues").setData("severity=BLOCKER").setUser("eric")
+ );
+
+ tester.newRequest("app").setParam("id", "13").execute()
+ .assertJson(getClass(), "logged_in_page_with_selected_filter.json");
+ }
+
+ @Test
+ public void app_selected_filter_can_not_be_modified() throws Exception {
+ // logged-in user is 'eric' but filter is owned by 'simon'
+ MockUserSession session = MockUserSession.set().setLogin("eric").setUserId(123).setGlobalPermissions("none");
+ when(service.find(13L, session)).thenReturn(
+ new DefaultIssueFilter().setId(13L).setName("Blocker issues").setData("severity=BLOCKER").setUser("simon").setShared(true)
+ );
+
+ tester.newRequest("app").setParam("id", "13").execute()
+ .assertJson(getClass(), "selected_filter_can_not_be_modified.json");
+ }
+
+}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonar.server.issue.filter;
+
+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.core.issue.DefaultIssueFilter;
+import org.sonar.server.user.MockUserSession;
+import org.sonar.server.ws.WsTester;
+
+import java.util.Arrays;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+@RunWith(MockitoJUnitRunner.class)
+public class FavoritesActionTest {
+
+ @Mock
+ IssueFilterService service;
+
+ @Mock
+ IssueFilterWriter writer;
+
+ FavoritesAction action;
+
+ WsTester tester;
+
+ @Before
+ public void setUp() throws Exception {
+ action = new FavoritesAction(service);
+ tester = new WsTester(new IssueFilterWs(mock(AppAction.class), mock(ShowAction.class), action));
+ }
+
+ @Test
+ public void favorites_of_anonymous() throws Exception {
+ MockUserSession.set();
+
+ tester.newRequest("favorites").execute()
+ .assertJson("{'favoriteFilters': []}");
+ }
+
+ @Test
+ public void favorites_of_logged_in_user() throws Exception {
+ MockUserSession session = MockUserSession.set().setLogin("eric").setUserId(123);
+ when(service.findFavoriteFilters(session)).thenReturn(Arrays.asList(
+ new DefaultIssueFilter().setId(13L).setName("Blocker issues").setData("severity=BLOCKER").setUser("simon").setShared(true)
+ ));
+
+ tester.newRequest("favorites").execute()
+ .assertJson("{'favoriteFilters': [{'id': 13, 'name': 'Blocker issues', 'user': 'simon', 'shared': true}]}");
+ }
+
+}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonar.server.issue.filter;
+
+import org.json.JSONException;
+import org.junit.Test;
+import org.skyscreamer.jsonassert.JSONAssert;
+import org.sonar.api.utils.text.JsonWriter;
+import org.sonar.core.issue.DefaultIssueFilter;
+import org.sonar.core.permission.GlobalPermissions;
+import org.sonar.server.user.MockUserSession;
+import org.sonar.server.user.UserSession;
+
+import java.io.StringWriter;
+
+public class IssueFilterWriterTest {
+
+ IssueFilterWriter writer = new IssueFilterWriter();
+
+ @Test
+ public void write_filter() throws Exception {
+ UserSession userSession = MockUserSession.set();
+ test(userSession,
+ new DefaultIssueFilter()
+ .setId(13L)
+ .setName("Blocker issues")
+ .setDescription("All Blocker Issues")
+ .setShared(true)
+ .setUser("simon")
+ .setData("severity=BLOCKER"),
+ "{\"filter\":{\n" +
+ " \"id\":13,\n" +
+ " \"name\":\"Blocker issues\",\n" +
+ " \"description\":\"All Blocker Issues\",\n" +
+ " \"shared\":true,\n" +
+ " \"query\":\"severity=BLOCKER\",\n" +
+ " \"user\":\"simon\",\n" +
+ " \"canModify\":false\n" +
+ " }}"
+ );
+ }
+
+ @Test
+ public void can_modify_if_logged_user_own_filter() throws Exception {
+ UserSession userSession = MockUserSession.set().setLogin("simon");
+ test(userSession,
+ new DefaultIssueFilter()
+ .setId(13L)
+ .setName("Blocker issues")
+ .setDescription("All Blocker Issues")
+ .setShared(true)
+ .setUser("simon")
+ .setData("severity=BLOCKER"),
+ "{\"filter\":{\n" +
+ " \"id\":13,\n" +
+ " \"name\":\"Blocker issues\",\n" +
+ " \"description\":\"All Blocker Issues\",\n" +
+ " \"shared\":true,\n" +
+ " \"query\":\"severity=BLOCKER\",\n" +
+ " \"user\":\"simon\",\n" +
+ " \"canModify\":true\n" +
+ " }}"
+ );
+ }
+
+ @Test
+ public void can_modify_if_logged_user_has_permission() throws Exception {
+ UserSession userSession = MockUserSession.set().setLogin("simon").setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN);
+ test(userSession,
+ new DefaultIssueFilter()
+ .setId(13L)
+ .setName("Blocker issues")
+ .setDescription("All Blocker Issues")
+ .setShared(true)
+ .setUser("julien")
+ .setData("severity=BLOCKER"),
+ "{\"filter\":{\n" +
+ " \"id\":13,\n" +
+ " \"name\":\"Blocker issues\",\n" +
+ " \"description\":\"All Blocker Issues\",\n" +
+ " \"shared\":true,\n" +
+ " \"query\":\"severity=BLOCKER\",\n" +
+ " \"user\":\"julien\",\n" +
+ " \"canModify\":true\n" +
+ " }}"
+ );
+ }
+
+ private void test(UserSession userSession, DefaultIssueFilter filter, String expected) throws JSONException {
+ StringWriter output = new StringWriter();
+ JsonWriter jsonWriter = JsonWriter.of(output);
+ jsonWriter.beginObject();
+ writer.write(userSession, filter, jsonWriter);
+ jsonWriter.endObject();
+ JSONAssert.assertEquals(output.toString(), expected, true);
+ }
+}
*/
package org.sonar.server.issue.filter;
+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.server.ws.WebService;
-import org.sonar.core.issue.DefaultIssueFilter;
-import org.sonar.server.exceptions.NotFoundException;
-import org.sonar.server.user.MockUserSession;
import org.sonar.server.ws.WsTester;
-import java.util.Arrays;
-
import static org.fest.assertions.Assertions.assertThat;
-import static org.fest.assertions.Fail.fail;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
+@RunWith(MockitoJUnitRunner.class)
public class IssueFilterWsTest {
- IssueFilterService service = mock(IssueFilterService.class);
- IssueFilterWs ws = new IssueFilterWs(service);
- WsTester tester = new WsTester(ws);
+ @Mock
+ IssueFilterService service;
+
+ @Mock
+ IssueFilterWriter issueFilterWriter;
+
+ IssueFilterWs ws;
+
+ WsTester tester;
+
+ @Before
+ public void setUp() throws Exception {
+ ws = new IssueFilterWs(new AppAction(service, issueFilterWriter), new ShowAction(service, issueFilterWriter), new FavoritesAction(service));
+ tester = new WsTester(ws);
+ }
@Test
public void define_ws() throws Exception {
WebService.Action app = controller.action("app");
assertThat(app).isNotNull();
- assertThat(app.handler()).isNotNull();
- assertThat(app.isPost()).isFalse();
- assertThat(app.isInternal()).isTrue();
- assertThat(app.since()).isEqualTo("4.2");
assertThat(app.params()).hasSize(1);
- WebService.Param appId = app.param("id");
- assertThat(appId).isNotNull();
- assertThat(appId.description()).isNotNull();
- assertThat(appId.isRequired()).isFalse();
-
WebService.Action show = controller.action("show");
assertThat(show).isNotNull();
- assertThat(show.handler()).isNotNull();
- assertThat(show.isPost()).isFalse();
- assertThat(show.isInternal()).isFalse();
- assertThat(show.since()).isEqualTo("4.2");
+ assertThat(show.responseExampleAsString()).isNotEmpty();
assertThat(show.params()).hasSize(1);
- WebService.Param showId = show.param("id");
- assertThat(showId).isNotNull();
- assertThat(showId.description()).isNotNull();
- assertThat(showId.isRequired()).isTrue();
-
WebService.Action favorites = controller.action("favorites");
assertThat(favorites).isNotNull();
- assertThat(favorites.handler()).isNotNull();
- assertThat(favorites.isPost()).isFalse();
- assertThat(favorites.isInternal()).isFalse();
- assertThat(favorites.since()).isEqualTo("4.2");
assertThat(favorites.params()).isEmpty();
}
- @Test
- public void anonymous_app() throws Exception {
- MockUserSession.set().setLogin(null);
- tester.newRequest("app").execute().assertJson(getClass(), "anonymous_page.json");
- }
-
- @Test
- public void logged_in_app() throws Exception {
- MockUserSession.set().setLogin("eric").setUserId(123);
- tester.newRequest("app").execute()
- .assertJson(getClass(), "logged_in_page.json");
- }
-
- @Test
- public void logged_in_app_with_favorites() throws Exception {
- MockUserSession session = MockUserSession.set().setLogin("eric").setUserId(123);
- when(service.findFavoriteFilters(session)).thenReturn(Arrays.asList(
- new DefaultIssueFilter().setId(6L).setName("My issues"),
- new DefaultIssueFilter().setId(13L).setName("Blocker issues")
- ));
- tester.newRequest("app").execute()
- .assertJson(getClass(), "logged_in_page_with_favorites.json");
- }
-
- @Test
- public void logged_in_app_with_selected_filter() throws Exception {
- MockUserSession session = MockUserSession.set().setLogin("eric").setUserId(123);
- when(service.find(13L, session)).thenReturn(
- new DefaultIssueFilter().setId(13L).setName("Blocker issues").setData("severity=BLOCKER").setUser("eric")
- );
-
- tester.newRequest("app").setParam("id", "13").execute()
- .assertJson(getClass(), "logged_in_page_with_selected_filter.json");
- }
-
- @Test
- public void app_selected_filter_can_not_be_modified() throws Exception {
- // logged-in user is 'eric' but filter is owned by 'simon'
- MockUserSession session = MockUserSession.set().setLogin("eric").setUserId(123).setGlobalPermissions("none");
- when(service.find(13L, session)).thenReturn(
- new DefaultIssueFilter().setId(13L).setName("Blocker issues").setData("severity=BLOCKER").setUser("simon").setShared(true)
- );
-
- tester.newRequest("app").setParam("id", "13").execute()
- .assertJson(getClass(), "selected_filter_can_not_be_modified.json");
- }
-
- @Test
- public void show_filter() throws Exception {
- // logged-in user is 'eric' but filter is owned by 'simon'
- MockUserSession session = MockUserSession.set().setLogin("eric").setUserId(123).setGlobalPermissions("none");
- when(service.find(13L, session)).thenReturn(
- new DefaultIssueFilter().setId(13L).setName("Blocker issues").setDescription("All Blocker Issues").setData("severity=BLOCKER").setUser("simon").setShared(true)
- );
-
- tester.newRequest("show").setParam("id", "13").execute()
- .assertJson(getClass(), "show_filter.json");
- }
-
- @Test
- public void show_unknown_filter() throws Exception {
- MockUserSession session = MockUserSession.set().setLogin("eric").setUserId(123).setGlobalPermissions("none");
- when(service.find(42L, session)).thenThrow(new NotFoundException("Filter 42 does not exist"));
-
- try {
- tester.newRequest("show").setParam("id", "42").execute();
- fail();
- } catch (NotFoundException e) {
- assertThat(e).hasMessage("Filter 42 does not exist");
- }
- }
-
- @Test
- public void favorites_of_anonymous() throws Exception {
- MockUserSession.set();
-
- tester.newRequest("favorites").execute()
- .assertJson("{'favoriteFilters': []}");
- }
-
- @Test
- public void favorites_of_logged_in_user() throws Exception {
- MockUserSession session = MockUserSession.set().setLogin("eric").setUserId(123);
- when(service.findFavoriteFilters(session)).thenReturn(Arrays.asList(
- new DefaultIssueFilter().setId(13L).setName("Blocker issues").setData("severity=BLOCKER").setUser("simon").setShared(true)
- ));
-
- tester.newRequest("favorites").execute()
- .assertJson("{'favoriteFilters': [{'id': 13, 'name': 'Blocker issues', 'user': 'simon', 'shared': true}]}");
- }
}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonar.server.issue.filter;
+
+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.core.issue.DefaultIssueFilter;
+import org.sonar.server.exceptions.NotFoundException;
+import org.sonar.server.user.MockUserSession;
+import org.sonar.server.ws.WsTester;
+
+import static org.fest.assertions.Assertions.assertThat;
+import static org.fest.assertions.Fail.fail;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+@RunWith(MockitoJUnitRunner.class)
+public class ShowActionTest {
+
+ @Mock
+ IssueFilterService service;
+
+ IssueFilterWriter writer = new IssueFilterWriter();
+
+ ShowAction action;
+
+ WsTester tester;
+
+ @Before
+ public void setUp() throws Exception {
+ action = new ShowAction(service, writer);
+ tester = new WsTester(new IssueFilterWs(mock(AppAction.class), action, mock(FavoritesAction.class)));
+ }
+
+ @Test
+ public void show_filter() throws Exception {
+ // logged-in user is 'eric' but filter is owned by 'simon'
+ MockUserSession session = MockUserSession.set().setLogin("eric").setUserId(123).setGlobalPermissions("none");
+ when(service.find(13L, session)).thenReturn(
+ new DefaultIssueFilter().setId(13L).setName("Blocker issues").setDescription("All Blocker Issues").setData("severity=BLOCKER").setUser("simon").setShared(true)
+ );
+
+ tester.newRequest("show").setParam("id", "13").execute()
+ .assertJson(getClass(), "show_filter.json");
+ }
+
+ @Test
+ public void show_unknown_filter() throws Exception {
+ MockUserSession session = MockUserSession.set().setLogin("eric").setUserId(123).setGlobalPermissions("none");
+ when(service.find(42L, session)).thenThrow(new NotFoundException("Filter 42 does not exist"));
+
+ try {
+ tester.newRequest("show").setParam("id", "42").execute();
+ fail();
+ } catch (NotFoundException e) {
+ assertThat(e).hasMessage("Filter 42 does not exist");
+ }
+ }
+
+}
+++ /dev/null
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-package org.sonar.server.issue.ws;
-
-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.fest.assertions.Assertions.assertThat;
-
-public class ActionPlanWsTest {
-
- WsTester tester = new WsTester(new ActionPlanWs());
-
- @Test
- public void define_action_plan_controller() throws Exception {
- WebService.Controller controller = tester.controller("api/action_plans");
- assertThat(controller).isNotNull();
- assertThat(controller.description()).isNotEmpty();
- assertThat(controller.actions()).hasSize(6);
- }
-
- @Test
- public void define_search_action() throws Exception {
- WebService.Controller controller = tester.controller("api/action_plans");
-
- WebService.Action action = controller.action("search");
- assertThat(action).isNotNull();
- assertThat(action.handler()).isInstanceOf(RailsHandler.class);
- assertThat(action.since()).isEqualTo("3.6");
- assertThat(action.isPost()).isFalse();
- assertThat(action.isInternal()).isFalse();
- assertThat(action.params()).hasSize(1);
-
- WebService.Param project = action.param("project");
- assertThat(project).isNotNull();
- assertThat(project.description()).isNotNull();
- assertThat(project.exampleValue()).isNotNull();
- assertThat(project.isRequired()).isTrue();
- }
-
- @Test
- public void define_create_action() throws Exception {
- WebService.Controller controller = tester.controller("api/action_plans");
-
- WebService.Action action = controller.action("create");
- assertThat(action).isNotNull();
- assertThat(action.handler()).isInstanceOf(RailsHandler.class);
- assertThat(action.since()).isEqualTo("3.6");
- assertThat(action.isPost()).isTrue();
- assertThat(action.isInternal()).isFalse();
- assertThat(action.params()).hasSize(4);
-
- WebService.Param name = action.param("name");
- assertThat(name).isNotNull();
- assertThat(name.description()).isNotNull();
- assertThat(name.exampleValue()).isNotNull();
- assertThat(name.isRequired()).isTrue();
-
- WebService.Param description = action.param("description");
- assertThat(description).isNotNull();
- assertThat(description.description()).isNotNull();
- assertThat(description.isRequired()).isFalse();
-
- WebService.Param project = action.param("project");
- assertThat(project).isNotNull();
- assertThat(project.description()).isNotNull();
- assertThat(project.exampleValue()).isNotNull();
- assertThat(project.isRequired()).isTrue();
-
- WebService.Param deadLine = action.param("deadLine");
- assertThat(deadLine).isNotNull();
- assertThat(deadLine.description()).isNotNull();
- assertThat(deadLine.exampleValue()).isNotNull();
- assertThat(deadLine.isRequired()).isFalse();
- }
-
- @Test
- public void define_delete_action() throws Exception {
- WebService.Controller controller = tester.controller("api/action_plans");
-
- WebService.Action action = controller.action("delete");
- assertThat(action).isNotNull();
- assertThat(action.handler()).isInstanceOf(RailsHandler.class);
- assertThat(action.since()).isEqualTo("3.6");
- assertThat(action.isPost()).isTrue();
- assertThat(action.isInternal()).isFalse();
- assertThat(action.params()).hasSize(1);
-
- WebService.Param key = action.param("key");
- assertThat(key).isNotNull();
- assertThat(key.description()).isNotNull();
- assertThat(key.exampleValue()).isNotNull();
- assertThat(key.isRequired()).isTrue();
- }
-
- @Test
- public void define_update_action() throws Exception {
- WebService.Controller controller = tester.controller("api/action_plans");
-
- WebService.Action action = controller.action("update");
- assertThat(action).isNotNull();
- assertThat(action.handler()).isInstanceOf(RailsHandler.class);
- assertThat(action.since()).isEqualTo("3.6");
- assertThat(action.isPost()).isTrue();
- assertThat(action.isInternal()).isFalse();
- assertThat(action.params()).hasSize(4);
-
- WebService.Param project = action.param("key");
- assertThat(project).isNotNull();
- assertThat(project.description()).isNotNull();
- assertThat(project.exampleValue()).isNotNull();
- assertThat(project.isRequired()).isTrue();
-
- WebService.Param name = action.param("name");
- assertThat(name).isNotNull();
- assertThat(name.description()).isNotNull();
- assertThat(name.exampleValue()).isNotNull();
- assertThat(name.isRequired()).isTrue();
-
- WebService.Param description = action.param("description");
- assertThat(description).isNotNull();
- assertThat(description.description()).isNotNull();
- assertThat(description.isRequired()).isFalse();
-
- WebService.Param deadLine = action.param("deadLine");
- assertThat(deadLine).isNotNull();
- assertThat(deadLine.description()).isNotNull();
- assertThat(deadLine.exampleValue()).isNotNull();
- assertThat(deadLine.isRequired()).isFalse();
- }
-
- @Test
- public void define_open_action() throws Exception {
- WebService.Controller controller = tester.controller("api/action_plans");
-
- WebService.Action action = controller.action("open");
- assertThat(action).isNotNull();
- assertThat(action.handler()).isInstanceOf(RailsHandler.class);
- assertThat(action.since()).isEqualTo("3.6");
- assertThat(action.isPost()).isTrue();
- assertThat(action.isInternal()).isFalse();
- assertThat(action.params()).hasSize(1);
-
- WebService.Param key = action.param("key");
- assertThat(key).isNotNull();
- assertThat(key.description()).isNotNull();
- assertThat(key.exampleValue()).isNotNull();
- assertThat(key.isRequired()).isTrue();
- }
-
- @Test
- public void define_close_action() throws Exception {
- WebService.Controller controller = tester.controller("api/action_plans");
-
- WebService.Action action = controller.action("close");
- assertThat(action).isNotNull();
- assertThat(action.handler()).isInstanceOf(RailsHandler.class);
- assertThat(action.since()).isEqualTo("3.6");
- assertThat(action.isPost()).isTrue();
- assertThat(action.isInternal()).isFalse();
- assertThat(action.params()).hasSize(1);
-
- WebService.Param key = action.param("key");
- assertThat(key).isNotNull();
- assertThat(key.description()).isNotNull();
- assertThat(key.exampleValue()).isNotNull();
- assertThat(key.isRequired()).isTrue();
- }
-}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.issue.ws;
+
+import com.google.common.collect.Lists;
+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.component.Component;
+import org.sonar.api.i18n.I18n;
+import org.sonar.api.issue.ActionPlan;
+import org.sonar.api.issue.Issue;
+import org.sonar.api.issue.IssueFinder;
+import org.sonar.api.issue.IssueQuery;
+import org.sonar.api.issue.action.Action;
+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.rules.Rule;
+import org.sonar.api.server.debt.internal.DefaultDebtCharacteristic;
+import org.sonar.api.user.User;
+import org.sonar.api.utils.DateUtils;
+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.issue.DefaultActionPlan;
+import org.sonar.core.issue.DefaultIssueQueryResult;
+import org.sonar.core.issue.workflow.Transition;
+import org.sonar.core.user.DefaultUser;
+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.IssueService;
+import org.sonar.server.user.MockUserSession;
+import org.sonar.server.user.UserSession;
+import org.sonar.server.ws.WsTester;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Locale;
+
+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;
+
+@RunWith(MockitoJUnitRunner.class)
+public class IssueShowActionTest {
+
+ @Mock
+ IssueFinder issueFinder;
+
+ @Mock
+ IssueService issueService;
+
+ @Mock
+ IssueChangelogService issueChangelogService;
+
+ @Mock
+ ActionService actionService;
+
+ @Mock
+ DebtModelService debtModel;
+
+ @Mock
+ I18n i18n;
+
+ @Mock
+ Durations durations;
+
+ List<Issue> issues;
+ DefaultIssueQueryResult result;
+
+ private Date issue_creation_date;
+
+ WsTester tester;
+
+ @Before
+ public void setUp() throws Exception {
+ issues = new ArrayList<Issue>();
+ result = new DefaultIssueQueryResult(issues);
+ result.addRules(newArrayList(Rule.create("squid", "AvoidCycle").setName("Avoid cycle")));
+ when(issueFinder.find(any(IssueQuery.class))).thenReturn(result);
+
+ when(issueChangelogService.changelog(any(Issue.class))).thenReturn(mock(IssueChangelog.class));
+
+ issue_creation_date = DateUtils.parseDateTime("2014-01-22T19:10:03+0100");
+ when(i18n.formatDateTime(any(Locale.class), eq(issue_creation_date))).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(issueFinder, issueService, issueChangelogService, actionService, debtModel, i18n, durations)));
+ }
+
+ @Test
+ public void show_issue() throws Exception {
+ String issueKey = "ABCD";
+ Issue issue = new DefaultIssue()
+ .setKey(issueKey)
+ .setComponentKey("org.sonar.server.issue.IssueClient")
+ .setProjectKey("org.sonar.Sonar")
+ .setRuleKey(RuleKey.of("squid", "AvoidCycle"))
+ .setLine(12)
+ .setEffortToFix(2.0)
+ .setMessage("Fix it")
+ .setResolution("FIXED")
+ .setStatus("CLOSED")
+ .setSeverity("MAJOR")
+ .setCreationDate(issue_creation_date);
+ issues.add(issue);
+
+ result.addComponents(Lists.<Component>newArrayList(new ComponentDto()
+ .setId(10L)
+ .setKey("org.sonar.server.issue.IssueClient")
+ .setLongName("SonarQube :: Issue Client")
+ .setQualifier("FIL")
+ .setSubProjectId(1L)
+ .setProjectId(1L)
+ ));
+
+ result.addComponents(Lists.<Component>newArrayList(new ComponentDto()
+ .setId(1L)
+ .setKey("org.sonar.Sonar")
+ .setLongName("SonarQube")
+ .setProjectId(1L)
+ ));
+
+ MockUserSession.set();
+ WsTester.TestRequest request = tester.newRequest("show").setParam("key", issueKey);
+ request.execute().assertJson(getClass(), "show_issue.json");
+ }
+
+ @Test
+ public void show_issue_with_sub_project() throws Exception {
+ String issueKey = "ABCD";
+ Issue issue = new DefaultIssue()
+ .setKey(issueKey)
+ .setComponentKey("org.sonar.server.issue.IssueClient")
+ .setProjectKey("org.sonar.Sonar")
+ .setRuleKey(RuleKey.of("squid", "AvoidCycle"))
+ .setLine(12)
+ .setEffortToFix(2.0)
+ .setMessage("Fix it")
+ .setResolution("FIXED")
+ .setStatus("CLOSED")
+ .setSeverity("MAJOR")
+ .setCreationDate(issue_creation_date);
+ issues.add(issue);
+
+ // File
+ result.addComponents(Lists.<Component>newArrayList(new ComponentDto()
+ .setId(10L)
+ .setKey("org.sonar.server.issue.IssueClient")
+ .setLongName("SonarQube :: Issue Client")
+ .setQualifier("FIL")
+ .setSubProjectId(2L)
+ .setProjectId(1L)));
+
+ // Module
+ result.addComponents(Lists.<Component>newArrayList(new ComponentDto()
+ .setId(2L)
+ .setKey("org.sonar.server.Server")
+ .setLongName("SonarQube :: Server")
+ .setQualifier("BRC")
+ .setSubProjectId(1L)
+ .setProjectId(1L)));
+
+ // Project
+ result.addComponents(Lists.<Component>newArrayList(new ComponentDto()
+ .setId(1L)
+ .setKey("org.sonar.Sonar")
+ .setLongName("SonarQube")));
+
+ MockUserSession.set();
+ WsTester.TestRequest request = tester.newRequest("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";
+ Issue issue = new DefaultIssue()
+ .setKey(issueKey)
+ .setComponentKey("org.sonar.server.issue.IssueClient")
+ .setProjectKey("org.sonar.Sonar")
+ .setRuleKey(RuleKey.of("squid", "AvoidCycle"))
+ .setLine(12)
+ .setEffortToFix(2.0)
+ .setMessage("Fix it")
+ .setResolution("FIXED")
+ .setStatus("CLOSED")
+ .setSeverity("MAJOR")
+ .setCreationDate(issue_creation_date);
+ issues.add(issue);
+
+ // File
+ result.addComponents(Lists.<Component>newArrayList(new ComponentDto()
+ .setId(10L)
+ .setKey("org.sonar.server.issue.IssueClient")
+ .setLongName("SonarQube :: Issue Client")
+ .setQualifier("FIL")
+ .setSubProjectId(2L)
+ .setProjectId(1L)));
+
+ // Module
+ result.addComponents(Lists.<Component>newArrayList(new ComponentDto()
+ .setId(2L)
+ .setKey("org.sonar.server.Server")
+ .setName("SonarQube :: Server")
+ .setQualifier("BRC")
+ .setSubProjectId(1L)
+ .setProjectId(1L)));
+
+ // Project
+ result.addComponents(Lists.<Component>newArrayList(new ComponentDto()
+ .setId(1L)
+ .setKey("org.sonar.Sonar")
+ .setName("SonarQube")));
+
+ MockUserSession.set();
+ WsTester.TestRequest request = tester.newRequest("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";
+ Issue issue = createIssue();
+ issues.add(issue);
+
+ Component project = mock(Component.class);
+ when(project.key()).thenReturn("org.sonar.Sonar");
+ when(project.longName()).thenReturn("SonarQube");
+ result.addProjects(newArrayList(project));
+
+ MockUserSession.set();
+ WsTester.TestRequest request = tester.newRequest("show").setParam("key", issueKey);
+ request.execute().assertJson(getClass(), "show_issue_on_removed_component.json");
+ }
+
+ @Test
+ public void show_issue_on_removed_project_and_component() throws Exception {
+ String issueKey = "ABCD";
+ Issue issue = createIssue();
+ issues.add(issue);
+
+ MockUserSession.set();
+ WsTester.TestRequest request = tester.newRequest("show").setParam("key", issueKey);
+ request.execute().assertJson(getClass(), "show_issue_on_removed_project_and_component.json");
+ }
+
+ @Test
+ public void show_issue_with_action_plan() throws Exception {
+ Issue issue = createStandardIssue()
+ .setActionPlanKey("AP-ABCD");
+ issues.add(issue);
+
+ result.addActionPlans(newArrayList((ActionPlan) new DefaultActionPlan().setKey("AP-ABCD").setName("Version 4.2")));
+
+ MockUserSession.set();
+ WsTester.TestRequest request = tester.newRequest("show").setParam("key", issue.key());
+ request.execute().assertJson(getClass(), "show_issue_with_action_plan.json");
+ }
+
+ @Test
+ public void show_issue_with_users() throws Exception {
+ Issue issue = createStandardIssue()
+ .setAssignee("john")
+ .setReporter("steven")
+ .setAuthorLogin("Henry");
+ issues.add(issue);
+
+ result.addUsers(Lists.<User>newArrayList(
+ new DefaultUser().setLogin("john").setName("John"),
+ new DefaultUser().setLogin("steven").setName("Steven")
+ ));
+
+ MockUserSession.set();
+ WsTester.TestRequest request = tester.newRequest("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));
+ Issue issue = createStandardIssue().setDebt(debt);
+ issues.add(issue);
+
+ when(durations.format(any(Locale.class), eq(debt), eq(Durations.DurationFormat.SHORT))).thenReturn("2 hours 1 minutes");
+
+ MockUserSession.set();
+ WsTester.TestRequest request = tester.newRequest("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 {
+ Issue issue = createStandardIssue().setDebt(Duration.create(7260L));
+ issues.add(issue);
+
+ result.rule(issue).setCharacteristicId(2);
+ when(debtModel.characteristicById(1)).thenReturn(new DefaultDebtCharacteristic().setId(1).setName("Maintainability"));
+ when(debtModel.characteristicById(2)).thenReturn(new DefaultDebtCharacteristic().setId(2).setName("Readability").setParentId(1));
+
+ MockUserSession.set();
+ WsTester.TestRequest request = tester.newRequest("show").setParam("key", issue.key());
+ request.execute().assertJson(getClass(), "show_issue_with_characteristics.json");
+ }
+
+ @Test
+ public void show_issue_with_default_characteristics() throws Exception {
+ Issue issue = createStandardIssue().setDebt(Duration.create(7260L));
+ issues.add(issue);
+
+ result.rule(issue).setDefaultCharacteristicId(2);
+ when(debtModel.characteristicById(1)).thenReturn(new DefaultDebtCharacteristic().setId(1).setName("Maintainability"));
+ when(debtModel.characteristicById(2)).thenReturn(new DefaultDebtCharacteristic().setId(2).setName("Readability").setParentId(1));
+
+ MockUserSession.set();
+ WsTester.TestRequest request = tester.newRequest("show").setParam("key", issue.key());
+ request.execute().assertJson(getClass(), "show_issue_with_characteristics.json");
+ }
+
+ @Test
+ public void use_user_characteristic_if_both_characteristic_ids_are_defined() throws Exception {
+ Issue issue = createStandardIssue().setDebt(Duration.create(7260L));
+ issues.add(issue);
+
+ result.rule(issue).setCharacteristicId(2);
+ when(debtModel.characteristicById(1)).thenReturn(new DefaultDebtCharacteristic().setId(1).setName("Maintainability"));
+ when(debtModel.characteristicById(2)).thenReturn(new DefaultDebtCharacteristic().setId(2).setName("Readability").setParentId(1));
+
+ result.rule(issue).setDefaultCharacteristicId(20);
+ when(debtModel.characteristicById(10)).thenReturn(new DefaultDebtCharacteristic().setId(10).setName("Default Maintainability"));
+ when(debtModel.characteristicById(20)).thenReturn(new DefaultDebtCharacteristic().setId(20).setName("Default Readability").setParentId(10));
+
+ MockUserSession.set();
+ WsTester.TestRequest request = tester.newRequest("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");
+
+ Issue issue = createStandardIssue()
+ .setCreationDate(creationDate)
+ .setUpdateDate(updateDate)
+ .setCloseDate(closedDate);
+ issues.add(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");
+
+ MockUserSession.set();
+ WsTester.TestRequest request = tester.newRequest("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");
+
+ Issue issue = createStandardIssue()
+ .addComment(
+ new DefaultIssueComment()
+ .setKey("COMMENT-ABCD")
+ .setMarkdownText("*My comment*")
+ .setUserLogin("john")
+ .setCreatedAt(date1))
+ .addComment(
+ new DefaultIssueComment()
+ .setKey("COMMENT-ABCE")
+ .setMarkdownText("Another comment")
+ .setUserLogin("arthur")
+ .setCreatedAt(date2)
+ );
+ issues.add(issue);
+ result.addUsers(Lists.<User>newArrayList(
+ new DefaultUser().setLogin("john").setName("John"),
+ 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");
+
+ MockUserSession.set().setLogin("arthur");
+ WsTester.TestRequest request = tester.newRequest("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");
+ issues.add(issue);
+
+ when(issueService.listTransitions(eq(issue), any(UserSession.class))).thenReturn(newArrayList(Transition.create("reopen", "RESOLVED", "REOPEN")));
+
+ MockUserSession.set().setLogin("john");
+ WsTester.TestRequest request = tester.newRequest("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");
+ issues.add(issue);
+
+ MockUserSession.set().setLogin("john");
+ WsTester.TestRequest request = tester.newRequest("show").setParam("key", issue.key());
+ request.execute().assertJson(getClass(), "show_issue_with_actions.json");
+ }
+
+ @Test
+ public void show_issue_with_set_severity_action() throws Exception {
+ DefaultIssue issue = createStandardIssue()
+ .setStatus("OPEN");
+ issues.add(issue);
+
+ MockUserSession.set().setLogin("john").addProjectPermissions(UserRole.ISSUE_ADMIN, issue.projectKey());
+ WsTester.TestRequest request = tester.newRequest("show").setParam("key", issue.key());
+ request.execute().assertJson(getClass(), "show_issue_with_set_severity_action.json");
+ }
+
+ @Test
+ public void show_issue_with_assign_to_me_action() throws Exception {
+ DefaultIssue issue = createStandardIssue()
+ .setStatus("OPEN");
+ issues.add(issue);
+
+ MockUserSession.set().setLogin("john");
+ WsTester.TestRequest request = tester.newRequest("show").setParam("key", issue.key());
+ request.execute().assertJson(getClass(), "show_issue_with_assign_to_me_action.json");
+ }
+
+ @Test
+ public void show_issue_without_assign_to_me_action() throws Exception {
+ DefaultIssue issue = createStandardIssue()
+ .setStatus("OPEN")
+ .setAssignee("john");
+ issues.add(issue);
+
+ result.addUsers(Lists.<User>newArrayList(
+ new DefaultUser().setLogin("john").setName("John")
+ ));
+
+ MockUserSession.set().setLogin("john");
+ WsTester.TestRequest request = tester.newRequest("show").setParam("key", issue.key());
+ request.execute().assertJson(getClass(), "show_issue_without_assign_to_me_action.json");
+ }
+
+ @Test
+ public void show_issue_with_actions_defined_by_plugins() throws Exception {
+ Issue issue = createStandardIssue()
+ .setStatus("OPEN");
+ issues.add(issue);
+
+ Action action = mock(Action.class);
+ when(action.key()).thenReturn("link-to-jira");
+ when(actionService.listAvailableActions(issue)).thenReturn(newArrayList(action));
+
+ MockUserSession.set().setLogin("john");
+ WsTester.TestRequest request = tester.newRequest("show").setParam("key", issue.key());
+ request.execute().assertJson(getClass(), "show_issue_with_actions_defined_by_plugins.json");
+ }
+
+ @Test
+ public void show_issue_with_changelog() throws Exception {
+ Issue issue = createStandardIssue();
+ issues.add(issue);
+
+ Date date1 = DateUtils.parseDateTime("2014-02-22T19:10:03+0100");
+ Date date2 = DateUtils.parseDateTime("2014-02-23T19:10:03+0100");
+
+ List<User> users = Lists.<User>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");
+
+ MockUserSession.set();
+ WsTester.TestRequest request = tester.newRequest("show").setParam("key", issue.key());
+ request.execute().assertJson(getClass(), "show_issue_with_changelog.json");
+ }
+
+ private DefaultIssue createStandardIssue() {
+ DefaultIssue issue = createIssue();
+ addComponentAndProject();
+ return issue;
+ }
+
+ private DefaultIssue createIssue() {
+ return new DefaultIssue()
+ .setKey("ABCD")
+ .setComponentKey("org.sonar.server.issue.IssueClient")
+ .setProjectKey("org.sonar.Sonar")
+ .setRuleKey(RuleKey.of("squid", "AvoidCycle"))
+ .setCreationDate(issue_creation_date);
+ }
+
+ private void addComponentAndProject() {
+ result.addComponents(Lists.<Component>newArrayList(new ComponentDto()
+ .setId(10L)
+ .setKey("org.sonar.server.issue.IssueClient")
+ .setLongName("SonarQube :: Issue Client")
+ .setQualifier("FIL")
+ .setSubProjectId(1L)
+ .setProjectId(1L)
+ ));
+
+ result.addComponents(Lists.<Component>newArrayList(new ComponentDto()
+ .setId(1L)
+ .setKey("org.sonar.Sonar")
+ .setLongName("SonarQube")
+ .setProjectId(1L)
+ ));
+ }
+
+}
+++ /dev/null
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.server.issue.ws;
-
-import com.google.common.collect.Lists;
-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.component.Component;
-import org.sonar.api.i18n.I18n;
-import org.sonar.api.issue.ActionPlan;
-import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.IssueFinder;
-import org.sonar.api.issue.IssueQuery;
-import org.sonar.api.issue.action.Action;
-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.rules.Rule;
-import org.sonar.api.server.debt.internal.DefaultDebtCharacteristic;
-import org.sonar.server.ws.WsTester;
-import org.sonar.api.user.User;
-import org.sonar.api.utils.DateUtils;
-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.issue.DefaultActionPlan;
-import org.sonar.core.issue.DefaultIssueQueryResult;
-import org.sonar.core.issue.workflow.Transition;
-import org.sonar.core.user.DefaultUser;
-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.IssueService;
-import org.sonar.server.user.MockUserSession;
-import org.sonar.server.user.UserSession;
-
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-import java.util.Locale;
-
-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;
-
-@RunWith(MockitoJUnitRunner.class)
-public class IssueShowWsHandlerTest {
-
- @Mock
- IssueFinder issueFinder;
-
- @Mock
- IssueService issueService;
-
- @Mock
- IssueChangelogService issueChangelogService;
-
- @Mock
- ActionService actionService;
-
- @Mock
- DebtModelService debtModel;
-
- @Mock
- I18n i18n;
-
- @Mock
- Durations durations;
-
- List<Issue> issues;
- DefaultIssueQueryResult result;
-
- private Date issue_creation_date;
-
- WsTester tester;
-
- @Before
- public void setUp() throws Exception {
- issues = new ArrayList<Issue>();
- result = new DefaultIssueQueryResult(issues);
- result.addRules(newArrayList(Rule.create("squid", "AvoidCycle").setName("Avoid cycle")));
- when(issueFinder.find(any(IssueQuery.class))).thenReturn(result);
-
- when(issueChangelogService.changelog(any(Issue.class))).thenReturn(mock(IssueChangelog.class));
-
- issue_creation_date = DateUtils.parseDateTime("2014-01-22T19:10:03+0100");
- when(i18n.formatDateTime(any(Locale.class), eq(issue_creation_date))).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 IssueShowWsHandler(issueFinder, issueService, issueChangelogService, actionService, debtModel, i18n, durations)));
- }
-
- @Test
- public void show_issue() throws Exception {
- String issueKey = "ABCD";
- Issue issue = new DefaultIssue()
- .setKey(issueKey)
- .setComponentKey("org.sonar.server.issue.IssueClient")
- .setProjectKey("org.sonar.Sonar")
- .setRuleKey(RuleKey.of("squid", "AvoidCycle"))
- .setLine(12)
- .setEffortToFix(2.0)
- .setMessage("Fix it")
- .setResolution("FIXED")
- .setStatus("CLOSED")
- .setSeverity("MAJOR")
- .setCreationDate(issue_creation_date);
- issues.add(issue);
-
- result.addComponents(Lists.<Component>newArrayList(new ComponentDto()
- .setId(10L)
- .setKey("org.sonar.server.issue.IssueClient")
- .setLongName("SonarQube :: Issue Client")
- .setQualifier("FIL")
- .setSubProjectId(1L)
- .setProjectId(1L)
- ));
-
- result.addComponents(Lists.<Component>newArrayList(new ComponentDto()
- .setId(1L)
- .setKey("org.sonar.Sonar")
- .setLongName("SonarQube")
- .setProjectId(1L)
- ));
-
- MockUserSession.set();
- WsTester.TestRequest request = tester.newRequest("show").setParam("key", issueKey);
- request.execute().assertJson(getClass(), "show_issue.json");
- }
-
- @Test
- public void show_issue_with_sub_project() throws Exception {
- String issueKey = "ABCD";
- Issue issue = new DefaultIssue()
- .setKey(issueKey)
- .setComponentKey("org.sonar.server.issue.IssueClient")
- .setProjectKey("org.sonar.Sonar")
- .setRuleKey(RuleKey.of("squid", "AvoidCycle"))
- .setLine(12)
- .setEffortToFix(2.0)
- .setMessage("Fix it")
- .setResolution("FIXED")
- .setStatus("CLOSED")
- .setSeverity("MAJOR")
- .setCreationDate(issue_creation_date);
- issues.add(issue);
-
- // File
- result.addComponents(Lists.<Component>newArrayList(new ComponentDto()
- .setId(10L)
- .setKey("org.sonar.server.issue.IssueClient")
- .setLongName("SonarQube :: Issue Client")
- .setQualifier("FIL")
- .setSubProjectId(2L)
- .setProjectId(1L)));
-
- // Module
- result.addComponents(Lists.<Component>newArrayList(new ComponentDto()
- .setId(2L)
- .setKey("org.sonar.server.Server")
- .setLongName("SonarQube :: Server")
- .setQualifier("BRC")
- .setSubProjectId(1L)
- .setProjectId(1L)));
-
- // Project
- result.addComponents(Lists.<Component>newArrayList(new ComponentDto()
- .setId(1L)
- .setKey("org.sonar.Sonar")
- .setLongName("SonarQube")));
-
- MockUserSession.set();
- WsTester.TestRequest request = tester.newRequest("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";
- Issue issue = new DefaultIssue()
- .setKey(issueKey)
- .setComponentKey("org.sonar.server.issue.IssueClient")
- .setProjectKey("org.sonar.Sonar")
- .setRuleKey(RuleKey.of("squid", "AvoidCycle"))
- .setLine(12)
- .setEffortToFix(2.0)
- .setMessage("Fix it")
- .setResolution("FIXED")
- .setStatus("CLOSED")
- .setSeverity("MAJOR")
- .setCreationDate(issue_creation_date);
- issues.add(issue);
-
- // File
- result.addComponents(Lists.<Component>newArrayList(new ComponentDto()
- .setId(10L)
- .setKey("org.sonar.server.issue.IssueClient")
- .setLongName("SonarQube :: Issue Client")
- .setQualifier("FIL")
- .setSubProjectId(2L)
- .setProjectId(1L)));
-
- // Module
- result.addComponents(Lists.<Component>newArrayList(new ComponentDto()
- .setId(2L)
- .setKey("org.sonar.server.Server")
- .setName("SonarQube :: Server")
- .setQualifier("BRC")
- .setSubProjectId(1L)
- .setProjectId(1L)));
-
- // Project
- result.addComponents(Lists.<Component>newArrayList(new ComponentDto()
- .setId(1L)
- .setKey("org.sonar.Sonar")
- .setName("SonarQube")));
-
- MockUserSession.set();
- WsTester.TestRequest request = tester.newRequest("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";
- Issue issue = createIssue();
- issues.add(issue);
-
- Component project = mock(Component.class);
- when(project.key()).thenReturn("org.sonar.Sonar");
- when(project.longName()).thenReturn("SonarQube");
- result.addProjects(newArrayList(project));
-
- MockUserSession.set();
- WsTester.TestRequest request = tester.newRequest("show").setParam("key", issueKey);
- request.execute().assertJson(getClass(), "show_issue_on_removed_component.json");
- }
-
- @Test
- public void show_issue_on_removed_project_and_component() throws Exception {
- String issueKey = "ABCD";
- Issue issue = createIssue();
- issues.add(issue);
-
- MockUserSession.set();
- WsTester.TestRequest request = tester.newRequest("show").setParam("key", issueKey);
- request.execute().assertJson(getClass(), "show_issue_on_removed_project_and_component.json");
- }
-
- @Test
- public void show_issue_with_action_plan() throws Exception {
- Issue issue = createStandardIssue()
- .setActionPlanKey("AP-ABCD");
- issues.add(issue);
-
- result.addActionPlans(newArrayList((ActionPlan) new DefaultActionPlan().setKey("AP-ABCD").setName("Version 4.2")));
-
- MockUserSession.set();
- WsTester.TestRequest request = tester.newRequest("show").setParam("key", issue.key());
- request.execute().assertJson(getClass(), "show_issue_with_action_plan.json");
- }
-
- @Test
- public void show_issue_with_users() throws Exception {
- Issue issue = createStandardIssue()
- .setAssignee("john")
- .setReporter("steven")
- .setAuthorLogin("Henry");
- issues.add(issue);
-
- result.addUsers(Lists.<User>newArrayList(
- new DefaultUser().setLogin("john").setName("John"),
- new DefaultUser().setLogin("steven").setName("Steven")
- ));
-
- MockUserSession.set();
- WsTester.TestRequest request = tester.newRequest("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));
- Issue issue = createStandardIssue().setDebt(debt);
- issues.add(issue);
-
- when(durations.format(any(Locale.class), eq(debt), eq(Durations.DurationFormat.SHORT))).thenReturn("2 hours 1 minutes");
-
- MockUserSession.set();
- WsTester.TestRequest request = tester.newRequest("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 {
- Issue issue = createStandardIssue().setDebt(Duration.create(7260L));
- issues.add(issue);
-
- result.rule(issue).setCharacteristicId(2);
- when(debtModel.characteristicById(1)).thenReturn(new DefaultDebtCharacteristic().setId(1).setName("Maintainability"));
- when(debtModel.characteristicById(2)).thenReturn(new DefaultDebtCharacteristic().setId(2).setName("Readability").setParentId(1));
-
- MockUserSession.set();
- WsTester.TestRequest request = tester.newRequest("show").setParam("key", issue.key());
- request.execute().assertJson(getClass(), "show_issue_with_characteristics.json");
- }
-
- @Test
- public void show_issue_with_default_characteristics() throws Exception {
- Issue issue = createStandardIssue().setDebt(Duration.create(7260L));
- issues.add(issue);
-
- result.rule(issue).setDefaultCharacteristicId(2);
- when(debtModel.characteristicById(1)).thenReturn(new DefaultDebtCharacteristic().setId(1).setName("Maintainability"));
- when(debtModel.characteristicById(2)).thenReturn(new DefaultDebtCharacteristic().setId(2).setName("Readability").setParentId(1));
-
- MockUserSession.set();
- WsTester.TestRequest request = tester.newRequest("show").setParam("key", issue.key());
- request.execute().assertJson(getClass(), "show_issue_with_characteristics.json");
- }
-
- @Test
- public void use_user_characteristic_if_both_characteristic_ids_are_defined() throws Exception {
- Issue issue = createStandardIssue().setDebt(Duration.create(7260L));
- issues.add(issue);
-
- result.rule(issue).setCharacteristicId(2);
- when(debtModel.characteristicById(1)).thenReturn(new DefaultDebtCharacteristic().setId(1).setName("Maintainability"));
- when(debtModel.characteristicById(2)).thenReturn(new DefaultDebtCharacteristic().setId(2).setName("Readability").setParentId(1));
-
- result.rule(issue).setDefaultCharacteristicId(20);
- when(debtModel.characteristicById(10)).thenReturn(new DefaultDebtCharacteristic().setId(10).setName("Default Maintainability"));
- when(debtModel.characteristicById(20)).thenReturn(new DefaultDebtCharacteristic().setId(20).setName("Default Readability").setParentId(10));
-
- MockUserSession.set();
- WsTester.TestRequest request = tester.newRequest("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");
-
- Issue issue = createStandardIssue()
- .setCreationDate(creationDate)
- .setUpdateDate(updateDate)
- .setCloseDate(closedDate);
- issues.add(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");
-
- MockUserSession.set();
- WsTester.TestRequest request = tester.newRequest("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");
-
- Issue issue = createStandardIssue()
- .addComment(
- new DefaultIssueComment()
- .setKey("COMMENT-ABCD")
- .setMarkdownText("*My comment*")
- .setUserLogin("john")
- .setCreatedAt(date1))
- .addComment(
- new DefaultIssueComment()
- .setKey("COMMENT-ABCE")
- .setMarkdownText("Another comment")
- .setUserLogin("arthur")
- .setCreatedAt(date2)
- );
- issues.add(issue);
- result.addUsers(Lists.<User>newArrayList(
- new DefaultUser().setLogin("john").setName("John"),
- 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");
-
- MockUserSession.set().setLogin("arthur");
- WsTester.TestRequest request = tester.newRequest("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");
- issues.add(issue);
-
- when(issueService.listTransitions(eq(issue), any(UserSession.class))).thenReturn(newArrayList(Transition.create("reopen", "RESOLVED", "REOPEN")));
-
- MockUserSession.set().setLogin("john");
- WsTester.TestRequest request = tester.newRequest("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");
- issues.add(issue);
-
- MockUserSession.set().setLogin("john");
- WsTester.TestRequest request = tester.newRequest("show").setParam("key", issue.key());
- request.execute().assertJson(getClass(), "show_issue_with_actions.json");
- }
-
- @Test
- public void show_issue_with_set_severity_action() throws Exception {
- DefaultIssue issue = createStandardIssue()
- .setStatus("OPEN");
- issues.add(issue);
-
- MockUserSession.set().setLogin("john").addProjectPermissions(UserRole.ISSUE_ADMIN, issue.projectKey());
- WsTester.TestRequest request = tester.newRequest("show").setParam("key", issue.key());
- request.execute().assertJson(getClass(), "show_issue_with_set_severity_action.json");
- }
-
- @Test
- public void show_issue_with_assign_to_me_action() throws Exception {
- DefaultIssue issue = createStandardIssue()
- .setStatus("OPEN");
- issues.add(issue);
-
- MockUserSession.set().setLogin("john");
- WsTester.TestRequest request = tester.newRequest("show").setParam("key", issue.key());
- request.execute().assertJson(getClass(), "show_issue_with_assign_to_me_action.json");
- }
-
- @Test
- public void show_issue_without_assign_to_me_action() throws Exception {
- DefaultIssue issue = createStandardIssue()
- .setStatus("OPEN")
- .setAssignee("john");
- issues.add(issue);
-
- result.addUsers(Lists.<User>newArrayList(
- new DefaultUser().setLogin("john").setName("John")
- ));
-
- MockUserSession.set().setLogin("john");
- WsTester.TestRequest request = tester.newRequest("show").setParam("key", issue.key());
- request.execute().assertJson(getClass(), "show_issue_without_assign_to_me_action.json");
- }
-
- @Test
- public void show_issue_with_actions_defined_by_plugins() throws Exception {
- Issue issue = createStandardIssue()
- .setStatus("OPEN");
- issues.add(issue);
-
- Action action = mock(Action.class);
- when(action.key()).thenReturn("link-to-jira");
- when(actionService.listAvailableActions(issue)).thenReturn(newArrayList(action));
-
- MockUserSession.set().setLogin("john");
- WsTester.TestRequest request = tester.newRequest("show").setParam("key", issue.key());
- request.execute().assertJson(getClass(), "show_issue_with_actions_defined_by_plugins.json");
- }
-
- @Test
- public void show_issue_with_changelog() throws Exception {
- Issue issue = createStandardIssue();
- issues.add(issue);
-
- Date date1 = DateUtils.parseDateTime("2014-02-22T19:10:03+0100");
- Date date2 = DateUtils.parseDateTime("2014-02-23T19:10:03+0100");
-
- List<User> users = Lists.<User>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");
-
- MockUserSession.set();
- WsTester.TestRequest request = tester.newRequest("show").setParam("key", issue.key());
- request.execute().assertJson(getClass(), "show_issue_with_changelog.json");
- }
-
- private DefaultIssue createStandardIssue() {
- DefaultIssue issue = createIssue();
- addComponentAndProject();
- return issue;
- }
-
- private DefaultIssue createIssue() {
- return new DefaultIssue()
- .setKey("ABCD")
- .setComponentKey("org.sonar.server.issue.IssueClient")
- .setProjectKey("org.sonar.Sonar")
- .setRuleKey(RuleKey.of("squid", "AvoidCycle"))
- .setCreationDate(issue_creation_date);
- }
-
- private void addComponentAndProject() {
- result.addComponents(Lists.<Component>newArrayList(new ComponentDto()
- .setId(10L)
- .setKey("org.sonar.server.issue.IssueClient")
- .setLongName("SonarQube :: Issue Client")
- .setQualifier("FIL")
- .setSubProjectId(1L)
- .setProjectId(1L)
- ));
-
- result.addComponents(Lists.<Component>newArrayList(new ComponentDto()
- .setId(1L)
- .setKey("org.sonar.Sonar")
- .setLongName("SonarQube")
- .setProjectId(1L)
- ));
- }
-
-}
package org.sonar.server.issue.ws;
import org.junit.Test;
+import org.sonar.api.i18n.I18n;
+import org.sonar.api.issue.IssueFinder;
+import org.sonar.api.server.ws.RailsHandler;
import org.sonar.api.server.ws.WebService;
+import org.sonar.api.utils.Durations;
+import org.sonar.server.debt.DebtModelService;
+import org.sonar.server.issue.ActionService;
+import org.sonar.server.issue.IssueChangelogService;
+import org.sonar.server.issue.IssueService;
import org.sonar.server.ws.WsTester;
import static org.fest.assertions.Assertions.assertThat;
import static org.mockito.Mockito.mock;
-
public class IssuesWsTest {
- IssueShowWsHandler showHandler = mock(IssueShowWsHandler.class);
- WsTester tester = new WsTester(new IssuesWs(showHandler));
+ IssueShowAction showAction = new IssueShowAction(mock(IssueFinder.class), mock(IssueService.class), mock(IssueChangelogService.class), mock(ActionService.class),
+ mock(DebtModelService.class), mock(I18n.class), mock(Durations.class));
+ WsTester tester = new WsTester(new IssuesWs(showAction));
@Test
- public void define_ws() throws Exception {
+ public void define_controller() throws Exception {
WebService.Controller controller = tester.controller("api/issues");
assertThat(controller).isNotNull();
assertThat(controller.description()).isNotEmpty();
+ assertThat(controller.since()).isEqualTo("3.6");
+ assertThat(controller.actions()).hasSize(2);
+ }
+
+ @Test
+ public void define_show_action() throws Exception {
+ WebService.Controller controller = tester.controller("api/issues");
WebService.Action show = controller.action("show");
assertThat(show).isNotNull();
assertThat(show.since()).isEqualTo("4.2");
assertThat(show.isPost()).isFalse();
assertThat(show.isInternal()).isTrue();
- assertThat(show.handler()).isSameAs(showHandler);
+ assertThat(show.handler()).isSameAs(showAction);
+
+ WebService.Param key = show.param("key");
+ assertThat(key).isNotNull();
+ assertThat(key.description()).isNotNull();
+ assertThat(key.isRequired()).isFalse();
+ }
+
+ @Test
+ public void define_search_action() throws Exception {
+ WebService.Controller controller = tester.controller("api/issues");
+
+ WebService.Action show = controller.action("search");
+ assertThat(show).isNotNull();
+ assertThat(show.handler()).isNotNull();
+ assertThat(show.since()).isEqualTo("3.6");
+ assertThat(show.isPost()).isFalse();
+ assertThat(show.isInternal()).isFalse();
+ assertThat(show.handler()).isInstanceOf(RailsHandler.class);
+ assertThat(show.params()).hasSize(2);
}
}
WebService.Action show = controller.action("show");
assertThat(show).isNotNull();
- assertThat(show.handler()).isNotNull();
- assertThat(show.since()).isEqualTo("4.2");
- assertThat(show.isPost()).isFalse();
assertThat(show.handler()).isSameAs(showAction);
+ assertThat(show.params()).hasSize(5);
+
+ WebService.Action scm = controller.action("scm");
+ assertThat(scm).isNotNull();
+ assertThat(scm.handler()).isSameAs(scmAction);
+ assertThat(scm.params()).hasSize(4);
}
}
*/
package org.sonar.server.ws;
+import com.google.common.io.Resources;
import org.junit.Test;
import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.RequestHandler;
.setSince("4.1")
.setPost(true)
.setInternal(true)
- .setResponseExample(getClass().getResource("/org/sonar/server/ws/ListingWsTest/metrics_example.json"))
+ .setResponseExample(Resources.getResource(getClass(), "ListingWsTest/metrics_example.json"))
.setHandler(new RequestHandler() {
@Override
public void handle(Request request, Response response) {
--- /dev/null
+{
+ "canManageFilters": false,
+ "canBulkChange": false
+}
--- /dev/null
+{
+ "canManageFilters": true,
+ "canBulkChange": true,
+ "favorites": []
+}
--- /dev/null
+{
+ "canManageFilters": true,
+ "canBulkChange": true,
+ "favorites": [
+ {
+ "id": 6,
+ "name": "My issues"
+ },
+ {
+ "id": 13,
+ "name": "Blocker issues"
+ }
+ ]
+}
--- /dev/null
+{
+ "canManageFilters": true,
+ "canBulkChange": true,
+ "filter": {
+ "id": 13,
+ "name": "Blocker issues",
+ "shared": false,
+ "query": "severity=BLOCKER",
+ "user": "eric",
+ "canModify": true
+ },
+ "favorites": [
+ ]
+}
--- /dev/null
+{
+ "canManageFilters": true,
+ "canBulkChange": true,
+ "filter": {
+ "id": 13,
+ "name": "Blocker issues",
+ "shared": true,
+ "query": "severity=BLOCKER",
+ "user": "simon",
+ "canModify": false
+ },
+ "favorites": [
+ ]
+}
+++ /dev/null
-{
- "canManageFilters": false,
- "canBulkChange": false
-}
+++ /dev/null
-{
- "canManageFilters": true,
- "canBulkChange": true,
- "favorites": []
-}
+++ /dev/null
-{
- "canManageFilters": true,
- "canBulkChange": true,
- "favorites": [
- {
- "id": 6,
- "name": "My issues"
- },
- {
- "id": 13,
- "name": "Blocker issues"
- }
- ]
-}
+++ /dev/null
-{
- "canManageFilters": true,
- "canBulkChange": true,
- "filter": {
- "id": 13,
- "name": "Blocker issues",
- "shared": false,
- "query": "severity=BLOCKER",
- "user": "eric",
- "canModify": true
- },
- "favorites": [
- ]
-}
+++ /dev/null
-{
- "canManageFilters": true,
- "canBulkChange": true,
- "filter": {
- "id": 13,
- "name": "Blocker issues",
- "shared": true,
- "query": "severity=BLOCKER",
- "user": "simon",
- "canModify": false
- },
- "favorites": [
- ]
-}
+++ /dev/null
-{
- "filter": {
- "id": 13,
- "name": "Blocker issues",
- "description": "All Blocker Issues",
- "shared": true,
- "query": "severity=BLOCKER",
- "user": "simon",
- "canModify": false
- }
-}
--- /dev/null
+{
+ "filter": {
+ "id": 13,
+ "name": "Blocker issues",
+ "description": "All Blocker Issues",
+ "shared": true,
+ "query": "severity=BLOCKER",
+ "user": "simon",
+ "canModify": false
+ }
+}
--- /dev/null
+{
+ "issue": {
+ "key": "ABCD",
+ "component": "org.sonar.server.issue.IssueClient",
+ "componentLongName": "SonarQube :: Issue Client",
+ "componentQualifier": "FIL",
+ "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"]
+ }
+ ]
+ }
+}
--- /dev/null
+{
+ "issue": {
+ "key": "ABCD",
+ "component": "org.sonar.server.issue.IssueClient",
+ "project": "org.sonar.Sonar",
+ "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"]
+ }
+ ]
+ }
+}
--- /dev/null
+{
+ "issue": {
+ "key": "ABCD",
+ "component": "org.sonar.server.issue.IssueClient",
+ "project": "org.sonar.Sonar",
+ "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"]
+ }
+ ]
+ }
+}
--- /dev/null
+{
+ "issue": {
+ "key": "ABCD",
+ "component": "org.sonar.server.issue.IssueClient",
+ "componentLongName": "SonarQube :: Issue Client",
+ "componentQualifier": "FIL",
+ "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"]
+ }
+ ]
+ }
+}
--- /dev/null
+{
+ "issue": {
+ "key": "ABCD",
+ "component": "org.sonar.server.issue.IssueClient",
+ "componentLongName": "SonarQube :: Issue Client",
+ "componentQualifier": "FIL",
+ "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", "assign_to_me", "plan"
+ ],
+ "comments": [],
+ "changelog": [
+ {
+ "creationDate": "2014-01-22T19:10:03+0100",
+ "fCreationDate": "Jan 22, 2014 10:03 AM",
+ "diffs": ["Created"]
+ }
+ ]
+ }
+}
--- /dev/null
+{
+ "issue": {
+ "key": "ABCD",
+ "component": "org.sonar.server.issue.IssueClient",
+ "componentLongName": "SonarQube :: Issue Client",
+ "componentQualifier": "FIL",
+ "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", "assign_to_me", "plan", "link-to-jira"
+ ],
+ "comments": [],
+ "changelog": [
+ {
+ "creationDate": "2014-01-22T19:10:03+0100",
+ "fCreationDate": "Jan 22, 2014 10:03 AM",
+ "diffs": ["Created"]
+ }
+ ]
+ }
+}
--- /dev/null
+{
+ "issue": {
+ "key": "ABCD",
+ "component": "org.sonar.server.issue.IssueClient",
+ "componentLongName": "SonarQube :: Issue Client",
+ "componentQualifier": "FIL",
+ "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", "assign_to_me", "plan"
+ ],
+ "comments": [],
+ "changelog": [
+ {
+ "creationDate": "2014-01-22T19:10:03+0100",
+ "fCreationDate": "Jan 22, 2014 10:03 AM",
+ "diffs": ["Created"]
+ }
+ ]
+ }
+}
--- /dev/null
+{
+ "issue": {
+ "key": "ABCD",
+ "component": "org.sonar.server.issue.IssueClient",
+ "componentLongName": "SonarQube :: Issue Client",
+ "componentQualifier": "FIL",
+ "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"]
+ }
+ ]
+ }
+}
--- /dev/null
+{
+ "issue": {
+ "key": "ABCD",
+ "component": "org.sonar.server.issue.IssueClient",
+ "componentLongName": "SonarQube :: Issue Client",
+ "componentQualifier": "FIL",
+ "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"]
+ }
+ ]
+ }
+}
--- /dev/null
+{
+ "issue": {
+ "key": "ABCD",
+ "component": "org.sonar.server.issue.IssueClient",
+ "componentLongName": "SonarQube :: Issue Client",
+ "componentQualifier": "FIL",
+ "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", "assign_to_me", "plan"],
+ "comments": [
+ {
+ "key": "COMMENT-ABCD",
+ "userName": "John",
+ "raw": "*My comment*",
+ "html": "<em>My comment</em>",
+ "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"]
+ }
+ ]
+ }
+}
--- /dev/null
+{
+ "issue": {
+ "key": "ABCD",
+ "component": "org.sonar.server.issue.IssueClient",
+ "componentLongName": "SonarQube :: Issue Client",
+ "componentQualifier": "FIL",
+ "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"]
+ }
+ ]
+ }
+}
--- /dev/null
+{
+ "issue": {
+ "key": "ABCD",
+ "component": "org.sonar.server.issue.IssueClient",
+ "componentLongName": "SonarQube :: Issue Client",
+ "componentQualifier": "FIL",
+ "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", "assign_to_me", "plan", "set_severity"
+ ],
+ "comments": [],
+ "changelog": [
+ {
+ "creationDate": "2014-01-22T19:10:03+0100",
+ "fCreationDate": "Jan 22, 2014 10:03 AM",
+ "diffs": ["Created"]
+ }
+ ]
+ }
+}
--- /dev/null
+{
+ "issue": {
+ "key": "ABCD",
+ "component": "org.sonar.server.issue.IssueClient",
+ "componentLongName": "SonarQube :: Issue Client",
+ "componentQualifier": "FIL",
+ "project": "org.sonar.Sonar",
+ "projectName": "SonarQube",
+ "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"]
+ }
+ ]
+ }
+}
--- /dev/null
+{
+ "issue": {
+ "key": "ABCD",
+ "component": "org.sonar.server.issue.IssueClient",
+ "componentLongName": "SonarQube :: Issue Client",
+ "componentQualifier": "FIL",
+ "project": "org.sonar.Sonar",
+ "projectName": "SonarQube",
+ "rule": "squid:AvoidCycle",
+ "ruleName": "Avoid cycle",
+ "debt": "2 hours 1 minutes",
+ "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"]
+ }
+ ]
+ }
+}
--- /dev/null
+{
+ "issue": {
+ "key": "ABCD",
+ "component": "org.sonar.server.issue.IssueClient",
+ "componentLongName": "SonarQube :: Issue Client",
+ "componentQualifier": "FIL",
+ "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"]
+ }
+ ]
+ }
+}
--- /dev/null
+{
+ "issue": {
+ "key": "ABCD",
+ "component": "org.sonar.server.issue.IssueClient",
+ "componentLongName": "SonarQube :: Issue Client",
+ "componentQualifier": "FIL",
+ "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"]
+ }
+ ]
+ }
+}
--- /dev/null
+{
+ "issue": {
+ "key": "ABCD",
+ "component": "org.sonar.server.issue.IssueClient",
+ "componentLongName": "SonarQube :: Issue Client",
+ "componentQualifier": "FIL",
+ "project": "org.sonar.Sonar",
+ "projectName": "SonarQube",
+ "rule": "squid:AvoidCycle",
+ "ruleName": "Avoid cycle",
+ "assignee": "john",
+ "assigneeName": "John",
+ "status": "OPEN",
+ "creationDate": "2014-01-22T19:10:03+0100",
+ "fCreationDate": "Jan 22, 2014 10:03 AM",
+ "transitions": [],
+ "actions": [
+ "comment", "assign", "plan"
+ ],
+ "comments": [],
+ "changelog": [
+ {
+ "creationDate": "2014-01-22T19:10:03+0100",
+ "fCreationDate": "Jan 22, 2014 10:03 AM",
+ "diffs": ["Created"]
+ }
+ ]
+ }
+}
+++ /dev/null
-{
- "issue": {
- "key": "ABCD",
- "component": "org.sonar.server.issue.IssueClient",
- "componentLongName": "SonarQube :: Issue Client",
- "componentQualifier": "FIL",
- "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"]
- }
- ]
- }
-}
+++ /dev/null
-{
- "issue": {
- "key": "ABCD",
- "component": "org.sonar.server.issue.IssueClient",
- "project": "org.sonar.Sonar",
- "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"]
- }
- ]
- }
-}
+++ /dev/null
-{
- "issue": {
- "key": "ABCD",
- "component": "org.sonar.server.issue.IssueClient",
- "project": "org.sonar.Sonar",
- "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"]
- }
- ]
- }
-}
+++ /dev/null
-{
- "issue": {
- "key": "ABCD",
- "component": "org.sonar.server.issue.IssueClient",
- "componentLongName": "SonarQube :: Issue Client",
- "componentQualifier": "FIL",
- "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"]
- }
- ]
- }
-}
+++ /dev/null
-{
- "issue": {
- "key": "ABCD",
- "component": "org.sonar.server.issue.IssueClient",
- "componentLongName": "SonarQube :: Issue Client",
- "componentQualifier": "FIL",
- "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", "assign_to_me", "plan"
- ],
- "comments": [],
- "changelog": [
- {
- "creationDate": "2014-01-22T19:10:03+0100",
- "fCreationDate": "Jan 22, 2014 10:03 AM",
- "diffs": ["Created"]
- }
- ]
- }
-}
+++ /dev/null
-{
- "issue": {
- "key": "ABCD",
- "component": "org.sonar.server.issue.IssueClient",
- "componentLongName": "SonarQube :: Issue Client",
- "componentQualifier": "FIL",
- "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", "assign_to_me", "plan", "link-to-jira"
- ],
- "comments": [],
- "changelog": [
- {
- "creationDate": "2014-01-22T19:10:03+0100",
- "fCreationDate": "Jan 22, 2014 10:03 AM",
- "diffs": ["Created"]
- }
- ]
- }
-}
+++ /dev/null
-{
- "issue": {
- "key": "ABCD",
- "component": "org.sonar.server.issue.IssueClient",
- "componentLongName": "SonarQube :: Issue Client",
- "componentQualifier": "FIL",
- "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", "assign_to_me", "plan"
- ],
- "comments": [],
- "changelog": [
- {
- "creationDate": "2014-01-22T19:10:03+0100",
- "fCreationDate": "Jan 22, 2014 10:03 AM",
- "diffs": ["Created"]
- }
- ]
- }
-}
+++ /dev/null
-{
- "issue": {
- "key": "ABCD",
- "component": "org.sonar.server.issue.IssueClient",
- "componentLongName": "SonarQube :: Issue Client",
- "componentQualifier": "FIL",
- "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"]
- }
- ]
- }
-}
+++ /dev/null
-{
- "issue": {
- "key": "ABCD",
- "component": "org.sonar.server.issue.IssueClient",
- "componentLongName": "SonarQube :: Issue Client",
- "componentQualifier": "FIL",
- "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"]
- }
- ]
- }
-}
+++ /dev/null
-{
- "issue": {
- "key": "ABCD",
- "component": "org.sonar.server.issue.IssueClient",
- "componentLongName": "SonarQube :: Issue Client",
- "componentQualifier": "FIL",
- "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", "assign_to_me", "plan"],
- "comments": [
- {
- "key": "COMMENT-ABCD",
- "userName": "John",
- "raw": "*My comment*",
- "html": "<em>My comment</em>",
- "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"]
- }
- ]
- }
-}
+++ /dev/null
-{
- "issue": {
- "key": "ABCD",
- "component": "org.sonar.server.issue.IssueClient",
- "componentLongName": "SonarQube :: Issue Client",
- "componentQualifier": "FIL",
- "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"]
- }
- ]
- }
-}
+++ /dev/null
-{
- "issue": {
- "key": "ABCD",
- "component": "org.sonar.server.issue.IssueClient",
- "componentLongName": "SonarQube :: Issue Client",
- "componentQualifier": "FIL",
- "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", "assign_to_me", "plan", "set_severity"
- ],
- "comments": [],
- "changelog": [
- {
- "creationDate": "2014-01-22T19:10:03+0100",
- "fCreationDate": "Jan 22, 2014 10:03 AM",
- "diffs": ["Created"]
- }
- ]
- }
-}
+++ /dev/null
-{
- "issue": {
- "key": "ABCD",
- "component": "org.sonar.server.issue.IssueClient",
- "componentLongName": "SonarQube :: Issue Client",
- "componentQualifier": "FIL",
- "project": "org.sonar.Sonar",
- "projectName": "SonarQube",
- "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"]
- }
- ]
- }
-}
+++ /dev/null
-{
- "issue": {
- "key": "ABCD",
- "component": "org.sonar.server.issue.IssueClient",
- "componentLongName": "SonarQube :: Issue Client",
- "componentQualifier": "FIL",
- "project": "org.sonar.Sonar",
- "projectName": "SonarQube",
- "rule": "squid:AvoidCycle",
- "ruleName": "Avoid cycle",
- "debt": "2 hours 1 minutes",
- "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"]
- }
- ]
- }
-}
+++ /dev/null
-{
- "issue": {
- "key": "ABCD",
- "component": "org.sonar.server.issue.IssueClient",
- "componentLongName": "SonarQube :: Issue Client",
- "componentQualifier": "FIL",
- "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"]
- }
- ]
- }
-}
+++ /dev/null
-{
- "issue": {
- "key": "ABCD",
- "component": "org.sonar.server.issue.IssueClient",
- "componentLongName": "SonarQube :: Issue Client",
- "componentQualifier": "FIL",
- "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"]
- }
- ]
- }
-}
+++ /dev/null
-{
- "issue": {
- "key": "ABCD",
- "component": "org.sonar.server.issue.IssueClient",
- "componentLongName": "SonarQube :: Issue Client",
- "componentQualifier": "FIL",
- "project": "org.sonar.Sonar",
- "projectName": "SonarQube",
- "rule": "squid:AvoidCycle",
- "ruleName": "Avoid cycle",
- "assignee": "john",
- "assigneeName": "John",
- "status": "OPEN",
- "creationDate": "2014-01-22T19:10:03+0100",
- "fCreationDate": "Jan 22, 2014 10:03 AM",
- "transitions": [],
- "actions": [
- "comment", "assign", "plan"
- ],
- "comments": [],
- "changelog": [
- {
- "creationDate": "2014-01-22T19:10:03+0100",
- "fCreationDate": "Jan 22, 2014 10:03 AM",
- "diffs": ["Created"]
- }
- ]
- }
-}