[AB-200] fixing link embeds not working for users who left the server

fixing some issues with optional dependencies (autowired creates null instances etc)
fixing roll and roulette using not the proper default values
fixing setPrefix not creating an instance, in case it originated from a default config
fixing too many configuration properties in utility
This commit is contained in:
Sheldan
2021-03-16 01:18:31 +01:00
parent 94d6497995
commit cfe7786d4d
15 changed files with 87 additions and 84 deletions

View File

@@ -42,7 +42,7 @@ public class Roll extends AbstractConditionableCommand {
@Override
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
List<Object> parameters = commandContext.getParameters().getParameters();
Integer high = configService.getLongValue(EntertainmentFeature.ROLL_DEFAULT_HIGH_KEY, commandContext.getGuild().getIdLong()).intValue();
Integer high = configService.getLongValueOrConfigDefault(EntertainmentFeature.ROLL_DEFAULT_HIGH_KEY, commandContext.getGuild().getIdLong()).intValue();
Integer low = 1;
if(parameters.size() > 1) {
low = (Integer) parameters.get(1);

View File

@@ -45,7 +45,7 @@ public class EntertainmentServiceBean implements EntertainmentService {
@Override
public boolean executeRoulette(Member memberExecuting) {
Long possibilities = configService.getLongValue(EntertainmentFeature.ROULETTE_BULLETS_CONFIG_KEY, memberExecuting.getGuild().getIdLong());
Long possibilities = configService.getLongValueOrConfigDefault(EntertainmentFeature.ROULETTE_BULLETS_CONFIG_KEY, memberExecuting.getGuild().getIdLong());
// 1/possibilities of chance, we don't have a state, each time its reset
return secureRandom.nextInt(possibilities.intValue()) == 0;
}

View File

@@ -12,9 +12,9 @@ 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 net.dv8tion.jda.api.entities.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
@@ -47,6 +47,9 @@ public class MessageEmbedServiceBean implements MessageEmbedService {
@Autowired
private MemberService memberService;
@Autowired
private UserService userService;
@Autowired
private TemplateService templateService;
@@ -105,15 +108,9 @@ public class MessageEmbedServiceBean implements MessageEmbedService {
@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);
}
return buildTemplateParameter(embeddingMessage, cachedMessage).thenCompose(messageEmbeddedModel ->
self.sendEmbeddingMessage(cachedMessage, target, userEmbeddingUserInServerId, messageEmbeddedModel)
);
}
@Transactional
@@ -132,25 +129,25 @@ public class MessageEmbedServiceBean implements MessageEmbedService {
}
@Transactional
public void loadUserAndPersistMessage(CachedMessage cachedMessage, Long userInServerId, Message createdMessage) {
AUserInAServer innerCause = userInServerManagementService.loadOrCreateUser(userInServerId);
public void loadUserAndPersistMessage(CachedMessage cachedMessage, Long embeddingUserId, Message createdMessage) {
AUserInAServer innerCause = userInServerManagementService.loadOrCreateUser(embeddingUserId);
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)
return userService.retrieveUserForId(embeddedMessage.getAuthor().getAuthorId()).thenApply(authorUser ->
self.loadMessageEmbedModel(message, embeddedMessage, authorUser)
);
}
@Transactional
public MessageEmbeddedModel loadMessageEmbedModel(Message message, CachedMessage embeddedMessage, Member member) {
public MessageEmbeddedModel loadMessageEmbedModel(Message message, CachedMessage embeddedMessage, User userAuthor) {
Optional<TextChannel> textChannelFromServer = channelService.getTextChannelFromServerOptional(embeddedMessage.getServerId(), embeddedMessage.getChannelId());
TextChannel sourceChannel = textChannelFromServer.orElse(null);
return MessageEmbeddedModel
.builder()
.member(message.getMember())
.author(member)
.author(userAuthor)
.sourceChannel(sourceChannel)
.embeddingUser(message.getMember())
.messageChannel(message.getChannel())

View File

@@ -39,7 +39,7 @@ public class MessageEmbedPostManagementServiceBean implements MessageEmbedPostMa
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())) {
if(!embeddedMessage.getServerId().equals(messageContainingEmbed.getGuild().getIdLong())) {
throw new CrossServerEmbedException(String.format("Message %s is not from server %s", embeddedMessage.getMessageUrl(), embeddingServer.getId()));
}
AChannel embeddingChannel = channelManagementService.loadChannel(messageContainingEmbed.getChannel().getIdLong());

View File

@@ -14,10 +14,7 @@ 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 net.dv8tion.jda.api.entities.*;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -64,6 +61,9 @@ public class MessageEmbedServiceBeanTest {
@Mock
private MessageEmbedPostManagementService messageEmbedPostManagementService;
@Mock
private UserService userService;
@Mock
private ReactionService reactionService;
@@ -100,6 +100,9 @@ public class MessageEmbedServiceBeanTest {
@Mock
private Member embeddedMember;
@Mock
private User embeddedUser;
@Test
public void testNoLinkInString(){
String message = "test";
@@ -203,14 +206,12 @@ public class MessageEmbedServiceBeanTest {
@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));
when(userService.retrieveUserForId(USER_ID)).thenReturn(CompletableFuture.completedFuture(embeddedUser));
MessageEmbeddedModel model = Mockito.mock(MessageEmbeddedModel.class);
when(self.loadMessageEmbedModel(embeddingMessage, cachedMessage, embeddingMember)).thenReturn(model);
when(self.loadMessageEmbedModel(embeddingMessage, cachedMessage, embeddedUser)).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());
@@ -221,7 +222,10 @@ public class MessageEmbedServiceBeanTest {
Long firstMessageId = 6L;
CachedMessage cachedMessage = mockCachedMessage(firstMessageId);
Long userEmbeddingUserInServerId = 5L;
when(userInServerManagementService.loadUserOptional(userEmbeddingUserInServerId)).thenReturn(Optional.empty());
CachedAuthor cachedAuthor = Mockito.mock(CachedAuthor.class);
when(cachedAuthor.getAuthorId()).thenReturn(USER_ID);
when(cachedMessage.getAuthor()).thenReturn(cachedAuthor);
when(userService.retrieveUserForId(USER_ID)).thenReturn(CompletableFuture.completedFuture(embeddedUser));
testUnit.embedLink(cachedMessage, textChannel, userEmbeddingUserInServerId, embeddingMessage);
verify(messageCache, times(0)).getMessageFromCache(anyLong(), anyLong(), anyLong());
}
@@ -259,11 +263,11 @@ public class MessageEmbedServiceBeanTest {
when(embeddingMessage.getGuild()).thenReturn(guild);
when(embeddingMessage.getChannel()).thenReturn(textChannel);
when(embeddingMessage.getMember()).thenReturn(embeddingMember);
MessageEmbeddedModel createdModel = testUnit.loadMessageEmbedModel(embeddingMessage, cachedMessage, embeddedMember);
MessageEmbeddedModel createdModel = testUnit.loadMessageEmbedModel(embeddingMessage, cachedMessage, embeddedUser);
Assert.assertEquals(textChannel, createdModel.getSourceChannel());
Assert.assertEquals(guild, createdModel.getGuild());
Assert.assertEquals(textChannel, createdModel.getMessageChannel());
Assert.assertEquals(embeddedMember, createdModel.getAuthor());
Assert.assertEquals(embeddedUser, createdModel.getAuthor());
Assert.assertEquals(embeddingMember, createdModel.getMember());
Assert.assertEquals(embeddingMember, createdModel.getEmbeddingUser());
Assert.assertEquals(cachedMessage, createdModel.getEmbeddedMessage());

View File

@@ -14,7 +14,6 @@
<column name="name" value="starStats"/>
<column name="module_id" valueComputed="${utilityModule}"/>
<column name="feature_id" valueComputed="${starboardFeature}"/>
<column name="created" valueComputed="${today}"/>
</insert>
</changeSet>

View File

@@ -1,52 +1,2 @@
abstracto.systemConfigs.starLvl1.name=starLvl1
abstracto.systemConfigs.starLvl1.longValue=5
abstracto.systemConfigs.starLvl2.name=starLvl2
abstracto.systemConfigs.starLvl2.longValue=8
abstracto.systemConfigs.starLvl3.name=starLvl3
abstracto.systemConfigs.starLvl3.longValue=13
abstracto.systemConfigs.starLvl4.name=starLvl4
abstracto.systemConfigs.starLvl4.longValue=17
abstracto.systemConfigs.starLvls.name=starLvls
abstracto.systemConfigs.starLvls.longValue=4
abstracto.systemConfigs.rouletteBullets.name=rouletteBullets
abstracto.systemConfigs.rouletteBullets.longValue=6
abstracto.systemConfigs.rollDefaultHigh.name=rollDefaultHigh
abstracto.systemConfigs.rollDefaultHigh.longValue=6
abstracto.featureFlags.starboard.featureName=starboard
abstracto.featureFlags.starboard.enabled=false
abstracto.featureFlags.remind.featureName=remind
abstracto.featureFlags.remind.enabled=false
abstracto.featureFlags.suggestion.featureName=suggestion
abstracto.featureFlags.suggestion.enabled=false
abstracto.featureFlags.utility.featureName=utility
abstracto.featureFlags.utility.enabled=false
abstracto.featureFlags.linkEmbeds.featureName=linkEmbeds
abstracto.featureFlags.linkEmbeds.enabled=false
abstracto.featureFlags.repostDetection.featureName=repostDetection
abstracto.featureFlags.repostDetection.enabled=false
abstracto.featureFlags.entertainment.featureName=entertainment
abstracto.featureFlags.entertainment.enabled=false
abstracto.postTargets.suggestions.name=suggestions
abstracto.postTargets.starboard.name=starboard
abstracto.featureModes.download.featureName=repostDetection
abstracto.featureModes.download.mode=download
abstracto.featureModes.download.enabled=true
abstracto.featureModes.leaderboard.featureName=repostDetection
abstracto.featureModes.leaderboard.mode=leaderboard
abstracto.featureModes.leaderboard.enabled=true

View File

@@ -26,7 +26,7 @@ public class SetPrefix extends AbstractConditionableCommand {
@Override
public CommandResult execute(CommandContext commandContext) {
String prefixValue = (String) commandContext.getParameters().getParameters().get(0);
configService.setStringValue("prefix", commandContext.getGuild().getIdLong(), prefixValue);
configService.setOrCreateConfigValue("prefix", commandContext.getGuild().getIdLong(), prefixValue);
return CommandResult.fromSuccess();
}

View File

@@ -36,6 +36,9 @@ public class DefaultConfigProperties {
}
private <T> void makeKeysLowerCase(Map<String, T> map) {
if(map == null) {
return;
}
Set<String> keys = new HashSet<>(map.keySet());
List<Pair<String, T>> pairs = new ArrayList<>();
keys.forEach(s ->

View File

@@ -15,11 +15,14 @@ import java.util.Optional;
@Slf4j
public class ConditionServiceBean implements ConditionService {
@Autowired
@Autowired(required = false)
private List<SystemCondition> conditionList;
@Override
public boolean checkConditions(ConditionContextInstance context) {
if(conditionList == null || conditionList.isEmpty()) {
return true;
}
Optional<SystemCondition> matchingCondition = conditionList
.stream()
.filter(systemCondition -> systemCondition.getConditionName().equalsIgnoreCase(context.getConditionName()))

View File

@@ -31,6 +31,11 @@ public class ConfigServiceBean implements ConfigService {
return getLongValue(name, serverId, 0L);
}
@Override
public Long getLongValueOrConfigDefault(String name, Long serverId) {
return getLongValue(name, serverId, defaultConfigManagementService.getDefaultConfig(name).getLongValue());
}
@Override
public Double getDoubleValue(String name, Long serverId, Double defaultValue) {
AConfig config = configManagementService.loadConfig(serverId, name);
@@ -40,6 +45,11 @@ public class ConfigServiceBean implements ConfigService {
return config.getDoubleValue();
}
@Override
public Double getDoubleValueOrConfigDefault(String name, Long serverId, Double defaultValue) {
return getDoubleValue(name, serverId, defaultConfigManagementService.getDefaultConfig(name).getDoubleValue());
}
@Override
public String getStringValue(String name, Long serverId, String defaultValue) {
AConfig config = configManagementService.loadConfig(serverId, name);
@@ -49,6 +59,11 @@ public class ConfigServiceBean implements ConfigService {
return config.getStringValue();
}
@Override
public String getStringValueOrConfigDefault(String name, Long serverId, String defaultValue) {
return getStringValue(name, serverId, defaultConfigManagementService.getDefaultConfig(name).getStringValue());
}
@Override
public Long getLongValue(String name, Long serverId, Long defaultValue) {
AConfig config = configManagementService.loadConfig(serverId, name);

View File

@@ -0,0 +1,19 @@
package dev.sheldan.abstracto.core.service;
import net.dv8tion.jda.api.entities.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.concurrent.CompletableFuture;
@Component
public class UserServiceBean implements UserService {
@Autowired
private BotService botService;
@Override
public CompletableFuture<User> retrieveUserForId(Long id) {
return botService.getInstance().retrieveUserById(id).submit();
}
}

View File

@@ -7,13 +7,14 @@ import lombok.Setter;
import lombok.experimental.SuperBuilder;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.TextChannel;
import net.dv8tion.jda.api.entities.User;
@Getter
@Setter
@SuperBuilder
public class MessageEmbeddedModel extends UserInitiatedServerContext {
private CachedMessage embeddedMessage;
private Member author;
private User author;
private TextChannel sourceChannel;
private Member embeddingUser;
}

View File

@@ -5,8 +5,11 @@ import dev.sheldan.abstracto.core.models.database.AConfig;
public interface ConfigService {
Double getDoubleValue(String name, Long serverId);
Long getLongValue(String name, Long serverId);
Long getLongValueOrConfigDefault(String name, Long serverId);
Double getDoubleValue(String name, Long serverId, Double defaultValue);
Double getDoubleValueOrConfigDefault(String name, Long serverId, Double defaultValue);
String getStringValue(String name, Long serverId, String defaultValue);
String getStringValueOrConfigDefault(String name, Long serverId, String defaultValue);
Long getLongValue(String name, Long serverId, Long defaultValue);
AConfig setOrCreateConfigValue(Long serverId, String name, AConfig value);
void setDoubleValue(String name, Long serverId, Double value);

View File

@@ -0,0 +1,9 @@
package dev.sheldan.abstracto.core.service;
import net.dv8tion.jda.api.entities.User;
import java.util.concurrent.CompletableFuture;
public interface UserService {
CompletableFuture<User> retrieveUserForId(Long id);
}