added tests for utility module

refactored various commands and services
optimized code for message embeds
removed emoteUtils completely and moved to service
removed suggestion validation, because its now done via feature config
fixed regex for discord links
changed template to handle the case in which a member which suggested it originally left the server
added suggestion update exception in cases the message to edit, does not qualify as a suggestion
added check to not allow cross server quoting and added test case
refactored mocking for jda objects
This commit is contained in:
Sheldan
2020-06-07 00:22:42 +02:00
parent a577932c42
commit ac93440546
91 changed files with 3721 additions and 425 deletions

View File

@@ -2,15 +2,11 @@ package dev.sheldan.abstracto.core.listener;
import dev.sheldan.abstracto.core.config.FeatureConfig;
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
import dev.sheldan.abstracto.core.service.BotService;
import dev.sheldan.abstracto.core.service.FeatureConfigService;
import dev.sheldan.abstracto.core.service.FeatureFlagService;
import dev.sheldan.abstracto.core.service.*;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
import dev.sheldan.abstracto.core.models.cache.CachedReaction;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.service.MessageCache;
import dev.sheldan.abstracto.core.utils.EmoteUtils;
import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.events.message.guild.react.GuildMessageReactionAddEvent;
import net.dv8tion.jda.api.events.message.guild.react.GuildMessageReactionRemoveAllEvent;
@@ -56,6 +52,9 @@ public class ReactionUpdatedListener extends ListenerAdapter {
@Autowired
private BotService botService;
@Autowired
private EmoteService emoteService;
@Override
@Transactional
public void onGuildMessageReactionAdd(@Nonnull GuildMessageReactionAddEvent event) {
@@ -79,7 +78,7 @@ public class ReactionUpdatedListener extends ListenerAdapter {
private void addReactionIfNotThere(CachedMessage message, CachedReaction reaction, AUserInAServer userReacting) {
Optional<CachedReaction> existingReaction = message.getReactions().stream().filter(reaction1 ->
EmoteUtils.compareAEmote(reaction1.getEmote(), reaction.getEmote())
emoteService.compareAEmote(reaction1.getEmote(), reaction.getEmote())
).findAny();
if(!existingReaction.isPresent()) {
message.getReactions().add(reaction);
@@ -94,7 +93,7 @@ public class ReactionUpdatedListener extends ListenerAdapter {
private void removeReactionIfThere(CachedMessage message, CachedReaction reaction, AUserInAServer userReacting) {
Optional<CachedReaction> existingReaction = message.getReactions().stream().filter(reaction1 ->
EmoteUtils.compareAEmote(reaction1.getEmote(), reaction.getEmote())
emoteService.compareAEmote(reaction1.getEmote(), reaction.getEmote())
).findAny();
if(existingReaction.isPresent()) {
CachedReaction cachedReaction = existingReaction.get();

View File

@@ -2,6 +2,8 @@ package dev.sheldan.abstracto.core.service;
import dev.sheldan.abstracto.core.config.DynamicKeyLoader;
import dev.sheldan.abstracto.core.exception.EmoteNotDefinedException;
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
import dev.sheldan.abstracto.core.models.cache.CachedReaction;
import dev.sheldan.abstracto.core.models.database.AEmote;
import dev.sheldan.abstracto.core.service.management.EmoteManagementService;
import lombok.extern.slf4j.Slf4j;
@@ -93,4 +95,37 @@ public class EmoteServiceBean implements EmoteService {
public String getDefaultEmote(String emoteKey) {
return keyLoader.getDefaultEmotes().get(emoteKey);
}
@Override
public boolean isReactionEmoteAEmote(MessageReaction.ReactionEmote reaction, AEmote storedEmote, Emote actualEmoteInGuild) {
if(reaction.isEmote() && storedEmote.getCustom()) {
if(actualEmoteInGuild != null) {
return actualEmoteInGuild.equals(reaction.getEmote());
} else {
return false;
}
} else if(reaction.isEmoji()){
return reaction.getEmoji().equals(storedEmote.getEmoteKey());
}
return false;
}
@Override
public Optional<CachedReaction> getReactionFromMessageByEmote(CachedMessage message, AEmote emote) {
return message.getReactions().stream().filter(reaction -> compareAEmote(reaction.getEmote(), emote)).findFirst();
}
@Override
public boolean compareAEmote(AEmote a, AEmote b) {
if(Boolean.TRUE.equals(a.getCustom()) && Boolean.TRUE.equals(b.getCustom())) {
return a.getEmoteId().equals(b.getEmoteId());
} else {
if(Boolean.FALSE.equals(a.getCustom()) && Boolean.FALSE.equals(b.getCustom())) {
return a.getEmoteKey().equals(b.getEmoteKey());
} else {
return false;
}
}
}
}

View File

@@ -132,22 +132,23 @@ public class PostTargetServiceBean implements PostTargetService {
}
@Override
public void editOrCreatedInPostTarget(Long messageId, MessageToSend messageToSend, PostTarget target, List<CompletableFuture<Message>> future) {
public List<CompletableFuture<Message>> editOrCreatedInPostTarget(Long messageId, MessageToSend messageToSend, PostTarget target) {
List<CompletableFuture<Message>> futures = new ArrayList<>();
TextChannel textChannelForPostTarget = getTextChannelForPostTarget(target);
CompletableFuture<Message> messageEditFuture = new CompletableFuture<>();
futures.add(messageEditFuture);
if(StringUtils.isBlank(messageToSend.getMessage().trim())) {
textChannelForPostTarget
.retrieveMessageById(messageId)
.queue(
existingMessage -> existingMessage
.editMessage(messageToSend.getEmbeds().get(0))
.submit().thenAccept(message -> future.get(0).complete(message)).exceptionally(throwable -> {
log.error("Failed to edit message {}.", messageId, throwable);
return null;
}),
.queue(messageEditFuture::complete, messageEditFuture::completeExceptionally),
throwable ->
sendEmbedInPostTarget(messageToSend, target).get(0)
.thenAccept(message -> future.get(0).complete(message)) .exceptionally(innerThrowable -> {
.thenAccept(messageEditFuture::complete).exceptionally(innerThrowable -> {
log.error("Failed to send message to create a message.", innerThrowable);
messageEditFuture.completeExceptionally(innerThrowable);
return null;
})
);
@@ -158,24 +159,24 @@ public class PostTargetServiceBean implements PostTargetService {
existingMessage -> existingMessage
.editMessage(messageToSend.getMessage())
.embed(messageToSend.getEmbeds().get(0))
.submit().thenAccept(message -> future.get(0).complete(message)).exceptionally(throwable -> {
log.error("Failed to edit message {}", messageId, throwable);
return null;
}),
.queue(messageEditFuture::complete, messageEditFuture::completeExceptionally),
throwable ->
sendEmbedInPostTarget(messageToSend, target).get(0)
.thenAccept(message -> future.get(0).complete(message)).exceptionally(innerThrowable -> {
.thenAccept(messageEditFuture::complete).exceptionally(innerThrowable -> {
log.error("Failed to send message to create a message.", innerThrowable);
messageEditFuture.completeExceptionally(innerThrowable);
return null;
})
);
}
return futures;
}
@Override
public void editOrCreatedInPostTarget(Long messageId, MessageToSend messageToSend, PostTargetEnum postTargetName, Long serverId, List<CompletableFuture<Message>> future) {
public List<CompletableFuture<Message>> editOrCreatedInPostTarget(Long messageId, MessageToSend messageToSend, PostTargetEnum postTargetName, Long serverId) {
PostTarget postTarget = this.getPostTarget(postTargetName, serverId);
this.editOrCreatedInPostTarget(messageId, messageToSend, postTarget, future);
return this.editOrCreatedInPostTarget(messageId, messageToSend, postTarget);
}
@Override

View File

@@ -1,9 +1,13 @@
package dev.sheldan.abstracto.core.service;
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
import dev.sheldan.abstracto.core.models.cache.CachedReaction;
import dev.sheldan.abstracto.core.models.database.AEmote;
import net.dv8tion.jda.api.entities.Emote;
import net.dv8tion.jda.api.entities.MessageReaction;
import java.util.Optional;
public interface EmoteService {
boolean isEmoteUsableByBot(Emote emote);
AEmote buildAEmoteFromReaction(MessageReaction.ReactionEmote reaction);
@@ -13,4 +17,7 @@ public interface EmoteService {
void throwIfEmoteDoesNotExist(String emoteKey, Long serverId);
AEmote getEmoteOrFakeEmote(String emoteKey, Long serverId);
String getDefaultEmote(String emoteKey);
boolean isReactionEmoteAEmote(MessageReaction.ReactionEmote reaction, AEmote storedEmote, Emote actualEmoteInGuild);
Optional<CachedReaction> getReactionFromMessageByEmote(CachedMessage message, AEmote emote);
boolean compareAEmote(AEmote a, AEmote b);
}

View File

@@ -21,8 +21,8 @@ public interface PostTargetService {
List<CompletableFuture<Message>> sendEmbedInPostTarget(MessageToSend message, PostTarget target);
List<CompletableFuture<Message>> editEmbedInPostTarget(Long messageId, MessageToSend message, PostTarget target);
List<CompletableFuture<Message>> editEmbedInPostTarget(Long messageId, MessageToSend message, PostTargetEnum postTargetName, Long serverId);
void editOrCreatedInPostTarget(Long messageId, MessageToSend messageToSend, PostTarget target, List<CompletableFuture<Message>> future);
void editOrCreatedInPostTarget(Long messageId, MessageToSend messageToSend, PostTargetEnum postTarget, Long serverId, List<CompletableFuture<Message>> future);
List<CompletableFuture<Message>> editOrCreatedInPostTarget(Long messageId, MessageToSend messageToSend, PostTarget target);
List<CompletableFuture<Message>> editOrCreatedInPostTarget(Long messageId, MessageToSend messageToSend, PostTargetEnum postTarget, Long serverId);
void throwIfPostTargetIsNotDefined(PostTargetEnum name, Long serverId);
boolean validPostTarget(String name);
List<PostTarget> getPostTargets(AServer server);

View File

@@ -1,46 +0,0 @@
package dev.sheldan.abstracto.core.utils;
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
import dev.sheldan.abstracto.core.models.cache.CachedReaction;
import dev.sheldan.abstracto.core.models.database.AEmote;
import net.dv8tion.jda.api.entities.Emote;
import net.dv8tion.jda.api.entities.MessageReaction;
import java.util.Optional;
public class EmoteUtils {
private EmoteUtils() {
}
public static boolean isReactionEmoteAEmote(MessageReaction.ReactionEmote reaction, AEmote emote, Emote emoteInGuild) {
if(reaction.isEmote() && emote.getCustom()) {
if(emoteInGuild != null) {
return emoteInGuild.equals(reaction.getEmote());
} else {
return false;
}
} else if(reaction.isEmoji()){
return reaction.getEmoji().equals(emote.getEmoteKey());
}
return false;
}
public static Optional<CachedReaction> getReactionFromMessageByEmote(CachedMessage message, AEmote emote) {
return message.getReactions().stream().filter(reaction -> compareAEmote(reaction.getEmote(), emote)).findFirst();
}
public static boolean compareAEmote(AEmote a, AEmote b) {
if(Boolean.TRUE.equals(a.getCustom()) && Boolean.TRUE.equals(b.getCustom())) {
return a.getEmoteId().equals(b.getEmoteId());
} else {
if(Boolean.FALSE.equals(a.getCustom()) && Boolean.FALSE.equals(b.getCustom())) {
return a.getEmoteKey().equals(b.getEmoteKey());
} else {
return false;
}
}
}
}