added message to user initiated context

fixed templates for ban and kick logging
refactored kicking service
fixed guild not found exception template
added command validator to be used for unit testing commands
added default values for command configuration
changed some interfaces to message channel instead of text channel
added separate executor service for un-mutes, which is shared
updated spring boot version to 2.3.1
removed database connection string from properties
added logback configuration
changed some future logic in purge
refactored error message for un mute, when there is no active mute
refactored listener interface and removed usage of context utils
added tests for moderation services
This commit is contained in:
Sheldan
2020-06-20 11:08:44 +02:00
parent 8acd4f818d
commit c44eb80fc5
140 changed files with 4176 additions and 225 deletions

View File

@@ -7,6 +7,7 @@ import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.models.database.ARole;
import dev.sheldan.abstracto.experience.service.management.DisabledExpRoleManagementService;
import dev.sheldan.abstracto.test.MockUtils;
import dev.sheldan.abstracto.test.command.CommandConfigValidator;
import dev.sheldan.abstracto.test.command.CommandTestUtilities;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -55,4 +56,9 @@ public class DisableExpForRoleTest {
verify(disabledExpRoleManagementService, times(wantedNumberOfInvocations)).setRoleToBeDisabledForExp(disabledRole);
CommandTestUtilities.checkSuccessfulCompletion(result);
}
@Test
public void validateCommand() {
CommandConfigValidator.validateCommandConfiguration(testUnit.getConfiguration());
}
}

View File

@@ -8,6 +8,7 @@ import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.experience.service.AUserExperienceService;
import dev.sheldan.abstracto.test.MockUtils;
import dev.sheldan.abstracto.test.command.CommandConfigValidator;
import dev.sheldan.abstracto.test.command.CommandTestUtilities;
import net.dv8tion.jda.api.entities.Member;
import org.junit.Test;
@@ -55,4 +56,8 @@ public class DisableExpGainTest {
CommandTestUtilities.checkSuccessfulCompletion(result);
}
@Test
public void validateCommand() {
CommandConfigValidator.validateCommandConfiguration(testUnit.getConfiguration());
}
}

View File

@@ -7,6 +7,7 @@ import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.models.database.ARole;
import dev.sheldan.abstracto.experience.service.management.DisabledExpRoleManagementService;
import dev.sheldan.abstracto.test.MockUtils;
import dev.sheldan.abstracto.test.command.CommandConfigValidator;
import dev.sheldan.abstracto.test.command.CommandTestUtilities;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -55,4 +56,9 @@ public class EnableExpForRoleTest {
verify(disabledExpRoleManagementService, times(wantedNumberOfInvocations)).removeRoleToBeDisabledForExp(disabledRole);
CommandTestUtilities.checkSuccessfulCompletion(result);
}
@Test
public void validateCommand() {
CommandConfigValidator.validateCommandConfiguration(testUnit.getConfiguration());
}
}

View File

@@ -8,6 +8,7 @@ import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.experience.service.AUserExperienceService;
import dev.sheldan.abstracto.test.MockUtils;
import dev.sheldan.abstracto.test.command.CommandConfigValidator;
import dev.sheldan.abstracto.test.command.CommandTestUtilities;
import net.dv8tion.jda.api.entities.Member;
import org.junit.Test;
@@ -55,4 +56,9 @@ public class EnableExpGainTest {
CommandTestUtilities.checkSuccessfulCompletion(result);
}
@Test
public void validateCommand() {
CommandConfigValidator.validateCommandConfiguration(testUnit.getConfiguration());
}
}

View File

@@ -5,6 +5,7 @@ import dev.sheldan.abstracto.core.command.exception.InsufficientParameters;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.service.ConfigService;
import dev.sheldan.abstracto.test.command.CommandConfigValidator;
import dev.sheldan.abstracto.test.command.CommandTestUtilities;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -42,6 +43,10 @@ public class ExpScaleTest {
CommandResult result = testUnit.execute(context);
CommandTestUtilities.checkSuccessfulCompletion(result);
verify(configService, times(1)).setDoubleValue(ExpScale.EXP_MULTIPLIER_KEY, context.getGuild().getIdLong(), newScale);
}
@Test
public void validateCommand() {
CommandConfigValidator.validateCommandConfiguration(testUnit.getConfiguration());
}
}

View File

@@ -12,6 +12,7 @@ import dev.sheldan.abstracto.experience.models.templates.LeaderBoardModel;
import dev.sheldan.abstracto.experience.service.AUserExperienceService;
import dev.sheldan.abstracto.templating.model.MessageToSend;
import dev.sheldan.abstracto.templating.service.TemplateService;
import dev.sheldan.abstracto.test.command.CommandConfigValidator;
import dev.sheldan.abstracto.test.command.CommandTestUtilities;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -71,4 +72,9 @@ public class LeaderBoardCommandTest {
verify(channelService, times(1)).sendMessageToSendToChannel(messageToSend, context.getChannel());
CommandTestUtilities.checkSuccessfulCompletion(result);
}
@Test
public void validateCommand() {
CommandConfigValidator.validateCommandConfiguration(testUnit.getConfiguration());
}
}

View File

@@ -10,6 +10,7 @@ import dev.sheldan.abstracto.experience.models.database.ADisabledExpRole;
import dev.sheldan.abstracto.experience.models.templates.DisabledExperienceRolesModel;
import dev.sheldan.abstracto.experience.service.management.DisabledExpRoleManagementService;
import dev.sheldan.abstracto.test.MockUtils;
import dev.sheldan.abstracto.test.command.CommandConfigValidator;
import dev.sheldan.abstracto.test.command.CommandTestUtilities;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -62,4 +63,9 @@ public class ListDisabledExperienceRolesTest {
verify(channelService, times(1)).sendEmbedTemplateInChannel(eq("list_disabled_experience_roles"),
any(DisabledExperienceRolesModel.class), eq(context.getChannel()));
}
@Test
public void validateCommand() {
CommandConfigValidator.validateCommandConfiguration(testUnit.getConfiguration());
}
}

View File

@@ -13,6 +13,7 @@ import dev.sheldan.abstracto.experience.service.AUserExperienceService;
import dev.sheldan.abstracto.experience.service.ExperienceLevelService;
import dev.sheldan.abstracto.templating.model.MessageToSend;
import dev.sheldan.abstracto.templating.service.TemplateService;
import dev.sheldan.abstracto.test.command.CommandConfigValidator;
import dev.sheldan.abstracto.test.command.CommandTestUtilities;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -62,4 +63,9 @@ public class RankTest {
verify(channelService, Mockito.times(1)).sendMessageToSendToChannel(messageToSend, context.getChannel());
CommandTestUtilities.checkSuccessfulCompletion(result);
}
@Test
public void validateCommand() {
CommandConfigValidator.validateCommandConfiguration(testUnit.getConfiguration());
}
}

View File

@@ -9,6 +9,7 @@ import dev.sheldan.abstracto.core.models.database.ARole;
import dev.sheldan.abstracto.core.service.RoleService;
import dev.sheldan.abstracto.experience.service.ExperienceRoleService;
import dev.sheldan.abstracto.test.MockUtils;
import dev.sheldan.abstracto.test.command.CommandConfigValidator;
import dev.sheldan.abstracto.test.command.CommandTestUtilities;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -75,4 +76,9 @@ public class SetExpRoleTest {
when(roleService.isRoleInServer(changedRole)).thenReturn(false);
testUnit.execute(context);
}
@Test
public void validateCommand() {
CommandConfigValidator.validateCommandConfiguration(testUnit.getConfiguration());
}
}

View File

@@ -5,6 +5,7 @@ import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.models.database.AChannel;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.experience.service.AUserExperienceService;
import dev.sheldan.abstracto.test.command.CommandConfigValidator;
import dev.sheldan.abstracto.test.command.CommandTestUtilities;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -32,4 +33,9 @@ public class SyncRolesTest {
verify(userExperienceService, times(1)).syncUserRolesWithFeedback(server, channel);
CommandTestUtilities.checkSuccessfulCompletion(result);
}
@Test
public void validateCommand() {
CommandConfigValidator.validateCommandConfiguration(testUnit.getConfiguration());
}
}

View File

@@ -7,6 +7,7 @@ import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.models.database.ARole;
import dev.sheldan.abstracto.experience.service.ExperienceRoleService;
import dev.sheldan.abstracto.test.MockUtils;
import dev.sheldan.abstracto.test.command.CommandConfigValidator;
import dev.sheldan.abstracto.test.command.CommandTestUtilities;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -47,4 +48,9 @@ public class UnSetExpRoleTest {
CommandTestUtilities.checkSuccessfulCompletion(result);
verify(experienceRoleService, times(1)).unsetRole(changedRole, context.getUserInitiatedContext().getChannel());
}
@Test
public void validateCommand() {
CommandConfigValidator.validateCommandConfiguration(testUnit.getConfiguration());
}
}

View File

