mirror of
https://github.com/Sheldan/abstracto.git
synced 2026-04-14 03:45:57 +00:00
[AB-197] splitting utility maven module into separate maven modules
aligning some package names removing some unnecessary computed values from liquibase
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.1.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.1.0 http://maven.apache.org/xsd/assembly-2.1.0.xsd">
|
||||
<id>liquibase</id>
|
||||
<formats>
|
||||
<format>zip</format>
|
||||
</formats>
|
||||
<includeBaseDirectory>false</includeBaseDirectory>
|
||||
<fileSets>
|
||||
<fileSet>
|
||||
<outputDirectory>.</outputDirectory>
|
||||
<directory>${project.basedir}/src/main/resources/migrations</directory>
|
||||
<includes>
|
||||
<include>**/*</include>
|
||||
</includes>
|
||||
</fileSet>
|
||||
</fileSets>
|
||||
</assembly>
|
||||
@@ -0,0 +1,10 @@
|
||||
package dev.sheldan.abstracto.linkembed.config;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.PropertySource;
|
||||
|
||||
@Configuration
|
||||
@PropertySource("classpath:link-embed-config.properties")
|
||||
public class LinkEmbedConfig {
|
||||
}
|
||||
|
||||
@@ -0,0 +1,125 @@
|
||||
package dev.sheldan.abstracto.linkembed.listener;
|
||||
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.config.ListenerPriority;
|
||||
import dev.sheldan.abstracto.core.execution.result.ExecutionResult;
|
||||
import dev.sheldan.abstracto.core.execution.result.MessageReceivedListenerResult;
|
||||
import dev.sheldan.abstracto.core.listener.sync.jda.MessageReceivedListener;
|
||||
import dev.sheldan.abstracto.core.metric.service.CounterMetric;
|
||||
import dev.sheldan.abstracto.core.metric.service.MetricService;
|
||||
import dev.sheldan.abstracto.core.metric.service.MetricTag;
|
||||
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
|
||||
import dev.sheldan.abstracto.core.service.MessageCache;
|
||||
import dev.sheldan.abstracto.core.service.MessageService;
|
||||
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
||||
import dev.sheldan.abstracto.linkembed.config.LinkEmbedFeatureDefinition;
|
||||
import dev.sheldan.abstracto.linkembed.model.MessageEmbedLink;
|
||||
import dev.sheldan.abstracto.linkembed.service.MessageEmbedService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
import net.dv8tion.jda.api.events.Event;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class MessageEmbedListener implements MessageReceivedListener {
|
||||
|
||||
@Autowired
|
||||
private MessageCache messageCache;
|
||||
|
||||
@Autowired
|
||||
private UserInServerManagementService userInServerManagementService;
|
||||
|
||||
@Autowired
|
||||
private MessageEmbedService messageEmbedService;
|
||||
|
||||
@Autowired
|
||||
private MessageEmbedListener self;
|
||||
|
||||
@Autowired
|
||||
private MetricService metricService;
|
||||
|
||||
@Autowired
|
||||
private MessageService messageService;
|
||||
|
||||
public static final String MESSAGE_EMBEDDED = "message.embedded";
|
||||
public static final String MESSAGE_EMBED_ACTION = "action";
|
||||
private static final CounterMetric MESSAGE_EMBED_CREATED = CounterMetric
|
||||
.builder()
|
||||
.name(MESSAGE_EMBEDDED)
|
||||
.tagList(Arrays.asList(MetricTag.getTag(MESSAGE_EMBED_ACTION, "created")))
|
||||
.build();
|
||||
|
||||
@Override
|
||||
public MessageReceivedListenerResult execute(Message message) {
|
||||
String messageRaw = message.getContentRaw();
|
||||
List<MessageEmbedLink> links = messageEmbedService.getLinksInMessage(messageRaw);
|
||||
if(!links.isEmpty()) {
|
||||
log.trace("We found {} links to embed in message {} in channel {} in guild {}.", links.size(), message.getId(), message.getChannel().getId(), message.getGuild().getId());
|
||||
Long userEmbeddingUserInServerId = userInServerManagementService.loadOrCreateUser(message.getMember()).getUserInServerId();
|
||||
for (MessageEmbedLink messageEmbedLink : links) {
|
||||
if(!messageEmbedLink.getServerId().equals(message.getGuild().getIdLong())) {
|
||||
log.info("Link for message {} was from a foreign server {}. Do not embed.", messageEmbedLink.getMessageId(), messageEmbedLink.getServerId());
|
||||
continue;
|
||||
}
|
||||
messageRaw = messageRaw.replace(messageEmbedLink.getWholeUrl(), "");
|
||||
Consumer<CachedMessage> cachedMessageConsumer = cachedMessage -> self.embedSingleLink(message, userEmbeddingUserInServerId, cachedMessage);
|
||||
messageCache.getMessageFromCache(messageEmbedLink.getServerId(), messageEmbedLink.getChannelId(), messageEmbedLink.getMessageId())
|
||||
.thenAccept(cachedMessageConsumer)
|
||||
.exceptionally(throwable -> {
|
||||
log.error("Error when embedding link for message {}", message.getId(), throwable);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
}
|
||||
if(StringUtils.isBlank(messageRaw) && !links.isEmpty()) {
|
||||
messageService.deleteMessage(message);
|
||||
return MessageReceivedListenerResult.DELETED;
|
||||
}
|
||||
if(!links.isEmpty()) {
|
||||
return MessageReceivedListenerResult.PROCESSED;
|
||||
}
|
||||
return MessageReceivedListenerResult.IGNORED;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void embedSingleLink(Message message, Long cause, CachedMessage cachedMessage) {
|
||||
log.info("Embedding link to message {} in channel {} in server {} to channel {} and server {}.",
|
||||
cachedMessage.getMessageId(), cachedMessage.getChannelId(), cachedMessage.getServerId(), message.getChannel().getId(), message.getGuild().getId());
|
||||
messageEmbedService.embedLink(cachedMessage, message.getTextChannel(), cause , message).thenAccept(unused ->
|
||||
metricService.incrementCounter(MESSAGE_EMBED_CREATED)
|
||||
).exceptionally(throwable -> {
|
||||
log.error("Failed to embed link towards message {} in channel {} in sever {} linked from message {} in channel {} in server {}.", cachedMessage.getMessageId(), cachedMessage.getChannelId(), cachedMessage.getServerId(),
|
||||
message.getId(), message.getChannel().getId(), message.getGuild().getId(), throwable);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldConsume(Event event, ExecutionResult result) {
|
||||
return result.equals(MessageReceivedListenerResult.DELETED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FeatureDefinition getFeature() {
|
||||
return LinkEmbedFeatureDefinition.LINK_EMBEDS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getPriority() {
|
||||
return ListenerPriority.MEDIUM;
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void postConstruct() {
|
||||
metricService.registerCounter(MESSAGE_EMBED_CREATED, "Message embeds created");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
package dev.sheldan.abstracto.linkembed.listener;
|
||||
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.listener.async.jda.AsyncReactionAddedListener;
|
||||
import dev.sheldan.abstracto.core.metric.service.CounterMetric;
|
||||
import dev.sheldan.abstracto.core.metric.service.MetricService;
|
||||
import dev.sheldan.abstracto.core.metric.service.MetricTag;
|
||||
import dev.sheldan.abstracto.core.models.ServerUser;
|
||||
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
|
||||
import dev.sheldan.abstracto.core.models.cache.CachedReactions;
|
||||
import dev.sheldan.abstracto.core.models.database.AEmote;
|
||||
import dev.sheldan.abstracto.core.service.BotService;
|
||||
import dev.sheldan.abstracto.core.service.EmoteService;
|
||||
import dev.sheldan.abstracto.core.service.MessageService;
|
||||
import dev.sheldan.abstracto.linkembed.config.LinkEmbedFeatureDefinition;
|
||||
import dev.sheldan.abstracto.linkembed.model.database.EmbeddedMessage;
|
||||
import dev.sheldan.abstracto.linkembed.service.management.MessageEmbedPostManagementService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.util.Arrays;
|
||||
import java.util.Optional;
|
||||
|
||||
import static dev.sheldan.abstracto.linkembed.listener.MessageEmbedListener.MESSAGE_EMBEDDED;
|
||||
import static dev.sheldan.abstracto.linkembed.listener.MessageEmbedListener.MESSAGE_EMBED_ACTION;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class MessageEmbedRemovalReactionListener implements AsyncReactionAddedListener {
|
||||
|
||||
public static final String REMOVAL_EMOTE = "removeEmbed";
|
||||
|
||||
@Autowired
|
||||
private BotService botService;
|
||||
|
||||
@Autowired
|
||||
private MessageEmbedPostManagementService messageEmbedPostManagementService;
|
||||
|
||||
@Autowired
|
||||
private MessageService messageService;
|
||||
|
||||
@Autowired
|
||||
private EmoteService emoteService;
|
||||
|
||||
@Autowired
|
||||
private MetricService metricService;
|
||||
|
||||
private static final CounterMetric MESSAGE_EMBED_REMOVED_CREATOR = CounterMetric
|
||||
.builder()
|
||||
.name(MESSAGE_EMBEDDED)
|
||||
.tagList(Arrays.asList(MetricTag.getTag(MESSAGE_EMBED_ACTION, "removed.creator")))
|
||||
.build();
|
||||
|
||||
private static final CounterMetric MESSAGE_EMBED_REMOVED_SOURCE = CounterMetric
|
||||
.builder()
|
||||
.name(MESSAGE_EMBEDDED)
|
||||
.tagList(Arrays.asList(MetricTag.getTag(MESSAGE_EMBED_ACTION, "removed.source")))
|
||||
.build();
|
||||
|
||||
|
||||
@Override
|
||||
public void executeReactionAdded(CachedMessage message, CachedReactions cachedReaction, ServerUser serverUser) {
|
||||
Long guildId = message.getServerId();
|
||||
AEmote aEmote = emoteService.getEmoteOrDefaultEmote(REMOVAL_EMOTE, guildId);
|
||||
if(emoteService.compareCachedEmoteWithAEmote(cachedReaction.getEmote(), aEmote)) {
|
||||
Optional<EmbeddedMessage> embeddedMessageOptional = messageEmbedPostManagementService.findEmbeddedPostByMessageId(message.getMessageId());
|
||||
if(embeddedMessageOptional.isPresent()) {
|
||||
EmbeddedMessage embeddedMessage = embeddedMessageOptional.get();
|
||||
boolean embeddedUserRemoves = embeddedMessage.getEmbeddedUser().getUserReference().getId().equals(serverUser.getUserId());
|
||||
boolean embeddingUserRemoves = embeddedMessage.getEmbeddingUser().getUserReference().getId().equals(serverUser.getUserId());
|
||||
if(embeddedUserRemoves || embeddingUserRemoves) {
|
||||
log.info("Removing embed in message {} in channel {} in server {} because of a user reaction.", message.getMessageId(), message.getChannelId(), message.getServerId());
|
||||
messageService.deleteMessageInChannelInServer(message.getServerId(), message.getChannelId(), message.getMessageId()).thenAccept(aVoid -> {
|
||||
Optional<EmbeddedMessage> innerOptional = messageEmbedPostManagementService.findEmbeddedPostByMessageId(message.getMessageId());
|
||||
innerOptional.ifPresent(value -> messageEmbedPostManagementService.deleteEmbeddedMessage(value));
|
||||
if(embeddedUserRemoves) {
|
||||
metricService.incrementCounter(MESSAGE_EMBED_REMOVED_SOURCE);
|
||||
} else {
|
||||
metricService.incrementCounter(MESSAGE_EMBED_REMOVED_CREATOR);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
log.trace("Somebody besides the original author and the user embedding added the removal reaction to the message {} in channel {} in server {}.",
|
||||
message.getMessageId(), message.getChannelId(), message.getServerId());
|
||||
}
|
||||
|
||||
} else {
|
||||
log.trace("Removal emote was placed on a message which was not recognized as an embedded message.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public FeatureDefinition getFeature() {
|
||||
return LinkEmbedFeatureDefinition.LINK_EMBEDS;
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void postConstruct() {
|
||||
metricService.registerCounter(MESSAGE_EMBED_REMOVED_CREATOR, "Message embeds which are created by the embedding user.");
|
||||
metricService.registerCounter(MESSAGE_EMBED_REMOVED_SOURCE, "Message embeds which are created by the embedded user.");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package dev.sheldan.abstracto.linkembed.repository;
|
||||
|
||||
|
||||
import dev.sheldan.abstracto.linkembed.model.database.EmbeddedMessage;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
public interface EmbeddedMessageRepository extends JpaRepository<EmbeddedMessage, Long> {
|
||||
|
||||
EmbeddedMessage findByEmbeddingMessageId(Long messageId);
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
package dev.sheldan.abstracto.linkembed.service;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.core.models.template.listener.MessageEmbeddedModel;
|
||||
import dev.sheldan.abstracto.core.service.*;
|
||||
import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
|
||||
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
|
||||
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
||||
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
|
||||
import dev.sheldan.abstracto.core.templating.service.TemplateService;
|
||||
import dev.sheldan.abstracto.linkembed.model.MessageEmbedLink;
|
||||
import dev.sheldan.abstracto.linkembed.service.management.MessageEmbedPostManagementService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
import net.dv8tion.jda.api.entities.TextChannel;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class MessageEmbedServiceBean implements MessageEmbedService {
|
||||
|
||||
private Pattern messageRegex = Pattern.compile("(?<whole>https://discord(?:app)?.com/channels/(?<server>\\d+)/(?<channel>\\d+)/(?<message>\\d+)(?:.*?))+");
|
||||
|
||||
public static final String MESSAGE_EMBED_TEMPLATE = "message_embed";
|
||||
public static final String REMOVAL_EMOTE = "removeEmbed";
|
||||
|
||||
@Autowired
|
||||
private ChannelManagementService channelManagementService;
|
||||
|
||||
@Autowired
|
||||
private ServerManagementService serverManagementService;
|
||||
|
||||
@Autowired
|
||||
private UserInServerManagementService userInServerManagementService;
|
||||
|
||||
@Autowired
|
||||
private MemberService memberService;
|
||||
|
||||
@Autowired
|
||||
private TemplateService templateService;
|
||||
|
||||
@Autowired
|
||||
private ChannelService channelService;
|
||||
|
||||
@Autowired
|
||||
private MessageEmbedServiceBean self;
|
||||
|
||||
@Autowired
|
||||
private MessageCache messageCache;
|
||||
|
||||
@Autowired
|
||||
private MessageEmbedPostManagementService messageEmbedPostManagementService;
|
||||
|
||||
@Autowired
|
||||
private ReactionService reactionService;
|
||||
|
||||
@Override
|
||||
public List<MessageEmbedLink> getLinksInMessage(String message) {
|
||||
List<MessageEmbedLink> links = new ArrayList<>();
|
||||
Matcher matcher = messageRegex.matcher(message);
|
||||
while(matcher.find()) {
|
||||
String serverId = matcher.group("server");
|
||||
String channelId = matcher.group("channel");
|
||||
String messageId = matcher.group("message");
|
||||
String wholeLink = matcher.group("whole");
|
||||
Long serverIdLong = Long.parseLong(serverId);
|
||||
Long channelIdLong = Long.parseLong(channelId);
|
||||
Long messageIdLong = Long.parseLong(messageId);
|
||||
MessageEmbedLink messageEmbedLink = MessageEmbedLink
|
||||
.builder()
|
||||
.serverId(serverIdLong)
|
||||
.channelId(channelIdLong)
|
||||
.messageId(messageIdLong)
|
||||
.wholeUrl(wholeLink)
|
||||
.build();
|
||||
links.add(messageEmbedLink);
|
||||
}
|
||||
return links;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void embedLinks(List<MessageEmbedLink> linksToEmbed, TextChannel target, Long userEmbeddingUserInServerId, Message embeddingMessage) {
|
||||
linksToEmbed.forEach(messageEmbedLink ->
|
||||
messageCache.getMessageFromCache(messageEmbedLink.getServerId(), messageEmbedLink.getChannelId(), messageEmbedLink.getMessageId())
|
||||
.thenAccept(cachedMessage -> self.embedLink(cachedMessage, target, userEmbeddingUserInServerId, embeddingMessage)
|
||||
|
||||
).exceptionally(throwable -> {
|
||||
log.error("Message embedding from cache failed for message {}.", messageEmbedLink.getMessageId(), throwable);
|
||||
return null;
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public CompletableFuture<Void> embedLink(CachedMessage cachedMessage, TextChannel target, Long userEmbeddingUserInServerId, Message embeddingMessage) {
|
||||
Optional<AUserInAServer> causeOpt = userInServerManagementService.loadUserOptional(userEmbeddingUserInServerId);
|
||||
if(causeOpt.isPresent()) {
|
||||
return buildTemplateParameter(embeddingMessage, cachedMessage).thenCompose(messageEmbeddedModel ->
|
||||
self.sendEmbeddingMessage(cachedMessage, target, userEmbeddingUserInServerId, messageEmbeddedModel)
|
||||
);
|
||||
} else {
|
||||
log.warn("User {} which was not found in database wanted to embed link in message {}.", userEmbeddingUserInServerId, embeddingMessage.getJumpUrl());
|
||||
return CompletableFuture.completedFuture(null);
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public CompletableFuture<Void> sendEmbeddingMessage(CachedMessage cachedMessage, TextChannel target, Long userEmbeddingUserInServerId, MessageEmbeddedModel messageEmbeddedModel) {
|
||||
MessageToSend embed = templateService.renderEmbedTemplate(MESSAGE_EMBED_TEMPLATE, messageEmbeddedModel);
|
||||
AUserInAServer cause = userInServerManagementService.loadOrCreateUser(userEmbeddingUserInServerId);
|
||||
List<CompletableFuture<Message>> completableFutures = channelService.sendMessageToSendToChannel(embed, target);
|
||||
log.trace("Embedding message {} from channel {} from server {}, because of user {}", cachedMessage.getMessageId(),
|
||||
cachedMessage.getChannelId(), cachedMessage.getServerId(), cause.getUserReference().getId());
|
||||
return CompletableFuture.allOf(completableFutures.toArray(new CompletableFuture[0])).thenCompose(aVoid -> {
|
||||
Message createdMessage = completableFutures.get(0).join();
|
||||
return reactionService.addReactionToMessageAsync(REMOVAL_EMOTE, cachedMessage.getServerId(), createdMessage).thenAccept(aVoid1 ->
|
||||
self.loadUserAndPersistMessage(cachedMessage, userEmbeddingUserInServerId, createdMessage)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void loadUserAndPersistMessage(CachedMessage cachedMessage, Long userInServerId, Message createdMessage) {
|
||||
AUserInAServer innerCause = userInServerManagementService.loadOrCreateUser(userInServerId);
|
||||
messageEmbedPostManagementService.createMessageEmbed(cachedMessage, createdMessage, innerCause);
|
||||
}
|
||||
|
||||
private CompletableFuture<MessageEmbeddedModel> buildTemplateParameter(Message message, CachedMessage embeddedMessage) {
|
||||
return memberService.getMemberInServerAsync(embeddedMessage.getServerId(), embeddedMessage.getAuthor().getAuthorId()).thenApply(member ->
|
||||
self.loadMessageEmbedModel(message, embeddedMessage, member)
|
||||
);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public MessageEmbeddedModel loadMessageEmbedModel(Message message, CachedMessage embeddedMessage, Member member) {
|
||||
Optional<TextChannel> textChannelFromServer = channelService.getTextChannelFromServerOptional(embeddedMessage.getServerId(), embeddedMessage.getChannelId());
|
||||
TextChannel sourceChannel = textChannelFromServer.orElse(null);
|
||||
return MessageEmbeddedModel
|
||||
.builder()
|
||||
.member(message.getMember())
|
||||
.author(member)
|
||||
.sourceChannel(sourceChannel)
|
||||
.embeddingUser(message.getMember())
|
||||
.messageChannel(message.getChannel())
|
||||
.guild(message.getGuild())
|
||||
.embeddedMessage(embeddedMessage)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
package dev.sheldan.abstracto.linkembed.service.management;
|
||||
|
||||
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.management.ChannelManagementService;
|
||||
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
|
||||
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
||||
import dev.sheldan.abstracto.linkembed.exception.CrossServerEmbedException;
|
||||
import dev.sheldan.abstracto.linkembed.model.database.EmbeddedMessage;
|
||||
import dev.sheldan.abstracto.linkembed.repository.EmbeddedMessageRepository;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class MessageEmbedPostManagementServiceBean implements MessageEmbedPostManagementService {
|
||||
|
||||
@Autowired
|
||||
private EmbeddedMessageRepository embeddedMessageRepository;
|
||||
|
||||
@Autowired
|
||||
private UserInServerManagementService userInServerManagementService;
|
||||
|
||||
@Autowired
|
||||
private ServerManagementService serverManagementService;
|
||||
|
||||
@Autowired
|
||||
private ChannelManagementService channelManagementService;
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void createMessageEmbed(CachedMessage embeddedMessage, Message messageContainingEmbed, AUserInAServer embeddingUser) {
|
||||
AServer embeddedServer = serverManagementService.loadOrCreate(embeddedMessage.getServerId());
|
||||
AServer embeddingServer = serverManagementService.loadOrCreate(messageContainingEmbed.getGuild().getIdLong());
|
||||
if(!embeddedServer.getId().equals(embeddingServer.getId())) {
|
||||
throw new CrossServerEmbedException(String.format("Message %s is not from server %s", embeddedMessage.getMessageUrl(), embeddingServer.getId()));
|
||||
}
|
||||
AChannel embeddingChannel = channelManagementService.loadChannel(messageContainingEmbed.getChannel().getIdLong());
|
||||
AChannel embeddedChannel = channelManagementService.loadChannel(embeddedMessage.getChannelId());
|
||||
AUserInAServer embeddedAuthor = userInServerManagementService.loadOrCreateUser(embeddedMessage.getServerId(), embeddedMessage.getAuthor().getAuthorId());
|
||||
EmbeddedMessage messageEmbedPost = EmbeddedMessage
|
||||
.builder()
|
||||
.embeddedMessageId(embeddedMessage.getMessageId())
|
||||
.embeddedChannel(embeddedChannel)
|
||||
.embeddedServer(embeddedServer)
|
||||
.embeddingServer(embeddingServer)
|
||||
.embeddingChannel(embeddingChannel)
|
||||
.embeddingMessageId(messageContainingEmbed.getIdLong())
|
||||
.embeddedUser(embeddedAuthor)
|
||||
.embeddingUser(embeddingUser)
|
||||
.build();
|
||||
|
||||
log.info("Saving embedded post: message {} by user {} in channel {} in server {} embedded message {} by user {} in channel {} in server {}.",
|
||||
messageContainingEmbed.getIdLong(), messageContainingEmbed.getAuthor().getIdLong(), embeddingChannel.getId(), messageContainingEmbed.getChannel().getIdLong(),
|
||||
embeddedMessage.getMessageId(), embeddedMessage.getAuthor().getAuthorId(), embeddedMessage.getChannelId(), embeddedMessage.getServerId());
|
||||
|
||||
embeddedMessageRepository.save(messageEmbedPost);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<EmbeddedMessage> findEmbeddedPostByMessageId(Long messageId) {
|
||||
return Optional.ofNullable(embeddedMessageRepository.findByEmbeddingMessageId(messageId));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void deleteEmbeddedMessage(EmbeddedMessage embeddedMessage) {
|
||||
log.info("Deleting embedded message {}.", embeddedMessage.getEmbeddingMessageId());
|
||||
embeddedMessageRepository.delete(embeddedMessage);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
abstracto.featureFlags.linkEmbeds.featureName=linkEmbeds
|
||||
abstracto.featureFlags.linkEmbeds.enabled=false
|
||||
@@ -0,0 +1,11 @@
|
||||
<?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-3.8.xsd
|
||||
http://www.liquibase.org/xml/ns/dbchangelog-ext ../dbchangelog-3.8.xsd
|
||||
http://www.liquibase.org/xml/ns/pro ../dbchangelog-3.8.xsd" >
|
||||
<include file="link-embed-tables/tables.xml" relativeToChangelogFile="true"/>
|
||||
<include file="link-embed-seedData/data.xml" relativeToChangelogFile="true"/>
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,11 @@
|
||||
<?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-3.8.xsd
|
||||
http://www.liquibase.org/xml/ns/dbchangelog-ext ../../dbchangelog-3.8.xsd
|
||||
http://www.liquibase.org/xml/ns/pro ../../dbchangelog-3.8.xsd" >
|
||||
<include file="default_emote.xml" relativeToChangelogFile="true"/>
|
||||
<include file="feature.xml" relativeToChangelogFile="true"/>
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,15 @@
|
||||
<?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-3.8.xsd
|
||||
http://www.liquibase.org/xml/ns/dbchangelog-ext ../../dbchangelog-3.8.xsd
|
||||
http://www.liquibase.org/xml/ns/pro ../../dbchangelog-3.8.xsd" >
|
||||
<changeSet author="Sheldan" id="link-embed_default_emote-insert">
|
||||
<insert tableName="default_emote">
|
||||
<column name="emote_key" value="removeEmbed"/>
|
||||
<column name="name" value="🗑"/>
|
||||
</insert>
|
||||
</changeSet>
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,14 @@
|
||||
<?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-3.8.xsd
|
||||
http://www.liquibase.org/xml/ns/dbchangelog-ext ../../dbchangelog-3.8.xsd
|
||||
http://www.liquibase.org/xml/ns/pro ../../dbchangelog-3.8.xsd" >
|
||||
<changeSet author="Sheldan" id="link-embed_feature-insertion">
|
||||
<insert tableName="feature">
|
||||
<column name="key" value="linkEmbeds"/>
|
||||
</insert>
|
||||
</changeSet>
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,56 @@
|
||||
<?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-3.8.xsd
|
||||
http://www.liquibase.org/xml/ns/dbchangelog-ext ../../dbchangelog-3.8.xsd
|
||||
http://www.liquibase.org/xml/ns/pro ../../dbchangelog-3.8.xsd" >
|
||||
<changeSet author="Sheldan" id="embedded_message-table">
|
||||
<createTable tableName="embedded_message">
|
||||
<column name="embedding_message_id" type="BIGINT">
|
||||
<constraints nullable="false" primaryKey="true" primaryKeyName="embedded_message_pkey"/>
|
||||
</column>
|
||||
<column name="created" type="TIMESTAMP WITHOUT TIME ZONE">
|
||||
<constraints nullable="true"/>
|
||||
</column>
|
||||
<column name="updated" type="TIMESTAMP WITHOUT TIME ZONE"/>
|
||||
<column name="embedded_message_id" type="BIGINT">
|
||||
<constraints nullable="true"/>
|
||||
</column>
|
||||
<column name="embedded_channel_id" type="BIGINT">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="embedded_server_id" type="BIGINT">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="embedded_user_in_server_id" type="BIGINT">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="embedding_channel_id" type="BIGINT">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="embedding_server_id" type="BIGINT">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="embedding_user_in_server_id" type="BIGINT">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
</createTable>
|
||||
<addForeignKeyConstraint baseColumnNames="embedding_channel_id" baseTableName="embedded_message" constraintName="fk_embed_channel_channel" deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="id" referencedTableName="channel" validate="true"/>
|
||||
<addForeignKeyConstraint baseColumnNames="embedded_channel_id" baseTableName="embedded_message" constraintName="fk_embed_embedded_channel_id_channel" deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="id" referencedTableName="channel" validate="true"/>
|
||||
<addForeignKeyConstraint baseColumnNames="embedding_user_in_server_id" baseTableName="embedded_message" constraintName="fk_embedded_user_in_server_id_user" deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="user_in_server_id" referencedTableName="user_in_server" validate="true"/>
|
||||
<addForeignKeyConstraint baseColumnNames="embedded_user_in_server_id" baseTableName="embedded_message" constraintName="fk_embedding_user_in_server_id_user" deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="user_in_server_id" referencedTableName="user_in_server" validate="true"/>
|
||||
<addForeignKeyConstraint baseColumnNames="embedding_server_id" baseTableName="embedded_message" constraintName="fk_embedding_server_id_server" deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="id" referencedTableName="server" validate="true"/>
|
||||
<addForeignKeyConstraint baseColumnNames="embedded_server_id" baseTableName="embedded_message" constraintName="fk_embed_embedded_server_id_server" deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="id" referencedTableName="server" validate="true"/>
|
||||
<sql>
|
||||
DROP TRIGGER IF EXISTS embedded_message_update_trigger ON embedded_message;
|
||||
CREATE TRIGGER embedded_message_update_trigger BEFORE UPDATE ON embedded_message FOR EACH ROW EXECUTE PROCEDURE update_trigger_procedure();
|
||||
</sql>
|
||||
<sql>
|
||||
DROP TRIGGER IF EXISTS embedded_message_insert_trigger ON embedded_message;
|
||||
CREATE TRIGGER embedded_message_insert_trigger BEFORE INSERT ON embedded_message FOR EACH ROW EXECUTE PROCEDURE insert_trigger_procedure();
|
||||
</sql>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
||||
@@ -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-3.8.xsd
|
||||
http://www.liquibase.org/xml/ns/dbchangelog-ext ../../dbchangelog-3.8.xsd
|
||||
http://www.liquibase.org/xml/ns/pro ../../dbchangelog-3.8.xsd" >
|
||||
<include file="embedded_message.xml" relativeToChangelogFile="true"/>
|
||||
</databaseChangeLog>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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-3.8.xsd
|
||||
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog-3.8.xsd
|
||||
http://www.liquibase.org/xml/ns/pro dbchangelog-3.8.xsd" >
|
||||
<include file="1.0-link-embed/collection.xml" relativeToChangelogFile="true"/>
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,216 @@
|
||||
package dev.sheldan.abstracto.linkembed.listener;
|
||||
|
||||
import dev.sheldan.abstracto.core.metric.service.MetricService;
|
||||
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.core.service.MessageCache;
|
||||
import dev.sheldan.abstracto.core.service.MessageService;
|
||||
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
||||
import dev.sheldan.abstracto.linkembed.model.MessageEmbedLink;
|
||||
import dev.sheldan.abstracto.linkembed.service.MessageEmbedService;
|
||||
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.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 java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class MessageEmbedListenerTest {
|
||||
|
||||
@InjectMocks
|
||||
private MessageEmbedListener testUnit;
|
||||
|
||||
@Mock
|
||||
private MessageCache messageCache;
|
||||
|
||||
@Mock
|
||||
private MetricService metricService;
|
||||
|
||||
@Mock
|
||||
private UserInServerManagementService userInServerManagementService;
|
||||
|
||||
@Mock
|
||||
private MessageEmbedService messageEmbedService;
|
||||
|
||||
@Mock
|
||||
private MessageService messageService;
|
||||
|
||||
@Mock
|
||||
private MessageEmbedListener self;
|
||||
|
||||
@Mock
|
||||
private Message message;
|
||||
|
||||
@Mock
|
||||
private TextChannel textChannel;
|
||||
|
||||
@Mock
|
||||
private Guild guild;
|
||||
|
||||
private static final Long FIRST_SERVER_ID = 12L;
|
||||
private static final Long SECOND_SERVER_ID = 13L;
|
||||
private static final Long FIRST_CHANNEL_ID = 45L;
|
||||
private static final Long USER_IN_SERVER_ID = 1L;
|
||||
private static final Long FIRST_MESSAGE_ID = 2L;
|
||||
private static final Long SECOND_MESSAGE_ID = 3L;
|
||||
|
||||
@Before
|
||||
public void setup(){
|
||||
when(guild.getIdLong()).thenReturn(FIRST_SERVER_ID);
|
||||
when(message.getGuild()).thenReturn(guild);
|
||||
when(message.getChannel()).thenReturn(textChannel);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoLinkFoundExecution() {
|
||||
String text = "text";
|
||||
when(message.getContentRaw()).thenReturn(text);
|
||||
List<MessageEmbedLink> foundMessageLinks = new ArrayList<>();
|
||||
when(messageEmbedService.getLinksInMessage(text)).thenReturn(foundMessageLinks);
|
||||
testUnit.execute(message);
|
||||
verify(messageService, times(0)).deleteMessage(message);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnlyOneLinkFoundExecution() {
|
||||
String linkText = "link";
|
||||
String text = linkText;
|
||||
executeLinkEmbedTest(linkText, text);
|
||||
verify(self, times(1)).embedSingleLink(eq(message), anyLong(), any(CachedMessage.class));
|
||||
verify(messageService, times(1)).deleteMessage(message);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOneLinkWithAdditionalTextExecution() {
|
||||
String linkText = "link";
|
||||
String text = linkText + "more text";
|
||||
executeLinkEmbedTest(linkText, text);
|
||||
verify(self, times(1)).embedSingleLink(eq(message), anyLong(), any(CachedMessage.class));
|
||||
verify(messageService, times(0)).deleteMessage(message);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLinkFromDifferentServer() {
|
||||
String linkText = "link";
|
||||
String text = linkText + "more text";
|
||||
AUserInAServer userInAServer = Mockito.mock(AUserInAServer.class);
|
||||
when(message.getContentRaw()).thenReturn(text);
|
||||
MessageEmbedLink foundLink = Mockito.mock(MessageEmbedLink.class);
|
||||
when(foundLink.getMessageId()).thenReturn(FIRST_MESSAGE_ID);
|
||||
when(foundLink.getServerId()).thenReturn(SECOND_SERVER_ID);
|
||||
List<MessageEmbedLink> foundMessageLinks = Arrays.asList(foundLink);
|
||||
Member author = Mockito.mock(Member.class);
|
||||
when(message.getMember()).thenReturn(author);
|
||||
when(userInServerManagementService.loadOrCreateUser(author)).thenReturn(userInAServer);
|
||||
when(messageEmbedService.getLinksInMessage(text)).thenReturn(foundMessageLinks);
|
||||
testUnit.execute(message);
|
||||
verify(messageService, times(0)).deleteMessage(message);
|
||||
verify(self, times(0)).embedSingleLink(eq(message), anyLong(), any(CachedMessage.class));
|
||||
verify(messageCache, times(0)).getMessageFromCache(anyLong(), anyLong(), anyLong());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTwoLinksOneGetsEmbedded() {
|
||||
String firstText = "link";
|
||||
String secondText = "secondLink";
|
||||
MessageEmbedLink differentOriginLink = Mockito.mock(MessageEmbedLink.class);
|
||||
when(differentOriginLink.getServerId()).thenReturn(SECOND_SERVER_ID);
|
||||
when(differentOriginLink.getMessageId()).thenReturn(SECOND_MESSAGE_ID);
|
||||
MessageEmbedLink sameServerLink = Mockito.mock(MessageEmbedLink.class);
|
||||
when(sameServerLink.getServerId()).thenReturn(FIRST_SERVER_ID);
|
||||
when(sameServerLink.getChannelId()).thenReturn(FIRST_CHANNEL_ID);
|
||||
when(sameServerLink.getMessageId()).thenReturn(FIRST_MESSAGE_ID);
|
||||
when(sameServerLink.getWholeUrl()).thenReturn(secondText);
|
||||
List<MessageEmbedLink> foundMessageLinks = Arrays.asList(differentOriginLink, sameServerLink);
|
||||
AUserInAServer embeddingUser = Mockito.mock(AUserInAServer.class);
|
||||
when(embeddingUser.getUserInServerId()).thenReturn(USER_IN_SERVER_ID);
|
||||
String completeMessage = firstText.concat(secondText);
|
||||
when(message.getContentRaw()).thenReturn(completeMessage);
|
||||
|
||||
Member author = Mockito.mock(Member.class);
|
||||
when(message.getMember()).thenReturn(author);
|
||||
when(message.getGuild()).thenReturn(guild);
|
||||
when(guild.getIdLong()).thenReturn(FIRST_SERVER_ID);
|
||||
when(userInServerManagementService.loadOrCreateUser(author)).thenReturn(embeddingUser);
|
||||
CachedMessage cachedMessage = Mockito.mock(CachedMessage.class);
|
||||
when(messageCache.getMessageFromCache(FIRST_SERVER_ID, FIRST_CHANNEL_ID, FIRST_MESSAGE_ID)).thenReturn(CompletableFuture.completedFuture(cachedMessage));
|
||||
when(messageEmbedService.getLinksInMessage(completeMessage)).thenReturn(foundMessageLinks);
|
||||
testUnit.execute(message);
|
||||
verify(messageService, times(0)).deleteMessage(message);
|
||||
verify(self, times(1)).embedSingleLink(message, USER_IN_SERVER_ID, cachedMessage);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultipleLinksFound() {
|
||||
String text = "link";
|
||||
MessageEmbedLink foundLink = Mockito.mock(MessageEmbedLink.class);
|
||||
when(foundLink.getServerId()).thenReturn(FIRST_SERVER_ID);
|
||||
when(foundLink.getChannelId()).thenReturn(FIRST_CHANNEL_ID);
|
||||
when(foundLink.getMessageId()).thenReturn(FIRST_MESSAGE_ID);
|
||||
when(foundLink.getWholeUrl()).thenReturn(text);
|
||||
MessageEmbedLink secondLink = Mockito.mock(MessageEmbedLink.class);
|
||||
when(secondLink.getServerId()).thenReturn(FIRST_SERVER_ID);
|
||||
when(secondLink.getChannelId()).thenReturn(FIRST_CHANNEL_ID);
|
||||
when(secondLink.getMessageId()).thenReturn(SECOND_MESSAGE_ID);
|
||||
when(secondLink.getWholeUrl()).thenReturn(text);
|
||||
List<MessageEmbedLink> foundMessageLinks = Arrays.asList(foundLink, secondLink);
|
||||
AUserInAServer userInAServer = Mockito.mock(AUserInAServer.class);
|
||||
when(userInAServer.getUserInServerId()).thenReturn(USER_IN_SERVER_ID);
|
||||
when(message.getContentRaw()).thenReturn(text);
|
||||
|
||||
Member author = Mockito.mock(Member.class);
|
||||
when(message.getMember()).thenReturn(author);
|
||||
when(userInServerManagementService.loadOrCreateUser(author)).thenReturn(userInAServer);
|
||||
CachedMessage cachedMessage = Mockito.mock(CachedMessage.class);
|
||||
CachedMessage secondCachedMessage = Mockito.mock(CachedMessage.class);
|
||||
when(messageCache.getMessageFromCache(FIRST_SERVER_ID, FIRST_CHANNEL_ID, FIRST_MESSAGE_ID)).thenReturn(CompletableFuture.completedFuture(cachedMessage));
|
||||
when(messageCache.getMessageFromCache(FIRST_SERVER_ID, FIRST_CHANNEL_ID, SECOND_MESSAGE_ID)).thenReturn(CompletableFuture.completedFuture(secondCachedMessage));
|
||||
when(messageEmbedService.getLinksInMessage(text)).thenReturn(foundMessageLinks);
|
||||
testUnit.execute(message);
|
||||
verify(messageService, times(1)).deleteMessage(message);
|
||||
verify(self, times(1)).embedSingleLink(message, USER_IN_SERVER_ID, cachedMessage);
|
||||
verify(self, times(1)).embedSingleLink(message, USER_IN_SERVER_ID, secondCachedMessage);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLoadUserAndEmbed() {
|
||||
CachedMessage cachedMessage = Mockito.mock(CachedMessage.class);
|
||||
long userId = 3L;
|
||||
when(message.getTextChannel()).thenReturn(textChannel);
|
||||
when(messageEmbedService.embedLink(cachedMessage, textChannel, userId, message)).thenReturn(CompletableFuture.completedFuture(null));
|
||||
testUnit.embedSingleLink(message, userId, cachedMessage);
|
||||
verify(metricService, times(1)).incrementCounter(any());
|
||||
}
|
||||
|
||||
private void executeLinkEmbedTest(String linkText, String text) {
|
||||
AUserInAServer userInAServer = Mockito.mock(AUserInAServer.class);
|
||||
when(message.getContentRaw()).thenReturn(text);
|
||||
MessageEmbedLink foundLink = Mockito.mock(MessageEmbedLink.class);
|
||||
when(foundLink.getWholeUrl()).thenReturn(linkText);
|
||||
when(foundLink.getMessageId()).thenReturn(FIRST_MESSAGE_ID);
|
||||
when(foundLink.getServerId()).thenReturn(FIRST_SERVER_ID);
|
||||
when(foundLink.getChannelId()).thenReturn(FIRST_CHANNEL_ID);
|
||||
List<MessageEmbedLink> foundMessageLinks = Arrays.asList(foundLink);
|
||||
Member author = Mockito.mock(Member.class);
|
||||
when(message.getMember()).thenReturn(author);
|
||||
when(userInServerManagementService.loadOrCreateUser(author)).thenReturn(userInAServer);
|
||||
CachedMessage cachedMessage = Mockito.mock(CachedMessage.class);
|
||||
when(messageCache.getMessageFromCache(FIRST_SERVER_ID, FIRST_CHANNEL_ID, FIRST_MESSAGE_ID)).thenReturn(CompletableFuture.completedFuture(cachedMessage));
|
||||
when(messageEmbedService.getLinksInMessage(text)).thenReturn(foundMessageLinks);
|
||||
testUnit.execute(message);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
package dev.sheldan.abstracto.linkembed.listener;
|
||||
|
||||
import dev.sheldan.abstracto.core.metric.service.MetricService;
|
||||
import dev.sheldan.abstracto.core.models.ServerUser;
|
||||
import dev.sheldan.abstracto.core.models.cache.CachedEmote;
|
||||
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
|
||||
import dev.sheldan.abstracto.core.models.cache.CachedReactions;
|
||||
import dev.sheldan.abstracto.core.models.database.AEmote;
|
||||
import dev.sheldan.abstracto.core.models.database.AUser;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.core.service.EmoteService;
|
||||
import dev.sheldan.abstracto.core.service.MessageService;
|
||||
import dev.sheldan.abstracto.linkembed.model.database.EmbeddedMessage;
|
||||
import dev.sheldan.abstracto.linkembed.service.management.MessageEmbedPostManagementService;
|
||||
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 java.util.concurrent.CompletableFuture;
|
||||
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class MessageEmbedRemovalReactionListenerTest {
|
||||
|
||||
@InjectMocks
|
||||
private MessageEmbedRemovalReactionListener testUnit;
|
||||
|
||||
@Mock
|
||||
private MessageEmbedPostManagementService messageEmbedPostManagementService;
|
||||
|
||||
@Mock
|
||||
private MessageService messageService;
|
||||
|
||||
@Mock
|
||||
private EmoteService emoteService;
|
||||
|
||||
@Mock
|
||||
private MetricService metricService;
|
||||
|
||||
@Mock
|
||||
private CachedReactions messageReaction;
|
||||
|
||||
@Mock
|
||||
private CachedEmote reactionEmote;
|
||||
|
||||
@Mock
|
||||
private AUserInAServer embeddingUser;
|
||||
|
||||
@Mock
|
||||
private AUser embeddingAUser;
|
||||
|
||||
@Mock
|
||||
private AUserInAServer embeddedUser;
|
||||
|
||||
@Mock
|
||||
private AUser embeddedAUser;
|
||||
|
||||
@Mock
|
||||
private ServerUser reactingUser;
|
||||
|
||||
private static final Long SERVER_ID = 4L;
|
||||
private static final Long CHANNEL_ID = 5L;
|
||||
private static final Long MESSAGE_ID = 6L;
|
||||
private static final Long USER_ID = 3L;
|
||||
|
||||
@Test
|
||||
public void testAddingWrongEmote() {
|
||||
executeRemovalEmoteAddedTest(false);
|
||||
verify(messageEmbedPostManagementService, times(0)).findEmbeddedPostByMessageId(MESSAGE_ID);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddingCorrectEmoteToWrongMessage() {
|
||||
when(messageEmbedPostManagementService.findEmbeddedPostByMessageId(MESSAGE_ID)).thenReturn(Optional.empty());
|
||||
executeRemovalEmoteAddedTest(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIncorrectUserAddingReaction() {
|
||||
when(embeddingUser.getUserReference()).thenReturn(embeddingAUser);
|
||||
when(embeddedUser.getUserReference()).thenReturn(embeddedAUser);
|
||||
when(embeddingAUser.getId()).thenReturn(USER_ID);
|
||||
when(embeddedAUser.getId()).thenReturn(USER_ID + 1);
|
||||
when(reactingUser.getUserId()).thenReturn(USER_ID + 2);
|
||||
executeDeletionTest(embeddingUser, embeddedUser, reactingUser, 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEmbeddedUserAddingReaction() {
|
||||
when(embeddedUser.getUserReference()).thenReturn(embeddedAUser);
|
||||
when(embeddedAUser.getId()).thenReturn(USER_ID + 1);
|
||||
when(embeddingUser.getUserReference()).thenReturn(embeddingAUser);
|
||||
when(embeddingAUser.getId()).thenReturn(USER_ID + 3);
|
||||
when(reactingUser.getUserId()).thenReturn(USER_ID + 1);
|
||||
executeDeletionTest(embeddingUser, embeddedUser, reactingUser, 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEmbeddingUserAddingReaction() {
|
||||
when(embeddingUser.getUserReference()).thenReturn(embeddingAUser);
|
||||
when(embeddedUser.getUserReference()).thenReturn(embeddedAUser);
|
||||
when(embeddingAUser.getId()).thenReturn(USER_ID);
|
||||
when(embeddedAUser.getId()).thenReturn(USER_ID + 1);
|
||||
when(reactingUser.getUserId()).thenReturn(USER_ID);
|
||||
executeDeletionTest(embeddingUser, embeddedUser, reactingUser, 1);
|
||||
}
|
||||
|
||||
private void executeDeletionTest(AUserInAServer embeddingUser, AUserInAServer embeddedUser, ServerUser userAddingReaction, int wantedDeletions) {
|
||||
CachedMessage cachedMessage = Mockito.mock(CachedMessage.class);
|
||||
when(cachedMessage.getServerId()).thenReturn(SERVER_ID);
|
||||
when(cachedMessage.getChannelId()).thenReturn(CHANNEL_ID);
|
||||
when(cachedMessage.getMessageId()).thenReturn(MESSAGE_ID);
|
||||
AEmote reactedEmote = Mockito.mock(AEmote.class);
|
||||
when(emoteService.getEmoteOrDefaultEmote(MessageEmbedRemovalReactionListener.REMOVAL_EMOTE, SERVER_ID)).thenReturn(reactedEmote);
|
||||
when(messageReaction.getEmote()).thenReturn(reactionEmote);
|
||||
when(emoteService.compareCachedEmoteWithAEmote(reactionEmote, reactedEmote)).thenReturn(true);
|
||||
EmbeddedMessage message = Mockito.mock(EmbeddedMessage.class);
|
||||
when(message.getEmbeddingUser()).thenReturn(embeddingUser);
|
||||
when(message.getEmbeddedUser()).thenReturn(embeddedUser);
|
||||
when(messageEmbedPostManagementService.findEmbeddedPostByMessageId(MESSAGE_ID)).thenReturn(Optional.of(message));
|
||||
when(messageService.deleteMessageInChannelInServer(SERVER_ID, CHANNEL_ID, MESSAGE_ID)).thenReturn(CompletableFuture.completedFuture(null));
|
||||
when(messageEmbedPostManagementService.findEmbeddedPostByMessageId(MESSAGE_ID)).thenReturn(Optional.of(message));
|
||||
testUnit.executeReactionAdded(cachedMessage, messageReaction, userAddingReaction);
|
||||
verify(messageService, times(wantedDeletions)).deleteMessageInChannelInServer(SERVER_ID, CHANNEL_ID, MESSAGE_ID);
|
||||
if(wantedDeletions > 0) {
|
||||
verify(messageEmbedPostManagementService, times(1)).deleteEmbeddedMessage(message);
|
||||
}
|
||||
}
|
||||
|
||||
private void executeRemovalEmoteAddedTest(boolean wasCorrectEmote) {
|
||||
CachedMessage cachedMessage = Mockito.mock(CachedMessage.class);
|
||||
when(cachedMessage.getServerId()).thenReturn(SERVER_ID);
|
||||
when(cachedMessage.getMessageId()).thenReturn(MESSAGE_ID);
|
||||
ServerUser serverUser = Mockito.mock(ServerUser.class);
|
||||
AEmote reactedEmote = Mockito.mock(AEmote.class);
|
||||
when(emoteService.getEmoteOrDefaultEmote(MessageEmbedRemovalReactionListener.REMOVAL_EMOTE, SERVER_ID)).thenReturn(reactedEmote);
|
||||
when(messageReaction.getEmote()).thenReturn(reactionEmote);
|
||||
when(emoteService.compareCachedEmoteWithAEmote(reactionEmote, reactedEmote)).thenReturn(wasCorrectEmote);
|
||||
testUnit.executeReactionAdded(cachedMessage, messageReaction, serverUser);
|
||||
verify(messageService, times(0)).deleteMessageInChannelInServer(anyLong(), anyLong(), anyLong());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,300 @@
|
||||
package dev.sheldan.abstracto.linkembed.service;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.cache.CachedAuthor;
|
||||
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
|
||||
import dev.sheldan.abstracto.core.models.database.AUser;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.core.models.template.listener.MessageEmbeddedModel;
|
||||
import dev.sheldan.abstracto.core.service.*;
|
||||
import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
|
||||
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
|
||||
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
||||
import dev.sheldan.abstracto.core.test.command.CommandTestUtilities;
|
||||
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
|
||||
import dev.sheldan.abstracto.core.templating.service.TemplateService;
|
||||
import dev.sheldan.abstracto.linkembed.model.MessageEmbedLink;
|
||||
import dev.sheldan.abstracto.linkembed.service.management.MessageEmbedPostManagementService;
|
||||
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.*;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class MessageEmbedServiceBeanTest {
|
||||
|
||||
@InjectMocks
|
||||
private MessageEmbedServiceBean testUnit;
|
||||
|
||||
@Mock
|
||||
private ChannelManagementService channelManagementService;
|
||||
|
||||
@Mock
|
||||
private ServerManagementService serverManagementService;
|
||||
|
||||
@Mock
|
||||
private UserInServerManagementService userInServerManagementService;
|
||||
|
||||
@Mock
|
||||
private MemberService memberService;
|
||||
|
||||
@Mock
|
||||
private TemplateService templateService;
|
||||
|
||||
@Mock
|
||||
private ChannelService channelService;
|
||||
|
||||
@Mock
|
||||
private MessageEmbedServiceBean self;
|
||||
|
||||
@Mock
|
||||
private MessageCache messageCache;
|
||||
|
||||
@Mock
|
||||
private MessageEmbedPostManagementService messageEmbedPostManagementService;
|
||||
|
||||
@Mock
|
||||
private ReactionService reactionService;
|
||||
|
||||
@Mock
|
||||
private TextChannel textChannel;
|
||||
|
||||
@Mock
|
||||
private Message embeddingMessage;
|
||||
|
||||
@Mock
|
||||
private Guild guild;
|
||||
|
||||
@Mock
|
||||
private CachedMessage cachedMessage;
|
||||
|
||||
@Captor
|
||||
private ArgumentCaptor<CachedMessage> cachedMessageArgumentCaptor;
|
||||
|
||||
private static final String FIRST_LINK_TEXT = "https://discordapp.com/channels/1/2/3";
|
||||
private static final String SHORTER_LINK_TEXT = "https://discord.com/channels/1/2/3";
|
||||
private static final String SECOND_LINK_TEXT = "https://discordapp.com/channels/2/3/4";
|
||||
|
||||
private static final Long EMBEDDING_USER_IN_SERVER_ID = 8L;
|
||||
private static final Long SERVER_ID = 8L;
|
||||
private static final Long CHANNEL_ID = 10L;
|
||||
private static final Long USER_ID = 9L;
|
||||
|
||||
@Mock
|
||||
private AUserInAServer embeddingUser;
|
||||
|
||||
@Mock
|
||||
private Member embeddingMember;
|
||||
|
||||
@Mock
|
||||
private Member embeddedMember;
|
||||
|
||||
@Test
|
||||
public void testNoLinkInString(){
|
||||
String message = "test";
|
||||
List<MessageEmbedLink> linksInMessage = testUnit.getLinksInMessage(message);
|
||||
Assert.assertEquals(0, linksInMessage.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDMLinkInString(){
|
||||
String message = "https://discordapp.com/channels/@me/1/2";
|
||||
List<MessageEmbedLink> linksInMessage = testUnit.getLinksInMessage(message);
|
||||
Assert.assertEquals(0, linksInMessage.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFindOneLinkInString(){
|
||||
List<MessageEmbedLink> linksInMessage = testUnit.getLinksInMessage(FIRST_LINK_TEXT);
|
||||
Assert.assertEquals(1, linksInMessage.size());
|
||||
MessageEmbedLink firstLink = linksInMessage.get(0);
|
||||
Assert.assertEquals(1, firstLink.getServerId().intValue());
|
||||
Assert.assertEquals(2, firstLink.getChannelId().intValue());
|
||||
Assert.assertEquals(3, firstLink.getMessageId().intValue());
|
||||
Assert.assertEquals(FIRST_LINK_TEXT, firstLink.getWholeUrl());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNewShortDomain(){
|
||||
List<MessageEmbedLink> linksInMessage = testUnit.getLinksInMessage(SHORTER_LINK_TEXT);
|
||||
Assert.assertEquals(1, linksInMessage.size());
|
||||
MessageEmbedLink firstLink = linksInMessage.get(0);
|
||||
Assert.assertEquals(1, firstLink.getServerId().intValue());
|
||||
Assert.assertEquals(2, firstLink.getChannelId().intValue());
|
||||
Assert.assertEquals(3, firstLink.getMessageId().intValue());
|
||||
Assert.assertEquals(SHORTER_LINK_TEXT, firstLink.getWholeUrl());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTwoLinksInString(){
|
||||
String message = String.format("%s %s", FIRST_LINK_TEXT, SECOND_LINK_TEXT);
|
||||
executeTestWithTwoLinks(message);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLinksWithTextInBetween(){
|
||||
String message = String.format("%s some more text %s", FIRST_LINK_TEXT, SECOND_LINK_TEXT);
|
||||
executeTestWithTwoLinks(message);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEmbedNoLinks() {
|
||||
testUnit.embedLinks(new ArrayList<>(), textChannel, 5L, embeddingMessage);
|
||||
verify(messageCache, times(0)).getMessageFromCache(anyLong(), anyLong(), anyLong());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEmbedSingularLink() {
|
||||
List<MessageEmbedLink> linksToEmbed = new ArrayList<>();
|
||||
Long channelId = 6L;
|
||||
Long firstMessageId = 6L;
|
||||
MessageEmbedLink messageEmbedLink = Mockito.mock(MessageEmbedLink.class);
|
||||
when(messageEmbedLink.getServerId()).thenReturn(SERVER_ID);
|
||||
when(messageEmbedLink.getChannelId()).thenReturn(channelId);
|
||||
when(messageEmbedLink.getMessageId()).thenReturn(firstMessageId);
|
||||
linksToEmbed.add(messageEmbedLink);
|
||||
CachedMessage firstCachedMessage = Mockito.mock(CachedMessage.class);
|
||||
when(messageCache.getMessageFromCache(SERVER_ID,channelId, firstMessageId)).thenReturn(CompletableFuture.completedFuture(firstCachedMessage));
|
||||
Long embeddingUserId = 5L;
|
||||
testUnit.embedLinks(linksToEmbed, textChannel, embeddingUserId, embeddingMessage);
|
||||
verify( self, times(1)).embedLink(eq(firstCachedMessage), eq(textChannel), eq(embeddingUserId) , eq(embeddingMessage));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEmbedMultipleLinks() {
|
||||
List<MessageEmbedLink> linksToEmbed = new ArrayList<>();
|
||||
Long firstMessageId = 6L;
|
||||
Long secondMessageId = 7L;
|
||||
MessageEmbedLink messageEmbedLink = mockMessageEmbedLink(firstMessageId);
|
||||
linksToEmbed.add(messageEmbedLink);
|
||||
MessageEmbedLink secondMessageEmbedLink = mockMessageEmbedLink(secondMessageId);
|
||||
linksToEmbed.add(secondMessageEmbedLink);
|
||||
CachedMessage firstCachedMessage = mockCachedMessage(firstMessageId);
|
||||
CachedMessage secondCacheMessage = mockCachedMessage(secondMessageId);
|
||||
when(messageCache.getMessageFromCache(SERVER_ID,CHANNEL_ID, firstMessageId)).thenReturn(CompletableFuture.completedFuture(firstCachedMessage));
|
||||
when(messageCache.getMessageFromCache(SERVER_ID,CHANNEL_ID, secondMessageId)).thenReturn(CompletableFuture.completedFuture(secondCacheMessage));
|
||||
Long embeddingUserId = 5L;
|
||||
testUnit.embedLinks(linksToEmbed, textChannel, embeddingUserId, embeddingMessage);
|
||||
verify( self, times(2)).embedLink(cachedMessageArgumentCaptor.capture(), eq(textChannel), eq(embeddingUserId) , eq(embeddingMessage));
|
||||
|
||||
List<CachedMessage> cachedMessages = cachedMessageArgumentCaptor.getAllValues();
|
||||
Assert.assertEquals(2, cachedMessages.size());
|
||||
CachedMessage firstEmbeddedMessage = cachedMessages.get(0);
|
||||
Assert.assertEquals(SERVER_ID, firstEmbeddedMessage.getServerId());
|
||||
Assert.assertEquals(CHANNEL_ID, firstEmbeddedMessage.getChannelId());
|
||||
Assert.assertEquals(firstMessageId, firstEmbeddedMessage.getMessageId());
|
||||
|
||||
CachedMessage secondEmbeddedMessage = cachedMessages.get(1);
|
||||
Assert.assertEquals(SERVER_ID, secondEmbeddedMessage.getServerId());
|
||||
Assert.assertEquals(CHANNEL_ID, secondEmbeddedMessage.getChannelId());
|
||||
Assert.assertEquals(secondMessageId, secondEmbeddedMessage.getMessageId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLoadingEmbeddingModel() {
|
||||
when(cachedMessage.getServerId()).thenReturn(SERVER_ID);
|
||||
CachedAuthor cachedAuthor = Mockito.mock(CachedAuthor.class);
|
||||
when(cachedAuthor.getAuthorId()).thenReturn(USER_ID);
|
||||
when(cachedMessage.getAuthor()).thenReturn(cachedAuthor);
|
||||
when(userInServerManagementService.loadUserOptional(EMBEDDING_USER_IN_SERVER_ID)).thenReturn(Optional.of(embeddingUser));
|
||||
when(memberService.getMemberInServerAsync(SERVER_ID, USER_ID)).thenReturn(CompletableFuture.completedFuture(embeddingMember));
|
||||
MessageEmbeddedModel model = Mockito.mock(MessageEmbeddedModel.class);
|
||||
when(self.loadMessageEmbedModel(embeddingMessage, cachedMessage, embeddingMember)).thenReturn(model);
|
||||
when(self.sendEmbeddingMessage(cachedMessage, textChannel, EMBEDDING_USER_IN_SERVER_ID, model)).thenReturn(CompletableFuture.completedFuture(null));
|
||||
CompletableFuture<Void> embedFuture = testUnit.embedLink(cachedMessage, textChannel, EMBEDDING_USER_IN_SERVER_ID, embeddingMessage);
|
||||
Assert.assertTrue(embedFuture.isDone());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotFoundUserEmbeddingLink() {
|
||||
Long firstMessageId = 6L;
|
||||
CachedMessage cachedMessage = mockCachedMessage(firstMessageId);
|
||||
Long userEmbeddingUserInServerId = 5L;
|
||||
when(userInServerManagementService.loadUserOptional(userEmbeddingUserInServerId)).thenReturn(Optional.empty());
|
||||
testUnit.embedLink(cachedMessage, textChannel, userEmbeddingUserInServerId, embeddingMessage);
|
||||
verify(messageCache, times(0)).getMessageFromCache(anyLong(), anyLong(), anyLong());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSendEmbeddingMessage() {
|
||||
MessageEmbeddedModel embeddedModel = Mockito.mock(MessageEmbeddedModel.class);
|
||||
MessageToSend messageToSend = Mockito.mock(MessageToSend.class);
|
||||
when(templateService.renderEmbedTemplate(MessageEmbedServiceBean.MESSAGE_EMBED_TEMPLATE, embeddedModel)).thenReturn(messageToSend);
|
||||
AUser user = Mockito.mock(AUser.class);
|
||||
when(embeddingUser.getUserReference()).thenReturn(user);
|
||||
when(userInServerManagementService.loadOrCreateUser(EMBEDDING_USER_IN_SERVER_ID)).thenReturn(embeddingUser);
|
||||
List<CompletableFuture<Message>> messageFutures = CommandTestUtilities.messageFutureList();
|
||||
when(channelService.sendMessageToSendToChannel(messageToSend, textChannel)).thenReturn(messageFutures);
|
||||
Message createdMessage = messageFutures.get(0).join();
|
||||
when(reactionService.addReactionToMessageAsync(MessageEmbedServiceBean.REMOVAL_EMOTE, cachedMessage.getServerId(),
|
||||
createdMessage)).thenReturn(CompletableFuture.completedFuture(null));
|
||||
CompletableFuture<Void> future = testUnit.sendEmbeddingMessage(cachedMessage, textChannel, EMBEDDING_USER_IN_SERVER_ID, embeddedModel);
|
||||
Assert.assertFalse(future.isCompletedExceptionally());
|
||||
verify(self, times(1)).loadUserAndPersistMessage(cachedMessage, EMBEDDING_USER_IN_SERVER_ID, createdMessage);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLoadUserAndPersistMessage() {
|
||||
when(userInServerManagementService.loadOrCreateUser(EMBEDDING_USER_IN_SERVER_ID)).thenReturn(embeddingUser);
|
||||
testUnit.loadUserAndPersistMessage(cachedMessage, EMBEDDING_USER_IN_SERVER_ID, embeddingMessage);
|
||||
verify(messageEmbedPostManagementService, times(1)).createMessageEmbed(cachedMessage, embeddingMessage, embeddingUser);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLoadMessageEmbedModel() {
|
||||
when(cachedMessage.getServerId()).thenReturn(SERVER_ID);
|
||||
when(cachedMessage.getChannelId()).thenReturn(CHANNEL_ID);
|
||||
when(channelService.getTextChannelFromServerOptional(SERVER_ID, CHANNEL_ID)).thenReturn(Optional.of(textChannel));
|
||||
when(embeddingMessage.getGuild()).thenReturn(guild);
|
||||
when(embeddingMessage.getChannel()).thenReturn(textChannel);
|
||||
when(embeddingMessage.getMember()).thenReturn(embeddingMember);
|
||||
MessageEmbeddedModel createdModel = testUnit.loadMessageEmbedModel(embeddingMessage, cachedMessage, embeddedMember);
|
||||
Assert.assertEquals(textChannel, createdModel.getSourceChannel());
|
||||
Assert.assertEquals(guild, createdModel.getGuild());
|
||||
Assert.assertEquals(textChannel, createdModel.getMessageChannel());
|
||||
Assert.assertEquals(embeddedMember, createdModel.getAuthor());
|
||||
Assert.assertEquals(embeddingMember, createdModel.getMember());
|
||||
Assert.assertEquals(embeddingMember, createdModel.getEmbeddingUser());
|
||||
Assert.assertEquals(cachedMessage, createdModel.getEmbeddedMessage());
|
||||
}
|
||||
private void executeTestWithTwoLinks(String message) {
|
||||
List<MessageEmbedLink> linksInMessage = testUnit.getLinksInMessage(message);
|
||||
Assert.assertEquals(2, linksInMessage.size());
|
||||
MessageEmbedLink firstLink = linksInMessage.get(0);
|
||||
Assert.assertEquals(1, firstLink.getServerId().intValue());
|
||||
Assert.assertEquals(2, firstLink.getChannelId().intValue());
|
||||
Assert.assertEquals(3, firstLink.getMessageId().intValue());
|
||||
|
||||
MessageEmbedLink secondLink = linksInMessage.get(1);
|
||||
Assert.assertEquals(2, secondLink.getServerId().intValue());
|
||||
Assert.assertEquals(3, secondLink.getChannelId().intValue());
|
||||
Assert.assertEquals(4, secondLink.getMessageId().intValue());
|
||||
}
|
||||
|
||||
private MessageEmbedLink mockMessageEmbedLink(Long messageId) {
|
||||
MessageEmbedLink secondMessageEmbedLink = Mockito.mock(MessageEmbedLink.class);
|
||||
when(secondMessageEmbedLink.getServerId()).thenReturn(SERVER_ID);
|
||||
when(secondMessageEmbedLink.getChannelId()).thenReturn(CHANNEL_ID);
|
||||
when(secondMessageEmbedLink.getMessageId()).thenReturn(messageId);
|
||||
return secondMessageEmbedLink;
|
||||
}
|
||||
|
||||
private CachedMessage mockCachedMessage(Long secondMessageId) {
|
||||
CachedMessage secondCacheMessage = Mockito.mock(CachedMessage.class);
|
||||
when(secondCacheMessage.getServerId()).thenReturn(SERVER_ID);
|
||||
when(secondCacheMessage.getChannelId()).thenReturn(CHANNEL_ID);
|
||||
when(secondCacheMessage.getMessageId()).thenReturn(secondMessageId);
|
||||
return secondCacheMessage;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
package dev.sheldan.abstracto.linkembed.service.management;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.cache.CachedAuthor;
|
||||
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
|
||||
import dev.sheldan.abstracto.core.models.database.AChannel;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
|
||||
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
|
||||
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
||||
import dev.sheldan.abstracto.linkembed.exception.CrossServerEmbedException;
|
||||
import dev.sheldan.abstracto.linkembed.model.database.EmbeddedMessage;
|
||||
import dev.sheldan.abstracto.linkembed.repository.EmbeddedMessageRepository;
|
||||
import net.dv8tion.jda.api.entities.Guild;
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
import net.dv8tion.jda.api.entities.MessageChannel;
|
||||
import net.dv8tion.jda.api.entities.User;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.*;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class MessageEmbedPostManagementServiceBeanTest {
|
||||
|
||||
@InjectMocks
|
||||
private MessageEmbedPostManagementServiceBean testUnit;
|
||||
|
||||
@Mock
|
||||
private EmbeddedMessageRepository embeddedMessageRepository;
|
||||
|
||||
@Mock
|
||||
private UserInServerManagementService userInServerManagementService;
|
||||
|
||||
@Mock
|
||||
private ServerManagementService serverManagementService;
|
||||
|
||||
@Mock
|
||||
private ChannelManagementService channelManagementService;
|
||||
|
||||
@Captor
|
||||
private ArgumentCaptor<EmbeddedMessage> messageArgumentCaptor;
|
||||
|
||||
private static final Long SERVER_ID = 1L;
|
||||
private static final Long EMBEDDING_CHANNEL_ID = 2L;
|
||||
private static final Long EMBEDDED_MESSAGE_ID = 5L;
|
||||
private static final Long EMBEDDING_MESSAGE_ID = 7L;
|
||||
private static final Long EMBEDDED_USER_ID = 8L;
|
||||
private static final Long EMBEDDING_USER_ID = 9L;
|
||||
|
||||
@Test
|
||||
public void testCreateCorrectEmbed() {
|
||||
AUserInAServer embeddingUser = Mockito.mock(AUserInAServer.class);
|
||||
AUserInAServer embeddedUser = Mockito.mock(AUserInAServer.class);
|
||||
AChannel channel = Mockito.mock(AChannel.class);
|
||||
AServer server = Mockito.mock(AServer.class);
|
||||
when(server.getId()).thenReturn(SERVER_ID);
|
||||
when(serverManagementService.loadOrCreate(SERVER_ID)).thenReturn(server);
|
||||
when(channelManagementService.loadChannel(EMBEDDING_CHANNEL_ID)).thenReturn(channel);
|
||||
CachedMessage cachedMessage = Mockito.mock(CachedMessage.class);
|
||||
when(cachedMessage.getMessageId()).thenReturn(EMBEDDED_MESSAGE_ID);
|
||||
when(cachedMessage.getServerId()).thenReturn(SERVER_ID);
|
||||
when(cachedMessage.getChannelId()).thenReturn(EMBEDDING_CHANNEL_ID);
|
||||
CachedAuthor cachedAuthor = Mockito.mock(CachedAuthor.class);
|
||||
when(cachedAuthor.getAuthorId()).thenReturn(EMBEDDED_USER_ID);
|
||||
when(cachedMessage.getAuthor()).thenReturn(cachedAuthor);
|
||||
when(cachedMessage.getServerId()).thenReturn(SERVER_ID);
|
||||
Message embeddingMessage = Mockito.mock(Message.class);
|
||||
MessageChannel embeddingChannel = Mockito.mock(MessageChannel.class);
|
||||
when(embeddingChannel.getIdLong()).thenReturn(EMBEDDING_CHANNEL_ID);
|
||||
when(embeddingMessage.getChannel()).thenReturn(embeddingChannel);
|
||||
User embeddingJdaUser = Mockito.mock(User.class);
|
||||
when(embeddingJdaUser.getIdLong()).thenReturn(EMBEDDING_USER_ID);
|
||||
when(embeddingMessage.getAuthor()).thenReturn(embeddingJdaUser);
|
||||
Guild guild = Mockito.mock(Guild.class);
|
||||
when(embeddingMessage.getGuild()).thenReturn(guild);
|
||||
when(guild.getIdLong()).thenReturn(SERVER_ID);
|
||||
when(embeddingMessage.getIdLong()).thenReturn(EMBEDDING_MESSAGE_ID);
|
||||
when(userInServerManagementService.loadOrCreateUser(SERVER_ID, EMBEDDED_USER_ID)).thenReturn(embeddedUser);
|
||||
testUnit.createMessageEmbed(cachedMessage, embeddingMessage, embeddingUser);
|
||||
verify(embeddedMessageRepository, times(1)).save(messageArgumentCaptor.capture());
|
||||
EmbeddedMessage savedMessage = messageArgumentCaptor.getValue();
|
||||
Assert.assertEquals(EMBEDDED_MESSAGE_ID, savedMessage.getEmbeddedMessageId());
|
||||
Assert.assertEquals(channel, savedMessage.getEmbeddedChannel());
|
||||
Assert.assertEquals(channel, savedMessage.getEmbeddingChannel());
|
||||
Assert.assertEquals(embeddedUser, savedMessage.getEmbeddedUser());
|
||||
Assert.assertEquals(embeddingUser, savedMessage.getEmbeddingUser());
|
||||
Assert.assertEquals(server, savedMessage.getEmbeddedServer());
|
||||
Assert.assertEquals(server, savedMessage.getEmbeddingServer());
|
||||
Assert.assertEquals(EMBEDDING_MESSAGE_ID, savedMessage.getEmbeddingMessageId());
|
||||
}
|
||||
|
||||
@Test(expected = CrossServerEmbedException.class)
|
||||
public void testToCreateEmbedForDifferentServers() {
|
||||
Long originServerId = 4L;
|
||||
AServer originalServer = Mockito.mock(AServer.class);
|
||||
when(originalServer.getId()).thenReturn(originServerId);
|
||||
AServer embeddingServer = Mockito.mock(AServer.class);
|
||||
when(embeddingServer.getId()).thenReturn(SERVER_ID);
|
||||
AUserInAServer embeddingUser = Mockito.mock(AUserInAServer.class);
|
||||
when(serverManagementService.loadOrCreate(SERVER_ID)).thenReturn(embeddingServer);
|
||||
when(serverManagementService.loadOrCreate(originServerId)).thenReturn(originalServer);
|
||||
CachedMessage cachedMessage = Mockito.mock(CachedMessage.class);
|
||||
when(cachedMessage.getServerId()).thenReturn(originServerId);
|
||||
Message message = Mockito.mock(Message.class);
|
||||
Guild guild = Mockito.mock(Guild.class);
|
||||
when(message.getGuild()).thenReturn(guild);
|
||||
when(guild.getIdLong()).thenReturn(SERVER_ID);
|
||||
testUnit.createMessageEmbed(cachedMessage, message, embeddingUser);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteEmbeddedMessage() {
|
||||
EmbeddedMessage message = Mockito.mock(EmbeddedMessage.class);
|
||||
testUnit.deleteEmbeddedMessage(message);
|
||||
verify(embeddedMessageRepository, times(1)).delete(message);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFindEmbeddedMessageByMessageIdSuccessful() {
|
||||
Long id = 5L;
|
||||
EmbeddedMessage message = Mockito.mock(EmbeddedMessage.class);
|
||||
when(embeddedMessageRepository.findByEmbeddingMessageId(id)).thenReturn(message);
|
||||
Optional<EmbeddedMessage> embeddedPostByMessageId = testUnit.findEmbeddedPostByMessageId(id);
|
||||
Assert.assertTrue(embeddedPostByMessageId.isPresent());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFindEmbeddedMessageByMessageIdFailing() {
|
||||
Long id = 5L;
|
||||
when(embeddedMessageRepository.findByEmbeddingMessageId(id)).thenReturn(null);
|
||||
Optional<EmbeddedMessage> embeddedPostByMessageId = testUnit.findEmbeddedPostByMessageId(id);
|
||||
Assert.assertFalse(embeddedPostByMessageId.isPresent());
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user