@Override
public void dispatch(Notification notification, Context context) {
String projectUuid = notification.getFieldValue("project.uuid");
- Multimap<String, NotificationChannel> subscribedRecipients = manager.findSubscribedRecipientsForDispatcher(this, projectUuid);
+ Multimap<String, NotificationChannel> subscribedRecipients = manager.findSubscribedRecipientsForDispatcher(
+ this, projectUuid, NotificationManager.SubscriberPermissionsOnProject.ALL_MUST_HAVE_ROLE_USER);
for (Map.Entry<String, Collection<NotificationChannel>> channelsByRecipients : subscribedRecipients.asMap().entrySet()) {
String userLogin = channelsByRecipients.getKey();
import org.sonar.server.notification.NotificationDispatcherMetadata;
import org.sonar.server.notification.NotificationManager;
+import static org.sonar.server.notification.NotificationManager.SubscriberPermissionsOnProject.ALL_MUST_HAVE_ROLE_USER;
+
/**
* This dispatcher means: "notify me each new alert event".
*
public void dispatch(Notification notification, Context context) {
String projectUuid = notification.getFieldValue("projectUuid");
if (projectUuid != null) {
- Multimap<String, NotificationChannel> subscribedRecipients = notifications.findSubscribedRecipientsForDispatcher(this, projectUuid);
+ Multimap<String, NotificationChannel> subscribedRecipients = notifications.findSubscribedRecipientsForDispatcher(
+ this, projectUuid, ALL_MUST_HAVE_ROLE_USER);
for (Map.Entry<String, Collection<NotificationChannel>> channelsByRecipients : subscribedRecipients.asMap().entrySet()) {
String userLogin = channelsByRecipients.getKey();
import org.sonar.server.notification.NotificationDispatcherMetadata;
import org.sonar.server.notification.NotificationManager;
+import static org.sonar.server.notification.NotificationManager.SubscriberPermissionsOnProject.ALL_MUST_HAVE_ROLE_USER;
+
/**
* This dispatcher means: "notify me when a change is done on an issue that is assigned to me or reported by me".
*
@Override
public void dispatch(Notification notification, Context context) {
String projectUuid = notification.getFieldValue("projectUuid");
- Multimap<String, NotificationChannel> subscribedRecipients = notificationManager.findSubscribedRecipientsForDispatcher(this, projectUuid);
+ Multimap<String, NotificationChannel> subscribedRecipients = notificationManager.findSubscribedRecipientsForDispatcher(
+ this, projectUuid, ALL_MUST_HAVE_ROLE_USER);
// See available fields in the class IssueNotifications.
import org.sonar.server.notification.NotificationDispatcherMetadata;
import org.sonar.server.notification.NotificationManager;
+import static org.sonar.server.notification.NotificationManager.SubscriberPermissionsOnProject.ALL_MUST_HAVE_ROLE_USER;
+
/**
* This dispatcher means: "notify me when an issue is resolved as false positive or won't fix".
*/
if (Objects.equals(newResolution, Issue.RESOLUTION_FALSE_POSITIVE) || Objects.equals(newResolution, Issue.RESOLUTION_WONT_FIX)) {
String author = notification.getFieldValue("changeAuthor");
String projectUuid = notification.getFieldValue("projectUuid");
- Multimap<String, NotificationChannel> subscribedRecipients = notifications.findSubscribedRecipientsForDispatcher(this, projectUuid);
+ Multimap<String, NotificationChannel> subscribedRecipients = notifications.findSubscribedRecipientsForDispatcher(
+ this, projectUuid, ALL_MUST_HAVE_ROLE_USER);
notify(author, context, subscribedRecipients);
}
}
import org.sonar.server.notification.NotificationDispatcherMetadata;
import org.sonar.server.notification.NotificationManager;
+import static org.sonar.server.notification.NotificationManager.SubscriberPermissionsOnProject.ALL_MUST_HAVE_ROLE_USER;
+
/**
* This dispatcher means: "notify me when new issues are introduced during project analysis"
*/
public void dispatch(Notification notification, Context context) {
String projectUuid = notification.getFieldValue("projectUuid");
String assignee = notification.getFieldValue("assignee");
- Multimap<String, NotificationChannel> subscribedRecipients = manager.findSubscribedRecipientsForDispatcher(this, projectUuid);
+ Multimap<String, NotificationChannel> subscribedRecipients = manager.findSubscribedRecipientsForDispatcher(
+ this, projectUuid, ALL_MUST_HAVE_ROLE_USER);
Collection<NotificationChannel> channels = subscribedRecipients.get(assignee);
for (NotificationChannel channel : channels) {
import org.sonar.server.notification.NotificationDispatcherMetadata;
import org.sonar.server.notification.NotificationManager;
+import static org.sonar.server.notification.NotificationManager.SubscriberPermissionsOnProject.ALL_MUST_HAVE_ROLE_USER;
+
/**
* This dispatcher means: "notify me when new issues are introduced during project analysis"
*/
@Override
public void dispatch(Notification notification, Context context) {
String projectUuid = notification.getFieldValue("projectUuid");
- Multimap<String, NotificationChannel> subscribedRecipients = manager.findSubscribedRecipientsForDispatcher(this, projectUuid);
+ Multimap<String, NotificationChannel> subscribedRecipients = manager.findSubscribedRecipientsForDispatcher(
+ this, projectUuid, ALL_MUST_HAVE_ROLE_USER);
for (Map.Entry<String, Collection<NotificationChannel>> channelsByRecipients : subscribedRecipients.asMap().entrySet()) {
String userLogin = channelsByRecipients.getKey();
import java.io.IOException;
import java.io.InvalidClassException;
import java.util.Arrays;
+import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
+import javax.annotation.Nullable;
import org.sonar.api.notifications.Notification;
import org.sonar.api.notifications.NotificationChannel;
import org.sonar.api.utils.SonarException;
import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;
-import org.sonar.api.web.UserRole;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.notification.NotificationQueueDto;
* {@inheritDoc}
*/
@Override
- public Multimap<String, NotificationChannel> findSubscribedRecipientsForDispatcher(NotificationDispatcher dispatcher, String projectUuid) {
+ public Multimap<String, NotificationChannel> findSubscribedRecipientsForDispatcher(NotificationDispatcher dispatcher, String projectUuid,
+ SubscriberPermissionsOnProject subscriberPermissionsOnProject) {
requireNonNull(projectUuid, "ProjectUUID is mandatory");
String dispatcherKey = dispatcher.getKey();
ImmutableSetMultimap.Builder<String, NotificationChannel> builder = ImmutableSetMultimap.builder();
try (DbSession dbSession = dbClient.openSession(false)) {
- Set<String> authorizedLogins = keepAuthorizedLogins(projectUuid, subscriberAndChannels, dbSession);
+ Set<String> authorizedLogins = keepAuthorizedLogins(dbSession, projectUuid, subscriberAndChannels, subscriberPermissionsOnProject);
subscriberAndChannels.stream()
.filter(subscriberAndChannel -> authorizedLogins.contains(subscriberAndChannel.getSubscriber().getLogin()))
.forEach(subscriberAndChannel -> builder.put(subscriberAndChannel.getSubscriber().getLogin(), subscriberAndChannel.getChannel()));
}
private Stream<SubscriberAndChannel> toSubscriberAndChannels(String dispatcherKey, String projectUuid, NotificationChannel notificationChannel) {
- return dbClient.propertiesDao().findUsersForNotification(dispatcherKey, notificationChannel.getKey(), projectUuid)
+ Set<Subscriber> usersForNotification = dbClient.propertiesDao().findUsersForNotification(dispatcherKey, notificationChannel.getKey(), projectUuid);
+ return usersForNotification
.stream()
.map(login -> new SubscriberAndChannel(login, notificationChannel));
}
- private Set<String> keepAuthorizedLogins(String projectUuid, Set<SubscriberAndChannel> subscriberAndChannels, DbSession dbSession) {
+ private Set<String> keepAuthorizedLogins(DbSession dbSession, String projectUuid, Set<SubscriberAndChannel> subscriberAndChannels,
+ SubscriberPermissionsOnProject requiredPermissions) {
+ if (requiredPermissions.getGlobalSubscribers().equals(requiredPermissions.getProjectSubscribers())) {
+ return keepAuthorizedLogins(dbSession, projectUuid, subscriberAndChannels, null, requiredPermissions.getGlobalSubscribers());
+ } else {
+ return Stream
+ .concat(
+ keepAuthorizedLogins(dbSession, projectUuid, subscriberAndChannels, true, requiredPermissions.getGlobalSubscribers()).stream(),
+ keepAuthorizedLogins(dbSession, projectUuid, subscriberAndChannels, false, requiredPermissions.getProjectSubscribers()).stream())
+ .collect(Collectors.toSet());
+ }
+ }
+
+ private Set<String> keepAuthorizedLogins(DbSession dbSession, String projectUuid, Set<SubscriberAndChannel> subscriberAndChannels,
+ @Nullable Boolean global, String permission) {
Set<String> logins = subscriberAndChannels.stream()
- .map(DefaultNotificationManager.SubscriberAndChannel::getSubscriber)
- .map(Subscriber::getLogin)
+ .filter(s -> global == null || s.getSubscriber().isGlobal() == global)
+ .map(s -> s.getSubscriber().getLogin())
.collect(Collectors.toSet());
- return dbClient.authorizationDao().keepAuthorizedLoginsOnProject(dbSession, logins, projectUuid, UserRole.USER);
+ if (logins.isEmpty()) {
+ return Collections.emptySet();
+ }
+ return dbClient.authorizationDao().keepAuthorizedLoginsOnProject(dbSession, logins, projectUuid, permission);
}
- private final class SubscriberAndChannel {
+ private static final class SubscriberAndChannel {
private final Subscriber subscriber;
private final NotificationChannel channel;
this.channel = channel;
}
- public Subscriber getSubscriber() {
+ Subscriber getSubscriber() {
return subscriber;
}
- public NotificationChannel getChannel() {
+ NotificationChannel getChannel() {
return channel;
}
package org.sonar.server.notification;
import com.google.common.collect.Multimap;
+import java.util.Objects;
import org.sonar.api.notifications.Notification;
import org.sonar.api.notifications.NotificationChannel;
+import org.sonar.api.web.UserRole;
+
+import static java.util.Objects.requireNonNull;
/**
* The notification manager receives notifications and is in charge of storing them so that they are processed by the notification service.
*
* @param dispatcher the dispatcher for which this list of users is requested
* @param projectUuid UUID of the project
+ * @param subscriberPermissionsOnProject the required permission for global and project subscribers
+ *
* @return the list of user login along with the subscribed channels
*/
- Multimap<String, NotificationChannel> findSubscribedRecipientsForDispatcher(NotificationDispatcher dispatcher, String projectUuid);
+ Multimap<String, NotificationChannel> findSubscribedRecipientsForDispatcher(NotificationDispatcher dispatcher, String projectUuid,
+ SubscriberPermissionsOnProject subscriberPermissionsOnProject);
+
+ final class SubscriberPermissionsOnProject {
+ public static final SubscriberPermissionsOnProject ALL_MUST_HAVE_ROLE_USER = new SubscriberPermissionsOnProject(UserRole.USER);
+
+ private final String globalSubscribers;
+ private final String projectSubscribers;
+
+ public SubscriberPermissionsOnProject(String globalAndProjectSubscribers) {
+ this(globalAndProjectSubscribers, globalAndProjectSubscribers);
+ }
+
+ public SubscriberPermissionsOnProject(String globalSubscribers, String projectSubscribers) {
+ this.globalSubscribers = requireNonNull(globalSubscribers, "global subscribers's required permission can't be null");
+ this.projectSubscribers = requireNonNull(projectSubscribers, "project subscribers's required permission can't be null");
+ }
+
+ public String getGlobalSubscribers() {
+ return globalSubscribers;
+ }
+
+ public String getProjectSubscribers() {
+ return projectSubscribers;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ SubscriberPermissionsOnProject that = (SubscriberPermissionsOnProject) o;
+ return globalSubscribers.equals(that.globalSubscribers) && projectSubscribers.equals(that.projectSubscribers);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(globalSubscribers, projectSubscribers);
+ }
+ }
}
import org.junit.Test;
import org.sonar.api.notifications.Notification;
import org.sonar.api.notifications.NotificationChannel;
+import org.sonar.api.web.UserRole;
import org.sonar.server.notification.NotificationDispatcher;
import org.sonar.server.notification.NotificationDispatcherMetadata;
import org.sonar.server.notification.NotificationManager;
multimap.put(login1, channel2);
multimap.put(login2, channel2);
multimap.put(login2, channel3);
- when(notificationManager.findSubscribedRecipientsForDispatcher(underTest, projectUuid))
+ when(notificationManager.findSubscribedRecipientsForDispatcher(underTest, projectUuid, new NotificationManager.SubscriberPermissionsOnProject(UserRole.USER)))
.thenReturn(multimap);
underTest.performDispatch(notificationMock, contextMock);
String projectUuid = randomAlphanumeric(9);
when(notificationMock.getFieldValue("project.uuid")).thenReturn(projectUuid);
HashMultimap<String, NotificationChannel> multimap = HashMultimap.create();
- when(notificationManager.findSubscribedRecipientsForDispatcher(underTest, projectUuid))
+ when(notificationManager.findSubscribedRecipientsForDispatcher(underTest, projectUuid, new NotificationManager.SubscriberPermissionsOnProject(UserRole.USER)))
.thenReturn(multimap);
underTest.performDispatch(notificationMock, contextMock);
import org.junit.Test;
import org.sonar.api.notifications.Notification;
import org.sonar.api.notifications.NotificationChannel;
+import org.sonar.api.web.UserRole;
import org.sonar.server.notification.NotificationDispatcher;
import org.sonar.server.notification.NotificationManager;
Multimap<String, NotificationChannel> recipients = HashMultimap.create();
recipients.put("user1", emailChannel);
recipients.put("user2", twitterChannel);
- when(notificationManager.findSubscribedRecipientsForDispatcher(dispatcher, "uuid_34")).thenReturn(recipients);
+ when(notificationManager.findSubscribedRecipientsForDispatcher(dispatcher, "uuid_34", new NotificationManager.SubscriberPermissionsOnProject(UserRole.USER))).thenReturn(recipients);
Notification notification = new Notification("alerts").setFieldValue("projectUuid", "uuid_34");
dispatcher.performDispatch(notification, context);
Multimap<String, NotificationChannel> recipients = HashMultimap.create();
recipients.put("user1", emailChannel);
recipients.put("user2", twitterChannel);
- when(notificationManager.findSubscribedRecipientsForDispatcher(dispatcher, "uuid_34")).thenReturn(recipients);
+ when(notificationManager.findSubscribedRecipientsForDispatcher(dispatcher, "uuid_34", new NotificationManager.SubscriberPermissionsOnProject(UserRole.USER))).thenReturn(recipients);
Notification notification = new Notification("alerts");
dispatcher.performDispatch(notification, context);
import org.mockito.runners.MockitoJUnitRunner;
import org.sonar.api.notifications.Notification;
import org.sonar.api.notifications.NotificationChannel;
+import org.sonar.api.web.UserRole;
import org.sonar.server.notification.NotificationDispatcher;
import org.sonar.server.notification.NotificationDispatcherMetadata;
import org.sonar.server.notification.NotificationManager;
recipients.put("simon", emailChannel);
recipients.put("freddy", twitterChannel);
recipients.put("godin", twitterChannel);
- when(notifications.findSubscribedRecipientsForDispatcher(dispatcher, "uuid1")).thenReturn(recipients);
+ when(notifications.findSubscribedRecipientsForDispatcher(dispatcher, "uuid1",
+ new NotificationManager.SubscriberPermissionsOnProject(UserRole.USER))).thenReturn(recipients);
Notification notification = new IssueChangeNotification()
.setFieldValue("projectKey", "struts")
recipients.put("simon", emailChannel);
recipients.put("freddy", twitterChannel);
recipients.put("godin", twitterChannel);
- when(notifications.findSubscribedRecipientsForDispatcher(dispatcher, "uuid1")).thenReturn(recipients);
+ when(notifications.findSubscribedRecipientsForDispatcher(dispatcher, "uuid1", new NotificationManager.SubscriberPermissionsOnProject(UserRole.USER))).thenReturn(recipients);
// change author is the assignee
dispatcher.performDispatch(
import org.sonar.api.issue.Issue;
import org.sonar.api.notifications.Notification;
import org.sonar.api.notifications.NotificationChannel;
+import org.sonar.api.web.UserRole;
import org.sonar.server.notification.NotificationDispatcher;
import org.sonar.server.notification.NotificationDispatcherMetadata;
import org.sonar.server.notification.NotificationManager;
recipients.put("simon", emailChannel);
recipients.put("freddy", twitterChannel);
recipients.put("godin", twitterChannel);
- when(notifications.findSubscribedRecipientsForDispatcher(underTest, "uuid1")).thenReturn(recipients);
+ when(notifications.findSubscribedRecipientsForDispatcher(underTest, "uuid1", new NotificationManager.SubscriberPermissionsOnProject(UserRole.USER))).thenReturn(recipients);
Notification fpNotif = new IssueChangeNotification().setFieldValue("projectKey", "struts")
.setFieldValue("projectUuid", "uuid1")
import org.junit.Test;
import org.sonar.api.notifications.Notification;
import org.sonar.api.notifications.NotificationChannel;
+import org.sonar.api.web.UserRole;
import org.sonar.server.notification.NotificationDispatcher;
import org.sonar.server.notification.NotificationManager;
Multimap<String, NotificationChannel> recipients = HashMultimap.create();
recipients.put("user1", emailChannel);
recipients.put("user2", twitterChannel);
- when(notificationManager.findSubscribedRecipientsForDispatcher(underTest, "uuid1")).thenReturn(recipients);
+ when(notificationManager.findSubscribedRecipientsForDispatcher(underTest, "uuid1", new NotificationManager.SubscriberPermissionsOnProject(UserRole.USER))).thenReturn(recipients);
Notification notification = new Notification(MyNewIssuesNotification.MY_NEW_ISSUES_NOTIF_TYPE)
.setFieldValue("projectKey", "struts")
import org.junit.Test;
import org.sonar.api.notifications.Notification;
import org.sonar.api.notifications.NotificationChannel;
+import org.sonar.api.web.UserRole;
import org.sonar.server.notification.NotificationDispatcher;
import org.sonar.server.notification.NotificationManager;
Multimap<String, NotificationChannel> recipients = HashMultimap.create();
recipients.put("user1", emailChannel);
recipients.put("user2", twitterChannel);
- when(notifications.findSubscribedRecipientsForDispatcher(dispatcher, "uuid1")).thenReturn(recipients);
+ when(notifications.findSubscribedRecipientsForDispatcher(dispatcher, "uuid1", new NotificationManager.SubscriberPermissionsOnProject(UserRole.USER))).thenReturn(recipients);
Notification notification = new Notification(NewIssuesNotification.TYPE)
.setFieldValue("projectKey", "struts")
import java.util.Collection;
import java.util.List;
import java.util.Map;
+import org.apache.commons.lang.RandomStringUtils;
import org.junit.Before;
-import org.junit.Rule;
import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Captor;
import org.mockito.InOrder;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
import org.sonar.api.notifications.Notification;
import org.sonar.api.notifications.NotificationChannel;
-import org.sonar.api.utils.System2;
+import org.sonar.api.web.UserRole;
import org.sonar.db.DbClient;
-import org.sonar.db.DbTester;
+import org.sonar.db.DbSession;
import org.sonar.db.notification.NotificationQueueDao;
import org.sonar.db.notification.NotificationQueueDto;
import org.sonar.db.permission.AuthorizationDao;
import org.sonar.db.property.PropertiesDao;
import org.sonar.db.property.Subscriber;
+import org.sonar.server.notification.NotificationManager.SubscriberPermissionsOnProject;
import static com.google.common.collect.Sets.newHashSet;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyBoolean;
+import static org.mockito.Matchers.anySet;
+import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
private DefaultNotificationManager underTest;
- @Rule
- public DbTester db = DbTester.create(System2.INSTANCE);
-
- @Mock
- private PropertiesDao propertiesDao;
-
- @Mock
- private NotificationDispatcher dispatcher;
-
- @Mock
- private NotificationChannel emailChannel;
-
- @Mock
- private NotificationChannel twitterChannel;
-
- @Mock
- private NotificationQueueDao notificationQueueDao;
-
- @Mock
- private AuthorizationDao authorizationDao;
-
- @Mock
- private DbClient dbClient;
-
- @Captor
- private ArgumentCaptor<List<String>> captorLogins;
+ private PropertiesDao propertiesDao = mock(PropertiesDao.class);
+ private NotificationDispatcher dispatcher = mock(NotificationDispatcher.class);
+ private NotificationChannel emailChannel = mock(NotificationChannel.class);
+ private NotificationChannel twitterChannel = mock(NotificationChannel.class);
+ private NotificationQueueDao notificationQueueDao = mock(NotificationQueueDao.class);
+ private AuthorizationDao authorizationDao = mock(AuthorizationDao.class);
+ private DbClient dbClient = mock(DbClient.class);
+ private DbSession dbSession = mock(DbSession.class);
@Before
public void setUp() {
- MockitoAnnotations.initMocks(this);
when(dispatcher.getKey()).thenReturn("NewViolations");
when(emailChannel.getKey()).thenReturn("Email");
when(twitterChannel.getKey()).thenReturn("Twitter");
+ when(dbClient.openSession(anyBoolean())).thenReturn(dbSession);
when(dbClient.propertiesDao()).thenReturn(propertiesDao);
when(dbClient.notificationQueueDao()).thenReturn(notificationQueueDao);
when(dbClient.authorizationDao()).thenReturn(authorizationDao);
public void shouldProvideChannelList() {
assertThat(underTest.getChannels()).containsOnly(emailChannel, twitterChannel);
- underTest = new DefaultNotificationManager(new NotificationChannel[] {}, db.getDbClient());
+ underTest = new DefaultNotificationManager(new NotificationChannel[] {}, dbClient);
assertThat(underTest.getChannels()).hasSize(0);
}
@Test
public void shouldFindNoRecipient() {
- assertThat(underTest.findSubscribedRecipientsForDispatcher(dispatcher, "uuid_45").asMap().entrySet()).hasSize(0);
+ assertThat(underTest.findSubscribedRecipientsForDispatcher(dispatcher, "uuid_45", new SubscriberPermissionsOnProject(UserRole.USER)).asMap().entrySet())
+ .hasSize(0);
}
@Test
public void shouldFindSubscribedRecipientForGivenResource() {
- when(propertiesDao.findUsersForNotification("NewViolations", "Email", "uuid_45"))
+ String projectUuid = "uuid_45";
+ when(propertiesDao.findUsersForNotification("NewViolations", "Email", projectUuid))
.thenReturn(newHashSet(new Subscriber("user1", false), new Subscriber("user3", false), new Subscriber("user3", true)));
when(propertiesDao.findUsersForNotification("NewViolations", "Twitter", "uuid_56"))
.thenReturn(newHashSet(new Subscriber("user2", false)));
- when(propertiesDao.findUsersForNotification("NewViolations", "Twitter", "uuid_45"))
+ when(propertiesDao.findUsersForNotification("NewViolations", "Twitter", projectUuid))
.thenReturn(newHashSet(new Subscriber("user3", true)));
- when(propertiesDao.findUsersForNotification("NewAlerts", "Twitter", "uuid_45"))
+ when(propertiesDao.findUsersForNotification("NewAlerts", "Twitter", projectUuid))
.thenReturn(newHashSet(new Subscriber("user4", false)));
- when(authorizationDao.keepAuthorizedLoginsOnProject(any(), eq(newHashSet("user1", "user3")), eq("uuid_45"), eq("user")))
+ when(authorizationDao.keepAuthorizedLoginsOnProject(dbSession, newHashSet("user1", "user3"), projectUuid, "user"))
.thenReturn(newHashSet("user1", "user3"));
- when(authorizationDao.keepAuthorizedLoginsOnProject(any(), eq(newHashSet("user3")), eq("uuid_45"), eq("user")))
+
+ Multimap<String, NotificationChannel> multiMap = underTest.findSubscribedRecipientsForDispatcher(dispatcher, projectUuid,
+ SubscriberPermissionsOnProject.ALL_MUST_HAVE_ROLE_USER);
+ assertThat(multiMap.entries()).hasSize(3);
+
+ Map<String, Collection<NotificationChannel>> map = multiMap.asMap();
+ assertThat(map.get("user1")).containsOnly(emailChannel);
+ assertThat(map.get("user2")).isNull();
+ assertThat(map.get("user3")).containsOnly(emailChannel, twitterChannel);
+ assertThat(map.get("user4")).isNull();
+
+ // code is optimized to perform only 1 SQL requests for all channels
+ verify(authorizationDao, times(1)).keepAuthorizedLoginsOnProject(eq(dbSession), anySet(), anyString(), anyString());
+ }
+
+ @Test
+ public void should_apply_distinct_permission_filtering_global_or_project_subscribers() {
+ String globalPermission = RandomStringUtils.randomAlphanumeric(4);
+ String projectPermission = RandomStringUtils.randomAlphanumeric(5);
+ String projectUuid = "uuid_45";
+ when(propertiesDao.findUsersForNotification("NewViolations", "Email", projectUuid))
+ .thenReturn(newHashSet(new Subscriber("user1", false), new Subscriber("user3", false), new Subscriber("user3", true)));
+ when(propertiesDao.findUsersForNotification("NewViolations", "Twitter", "uuid_56"))
+ .thenReturn(newHashSet(new Subscriber("user2", false)));
+ when(propertiesDao.findUsersForNotification("NewViolations", "Twitter", projectUuid))
+ .thenReturn(newHashSet(new Subscriber("user3", true)));
+ when(propertiesDao.findUsersForNotification("NewAlerts", "Twitter", projectUuid))
+ .thenReturn(newHashSet(new Subscriber("user4", false)));
+
+ when(authorizationDao.keepAuthorizedLoginsOnProject(dbSession, newHashSet("user3", "user4"), projectUuid, globalPermission))
.thenReturn(newHashSet("user3"));
+ when(authorizationDao.keepAuthorizedLoginsOnProject(dbSession, newHashSet("user1", "user3"), projectUuid, projectPermission))
+ .thenReturn(newHashSet("user1", "user3"));
- Multimap<String, NotificationChannel> multiMap = underTest.findSubscribedRecipientsForDispatcher(dispatcher, "uuid_45");
+ Multimap<String, NotificationChannel> multiMap = underTest.findSubscribedRecipientsForDispatcher(dispatcher, projectUuid,
+ new SubscriberPermissionsOnProject(globalPermission, projectPermission));
assertThat(multiMap.entries()).hasSize(3);
Map<String, Collection<NotificationChannel>> map = multiMap.asMap();
assertThat(map.get("user2")).isNull();
assertThat(map.get("user3")).containsOnly(emailChannel, twitterChannel);
assertThat(map.get("user4")).isNull();
+
+ // code is optimized to perform only 2 SQL requests for all channels
+ verify(authorizationDao, times(1)).keepAuthorizedLoginsOnProject(eq(dbSession), anySet(), anyString(), eq(globalPermission));
+ verify(authorizationDao, times(1)).keepAuthorizedLoginsOnProject(eq(dbSession), anySet(), anyString(), eq(projectPermission));
+ }
+
+ @Test
+ public void do_not_call_db_for_project_permission_filtering_if_there_is_no_project_subscriber() {
+ String globalPermission = RandomStringUtils.randomAlphanumeric(4);
+ String projectPermission = RandomStringUtils.randomAlphanumeric(5);
+ String projectUuid = "uuid_45";
+ when(propertiesDao.findUsersForNotification("NewViolations", "Email", projectUuid))
+ .thenReturn(newHashSet(new Subscriber("user3", true)));
+ when(propertiesDao.findUsersForNotification("NewViolations", "Twitter", projectUuid))
+ .thenReturn(newHashSet(new Subscriber("user3", true)));
+
+ when(authorizationDao.keepAuthorizedLoginsOnProject(dbSession, newHashSet("user3"), projectUuid, globalPermission))
+ .thenReturn(newHashSet("user3"));
+
+ Multimap<String, NotificationChannel> multiMap = underTest.findSubscribedRecipientsForDispatcher(dispatcher, projectUuid,
+ new SubscriberPermissionsOnProject(globalPermission, projectPermission));
+ assertThat(multiMap.entries()).hasSize(2);
+
+ Map<String, Collection<NotificationChannel>> map = multiMap.asMap();
+ assertThat(map.get("user3")).containsOnly(emailChannel, twitterChannel);
+
+ verify(authorizationDao, times(1)).keepAuthorizedLoginsOnProject(eq(dbSession), anySet(), anyString(), eq(globalPermission));
+ verify(authorizationDao, times(0)).keepAuthorizedLoginsOnProject(eq(dbSession), anySet(), anyString(), eq(projectPermission));
+ }
+
+ @Test
+ public void do_not_call_db_for_project_permission_filtering_if_there_is_no_global_subscriber() {
+ String globalPermission = RandomStringUtils.randomAlphanumeric(4);
+ String projectPermission = RandomStringUtils.randomAlphanumeric(5);
+ String projectUuid = "uuid_45";
+ when(propertiesDao.findUsersForNotification("NewViolations", "Email", projectUuid))
+ .thenReturn(newHashSet(new Subscriber("user3", false)));
+ when(propertiesDao.findUsersForNotification("NewViolations", "Twitter", projectUuid))
+ .thenReturn(newHashSet(new Subscriber("user3", false)));
+
+ when(authorizationDao.keepAuthorizedLoginsOnProject(dbSession, newHashSet("user3"), projectUuid, projectPermission))
+ .thenReturn(newHashSet("user3"));
+
+ Multimap<String, NotificationChannel> multiMap = underTest.findSubscribedRecipientsForDispatcher(dispatcher, projectUuid,
+ new SubscriberPermissionsOnProject(globalPermission, projectPermission));
+ assertThat(multiMap.entries()).hasSize(2);
+
+ Map<String, Collection<NotificationChannel>> map = multiMap.asMap();
+ assertThat(map.get("user3")).containsOnly(emailChannel, twitterChannel);
+
+ verify(authorizationDao, times(0)).keepAuthorizedLoginsOnProject(eq(dbSession), anySet(), anyString(), eq(globalPermission));
+ verify(authorizationDao, times(1)).keepAuthorizedLoginsOnProject(eq(dbSession), anySet(), anyString(), eq(projectPermission));
}
}