[AB-365] introducing slash commands for a selection of commands

adding method for pinning a message
moving suggestion to correct deployment
This commit is contained in:
Sheldan
2022-05-17 00:39:06 +02:00
parent 1913bc930d
commit 1d6de3f1e8
286 changed files with 8021 additions and 3065 deletions

View File

@@ -2,21 +2,21 @@ package dev.sheldan.abstracto.suggestion.command;
import dev.sheldan.abstracto.core.command.UtilityModuleDefinition;
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.command.config.ParameterValidator;
import dev.sheldan.abstracto.core.command.config.*;
import dev.sheldan.abstracto.core.command.config.validator.MinIntegerValueValidator;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandParameterService;
import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.interaction.InteractionService;
import dev.sheldan.abstracto.suggestion.config.SuggestionFeatureDefinition;
import dev.sheldan.abstracto.suggestion.config.SuggestionSlashCommandNames;
import dev.sheldan.abstracto.suggestion.service.SuggestionService;
import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
@@ -25,32 +25,84 @@ import java.util.concurrent.CompletableFuture;
@Slf4j
public class Accept extends AbstractConditionableCommand {
private static final String ACCEPT_COMMAND = "accept";
private static final String SUGGESTION_ID_PARAMETER = "suggestionId";
private static final String TEXT_PARAMETER = "text";
private static final String ACCEPT_RESPONSE = "accept_response";
@Autowired
private SuggestionService suggestionService;
@Autowired
private SlashCommandParameterService slashCommandParameterService;
@Autowired
private InteractionService interactionService;
@Override
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
List<Object> parameters = commandContext.getParameters().getParameters();
Long suggestionId = (Long) parameters.get(0);
String text = parameters.size() == 2 ? (String) parameters.get(1) : "";
log.debug("Using default reason for accept: {}.", parameters.size() != 2);
return suggestionService.acceptSuggestion(suggestionId, commandContext.getMessage(), text)
return suggestionService.acceptSuggestion(suggestionId, commandContext.getAuthor(), text)
.thenApply(aVoid -> CommandResult.fromSuccess());
}
@Override
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
Long suggestionId = slashCommandParameterService.getCommandOption(SUGGESTION_ID_PARAMETER, event, Integer.class).longValue();
String acceptText;
if(slashCommandParameterService.hasCommandOption(TEXT_PARAMETER, event)) {
acceptText = slashCommandParameterService.getCommandOption(TEXT_PARAMETER, event, String.class);
} else {
acceptText = "";
}
return suggestionService.acceptSuggestion(suggestionId, event.getMember(), acceptText)
.thenCompose(unused -> interactionService.replyEmbed(ACCEPT_RESPONSE, event))
.thenApply(aVoid -> CommandResult.fromSuccess());
}
@Override
public CommandConfiguration getConfiguration() {
List<Parameter> parameters = new ArrayList<>();
List<ParameterValidator> suggestionIdValidator = Arrays.asList(MinIntegerValueValidator.min(1L));
parameters.add(Parameter.builder().name("suggestionId").validators(suggestionIdValidator).type(Long.class).templated(true).build());
parameters.add(Parameter.builder().name("text").type(String.class).optional(true).remainder(true).templated(true).build());
HelpInfo helpInfo = HelpInfo.builder().templated(true).hasExample(true).build();
Parameter suggestionIdParameter = Parameter
.builder()
.name(SUGGESTION_ID_PARAMETER)
.validators(suggestionIdValidator)
.type(Long.class)
.templated(true)
.build();
Parameter textParameter = Parameter
.builder()
.name(TEXT_PARAMETER)
.type(String.class)
.optional(true)
.remainder(true)
.templated(true)
.build();
List<Parameter> parameters = Arrays.asList(suggestionIdParameter, textParameter);
HelpInfo helpInfo = HelpInfo
.builder()
.templated(true)
.hasExample(true)
.build();
SlashCommandConfig slashCommandConfig = SlashCommandConfig
.builder()
.enabled(true)
.rootCommandName(SuggestionSlashCommandNames.SUGGEST)
.commandName(ACCEPT_COMMAND)
.build();
return CommandConfiguration.builder()
.name("accept")
.name(ACCEPT_COMMAND)
.module(UtilityModuleDefinition.UTILITY)
.templated(true)
.async(true)
.slashCommandConfig(slashCommandConfig)
.supportsEmbedException(true)
.causesReaction(true)
.parameters(parameters)

View File

@@ -2,17 +2,18 @@ package dev.sheldan.abstracto.suggestion.command;
import dev.sheldan.abstracto.core.command.UtilityModuleDefinition;
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.command.config.ParameterValidator;
import dev.sheldan.abstracto.core.command.config.*;
import dev.sheldan.abstracto.core.command.config.validator.MinIntegerValueValidator;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandParameterService;
import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.interaction.InteractionService;
import dev.sheldan.abstracto.suggestion.config.SuggestionFeatureDefinition;
import dev.sheldan.abstracto.suggestion.config.SuggestionSlashCommandNames;
import dev.sheldan.abstracto.suggestion.service.SuggestionService;
import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -25,31 +26,82 @@ import java.util.concurrent.CompletableFuture;
@Slf4j
public class Reject extends AbstractConditionableCommand {
private static final String REJECT_COMMAND = "reject";
private static final String TEXT_PARAMETER = "text";
private static final String SUGGESTION_ID_PARAMETER = "suggestionId";
private static final String REJECT_RESPONSE = "reject_response";
@Autowired
private SuggestionService suggestionService;
@Autowired
private SlashCommandParameterService slashCommandParameterService;
@Autowired
private InteractionService interactionService;
@Override
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
List<Object> parameters = commandContext.getParameters().getParameters();
Long suggestionId = (Long) parameters.get(0);
String text = parameters.size() == 2 ? (String) parameters.get(1) : "";
log.debug("Using default reason for accept: {}.", parameters.size() != 2);
return suggestionService.rejectSuggestion(suggestionId, commandContext.getMessage(), text)
log.debug("Using default reason for reject: {}.", parameters.size() != 2);
return suggestionService.rejectSuggestion(suggestionId, commandContext.getAuthor(), text)
.thenApply(aVoid -> CommandResult.fromSuccess());
}
@Override
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
Long suggestionId = slashCommandParameterService.getCommandOption(SUGGESTION_ID_PARAMETER, event, Integer.class).longValue();
String rejectText;
if(slashCommandParameterService.hasCommandOption(TEXT_PARAMETER, event)) {
rejectText = slashCommandParameterService.getCommandOption(TEXT_PARAMETER, event, String.class);
} else {
rejectText = "";
}
return suggestionService.rejectSuggestion(suggestionId, event.getMember(), rejectText)
.thenCompose(unused -> interactionService.replyEmbed(REJECT_RESPONSE, event))
.thenApply(aVoid -> CommandResult.fromSuccess());
}
@Override
public CommandConfiguration getConfiguration() {
List<Parameter> parameters = new ArrayList<>();
List<ParameterValidator> suggestionIdValidator = Arrays.asList(MinIntegerValueValidator.min(1L));
parameters.add(Parameter.builder().name("suggestionId").validators(suggestionIdValidator).type(Long.class).templated(true).build());
parameters.add(Parameter.builder().name("text").type(String.class).optional(true).remainder(true).templated(true).build());
HelpInfo helpInfo = HelpInfo.builder().templated(true).hasExample(true).build();
Parameter suggestionIdParameter = Parameter
.builder()
.name(SUGGESTION_ID_PARAMETER)
.validators(suggestionIdValidator)
.type(Long.class)
.templated(true)
.build();
Parameter textParameter = Parameter
.builder()
.name(TEXT_PARAMETER)
.type(String.class)
.optional(true)
.remainder(true)
.templated(true)
.build();
List<Parameter> parameters = Arrays.asList(suggestionIdParameter, textParameter);
HelpInfo helpInfo = HelpInfo
.builder()
.templated(true)
.hasExample(true)
.build();
SlashCommandConfig slashCommandConfig = SlashCommandConfig
.builder()
.enabled(true)
.rootCommandName(SuggestionSlashCommandNames.SUGGEST)
.commandName(REJECT_COMMAND)
.build();
return CommandConfiguration.builder()
.name("reject")
.name(REJECT_COMMAND)
.module(UtilityModuleDefinition.UTILITY)
.templated(true)
.slashCommandConfig(slashCommandConfig)
.async(true)
.supportsEmbedException(true)
.causesReaction(true)

View File

@@ -2,23 +2,23 @@ package dev.sheldan.abstracto.suggestion.command;
import dev.sheldan.abstracto.core.command.UtilityModuleDefinition;
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.command.config.ParameterValidator;
import dev.sheldan.abstracto.core.command.config.*;
import dev.sheldan.abstracto.core.command.config.validator.MinIntegerValueValidator;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandParameterService;
import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.interaction.InteractionService;
import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.core.utils.FutureUtils;
import dev.sheldan.abstracto.suggestion.config.SuggestionFeatureDefinition;
import dev.sheldan.abstracto.suggestion.config.SuggestionSlashCommandNames;
import dev.sheldan.abstracto.suggestion.model.template.SuggestionInfoModel;
import dev.sheldan.abstracto.suggestion.service.SuggestionService;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
@@ -27,6 +27,8 @@ import java.util.concurrent.CompletableFuture;
public class ShowSuggestion extends AbstractConditionableCommand {
public static final String SHOW_SUGGESTION_TEMPLATE_KEY = "suggestion_info_response";
public static final String SHOW_SUGGESTION_COMMAND = "showSuggestion";
public static final String SUGGESTION_ID_PARAMETER = "suggestionId";
@Autowired
private SuggestionService suggestionService;
@@ -34,6 +36,12 @@ public class ShowSuggestion extends AbstractConditionableCommand {
@Autowired
private ChannelService channelService;
@Autowired
private SlashCommandParameterService slashCommandParameterService;
@Autowired
private InteractionService interactionService;
@Override
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
List<Object> parameters = commandContext.getParameters().getParameters();
@@ -45,15 +53,44 @@ public class ShowSuggestion extends AbstractConditionableCommand {
.thenApply(unused -> CommandResult.fromSuccess());
}
@Override
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
Long suggestionId = slashCommandParameterService.getCommandOption(SUGGESTION_ID_PARAMETER, event, Long.class, Integer.class).longValue();
SuggestionInfoModel suggestionInfoModel = suggestionService.getSuggestionInfo(event.getGuild().getIdLong(), suggestionId);
return interactionService.replyEmbed(SHOW_SUGGESTION_TEMPLATE_KEY, suggestionInfoModel, event)
.thenApply(interactionHook -> CommandResult.fromSuccess());
}
@Override
public CommandConfiguration getConfiguration() {
List<Parameter> parameters = new ArrayList<>();
List<ParameterValidator> suggestionIdValidator = Arrays.asList(MinIntegerValueValidator.min(1L));
parameters.add(Parameter.builder().name("suggestionId").validators(suggestionIdValidator).type(Long.class).templated(true).build());
HelpInfo helpInfo = HelpInfo.builder().templated(true).hasExample(false).build();
Parameter suggestionIdParameter = Parameter
.builder()
.name(SUGGESTION_ID_PARAMETER)
.validators(suggestionIdValidator)
.type(Long.class)
.templated(true)
.build();
HelpInfo helpInfo = HelpInfo
.builder()
.templated(true)
.hasExample(false)
.build();
List<Parameter> parameters = Arrays.asList(suggestionIdParameter);
SlashCommandConfig slashCommandConfig = SlashCommandConfig
.builder()
.enabled(true)
.rootCommandName(SuggestionSlashCommandNames.SUGGEST)
.commandName(SHOW_SUGGESTION_COMMAND)
.build();
return CommandConfiguration.builder()
.name("showSuggestion")
.name(SHOW_SUGGESTION_COMMAND)
.slashCommandConfig(slashCommandConfig)
.module(UtilityModuleDefinition.UTILITY)
.templated(true)
.async(true)

View File

@@ -5,42 +5,129 @@ import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.command.config.SlashCommandConfig;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandParameterService;
import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.interaction.InteractionService;
import dev.sheldan.abstracto.core.models.ServerChannelMessageUser;
import dev.sheldan.abstracto.suggestion.config.SuggestionFeatureDefinition;
import dev.sheldan.abstracto.suggestion.config.SuggestionSlashCommandNames;
import dev.sheldan.abstracto.suggestion.service.SuggestionService;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.io.File;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
@Component
public class Suggest extends AbstractConditionableCommand {
private static final String TEXT_PARAMETER = "text";
private static final String SUGGEST_COMMAND = "suggest";
private static final String ATTACHMENT_PARAMETER = "attachment";
private static final String SUGGEST_RESPONSE = "suggest_response";
@Autowired
private SuggestionService suggestionService;
@Autowired
private SlashCommandParameterService slashCommandParameterService;
@Autowired
private InteractionService interactionService;
@Override
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
List<Object> parameters = commandContext.getParameters().getParameters();
String text = (String) parameters.get(0);
return suggestionService.createSuggestionMessage(commandContext.getMessage(), text)
ServerChannelMessageUser cause = ServerChannelMessageUser
.builder()
.serverId(commandContext.getGuild().getIdLong())
.channelId(commandContext.getChannel().getIdLong())
.messageId(commandContext.getMessage().getIdLong())
.userId(commandContext.getAuthor().getIdLong())
.build();
String attachmentURL = commandContext
.getMessage()
.getAttachments()
.stream()
.filter(Message.Attachment::isImage)
.findFirst()
.map(Message.Attachment::getProxyUrl)
.orElse(null);
return suggestionService.createSuggestionMessage(cause, text, attachmentURL)
.thenApply(aVoid -> CommandResult.fromSuccess());
}
@Override
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
String suggestionText = slashCommandParameterService.getCommandOption(TEXT_PARAMETER, event, String.class);
String attachmentURL;
if(slashCommandParameterService.hasCommandOption(ATTACHMENT_PARAMETER, event)) {
Message.Attachment attachment = slashCommandParameterService.getCommandOption(ATTACHMENT_PARAMETER, event, File.class, Message.Attachment.class);
if(attachment.isImage()) {
attachmentURL = attachment.getProxyUrl();
} else {
attachmentURL = null;
}
} else {
attachmentURL = null;
}
ServerChannelMessageUser cause = ServerChannelMessageUser
.builder()
.userId(event.getMember().getIdLong())
.channelId(event.getChannel().getIdLong())
.serverId(event.getGuild().getIdLong())
.build();
return suggestionService.createSuggestionMessage(cause, suggestionText, attachmentURL)
.thenCompose(unused -> interactionService.replyEmbed(SUGGEST_RESPONSE, event))
.thenApply(interactionHook -> CommandResult.fromSuccess());
}
@Override
public CommandConfiguration getConfiguration() {
List<Parameter> parameters = new ArrayList<>();
parameters.add(Parameter.builder().name("text").type(String.class).templated(true).remainder(true).build());
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
Parameter textParameter = Parameter
.builder()
.name(TEXT_PARAMETER)
.type(String.class)
.templated(true)
.remainder(true)
.build();
Parameter fileAttachmentParameter = Parameter
.builder()
.name(ATTACHMENT_PARAMETER)
.type(File.class)
.slashCommandOnly(true)
.templated(true)
.optional(true)
.build();
List<Parameter> parameters = Arrays.asList(textParameter, fileAttachmentParameter);
HelpInfo helpInfo = HelpInfo
.builder()
.templated(true)
.build();
SlashCommandConfig slashCommandConfig = SlashCommandConfig
.builder()
.enabled(true)
.rootCommandName(SuggestionSlashCommandNames.SUGGEST_PUBLIC)
.commandName("create")
.build();
return CommandConfiguration.builder()
.name("suggest")
.name(SUGGEST_COMMAND)
.module(UtilityModuleDefinition.UTILITY)
.templated(true)
.async(true)
.slashCommandConfig(slashCommandConfig)
.supportsEmbedException(true)
.causesReaction(true)
.parameters(parameters)

View File

@@ -2,20 +2,20 @@ package dev.sheldan.abstracto.suggestion.command;
import dev.sheldan.abstracto.core.command.UtilityModuleDefinition;
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.command.config.ParameterValidator;
import dev.sheldan.abstracto.core.command.config.*;
import dev.sheldan.abstracto.core.command.config.validator.MinIntegerValueValidator;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandParameterService;
import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.interaction.InteractionService;
import dev.sheldan.abstracto.suggestion.config.SuggestionFeatureDefinition;
import dev.sheldan.abstracto.suggestion.config.SuggestionSlashCommandNames;
import dev.sheldan.abstracto.suggestion.service.SuggestionService;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
@@ -23,9 +23,19 @@ import java.util.concurrent.CompletableFuture;
@Component
public class UnSuggest extends AbstractConditionableCommand {
private static final String SUGGESTION_ID_PARAMETER = "suggestionId";
private static final String UN_SUGGEST_COMMAND = "unSuggest";
private static final String UN_SUGGEST_RESPONSE = "unSuggest_response";
@Autowired
private SuggestionService suggestionService;
@Autowired
private SlashCommandParameterService slashCommandParameterService;
@Autowired
private InteractionService interactionService;
@Override
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
List<Object> parameters = commandContext.getParameters().getParameters();
@@ -34,16 +44,43 @@ public class UnSuggest extends AbstractConditionableCommand {
.thenApply(aVoid -> CommandResult.fromSuccess());
}
@Override
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
Long suggestionId = slashCommandParameterService.getCommandOption(SUGGESTION_ID_PARAMETER, event, Long.class, Integer.class).longValue();
return suggestionService.removeSuggestion(suggestionId, event.getMember())
.thenCompose(unused -> interactionService.replyEmbed(UN_SUGGEST_RESPONSE, event))
.thenApply(aVoid -> CommandResult.fromSuccess());
}
@Override
public CommandConfiguration getConfiguration() {
List<Parameter> parameters = new ArrayList<>();
List<ParameterValidator> suggestionIdValidator = Arrays.asList(MinIntegerValueValidator.min(1L));
parameters.add(Parameter.builder().name("suggestionId").validators(suggestionIdValidator).type(Long.class).templated(true).build());
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
Parameter suggestionIdParameter = Parameter
.builder()
.name(SUGGESTION_ID_PARAMETER)
.validators(suggestionIdValidator)
.type(Long.class)
.templated(true)
.build();
List<Parameter> parameters = Arrays.asList(suggestionIdParameter);
HelpInfo helpInfo = HelpInfo
.builder()
.templated(true)
.build();
SlashCommandConfig slashCommandConfig = SlashCommandConfig
.builder()
.enabled(true)
.rootCommandName(SuggestionSlashCommandNames.SUGGEST_PUBLIC)
.commandName("remove")
.build();
return CommandConfiguration.builder()
.name("unSuggest")
.name(UN_SUGGEST_COMMAND)
.module(UtilityModuleDefinition.UTILITY)
.templated(true)
.slashCommandConfig(slashCommandConfig)
.async(true)
.supportsEmbedException(true)
.causesReaction(true)

View File

@@ -2,21 +2,21 @@ package dev.sheldan.abstracto.suggestion.command;
import dev.sheldan.abstracto.core.command.UtilityModuleDefinition;
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.command.config.ParameterValidator;
import dev.sheldan.abstracto.core.command.config.*;
import dev.sheldan.abstracto.core.command.config.validator.MinIntegerValueValidator;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandParameterService;
import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.interaction.InteractionService;
import dev.sheldan.abstracto.suggestion.config.SuggestionFeatureDefinition;
import dev.sheldan.abstracto.suggestion.config.SuggestionSlashCommandNames;
import dev.sheldan.abstracto.suggestion.service.SuggestionService;
import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
@@ -25,32 +25,83 @@ import java.util.concurrent.CompletableFuture;
@Component
public class Veto extends AbstractConditionableCommand {
private static final String VETO_COMMAND = "veto";
private static final String TEXT_PARAMETER = "text";
private static final String SUGGESTION_ID_PARAMETER = "suggestionId";
private static final String VETO_RESPONSE = "veto_response";
@Autowired
private SuggestionService suggestionService;
@Autowired
private InteractionService interactionService;
@Autowired
private SlashCommandParameterService slashCommandParameterService;
@Override
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
List<Object> parameters = commandContext.getParameters().getParameters();
Long suggestionId = (Long) parameters.get(0);
String text = parameters.size() == 2 ? (String) parameters.get(1) : "";
log.debug("Using default reason for veto: {}.", parameters.size() != 2);
return suggestionService.vetoSuggestion(suggestionId, commandContext.getMessage(), text)
return suggestionService.vetoSuggestion(suggestionId, commandContext.getAuthor(), text)
.thenApply(aVoid -> CommandResult.fromSuccess());
}
@Override
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
Long suggestionId = slashCommandParameterService.getCommandOption(SUGGESTION_ID_PARAMETER, event, Integer.class).longValue();
String vetoText;
if(slashCommandParameterService.hasCommandOption(TEXT_PARAMETER, event)) {
vetoText = slashCommandParameterService.getCommandOption(TEXT_PARAMETER, event, String.class);
} else {
vetoText = "";
}
return suggestionService.vetoSuggestion(suggestionId, event.getMember(), vetoText)
.thenCompose(unused -> interactionService.replyEmbed(VETO_RESPONSE, event))
.thenApply(aVoid -> CommandResult.fromSuccess());
}
@Override
public CommandConfiguration getConfiguration() {
List<Parameter> parameters = new ArrayList<>();
List<ParameterValidator> suggestionIdValidator = Arrays.asList(MinIntegerValueValidator.min(1L));
parameters.add(Parameter.builder().name("suggestionId").validators(suggestionIdValidator).type(Long.class).templated(true).build());
parameters.add(Parameter.builder().name("text").type(String.class).optional(true).remainder(true).templated(true).build());
HelpInfo helpInfo = HelpInfo.builder().templated(true).hasExample(true).build();
Parameter suggestionIdParameter = Parameter
.builder()
.name(SUGGESTION_ID_PARAMETER)
.validators(suggestionIdValidator)
.type(Long.class)
.templated(true)
.build();
Parameter textParameter = Parameter
.builder()
.name(TEXT_PARAMETER)
.type(String.class)
.optional(true)
.remainder(true)
.templated(true)
.build();
List<Parameter> parameters = Arrays.asList(suggestionIdParameter, textParameter);
HelpInfo helpInfo = HelpInfo
.builder()
.templated(true)
.hasExample(true)
.build();
SlashCommandConfig slashCommandConfig = SlashCommandConfig
.builder()
.enabled(true)
.rootCommandName(SuggestionSlashCommandNames.SUGGEST)
.commandName(VETO_COMMAND)
.build();
return CommandConfiguration.builder()
.name("veto")
.name(VETO_COMMAND)
.module(UtilityModuleDefinition.UTILITY)
.templated(true)
.async(true)
.slashCommandConfig(slashCommandConfig)
.supportsEmbedException(true)
.causesReaction(true)
.parameters(parameters)

View File

@@ -1,6 +1,7 @@
package dev.sheldan.abstracto.suggestion.service;
import dev.sheldan.abstracto.core.models.ServerChannelMessage;
import dev.sheldan.abstracto.core.models.ServerChannelMessageUser;
import dev.sheldan.abstracto.core.models.ServerSpecificId;
import dev.sheldan.abstracto.core.models.ServerUser;
import dev.sheldan.abstracto.core.models.database.AServer;
@@ -61,9 +62,6 @@ public class SuggestionServiceBean implements SuggestionService {
@Autowired
private TemplateService templateService;
@Autowired
private ChannelService channelService;
@Autowired
private MemberService memberService;
@@ -113,14 +111,14 @@ public class SuggestionServiceBean implements SuggestionService {
private Long autoRemovalMaxDays;
@Override
public CompletableFuture<Void> createSuggestionMessage(Message commandMessage, String text) {
public CompletableFuture<Void> createSuggestionMessage(ServerChannelMessageUser cause, String text, String attachmentURL) {
// it is done that way, because we cannot always be sure, that the message contains the member
return memberService.getMemberInServerAsync(commandMessage.getGuild().getIdLong(), commandMessage.getAuthor().getIdLong())
.thenCompose(suggester -> self.createMessageWithSuggester(commandMessage, text, suggester));
return memberService.getMemberInServerAsync(cause.getServerId(), cause.getUserId())
.thenCompose(suggester -> self.createMessageWithSuggester(cause.getChannelId(), cause.getMessageId(), text, suggester, attachmentURL));
}
@Transactional
public CompletableFuture<Void> createMessageWithSuggester(Message commandMessage, String text, Member suggester) {
public CompletableFuture<Void> createMessageWithSuggester(Long suggestionChannelId, Long suggestionMessageId, String text, Member suggester, String attachmentURL) {
postTargetService.validatePostTarget(SuggestionPostTarget.SUGGESTION, suggester.getGuild().getIdLong());
Long serverId = suggester.getGuild().getIdLong();
AServer server = serverManagementService.loadServer(serverId);
@@ -132,7 +130,7 @@ public class SuggestionServiceBean implements SuggestionService {
.suggestionId(newSuggestionId)
.state(SuggestionState.NEW)
.serverId(serverId)
.message(commandMessage)
.attachmentURL(attachmentURL)
.member(suggester)
.suggesterUser(userSuggester)
.useButtons(useButtons)
@@ -146,11 +144,11 @@ public class SuggestionServiceBean implements SuggestionService {
log.info("Creating suggestion with id {} in server {} from member {}.", newSuggestionId, serverId, suggester.getIdLong());
List<CompletableFuture<Message>> completableFutures = postTargetService.sendEmbedInPostTarget(messageToSend, SuggestionPostTarget.SUGGESTION, serverId);
return FutureUtils.toSingleFutureGeneric(completableFutures)
.thenCompose(aVoid -> self.addDeletionPossibility(commandMessage, text, suggester, serverId, newSuggestionId, completableFutures, model));
.thenCompose(aVoid -> self.addDeletionPossibility(suggestionChannelId, suggestionMessageId, text, suggester, serverId, newSuggestionId, completableFutures, model));
}
@Transactional
public CompletableFuture<Void> addDeletionPossibility(Message commandMessage, String text, Member suggester, Long serverId,
public CompletableFuture<Void> addDeletionPossibility(Long suggestionChannelId, Long suggestionMessageId, String text, Member suggester, Long serverId,
Long newSuggestionId, List<CompletableFuture<Message>> completableFutures, SuggestionLog model) {
Message message = completableFutures.get(0).join();
if(model.getUseButtons()) {
@@ -161,7 +159,7 @@ public class SuggestionServiceBean implements SuggestionService {
componentPayloadManagementService.createPayload(model.getAgreeButtonModel(), server);
componentPayloadManagementService.createPayload(model.getDisAgreeButtonModel(), server);
componentPayloadManagementService.createPayload(model.getRemoveVoteButtonModel(), server);
self.persistSuggestionInDatabase(suggester, text, message, newSuggestionId, commandMessage);
self.persistSuggestionInDatabase(suggester, text, message, newSuggestionId, suggestionChannelId, suggestionMessageId);
return CompletableFuture.completedFuture(null);
} else {
log.debug("Posted message, adding reaction for suggestion {} to message {}.", newSuggestionId, message.getId());
@@ -169,7 +167,7 @@ public class SuggestionServiceBean implements SuggestionService {
CompletableFuture<Void> secondReaction = reactionService.addReactionToMessageAsync(SUGGESTION_NO_EMOTE, serverId, message);
return CompletableFuture.allOf(firstReaction, secondReaction).thenAccept(aVoid1 -> {
log.debug("Reaction added to message {} for suggestion {}.", message.getId(), newSuggestionId);
self.persistSuggestionInDatabase(suggester, text, message, newSuggestionId, commandMessage);
self.persistSuggestionInDatabase(suggester, text, message, newSuggestionId, suggestionChannelId, suggestionMessageId);
});
}
}
@@ -193,10 +191,10 @@ public class SuggestionServiceBean implements SuggestionService {
}
@Transactional
public void persistSuggestionInDatabase(Member member, String text, Message message, Long suggestionId, Message commandMessage) {
public void persistSuggestionInDatabase(Member member, String text, Message message, Long suggestionId, Long suggestionChannelId, Long suggestionMessageId) {
Long serverId = member.getGuild().getIdLong();
log.info("Persisting suggestion {} for server {} in database.", suggestionId, serverId);
Suggestion suggestion = suggestionManagementService.createSuggestion(member, text, message, suggestionId, commandMessage);
Suggestion suggestion = suggestionManagementService.createSuggestion(member, text, message, suggestionId, suggestionChannelId, suggestionMessageId);
if(featureModeService.featureModeActive(SuggestionFeatureDefinition.SUGGEST, serverId, SuggestionFeatureMode.SUGGESTION_REMINDER)) {
String triggerKey = scheduleSuggestionReminder(serverId, suggestionId);
suggestion.setSuggestionReminderJobTriggerKey(triggerKey);
@@ -216,14 +214,13 @@ public class SuggestionServiceBean implements SuggestionService {
}
@Override
public CompletableFuture<Void> acceptSuggestion(Long suggestionId, Message commandMessage, String text) {
return memberService.getMemberInServerAsync(commandMessage.getGuild().getIdLong(), commandMessage.getAuthor().getIdLong())
.thenCompose(member -> self.setSuggestionToFinalState(member, suggestionId, commandMessage, text, SuggestionState.ACCEPTED));
public CompletableFuture<Void> acceptSuggestion(Long suggestionId, Member actingMember, String text) {
return self.setSuggestionToFinalState(actingMember, suggestionId, text, SuggestionState.ACCEPTED);
}
@Transactional
public CompletableFuture<Void> setSuggestionToFinalState(Member executingMember, Long suggestionId, Message commandMessage, String text, SuggestionState state) {
Long serverId = commandMessage.getGuild().getIdLong();
public CompletableFuture<Void> setSuggestionToFinalState(Member executingMember, Long suggestionId, String text, SuggestionState state) {
Long serverId = executingMember.getGuild().getIdLong();
postTargetService.validatePostTarget(SuggestionPostTarget.SUGGESTION, serverId);
Suggestion suggestion = suggestionManagementService.getSuggestion(serverId, suggestionId);
suggestionManagementService.setSuggestionState(suggestion, state);
@@ -233,9 +230,8 @@ public class SuggestionServiceBean implements SuggestionService {
}
@Override
public CompletableFuture<Void> vetoSuggestion(Long suggestionId, Message commandMessage, String text) {
return memberService.getMemberInServerAsync(commandMessage.getGuild().getIdLong(), commandMessage.getAuthor().getIdLong())
.thenCompose(member -> self.setSuggestionToFinalState(member, suggestionId, commandMessage, text, SuggestionState.VETOED));
public CompletableFuture<Void> vetoSuggestion(Long suggestionId, Member actingMember, String text) {
return self.setSuggestionToFinalState(actingMember, suggestionId, text, SuggestionState.VETOED);
}
private CompletableFuture<Void> updateSuggestion(Member memberExecutingCommand, String reason, Suggestion suggestion) {
@@ -302,9 +298,8 @@ public class SuggestionServiceBean implements SuggestionService {
}
@Override
public CompletableFuture<Void> rejectSuggestion(Long suggestionId, Message commandMessage, String text) {
return memberService.getMemberInServerAsync(commandMessage.getGuild().getIdLong(), commandMessage.getAuthor().getIdLong())
.thenCompose(member -> self.setSuggestionToFinalState(member, suggestionId, commandMessage, text, SuggestionState.REJECTED));
public CompletableFuture<Void> rejectSuggestion(Long suggestionId, Member actingMember, String text) {
return self.setSuggestionToFinalState(actingMember, suggestionId, text, SuggestionState.REJECTED);
}
@Override

View File

@@ -4,7 +4,6 @@ import dev.sheldan.abstracto.core.models.ServerSpecificId;
import dev.sheldan.abstracto.core.models.database.AChannel;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.suggestion.exception.SuggestionNotFoundException;
import dev.sheldan.abstracto.suggestion.model.database.Suggestion;
@@ -33,20 +32,17 @@ public class SuggestionManagementServiceBean implements SuggestionManagementServ
@Autowired
private UserInServerManagementService userInServerManagementService;
@Autowired
private ServerManagementService serverManagementService;
@Override
public Suggestion createSuggestion(Member suggester, String text, Message message, Long suggestionId, Message commandMessage) {
public Suggestion createSuggestion(Member suggester, String text, Message message, Long suggestionId, Long suggestionChannelId, Long suggestionMessageId) {
AUserInAServer user = userInServerManagementService.loadOrCreateUser(suggester);
return this.createSuggestion(user, text, message, suggestionId, commandMessage);
return this.createSuggestion(user, text, message, suggestionId, suggestionChannelId, suggestionMessageId);
}
@Override
public Suggestion createSuggestion(AUserInAServer suggester, String text, Message createdMessage, Long suggestionId, Message commandMessage) {
public Suggestion createSuggestion(AUserInAServer suggester, String text, Message createdMessage, Long suggestionId, Long suggestionChannelId, Long suggestionMessageId) {
long channelId = createdMessage.getChannel().getIdLong();
AChannel channel = channelManagementService.loadChannel(channelId);
AChannel commandChannel = channelManagementService.loadChannel(commandMessage.getChannel().getIdLong());
AChannel commandChannel = channelManagementService.loadChannel(suggestionChannelId);
Suggestion suggestion = Suggestion
.builder()
.state(SuggestionState.NEW)
@@ -56,7 +52,7 @@ public class SuggestionManagementServiceBean implements SuggestionManagementServ
.server(suggester.getServerReference())
.channel(channel)
.commandChannel(commandChannel)
.commandMessageId(commandMessage.getIdLong())
.commandMessageId(suggestionMessageId)
.messageId(createdMessage.getIdLong())
.build();
log.info("Persisting suggestion {} at message {} in channel {} on server {} from user {}.",

View File

@@ -0,0 +1,10 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog dbchangelog.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd">
<include file="tables/tables.xml" relativeToChangelogFile="true"/>
</databaseChangeLog>

View File

@@ -0,0 +1,12 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog dbchangelog.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" >
<changeSet author="Sheldan" id="remove-required-message-id-suggestion">
<dropNotNullConstraint columnName="command_message_id" tableName="suggestion"/>
</changeSet>
</databaseChangeLog>

View File

@@ -0,0 +1,10 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog dbchangelog.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" >
<include file="suggestion.xml" relativeToChangelogFile="true"/>
</databaseChangeLog>

View File

@@ -10,4 +10,5 @@
<include file="1.2.12/collection.xml" relativeToChangelogFile="true"/>
<include file="1.2.13/collection.xml" relativeToChangelogFile="true"/>
<include file="1.3.8/collection.xml" relativeToChangelogFile="true"/>
<include file="1.4.0/collection.xml" relativeToChangelogFile="true"/>
</databaseChangeLog>

View File

@@ -1,47 +0,0 @@
package dev.sheldan.abstracto.suggestion.command;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.test.command.CommandConfigValidator;
import dev.sheldan.abstracto.core.test.command.CommandTestUtilities;
import dev.sheldan.abstracto.suggestion.model.template.SuggestionLog;
import dev.sheldan.abstracto.suggestion.service.SuggestionService;
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.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.*;
@RunWith(MockitoJUnitRunner.class)
public class AcceptTest {
@InjectMocks
private Accept testUnit;
@Mock
private SuggestionService suggestionService;
@Test
public void testExecuteCommand() throws ExecutionException, InterruptedException {
String text = "text";
Long suggestionId = 5L;
CommandContext context = CommandTestUtilities.getWithParameters(Arrays.asList(suggestionId, text));
when(suggestionService.acceptSuggestion(eq(suggestionId), eq(context.getMessage()), eq(text))).thenReturn(CompletableFuture.completedFuture(null));
CompletableFuture<CommandResult> result = testUnit.executeAsync(context);
verify(suggestionService, times(1)).acceptSuggestion(eq(suggestionId), eq(context.getMessage()), eq(text));
CommandTestUtilities.checkSuccessfulCompletion(result.get());
}
@Test
public void validateCommand() {
CommandConfigValidator.validateCommandConfiguration(testUnit.getConfiguration());
}
}

View File

@@ -1,47 +0,0 @@
package dev.sheldan.abstracto.suggestion.command;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.test.command.CommandConfigValidator;
import dev.sheldan.abstracto.core.test.command.CommandTestUtilities;
import dev.sheldan.abstracto.suggestion.model.template.SuggestionLog;
import dev.sheldan.abstracto.suggestion.service.SuggestionService;
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.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.*;
@RunWith(MockitoJUnitRunner.class)
public class RejectTest {
@InjectMocks
private Reject testUnit;
@Mock
private SuggestionService suggestionService;
@Test
public void testExecuteCommand() throws ExecutionException, InterruptedException {
String text = "text";
Long suggestionId = 5L;
CommandContext context = CommandTestUtilities.getWithParameters(Arrays.asList(suggestionId, text));
when(suggestionService.rejectSuggestion(eq(suggestionId), eq(context.getMessage()), eq(text))).thenReturn(CompletableFuture.completedFuture(null));
CompletableFuture<CommandResult> result = testUnit.executeAsync(context);
verify(suggestionService, times(1)).rejectSuggestion(eq(suggestionId), eq(context.getMessage()), eq(text));
CommandTestUtilities.checkSuccessfulCompletion(result.get());
}
@Test
public void validateCommand() {
CommandConfigValidator.validateCommandConfiguration(testUnit.getConfiguration());
}
}

View File

@@ -1,45 +0,0 @@
package dev.sheldan.abstracto.suggestion.command;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.test.command.CommandConfigValidator;
import dev.sheldan.abstracto.core.test.command.CommandTestUtilities;
import dev.sheldan.abstracto.suggestion.model.template.SuggestionLog;
import dev.sheldan.abstracto.suggestion.service.SuggestionService;
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.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import static org.mockito.Mockito.*;
@RunWith(MockitoJUnitRunner.class)
public class SuggestTest {
@InjectMocks
private Suggest testUnit;
@Mock
private SuggestionService suggestionService;
@Test
public void testExecuteCommand() throws ExecutionException, InterruptedException {
String text = "text";
CommandContext context = CommandTestUtilities.getWithParameters(Arrays.asList(text));
when(suggestionService.createSuggestionMessage(eq(context.getMessage()), eq(text))).thenReturn(CompletableFuture.completedFuture(null));
CompletableFuture<CommandResult> result = testUnit.executeAsync(context);
verify(suggestionService, times(1)).createSuggestionMessage(eq(context.getMessage()), eq(text));
CommandTestUtilities.checkSuccessfulCompletion(result.get());
}
@Test
public void validateCommand() {
CommandConfigValidator.validateCommandConfiguration(testUnit.getConfiguration());
}
}

View File

@@ -1,153 +0,0 @@
package dev.sheldan.abstracto.suggestion.service;
import dev.sheldan.abstracto.core.models.database.AChannel;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.service.*;
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
import dev.sheldan.abstracto.core.templating.service.TemplateService;
import dev.sheldan.abstracto.suggestion.config.SuggestionFeatureDefinition;
import dev.sheldan.abstracto.suggestion.config.SuggestionFeatureMode;
import dev.sheldan.abstracto.suggestion.config.SuggestionPostTarget;
import dev.sheldan.abstracto.suggestion.exception.SuggestionNotFoundException;
import dev.sheldan.abstracto.suggestion.model.database.SuggestionState;
import dev.sheldan.abstracto.suggestion.model.template.SuggestionLog;
import dev.sheldan.abstracto.suggestion.service.management.SuggestionManagementService;
import net.dv8tion.jda.api.entities.*;
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 static org.mockito.Mockito.*;
@RunWith(MockitoJUnitRunner.class)
public class SuggestionServiceBeanTest {
public static final String CLOSING_TEXT = "accepted";
@InjectMocks
private SuggestionServiceBean testUnit;
@Mock
private SuggestionManagementService suggestionManagementService;
@Mock
private PostTargetService postTargetService;
@Mock
private TemplateService templateService;
@Mock
private ChannelService channelService;
@Mock
private MemberService memberService;
@Mock
private ReactionService reactionService;
@Mock
private SuggestionServiceBean self;
@Mock
private Guild guild;
@Mock
private TextChannel textChannel;
@Mock
private CounterService counterService;
@Mock
private UserInServerManagementService userInServerManagementService;
@Mock
private ServerManagementService serverManagementService;
@Mock
private FeatureModeService featureModeService;
@Mock
private UserService userService;
@Mock
private AServer server;
@Mock
private AChannel channel;
@Mock
private AUserInAServer suggester;
@Mock
private User suggesterUser;
@Mock
private Member member;
@Mock
private Message message;
private static final Long SUGGESTER_ID = 8L;
private static final Long SERVER_ID = 3L;
private static final Long CHANNEL_ID = 7L;
private static final Long SUGGESTION_ID = 5L;
private static final Long USER_ID = 6L;
@Test
public void testCreateSuggestionMessage() {
String suggestionText = "text";
when(guild.getIdLong()).thenReturn(SERVER_ID);
when(message.getAuthor()).thenReturn(suggesterUser);
when(message.getGuild()).thenReturn(guild);
when(suggesterUser.getIdLong()).thenReturn(SUGGESTER_ID);
when(memberService.getMemberInServerAsync(SERVER_ID, SUGGESTER_ID)).thenReturn(CompletableFuture.completedFuture(member));
testUnit.createSuggestionMessage(message, suggestionText);
verify(self).createMessageWithSuggester(message, suggestionText, member);
}
@Test
public void testCreateSuggestion() {
when(member.getGuild()).thenReturn(guild);
when(guild.getIdLong()).thenReturn(SERVER_ID);
String text = "text";
Message message = Mockito.mock(Message.class);
Message commandMessage = Mockito.mock(Message.class);
when(featureModeService.featureModeActive(SuggestionFeatureDefinition.SUGGEST, SERVER_ID, SuggestionFeatureMode.SUGGESTION_REMINDER)).thenReturn(false);
testUnit.persistSuggestionInDatabase(member, text, message, SUGGESTION_ID, commandMessage);
verify(suggestionManagementService, times(1)).createSuggestion(member, text, message, SUGGESTION_ID, commandMessage);
}
@Test
public void testAcceptNotExistingSuggestion() {
when(guild.getIdLong()).thenReturn(SERVER_ID);
when(message.getGuild()).thenReturn(guild);
when(message.getAuthor()).thenReturn(suggesterUser);
when(suggesterUser.getIdLong()).thenReturn(SUGGESTER_ID);
when(memberService.getMemberInServerAsync(SERVER_ID, SUGGESTER_ID)).thenReturn(CompletableFuture.completedFuture(member));
testUnit.acceptSuggestion(SUGGESTION_ID, message, CLOSING_TEXT);
verify(self).setSuggestionToFinalState(member, SUGGESTION_ID, message, CLOSING_TEXT, SuggestionState.ACCEPTED);
}
@Test
public void testRejectNotExistingSuggestion() {
when(guild.getIdLong()).thenReturn(SERVER_ID);
when(message.getGuild()).thenReturn(guild);
when(message.getAuthor()).thenReturn(suggesterUser);
when(suggesterUser.getIdLong()).thenReturn(SUGGESTER_ID);
when(memberService.getMemberInServerAsync(SERVER_ID, SUGGESTER_ID)).thenReturn(CompletableFuture.completedFuture(member));
testUnit.rejectSuggestion(SUGGESTION_ID, message, CLOSING_TEXT);
verify(self).setSuggestionToFinalState(member, SUGGESTION_ID, message, CLOSING_TEXT, SuggestionState.REJECTED);
}
}

View File

@@ -1,149 +0,0 @@
package dev.sheldan.abstracto.suggestion.service.management;
import dev.sheldan.abstracto.core.models.ServerSpecificId;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.models.database.AUser;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.suggestion.model.database.Suggestion;
import dev.sheldan.abstracto.suggestion.model.database.SuggestionState;
import dev.sheldan.abstracto.suggestion.repository.SuggestionRepository;
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.MessageChannel;
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 java.util.Optional;
import static org.mockito.Mockito.*;
@RunWith(MockitoJUnitRunner.class)
public class SuggestionManagementServiceBeanTest {
@InjectMocks
private SuggestionManagementServiceBean testUnit;
@Mock
private SuggestionRepository suggestionRepository;
@Mock
private ChannelManagementService channelManagementService;
@Mock
private UserInServerManagementService userInServerManagementService;
@Mock
private ServerManagementService serverManagementService;
@Mock
private AServer server;
@Mock
private AUserInAServer aUserInAServer;
@Mock
private AUser aUser;
public static final long CHANNEL_ID = 6L;
public static final long SERVER_ID = 6L;
public static final long SUGGESTION_ID = 6L;
@Test
public void testCreateSuggestionViaUser() {
String text = "text";
when(aUserInAServer.getServerReference()).thenReturn(server);
when(aUserInAServer.getUserReference()).thenReturn(aUser);
Guild guild = Mockito.mock(Guild.class);
Message message = Mockito.mock(Message.class);
MessageChannel messageChannel = Mockito.mock(MessageChannel.class);
when(messageChannel.getIdLong()).thenReturn(CHANNEL_ID);
when(message.getChannel()).thenReturn(messageChannel);
when(message.getGuild()).thenReturn(guild);
when(guild.getId()).thenReturn("8");
long suggestionId = 1L;
ArgumentCaptor<Suggestion> suggestionArgumentCaptor = ArgumentCaptor.forClass(Suggestion.class);
Suggestion savedSuggestion = Mockito.mock(Suggestion.class);
when(suggestionRepository.save(suggestionArgumentCaptor.capture())).thenReturn(savedSuggestion);
Message commandMessage = Mockito.mock(Message.class);
when(commandMessage.getChannel()).thenReturn(messageChannel);
Suggestion createdSuggestion = testUnit.createSuggestion(aUserInAServer, text, message, suggestionId, commandMessage);
Assert.assertEquals(savedSuggestion, createdSuggestion);
Suggestion capturedSuggestion = suggestionArgumentCaptor.getValue();
Assert.assertEquals(SuggestionState.NEW, capturedSuggestion.getState());
Assert.assertEquals(aUserInAServer, capturedSuggestion.getSuggester());
Assert.assertEquals(server, capturedSuggestion.getServer());
}
@Test
public void testCreateSuggestionViaMember() {
Member member = Mockito.mock(Member.class);
String text = "text";
Guild guild = Mockito.mock(Guild.class);
Message message = Mockito.mock(Message.class);
MessageChannel messageChannel = Mockito.mock(MessageChannel.class);
when(messageChannel.getIdLong()).thenReturn(CHANNEL_ID);
when(aUserInAServer.getServerReference()).thenReturn(server);
when(aUserInAServer.getUserReference()).thenReturn(aUser);
when(message.getChannel()).thenReturn(messageChannel);
when(message.getGuild()).thenReturn(guild);
when(guild.getId()).thenReturn("5");
when(userInServerManagementService.loadOrCreateUser(member)).thenReturn(aUserInAServer);
long suggestionId = 1L;
ArgumentCaptor<Suggestion> suggestionArgumentCaptor = ArgumentCaptor.forClass(Suggestion.class);
Suggestion savedSuggestion = Mockito.mock(Suggestion.class);
when(suggestionRepository.save(suggestionArgumentCaptor.capture())).thenReturn(savedSuggestion);
Message commandMessage = Mockito.mock(Message.class);
when(commandMessage.getChannel()).thenReturn(messageChannel);
Suggestion createdSuggestion = testUnit.createSuggestion(member, text, message, suggestionId, commandMessage);
Assert.assertEquals(savedSuggestion, createdSuggestion);
Suggestion capturedSuggestion = suggestionArgumentCaptor.getValue();
Assert.assertEquals(SuggestionState.NEW, capturedSuggestion.getState());
Assert.assertEquals(aUserInAServer, capturedSuggestion.getSuggester());
Assert.assertEquals(server, capturedSuggestion.getServer());
}
@Test
public void testGetSuggestion() {
Suggestion foundSuggestion = createSuggestion();
when(suggestionRepository.findById(new ServerSpecificId(SERVER_ID, SUGGESTION_ID))).thenReturn(Optional.of(foundSuggestion));
Optional<Suggestion> suggestionOptional = testUnit.getSuggestionOptional(SERVER_ID, SUGGESTION_ID);
Assert.assertTrue(suggestionOptional.isPresent());
suggestionOptional.ifPresent(suggestion -> Assert.assertEquals(SUGGESTION_ID, suggestion.getSuggestionId().getId().longValue()));
}
@Test
public void testGetSuggestionNotFound() {
when(suggestionRepository.findById(new ServerSpecificId(SERVER_ID, SUGGESTION_ID))).thenReturn(Optional.empty());
Optional<Suggestion> suggestionOptional = testUnit.getSuggestionOptional(SERVER_ID, SUGGESTION_ID);
Assert.assertFalse(suggestionOptional.isPresent());
}
@Test
public void setSuggestionState() {
Suggestion suggestion = createSuggestion();
testUnit.setSuggestionState(suggestion, SuggestionState.ACCEPTED);
verify(suggestion, times(1)).setState(SuggestionState.ACCEPTED);
verify(suggestionRepository, times(1)).save(suggestion);
}
private Suggestion createSuggestion() {
Suggestion foundSuggestion = Mockito.mock(Suggestion.class);
ServerSpecificId suggestionId = Mockito.mock(ServerSpecificId.class);
when(suggestionId.getId()).thenReturn(SUGGESTION_ID);
when(suggestionId.getServerId()).thenReturn(SERVER_ID);
when(foundSuggestion.getSuggestionId()).thenReturn(suggestionId);
return foundSuggestion;
}
}