@@ -23,6 +23,14 @@
<artifactId>scheduling-int</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>dev.sheldan.abstracto</groupId>
<artifactId>test-commons</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@@ -24,6 +24,7 @@ import java.util.List;
@Slf4j
public class Ban extends AbstractConditionableCommand {
public static final String BAN_DEFAULT_REASON_TEMPLATE = "ban_default_reason";
@Autowired
private BanService banService;
@@ -32,9 +33,10 @@ public class Ban extends AbstractConditionableCommand {
@Override
public CommandResult execute(CommandContext commandContext) {
checkParameters(commandContext);
List<Object> parameters = commandContext.getParameters().getParameters();
Member member = (Member) parameters.get(0);
String defaultReason = templateService.renderTemplateWithMap("ban_default_reason", null);
String defaultReason = templateService.renderSimpleTemplate(BAN_DEFAULT_REASON_TEMPLATE);
String reason = parameters.size() == 2 ? (String) parameters.get(1) : defaultReason;
BanLog banLogModel = (BanLog) ContextConverter.fromCommandContext(commandContext, BanLog.class);

View File

@@ -28,15 +28,16 @@ public class BanId extends AbstractConditionableCommand {
@Override
public CommandResult execute(CommandContext commandContext) {
checkParameters(commandContext);
List<Object> parameters = commandContext.getParameters().getParameters();
Long userId = (Long) parameters.get(0);
String defaultReason = templateService.renderTemplateWithMap("ban_default_reason", null);
String defaultReason = templateService.renderSimpleTemplate(Ban.BAN_DEFAULT_REASON_TEMPLATE);
String reason = parameters.size() == 2 ? (String) parameters.get(1) : defaultReason;
BanIdLog banLogModel = (BanIdLog) ContextConverter.fromCommandContext(commandContext, BanIdLog.class);
banLogModel.setBannedUserId(userId);
banLogModel.setBanningUser(commandContext.getAuthor());
banLogModel.setReason(reason);
banService.banMember(userId, commandContext.getGuild().getIdLong(), reason, banLogModel);
banService.banMember(commandContext.getGuild().getIdLong(), userId, reason, banLogModel);
return CommandResult.fromSuccess();
}

View File

@@ -24,6 +24,7 @@ public class DecayAllWarnings extends AbstractConditionableCommand {
@Override
public CommandResult execute(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);

View File

@@ -20,6 +20,7 @@ import java.util.List;
@Component
public class DeleteNote extends AbstractConditionableCommand {
public static final String NOTE_NOT_FOUND_EXCEPTION_TEMPLATE = "note_not_found_exception";
@Autowired
private UserNoteManagementService userNoteManagementService;
@@ -28,11 +29,12 @@ public class DeleteNote extends AbstractConditionableCommand {
@Override
public CommandResult execute(CommandContext commandContext) {
checkParameters(commandContext);
Long id = (Long) commandContext.getParameters().getParameters().get(0);
if(userNoteManagementService.noteExists(id)) {
userNoteManagementService.deleteNote(id);
} else {
return CommandResult.fromError(templateService.renderSimpleTemplate("note_not_found_exception"));
return CommandResult.fromError(templateService.renderSimpleTemplate(NOTE_NOT_FOUND_EXCEPTION_TEMPLATE));
}
return CommandResult.fromSuccess();
}

View File

@@ -27,6 +27,7 @@ public class DeleteWarning extends AbstractConditionableCommand {
@Override
public CommandResult execute(CommandContext commandContext) {
checkParameters(commandContext);
Long warnId = (Long) commandContext.getParameters().getParameters().get(0);
Optional<Warning> optional = warnManagementService.findById(warnId);
optional.ifPresent(warning -> {

View File

@@ -22,6 +22,7 @@ import java.util.List;
@Component
public class Kick extends AbstractConditionableCommand {
public static final String KICK_DEFAULT_REASON_TEMPLATE = "kick_default_reason";
@Autowired
private TemplateService templateService;
@@ -30,10 +31,10 @@ public class Kick extends AbstractConditionableCommand {
@Override
public CommandResult execute(CommandContext commandContext) {
checkParameters(commandContext);
List<Object> parameters = commandContext.getParameters().getParameters();
Member member = (Member) parameters.get(0);
String defaultReason = templateService.renderTemplateWithMap("ban_default_reason", null);
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);

View File

@@ -9,10 +9,8 @@ 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.service.ChannelService;
import dev.sheldan.abstracto.core.service.FeatureFlagService;
import dev.sheldan.abstracto.moderation.config.ModerationModule;
import dev.sheldan.abstracto.moderation.config.features.ModerationFeatures;
import dev.sheldan.abstracto.moderation.config.features.WarningDecayFeature;
import dev.sheldan.abstracto.moderation.models.template.commands.MyWarningsModel;
import dev.sheldan.abstracto.moderation.service.management.WarnManagementService;
import org.springframework.beans.factory.annotation.Autowired;
@@ -25,18 +23,13 @@ import java.util.List;
@Component
public class MyWarnings extends AbstractConditionableCommand {
public static final String MY_WARNINGS_RESPONSE_EMBED_TEMPLATE = "myWarnings_response";
@Autowired
private ChannelService channelService;
@Autowired
private WarnManagementService warnManagementService;
@Autowired
private FeatureFlagService featureFlagService;
@Autowired
private WarningDecayFeature warningDecayFeature;
@Override
public CommandResult execute(CommandContext commandContext) {
MyWarningsModel model = (MyWarningsModel) ContextConverter.fromCommandContext(commandContext, MyWarningsModel.class);
@@ -44,7 +37,7 @@ public class MyWarnings extends AbstractConditionableCommand {
model.setCurrentWarnCount(currentWarnCount);
Long totalWarnCount = warnManagementService.getTotalWarnsForUser(commandContext.getUserInitiatedContext().getAUserInAServer());
model.setTotalWarnCount(totalWarnCount);
channelService.sendEmbedTemplateInChannel("myWarnings_response", model, commandContext.getChannel());
channelService.sendEmbedTemplateInChannel(MY_WARNINGS_RESPONSE_EMBED_TEMPLATE, model, commandContext.getChannel());
return CommandResult.fromSuccess();
}

View File

@@ -34,6 +34,7 @@ public class Purge extends AbstractConditionableCommand {
@Override
public CommandResult execute(CommandContext commandContext) {
checkParameters(commandContext);
Integer amountOfMessages = (Integer) commandContext.getParameters().getParameters().get(0);
Member memberToPurgeMessagesOf = null;
if(commandContext.getParameters().getParameters().size() == 2) {

View File

@@ -27,6 +27,7 @@ public class SlowMode extends AbstractConditionableCommand {
@Override
public CommandResult execute(CommandContext commandContext) {
checkParameters(commandContext);
TextChannel channel;
String durationString = (String) commandContext.getParameters().getParameters().get(0);
Duration duration;

View File

@@ -30,6 +30,7 @@ public class UserNoteCommand extends AbstractConditionableCommand {
@Override
public CommandResult execute(CommandContext commandContext) {
checkParameters(commandContext);
List<Object> parameters = commandContext.getParameters().getParameters();
Member member = (Member) parameters.get(0);
String text = (String) parameters.get(1);

View File

@@ -28,6 +28,7 @@ import java.util.List;
@Component
public class UserNotes extends AbstractConditionableCommand {
public static final String USER_NOTES_RESPONSE_TEMPLATE = "user_notes_response";
@Autowired
private UserNoteManagementService userNoteManagementService;
@@ -45,6 +46,7 @@ public class UserNotes extends AbstractConditionableCommand {
@Override
public CommandResult execute(CommandContext commandContext) {
checkParameters(commandContext);
List<Object> parameters = commandContext.getParameters().getParameters();
List<UserNote> userNotes;
@@ -63,7 +65,7 @@ public class UserNotes extends AbstractConditionableCommand {
userNotes = userNoteManagementService.loadNotesForServer(commandContext.getUserInitiatedContext().getServer());
}
model.setUserNotes(userNotesConverter.fromNotes(userNotes));
channelService.sendEmbedTemplateInChannel("user_notes_response", model, commandContext.getChannel());
channelService.sendEmbedTemplateInChannel(USER_NOTES_RESPONSE_TEMPLATE, model, commandContext.getChannel());
return CommandResult.fromSuccess();
}

View File

@@ -24,6 +24,7 @@ import java.util.List;
@Slf4j
public class Warn extends AbstractConditionableCommand {
public static final String WARN_DEFAULT_REASON_TEMPLATE = "warn_default_reason";
@Autowired
private WarnService warnService;
@@ -32,9 +33,10 @@ public class Warn extends AbstractConditionableCommand {
@Override
public CommandResult execute(CommandContext commandContext) {
checkParameters(commandContext);
List<Object> parameters = commandContext.getParameters().getParameters();
Member member = (Member) parameters.get(0);
String defaultReason = templateService.renderTemplateWithMap("warn_default_reason", null);
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);

View File

@@ -10,7 +10,6 @@ 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.service.BotService;
import dev.sheldan.abstracto.core.service.PaginatorService;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.moderation.config.ModerationModule;
@@ -20,7 +19,6 @@ import dev.sheldan.abstracto.moderation.models.database.Warning;
import dev.sheldan.abstracto.moderation.models.template.commands.WarnEntry;
import dev.sheldan.abstracto.moderation.models.template.commands.WarningsModel;
import dev.sheldan.abstracto.moderation.service.management.WarnManagementService;
import dev.sheldan.abstracto.templating.service.TemplateService;
import net.dv8tion.jda.api.entities.Member;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -31,15 +29,10 @@ import java.util.List;
@Component
public class Warnings extends AbstractConditionableCommand {
@Autowired
private BotService botService;
public static final String WARNINGS_RESPONSE_TEMPLATE = "warnings_response";
@Autowired
private WarnManagementService warnManagementService;
@Autowired
private TemplateService templateService;
@Autowired
private UserInServerManagementService userInServerManagementService;
@@ -54,6 +47,7 @@ public class Warnings extends AbstractConditionableCommand {
@Override
public CommandResult execute(CommandContext commandContext) {
checkParameters(commandContext);
List<Warning> warnsToDisplay;
if(!commandContext.getParameters().getParameters().isEmpty()) {
Member member = (Member) commandContext.getParameters().getParameters().get(0);
@@ -66,7 +60,7 @@ public class Warnings extends AbstractConditionableCommand {
WarningsModel model = (WarningsModel) ContextConverter.fromCommandContext(commandContext, WarningsModel.class);
model.setWarnings(warnEntries);
Paginator paginator = paginatorService.createPaginatorFromTemplate("warnings_response", model, eventWaiter);
Paginator paginator = paginatorService.createPaginatorFromTemplate(WARNINGS_RESPONSE_TEMPLATE, model, eventWaiter);
paginator.display(commandContext.getChannel());
return CommandResult.fromSuccess();
}
@@ -74,7 +68,7 @@ public class Warnings extends AbstractConditionableCommand {
@Override
public CommandConfiguration getConfiguration() {
List<Parameter> parameters = new ArrayList<>();
parameters.add(Parameter.builder().name("user").type(Member.class).optional(true).build());
parameters.add(Parameter.builder().name("user").type(Member.class).templated(true).optional(true).build());
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
return CommandConfiguration.builder()
.name("warnings")

View File

@@ -30,6 +30,7 @@ public class Mute extends AbstractConditionableCommand {
@Override
public CommandResult execute(CommandContext commandContext) {
checkParameters(commandContext);
List<Object> parameters = commandContext.getParameters().getParameters();
Member member = (Member) parameters.get(0);
Duration duration = (Duration) parameters.get(1);

View File

@@ -25,6 +25,7 @@ public class SetMuteRole extends AbstractConditionableCommand {
@Override
public CommandResult execute(CommandContext commandContext) {
checkParameters(commandContext);
ARole role = (ARole) commandContext.getParameters().getParameters().get(0);
muteRoleManagementService.setMuteRoleForServer(commandContext.getUserInitiatedContext().getServer(), role);
return CommandResult.fromSuccess();

View File

@@ -9,10 +9,10 @@ import dev.sheldan.abstracto.core.command.execution.CommandResult;
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.exception.MuteException;
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;
import net.dv8tion.jda.api.entities.Member;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -23,30 +23,35 @@ import java.util.List;
@Component
public class UnMute extends AbstractConditionableCommand {
public static final String NO_ACTIVE_MUTE = "unMute_has_no_active_mute";
@Autowired
private MuteService muteService;
@Autowired
private MuteManagementService muteManagementService;
@Autowired
private TemplateService templateService;
@Override
public CommandResult execute(CommandContext commandContext) {
checkParameters(commandContext);
List<Object> parameters = commandContext.getParameters().getParameters();
Member member = (Member) parameters.get(0);
Mute mute = muteManagementService.getAMuteOf(member);
if(mute == null) {
throw new MuteException("User has no active mutes");
if(!muteManagementService.hasActiveMute(member)) {
return CommandResult.fromError(templateService.renderSimpleTemplate(NO_ACTIVE_MUTE));
}
Mute mute = muteManagementService.getAMuteOf(member);
muteService.unmuteUser(mute);
muteService.cancelUnmuteJob(mute);
muteService.completelyUnmuteUser(member);
muteService.completelyUnMuteMember(member);
return CommandResult.fromSuccess();
}
@Override
public CommandConfiguration getConfiguration() {
List<Parameter> parameters = new ArrayList<>();
parameters.add(Parameter.builder().name("user").type(Member.class).build());
parameters.add(Parameter.builder().name("user").type(Member.class).templated(true).build());
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
return CommandConfiguration.builder()
.name("unMute")

View File

@@ -0,0 +1,17 @@
package dev.sheldan.abstracto.moderation.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
@Configuration
public class ModerationSpringConfig {
@Bean(name = "unmuteScheduler")
public ScheduledExecutorService getUnMuteExecutor() {
return Executors.newScheduledThreadPool(1);
}
}

View File

@@ -2,7 +2,6 @@ package dev.sheldan.abstracto.moderation.converter;
import dev.sheldan.abstracto.core.models.FullUser;
import dev.sheldan.abstracto.core.service.BotService;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.moderation.models.database.Warning;
import dev.sheldan.abstracto.moderation.models.template.commands.WarnEntry;
import org.springframework.beans.factory.annotation.Autowired;
@@ -14,9 +13,6 @@ import java.util.List;
@Component
public class WarnEntryConverter {
@Autowired
private UserInServerManagementService userInServerManagementService;
@Autowired
private BotService botService;

View File

@@ -2,7 +2,6 @@ package dev.sheldan.abstracto.moderation.job;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.service.FeatureFlagService;
import dev.sheldan.abstracto.core.service.management.FeatureFlagManagementService;
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
import dev.sheldan.abstracto.moderation.config.features.WarningDecayFeature;
import dev.sheldan.abstracto.moderation.service.WarnService;
@@ -27,9 +26,6 @@ public class WarnDecayJob extends QuartzJobBean {
@Autowired
private ServerManagementService serverManagementService;
@Autowired
private FeatureFlagManagementService featureFlagManagementService;
@Autowired
private FeatureFlagService featureFlagService;

View File

@@ -11,18 +11,16 @@ import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.User;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.Nonnull;
import java.util.HashMap;
@Service
@Slf4j
public class JoinLogger implements JoinListener {
private static final String USER_JOIN_TEMPLATE = "user_join";
public static final String USER_JOIN_TEMPLATE = "user_join";
@Autowired
private TemplateService templateService;
@@ -31,8 +29,7 @@ public class JoinLogger implements JoinListener {
private PostTargetService postTargetService;
@NotNull
private HashMap<String, Object> getUserParameter(@Nonnull User user) {
private HashMap<String, Object> getUserParameter(User user) {
HashMap<String, Object> parameters = new HashMap<>();
parameters.put("user", user);
return parameters;

View File

@@ -21,7 +21,7 @@ import java.util.HashMap;
@Slf4j
public class LeaveLogger implements LeaveListener {
private static final String USER_LEAVE_TEMPLATE = "user_leave";
public static final String USER_LEAVE_TEMPLATE = "user_leave";
@Autowired
private TemplateService templateService;

View File

@@ -2,6 +2,8 @@ package dev.sheldan.abstracto.moderation.listener;
import dev.sheldan.abstracto.core.config.FeatureEnum;
import dev.sheldan.abstracto.core.listener.MessageDeletedListener;
import dev.sheldan.abstracto.core.models.AServerAChannelAUser;
import dev.sheldan.abstracto.core.models.GuildChannelMember;
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
import dev.sheldan.abstracto.moderation.config.features.ModerationFeatures;
import dev.sheldan.abstracto.moderation.config.posttargets.LoggingPostTarget;
@@ -19,8 +21,8 @@ import org.springframework.stereotype.Component;
@Slf4j
public class MessageDeleteLogListener implements MessageDeletedListener {
private static final String MESSAGE_DELETED_TEMPLATE = "message_deleted";
private static final String MESSAGE_DELETED_ATTACHMENT_TEMPLATE = "message_deleted_attachment";
public static final String MESSAGE_DELETED_TEMPLATE = "message_deleted";
public static final String MESSAGE_DELETED_ATTACHMENT_TEMPLATE = "message_deleted_attachment";
@Autowired
private ContextUtils contextUtils;
@@ -32,18 +34,38 @@ public class MessageDeleteLogListener implements MessageDeletedListener {
private PostTargetService postTargetService;
@Override
public void execute(CachedMessage messageFromCache) {
public void execute(CachedMessage messageFromCache, AServerAChannelAUser authorUser, GuildChannelMember authorMember) {
log.trace("Message {} in channel {} in guild {} was deleted.", messageFromCache.getMessageId(), messageFromCache.getChannelId(), messageFromCache.getServerId());
MessageDeletedLog logModel = (MessageDeletedLog) contextUtils.fromMessage(messageFromCache, MessageDeletedLog.class);
logModel.setMessage(messageFromCache);
MessageDeletedLog logModel = MessageDeletedLog
.builder()
.cachedMessage(messageFromCache)
.server(authorUser.getGuild())
.channel(authorUser.getChannel())
.user(authorUser.getUser())
.aUserInAServer(authorUser.getAUserInAServer())
.guild(authorMember.getGuild())
.messageChannel(authorMember.getTextChannel())
.member(authorMember.getMember())
.build();
MessageToSend message = templateService.renderEmbedTemplate(MESSAGE_DELETED_TEMPLATE, logModel);
postTargetService.sendEmbedInPostTarget(message, LoggingPostTarget.DELETE_LOG, messageFromCache.getServerId());
for (int i = 0; i < messageFromCache.getAttachmentUrls().size(); i++) {
MessageDeletedAttachmentLog log = (MessageDeletedAttachmentLog) contextUtils.fromMessage(messageFromCache, MessageDeletedAttachmentLog.class);
log.setImageUrl(messageFromCache.getAttachmentUrls().get(i));
log.setCounter(i + 1);
MessageToSend attachmentEmbed = templateService.renderEmbedTemplate(MESSAGE_DELETED_ATTACHMENT_TEMPLATE, log);
postTargetService.sendEmbedInPostTarget(attachmentEmbed, LoggingPostTarget.DELETE_LOG, messageFromCache.getServerId());
if(messageFromCache.getAttachmentUrls() != null){
for (int i = 0; i < messageFromCache.getAttachmentUrls().size(); i++) {
MessageDeletedAttachmentLog log = MessageDeletedAttachmentLog
.builder()
.imageUrl(messageFromCache.getAttachmentUrls().get(i))
.counter(i + 1)
.server(authorUser.getGuild())
.channel(authorUser.getChannel())
.user(authorUser.getUser())
.aUserInAServer(authorUser.getAUserInAServer())
.guild(authorMember.getGuild())
.messageChannel(authorMember.getTextChannel())
.member(authorMember.getMember())
.build();
MessageToSend attachmentEmbed = templateService.renderEmbedTemplate(MESSAGE_DELETED_ATTACHMENT_TEMPLATE, log);
postTargetService.sendEmbedInPostTarget(attachmentEmbed, LoggingPostTarget.DELETE_LOG, messageFromCache.getServerId());
}
}
}

View File

@@ -19,7 +19,7 @@ import org.springframework.transaction.annotation.Transactional;
@Slf4j
public class MessageEditedListener implements MessageTextUpdatedListener {
private static final String MESSAGE_EDITED_TEMPLATE = "message_edited";
public static final String MESSAGE_EDITED_TEMPLATE = "message_edited";
@Autowired
private TemplateService templateService;
@@ -35,13 +35,14 @@ public class MessageEditedListener implements MessageTextUpdatedListener {
return;
}
log.trace("Message {} in channel {} in guild {} was edited.", messageBefore.getMessageId(), messageBefore.getChannelId(), messageBefore.getServerId());
MessageEditedLog log = MessageEditedLog.
builder().
messageAfter(messageAfter)
MessageEditedLog log = MessageEditedLog
.builder()
.messageAfter(messageAfter)
.messageBefore(messageBefore)
.messageChannel(messageAfter.getTextChannel())
.guild(messageAfter.getGuild())
.member(messageAfter.getMember()).build();
.member(messageAfter.getMember())
.build();
MessageToSend message = templateService.renderEmbedTemplate(MESSAGE_EDITED_TEMPLATE, log);
postTargetService.sendEmbedInPostTarget(message, LoggingPostTarget.EDIT_LOG, messageBefore.getServerId());
}

View File

@@ -1,6 +1,7 @@
package dev.sheldan.abstracto.moderation.listener;
import dev.sheldan.abstracto.core.service.management.DefaultConfigManagementService;
import dev.sheldan.abstracto.moderation.config.features.WarningDecayFeature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.event.ContextRefreshedEvent;
@@ -20,6 +21,6 @@ public class ModerationDefaultConfigListener {
@EventListener
@Transactional
public void handleContextRefreshEvent(ContextRefreshedEvent ctxStartEvt) {
defaultConfigManagementService.createDefaultConfig("decayDays", decayDays);
defaultConfigManagementService.createDefaultConfig(WarningDecayFeature.DECAY_DAYS_KEY, decayDays);
}
}

View File

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

View File

@@ -5,6 +5,7 @@ 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.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;
@@ -18,8 +19,9 @@ import java.util.Optional;
@Slf4j
public class BanServiceBean implements BanService {
private static final String BAN_LOG_TEMPLATE = "ban_log";
private static final String BAN_ID_LOG_TEMPLATE = "banid_log";
public static final String BAN_LOG_TEMPLATE = "ban_log";
public static final String BAN_ID_LOG_TEMPLATE = "banId_log";
@Autowired
private BotService botService;
@@ -31,26 +33,30 @@ public class BanServiceBean implements BanService {
@Override
public void banMember(Member member, String reason, ServerContext banLog) {
this.banUser(member.getGuild().getIdLong(), member.getIdLong(), reason);
String warnLogMessage = templateService.renderTemplate(BAN_LOG_TEMPLATE, banLog);
postTargetService.sendTextInPostTarget(warnLogMessage, ModerationPostTarget.BAN_LOG, banLog.getServer().getId());
this.banUser(member.getGuild(), member.getIdLong(), reason);
MessageToSend banLogMessage = templateService.renderEmbedTemplate(BAN_LOG_TEMPLATE, banLog);
postTargetService.sendEmbedInPostTarget(banLogMessage, ModerationPostTarget.BAN_LOG, member.getGuild().getIdLong());
}
@Override
public void banMember(Long guildId, Long userId, String reason, ServerContext banIdLog) {
banUser(guildId, userId, reason);
String warnLogMessage = templateService.renderTemplate(BAN_ID_LOG_TEMPLATE, banIdLog);
postTargetService.sendTextInPostTarget(warnLogMessage, ModerationPostTarget.BAN_LOG, guildId);
MessageToSend banLogMessage = templateService.renderEmbedTemplate(BAN_ID_LOG_TEMPLATE, banIdLog);
postTargetService.sendEmbedInPostTarget(banLogMessage, ModerationPostTarget.BAN_LOG, guildId);
}
private 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);
guildByIdOptional.get().ban(userId.toString(), 0, reason).queue();
banUser(guildByIdOptional.get(), userId, reason);
} else {
log.warn("Guild {} not found. Not able to ban user {}", guildId, userId);
throw new GuildException(guildId);
}
}
private void banUser(Guild guild, Long userId, String reason) {
guild.ban(userId.toString(), 0, reason).queue();
}
}

View File

@@ -1,10 +1,9 @@
package dev.sheldan.abstracto.moderation.service;
import dev.sheldan.abstracto.core.exception.GuildException;
import dev.sheldan.abstracto.core.service.BotService;
import dev.sheldan.abstracto.core.service.PostTargetService;
import dev.sheldan.abstracto.moderation.config.posttargets.ModerationPostTarget;
import dev.sheldan.abstracto.moderation.models.template.commands.KickLogModel;
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;
@@ -12,15 +11,11 @@ import net.dv8tion.jda.api.entities.Member;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Optional;
@Component
@Slf4j
public class KickServiceBean implements KickService {
private static final String KICK_LOG_TEMPLATE = "kick_log";
@Autowired
private BotService botService;
public static final String KICK_LOG_TEMPLATE = "kick_log";
@Autowired
private TemplateService templateService;
@@ -30,19 +25,14 @@ public class KickServiceBean implements KickService {
@Override
public void kickMember(Member member, String reason, KickLogModel kickLogModel) {
Optional<Guild> guildById = botService.getGuildById(kickLogModel.getGuild().getIdLong());
log.info("Kicking user {} from guild {}", member.getUser().getIdLong(), member.getGuild().getIdLong());
if(guildById.isPresent()) {
guildById.get().kick(member, reason).queue();
this.sendKickLog(kickLogModel);
} else {
log.warn("Not able to kick. Guild {} not found.", kickLogModel.getGuild().getIdLong());
throw new GuildException(kickLogModel.getGuild().getIdLong());
}
Guild guild = member.getGuild();
log.info("Kicking user {} from guild {}", member.getUser().getIdLong(), guild.getIdLong());
guild.kick(member, reason).queue();
this.sendKickLog(kickLogModel);
}
private void sendKickLog(KickLogModel kickLogModel) {
String warnLogMessage = templateService.renderTemplate(KICK_LOG_TEMPLATE, kickLogModel);
postTargetService.sendTextInPostTarget(warnLogMessage, ModerationPostTarget.KICK_LOG, kickLogModel.getServer().getId());
MessageToSend warnLogMessage = templateService.renderEmbedTemplate(KICK_LOG_TEMPLATE, kickLogModel);
postTargetService.sendEmbedInPostTarget(warnLogMessage, ModerationPostTarget.KICK_LOG, kickLogModel.getServer().getId());
}
}

View File

@@ -1,6 +1,5 @@
package dev.sheldan.abstracto.moderation.service;
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
import dev.sheldan.abstracto.core.exception.ChannelNotFoundException;
import dev.sheldan.abstracto.core.models.AServerAChannelMessage;
import dev.sheldan.abstracto.core.models.FullUser;
@@ -23,12 +22,10 @@ import dev.sheldan.abstracto.scheduling.service.SchedulerService;
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 net.dv8tion.jda.api.entities.TextChannel;
import net.dv8tion.jda.api.entities.*;
import org.quartz.JobDataMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
@@ -37,7 +34,6 @@ import java.time.Instant;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
@@ -75,18 +71,22 @@ public class MuteServiceBean implements MuteService {
@Autowired
private MuteService self;
@Autowired
@Qualifier("unmuteScheduler")
private ScheduledExecutorService unMuteScheduler;
@Autowired
private ChannelManagementService channelManagementService;
private static final String MUTE_LOG_TEMPLATE = "mute_log";
private static final String UNMUTE_LOG_TEMPLATE = "unmute_log";
private static final String MUTE_NOTIFICATION_TEMPLATE = "mute_notification";
public static final String MUTE_LOG_TEMPLATE = "mute_log";
public static final String UNMUTE_LOG_TEMPLATE = "unmute_log";
public static final String MUTE_NOTIFICATION_TEMPLATE = "mute_notification";
@Override
public Mute muteMember(Member memberToMute, Member mutingMember, String reason, Instant unmuteDate, Message message) {
FullUser mutedUser = FullUser
.builder()
.aUserInAServer(userInServerManagementService.loadUser(memberToMute))
.aUserInAServer(userInServerManagementService.loadUser(memberToMute))
.member(memberToMute)
.build();
@@ -99,7 +99,7 @@ public class MuteServiceBean implements MuteService {
}
@Override
public Mute muteMember(AUserInAServer userBeingMuted, AUserInAServer userMuting, String reason, Instant unmuteDate, Message message) {
public Mute muteAUserInAServer(AUserInAServer userBeingMuted, AUserInAServer userMuting, String reason, Instant unmuteDate, Message message) {
FullUser mutedUser = FullUser
.builder()
.aUserInAServer(userBeingMuted)
@@ -116,20 +116,44 @@ public class MuteServiceBean implements MuteService {
@Override
public Mute muteUser(FullUser userBeingMuted, FullUser userMuting, String reason, Instant unmuteDate, Message message) {
AServer serverBeingMutedIn = userBeingMuted.getAUserInAServer().getServerReference();
if(!muteRoleManagementService.muteRoleForServerExists(serverBeingMutedIn)) {
log.error("Mute role for server {} has not been setup.", serverBeingMutedIn.getId());
throw new MuteException("Mute role for server has not been setup");
}
Member memberBeingMuted = userBeingMuted.getMember();
log.info("User {} mutes {} until {}",
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());
} else {
log.trace("This mute was not triggered by a message.");
}
if(!muteRoleManagementService.muteRoleForServerExists(userBeingMuted.getAUserInAServer().getServerReference())) {
log.error("Mute role for server {} has not been setup.", userBeingMuted.getAUserInAServer().getServerReference().getId());
throw new MuteException("Mute role for server has not been setup");
}
AUserInAServer userInServerBeingMuted = userBeingMuted.getAUserInAServer();
applyMuteRole(userInServerBeingMuted);
Mute mute = createMuteObject(userMuting, reason, unmuteDate, message, userInServerBeingMuted);
Guild guild = memberBeingMuted.getGuild();
if(memberBeingMuted.getVoiceState() != null && memberBeingMuted.getVoiceState().getChannel() != null) {
guild.kickVoiceMember(memberBeingMuted).queue();
}
sendMuteNotification(message, memberBeingMuted, mute, guild);
String triggerKey = startUnmuteJobFor(unmuteDate, mute);
mute.setTriggerKey(triggerKey);
muteManagementService.saveMute(mute);
return mute;
}
private void sendMuteNotification(Message message, Member memberBeingMuted, Mute mute, Guild guild) {
log.trace("Notifying the user about the mute.");
MuteNotification muteNotification = MuteNotification.builder().mute(mute).serverName(guild.getName()).build();
String muteNotificationMessage = templateService.renderTemplate(MUTE_NOTIFICATION_TEMPLATE, muteNotification);
MessageChannel textChannel = message != null ? message.getChannel() : null;
messageService.sendMessageToUser(memberBeingMuted.getUser(), muteNotificationMessage, textChannel);
}
private Mute createMuteObject(FullUser userMuting, String reason, Instant unmuteDate, Message message, AUserInAServer userInServerBeingMuted) {
AServerAChannelMessage origin = null;
if(message != null) {
long channelId = message.getChannel().getIdLong();
@@ -142,21 +166,7 @@ public class MuteServiceBean implements MuteService {
.messageId(message.getIdLong())
.build();
}
Mute mute = muteManagementService.createMute(userInServerBeingMuted, userMuting.getAUserInAServer(), reason, unmuteDate, origin);
Guild guild = memberBeingMuted.getGuild();
if(memberBeingMuted.getVoiceState() != null && memberBeingMuted.getVoiceState().getChannel() != null) {
guild.kickVoiceMember(memberBeingMuted).queue();
}
log.trace("Notifying the user about the mute.");
MuteNotification muteNotification = MuteNotification.builder().mute(mute).serverName(guild.getName()).build();
String muteNotificationMessage = templateService.renderTemplate(MUTE_NOTIFICATION_TEMPLATE, muteNotification);
TextChannel textChannel = message != null ? message.getTextChannel() : null;
messageService.sendMessageToUser(memberBeingMuted.getUser(), muteNotificationMessage, textChannel);
String triggerKey = startUnmuteJobFor(unmuteDate, mute);
mute.setTriggerKey(triggerKey);
muteManagementService.saveMute(mute);
return mute;
return muteManagementService.createMute(userInServerBeingMuted, userMuting.getAUserInAServer(), reason, unmuteDate, origin);
}
@Override
@@ -170,10 +180,9 @@ public class MuteServiceBean implements MuteService {
Duration muteDuration = Duration.between(Instant.now(), unmuteDate);
if(muteDuration.getSeconds() < 60) {
log.trace("Directly scheduling the unmute, because it was below the threshold.");
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
scheduler.schedule(() -> {
unMuteScheduler.schedule(() -> {
try {
self.unmuteUser(mute);
self.endMute(mute.getId());
} catch (Exception exception) {
log.error("Failed to remind immediately.", exception);
}
@@ -217,18 +226,12 @@ public class MuteServiceBean implements MuteService {
@Override
@Transactional
public void unmuteUser(Mute mute) {
AServer mutingServer = mute.getMutingServer();
Optional<Mute> updatedMuteOpt = muteManagementService.findMute(mute.getId());
Mute updatedMute = updatedMuteOpt.orElseThrow(() -> new AbstractoRunTimeException(String.format("Cannot find mute with id %s", mute.getId())));
// we do not store any reference to the instant unmutes (<=60sec), so we cannot cancel it
// but if the person gets unmuted immediately, via command, this might still execute of the instant unmute
// so we need to load the mute, and check if the mute was unmuted already, because the mute object we have at
// hand was loaded earlier, and does not reflect the true state
if(Boolean.TRUE.equals(updatedMute.getMuteEnded())) {
log.info("Mute {} has ended already, {} does not need to be unmuted anymore.", mute.getId(), mute.getMutedUser().getUserReference().getId());
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;
}
log.info("Unmuting {} in server {}", mutingServer.getId(), mute.getMutedUser().getUserReference().getId());
AServer mutingServer = mute.getMutingServer();
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());
@@ -259,7 +262,7 @@ public class MuteServiceBean implements MuteService {
}
@Override
public void completelyUnmuteUser(AUserInAServer aUserInAServer) {
public void completelyUnMuteUser(AUserInAServer aUserInAServer) {
List<Mute> allMutesOfUser = muteManagementService.getAllMutesOf(aUserInAServer);
allMutesOfUser.forEach(mute -> {
mute.setMuteEnded(true);
@@ -269,7 +272,7 @@ public class MuteServiceBean implements MuteService {
}
@Override
public void completelyUnmuteUser(Member member) {
completelyUnmuteUser(userInServerManagementService.loadUser(member));
public void completelyUnMuteMember(Member member) {
completelyUnMuteUser(userInServerManagementService.loadUser(member));
}
}

View File

@@ -12,7 +12,6 @@ import net.dv8tion.jda.api.entities.MessageHistory;
import net.dv8tion.jda.api.entities.TextChannel;
import net.dv8tion.jda.api.utils.MiscUtil;
import net.dv8tion.jda.api.utils.TimeUtil;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -37,9 +36,8 @@ public class PurgeServiceBean implements PurgeService {
return purgeMessages(amountToDelete, channel, startId, purgedMember, amountToDelete, 0, 0L);
}
@NotNull
private CompletableFuture<Void> purgeMessages(Integer amountToDelete, TextChannel channel, Long startId, Member purgedMember, Integer totalCount, Integer currentCount, Long statusMessageId) {
CompletableFuture<Void> deletionFuture = new CompletableFuture<>();
int toDeleteInThisIteration;
int messageLimit = 100;
if(amountToDelete >= messageLimit){
@@ -51,8 +49,9 @@ public class PurgeServiceBean implements PurgeService {
CompletableFuture<MessageHistory> historyFuture = channel.getHistoryBefore(startId, toDeleteInThisIteration).submit();
CompletableFuture<Long> statusMessageFuture = getOrCreatedStatusMessage(channel, totalCount, statusMessageId);
CompletableFuture<Void> coreFuture = CompletableFuture.allOf(historyFuture, statusMessageFuture);
coreFuture.thenAccept(voidParam -> {
CompletableFuture<Void> deletionFuture = new CompletableFuture<>();
CompletableFuture<Void> retrievalFuture = CompletableFuture.allOf(historyFuture, statusMessageFuture);
retrievalFuture.thenAccept(voidParam -> {
try {
List<Message> retrievedHistory = historyFuture.get().getRetrievedHistory();
List<Message> messagesToDeleteNow = filterMessagesToDelete(retrievedHistory, purgedMember);
@@ -70,7 +69,7 @@ public class PurgeServiceBean implements PurgeService {
if (messagesToDeleteNow.size() > 1) {
bulkDeleteMessages(channel, deletionFuture, messagesToDeleteNow, consumer);
} else if (messagesToDeleteNow.size() == 1) {
messagesToDeleteNow.get(0).delete().queue(consumer, deletionFuture::completeExceptionally);
latestMessage.delete().queue(consumer, deletionFuture::completeExceptionally);
}
} catch (Exception e) {
@@ -82,7 +81,7 @@ public class PurgeServiceBean implements PurgeService {
return null;
});
return CompletableFuture.allOf(coreFuture, deletionFuture);
return CompletableFuture.allOf(retrievalFuture, deletionFuture);
}
private void bulkDeleteMessages(TextChannel channel, CompletableFuture<Void> deletionFuture, List<Message> messagesToDeleteNow, Consumer<Void> consumer) {
@@ -127,8 +126,13 @@ public class PurgeServiceBean implements PurgeService {
private Consumer<Void> deletionConsumer(Integer amountToDelete, TextChannel channel, Member purgedMember, Integer totalCount, Integer currentCount, CompletableFuture<Void> deletionFuture, Long currentStatusMessageId, Message earliestMessage) {
return aVoid -> {
if (amountToDelete > 1) {
purgeMessages(amountToDelete, channel, earliestMessage.getIdLong(), purgedMember, totalCount, currentCount, currentStatusMessageId).thenAccept(aVoid1 ->
deletionFuture.complete(null)
purgeMessages(amountToDelete, channel, earliestMessage.getIdLong(), purgedMember, totalCount, currentCount, currentStatusMessageId).whenComplete((avoid, throwable) -> {
if (throwable != null) {
deletionFuture.completeExceptionally(throwable);
} else {
deletionFuture.complete(null);
}
}
);
} else {
channel.deleteMessageById(currentStatusMessageId).queueAfter(5, TimeUnit.SECONDS);

View File

@@ -29,7 +29,7 @@ public class SlowModeServiceBean implements SlowModeService {
}
@Override
public void disableSlowMOde(TextChannel channel) {
public void disableSlowMode(TextChannel channel) {
setSlowMode(channel, Duration.ZERO);
}

View File

@@ -1,10 +1,10 @@
package dev.sheldan.abstracto.moderation.service;
import dev.sheldan.abstracto.core.models.FullUser;
import dev.sheldan.abstracto.core.models.context.ServerContext;
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.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;
@@ -55,11 +55,11 @@ public class WarnServiceBean implements WarnService {
@Autowired
private ConfigService configService;
private static final String WARN_LOG_TEMPLATE = "warn_log";
private static final String WARN_NOTIFICATION_TEMPLATE = "warn_notification";
public static final String WARN_LOG_TEMPLATE = "warn_log";
public static final String WARN_NOTIFICATION_TEMPLATE = "warn_notification";
@Override
public Warning warnUser(AUserInAServer warnedAUserInAServer, AUserInAServer warningAUserInAServer, String reason, TextChannel feedbackChannel) {
public Warning warnUser(AUserInAServer warnedAUserInAServer, AUserInAServer warningAUserInAServer, String reason, MessageChannel feedbackChannel) {
FullUser warnedUser = FullUser
.builder()
.aUserInAServer(warnedAUserInAServer)
@@ -71,11 +71,11 @@ public class WarnServiceBean implements WarnService {
.aUserInAServer(warningAUserInAServer)
.member(botService.getMemberInServer(warningAUserInAServer))
.build();
return warnUser(warnedUser, warningUser, reason, feedbackChannel);
return warnFullUser(warnedUser, warningUser, reason, feedbackChannel);
}
@Override
public Warning warnUser(Member warnedMember, Member warningMember, String reason, TextChannel feedbackChannel) {
public Warning warnMember(Member warnedMember, Member warningMember, String reason, MessageChannel feedbackChannel) {
FullUser warnedUser = FullUser
.builder()
.aUserInAServer(userInServerManagementService.loadUser(warnedMember))
@@ -87,13 +87,13 @@ public class WarnServiceBean implements WarnService {
.aUserInAServer(userInServerManagementService.loadUser(warningMember))
.member(warningMember)
.build();
return warnUser(warnedUser, warningUser, reason, feedbackChannel);
return warnFullUser(warnedUser, warningUser, reason, feedbackChannel);
}
@Override
public Warning warnUser(FullUser warnedMember, FullUser warningMember, String reason, TextChannel feedbackChannel) {
public Warning warnFullUser(FullUser warnedMember, FullUser warningMember, String reason, MessageChannel feedbackChannel) {
Guild guild = warnedMember.getMember().getGuild();
log.info("User {} is warning {} in server {} because of {}", warnedMember.getMember().getId(), warningMember.getMember().getId(), guild.getIdLong(), reason);
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();
String warnNotificationMessage = templateService.renderTemplate(WARN_NOTIFICATION_TEMPLATE, warnNotification);
@@ -102,16 +102,17 @@ public class WarnServiceBean implements WarnService {
}
@Override
public void warnUserWithLog(Member warnedMember, Member warningMember, String reason, WarnLog warnLog, TextChannel feedbackChannel) {
Warning warning = warnUser(warnedMember, warningMember, reason, feedbackChannel);
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;
}
@Override
@Transactional
public void decayWarningsForServer(AServer server) {
Long days = configService.getLongValue("decayDays", server.getId());
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);
@@ -120,10 +121,13 @@ public class WarnServiceBean implements WarnService {
private void decayWarnings(List<Warning> warningsToDecay) {
Instant now = Instant.now();
warningsToDecay.forEach(warning -> {
warning.setDecayDate(now);
warning.setDecayed(true);
});
warningsToDecay.forEach(warning -> decayWarning(warning, now));
}
@Override
public void decayWarning(Warning warning, Instant now) {
warning.setDecayDate(now);
warning.setDecayed(true);
}
private void logDecayedWarnings(AServer server, List<Warning> warningsToDecay) {
@@ -156,7 +160,7 @@ public class WarnServiceBean implements WarnService {
}
}
private void sendWarnLog(ServerContext warnLogModel) {
private void sendWarnLog(WarnLog warnLogModel) {
MessageToSend message = templateService.renderEmbedTemplate(WARN_LOG_TEMPLATE, warnLogModel);
postTargetService.sendEmbedInPostTarget(message, WarningPostTarget.WARN_LOG, warnLogModel.getServer().getId());
}

View File

@@ -26,11 +26,10 @@ public class MuteManagementServiceBean implements MuteManagementService {
@Override
public Mute createMute(AUserInAServer mutedUser, AUserInAServer mutingUser, String reason, Instant unmuteDate, AServerAChannelMessage muteMessage) {
log.trace("Creating mute for user {} executed by user {} in server {}, user will be unmuted at {}",
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);
Mute mute = Mute
.builder()
.muteDate(Instant.now())
.mutedUser(mutedUser)
.mutingUser(mutingUser)
.muteTargetDate(unmuteDate)
@@ -60,6 +59,11 @@ public class MuteManagementServiceBean implements MuteManagementService {
return muteRepository.existsByMutedUserAndMuteEndedFalse(userInAServer);
}
@Override
public boolean hasActiveMute(Member member) {
return muteRepository.existsByMutedUserAndMuteEndedFalse(userInServerManagementService.loadUser(member));
}
@Override
public Mute getAMuteOf(AUserInAServer userInAServer) {
return muteRepository.findTopByMutedUserAndMuteEndedFalse(userInAServer);

View File

@@ -42,10 +42,10 @@ public class MuteRoleManagementServiceBean implements MuteRoleManagementService
@Override
public MuteRole setMuteRoleForServer(AServer server, ARole role) {
log.info("Setting muted role for server {} to role {}", server.getId(), role.getId());
MuteRole existing = retrieveMuteRoleForServer(server);
if(existing == null) {
if(!muteRoleForServerExists(server)) {
return createMuteRoleForServer(server, role);
} else {
MuteRole existing = retrieveMuteRoleForServer(server);
log.trace("Updating mute role for server {} to be role {} instead.", server.getId(), role.getId());
existing.setRole(role);
return existing;
@@ -54,6 +54,6 @@ public class MuteRoleManagementServiceBean implements MuteRoleManagementService
@Override
public boolean muteRoleForServerExists(AServer server) {
return retrieveMuteRoleForServer(server) != null;
return muteRoleRepository.existsByRoleServer(server);
}
}

View File

@@ -15,7 +15,6 @@ public class UserNoteManagementServiceBean implements UserNoteManagementService
@Autowired
private UserNoteRepository userNoteRepository;
@Override
public UserNote createUserNote(AUserInAServer aUserInAServer, String note) {
UserNote newNote = UserNote

View File

@@ -0,0 +1,32 @@
{
"author": {
"name": "${bannedUser.effectiveName}",
"avatar": "${bannedUser.user.effectiveAvatarUrl}"
},
"title": {
"title": "<#include "ban_log_title">"
},
"color" : {
"r": 200,
"g": 0,
"b": 255
},
"fields": [
{
"name": "<#include "ban_log_banned_user_field_title">",
"value": "${bannedUser.effectiveName} ${bannedUser.asMention} (${bannedUser.idLong?c})"
},
{
"name": "<#include "ban_log_banning_user_field_title">",
"value": "${banningUser.effectiveName} ${banningUser.asMention} (${banningUser.idLong?c})"
},
{
"name": "<#include "ban_log_jump_link_field_title">",
"value": "[${messageChannel.name}](${message.jumpUrl})"
},
{
"name": "<#include "ban_log_reason_field_title">",
"value": "${reason}"
}
]
}

View File

@@ -0,0 +1,28 @@
{
"title": {
"title": "<#include "ban_log_title">"
},
"color" : {
"r": 200,
"g": 0,
"b": 255
},
"fields": [
{
"name": "<#include "ban_log_banned_user_field_title">",
"value": "${bannedUserId?c}"
},
{
"name": "<#include "ban_log_banning_user_field_title">",
"value": "${banningUser.effectiveName} ${banningUser.asMention} (${banningUser.idLong?c})"
},
{
"name": "<#include "ban_log_jump_link_field_title">",
"value": "[${messageChannel.name}](${message.jumpUrl})"
},
{
"name": "<#include "ban_log_reason_field_title">",
"value": "${reason}"
}
]
}

View File

@@ -0,0 +1,32 @@
{
"author": {
"name": "${kickedUser.effectiveName}",
"avatar": "${kickedUser.user.effectiveAvatarUrl}"
},
"title": {
"title": "<#include "kick_log_title">"
},
"color" : {
"r": 200,
"g": 0,
"b": 255
},
"fields": [
{
"name": "<#include "kick_log_kicked_user_field_title">",
"value": "${kickedUser.effectiveName} ${kickedUser.asMention} (${kickedUser.idLong?c})"
},
{
"name": "<#include "kick_log_kicking_user_field_title">",
"value": "${kickingUser.effectiveName} ${kickingUser.asMention} (${kickingUser.idLong?c})"
},
{
"name": "<#include "kick_log_jump_link_field_title">",
"value": "[${messageChannel.name}](${message.jumpUrl})"
},
{
"name": "<#include "kick_log_reason_field_title">",
"value": "${reason}"
}
]
}

View File

@@ -12,11 +12,11 @@
"fields": [
{
"name": "<#include "messageDeleted_original_message_field_title">",
"value": "${message.content}"
"value": "${cachedMessage.content}"
},
{
"name": "<#include "messageDeleted_message_link_field_title">",
"value": "[${messageChannel.name}](${message.messageUrl})"
"value": "[${messageChannel.name}](${cachedMessage.messageUrl})"
}
]
}

View File

@@ -0,0 +1,87 @@
package dev.sheldan.abstracto.moderation.commands;
import dev.sheldan.abstracto.core.command.exception.IncorrectParameter;
import dev.sheldan.abstracto.core.command.exception.InsufficientParameters;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.moderation.models.template.commands.BanIdLog;
import dev.sheldan.abstracto.moderation.service.BanService;
import dev.sheldan.abstracto.templating.service.TemplateService;
import dev.sheldan.abstracto.test.command.CommandConfigValidator;
import dev.sheldan.abstracto.test.command.CommandTestUtilities;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.*;
import org.mockito.junit.MockitoJUnitRunner;
import java.util.Arrays;
import static org.mockito.Mockito.*;
@RunWith(MockitoJUnitRunner.class)
public class BanIdTest {
@InjectMocks
private BanId testUnit;
@Mock
private BanService banService;
@Mock
private TemplateService templateService;
@Captor
private ArgumentCaptor<BanIdLog> banLogModelCaptor;
private static final String REASON = "reason";
private static final Long BANNED_USER_ID = 4L;
@Test
public void testBanIdWithDefaultReason() {
CommandContext parameters = CommandTestUtilities.getWithParameters(Arrays.asList(BANNED_USER_ID));
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());
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);
}
@Test
public void testBanWithReason() {
String customReason = "reason2";
CommandContext parameters = CommandTestUtilities.getWithParameters(Arrays.asList(BANNED_USER_ID, customReason));
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());
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);
}
@Test(expected = InsufficientParameters.class)
public void testTooLittleParameters() {
CommandTestUtilities.executeNoParametersTest(testUnit);
}
@Test(expected = IncorrectParameter.class)
public void testIncorrectParameterType() {
CommandTestUtilities.executeWrongParametersTest(testUnit);
}
@Test
public void validateCommand() {
CommandConfigValidator.validateCommandConfiguration(testUnit.getConfiguration());
}
}

View File

@@ -0,0 +1,84 @@
package dev.sheldan.abstracto.moderation.commands;
import dev.sheldan.abstracto.core.command.exception.IncorrectParameter;
import dev.sheldan.abstracto.core.command.exception.InsufficientParameters;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.moderation.models.template.commands.BanLog;
import dev.sheldan.abstracto.moderation.service.BanService;
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.*;
import org.mockito.junit.MockitoJUnitRunner;
import java.util.Arrays;
import static org.mockito.Mockito.*;
@RunWith(MockitoJUnitRunner.class)
public class BanTest {
@InjectMocks
private Ban testUnit;
@Mock
private BanService banService;
@Mock
private TemplateService templateService;
@Captor
private ArgumentCaptor<BanLog> banLogModelCaptor;
private static final String REASON = "reason";
@Mock
private Member bannedMember;
@Test
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());
BanLog usedModel = banLogModelCaptor.getValue();
Assert.assertEquals(REASON, usedModel.getReason());
Assert.assertEquals(bannedMember, usedModel.getBannedUser());
Assert.assertEquals(parameters.getAuthor(), usedModel.getBanningUser());
CommandTestUtilities.checkSuccessfulCompletion(result);
}
@Test
public void testBanWithReason() {
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());
BanLog usedModel = banLogModelCaptor.getValue();
Assert.assertEquals(customReason, usedModel.getReason());
Assert.assertEquals(bannedMember, usedModel.getBannedUser());
Assert.assertEquals(parameters.getAuthor(), usedModel.getBanningUser());
CommandTestUtilities.checkSuccessfulCompletion(result);
}
@Test(expected = InsufficientParameters.class)
public void testTooLittleParameters() {
CommandTestUtilities.executeNoParametersTest(testUnit);
}
@Test(expected = IncorrectParameter.class)
public void testIncorrectParameterType() {
CommandTestUtilities.executeWrongParametersTest(testUnit);
}
@Test
public void validateCommand() {
CommandConfigValidator.validateCommandConfiguration(testUnit.getConfiguration());
}
}

View File

@@ -0,0 +1,54 @@
package dev.sheldan.abstracto.moderation.commands;
import dev.sheldan.abstracto.core.command.exception.IncorrectParameter;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.moderation.service.WarnService;
import dev.sheldan.abstracto.test.command.CommandConfigValidator;
import dev.sheldan.abstracto.test.command.CommandTestUtilities;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import java.util.Arrays;
import static org.mockito.Mockito.*;
@RunWith(MockitoJUnitRunner.class)
public class DecayAllWarningsTest {
@InjectMocks
private DecayAllWarnings testUnit;
@Mock
private WarnService warnService;
@Test
public void testDecayAllWarningsWithLog() {
executeTest(true);
}
@Test
public void testDecayAllWarningsWithoutLog() {
executeTest(false);
}
@Test
public void validateCommand() {
CommandConfigValidator.validateCommandConfiguration(testUnit.getConfiguration());
}
@Test(expected = IncorrectParameter.class)
public void testIncorrectParameterType() {
CommandTestUtilities.executeWrongParametersTest(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);
}
}

View File

@@ -0,0 +1,37 @@
package dev.sheldan.abstracto.moderation.commands;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.moderation.service.WarnService;
import dev.sheldan.abstracto.test.command.CommandConfigValidator;
import dev.sheldan.abstracto.test.command.CommandTestUtilities;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import static org.mockito.Mockito.*;
@RunWith(MockitoJUnitRunner.class)
public class DecayWarningsTest {
@InjectMocks
private DecayWarnings testUnit;
@Mock
private WarnService warnService;
@Test
public void testExecuteCommand() {
CommandContext noParameters = CommandTestUtilities.getNoParameters();
CommandResult result = testUnit.execute(noParameters);
CommandTestUtilities.checkSuccessfulCompletion(result);
verify(warnService, times(1)).decayWarningsForServer(noParameters.getUserInitiatedContext().getServer());
}
@Test
public void validateCommand() {
CommandConfigValidator.validateCommandConfiguration(testUnit.getConfiguration());
}
}

View File

@@ -0,0 +1,71 @@
package dev.sheldan.abstracto.moderation.commands;
import dev.sheldan.abstracto.core.command.exception.IncorrectParameter;
import dev.sheldan.abstracto.core.command.exception.InsufficientParameters;
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.service.management.UserNoteManagementService;
import dev.sheldan.abstracto.templating.service.TemplateService;
import dev.sheldan.abstracto.test.command.CommandConfigValidator;
import dev.sheldan.abstracto.test.command.CommandTestUtilities;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import java.util.Arrays;
import static org.mockito.Mockito.*;
@RunWith(MockitoJUnitRunner.class)
public class DeleteNoteTest {
@InjectMocks
private DeleteNote testUnit;
@Mock
private UserNoteManagementService userNoteManagementService;
@Mock
private TemplateService templateService;
private static final Long NOTE_ID = 5L;
@Test
public void testDeleteExistingNote() {
CommandContext parameters = CommandTestUtilities.getWithParameters(Arrays.asList(NOTE_ID));
when(userNoteManagementService.noteExists(NOTE_ID)).thenReturn(true);
CommandResult result = testUnit.execute(parameters);
CommandTestUtilities.checkSuccessfulCompletion(result);
verify(userNoteManagementService, times(1)).deleteNote(NOTE_ID);
}
@Test
public void testDeleteNotExistingNote() {
CommandContext parameters = CommandTestUtilities.getWithParameters(Arrays.asList(NOTE_ID));
when(userNoteManagementService.noteExists(NOTE_ID)).thenReturn(false);
when(templateService.renderSimpleTemplate(DeleteNote.NOTE_NOT_FOUND_EXCEPTION_TEMPLATE)).thenReturn("error");
CommandResult result = testUnit.execute(parameters);
Assert.assertEquals(ResultState.ERROR, result.getResult());
Assert.assertNotNull(result.getMessage());
}
@Test(expected = InsufficientParameters.class)
public void testTooLittleParameters() {
CommandTestUtilities.executeNoParametersTest(testUnit);
}
@Test(expected = IncorrectParameter.class)
public void testIncorrectParameterType() {
CommandTestUtilities.executeWrongParametersTest(testUnit);
}
@Test
public void validateCommand() {
CommandConfigValidator.validateCommandConfiguration(testUnit.getConfiguration());
}
}

View File

@@ -0,0 +1,70 @@
package dev.sheldan.abstracto.moderation.commands;
import dev.sheldan.abstracto.core.command.exception.IncorrectParameter;
import dev.sheldan.abstracto.core.command.exception.InsufficientParameters;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
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 dev.sheldan.abstracto.moderation.service.management.WarnManagementService;
import dev.sheldan.abstracto.test.MockUtils;
import dev.sheldan.abstracto.test.command.CommandConfigValidator;
import dev.sheldan.abstracto.test.command.CommandTestUtilities;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import java.util.Arrays;
import java.util.Optional;
import static org.mockito.Mockito.*;
@RunWith(MockitoJUnitRunner.class)
public class DeleteWarningTest {
@InjectMocks
private DeleteWarning testUnit;
@Mock
private WarnManagementService warnManagementService;
private static final Long WARN_ID = 5L;
@Test
public void testDeleteExistingWarning() {
AServer server = MockUtils.getServer();
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));
CommandResult result = testUnit.execute(parameters);
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);
}
@Test(expected = InsufficientParameters.class)
public void testTooLittleParameters() {
CommandTestUtilities.executeNoParametersTest(testUnit);
}
@Test(expected = IncorrectParameter.class)
public void testIncorrectParameterType() {
CommandTestUtilities.executeWrongParametersTest(testUnit);
}
@Test
public void validateCommand() {
CommandConfigValidator.validateCommandConfiguration(testUnit.getConfiguration());
}
}

View File

@@ -0,0 +1,87 @@
package dev.sheldan.abstracto.moderation.commands;
import dev.sheldan.abstracto.core.command.exception.IncorrectParameter;
import dev.sheldan.abstracto.core.command.exception.InsufficientParameters;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.moderation.models.template.commands.KickLogModel;
import dev.sheldan.abstracto.moderation.service.KickServiceBean;
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.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import java.util.Arrays;
import static org.mockito.Mockito.*;
@RunWith(MockitoJUnitRunner.class)
public class KickTest {
@InjectMocks
private Kick testUnit;
@Mock
private TemplateService templateService;
@Mock
private KickServiceBean kickService;
@Mock
private Member memberToKick;
@Captor
private ArgumentCaptor<KickLogModel> logModelArgumentCaptor;
private static final String REASON = "reason";
@Test
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());
KickLogModel usedLogModel = logModelArgumentCaptor.getValue();
Assert.assertEquals(REASON, usedLogModel.getReason());
Assert.assertEquals(memberToKick, usedLogModel.getKickedUser());
Assert.assertEquals(parameters.getAuthor(), usedLogModel.getKickingUser());
CommandTestUtilities.checkSuccessfulCompletion(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());
KickLogModel usedLogModel = logModelArgumentCaptor.getValue();
Assert.assertEquals(customReason, usedLogModel.getReason());
Assert.assertEquals(memberToKick, usedLogModel.getKickedUser());
Assert.assertEquals(parameters.getAuthor(), usedLogModel.getKickingUser());
CommandTestUtilities.checkSuccessfulCompletion(result);
}
@Test(expected = InsufficientParameters.class)
public void testTooLittleParameters() {
CommandTestUtilities.executeNoParametersTest(testUnit);
}
@Test(expected = IncorrectParameter.class)
public void testIncorrectParameterType() {
CommandTestUtilities.executeWrongParametersTest(testUnit);
}
@Test
public void validateCommand() {
CommandConfigValidator.validateCommandConfiguration(testUnit.getConfiguration());
}
}

View File

@@ -0,0 +1,64 @@
package dev.sheldan.abstracto.moderation.commands;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.core.service.FeatureFlagService;
import dev.sheldan.abstracto.moderation.config.features.WarningDecayFeature;
import dev.sheldan.abstracto.moderation.models.template.commands.MyWarningsModel;
import dev.sheldan.abstracto.moderation.service.management.WarnManagementService;
import dev.sheldan.abstracto.test.command.CommandConfigValidator;
import dev.sheldan.abstracto.test.command.CommandTestUtilities;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import static org.mockito.Mockito.*;
@RunWith(MockitoJUnitRunner.class)
public class MyWarningsTest {
@InjectMocks
private MyWarnings testUnit;
@Mock
private ChannelService channelService;
@Mock
private WarnManagementService warnManagementService;
@Mock
private FeatureFlagService featureFlagService;
@Mock
private WarningDecayFeature warningDecayFeature;
@Captor
private ArgumentCaptor<MyWarningsModel> argumentCaptor;
@Test
public void testExecuteMyWarningsCommand() {
CommandContext noParameter = CommandTestUtilities.getNoParameters();
Long activeWarnCount = 8L;
when(warnManagementService.getActiveWarnsForUser(noParameter.getUserInitiatedContext().getAUserInAServer())).thenReturn(activeWarnCount);
Long totalWarnCount = 10L;
when(warnManagementService.getTotalWarnsForUser(noParameter.getUserInitiatedContext().getAUserInAServer())).thenReturn(totalWarnCount);
CommandResult result = testUnit.execute(noParameter);
verify(channelService, times(1)).sendEmbedTemplateInChannel(eq(MyWarnings.MY_WARNINGS_RESPONSE_EMBED_TEMPLATE), argumentCaptor.capture(), eq(noParameter.getChannel()));
CommandTestUtilities.checkSuccessfulCompletion(result);
MyWarningsModel usedModel = argumentCaptor.getValue();
Assert.assertEquals(activeWarnCount, usedModel.getCurrentWarnCount());
Assert.assertEquals(totalWarnCount, usedModel.getTotalWarnCount());
}
@Test
public void validateCommand() {
CommandConfigValidator.validateCommandConfiguration(testUnit.getConfiguration());
}
}

View File

@@ -0,0 +1,91 @@
package dev.sheldan.abstracto.moderation.commands;
import dev.sheldan.abstracto.core.command.exception.IncorrectParameter;
import dev.sheldan.abstracto.core.command.exception.InsufficientParameters;
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;
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;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;
import java.util.Arrays;
import java.util.concurrent.CompletableFuture;
import static org.mockito.Mockito.*;
@RunWith(MockitoJUnitRunner.class)
public class PurgeTest {
@InjectMocks
private Purge testUnit;
@Mock
private PurgeService purgeService;
@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());
}
@Test
public void testExecutePurgeOfMemberCommand() {
Member messageAuthor = Mockito.mock(Member.class);
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());
}
@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 = InsufficientParameters.class)
public void testTooLittleParameters() {
CommandTestUtilities.executeNoParametersTest(testUnit);
}
@Test(expected = IncorrectParameter.class)
public void testIncorrectParameterType() {
CommandTestUtilities.executeWrongParametersTest(testUnit);
}
@Test
public void validateCommand() {
CommandConfigValidator.validateCommandConfiguration(testUnit.getConfiguration());
}
}

View File

@@ -0,0 +1,85 @@
package dev.sheldan.abstracto.moderation.commands;
import dev.sheldan.abstracto.core.command.exception.IncorrectParameter;
import dev.sheldan.abstracto.core.command.exception.InsufficientParameters;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.moderation.service.SlowModeService;
import dev.sheldan.abstracto.test.command.CommandConfigValidator;
import dev.sheldan.abstracto.test.command.CommandTestUtilities;
import net.dv8tion.jda.api.entities.TextChannel;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;
import java.time.Duration;
import java.util.Arrays;
import static org.mockito.Mockito.*;
@RunWith(MockitoJUnitRunner.class)
public class SlowModeTest {
@InjectMocks
private SlowMode testUnit;
@Mock
private SlowModeService slowModeService;
@Test
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);
}
@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);
}
@Test
public void testDisableSlowModeOtherChannel() {
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);
}
@Test
public void testExecuteSlowModeWithDurationOtherChannel() {
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);
}
@Test(expected = InsufficientParameters.class)
public void testTooLittleParameters() {
CommandTestUtilities.executeNoParametersTest(testUnit);
}
@Test(expected = IncorrectParameter.class)
public void testIncorrectParameterType() {
CommandTestUtilities.executeWrongParametersTest(testUnit);
}
@Test
public void validateCommand() {
CommandConfigValidator.validateCommandConfiguration(testUnit.getConfiguration());
}
}

View File

@@ -0,0 +1,60 @@
package dev.sheldan.abstracto.moderation.commands;
import dev.sheldan.abstracto.core.command.exception.IncorrectParameter;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.moderation.service.management.UserNoteManagementService;
import dev.sheldan.abstracto.test.MockUtils;
import dev.sheldan.abstracto.test.command.CommandConfigValidator;
import dev.sheldan.abstracto.test.command.CommandTestUtilities;
import net.dv8tion.jda.api.entities.Member;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;
import java.util.Arrays;
import static org.mockito.Mockito.*;
@RunWith(MockitoJUnitRunner.class)
public class UserNoteCommandTest {
@InjectMocks
private UserNoteCommand testUnit;
@Mock
private UserNoteManagementService userNoteManagementService;
@Mock
private UserInServerManagementService userInServerManagementService;
@Test
public void testExecuteUserNoteCommand() {
Member member = Mockito.mock(Member.class);
AServer server = MockUtils.getServer();
AUserInAServer userInAServer = MockUtils.getUserObject(4L, server);
String note = "note";
CommandContext parameters = CommandTestUtilities.getWithParameters(Arrays.asList(member, note));
when(userInServerManagementService.loadUser(member)).thenReturn(userInAServer);
CommandResult result = testUnit.execute(parameters);
verify(userNoteManagementService, times(1)).createUserNote(userInAServer, note);
CommandTestUtilities.checkSuccessfulCompletion(result);
}
@Test(expected = IncorrectParameter.class)
public void testIncorrectParameterType() {
CommandTestUtilities.executeWrongParametersTest(testUnit);
}
@Test
public void validateCommand() {
CommandConfigValidator.validateCommandConfiguration(testUnit.getConfiguration());
}
}

View File

@@ -0,0 +1,116 @@
package dev.sheldan.abstracto.moderation.commands;
import dev.sheldan.abstracto.core.command.exception.IncorrectParameter;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
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.moderation.converter.UserNotesConverter;
import dev.sheldan.abstracto.moderation.models.database.UserNote;
import dev.sheldan.abstracto.moderation.models.template.commands.ListNotesModel;
import dev.sheldan.abstracto.moderation.models.template.commands.NoteEntryModel;
import dev.sheldan.abstracto.moderation.service.management.UserNoteManagementService;
import dev.sheldan.abstracto.templating.service.TemplateService;
import dev.sheldan.abstracto.test.MockUtils;
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.*;
import org.mockito.junit.MockitoJUnitRunner;
import java.util.Arrays;
import java.util.List;
import static org.mockito.Mockito.*;
@RunWith(MockitoJUnitRunner.class)
public class UserNotesTest {
@InjectMocks
private UserNotes testUnit;
@Mock
private UserNoteManagementService userNoteManagementService;
@Mock
private TemplateService templateService;
@Mock
private UserInServerManagementService userInServerManagementService;
@Mock
private ChannelService channelService;
@Mock
private UserNotesConverter userNotesConverter;
@Captor
private ArgumentCaptor<ListNotesModel> captor;
@Test
public void testExecuteUserNotesCommandForMember() {
Member member = Mockito.mock(Member.class);
CommandContext parameters = CommandTestUtilities.getWithParameters(Arrays.asList(member));
AUserInAServer userNoteUser = MockUtils.getUserObject(4L, parameters.getUserInitiatedContext().getServer());
when(userInServerManagementService.loadUser(member)).thenReturn(userNoteUser);
UserNote firstNote = UserNote.builder().build();
UserNote secondNote = UserNote.builder().build();
List<UserNote> userNotes = Arrays.asList(firstNote, secondNote);
when(userNoteManagementService.loadNotesForUser(userNoteUser)).thenReturn(userNotes);
NoteEntryModel firstConvertedNote = NoteEntryModel.builder().build();
NoteEntryModel secondConvertedNote = NoteEntryModel.builder().build();
List<NoteEntryModel> convertedNotes = Arrays.asList(firstConvertedNote, secondConvertedNote);
when(userNotesConverter.fromNotes(userNotes)).thenReturn(convertedNotes);
CommandResult result = testUnit.execute(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());
for (int i = 0; i < usedModel.getUserNotes().size(); i++) {
NoteEntryModel usedEntry = usedModel.getUserNotes().get(i);
NoteEntryModel expectedEntry = convertedNotes.get(i);
Assert.assertEquals(expectedEntry, usedEntry);
}
Assert.assertEquals(userNoteUser, usedModel.getSpecifiedUser().getAUserInAServer());
Assert.assertEquals(member, usedModel.getSpecifiedUser().getMember());
CommandTestUtilities.checkSuccessfulCompletion(result);
}
@Test
public void testExecuteUserNotesCommandForServer() {
CommandContext parameters = CommandTestUtilities.getNoParameters();
UserNote firstNote = UserNote.builder().build();
UserNote secondNote = UserNote.builder().build();
List<UserNote> userNotes = Arrays.asList(firstNote, secondNote);
when(userNoteManagementService.loadNotesForServer(parameters.getUserInitiatedContext().getServer())).thenReturn(userNotes);
NoteEntryModel firstConvertedNote = NoteEntryModel.builder().build();
NoteEntryModel secondConvertedNote = NoteEntryModel.builder().build();
List<NoteEntryModel> convertedNotes = Arrays.asList(firstConvertedNote, secondConvertedNote);
when(userNotesConverter.fromNotes(userNotes)).thenReturn(convertedNotes);
CommandResult result = testUnit.execute(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());
for (int i = 0; i < usedModel.getUserNotes().size(); i++) {
NoteEntryModel usedEntry = usedModel.getUserNotes().get(i);
NoteEntryModel expectedEntry = convertedNotes.get(i);
Assert.assertEquals(expectedEntry, usedEntry);
}
Assert.assertNull(usedModel.getSpecifiedUser());
CommandTestUtilities.checkSuccessfulCompletion(result);
}
@Test(expected = IncorrectParameter.class)
public void testIncorrectParameterType() {
CommandTestUtilities.executeWrongParametersTest(testUnit);
}
@Test
public void validateCommand() {
CommandConfigValidator.validateCommandConfiguration(testUnit.getConfiguration());
}
}

View File

@@ -0,0 +1,83 @@
package dev.sheldan.abstracto.moderation.commands;
import dev.sheldan.abstracto.core.command.exception.IncorrectParameter;
import dev.sheldan.abstracto.core.command.exception.InsufficientParameters;
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.service.WarnService;
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.*;
import org.mockito.junit.MockitoJUnitRunner;
import java.util.Arrays;
import static org.mockito.Mockito.*;
@RunWith(MockitoJUnitRunner.class)
public class WarnTest {
@InjectMocks
private Warn testUnit;
@Mock
private WarnService warnService;
@Mock
private TemplateService templateService;
private static final String DEFAULT_REASON = "defaultReason";
@Captor
private ArgumentCaptor<WarnLog> parameterCaptor;
@Test
public void testExecuteWarnCommandWithReason() {
Member warnedMember = Mockito.mock(Member.class);
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();
Assert.assertEquals(reason, value.getReason());
Assert.assertEquals(warnedMember, value.getWarnedUser());
Assert.assertEquals(parameters.getAuthor(), value.getWarningUser());
CommandTestUtilities.checkSuccessfulCompletion(result);
}
@Test
public void testExecuteWarnCommandWithDefaultReason() {
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();
Assert.assertEquals(DEFAULT_REASON, value.getReason());
Assert.assertEquals(warnedMember, value.getWarnedUser());
Assert.assertEquals(parameters.getAuthor(), value.getWarningUser());
CommandTestUtilities.checkSuccessfulCompletion(result);
}
@Test(expected = InsufficientParameters.class)
public void testTooLittleParameters() {
CommandTestUtilities.executeNoParametersTest(testUnit);
}
@Test(expected = IncorrectParameter.class)
public void testIncorrectParameterType() {
CommandTestUtilities.executeWrongParametersTest(testUnit);
}
@Test
public void validateCommand() {
CommandConfigValidator.validateCommandConfiguration(testUnit.getConfiguration());
}
}

View File

@@ -0,0 +1,109 @@
package dev.sheldan.abstracto.moderation.commands;
import com.jagrosh.jdautilities.commons.waiter.EventWaiter;
import com.jagrosh.jdautilities.menu.Paginator;
import dev.sheldan.abstracto.core.command.exception.IncorrectParameter;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.service.PaginatorService;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.moderation.converter.WarnEntryConverter;
import dev.sheldan.abstracto.moderation.models.database.Warning;
import dev.sheldan.abstracto.moderation.models.template.commands.WarnEntry;
import dev.sheldan.abstracto.moderation.models.template.commands.WarningsModel;
import dev.sheldan.abstracto.moderation.service.management.WarnManagementService;
import dev.sheldan.abstracto.test.MockUtils;
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.*;
import org.mockito.junit.MockitoJUnitRunner;
import java.util.Arrays;
import java.util.List;
import static org.mockito.Mockito.*;
@RunWith(MockitoJUnitRunner.class)
public class WarningsTest {
@InjectMocks
private Warnings testUnit;
@Mock
private WarnManagementService warnManagementService;
@Mock
private UserInServerManagementService userInServerManagementService;
@Mock
private WarnEntryConverter warnEntryConverter;
@Mock
private PaginatorService paginatorService;
@Mock
private EventWaiter eventWaiter;
@Captor
private ArgumentCaptor<WarningsModel> captor;
@Test
public void testNoParametersForWarningsCommand(){
CommandContext noParams = CommandTestUtilities.getNoParameters();
Warning firstWarning = Warning.builder().build();
WarnEntry firstModelWarning = WarnEntry.builder().build();
Warning secondWarning = Warning.builder().build();
WarnEntry secondModelWarning = WarnEntry.builder().build();
List<Warning> warningsToDisplay = Arrays.asList(firstWarning, secondWarning);
List<WarnEntry> modelWarnings = Arrays.asList(firstModelWarning, secondModelWarning);
when(warnManagementService.getAllWarningsOfServer(noParams.getUserInitiatedContext().getServer())).thenReturn(warningsToDisplay);
when(warnEntryConverter.fromWarnings(warningsToDisplay)).thenReturn(modelWarnings);
Paginator paginator = Mockito.mock(Paginator.class);
when(paginatorService.createPaginatorFromTemplate(eq(Warnings.WARNINGS_RESPONSE_TEMPLATE), captor.capture(), eq(eventWaiter))).thenReturn(paginator);
CommandResult result = testUnit.execute(noParams);
CommandTestUtilities.checkSuccessfulCompletion(result);
WarningsModel warningsModel = captor.getValue();
Assert.assertEquals(warningsToDisplay.size(), warningsModel.getWarnings().size());
Assert.assertEquals(firstModelWarning, warningsModel.getWarnings().get(0));
Assert.assertEquals(secondModelWarning, warningsModel.getWarnings().get(1));
}
@Test
public void testExecuteWarningsForMember(){
Member member = Mockito.mock(Member.class);
CommandContext parameters = CommandTestUtilities.getWithParameters(Arrays.asList(member));
AUserInAServer warnedUser = MockUtils.getUserObject(5L, parameters.getUserInitiatedContext().getServer());
when(userInServerManagementService.loadUser(member)).thenReturn(warnedUser);
Warning firstWarning = Warning.builder().build();
WarnEntry firstModelWarning = WarnEntry.builder().build();
Warning secondWarning = Warning.builder().build();
WarnEntry secondModelWarning = WarnEntry.builder().build();
List<Warning> warningsToDisplay = Arrays.asList(firstWarning, secondWarning);
when(warnManagementService.getAllWarnsForUser(warnedUser)).thenReturn(warningsToDisplay);
List<WarnEntry> modelWarnings = Arrays.asList(firstModelWarning, secondModelWarning);
when(warnEntryConverter.fromWarnings(warningsToDisplay)).thenReturn(modelWarnings);
Paginator paginator = Mockito.mock(Paginator.class);
when(paginatorService.createPaginatorFromTemplate(eq(Warnings.WARNINGS_RESPONSE_TEMPLATE), captor.capture(), eq(eventWaiter))).thenReturn(paginator);
CommandResult result = testUnit.execute(parameters);
CommandTestUtilities.checkSuccessfulCompletion(result);
WarningsModel warningsModel = captor.getValue();
Assert.assertEquals(warningsToDisplay.size(), warningsModel.getWarnings().size());
Assert.assertEquals(firstModelWarning, warningsModel.getWarnings().get(0));
Assert.assertEquals(secondModelWarning, warningsModel.getWarnings().get(1));
}
@Test(expected = IncorrectParameter.class)
public void testIncorrectParameterType() {
CommandTestUtilities.executeWrongParametersTest(testUnit);
}
@Test
public void validateCommand() {
CommandConfigValidator.validateCommandConfiguration(testUnit.getConfiguration());
}
}

View File

@@ -0,0 +1,64 @@
package dev.sheldan.abstracto.moderation.commands.mute;
import dev.sheldan.abstracto.core.command.exception.IncorrectParameter;
import dev.sheldan.abstracto.core.command.exception.InsufficientParameters;
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.service.MuteService;
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.*;
import org.mockito.junit.MockitoJUnitRunner;
import java.time.Duration;
import java.time.Instant;
import java.util.Arrays;
import static org.mockito.Mockito.*;
@RunWith(MockitoJUnitRunner.class)
public class MuteTest {
@InjectMocks
private Mute testUnit;
@Mock
private MuteService muteService;
@Captor
private ArgumentCaptor<MuteLog> muteLogArgumentCaptor;
@Test
public void testMuteMember() {
Member mutedMember = Mockito.mock(Member.class);
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();
Assert.assertEquals(mutedMember, muteLog.getMutedUser());
Assert.assertEquals(parameters.getAuthor(), muteLog.getMutingUser());
}
@Test(expected = InsufficientParameters.class)
public void testTooLittleParameters() {
CommandTestUtilities.executeNoParametersTest(testUnit);
}
@Test(expected = IncorrectParameter.class)
public void testIncorrectParameterType() {
CommandTestUtilities.executeWrongParametersTest(testUnit);
}
@Test
public void validateCommand() {
CommandConfigValidator.validateCommandConfiguration(testUnit.getConfiguration());
}
}

View File

@@ -0,0 +1,53 @@
package dev.sheldan.abstracto.moderation.commands.mute;
import dev.sheldan.abstracto.core.command.exception.IncorrectParameter;
import dev.sheldan.abstracto.core.command.exception.InsufficientParameters;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.models.database.ARole;
import dev.sheldan.abstracto.moderation.service.management.MuteRoleManagementService;
import dev.sheldan.abstracto.test.command.CommandConfigValidator;
import dev.sheldan.abstracto.test.command.CommandTestUtilities;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import java.util.Arrays;
import static org.mockito.Mockito.*;
@RunWith(MockitoJUnitRunner.class)
public class SetMuteRoleTest {
@InjectMocks
private SetMuteRole testUnit;
@Mock
private MuteRoleManagementService muteRoleManagementService;
@Test
public void testExecuteCommand() {
ARole muteRoleToSet = ARole.builder().build();
CommandContext parameters = CommandTestUtilities.getWithParameters(Arrays.asList(muteRoleToSet));
CommandResult result = testUnit.execute(parameters);
verify(muteRoleManagementService, times(1)).setMuteRoleForServer(parameters.getUserInitiatedContext().getServer(), muteRoleToSet);
CommandTestUtilities.checkSuccessfulCompletion(result);
}
@Test(expected = InsufficientParameters.class)
public void testTooLittleParameters() {
CommandTestUtilities.executeNoParametersTest(testUnit);
}
@Test(expected = IncorrectParameter.class)
public void testIncorrectParameterType() {
CommandTestUtilities.executeWrongParametersTest(testUnit);
}
@Test
public void validateCommand() {
CommandConfigValidator.validateCommandConfiguration(testUnit.getConfiguration());
}
}

View File

@@ -0,0 +1,83 @@
package dev.sheldan.abstracto.moderation.commands.mute;
import dev.sheldan.abstracto.core.command.exception.IncorrectParameter;
import dev.sheldan.abstracto.core.command.exception.InsufficientParameters;
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.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;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import java.util.Arrays;
import static org.mockito.Mockito.*;
@RunWith(MockitoJUnitRunner.class)
public class UnMuteTest {
@InjectMocks
private UnMute testUnit;
@Mock
private MuteService muteService;
@Mock
private MuteManagementService muteManagementService;
@Mock
private TemplateService templateService;
@Mock
private Member memberToUnMute;
@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);
}
@Test
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());
}
@Test(expected = InsufficientParameters.class)
public void testTooLittleParameters() {
CommandTestUtilities.executeNoParametersTest(testUnit);
}
@Test(expected = IncorrectParameter.class)
public void testIncorrectParameterType() {
CommandTestUtilities.executeWrongParametersTest(testUnit);
}
@Test
public void validateCommand() {
CommandConfigValidator.validateCommandConfiguration(testUnit.getConfiguration());
}
}

View File

@@ -0,0 +1,61 @@
package dev.sheldan.abstracto.moderation.converter;
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.management.UserInServerManagementService;
import dev.sheldan.abstracto.moderation.models.database.UserNote;
import dev.sheldan.abstracto.moderation.models.template.commands.NoteEntryModel;
import dev.sheldan.abstracto.test.MockUtils;
import net.dv8tion.jda.api.entities.Member;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import static org.mockito.Mockito.*;
@RunWith(MockitoJUnitRunner.class)
public class UserNotesConverterTest {
@InjectMocks
private UserNotesConverter testUnit;
@Mock
private UserInServerManagementService userInServerManagementService;
@Mock
private BotService botService;
@Test
public void testWithEmptyList() {
List<NoteEntryModel> entryModels = testUnit.fromNotes(Collections.emptyList());
Assert.assertEquals(0, entryModels.size());
}
@Test
public void testWithSomeUserNotes() {
AServer server = MockUtils.getServer();
AUserInAServer userInAServer = MockUtils.getUserObject(4L, server);
Member member = Mockito.mock(Member.class);
when(botService.getMemberInServer(userInAServer)).thenReturn(member);
UserNote firstNote = UserNote.builder().user(userInAServer).build();
UserNote secondNote = UserNote.builder().user(userInAServer).build();
List<NoteEntryModel> entryModels = testUnit.fromNotes(Arrays.asList(firstNote, secondNote));
Assert.assertEquals(2, entryModels.size());
NoteEntryModel firstEntry = entryModels.get(0);
Assert.assertEquals(member, firstEntry.getFullUser().getMember());
Assert.assertEquals(userInAServer, firstEntry.getFullUser().getAUserInAServer());
NoteEntryModel secondEntry = entryModels.get(1);
Assert.assertEquals(member, secondEntry.getFullUser().getMember());
Assert.assertEquals(userInAServer, secondEntry.getFullUser().getAUserInAServer());
}
}

View File

@@ -0,0 +1,63 @@
package dev.sheldan.abstracto.moderation.converter;
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.moderation.models.database.Warning;
import dev.sheldan.abstracto.moderation.models.template.commands.WarnEntry;
import dev.sheldan.abstracto.test.MockUtils;
import net.dv8tion.jda.api.entities.Member;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import static org.mockito.Mockito.*;
@RunWith(MockitoJUnitRunner.class)
public class WarnEntryConverterTest {
@InjectMocks
private WarnEntryConverter testUnit;
@Mock
private BotService botService;
@Test
public void testWithEmptyList() {
List<WarnEntry> entryModels = testUnit.fromWarnings(Collections.emptyList());
Assert.assertEquals(0, entryModels.size());
}
@Test
public void testWithSomeUserNotes() {
AServer server = MockUtils.getServer();
AUserInAServer warnedUserInAServer = MockUtils.getUserObject(4L, server);
AUserInAServer warningUserInAServer = MockUtils.getUserObject(6L, server);
Member warnedMember = Mockito.mock(Member.class);
Member warningMember = Mockito.mock(Member.class);
when(botService.getMemberInServer(warnedUserInAServer)).thenReturn(warnedMember);
when(botService.getMemberInServer(warningUserInAServer)).thenReturn(warningMember);
Warning firstNote = Warning.builder().warnedUser(warnedUserInAServer).warningUser(warningUserInAServer).build();
Warning secondNote = Warning.builder().warnedUser(warnedUserInAServer).warningUser(warningUserInAServer).build();
List<WarnEntry> entryModels = testUnit.fromWarnings(Arrays.asList(firstNote, secondNote));
Assert.assertEquals(2, entryModels.size());
WarnEntry firstEntry = entryModels.get(0);
Assert.assertEquals(warningMember, firstEntry.getWarningUser().getMember());
Assert.assertEquals(warnedMember, firstEntry.getWarnedUser().getMember());
Assert.assertEquals(warningUserInAServer, firstEntry.getWarningUser().getAUserInAServer());
Assert.assertEquals(warnedUserInAServer, firstEntry.getWarnedUser().getAUserInAServer());
WarnEntry secondEntry = entryModels.get(1);
Assert.assertEquals(warningMember, secondEntry.getWarningUser().getMember());
Assert.assertEquals(warnedMember, secondEntry.getWarnedUser().getMember());
Assert.assertEquals(warningUserInAServer, secondEntry.getWarningUser().getAUserInAServer());
Assert.assertEquals(warnedUserInAServer, secondEntry.getWarnedUser().getAUserInAServer());
}
}

View File

@@ -0,0 +1,100 @@
package dev.sheldan.abstracto.moderation.job;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.service.FeatureFlagService;
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
import dev.sheldan.abstracto.moderation.config.features.WarningDecayFeature;
import dev.sheldan.abstracto.moderation.service.WarnService;
import dev.sheldan.abstracto.test.MockUtils;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import org.quartz.JobExecutionException;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import static org.mockito.Mockito.*;
@RunWith(MockitoJUnitRunner.class)
public class WarnDecayJobTest {
@InjectMocks
private WarnDecayJob testUnit;
@Mock
private ServerManagementService serverManagementService;
@Mock
private FeatureFlagService featureFlagService;
@Mock
private WarningDecayFeature warningDecayFeature;
@Mock
private WarnService warnService;
private AServer firstServer;
private AServer secondServer;
@Before
public void setup() {
this.firstServer = MockUtils.getServer(1L);
this.secondServer = MockUtils.getServer(2L);
}
@Test
public void executeJobForNoServers() throws JobExecutionException {
when(serverManagementService.getAllServers()).thenReturn(Collections.emptyList());
testUnit.executeInternal(null);
verify(featureFlagService, times(0)).isFeatureEnabled(eq(warningDecayFeature), any(AServer.class));
verify(warnService, times(0)).decayWarningsForServer(any(AServer.class));
}
@Test
public void executeJobForAEnabledServer() throws JobExecutionException {
when(serverManagementService.getAllServers()).thenReturn(Arrays.asList(firstServer));
when(featureFlagService.isFeatureEnabled(warningDecayFeature, firstServer)).thenReturn(true);
testUnit.executeInternal(null);
verify(warnService, times(1)).decayWarningsForServer(eq(firstServer));
}
@Test
public void executeJobForADisabledServer() throws JobExecutionException {
when(serverManagementService.getAllServers()).thenReturn(Arrays.asList(firstServer));
when(featureFlagService.isFeatureEnabled(warningDecayFeature, firstServer)).thenReturn(false);
testUnit.executeInternal(null);
verify(warnService, times(0)).decayWarningsForServer(eq(firstServer));
}
@Test
public void executeJobForMixedServers() throws JobExecutionException {
when(serverManagementService.getAllServers()).thenReturn(Arrays.asList(firstServer, secondServer));
when(featureFlagService.isFeatureEnabled(warningDecayFeature, firstServer)).thenReturn(true);
when(featureFlagService.isFeatureEnabled(warningDecayFeature, secondServer)).thenReturn(false);
testUnit.executeInternal(null);
verify(warnService, times(1)).decayWarningsForServer(eq(firstServer));
}
@Test
public void executeJobForMultipleEnabledServers() throws JobExecutionException {
when(serverManagementService.getAllServers()).thenReturn(Arrays.asList(firstServer, secondServer));
when(featureFlagService.isFeatureEnabled(warningDecayFeature, firstServer)).thenReturn(true);
when(featureFlagService.isFeatureEnabled(warningDecayFeature, secondServer)).thenReturn(true);
testUnit.executeInternal(null);
ArgumentCaptor<AServer> serverCaptor = ArgumentCaptor.forClass(AServer.class);
verify(warnService, times(2)).decayWarningsForServer(serverCaptor.capture());
List<AServer> capturedServers = serverCaptor.getAllValues();
Assert.assertEquals(2, capturedServers.size());
Assert.assertEquals(firstServer, capturedServers.get(0));
Assert.assertEquals(secondServer, capturedServers.get(1));
}
}

View File

@@ -0,0 +1,45 @@
package dev.sheldan.abstracto.moderation.listener;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.service.PostTargetService;
import dev.sheldan.abstracto.moderation.config.posttargets.LoggingPostTarget;
import dev.sheldan.abstracto.templating.service.TemplateService;
import dev.sheldan.abstracto.test.MockUtils;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Member;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;
import static org.mockito.Mockito.*;
@RunWith(MockitoJUnitRunner.class)
public class JoinLoggerTest {
@InjectMocks
private JoinLogger testUnit;
@Mock
private TemplateService templateService;
@Mock
private PostTargetService postTargetService;
@Test
public void executeListener() {
Member joiningMember = Mockito.mock(Member.class);
Guild guild = Mockito.mock(Guild.class);
Long guildId = 6L;
when(guild.getIdLong()).thenReturn(guildId);
AServer server = MockUtils.getServer();
AUserInAServer aUserInAServer = MockUtils.getUserObject(5L, server);
String message = "text";
when(templateService.renderTemplateWithMap(eq(JoinLogger.USER_JOIN_TEMPLATE), any())).thenReturn(message);
testUnit.execute(joiningMember, guild, aUserInAServer);
verify(postTargetService, times(1)).sendTextInPostTarget(message, LoggingPostTarget.JOIN_LOG, guildId);
}
}

View File

@@ -0,0 +1,50 @@
package dev.sheldan.abstracto.moderation.listener;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.moderation.service.MuteService;
import dev.sheldan.abstracto.moderation.service.management.MuteManagementService;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Member;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import static org.mockito.Mockito.*;
@RunWith(MockitoJUnitRunner.class)
public class JoinMuteListenerTest {
@InjectMocks
private JoinMuteListener testUnit;
@Mock
private MuteManagementService muteManagementService;
@Mock
private MuteService muteService;
@Mock
private Member member;
@Mock
private Guild guild;
@Mock
private AUserInAServer joiningUser;
@Test
public void testNonMutedUserJoins() {
when(muteManagementService.hasActiveMute(joiningUser)).thenReturn(false);
testUnit.execute(member, guild, joiningUser);
verify(muteService, times(0)).applyMuteRole(joiningUser);
}
@Test
public void testMutedUserJoins() {
when(muteManagementService.hasActiveMute(joiningUser)).thenReturn(true);
testUnit.execute(member, guild, joiningUser);
verify(muteService, times(1)).applyMuteRole(joiningUser);
}
}

View File

@@ -0,0 +1,44 @@
package dev.sheldan.abstracto.moderation.listener;
import dev.sheldan.abstracto.core.service.PostTargetService;
import dev.sheldan.abstracto.moderation.config.posttargets.LoggingPostTarget;
import dev.sheldan.abstracto.templating.service.TemplateService;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.User;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;
import static org.mockito.Mockito.*;
@RunWith(MockitoJUnitRunner.class)
public class LeaveLoggerTest {
@InjectMocks
private LeaveLogger testUnit;
@Mock
private TemplateService templateService;
@Mock
private PostTargetService postTargetService;
@Test
public void executeListener() {
Member leavingMember = Mockito.mock(Member.class);
Guild guild = Mockito.mock(Guild.class);
User user = Mockito.mock(User.class);
when(leavingMember.getUser()).thenReturn(user);
Long guildId = 6L;
when(guild.getIdLong()).thenReturn(guildId);
String message = "text";
when(templateService.renderTemplateWithMap(eq(LeaveLogger.USER_LEAVE_TEMPLATE), any())).thenReturn(message);
testUnit.execute(leavingMember, guild);
verify(postTargetService, times(1)).sendTextInPostTarget(message, LoggingPostTarget.LEAVE_LOG, guildId);
}
}

View File

@@ -0,0 +1,150 @@
package dev.sheldan.abstracto.moderation.listener;
import dev.sheldan.abstracto.core.models.AServerAChannelAUser;
import dev.sheldan.abstracto.core.models.GuildChannelMember;
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
import dev.sheldan.abstracto.core.models.database.AChannel;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.service.PostTargetService;
import dev.sheldan.abstracto.core.utils.ContextUtils;
import dev.sheldan.abstracto.moderation.config.posttargets.LoggingPostTarget;
import dev.sheldan.abstracto.moderation.models.template.listener.MessageDeletedAttachmentLog;
import dev.sheldan.abstracto.moderation.models.template.listener.MessageDeletedLog;
import dev.sheldan.abstracto.templating.model.MessageToSend;
import dev.sheldan.abstracto.templating.service.TemplateService;
import dev.sheldan.abstracto.test.MockUtils;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.TextChannel;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.*;
import org.mockito.junit.MockitoJUnitRunner;
import java.util.Arrays;
import java.util.List;
import static org.mockito.Mockito.*;
@RunWith(MockitoJUnitRunner.class)
public class MessageDeleteLogListenerTest {
@InjectMocks
private MessageDeleteLogListener testUnit;
@Mock
private ContextUtils contextUtils;
@Mock
private TemplateService templateService;
@Mock
private PostTargetService postTargetService;
private AServerAChannelAUser authorUser;
private GuildChannelMember authorMember;
@Captor
private ArgumentCaptor<MessageDeletedLog> captor;
@Captor
private ArgumentCaptor<MessageDeletedAttachmentLog> attachmentCaptor;
@Captor
private ArgumentCaptor<MessageToSend> messageCaptor;
@Before
public void setup() {
AServer server = MockUtils.getServer();
AUserInAServer aUserInAServer = MockUtils.getUserObject(4L, server);
AChannel channel = MockUtils.getTextChannel(server, 5L);
authorUser = AServerAChannelAUser.builder().guild(server).channel(channel).aUserInAServer(aUserInAServer).build();
Member member = Mockito.mock(Member.class);
Guild guild = Mockito.mock(Guild.class);
TextChannel textChannel = Mockito.mock(TextChannel.class);
authorMember = GuildChannelMember.builder().guild(guild).textChannel(textChannel).member(member).build();
}
@Test
public void testExecuteListenerWithSimpleMessage() {
CachedMessage message = CachedMessage.builder().serverId(authorUser.getGuild().getId()).build();
MessageToSend messageToSend = Mockito.mock(MessageToSend.class);
when(templateService.renderEmbedTemplate(eq(MessageDeleteLogListener.MESSAGE_DELETED_TEMPLATE), captor.capture())).thenReturn(messageToSend);
testUnit.execute(message, authorUser, authorMember);
verify(postTargetService, times(1)).sendEmbedInPostTarget(messageToSend, LoggingPostTarget.DELETE_LOG, authorUser.getGuild().getId());
MessageDeletedLog messageDeletedLog = captor.getValue();
Assert.assertEquals(message, messageDeletedLog.getCachedMessage());
Assert.assertEquals(authorUser.getGuild(), messageDeletedLog.getServer());
Assert.assertEquals(authorUser.getChannel(), messageDeletedLog.getChannel());
Assert.assertEquals(authorUser.getUser(), messageDeletedLog.getUser());
Assert.assertEquals(authorUser.getAUserInAServer(), messageDeletedLog.getAUserInAServer());
Assert.assertEquals(authorMember.getGuild(), messageDeletedLog.getGuild());
Assert.assertEquals(authorMember.getTextChannel(), messageDeletedLog.getMessageChannel());
Assert.assertEquals(authorMember.getMember(), messageDeletedLog.getMember());
}
@Test
public void testExecuteListenerWithOneAttachment() {
String attachmentUrl = "url";
CachedMessage message = CachedMessage.builder().serverId(authorUser.getGuild().getId()).attachmentUrls(Arrays.asList(attachmentUrl)).build();
MessageToSend messageToSend = Mockito.mock(MessageToSend.class);
MessageToSend attachmentMessage = Mockito.mock(MessageToSend.class);
when(templateService.renderEmbedTemplate(eq(MessageDeleteLogListener.MESSAGE_DELETED_TEMPLATE), captor.capture())).thenReturn(messageToSend);
when(templateService.renderEmbedTemplate(eq(MessageDeleteLogListener.MESSAGE_DELETED_ATTACHMENT_TEMPLATE), attachmentCaptor.capture())).thenReturn(attachmentMessage);
testUnit.execute(message, authorUser, authorMember);
verify(postTargetService, times(2)).sendEmbedInPostTarget(messageCaptor.capture(), eq(LoggingPostTarget.DELETE_LOG), eq(authorUser.getGuild().getId()));
List<MessageToSend> messagesSent = messageCaptor.getAllValues();
Assert.assertEquals(messageToSend, messagesSent.get(0));
Assert.assertEquals(attachmentMessage, messagesSent.get(1));
MessageDeletedAttachmentLog attachmentLog = attachmentCaptor.getValue();
verifyAttachmentLog(attachmentUrl, attachmentLog, 1);
verifyMessageDeletedLog();
}
@Test
public void testExecuteListenerWithTwoAttachment() {
String attachmentUrl = "url";
String secondAttachmentUrl = "url2";
CachedMessage message = CachedMessage.builder().serverId(authorUser.getGuild().getId()).attachmentUrls(Arrays.asList(attachmentUrl, secondAttachmentUrl)).build();
MessageToSend messageToSend = Mockito.mock(MessageToSend.class);
MessageToSend attachmentMessage = Mockito.mock(MessageToSend.class);
when(templateService.renderEmbedTemplate(eq(MessageDeleteLogListener.MESSAGE_DELETED_TEMPLATE), captor.capture())).thenReturn(messageToSend);
when(templateService.renderEmbedTemplate(eq(MessageDeleteLogListener.MESSAGE_DELETED_ATTACHMENT_TEMPLATE), attachmentCaptor.capture())).thenReturn(attachmentMessage);
testUnit.execute(message, authorUser, authorMember);
verify(postTargetService, times(3)).sendEmbedInPostTarget(messageCaptor.capture(), eq(LoggingPostTarget.DELETE_LOG), eq(authorUser.getGuild().getId()));
List<MessageToSend> messagesSent = messageCaptor.getAllValues();
Assert.assertEquals(messageToSend, messagesSent.get(0));
Assert.assertEquals(attachmentMessage, messagesSent.get(1));
List<MessageDeletedAttachmentLog> attachmentLog = attachmentCaptor.getAllValues();
verifyAttachmentLog(attachmentUrl, attachmentLog.get(0), 1);
verifyAttachmentLog(secondAttachmentUrl, attachmentLog.get(1), 2);
verifyMessageDeletedLog();
}
private void verifyMessageDeletedLog() {
MessageDeletedLog messageDeletedLog = captor.getValue();
Assert.assertEquals(authorUser.getGuild(), messageDeletedLog.getServer());
Assert.assertEquals(authorUser.getChannel(), messageDeletedLog.getChannel());
Assert.assertEquals(authorUser.getUser(), messageDeletedLog.getUser());
Assert.assertEquals(authorUser.getAUserInAServer(), messageDeletedLog.getAUserInAServer());
Assert.assertEquals(authorMember.getGuild(), messageDeletedLog.getGuild());
Assert.assertEquals(authorMember.getTextChannel(), messageDeletedLog.getMessageChannel());
Assert.assertEquals(authorMember.getMember(), messageDeletedLog.getMember());
}
private void verifyAttachmentLog(String attachmentUrl, MessageDeletedAttachmentLog attachmentLog, Integer index) {
Assert.assertEquals(attachmentUrl, attachmentLog.getImageUrl());
Assert.assertEquals(index, attachmentLog.getCounter());
Assert.assertEquals(authorUser.getGuild(), attachmentLog.getServer());
Assert.assertEquals(authorUser.getChannel(), attachmentLog.getChannel());
Assert.assertEquals(authorUser.getUser(), attachmentLog.getUser());
Assert.assertEquals(authorUser.getAUserInAServer(), attachmentLog.getAUserInAServer());
Assert.assertEquals(authorMember.getGuild(), attachmentLog.getGuild());
Assert.assertEquals(authorMember.getTextChannel(), attachmentLog.getMessageChannel());
Assert.assertEquals(authorMember.getMember(), attachmentLog.getMember());
}
}

View File

@@ -0,0 +1,77 @@
package dev.sheldan.abstracto.moderation.listener;
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
import dev.sheldan.abstracto.core.service.PostTargetService;
import dev.sheldan.abstracto.moderation.config.posttargets.LoggingPostTarget;
import dev.sheldan.abstracto.moderation.models.template.listener.MessageEditedLog;
import dev.sheldan.abstracto.templating.model.MessageToSend;
import dev.sheldan.abstracto.templating.service.TemplateService;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.TextChannel;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;
import static org.mockito.Mockito.*;
@RunWith(MockitoJUnitRunner.class)
public class MessageEditedListenerTest {
@InjectMocks
private MessageEditedListener testUnit;
@Mock
private TemplateService templateService;
@Mock
private PostTargetService postTargetService;
@Mock
private Message messageAfter;
@Mock
private CachedMessage messageBefore;
@Test
public void testExecuteListenerWithSameContent() {
String content = "text";
when(messageAfter.getContentRaw()).thenReturn(content);
when(messageBefore.getContent()).thenReturn(content);
testUnit.execute(messageBefore, messageAfter);
verify(templateService, times(0)).renderEmbedTemplate(eq(MessageEditedListener.MESSAGE_EDITED_TEMPLATE), any());
}
@Test
public void testExecuteListenerWithDifferentContent() {
String content = "text";
String contentAfterwards = "text2";
TextChannel channel = Mockito.mock(TextChannel.class);
Long serverId = 5L;
when(messageAfter.getContentRaw()).thenReturn(contentAfterwards);
when(messageAfter.getTextChannel()).thenReturn(channel);
Guild guild = Mockito.mock(Guild.class);
when(messageAfter.getGuild()).thenReturn(guild);
Member member = Mockito.mock(Member.class);
when(messageAfter.getMember()).thenReturn(member);
when(messageBefore.getContent()).thenReturn(content);
when(messageBefore.getServerId()).thenReturn(serverId);
MessageToSend messageToSend = Mockito.mock(MessageToSend.class);
ArgumentCaptor<MessageEditedLog> captor = ArgumentCaptor.forClass(MessageEditedLog.class);
when(templateService.renderEmbedTemplate(eq(MessageEditedListener.MESSAGE_EDITED_TEMPLATE), captor.capture())).thenReturn(messageToSend);
testUnit.execute(messageBefore, messageAfter);
verify(postTargetService, times(1)).sendEmbedInPostTarget(messageToSend, LoggingPostTarget.EDIT_LOG, serverId);
MessageEditedLog capturedValue = captor.getValue();
Assert.assertEquals(messageBefore, capturedValue.getMessageBefore());
Assert.assertEquals(messageAfter, capturedValue.getMessageAfter());
Assert.assertEquals(channel, capturedValue.getMessageChannel());
Assert.assertEquals(guild, capturedValue.getGuild());
Assert.assertEquals(member, capturedValue.getMember());
}
}

View File

@@ -0,0 +1,85 @@
package dev.sheldan.abstracto.moderation.service;
import dev.sheldan.abstracto.core.exception.GuildException;
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.moderation.config.posttargets.ModerationPostTarget;
import dev.sheldan.abstracto.templating.model.MessageToSend;
import dev.sheldan.abstracto.templating.service.TemplateService;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.requests.restaction.AuditableRestAction;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;
import java.util.Optional;
import static org.mockito.Mockito.*;
@RunWith(MockitoJUnitRunner.class)
public class BanServiceBeanTest {
public static final String REASON = "reason";
@InjectMocks
private BanServiceBean testUnit;
@Mock
private BotService botService;
@Mock
private TemplateService templateService;
@Mock
private PostTargetService postTargetService;
@Test
public void testBanMemberByMember() {
Long userId = 8L;
Long serverId = 9L;
Member memberToBan = Mockito.mock(Member.class);
when(memberToBan.getIdLong()).thenReturn(userId);
ServerContext context = Mockito.mock(ServerContext.class);
Guild mockedGuild = Mockito.mock(Guild.class);
when(memberToBan.getGuild()).thenReturn(mockedGuild);
when(mockedGuild.getIdLong()).thenReturn(serverId);
AuditableRestAction mockedAction = mock(AuditableRestAction.class);
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);
testUnit.banMember(memberToBan, REASON, context);
verify(mockedGuild, times(1)).ban(userId.toString(), 0, REASON);
verify(postTargetService, times(1)).sendEmbedInPostTarget(mockedMessage, ModerationPostTarget.BAN_LOG, serverId);
}
@Test
public void testBanMemberById() {
Long userId = 8L;
Long serverId = 5L;
ServerContext context = Mockito.mock(ServerContext.class);
Guild mockedGuild = Mockito.mock(Guild.class);
AuditableRestAction mockedAction = mock(AuditableRestAction.class);
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);
when(botService.getGuildById(serverId)).thenReturn(Optional.of(mockedGuild));
testUnit.banMember(serverId, userId, REASON, context);
verify(mockedGuild, times(1)).ban(userId.toString(), 0, REASON);
verify(postTargetService, times(1)).sendEmbedInPostTarget(mockedMessage, ModerationPostTarget.BAN_LOG, serverId);
}
@Test(expected = GuildException.class)
public void tryToBanInNonExistentGuild() {
Long userId = 8L;
Long serverId = 5L;
ServerContext context = Mockito.mock(ServerContext.class);
when(botService.getGuildById(serverId)).thenReturn(Optional.empty());
testUnit.banMember(serverId, userId, REASON, context);
}
}

View File

@@ -0,0 +1,55 @@
package dev.sheldan.abstracto.moderation.service;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.service.PostTargetService;
import dev.sheldan.abstracto.moderation.config.posttargets.ModerationPostTarget;
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 net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.User;
import net.dv8tion.jda.api.requests.restaction.AuditableRestAction;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;
import static org.mockito.Mockito.*;
@RunWith(MockitoJUnitRunner.class)
public class KickServiceBeanTest {
@InjectMocks
private KickServiceBean testUnit;
@Mock
private TemplateService templateService;
@Mock
private PostTargetService postTargetService;
@Test
public void testKickMember() {
AServer server = MockUtils.getServer();
User user = Mockito.mock(User.class);
Member member = Mockito.mock(Member.class);
when(member.getUser()).thenReturn(user);
when(user.getIdLong()).thenReturn(6L);
Guild mockedGuild = Mockito.mock(Guild.class);
when(member.getGuild()).thenReturn(mockedGuild);
AuditableRestAction<Void> mockedAction = Mockito.mock(AuditableRestAction.class);
String reason = "reason";
when(mockedGuild.kick(member, reason)).thenReturn(mockedAction);
KickLogModel model = Mockito.mock(KickLogModel.class);
when(model.getServer()).thenReturn(server);
MessageToSend messageToSend = Mockito.mock(MessageToSend.class);
when(templateService.renderEmbedTemplate(KickServiceBean.KICK_LOG_TEMPLATE, model)).thenReturn(messageToSend);
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

@@ -0,0 +1,371 @@
package dev.sheldan.abstracto.moderation.service;
import dev.sheldan.abstracto.core.models.AServerAChannelMessage;
import dev.sheldan.abstracto.core.models.FullUser;
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.management.ChannelManagementService;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.moderation.config.posttargets.MutingPostTarget;
import dev.sheldan.abstracto.moderation.exception.MuteException;
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.MuteNotification;
import dev.sheldan.abstracto.moderation.models.template.commands.UnMuteLog;
import dev.sheldan.abstracto.moderation.service.management.MuteManagementService;
import dev.sheldan.abstracto.moderation.service.management.MuteRoleManagementService;
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 net.dv8tion.jda.api.entities.*;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;
import 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.ScheduledExecutorService;
import static org.mockito.Mockito.*;
@RunWith(MockitoJUnitRunner.class)
public class MuteServiceBeanTest {
@InjectMocks
private MuteServiceBean testUnit;
@Mock
private MuteRoleManagementService muteRoleManagementService;
@Mock
private RoleService roleService;
@Mock
private UserInServerManagementService userInServerManagementService;
@Mock
private SchedulerService schedulerService;
@Mock
private MuteManagementService muteManagementService;
@Mock
private TemplateService templateService;
@Mock
private BotService botService;
@Mock
private MessageService messageService;
@Mock
private PostTargetService postTargetService;
@Mock
private MuteService self;
@Mock
private ScheduledExecutorService executorService;
@Mock
private ChannelManagementService channelManagementService;
@Mock
private AUserInAServer userBeingMuted;
@Mock
private AUserInAServer userMuting;
@Mock
private User jdaUserBeingMuted;
@Mock
private Member memberBeingMuted;
@Mock
private Member memberMuting;
@Mock
private AServer server;
@Mock
private AChannel aChannel;
@Mock
private MessageChannel channel;
@Mock
private Message cause;
@Mock
private Guild guild;
@Mock
private ARole aRole;
@Mock
private MuteRole muteRole;
@Mock
private MessageToSend messageToSend;
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";
@Before
public void setup() {
server = MockUtils.getServer();
userBeingMuted = MockUtils.getUserObject(3L, server);
userMuting = MockUtils.getUserObject(4L, server);
aChannel = MockUtils.getTextChannel(server, CHANNEL_ID);
jdaUserBeingMuted = Mockito.mock(User.class);
guild = Mockito.mock(Guild.class);
memberMuting = Mockito.mock(Member.class);
memberBeingMuted = Mockito.mock(Member.class);
channel = Mockito.mock(MessageChannel.class);
cause = Mockito.mock(Message.class);
aRole = ARole.builder().build();
muteRole = MuteRole.builder().role(aRole).build();
messageToSend = Mockito.mock(MessageToSend.class);
}
@Test
public void testMuteUserWithScheduler() {
Instant unMuteDate = longerMute();
when(memberBeingMuted.getGuild()).thenReturn(guild);
when(memberBeingMuted.getUser()).thenReturn(jdaUserBeingMuted);
FullUser mutedUser = FullUser.builder().member(memberBeingMuted).aUserInAServer(userBeingMuted).build();
FullUser mutingUser = FullUser.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);
}
@Test
public void testMuteWithDirectUnMute() {
when(memberBeingMuted.getGuild()).thenReturn(guild);
when(memberBeingMuted.getUser()).thenReturn(jdaUserBeingMuted);
FullUser mutedUser = FullUser.builder().member(memberBeingMuted).aUserInAServer(userBeingMuted).build();
FullUser mutingUser = FullUser.builder().member(memberMuting).aUserInAServer(userMuting).build();
Instant unMuteDate = shorterMute();
setupShortMute(unMuteDate);
testUnit.muteUser(mutedUser, mutingUser, REASON, unMuteDate, cause);
verifyDirectMute();
}
@Test(expected = MuteException.class)
public void testMuteUserWithoutMuteRole() {
FullUser mutedUser = FullUser.builder().aUserInAServer(userBeingMuted).build();
when(muteRoleManagementService.muteRoleForServerExists(server)).thenReturn(false);
testUnit.muteUser(mutedUser, FullUser.builder().build(), REASON, longerMute(), Mockito.mock(Message.class));
}
@Test
public void testCancelUnMuteJob() {
Mute mute = Mute.builder().triggerKey(TRIGGER).build();
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());
}
@Test
public void testMuteMember() {
when(userInServerManagementService.loadUser(memberBeingMuted)).thenReturn(userBeingMuted);
when(userInServerManagementService.loadUser(memberMuting)).thenReturn(userMuting);
Instant unMuteDate = shorterMute();
setupShortMute(unMuteDate);
testUnit.muteMember(memberBeingMuted, memberMuting, REASON, unMuteDate, cause);
verifyDirectMute();
}
@Test
public void testMuteAUserInAServer() {
when(botService.getMemberInServer(userBeingMuted)).thenReturn(memberBeingMuted);
when(botService.getMemberInServer(userMuting)).thenReturn(memberMuting);
Instant unMuteDate = shorterMute();
setupShortMute(unMuteDate);
testUnit.muteAUserInAServer(userBeingMuted, userMuting, REASON, unMuteDate, cause);
verifyDirectMute();
}
@Test
public void testMuteMemberWithLog() {
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);
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());
}
@Test
public void testUnMuteMemberWhoseMuteEnded() {
Mute mute = Mockito.mock(Mute.class);
when(mute.getMuteEnded()).thenReturn(true);
when(mute.getMutedUser()).thenReturn(userBeingMuted);
testUnit.unmuteUser(mute);
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);
}
@Test
public void testEndNonExistingMute() {
Long muteId = 6L;
when(muteManagementService.findMute(muteId)).thenReturn(Optional.empty());
testUnit.endMute(muteId);
verifyNoUnMuteHappened();
}
@Test
public void testUnMuteMemberInGuild() {
executeUnMuteWithLogTest(true, 1);
}
@Test
public void testUnMuteMemberWhoLeftGuild() {
executeUnMuteWithLogTest(false, 0);
}
@Test
public void testCompletelyUnMuteNotMutedUser() {
when(muteManagementService.getAllMutesOf(userBeingMuted)).thenReturn(Arrays.asList());
testUnit.completelyUnMuteUser(userBeingMuted);
verify(muteManagementService, times(0)).saveMute(any(Mute.class));
}
@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));
verify(schedulerService, times(0)).stopTrigger(anyString());
}
@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);
verify(muteManagementService, times(1)).saveMute(any(Mute.class));
verify(schedulerService, times(1)).stopTrigger(TRIGGER);
}
@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);
testUnit.completelyUnMuteMember(memberBeingMuted);
verify(muteManagementService, times(1)).saveMute(any(Mute.class));
verify(schedulerService, times(1)).stopTrigger(TRIGGER);
}
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);
when(mute.getMutedUser()).thenReturn(userBeingMuted);
when(mute.getMutingServer()).thenReturn(server);
setupUnMuteMocks(stillInGuild);
testUnit.unmuteUser(mute);
verifyUnMute(roleRemovals);
}
private void setupUnMuteMocks(boolean stillInGuild) {
when(muteRoleManagementService.retrieveMuteRoleForServer(server)).thenReturn(muteRole);
when(botService.getGuildByIdNullable(server.getId())).thenReturn(guild);
when(botService.isUserInGuild(guild, userBeingMuted)).thenReturn(stillInGuild);
when(botService.getMemberInServer(userBeingMuted)).thenReturn(memberBeingMuted);
when(templateService.renderEmbedTemplate(eq(MuteServiceBean.UNMUTE_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(Optional.of(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());
}
private Instant longerMute() {
return Instant.now().plus(Duration.ofHours(1));
}
private Instant shorterMute() {
return Instant.now().plus(Duration.ofSeconds(4));
}
}

View File

@@ -0,0 +1,273 @@
package dev.sheldan.abstracto.moderation.service;
import dev.sheldan.abstracto.core.service.MessageService;
import dev.sheldan.abstracto.moderation.exception.NoMessageFoundException;
import dev.sheldan.abstracto.moderation.models.template.commands.PurgeStatusUpdateModel;
import dev.sheldan.abstracto.templating.model.MessageToSend;
import dev.sheldan.abstracto.templating.service.TemplateService;
import net.dv8tion.jda.api.entities.*;
import net.dv8tion.jda.api.requests.RestAction;
import net.dv8tion.jda.api.requests.restaction.AuditableRestAction;
import net.dv8tion.jda.api.utils.TimeUtil;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import static org.mockito.Mockito.*;
@RunWith(MockitoJUnitRunner.class)
public class PurgeServiceBeanTest {
@InjectMocks
private PurgeServiceBean testUnit;
@Mock
private MessageService messageService;
@Mock
private TemplateService templateService;
@Mock
private TextChannel textChannel;
@Mock
private Member purgedMember;
private static final Long START_MESSAGE_ID = 4L;
private static final Long STATUS_MESSAGE_ID = 7L;
private static final Long AUTHOR_ID = 17L;
@Mock
private User messageAuthor;
@Mock
private Message firstMessage;
@Mock
private Message secondMessage;
@Mock
private Message thirdMessage;
@Mock
private Message fourthMessage;
@Mock
private MessageHistory history;
@Mock
private MessageHistory.MessageRetrieveAction retrieveAction;
@Mock
private MessageToSend firstStatusUpdateMessage;
@Mock
private RestAction deleteMessagesAction;
@Mock
private AuditableRestAction deleteStatusAction;
@Test
public void testPurgeMessageViaStartMessage() {
Integer amountToDelete = 50;
when(textChannel.getHistoryBefore(START_MESSAGE_ID, amountToDelete)).thenReturn(retrieveAction);
when(retrieveAction.submit()).thenReturn(CompletableFuture.completedFuture(history));
setupOneMessageBatch(getDeletableMessageId(), getDeletableMessageId());
Message messageToStartOffAT = Mockito.mock(Message.class);
when(messageToStartOffAT.getIdLong()).thenReturn(START_MESSAGE_ID);
CompletableFuture<Void> futures = testUnit.purgeMessagesInChannel(amountToDelete, textChannel, messageToStartOffAT, purgedMember);
futures.whenComplete((aVoid, throwable) -> Assert.assertNull(throwable));
verify(deleteStatusAction, times(1)).queueAfter(5, TimeUnit.SECONDS);
verify(messageService, times(1)).updateStatusMessage(eq(textChannel), anyLong(), any());
}
@Test
public void testPurgeMessageNotNoUser() {
Integer amountToDelete = 50;
when(textChannel.getHistoryBefore(START_MESSAGE_ID, amountToDelete)).thenReturn(retrieveAction);
when(retrieveAction.submit()).thenReturn(CompletableFuture.completedFuture(history));
when(firstMessage.getId()).thenReturn(getDeletableMessageId().toString());
when(secondMessage.getId()).thenReturn(getDeletableMessageId().toString());
setupFirstMessageHistoryMocks();
setupStatusMessageMocks();
mockConsumer(deleteMessagesAction);
CompletableFuture<Void> futures = testUnit.purgeMessagesInChannel(amountToDelete, textChannel, START_MESSAGE_ID, null);
futures.whenComplete((aVoid, throwable) -> Assert.assertNull(throwable));
verify(deleteStatusAction, times(1)).queueAfter(5, TimeUnit.SECONDS);
verify(messageService, times(1)).updateStatusMessage(eq(textChannel), anyLong(), any());
}
@Test
public void testPurgeSingleMessage() {
Integer amountToDelete = 50;
when(textChannel.getHistoryBefore(START_MESSAGE_ID, amountToDelete)).thenReturn(retrieveAction);
when(retrieveAction.submit()).thenReturn(CompletableFuture.completedFuture(history));
when(firstMessage.getId()).thenReturn(getDeletableMessageId().toString());
when(firstMessage.getAuthor()).thenReturn(messageAuthor);
setupMembersWithAuthorId();
List<Message> messagesToDelete = Arrays.asList(firstMessage);
when(history.getRetrievedHistory()).thenReturn(messagesToDelete);
setupStatusMessageMocks();
AuditableRestAction auditableRestAction = Mockito.mock(AuditableRestAction.class);
when(firstMessage.delete()).thenReturn(auditableRestAction);
mockConsumer(auditableRestAction);
CompletableFuture<Void> futures = testUnit.purgeMessagesInChannel(amountToDelete, textChannel, START_MESSAGE_ID, purgedMember);
futures.whenComplete((aVoid, throwable) -> Assert.assertNull(throwable));
verify(deleteStatusAction, times(1)).queueAfter(5, TimeUnit.SECONDS);
verify(messageService, times(1)).updateStatusMessage(eq(textChannel), anyLong(), any());
}
@Test
public void testPurgeMessagesInTwoIterationsSecondIterationsTooOld() {
Integer amountToDelete = 150;
Long latestDeletedMessageId = getDeletableMessageId();
when(textChannel.getHistoryBefore(START_MESSAGE_ID, 100)).thenReturn(retrieveAction);
when(retrieveAction.submit()).thenReturn(CompletableFuture.completedFuture(history));
MessageHistory.MessageRetrieveAction secondRetrieveAction = Mockito.mock(MessageHistory.MessageRetrieveAction.class);
when(textChannel.getHistoryBefore(latestDeletedMessageId, 50)).thenReturn(secondRetrieveAction);
MessageHistory secondHistory = Mockito.mock(MessageHistory.class);
when(secondRetrieveAction.submit()).thenReturn(CompletableFuture.completedFuture(secondHistory));
when(secondMessage.getIdLong()).thenReturn(latestDeletedMessageId);
when(thirdMessage.getId()).thenReturn(getNotDeletableMessageId().toString());
when(fourthMessage.getId()).thenReturn(getNotDeletableMessageId().toString());
setupOneMessageBatch(getDeletableMessageId(), latestDeletedMessageId);
List<Message> secondMessagesToDelete = Arrays.asList(thirdMessage, fourthMessage);
when(secondHistory.getRetrievedHistory()).thenReturn(secondMessagesToDelete);
CompletableFuture<Void> futures = testUnit.purgeMessagesInChannel(amountToDelete, textChannel, START_MESSAGE_ID, purgedMember);
futures.whenComplete((aVoid, throwable) -> Assert.assertTrue(throwable.getCause() instanceof NoMessageFoundException));
verify(deleteStatusAction, times(1)).queueAfter(5, TimeUnit.SECONDS);
verify(messageService, times(1)).updateStatusMessage(eq(textChannel), anyLong(), any());
}
@Test
public void testPurgeMessagesInTwoIterations() {
Integer amountToDelete = 150;
Long latestDeletedMessageId = getDeletableMessageId();
when(textChannel.getHistoryBefore(START_MESSAGE_ID, 100)).thenReturn(retrieveAction);
when(retrieveAction.submit()).thenReturn(CompletableFuture.completedFuture(history));
MessageHistory.MessageRetrieveAction secondRetrieveAction = Mockito.mock(MessageHistory.MessageRetrieveAction.class);
when(textChannel.getHistoryBefore(latestDeletedMessageId, 50)).thenReturn(secondRetrieveAction);
MessageHistory secondHistory = Mockito.mock(MessageHistory.class);
when(secondRetrieveAction.submit()).thenReturn(CompletableFuture.completedFuture(secondHistory));
when(secondMessage.getIdLong()).thenReturn(latestDeletedMessageId);
setupOneMessageBatch(getDeletableMessageId(), latestDeletedMessageId);
setupFirstMessages(thirdMessage, getDeletableMessageId(), fourthMessage, latestDeletedMessageId, messageAuthor);
RestAction secondDeleteMessagesAction = Mockito.mock(RestAction.class);
List<Message> secondMessagesToDelete = Arrays.asList(thirdMessage, fourthMessage);
when(secondHistory.getRetrievedHistory()).thenReturn(secondMessagesToDelete);
when(textChannel.deleteMessages(secondMessagesToDelete)).thenReturn(secondDeleteMessagesAction);
mockConsumer(secondDeleteMessagesAction);
CompletableFuture<Void> futures = testUnit.purgeMessagesInChannel(amountToDelete, textChannel, START_MESSAGE_ID, purgedMember);
futures.whenComplete((aVoid, throwable) -> Assert.assertNull(throwable));
verify(deleteStatusAction, times(1)).queueAfter(5, TimeUnit.SECONDS);
verify(messageService, times(2)).updateStatusMessage(eq(textChannel), anyLong(), any());
}
@Test
public void testPurgeMessagesInOneIteration() {
Integer amountToDelete = 50;
when(textChannel.getHistoryBefore(START_MESSAGE_ID, amountToDelete)).thenReturn(retrieveAction);
when(retrieveAction.submit()).thenReturn(CompletableFuture.completedFuture(history));
setupOneMessageBatch(getDeletableMessageId(), getDeletableMessageId());
CompletableFuture<Void> futures = testUnit.purgeMessagesInChannel(amountToDelete, textChannel, START_MESSAGE_ID, purgedMember);
futures.whenComplete((aVoid, throwable) -> Assert.assertNull(throwable));
verify(deleteStatusAction, times(1)).queueAfter(5, TimeUnit.SECONDS);
verify(messageService, times(1)).updateStatusMessage(eq(textChannel), anyLong(), any());
}
@Test
public void testPurgeTooOldMessage() {
Integer amountToDelete = 50;
when(textChannel.getHistoryBefore(START_MESSAGE_ID, amountToDelete)).thenReturn(retrieveAction);
when(retrieveAction.submit()).thenReturn(CompletableFuture.completedFuture(history));
when(firstMessage.getId()).thenReturn(getNotDeletableMessageId().toString());
when(history.getRetrievedHistory()).thenReturn(Arrays.asList(firstMessage));
setupStatusMessageMocks();
CompletableFuture<Void> futures = testUnit.purgeMessagesInChannel(amountToDelete, textChannel, START_MESSAGE_ID, purgedMember);
futures.whenComplete((aVoid, throwable) -> Assert.assertTrue(throwable.getCause() instanceof NoMessageFoundException));
}
private void setupOneMessageBatch(Long deletableMessageId, Long deletableMessageId2) {
setupFirstMessages(firstMessage, deletableMessageId, secondMessage, deletableMessageId2, messageAuthor);
setupMembersWithAuthorId();
setupFirstMessageHistoryMocks();
mockConsumer(deleteMessagesAction);
setupStatusMessageMocks();
}
private void setupFirstMessageHistoryMocks() {
List<Message> messagesToDelete = Arrays.asList(firstMessage, secondMessage);
when(history.getRetrievedHistory()).thenReturn(messagesToDelete);
when(textChannel.deleteMessages(messagesToDelete)).thenReturn(deleteMessagesAction);
}
private void setupStatusMessageMocks() {
when(templateService.renderTemplateToMessageToSend(eq("purge_status_update"), any(PurgeStatusUpdateModel.class))).thenReturn(firstStatusUpdateMessage);
when(messageService.createStatusMessageId(firstStatusUpdateMessage, textChannel)).thenReturn(CompletableFuture.completedFuture(STATUS_MESSAGE_ID));
when(textChannel.deleteMessageById(STATUS_MESSAGE_ID)).thenReturn(deleteStatusAction);
}
private void setupMembersWithAuthorId() {
when(messageAuthor.getIdLong()).thenReturn(AUTHOR_ID);
when(purgedMember.getIdLong()).thenReturn(AUTHOR_ID);
}
private void setupFirstMessages(Message firstMessageToMock, Long firstMessageId, Message secondMessageToMock, Long secondMessageId, User author) {
when(firstMessageToMock.getId()).thenReturn(firstMessageId.toString());
when(firstMessageToMock.getAuthor()).thenReturn(author);
when(secondMessageToMock.getId()).thenReturn(secondMessageId.toString());
when(secondMessageToMock.getAuthor()).thenReturn(author);
}
private void mockConsumer(RestAction secondDeleteMessagesAction) {
doAnswer(invocationOnMock -> {
Object consumerObj = invocationOnMock.getArguments()[0];
if(consumerObj instanceof Consumer) {
Consumer<Void> consumer = (Consumer) consumerObj;
consumer.accept(null);
}
return null;
}).when(secondDeleteMessagesAction).queue(any(Consumer.class), any(Consumer.class));
}
private Long getDeletableMessageId() {
return TimeUtil.getDiscordTimestamp((System.currentTimeMillis() - (7 * 24 * 60 * 60 * 1000)));
}
private Long getNotDeletableMessageId() {
return TimeUtil.getDiscordTimestamp((System.currentTimeMillis() - (21 * 24 * 60 * 60 * 1000)));
}
}

View File

@@ -0,0 +1,90 @@
package dev.sheldan.abstracto.moderation.service;
import dev.sheldan.abstracto.core.exception.ChannelNotFoundException;
import dev.sheldan.abstracto.core.models.database.AChannel;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.service.BotService;
import dev.sheldan.abstracto.test.MockUtils;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.TextChannel;
import net.dv8tion.jda.api.managers.ChannelManager;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import java.time.Duration;
import java.util.Optional;
import static org.mockito.Mockito.*;
@RunWith(MockitoJUnitRunner.class)
public class SlowModeServiceBeanTest {
@InjectMocks
private SlowModeServiceBean testUnit;
@Mock
private BotService botService;
@Mock
private ChannelManager channelManager;
@Mock
private ChannelManager returnedManager;
@Mock
private Guild guild;
@Mock
private TextChannel channel;
@Test
public void setSlowModeInTextChannel() {
when(channelManager.setSlowmode(anyInt())).thenReturn(returnedManager);
when(channel.getGuild()).thenReturn(guild);
when(channel.getManager()).thenReturn(channelManager);
Duration duration = Duration.ofMinutes(5);
testUnit.setSlowMode(channel, duration);
verify(channelManager, times(1)).setSlowmode((int)duration.getSeconds());
}
@Test
public void testSlowModeInAChannel() {
AServer server = MockUtils.getServer();
AChannel aChannel = MockUtils.getTextChannel(server, 5L);
Duration duration = Duration.ofMinutes(5);
when(channelManager.setSlowmode(anyInt())).thenReturn(returnedManager);
when(channel.getGuild()).thenReturn(guild);
when(channel.getManager()).thenReturn(channelManager);
when(botService.getTextChannelFromServer(server.getId(), aChannel.getId())).thenReturn(Optional.of(channel));
testUnit.setSlowMode(aChannel, duration);
verify(channelManager, times(1)).setSlowmode((int)duration.getSeconds());
}
@Test
public void testDisableSlowMode() {
when(channelManager.setSlowmode(anyInt())).thenReturn(returnedManager);
when(channel.getGuild()).thenReturn(guild);
when(channel.getManager()).thenReturn(channelManager);
testUnit.disableSlowMode(channel);
verify(channelManager, times(1)).setSlowmode(0);
}
@Test(expected = IllegalArgumentException.class)
public void setTooLongSlowModeInChannel() {
when(channel.getGuild()).thenReturn(guild);
Duration duration = Duration.ofHours(24);
testUnit.setSlowMode(channel, duration);
}
@Test(expected = ChannelNotFoundException.class)
public void testSlowModeInAChannelNotFound() {
AServer server = MockUtils.getServer();
AChannel aChannel = MockUtils.getTextChannel(server, 5L);
Duration duration = Duration.ofMinutes(5);
when(botService.getTextChannelFromServer(server.getId(), aChannel.getId())).thenReturn(Optional.empty());
testUnit.setSlowMode(aChannel, duration);
}
}

View File

@@ -0,0 +1,249 @@
package dev.sheldan.abstracto.moderation.service;
import dev.sheldan.abstracto.core.models.FullUser;
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.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.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 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.*;
import org.mockito.junit.MockitoJUnitRunner;
import java.time.Instant;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import static org.mockito.Mockito.*;
@RunWith(MockitoJUnitRunner.class)
public class WarnServiceBeanTest {
@InjectMocks
private WarnServiceBean testUnit;
@Mock
private UserInServerManagementService userInServerManagementService;
@Mock
private WarnManagementService warnManagementService;
@Mock
private PostTargetService postTargetService;
@Mock
private TemplateService templateService;
@Mock
private BotService botService;
@Mock
private MessageService messageService;
@Mock
private ConfigService configService;
@Mock
private Member warnedMember;
@Mock
private Member warningMember;
@Mock
private Member secondWarnedMember;
@Mock
private Guild guild;
@Mock
private MessageToSend messageToSend;
@Mock
private MessageChannel feedBackChannel;
@Mock
private User warnedSimpleUser;
@Captor
private ArgumentCaptor<WarnDecayLogModel> warnDecayLogModelArgumentCaptor;
@Captor
private ArgumentCaptor<WarnNotification> notificationCaptor;
private AServer server;
private AUserInAServer warningUser;
private AUserInAServer firstWarnedUser;
private AUserInAServer secondWarnedUser;
private Warning firstWarning;
private Warning secondWarning;
private static final String REASON = "reason";
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);
}
@Test
public void testDecayWarning() {
Warning warning = getDefaultWarning();
Instant date = Instant.now();
testUnit.decayWarning(warning, date);
Assert.assertTrue(warning.getDecayed());
Assert.assertEquals(date, warning.getDecayDate());
}
@Test
public void testDecayWarningsForServer() {
setupWarnDecay();
testUnit.decayWarningsForServer(server);
verifyWarnDecayWithLog(true);
}
@Test
public void testDecayAllWarningsForServerWithLog() {
setupWarnDecay();
testUnit.decayAllWarningsForServer(server, true);
verifyWarnDecayWithLog(true);
}
@Test
public void testDecayAllWarningsForServerWithoutLog() {
setupWarnDecay();
testUnit.decayAllWarningsForServer(server, false);
verifyWarnDecayWithLog(false);
}
@Test
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(warnManagementService.getActiveWarningsInServerOlderThan(eq(server), any(Instant.class))).thenReturn(warnings);
testUnit.decayAllWarningsForServer(server, true);
verify(postTargetService, times(1)).sendEmbedInPostTarget(messageToSend, WarnDecayPostTarget.DECAY_LOG, server.getId());
WarnDecayLogModel model = warnDecayLogModelArgumentCaptor.getValue();
List<WarnDecayWarning> usedWarnings = model.getWarnings();
Assert.assertEquals(0, usedWarnings.size());
}
@Test
public void testWarnFullUser() {
setupMocksForWarning();
FullUser warnedFullUser = FullUser.builder().member(warnedMember).aUserInAServer(firstWarnedUser).build();
FullUser warningFullUser = FullUser.builder().member(warningMember).aUserInAServer(warningUser).build();
Warning warning = testUnit.warnFullUser(warnedFullUser, warningFullUser, REASON, feedBackChannel);
verifyWarning(warning);
}
@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);
}
@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() {
when(warnedMember.getGuild()).thenReturn(guild);
when(guild.getName()).thenReturn(GUILD_NAME);
when(warnedMember.getUser()).thenReturn(warnedSimpleUser);
when(warnManagementService.createWarning(firstWarnedUser, warningUser, REASON)).thenReturn(firstWarning);
when(templateService.renderTemplate(eq(WarnServiceBean.WARN_NOTIFICATION_TEMPLATE), notificationCaptor.capture())).thenReturn(NOTIFICATION_TEXT);
}
private void verifyWarnDecayWithLog(boolean withLog) {
int logCount = withLog ? 1 : 0;
verify(postTargetService, times(logCount)).sendEmbedInPostTarget(messageToSend, WarnDecayPostTarget.DECAY_LOG, server.getId());
if(withLog) {
WarnDecayLogModel model = warnDecayLogModelArgumentCaptor.getValue();
List<WarnDecayWarning> usedWarnings = model.getWarnings();
Assert.assertEquals(firstWarning, usedWarnings.get(0).getWarning());
Assert.assertEquals(warnedMember, usedWarnings.get(0).getWarnedMember());
Assert.assertEquals(warningMember, usedWarnings.get(0).getWarningMember());
Assert.assertEquals(secondWarning, usedWarnings.get(1).getWarning());
Assert.assertEquals(secondWarnedMember, usedWarnings.get(1).getWarnedMember());
Assert.assertEquals(warningMember, usedWarnings.get(1).getWarningMember());
Assert.assertEquals(2, usedWarnings.size());
}
}
private void setupWarnDecay() {
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(warnManagementService.getActiveWarningsInServerOlderThan(eq(server), any(Instant.class))).thenReturn(warnings);
}
public Warning getDefaultWarning() {
return Warning.builder().build();
}
}

View File

@@ -0,0 +1,141 @@
package dev.sheldan.abstracto.moderation.service.management;
import dev.sheldan.abstracto.core.models.AServerAChannelMessage;
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.management.UserInServerManagementService;
import dev.sheldan.abstracto.moderation.models.database.Mute;
import dev.sheldan.abstracto.moderation.repository.MuteRepository;
import dev.sheldan.abstracto.test.MockUtils;
import net.dv8tion.jda.api.entities.Member;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.*;
import org.mockito.junit.MockitoJUnitRunner;
import java.time.Instant;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import static org.mockito.Mockito.*;
@RunWith(MockitoJUnitRunner.class)
public class MuteManagementServiceBeanTest {
@InjectMocks
private MuteManagementServiceBean testUnit;
@Mock
private MuteRepository muteRepository;
@Mock
private UserInServerManagementService userInServerManagementService;
@Captor
private ArgumentCaptor<Mute> muteArgumentCaptor;
@Test
public void testCreateMute() {
AServer server = MockUtils.getServer();
long messageId = 9L;
AChannel channel = MockUtils.getTextChannel(server, 8L);
AUserInAServer mutingUser = MockUtils.getUserObject(5L, server);
AUserInAServer mutedUser = MockUtils.getUserObject(7L, server);
String reason = "reason";
Instant unMuteDate = Instant.now();
AServerAChannelMessage muteMessage = AServerAChannelMessage.builder().server(server).channel(channel).messageId(messageId).build();
testUnit.createMute(mutedUser, mutingUser, reason, unMuteDate, muteMessage);
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.assertFalse(createdMute.getMuteEnded());
Assert.assertEquals(messageId, createdMute.getMessageId().longValue());
Assert.assertEquals(channel, createdMute.getMutingChannel());
Assert.assertEquals(unMuteDate, createdMute.getMuteTargetDate());
}
@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);
Assert.assertTrue(foundMuteOptional.isPresent());
foundMuteOptional.ifPresent(foundMute -> Assert.assertEquals(id, foundMute.getId()));
}
@Test
public void testFindNonExistingMute() {
Long id = 5L;
when(muteRepository.findById(id)).thenReturn(Optional.empty());
Optional<Mute> foundMuteOptional = testUnit.findMute(id);
Assert.assertFalse(foundMuteOptional.isPresent());
}
@Test
public void testSaveMute() {
Mute mute = Mute.builder().build();
testUnit.saveMute(mute);
verify(muteRepository, times(1)).save(mute);
}
@Test
public void testGetMuteOfUser() {
AServer server = MockUtils.getServer();
AUserInAServer userInAServer = MockUtils.getUserObject(9L, server);
Mute mute = Mute.builder().build();
when(muteRepository.findTopByMutedUserAndMuteEndedFalse(userInAServer)).thenReturn(mute);
Mute aMuteOf = testUnit.getAMuteOf(userInAServer);
Assert.assertEquals(mute, aMuteOf);
}
@Test
public void testGetMuteOfMember() {
AServer server = MockUtils.getServer();
AUserInAServer userInAServer = MockUtils.getUserObject(9L, server);
Member member = Mockito.mock(Member.class);
when(userInServerManagementService.loadUser(member)).thenReturn(userInAServer);
Mute mute = Mute.builder().build();
when(muteRepository.findTopByMutedUserAndMuteEndedFalse(userInAServer)).thenReturn(mute);
Mute aMuteOf = testUnit.getAMuteOf(member);
Assert.assertEquals(mute, aMuteOf);
}
@Test
public void testGetAllMutesOf() {
AServer server = MockUtils.getServer();
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));
List<Mute> allMutesOf = testUnit.getAllMutesOf(userInAServer);
Assert.assertEquals(2, allMutesOf.size());
Assert.assertEquals(mute1, allMutesOf.get(0));
Assert.assertEquals(mute2, allMutesOf.get(1));
}
@Test
public void testHasActiveMute() {
checkExist(true);
}
@Test
public void testHasNoActiveMute() {
checkExist(false);
}
private void checkExist(boolean value) {
AServer server = MockUtils.getServer();
AUserInAServer userInAServer = MockUtils.getUserObject(9L, server);
when(muteRepository.existsByMutedUserAndMuteEndedFalse(userInAServer)).thenReturn(value);
boolean result = testUnit.hasActiveMute(userInAServer);
Assert.assertEquals(value, result);
}
}

View File

@@ -0,0 +1,101 @@
package dev.sheldan.abstracto.moderation.service.management;
import dev.sheldan.abstracto.core.models.database.ARole;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.moderation.models.database.MuteRole;
import dev.sheldan.abstracto.moderation.repository.MuteRoleRepository;
import dev.sheldan.abstracto.test.MockUtils;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import java.util.Arrays;
import java.util.List;
import static org.mockito.Mockito.*;
@RunWith(MockitoJUnitRunner.class)
public class MuteRoleManagementServiceBeanTest {
@InjectMocks
private MuteRoleManagementServiceBean testUnit;
@Mock
private MuteRoleRepository muteRoleRepository;
private AServer server;
@Before
public void setup() {
this.server = MockUtils.getServer();
}
@Test
public void testRetrieveMuteRoleForServer() {
MuteRole role = getMuteRole();
when(muteRoleRepository.findByRoleServer(server)).thenReturn(role);
MuteRole muteRole = testUnit.retrieveMuteRoleForServer(server);
Assert.assertEquals(role, muteRole);
}
@Test
public void testServeHasMuteRole() {
when(muteRoleRepository.existsByRoleServer(server)).thenReturn(true);
Assert.assertTrue(testUnit.muteRoleForServerExists(server));
}
@Test
public void testCreateMuteRoleForServer() {
ARole role = ARole.builder().build();
MuteRole muteRoleForServer = testUnit.createMuteRoleForServer(server, role);
verifyRoleSaved(role, muteRoleForServer, 1);
}
@Test
public void testRetrieveRolesForServer() {
List<MuteRole> existingRoles = Arrays.asList(getMuteRole(), getMuteRole());
when(muteRoleRepository.findAllByRoleServer(server)).thenReturn(existingRoles);
List<MuteRole> foundRoles = testUnit.retrieveMuteRolesForServer(server);
Assert.assertEquals(existingRoles.size(), foundRoles.size());
for (int i = 0; i < existingRoles.size(); i++) {
MuteRole existingRole = existingRoles.get(i);
MuteRole foundRole = foundRoles.get(i);
Assert.assertEquals(existingRole, foundRole);
}
}
@Test
public void testSetMuteRoleWithoutPrevious() {
ARole role = ARole.builder().build();
when(muteRoleRepository.existsByRoleServer(server)).thenReturn(false);
MuteRole muteRole = testUnit.setMuteRoleForServer(server, role);
verifyRoleSaved(role, muteRole, 1);
}
@Test
public void testSetMuteRoleWithPrevious() {
ARole role = ARole.builder().build();
when(muteRoleRepository.existsByRoleServer(server)).thenReturn(true);
MuteRole existingRole = getMuteRole();
when(muteRoleRepository.findByRoleServer(server)).thenReturn(existingRole);
MuteRole muteRole = testUnit.setMuteRoleForServer(server, role);
verifyRoleSaved(role, muteRole, 0);
}
private void verifyRoleSaved(ARole role, MuteRole muteRoleForServer, Integer saveCount) {
Assert.assertEquals(role, muteRoleForServer.getRole());
Assert.assertEquals(server, muteRoleForServer.getRoleServer());
verify(muteRoleRepository, times(saveCount)).save(muteRoleForServer);
}
private MuteRole getMuteRole() {
return MuteRole.builder().roleServer(server).build();
}
}

View File

@@ -0,0 +1,91 @@
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.moderation.models.database.UserNote;
import dev.sheldan.abstracto.moderation.repository.UserNoteRepository;
import dev.sheldan.abstracto.test.MockUtils;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import java.util.Arrays;
import java.util.List;
import static org.mockito.Mockito.*;
@RunWith(MockitoJUnitRunner.class)
public class UserNoteManagementServiceBeanTest {
@InjectMocks
private UserNoteManagementServiceBean testUnit;
@Mock
private UserNoteRepository userNoteRepository;
private static final String NOTE_TEXT = "noteText";
private static final Long NOTE_ID = 5L;
private AServer server;
private AUserInAServer userInAServer;
@Before
public void setup() {
this.server = MockUtils.getServer();
this.userInAServer = MockUtils.getUserObject(8L, server);
}
@Test
public void testCreateUserNote() {
UserNote userNote = testUnit.createUserNote(userInAServer, NOTE_TEXT);
verify(userNoteRepository, times(1)).save(userNote);
Assert.assertEquals(userNote.getUser(), userInAServer);
Assert.assertEquals(userNote.getNote(), NOTE_TEXT);
}
@Test
public void testDeleteNote() {
testUnit.deleteNote(NOTE_ID);
verify(userNoteRepository, times(1)).deleteById(NOTE_ID);
}
@Test
public void testNoteExists() {
when(userNoteRepository.existsById(NOTE_ID)).thenReturn(true);
Assert.assertTrue(testUnit.noteExists(NOTE_ID));
}
@Test
public void testLoadNotesForUser() {
UserNote note = UserNote.builder().build();
UserNote note2 = UserNote.builder().build();
List<UserNote> notes = Arrays.asList(note, note2);
when(userNoteRepository.findByUser(userInAServer)).thenReturn(notes);
List<UserNote> foundNotes = testUnit.loadNotesForUser(userInAServer);
Assert.assertEquals(notes.size(), foundNotes.size());
for (int i = 0; i < foundNotes.size(); i++) {
UserNote existingNote = notes.get(i);
UserNote foundNote = foundNotes.get(i);
Assert.assertEquals(existingNote, foundNote);
}
}
@Test
public void testLoadNotesForServer() {
UserNote note = UserNote.builder().build();
UserNote note2 = UserNote.builder().build();
List<UserNote> notes = Arrays.asList(note, note2);
when(userNoteRepository.findByUser_ServerReference(server)).thenReturn(notes);
List<UserNote> foundNotes = testUnit.loadNotesForServer(server);
Assert.assertEquals(notes.size(), foundNotes.size());
for (int i = 0; i < foundNotes.size(); i++) {
UserNote existingNote = notes.get(i);
UserNote foundNote = foundNotes.get(i);
Assert.assertEquals(existingNote, foundNote);
}
}
}

View File

@@ -0,0 +1,133 @@
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.moderation.models.database.Warning;
import dev.sheldan.abstracto.moderation.repository.WarnRepository;
import dev.sheldan.abstracto.test.MockUtils;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import java.time.Instant;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import static org.mockito.Mockito.*;
@RunWith(MockitoJUnitRunner.class)
public class WarnManagementServiceBeanTest {
@InjectMocks
private WarnManagementServiceBean testUnit;
@Mock
private WarnRepository warnRepository;
private AUserInAServer warnedUser;
private AServer server;
@Before
public void setup() {
this.server = MockUtils.getServer();
this.warnedUser = MockUtils.getUserObject(5L, server);
}
@Test
public void testCreateWarning() {
AUserInAServer warningUser = MockUtils.getUserObject(7L, server);
String reason = "REASON";
Warning warning = testUnit.createWarning(warnedUser, warningUser, reason);
Assert.assertEquals(warningUser, warning.getWarningUser());
Assert.assertEquals(warnedUser, warning.getWarnedUser());
Assert.assertEquals(reason, warning.getReason());
Assert.assertFalse(warning.getDecayed());
verify(warnRepository, times(1)).save(warning);
}
@Test
public void testRetrieveWarningsOlderThan() {
Instant date = Instant.now();
List<Warning> existingWarnings = Arrays.asList(getWarning(), getWarning());
when(warnRepository.findAllByWarnedUser_ServerReferenceAndDecayedFalseAndWarnDateLessThan(server, date)).thenReturn(existingWarnings);
List<Warning> activeWarningsInServerOlderThan = testUnit.getActiveWarningsInServerOlderThan(server, date);
checkFoundWarns(existingWarnings, activeWarningsInServerOlderThan);
}
@Test
public void testWarnCountOfUser() {
Long count = 5L;
when(warnRepository.countByWarnedUser(warnedUser)).thenReturn(count);
Long activeWarnsForUserCount = testUnit.getTotalWarnsForUser(warnedUser);
Assert.assertEquals(count, activeWarnsForUserCount);
}
@Test
public void testGetAllWarningsOfUser() {
List<Warning> existingWarnings = Arrays.asList(getWarning(), getWarning());
when(warnRepository.findByWarnedUser(warnedUser)).thenReturn(existingWarnings);
List<Warning> foundWarnings = testUnit.getAllWarnsForUser(warnedUser);
checkFoundWarns(existingWarnings, foundWarnings);
}
@Test
public void testGetAllWarningsOfServer() {
List<Warning> existingWarnings = Arrays.asList(getWarning(), getWarning());
when(warnRepository.findAllByWarnedUser_ServerReference(server)).thenReturn(existingWarnings);
List<Warning> foundWarnings = testUnit.getAllWarningsOfServer(server);
checkFoundWarns(existingWarnings, foundWarnings);
}
@Test
public void testActiveWarnCountOfUser() {
Long count = 5L;
when(warnRepository.countByWarnedUserAndDecayedFalse(warnedUser)).thenReturn(count);
Long activeWarnsForUserCount = testUnit.getActiveWarnsForUser(warnedUser);
Assert.assertEquals(count, activeWarnsForUserCount);
}
@Test
public void testFindByIdExisting() {
Long warnId = 6L;
Warning existingWarning = getWarning();
when(warnRepository.findById(warnId)).thenReturn(Optional.ofNullable(existingWarning));
Optional<Warning> warningOptional = testUnit.findById(warnId);
Assert.assertTrue(warningOptional.isPresent());
warningOptional.ifPresent(foundWarning -> Assert.assertEquals(existingWarning, foundWarning));
}
@Test
public void testFindByIdNotExisting() {
Long warnId = 6L;
when(warnRepository.findById(warnId)).thenReturn(Optional.ofNullable(null));
Optional<Warning> warningOptional = testUnit.findById(warnId);
Assert.assertFalse(warningOptional.isPresent());
}
@Test
public void testDeleteWarning() {
Warning warning = getWarning();
testUnit.deleteWarning(warning);
verify(warnRepository, times(1)).delete(warning);
}
private void checkFoundWarns(List<Warning> existingWarnings, List<Warning> activeWarningsInServerOlderThan) {
Assert.assertEquals(existingWarnings.size(), activeWarningsInServerOlderThan.size());
for (int i = 0; i < existingWarnings.size(); i++) {
Warning existingWarning = existingWarnings.get(i);
Warning foundWarning = activeWarningsInServerOlderThan.get(i);
Assert.assertEquals(existingWarning, foundWarning);
}
}
private Warning getWarning() {
return Warning.builder().build();
}
}

View File

@@ -13,6 +13,7 @@ import java.util.List;
@Component
public class WarningDecayFeature implements FeatureConfig {
public static final String DECAY_DAYS_KEY = "decayDays";
@Autowired
private WarningFeature warningFeature;
@@ -24,7 +25,7 @@ public class WarningDecayFeature implements FeatureConfig {
@Override
public List<String> getRequiredSystemConfigKeys() {
return Arrays.asList("decayDays");
return Arrays.asList(DECAY_DAYS_KEY);
}
@Override

View File

@@ -2,10 +2,21 @@ package dev.sheldan.abstracto.moderation.exception;
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
import dev.sheldan.abstracto.templating.Templatable;
public class MuteException extends AbstractoRunTimeException {
public class MuteException extends AbstractoRunTimeException implements Templatable {
public MuteException(String message) {
super(message);
}
@Override
public String getTemplateName() {
return "unMute_has_no_active_mute";
}
@Override
public Object getTemplateModel() {
return null;
}
}

View File

@@ -93,6 +93,7 @@ public class Mute {
@PrePersist
private void onInsert() {
this.created = Instant.now();
this.muteDate = Instant.now();
}
@Column(name = "updated")

View File

@@ -29,6 +29,7 @@ public class Warning {
* The {@link AUserInAServer} which was warned
*/
@Getter
@Setter
@ManyToOne
@JoinColumn(name = "warnedUserId", nullable = false)
private AUserInAServer warnedUser;
@@ -37,6 +38,7 @@ public class Warning {
* The {@link AUserInAServer} which gave the warning
*/
@Getter
@Setter
@ManyToOne
@JoinColumn(name = "warningUserId", nullable = false)
private AUserInAServer warningUser;
@@ -45,12 +47,14 @@ public class Warning {
* The reason why this warning was cast
*/
@Getter
@Setter
private String reason;
/**
* The date at which the warning was cast
*/
@Getter
@Setter
private Instant warnDate;
/**

View File

@@ -6,7 +6,6 @@ import lombok.Getter;
import lombok.Setter;
import lombok.experimental.SuperBuilder;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.Message;
import java.time.Duration;
@@ -26,10 +25,6 @@ public class MuteLog extends UserInitiatedServerContext {
* The {@link Member} executing the mute
*/
private Member mutingUser;
/**
* The {@link Message} triggering the command to mute
*/
private Message message;
/**
* The persisted mute object from the database containing the information about the mute
*/

View File

@@ -6,7 +6,6 @@ import lombok.Getter;
import lombok.Setter;
import lombok.experimental.SuperBuilder;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.Message;
/**
* Used when rendering the notification when a member was warned. The template is: "warn_log_embed"
@@ -27,10 +26,6 @@ public class WarnLog extends UserInitiatedServerContext {
* The {@link Member} casting the warn
*/
private Member warningUser;
/**
* The {@link Message} which contained the command triggering the warn
*/
private Message message;
/**
* The persisted {@link Warning} object from the database containing the information about the warning
*/

View File

@@ -16,5 +16,5 @@ public class MessageDeletedLog extends UserInitiatedServerContext {
/**
* A {@link CachedMessage} representing the deleted message
*/
private CachedMessage message;
private CachedMessage cachedMessage;
}

View File

@@ -11,7 +11,7 @@ import java.time.Instant;
public interface MuteService {
Mute muteMember(Member memberToMute, Member userMuting, String reason, Instant unmuteDate, Message message);
Mute muteMember(AUserInAServer member, AUserInAServer userMuting, String reason, Instant unmuteDate, Message message);
Mute muteAUserInAServer(AUserInAServer member, AUserInAServer userMuting, String reason, Instant unmuteDate, Message message);
Mute muteUser(FullUser userToMute, FullUser userMuting, String reason, Instant unmuteDate, Message message);
void applyMuteRole(AUserInAServer aUserInAServer);
void muteMemberWithLog(Member memberToMute, Member memberMuting, String reason, Instant unmuteDate, MuteLog log, Message message);
@@ -19,6 +19,6 @@ public interface MuteService {
void cancelUnmuteJob(Mute mute);
void unmuteUser(Mute mute);
void endMute(Long muteId);
void completelyUnmuteUser(AUserInAServer aUserInAServer);
void completelyUnmuteUser(Member member);
void completelyUnMuteUser(AUserInAServer aUserInAServer);
void completelyUnMuteMember(Member member);
}

View File

@@ -7,6 +7,6 @@ import java.time.Duration;
public interface SlowModeService {
void setSlowMode(TextChannel channel, Duration duration);
void disableSlowMOde(TextChannel channel);
void disableSlowMode(TextChannel channel);
void setSlowMode(AChannel channel, Duration duration);
}

View File

@@ -6,14 +6,17 @@ import dev.sheldan.abstracto.moderation.models.database.Warning;
import dev.sheldan.abstracto.moderation.models.template.commands.WarnLog;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.TextChannel;
import net.dv8tion.jda.api.entities.MessageChannel;
import java.time.Instant;
public interface WarnService {
Warning warnUser(AUserInAServer warnedAUser, AUserInAServer warningAUser, String reason, TextChannel feedbackChannel);
Warning warnUser(Member warnedMember, Member warningMember, String reason, TextChannel feedbackChannel);
Warning warnUser(FullUser warnedUser, FullUser warningUser, String reason, TextChannel feedbackChannel);
void warnUserWithLog(Member warnedMember, Member warningMember, String reason, WarnLog warnLog, TextChannel feedbackChannel);
Warning warnUser(AUserInAServer warnedAUser, AUserInAServer warningAUser, String reason, MessageChannel feedbackChannel);
Warning warnMember(Member warnedMember, Member warningMember, String reason, MessageChannel feedbackChannel);
Warning warnFullUser(FullUser warnedUser, FullUser warningUser, String reason, MessageChannel feedbackChannel);
Warning warnUserWithLog(Member warnedMember, Member warningMember, String reason, WarnLog warnLog, MessageChannel feedbackChannel);
void decayWarning(Warning warning, Instant decayDate);
void decayWarningsForServer(AServer server);
void decayAllWarningsForServer(AServer server, boolean logWarnings);
}

View File

@@ -45,6 +45,13 @@ public interface MuteManagementService {
*/
boolean hasActiveMute(AUserInAServer userInAServer);
/**
* Returns if the given {@link AUserInAServer} has an active mute which has not yet been ended yet.
* @param member The {@link Member} to check for
* @return Whether or not the userInAServer has an active mute
*/
boolean hasActiveMute(Member member);
/**
* Returns any active {@link Mute} of this {@link AUserInAServer} in the database
* @param userInAServer The {@link AUserInAServer} to search a mute for

View File

@@ -40,7 +40,6 @@ public class Remind extends AbstractConditionableCommand {
String text = (String) parameters.get(1);
AUserInAServer aUserInAServer = commandContext.getUserInitiatedContext().getAUserInAServer();
ReminderModel remindModel = (ReminderModel) ContextConverter.fromCommandContext(commandContext, ReminderModel.class);
remindModel.setMessage(commandContext.getMessage());
remindModel.setRemindText(text);
Reminder createdReminder = remindService.createReminderInForUser(aUserInAServer, text, remindTime, commandContext.getMessage());
remindModel.setReminder(createdReminder);

View File

@@ -0,0 +1,17 @@
package dev.sheldan.abstracto.utility.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
@Configuration
public class UtilitySpringConfig {
@Bean(name = "reminderScheduler")
public ScheduledExecutorService getUnMuteExecutor() {
return Executors.newScheduledThreadPool(1);
}
}

View File

@@ -2,6 +2,8 @@ package dev.sheldan.abstracto.utility.listener.starboard;
import dev.sheldan.abstracto.core.config.FeatureEnum;
import dev.sheldan.abstracto.core.listener.MessageDeletedListener;
import dev.sheldan.abstracto.core.models.AServerAChannelAUser;
import dev.sheldan.abstracto.core.models.GuildChannelMember;
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
import dev.sheldan.abstracto.utility.config.features.UtilityFeature;
import dev.sheldan.abstracto.utility.models.database.StarboardPost;
@@ -20,7 +22,7 @@ public class StarboardPostDeletedListener implements MessageDeletedListener {
private StarboardPostManagementService starboardPostManagementService;
@Override
public void execute(CachedMessage messageBefore) {
public void execute(CachedMessage messageBefore, AServerAChannelAUser authorUser, GuildChannelMember authorMember) {
Optional<StarboardPost> byStarboardPostId = starboardPostManagementService.findByStarboardPostId(messageBefore.getMessageId());
if(byStarboardPostId.isPresent()) {
StarboardPost post = byStarboardPostId.get();

Some files were not shown because too many files have changed in this diff Show More