[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:
Sheldan
2021-03-12 17:29:49 +01:00
parent e2da800d84
commit 2ed456c164
835 changed files with 12790 additions and 3310 deletions

View File

@@ -0,0 +1,60 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>link-embed</artifactId>
<groupId>dev.sheldan.abstracto.modules</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>link-embed-impl</artifactId>
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptors>
<descriptor>src/main/assembly/liquibase.xml</descriptor>
</descriptors>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>dev.sheldan.abstracto.modules</groupId>
<artifactId>link-embed-int</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>dev.sheldan.abstracto.core</groupId>
<artifactId>metrics-int</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>dev.sheldan.abstracto.core</groupId>
<artifactId>core-int</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@@ -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>

View File

@@ -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 {
}

View File

@@ -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");
}
}

View File

@@ -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.");
}
}

View File

@@ -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);
}

View File

@@ -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();
}
}

View File

@@ -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);
}
}

View File

@@ -0,0 +1,2 @@
abstracto.featureFlags.linkEmbeds.featureName=linkEmbeds
abstracto.featureFlags.linkEmbeds.enabled=false

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

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-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>

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-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>

View File

@@ -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);
}
}

View File

@@ -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());
}
}

View File

@@ -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;
}
}

View File

@@ -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());
}
}