[AB-154] split up private and guild message received handler, split handlers into async and sync handlers

adapting the tests and improving tests to reduce usage of MockUtils
adding some util methods to message bean
extending cache for cached messages
enabling to build cached messages from messages in DM channels (they are not part of the message cache)
splitting multiple listeners to different beans, for better overview (emote updated)
adding convenience service for reactions specifically
split cached reaction and cached reactions, singular only contains one user, while the later contains all users
fixing liquibase configuration for assigned role user
fixing assignable role not having a transaction
moved caching update a bit earlier in various methods
fixing bug that a manual unmute caused duplicate unmute notification
fixing short scheduled unmute not checking the new mute state
limiting parameters for roll
This commit is contained in:
Sheldan
2020-12-20 19:21:24 +01:00
parent 69aa82e26e
commit fb3ed69650
200 changed files with 4253 additions and 1813 deletions

View File

@@ -1,26 +1,30 @@
package dev.sheldan.abstracto.moderation.listener;
import dev.sheldan.abstracto.core.config.FeatureEnum;
import dev.sheldan.abstracto.core.config.ListenerPriority;
import dev.sheldan.abstracto.core.listener.MessageDeletedListener;
import dev.sheldan.abstracto.core.models.AServerAChannelAUser;
import dev.sheldan.abstracto.core.models.GuildChannelMember;
import dev.sheldan.abstracto.core.listener.async.jda.AsyncMessageDeletedListener;
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
import dev.sheldan.abstracto.core.service.BotService;
import dev.sheldan.abstracto.core.service.PostTargetService;
import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.core.utils.ContextUtils;
import dev.sheldan.abstracto.moderation.config.features.ModerationFeatures;
import dev.sheldan.abstracto.moderation.config.posttargets.LoggingPostTarget;
import dev.sheldan.abstracto.templating.model.MessageToSend;
import dev.sheldan.abstracto.core.service.PostTargetService;
import dev.sheldan.abstracto.core.utils.ContextUtils;
import dev.sheldan.abstracto.moderation.models.template.listener.MessageDeletedAttachmentLog;
import dev.sheldan.abstracto.moderation.models.template.listener.MessageDeletedLog;
import dev.sheldan.abstracto.templating.model.MessageToSend;
import dev.sheldan.abstracto.templating.service.TemplateService;
import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.TextChannel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
@Component
@Slf4j
public class MessageDeleteLogListener implements MessageDeletedListener {
public class MessageDeleteLogListener implements AsyncMessageDeletedListener {
public static final String MESSAGE_DELETED_TEMPLATE = "message_deleted";
public static final String MESSAGE_DELETED_ATTACHMENT_TEMPLATE = "message_deleted_attachment";
@@ -34,36 +38,52 @@ public class MessageDeleteLogListener implements MessageDeletedListener {
@Autowired
private PostTargetService postTargetService;
@Autowired
private BotService botService;
@Autowired
private ChannelManagementService channelManagementService;
@Autowired
private ServerManagementService serverManagementService;
@Autowired
private UserInServerManagementService userInServerManagementService;
@Autowired
private MessageDeleteLogListener self;
@Override
public void execute(CachedMessage messageFromCache, AServerAChannelAUser authorUser, GuildChannelMember authorMember) {
public void execute(CachedMessage messageFromCache) {
botService.getMemberInServerAsync(messageFromCache.getServerId(), messageFromCache.getAuthor().getAuthorId()).thenAccept(member ->
self.executeListener(messageFromCache, member)
);
}
@Transactional
public void executeListener(CachedMessage messageFromCache, Member authorMember) {
log.trace("Message {} in channel {} in guild {} was deleted.", messageFromCache.getMessageId(), messageFromCache.getChannelId(), messageFromCache.getServerId());
TextChannel textChannel = botService.getTextChannelFromServer(messageFromCache.getServerId(), messageFromCache.getChannelId());
MessageDeletedLog logModel = MessageDeletedLog
.builder()
.cachedMessage(messageFromCache)
.server(authorUser.getGuild())
.channel(authorUser.getChannel())
.user(authorUser.getUser())
.aUserInAServer(authorUser.getAUserInAServer())
.guild(authorMember.getGuild())
.messageChannel(authorMember.getTextChannel())
.member(authorMember.getMember())
.channel(textChannel)
.member(authorMember)
.build();
MessageToSend message = templateService.renderEmbedTemplate(MESSAGE_DELETED_TEMPLATE, logModel);
postTargetService.sendEmbedInPostTarget(message, LoggingPostTarget.DELETE_LOG, messageFromCache.getServerId());
if(messageFromCache.getAttachmentUrls() != null){
log.trace("Notifying about deletions of {} attachments.", messageFromCache.getAttachmentUrls().size());
for (int i = 0; i < messageFromCache.getAttachmentUrls().size(); i++) {
if(messageFromCache.getAttachments() != null){
log.trace("Notifying about deletions of {} attachments.", messageFromCache.getAttachments().size());
for (int i = 0; i < messageFromCache.getAttachments().size(); i++) {
MessageDeletedAttachmentLog log = MessageDeletedAttachmentLog
.builder()
.imageUrl(messageFromCache.getAttachmentUrls().get(i))
.imageUrl(messageFromCache.getAttachments().get(i).getProxyUrl())
.counter(i + 1)
.server(authorUser.getGuild())
.channel(authorUser.getChannel())
.user(authorUser.getUser())
.aUserInAServer(authorUser.getAUserInAServer())
.guild(authorMember.getGuild())
.messageChannel(authorMember.getTextChannel())
.member(authorMember.getMember())
.channel(textChannel)
.member(authorMember)
.build();
MessageToSend attachmentEmbed = templateService.renderEmbedTemplate(MESSAGE_DELETED_ATTACHMENT_TEMPLATE, log);
postTargetService.sendEmbedInPostTarget(attachmentEmbed, LoggingPostTarget.DELETE_LOG, messageFromCache.getServerId());
@@ -76,8 +96,4 @@ public class MessageDeleteLogListener implements MessageDeletedListener {
return ModerationFeatures.LOGGING;
}
@Override
public Integer getPriority() {
return ListenerPriority.MEDIUM;
}
}

View File

@@ -1,24 +1,23 @@
package dev.sheldan.abstracto.moderation.listener;
import dev.sheldan.abstracto.core.config.FeatureEnum;
import dev.sheldan.abstracto.core.config.ListenerPriority;
import dev.sheldan.abstracto.core.listener.MessageTextUpdatedListener;
import dev.sheldan.abstracto.core.listener.async.jda.AsyncMessageTextUpdatedListener;
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
import dev.sheldan.abstracto.core.service.BotService;
import dev.sheldan.abstracto.core.service.PostTargetService;
import dev.sheldan.abstracto.moderation.config.features.ModerationFeatures;
import dev.sheldan.abstracto.moderation.config.posttargets.LoggingPostTarget;
import dev.sheldan.abstracto.templating.model.MessageToSend;
import dev.sheldan.abstracto.core.service.PostTargetService;
import dev.sheldan.abstracto.moderation.models.template.listener.MessageEditedLog;
import dev.sheldan.abstracto.templating.model.MessageToSend;
import dev.sheldan.abstracto.templating.service.TemplateService;
import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.TextChannel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@Slf4j
public class MessageEditedListener implements MessageTextUpdatedListener {
public class MessageEditedListener implements AsyncMessageTextUpdatedListener {
public static final String MESSAGE_EDITED_TEMPLATE = "message_edited";
@@ -28,24 +27,33 @@ public class MessageEditedListener implements MessageTextUpdatedListener {
@Autowired
private PostTargetService postTargetService;
@Autowired
private BotService botService;
@Override
@Transactional
public void execute(CachedMessage messageBefore, Message messageAfter) {
if(messageBefore.getContent().equals(messageAfter.getContentRaw())){
public void execute(CachedMessage messageBefore, CachedMessage messageAfter) {
if(messageBefore.getContent().equals(messageAfter.getContent())) {
log.trace("Message content was the same. Possible reason was: message was not in cache.");
return;
}
log.trace("Message {} in channel {} in guild {} was edited.", messageBefore.getMessageId(), messageBefore.getChannelId(), messageBefore.getServerId());
MessageEditedLog log = MessageEditedLog
.builder()
.messageAfter(messageAfter)
.messageBefore(messageBefore)
.messageChannel(messageAfter.getTextChannel())
.guild(messageAfter.getGuild())
.member(messageAfter.getMember())
.build();
MessageToSend message = templateService.renderEmbedTemplate(MESSAGE_EDITED_TEMPLATE, log);
postTargetService.sendEmbedInPostTarget(message, LoggingPostTarget.EDIT_LOG, messageBefore.getServerId());
botService.getMemberInServerAsync(messageAfter.getServerId(), messageAfter.getAuthor().getAuthorId()).thenAccept(author -> {
log.trace("Message {} in channel {} in guild {} was edited.", messageBefore.getMessageId(), messageBefore.getChannelId(), messageBefore.getServerId());
TextChannel textChannel = botService.getTextChannelFromServer(messageAfter.getServerId(), messageAfter.getChannelId());
MessageEditedLog log = MessageEditedLog
.builder()
.messageAfter(messageAfter)
.messageBefore(messageBefore)
.messageChannel(textChannel)
.guild(textChannel.getGuild())
.member(author)
.build();
MessageToSend message = templateService.renderEmbedTemplate(MESSAGE_EDITED_TEMPLATE, log);
postTargetService.sendEmbedInPostTarget(message, LoggingPostTarget.EDIT_LOG, messageBefore.getServerId());
}).exceptionally(throwable -> {
log.error("Failed to load member {} for message edited listener in server {} for message {} in channel {}.",
messageAfter.getAuthor().getAuthorId(), messageAfter.getServerId(), messageAfter.getMessageId(), messageAfter.getChannelId(), throwable);
return null;
});
}
@Override
@@ -53,8 +61,4 @@ public class MessageEditedListener implements MessageTextUpdatedListener {
return ModerationFeatures.LOGGING;
}
@Override
public Integer getPriority() {
return ListenerPriority.MEDIUM;
}
}

View File

@@ -1,13 +1,12 @@
package dev.sheldan.abstracto.moderation.listener;
import dev.sheldan.abstracto.core.listener.ServerConfigListener;
import dev.sheldan.abstracto.core.listener.sync.entity.ServerConfigListener;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.service.management.ConfigManagementService;
import dev.sheldan.abstracto.core.service.management.DefaultConfigManagementService;
import dev.sheldan.abstracto.moderation.config.features.WarningDecayFeature;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component

View File

@@ -1,25 +1,25 @@
package dev.sheldan.abstracto.moderation.listener;
package dev.sheldan.abstracto.moderation.listener.async;
import dev.sheldan.abstracto.core.config.FeatureEnum;
import dev.sheldan.abstracto.core.config.ListenerPriority;
import dev.sheldan.abstracto.core.listener.JoinListener;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.listener.async.jda.AsyncJoinListener;
import dev.sheldan.abstracto.core.models.ServerUser;
import dev.sheldan.abstracto.core.service.BotService;
import dev.sheldan.abstracto.core.service.PostTargetService;
import dev.sheldan.abstracto.moderation.config.features.ModerationFeatures;
import dev.sheldan.abstracto.moderation.config.posttargets.LoggingPostTarget;
import dev.sheldan.abstracto.templating.service.TemplateService;
import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.HashMap;
@Service
@Slf4j
public class JoinLogger implements JoinListener {
public class JoinLogger implements AsyncJoinListener {
public static final String USER_JOIN_TEMPLATE = "user_join";
@@ -29,6 +29,11 @@ public class JoinLogger implements JoinListener {
@Autowired
private PostTargetService postTargetService;
@Autowired
private BotService botService;
@Autowired
private JoinLogger self;
private HashMap<String, Object> getUserParameter(User user) {
HashMap<String, Object> parameters = new HashMap<>();
@@ -37,11 +42,18 @@ public class JoinLogger implements JoinListener {
}
@Override
public void execute(Member member, Guild guild, AUserInAServer aUserInAServer) {
log.info("User {} joined server {}.", aUserInAServer.getUserReference().getId(), aUserInAServer.getServerReference().getId());
public void execute(ServerUser serverUser) {
log.info("User {} joined server {}.", serverUser.getUserId(), serverUser.getServerId());
botService.getMemberInServerAsync(serverUser.getServerId(), serverUser.getUserId()).thenAccept(member ->
self.sendJoinLog(serverUser, member)
);
}
@Transactional
public void sendJoinLog(ServerUser serverUser, Member member) {
HashMap<String, Object> parameters = getUserParameter(member.getUser());
String text = templateService.renderTemplateWithMap(USER_JOIN_TEMPLATE, parameters);
postTargetService.sendTextInPostTarget(text, LoggingPostTarget.JOIN_LOG, guild.getIdLong());
postTargetService.sendTextInPostTarget(text, LoggingPostTarget.JOIN_LOG, serverUser.getServerId());
}
@Override
@@ -49,8 +61,4 @@ public class JoinLogger implements JoinListener {
return ModerationFeatures.LOGGING;
}
@Override
public Integer getPriority() {
return ListenerPriority.MEDIUM;
}
}

View File

@@ -1,21 +1,20 @@
package dev.sheldan.abstracto.moderation.listener;
package dev.sheldan.abstracto.moderation.listener.async;
import dev.sheldan.abstracto.core.config.FeatureEnum;
import dev.sheldan.abstracto.core.config.ListenerPriority;
import dev.sheldan.abstracto.core.listener.JoinListener;
import dev.sheldan.abstracto.core.listener.async.jda.AsyncJoinListener;
import dev.sheldan.abstracto.core.models.ServerUser;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.moderation.config.features.ModerationFeatures;
import dev.sheldan.abstracto.moderation.service.MuteService;
import dev.sheldan.abstracto.moderation.service.management.MuteManagementService;
import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Member;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
@Slf4j
public class JoinMuteListener implements JoinListener {
public class JoinMuteListener implements AsyncJoinListener {
@Autowired
private MuteManagementService muteManagementService;
@@ -23,10 +22,14 @@ public class JoinMuteListener implements JoinListener {
@Autowired
private MuteService muteService;
@Autowired
private UserInServerManagementService userInServerManagementService;
@Override
public void execute(Member member, Guild guild, AUserInAServer aUserInAServer) {
public void execute(ServerUser serverUser) {
AUserInAServer aUserInAServer = userInServerManagementService.loadUser(serverUser.getServerId(), serverUser.getUserId());
if(muteManagementService.hasActiveMute(aUserInAServer)) {
log.info("Re-muting user {} which joined the server {}, because the mute has not ended yet.", member.getIdLong(), guild.getIdLong());
log.info("Re-muting user {} which joined the server {}, because the mute has not ended yet.", serverUser.getUserId(), serverUser.getServerId());
muteService.applyMuteRole(aUserInAServer);
}
}
@@ -36,8 +39,4 @@ public class JoinMuteListener implements JoinListener {
return ModerationFeatures.MUTING;
}
@Override
public Integer getPriority() {
return ListenerPriority.HIGH;
}
}

View File

@@ -1,26 +1,27 @@
package dev.sheldan.abstracto.moderation.listener;
package dev.sheldan.abstracto.moderation.listener.async;
import dev.sheldan.abstracto.core.config.FeatureEnum;
import dev.sheldan.abstracto.core.config.ListenerPriority;
import dev.sheldan.abstracto.core.listener.LeaveListener;
import dev.sheldan.abstracto.core.listener.async.jda.AsyncLeaveListener;
import dev.sheldan.abstracto.core.models.ServerUser;
import dev.sheldan.abstracto.core.service.BotService;
import dev.sheldan.abstracto.core.service.PostTargetService;
import dev.sheldan.abstracto.moderation.config.features.ModerationFeatures;
import dev.sheldan.abstracto.moderation.config.posttargets.LoggingPostTarget;
import dev.sheldan.abstracto.templating.service.TemplateService;
import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.User;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Nonnull;
import java.util.HashMap;
@Service
@Slf4j
public class LeaveLogger implements LeaveListener {
public class LeaveLogger implements AsyncLeaveListener {
public static final String USER_LEAVE_TEMPLATE = "user_leave";
@@ -30,6 +31,11 @@ public class LeaveLogger implements LeaveListener {
@Autowired
private PostTargetService postTargetService;
@Autowired
private BotService botService;
@Autowired
private LeaveLogger self;
@NotNull
private HashMap<String, Object> getUserParameter(@Nonnull User user) {
@@ -40,10 +46,17 @@ public class LeaveLogger implements LeaveListener {
}
@Override
public void execute(Member member, Guild guild) {
log.info("User {} left server {}.", member.getUser().getId(), guild.getIdLong());
public void execute(ServerUser serverUser) {
log.info("User {} left server {}.", serverUser.getUserId(), serverUser.getServerId());
botService.getMemberInServerAsync(serverUser.getServerId(), serverUser.getUserId()).thenAccept(member ->
self.executeJoinLogging(serverUser, member)
);
}
@Transactional
public void executeJoinLogging(ServerUser serverUser, Member member) {
String text = templateService.renderTemplateWithMap(USER_LEAVE_TEMPLATE, getUserParameter(member.getUser()));
postTargetService.sendTextInPostTarget(text, LoggingPostTarget.LEAVE_LOG, guild.getIdLong());
postTargetService.sendTextInPostTarget(text, LoggingPostTarget.LEAVE_LOG, serverUser.getServerId());
}
@Override
@@ -51,8 +64,4 @@ public class LeaveLogger implements LeaveListener {
return ModerationFeatures.LOGGING;
}
@Override
public Integer getPriority() {
return ListenerPriority.MEDIUM;
}
}

View File

@@ -268,15 +268,11 @@ public class MuteServiceBean implements MuteService {
throw new NoMuteFoundException();
}
Mute mute = muteManagementService.getAMuteOf(aUserInAServer);
if(Boolean.TRUE.equals(mute.getMuteEnded())) {
log.info("Mute {} has ended already, user {} does not need to be unMuted anymore.", mute.getMuteId().getId(), mute.getMutedUser().getUserReference().getId());
return CompletableFuture.completedFuture(null);
}
Long muteId = mute.getMuteId().getId();
CompletableFuture<Member> mutingMemberFuture = botService.getMemberInServerAsync(mute.getMutingUser());
CompletableFuture<Member> mutedMemberFuture = botService.getMemberInServerAsync(mute.getMutedUser());
Guild guild = botService.getGuildById(mute.getServer().getId());
return endMute(mute).thenCompose(unused ->
Guild guild = botService.getGuildById(mute.getMuteId().getServerId());
return endMute(mute, false).thenCompose(unused ->
CompletableFuture.allOf(mutingMemberFuture, mutedMemberFuture)
).thenCompose(unused -> self.sendUnMuteLogForManualUnMute(muteId, mutingMemberFuture, mutedMemberFuture, guild));
}
@@ -296,7 +292,11 @@ public class MuteServiceBean implements MuteService {
}
@Override
public CompletableFuture<Void> endMute(Mute mute) {
public CompletableFuture<Void> endMute(Mute mute, Boolean sendNotification) {
if(mute.getMuteEnded()) {
log.info("Mute {} in server {} has already ended. Not unmuting.", mute.getMuteId().getId(), mute.getMuteId().getServerId());
return CompletableFuture.completedFuture(null);
}
Long muteId = mute.getMuteId().getId();
AServer mutingServer = mute.getServer();
log.info("UnMuting {} in server {}", mute.getMutedUser().getUserReference().getId(), mutingServer.getId());
@@ -315,9 +315,13 @@ public class MuteServiceBean implements MuteService {
CompletableFuture<Member> mutedMemberFuture = botService.getMemberInServerAsync(mute.getMutedUser());
CompletableFuture<Void> finalFuture = new CompletableFuture<>();
CompletableFuture.allOf(mutingMemberFuture, mutedMemberFuture, roleRemovalFuture, mutingMemberFuture, mutedMemberFuture).handle((aVoid, throwable) -> {
self.sendUnmuteLog(muteId, guild, mutingMemberFuture, mutedMemberFuture).thenAccept(aVoid1 ->
finalFuture.complete(null)
);
if(sendNotification) {
self.sendUnmuteLog(muteId, guild, mutingMemberFuture, mutedMemberFuture).thenAccept(aVoid1 ->
finalFuture.complete(null)
);
} else {
finalFuture.complete(null);
}
return null;
});
@@ -357,7 +361,7 @@ public class MuteServiceBean implements MuteService {
log.info("UnMuting the mute {} in server {}", muteId, serverId);
Optional<Mute> muteOptional = muteManagementService.findMuteOptional(muteId, serverId);
if(muteOptional.isPresent()) {
return endMute(muteOptional.get());
return endMute(muteOptional.get(), true);
} else {
throw new NoMuteFoundException();
}

View File

@@ -1,20 +1,20 @@
package dev.sheldan.abstracto.moderation.listener;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.models.ServerUser;
import dev.sheldan.abstracto.core.service.BotService;
import dev.sheldan.abstracto.core.service.PostTargetService;
import dev.sheldan.abstracto.moderation.config.posttargets.LoggingPostTarget;
import dev.sheldan.abstracto.moderation.listener.async.JoinLogger;
import dev.sheldan.abstracto.templating.service.TemplateService;
import dev.sheldan.abstracto.core.test.MockUtils;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Member;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;
import java.util.concurrent.CompletableFuture;
import static org.mockito.Mockito.*;
@RunWith(MockitoJUnitRunner.class)
@@ -29,17 +29,37 @@ public class JoinLoggerTest {
@Mock
private PostTargetService postTargetService;
@Mock
private BotService botService;
@Mock
private JoinLogger self;
@Mock
private ServerUser serverUser;
@Mock
private Member member;
private static final Long SERVER_ID = 1L;
private static final Long USER_ID = 2L;
@Test
public void executeListener() {
Member joiningMember = Mockito.mock(Member.class);
Guild guild = Mockito.mock(Guild.class);
Long guildId = 6L;
when(guild.getIdLong()).thenReturn(guildId);
AServer server = MockUtils.getServer();
AUserInAServer aUserInAServer = MockUtils.getUserObject(5L, server);
public void testExecute() {
when(serverUser.getUserId()).thenReturn(USER_ID);
when(serverUser.getServerId()).thenReturn(SERVER_ID);
when(botService.getMemberInServerAsync(SERVER_ID, USER_ID)).thenReturn(CompletableFuture.completedFuture(member));
testUnit.execute(serverUser);
verify(self, times(1)).sendJoinLog(serverUser, member);
}
@Test
public void testJoinLog() {
String message = "text";
when(serverUser.getServerId()).thenReturn(SERVER_ID);
when(templateService.renderTemplateWithMap(eq(JoinLogger.USER_JOIN_TEMPLATE), any())).thenReturn(message);
testUnit.execute(joiningMember, guild, aUserInAServer);
verify(postTargetService, times(1)).sendTextInPostTarget(message, LoggingPostTarget.JOIN_LOG, guildId);
testUnit.sendJoinLog(serverUser, member);
verify(postTargetService, times(1)).sendTextInPostTarget(message, LoggingPostTarget.JOIN_LOG, SERVER_ID);
}
}

View File

@@ -1,6 +1,9 @@
package dev.sheldan.abstracto.moderation.listener;
import dev.sheldan.abstracto.core.models.ServerUser;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.moderation.listener.async.JoinMuteListener;
import dev.sheldan.abstracto.moderation.service.MuteService;
import dev.sheldan.abstracto.moderation.service.management.MuteManagementService;
import net.dv8tion.jda.api.entities.Guild;
@@ -25,6 +28,9 @@ public class JoinMuteListenerTest {
@Mock
private MuteService muteService;
@Mock
private UserInServerManagementService userInServerManagementService;
@Mock
private Member member;
@@ -34,17 +40,29 @@ public class JoinMuteListenerTest {
@Mock
private AUserInAServer joiningUser;
@Mock
private ServerUser serverUser;
private static final Long SERVER_ID = 3L;
private static final Long USER_ID = 4L;
@Test
public void testNonMutedUserJoins() {
when(serverUser.getServerId()).thenReturn(SERVER_ID);
when(serverUser.getUserId()).thenReturn(USER_ID);
when(userInServerManagementService.loadUser(SERVER_ID, USER_ID)).thenReturn(joiningUser);
when(muteManagementService.hasActiveMute(joiningUser)).thenReturn(false);
testUnit.execute(member, guild, joiningUser);
testUnit.execute(serverUser);
verify(muteService, times(0)).applyMuteRole(joiningUser);
}
@Test
public void testMutedUserJoins() {
when(serverUser.getServerId()).thenReturn(SERVER_ID);
when(serverUser.getUserId()).thenReturn(USER_ID);
when(userInServerManagementService.loadUser(SERVER_ID, USER_ID)).thenReturn(joiningUser);
when(muteManagementService.hasActiveMute(joiningUser)).thenReturn(true);
testUnit.execute(member, guild, joiningUser);
testUnit.execute(serverUser);
verify(muteService, times(1)).applyMuteRole(joiningUser);
}
}

View File

@@ -1,9 +1,11 @@
package dev.sheldan.abstracto.moderation.listener;
import dev.sheldan.abstracto.core.models.ServerUser;
import dev.sheldan.abstracto.core.service.BotService;
import dev.sheldan.abstracto.core.service.PostTargetService;
import dev.sheldan.abstracto.moderation.config.posttargets.LoggingPostTarget;
import dev.sheldan.abstracto.moderation.listener.async.LeaveLogger;
import dev.sheldan.abstracto.templating.service.TemplateService;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.User;
import org.junit.Test;
@@ -13,6 +15,8 @@ import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;
import java.util.concurrent.CompletableFuture;
import static org.mockito.Mockito.*;
@RunWith(MockitoJUnitRunner.class)
@@ -27,18 +31,39 @@ public class LeaveLoggerTest {
@Mock
private PostTargetService postTargetService;
@Mock
private BotService botService;
@Mock
private LeaveLogger self;
@Mock
private ServerUser leavingUser;
@Mock
private Member member;
private static final Long SERVER_ID = 1L;
private static final Long USER_ID = 2L;
@Test
public void testExecute() {
when(leavingUser.getUserId()).thenReturn(USER_ID);
when(leavingUser.getServerId()).thenReturn(SERVER_ID);
when(botService.getMemberInServerAsync(SERVER_ID, USER_ID)).thenReturn(CompletableFuture.completedFuture(member));
testUnit.execute(leavingUser);
verify(self, times(1)).executeJoinLogging(leavingUser, member);
}
@Test
public void executeListener() {
Member leavingMember = Mockito.mock(Member.class);
Guild guild = Mockito.mock(Guild.class);
User user = Mockito.mock(User.class);
when(leavingMember.getUser()).thenReturn(user);
Long guildId = 6L;
when(guild.getIdLong()).thenReturn(guildId);
when(member.getUser()).thenReturn(user);
String message = "text";
when(leavingUser.getServerId()).thenReturn(SERVER_ID);
when(templateService.renderTemplateWithMap(eq(LeaveLogger.USER_LEAVE_TEMPLATE), any())).thenReturn(message);
testUnit.execute(leavingMember, guild);
verify(postTargetService, times(1)).sendTextInPostTarget(message, LoggingPostTarget.LEAVE_LOG, guildId);
testUnit.executeJoinLogging(leavingUser, member);
verify(postTargetService, times(1)).sendTextInPostTarget(message, LoggingPostTarget.LEAVE_LOG, SERVER_ID);
}
}

View File

@@ -1,24 +1,22 @@
package dev.sheldan.abstracto.moderation.listener;
import dev.sheldan.abstracto.core.models.AServerAChannelAUser;
import dev.sheldan.abstracto.core.models.GuildChannelMember;
import dev.sheldan.abstracto.core.models.cache.CachedAttachment;
import dev.sheldan.abstracto.core.models.cache.CachedAuthor;
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
import dev.sheldan.abstracto.core.models.database.AChannel;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.service.BotService;
import dev.sheldan.abstracto.core.service.PostTargetService;
import dev.sheldan.abstracto.core.utils.ContextUtils;
import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.moderation.config.posttargets.LoggingPostTarget;
import dev.sheldan.abstracto.moderation.models.template.listener.MessageDeletedAttachmentLog;
import dev.sheldan.abstracto.moderation.models.template.listener.MessageDeletedLog;
import dev.sheldan.abstracto.templating.model.MessageToSend;
import dev.sheldan.abstracto.templating.service.TemplateService;
import dev.sheldan.abstracto.core.test.MockUtils;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.TextChannel;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.*;
@@ -26,6 +24,7 @@ import org.mockito.junit.MockitoJUnitRunner;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import static org.mockito.Mockito.*;
@@ -34,17 +33,26 @@ public class MessageDeleteLogListenerTest {
@InjectMocks
private MessageDeleteLogListener testUnit;
@Mock
private ContextUtils contextUtils;
@Mock
private TemplateService templateService;
@Mock
private PostTargetService postTargetService;
private AServerAChannelAUser authorUser;
private GuildChannelMember authorMember;
@Mock
private BotService botService;
@Mock
private ChannelManagementService channelManagementService;
@Mock
private ServerManagementService serverManagementService;
@Mock
private UserInServerManagementService userInServerManagementService;
@Mock
private MessageDeleteLogListener self;
@Captor
private ArgumentCaptor<MessageDeletedLog> captor;
@@ -55,46 +63,69 @@ public class MessageDeleteLogListenerTest {
@Captor
private ArgumentCaptor<MessageToSend> messageCaptor;
@Before
public void setup() {
AServer server = MockUtils.getServer();
AUserInAServer aUserInAServer = MockUtils.getUserObject(4L, server);
AChannel channel = MockUtils.getTextChannel(server, 5L);
authorUser = AServerAChannelAUser.builder().guild(server).channel(channel).aUserInAServer(aUserInAServer).build();
Member member = Mockito.mock(Member.class);
Guild guild = Mockito.mock(Guild.class);
TextChannel textChannel = Mockito.mock(TextChannel.class);
authorMember = GuildChannelMember.builder().guild(guild).textChannel(textChannel).member(member).build();
private static final Long SERVER_ID = 1L;
private static final Long AUTHOR_ID = 2L;
private static final Long CHANNEL_ID = 3L;
@Mock
private CachedMessage deletedMessage;
@Mock
private CachedAuthor cachedAuthor;
@Mock
private TextChannel textChannel;
@Mock
private Member member;
@Mock
private Guild guild;
@Test
public void testExecuteListener() {
when(deletedMessage.getAuthor()).thenReturn(cachedAuthor);
when(cachedAuthor.getAuthorId()).thenReturn(AUTHOR_ID);
when(deletedMessage.getServerId()).thenReturn(SERVER_ID);
when(botService.getMemberInServerAsync(SERVER_ID, AUTHOR_ID)).thenReturn(CompletableFuture.completedFuture(member));
testUnit.execute(deletedMessage);
verify(self, times(1)).executeListener(deletedMessage, member);
}
@Test
public void testExecuteListenerWithSimpleMessage() {
CachedMessage message = CachedMessage.builder().serverId(authorUser.getGuild().getId()).build();
when(deletedMessage.getServerId()).thenReturn(SERVER_ID);
when(deletedMessage.getChannelId()).thenReturn(CHANNEL_ID);
MessageToSend messageToSend = Mockito.mock(MessageToSend.class);
when(member.getGuild()).thenReturn(guild);
when(templateService.renderEmbedTemplate(eq(MessageDeleteLogListener.MESSAGE_DELETED_TEMPLATE), captor.capture())).thenReturn(messageToSend);
testUnit.execute(message, authorUser, authorMember);
verify(postTargetService, times(1)).sendEmbedInPostTarget(messageToSend, LoggingPostTarget.DELETE_LOG, authorUser.getGuild().getId());
when(botService.getTextChannelFromServer(SERVER_ID, CHANNEL_ID)).thenReturn(textChannel);
testUnit.executeListener(deletedMessage, member);
verify(postTargetService, times(1)).sendEmbedInPostTarget(messageToSend, LoggingPostTarget.DELETE_LOG, SERVER_ID);
MessageDeletedLog messageDeletedLog = captor.getValue();
Assert.assertEquals(message, messageDeletedLog.getCachedMessage());
Assert.assertEquals(authorUser.getGuild(), messageDeletedLog.getServer());
Assert.assertEquals(authorUser.getChannel(), messageDeletedLog.getChannel());
Assert.assertEquals(authorUser.getUser(), messageDeletedLog.getUser());
Assert.assertEquals(authorUser.getAUserInAServer(), messageDeletedLog.getAUserInAServer());
Assert.assertEquals(authorMember.getGuild(), messageDeletedLog.getGuild());
Assert.assertEquals(authorMember.getTextChannel(), messageDeletedLog.getMessageChannel());
Assert.assertEquals(authorMember.getMember(), messageDeletedLog.getMember());
Assert.assertEquals(deletedMessage, messageDeletedLog.getCachedMessage());
Assert.assertEquals(guild, messageDeletedLog.getGuild());
Assert.assertEquals(textChannel, messageDeletedLog.getChannel());
Assert.assertEquals(member, messageDeletedLog.getMember());
}
@Test
public void testExecuteListenerWithOneAttachment() {
String attachmentUrl = "url";
CachedMessage message = CachedMessage.builder().serverId(authorUser.getGuild().getId()).attachmentUrls(Arrays.asList(attachmentUrl)).build();
when(deletedMessage.getServerId()).thenReturn(SERVER_ID);
when(deletedMessage.getChannelId()).thenReturn(CHANNEL_ID);
when(botService.getTextChannelFromServer(SERVER_ID, CHANNEL_ID)).thenReturn(textChannel);
CachedAttachment cachedAttachment = Mockito.mock(CachedAttachment.class);
when(cachedAttachment.getProxyUrl()).thenReturn(attachmentUrl);
List<CachedAttachment> attachmentList = Arrays.asList(cachedAttachment);
when(deletedMessage.getAttachments()).thenReturn(attachmentList);
MessageToSend messageToSend = Mockito.mock(MessageToSend.class);
MessageToSend attachmentMessage = Mockito.mock(MessageToSend.class);
when(member.getGuild()).thenReturn(guild);
when(templateService.renderEmbedTemplate(eq(MessageDeleteLogListener.MESSAGE_DELETED_TEMPLATE), captor.capture())).thenReturn(messageToSend);
when(templateService.renderEmbedTemplate(eq(MessageDeleteLogListener.MESSAGE_DELETED_ATTACHMENT_TEMPLATE), attachmentCaptor.capture())).thenReturn(attachmentMessage);
testUnit.execute(message, authorUser, authorMember);
verify(postTargetService, times(2)).sendEmbedInPostTarget(messageCaptor.capture(), eq(LoggingPostTarget.DELETE_LOG), eq(authorUser.getGuild().getId()));
testUnit.executeListener(deletedMessage, member);
verify(postTargetService, times(2)).sendEmbedInPostTarget(messageCaptor.capture(), eq(LoggingPostTarget.DELETE_LOG), eq(SERVER_ID));
List<MessageToSend> messagesSent = messageCaptor.getAllValues();
Assert.assertEquals(messageToSend, messagesSent.get(0));
Assert.assertEquals(attachmentMessage, messagesSent.get(1));
@@ -105,15 +136,24 @@ public class MessageDeleteLogListenerTest {
@Test
public void testExecuteListenerWithTwoAttachment() {
when(deletedMessage.getServerId()).thenReturn(SERVER_ID);
when(deletedMessage.getChannelId()).thenReturn(CHANNEL_ID);
when(botService.getTextChannelFromServer(SERVER_ID, CHANNEL_ID)).thenReturn(textChannel);
String attachmentUrl = "url";
String secondAttachmentUrl = "url2";
CachedMessage message = CachedMessage.builder().serverId(authorUser.getGuild().getId()).attachmentUrls(Arrays.asList(attachmentUrl, secondAttachmentUrl)).build();
CachedAttachment cachedAttachment = Mockito.mock(CachedAttachment.class);
when(cachedAttachment.getProxyUrl()).thenReturn(attachmentUrl);
CachedAttachment secondCachedAttachment = Mockito.mock(CachedAttachment.class);
when(secondCachedAttachment.getProxyUrl()).thenReturn(secondAttachmentUrl);
List<CachedAttachment> cachedAttachments = Arrays.asList(cachedAttachment, secondCachedAttachment);
when(deletedMessage.getAttachments()).thenReturn(cachedAttachments);
MessageToSend messageToSend = Mockito.mock(MessageToSend.class);
when(member.getGuild()).thenReturn(guild);
MessageToSend attachmentMessage = Mockito.mock(MessageToSend.class);
when(templateService.renderEmbedTemplate(eq(MessageDeleteLogListener.MESSAGE_DELETED_TEMPLATE), captor.capture())).thenReturn(messageToSend);
when(templateService.renderEmbedTemplate(eq(MessageDeleteLogListener.MESSAGE_DELETED_ATTACHMENT_TEMPLATE), attachmentCaptor.capture())).thenReturn(attachmentMessage);
testUnit.execute(message, authorUser, authorMember);
verify(postTargetService, times(3)).sendEmbedInPostTarget(messageCaptor.capture(), eq(LoggingPostTarget.DELETE_LOG), eq(authorUser.getGuild().getId()));
testUnit.executeListener(deletedMessage, member);
verify(postTargetService, times(3)).sendEmbedInPostTarget(messageCaptor.capture(), eq(LoggingPostTarget.DELETE_LOG), eq(SERVER_ID));
List<MessageToSend> messagesSent = messageCaptor.getAllValues();
Assert.assertEquals(messageToSend, messagesSent.get(0));
Assert.assertEquals(attachmentMessage, messagesSent.get(1));
@@ -125,25 +165,17 @@ public class MessageDeleteLogListenerTest {
private void verifyMessageDeletedLog() {
MessageDeletedLog messageDeletedLog = captor.getValue();
Assert.assertEquals(authorUser.getGuild(), messageDeletedLog.getServer());
Assert.assertEquals(authorUser.getChannel(), messageDeletedLog.getChannel());
Assert.assertEquals(authorUser.getUser(), messageDeletedLog.getUser());
Assert.assertEquals(authorUser.getAUserInAServer(), messageDeletedLog.getAUserInAServer());
Assert.assertEquals(authorMember.getGuild(), messageDeletedLog.getGuild());
Assert.assertEquals(authorMember.getTextChannel(), messageDeletedLog.getMessageChannel());
Assert.assertEquals(authorMember.getMember(), messageDeletedLog.getMember());
Assert.assertEquals(guild, messageDeletedLog.getGuild());
Assert.assertEquals(textChannel, messageDeletedLog.getChannel());
Assert.assertEquals(member, messageDeletedLog.getMember());
}
private void verifyAttachmentLog(String attachmentUrl, MessageDeletedAttachmentLog attachmentLog, Integer index) {
Assert.assertEquals(attachmentUrl, attachmentLog.getImageUrl());
Assert.assertEquals(index, attachmentLog.getCounter());
Assert.assertEquals(authorUser.getGuild(), attachmentLog.getServer());
Assert.assertEquals(authorUser.getChannel(), attachmentLog.getChannel());
Assert.assertEquals(authorUser.getUser(), attachmentLog.getUser());
Assert.assertEquals(authorUser.getAUserInAServer(), attachmentLog.getAUserInAServer());
Assert.assertEquals(authorMember.getGuild(), attachmentLog.getGuild());
Assert.assertEquals(authorMember.getTextChannel(), attachmentLog.getMessageChannel());
Assert.assertEquals(authorMember.getMember(), attachmentLog.getMember());
Assert.assertEquals(guild, attachmentLog.getGuild());
Assert.assertEquals(textChannel, attachmentLog.getChannel());
Assert.assertEquals(member, attachmentLog.getMember());
}

View File

@@ -1,6 +1,8 @@
package dev.sheldan.abstracto.moderation.listener;
import dev.sheldan.abstracto.core.models.cache.CachedAuthor;
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
import dev.sheldan.abstracto.core.service.BotService;
import dev.sheldan.abstracto.core.service.PostTargetService;
import dev.sheldan.abstracto.moderation.config.posttargets.LoggingPostTarget;
import dev.sheldan.abstracto.moderation.models.template.listener.MessageEditedLog;
@@ -8,7 +10,6 @@ import dev.sheldan.abstracto.templating.model.MessageToSend;
import dev.sheldan.abstracto.templating.service.TemplateService;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.TextChannel;
import org.junit.Assert;
import org.junit.Test;
@@ -19,6 +20,8 @@ import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;
import java.util.concurrent.CompletableFuture;
import static org.mockito.Mockito.*;
@RunWith(MockitoJUnitRunner.class)
@@ -34,15 +37,22 @@ public class MessageEditedListenerTest {
private PostTargetService postTargetService;
@Mock
private Message messageAfter;
private BotService botService;
@Mock
private CachedMessage messageAfter;
@Mock
private CachedMessage messageBefore;
private static final Long SERVER_ID = 4L;
private static final Long CHANNEL_ID = 5L;
private static final Long AUTHOR_ID = 6L;
@Test
public void testExecuteListenerWithSameContent() {
String content = "text";
when(messageAfter.getContentRaw()).thenReturn(content);
when(messageAfter.getContent()).thenReturn(content);
when(messageBefore.getContent()).thenReturn(content);
testUnit.execute(messageBefore, messageAfter);
verify(templateService, times(0)).renderEmbedTemplate(eq(MessageEditedListener.MESSAGE_EDITED_TEMPLATE), any());
@@ -53,25 +63,29 @@ public class MessageEditedListenerTest {
String content = "text";
String contentAfterwards = "text2";
TextChannel channel = Mockito.mock(TextChannel.class);
Long serverId = 5L;
when(messageAfter.getContentRaw()).thenReturn(contentAfterwards);
when(messageAfter.getTextChannel()).thenReturn(channel);
when(messageAfter.getContent()).thenReturn(contentAfterwards);
when(messageAfter.getChannelId()).thenReturn(CHANNEL_ID);
Guild guild = Mockito.mock(Guild.class);
when(messageAfter.getGuild()).thenReturn(guild);
Member member = Mockito.mock(Member.class);
when(messageAfter.getMember()).thenReturn(member);
when(channel.getGuild()).thenReturn(guild);
when(messageAfter.getServerId()).thenReturn(SERVER_ID);
Member author = Mockito.mock(Member.class);
CachedAuthor cachedAuthor = Mockito.mock(CachedAuthor.class);
when(cachedAuthor.getAuthorId()).thenReturn(AUTHOR_ID);
when(messageAfter.getAuthor()).thenReturn(cachedAuthor);
when(messageBefore.getContent()).thenReturn(content);
when(messageBefore.getServerId()).thenReturn(serverId);
when(messageBefore.getServerId()).thenReturn(SERVER_ID);
MessageToSend messageToSend = Mockito.mock(MessageToSend.class);
ArgumentCaptor<MessageEditedLog> captor = ArgumentCaptor.forClass(MessageEditedLog.class);
when(templateService.renderEmbedTemplate(eq(MessageEditedListener.MESSAGE_EDITED_TEMPLATE), captor.capture())).thenReturn(messageToSend);
when(botService.getMemberInServerAsync(SERVER_ID, AUTHOR_ID)).thenReturn(CompletableFuture.completedFuture(author));
when(botService.getTextChannelFromServer(SERVER_ID, CHANNEL_ID)).thenReturn(channel);
testUnit.execute(messageBefore, messageAfter);
verify(postTargetService, times(1)).sendEmbedInPostTarget(messageToSend, LoggingPostTarget.EDIT_LOG, serverId);
verify(postTargetService, times(1)).sendEmbedInPostTarget(messageToSend, LoggingPostTarget.EDIT_LOG, SERVER_ID);
MessageEditedLog capturedValue = captor.getValue();
Assert.assertEquals(messageBefore, capturedValue.getMessageBefore());
Assert.assertEquals(messageAfter, capturedValue.getMessageAfter());
Assert.assertEquals(channel, capturedValue.getMessageChannel());
Assert.assertEquals(guild, capturedValue.getGuild());
Assert.assertEquals(member, capturedValue.getMember());
Assert.assertEquals(author, capturedValue.getMember());
}
}

View File

@@ -302,6 +302,7 @@ public class MuteServiceBeanTest {
when(muteManagementService.hasActiveMute(userBeingMuted)).thenReturn(true);
when(muteManagementService.getAMuteOf(userBeingMuted)).thenReturn(mute);
when(mute.getMuteId()).thenReturn(new ServerSpecificId(SERVER_ID, MUTE_ID));
when(botService.getGuildById(SERVER_ID)).thenReturn(guild);
testUnit.unMuteUser(userBeingMuted);
verifyNoUnMuteHappened();
}