aboutsummaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
authorTeryk Bellahsene <teryk.bellahsene@sonarsource.com>2017-05-12 12:37:11 +0200
committerTeryk Bellahsene <teryk.bellahsene@sonarsource.com>2017-05-12 17:48:36 +0200
commit44bb86905beb8652719b777ec45befc9d325af01 (patch)
tree3ce300b306d3b67f0d1e605b127db0f9c804cfd2 /server
parent2128feb694eeeada2b33fd8772e70cbeb44ed4b8 (diff)
downloadsonarqube-44bb86905beb8652719b777ec45befc9d325af01.tar.gz
sonarqube-44bb86905beb8652719b777ec45befc9d325af01.zip
SONAR-3915 Give the admin a way to send users issue reports on non favorite projects
Diffstat (limited to 'server')
-rw-r--r--server/sonar-db-dao/src/test/java/org/sonar/db/notification/NotificationDbTester.java4
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/notification/NotificationUpdater.java32
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/notification/ws/AddAction.java101
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/notification/ws/ListAction.java65
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/notification/ws/RemoveAction.java95
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/notification/ws/AddActionTest.java42
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/notification/ws/ListActionTest.java100
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/notification/ws/RemoveActionTest.java74
8 files changed, 339 insertions, 174 deletions
diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/notification/NotificationDbTester.java b/server/sonar-db-dao/src/test/java/org/sonar/db/notification/NotificationDbTester.java
index 43fbcbb14fd..778019eba87 100644
--- a/server/sonar-db-dao/src/test/java/org/sonar/db/notification/NotificationDbTester.java
+++ b/server/sonar-db-dao/src/test/java/org/sonar/db/notification/NotificationDbTester.java
@@ -48,7 +48,7 @@ public class NotificationDbTester {
List<PropertyDto> result = dbClient.propertiesDao().selectByQuery(PropertyQuery.builder()
.setKey(String.join(".", PROP_NOTIFICATION_PREFIX, dispatcher, channel))
.setComponentId(component == null ? null : component.getId())
- .setUserId((int) userId)
+ .setUserId(userId)
.build(), dbSession).stream()
.filter(prop -> component == null ? prop.getResourceId() == null : prop.getResourceId() != null)
.collect(MoreCollectors.toList());
@@ -60,7 +60,7 @@ public class NotificationDbTester {
List<PropertyDto> result = dbClient.propertiesDao().selectByQuery(PropertyQuery.builder()
.setKey(String.join(".", PROP_NOTIFICATION_PREFIX, dispatcher, channel))
.setComponentId(component == null ? null : component.getId())
- .setUserId((int) userId)
+ .setUserId(userId)
.build(), dbSession);
assertThat(result).isEmpty();
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/notification/NotificationUpdater.java b/server/sonar-server/src/main/java/org/sonar/server/notification/NotificationUpdater.java
index 3df6ce3c812..8ae948cc9c0 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/notification/NotificationUpdater.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/notification/NotificationUpdater.java
@@ -28,7 +28,7 @@ import org.sonar.db.DbSession;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.property.PropertyDto;
import org.sonar.db.property.PropertyQuery;
-import org.sonar.server.user.UserSession;
+import org.sonar.db.user.UserDto;
import static com.google.common.base.Preconditions.checkArgument;
@@ -36,23 +36,16 @@ public class NotificationUpdater {
private static final String PROP_NOTIFICATION_PREFIX = "notification";
private static final String PROP_NOTIFICATION_VALUE = "true";
- private final UserSession userSession;
private final DbClient dbClient;
- public NotificationUpdater(UserSession userSession, DbClient dbClient) {
- this.userSession = userSession;
+ public NotificationUpdater(DbClient dbClient) {
this.dbClient = dbClient;
}
/**
- * Add a notification to the current authenticated user.
- * Does nothing if the user is not authenticated.
+ * Add a notification to a user.
*/
- public void add(DbSession dbSession, String channel, String dispatcher, @Nullable ComponentDto project) {
- if (!userSession.isLoggedIn()) {
- return;
- }
-
+ public void add(DbSession dbSession, String channel, String dispatcher, UserDto user, @Nullable ComponentDto project) {
String key = String.join(".", PROP_NOTIFICATION_PREFIX, dispatcher, channel);
Long projectId = project == null ? null : project.getId();
@@ -60,7 +53,7 @@ public class NotificationUpdater {
PropertyQuery.builder()
.setKey(key)
.setComponentId(projectId)
- .setUserId(userSession.getUserId())
+ .setUserId(user.getId())
.build(),
dbSession).stream()
.filter(notificationScope(project))
@@ -70,20 +63,15 @@ public class NotificationUpdater {
dbClient.propertiesDao().saveProperty(dbSession, new PropertyDto()
.setKey(key)
- .setUserId(userSession.getUserId())
+ .setUserId(user.getId())
.setValue(PROP_NOTIFICATION_VALUE)
.setResourceId(projectId));
}
/**
- * Remove a notification to the current authenticated user.
- * Does nothing if the user is not authenticated.
+ * Remove a notification from a user.
*/
- public void remove(DbSession dbSession, String channel, String dispatcher, @Nullable ComponentDto project) {
- if (!userSession.isLoggedIn()) {
- return;
- }
-
+ public void remove(DbSession dbSession, String channel, String dispatcher, UserDto user, @Nullable ComponentDto project) {
String key = String.join(".", PROP_NOTIFICATION_PREFIX, dispatcher, channel);
Long projectId = project == null ? null : project.getId();
@@ -91,7 +79,7 @@ public class NotificationUpdater {
PropertyQuery.builder()
.setKey(key)
.setComponentId(projectId)
- .setUserId(userSession.getUserId())
+ .setUserId(user.getId())
.build(),
dbSession).stream()
.filter(notificationScope(project))
@@ -100,7 +88,7 @@ public class NotificationUpdater {
dbClient.propertiesDao().delete(dbSession, new PropertyDto()
.setKey(key)
- .setUserId(userSession.getUserId())
+ .setUserId(user.getId())
.setValue(PROP_NOTIFICATION_VALUE)
.setResourceId(projectId));
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/notification/ws/AddAction.java b/server/sonar-server/src/main/java/org/sonar/server/notification/ws/AddAction.java
index 921387991bd..51685ce0c1f 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/notification/ws/AddAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/notification/ws/AddAction.java
@@ -21,9 +21,7 @@ package org.sonar.server.notification.ws;
import java.util.List;
import java.util.Optional;
-import java.util.function.Consumer;
-import java.util.function.Function;
-import java.util.stream.Stream;
+import javax.annotation.CheckForNull;
import org.sonar.api.notifications.NotificationChannel;
import org.sonar.api.resources.Qualifiers;
import org.sonar.api.resources.Scopes;
@@ -33,6 +31,7 @@ import org.sonar.api.server.ws.WebService;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.component.ComponentDto;
+import org.sonar.db.user.UserDto;
import org.sonar.server.component.ComponentFinder;
import org.sonar.server.issue.notification.MyNewIssuesNotificationDispatcher;
import org.sonar.server.notification.NotificationCenter;
@@ -47,9 +46,11 @@ import static org.sonar.core.util.Protobuf.setNullable;
import static org.sonar.core.util.stream.MoreCollectors.toList;
import static org.sonar.server.notification.NotificationDispatcherMetadata.GLOBAL_NOTIFICATION;
import static org.sonar.server.notification.NotificationDispatcherMetadata.PER_PROJECT_NOTIFICATION;
+import static org.sonar.server.ws.WsUtils.checkFound;
import static org.sonar.server.ws.WsUtils.checkRequest;
import static org.sonarqube.ws.client.notification.NotificationsWsParameters.ACTION_ADD;
import static org.sonarqube.ws.client.notification.NotificationsWsParameters.PARAM_CHANNEL;
+import static org.sonarqube.ws.client.notification.NotificationsWsParameters.PARAM_LOGIN;
import static org.sonarqube.ws.client.notification.NotificationsWsParameters.PARAM_PROJECT;
import static org.sonarqube.ws.client.notification.NotificationsWsParameters.PARAM_TYPE;
@@ -76,7 +77,11 @@ public class AddAction implements NotificationsWsAction {
public void define(WebService.NewController context) {
WebService.NewAction action = context.createAction(ACTION_ADD)
.setDescription("Add a notification for the authenticated user.<br>" +
- "Requires authentication. If a project is provided, requires the 'Browse' permission on the specified project.")
+ "Requires one of the following permissions:" +
+ "<ul>" +
+ " <li>Authentication if no login is provided. If a project is provided, requires the 'Browse' permission on the specified project.</li>" +
+ " <li>System administration if a login is provided. If a project is provided, requires the 'Browse' permission on the specified project.</li>" +
+ "</ul>")
.setSince("6.3")
.setPost(true)
.setHandler(this);
@@ -101,61 +106,71 @@ public class AddAction implements NotificationsWsAction {
String.join(", ", projectDispatchers))
.setRequired(true)
.setExampleValue(MyNewIssuesNotificationDispatcher.KEY);
+
+ action.createParam(PARAM_LOGIN)
+ .setDescription("User login")
+ .setSince("6.4");
}
@Override
public void handle(Request request, Response response) throws Exception {
- Stream.of(request)
- .map(toWsRequest())
- .peek(checkPermissions())
- .forEach(add());
+ AddRequest addRequest = toWsRequest(request);
+ add(addRequest);
response.noContent();
}
- private Consumer<AddRequest> add() {
- return request -> {
- try (DbSession dbSession = dbClient.openSession(false)) {
- Optional<ComponentDto> project = searchProject(dbSession, request);
- notificationUpdater.add(dbSession, request.getChannel(), request.getType(), project.orElse(null));
- dbSession.commit();
- }
- };
+ private void add(AddRequest request) {
+ try (DbSession dbSession = dbClient.openSession(false)) {
+ checkPermissions(request);
+ UserDto user = getUser(dbSession, request);
+ ComponentDto project = searchProject(dbSession, request);
+ notificationUpdater.add(dbSession, request.getChannel(), request.getType(), user, project);
+ dbSession.commit();
+ }
+ }
+
+ private UserDto getUser(DbSession dbSession, AddRequest request) {
+ String login = request.getLogin() == null ? userSession.getLogin() : request.getLogin();
+ return checkFound(dbClient.userDao().selectByLogin(dbSession, login), "User '%s' not found", login);
}
- private Optional<ComponentDto> searchProject(DbSession dbSession, AddRequest request) {
+ @CheckForNull
+ private ComponentDto searchProject(DbSession dbSession, AddRequest request) {
Optional<ComponentDto> project = request.getProject() == null ? empty() : Optional.of(componentFinder.getByKey(dbSession, request.getProject()));
project.ifPresent(p -> checkRequest(Qualifiers.PROJECT.equals(p.qualifier()) && Scopes.PROJECT.equals(p.scope()),
"Component '%s' must be a project", request.getProject()));
- return project;
+ return project.orElse(null);
}
- private Consumer<AddRequest> checkPermissions() {
- return request -> userSession.checkLoggedIn();
+ private void checkPermissions(AddRequest request) {
+ if (request.getLogin() == null) {
+ userSession.checkLoggedIn();
+ } else {
+ userSession.checkIsSystemAdministrator();
+ }
}
- private Function<Request, AddRequest> toWsRequest() {
- return request -> {
- AddRequest.Builder requestBuilder = AddRequest.builder()
- .setType(request.mandatoryParam(PARAM_TYPE))
- .setChannel(request.mandatoryParam(PARAM_CHANNEL));
- String project = request.param(PARAM_PROJECT);
- setNullable(project, requestBuilder::setProject);
- AddRequest wsRequest = requestBuilder.build();
-
- if (wsRequest.getProject() == null) {
- checkRequest(globalDispatchers.contains(wsRequest.getType()), "Value of parameter '%s' (%s) must be one of: %s",
- PARAM_TYPE,
- wsRequest.getType(),
- globalDispatchers);
- } else {
- checkRequest(projectDispatchers.contains(wsRequest.getType()), "Value of parameter '%s' (%s) must be one of: %s",
- PARAM_TYPE,
- wsRequest.getType(),
- projectDispatchers);
- }
-
- return wsRequest;
- };
+ private AddRequest toWsRequest(Request request) {
+ AddRequest.Builder requestBuilder = AddRequest.builder()
+ .setType(request.mandatoryParam(PARAM_TYPE))
+ .setChannel(request.mandatoryParam(PARAM_CHANNEL));
+ setNullable(request.param(PARAM_PROJECT), requestBuilder::setProject);
+ setNullable(request.param(PARAM_LOGIN), requestBuilder::setLogin);
+ AddRequest wsRequest = requestBuilder.build();
+
+ if (wsRequest.getProject() == null) {
+ checkRequest(globalDispatchers.contains(wsRequest.getType()), "Value of parameter '%s' (%s) must be one of: %s",
+ PARAM_TYPE,
+ wsRequest.getType(),
+ globalDispatchers);
+ } else {
+ checkRequest(projectDispatchers.contains(wsRequest.getType()), "Value of parameter '%s' (%s) must be one of: %s",
+ PARAM_TYPE,
+ wsRequest.getType(),
+ projectDispatchers);
+ }
+
+ return wsRequest;
}
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/notification/ws/ListAction.java b/server/sonar-server/src/main/java/org/sonar/server/notification/ws/ListAction.java
index a24d4c8a37a..b1b634b389c 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/notification/ws/ListAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/notification/ws/ListAction.java
@@ -25,7 +25,6 @@ import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
-import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.UnaryOperator;
@@ -42,6 +41,7 @@ import org.sonar.db.component.ComponentDto;
import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.property.PropertyDto;
import org.sonar.db.property.PropertyQuery;
+import org.sonar.db.user.UserDto;
import org.sonar.server.notification.NotificationCenter;
import org.sonar.server.user.UserSession;
import org.sonarqube.ws.Notifications.ListResponse;
@@ -55,8 +55,10 @@ import static org.sonar.core.util.Protobuf.setNullable;
import static org.sonar.core.util.stream.MoreCollectors.toOneElement;
import static org.sonar.server.notification.NotificationDispatcherMetadata.GLOBAL_NOTIFICATION;
import static org.sonar.server.notification.NotificationDispatcherMetadata.PER_PROJECT_NOTIFICATION;
+import static org.sonar.server.ws.WsUtils.checkFound;
import static org.sonar.server.ws.WsUtils.writeProtobuf;
import static org.sonarqube.ws.client.notification.NotificationsWsParameters.ACTION_LIST;
+import static org.sonarqube.ws.client.notification.NotificationsWsParameters.PARAM_LOGIN;
public class ListAction implements NotificationsWsAction {
private static final Splitter PROPERTY_KEY_SPLITTER = Splitter.on(".");
@@ -77,42 +79,53 @@ public class ListAction implements NotificationsWsAction {
@Override
public void define(WebService.NewController context) {
- context.createAction(ACTION_LIST)
+ WebService.NewAction action = context.createAction(ACTION_LIST)
.setDescription("List notifications of the authenticated user.<br>" +
- "Requires authentication.")
+ "Requires one of the following permissions:" +
+ "<ul>" +
+ " <li>Authentication if no login is provided</li>" +
+ " <li>System administration if a login is provided</li>" +
+ "</ul>")
.setSince("6.3")
.setResponseExample(getClass().getResource("list-example.json"))
.setHandler(this);
+
+ action.createParam(PARAM_LOGIN)
+ .setDescription("User login")
+ .setSince("6.4");
}
@Override
public void handle(Request request, Response response) throws Exception {
- ListResponse listResponse = Stream.of(request)
- .peek(checkPermissions())
- .map(search())
- .collect(toOneElement());
+ ListResponse listResponse = search(request);
writeProtobuf(listResponse, request, response);
}
- private Function<Request, ListResponse> search() {
- return request -> {
- try (DbSession dbSession = dbClient.openSession(false)) {
- return Stream
- .of(ListResponse.newBuilder())
- .map(r -> r.addAllChannels(channels))
- .map(r -> r.addAllGlobalTypes(globalDispatchers))
- .map(r -> r.addAllPerProjectTypes(perProjectDispatchers))
- .map(addNotifications(dbSession))
- .map(ListResponse.Builder::build)
- .collect(toOneElement());
- }
- };
+ private ListResponse search(Request request) {
+ try (DbSession dbSession = dbClient.openSession(false)) {
+ checkPermissions(request);
+ UserDto user = getUser(dbSession, request);
+
+ return Stream
+ .of(ListResponse.newBuilder())
+ .map(r -> r.addAllChannels(channels))
+ .map(r -> r.addAllGlobalTypes(globalDispatchers))
+ .map(r -> r.addAllPerProjectTypes(perProjectDispatchers))
+ .map(addNotifications(dbSession, user))
+ .map(ListResponse.Builder::build)
+ .collect(toOneElement());
+ }
+ }
+
+ private UserDto getUser(DbSession dbSession, Request request) {
+ String login = request.param(PARAM_LOGIN) == null ? userSession.getLogin() : request.param(PARAM_LOGIN);
+ return checkFound(dbClient.userDao().selectByLogin(dbSession, login), "User '%s' not found", login);
}
- private UnaryOperator<ListResponse.Builder> addNotifications(DbSession dbSession) {
+ private UnaryOperator<ListResponse.Builder> addNotifications(DbSession dbSession, UserDto user) {
return response -> {
- List<PropertyDto> properties = dbClient.propertiesDao().selectByQuery(PropertyQuery.builder().setUserId(userSession.getUserId()).build(), dbSession);
+ List<PropertyDto> properties = dbClient.propertiesDao().selectByQuery(PropertyQuery.builder().setUserId(user.getId()).build(), dbSession);
Map<Long, ComponentDto> componentsById = searchProjects(dbSession, properties);
Map<String, OrganizationDto> organizationsByUuid = getOrganizations(dbSession, componentsById.values());
@@ -195,7 +208,11 @@ public class ListAction implements NotificationsWsAction {
.setProjectName(project.name());
}
- private Consumer<Request> checkPermissions() {
- return request -> userSession.checkLoggedIn();
+ private void checkPermissions(Request request) {
+ if (request.param(PARAM_LOGIN) == null) {
+ userSession.checkLoggedIn();
+ } else {
+ userSession.checkIsSystemAdministrator();
+ }
}
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/notification/ws/RemoveAction.java b/server/sonar-server/src/main/java/org/sonar/server/notification/ws/RemoveAction.java
index 573f2a7df62..e44841a5bde 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/notification/ws/RemoveAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/notification/ws/RemoveAction.java
@@ -21,10 +21,7 @@ package org.sonar.server.notification.ws;
import java.util.List;
import java.util.Optional;
-import java.util.function.Consumer;
-import java.util.function.Function;
import java.util.stream.Collectors;
-import java.util.stream.Stream;
import org.sonar.api.notifications.NotificationChannel;
import org.sonar.api.resources.Qualifiers;
import org.sonar.api.resources.Scopes;
@@ -34,6 +31,7 @@ import org.sonar.api.server.ws.WebService;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.component.ComponentDto;
+import org.sonar.db.user.UserDto;
import org.sonar.server.component.ComponentFinder;
import org.sonar.server.issue.notification.MyNewIssuesNotificationDispatcher;
import org.sonar.server.notification.NotificationCenter;
@@ -47,9 +45,11 @@ import static java.util.Optional.empty;
import static org.sonar.core.util.Protobuf.setNullable;
import static org.sonar.server.notification.NotificationDispatcherMetadata.GLOBAL_NOTIFICATION;
import static org.sonar.server.notification.NotificationDispatcherMetadata.PER_PROJECT_NOTIFICATION;
+import static org.sonar.server.ws.WsUtils.checkFound;
import static org.sonar.server.ws.WsUtils.checkRequest;
import static org.sonarqube.ws.client.notification.NotificationsWsParameters.ACTION_REMOVE;
import static org.sonarqube.ws.client.notification.NotificationsWsParameters.PARAM_CHANNEL;
+import static org.sonarqube.ws.client.notification.NotificationsWsParameters.PARAM_LOGIN;
import static org.sonarqube.ws.client.notification.NotificationsWsParameters.PARAM_PROJECT;
import static org.sonarqube.ws.client.notification.NotificationsWsParameters.PARAM_TYPE;
@@ -76,7 +76,11 @@ public class RemoveAction implements NotificationsWsAction {
public void define(WebService.NewController context) {
WebService.NewAction action = context.createAction(ACTION_REMOVE)
.setDescription("Remove a notification for the authenticated user.<br>" +
- "Requires authentication. If a project is provided, requires the 'Browse' permission on the specified project.")
+ "Requires one of the following permissions:" +
+ "<ul>" +
+ " <li>Authentication if no login is provided</li>" +
+ " <li>System administration if a login is provided</li>" +
+ "</ul>")
.setSince("6.3")
.setPost(true)
.setHandler(this);
@@ -101,26 +105,33 @@ public class RemoveAction implements NotificationsWsAction {
projectDispatchers.stream().sorted().collect(Collectors.joining(", ")))
.setRequired(true)
.setExampleValue(MyNewIssuesNotificationDispatcher.KEY);
+
+ action.createParam(PARAM_LOGIN)
+ .setDescription("User login")
+ .setSince("6.4");
}
@Override
public void handle(Request request, Response response) throws Exception {
- Stream.of(request)
- .map(toWsRequest())
- .peek(checkPermissions())
- .forEach(remove());
+ RemoveRequest removeRequest = toWsRequest(request);
+ remove(removeRequest);
response.noContent();
}
- private Consumer<RemoveRequest> remove() {
- return request -> {
- try (DbSession dbSession = dbClient.openSession(false)) {
- Optional<ComponentDto> project = searchProject(dbSession, request);
- notificationUpdater.remove(dbSession, request.getChannel(), request.getType(), project.orElse(null));
- dbSession.commit();
- }
- };
+ private void remove(RemoveRequest request) {
+ try (DbSession dbSession = dbClient.openSession(false)) {
+ checkPermissions(request);
+ UserDto user = getUser(dbSession, request);
+ Optional<ComponentDto> project = searchProject(dbSession, request);
+ notificationUpdater.remove(dbSession, request.getChannel(), request.getType(), user, project.orElse(null));
+ dbSession.commit();
+ }
+ }
+
+ private UserDto getUser(DbSession dbSession, RemoveRequest request) {
+ String login = request.getLogin() == null ? userSession.getLogin() : request.getLogin();
+ return checkFound(dbClient.userDao().selectByLogin(dbSession, login), "User '%s' not found", login);
}
private Optional<ComponentDto> searchProject(DbSession dbSession, RemoveRequest request) {
@@ -130,32 +141,34 @@ public class RemoveAction implements NotificationsWsAction {
return project;
}
- private Consumer<RemoveRequest> checkPermissions() {
- return request -> userSession.checkLoggedIn();
+ private void checkPermissions(RemoveRequest request) {
+ if (request.getLogin() == null) {
+ userSession.checkLoggedIn();
+ } else {
+ userSession.checkIsSystemAdministrator();
+ }
}
- private Function<Request, RemoveRequest> toWsRequest() {
- return request -> {
- RemoveRequest.Builder requestBuilder = RemoveRequest.builder()
- .setType(request.mandatoryParam(PARAM_TYPE))
- .setChannel(request.mandatoryParam(PARAM_CHANNEL));
- String project = request.param(PARAM_PROJECT);
- setNullable(project, requestBuilder::setProject);
- RemoveRequest wsRequest = requestBuilder.build();
-
- if (wsRequest.getProject() == null) {
- checkRequest(globalDispatchers.contains(wsRequest.getType()), "Value of parameter '%s' (%s) must be one of: %s",
- PARAM_TYPE,
- wsRequest.getType(),
- globalDispatchers);
- } else {
- checkRequest(projectDispatchers.contains(wsRequest.getType()), "Value of parameter '%s' (%s) must be one of: %s",
- PARAM_TYPE,
- wsRequest.getType(),
- projectDispatchers);
- }
-
- return wsRequest;
- };
+ private RemoveRequest toWsRequest(Request request) {
+ RemoveRequest.Builder requestBuilder = RemoveRequest.builder()
+ .setType(request.mandatoryParam(PARAM_TYPE))
+ .setChannel(request.mandatoryParam(PARAM_CHANNEL));
+ setNullable(request.param(PARAM_PROJECT), requestBuilder::setProject);
+ setNullable(request.param(PARAM_LOGIN), requestBuilder::setLogin);
+ RemoveRequest wsRequest = requestBuilder.build();
+
+ if (wsRequest.getProject() == null) {
+ checkRequest(globalDispatchers.contains(wsRequest.getType()), "Value of parameter '%s' (%s) must be one of: %s",
+ PARAM_TYPE,
+ wsRequest.getType(),
+ globalDispatchers);
+ } else {
+ checkRequest(projectDispatchers.contains(wsRequest.getType()), "Value of parameter '%s' (%s) must be one of: %s",
+ PARAM_TYPE,
+ wsRequest.getType(),
+ projectDispatchers);
+ }
+
+ return wsRequest;
}
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/notification/ws/AddActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/notification/ws/AddActionTest.java
index 99b06b03cfa..3cc9e0de99f 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/notification/ws/AddActionTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/notification/ws/AddActionTest.java
@@ -28,8 +28,10 @@ import org.sonar.api.notifications.NotificationChannel;
import org.sonar.db.DbClient;
import org.sonar.db.DbTester;
import org.sonar.db.component.ComponentDto;
+import org.sonar.db.user.UserDto;
import org.sonar.server.component.ComponentFinder;
import org.sonar.server.exceptions.BadRequestException;
+import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.exceptions.NotFoundException;
import org.sonar.server.exceptions.UnauthorizedException;
import org.sonar.server.notification.NotificationCenter;
@@ -48,6 +50,7 @@ import static org.sonar.db.component.ComponentTesting.newView;
import static org.sonar.server.notification.NotificationDispatcherMetadata.GLOBAL_NOTIFICATION;
import static org.sonar.server.notification.NotificationDispatcherMetadata.PER_PROJECT_NOTIFICATION;
import static org.sonarqube.ws.client.notification.NotificationsWsParameters.PARAM_CHANNEL;
+import static org.sonarqube.ws.client.notification.NotificationsWsParameters.PARAM_LOGIN;
import static org.sonarqube.ws.client.notification.NotificationsWsParameters.PARAM_PROJECT;
import static org.sonarqube.ws.client.notification.NotificationsWsParameters.PARAM_TYPE;
@@ -55,10 +58,11 @@ public class AddActionTest {
private static final String NOTIF_MY_NEW_ISSUES = "Dispatcher1";
private static final String NOTIF_NEW_ISSUES = "Dispatcher2";
private static final String NOTIF_NEW_QUALITY_GATE_STATUS = "Dispatcher3";
+ private static final String USER_LOGIN = "george.orwell";
@Rule
public ExpectedException expectedException = ExpectedException.none();
@Rule
- public UserSessionRule userSession = UserSessionRule.standalone().logIn().setUserId(123);
+ public UserSessionRule userSession;
@Rule
public DbTester db = DbTester.create();
private DbClient dbClient = db.getDbClient();
@@ -68,6 +72,8 @@ public class AddActionTest {
// default channel, based on class simple name
private NotificationChannel defaultChannel = new FakeNotificationChannel("EmailNotificationChannel");
+ private UserDto user;
+
private NotificationCenter notificationCenter;
private AddAction underTest;
private WsActionTester ws;
@@ -86,10 +92,13 @@ public class AddActionTest {
.setProperty(GLOBAL_NOTIFICATION, "true")
.setProperty(PER_PROJECT_NOTIFICATION, "true");
+ user = db.users().insertUser(USER_LOGIN);
+ userSession = UserSessionRule.standalone().logIn(user);
+
notificationCenter = new NotificationCenter(
new NotificationDispatcherMetadata[] {metadata1, metadata2, metadata3},
new NotificationChannel[] {emailChannel, twitterChannel, defaultChannel});
- underTest = new AddAction(notificationCenter, new NotificationUpdater(userSession, dbClient), dbClient, new ComponentFinder(dbClient), userSession);
+ underTest = new AddAction(notificationCenter, new NotificationUpdater(dbClient), dbClient, new ComponentFinder(dbClient), userSession);
ws = new WsActionTester(underTest);
}
@@ -146,6 +155,34 @@ public class AddActionTest {
}
@Test
+ public void add_a_notification_to_a_user_as_system_administrator() {
+ userSession.logIn().setSystemAdministrator();
+
+ call(request.setLogin(user.getLogin()));
+
+ db.notifications().assertExists(defaultChannel.getKey(), NOTIF_MY_NEW_ISSUES, user.getId(), null);
+ }
+
+ @Test
+ public void fail_if_login_is_provided_and_unknown() {
+ userSession.logIn().setSystemAdministrator();
+
+ expectedException.expect(NotFoundException.class);
+ expectedException.expectMessage("User 'LOGIN 404' not found");
+
+ call(request.setLogin("LOGIN 404"));
+ }
+
+ @Test
+ public void fail_if_login_provided_and_not_system_administrator() {
+ userSession.logIn().setNonSystemAdministrator();
+
+ expectedException.expect(ForbiddenException.class);
+
+ call(request.setLogin(user.getLogin()));
+ }
+
+ @Test
public void fail_when_notification_already_exists() {
call(request);
@@ -219,6 +256,7 @@ public class AddActionTest {
request.setParam(PARAM_TYPE, wsRequest.getType());
setNullable(wsRequest.getChannel(), channel -> request.setParam(PARAM_CHANNEL, channel));
setNullable(wsRequest.getProject(), project -> request.setParam(PARAM_PROJECT, project));
+ setNullable(wsRequest.getLogin(), login -> request.setParam(PARAM_LOGIN, login));
return request.execute();
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/notification/ws/ListActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/notification/ws/ListActionTest.java
index 83bbe48a3ab..7707606d715 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/notification/ws/ListActionTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/notification/ws/ListActionTest.java
@@ -33,6 +33,9 @@ import org.sonar.db.component.ComponentDto;
import org.sonar.db.component.ComponentTesting;
import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.permission.UserPermissionDto;
+import org.sonar.db.user.UserDto;
+import org.sonar.server.exceptions.ForbiddenException;
+import org.sonar.server.exceptions.NotFoundException;
import org.sonar.server.exceptions.UnauthorizedException;
import org.sonar.server.notification.NotificationCenter;
import org.sonar.server.notification.NotificationDispatcherMetadata;
@@ -57,7 +60,7 @@ public class ListActionTest {
@Rule
public ExpectedException expectedException = ExpectedException.none();
@Rule
- public UserSessionRule userSession = UserSessionRule.standalone().logIn().setUserId(123);
+ public UserSessionRule userSession;
@Rule
public DbTester db = DbTester.create();
@@ -66,6 +69,7 @@ public class ListActionTest {
private NotificationChannel emailChannel = new FakeNotificationChannel("EmailChannel");
private NotificationChannel twitterChannel = new FakeNotificationChannel("TwitterChannel");
+ private UserDto user;
private NotificationUpdater notificationUpdater;
@@ -82,10 +86,13 @@ public class ListActionTest {
.setProperty(GLOBAL_NOTIFICATION, "true")
.setProperty(PER_PROJECT_NOTIFICATION, "true");
+ user = db.users().insertUser();
+ userSession = UserSessionRule.standalone().logIn(user);
+
NotificationCenter notificationCenter = new NotificationCenter(
new NotificationDispatcherMetadata[] {metadata1, metadata2, metadata3},
new NotificationChannel[] {emailChannel, twitterChannel});
- notificationUpdater = new NotificationUpdater(userSession, dbClient);
+ notificationUpdater = new NotificationUpdater(dbClient);
ListAction underTest = new ListAction(notificationCenter, dbClient, userSession);
ws = new WsActionTester(underTest);
}
@@ -115,8 +122,8 @@ public class ListActionTest {
public void filter_unauthorized_projects() {
ComponentDto project = addComponent(ComponentTesting.newPrivateProjectDto(db.organizations().insert()).setKey("K1"));
ComponentDto anotherProject = db.components().insertPrivateProject();
- notificationUpdater.add(dbSession, emailChannel.getKey(), NOTIF_MY_NEW_ISSUES, project);
- notificationUpdater.add(dbSession, emailChannel.getKey(), NOTIF_MY_NEW_ISSUES, anotherProject);
+ notificationUpdater.add(dbSession, emailChannel.getKey(), NOTIF_MY_NEW_ISSUES, user, project);
+ notificationUpdater.add(dbSession, emailChannel.getKey(), NOTIF_MY_NEW_ISSUES, user, anotherProject);
dbSession.commit();
ListResponse result = call();
@@ -126,8 +133,8 @@ public class ListActionTest {
@Test
public void filter_channels() {
- notificationUpdater.add(dbSession, emailChannel.getKey(), NOTIF_MY_NEW_ISSUES, null);
- notificationUpdater.add(dbSession, "Unknown Channel", NOTIF_MY_NEW_ISSUES, null);
+ notificationUpdater.add(dbSession, emailChannel.getKey(), NOTIF_MY_NEW_ISSUES, user, null);
+ notificationUpdater.add(dbSession, "Unknown Channel", NOTIF_MY_NEW_ISSUES, user, null);
dbSession.commit();
ListResponse result = call();
@@ -137,8 +144,8 @@ public class ListActionTest {
@Test
public void filter_overall_dispatchers() {
- notificationUpdater.add(dbSession, emailChannel.getKey(), NOTIF_MY_NEW_ISSUES, null);
- notificationUpdater.add(dbSession, emailChannel.getKey(), "Unknown Notification", null);
+ notificationUpdater.add(dbSession, emailChannel.getKey(), NOTIF_MY_NEW_ISSUES, user, null);
+ notificationUpdater.add(dbSession, emailChannel.getKey(), "Unknown Notification", user, null);
dbSession.commit();
ListResponse result = call();
@@ -149,8 +156,8 @@ public class ListActionTest {
@Test
public void filter_per_project_dispatchers() {
ComponentDto project = addComponent(ComponentTesting.newPrivateProjectDto(db.organizations().insert()).setKey("K1"));
- notificationUpdater.add(dbSession, emailChannel.getKey(), NOTIF_MY_NEW_ISSUES, project);
- notificationUpdater.add(dbSession, emailChannel.getKey(), "Unknown Notification", project);
+ notificationUpdater.add(dbSession, emailChannel.getKey(), NOTIF_MY_NEW_ISSUES, user, project);
+ notificationUpdater.add(dbSession, emailChannel.getKey(), "Unknown Notification", user, project);
dbSession.commit();
ListResponse result = call();
@@ -164,12 +171,12 @@ public class ListActionTest {
public void order_with_global_then_by_channel_and_dispatcher() {
OrganizationDto organization = db.organizations().insert();
ComponentDto project = addComponent(ComponentTesting.newPrivateProjectDto(organization).setKey("K1"));
- notificationUpdater.add(dbSession, twitterChannel.getKey(), NOTIF_MY_NEW_ISSUES, null);
- notificationUpdater.add(dbSession, emailChannel.getKey(), NOTIF_MY_NEW_ISSUES, null);
- notificationUpdater.add(dbSession, emailChannel.getKey(), NOTIF_NEW_ISSUES, null);
- notificationUpdater.add(dbSession, twitterChannel.getKey(), NOTIF_MY_NEW_ISSUES, project);
- notificationUpdater.add(dbSession, emailChannel.getKey(), NOTIF_MY_NEW_ISSUES, project);
- notificationUpdater.add(dbSession, emailChannel.getKey(), NOTIF_NEW_QUALITY_GATE_STATUS, project);
+ notificationUpdater.add(dbSession, twitterChannel.getKey(), NOTIF_MY_NEW_ISSUES, user, null);
+ notificationUpdater.add(dbSession, emailChannel.getKey(), NOTIF_MY_NEW_ISSUES, user, null);
+ notificationUpdater.add(dbSession, emailChannel.getKey(), NOTIF_NEW_ISSUES, user, null);
+ notificationUpdater.add(dbSession, twitterChannel.getKey(), NOTIF_MY_NEW_ISSUES, user, project);
+ notificationUpdater.add(dbSession, emailChannel.getKey(), NOTIF_MY_NEW_ISSUES, user, project);
+ notificationUpdater.add(dbSession, emailChannel.getKey(), NOTIF_NEW_QUALITY_GATE_STATUS, user, project);
dbSession.commit();
ListResponse result = call();
@@ -186,15 +193,51 @@ public class ListActionTest {
}
@Test
+ public void list_user_notifications_as_system_admin() {
+ userSession.logIn().setSystemAdministrator();
+
+ notificationUpdater.add(dbSession, emailChannel.getKey(), NOTIF_MY_NEW_ISSUES, user, null);
+ notificationUpdater.add(dbSession, emailChannel.getKey(), NOTIF_NEW_ISSUES, user, null);
+ dbSession.commit();
+
+ ListResponse result = call(user.getLogin());
+
+ assertThat(result.getNotificationsList())
+ .extracting(Notification::getType)
+ .containsOnly(NOTIF_MY_NEW_ISSUES, NOTIF_NEW_ISSUES);
+ }
+
+ @Test
+ public void fail_if_login_and_not_system_admin() {
+ userSession.logIn().setNonSystemAdministrator();
+ notificationUpdater.add(dbSession, emailChannel.getKey(), NOTIF_MY_NEW_ISSUES, user, null);
+ dbSession.commit();
+
+ expectedException.expect(ForbiddenException.class);
+
+ call(user.getLogin());
+ }
+
+ @Test
+ public void fail_if_login_is_provided_and_unknown() {
+ userSession.logIn().setSystemAdministrator();
+
+ expectedException.expect(NotFoundException.class);
+ expectedException.expectMessage("User 'LOGIN 404' not found");
+
+ call("LOGIN 404");
+ }
+
+ @Test
public void json_example() {
OrganizationDto organization = db.organizations().insertForKey("my-org-1");
ComponentDto project = addComponent(ComponentTesting.newPrivateProjectDto(organization).setKey(KEY_PROJECT_EXAMPLE_001).setName("My Project"));
- notificationUpdater.add(dbSession, twitterChannel.getKey(), NOTIF_MY_NEW_ISSUES, null);
- notificationUpdater.add(dbSession, emailChannel.getKey(), NOTIF_MY_NEW_ISSUES, null);
- notificationUpdater.add(dbSession, emailChannel.getKey(), NOTIF_NEW_ISSUES, null);
- notificationUpdater.add(dbSession, twitterChannel.getKey(), NOTIF_MY_NEW_ISSUES, project);
- notificationUpdater.add(dbSession, emailChannel.getKey(), NOTIF_MY_NEW_ISSUES, project);
- notificationUpdater.add(dbSession, emailChannel.getKey(), NOTIF_NEW_QUALITY_GATE_STATUS, project);
+ notificationUpdater.add(dbSession, twitterChannel.getKey(), NOTIF_MY_NEW_ISSUES, user, null);
+ notificationUpdater.add(dbSession, emailChannel.getKey(), NOTIF_MY_NEW_ISSUES, user, null);
+ notificationUpdater.add(dbSession, emailChannel.getKey(), NOTIF_NEW_ISSUES, user, null);
+ notificationUpdater.add(dbSession, twitterChannel.getKey(), NOTIF_MY_NEW_ISSUES, user, project);
+ notificationUpdater.add(dbSession, emailChannel.getKey(), NOTIF_MY_NEW_ISSUES, user, project);
+ notificationUpdater.add(dbSession, emailChannel.getKey(), NOTIF_NEW_QUALITY_GATE_STATUS, user, project);
dbSession.commit();
String result = ws.newRequest().execute().getInput();
@@ -210,8 +253,13 @@ public class ListActionTest {
assertThat(definition.key()).isEqualTo("list");
assertThat(definition.isPost()).isFalse();
- assertThat(definition.params()).isEmpty();
+ assertThat(definition.since()).isEqualTo("6.3");
assertThat(definition.responseExampleAsString()).isNotEmpty();
+ assertThat(definition.params()).hasSize(1);
+
+ WebService.Param loginParam = definition.param("login");
+ assertThat(loginParam.since()).isEqualTo("6.4");
+ assertThat(loginParam.isRequired()).isFalse();
}
@Test
@@ -227,9 +275,13 @@ public class ListActionTest {
return ws.newRequest().executeProtobuf(ListResponse.class);
}
+ private ListResponse call(String login) {
+ return ws.newRequest().setParam("login", login).executeProtobuf(ListResponse.class);
+ }
+
private ComponentDto addComponent(ComponentDto component) {
db.components().insertComponent(component);
- dbClient.userPermissionDao().insert(dbSession, new UserPermissionDto(component.getOrganizationUuid(), UserRole.USER, userSession.getUserId(), component.getId()));
+ dbClient.userPermissionDao().insert(dbSession, new UserPermissionDto(component.getOrganizationUuid(), UserRole.USER, user.getId(), component.getId()));
db.commit();
return component;
diff --git a/server/sonar-server/src/test/java/org/sonar/server/notification/ws/RemoveActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/notification/ws/RemoveActionTest.java
index c467a1cc2af..8cc3f5ccf87 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/notification/ws/RemoveActionTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/notification/ws/RemoveActionTest.java
@@ -29,8 +29,10 @@ import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.DbTester;
import org.sonar.db.component.ComponentDto;
+import org.sonar.db.user.UserDto;
import org.sonar.server.component.ComponentFinder;
import org.sonar.server.exceptions.BadRequestException;
+import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.exceptions.NotFoundException;
import org.sonar.server.exceptions.UnauthorizedException;
import org.sonar.server.notification.NotificationCenter;
@@ -40,7 +42,7 @@ import org.sonar.server.tester.UserSessionRule;
import org.sonar.server.ws.TestRequest;
import org.sonar.server.ws.TestResponse;
import org.sonar.server.ws.WsActionTester;
-import org.sonarqube.ws.client.notification.AddRequest;
+import org.sonarqube.ws.client.notification.RemoveRequest;
import static java.net.HttpURLConnection.HTTP_NO_CONTENT;
import static org.assertj.core.api.Assertions.assertThat;
@@ -49,6 +51,7 @@ import static org.sonar.db.component.ComponentTesting.newView;
import static org.sonar.server.notification.NotificationDispatcherMetadata.GLOBAL_NOTIFICATION;
import static org.sonar.server.notification.NotificationDispatcherMetadata.PER_PROJECT_NOTIFICATION;
import static org.sonarqube.ws.client.notification.NotificationsWsParameters.PARAM_CHANNEL;
+import static org.sonarqube.ws.client.notification.NotificationsWsParameters.PARAM_LOGIN;
import static org.sonarqube.ws.client.notification.NotificationsWsParameters.PARAM_PROJECT;
import static org.sonarqube.ws.client.notification.NotificationsWsParameters.PARAM_TYPE;
@@ -59,7 +62,7 @@ public class RemoveActionTest {
@Rule
public ExpectedException expectedException = ExpectedException.none();
@Rule
- public UserSessionRule userSession = UserSessionRule.standalone().logIn().setUserId(123);
+ public UserSessionRule userSession;
@Rule
public DbTester db = DbTester.create();
private DbClient dbClient = db.getDbClient();
@@ -75,11 +78,15 @@ public class RemoveActionTest {
private RemoveAction underTest;
private WsActionTester ws;
- private AddRequest.Builder request = AddRequest.builder()
- .setType(NOTIF_MY_NEW_ISSUES);
+ private RemoveRequest.Builder request = RemoveRequest.builder().setType(NOTIF_MY_NEW_ISSUES);
+
+ private UserDto user;
@Before
public void setUp() {
+ user = db.users().insertUser();
+ userSession = UserSessionRule.standalone().logIn(user);
+
NotificationDispatcherMetadata metadata1 = NotificationDispatcherMetadata.create(NOTIF_MY_NEW_ISSUES)
.setProperty(GLOBAL_NOTIFICATION, "true")
.setProperty(PER_PROJECT_NOTIFICATION, "true");
@@ -92,46 +99,46 @@ public class RemoveActionTest {
notificationCenter = new NotificationCenter(
new NotificationDispatcherMetadata[] {metadata1, metadata2, metadata3},
new NotificationChannel[] {emailChannel, twitterChannel, defaultChannel});
- notificationUpdater = new NotificationUpdater(userSession, dbClient);
+ notificationUpdater = new NotificationUpdater(dbClient);
underTest = new RemoveAction(notificationCenter, notificationUpdater, dbClient, new ComponentFinder(dbClient), userSession);
ws = new WsActionTester(underTest);
}
@Test
public void remove_to_email_channel_by_default() {
- notificationUpdater.add(dbSession, defaultChannel.getKey(), NOTIF_MY_NEW_ISSUES, null);
+ notificationUpdater.add(dbSession, defaultChannel.getKey(), NOTIF_MY_NEW_ISSUES, user, null);
dbSession.commit();
call(request);
- db.notifications().assertDoesNotExist(defaultChannel.getKey(), NOTIF_MY_NEW_ISSUES, userSession.getUserId(), null);
+ db.notifications().assertDoesNotExist(defaultChannel.getKey(), NOTIF_MY_NEW_ISSUES, user.getId(), null);
}
@Test
public void remove_from_a_specific_channel() {
- notificationUpdater.add(dbSession, twitterChannel.getKey(), NOTIF_NEW_QUALITY_GATE_STATUS, null);
+ notificationUpdater.add(dbSession, twitterChannel.getKey(), NOTIF_NEW_QUALITY_GATE_STATUS, user, null);
dbSession.commit();
call(request.setType(NOTIF_NEW_QUALITY_GATE_STATUS).setChannel(twitterChannel.getKey()));
- db.notifications().assertDoesNotExist(twitterChannel.getKey(), NOTIF_NEW_QUALITY_GATE_STATUS, userSession.getUserId(), null);
+ db.notifications().assertDoesNotExist(twitterChannel.getKey(), NOTIF_NEW_QUALITY_GATE_STATUS, user.getId(), null);
}
@Test
public void remove_a_project_notification() {
ComponentDto project = db.components().insertPrivateProject();
- notificationUpdater.add(dbSession, defaultChannel.getKey(), NOTIF_MY_NEW_ISSUES, project);
+ notificationUpdater.add(dbSession, defaultChannel.getKey(), NOTIF_MY_NEW_ISSUES, user, project);
dbSession.commit();
call(request.setProject(project.getKey()));
- db.notifications().assertDoesNotExist(defaultChannel.getKey(), NOTIF_MY_NEW_ISSUES, userSession.getUserId(), project);
+ db.notifications().assertDoesNotExist(defaultChannel.getKey(), NOTIF_MY_NEW_ISSUES, user.getId(), project);
}
@Test
public void fail_when_remove_a_global_notification_when_a_project_one_exists() {
ComponentDto project = db.components().insertPrivateProject();
- notificationUpdater.add(dbSession, defaultChannel.getKey(), NOTIF_MY_NEW_ISSUES, project);
+ notificationUpdater.add(dbSession, defaultChannel.getKey(), NOTIF_MY_NEW_ISSUES, user, project);
dbSession.commit();
expectedException.expect(IllegalArgumentException.class);
@@ -143,7 +150,7 @@ public class RemoveActionTest {
@Test
public void fail_when_remove_a_project_notification_when_a_global_one_exists() {
ComponentDto project = db.components().insertPrivateProject();
- notificationUpdater.add(dbSession, defaultChannel.getKey(), NOTIF_MY_NEW_ISSUES, null);
+ notificationUpdater.add(dbSession, defaultChannel.getKey(), NOTIF_MY_NEW_ISSUES, user, null);
dbSession.commit();
expectedException.expect(IllegalArgumentException.class);
@@ -154,7 +161,7 @@ public class RemoveActionTest {
@Test
public void http_no_content() {
- notificationUpdater.add(dbSession, defaultChannel.getKey(), NOTIF_MY_NEW_ISSUES, null);
+ notificationUpdater.add(dbSession, defaultChannel.getKey(), NOTIF_MY_NEW_ISSUES, user, null);
dbSession.commit();
TestResponse result = call(request);
@@ -163,6 +170,39 @@ public class RemoveActionTest {
}
@Test
+ public void remove_a_notification_from_a_user_as_system_administrator() {
+ notificationUpdater.add(dbSession, defaultChannel.getKey(), NOTIF_MY_NEW_ISSUES, user, null);
+ db.notifications().assertExists(defaultChannel.getKey(), NOTIF_MY_NEW_ISSUES, user.getId(), null);
+ userSession.logIn().setSystemAdministrator();
+ dbSession.commit();
+
+ call(request.setLogin(user.getLogin()));
+
+ db.notifications().assertDoesNotExist(defaultChannel.getKey(), NOTIF_MY_NEW_ISSUES, user.getId(), null);
+ }
+
+ @Test
+ public void fail_if_login_is_provided_and_unknown() {
+ userSession.logIn().setSystemAdministrator();
+
+ expectedException.expect(NotFoundException.class);
+ expectedException.expectMessage("User 'LOGIN 404' not found");
+
+ call(request.setLogin("LOGIN 404"));
+ }
+
+ @Test
+ public void fail_if_login_provided_and_not_system_administrator() {
+ userSession.logIn().setNonSystemAdministrator();
+ notificationUpdater.add(dbSession, defaultChannel.getKey(), NOTIF_MY_NEW_ISSUES, user, null);
+ dbSession.commit();
+
+ expectedException.expect(ForbiddenException.class);
+
+ call(request.setLogin(user.getLogin()));
+ }
+
+ @Test
public void fail_when_notification_does_not_exist() {
expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("Notification doesn't exist");
@@ -228,12 +268,14 @@ public class RemoveActionTest {
call(request);
}
- private TestResponse call(AddRequest.Builder wsRequestBuilder) {
- AddRequest wsRequest = wsRequestBuilder.build();
+ private TestResponse call(RemoveRequest.Builder wsRequestBuilder) {
+ RemoveRequest wsRequest = wsRequestBuilder.build();
+
TestRequest request = ws.newRequest();
request.setParam(PARAM_TYPE, wsRequest.getType());
setNullable(wsRequest.getChannel(), channel -> request.setParam(PARAM_CHANNEL, channel));
setNullable(wsRequest.getProject(), project -> request.setParam(PARAM_PROJECT, project));
+ setNullable(wsRequest.getLogin(), login -> request.setParam(PARAM_LOGIN, login));
return request.execute();
}