aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-server-common
diff options
context:
space:
mode:
authorDuarte Meneses <duarte.meneses@sonarsource.com>2023-05-15 19:49:00 -0500
committersonartech <sonartech@sonarsource.com>2023-06-01 20:02:59 +0000
commit46effb33d74b5b37f097288d6bac6343a2d06a8c (patch)
treed97ed78ac7d0413214353667dcf2424101f79646 /server/sonar-server-common
parent9bc77e5b117af186e37aff6e22a0ed6da96d5ae5 (diff)
downloadsonarqube-46effb33d74b5b37f097288d6bac6343a2d06a8c.tar.gz
sonarqube-46effb33d74b5b37f097288d6bac6343a2d06a8c.zip
SONAR-18856 Refactor favorites and properties
Diffstat (limited to 'server/sonar-server-common')
-rw-r--r--server/sonar-server-common/src/it/java/org/sonar/server/favorite/FavoriteUpdaterIT.java32
-rw-r--r--server/sonar-server-common/src/main/java/org/sonar/server/favorite/FavoriteUpdater.java15
-rw-r--r--server/sonar-server-common/src/main/java/org/sonar/server/notification/DefaultNotificationManager.java76
-rw-r--r--server/sonar-server-common/src/main/java/org/sonar/server/notification/NotificationManager.java17
-rw-r--r--server/sonar-server-common/src/test/java/org/sonar/server/notification/DefaultNotificationManagerTest.java119
5 files changed, 25 insertions, 234 deletions
diff --git a/server/sonar-server-common/src/it/java/org/sonar/server/favorite/FavoriteUpdaterIT.java b/server/sonar-server-common/src/it/java/org/sonar/server/favorite/FavoriteUpdaterIT.java
index 82a496a830c..2a69e111bf7 100644
--- a/server/sonar-server-common/src/it/java/org/sonar/server/favorite/FavoriteUpdaterIT.java
+++ b/server/sonar-server-common/src/it/java/org/sonar/server/favorite/FavoriteUpdaterIT.java
@@ -26,6 +26,8 @@ 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.entity.EntityDto;
+import org.sonar.db.project.ProjectDto;
import org.sonar.db.property.PropertyQuery;
import org.sonar.db.user.UserDto;
@@ -44,7 +46,7 @@ public class FavoriteUpdaterIT {
@Test
public void put_favorite() {
- ComponentDto project = db.components().insertPrivateProject().getMainBranchComponent();
+ ProjectDto project = db.components().insertPrivateProject().getProjectDto();
UserDto user = db.users().insertUser();
assertNoFavorite(project, user);
@@ -55,23 +57,23 @@ public class FavoriteUpdaterIT {
@Test
public void do_nothing_when_no_user() {
- ComponentDto project = db.components().insertPrivateProject().getMainBranchComponent();
+ ProjectDto project = db.components().insertPrivateProject().getProjectDto();
underTest.add(dbSession, project, null, null,true);
assertThat(dbClient.propertiesDao().selectByQuery(PropertyQuery.builder()
- .setComponentUuid(project.uuid())
+ .setComponentUuid(project.getUuid())
.build(), dbSession)).isEmpty();
}
@Test
public void do_not_add_favorite_when_already_100_favorite_projects() {
UserDto user = db.users().insertUser();
- IntStream.rangeClosed(1, 100).forEach(i -> db.favorites().add(db.components().insertPrivateProject().getMainBranchComponent(), user.getUuid(), user.getName()));
+ IntStream.rangeClosed(1, 100).forEach(i -> db.favorites().add(db.components().insertPrivateProject().getProjectDto(), user.getUuid(), user.getName()));
assertThat(dbClient.propertiesDao().selectByQuery(PropertyQuery.builder()
.setUserUuid(user.getUuid())
.build(), dbSession)).hasSize(100);
- ComponentDto project = db.components().insertPrivateProject().getMainBranchComponent();
+ ProjectDto project = db.components().insertPrivateProject().getProjectDto();
underTest.add(dbSession, project, user.getUuid(), user.getLogin(), false);
@@ -83,12 +85,12 @@ public class FavoriteUpdaterIT {
@Test
public void do_not_add_favorite_when_already_100_favorite_portfolios() {
UserDto user = db.users().insertUser();
- IntStream.rangeClosed(1, 100).forEach(i -> db.favorites().add(db.components().insertPrivateProject().getMainBranchComponent(),
+ IntStream.rangeClosed(1, 100).forEach(i -> db.favorites().add(db.components().insertPrivateProject().getProjectDto(),
user.getUuid(), user.getLogin()));
assertThat(dbClient.propertiesDao().selectByQuery(PropertyQuery.builder()
.setUserUuid(user.getUuid())
.build(), dbSession)).hasSize(100);
- ComponentDto project = db.components().insertPrivateProject().getMainBranchComponent();
+ ProjectDto project = db.components().insertPrivateProject().getProjectDto();
underTest.add(dbSession, project, user.getUuid(), user.getLogin(), false);
@@ -100,9 +102,9 @@ public class FavoriteUpdaterIT {
@Test
public void fail_when_more_than_100_projects_favorites() {
UserDto user = db.users().insertUser();
- IntStream.rangeClosed(1, 100).forEach(i -> db.favorites().add(db.components().insertPrivateProject().getMainBranchComponent(),
+ IntStream.rangeClosed(1, 100).forEach(i -> db.favorites().add(db.components().insertPrivateProject().getProjectDto(),
user.getUuid(), user.getLogin()));
- ComponentDto project = db.components().insertPrivateProject().getMainBranchComponent();
+ ProjectDto project = db.components().insertPrivateProject().getProjectDto();
assertThatThrownBy(() -> underTest.add(dbSession, project, user.getUuid(), user.getLogin(), true))
.isInstanceOf(IllegalArgumentException.class)
@@ -111,27 +113,27 @@ public class FavoriteUpdaterIT {
@Test
public void fail_when_adding_existing_favorite() {
- ComponentDto project = db.components().insertPrivateProject().getMainBranchComponent();
+ ProjectDto project = db.components().insertPrivateProject().getProjectDto();
UserDto user = db.users().insertUser();
underTest.add(dbSession, project, user.getUuid(), user.getLogin(), true);
assertFavorite(project, user);
assertThatThrownBy(() -> underTest.add(dbSession, project, user.getUuid(), user.getLogin(), true))
.isInstanceOf(IllegalArgumentException.class)
- .hasMessage(String.format("Component '%s' (uuid: %s) is already a favorite", project.getKey(), project.uuid()));
+ .hasMessage(String.format("Component '%s' (uuid: %s) is already a favorite", project.getKey(), project.getUuid()));
}
- private void assertFavorite(ComponentDto project, UserDto user) {
+ private void assertFavorite(EntityDto entity, UserDto user) {
assertThat(dbClient.propertiesDao().selectByQuery(PropertyQuery.builder()
.setUserUuid(user.getUuid())
- .setComponentUuid(project.uuid())
+ .setComponentUuid(entity.getUuid())
.build(), dbSession)).hasSize(1);
}
- private void assertNoFavorite(ComponentDto project, UserDto user) {
+ private void assertNoFavorite(EntityDto entity, UserDto user) {
assertThat(dbClient.propertiesDao().selectByQuery(PropertyQuery.builder()
.setUserUuid(user.getUuid())
- .setComponentUuid(project.uuid())
+ .setComponentUuid(entity.getUuid())
.build(), dbSession)).isEmpty();
}
}
diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/favorite/FavoriteUpdater.java b/server/sonar-server-common/src/main/java/org/sonar/server/favorite/FavoriteUpdater.java
index 2fd5671d931..54940fc75a1 100644
--- a/server/sonar-server-common/src/main/java/org/sonar/server/favorite/FavoriteUpdater.java
+++ b/server/sonar-server-common/src/main/java/org/sonar/server/favorite/FavoriteUpdater.java
@@ -24,6 +24,7 @@ import javax.annotation.Nullable;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.component.ComponentDto;
+import org.sonar.db.entity.EntityDto;
import org.sonar.db.property.PropertyDto;
import org.sonar.db.property.PropertyQuery;
@@ -41,7 +42,7 @@ public class FavoriteUpdater {
/**
* Set favorite to the logged in user. If no user, no action is done
*/
- public void add(DbSession dbSession, ComponentDto componentDto, @Nullable String userUuid, @Nullable String userLogin, boolean failIfTooManyFavorites) {
+ public void add(DbSession dbSession, EntityDto entity, @Nullable String userUuid, @Nullable String userLogin, boolean failIfTooManyFavorites) {
if (userUuid == null) {
return;
}
@@ -49,21 +50,21 @@ public class FavoriteUpdater {
List<PropertyDto> existingFavoriteOnComponent = dbClient.propertiesDao().selectByQuery(PropertyQuery.builder()
.setKey(PROP_FAVORITE_KEY)
.setUserUuid(userUuid)
- .setComponentUuid(componentDto.uuid())
+ .setComponentUuid(entity.getUuid())
.build(), dbSession);
- checkArgument(existingFavoriteOnComponent.isEmpty(), "Component '%s' (uuid: %s) is already a favorite", componentDto.getKey(), componentDto.uuid());
+ checkArgument(existingFavoriteOnComponent.isEmpty(), "Component '%s' (uuid: %s) is already a favorite", entity.getKey(), entity.getUuid());
- List<PropertyDto> existingFavorites = dbClient.propertiesDao().selectByKeyAndUserUuidAndComponentQualifier(dbSession, PROP_FAVORITE_KEY, userUuid, componentDto.qualifier());
+ List<PropertyDto> existingFavorites = dbClient.propertiesDao().selectByKeyAndUserUuidAndComponentQualifier(dbSession, PROP_FAVORITE_KEY, userUuid, entity.getQualifier());
if (existingFavorites.size() >= 100) {
- checkArgument(!failIfTooManyFavorites, "You cannot have more than 100 favorites on components with qualifier '%s'", componentDto.qualifier());
+ checkArgument(!failIfTooManyFavorites, "You cannot have more than 100 favorites on components with qualifier '%s'", entity.getQualifier());
return;
}
dbClient.propertiesDao().saveProperty(dbSession, new PropertyDto()
.setKey(PROP_FAVORITE_KEY)
- .setComponentUuid(componentDto.uuid())
+ .setComponentUuid(entity.getUuid())
.setUserUuid(userUuid),
userLogin,
- componentDto.getKey(), componentDto.name(), componentDto.qualifier());
+ entity.getKey(), entity.getName(), entity.getQualifier());
}
/**
diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/notification/DefaultNotificationManager.java b/server/sonar-server-common/src/main/java/org/sonar/server/notification/DefaultNotificationManager.java
index 8b6800ae195..eed10f265f2 100644
--- a/server/sonar-server-common/src/main/java/org/sonar/server/notification/DefaultNotificationManager.java
+++ b/server/sonar-server-common/src/main/java/org/sonar/server/notification/DefaultNotificationManager.java
@@ -113,69 +113,10 @@ public class DefaultNotificationManager implements NotificationManager {
return dbClient.notificationQueueDao().count();
}
- /**
- * {@inheritDoc}
- */
- @Override
- public Multimap<String, NotificationChannel> findSubscribedRecipientsForDispatcher(NotificationDispatcher dispatcher,
- String projectKey, SubscriberPermissionsOnProject subscriberPermissionsOnProject) {
- verifyProjectKey(projectKey);
- String dispatcherKey = dispatcher.getKey();
-
- Set<SubscriberAndChannel> subscriberAndChannels = Arrays.stream(notificationChannels)
- .flatMap(notificationChannel -> toSubscriberAndChannels(dispatcherKey, projectKey, notificationChannel))
- .collect(Collectors.toSet());
-
- if (subscriberAndChannels.isEmpty()) {
- return ImmutableMultimap.of();
- }
-
- ImmutableSetMultimap.Builder<String, NotificationChannel> builder = ImmutableSetMultimap.builder();
- try (DbSession dbSession = dbClient.openSession(false)) {
- Set<String> authorizedLogins = keepAuthorizedLogins(dbSession, projectKey, subscriberAndChannels, subscriberPermissionsOnProject);
- subscriberAndChannels.stream()
- .filter(subscriberAndChannel -> authorizedLogins.contains(subscriberAndChannel.subscriber().getLogin()))
- .forEach(subscriberAndChannel -> builder.put(subscriberAndChannel.subscriber().getLogin(), subscriberAndChannel.channel()));
- }
- return builder.build();
- }
-
private static void verifyProjectKey(String projectKey) {
requireNonNull(projectKey, "projectKey is mandatory");
}
- private Stream<SubscriberAndChannel> toSubscriberAndChannels(String dispatcherKey, String projectKey, NotificationChannel notificationChannel) {
- Set<Subscriber> usersForNotification = dbClient.propertiesDao().findUsersForNotification(dispatcherKey, notificationChannel.getKey(), projectKey);
- return usersForNotification
- .stream()
- .map(login -> new SubscriberAndChannel(login, notificationChannel));
- }
-
- private Set<String> keepAuthorizedLogins(DbSession dbSession, String projectKey, Set<SubscriberAndChannel> subscriberAndChannels,
- SubscriberPermissionsOnProject requiredPermissions) {
- if (requiredPermissions.getGlobalSubscribers().equals(requiredPermissions.getProjectSubscribers())) {
- return keepAuthorizedLogins(dbSession, projectKey, subscriberAndChannels, null, requiredPermissions.getGlobalSubscribers());
- } else {
- return Stream
- .concat(
- keepAuthorizedLogins(dbSession, projectKey, subscriberAndChannels, true, requiredPermissions.getGlobalSubscribers()).stream(),
- keepAuthorizedLogins(dbSession, projectKey, subscriberAndChannels, false, requiredPermissions.getProjectSubscribers()).stream())
- .collect(Collectors.toSet());
- }
- }
-
- private Set<String> keepAuthorizedLogins(DbSession dbSession, String projectKey, Set<SubscriberAndChannel> subscriberAndChannels,
- @Nullable Boolean global, String permission) {
- Set<String> logins = subscriberAndChannels.stream()
- .filter(s -> global == null || s.subscriber().isGlobal() == global)
- .map(s -> s.subscriber().getLogin())
- .collect(Collectors.toSet());
- if (logins.isEmpty()) {
- return Collections.emptySet();
- }
- return dbClient.authorizationDao().keepAuthorizedLoginsOnProject(dbSession, logins, projectKey, permission);
- }
-
@Override
public Set<EmailRecipient> findSubscribedEmailRecipients(String dispatcherKey, String projectKey, SubscriberPermissionsOnProject subscriberPermissionsOnProject) {
verifyProjectKey(projectKey);
@@ -244,23 +185,6 @@ public class DefaultNotificationManager implements NotificationManager {
.filter(s -> authorizedLogins.contains(s.getLogin()));
}
- private record SubscriberAndChannel(Subscriber subscriber, NotificationChannel channel) {
-
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
- if (o == null || getClass() != o.getClass()) {
- return false;
- }
- SubscriberAndChannel that = (SubscriberAndChannel) o;
- return Objects.equals(subscriber, that.subscriber) &&
- Objects.equals(channel, that.channel);
- }
-
- }
-
@VisibleForTesting
protected List<NotificationChannel> getChannels() {
return Arrays.asList(notificationChannels);
diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/notification/NotificationManager.java b/server/sonar-server-common/src/main/java/org/sonar/server/notification/NotificationManager.java
index 6517c4ee9a1..be336191a8f 100644
--- a/server/sonar-server-common/src/main/java/org/sonar/server/notification/NotificationManager.java
+++ b/server/sonar-server-common/src/main/java/org/sonar/server/notification/NotificationManager.java
@@ -44,23 +44,6 @@ public interface NotificationManager {
*/
<T extends Notification> void scheduleForSending(T notification);
- /**
- * <p>
- * Returns the list of users who subscribed to the given dispatcher, along with the notification channels (email, twitter, ...) that they choose
- * for this dispatcher.
- * </p>
- * <p>
- * The resource ID can be null in case of notifications that have nothing to do with a specific project (like system notifications).
- * </p>
- *
- * @param dispatcher the dispatcher for which this list of users is requested
- * @param projectKey key 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 projectKey,
- SubscriberPermissionsOnProject subscriberPermissionsOnProject);
-
record EmailRecipient(String login, String email) {
public EmailRecipient(String login, String email) {
this.login = requireNonNull(login, "login can't be null");
diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/notification/DefaultNotificationManagerTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/notification/DefaultNotificationManagerTest.java
index d07f5d1567a..310615af703 100644
--- a/server/sonar-server-common/src/test/java/org/sonar/server/notification/DefaultNotificationManagerTest.java
+++ b/server/sonar-server-common/src/test/java/org/sonar/server/notification/DefaultNotificationManagerTest.java
@@ -143,125 +143,6 @@ public class DefaultNotificationManagerTest {
}
@Test
- public void shouldFindNoRecipient() {
- assertThat(underTest.findSubscribedRecipientsForDispatcher(dispatcher, "uuid_45", new SubscriberPermissionsOnProject(UserRole.USER)).asMap().entrySet())
- .isEmpty();
- }
-
- @Test
- public void shouldFindSubscribedRecipientForGivenResource() {
- String projectKey = randomAlphabetic(6);
- String otherProjectKey = randomAlphabetic(7);
- when(propertiesDao.findUsersForNotification("NewViolations", "Email", projectKey))
- .thenReturn(newHashSet(new Subscriber("user1", false), new Subscriber("user3", false), new Subscriber("user3", true)));
- when(propertiesDao.findUsersForNotification("NewViolations", "Twitter", otherProjectKey))
- .thenReturn(newHashSet(new Subscriber("user2", false)));
- when(propertiesDao.findUsersForNotification("NewViolations", "Twitter", projectKey))
- .thenReturn(newHashSet(new Subscriber("user3", true)));
- when(propertiesDao.findUsersForNotification("NewAlerts", "Twitter", projectKey))
- .thenReturn(newHashSet(new Subscriber("user4", false)));
-
- when(authorizationDao.keepAuthorizedLoginsOnProject(dbSession, newHashSet("user1", "user3"), projectKey, "user"))
- .thenReturn(newHashSet("user1", "user3"));
-
- Multimap<String, NotificationChannel> multiMap = underTest.findSubscribedRecipientsForDispatcher(dispatcher, projectKey,
- 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 = randomAlphanumeric(4);
- String projectPermission = randomAlphanumeric(5);
- String projectKey = randomAlphabetic(6);
- String otherProjectKey = randomAlphabetic(7);
- when(propertiesDao.findUsersForNotification("NewViolations", "Email", projectKey))
- .thenReturn(newHashSet(new Subscriber("user1", false), new Subscriber("user3", false), new Subscriber("user3", true)));
- when(propertiesDao.findUsersForNotification("NewViolations", "Twitter", otherProjectKey))
- .thenReturn(newHashSet(new Subscriber("user2", false)));
- when(propertiesDao.findUsersForNotification("NewViolations", "Twitter", projectKey))
- .thenReturn(newHashSet(new Subscriber("user3", true)));
- when(propertiesDao.findUsersForNotification("NewAlerts", "Twitter", projectKey))
- .thenReturn(newHashSet(new Subscriber("user4", false)));
-
- when(authorizationDao.keepAuthorizedLoginsOnProject(dbSession, newHashSet("user3", "user4"), projectKey, globalPermission))
- .thenReturn(newHashSet("user3"));
- when(authorizationDao.keepAuthorizedLoginsOnProject(dbSession, newHashSet("user1", "user3"), projectKey, projectPermission))
- .thenReturn(newHashSet("user1", "user3"));
-
- Multimap<String, NotificationChannel> multiMap = underTest.findSubscribedRecipientsForDispatcher(dispatcher, projectKey,
- new SubscriberPermissionsOnProject(globalPermission, projectPermission));
- 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 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 = randomAlphanumeric(4);
- String projectPermission = randomAlphanumeric(5);
- String projectKey = randomAlphabetic(6);
- when(propertiesDao.findUsersForNotification("NewViolations", "Email", projectKey))
- .thenReturn(newHashSet(new Subscriber("user3", true)));
- when(propertiesDao.findUsersForNotification("NewViolations", "Twitter", projectKey))
- .thenReturn(newHashSet(new Subscriber("user3", true)));
-
- when(authorizationDao.keepAuthorizedLoginsOnProject(dbSession, newHashSet("user3"), projectKey, globalPermission))
- .thenReturn(newHashSet("user3"));
-
- Multimap<String, NotificationChannel> multiMap = underTest.findSubscribedRecipientsForDispatcher(dispatcher, projectKey,
- 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 = randomAlphanumeric(4);
- String projectPermission = randomAlphanumeric(5);
- String projectKey = randomAlphabetic(6);
- when(propertiesDao.findUsersForNotification("NewViolations", "Email", projectKey))
- .thenReturn(newHashSet(new Subscriber("user3", false)));
- when(propertiesDao.findUsersForNotification("NewViolations", "Twitter", projectKey))
- .thenReturn(newHashSet(new Subscriber("user3", false)));
-
- when(authorizationDao.keepAuthorizedLoginsOnProject(dbSession, newHashSet("user3"), projectKey, projectPermission))
- .thenReturn(newHashSet("user3"));
-
- Multimap<String, NotificationChannel> multiMap = underTest.findSubscribedRecipientsForDispatcher(dispatcher, projectKey,
- 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));
- }
-
- @Test
public void findSubscribedEmailRecipients_fails_with_NPE_if_projectKey_is_null() {
String dispatcherKey = randomAlphabetic(12);