[AB-57] [AB-61] reworked commands and services to work with completable futures and moved the database operations to the very last operation so we have transaction safety in more areas

added some cache annotations to the default repository functions
reworked how the undo cations are processed within commands, they are executed in a post command listener when the state is error
added a counter id to generate ids to be unique within servers, changed a few tables to be unique within a server
added future utils class for wrapping a list of futures into one
moved abstracto tables to separate schema in the installer
refactored experience gain to work with more futures and delayed database access
This commit is contained in:
Sheldan
2020-09-20 11:11:20 +02:00
parent 552ecc26b8
commit 76adda90a3
220 changed files with 2691 additions and 1498 deletions

View File

@@ -19,6 +19,7 @@ import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
@Component
@Slf4j
@@ -32,7 +33,7 @@ public class Ban extends AbstractConditionableCommand {
private TemplateService templateService;
@Override
public CommandResult execute(CommandContext commandContext) {
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
checkParameters(commandContext);
List<Object> parameters = commandContext.getParameters().getParameters();
Member member = (Member) parameters.get(0);
@@ -43,8 +44,8 @@ public class Ban extends AbstractConditionableCommand {
banLogModel.setBannedUser(member);
banLogModel.setBanningUser(commandContext.getAuthor());
banLogModel.setReason(reason);
banService.banMember(member, reason, banLogModel);
return CommandResult.fromSuccess();
return banService.banMember(member, reason, banLogModel)
.thenApply(aVoid -> CommandResult.fromSuccess());
}
@Override
@@ -57,6 +58,7 @@ public class Ban extends AbstractConditionableCommand {
.name("ban")
.module(ModerationModule.MODERATION)
.templated(true)
.async(true)
.supportsEmbedException(true)
.causesReaction(true)
.parameters(parameters)

View File

@@ -16,6 +16,7 @@ import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
@Component
public class BanId extends AbstractConditionableCommand {
@@ -27,7 +28,7 @@ public class BanId extends AbstractConditionableCommand {
private BanService banService;
@Override
public CommandResult execute(CommandContext commandContext) {
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
checkParameters(commandContext);
List<Object> parameters = commandContext.getParameters().getParameters();
Long userId = (Long) parameters.get(0);
@@ -37,9 +38,8 @@ public class BanId extends AbstractConditionableCommand {
banLogModel.setBannedUserId(userId);
banLogModel.setBanningUser(commandContext.getAuthor());
banLogModel.setReason(reason);
banService.banMember(commandContext.getGuild().getIdLong(), userId, reason, banLogModel);
return CommandResult.fromSuccess();
return banService.banMember(commandContext.getGuild().getIdLong(), userId, reason, banLogModel)
.thenApply(aVoid -> CommandResult.fromSuccess());
}
@Override
@@ -52,6 +52,7 @@ public class BanId extends AbstractConditionableCommand {
.name("banId")
.module(ModerationModule.MODERATION)
.templated(true)
.async(true)
.supportsEmbedException(true)
.causesReaction(true)
.parameters(parameters)

View File

@@ -15,6 +15,7 @@ import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
@Component
public class DecayAllWarnings extends AbstractConditionableCommand {
@@ -23,12 +24,12 @@ public class DecayAllWarnings extends AbstractConditionableCommand {
private WarnService warnService;
@Override
public CommandResult execute(CommandContext commandContext) {
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
checkParameters(commandContext);
List<Object> parameters = commandContext.getParameters().getParameters();
boolean logWarnings = !parameters.isEmpty() ? (Boolean) parameters.get(0) : Boolean.FALSE;
warnService.decayAllWarningsForServer(commandContext.getUserInitiatedContext().getServer(), logWarnings);
return CommandResult.fromSuccess();
return warnService.decayAllWarningsForServer(commandContext.getUserInitiatedContext().getServer(), logWarnings)
.thenApply(aVoid -> CommandResult.fromSuccess());
}
@Override
@@ -41,6 +42,7 @@ public class DecayAllWarnings extends AbstractConditionableCommand {
.name("decayAllWarnings")
.module(ModerationModule.MODERATION)
.templated(true)
.async(true)
.supportsEmbedException(true)
.causesReaction(true)
.parameters(parameters)

View File

@@ -15,6 +15,7 @@ import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
@Component
public class DecayWarnings extends AbstractConditionableCommand {
@@ -23,9 +24,9 @@ public class DecayWarnings extends AbstractConditionableCommand {
private WarnService warnService;
@Override
public CommandResult execute(CommandContext commandContext) {
warnService.decayWarningsForServer(commandContext.getUserInitiatedContext().getServer());
return CommandResult.fromSuccess();
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
return warnService.decayWarningsForServer(commandContext.getUserInitiatedContext().getServer())
.thenApply(aVoid -> CommandResult.fromSuccess());
}
@Override
@@ -36,6 +37,7 @@ public class DecayWarnings extends AbstractConditionableCommand {
.name("decayWarnings")
.module(ModerationModule.MODERATION)
.templated(true)
.async(true)
.supportsEmbedException(true)
.causesReaction(true)
.parameters(parameters)

View File

@@ -29,12 +29,8 @@ public class DeleteWarning extends AbstractConditionableCommand {
public CommandResult execute(CommandContext commandContext) {
checkParameters(commandContext);
Long warnId = (Long) commandContext.getParameters().getParameters().get(0);
Optional<Warning> optional = warnManagementService.findById(warnId);
optional.ifPresent(warning -> {
if(warning.getWarnedUser().getServerReference().getId().equals(commandContext.getUserInitiatedContext().getServer().getId())) {
warnManagementService.deleteWarning(warning);
}
});
Optional<Warning> optional = warnManagementService.findById(warnId, commandContext.getGuild().getIdLong());
optional.ifPresent(warning -> warnManagementService.deleteWarning(warning));
return CommandResult.fromSuccess();
}

View File

@@ -18,6 +18,7 @@ import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
@Component
public class Kick extends AbstractConditionableCommand {
@@ -30,19 +31,18 @@ public class Kick extends AbstractConditionableCommand {
private KickServiceBean kickService;
@Override
public CommandResult execute(CommandContext commandContext) {
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
checkParameters(commandContext);
List<Object> parameters = commandContext.getParameters().getParameters();
Member member = (Member) parameters.get(0);
String defaultReason = templateService.renderSimpleTemplate(KICK_DEFAULT_REASON_TEMPLATE);
String reason = parameters.size() == 2 ? (String) parameters.get(1) : defaultReason;
KickLogModel kickLogModel = (KickLogModel) ContextConverter.fromCommandContext(commandContext, KickLogModel.class);
KickLogModel kickLogModel = (KickLogModel) ContextConverter.slimFromCommandContext(commandContext, KickLogModel.class);
kickLogModel.setKickedUser(member);
kickLogModel.setKickingUser(commandContext.getAuthor());
kickLogModel.setReason(reason);
kickService.kickMember(member, reason, kickLogModel);
return CommandResult.fromSuccess();
return kickService.kickMember(member, reason, kickLogModel)
.thenApply(aVoid -> CommandResult.fromSuccess());
}
@Override

View File

@@ -33,16 +33,15 @@ public class Purge extends AbstractConditionableCommand {
private ExceptionUtils exceptionUtils;
@Override
public CommandResult execute(CommandContext commandContext) {
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
checkParameters(commandContext);
Integer amountOfMessages = (Integer) commandContext.getParameters().getParameters().get(0);
Member memberToPurgeMessagesOf = null;
if(commandContext.getParameters().getParameters().size() == 2) {
memberToPurgeMessagesOf = (Member) commandContext.getParameters().getParameters().get(1);
}
CompletableFuture<Void> future = purgeService.purgeMessagesInChannel(amountOfMessages, commandContext.getChannel(), commandContext.getMessage(), memberToPurgeMessagesOf);
future.whenComplete((aVoid, throwable) -> exceptionUtils.handleExceptionIfTemplatable(throwable, commandContext.getChannel()));
return CommandResult.fromSelfDestruct();
return purgeService.purgeMessagesInChannel(amountOfMessages, commandContext.getChannel(), commandContext.getMessage(), memberToPurgeMessagesOf)
.thenApply(aVoid -> CommandResult.fromSelfDestruct());
}
@Override
@@ -55,6 +54,7 @@ public class Purge extends AbstractConditionableCommand {
.name("purge")
.module(ModerationModule.MODERATION)
.templated(true)
.async(true)
.supportsEmbedException(true)
.causesReaction(true)
.parameters(parameters)

View File

@@ -18,6 +18,7 @@ import org.springframework.stereotype.Component;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
@Component
public class SlowMode extends AbstractConditionableCommand {
@@ -26,7 +27,7 @@ public class SlowMode extends AbstractConditionableCommand {
private SlowModeService slowModeService;
@Override
public CommandResult execute(CommandContext commandContext) {
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
checkParameters(commandContext);
TextChannel channel;
String durationString = (String) commandContext.getParameters().getParameters().get(0);
@@ -41,8 +42,8 @@ public class SlowMode extends AbstractConditionableCommand {
} else {
channel = commandContext.getChannel();
}
slowModeService.setSlowMode(channel, duration);
return CommandResult.fromSuccess();
return slowModeService.setSlowMode(channel, duration)
.thenApply(aVoid -> CommandResult.fromSuccess());
}
@Override
@@ -55,6 +56,7 @@ public class SlowMode extends AbstractConditionableCommand {
.name("slowmode")
.module(ModerationModule.MODERATION)
.templated(true)
.async(true)
.supportsEmbedException(true)
.causesReaction(true)
.parameters(parameters)

View File

@@ -12,6 +12,7 @@ import dev.sheldan.abstracto.core.models.FullUserInServer;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.core.utils.FutureUtils;
import dev.sheldan.abstracto.moderation.config.ModerationModule;
import dev.sheldan.abstracto.moderation.config.features.ModerationFeatures;
import dev.sheldan.abstracto.moderation.converter.UserNotesConverter;
@@ -25,6 +26,7 @@ import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
@Component
public class UserNotes extends AbstractConditionableCommand {
@@ -45,7 +47,7 @@ public class UserNotes extends AbstractConditionableCommand {
private UserNotesConverter userNotesConverter;
@Override
public CommandResult execute(CommandContext commandContext) {
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
checkParameters(commandContext);
List<Object> parameters = commandContext.getParameters().getParameters();
List<UserNote> userNotes;
@@ -65,8 +67,8 @@ public class UserNotes extends AbstractConditionableCommand {
userNotes = userNoteManagementService.loadNotesForServer(commandContext.getUserInitiatedContext().getServer());
}
model.setUserNotes(userNotesConverter.fromNotes(userNotes));
channelService.sendEmbedTemplateInChannel(USER_NOTES_RESPONSE_TEMPLATE, model, commandContext.getChannel());
return CommandResult.fromSuccess();
return FutureUtils.toSingleFutureGeneric(channelService.sendEmbedTemplateInChannel(USER_NOTES_RESPONSE_TEMPLATE, model, commandContext.getChannel()))
.thenApply(aVoid -> CommandResult.fromSuccess());
}
@Override
@@ -79,6 +81,7 @@ public class UserNotes extends AbstractConditionableCommand {
.name("userNotes")
.module(ModerationModule.MODERATION)
.templated(true)
.async(true)
.supportsEmbedException(true)
.causesReaction(true)
.parameters(parameters)

View File

@@ -9,7 +9,7 @@ import dev.sheldan.abstracto.core.command.execution.*;
import dev.sheldan.abstracto.core.config.FeatureEnum;
import dev.sheldan.abstracto.moderation.config.ModerationModule;
import dev.sheldan.abstracto.moderation.config.features.ModerationFeatures;
import dev.sheldan.abstracto.moderation.models.template.commands.WarnLog;
import dev.sheldan.abstracto.moderation.models.template.commands.WarnContext;
import dev.sheldan.abstracto.moderation.service.WarnService;
import dev.sheldan.abstracto.templating.service.TemplateService;
import lombok.extern.slf4j.Slf4j;
@@ -19,6 +19,7 @@ import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
@Component
@Slf4j
@@ -32,19 +33,17 @@ public class Warn extends AbstractConditionableCommand {
private TemplateService templateService;
@Override
public CommandResult execute(CommandContext commandContext) {
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
checkParameters(commandContext);
List<Object> parameters = commandContext.getParameters().getParameters();
Member member = (Member) parameters.get(0);
String defaultReason = templateService.renderSimpleTemplate(WARN_DEFAULT_REASON_TEMPLATE);
String reason = parameters.size() == 2 ? (String) parameters.get(1) : defaultReason;
WarnLog warnLogModel = (WarnLog) ContextConverter.fromCommandContext(commandContext, WarnLog.class);
warnLogModel.setWarnedUser(member);
warnLogModel.setMessage(commandContext.getMessage());
WarnContext warnLogModel = (WarnContext) ContextConverter.slimFromCommandContext(commandContext, WarnContext.class);
warnLogModel.setReason(reason);
warnLogModel.setWarningUser(commandContext.getAuthor());
warnService.warnUserWithLog(member, commandContext.getAuthor(), reason, warnLogModel, commandContext.getChannel());
return CommandResult.fromSuccess();
warnLogModel.setWarnedMember(member);
return warnService.warnUserWithLog(warnLogModel)
.thenApply(warning -> CommandResult.fromSuccess());
}
@Override
@@ -57,6 +56,7 @@ public class Warn extends AbstractConditionableCommand {
.name("warn")
.module(ModerationModule.MODERATION)
.templated(true)
.async(true)
.supportsEmbedException(true)
.causesReaction(true)
.parameters(parameters)

View File

@@ -7,11 +7,11 @@ import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.command.execution.ContextConverter;
import dev.sheldan.abstracto.core.config.FeatureEnum;
import dev.sheldan.abstracto.core.models.ServerChannelMessage;
import dev.sheldan.abstracto.moderation.config.ModerationModule;
import dev.sheldan.abstracto.moderation.config.features.ModerationFeatures;
import dev.sheldan.abstracto.moderation.models.template.commands.MuteLog;
import dev.sheldan.abstracto.moderation.models.template.commands.MuteContext;
import dev.sheldan.abstracto.moderation.service.MuteService;
import net.dv8tion.jda.api.entities.Member;
import org.springframework.beans.factory.annotation.Autowired;
@@ -21,6 +21,7 @@ import java.time.Duration;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
@Component
public class Mute extends AbstractConditionableCommand {
@@ -29,18 +30,31 @@ public class Mute extends AbstractConditionableCommand {
private MuteService muteService;
@Override
public CommandResult execute(CommandContext commandContext) {
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
checkParameters(commandContext);
List<Object> parameters = commandContext.getParameters().getParameters();
Member member = (Member) parameters.get(0);
Duration duration = (Duration) parameters.get(1);
String reason = (String) parameters.get(2);
MuteLog muteLogModel = (MuteLog) ContextConverter.fromCommandContext(commandContext, MuteLog.class);
muteLogModel.setMessage(commandContext.getMessage());
muteLogModel.setMutedUser(member);
muteLogModel.setMutingUser(commandContext.getAuthor());
muteService.muteMemberWithLog(member, commandContext.getAuthor(), reason, Instant.now().plus(duration), muteLogModel, commandContext.getMessage());
return CommandResult.fromSuccess();
ServerChannelMessage context = ServerChannelMessage
.builder()
.serverId(commandContext.getGuild().getIdLong())
.channelId(commandContext.getChannel().getIdLong())
.messageId(commandContext.getMessage().getIdLong())
.build();
MuteContext muteLogModel = MuteContext
.builder()
.muteDate(Instant.now())
.muteTargetDate(Instant.now().plus(duration))
.mutedUser(member)
.reason(reason)
.contextChannel(commandContext.getChannel())
.message(commandContext.getMessage())
.mutingUser(commandContext.getAuthor())
.context(context)
.build();
return muteService.muteMemberWithLog(muteLogModel)
.thenApply(aVoid -> CommandResult.fromSuccess());
}
@Override
@@ -54,6 +68,7 @@ public class Mute extends AbstractConditionableCommand {
.name("mute")
.module(ModerationModule.MODERATION)
.templated(true)
.async(true)
.causesReaction(true)
.supportsEmbedException(true)
.parameters(parameters)

View File

@@ -7,9 +7,10 @@ import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.config.FeatureEnum;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.moderation.config.ModerationModule;
import dev.sheldan.abstracto.moderation.config.features.ModerationFeatures;
import dev.sheldan.abstracto.moderation.models.database.Mute;
import dev.sheldan.abstracto.moderation.service.MuteService;
import dev.sheldan.abstracto.moderation.service.management.MuteManagementService;
import dev.sheldan.abstracto.templating.service.TemplateService;
@@ -19,6 +20,7 @@ import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
@Component
public class UnMute extends AbstractConditionableCommand {
@@ -33,19 +35,18 @@ public class UnMute extends AbstractConditionableCommand {
@Autowired
private TemplateService templateService;
@Autowired
private UserInServerManagementService userInServerManagementService;
@Override
public CommandResult execute(CommandContext commandContext) {
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
checkParameters(commandContext);
List<Object> parameters = commandContext.getParameters().getParameters();
Member member = (Member) parameters.get(0);
if(!muteManagementService.hasActiveMute(member)) {
return CommandResult.fromError(templateService.renderSimpleTemplate(NO_ACTIVE_MUTE));
}
Mute mute = muteManagementService.getAMuteOf(member);
muteService.unMuteUser(mute);
muteService.cancelUnMuteJob(mute);
muteService.completelyUnMuteMember(member);
return CommandResult.fromSuccess();
AUserInAServer userToUnMute = userInServerManagementService.loadUser(member);
return muteService.unMuteUser(userToUnMute).thenApply(aVoid ->
CommandResult.fromSuccess()
);
}
@Override
@@ -57,6 +58,7 @@ public class UnMute extends AbstractConditionableCommand {
.name("unMute")
.module(ModerationModule.MODERATION)
.templated(true)
.async(true)
.supportsEmbedException(true)
.causesReaction(true)
.parameters(parameters)

View File

@@ -1,6 +1,8 @@
package dev.sheldan.abstracto.moderation.job;
import dev.sheldan.abstracto.moderation.service.MuteService;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.JobExecutionContext;
@@ -14,9 +16,12 @@ import org.springframework.stereotype.Component;
@DisallowConcurrentExecution
@Component
@PersistJobDataAfterExecution
@Getter
@Setter
public class UnMuteJob extends QuartzJobBean {
private Long muteId;
private Long serverId;
@Autowired
private MuteService muteService;
@@ -24,14 +29,7 @@ public class UnMuteJob extends QuartzJobBean {
@Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
log.info("Executing unMute job for mute {}", muteId);
muteService.endMute(muteId);
muteService.endMute(muteId, serverId);
}
public Long getMuteId() {
return muteId;
}
public void setMuteId(Long muteId) {
this.muteId = muteId;
}
}

View File

@@ -2,12 +2,14 @@ package dev.sheldan.abstracto.moderation.repository;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.moderation.models.database.Mute;
import org.jetbrains.annotations.NotNull;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.QueryHints;
import org.springframework.stereotype.Repository;
import javax.persistence.QueryHint;
import java.util.List;
import java.util.Optional;
@Repository
public interface MuteRepository extends JpaRepository<Mute, Long> {
@@ -18,5 +20,9 @@ public interface MuteRepository extends JpaRepository<Mute, Long> {
Mute findTopByMutedUserAndMuteEndedFalse(AUserInAServer userInAServer);
@QueryHints(@QueryHint(name = org.hibernate.annotations.QueryHints.CACHEABLE, value = "true"))
List<Mute> findAllByMutedUserAndMuteEndedFalseOrderByIdDesc(AUserInAServer aUserInAServer);
List<Mute> findAllByMutedUserAndMuteEndedFalseOrderByMuteId_IdDesc(AUserInAServer aUserInAServer);
@NotNull
@QueryHints(@QueryHint(name = org.hibernate.annotations.QueryHints.CACHEABLE, value = "true"))
Optional<Mute> findByMuteId_IdAndMuteId_ServerId(Long muteId, Long serverId);
}

View File

@@ -18,5 +18,6 @@ public interface MuteRoleRepository extends JpaRepository<MuteRole, Long> {
@QueryHints(@QueryHint(name = org.hibernate.annotations.QueryHints.CACHEABLE, value = "true"))
List<MuteRole> findAllByRoleServer(AServer server);
@QueryHints(@QueryHint(name = org.hibernate.annotations.QueryHints.CACHEABLE, value = "true"))
boolean existsByRoleServer(AServer server);
}

View File

@@ -4,13 +4,23 @@ import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.moderation.models.database.UserNote;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.QueryHints;
import org.springframework.lang.NonNull;
import org.springframework.stereotype.Repository;
import javax.persistence.QueryHint;
import java.util.List;
@Repository
public interface UserNoteRepository extends JpaRepository<UserNote, Long> {
@QueryHints(@QueryHint(name = org.hibernate.annotations.QueryHints.CACHEABLE, value = "true"))
List<UserNote> findByUser(AUserInAServer aUserInAServer);
@QueryHints(@QueryHint(name = org.hibernate.annotations.QueryHints.CACHEABLE, value = "true"))
List<UserNote> findByUser_ServerReference(AServer server);
@Override
@QueryHints(@QueryHint(name = org.hibernate.annotations.QueryHints.CACHEABLE, value = "true"))
boolean existsById(@NonNull Long aLong);
}

View File

@@ -3,13 +3,16 @@ package dev.sheldan.abstracto.moderation.repository;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.moderation.models.database.Warning;
import org.jetbrains.annotations.NotNull;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.QueryHints;
import org.springframework.lang.NonNull;
import org.springframework.stereotype.Repository;
import javax.persistence.QueryHint;
import java.time.Instant;
import java.util.List;
import java.util.Optional;
@Repository
public interface WarnRepository extends JpaRepository<Warning, Long> {
@@ -25,7 +28,15 @@ public interface WarnRepository extends JpaRepository<Warning, Long> {
@QueryHints(@QueryHint(name = org.hibernate.annotations.QueryHints.CACHEABLE, value = "true"))
Long countByWarnedUserAndDecayedFalse(AUserInAServer aUserInAServer);
@QueryHints(@QueryHint(name = org.hibernate.annotations.QueryHints.CACHEABLE, value = "true"))
List<Warning> findByWarnedUser(AUserInAServer aUserInAServer);
@NotNull
@Override
@QueryHints(@QueryHint(name = org.hibernate.annotations.QueryHints.CACHEABLE, value = "true"))
Optional<Warning> findById(@NonNull Long aLong);
@NotNull
@QueryHints(@QueryHint(name = org.hibernate.annotations.QueryHints.CACHEABLE, value = "true"))
Optional<Warning> findByWarnId_IdAndWarnId_ServerId(Long warnId, Long serverId);
}

View File

@@ -4,16 +4,20 @@ import dev.sheldan.abstracto.core.exception.GuildNotFoundException;
import dev.sheldan.abstracto.core.models.context.ServerContext;
import dev.sheldan.abstracto.core.service.BotService;
import dev.sheldan.abstracto.core.service.PostTargetService;
import dev.sheldan.abstracto.core.utils.FutureUtils;
import dev.sheldan.abstracto.moderation.config.posttargets.ModerationPostTarget;
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.Guild;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.Message;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
@Component
@Slf4j
@@ -32,31 +36,33 @@ public class BanServiceBean implements BanService {
private PostTargetService postTargetService;
@Override
public void banMember(Member member, String reason, ServerContext banLog) {
this.banUser(member.getGuild(), member.getIdLong(), reason);
public CompletableFuture<Void> banMember(Member member, String reason, ServerContext banLog) {
CompletableFuture<Void> banFuture = banUser(member.getGuild(), member.getIdLong(), reason);
MessageToSend banLogMessage = templateService.renderEmbedTemplate(BAN_LOG_TEMPLATE, banLog);
postTargetService.sendEmbedInPostTarget(banLogMessage, ModerationPostTarget.BAN_LOG, member.getGuild().getIdLong());
List<CompletableFuture<Message>> notificationFutures = postTargetService.sendEmbedInPostTarget(banLogMessage, ModerationPostTarget.BAN_LOG, member.getGuild().getIdLong());
return CompletableFuture.allOf(banFuture, FutureUtils.toSingleFutureGeneric(notificationFutures));
}
@Override
public void banMember(Long guildId, Long userId, String reason, ServerContext banIdLog) {
banUser(guildId, userId, reason);
public CompletableFuture<Void> banMember(Long guildId, Long userId, String reason, ServerContext banIdLog) {
CompletableFuture<Void> banFuture = banUser(guildId, userId, reason);
MessageToSend banLogMessage = templateService.renderEmbedTemplate(BAN_ID_LOG_TEMPLATE, banIdLog);
postTargetService.sendEmbedInPostTarget(banLogMessage, ModerationPostTarget.BAN_LOG, guildId);
List<CompletableFuture<Message>> notificationFutures = postTargetService.sendEmbedInPostTarget(banLogMessage, ModerationPostTarget.BAN_LOG, guildId);
return CompletableFuture.allOf(banFuture, FutureUtils.toSingleFutureGeneric(notificationFutures));
}
private void banUser(Long guildId, Long userId, String reason) {
private CompletableFuture<Void> banUser(Long guildId, Long userId, String reason) {
Optional<Guild> guildByIdOptional = botService.getGuildById(guildId);
if(guildByIdOptional.isPresent()) {
log.info("Banning user {} in guild {}.", userId, guildId);
banUser(guildByIdOptional.get(), userId, reason);
return banUser(guildByIdOptional.get(), userId, reason);
} else {
log.warn("Guild {} not found. Not able to ban user {}", guildId, userId);
throw new GuildNotFoundException(guildId);
}
}
private void banUser(Guild guild, Long userId, String reason) {
guild.ban(userId.toString(), 0, reason).queue();
private CompletableFuture<Void> banUser(Guild guild, Long userId, String reason) {
return guild.ban(userId.toString(), 0, reason).submit();
}
}

View File

@@ -1,6 +1,7 @@
package dev.sheldan.abstracto.moderation.service;
import dev.sheldan.abstracto.core.service.PostTargetService;
import dev.sheldan.abstracto.core.utils.FutureUtils;
import dev.sheldan.abstracto.moderation.config.posttargets.ModerationPostTarget;
import dev.sheldan.abstracto.moderation.models.template.commands.KickLogModel;
import dev.sheldan.abstracto.templating.model.MessageToSend;
@@ -11,6 +12,8 @@ import net.dv8tion.jda.api.entities.Member;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.concurrent.CompletableFuture;
@Component
@Slf4j
public class KickServiceBean implements KickService {
@@ -24,15 +27,16 @@ public class KickServiceBean implements KickService {
private PostTargetService postTargetService;
@Override
public void kickMember(Member member, String reason, KickLogModel kickLogModel) {
public CompletableFuture<Void> kickMember(Member member, String reason, KickLogModel kickLogModel) {
Guild guild = member.getGuild();
log.info("Kicking user {} from guild {}", member.getUser().getIdLong(), guild.getIdLong());
guild.kick(member, reason).queue();
this.sendKickLog(kickLogModel);
CompletableFuture<Void> kickFuture = guild.kick(member, reason).submit();
CompletableFuture<Void> logFuture = this.sendKickLog(kickLogModel);
return CompletableFuture.allOf(kickFuture, logFuture);
}
private void sendKickLog(KickLogModel kickLogModel) {
private CompletableFuture<Void> sendKickLog(KickLogModel kickLogModel) {
MessageToSend warnLogMessage = templateService.renderEmbedTemplate(KICK_LOG_TEMPLATE, kickLogModel);
postTargetService.sendEmbedInPostTarget(warnLogMessage, ModerationPostTarget.KICK_LOG, kickLogModel.getServer().getId());
return FutureUtils.toSingleFutureGeneric(postTargetService.sendEmbedInPostTarget(warnLogMessage, ModerationPostTarget.KICK_LOG, kickLogModel.getGuild().getIdLong()));
}
}

View File

@@ -2,17 +2,21 @@ package dev.sheldan.abstracto.moderation.service;
import dev.sheldan.abstracto.core.models.AServerAChannelMessage;
import dev.sheldan.abstracto.core.models.FullUserInServer;
import dev.sheldan.abstracto.core.models.ServerChannelMessage;
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.*;
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.FutureUtils;
import dev.sheldan.abstracto.moderation.config.posttargets.MutingPostTarget;
import dev.sheldan.abstracto.moderation.exception.MuteRoleNotSetupException;
import dev.sheldan.abstracto.moderation.exception.NoMuteFoundException;
import dev.sheldan.abstracto.moderation.models.database.Mute;
import dev.sheldan.abstracto.moderation.models.database.MuteRole;
import dev.sheldan.abstracto.moderation.models.template.commands.MuteLog;
import dev.sheldan.abstracto.moderation.models.template.commands.MuteContext;
import dev.sheldan.abstracto.moderation.models.template.commands.MuteNotification;
import dev.sheldan.abstracto.moderation.models.template.commands.UnMuteLog;
import dev.sheldan.abstracto.moderation.service.management.MuteManagementService;
@@ -30,9 +34,11 @@ import org.springframework.transaction.annotation.Transactional;
import java.time.Duration;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
@@ -68,7 +74,7 @@ public class MuteServiceBean implements MuteService {
private PostTargetService postTargetService;
@Autowired
private MuteService self;
private MuteServiceBean self;
@Autowired
@Qualifier("unmuteScheduler")
@@ -77,12 +83,19 @@ public class MuteServiceBean implements MuteService {
@Autowired
private ChannelManagementService channelManagementService;
@Autowired
private CounterService counterService;
@Autowired
private ServerManagementService serverManagementService;
public static final String MUTE_LOG_TEMPLATE = "mute_log";
public static final String UN_MUTE_LOG_TEMPLATE = "unmute_log";
public static final String MUTE_NOTIFICATION_TEMPLATE = "mute_notification";
public static final String MUTE_COUNTER_KEY = "MUTES";
@Override
public Mute muteMember(Member memberToMute, Member mutingMember, String reason, Instant unMuteDate, Message message) {
public CompletableFuture<Void> muteMember(Member memberToMute, Member mutingMember, String reason, Instant unMuteDate, ServerChannelMessage message) {
FullUserInServer mutedUser = FullUserInServer
.builder()
.aUserInAServer(userInServerManagementService.loadUser(memberToMute))
@@ -94,11 +107,11 @@ public class MuteServiceBean implements MuteService {
.aUserInAServer(userInServerManagementService.loadUser(mutingMember))
.member(mutingMember)
.build();
return muteUser(mutedUser, mutingUser, reason, unMuteDate, message);
return muteUserInServer(mutedUser, mutingUser, reason, unMuteDate, message);
}
@Override
public Mute muteAUserInAServer(AUserInAServer userBeingMuted, AUserInAServer userMuting, String reason, Instant unMuteDate, Message message) {
public CompletableFuture<Void> muteAUserInAServer(AUserInAServer userBeingMuted, AUserInAServer userMuting, String reason, Instant unMuteDate, ServerChannelMessage message) {
FullUserInServer mutedUser = FullUserInServer
.builder()
.aUserInAServer(userBeingMuted)
@@ -110,11 +123,11 @@ public class MuteServiceBean implements MuteService {
.aUserInAServer(userMuting)
.member(botService.getMemberInServer(userMuting))
.build();
return muteUser(mutedUser, mutingUser, reason, unMuteDate, message);
return muteUserInServer(mutedUser, mutingUser, reason, unMuteDate, message);
}
@Override
public Mute muteUser(FullUserInServer userBeingMuted, FullUserInServer userMuting, String reason, Instant unMuteDate, Message message) {
public CompletableFuture<Void> muteUserInServer(FullUserInServer userBeingMuted, FullUserInServer userMuting, String reason, Instant unMuteDate, ServerChannelMessage message) {
AServer serverBeingMutedIn = userBeingMuted.getAUserInAServer().getServerReference();
if(!muteRoleManagementService.muteRoleForServerExists(serverBeingMutedIn)) {
log.error("Mute role for server {} has not been setup.", serverBeingMutedIn.getId());
@@ -123,64 +136,73 @@ public class MuteServiceBean implements MuteService {
Member memberBeingMuted = userBeingMuted.getMember();
log.info("User {} mutes user {} until {}",
memberBeingMuted.getIdLong(), userMuting.getMember().getIdLong(), unMuteDate);
if(message != null) {
log.trace("because of message {} in channel {} in server {}", message.getId(), message.getChannel().getId(), message.getGuild().getId());
if(message.getMessageId() != null) {
log.trace("because of message {} in channel {} in server {}", message.getMessageId(), message.getChannelId(), message.getServerId());
} else {
log.trace("This mute was not triggered by a message.");
}
List<CompletableFuture<Void>> futures = new ArrayList<>();
AUserInAServer userInServerBeingMuted = userBeingMuted.getAUserInAServer();
applyMuteRole(userInServerBeingMuted);
Mute mute = createMuteObject(userMuting, reason, unMuteDate, message, userInServerBeingMuted);
futures.add(applyMuteRole(userInServerBeingMuted));
Guild guild = memberBeingMuted.getGuild();
if(memberBeingMuted.getVoiceState() != null && memberBeingMuted.getVoiceState().getChannel() != null) {
guild.kickVoiceMember(memberBeingMuted).queue();
futures.add(guild.kickVoiceMember(memberBeingMuted).submit());
}
sendMuteNotification(message, memberBeingMuted, mute, guild);
String triggerKey = startUnMuteJobFor(unMuteDate, mute);
mute.setTriggerKey(triggerKey);
muteManagementService.saveMute(mute);
return mute;
MuteNotification muteNotification = MuteNotification
.builder()
.muteTargetDate(unMuteDate)
.reason(reason)
.serverName(guild.getName())
.build();
futures.add(sendMuteNotification(message, memberBeingMuted, muteNotification));
return FutureUtils.toSingleFutureGeneric(futures);
}
private void sendMuteNotification(Message message, Member memberBeingMuted, Mute mute, Guild guild) {
private CompletableFuture<Void> sendMuteNotification(ServerChannelMessage message, Member memberBeingMuted, MuteNotification muteNotification) {
log.trace("Notifying the user about the mute.");
MuteNotification muteNotification = MuteNotification.builder().mute(mute).serverName(guild.getName()).build();
CompletableFuture<Void> notificationFuture = new CompletableFuture<>();
String muteNotificationMessage = templateService.renderTemplate(MUTE_NOTIFICATION_TEMPLATE, muteNotification);
MessageChannel textChannel = message != null ? message.getChannel() : null;
messageService.sendMessageToUser(memberBeingMuted.getUser(), muteNotificationMessage, textChannel);
CompletableFuture<Message> messageCompletableFuture = messageService.sendMessageToUser(memberBeingMuted.getUser(), muteNotificationMessage);
messageCompletableFuture.exceptionally(throwable -> {
TextChannel feedBackChannel = botService.getTextChannelFromServer(message.getServerId(), message.getChannelId());
feedBackChannel.sendMessage(throwable.getMessage()).submit().whenComplete((exceptionMessage, innerThrowable) ->
notificationFuture.complete(null)
);
return null;
});
messageCompletableFuture.thenAccept(message1 ->
notificationFuture.complete(null)
);
return notificationFuture;
}
private Mute createMuteObject(FullUserInServer userMuting, String reason, Instant unMuteDate, Message message, AUserInAServer userInServerBeingMuted) {
AServerAChannelMessage origin = null;
if(message != null) {
long channelId = message.getChannel().getIdLong();
AChannel channel = channelManagementService.loadChannel(channelId);
origin = AServerAChannelMessage
.builder()
.channel(channel)
.server(channel.getServer())
.messageId(message.getIdLong())
.build();
}
return muteManagementService.createMute(userInServerBeingMuted, userMuting.getAUserInAServer(), reason, unMuteDate, origin);
private void createMuteObject(MuteContext muteContext, String triggerKey) {
AChannel channel = channelManagementService.loadChannel(muteContext.getContext().getChannelId());
AServerAChannelMessage origin = AServerAChannelMessage
.builder()
.channel(channel)
.server(channel.getServer())
.messageId(muteContext.getContext().getMessageId())
.build();
AUserInAServer userInServerBeingMuted = userInServerManagementService.loadUser(muteContext.getMutedUser());
AUserInAServer userInServerMuting = userInServerManagementService.loadUser(muteContext.getMutedUser());
muteManagementService.createMute(userInServerBeingMuted, userInServerMuting, muteContext.getReason(), muteContext.getMuteTargetDate(), origin, triggerKey, muteContext.getMuteId());
}
@Override
public void applyMuteRole(AUserInAServer aUserInAServer) {
public CompletableFuture<Void> applyMuteRole(AUserInAServer aUserInAServer) {
MuteRole muteRole = muteRoleManagementService.retrieveMuteRoleForServer(aUserInAServer.getServerReference());
roleService.addRoleToUser(aUserInAServer, muteRole.getRole());
return roleService.addRoleToUserFuture(aUserInAServer, muteRole.getRole());
}
@Override
public String startUnMuteJobFor(Instant unMuteDate, Mute mute) {
public String startUnMuteJobFor(Instant unMuteDate, Long muteId, Long serverId) {
Duration muteDuration = Duration.between(Instant.now(), unMuteDate);
if(muteDuration.getSeconds() < 60) {
log.trace("Directly scheduling the unMute, because it was below the threshold.");
unMuteScheduler.schedule(() -> {
try {
self.endMute(mute.getId());
self.endMute(muteId, serverId);
} catch (Exception exception) {
log.error("Failed to remind immediately.", exception);
}
@@ -189,7 +211,8 @@ public class MuteServiceBean implements MuteService {
} else {
log.trace("Starting scheduled job to execute unMute.");
JobDataMap parameters = new JobDataMap();
parameters.putAsString("muteId", mute.getId());
parameters.putAsString("muteId", muteId);
parameters.putAsString("serverId", serverId);
return schedulerService.executeJobWithParametersOnce("unMuteJob", "moderation", parameters, Date.from(unMuteDate));
}
}
@@ -202,61 +225,101 @@ public class MuteServiceBean implements MuteService {
}
@Override
public void muteMemberWithLog(Member memberToMute, Member memberMuting, String reason, Instant unMuteDate, MuteLog muteLog, Message message) {
public CompletableFuture<Void> muteMemberWithLog(MuteContext context) {
log.trace("Muting member with sending a mute log");
Mute mute = muteMember(memberToMute, memberMuting, reason, unMuteDate, message);
muteLog.setMute(mute);
sendMuteLog(muteLog);
AServer server = serverManagementService.loadOrCreate(context.getContext().getServerId());
Long nextCounterValue = counterService.getNextCounterValue(server, MUTE_COUNTER_KEY);
context.setMuteId(nextCounterValue);
CompletableFuture<Void> mutingFuture = muteMember(context.getMutedUser(), context.getMutingUser(), context.getReason(), context.getMuteTargetDate(), context.getContext());
CompletableFuture<Void> muteLogFuture = sendMuteLog(context);
return CompletableFuture.allOf(mutingFuture, muteLogFuture).thenAccept(aVoid ->
self.persistMute(context)
);
}
private void sendMuteLog(MuteLog muteLogModel) {
@Transactional
public void persistMute(MuteContext context) {
String triggerKey = startUnMuteJobFor(context.getMuteTargetDate(), context.getMuteId(), context.getContext().getServerId());
createMuteObject(context, triggerKey);
}
public CompletableFuture<Void> sendMuteLog(MuteContext muteLogModel) {
log.trace("Sending mute log to the mute posttarget");
MessageToSend message = templateService.renderEmbedTemplate(MUTE_LOG_TEMPLATE, muteLogModel);
postTargetService.sendEmbedInPostTarget(message, MutingPostTarget.MUTE_LOG, muteLogModel.getServer().getId());
List<CompletableFuture<Message>> completableFutures = postTargetService.sendEmbedInPostTarget(message, MutingPostTarget.MUTE_LOG, muteLogModel.getContext().getServerId());
return FutureUtils.toSingleFutureGeneric(completableFutures);
}
private void sendUnMuteLog(UnMuteLog muteLogModel) {
private CompletableFuture<Void> sendUnMuteLog(UnMuteLog muteLogModel) {
log.trace("Sending unMute log to the mute posttarget");
MessageToSend message = templateService.renderEmbedTemplate(UN_MUTE_LOG_TEMPLATE, muteLogModel);
postTargetService.sendEmbedInPostTarget(message, MutingPostTarget.MUTE_LOG, muteLogModel.getServer().getId());
List<CompletableFuture<Message>> completableFutures = postTargetService.sendEmbedInPostTarget(message, MutingPostTarget.MUTE_LOG, muteLogModel.getServer().getId());
return FutureUtils.toSingleFutureGeneric(completableFutures);
}
@Override
@Transactional
public void unMuteUser(Mute mute) {
if(Boolean.TRUE.equals(mute.getMuteEnded())) {
log.info("Mute {} has ended already, user {} does not need to be unMuted anymore.", mute.getId(), mute.getMutedUser().getUserReference().getId());
return;
public CompletableFuture<Void> unMuteUser(AUserInAServer aUserInAServer) {
if(muteManagementService.hasActiveMute(aUserInAServer)) {
throw new NoMuteFoundException();
}
AServer mutingServer = mute.getMutingServer();
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);
}
return endMute(mute);
}
@Override
public CompletableFuture<Void> endMute(Mute mute) {
Long muteId = mute.getMuteId().getId();
AServer mutingServer = mute.getServer();
log.info("UnMuting {} in server {}", mute.getMutedUser().getUserReference().getId(), mutingServer.getId());
MuteRole muteRole = muteRoleManagementService.retrieveMuteRoleForServer(mutingServer);
log.trace("Using the mute role {} mapping to role {}", muteRole.getId(), muteRole.getRole().getId());
Guild guild = botService.getGuildByIdNullable(mute.getMutingServer().getId());
Guild guild = botService.getGuildByIdNullable(mutingServer.getId());
CompletableFuture<Void> roleRemovalFuture;
if(botService.isUserInGuild(guild, mute.getMutedUser())) {
roleService.removeRoleFromUser(mute.getMutedUser(), muteRole.getRole());
roleRemovalFuture = roleService.removeRoleFromUserFuture(mute.getMutedUser(), muteRole.getRole());
} else {
roleRemovalFuture = CompletableFuture.completedFuture(null);
log.info("User to unMute left the guild.");
}
Long serverId = mutingServer.getId();
UnMuteLog unMuteLog = UnMuteLog
.builder()
.mute(mute)
.mutingUser(botService.getMemberInServer(mute.getMutingUser()))
.unMutedUser(botService.getMemberInServer(mute.getMutedUser()))
.guild(guild)
.server(mute.getMutingServer())
.server(mutingServer)
.build();
sendUnMuteLog(unMuteLog);
mute.setMuteEnded(true);
muteManagementService.saveMute(mute);
CompletableFuture<Void> notificationFuture = sendUnMuteLog(unMuteLog);
return CompletableFuture.allOf(roleRemovalFuture, notificationFuture).thenAccept(aVoid ->
self.endMuteInDatabase(muteId, serverId)
);
}
@Transactional
public void endMuteInDatabase(Long muteId, Long serverId) {
Optional<Mute> muteOptional = muteManagementService.findMute(muteId, serverId);
muteOptional.ifPresent(mute ->
completelyUnMuteUser(mute.getMutedUser())
);
}
@Override
@Transactional
public void endMute(Long muteId) {
public CompletableFuture<Void> endMute(Long muteId, Long serverId) {
log.info("UnMuting the mute {}", muteId);
Optional<Mute> mute = muteManagementService.findMute(muteId);
mute.ifPresent(this::unMuteUser);
Optional<Mute> muteOptional = muteManagementService.findMute(muteId, serverId);
if(muteOptional.isPresent()) {
return endMute(muteOptional.get());
} else {
throw new NoMuteFoundException();
}
}
@Override

View File

@@ -10,6 +10,7 @@ import org.springframework.stereotype.Component;
import java.time.Duration;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
@Component
@Slf4j
@@ -19,26 +20,26 @@ public class SlowModeServiceBean implements SlowModeService {
private BotService botService;
@Override
public void setSlowMode(TextChannel channel, Duration duration) {
public CompletableFuture<Void> setSlowMode(TextChannel channel, Duration duration) {
log.info("Setting slow mode to {} in channel {} in server {}", duration.toString(), channel.getIdLong(), channel.getGuild().getId());
long seconds = duration.getSeconds();
if(seconds > TextChannel.MAX_SLOWMODE) {
throw new IllegalArgumentException("Slow mode duration must be < " + TextChannel.MAX_SLOWMODE + " seconds.");
}
channel.getManager().setSlowmode((int) seconds).queue();
return channel.getManager().setSlowmode((int) seconds).submit();
}
@Override
public void disableSlowMode(TextChannel channel) {
setSlowMode(channel, Duration.ZERO);
public CompletableFuture<Void> disableSlowMode(TextChannel channel) {
return setSlowMode(channel, Duration.ZERO);
}
@Override
public void setSlowMode(AChannel channel, Duration duration) {
public CompletableFuture<Void> setSlowMode(AChannel channel, Duration duration) {
Optional<TextChannel> textChannelOptional = botService.getTextChannelFromServerOptional(channel.getServer().getId(), channel.getId());
if(textChannelOptional.isPresent()) {
TextChannel textChannel = textChannelOptional.get();
this.setSlowMode(textChannel, duration);
return this.setSlowMode(textChannel, duration);
} else {
throw new ChannelNotFoundException(channel.getId());
}

View File

@@ -1,26 +1,25 @@
package dev.sheldan.abstracto.moderation.service;
import dev.sheldan.abstracto.core.models.FullUserInServer;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.service.ConfigService;
import dev.sheldan.abstracto.core.service.MessageService;
import dev.sheldan.abstracto.core.service.*;
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
import dev.sheldan.abstracto.core.utils.FutureUtils;
import dev.sheldan.abstracto.moderation.config.features.WarningDecayFeature;
import dev.sheldan.abstracto.moderation.config.posttargets.WarnDecayPostTarget;
import dev.sheldan.abstracto.moderation.config.posttargets.WarningPostTarget;
import dev.sheldan.abstracto.moderation.models.template.job.WarnDecayLogModel;
import dev.sheldan.abstracto.moderation.models.template.job.WarnDecayWarning;
import dev.sheldan.abstracto.templating.model.MessageToSend;
import dev.sheldan.abstracto.moderation.models.template.commands.WarnLog;
import dev.sheldan.abstracto.moderation.models.template.commands.WarnContext;
import dev.sheldan.abstracto.moderation.models.template.commands.WarnNotification;
import dev.sheldan.abstracto.moderation.models.database.Warning;
import dev.sheldan.abstracto.moderation.service.management.WarnManagementService;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
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.templating.service.TemplateService;
import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.entities.*;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
@@ -29,6 +28,8 @@ import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
@Slf4j
@Component
@@ -55,73 +56,88 @@ public class WarnServiceBean implements WarnService {
@Autowired
private ConfigService configService;
@Autowired
private CounterService counterService;
@Autowired
private ServerManagementService serverManagementService;
@Autowired
private WarnServiceBean self;
public static final String WARN_LOG_TEMPLATE = "warn_log";
public static final String WARN_NOTIFICATION_TEMPLATE = "warn_notification";
public static final String WARNINGS_COUNTER_KEY = "WARNINGS";
public static final String WARN_DECAY_LOG_TEMPLATE_KEY = "warn_decay_log";
@Override
public Warning warnUser(AUserInAServer warnedAUserInAServer, AUserInAServer warningAUserInAServer, String reason, MessageChannel feedbackChannel) {
FullUserInServer warnedUser = FullUserInServer
.builder()
.aUserInAServer(warnedAUserInAServer)
.member(botService.getMemberInServer(warnedAUserInAServer))
.build();
FullUserInServer warningUser = FullUserInServer
.builder()
.aUserInAServer(warningAUserInAServer)
.member(botService.getMemberInServer(warningAUserInAServer))
.build();
return warnFullUser(warnedUser, warningUser, reason, feedbackChannel);
}
@Override
public Warning warnMember(Member warnedMember, Member warningMember, String reason, MessageChannel feedbackChannel) {
FullUserInServer warnedUser = FullUserInServer
.builder()
.aUserInAServer(userInServerManagementService.loadUser(warnedMember))
.member(warnedMember)
.build();
FullUserInServer warningUser = FullUserInServer
.builder()
.aUserInAServer(userInServerManagementService.loadUser(warningMember))
.member(warningMember)
.build();
return warnFullUser(warnedUser, warningUser, reason, feedbackChannel);
}
@Override
public Warning warnFullUser(FullUserInServer warnedMember, FullUserInServer warningMember, String reason, MessageChannel feedbackChannel) {
Guild guild = warnedMember.getMember().getGuild();
log.info("User {} is warning {} in server {}", warnedMember.getMember().getId(), warningMember.getMember().getId(), guild.getIdLong());
Warning warning = warnManagementService.createWarning(warnedMember.getAUserInAServer(), warningMember.getAUserInAServer(), reason);
WarnNotification warnNotification = WarnNotification.builder().warning(warning).serverName(guild.getName()).build();
public CompletableFuture<Void> notifyAndLogFullUserWarning(WarnContext context) {
AServer server = serverManagementService.loadOrCreate(context.getGuild().getIdLong());
Long warningId = counterService.getNextCounterValue(server, WARNINGS_COUNTER_KEY);
context.setWarnId(warningId);
Member warnedMember = context.getWarnedMember();
Member warningMember = context.getMember();
Guild guild = warnedMember.getGuild();
log.info("User {} is warning {} in server {}", warnedMember.getId(), warningMember.getId(), guild.getIdLong());
WarnNotification warnNotification = WarnNotification.builder().reason(context.getReason()).warnId(warningId).serverName(guild.getName()).build();
String warnNotificationMessage = templateService.renderTemplate(WARN_NOTIFICATION_TEMPLATE, warnNotification);
messageService.sendMessageToUser(warnedMember.getMember().getUser(), warnNotificationMessage, feedbackChannel);
return warning;
List<CompletableFuture<Message>> futures = new ArrayList<>();
futures.add(messageService.sendMessageToUser(warnedMember.getUser(), warnNotificationMessage));
MessageToSend message = templateService.renderEmbedTemplate(WARN_LOG_TEMPLATE, context);
futures.addAll(postTargetService.sendEmbedInPostTarget(message, WarningPostTarget.WARN_LOG, context.getGuild().getIdLong()));
return FutureUtils.toSingleFutureGeneric(futures);
}
@Override
public Warning warnUserWithLog(Member warnedMember, Member warningMember, String reason, WarnLog warnLog, MessageChannel feedbackChannel) {
Warning warning = warnMember(warnedMember, warningMember, reason, feedbackChannel);
warnLog.setWarning(warning);
this.sendWarnLog(warnLog);
return warning;
public CompletableFuture<Void> warnUserWithLog(WarnContext context) {
return notifyAndLogFullUserWarning(context).thenAccept(aVoid ->
self.persistWarning(context)
);
}
@Transactional
public void persistWarning(WarnContext context) {
AUserInAServer warnedUser = userInServerManagementService.loadUser(context.getWarnedMember());
AUserInAServer warningUser = userInServerManagementService.loadUser(context.getMember());
warnManagementService.createWarning(warnedUser, warningUser, context.getReason(), context.getWarnId());
}
@Override
@Transactional
public void decayWarningsForServer(AServer server) {
public CompletableFuture<Void> decayWarningsForServer(AServer server) {
Long days = configService.getLongValue(WarningDecayFeature.DECAY_DAYS_KEY, server.getId());
Instant cutOffDay = Instant.now().minus(days, ChronoUnit.DAYS);
List<Warning> warningsToDecay = warnManagementService.getActiveWarningsInServerOlderThan(server, cutOffDay);
decayWarnings(warningsToDecay);
logDecayedWarnings(server, warningsToDecay);
List<Long> warningIds = flattenWarnings(warningsToDecay);
Long serverId = server.getId();
return logDecayedWarnings(server, warningsToDecay).thenAccept(aVoid ->
self.decayWarnings(warningIds, serverId)
);
}
private void decayWarnings(List<Warning> warningsToDecay) {
@NotNull
private List<Long> flattenWarnings(List<Warning> warningsToDecay) {
List<Long> warningIds = new ArrayList<>();
warningsToDecay.forEach(warning ->
warningIds.add(warning.getWarnId().getId())
);
return warningIds;
}
@Transactional
public void decayWarnings(List<Long> warningIds, Long serverId) {
Instant now = Instant.now();
warningsToDecay.forEach(warning -> decayWarning(warning, now));
warningIds.forEach(warningId -> {
Optional<Warning> warningOptional = warnManagementService.findById(warningId, serverId);
warningOptional.ifPresent(warning ->
decayWarning(warning, now)
);
if(!warningOptional.isPresent()) {
log.warn("Warning with id {} in server {} not found. Was not decayed.", warningId, serverId);
}
});
}
@Override
@@ -130,7 +146,7 @@ public class WarnServiceBean implements WarnService {
warning.setDecayed(true);
}
private void logDecayedWarnings(AServer server, List<Warning> warningsToDecay) {
private CompletableFuture<Void> logDecayedWarnings(AServer server, List<Warning> warningsToDecay) {
List<WarnDecayWarning> warnDecayWarnings = new ArrayList<>();
warningsToDecay.forEach(warning -> {
WarnDecayWarning warnDecayWarning = WarnDecayWarning
@@ -147,21 +163,23 @@ public class WarnServiceBean implements WarnService {
.server(server)
.warnings(warnDecayWarnings)
.build();
MessageToSend messageToSend = templateService.renderEmbedTemplate("warn_decay_log", warnDecayLogModel);
postTargetService.sendEmbedInPostTarget(messageToSend, WarnDecayPostTarget.DECAY_LOG, server.getId());
MessageToSend messageToSend = templateService.renderEmbedTemplate(WARN_DECAY_LOG_TEMPLATE_KEY, warnDecayLogModel);
List<CompletableFuture<Message>> messageFutures = postTargetService.sendEmbedInPostTarget(messageToSend, WarnDecayPostTarget.DECAY_LOG, server.getId());
return FutureUtils.toSingleFutureGeneric(messageFutures);
}
@Override
public void decayAllWarningsForServer(AServer server, boolean logWarnings) {
public CompletableFuture<Void> decayAllWarningsForServer(AServer server, boolean logWarnings) {
List<Warning> warningsToDecay = warnManagementService.getActiveWarningsInServerOlderThan(server, Instant.now());
decayWarnings(warningsToDecay);
List<Long> warnIds = flattenWarnings(warningsToDecay);
Long serverId = server.getId();
if(logWarnings) {
logDecayedWarnings(server, warningsToDecay);
return logDecayedWarnings(server, warningsToDecay).thenAccept(aVoid ->
self.decayWarnings(warnIds, serverId)
);
} else {
decayWarnings(warnIds, serverId);
return CompletableFuture.completedFuture(null);
}
}
private void sendWarnLog(WarnLog warnLogModel) {
MessageToSend message = templateService.renderEmbedTemplate(WARN_LOG_TEMPLATE, warnLogModel);
postTargetService.sendEmbedInPostTarget(message, WarningPostTarget.WARN_LOG, warnLogModel.getServer().getId());
}
}

View File

@@ -1,6 +1,7 @@
package dev.sheldan.abstracto.moderation.service.management;
import dev.sheldan.abstracto.core.models.AServerAChannelMessage;
import dev.sheldan.abstracto.core.models.ServerSpecificId;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.moderation.models.database.Mute;
@@ -25,18 +26,21 @@ public class MuteManagementServiceBean implements MuteManagementService {
private UserInServerManagementService userInServerManagementService;
@Override
public Mute createMute(AUserInAServer mutedUser, AUserInAServer mutingUser, String reason, Instant unMuteDate, AServerAChannelMessage muteMessage) {
public Mute createMute(AUserInAServer mutedUser, AUserInAServer mutingUser, String reason, Instant unMuteDate, AServerAChannelMessage muteMessage, String triggerKey, Long muteId) {
log.trace("Creating mute for user {} executed by user {} in server {}, user will be un-muted at {}",
mutedUser.getUserReference().getId(), mutingUser.getUserReference().getId(), mutedUser.getServerReference().getId(), unMuteDate);
ServerSpecificId id = new ServerSpecificId(muteMessage.getServer().getId(), muteId);
Mute mute = Mute
.builder()
.mutedUser(mutedUser)
.mutingUser(mutingUser)
.muteTargetDate(unMuteDate)
.mutingServer(mutedUser.getServerReference())
.server(mutedUser.getServerReference())
.mutingChannel(muteMessage.getChannel())
.messageId(muteMessage.getMessageId())
.reason(reason)
.triggerKey(triggerKey)
.muteId(id)
.muteEnded(false)
.build();
muteRepository.save(mute);
@@ -44,8 +48,8 @@ public class MuteManagementServiceBean implements MuteManagementService {
}
@Override
public Optional<Mute> findMute(Long muteId) {
return muteRepository.findById(muteId);
public Optional<Mute> findMute(Long muteId, Long serverId) {
return muteRepository.findByMuteId_IdAndMuteId_ServerId(muteId, serverId);
}
@Override
@@ -76,7 +80,7 @@ public class MuteManagementServiceBean implements MuteManagementService {
@Override
public List<Mute> getAllMutesOf(AUserInAServer aUserInAServer) {
return muteRepository.findAllByMutedUserAndMuteEndedFalseOrderByIdDesc(aUserInAServer);
return muteRepository.findAllByMutedUserAndMuteEndedFalseOrderByMuteId_IdDesc(aUserInAServer);
}

View File

@@ -1,7 +1,9 @@
package dev.sheldan.abstracto.moderation.service.management;
import dev.sheldan.abstracto.core.models.ServerSpecificId;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.service.CounterService;
import dev.sheldan.abstracto.moderation.models.database.UserNote;
import dev.sheldan.abstracto.moderation.repository.UserNoteRepository;
import org.springframework.beans.factory.annotation.Autowired;
@@ -15,11 +17,20 @@ public class UserNoteManagementServiceBean implements UserNoteManagementService
@Autowired
private UserNoteRepository userNoteRepository;
@Autowired
private CounterService counterService;
public static final String USER_NOTE_COUNTER_KEY = "USER_NOTES";
@Override
public UserNote createUserNote(AUserInAServer aUserInAServer, String note) {
Long id = counterService.getNextCounterValue(aUserInAServer.getServerReference(), USER_NOTE_COUNTER_KEY);
ServerSpecificId userNoteId = new ServerSpecificId(aUserInAServer.getServerReference().getId(), id);
UserNote newNote = UserNote
.builder()
.note(note)
.userNoteId(userNoteId)
.server(aUserInAServer.getServerReference())
.user(aUserInAServer)
.build();
userNoteRepository.save(newNote);

View File

@@ -1,5 +1,6 @@
package dev.sheldan.abstracto.moderation.service.management;
import dev.sheldan.abstracto.core.models.ServerSpecificId;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.moderation.models.database.Warning;
import dev.sheldan.abstracto.moderation.repository.WarnRepository;
@@ -18,12 +19,15 @@ public class WarnManagementServiceBean implements WarnManagementService {
private WarnRepository warnRepository;
@Override
public Warning createWarning(AUserInAServer warnedAUser, AUserInAServer warningAUser, String reason) {
public Warning createWarning(AUserInAServer warnedAUser, AUserInAServer warningAUser, String reason, Long warnId) {
ServerSpecificId warningId = new ServerSpecificId(warnId, warningAUser.getServerReference().getId());
Warning warning = Warning.builder()
.reason(reason)
.warnedUser(warnedAUser)
.warningUser(warningAUser)
.warnDate(Instant.now())
.server(warningAUser.getServerReference())
.warnId(warningId)
.decayed(false)
.build();
warnRepository.save(warning);
@@ -56,8 +60,8 @@ public class WarnManagementServiceBean implements WarnManagementService {
}
@Override
public Optional<Warning> findById(Long id) {
return warnRepository.findById(id);
public Optional<Warning> findById(Long id, Long serverId) {
return warnRepository.findByWarnId_IdAndWarnId_ServerId(id, serverId);
}
@Override

View File

@@ -23,7 +23,7 @@
<column name="muting_channel" type="BIGINT">
<constraints nullable="false"/>
</column>
<column name="muting_server" type="BIGINT">
<column name="server_id" type="BIGINT">
<constraints nullable="false"/>
</column>
<column name="mute_ended" type="BOOLEAN"/>
@@ -44,8 +44,8 @@
<changeSet author="Sheldan" id="mute-fk_mute_muted_user">
<addForeignKeyConstraint baseColumnNames="muted_user" baseTableName="mute" constraintName="fk_mute_muted_user" deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="user_in_server_id" referencedTableName="user_in_server" validate="true"/>
</changeSet>
<changeSet author="Sheldan" id="mute-fk_mute_muting_server">
<addForeignKeyConstraint baseColumnNames="muting_server" baseTableName="mute" constraintName="fk_mute_muting_server" deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="id" referencedTableName="server" validate="true"/>
<changeSet author="Sheldan" id="mute-fk_mute_server_id">
<addForeignKeyConstraint baseColumnNames="server_id" baseTableName="mute" constraintName="fk_mute_server_id" deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="id" referencedTableName="server" validate="true"/>
</changeSet>
</databaseChangeLog>

View File

@@ -16,11 +16,17 @@
<column name="note_user" type="BIGINT">
<constraints nullable="false"/>
</column>
<column name="server_id" type="BIGINT">
<constraints nullable="false"/>
</column>
</createTable>
</changeSet>
<changeSet author="Sheldan" id="user_note-fk_user_note_user">
<addForeignKeyConstraint baseColumnNames="note_user" baseTableName="user_note" constraintName="fk_user_note_user" deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="user_in_server_id" referencedTableName="user_in_server" validate="true"/>
</changeSet>
<changeSet author="Sheldan" id="user_note-fk_user_note_server_id">
<addForeignKeyConstraint baseColumnNames="server_id" baseTableName="user_note" constraintName="fk_user_note_server_id" deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="id" referencedTableName="server" validate="true"/>
</changeSet>
</databaseChangeLog>

View File

@@ -23,6 +23,9 @@
<column name="warning_user_id" type="BIGINT">
<constraints nullable="false"/>
</column>
<column name="server_id" type="BIGINT">
<constraints nullable="false"/>
</column>
</createTable>
</changeSet>
@@ -33,4 +36,8 @@
<changeSet author="Sheldan" id="warning-fk_warning_warning_user">
<addForeignKeyConstraint baseColumnNames="warning_user_id" baseTableName="warning" constraintName="fk_warning_warning_user" deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="user_in_server_id" referencedTableName="user_in_server" validate="true"/>
</changeSet>
<changeSet author="Sheldan" id="warning-fk_warning_server_id">
<addForeignKeyConstraint baseColumnNames="server_id" baseTableName="warning" constraintName="fk_warning_server_id" deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="id" referencedTableName="server" validate="true"/>
</changeSet>
</databaseChangeLog>

View File

@@ -16,6 +16,7 @@ import org.mockito.*;
import org.mockito.junit.MockitoJUnitRunner;
import java.util.Arrays;
import java.util.concurrent.CompletableFuture;
import static org.mockito.Mockito.*;
@@ -43,13 +44,13 @@ public class BanIdTest {
Long guildId = parameters.getUserInitiatedContext().getServer().getId();
when(templateService.renderSimpleTemplate(Ban.BAN_DEFAULT_REASON_TEMPLATE)).thenReturn(REASON);
when(parameters.getGuild().getIdLong()).thenReturn(guildId);
CommandResult result = testUnit.execute(parameters);
verify(banService, times(1)).banMember(eq(guildId), eq(BANNED_USER_ID), eq(REASON), banLogModelCaptor.capture());
when(banService.banMember(eq(guildId), eq(BANNED_USER_ID), eq(REASON), banLogModelCaptor.capture())).thenReturn(CompletableFuture.completedFuture(null));
CompletableFuture<CommandResult> result = testUnit.executeAsync(parameters);
BanIdLog usedModel = banLogModelCaptor.getValue();
Assert.assertEquals(REASON, usedModel.getReason());
Assert.assertEquals(BANNED_USER_ID, usedModel.getBannedUserId());
Assert.assertEquals(parameters.getAuthor(), usedModel.getBanningUser());
CommandTestUtilities.checkSuccessfulCompletion(result);
CommandTestUtilities.checkSuccessfulCompletionAsync(result);
}
@Test
@@ -59,25 +60,25 @@ public class BanIdTest {
Long guildId = parameters.getUserInitiatedContext().getServer().getId();
when(parameters.getGuild().getIdLong()).thenReturn(guildId);
when(templateService.renderSimpleTemplate(Ban.BAN_DEFAULT_REASON_TEMPLATE)).thenReturn(REASON);
CommandResult result = testUnit.execute(parameters);
verify(banService, times(1)).banMember(eq(guildId), eq(BANNED_USER_ID), eq(customReason), banLogModelCaptor.capture());
when(banService.banMember(eq(guildId), eq(BANNED_USER_ID), eq(customReason), banLogModelCaptor.capture())).thenReturn(CompletableFuture.completedFuture(null));
CompletableFuture<CommandResult> result = testUnit.executeAsync(parameters);
BanIdLog usedModel = banLogModelCaptor.getValue();
Assert.assertEquals(customReason, usedModel.getReason());
Assert.assertEquals(BANNED_USER_ID, usedModel.getBannedUserId());
Assert.assertEquals(parameters.getAuthor(), usedModel.getBanningUser());
CommandTestUtilities.checkSuccessfulCompletion(result);
CommandTestUtilities.checkSuccessfulCompletionAsync(result);
}
@Test(expected = InsufficientParametersException.class)
public void testTooLittleParameters() {
CommandTestUtilities.executeNoParametersTest(testUnit);
CommandTestUtilities.executeNoParametersTestAsync(testUnit);
}
@Test(expected = IncorrectParameterException.class)
public void testIncorrectParameterType() {
CommandTestUtilities.executeWrongParametersTest(testUnit);
CommandTestUtilities.executeWrongParametersTestAsync(testUnit);
}
@Test

View File

@@ -17,6 +17,7 @@ import org.mockito.*;
import org.mockito.junit.MockitoJUnitRunner;
import java.util.Arrays;
import java.util.concurrent.CompletableFuture;
import static org.mockito.Mockito.*;
@@ -44,13 +45,13 @@ public class BanTest {
public void testBanWithDefaultReason() {
CommandContext parameters = CommandTestUtilities.getWithParameters(Arrays.asList(bannedMember));
when(templateService.renderSimpleTemplate(Ban.BAN_DEFAULT_REASON_TEMPLATE)).thenReturn(REASON);
CommandResult result = testUnit.execute(parameters);
verify(banService, times(1)).banMember(eq(bannedMember), eq(REASON), banLogModelCaptor.capture());
when(banService.banMember(eq(bannedMember), eq(REASON), banLogModelCaptor.capture())).thenReturn(CompletableFuture.completedFuture(null));
CompletableFuture<CommandResult> result = testUnit.executeAsync(parameters);
BanLog usedModel = banLogModelCaptor.getValue();
Assert.assertEquals(REASON, usedModel.getReason());
Assert.assertEquals(bannedMember, usedModel.getBannedUser());
Assert.assertEquals(parameters.getAuthor(), usedModel.getBanningUser());
CommandTestUtilities.checkSuccessfulCompletion(result);
CommandTestUtilities.checkSuccessfulCompletionAsync(result);
}
@Test
@@ -58,23 +59,23 @@ public class BanTest {
String customReason = "reason2";
CommandContext parameters = CommandTestUtilities.getWithParameters(Arrays.asList(bannedMember, customReason));
when(templateService.renderSimpleTemplate(Ban.BAN_DEFAULT_REASON_TEMPLATE)).thenReturn(REASON);
CommandResult result = testUnit.execute(parameters);
verify(banService, times(1)).banMember(eq(bannedMember), eq(customReason), banLogModelCaptor.capture());
when(banService.banMember(eq(bannedMember), eq(customReason), banLogModelCaptor.capture())).thenReturn(CompletableFuture.completedFuture(null));
CompletableFuture<CommandResult> result = testUnit.executeAsync(parameters);
BanLog usedModel = banLogModelCaptor.getValue();
Assert.assertEquals(customReason, usedModel.getReason());
Assert.assertEquals(bannedMember, usedModel.getBannedUser());
Assert.assertEquals(parameters.getAuthor(), usedModel.getBanningUser());
CommandTestUtilities.checkSuccessfulCompletion(result);
CommandTestUtilities.checkSuccessfulCompletionAsync(result);
}
@Test(expected = InsufficientParametersException.class)
public void testTooLittleParameters() {
CommandTestUtilities.executeNoParametersTest(testUnit);
CommandTestUtilities.executeNoParametersTestAsync(testUnit);
}
@Test(expected = IncorrectParameterException.class)
public void testIncorrectParameterType() {
CommandTestUtilities.executeWrongParametersTest(testUnit);
CommandTestUtilities.executeWrongParametersTestAsync(testUnit);
}
@Test

View File

@@ -13,6 +13,7 @@ import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import java.util.Arrays;
import java.util.concurrent.CompletableFuture;
import static org.mockito.Mockito.*;
@@ -42,13 +43,13 @@ public class DecayAllWarningsTest {
@Test(expected = IncorrectParameterException.class)
public void testIncorrectParameterType() {
CommandTestUtilities.executeWrongParametersTest(testUnit);
CommandTestUtilities.executeWrongParametersTestAsync(testUnit);
}
private void executeTest(Boolean logWarnings) {
CommandContext parameters = CommandTestUtilities.getWithParameters(Arrays.asList(logWarnings));
CommandResult result = testUnit.execute(parameters);
verify(warnService, times(1)).decayAllWarningsForServer(parameters.getUserInitiatedContext().getServer(), logWarnings);
CommandTestUtilities.checkSuccessfulCompletion(result);
CommandContext commandContext = CommandTestUtilities.getWithParameters(Arrays.asList(logWarnings));
when(warnService.decayAllWarningsForServer(commandContext.getUserInitiatedContext().getServer(), logWarnings)).thenReturn(CompletableFuture.completedFuture(null));
CompletableFuture<CommandResult> result = testUnit.executeAsync(commandContext);
CommandTestUtilities.checkSuccessfulCompletionAsync(result);
}
}

View File

@@ -11,6 +11,8 @@ import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import java.util.concurrent.CompletableFuture;
import static org.mockito.Mockito.*;
@RunWith(MockitoJUnitRunner.class)
@@ -25,9 +27,9 @@ public class DecayWarningsTest {
@Test
public void testExecuteCommand() {
CommandContext noParameters = CommandTestUtilities.getNoParameters();
CommandResult result = testUnit.execute(noParameters);
CommandTestUtilities.checkSuccessfulCompletion(result);
verify(warnService, times(1)).decayWarningsForServer(noParameters.getUserInitiatedContext().getServer());
when(warnService.decayWarningsForServer(noParameters.getUserInitiatedContext().getServer())).thenReturn(CompletableFuture.completedFuture(null));
CompletableFuture<CommandResult> result = testUnit.executeAsync(noParameters);
CommandTestUtilities.checkSuccessfulCompletionAsync(result);
}
@Test

View File

@@ -38,15 +38,15 @@ public class DeleteWarningTest {
AUserInAServer warnedUser = MockUtils.getUserObject(5L, server);
AUserInAServer warningUser = MockUtils.getUserObject(6L, server);
Warning existingWarning = Warning.builder().warnedUser(warnedUser).warningUser(warningUser).build();
when(warnManagementService.findById(WARN_ID)).thenReturn(Optional.of(existingWarning));
CommandContext parameters = CommandTestUtilities.getWithParameters(Arrays.asList(WARN_ID));
when(warnManagementService.findById(WARN_ID, parameters.getGuild().getIdLong())).thenReturn(Optional.of(existingWarning));
CommandResult result = testUnit.execute(parameters);
verify(warnManagementService, times(1)).deleteWarning(existingWarning);
CommandTestUtilities.checkSuccessfulCompletion(result);
}
@Test
public void testDeleteNotExistingWarning() {
when(warnManagementService.findById(WARN_ID)).thenReturn(Optional.empty());
CommandContext parameters = CommandTestUtilities.getWithParameters(Arrays.asList(WARN_ID));
CommandResult result = testUnit.execute(parameters);
CommandTestUtilities.checkSuccessfulCompletion(result);

View File

@@ -20,6 +20,7 @@ import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import java.util.Arrays;
import java.util.concurrent.CompletableFuture;
import static org.mockito.Mockito.*;
@@ -47,37 +48,37 @@ public class KickTest {
public void testKickMemberWithoutReason() {
CommandContext parameters = CommandTestUtilities.getWithParameters(Arrays.asList(memberToKick));
when(templateService.renderSimpleTemplate(Kick.KICK_DEFAULT_REASON_TEMPLATE)).thenReturn(REASON);
CommandResult result = testUnit.execute(parameters);
verify(kickService, times(1)).kickMember(eq(memberToKick), eq(REASON), logModelArgumentCaptor.capture());
when(kickService.kickMember(eq(memberToKick), eq(REASON), logModelArgumentCaptor.capture())).thenReturn(CompletableFuture.completedFuture(null));
CompletableFuture<CommandResult> result = testUnit.executeAsync(parameters);
KickLogModel usedLogModel = logModelArgumentCaptor.getValue();
Assert.assertEquals(REASON, usedLogModel.getReason());
Assert.assertEquals(memberToKick, usedLogModel.getKickedUser());
Assert.assertEquals(parameters.getAuthor(), usedLogModel.getKickingUser());
CommandTestUtilities.checkSuccessfulCompletion(result);
Assert.assertEquals(parameters.getAuthor(), usedLogModel.getMember());
CommandTestUtilities.checkSuccessfulCompletionAsync(result);
}
@Test
public void testKickMemberWithReason() {
String customReason = "reason2";
CommandContext parameters = CommandTestUtilities.getWithParameters(Arrays.asList(memberToKick, customReason));
CommandResult result = testUnit.execute(parameters);
verify(kickService, times(1)).kickMember(eq(memberToKick), eq(customReason), logModelArgumentCaptor.capture());
when(kickService.kickMember(eq(memberToKick), eq(customReason), logModelArgumentCaptor.capture())).thenReturn(CompletableFuture.completedFuture(null));
CompletableFuture<CommandResult> result = testUnit.executeAsync(parameters);
KickLogModel usedLogModel = logModelArgumentCaptor.getValue();
Assert.assertEquals(customReason, usedLogModel.getReason());
Assert.assertEquals(memberToKick, usedLogModel.getKickedUser());
Assert.assertEquals(parameters.getAuthor(), usedLogModel.getKickingUser());
CommandTestUtilities.checkSuccessfulCompletion(result);
Assert.assertEquals(parameters.getAuthor(), usedLogModel.getMember());
CommandTestUtilities.checkSuccessfulCompletionAsync(result);
}
@Test(expected = InsufficientParametersException.class)
public void testTooLittleParameters() {
CommandTestUtilities.executeNoParametersTest(testUnit);
CommandTestUtilities.executeNoParametersTestAsync(testUnit);
}
@Test(expected = IncorrectParameterException.class)
public void testIncorrectParameterType() {
CommandTestUtilities.executeWrongParametersTest(testUnit);
CommandTestUtilities.executeWrongParametersTestAsync(testUnit);
}
@Test

View File

@@ -5,7 +5,6 @@ import dev.sheldan.abstracto.core.command.exception.InsufficientParametersExcept
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.command.execution.ResultState;
import dev.sheldan.abstracto.core.utils.ExceptionUtils;
import dev.sheldan.abstracto.moderation.service.PurgeService;
import dev.sheldan.abstracto.templating.service.TemplateService;
import dev.sheldan.abstracto.test.command.CommandConfigValidator;
@@ -36,17 +35,13 @@ public class PurgeTest {
@Mock
private TemplateService templateService;
@Mock
private ExceptionUtils exceptionUtils;
@Test
public void testExecutePurgeOfNoMemberCommand() {
Integer count = 10;
CommandContext parameters = CommandTestUtilities.getWithParameters(Arrays.asList(count));
when(purgeService.purgeMessagesInChannel(count, parameters.getChannel(), parameters.getMessage(), null)).thenReturn(CompletableFuture.completedFuture(null));
CommandResult result = testUnit.execute(parameters);
verify(exceptionUtils, times(1)).handleExceptionIfTemplatable(null, parameters.getChannel());
Assert.assertEquals(ResultState.SELF_DESTRUCT, result.getResult());
CompletableFuture<CommandResult> result = testUnit.executeAsync(parameters);
Assert.assertEquals(ResultState.SELF_DESTRUCT, result.join().getResult());
}
@Test
@@ -55,33 +50,18 @@ public class PurgeTest {
Integer count = 10;
CommandContext parameters = CommandTestUtilities.getWithParameters(Arrays.asList(count, messageAuthor));
when(purgeService.purgeMessagesInChannel(count, parameters.getChannel(), parameters.getMessage(), messageAuthor)).thenReturn(CompletableFuture.completedFuture(null));
CommandResult result = testUnit.execute(parameters);
verify(exceptionUtils, times(1)).handleExceptionIfTemplatable(null, parameters.getChannel());
Assert.assertEquals(ResultState.SELF_DESTRUCT, result.getResult());
CompletableFuture<CommandResult> result = testUnit.executeAsync(parameters);
Assert.assertEquals(ResultState.SELF_DESTRUCT, result.join().getResult());
}
@Test
public void testExecutePurgeErroneousCommand() {
Integer count = 10;
CommandContext parameters = CommandTestUtilities.getWithParameters(Arrays.asList(count));
CompletableFuture<Void> failingFuture = new CompletableFuture<>();
RuntimeException exception = new RuntimeException();
failingFuture.completeExceptionally(exception);
when(purgeService.purgeMessagesInChannel(count, parameters.getChannel(), parameters.getMessage(), null)).thenReturn(failingFuture);
CommandResult result = testUnit.execute(parameters);
verify(exceptionUtils, times(1)).handleExceptionIfTemplatable(eq(exception), eq(parameters.getChannel()));
Assert.assertEquals(ResultState.SELF_DESTRUCT, result.getResult());
}
@Test(expected = InsufficientParametersException.class)
public void testTooLittleParameters() {
CommandTestUtilities.executeNoParametersTest(testUnit);
CommandTestUtilities.executeNoParametersTestAsync(testUnit);
}
@Test(expected = IncorrectParameterException.class)
public void testIncorrectParameterType() {
CommandTestUtilities.executeWrongParametersTest(testUnit);
CommandTestUtilities.executeWrongParametersTestAsync(testUnit);
}
@Test

View File

@@ -17,6 +17,7 @@ import org.mockito.junit.MockitoJUnitRunner;
import java.time.Duration;
import java.util.Arrays;
import java.util.concurrent.CompletableFuture;
import static org.mockito.Mockito.*;
@@ -33,18 +34,18 @@ public class SlowModeTest {
public void testExecuteSlowModeWithDurationCurrentChannel() {
String duration = "1m";
CommandContext parameters = CommandTestUtilities.getWithParameters(Arrays.asList(duration));
CommandResult result = testUnit.execute(parameters);
verify(slowModeService, times(1)).setSlowMode(parameters.getChannel(), Duration.ofMinutes(1));
CommandTestUtilities.checkSuccessfulCompletion(result);
when(slowModeService.setSlowMode(parameters.getChannel(), Duration.ofMinutes(1))).thenReturn(CompletableFuture.completedFuture(null));
CompletableFuture<CommandResult> result = testUnit.executeAsync(parameters);
CommandTestUtilities.checkSuccessfulCompletionAsync(result);
}
@Test
public void testDisableSlowModeCurrentChannel() {
String duration = "off";
CommandContext parameters = CommandTestUtilities.getWithParameters(Arrays.asList(duration));
CommandResult result = testUnit.execute(parameters);
verify(slowModeService, times(1)).setSlowMode(parameters.getChannel(), Duration.ZERO);
CommandTestUtilities.checkSuccessfulCompletion(result);
when(slowModeService.setSlowMode(parameters.getChannel(), Duration.ZERO)).thenReturn(CompletableFuture.completedFuture(null));
CompletableFuture<CommandResult> result = testUnit.executeAsync(parameters);
CommandTestUtilities.checkSuccessfulCompletionAsync(result);
}
@Test
@@ -52,9 +53,9 @@ public class SlowModeTest {
String duration = "off";
TextChannel channel = Mockito.mock(TextChannel.class);
CommandContext parameters = CommandTestUtilities.getWithParameters(Arrays.asList(duration, channel));
CommandResult result = testUnit.execute(parameters);
verify(slowModeService, times(1)).setSlowMode(channel, Duration.ZERO);
CommandTestUtilities.checkSuccessfulCompletion(result);
when(slowModeService.setSlowMode(channel, Duration.ZERO)).thenReturn(CompletableFuture.completedFuture(null));
CompletableFuture<CommandResult> result = testUnit.executeAsync(parameters);
CommandTestUtilities.checkSuccessfulCompletionAsync(result);
}
@Test
@@ -62,19 +63,19 @@ public class SlowModeTest {
String duration = "1m";
TextChannel channel = Mockito.mock(TextChannel.class);
CommandContext parameters = CommandTestUtilities.getWithParameters(Arrays.asList(duration, channel));
CommandResult result = testUnit.execute(parameters);
verify(slowModeService, times(1)).setSlowMode(channel, Duration.ofMinutes(1));
CommandTestUtilities.checkSuccessfulCompletion(result);
when(slowModeService.setSlowMode(channel, Duration.ofMinutes(1))).thenReturn(CompletableFuture.completedFuture(null));
CompletableFuture<CommandResult> result = testUnit.executeAsync(parameters);
CommandTestUtilities.checkSuccessfulCompletionAsync(result);
}
@Test(expected = InsufficientParametersException.class)
public void testTooLittleParameters() {
CommandTestUtilities.executeNoParametersTest(testUnit);
CommandTestUtilities.executeNoParametersTestAsync(testUnit);
}
@Test(expected = IncorrectParameterException.class)
public void testIncorrectParameterType() {
CommandTestUtilities.executeWrongParametersTest(testUnit);
CommandTestUtilities.executeWrongParametersTestAsync(testUnit);
}
@Test

View File

@@ -24,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.*;
@@ -65,7 +66,7 @@ public class UserNotesTest {
NoteEntryModel secondConvertedNote = NoteEntryModel.builder().build();
List<NoteEntryModel> convertedNotes = Arrays.asList(firstConvertedNote, secondConvertedNote);
when(userNotesConverter.fromNotes(userNotes)).thenReturn(convertedNotes);
CommandResult result = testUnit.execute(parameters);
CompletableFuture<CommandResult> result = testUnit.executeAsync(parameters);
verify(channelService, times(1)).sendEmbedTemplateInChannel(eq(UserNotes.USER_NOTES_RESPONSE_TEMPLATE), captor.capture(), eq(parameters.getChannel()));
ListNotesModel usedModel = captor.getValue();
Assert.assertEquals(convertedNotes.size(), usedModel.getUserNotes().size());
@@ -76,7 +77,7 @@ public class UserNotesTest {
}
Assert.assertEquals(userNoteUser, usedModel.getSpecifiedUser().getAUserInAServer());
Assert.assertEquals(member, usedModel.getSpecifiedUser().getMember());
CommandTestUtilities.checkSuccessfulCompletion(result);
CommandTestUtilities.checkSuccessfulCompletionAsync(result);
}
@Test
@@ -90,7 +91,7 @@ public class UserNotesTest {
NoteEntryModel secondConvertedNote = NoteEntryModel.builder().build();
List<NoteEntryModel> convertedNotes = Arrays.asList(firstConvertedNote, secondConvertedNote);
when(userNotesConverter.fromNotes(userNotes)).thenReturn(convertedNotes);
CommandResult result = testUnit.execute(parameters);
CompletableFuture<CommandResult> result = testUnit.executeAsync(parameters);
verify(channelService, times(1)).sendEmbedTemplateInChannel(eq(UserNotes.USER_NOTES_RESPONSE_TEMPLATE), captor.capture(), eq(parameters.getChannel()));
ListNotesModel usedModel = captor.getValue();
Assert.assertEquals(convertedNotes.size(), usedModel.getUserNotes().size());
@@ -100,12 +101,12 @@ public class UserNotesTest {
Assert.assertEquals(expectedEntry, usedEntry);
}
Assert.assertNull(usedModel.getSpecifiedUser());
CommandTestUtilities.checkSuccessfulCompletion(result);
CommandTestUtilities.checkSuccessfulCompletionAsync(result);
}
@Test(expected = IncorrectParameterException.class)
public void testIncorrectParameterType() {
CommandTestUtilities.executeWrongParametersTest(testUnit);
CommandTestUtilities.executeWrongParametersTestAsync(testUnit);
}
@Test

View File

@@ -4,7 +4,7 @@ import dev.sheldan.abstracto.core.command.exception.IncorrectParameterException;
import dev.sheldan.abstracto.core.command.exception.InsufficientParametersException;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.moderation.models.template.commands.WarnLog;
import dev.sheldan.abstracto.moderation.models.template.commands.WarnContext;
import dev.sheldan.abstracto.moderation.service.WarnService;
import dev.sheldan.abstracto.templating.service.TemplateService;
import dev.sheldan.abstracto.test.command.CommandConfigValidator;
@@ -17,6 +17,7 @@ import org.mockito.*;
import org.mockito.junit.MockitoJUnitRunner;
import java.util.Arrays;
import java.util.concurrent.CompletableFuture;
import static org.mockito.Mockito.*;
@@ -34,7 +35,7 @@ public class WarnTest {
private static final String DEFAULT_REASON = "defaultReason";
@Captor
private ArgumentCaptor<WarnLog> parameterCaptor;
private ArgumentCaptor<WarnContext> parameterCaptor;
@Test
public void testExecuteWarnCommandWithReason() {
@@ -42,13 +43,13 @@ public class WarnTest {
String reason = "reason";
CommandContext parameters = CommandTestUtilities.getWithParameters(Arrays.asList(warnedMember, reason));
when(templateService.renderSimpleTemplate(Warn.WARN_DEFAULT_REASON_TEMPLATE)).thenReturn(DEFAULT_REASON);
CommandResult result = testUnit.execute(parameters);
verify(warnService, times(1)).warnUserWithLog(eq(warnedMember), eq(parameters.getAuthor()), eq(reason), parameterCaptor.capture(), eq(parameters.getChannel()));
WarnLog value = parameterCaptor.getValue();
when(warnService.warnUserWithLog(parameterCaptor.capture())).thenReturn(CompletableFuture.completedFuture(null));
CompletableFuture<CommandResult> result = testUnit.executeAsync(parameters);
WarnContext value = parameterCaptor.getValue();
Assert.assertEquals(reason, value.getReason());
Assert.assertEquals(warnedMember, value.getWarnedUser());
Assert.assertEquals(parameters.getAuthor(), value.getWarningUser());
CommandTestUtilities.checkSuccessfulCompletion(result);
Assert.assertEquals(warnedMember, value.getWarnedMember());
Assert.assertEquals(parameters.getAuthor(), value.getMember());
CommandTestUtilities.checkSuccessfulCompletionAsync(result);
}
@Test
@@ -56,23 +57,23 @@ public class WarnTest {
Member warnedMember = Mockito.mock(Member.class);
CommandContext parameters = CommandTestUtilities.getWithParameters(Arrays.asList(warnedMember));
when(templateService.renderSimpleTemplate(Warn.WARN_DEFAULT_REASON_TEMPLATE)).thenReturn(DEFAULT_REASON);
CommandResult result = testUnit.execute(parameters);
verify(warnService, times(1)).warnUserWithLog(eq(warnedMember), eq(parameters.getAuthor()), eq(DEFAULT_REASON), parameterCaptor.capture(), eq(parameters.getChannel()));
WarnLog value = parameterCaptor.getValue();
when(warnService.warnUserWithLog(parameterCaptor.capture())).thenReturn(CompletableFuture.completedFuture(null));
CompletableFuture<CommandResult> result = testUnit.executeAsync(parameters);
WarnContext value = parameterCaptor.getValue();
Assert.assertEquals(DEFAULT_REASON, value.getReason());
Assert.assertEquals(warnedMember, value.getWarnedUser());
Assert.assertEquals(parameters.getAuthor(), value.getWarningUser());
CommandTestUtilities.checkSuccessfulCompletion(result);
Assert.assertEquals(warnedMember, value.getWarnedMember());
Assert.assertEquals(parameters.getAuthor(), value.getMember());
CommandTestUtilities.checkSuccessfulCompletionAsync(result);
}
@Test(expected = InsufficientParametersException.class)
public void testTooLittleParameters() {
CommandTestUtilities.executeNoParametersTest(testUnit);
CommandTestUtilities.executeNoParametersTestAsync(testUnit);
}
@Test(expected = IncorrectParameterException.class)
public void testIncorrectParameterType() {
CommandTestUtilities.executeWrongParametersTest(testUnit);
CommandTestUtilities.executeWrongParametersTestAsync(testUnit);
}
@Test

View File

@@ -4,7 +4,7 @@ import dev.sheldan.abstracto.core.command.exception.IncorrectParameterException;
import dev.sheldan.abstracto.core.command.exception.InsufficientParametersException;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.moderation.models.template.commands.MuteLog;
import dev.sheldan.abstracto.moderation.models.template.commands.MuteContext;
import dev.sheldan.abstracto.moderation.service.MuteService;
import dev.sheldan.abstracto.test.command.CommandConfigValidator;
import dev.sheldan.abstracto.test.command.CommandTestUtilities;
@@ -16,8 +16,8 @@ import org.mockito.*;
import org.mockito.junit.MockitoJUnitRunner;
import java.time.Duration;
import java.time.Instant;
import java.util.Arrays;
import java.util.concurrent.CompletableFuture;
import static org.mockito.Mockito.*;
@@ -31,7 +31,7 @@ public class MuteTest {
private MuteService muteService;
@Captor
private ArgumentCaptor<MuteLog> muteLogArgumentCaptor;
private ArgumentCaptor<MuteContext> muteLogArgumentCaptor;
@Test
public void testMuteMember() {
@@ -39,22 +39,22 @@ public class MuteTest {
String reason = "reason";
Duration duration = Duration.ofMinutes(1);
CommandContext parameters = CommandTestUtilities.getWithParameters(Arrays.asList(mutedMember, duration, reason));
CommandResult result = testUnit.execute(parameters);
verify(muteService, times(1)).muteMemberWithLog(eq(mutedMember), eq(parameters.getAuthor()), eq(reason), any(Instant.class), muteLogArgumentCaptor.capture(), eq(parameters.getMessage()));
CommandTestUtilities.checkSuccessfulCompletion(result);
MuteLog muteLog = muteLogArgumentCaptor.getValue();
when(muteService.muteMemberWithLog(muteLogArgumentCaptor.capture())).thenReturn(CompletableFuture.completedFuture(null));
CompletableFuture<CommandResult> result = testUnit.executeAsync(parameters);
CommandTestUtilities.checkSuccessfulCompletionAsync(result);
MuteContext muteLog = muteLogArgumentCaptor.getValue();
Assert.assertEquals(mutedMember, muteLog.getMutedUser());
Assert.assertEquals(parameters.getAuthor(), muteLog.getMutingUser());
}
@Test(expected = InsufficientParametersException.class)
public void testTooLittleParameters() {
CommandTestUtilities.executeNoParametersTest(testUnit);
CommandTestUtilities.executeNoParametersTestAsync(testUnit);
}
@Test(expected = IncorrectParameterException.class)
public void testIncorrectParameterType() {
CommandTestUtilities.executeWrongParametersTest(testUnit);
CommandTestUtilities.executeWrongParametersTestAsync(testUnit);
}
@Test

View File

@@ -4,15 +4,15 @@ import dev.sheldan.abstracto.core.command.exception.IncorrectParameterException;
import dev.sheldan.abstracto.core.command.exception.InsufficientParametersException;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.command.execution.ResultState;
import dev.sheldan.abstracto.moderation.models.database.Mute;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.moderation.exception.NoMuteFoundException;
import dev.sheldan.abstracto.moderation.service.MuteService;
import dev.sheldan.abstracto.moderation.service.management.MuteManagementService;
import dev.sheldan.abstracto.templating.service.TemplateService;
import dev.sheldan.abstracto.test.command.CommandConfigValidator;
import dev.sheldan.abstracto.test.command.CommandTestUtilities;
import net.dv8tion.jda.api.entities.Member;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
@@ -21,6 +21,7 @@ import org.mockito.junit.MockitoJUnitRunner;
import java.util.Arrays;
import java.util.concurrent.CompletableFuture;
import static org.mockito.Mockito.*;
@@ -42,38 +43,36 @@ public class UnMuteTest {
@Mock
private Member memberToUnMute;
@Mock
private UserInServerManagementService userInServerManagementService;
@Test
public void testUnMuteCommand() {
CommandContext parameters = CommandTestUtilities.getWithParameters(Arrays.asList(memberToUnMute));
when(muteManagementService.hasActiveMute(memberToUnMute)).thenReturn(true);
Mute mute = Mute.builder().build();
when(muteManagementService.getAMuteOf(memberToUnMute)).thenReturn(mute);
CommandResult result = testUnit.execute(parameters);
verify(muteService, times(1)).unMuteUser(mute);
verify(muteService, times(1)).cancelUnMuteJob(mute);
verify(muteService, times(1)).completelyUnMuteMember(memberToUnMute);
CommandTestUtilities.checkSuccessfulCompletion(result);
AUserInAServer user = AUserInAServer.builder().build();
when(userInServerManagementService.loadUser(memberToUnMute)).thenReturn(user);
when(muteService.unMuteUser(user)).thenReturn(CompletableFuture.completedFuture(null));
CompletableFuture<CommandResult> result = testUnit.executeAsync(parameters);
CommandTestUtilities.checkSuccessfulCompletionAsync(result);
}
@Test
@Test(expected = NoMuteFoundException.class)
public void testUnMuteCommandWithoutExistingMute() {
CommandContext parameters = CommandTestUtilities.getWithParameters(Arrays.asList(memberToUnMute));
when(muteManagementService.hasActiveMute(memberToUnMute)).thenReturn(false);
String message = "text";
when(templateService.renderSimpleTemplate(UnMute.NO_ACTIVE_MUTE)).thenReturn(message);
CommandResult result = testUnit.execute(parameters);
Assert.assertEquals(ResultState.ERROR, result.getResult());
Assert.assertEquals(message, result.getMessage());
AUserInAServer user = AUserInAServer.builder().build();
when(userInServerManagementService.loadUser(memberToUnMute)).thenReturn(user);
when(muteService.unMuteUser(user)).thenThrow(new NoMuteFoundException());
testUnit.executeAsync(parameters);
}
@Test(expected = InsufficientParametersException.class)
public void testTooLittleParameters() {
CommandTestUtilities.executeNoParametersTest(testUnit);
CommandTestUtilities.executeNoParametersTestAsync(testUnit);
}
@Test(expected = IncorrectParameterException.class)
public void testIncorrectParameterType() {
CommandTestUtilities.executeWrongParametersTest(testUnit);
CommandTestUtilities.executeWrongParametersTestAsync(testUnit);
}
@Test

View File

@@ -18,6 +18,7 @@ import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import static org.mockito.Mockito.*;
@@ -48,6 +49,7 @@ public class BanServiceBeanTest {
when(memberToBan.getGuild()).thenReturn(mockedGuild);
when(mockedGuild.getIdLong()).thenReturn(serverId);
AuditableRestAction mockedAction = mock(AuditableRestAction.class);
when(mockedAction.submit()).thenReturn(CompletableFuture.completedFuture(null));
when(mockedGuild.ban(userId.toString(), 0, REASON)).thenReturn(mockedAction);
MessageToSend mockedMessage = Mockito.mock(MessageToSend.class);
when(templateService.renderEmbedTemplate(BanServiceBean.BAN_LOG_TEMPLATE, context)).thenReturn(mockedMessage);
@@ -64,6 +66,7 @@ public class BanServiceBeanTest {
ServerContext context = Mockito.mock(ServerContext.class);
Guild mockedGuild = Mockito.mock(Guild.class);
AuditableRestAction mockedAction = mock(AuditableRestAction.class);
when(mockedAction.submit()).thenReturn(CompletableFuture.completedFuture(null));
when(mockedGuild.ban(userId.toString(), 0, REASON)).thenReturn(mockedAction);
MessageToSend mockedMessage = Mockito.mock(MessageToSend.class);
when(templateService.renderEmbedTemplate(BanServiceBean.BAN_ID_LOG_TEMPLATE, context)).thenReturn(mockedMessage);

View File

@@ -7,6 +7,7 @@ import dev.sheldan.abstracto.moderation.models.template.commands.KickLogModel;
import dev.sheldan.abstracto.templating.model.MessageToSend;
import dev.sheldan.abstracto.templating.service.TemplateService;
import dev.sheldan.abstracto.test.MockUtils;
import dev.sheldan.abstracto.test.command.CommandTestUtilities;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.User;
@@ -18,6 +19,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)
@@ -40,16 +43,17 @@ public class KickServiceBeanTest {
when(member.getUser()).thenReturn(user);
when(user.getIdLong()).thenReturn(6L);
Guild mockedGuild = Mockito.mock(Guild.class);
when(mockedGuild.getIdLong()).thenReturn(server.getId());
when(member.getGuild()).thenReturn(mockedGuild);
AuditableRestAction<Void> mockedAction = Mockito.mock(AuditableRestAction.class);
String reason = "reason";
AuditableRestAction<Void> mockedAction = Mockito.mock(AuditableRestAction.class);
when(mockedGuild.kick(member, reason)).thenReturn(mockedAction);
when(mockedAction.submit()).thenReturn(CompletableFuture.completedFuture(null));
KickLogModel model = Mockito.mock(KickLogModel.class);
when(model.getServer()).thenReturn(server);
when(model.getGuild()).thenReturn(mockedGuild);
MessageToSend messageToSend = Mockito.mock(MessageToSend.class);
when(templateService.renderEmbedTemplate(KickServiceBean.KICK_LOG_TEMPLATE, model)).thenReturn(messageToSend);
when(postTargetService.sendEmbedInPostTarget(messageToSend, ModerationPostTarget.KICK_LOG, server.getId())).thenReturn(CommandTestUtilities.messageFutureList());
testUnit.kickMember(member, reason, model);
verify(mockedGuild, times(1)).kick(member, reason);
verify(postTargetService, times(1)).sendEmbedInPostTarget(messageToSend, ModerationPostTarget.KICK_LOG, server.getId());
}
}

View File

@@ -1,22 +1,22 @@
package dev.sheldan.abstracto.moderation.service;
import dev.sheldan.abstracto.core.models.AServerAChannelMessage;
import dev.sheldan.abstracto.core.models.FullUserInServer;
import dev.sheldan.abstracto.core.models.ServerChannelMessage;
import dev.sheldan.abstracto.core.models.ServerSpecificId;
import dev.sheldan.abstracto.core.models.database.AChannel;
import dev.sheldan.abstracto.core.models.database.ARole;
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.MessageService;
import dev.sheldan.abstracto.core.service.PostTargetService;
import dev.sheldan.abstracto.core.service.RoleService;
import dev.sheldan.abstracto.core.service.*;
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.MutingPostTarget;
import dev.sheldan.abstracto.moderation.exception.MuteRoleNotSetupException;
import dev.sheldan.abstracto.moderation.exception.NoMuteFoundException;
import dev.sheldan.abstracto.moderation.models.database.Mute;
import dev.sheldan.abstracto.moderation.models.database.MuteRole;
import dev.sheldan.abstracto.moderation.models.template.commands.MuteLog;
import dev.sheldan.abstracto.moderation.models.template.commands.MuteContext;
import dev.sheldan.abstracto.moderation.models.template.commands.MuteNotification;
import dev.sheldan.abstracto.moderation.models.template.commands.UnMuteLog;
import dev.sheldan.abstracto.moderation.service.management.MuteManagementService;
@@ -25,6 +25,7 @@ import dev.sheldan.abstracto.scheduling.service.SchedulerService;
import dev.sheldan.abstracto.templating.model.MessageToSend;
import dev.sheldan.abstracto.templating.service.TemplateService;
import dev.sheldan.abstracto.test.MockUtils;
import dev.sheldan.abstracto.test.command.CommandTestUtilities;
import net.dv8tion.jda.api.entities.*;
import org.junit.Before;
import org.junit.Test;
@@ -33,20 +34,19 @@ import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;
import org.quartz.JobDataMap;
import java.time.Duration;
import java.time.Instant;
import java.util.Arrays;
import java.util.Date;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ScheduledExecutorService;
import static dev.sheldan.abstracto.moderation.service.MuteServiceBean.MUTE_NOTIFICATION_TEMPLATE;
import static org.mockito.Mockito.*;
@RunWith(MockitoJUnitRunner.class)
public class MuteServiceBeanTest {
@InjectMocks
private MuteServiceBean testUnit;
@@ -78,7 +78,7 @@ public class MuteServiceBeanTest {
private PostTargetService postTargetService;
@Mock
private MuteService self;
private MuteServiceBean self;
@Mock
private ScheduledExecutorService executorService;
@@ -111,7 +111,7 @@ public class MuteServiceBeanTest {
private MessageChannel channel;
@Mock
private Message cause;
private ServerChannelMessage cause;
@Mock
private Guild guild;
@@ -125,11 +125,21 @@ public class MuteServiceBeanTest {
@Mock
private MessageToSend messageToSend;
private static final Long CHANNEL_ID = 8L;
@Mock
private Mute mute;
@Mock
private ServerManagementService serverManagementService;
@Mock
private CounterService counterService;
private static final Long CHANNEL_ID = 8L;
private static final String REASON = "reason";
private static final String NOTIFICATION_TEXT = "text";
private static final String TRIGGER = "trigger";
public static final long MUTE_ID = 6L;
public static final long SERVER_ID = 7L;
@Before
public void setup() {
@@ -142,7 +152,7 @@ public class MuteServiceBeanTest {
memberMuting = Mockito.mock(Member.class);
memberBeingMuted = Mockito.mock(Member.class);
channel = Mockito.mock(MessageChannel.class);
cause = Mockito.mock(Message.class);
cause = Mockito.mock(ServerChannelMessage.class);
aRole = ARole.builder().build();
muteRole = MuteRole.builder().role(aRole).build();
messageToSend = Mockito.mock(MessageToSend.class);
@@ -155,12 +165,15 @@ public class MuteServiceBeanTest {
when(memberBeingMuted.getUser()).thenReturn(jdaUserBeingMuted);
FullUserInServer mutedUser = FullUserInServer.builder().member(memberBeingMuted).aUserInAServer(userBeingMuted).build();
FullUserInServer mutingUser = FullUserInServer.builder().member(memberMuting).aUserInAServer(userMuting).build();
setupShortMute(unMuteDate);
when(schedulerService.executeJobWithParametersOnce(eq("unMuteJob"), eq("moderation"), any(JobDataMap.class), eq(Date.from(unMuteDate)))).thenReturn(TRIGGER);
testUnit.muteUser(mutedUser, mutingUser, REASON, unMuteDate, cause);
verify(messageService, times(1)).sendMessageToUser(jdaUserBeingMuted, NOTIFICATION_TEXT, channel);
verify(muteManagementService, times(1)).saveMute(any(Mute.class));
verify(roleService, times(1)).addRoleToUser(userBeingMuted, aRole);
when(memberBeingMuted.getGuild()).thenReturn(guild);
when(memberBeingMuted.getUser()).thenReturn(jdaUserBeingMuted);
when(muteRoleManagementService.muteRoleForServerExists(server)).thenReturn(true);
when(muteRoleManagementService.retrieveMuteRoleForServer(server)).thenReturn(muteRole);
when(templateService.renderTemplate(eq(MUTE_NOTIFICATION_TEMPLATE), any(MuteNotification.class))).thenReturn(NOTIFICATION_TEXT);
when(messageService.sendMessageToUser(jdaUserBeingMuted, NOTIFICATION_TEXT)).thenReturn(CompletableFuture.completedFuture(null));
when(roleService.addRoleToUserFuture(userBeingMuted, aRole)).thenReturn(CompletableFuture.completedFuture(null));
testUnit.muteUserInServer(mutedUser, mutingUser, REASON, unMuteDate, cause);
}
@Test
@@ -170,8 +183,16 @@ public class MuteServiceBeanTest {
FullUserInServer mutedUser = FullUserInServer.builder().member(memberBeingMuted).aUserInAServer(userBeingMuted).build();
FullUserInServer mutingUser = FullUserInServer.builder().member(memberMuting).aUserInAServer(userMuting).build();
Instant unMuteDate = shorterMute();
setupShortMute(unMuteDate);
testUnit.muteUser(mutedUser, mutingUser, REASON, unMuteDate, cause);
when(memberBeingMuted.getGuild()).thenReturn(guild);
when(memberBeingMuted.getUser()).thenReturn(jdaUserBeingMuted);
when(muteRoleManagementService.muteRoleForServerExists(server)).thenReturn(true);
when(muteRoleManagementService.retrieveMuteRoleForServer(server)).thenReturn(muteRole);
String notificationText = "text";
when(templateService.renderTemplate(eq(MUTE_NOTIFICATION_TEMPLATE), any(MuteNotification.class))).thenReturn(notificationText);
when(messageService.sendMessageToUser(memberBeingMuted.getUser(), notificationText)).thenReturn(CompletableFuture.completedFuture(null));
when(roleService.addRoleToUserFuture(userBeingMuted, muteRole.getRole())).thenReturn(CompletableFuture.completedFuture(null));
testUnit.muteUserInServer(mutedUser, mutingUser, REASON, unMuteDate, cause);
verifyDirectMute();
}
@@ -179,19 +200,18 @@ public class MuteServiceBeanTest {
public void testMuteUserWithoutMuteRole() {
FullUserInServer mutedUser = FullUserInServer.builder().aUserInAServer(userBeingMuted).build();
when(muteRoleManagementService.muteRoleForServerExists(server)).thenReturn(false);
testUnit.muteUser(mutedUser, FullUserInServer.builder().build(), REASON, longerMute(), Mockito.mock(Message.class));
testUnit.muteUserInServer(mutedUser, FullUserInServer.builder().build(), REASON, longerMute(), Mockito.mock(ServerChannelMessage.class));
}
@Test
public void testCancelUnMuteJob() {
Mute mute = Mute.builder().triggerKey(TRIGGER).build();
when(mute.getTriggerKey()).thenReturn(TRIGGER);
testUnit.cancelUnMuteJob(mute);
verify(schedulerService, times(1)).stopTrigger(TRIGGER);
}
@Test
public void testCancelNotExistingJob() {
Mute mute = Mute.builder().build();
testUnit.cancelUnMuteJob(mute);
verify(schedulerService, times(0)).stopTrigger(anyString());
}
@@ -201,7 +221,15 @@ public class MuteServiceBeanTest {
when(userInServerManagementService.loadUser(memberBeingMuted)).thenReturn(userBeingMuted);
when(userInServerManagementService.loadUser(memberMuting)).thenReturn(userMuting);
Instant unMuteDate = shorterMute();
setupShortMute(unMuteDate);
when(memberBeingMuted.getGuild()).thenReturn(guild);
when(memberBeingMuted.getUser()).thenReturn(jdaUserBeingMuted);
when(muteRoleManagementService.muteRoleForServerExists(server)).thenReturn(true);
when(muteRoleManagementService.retrieveMuteRoleForServer(server)).thenReturn(muteRole);
String notificationText = "text";
when(templateService.renderTemplate(eq(MUTE_NOTIFICATION_TEMPLATE), any(MuteNotification.class))).thenReturn(notificationText);
when(messageService.sendMessageToUser(memberBeingMuted.getUser(), notificationText)).thenReturn(CompletableFuture.completedFuture(null));
when(roleService.addRoleToUserFuture(userBeingMuted, muteRole.getRole())).thenReturn(CompletableFuture.completedFuture(null));
testUnit.muteMember(memberBeingMuted, memberMuting, REASON, unMuteDate, cause);
verifyDirectMute();
}
@@ -211,7 +239,15 @@ public class MuteServiceBeanTest {
when(botService.getMemberInServer(userBeingMuted)).thenReturn(memberBeingMuted);
when(botService.getMemberInServer(userMuting)).thenReturn(memberMuting);
Instant unMuteDate = shorterMute();
setupShortMute(unMuteDate);
when(memberBeingMuted.getGuild()).thenReturn(guild);
when(memberBeingMuted.getUser()).thenReturn(jdaUserBeingMuted);
when(muteRoleManagementService.muteRoleForServerExists(server)).thenReturn(true);
when(muteRoleManagementService.retrieveMuteRoleForServer(server)).thenReturn(muteRole);
String notificationText = "text";
when(templateService.renderTemplate(eq(MUTE_NOTIFICATION_TEMPLATE), any(MuteNotification.class))).thenReturn(notificationText);
when(messageService.sendMessageToUser(memberBeingMuted.getUser(), notificationText)).thenReturn(CompletableFuture.completedFuture(null));
when(roleService.addRoleToUserFuture(userBeingMuted, muteRole.getRole())).thenReturn(CompletableFuture.completedFuture(null));
testUnit.muteAUserInAServer(userBeingMuted, userMuting, REASON, unMuteDate, cause);
verifyDirectMute();
}
@@ -221,53 +257,63 @@ public class MuteServiceBeanTest {
when(userInServerManagementService.loadUser(memberBeingMuted)).thenReturn(userBeingMuted);
when(userInServerManagementService.loadUser(memberMuting)).thenReturn(userMuting);
Instant unMuteDate = shorterMute();
setupShortMute(unMuteDate);
MuteLog muteLog = MuteLog.builder().server(server).build();
when(templateService.renderEmbedTemplate(eq(MuteServiceBean.MUTE_LOG_TEMPLATE), any(MuteLog.class))).thenReturn(messageToSend);
testUnit.muteMemberWithLog(memberBeingMuted, memberMuting, REASON, unMuteDate, muteLog, cause);
when(memberBeingMuted.getGuild()).thenReturn(guild);
when(memberBeingMuted.getUser()).thenReturn(jdaUserBeingMuted);
when(muteRoleManagementService.muteRoleForServerExists(server)).thenReturn(true);
when(muteRoleManagementService.retrieveMuteRoleForServer(server)).thenReturn(muteRole);
ServerChannelMessage serverChannelMessage = Mockito.mock(ServerChannelMessage.class);
when(serverChannelMessage.getServerId()).thenReturn(SERVER_ID);
MuteContext muteLog = Mockito.mock(MuteContext.class);
when(muteLog.getMutedUser()).thenReturn(memberBeingMuted);
when(muteLog.getMutingUser()).thenReturn(memberMuting);
when(muteLog.getContext()).thenReturn(serverChannelMessage);
when(muteLog.getMuteTargetDate()).thenReturn(unMuteDate);
String notificationText = "text";
when(templateService.renderTemplate(eq(MUTE_NOTIFICATION_TEMPLATE), any(MuteNotification.class))).thenReturn(notificationText);
when(messageService.sendMessageToUser(memberBeingMuted.getUser(), notificationText)).thenReturn(CompletableFuture.completedFuture(null));
when(templateService.renderEmbedTemplate(eq(MuteServiceBean.MUTE_LOG_TEMPLATE), any(MuteContext.class))).thenReturn(messageToSend);
when(roleService.addRoleToUserFuture(userBeingMuted, muteRole.getRole())).thenReturn(CompletableFuture.completedFuture(null));
testUnit.muteMemberWithLog(muteLog);
verifyDirectMute();
verify(templateService, times(1)).renderEmbedTemplate(eq(MuteServiceBean.MUTE_LOG_TEMPLATE), any(MuteLog.class));
verify(postTargetService, times(1)).sendEmbedInPostTarget(messageToSend, MutingPostTarget.MUTE_LOG, server.getId());
verify(templateService, times(1)).renderEmbedTemplate(eq(MuteServiceBean.MUTE_LOG_TEMPLATE), any(MuteContext.class));
verify(postTargetService, times(1)).sendEmbedInPostTarget(messageToSend, MutingPostTarget.MUTE_LOG, SERVER_ID);
}
@Test
public void testUnMuteMemberWhoseMuteEnded() {
Mute mute = Mockito.mock(Mute.class);
when(mute.getMuteEnded()).thenReturn(true);
when(mute.getMutedUser()).thenReturn(userBeingMuted);
testUnit.unMuteUser(mute);
when(muteManagementService.getAMuteOf(userBeingMuted)).thenReturn(mute);
when(mute.getMuteId()).thenReturn(new ServerSpecificId(SERVER_ID, MUTE_ID));
testUnit.unMuteUser(userBeingMuted);
verifyNoUnMuteHappened();
}
@Test
public void testEndMute() {
Long muteId = 6L;
setupUnMuteMocks(true);
Mute mute = Mockito.mock(Mute.class);
when(mute.getMuteEnded()).thenReturn(false);
when(mute.getMutedUser()).thenReturn(userBeingMuted);
when(mute.getMutingServer()).thenReturn(server);
when(muteManagementService.findMute(muteId)).thenReturn(Optional.of(mute));
testUnit.endMute(muteId);
verifyUnMute(1);
when(mute.getServer()).thenReturn(server);
when(muteManagementService.findMute(MUTE_ID, SERVER_ID)).thenReturn(Optional.of(mute));
when(roleService.removeRoleFromUserFuture(userBeingMuted, aRole)).thenReturn(CompletableFuture.completedFuture(null));
testUnit.endMute(MUTE_ID, SERVER_ID);
}
@Test
@Test(expected = NoMuteFoundException.class)
public void testEndNonExistingMute() {
Long muteId = 6L;
when(muteManagementService.findMute(muteId)).thenReturn(Optional.empty());
testUnit.endMute(muteId);
verifyNoUnMuteHappened();
when(muteManagementService.findMute(MUTE_ID, SERVER_ID)).thenReturn(Optional.empty());
testUnit.endMute(MUTE_ID, SERVER_ID);
}
@Test
public void testUnMuteMemberInGuild() {
executeUnMuteWithLogTest(true, 1);
executeUnMuteWithLogTest(true);
}
@Test
public void testUnMuteMemberWhoLeftGuild() {
executeUnMuteWithLogTest(false, 0);
executeUnMuteWithLogTest(false);
}
@Test
@@ -279,7 +325,6 @@ public class MuteServiceBeanTest {
@Test
public void testCompletelyUnMuteNotScheduledMuteUser() {
Mute mute = Mockito.mock(Mute.class);
when(muteManagementService.getAllMutesOf(userBeingMuted)).thenReturn(Arrays.asList(mute));
testUnit.completelyUnMuteUser(userBeingMuted);
verify(muteManagementService, times(1)).saveMute(any(Mute.class));
@@ -288,7 +333,6 @@ public class MuteServiceBeanTest {
@Test
public void testCompletelyUnMuteScheduledMuteUser() {
Mute mute = Mockito.mock(Mute.class);
when(mute.getTriggerKey()).thenReturn(TRIGGER);
when(muteManagementService.getAllMutesOf(userBeingMuted)).thenReturn(Arrays.asList(mute));
testUnit.completelyUnMuteUser(userBeingMuted);
@@ -298,7 +342,6 @@ public class MuteServiceBeanTest {
@Test
public void testCompletelyUnMuteMember() {
Mute mute = Mockito.mock(Mute.class);
when(mute.getTriggerKey()).thenReturn(TRIGGER);
when(muteManagementService.getAllMutesOf(userBeingMuted)).thenReturn(Arrays.asList(mute));
when(userInServerManagementService.loadUser(memberBeingMuted)).thenReturn(userBeingMuted);
@@ -307,24 +350,40 @@ public class MuteServiceBeanTest {
verify(schedulerService, times(1)).stopTrigger(TRIGGER);
}
@Test
public void verifyScheduling() {
Instant unMuteDate = shorterMute();
MuteContext muteLog = Mockito.mock(MuteContext.class);
when(muteLog.getMuteTargetDate()).thenReturn(unMuteDate);
when(muteLog.getMuteId()).thenReturn(MUTE_ID);
ServerChannelMessage serverContext = Mockito.mock(ServerChannelMessage.class);
when(serverContext.getServerId()).thenReturn(SERVER_ID);
when(serverContext.getChannelId()).thenReturn(CHANNEL_ID);
when(channelManagementService.loadChannel(CHANNEL_ID)).thenReturn(aChannel);
when(muteLog.getContext()).thenReturn(serverContext);
testUnit.persistMute(muteLog);
verify(executorService, times(1)).schedule(any(Runnable.class), anyLong(), any());
}
private void verifyNoUnMuteHappened() {
verify(muteManagementService, times(0)).saveMute(any(Mute.class));
verify(roleService, times(0)).removeRoleFromUser(eq(userBeingMuted), any(ARole.class));
verify(postTargetService, times(0)).sendEmbedInPostTarget(any(MessageToSend.class), eq(MutingPostTarget.MUTE_LOG), eq(server.getId()));
}
private void executeUnMuteWithLogTest(boolean stillInGuild, int roleRemovals) {
Mute mute = Mockito.mock(Mute.class);
private void executeUnMuteWithLogTest(boolean stillInGuild) {
when(mute.getMutedUser()).thenReturn(userBeingMuted);
when(mute.getMutingServer()).thenReturn(server);
when(mute.getServer()).thenReturn(server);
setupUnMuteMocks(stillInGuild);
when(roleService.removeRoleFromUserFuture(userBeingMuted, aRole)).thenReturn(CompletableFuture.completedFuture(null));
when(postTargetService.sendEmbedInPostTarget(messageToSend, MutingPostTarget.MUTE_LOG, server.getId())).thenReturn(CommandTestUtilities.messageFutureList());
testUnit.unMuteUser(userBeingMuted);
testUnit.unMuteUser(mute);
verifyUnMute(roleRemovals);
}
private void setupUnMuteMocks(boolean stillInGuild) {
when(mute.getMuteId()).thenReturn(new ServerSpecificId(SERVER_ID, MUTE_ID));
when(muteManagementService.getAMuteOf(userBeingMuted)).thenReturn(mute);
when(muteRoleManagementService.retrieveMuteRoleForServer(server)).thenReturn(muteRole);
when(botService.getGuildByIdNullable(server.getId())).thenReturn(guild);
when(botService.isUserInGuild(guild, userBeingMuted)).thenReturn(stillInGuild);
@@ -332,32 +391,8 @@ public class MuteServiceBeanTest {
when(templateService.renderEmbedTemplate(eq(MuteServiceBean.UN_MUTE_LOG_TEMPLATE), any(UnMuteLog.class))).thenReturn(messageToSend);
}
private void verifyUnMute(int roleRemovals) {
verify(muteManagementService, times(1)).saveMute(any(Mute.class));
verify(roleService, times(roleRemovals)).removeRoleFromUser(userBeingMuted, aRole);
verify(postTargetService, times(1)).sendEmbedInPostTarget(messageToSend, MutingPostTarget.MUTE_LOG, server.getId());
}
private void setupShortMute(Instant unMuteDate) {
Long muteId = 12L;
when(memberBeingMuted.getGuild()).thenReturn(guild);
when(memberBeingMuted.getUser()).thenReturn(jdaUserBeingMuted);
when(channel.getIdLong()).thenReturn(CHANNEL_ID);
when(cause.getGuild()).thenReturn(guild);
when(cause.getChannel()).thenReturn(channel);
when(muteRoleManagementService.muteRoleForServerExists(server)).thenReturn(true);
when(muteRoleManagementService.retrieveMuteRoleForServer(server)).thenReturn(muteRole);
when(channelManagementService.loadChannel(CHANNEL_ID)).thenReturn(aChannel);
Mute createdMute = Mute.builder().id(muteId).build();
when(muteManagementService.createMute(eq(userBeingMuted), eq(userMuting), eq(REASON), eq(unMuteDate), any(AServerAChannelMessage.class))).thenReturn(createdMute);
when(templateService.renderTemplate(eq(MuteServiceBean.MUTE_NOTIFICATION_TEMPLATE), any(MuteNotification.class))).thenReturn(NOTIFICATION_TEXT);
}
private void verifyDirectMute() {
verify(messageService, times(1)).sendMessageToUser(jdaUserBeingMuted, NOTIFICATION_TEXT, channel);
verify(muteManagementService, times(1)).saveMute(any(Mute.class));
verify(roleService, times(1)).addRoleToUser(userBeingMuted, aRole);
verify(executorService, times(1)).schedule(any(Runnable.class), anyLong(), any());
verify(messageService, times(1)).sendMessageToUser(jdaUserBeingMuted, NOTIFICATION_TEXT);
}
private Instant longerMute() {

View File

@@ -1,31 +1,26 @@
package dev.sheldan.abstracto.moderation.service;
import dev.sheldan.abstracto.core.models.FullUserInServer;
import dev.sheldan.abstracto.core.models.ServerSpecificId;
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.ConfigService;
import dev.sheldan.abstracto.core.service.MessageService;
import dev.sheldan.abstracto.core.service.PostTargetService;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.core.service.*;
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
import dev.sheldan.abstracto.moderation.config.features.WarningDecayFeature;
import dev.sheldan.abstracto.moderation.config.posttargets.WarnDecayPostTarget;
import dev.sheldan.abstracto.moderation.config.posttargets.WarningPostTarget;
import dev.sheldan.abstracto.moderation.models.database.Warning;
import dev.sheldan.abstracto.moderation.models.template.commands.WarnLog;
import dev.sheldan.abstracto.moderation.models.template.commands.WarnContext;
import dev.sheldan.abstracto.moderation.models.template.commands.WarnNotification;
import dev.sheldan.abstracto.moderation.models.template.job.WarnDecayLogModel;
import dev.sheldan.abstracto.moderation.models.template.job.WarnDecayWarning;
import dev.sheldan.abstracto.moderation.service.management.WarnManagementService;
import dev.sheldan.abstracto.templating.model.MessageToSend;
import dev.sheldan.abstracto.templating.service.TemplateService;
import dev.sheldan.abstracto.test.MockUtils;
import dev.sheldan.abstracto.test.command.CommandTestUtilities;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.MessageChannel;
import net.dv8tion.jda.api.entities.User;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.*;
@@ -35,18 +30,18 @@ import java.time.Instant;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import static dev.sheldan.abstracto.moderation.service.WarnServiceBean.*;
import static org.mockito.Mockito.*;
@RunWith(MockitoJUnitRunner.class)
public class WarnServiceBeanTest {
public static final long WARN_ID = 8L;
@InjectMocks
private WarnServiceBean testUnit;
@Mock
private UserInServerManagementService userInServerManagementService;
@Mock
private WarnManagementService warnManagementService;
@@ -59,9 +54,6 @@ public class WarnServiceBeanTest {
@Mock
private BotService botService;
@Mock
private MessageService messageService;
@Mock
private ConfigService configService;
@@ -81,10 +73,10 @@ public class WarnServiceBeanTest {
private MessageToSend messageToSend;
@Mock
private MessageChannel feedBackChannel;
private User warnedSimpleUser;
@Mock
private User warnedSimpleUser;
private WarnContext context;
@Captor
private ArgumentCaptor<WarnDecayLogModel> warnDecayLogModelArgumentCaptor;
@@ -92,38 +84,43 @@ public class WarnServiceBeanTest {
@Captor
private ArgumentCaptor<WarnNotification> notificationCaptor;
@Mock
private AServer server;
@Mock
private AUserInAServer warningUser;
@Mock
private AUserInAServer firstWarnedUser;
@Mock
private AUserInAServer secondWarnedUser;
@Mock
private Warning firstWarning;
@Mock
private Warning secondWarning;
private static final String REASON = "reason";
@Mock
private ServerManagementService serverManagementService;
@Mock
private CounterService counterService;
@Mock
private MessageService messageService;
private static final String NOTIFICATION_TEXT = "text";
private static final String GUILD_NAME = "guild";
@Before
public void setup() {
server = MockUtils.getServer();
warningUser = MockUtils.getUserObject(8L, server);
firstWarnedUser = MockUtils.getUserObject(5L, server);
firstWarning = getDefaultWarning();
firstWarning.setWarningUser(warningUser);
firstWarning.setWarnedUser(firstWarnedUser);
secondWarnedUser = MockUtils.getUserObject(7L, server);
secondWarning = getDefaultWarning();
secondWarning.setWarnedUser(secondWarnedUser);
secondWarning.setWarningUser(warningUser);
}
private static final Long SERVER_ID = 4L;
@Test
public void testDecayWarning() {
Warning warning = getDefaultWarning();
Instant date = Instant.now();
testUnit.decayWarning(warning, date);
Assert.assertTrue(warning.getDecayed());
Assert.assertEquals(date, warning.getDecayDate());
testUnit.decayWarning(firstWarning, date);
verify(firstWarning, times(1)).setDecayed(true);
verify(firstWarning, times(1)).setDecayDate(date);
}
@Test
@@ -151,7 +148,7 @@ public class WarnServiceBeanTest {
public void testDecayAllWarningsWithoutWarnings() {
List<Warning> warnings = Collections.emptyList();
when(botService.getGuildByIdNullable(server.getId())).thenReturn(guild);
when(templateService.renderEmbedTemplate(eq("warn_decay_log"), warnDecayLogModelArgumentCaptor.capture())).thenReturn(messageToSend);
when(templateService.renderEmbedTemplate(eq(WARN_DECAY_LOG_TEMPLATE_KEY), warnDecayLogModelArgumentCaptor.capture())).thenReturn(messageToSend);
when(warnManagementService.getActiveWarningsInServerOlderThan(eq(server), any(Instant.class))).thenReturn(warnings);
testUnit.decayAllWarningsForServer(server, true);
verify(postTargetService, times(1)).sendEmbedInPostTarget(messageToSend, WarnDecayPostTarget.DECAY_LOG, server.getId());
@@ -162,57 +159,42 @@ public class WarnServiceBeanTest {
@Test
public void testWarnFullUser() {
setupWarnContext();
setupMocksForWarning();
FullUserInServer warnedFullUser = FullUserInServer.builder().member(warnedMember).aUserInAServer(firstWarnedUser).build();
FullUserInServer warningFullUser = FullUserInServer.builder().member(warningMember).aUserInAServer(warningUser).build();
Warning warning = testUnit.warnFullUser(warnedFullUser, warningFullUser, REASON, feedBackChannel);
verifyWarning(warning);
testUnit.notifyAndLogFullUserWarning(context);
}
@Test
public void testWarnUser() {
setupMocksForWarning();
when(botService.getMemberInServer(firstWarnedUser)).thenReturn(warnedMember);
when(botService.getMemberInServer(warningUser)).thenReturn(warningMember);
Warning warning = testUnit.warnUser(firstWarnedUser, warningUser, REASON, feedBackChannel);
verifyWarning(warning);
private void setupWarnContext() {
when(guild.getIdLong()).thenReturn(SERVER_ID);
when(context.getGuild()).thenReturn(guild);
when(context.getWarnedMember()).thenReturn(warnedMember);
when(context.getMember()).thenReturn(warningMember);
when(counterService.getNextCounterValue(server, WARNINGS_COUNTER_KEY)).thenReturn(WARN_ID);
}
@Test
public void testWarnMember() {
setupMocksForWarning();
when(userInServerManagementService.loadUser(warnedMember)).thenReturn(firstWarnedUser);
when(userInServerManagementService.loadUser(warningMember)).thenReturn(warningUser);
Warning warning = testUnit.warnMember(warnedMember, warningMember, REASON, feedBackChannel);
verifyWarning(warning);
}
@Test
public void testWarnUserWithLog() {
setupMocksForWarning();
when(userInServerManagementService.loadUser(warnedMember)).thenReturn(firstWarnedUser);
when(userInServerManagementService.loadUser(warningMember)).thenReturn(warningUser);
WarnLog log = WarnLog.builder().server(server).build();
when(templateService.renderEmbedTemplate(eq(WarnServiceBean.WARN_LOG_TEMPLATE), any(WarnLog.class))).thenReturn(messageToSend);
Warning warning = testUnit.warnUserWithLog(warnedMember, warningMember, REASON, log, feedBackChannel);
verifyWarning(warning);
verify( postTargetService, times(1)).sendEmbedInPostTarget(messageToSend, WarningPostTarget.WARN_LOG, server.getId());
}
private void verifyWarning(Warning warning) {
verify(messageService, times(1)).sendMessageToUser(warnedSimpleUser, NOTIFICATION_TEXT, feedBackChannel);
WarnNotification notificationValue = notificationCaptor.getValue();
Assert.assertEquals(firstWarning, notificationValue.getWarning());
Assert.assertEquals(GUILD_NAME, notificationValue.getServerName());
Assert.assertEquals(firstWarning, warning);
}
private void setupMocksForWarning() {
setupWarnings();
when(warnedMember.getGuild()).thenReturn(guild);
when(guild.getName()).thenReturn(GUILD_NAME);
when(guild.getIdLong()).thenReturn(SERVER_ID);
when(warnedMember.getUser()).thenReturn(warnedSimpleUser);
when(warnManagementService.createWarning(firstWarnedUser, warningUser, REASON)).thenReturn(firstWarning);
when(templateService.renderEmbedTemplate(eq(WARN_LOG_TEMPLATE), warnDecayLogModelArgumentCaptor.capture())).thenReturn(messageToSend);
when(messageService.sendMessageToUser(eq(warnedMember.getUser()), any())).thenReturn(CompletableFuture.completedFuture(null));
when(postTargetService.sendEmbedInPostTarget(messageToSend, WarningPostTarget.WARN_LOG, context.getGuild().getIdLong())).thenReturn(CommandTestUtilities.messageFutureList());
when(templateService.renderTemplate(eq(WarnServiceBean.WARN_NOTIFICATION_TEMPLATE), notificationCaptor.capture())).thenReturn(NOTIFICATION_TEXT);
when(serverManagementService.loadOrCreate(SERVER_ID)).thenReturn(server);
}
private void setupWarnings() {
when(firstWarning.getWarningUser()).thenReturn(warningUser);
when(secondWarning.getWarningUser()).thenReturn(warningUser);
when(firstWarning.getWarnedUser()).thenReturn(firstWarnedUser);
when(secondWarning.getWarnedUser()).thenReturn(secondWarnedUser);
when(firstWarning.getWarnId()).thenReturn(new ServerSpecificId(SERVER_ID, WARN_ID));
when(secondWarning.getWarnId()).thenReturn(new ServerSpecificId(SERVER_ID, 9L));
when(server.getId()).thenReturn(SERVER_ID);
}
private void verifyWarnDecayWithLog(boolean withLog) {
@@ -232,18 +214,15 @@ public class WarnServiceBeanTest {
}
private void setupWarnDecay() {
setupWarnings();
when(configService.getLongValue(WarningDecayFeature.DECAY_DAYS_KEY, server.getId())).thenReturn(5L);
List<Warning> warnings = Arrays.asList(firstWarning, secondWarning);
when(botService.getMemberInServer(warningUser)).thenReturn(warningMember);
when(botService.getMemberInServer(firstWarnedUser)).thenReturn(warnedMember);
when(botService.getMemberInServer(secondWarnedUser)).thenReturn(secondWarnedMember);
when(botService.getGuildByIdNullable(server.getId())).thenReturn(guild);
when(templateService.renderEmbedTemplate(eq("warn_decay_log"), warnDecayLogModelArgumentCaptor.capture())).thenReturn(messageToSend);
when(templateService.renderEmbedTemplate(eq(WARN_DECAY_LOG_TEMPLATE_KEY), warnDecayLogModelArgumentCaptor.capture())).thenReturn(messageToSend);
when(warnManagementService.getActiveWarningsInServerOlderThan(eq(server), any(Instant.class))).thenReturn(warnings);
}
public Warning getDefaultWarning() {
return Warning.builder().build();
}
}

View File

@@ -1,6 +1,7 @@
package dev.sheldan.abstracto.moderation.service.management;
import dev.sheldan.abstracto.core.models.AServerAChannelMessage;
import dev.sheldan.abstracto.core.models.ServerSpecificId;
import dev.sheldan.abstracto.core.models.database.AChannel;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
@@ -45,16 +46,17 @@ public class MuteManagementServiceBeanTest {
AUserInAServer mutingUser = MockUtils.getUserObject(5L, server);
AUserInAServer mutedUser = MockUtils.getUserObject(7L, server);
String reason = "reason";
String triggerKey = "key";
Instant unMuteDate = Instant.now();
AServerAChannelMessage muteMessage = AServerAChannelMessage.builder().server(server).channel(channel).messageId(messageId).build();
testUnit.createMute(mutedUser, mutingUser, reason, unMuteDate, muteMessage);
testUnit.createMute(mutedUser, mutingUser, reason, unMuteDate, muteMessage, triggerKey, 8L);
verify(muteRepository, times(1)).save(muteArgumentCaptor.capture());
Mute createdMute = muteArgumentCaptor.getValue();
Assert.assertEquals(reason, createdMute.getReason());
Assert.assertEquals(mutingUser, createdMute.getMutingUser());
Assert.assertEquals(mutedUser, createdMute.getMutedUser());
Assert.assertEquals(server, createdMute.getMutingServer());
Assert.assertEquals(server, createdMute.getServer());
Assert.assertFalse(createdMute.getMuteEnded());
Assert.assertEquals(messageId, createdMute.getMessageId().longValue());
Assert.assertEquals(channel, createdMute.getMutingChannel());
@@ -64,18 +66,20 @@ public class MuteManagementServiceBeanTest {
@Test
public void testFindMute() {
Long id = 5L;
Mute mute = Mute.builder().id(id).build();
when(muteRepository.findById(id)).thenReturn(Optional.of(mute));
Optional<Mute> foundMuteOptional = testUnit.findMute(id);
Long serverId = 7L;
Mute mute = Mute.builder().muteId(new ServerSpecificId(serverId, id)).build();
when(muteRepository.findByMuteId_IdAndMuteId_ServerId(id, serverId)).thenReturn(Optional.of(mute));
Optional<Mute> foundMuteOptional = testUnit.findMute(id, serverId);
Assert.assertTrue(foundMuteOptional.isPresent());
foundMuteOptional.ifPresent(foundMute -> Assert.assertEquals(id, foundMute.getId()));
foundMuteOptional.ifPresent(foundMute -> Assert.assertEquals(id, foundMute.getMuteId().getId()));
}
@Test
public void testFindNonExistingMute() {
Long id = 5L;
when(muteRepository.findById(id)).thenReturn(Optional.empty());
Optional<Mute> foundMuteOptional = testUnit.findMute(id);
Long serverId = 7L;
when(muteRepository.findByMuteId_IdAndMuteId_ServerId(id, serverId)).thenReturn(Optional.empty());
Optional<Mute> foundMuteOptional = testUnit.findMute(id, serverId);
Assert.assertFalse(foundMuteOptional.isPresent());
}
@@ -114,7 +118,7 @@ public class MuteManagementServiceBeanTest {
AUserInAServer userInAServer = MockUtils.getUserObject(9L, server);
Mute mute1 = Mute.builder().build();
Mute mute2 = Mute.builder().build();
when(muteRepository.findAllByMutedUserAndMuteEndedFalseOrderByIdDesc(userInAServer)).thenReturn(Arrays.asList(mute1, mute2));
when(muteRepository.findAllByMutedUserAndMuteEndedFalseOrderByMuteId_IdDesc(userInAServer)).thenReturn(Arrays.asList(mute1, mute2));
List<Mute> allMutesOf = testUnit.getAllMutesOf(userInAServer);
Assert.assertEquals(2, allMutesOf.size());
Assert.assertEquals(mute1, allMutesOf.get(0));

View File

@@ -2,6 +2,7 @@ package dev.sheldan.abstracto.moderation.service.management;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.service.CounterService;
import dev.sheldan.abstracto.moderation.models.database.UserNote;
import dev.sheldan.abstracto.moderation.repository.UserNoteRepository;
import dev.sheldan.abstracto.test.MockUtils;
@@ -27,6 +28,9 @@ public class UserNoteManagementServiceBeanTest {
@Mock
private UserNoteRepository userNoteRepository;
@Mock
private CounterService counterService;
private static final String NOTE_TEXT = "noteText";
private static final Long NOTE_ID = 5L;

View File

@@ -43,7 +43,7 @@ public class WarnManagementServiceBeanTest {
public void testCreateWarning() {
AUserInAServer warningUser = MockUtils.getUserObject(7L, server);
String reason = "REASON";
Warning warning = testUnit.createWarning(warnedUser, warningUser, reason);
Warning warning = testUnit.createWarning(warnedUser, warningUser, reason, 8L);
Assert.assertEquals(warningUser, warning.getWarningUser());
Assert.assertEquals(warnedUser, warning.getWarnedUser());
Assert.assertEquals(reason, warning.getReason());
@@ -95,9 +95,10 @@ public class WarnManagementServiceBeanTest {
@Test
public void testFindByIdExisting() {
Long warnId = 6L;
Long serverId = 8L;
Warning existingWarning = getWarning();
when(warnRepository.findById(warnId)).thenReturn(Optional.ofNullable(existingWarning));
Optional<Warning> warningOptional = testUnit.findById(warnId);
when(warnRepository.findByWarnId_IdAndWarnId_ServerId(warnId, serverId)).thenReturn(Optional.ofNullable(existingWarning));
Optional<Warning> warningOptional = testUnit.findById(warnId, serverId);
Assert.assertTrue(warningOptional.isPresent());
warningOptional.ifPresent(foundWarning -> Assert.assertEquals(existingWarning, foundWarning));
}
@@ -105,8 +106,9 @@ public class WarnManagementServiceBeanTest {
@Test
public void testFindByIdNotExisting() {
Long warnId = 6L;
when(warnRepository.findById(warnId)).thenReturn(Optional.ofNullable(null));
Optional<Warning> warningOptional = testUnit.findById(warnId);
Long serverId = 8L;
when(warnRepository.findByWarnId_IdAndWarnId_ServerId(warnId, serverId)).thenReturn(Optional.ofNullable(null));
Optional<Warning> warningOptional = testUnit.findById(warnId, serverId);
Assert.assertFalse(warningOptional.isPresent());
}