mirror of
https://github.com/Sheldan/abstracto.git
synced 2026-07-06 20:47:16 +00:00
[AB-139] changing the places at which there might be an uncached member object
fixing integer validator fixing syncing roles not working if the role did not change in the database fixing warn id being flipped fixing star stats model
This commit is contained in:
@@ -554,7 +554,7 @@ public class AssignableRolePlaceServiceBean implements AssignableRolePlaceServic
|
||||
public void showAssignablePlaceConfig(AServer server, String name, MessageChannel channel) {
|
||||
AssignableRolePlace place = rolePlaceManagementService.findByServerAndKey(server, name);
|
||||
List<AssignablePostConfigRole> roles = new ArrayList<>();
|
||||
Guild guild = botService.getGuildByIdNullable(server.getId());
|
||||
Guild guild = botService.getGuildById(server.getId());
|
||||
log.info("Showing assignable role place config for place {} in channel {} on server {}.", place.getId(), channel.getId(), server.getId());
|
||||
List<AssignableRole> assignableRoles = place.getAssignableRoles().stream().sorted(Comparator.comparingInt(AssignableRole::getPosition)).collect(Collectors.toList());
|
||||
for (AssignableRole role : assignableRoles) {
|
||||
@@ -609,17 +609,16 @@ public class AssignableRolePlaceServiceBean implements AssignableRolePlaceServic
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> removeExistingReactionsAndRoles(AssignableRolePlace place, AssignedRoleUser user) {
|
||||
Member memberInServer = botService.getMemberInServer(user.getUser());
|
||||
List<CompletableFuture<Void>> futures = new ArrayList<>();
|
||||
log.info("Removing all existing reactions and roles by user {} on assignable role place {} in server {}.", user.getId(), place.getId(), user.getUser().getServerReference().getId());
|
||||
user.getRoles().forEach(assignableRole -> {
|
||||
futures.add(roleService.removeAssignableRoleFromUser(assignableRole, memberInServer));
|
||||
log.trace("Removing role {} from user {} in server {} because of assignable role clearing.", assignableRole.getRole().getId(), memberInServer.getId(), place.getServer().getId());
|
||||
futures.add(roleService.removeAssignableRoleFromUser(assignableRole, user.getUser()));
|
||||
log.trace("Removing role {} from user {} in server {} because of assignable role clearing.", assignableRole.getRole().getId(), user.getUser().getUserReference().getId(), place.getServer().getId());
|
||||
AEmote emoteToUseObject = emoteManagementService.loadEmote(assignableRole.getEmote().getId());
|
||||
AssignableRolePlacePost assignablePlacePost = assignableRole.getAssignableRolePlacePost();
|
||||
log.trace("Removing reaction with emote {} from user {} in server {} because of assignable role clearing.", emoteToUseObject.getId(), user.getUser().getUserReference().getId(), place.getServer().getId());
|
||||
futures.add(messageService.removeReactionOfUserFromMessageWithFuture(emoteToUseObject, place.getServer().getId(),
|
||||
assignablePlacePost.getUsedChannel().getId(), assignablePlacePost.getId(), memberInServer));
|
||||
assignablePlacePost.getUsedChannel().getId(), assignablePlacePost.getId(), user.getUser().getUserReference().getId()));
|
||||
});
|
||||
return CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]));
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import dev.sheldan.abstracto.assignableroles.service.management.AssignableRoleMa
|
||||
import dev.sheldan.abstracto.assignableroles.service.management.AssignedRoleUserManagementService;
|
||||
import dev.sheldan.abstracto.assignableroles.service.management.AssignedRoleUserManagementServiceBean;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.core.service.BotService;
|
||||
import dev.sheldan.abstracto.core.service.RoleService;
|
||||
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -39,6 +40,9 @@ public class AssignableRoleServiceBean implements AssignableRoleService {
|
||||
@Autowired
|
||||
private AssignableRoleServiceBean self;
|
||||
|
||||
@Autowired
|
||||
private BotService botService;
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> assignAssignableRoleToUser(Long assignableRoleId, Member toAdd) {
|
||||
AssignableRole role = assignableRoleManagementServiceBean.getByAssignableRoleId(assignableRoleId);
|
||||
@@ -69,14 +73,29 @@ public class AssignableRoleServiceBean implements AssignableRoleService {
|
||||
@Override
|
||||
public CompletableFuture<Void> removeAssignableRoleFromUser(AssignableRole assignableRole, Member member) {
|
||||
log.info("Removing assignable role {} from user {} in server {}.", assignableRole.getId(), member.getId(), member.getGuild().getId());
|
||||
return roleService.removeRoleFromMemberFuture(member, assignableRole.getRole());
|
||||
return roleService.removeRoleFromMemberAsync(member, assignableRole.getRole());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public CompletableFuture<Void> removeAssignableRoleFromUser(Long assignableRoleId, Member member) {
|
||||
AssignableRole role = assignableRoleManagementServiceBean.getByAssignableRoleId(assignableRoleId);
|
||||
return self.removeAssignableRoleFromUser(role, member);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> removeAssignableRoleFromUser(AssignableRole assignableRole, AUserInAServer aUserInAServer) {
|
||||
Long assignableRoleId = assignableRole.getId();
|
||||
return botService.getMemberInServerAsync(aUserInAServer).thenCompose(member ->
|
||||
self.removeAssignableRoleFromUser(assignableRoleId, member)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> fullyRemoveAssignableRoleFromUser(AssignableRole assignableRole, Member member) {
|
||||
Long assignableRoleId = assignableRole.getId();
|
||||
return this.removeAssignableRoleFromUser(assignableRole, member).thenAccept(aVoid ->
|
||||
self.removeRoleFromUser(assignableRoleId, member)
|
||||
self.persistRoleRemovalFromUser(assignableRoleId, member)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -114,7 +133,7 @@ public class AssignableRoleServiceBean implements AssignableRoleService {
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void removeRoleFromUser(Long assignableRoleId, Member member) {
|
||||
public void persistRoleRemovalFromUser(Long assignableRoleId, Member member) {
|
||||
AssignableRole role = assignableRoleManagementServiceBean.getByAssignableRoleId(assignableRoleId);
|
||||
AUserInAServer aUserInAServer = userInServerManagementService.loadUser(member);
|
||||
removeRoleFromUser(role, aUserInAServer);
|
||||
|
||||
@@ -12,6 +12,8 @@ public interface AssignableRoleService {
|
||||
void clearAllRolesOfUserInPlace(AssignableRolePlace place, AUserInAServer user);
|
||||
CompletableFuture<Void> fullyAssignAssignableRoleToUser(Long assignableRoleId, Member toAdd);
|
||||
CompletableFuture<Void> removeAssignableRoleFromUser(AssignableRole assignableRole, Member member);
|
||||
CompletableFuture<Void> removeAssignableRoleFromUser(Long assignableRoleId, Member member);
|
||||
CompletableFuture<Void> removeAssignableRoleFromUser(AssignableRole assignableRole, AUserInAServer aUserInAServer);
|
||||
CompletableFuture<Void> fullyRemoveAssignableRoleFromUser(AssignableRole assignableRole, Member member);
|
||||
void addRoleToUser(Long assignableRoleId, AUserInAServer aUserInAServer);
|
||||
void addRoleToUser(AssignableRole assignableRole, AUserInAServer aUserInAServer);
|
||||
|
||||
@@ -16,6 +16,7 @@ import dev.sheldan.abstracto.experience.config.features.ExperienceFeature;
|
||||
import dev.sheldan.abstracto.experience.converter.LeaderBoardModelConverter;
|
||||
import dev.sheldan.abstracto.experience.models.LeaderBoard;
|
||||
import dev.sheldan.abstracto.experience.models.LeaderBoardEntry;
|
||||
import dev.sheldan.abstracto.experience.models.templates.LeaderBoardEntryModel;
|
||||
import dev.sheldan.abstracto.experience.models.templates.LeaderBoardModel;
|
||||
import dev.sheldan.abstracto.experience.service.AUserExperienceService;
|
||||
import dev.sheldan.abstracto.templating.model.MessageToSend;
|
||||
@@ -28,6 +29,7 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Shows the experience gain information of the top 10 users in the server, or if a page number is provided as a parameter, only the members which are on this page.
|
||||
@@ -57,15 +59,22 @@ public class LeaderBoardCommand extends AbstractConditionableCommand {
|
||||
// parameter is optional, in case its not present, we default to the 0th page
|
||||
Integer page = !parameters.isEmpty() ? (Integer) parameters.get(0) : 1;
|
||||
LeaderBoard leaderBoard = userExperienceService.findLeaderBoardData(commandContext.getUserInitiatedContext().getServer(), page);
|
||||
LeaderBoardModel leaderBoardModel = (LeaderBoardModel) ContextConverter.fromCommandContext(commandContext, LeaderBoardModel.class);
|
||||
leaderBoardModel.setUserExperiences(converter.fromLeaderBoard(leaderBoard));
|
||||
LeaderBoardModel leaderBoardModel = (LeaderBoardModel) ContextConverter.slimFromCommandContext(commandContext, LeaderBoardModel.class);
|
||||
List<CompletableFuture<LeaderBoardEntryModel>> futures = new ArrayList<>();
|
||||
List<CompletableFuture<LeaderBoardEntryModel>> completableFutures = converter.fromLeaderBoard(leaderBoard);
|
||||
futures.addAll(completableFutures);
|
||||
log.info("Rendering leaderboard for page {} in server {} for user {}.", page, commandContext.getAuthor().getId(), commandContext.getGuild().getId());
|
||||
|
||||
LeaderBoardEntry userRank = userExperienceService.getRankOfUserInServer(commandContext.getUserInitiatedContext().getAUserInAServer());
|
||||
leaderBoardModel.setUserExecuting(converter.fromLeaderBoardEntry(userRank));
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate(LEADER_BOARD_POST_EMBED_TEMPLATE, leaderBoardModel);
|
||||
return FutureUtils.toSingleFutureGeneric(channelService.sendMessageToSendToChannel(messageToSend, commandContext.getChannel()))
|
||||
.thenApply(aVoid -> CommandResult.fromSuccess());
|
||||
CompletableFuture<LeaderBoardEntryModel> userRankFuture = converter.fromLeaderBoardEntry(userRank);
|
||||
futures.add(userRankFuture);
|
||||
return FutureUtils.toSingleFutureGeneric(futures).thenCompose(aVoid -> {
|
||||
List<LeaderBoardEntryModel> finalModels = completableFutures.stream().map(CompletableFuture::join).collect(Collectors.toList());
|
||||
leaderBoardModel.setUserExperiences(finalModels);
|
||||
leaderBoardModel.setUserExecuting(userRankFuture.join());
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate(LEADER_BOARD_POST_EMBED_TEMPLATE, leaderBoardModel);
|
||||
return FutureUtils.toSingleFutureGeneric(channelService.sendMessageToSendToChannel(messageToSend, commandContext.getChannel()));
|
||||
}).thenApply(aVoid -> CommandResult.fromSuccess());
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -8,20 +8,25 @@ import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.command.execution.ContextConverter;
|
||||
import dev.sheldan.abstracto.core.config.FeatureEnum;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.core.service.ChannelService;
|
||||
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
||||
import dev.sheldan.abstracto.core.utils.FutureUtils;
|
||||
import dev.sheldan.abstracto.experience.config.features.ExperienceFeature;
|
||||
import dev.sheldan.abstracto.experience.converter.LeaderBoardModelConverter;
|
||||
import dev.sheldan.abstracto.experience.models.LeaderBoardEntry;
|
||||
import dev.sheldan.abstracto.experience.models.database.AUserExperience;
|
||||
import dev.sheldan.abstracto.experience.models.templates.LeaderBoardEntryModel;
|
||||
import dev.sheldan.abstracto.experience.models.templates.RankModel;
|
||||
import dev.sheldan.abstracto.experience.service.ExperienceLevelService;
|
||||
import dev.sheldan.abstracto.experience.service.AUserExperienceService;
|
||||
import dev.sheldan.abstracto.experience.service.management.UserExperienceManagementService;
|
||||
import dev.sheldan.abstracto.templating.model.MessageToSend;
|
||||
import dev.sheldan.abstracto.templating.service.TemplateService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
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;
|
||||
@@ -50,19 +55,35 @@ public class Rank extends AbstractConditionableCommand {
|
||||
@Autowired
|
||||
private ChannelService channelService;
|
||||
|
||||
@Autowired
|
||||
private Rank self;
|
||||
|
||||
@Autowired
|
||||
private UserInServerManagementService userInServerManagementService;
|
||||
|
||||
@Autowired
|
||||
private UserExperienceManagementService userExperienceManagementService;
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
|
||||
checkParameters(commandContext);
|
||||
RankModel rankModel = (RankModel) ContextConverter.fromCommandContext(commandContext, RankModel.class);
|
||||
RankModel rankModel = (RankModel) ContextConverter.slimFromCommandContext(commandContext, RankModel.class);
|
||||
LeaderBoardEntry userRank = userExperienceService.getRankOfUserInServer(commandContext.getUserInitiatedContext().getAUserInAServer());
|
||||
rankModel.setRankUser(converter.fromLeaderBoardEntry(userRank));
|
||||
AUserExperience experienceObj = userRank.getExperience();
|
||||
CompletableFuture<LeaderBoardEntryModel> future = converter.fromLeaderBoardEntry(userRank);
|
||||
return future.thenCompose(leaderBoardEntryModel ->
|
||||
self.renderAndSendRank(commandContext, rankModel, leaderBoardEntryModel)
|
||||
).thenApply(result -> CommandResult.fromSuccess());
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public CompletableFuture<Void> renderAndSendRank(CommandContext commandContext, RankModel rankModel, LeaderBoardEntryModel leaderBoardEntryModel) {
|
||||
rankModel.setRankUser(leaderBoardEntryModel);
|
||||
AUserInAServer aUserInAServer = userInServerManagementService.loadUser(commandContext.getAuthor());
|
||||
AUserExperience experienceObj = userExperienceManagementService.findUserInServer(aUserInAServer);
|
||||
log.info("Rendering rank for user {} in server {}.", commandContext.getAuthor().getId(), commandContext.getGuild().getId());
|
||||
rankModel.setExperienceToNextLevel(experienceLevelService.calculateExperienceToNextLevel(experienceObj.getCurrentLevel().getLevel(), experienceObj.getExperience()));
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate(RANK_POST_EMBED_TEMPLATE, rankModel);
|
||||
return FutureUtils.toSingleFutureGeneric(channelService.sendMessageToSendToChannel(messageToSend, commandContext.getChannel()))
|
||||
.thenApply(aVoid -> CommandResult.fromSuccess());
|
||||
return FutureUtils.toSingleFutureGeneric(channelService.sendMessageToSendToChannel(messageToSend, commandContext.getChannel()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -12,6 +12,7 @@ import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
/**
|
||||
* Converter used to convert from {@link LeaderBoard} to a list of {@link LeaderBoardEntryModel}
|
||||
@@ -30,11 +31,11 @@ public class LeaderBoardModelConverter {
|
||||
* @return The list of {@link LeaderBoardEntryModel} which contain the fully fledged information provided to the
|
||||
* leader board template
|
||||
*/
|
||||
public List<LeaderBoardEntryModel> fromLeaderBoard(LeaderBoard leaderBoard) {
|
||||
List<LeaderBoardEntryModel> models = new ArrayList<>();
|
||||
public List<CompletableFuture<LeaderBoardEntryModel>> fromLeaderBoard(LeaderBoard leaderBoard) {
|
||||
List<CompletableFuture<LeaderBoardEntryModel>> models = new ArrayList<>();
|
||||
log.trace("Converting {} entries to a list of leaderbord entries.", leaderBoard.getEntries().size());
|
||||
leaderBoard.getEntries().forEach(leaderBoardEntry -> {
|
||||
LeaderBoardEntryModel entry = fromLeaderBoardEntry(leaderBoardEntry);
|
||||
CompletableFuture<LeaderBoardEntryModel> entry = fromLeaderBoardEntry(leaderBoardEntry);
|
||||
models.add(entry);
|
||||
});
|
||||
return models;
|
||||
@@ -47,14 +48,15 @@ public class LeaderBoardModelConverter {
|
||||
* @return The {@link LeaderBoardEntryModel} accompanied with the {@link Member} reference, might be null, if the
|
||||
* user left the guild
|
||||
*/
|
||||
public LeaderBoardEntryModel fromLeaderBoardEntry(LeaderBoardEntry leaderBoardEntry) {
|
||||
public CompletableFuture<LeaderBoardEntryModel> fromLeaderBoardEntry(LeaderBoardEntry leaderBoardEntry) {
|
||||
AUserInAServer entryUser = leaderBoardEntry.getExperience().getUser();
|
||||
Member entryMember = botService.getMemberInServer(entryUser.getServerReference().getId(), entryUser.getUserReference().getId());
|
||||
return LeaderBoardEntryModel
|
||||
.builder()
|
||||
.experience(leaderBoardEntry.getExperience())
|
||||
.member(entryMember).rank(leaderBoardEntry.getRank())
|
||||
.rank(leaderBoardEntry.getRank())
|
||||
.build();
|
||||
return botService.getMemberInServerAsync(entryUser.getServerReference().getId(), entryUser.getUserReference().getId()).thenApply(member ->
|
||||
LeaderBoardEntryModel
|
||||
.builder()
|
||||
.experience(leaderBoardEntry.getExperience())
|
||||
.member(member).rank(leaderBoardEntry.getRank())
|
||||
.rank(leaderBoardEntry.getRank())
|
||||
.build()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -186,7 +186,7 @@ public class AUserExperienceServiceBean implements AUserExperienceService {
|
||||
AUserInAServer userInAServer = userInServerManagementService.loadUser(userInAServerId);
|
||||
gainedExperience = (int) Math.floor(gainedExperience * multiplier);
|
||||
Member member = botService.getMemberInServer(userInAServer);
|
||||
if(!roleService.hasAnyOfTheRoles(member, disabledRoles)) {
|
||||
if(member != null && !roleService.hasAnyOfTheRoles(member, disabledRoles)) {
|
||||
log.trace("Handling {}. The user gains {}", userInAServer.getUserReference().getId(), gainedExperience);
|
||||
Optional<AUserExperience> aUserExperienceOptional = userExperienceManagementService.findByUserInServerIdOptional(userInAServerId);
|
||||
if(aUserExperienceOptional.isPresent()) {
|
||||
@@ -230,7 +230,7 @@ public class AUserExperienceServiceBean implements AUserExperienceService {
|
||||
futures.add(resultFuture);
|
||||
}
|
||||
} else {
|
||||
log.trace("User {} has a role which makes the user unable to gain experience.", userInAServer.getUserInServerId());
|
||||
log.trace("User {} has a role which makes the user unable to gain experience or the member could not be found in the server.", userInAServer.getUserInServerId());
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -321,43 +321,62 @@ public class AUserExperienceServiceBean implements AUserExperienceService {
|
||||
.userInServerId(user.getUserInServerId())
|
||||
.experienceRoleId(null)
|
||||
.build();
|
||||
if(!botService.isUserInGuild(userExperience.getUser())) {
|
||||
log.trace("User {} is not in server {} anymore. No role calculation done.", userExperience.getUser().getUserInServerId(), userExperience.getUser().getServerReference().getId());
|
||||
return CompletableFuture.completedFuture(returnNullRole.apply(null));
|
||||
}
|
||||
Long userInServerId = user.getUserInServerId();
|
||||
log.trace("Updating experience role for user {} in server {}", user.getUserReference().getId(), user.getServerReference().getId());
|
||||
Long serverId = user.getServerReference().getId();
|
||||
log.trace("Updating experience role for user {} in server {}", user.getUserReference().getId(), serverId);
|
||||
AExperienceRole role = experienceRoleService.calculateRole(roles, currentLevel);
|
||||
Member member = botService.getMemberInServer(user.getServerReference(), user.getUserReference());
|
||||
boolean currentlyHasNoExperienceRole = userExperience.getCurrentExperienceRole() == null;
|
||||
// if calculation results in no role, do not add a role
|
||||
if(role == null) {
|
||||
log.trace("User {} in server {} does not have an experience role, according to new calculation.",
|
||||
user.getUserReference().getId(), user.getServerReference().getId());
|
||||
user.getUserReference().getId(), serverId);
|
||||
// if the user has a experience role currently, remove it
|
||||
if(!currentlyHasNoExperienceRole){
|
||||
return roleService.removeRoleFromUserFuture(user, userExperience.getCurrentExperienceRole().getRole())
|
||||
.thenApply(returnNullRole);
|
||||
}
|
||||
return CompletableFuture.completedFuture(returnNullRole.apply(null));
|
||||
}
|
||||
boolean userHasRoleAlready = roleService.memberHasRole(member, role.getRole());
|
||||
Long experienceRoleId = role.getId();
|
||||
Function<Void, RoleCalculationResult> fullResult = aVoid -> RoleCalculationResult
|
||||
.builder()
|
||||
.experienceRoleId(experienceRoleId)
|
||||
.userInServerId(userInServerId)
|
||||
.build();
|
||||
if(!userHasRoleAlready && (currentlyHasNoExperienceRole || !role.getRole().getId().equals(userExperience.getCurrentExperienceRole().getRole().getId()))) {
|
||||
log.info("User {} in server {} gets a new role {} because of experience.", user.getUserReference().getId(), user.getServerReference().getId(), role.getRole().getId());
|
||||
CompletableFuture<Void> removalFuture;
|
||||
if(!currentlyHasNoExperienceRole && botService.isUserInGuild(userExperience.getUser())) {
|
||||
removalFuture = roleService.removeRoleFromUserFuture(user, userExperience.getCurrentExperienceRole().getRole());
|
||||
} else {
|
||||
removalFuture = CompletableFuture.completedFuture(null);
|
||||
Long roleId = role.getRole().getId();
|
||||
// if the new role is already the one configured in the database
|
||||
Long userId = user.getUserReference().getId();
|
||||
Long oldUserExperienceRoleId = currentlyHasNoExperienceRole ? 0L : userExperience.getCurrentExperienceRole().getRole().getId();
|
||||
return botService.getMemberInServerAsync(user).thenCompose(member -> {
|
||||
boolean userHasRoleAlready = roleService.memberHasRole(member, roleId);
|
||||
boolean userHasOldRole = false;
|
||||
boolean rolesChanged = true;
|
||||
if(!currentlyHasNoExperienceRole) {
|
||||
userHasOldRole = roleService.memberHasRole(member, oldUserExperienceRoleId);
|
||||
rolesChanged = !roleId.equals(oldUserExperienceRoleId);
|
||||
}
|
||||
CompletableFuture<Void> addRoleFuture = roleService.addRoleToUserFuture(user, role.getRole());
|
||||
return CompletableFuture.allOf(removalFuture, addRoleFuture).thenApply(fullResult);
|
||||
}
|
||||
return CompletableFuture.completedFuture(fullResult.apply(null));
|
||||
Function<Void, RoleCalculationResult> fullResult = aVoid -> RoleCalculationResult
|
||||
.builder()
|
||||
.experienceRoleId(experienceRoleId)
|
||||
.userInServerId(userInServerId)
|
||||
.build();
|
||||
// if the roles changed or
|
||||
// the user does not have the new target role already
|
||||
// the user still has the old role
|
||||
if((!userHasRoleAlready || userHasOldRole)) {
|
||||
log.info("User {} in server {} gets a new role {} because of experience.", userId, serverId, roleId);
|
||||
CompletableFuture<Void> removalFuture;
|
||||
if(userHasOldRole && rolesChanged) {
|
||||
removalFuture = roleService.removeRoleFromMemberAsync(member, oldUserExperienceRoleId);
|
||||
} else {
|
||||
removalFuture = CompletableFuture.completedFuture(null);
|
||||
}
|
||||
CompletableFuture<Void> addRoleFuture;
|
||||
if(!userHasRoleAlready) {
|
||||
addRoleFuture = roleService.addRoleToMemberFuture(member, roleId);
|
||||
} else {
|
||||
addRoleFuture = CompletableFuture.completedFuture(null);
|
||||
}
|
||||
return CompletableFuture.allOf(removalFuture, addRoleFuture).thenApply(fullResult);
|
||||
}
|
||||
// we are turning the full calculation result regardless
|
||||
return CompletableFuture.completedFuture(fullResult.apply(null));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -405,7 +424,7 @@ public class AUserExperienceServiceBean implements AUserExperienceService {
|
||||
if(result != null) {
|
||||
AUserInAServer user = userInServerManagementService.loadUser(result.getUserInServerId());
|
||||
AUserExperience userExperience = userExperienceManagementService.findUserInServer(user);
|
||||
log.trace("Updating experience role for {} in server {} to {}", user.getUserInServerId(), user.getServerReference(), result.getExperienceRoleId());
|
||||
log.trace("Updating experience role for {} in server {} to {}", user.getUserInServerId(), user.getServerReference().getId(), result.getExperienceRoleId());
|
||||
if(result.getExperienceRoleId() != null) {
|
||||
log.trace("User experience {} gets new experience role with id {}.", userExperience.getId(), result.getExperienceRoleId());
|
||||
AExperienceRole role = experienceRoleManagementService.getExperienceRoleById(result.getExperienceRoleId());
|
||||
|
||||
@@ -83,7 +83,7 @@ public class ExperienceRoleManagementServiceBean implements ExperienceRoleManage
|
||||
public AExperienceRole setLevelToRole(AExperienceLevel level, ARole role) {
|
||||
Optional<AExperienceRole> byRoleServerAndRoleOptional = getRoleInServerOptional(role);
|
||||
AExperienceRole experienceRole;
|
||||
log.info("Setting role {} in server {} to level {}.", role.getId(), role.getServer().getId(), level);
|
||||
log.info("Setting role {} in server {} to level {}.", role.getId(), role.getServer().getId(), level.getLevel());
|
||||
if(byRoleServerAndRoleOptional.isPresent()) {
|
||||
log.trace("Role already existed. Updating.");
|
||||
experienceRole = byRoleServerAndRoleOptional.get();
|
||||
|
||||
@@ -66,7 +66,7 @@ public class LeaderBoardCommandTest {
|
||||
LeaderBoardEntry executingUserRank = LeaderBoardEntry.builder().build();
|
||||
when(userExperienceService.getRankOfUserInServer(context.getUserInitiatedContext().getAUserInAServer())).thenReturn(executingUserRank);
|
||||
LeaderBoardEntryModel leaderBoardEntryModel = LeaderBoardEntryModel.builder().build();
|
||||
when(converter.fromLeaderBoardEntry(executingUserRank)).thenReturn(leaderBoardEntryModel);
|
||||
when(converter.fromLeaderBoardEntry(executingUserRank)).thenReturn(CompletableFuture.completedFuture(leaderBoardEntryModel));
|
||||
MessageToSend messageToSend = MessageToSend.builder().build();
|
||||
when(templateService.renderEmbedTemplate(eq(LeaderBoardCommand.LEADER_BOARD_POST_EMBED_TEMPLATE), any(LeaderBoardModel.class))).thenReturn(messageToSend);
|
||||
CompletableFuture<CommandResult> result = testUnit.executeAsync(context);
|
||||
|
||||
@@ -2,7 +2,9 @@ package dev.sheldan.abstracto.experience.commands;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.core.service.ChannelService;
|
||||
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
||||
import dev.sheldan.abstracto.experience.converter.LeaderBoardModelConverter;
|
||||
import dev.sheldan.abstracto.experience.models.LeaderBoardEntry;
|
||||
import dev.sheldan.abstracto.experience.models.database.AExperienceLevel;
|
||||
@@ -11,6 +13,7 @@ import dev.sheldan.abstracto.experience.models.templates.LeaderBoardEntryModel;
|
||||
import dev.sheldan.abstracto.experience.models.templates.RankModel;
|
||||
import dev.sheldan.abstracto.experience.service.AUserExperienceService;
|
||||
import dev.sheldan.abstracto.experience.service.ExperienceLevelService;
|
||||
import dev.sheldan.abstracto.experience.service.management.UserExperienceManagementService;
|
||||
import dev.sheldan.abstracto.templating.model.MessageToSend;
|
||||
import dev.sheldan.abstracto.templating.service.TemplateService;
|
||||
import dev.sheldan.abstracto.test.command.CommandConfigValidator;
|
||||
@@ -22,8 +25,10 @@ import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import static dev.sheldan.abstracto.experience.commands.Rank.RANK_POST_EMBED_TEMPLATE;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
@@ -47,23 +52,49 @@ public class RankTest {
|
||||
@Mock
|
||||
private ChannelService channelService;
|
||||
|
||||
@Mock
|
||||
private UserInServerManagementService userInServerManagementService;
|
||||
|
||||
@Mock
|
||||
private Rank self;
|
||||
|
||||
@Mock
|
||||
private AUserInAServer aUserInAServer;
|
||||
|
||||
@Mock
|
||||
private UserExperienceManagementService userExperienceManagementService;
|
||||
|
||||
@Test
|
||||
public void testRankExecution() {
|
||||
CommandContext context = CommandTestUtilities.getNoParameters();
|
||||
LeaderBoardEntry leaderBoardEntry = Mockito.mock(LeaderBoardEntry.class);
|
||||
when(userExperienceService.getRankOfUserInServer(context.getUserInitiatedContext().getAUserInAServer())).thenReturn(leaderBoardEntry);
|
||||
LeaderBoardEntryModel leaderBoardEntryModel = Mockito.mock(LeaderBoardEntryModel.class);
|
||||
when(converter.fromLeaderBoardEntry(leaderBoardEntry)).thenReturn(CompletableFuture.completedFuture(leaderBoardEntryModel));
|
||||
when(self.renderAndSendRank(eq(context), any(RankModel.class), eq(leaderBoardEntryModel))).thenReturn(CompletableFuture.completedFuture(null));
|
||||
CompletableFuture<CommandResult> result = testUnit.executeAsync(context);
|
||||
CommandTestUtilities.checkSuccessfulCompletionAsync(result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRenderAndSend() {
|
||||
int currentLevelValue = 50;
|
||||
long currentExperience = 50L;
|
||||
AExperienceLevel currentLevel = Mockito.mock(AExperienceLevel.class);
|
||||
when(currentLevel.getLevel()).thenReturn(currentLevelValue);
|
||||
AUserExperience aUserExperience = Mockito.mock(AUserExperience.class);
|
||||
when(aUserExperience.getCurrentLevel()).thenReturn(currentLevel);
|
||||
when(aUserExperience.getExperience()).thenReturn(currentExperience);
|
||||
CommandContext context = CommandTestUtilities.getNoParameters();
|
||||
AExperienceLevel currentLevel = AExperienceLevel.builder().level(currentLevelValue).build();
|
||||
AUserExperience aUserExperience = AUserExperience.builder().experience(currentExperience).currentLevel(currentLevel).build();
|
||||
LeaderBoardEntry leaderBoardEntry = LeaderBoardEntry.builder().experience(aUserExperience).build();
|
||||
when(userExperienceService.getRankOfUserInServer(context.getUserInitiatedContext().getAUserInAServer())).thenReturn(leaderBoardEntry);
|
||||
LeaderBoardEntryModel leaderBoardEntryModel = LeaderBoardEntryModel.builder().build();
|
||||
when(converter.fromLeaderBoardEntry(leaderBoardEntry)).thenReturn(leaderBoardEntryModel);
|
||||
RankModel rankModel = Mockito.mock(RankModel.class);
|
||||
LeaderBoardEntryModel leaderBoardEntryModel = Mockito.mock(LeaderBoardEntryModel.class);
|
||||
when(userInServerManagementService.loadUser(context.getAuthor())).thenReturn(aUserInAServer);
|
||||
when(userExperienceManagementService.findUserInServer(aUserInAServer)).thenReturn(aUserExperience);
|
||||
when(experienceLevelService.calculateExperienceToNextLevel(currentLevelValue, currentExperience)).thenReturn(140L);
|
||||
MessageToSend messageToSend = MessageToSend.builder().build();
|
||||
when(templateService.renderEmbedTemplate(eq(Rank.RANK_POST_EMBED_TEMPLATE), any(RankModel.class))).thenReturn(messageToSend);
|
||||
CompletableFuture<CommandResult> result = testUnit.executeAsync(context);
|
||||
verify(channelService, Mockito.times(1)).sendMessageToSendToChannel(messageToSend, context.getChannel());
|
||||
CommandTestUtilities.checkSuccessfulCompletionAsync(result);
|
||||
MessageToSend messageToSend = Mockito.mock(MessageToSend.class);
|
||||
when(templateService.renderEmbedTemplate(RANK_POST_EMBED_TEMPLATE, rankModel)).thenReturn(messageToSend);
|
||||
when(channelService.sendMessageToSendToChannel(messageToSend, context.getChannel())).thenReturn(Arrays.asList(CompletableFuture.completedFuture(null)));
|
||||
testUnit.renderAndSendRank(context, rankModel, leaderBoardEntryModel).join();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -20,6 +20,7 @@ import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@@ -43,11 +44,14 @@ public class LeaderBoardModelConverterTest extends ExperienceRelatedTest {
|
||||
LeaderBoardEntry entry2 = getEntry(server, secondExperience, secondRank);
|
||||
List<LeaderBoardEntry> entries = Arrays.asList(entry, entry2);
|
||||
LeaderBoard leaderBoard = LeaderBoard.builder().entries(entries).build();
|
||||
List<LeaderBoardEntryModel> leaderBoardEntryModels = testUnit.fromLeaderBoard(leaderBoard);
|
||||
LeaderBoardEntryModel firstEntry = leaderBoardEntryModels.get(0);
|
||||
Member member = Mockito.mock(Member.class);
|
||||
when(botService.getMemberInServerAsync(server.getId(), entry.getExperience().getUser().getUserReference().getId())).thenReturn(CompletableFuture.completedFuture(member));
|
||||
when(botService.getMemberInServerAsync(server.getId(), entry2.getExperience().getUser().getUserReference().getId())).thenReturn(CompletableFuture.completedFuture(member));
|
||||
List<CompletableFuture<LeaderBoardEntryModel>> leaderBoardEntryModels = testUnit.fromLeaderBoard(leaderBoard);
|
||||
LeaderBoardEntryModel firstEntry = leaderBoardEntryModels.get(0).join();
|
||||
Assert.assertEquals(firstRank, firstEntry.getRank().intValue());
|
||||
Assert.assertEquals(firstExperience, firstEntry.getExperience().getExperience().longValue());
|
||||
LeaderBoardEntryModel secondEntry = leaderBoardEntryModels.get(1);
|
||||
LeaderBoardEntryModel secondEntry = leaderBoardEntryModels.get(1).join();
|
||||
Assert.assertEquals(secondRank, secondEntry.getRank().intValue());
|
||||
Assert.assertEquals(secondExperience, secondEntry.getExperience().getExperience().longValue());
|
||||
Assert.assertEquals(entries.size(), leaderBoardEntryModels.size());
|
||||
@@ -63,11 +67,12 @@ public class LeaderBoardModelConverterTest extends ExperienceRelatedTest {
|
||||
User user = Mockito.mock(User.class);
|
||||
when(user.getIdLong()).thenReturn(userId);
|
||||
when(member.getUser()).thenReturn(user);
|
||||
when(botService.getMemberInServer(server.getId(), experience.getUser().getUserReference().getId())).thenReturn(member);
|
||||
LeaderBoardEntryModel leaderBoardEntryModel = testUnit.fromLeaderBoardEntry(entry);
|
||||
Assert.assertEquals(1, leaderBoardEntryModel.getRank().intValue());
|
||||
Assert.assertEquals(experience.getUser().getUserReference().getId(), leaderBoardEntryModel.getExperience().getUser().getUserReference().getId());
|
||||
Assert.assertEquals(experience.getUser().getUserReference().getId().longValue(), leaderBoardEntryModel.getMember().getUser().getIdLong());
|
||||
when(botService.getMemberInServerAsync(server.getId(), experience.getUser().getUserReference().getId())).thenReturn(CompletableFuture.completedFuture(member));
|
||||
CompletableFuture<LeaderBoardEntryModel> leaderBoardEntryModel = testUnit.fromLeaderBoardEntry(entry);
|
||||
LeaderBoardEntryModel entryModel = leaderBoardEntryModel.join();
|
||||
Assert.assertEquals(1, entryModel.getRank().intValue());
|
||||
Assert.assertEquals(experience.getUser().getUserReference().getId(), entryModel.getExperience().getUser().getUserReference().getId());
|
||||
Assert.assertEquals(experience.getUser().getUserReference().getId().longValue(), entryModel.getMember().getUser().getIdLong());
|
||||
}
|
||||
|
||||
private LeaderBoardEntry getEntry(AServer server, Integer experienceParameter, Integer rank) {
|
||||
|
||||
@@ -36,7 +36,6 @@ import static org.mockito.Mockito.*;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class AUserExperienceServiceBeanTest extends ExperienceRelatedTest {
|
||||
@@ -92,12 +91,21 @@ public class AUserExperienceServiceBeanTest extends ExperienceRelatedTest {
|
||||
@Mock
|
||||
private AUserExperience userExperience;
|
||||
|
||||
@Mock
|
||||
private AUserExperience userExperience2;
|
||||
|
||||
@Mock
|
||||
private AUserInAServer aUserInAServer;
|
||||
|
||||
@Mock
|
||||
private AUserInAServer aUserInAServer2;
|
||||
|
||||
@Mock
|
||||
private AUser user;
|
||||
|
||||
@Mock
|
||||
private AUser user2;
|
||||
|
||||
@Mock
|
||||
private ServerExperience serverExperience;
|
||||
|
||||
@@ -108,7 +116,10 @@ public class AUserExperienceServiceBeanTest extends ExperienceRelatedTest {
|
||||
private AServer server;
|
||||
|
||||
@Mock
|
||||
private Member member;
|
||||
private Member firstMember;
|
||||
|
||||
@Mock
|
||||
private Member secondMember;
|
||||
|
||||
private static final Long USER_IN_SERVER_ID = 4L;
|
||||
private static final Long USER_ID = 8L;
|
||||
@@ -166,7 +177,6 @@ public class AUserExperienceServiceBeanTest extends ExperienceRelatedTest {
|
||||
AExperienceRole previousExperienceRole = experienceRoles.get(1);
|
||||
setupSimpleSingleUserTest(levels, experienceRoles);
|
||||
when(userExperience.getCurrentExperienceRole()).thenReturn(previousExperienceRole);
|
||||
when(botService.isUserInGuild(aUserInAServer)).thenReturn(true);
|
||||
when(roleService.removeRoleFromUserFuture(userExperience.getUser(), userExperience.getCurrentExperienceRole().getRole())).thenReturn(CompletableFuture.completedFuture(null));
|
||||
when(userExperienceManagementService.findByUserInServerIdOptional(USER_IN_SERVER_ID)).thenReturn(Optional.of(userExperience));
|
||||
testUnit.handleExperienceGain(servers).join();
|
||||
@@ -184,9 +194,8 @@ public class AUserExperienceServiceBeanTest extends ExperienceRelatedTest {
|
||||
when(userExperience.getExperience()).thenReturn(199L);
|
||||
AExperienceRole newRole = experienceRoles.get(2);
|
||||
when(experienceRoleService.calculateRole(eq(experienceRoles), any())).thenReturn(newRole);
|
||||
|
||||
AExperienceRole newAwardedRole = experienceRoles.get(3);
|
||||
when(roleService.memberHasRole(member, newRole.getRole())).thenReturn(true);
|
||||
when(roleService.memberHasRole(firstMember, newRole.getRole().getId())).thenReturn(true);
|
||||
when(userExperienceManagementService.findByUserInServerIdOptional(USER_IN_SERVER_ID)).thenReturn(Optional.of(userExperience));
|
||||
testUnit.handleExperienceGain(servers).join();
|
||||
verify(roleService, times(0)).addRoleToUser(aUserInAServer, newAwardedRole.getRole());
|
||||
@@ -200,15 +209,14 @@ public class AUserExperienceServiceBeanTest extends ExperienceRelatedTest {
|
||||
List<AExperienceRole> experienceRoles = getExperienceRoles(levels);
|
||||
AExperienceRole previousExperienceRole = experienceRoles.get(1);
|
||||
setupSimpleSingleUserTest(levels, experienceRoles);
|
||||
when(botService.getMemberInServer(server, aUserInAServer.getUserReference())).thenReturn(member);
|
||||
AExperienceRole newRole = experienceRoles.get(1);
|
||||
when(userExperience.getCurrentExperienceRole()).thenReturn(newRole);
|
||||
when(experienceRoleService.calculateRole(eq(experienceRoles), any())).thenReturn(newRole);
|
||||
|
||||
AExperienceRole newAwardedRole = experienceRoles.get(3);
|
||||
when(roleService.memberHasRole(member, newRole.getRole())).thenReturn(true);
|
||||
when(roleService.memberHasRole(firstMember, newRole.getRole().getId())).thenReturn(true);
|
||||
when(userExperienceManagementService.findByUserInServerIdOptional(USER_IN_SERVER_ID)).thenReturn(Optional.of(userExperience));
|
||||
testUnit.handleExperienceGain(servers).join();
|
||||
verify(roleService, times(0)).addRoleToUser(aUserInAServer, newAwardedRole.getRole());
|
||||
verify(roleService, times(0)).addRoleToUser(aUserInAServer, newRole.getRole());
|
||||
verify(roleService, times(0)).removeRoleFromUser(aUserInAServer, previousExperienceRole.getRole());
|
||||
}
|
||||
|
||||
@@ -220,16 +228,15 @@ public class AUserExperienceServiceBeanTest extends ExperienceRelatedTest {
|
||||
AExperienceRole previousExperienceRole = null;
|
||||
when(userExperience.getCurrentExperienceRole()).thenReturn(previousExperienceRole);
|
||||
setupSimpleSingleUserTest(levels, experienceRoles);
|
||||
when(botService.getMemberInServer(server, aUserInAServer.getUserReference())).thenReturn(member);
|
||||
when(botService.getMemberInServer(aUserInAServer)).thenReturn(firstMember);
|
||||
AExperienceRole newRole = experienceRoles.get(1);
|
||||
when(experienceRoleService.calculateRole(eq(experienceRoles), any())).thenReturn(newRole);
|
||||
|
||||
when(roleService.memberHasRole(member, newRole.getRole())).thenReturn(false);
|
||||
when(roleService.addRoleToUserFuture(userExperience.getUser(), newRole.getRole())).thenReturn(CompletableFuture.completedFuture(null));
|
||||
when(roleService.memberHasRole(firstMember, newRole.getRole().getId())).thenReturn(false);
|
||||
when(roleService.addRoleToMemberFuture(firstMember, newRole.getRole().getId())).thenReturn(CompletableFuture.completedFuture(null));
|
||||
when(userExperienceManagementService.findByUserInServerIdOptional(USER_IN_SERVER_ID)).thenReturn(Optional.of(userExperience));
|
||||
when(roleService.addRoleToMemberFuture(firstMember, newRole.getRole().getId())).thenReturn(CompletableFuture.completedFuture(null));
|
||||
testUnit.handleExperienceGain(servers).join();
|
||||
verify(roleService, times(0)).removeRoleFromUserFuture(eq(aUserInAServer), any());
|
||||
verify(roleService, times(1)).addRoleToUserFuture(eq(aUserInAServer), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -242,7 +249,7 @@ public class AUserExperienceServiceBeanTest extends ExperienceRelatedTest {
|
||||
when(userExperience.getExperience()).thenReturn(50L);
|
||||
when(serverExperience.getUserInServerIds()).thenReturn(Arrays.asList(USER_IN_SERVER_ID));
|
||||
when(userExperience.getCurrentExperienceRole()).thenReturn(previousExperienceRole);
|
||||
when(botService.getMemberInServer(server, aUserInAServer.getUserReference())).thenReturn(member);
|
||||
when(botService.getMemberInServer(aUserInAServer)).thenReturn(firstMember);
|
||||
AExperienceRole newRole = null;
|
||||
when(experienceRoleService.calculateRole(eq(experienceRoles), any())).thenReturn(newRole);
|
||||
|
||||
@@ -262,7 +269,7 @@ public class AUserExperienceServiceBeanTest extends ExperienceRelatedTest {
|
||||
when(serverExperience.getUserInServerIds()).thenReturn(Arrays.asList(USER_IN_SERVER_ID));
|
||||
AExperienceRole previousExperienceRole = experienceRoles.get(0);
|
||||
when(userExperience.getCurrentExperienceRole()).thenReturn(previousExperienceRole);
|
||||
when(botService.getMemberInServer(server, aUserInAServer.getUserReference())).thenReturn(member);
|
||||
when(botService.getMemberInServer(aUserInAServer)).thenReturn(firstMember);
|
||||
AExperienceRole newRole = null;
|
||||
when(experienceRoleService.calculateRole(eq(experienceRoles), any())).thenReturn(newRole);
|
||||
|
||||
@@ -284,10 +291,9 @@ public class AUserExperienceServiceBeanTest extends ExperienceRelatedTest {
|
||||
when(experienceRoleManagementService.getExperienceRolesForServer(server)).thenReturn(experienceRoles);
|
||||
when(disabledExpRoleManagementService.getDisabledRolesForServer(server)).thenReturn(new ArrayList<>());
|
||||
when(userInServerManagementService.loadUser(USER_IN_SERVER_ID)).thenReturn(aUserInAServer);
|
||||
when(user.getId()).thenReturn(USER_ID);
|
||||
when(aUserInAServer.getUserReference()).thenReturn(user);
|
||||
when(aUserInAServer.getUserReference()).thenReturn(user);
|
||||
when(serverExperience.getUserInServerIds()).thenReturn(Arrays.asList(USER_IN_SERVER_ID));
|
||||
when(botService.getMemberInServer(aUserInAServer)).thenReturn(firstMember);
|
||||
when(userExperience.getExperienceGainDisabled()).thenReturn(true);
|
||||
|
||||
when(userExperienceManagementService.findByUserInServerIdOptional(USER_IN_SERVER_ID)).thenReturn(Optional.of(userExperience));
|
||||
@@ -323,6 +329,8 @@ public class AUserExperienceServiceBeanTest extends ExperienceRelatedTest {
|
||||
when(aUserInAServer.getUserReference()).thenReturn(user);
|
||||
when(aUserInAServer.getServerReference()).thenReturn(server);
|
||||
when(server.getId()).thenReturn(8L);
|
||||
when(botService.getMemberInServer(aUserInAServer)).thenReturn(firstMember);
|
||||
when(roleService.hasAnyOfTheRoles(eq(firstMember), anyList())).thenReturn(false);
|
||||
when(user.getId()).thenReturn(7L);
|
||||
CompletableFuture<Void> future = testUnit.handleExperienceGain(servers);
|
||||
future.join();
|
||||
@@ -331,35 +339,94 @@ public class AUserExperienceServiceBeanTest extends ExperienceRelatedTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSyncNoRoleUserGettingRole() {
|
||||
List<AExperienceRole> usedExperienceRoles = getExperienceRoles(getLevelConfiguration());
|
||||
AExperienceRole previousRole = null;
|
||||
public void testSyncNoRoleUserGettingRole2() {
|
||||
AExperienceLevel level0 = Mockito.mock(AExperienceLevel.class);
|
||||
AExperienceLevel level1 = Mockito.mock(AExperienceLevel.class);
|
||||
List<AExperienceRole> usedExperienceRoles = getExperienceRoles(Arrays.asList(level0, level1));
|
||||
userExperience.setCurrentExperienceRole(null);
|
||||
AExperienceRole afterRole = usedExperienceRoles.get(0);
|
||||
executeSyncSingleUserTest(server, usedExperienceRoles, previousRole, afterRole);
|
||||
when(aUserInAServer.getUserReference()).thenReturn(user);
|
||||
when(aUserInAServer.getServerReference()).thenReturn(server);
|
||||
when(userExperience.getUser()).thenReturn(aUserInAServer);
|
||||
|
||||
when(botService.getMemberInServerAsync(aUserInAServer)).thenReturn(CompletableFuture.completedFuture(firstMember));
|
||||
|
||||
when(experienceRoleManagementService.getExperienceRolesForServer(server)).thenReturn(usedExperienceRoles);
|
||||
when(experienceRoleService.calculateRole(usedExperienceRoles, userExperience.getLevelOrDefault())).thenReturn(afterRole);
|
||||
when(botService.getMemberInServerAsync(userExperience.getUser())).thenReturn(CompletableFuture.completedFuture(firstMember));
|
||||
when(roleService.addRoleToMemberFuture(firstMember, afterRole.getRole().getId())).thenReturn(CompletableFuture.completedFuture(null));
|
||||
CompletableFuture<RoleCalculationResult> calculationFuture = testUnit.syncForSingleUser(userExperience);
|
||||
RoleCalculationResult result = calculationFuture.join();
|
||||
Assert.assertEquals(afterRole.getRole().getId(), result.getExperienceRoleId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSyncUserLosingRole() {
|
||||
List<AExperienceRole> usedExperienceRoles = getExperienceRoles(getLevelConfiguration());
|
||||
AExperienceRole previousRole = usedExperienceRoles.get(0);
|
||||
AExperienceLevel level0 = Mockito.mock(AExperienceLevel.class);
|
||||
AExperienceLevel level1 = Mockito.mock(AExperienceLevel.class);
|
||||
List<AExperienceRole> usedExperienceRoles = getExperienceRoles(Arrays.asList(level0, level1));
|
||||
AExperienceRole beforeRole = usedExperienceRoles.get(0);
|
||||
when(userExperience.getCurrentExperienceRole()).thenReturn(beforeRole);
|
||||
AExperienceRole afterRole = null;
|
||||
executeSyncSingleUserTest(server, usedExperienceRoles, previousRole, afterRole);
|
||||
when(aUserInAServer.getUserReference()).thenReturn(user);
|
||||
when(aUserInAServer.getServerReference()).thenReturn(server);
|
||||
when(userExperience.getUser()).thenReturn(aUserInAServer);
|
||||
|
||||
when(experienceRoleManagementService.getExperienceRolesForServer(server)).thenReturn(usedExperienceRoles);
|
||||
when(experienceRoleService.calculateRole(usedExperienceRoles, userExperience.getLevelOrDefault())).thenReturn(afterRole);
|
||||
when(roleService.removeRoleFromUserFuture(aUserInAServer, beforeRole.getRole())).thenReturn(CompletableFuture.completedFuture(null));
|
||||
CompletableFuture<RoleCalculationResult> calculationFuture = testUnit.syncForSingleUser(userExperience);
|
||||
RoleCalculationResult result = calculationFuture.join();
|
||||
Assert.assertNull(result.getExperienceRoleId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSyncUserKeepRole() {
|
||||
List<AExperienceRole> usedExperienceRoles = getExperienceRoles(getLevelConfiguration());
|
||||
AExperienceRole previousRole = usedExperienceRoles.get(0);
|
||||
public void testSyncUserKeepingRole() {
|
||||
AExperienceLevel level0 = Mockito.mock(AExperienceLevel.class);
|
||||
AExperienceLevel level1 = Mockito.mock(AExperienceLevel.class);
|
||||
List<AExperienceRole> usedExperienceRoles = getExperienceRoles(Arrays.asList(level0, level1));
|
||||
AExperienceRole beforeRole = usedExperienceRoles.get(0);
|
||||
when(userExperience.getCurrentExperienceRole()).thenReturn(beforeRole);
|
||||
AExperienceRole afterRole = usedExperienceRoles.get(0);
|
||||
executeSyncSingleUserTest(server, usedExperienceRoles, previousRole, afterRole);
|
||||
when(aUserInAServer.getUserReference()).thenReturn(user);
|
||||
when(aUserInAServer.getServerReference()).thenReturn(server);
|
||||
when(userExperience.getUser()).thenReturn(aUserInAServer);
|
||||
|
||||
when(botService.getMemberInServerAsync(aUserInAServer)).thenReturn(CompletableFuture.completedFuture(firstMember));
|
||||
|
||||
when(experienceRoleManagementService.getExperienceRolesForServer(server)).thenReturn(usedExperienceRoles);
|
||||
when(experienceRoleService.calculateRole(usedExperienceRoles, userExperience.getLevelOrDefault())).thenReturn(afterRole);
|
||||
when(botService.getMemberInServerAsync(userExperience.getUser())).thenReturn(CompletableFuture.completedFuture(firstMember));
|
||||
when(roleService.memberHasRole(firstMember, afterRole.getRole().getId())).thenReturn(true);
|
||||
CompletableFuture<RoleCalculationResult> calculationFuture = testUnit.syncForSingleUser(userExperience);
|
||||
RoleCalculationResult result = calculationFuture.join();
|
||||
Assert.assertEquals(afterRole.getRole().getId(), result.getExperienceRoleId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSyncUserChangingRole() {
|
||||
List<AExperienceRole> usedExperienceRoles = getExperienceRoles(getLevelConfiguration());
|
||||
AExperienceRole previousRole = usedExperienceRoles.get(0);
|
||||
AExperienceLevel level0 = Mockito.mock(AExperienceLevel.class);
|
||||
AExperienceLevel level1 = Mockito.mock(AExperienceLevel.class);
|
||||
List<AExperienceRole> usedExperienceRoles = getExperienceRoles(Arrays.asList(level0, level1));
|
||||
AExperienceRole beforeRole = usedExperienceRoles.get(0);
|
||||
when(userExperience.getCurrentExperienceRole()).thenReturn(beforeRole);
|
||||
AExperienceRole afterRole = usedExperienceRoles.get(1);
|
||||
executeSyncSingleUserTest(server, usedExperienceRoles, previousRole, afterRole);
|
||||
when(aUserInAServer.getUserReference()).thenReturn(user);
|
||||
when(aUserInAServer.getServerReference()).thenReturn(server);
|
||||
when(userExperience.getUser()).thenReturn(aUserInAServer);
|
||||
when(roleService.memberHasRole(firstMember, beforeRole.getRole().getId())).thenReturn(true);
|
||||
|
||||
when(botService.getMemberInServerAsync(aUserInAServer)).thenReturn(CompletableFuture.completedFuture(firstMember));
|
||||
|
||||
when(experienceRoleManagementService.getExperienceRolesForServer(server)).thenReturn(usedExperienceRoles);
|
||||
when(experienceRoleService.calculateRole(usedExperienceRoles, userExperience.getLevelOrDefault())).thenReturn(afterRole);
|
||||
when(botService.getMemberInServerAsync(userExperience.getUser())).thenReturn(CompletableFuture.completedFuture(firstMember));
|
||||
when(roleService.memberHasRole(firstMember, afterRole.getRole().getId())).thenReturn(false);
|
||||
when(roleService.removeRoleFromMemberAsync(firstMember, beforeRole.getRole().getId())).thenReturn(CompletableFuture.completedFuture(null));
|
||||
when(roleService.addRoleToMemberFuture(firstMember, afterRole.getRole().getId())).thenReturn(CompletableFuture.completedFuture(null));
|
||||
CompletableFuture<RoleCalculationResult> calculationFuture = testUnit.syncForSingleUser(userExperience);
|
||||
RoleCalculationResult result = calculationFuture.join();
|
||||
Assert.assertEquals(afterRole.getRole().getId(), result.getExperienceRoleId());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -415,39 +482,51 @@ public class AUserExperienceServiceBeanTest extends ExperienceRelatedTest {
|
||||
|
||||
@Test
|
||||
public void testSyncAllUsers() {
|
||||
List<AExperienceRole> usedExperienceRoles = getExperienceRoles(getLevelConfiguration());
|
||||
AExperienceRole firstPreviousRole = null;
|
||||
AExperienceRole firstAfterRole = usedExperienceRoles.get(0);
|
||||
AExperienceRole secondPreviousRole = null;
|
||||
AExperienceRole secondAfterRole = null;
|
||||
AExperienceLevel level0 = AExperienceLevel.builder().level(0).build();
|
||||
AExperienceLevel level1 = AExperienceLevel.builder().level(1).build();
|
||||
AUserExperience experience = AUserExperience.builder().experience(40L).user(MockUtils.getUserObject(3L, server)).currentLevel(level1).build();
|
||||
AUserExperience experience2 = AUserExperience.builder().experience(201L).user(MockUtils.getUserObject(4L, server)).currentLevel(level0).build();
|
||||
List<AUserExperience> experiences = Arrays.asList(experience, experience2);
|
||||
AExperienceLevel level0 = Mockito.mock(AExperienceLevel.class);
|
||||
AExperienceLevel level1 = Mockito.mock(AExperienceLevel.class);
|
||||
List<AExperienceRole> usedExperienceRoles = getExperienceRoles(Arrays.asList(level0, level1));
|
||||
AExperienceRole beforeRole = usedExperienceRoles.get(0);
|
||||
|
||||
when(userExperience.getCurrentExperienceRole()).thenReturn(beforeRole);
|
||||
AExperienceRole afterRole = usedExperienceRoles.get(1);
|
||||
when(aUserInAServer.getUserReference()).thenReturn(user);
|
||||
when(user.getId()).thenReturn(8L);
|
||||
when(aUserInAServer.getServerReference()).thenReturn(server);
|
||||
when(userExperience.getUser()).thenReturn(aUserInAServer);
|
||||
when(userExperience.getCurrentLevel()).thenReturn(level0);
|
||||
|
||||
when(aUserInAServer2.getUserReference()).thenReturn(user2);
|
||||
when(user2.getId()).thenReturn(9L);
|
||||
when(aUserInAServer2.getServerReference()).thenReturn(server);
|
||||
when(userExperience2.getUser()).thenReturn(aUserInAServer2);
|
||||
when(userExperience2.getCurrentLevel()).thenReturn(level0);
|
||||
|
||||
when(userExperience2.getCurrentExperienceRole()).thenReturn(beforeRole);
|
||||
|
||||
when(botService.getMemberInServerAsync(aUserInAServer)).thenReturn(CompletableFuture.completedFuture(firstMember));
|
||||
when(botService.getMemberInServerAsync(aUserInAServer2)).thenReturn(CompletableFuture.completedFuture(secondMember));
|
||||
|
||||
when(server.getId()).thenReturn(15L);
|
||||
|
||||
List<AUserInAServer> users = experiences.stream().map(AUserExperience::getUser).collect(Collectors.toList());
|
||||
Member firstMember = Mockito.mock(Member.class);
|
||||
when(botService.getMemberInServer(server, users.get(0).getUserReference())).thenReturn(firstMember);
|
||||
Member secondMember = Mockito.mock(Member.class);
|
||||
when(botService.getMemberInServer(server, users.get(1).getUserReference())).thenReturn(secondMember);
|
||||
experience.setCurrentExperienceRole(firstPreviousRole);
|
||||
experience2.setCurrentExperienceRole(secondPreviousRole);
|
||||
when(userExperienceManagementService.loadAllUsers(server)).thenReturn(experiences);
|
||||
when(experienceRoleManagementService.getExperienceRolesForServer(server)).thenReturn(usedExperienceRoles);
|
||||
when(experienceRoleService.calculateRole(usedExperienceRoles, experience.getLevelOrDefault())).thenReturn(firstAfterRole);
|
||||
when(experienceRoleService.calculateRole(usedExperienceRoles, experience2.getLevelOrDefault())).thenReturn(secondAfterRole);
|
||||
when(botService.getMemberInServer(server, experience.getUser().getUserReference())).thenReturn(firstMember);
|
||||
when(botService.getMemberInServer(server, experience2.getUser().getUserReference())).thenReturn(secondMember);
|
||||
when(botService.isUserInGuild(experience.getUser())).thenReturn(true);
|
||||
when(botService.isUserInGuild(experience2.getUser())).thenReturn(true);
|
||||
when(roleService.addRoleToUserFuture(experience.getUser(), firstAfterRole.getRole())).thenReturn(CompletableFuture.completedFuture(null));
|
||||
when(roleService.memberHasRole(firstMember, firstAfterRole.getRole())).thenReturn(false);
|
||||
List<CompletableFuture<RoleCalculationResult>> futures = testUnit.syncUserRoles(server);
|
||||
RoleCalculationResult result = futures.get(0).join();
|
||||
RoleCalculationResult result2 = futures.get(1).join();
|
||||
Assert.assertEquals(firstAfterRole.getRole().getId(), result.getExperienceRoleId());
|
||||
Assert.assertNull(result2.getExperienceRoleId());
|
||||
when(experienceRoleService.calculateRole(usedExperienceRoles, userExperience.getLevelOrDefault())).thenReturn(afterRole);
|
||||
when(experienceRoleService.calculateRole(usedExperienceRoles, userExperience2.getLevelOrDefault())).thenReturn(afterRole);
|
||||
when(botService.getMemberInServerAsync(userExperience.getUser())).thenReturn(CompletableFuture.completedFuture(firstMember));
|
||||
when(botService.getMemberInServerAsync(userExperience2.getUser())).thenReturn(CompletableFuture.completedFuture(secondMember));
|
||||
when(roleService.memberHasRole(firstMember, afterRole.getRole().getId())).thenReturn(false);
|
||||
when(roleService.memberHasRole(firstMember, beforeRole.getRole().getId())).thenReturn(true);
|
||||
when(roleService.memberHasRole(secondMember, afterRole.getRole().getId())).thenReturn(true);
|
||||
when(roleService.removeRoleFromMemberAsync(firstMember, beforeRole.getRole().getId())).thenReturn(CompletableFuture.completedFuture(null));
|
||||
when(roleService.addRoleToMemberFuture(firstMember, afterRole.getRole().getId())).thenReturn(CompletableFuture.completedFuture(null));
|
||||
List<AUserExperience> experiences = Arrays.asList(userExperience, userExperience2);
|
||||
when(userExperienceManagementService.loadAllUsers(server)).thenReturn(experiences);
|
||||
List<CompletableFuture<RoleCalculationResult>> calculationFutures = testUnit.syncUserRoles(server);
|
||||
verify(roleService, times(0)).removeRoleFromMemberAsync(secondMember, beforeRole.getRole().getId());
|
||||
verify(roleService, times(0)).addRoleToMemberFuture(secondMember, afterRole.getRole().getId());
|
||||
RoleCalculationResult firstResult = calculationFutures.get(0).join();
|
||||
Assert.assertEquals(afterRole.getRole().getId(), firstResult.getExperienceRoleId());
|
||||
RoleCalculationResult secondResult = calculationFutures.get(1).join();
|
||||
Assert.assertEquals(afterRole.getRole().getId(), secondResult.getExperienceRoleId());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -534,12 +613,12 @@ public class AUserExperienceServiceBeanTest extends ExperienceRelatedTest {
|
||||
when(userInServerManagementService.loadUser(USER_IN_SERVER_ID)).thenReturn(aUserInAServer);
|
||||
when(user.getId()).thenReturn(USER_ID);
|
||||
when(aUserInAServer.getUserReference()).thenReturn(user);
|
||||
when(botService.getMemberInServer(server, aUserInAServer.getUserReference())).thenReturn(member);
|
||||
when(botService.getMemberInServer(aUserInAServer)).thenReturn(firstMember);
|
||||
when(botService.getMemberInServerAsync(aUserInAServer)).thenReturn(CompletableFuture.completedFuture(firstMember));
|
||||
when(userExperience.getExperience()).thenReturn(500L);
|
||||
when(userExperience.getUser()).thenReturn(aUserInAServer);
|
||||
when(aUserInAServer.getUserReference()).thenReturn(user);
|
||||
when(aUserInAServer.getServerReference()).thenReturn(server);
|
||||
when(botService.isUserInGuild(userExperience.getUser())).thenReturn(true);
|
||||
when(server.getId()).thenReturn(SERVER_ID);
|
||||
when(user.getId()).thenReturn(USER_ID);
|
||||
}
|
||||
@@ -556,37 +635,6 @@ public class AUserExperienceServiceBeanTest extends ExperienceRelatedTest {
|
||||
verify(messageService, times(messageCount)).updateStatusMessage(channel, messageId, statusMessage);
|
||||
}
|
||||
|
||||
private void executeSyncSingleUserTest(AServer server, List<AExperienceRole> usedExperienceRoles, AExperienceRole previousRole, AExperienceRole afterRole) {
|
||||
AExperienceLevel level0 = AExperienceLevel.builder().level(0).build();
|
||||
AUserExperience experience = AUserExperience.builder().experience(40L).user(MockUtils.getUserObject(3L, server)).currentLevel(level0).build();
|
||||
List<AUserExperience> experiences = Arrays.asList(experience);
|
||||
|
||||
List<AUserInAServer> users = experiences.stream().map(AUserExperience::getUser).collect(Collectors.toList());
|
||||
when(botService.getMemberInServer(server, users.get(0).getUserReference())).thenReturn(member);
|
||||
experience.setCurrentExperienceRole(previousRole);
|
||||
when(experienceRoleManagementService.getExperienceRolesForServer(server)).thenReturn(usedExperienceRoles);
|
||||
when(experienceRoleService.calculateRole(usedExperienceRoles, experience.getLevelOrDefault())).thenReturn(afterRole);
|
||||
when(botService.getMemberInServer(server, experience.getUser().getUserReference())).thenReturn(member);
|
||||
users.forEach(innerUser -> when(botService.isUserInGuild(innerUser)).thenReturn(true));
|
||||
if(afterRole != null) {
|
||||
when(roleService.addRoleToUserFuture(experience.getUser(), afterRole.getRole())).thenReturn(CompletableFuture.completedFuture(null));
|
||||
}
|
||||
if(previousRole != null) {
|
||||
when(roleService.removeRoleFromUserFuture(experience.getUser(), previousRole.getRole())).thenReturn(CompletableFuture.completedFuture(null));
|
||||
}
|
||||
if(afterRole != null && previousRole != null) {
|
||||
boolean sameRole = previousRole.getRole().getId().equals(afterRole.getRole().getId());
|
||||
when(roleService.memberHasRole(member, afterRole.getRole())).thenReturn(sameRole);
|
||||
}
|
||||
CompletableFuture<RoleCalculationResult> calculationFuture = testUnit.syncForSingleUser(experience);
|
||||
RoleCalculationResult result = calculationFuture.join();
|
||||
if(afterRole != null) {
|
||||
Assert.assertEquals(afterRole.getRole().getId(), result.getExperienceRoleId());
|
||||
} else {
|
||||
Assert.assertNull(result.getExperienceRoleId());
|
||||
}
|
||||
}
|
||||
|
||||
private void executeLeaderBoardTest(AServer server, Integer page) {
|
||||
int pageSize = 10;
|
||||
List<AUserExperience> experiences = getUserExperiences(pageSize, server);
|
||||
|
||||
@@ -13,6 +13,7 @@ public class ExperienceGainResult {
|
||||
private CompletableFuture<RoleCalculationResult> calculationResult;
|
||||
private Long userInServerId;
|
||||
private Long newExperience;
|
||||
private Long serverId;
|
||||
private Integer newLevel;
|
||||
private Long newMessageCount;
|
||||
@Builder.Default
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package dev.sheldan.abstracto.experience.models.templates;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.context.UserInitiatedServerContext;
|
||||
import dev.sheldan.abstracto.core.models.context.SlimUserInitiatedServerContext;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
@@ -15,7 +15,7 @@ import java.util.List;
|
||||
@Getter
|
||||
@Setter
|
||||
@SuperBuilder
|
||||
public class LeaderBoardModel extends UserInitiatedServerContext {
|
||||
public class LeaderBoardModel extends SlimUserInitiatedServerContext {
|
||||
/**
|
||||
* List of {@link LeaderBoardEntryModel} containing the information about the users from the requested page.
|
||||
*/
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package dev.sheldan.abstracto.experience.models.templates;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.context.UserInitiatedServerContext;
|
||||
import dev.sheldan.abstracto.core.models.context.SlimUserInitiatedServerContext;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
@@ -13,7 +13,7 @@ import lombok.experimental.SuperBuilder;
|
||||
@Getter
|
||||
@Setter
|
||||
@SuperBuilder
|
||||
public class RankModel extends UserInitiatedServerContext {
|
||||
public class RankModel extends SlimUserInitiatedServerContext {
|
||||
/**
|
||||
* The {@link LeaderBoardEntryModel} containing the experience information about the user executing the rank
|
||||
* command.
|
||||
|
||||
@@ -31,7 +31,7 @@ public class DeleteWarning extends AbstractConditionableCommand {
|
||||
public CommandResult execute(CommandContext commandContext) {
|
||||
checkParameters(commandContext);
|
||||
Long warnId = (Long) commandContext.getParameters().getParameters().get(0);
|
||||
Optional<Warning> optional = warnManagementService.findById(warnId, commandContext.getGuild().getIdLong());
|
||||
Optional<Warning> optional = warnManagementService.findByIdOptional(warnId, commandContext.getGuild().getIdLong());
|
||||
optional.ifPresent(warning -> warnManagementService.deleteWarning(warning));
|
||||
return CommandResult.fromSuccess();
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ import dev.sheldan.abstracto.moderation.config.features.ModerationFeatures;
|
||||
import dev.sheldan.abstracto.moderation.converter.UserNotesConverter;
|
||||
import dev.sheldan.abstracto.moderation.models.database.UserNote;
|
||||
import dev.sheldan.abstracto.moderation.models.template.commands.ListNotesModel;
|
||||
import dev.sheldan.abstracto.moderation.models.template.commands.NoteEntryModel;
|
||||
import dev.sheldan.abstracto.moderation.service.management.UserNoteManagementService;
|
||||
import dev.sheldan.abstracto.templating.service.TemplateService;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
@@ -66,9 +67,12 @@ public class UserNotes extends AbstractConditionableCommand {
|
||||
} else {
|
||||
userNotes = userNoteManagementService.loadNotesForServer(commandContext.getUserInitiatedContext().getServer());
|
||||
}
|
||||
model.setUserNotes(userNotesConverter.fromNotes(userNotes));
|
||||
return FutureUtils.toSingleFutureGeneric(channelService.sendEmbedTemplateInChannel(USER_NOTES_RESPONSE_TEMPLATE, model, commandContext.getChannel()))
|
||||
.thenApply(aVoid -> CommandResult.fromSuccess());
|
||||
CompletableFuture<List<NoteEntryModel>> listCompletableFuture = userNotesConverter.fromNotes(userNotes);
|
||||
return listCompletableFuture.thenCompose(noteEntryModels -> {
|
||||
model.setUserNotes(noteEntryModels);
|
||||
return FutureUtils.toSingleFutureGeneric(channelService.sendEmbedTemplateInChannel(USER_NOTES_RESPONSE_TEMPLATE, model, commandContext.getChannel()))
|
||||
.thenApply(aVoid -> CommandResult.fromSuccess());
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -22,9 +22,11 @@ import dev.sheldan.abstracto.moderation.service.management.WarnManagementService
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
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.concurrent.CompletableFuture;
|
||||
|
||||
@Component
|
||||
public class Warnings extends AbstractConditionableCommand {
|
||||
@@ -45,8 +47,11 @@ public class Warnings extends AbstractConditionableCommand {
|
||||
@Autowired
|
||||
private EventWaiter eventWaiter;
|
||||
|
||||
@Autowired
|
||||
private Warnings self;
|
||||
|
||||
@Override
|
||||
public CommandResult execute(CommandContext commandContext) {
|
||||
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
|
||||
checkParameters(commandContext);
|
||||
List<Warning> warnsToDisplay;
|
||||
if(!commandContext.getParameters().getParameters().isEmpty()) {
|
||||
@@ -55,14 +60,21 @@ public class Warnings extends AbstractConditionableCommand {
|
||||
} else {
|
||||
warnsToDisplay = warnManagementService.getAllWarningsOfServer(commandContext.getUserInitiatedContext().getServer());
|
||||
}
|
||||
List<WarnEntry> warnEntries = warnEntryConverter.fromWarnings(warnsToDisplay);
|
||||
return warnEntryConverter.fromWarnings(warnsToDisplay).thenApply(warnEntries -> {
|
||||
self.renderWarnings(commandContext, warnEntries);
|
||||
return CommandResult.fromSuccess();
|
||||
});
|
||||
|
||||
WarningsModel model = (WarningsModel) ContextConverter.fromCommandContext(commandContext, WarningsModel.class);
|
||||
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void renderWarnings(CommandContext commandContext, List<WarnEntry> warnEntries) {
|
||||
WarningsModel model = (WarningsModel) ContextConverter.slimFromCommandContext(commandContext, WarningsModel.class);
|
||||
model.setWarnings(warnEntries);
|
||||
|
||||
Paginator paginator = paginatorService.createPaginatorFromTemplate(WARNINGS_RESPONSE_TEMPLATE, model, eventWaiter);
|
||||
paginator.display(commandContext.getChannel());
|
||||
return CommandResult.fromSuccess();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -74,6 +86,7 @@ public class Warnings extends AbstractConditionableCommand {
|
||||
.name("warnings")
|
||||
.module(ModerationModule.MODERATION)
|
||||
.templated(true)
|
||||
.async(true)
|
||||
.causesReaction(true)
|
||||
.supportsEmbedException(true)
|
||||
.parameters(parameters)
|
||||
|
||||
@@ -1,15 +1,23 @@
|
||||
package dev.sheldan.abstracto.moderation.converter;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.FullUserInServer;
|
||||
import dev.sheldan.abstracto.core.models.ServerSpecificId;
|
||||
import dev.sheldan.abstracto.core.service.BotService;
|
||||
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
||||
import dev.sheldan.abstracto.core.utils.FutureUtils;
|
||||
import dev.sheldan.abstracto.moderation.models.database.UserNote;
|
||||
import dev.sheldan.abstracto.moderation.models.template.commands.NoteEntryModel;
|
||||
import dev.sheldan.abstracto.moderation.service.management.UserNoteManagementService;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
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.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Component
|
||||
public class UserNotesConverter {
|
||||
@@ -19,18 +27,45 @@ public class UserNotesConverter {
|
||||
@Autowired
|
||||
private BotService botService;
|
||||
|
||||
public List<NoteEntryModel> fromNotes(List<UserNote> userNotes){
|
||||
List<NoteEntryModel> entryModels = new ArrayList<>();
|
||||
@Autowired
|
||||
private UserNotesConverter self;
|
||||
|
||||
@Autowired
|
||||
private UserNoteManagementService userNoteManagementService;
|
||||
|
||||
|
||||
public CompletableFuture<List<NoteEntryModel>> fromNotes(List<UserNote> userNotes){
|
||||
List<CompletableFuture<Member>> memberFutures = new ArrayList<>();
|
||||
HashMap<ServerSpecificId, CompletableFuture<Member>> noteMemberMap = new HashMap<>();
|
||||
userNotes.forEach(userNote -> {
|
||||
CompletableFuture<Member> memberFuture = botService.getMemberInServerAsync(userNote.getUser());
|
||||
memberFutures.add(memberFuture);
|
||||
noteMemberMap.put(userNote.getUserNoteId(), memberFuture);
|
||||
});
|
||||
if(userNotes.isEmpty()) {
|
||||
memberFutures.add(CompletableFuture.completedFuture(null));
|
||||
}
|
||||
|
||||
return FutureUtils.toSingleFutureGeneric(memberFutures).thenApply(aVoid ->
|
||||
self.loadFullNotes(noteMemberMap)
|
||||
);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public List<NoteEntryModel> loadFullNotes(Map<ServerSpecificId, CompletableFuture<Member>> futureHashMap) {
|
||||
List<NoteEntryModel> entryModels = new ArrayList<>();
|
||||
futureHashMap.keySet().forEach(serverSpecificId -> {
|
||||
Member member = futureHashMap.get(serverSpecificId).join();
|
||||
UserNote note = userNoteManagementService.loadNote(serverSpecificId.getId(), serverSpecificId.getServerId());
|
||||
FullUserInServer fullUser = FullUserInServer
|
||||
.builder()
|
||||
.member(botService.getMemberInServer(userNote.getUser()))
|
||||
.aUserInAServer(userNote.getUser())
|
||||
.member(member)
|
||||
.aUserInAServer(note.getUser())
|
||||
.build();
|
||||
NoteEntryModel entryModel = NoteEntryModel
|
||||
.builder()
|
||||
.note(note)
|
||||
.fullUser(fullUser)
|
||||
.note(userNote)
|
||||
.build();
|
||||
entryModels.add(entryModel);
|
||||
});
|
||||
|
||||
@@ -1,14 +1,24 @@
|
||||
package dev.sheldan.abstracto.moderation.converter;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.FullUserInServer;
|
||||
import dev.sheldan.abstracto.core.models.FutureMemberPair;
|
||||
import dev.sheldan.abstracto.core.models.ServerSpecificId;
|
||||
import dev.sheldan.abstracto.core.service.BotService;
|
||||
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
||||
import dev.sheldan.abstracto.core.utils.FutureUtils;
|
||||
import dev.sheldan.abstracto.moderation.models.database.Warning;
|
||||
import dev.sheldan.abstracto.moderation.models.template.commands.WarnEntry;
|
||||
import dev.sheldan.abstracto.moderation.service.management.WarnManagementService;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
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.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Component
|
||||
public class WarnEntryConverter {
|
||||
@@ -16,25 +26,56 @@ public class WarnEntryConverter {
|
||||
@Autowired
|
||||
private BotService botService;
|
||||
|
||||
public List<WarnEntry> fromWarnings(List<Warning> warnings) {
|
||||
List<WarnEntry> entries = new ArrayList<>();
|
||||
@Autowired
|
||||
private UserInServerManagementService userInServerManagementService;
|
||||
|
||||
@Autowired
|
||||
private WarnManagementService warnManagementService;
|
||||
|
||||
@Autowired
|
||||
private WarnEntryConverter self;
|
||||
|
||||
public CompletableFuture<List<WarnEntry>> fromWarnings(List<Warning> warnings) {
|
||||
Map<ServerSpecificId, FutureMemberPair> loadedWarnings = new HashMap<>();
|
||||
List<CompletableFuture<Member>> allFutures = new ArrayList<>();
|
||||
// TODO maybe optimize to not need to look into the cache twice
|
||||
warnings.forEach(warning -> {
|
||||
CompletableFuture<Member> warningMemberFuture = botService.getMemberInServerAsync(warning.getWarningUser());
|
||||
CompletableFuture<Member> warnedMemberFuture = botService.getMemberInServerAsync(warning.getWarnedUser());
|
||||
FutureMemberPair futurePair = FutureMemberPair.builder().firstMember(warningMemberFuture).secondMember(warnedMemberFuture).build();
|
||||
loadedWarnings.put(warning.getWarnId(), futurePair);
|
||||
allFutures.add(warningMemberFuture);
|
||||
allFutures.add(warnedMemberFuture);
|
||||
});
|
||||
return FutureUtils.toSingleFutureGeneric(allFutures).thenApply(aVoid ->
|
||||
self.loadFullWarnEntries(loadedWarnings)
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public List<WarnEntry> loadFullWarnEntries(Map<ServerSpecificId, FutureMemberPair> loadedWarnInfo) {
|
||||
List<WarnEntry> entries = new ArrayList<>();
|
||||
loadedWarnInfo.keySet().forEach(warning -> {
|
||||
FutureMemberPair memberPair = loadedWarnInfo.get(warning);
|
||||
Member warnedMember = memberPair.getSecondMember().join();
|
||||
FullUserInServer warnedUser = FullUserInServer
|
||||
.builder()
|
||||
.member(botService.getMemberInServer(warning.getWarnedUser()))
|
||||
.aUserInAServer(warning.getWarnedUser())
|
||||
.member(warnedMember)
|
||||
.aUserInAServer(userInServerManagementService.loadUser(warnedMember))
|
||||
.build();
|
||||
|
||||
Member warningMember = memberPair.getFirstMember().join();
|
||||
FullUserInServer warningUser = FullUserInServer
|
||||
.builder()
|
||||
.member(botService.getMemberInServer(warning.getWarningUser()))
|
||||
.aUserInAServer(warning.getWarningUser())
|
||||
.member(warningMember)
|
||||
.aUserInAServer(userInServerManagementService.loadUser(warningMember))
|
||||
.build();
|
||||
WarnEntry entry = WarnEntry
|
||||
.builder()
|
||||
.warnedUser(warnedUser)
|
||||
.warningUser(warningUser)
|
||||
.warning(warning)
|
||||
.warning(warnManagementService.findById(warning.getId(), warning.getServerId()))
|
||||
.build();
|
||||
entries.add(entry);
|
||||
});
|
||||
|
||||
@@ -20,8 +20,11 @@ public interface UserNoteRepository extends JpaRepository<UserNote, Long> {
|
||||
List<UserNote> findByUser_ServerReference(AServer server);
|
||||
|
||||
@QueryHints(@QueryHint(name = org.hibernate.annotations.QueryHints.CACHEABLE, value = "true"))
|
||||
boolean existsByUserNoteId_IdAndUserNoteId_ServerId(@NonNull Long aLong, Long serverId);
|
||||
boolean existsByUserNoteId_IdAndUserNoteId_ServerId(@NonNull Long userNoteId, Long serverId);
|
||||
|
||||
void deleteByUserNoteId_IdAndUserNoteId_ServerId(@NonNull Long aLong, Long serverId);
|
||||
|
||||
@QueryHints(@QueryHint(name = org.hibernate.annotations.QueryHints.CACHEABLE, value = "true"))
|
||||
UserNote findByUserNoteId_IdAndUserNoteId_ServerId(Long userNoteId, Long serverId);
|
||||
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ public class BanServiceBean implements BanService {
|
||||
}
|
||||
|
||||
private CompletableFuture<Void> banUser(Long guildId, Long userId, String reason) {
|
||||
Optional<Guild> guildByIdOptional = botService.getGuildById(guildId);
|
||||
Optional<Guild> guildByIdOptional = botService.getGuildByIdOptional(guildId);
|
||||
if(guildByIdOptional.isPresent()) {
|
||||
return banUser(guildByIdOptional.get(), userId, reason);
|
||||
} else {
|
||||
|
||||
@@ -39,6 +39,7 @@ import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.CompletionStage;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@@ -110,22 +111,6 @@ public class MuteServiceBean implements MuteService {
|
||||
return muteUserInServer(mutedUser, mutingUser, reason, unMuteDate, message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> muteAUserInAServer(AUserInAServer userBeingMuted, AUserInAServer userMuting, String reason, Instant unMuteDate, ServerChannelMessage message) {
|
||||
FullUserInServer mutedUser = FullUserInServer
|
||||
.builder()
|
||||
.aUserInAServer(userBeingMuted)
|
||||
.member(botService.getMemberInServer(userBeingMuted))
|
||||
.build();
|
||||
|
||||
FullUserInServer mutingUser = FullUserInServer
|
||||
.builder()
|
||||
.aUserInAServer(userMuting)
|
||||
.member(botService.getMemberInServer(userMuting))
|
||||
.build();
|
||||
return muteUserInServer(mutedUser, mutingUser, reason, unMuteDate, message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> muteUserInServer(FullUserInServer userBeingMuted, FullUserInServer userMuting, String reason, Instant unMuteDate, ServerChannelMessage message) {
|
||||
AServer serverBeingMutedIn = userBeingMuted.getAUserInAServer().getServerReference();
|
||||
@@ -251,7 +236,7 @@ public class MuteServiceBean implements MuteService {
|
||||
return FutureUtils.toSingleFutureGeneric(completableFutures);
|
||||
}
|
||||
|
||||
private CompletableFuture<Void> sendUnMuteLog(UnMuteLog muteLogModel) {
|
||||
private CompletableFuture<Void> sendUnMuteLogMessage(UnMuteLog muteLogModel) {
|
||||
log.trace("Sending unMute log to the mute posttarget.");
|
||||
MessageToSend message = templateService.renderEmbedTemplate(UN_MUTE_LOG_TEMPLATE, muteLogModel);
|
||||
List<CompletableFuture<Message>> completableFutures = postTargetService.sendEmbedInPostTarget(message, MutingPostTarget.MUTE_LOG, muteLogModel.getServer().getId());
|
||||
@@ -279,7 +264,7 @@ public class MuteServiceBean implements MuteService {
|
||||
log.info("UnMuting {} in server {}", mute.getMutedUser().getUserReference().getId(), mutingServer.getId());
|
||||
MuteRole muteRole = muteRoleManagementService.retrieveMuteRoleForServer(mutingServer);
|
||||
log.trace("Using the mute role {} mapping to role {}", muteRole.getId(), muteRole.getRole().getId());
|
||||
Guild guild = botService.getGuildByIdNullable(mutingServer.getId());
|
||||
Guild guild = botService.getGuildById(mutingServer.getId());
|
||||
CompletableFuture<Void> roleRemovalFuture;
|
||||
if(botService.isUserInGuild(guild, mute.getMutedUser())) {
|
||||
roleRemovalFuture = roleService.removeRoleFromUserFuture(mute.getMutedUser(), muteRole.getRole());
|
||||
@@ -287,24 +272,40 @@ public class MuteServiceBean implements MuteService {
|
||||
roleRemovalFuture = CompletableFuture.completedFuture(null);
|
||||
log.info("User to unMute left the guild.");
|
||||
}
|
||||
Long serverId = mutingServer.getId();
|
||||
CompletableFuture<Member> mutingMemberFuture = botService.getMemberInServerAsync(mute.getMutingUser());
|
||||
CompletableFuture<Member> mutedMemberFuture = botService.getMemberInServerAsync(mute.getMutedUser());
|
||||
CompletableFuture<Void> finalFuture = new CompletableFuture<>();
|
||||
CompletableFuture.allOf(mutingMemberFuture, mutedMemberFuture, roleRemovalFuture, mutingMemberFuture, mutedMemberFuture).handle((aVoid, throwable) -> {
|
||||
self.sendUnmuteLog(muteId, guild, mutingMemberFuture, mutedMemberFuture).thenAccept(aVoid1 ->
|
||||
finalFuture.complete(null)
|
||||
);
|
||||
return null;
|
||||
});
|
||||
|
||||
return finalFuture;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public CompletionStage<Void> sendUnmuteLog(Long muteId, Guild guild, CompletableFuture<Member> mutingMemberFuture, CompletableFuture<Member> mutedMemberFuture) {
|
||||
Mute mute = muteManagementService.findMute(muteId, guild.getIdLong());
|
||||
AServer mutingServer = serverManagementService.loadServer(guild.getIdLong());
|
||||
UnMuteLog unMuteLog = UnMuteLog
|
||||
.builder()
|
||||
.mute(mute)
|
||||
.mutingUser(botService.getMemberInServer(mute.getMutingUser()))
|
||||
.unMutedUser(botService.getMemberInServer(mute.getMutedUser()))
|
||||
.mutingUser(mutingMemberFuture.join())
|
||||
.unMutedUser(mutedMemberFuture.join())
|
||||
.guild(guild)
|
||||
.server(mutingServer)
|
||||
.build();
|
||||
CompletableFuture<Void> notificationFuture = sendUnMuteLog(unMuteLog);
|
||||
return CompletableFuture.allOf(roleRemovalFuture, notificationFuture).thenAccept(aVoid ->
|
||||
self.endMuteInDatabase(muteId, serverId)
|
||||
CompletableFuture<Void> notificationFuture = sendUnMuteLogMessage(unMuteLog);
|
||||
return CompletableFuture.allOf(notificationFuture).thenAccept(aVoid ->
|
||||
self.endMuteInDatabase(muteId, guild.getIdLong())
|
||||
);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void endMuteInDatabase(Long muteId, Long serverId) {
|
||||
Optional<Mute> muteOptional = muteManagementService.findMute(muteId, serverId);
|
||||
Optional<Mute> muteOptional = muteManagementService.findMuteOptional(muteId, serverId);
|
||||
muteOptional.ifPresent(mute ->
|
||||
completelyUnMuteUser(mute.getMutedUser())
|
||||
);
|
||||
@@ -315,7 +316,7 @@ public class MuteServiceBean implements MuteService {
|
||||
@Transactional
|
||||
public CompletableFuture<Void> endMute(Long muteId, Long serverId) {
|
||||
log.info("UnMuting the mute {} in server {}", muteId, serverId);
|
||||
Optional<Mute> muteOptional = muteManagementService.findMute(muteId, serverId);
|
||||
Optional<Mute> muteOptional = muteManagementService.findMuteOptional(muteId, serverId);
|
||||
if(muteOptional.isPresent()) {
|
||||
return endMute(muteOptional.get());
|
||||
} else {
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package dev.sheldan.abstracto.moderation.service;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.FutureMemberPair;
|
||||
import dev.sheldan.abstracto.core.models.ServerSpecificId;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.core.service.*;
|
||||
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
|
||||
@@ -19,7 +21,6 @@ import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.templating.service.TemplateService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.entities.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
@@ -27,9 +28,12 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
import java.time.Instant;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.CompletionStage;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
@@ -120,7 +124,6 @@ public class WarnServiceBean implements WarnService {
|
||||
);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private List<Long> flattenWarnings(List<Warning> warningsToDecay) {
|
||||
List<Long> warningIds = new ArrayList<>();
|
||||
warningsToDecay.forEach(warning ->
|
||||
@@ -134,7 +137,7 @@ public class WarnServiceBean implements WarnService {
|
||||
Instant now = Instant.now();
|
||||
log.info("Decaying {} warnings.", warningIds.size());
|
||||
warningIds.forEach(warningId -> {
|
||||
Optional<Warning> warningOptional = warnManagementService.findById(warningId, serverId);
|
||||
Optional<Warning> warningOptional = warnManagementService.findByIdOptional(warningId, serverId);
|
||||
warningOptional.ifPresent(warning ->
|
||||
decayWarning(warning, now)
|
||||
);
|
||||
@@ -152,20 +155,47 @@ public class WarnServiceBean implements WarnService {
|
||||
}
|
||||
|
||||
private CompletableFuture<Void> logDecayedWarnings(AServer server, List<Warning> warningsToDecay) {
|
||||
log.trace("Logging decaying {} warnings in server {}.", warningsToDecay.size(), server.getId());
|
||||
List<WarnDecayWarning> warnDecayWarnings = new ArrayList<>();
|
||||
log.trace("Loading members decaying {} warnings in server {}.", warningsToDecay.size(), server.getId());
|
||||
HashMap<ServerSpecificId, FutureMemberPair> warningMembers = new HashMap<>();
|
||||
List<CompletableFuture<Member>> allFutures = new ArrayList<>();
|
||||
Long serverId = server.getId();
|
||||
warningsToDecay.forEach(warning -> {
|
||||
CompletableFuture<Member> warningMember = botService.getMemberInServerAsync(warning.getWarningUser());
|
||||
CompletableFuture<Member> warnedMember = botService.getMemberInServerAsync(warning.getWarnedUser());
|
||||
FutureMemberPair futurePair = FutureMemberPair.builder().firstMember(warningMember).secondMember(warnedMember).build();
|
||||
warningMembers.put(warning.getWarnId(), futurePair);
|
||||
});
|
||||
CompletableFuture<Void> sendingFuture = new CompletableFuture<>();
|
||||
FutureUtils.toSingleFutureGeneric(allFutures).handle((aVoid, throwable) -> {
|
||||
self.renderAndSendWarnDecayLogs(serverId, warningMembers).thenAccept(aVoid1 ->
|
||||
sendingFuture.complete(null)
|
||||
);
|
||||
return null;
|
||||
});
|
||||
|
||||
return sendingFuture;
|
||||
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public CompletionStage<Void> renderAndSendWarnDecayLogs(Long serverId, Map<ServerSpecificId, FutureMemberPair> warningMembers) {
|
||||
AServer server = serverManagementService.loadServer(serverId);
|
||||
List<WarnDecayWarning> warnDecayWarnings = new ArrayList<>();
|
||||
warningMembers.keySet().forEach(serverSpecificId -> {
|
||||
Warning warning = warnManagementService.findById(serverSpecificId.getId(), serverSpecificId.getServerId());
|
||||
FutureMemberPair pair = warningMembers.get(serverSpecificId);
|
||||
// TODO add ids to render in case any member left the server
|
||||
WarnDecayWarning warnDecayWarning = WarnDecayWarning
|
||||
.builder()
|
||||
.warnedMember(botService.getMemberInServer(warning.getWarnedUser()))
|
||||
.warningMember(botService.getMemberInServer(warning.getWarningUser()))
|
||||
.warnedMember(pair.getFirstMember().join())
|
||||
.warningMember(pair.getSecondMember().join())
|
||||
.warning(warning)
|
||||
.build();
|
||||
warnDecayWarnings.add(warnDecayWarning);
|
||||
});
|
||||
WarnDecayLogModel warnDecayLogModel = WarnDecayLogModel
|
||||
.builder()
|
||||
.guild(botService.getGuildByIdNullable(server.getId()))
|
||||
.guild(botService.getGuildById(server.getId()))
|
||||
.server(server)
|
||||
.warnings(warnDecayWarnings)
|
||||
.build();
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package dev.sheldan.abstracto.moderation.service.management;
|
||||
|
||||
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
|
||||
import dev.sheldan.abstracto.core.models.AServerAChannelMessage;
|
||||
import dev.sheldan.abstracto.core.models.ServerSpecificId;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
@@ -48,10 +49,15 @@ public class MuteManagementServiceBean implements MuteManagementService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Mute> findMute(Long muteId, Long serverId) {
|
||||
public Optional<Mute> findMuteOptional(Long muteId, Long serverId) {
|
||||
return muteRepository.findByMuteId_IdAndMuteId_ServerId(muteId, serverId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mute findMute(Long muteId, Long serverId) {
|
||||
return findMuteOptional(muteId, serverId).orElseThrow(() -> new AbstractoRunTimeException("Mute not found."));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mute saveMute(Mute mute) {
|
||||
muteRepository.save(mute);
|
||||
|
||||
@@ -46,6 +46,11 @@ public class UserNoteManagementServiceBean implements UserNoteManagementService
|
||||
userNoteRepository.deleteByUserNoteId_IdAndUserNoteId_ServerId(id, server.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserNote loadNote(Long userNoteId, Long serverId) {
|
||||
return userNoteRepository.findByUserNoteId_IdAndUserNoteId_ServerId(userNoteId, serverId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean noteExists(Long id, AServer server) {
|
||||
return userNoteRepository.existsByUserNoteId_IdAndUserNoteId_ServerId(id, server.getId());
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package dev.sheldan.abstracto.moderation.service.management;
|
||||
|
||||
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
|
||||
import dev.sheldan.abstracto.core.models.ServerSpecificId;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.moderation.models.database.Warning;
|
||||
@@ -24,7 +25,7 @@ public class WarnManagementServiceBean implements WarnManagementService {
|
||||
public Warning createWarning(AUserInAServer warnedAUser, AUserInAServer warningAUser, String reason, Long warnId) {
|
||||
log.info("Creating warning with id {} for user {} in server {} cast by user {}.",
|
||||
warnId, warnedAUser.getUserReference().getId(), warningAUser.getServerReference().getId(), warningAUser.getUserReference().getId());
|
||||
ServerSpecificId warningId = new ServerSpecificId(warnId, warningAUser.getServerReference().getId());
|
||||
ServerSpecificId warningId = new ServerSpecificId(warningAUser.getServerReference().getId(), warnId);
|
||||
Warning warning = Warning.builder()
|
||||
.reason(reason)
|
||||
.warnedUser(warnedAUser)
|
||||
@@ -64,10 +65,15 @@ public class WarnManagementServiceBean implements WarnManagementService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Warning> findById(Long id, Long serverId) {
|
||||
public Optional<Warning> findByIdOptional(Long id, Long serverId) {
|
||||
return warnRepository.findByWarnId_IdAndWarnId_ServerId(id, serverId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Warning findById(Long id, Long serverId) {
|
||||
return findByIdOptional(id, serverId).orElseThrow(() -> new AbstractoRunTimeException("Warning not found."));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteWarning(Warning warning) {
|
||||
log.info("Deleting warning with id {} in server {}.", warning.getWarnId().getId(), warning.getWarnId().getServerId());
|
||||
|
||||
@@ -5,6 +5,7 @@ import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.moderation.service.WarnService;
|
||||
import dev.sheldan.abstracto.test.command.CommandConfigValidator;
|
||||
import dev.sheldan.abstracto.test.command.CommandTestUtilities;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.InjectMocks;
|
||||
@@ -16,6 +17,7 @@ import java.util.concurrent.CompletableFuture;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
@Slf4j
|
||||
public class DecayWarningsTest {
|
||||
|
||||
@InjectMocks
|
||||
|
||||
@@ -39,7 +39,7 @@ public class DeleteWarningTest {
|
||||
AUserInAServer warningUser = MockUtils.getUserObject(6L, server);
|
||||
Warning existingWarning = Warning.builder().warnedUser(warnedUser).warningUser(warningUser).build();
|
||||
CommandContext parameters = CommandTestUtilities.getWithParameters(Arrays.asList(WARN_ID));
|
||||
when(warnManagementService.findById(WARN_ID, parameters.getGuild().getIdLong())).thenReturn(Optional.of(existingWarning));
|
||||
when(warnManagementService.findByIdOptional(WARN_ID, parameters.getGuild().getIdLong())).thenReturn(Optional.of(existingWarning));
|
||||
CommandResult result = testUnit.execute(parameters);
|
||||
verify(warnManagementService, times(1)).deleteWarning(existingWarning);
|
||||
CommandTestUtilities.checkSuccessfulCompletion(result);
|
||||
|
||||
@@ -64,15 +64,16 @@ public class UserNotesTest {
|
||||
when(userNoteManagementService.loadNotesForUser(userNoteUser)).thenReturn(userNotes);
|
||||
NoteEntryModel firstConvertedNote = NoteEntryModel.builder().build();
|
||||
NoteEntryModel secondConvertedNote = NoteEntryModel.builder().build();
|
||||
List<NoteEntryModel> convertedNotes = Arrays.asList(firstConvertedNote, secondConvertedNote);
|
||||
CompletableFuture<List<NoteEntryModel>> convertedNotes = CompletableFuture.completedFuture(Arrays.asList(firstConvertedNote, secondConvertedNote));
|
||||
when(userNotesConverter.fromNotes(userNotes)).thenReturn(convertedNotes);
|
||||
CompletableFuture<CommandResult> result = testUnit.executeAsync(parameters);
|
||||
verify(channelService, times(1)).sendEmbedTemplateInChannel(eq(UserNotes.USER_NOTES_RESPONSE_TEMPLATE), captor.capture(), eq(parameters.getChannel()));
|
||||
ListNotesModel usedModel = captor.getValue();
|
||||
Assert.assertEquals(convertedNotes.size(), usedModel.getUserNotes().size());
|
||||
List<NoteEntryModel> notes = convertedNotes.join();
|
||||
Assert.assertEquals(notes.size(), usedModel.getUserNotes().size());
|
||||
for (int i = 0; i < usedModel.getUserNotes().size(); i++) {
|
||||
NoteEntryModel usedEntry = usedModel.getUserNotes().get(i);
|
||||
NoteEntryModel expectedEntry = convertedNotes.get(i);
|
||||
NoteEntryModel expectedEntry = notes.get(i);
|
||||
Assert.assertEquals(expectedEntry, usedEntry);
|
||||
}
|
||||
Assert.assertEquals(userNoteUser, usedModel.getSpecifiedUser().getAUserInAServer());
|
||||
@@ -89,15 +90,16 @@ public class UserNotesTest {
|
||||
when(userNoteManagementService.loadNotesForServer(parameters.getUserInitiatedContext().getServer())).thenReturn(userNotes);
|
||||
NoteEntryModel firstConvertedNote = NoteEntryModel.builder().build();
|
||||
NoteEntryModel secondConvertedNote = NoteEntryModel.builder().build();
|
||||
List<NoteEntryModel> convertedNotes = Arrays.asList(firstConvertedNote, secondConvertedNote);
|
||||
CompletableFuture<List<NoteEntryModel>> convertedNotes = CompletableFuture.completedFuture(Arrays.asList(firstConvertedNote, secondConvertedNote));
|
||||
when(userNotesConverter.fromNotes(userNotes)).thenReturn(convertedNotes);
|
||||
CompletableFuture<CommandResult> result = testUnit.executeAsync(parameters);
|
||||
List<NoteEntryModel> notes = convertedNotes.join();
|
||||
verify(channelService, times(1)).sendEmbedTemplateInChannel(eq(UserNotes.USER_NOTES_RESPONSE_TEMPLATE), captor.capture(), eq(parameters.getChannel()));
|
||||
ListNotesModel usedModel = captor.getValue();
|
||||
Assert.assertEquals(convertedNotes.size(), usedModel.getUserNotes().size());
|
||||
Assert.assertEquals(notes.size(), usedModel.getUserNotes().size());
|
||||
for (int i = 0; i < usedModel.getUserNotes().size(); i++) {
|
||||
NoteEntryModel usedEntry = usedModel.getUserNotes().get(i);
|
||||
NoteEntryModel expectedEntry = convertedNotes.get(i);
|
||||
NoteEntryModel expectedEntry = notes.get(i);
|
||||
Assert.assertEquals(expectedEntry, usedEntry);
|
||||
}
|
||||
Assert.assertNull(usedModel.getSpecifiedUser());
|
||||
|
||||
@@ -13,7 +13,6 @@ import dev.sheldan.abstracto.moderation.models.database.Warning;
|
||||
import dev.sheldan.abstracto.moderation.models.template.commands.WarnEntry;
|
||||
import dev.sheldan.abstracto.moderation.models.template.commands.WarningsModel;
|
||||
import dev.sheldan.abstracto.moderation.service.management.WarnManagementService;
|
||||
import dev.sheldan.abstracto.test.MockUtils;
|
||||
import dev.sheldan.abstracto.test.command.CommandConfigValidator;
|
||||
import dev.sheldan.abstracto.test.command.CommandTestUtilities;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
@@ -25,6 +24,7 @@ import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@@ -52,23 +52,37 @@ public class WarningsTest {
|
||||
@Captor
|
||||
private ArgumentCaptor<WarningsModel> captor;
|
||||
|
||||
@Mock
|
||||
private Warnings self;
|
||||
|
||||
@Test
|
||||
public void testNoParametersForWarningsCommand(){
|
||||
CommandContext noParams = CommandTestUtilities.getNoParameters();
|
||||
Warning firstWarning = Warning.builder().build();
|
||||
WarnEntry firstModelWarning = WarnEntry.builder().build();
|
||||
Warning secondWarning = Warning.builder().build();
|
||||
WarnEntry secondModelWarning = WarnEntry.builder().build();
|
||||
Warning firstWarning = Mockito.mock(Warning.class);
|
||||
WarnEntry firstModelWarning = Mockito.mock(WarnEntry.class);
|
||||
Warning secondWarning = Mockito.mock(Warning.class);
|
||||
WarnEntry secondModelWarning = Mockito.mock(WarnEntry.class);
|
||||
List<Warning> warningsToDisplay = Arrays.asList(firstWarning, secondWarning);
|
||||
List<WarnEntry> modelWarnings = Arrays.asList(firstModelWarning, secondModelWarning);
|
||||
when(warnManagementService.getAllWarningsOfServer(noParams.getUserInitiatedContext().getServer())).thenReturn(warningsToDisplay);
|
||||
when(warnEntryConverter.fromWarnings(warningsToDisplay)).thenReturn(modelWarnings);
|
||||
when(warnEntryConverter.fromWarnings(warningsToDisplay)).thenReturn(CompletableFuture.completedFuture(modelWarnings));
|
||||
|
||||
CompletableFuture<CommandResult> result = testUnit.executeAsync(noParams);
|
||||
CommandTestUtilities.checkSuccessfulCompletionAsync(result);
|
||||
verify(self, times(1)).renderWarnings(noParams, modelWarnings);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWarningsRendering() {
|
||||
CommandContext noParams = CommandTestUtilities.getNoParameters();
|
||||
WarnEntry firstModelWarning = Mockito.mock(WarnEntry.class);
|
||||
WarnEntry secondModelWarning = Mockito.mock(WarnEntry.class);
|
||||
Paginator paginator = Mockito.mock(Paginator.class);
|
||||
when(paginatorService.createPaginatorFromTemplate(eq(Warnings.WARNINGS_RESPONSE_TEMPLATE), captor.capture(), eq(eventWaiter))).thenReturn(paginator);
|
||||
CommandResult result = testUnit.execute(noParams);
|
||||
CommandTestUtilities.checkSuccessfulCompletion(result);
|
||||
List<WarnEntry> modelWarnings = Arrays.asList(firstModelWarning, secondModelWarning);
|
||||
testUnit.renderWarnings(noParams, modelWarnings);
|
||||
WarningsModel warningsModel = captor.getValue();
|
||||
Assert.assertEquals(warningsToDisplay.size(), warningsModel.getWarnings().size());
|
||||
Assert.assertEquals(firstModelWarning, warningsModel.getWarnings().get(0));
|
||||
Assert.assertEquals(secondModelWarning, warningsModel.getWarnings().get(1));
|
||||
}
|
||||
@@ -77,29 +91,26 @@ public class WarningsTest {
|
||||
public void testExecuteWarningsForMember(){
|
||||
Member member = Mockito.mock(Member.class);
|
||||
CommandContext parameters = CommandTestUtilities.getWithParameters(Arrays.asList(member));
|
||||
AUserInAServer warnedUser = MockUtils.getUserObject(5L, parameters.getUserInitiatedContext().getServer());
|
||||
when(userInServerManagementService.loadUser(member)).thenReturn(warnedUser);
|
||||
Warning firstWarning = Warning.builder().build();
|
||||
WarnEntry firstModelWarning = WarnEntry.builder().build();
|
||||
Warning secondWarning = Warning.builder().build();
|
||||
WarnEntry secondModelWarning = WarnEntry.builder().build();
|
||||
AUserInAServer warnedUser = Mockito.mock(AUserInAServer.class);
|
||||
Warning firstWarning = Mockito.mock(Warning.class);
|
||||
WarnEntry firstModelWarning = Mockito.mock(WarnEntry.class);
|
||||
Warning secondWarning = Mockito.mock(Warning.class);
|
||||
WarnEntry secondModelWarning = Mockito.mock(WarnEntry.class);
|
||||
List<Warning> warningsToDisplay = Arrays.asList(firstWarning, secondWarning);
|
||||
when(warnManagementService.getAllWarnsForUser(warnedUser)).thenReturn(warningsToDisplay);
|
||||
List<WarnEntry> modelWarnings = Arrays.asList(firstModelWarning, secondModelWarning);
|
||||
when(warnEntryConverter.fromWarnings(warningsToDisplay)).thenReturn(modelWarnings);
|
||||
Paginator paginator = Mockito.mock(Paginator.class);
|
||||
when(paginatorService.createPaginatorFromTemplate(eq(Warnings.WARNINGS_RESPONSE_TEMPLATE), captor.capture(), eq(eventWaiter))).thenReturn(paginator);
|
||||
CommandResult result = testUnit.execute(parameters);
|
||||
CommandTestUtilities.checkSuccessfulCompletion(result);
|
||||
WarningsModel warningsModel = captor.getValue();
|
||||
Assert.assertEquals(warningsToDisplay.size(), warningsModel.getWarnings().size());
|
||||
Assert.assertEquals(firstModelWarning, warningsModel.getWarnings().get(0));
|
||||
Assert.assertEquals(secondModelWarning, warningsModel.getWarnings().get(1));
|
||||
when(userInServerManagementService.loadUser(member)).thenReturn(warnedUser);
|
||||
when(warnManagementService.getAllWarnsForUser(warnedUser)).thenReturn(warningsToDisplay);
|
||||
when(warnEntryConverter.fromWarnings(warningsToDisplay)).thenReturn(CompletableFuture.completedFuture(modelWarnings));
|
||||
|
||||
CompletableFuture<CommandResult> result = testUnit.executeAsync(parameters);
|
||||
CommandTestUtilities.checkSuccessfulCompletionAsync(result);
|
||||
verify(self, times(1)).renderWarnings(parameters, modelWarnings);
|
||||
|
||||
}
|
||||
|
||||
@Test(expected = IncorrectParameterTypeException.class)
|
||||
public void testIncorrectParameterType() {
|
||||
CommandTestUtilities.executeWrongParametersTest(testUnit);
|
||||
CommandTestUtilities.executeWrongParametersTestAsync(testUnit);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
package dev.sheldan.abstracto.moderation.converter;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.ServerSpecificId;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.core.service.BotService;
|
||||
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
||||
import dev.sheldan.abstracto.moderation.models.database.UserNote;
|
||||
import dev.sheldan.abstracto.moderation.models.template.commands.NoteEntryModel;
|
||||
import dev.sheldan.abstracto.moderation.service.management.UserNoteManagementService;
|
||||
import dev.sheldan.abstracto.test.MockUtils;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import org.junit.Assert;
|
||||
@@ -18,7 +20,9 @@ import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@@ -34,10 +38,16 @@ public class UserNotesConverterTest {
|
||||
@Mock
|
||||
private BotService botService;
|
||||
|
||||
@Mock
|
||||
private UserNotesConverter self;
|
||||
|
||||
@Mock
|
||||
private UserNoteManagementService userNoteManagementService;
|
||||
|
||||
@Test
|
||||
public void testWithEmptyList() {
|
||||
List<NoteEntryModel> entryModels = testUnit.fromNotes(Collections.emptyList());
|
||||
Assert.assertEquals(0, entryModels.size());
|
||||
CompletableFuture<List<NoteEntryModel>> entryModels = testUnit.fromNotes(Collections.emptyList());
|
||||
Assert.assertEquals(0, entryModels.join().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -45,15 +55,34 @@ public class UserNotesConverterTest {
|
||||
AServer server = MockUtils.getServer();
|
||||
AUserInAServer userInAServer = MockUtils.getUserObject(4L, server);
|
||||
Member member = Mockito.mock(Member.class);
|
||||
when(botService.getMemberInServer(userInAServer)).thenReturn(member);
|
||||
UserNote firstNote = UserNote.builder().user(userInAServer).build();
|
||||
UserNote secondNote = UserNote.builder().user(userInAServer).build();
|
||||
List<NoteEntryModel> entryModels = testUnit.fromNotes(Arrays.asList(firstNote, secondNote));
|
||||
Assert.assertEquals(2, entryModels.size());
|
||||
NoteEntryModel firstEntry = entryModels.get(0);
|
||||
when(botService.getMemberInServerAsync(userInAServer)).thenReturn(CompletableFuture.completedFuture(member));
|
||||
UserNote firstNote = UserNote.builder().userNoteId(new ServerSpecificId(3L, 4L)).user(userInAServer).build();
|
||||
UserNote secondNote = UserNote.builder().userNoteId(new ServerSpecificId(3L, 5L)).user(userInAServer).build();
|
||||
testUnit.fromNotes(Arrays.asList(firstNote, secondNote));
|
||||
verify(self, times(1)).loadFullNotes(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLoadingFullNotes() {
|
||||
AUserInAServer userInAServer = Mockito.mock(AUserInAServer.class);
|
||||
Member member = Mockito.mock(Member.class);
|
||||
UserNote note1 = Mockito.mock(UserNote.class);
|
||||
UserNote note2 = Mockito.mock(UserNote.class);
|
||||
when(note1.getUser()).thenReturn(userInAServer);
|
||||
when(note2.getUser()).thenReturn(userInAServer);
|
||||
ServerSpecificId firstUserNoteId = new ServerSpecificId(3L, 4L);
|
||||
ServerSpecificId secondUserNoteId = new ServerSpecificId(3L, 5L);
|
||||
HashMap<ServerSpecificId, CompletableFuture<Member>> map = new HashMap<>();
|
||||
map.put(firstUserNoteId, CompletableFuture.completedFuture(member));
|
||||
map.put(secondUserNoteId, CompletableFuture.completedFuture(member));
|
||||
when(userNoteManagementService.loadNote(4L, 3L)).thenReturn(note1);
|
||||
when(userNoteManagementService.loadNote(5L, 3L)).thenReturn(note2);
|
||||
List<NoteEntryModel> models = testUnit.loadFullNotes(map);
|
||||
Assert.assertEquals(2, models.size());
|
||||
NoteEntryModel firstEntry = models.get(0);
|
||||
Assert.assertEquals(member, firstEntry.getFullUser().getMember());
|
||||
Assert.assertEquals(userInAServer, firstEntry.getFullUser().getAUserInAServer());
|
||||
NoteEntryModel secondEntry = entryModels.get(1);
|
||||
NoteEntryModel secondEntry = models.get(1);
|
||||
Assert.assertEquals(member, secondEntry.getFullUser().getMember());
|
||||
Assert.assertEquals(userInAServer, secondEntry.getFullUser().getAUserInAServer());
|
||||
}
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
package dev.sheldan.abstracto.moderation.converter;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.core.models.FutureMemberPair;
|
||||
import dev.sheldan.abstracto.core.models.ServerSpecificId;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.core.service.BotService;
|
||||
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
||||
import dev.sheldan.abstracto.moderation.models.database.Warning;
|
||||
import dev.sheldan.abstracto.moderation.models.template.commands.WarnEntry;
|
||||
import dev.sheldan.abstracto.test.MockUtils;
|
||||
import dev.sheldan.abstracto.moderation.service.management.WarnManagementService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
@@ -17,11 +20,14 @@ import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
@Slf4j
|
||||
public class WarnEntryConverterTest {
|
||||
|
||||
@InjectMocks
|
||||
@@ -30,34 +36,74 @@ public class WarnEntryConverterTest {
|
||||
@Mock
|
||||
private BotService botService;
|
||||
|
||||
@Mock
|
||||
private WarnEntryConverter self;
|
||||
|
||||
@Mock
|
||||
private WarnManagementService warnManagementService;
|
||||
|
||||
@Mock
|
||||
private UserInServerManagementService userInServerManagementService;
|
||||
|
||||
private static final Long SERVER_ID = 5L;
|
||||
private static final Long WARN_ID_1 = 6L;
|
||||
private static final Long WARN_ID_2 = 7L;
|
||||
|
||||
@Test
|
||||
public void testWithEmptyList() {
|
||||
List<WarnEntry> entryModels = testUnit.fromWarnings(Collections.emptyList());
|
||||
Assert.assertEquals(0, entryModels.size());
|
||||
CompletableFuture<List<WarnEntry>> entryModels = testUnit.fromWarnings(Collections.emptyList());
|
||||
Assert.assertEquals(0, entryModels.join().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithSomeUserNotes() {
|
||||
AServer server = MockUtils.getServer();
|
||||
AUserInAServer warnedUserInAServer = MockUtils.getUserObject(4L, server);
|
||||
AUserInAServer warningUserInAServer = MockUtils.getUserObject(6L, server);
|
||||
AUserInAServer warnedUser = Mockito.mock(AUserInAServer.class);
|
||||
AUserInAServer warningUser = Mockito.mock(AUserInAServer.class);
|
||||
Member warnedMember = Mockito.mock(Member.class);
|
||||
Member warningMember = Mockito.mock(Member.class);
|
||||
when(botService.getMemberInServer(warnedUserInAServer)).thenReturn(warnedMember);
|
||||
when(botService.getMemberInServer(warningUserInAServer)).thenReturn(warningMember);
|
||||
Warning firstNote = Warning.builder().warnedUser(warnedUserInAServer).warningUser(warningUserInAServer).build();
|
||||
Warning secondNote = Warning.builder().warnedUser(warnedUserInAServer).warningUser(warningUserInAServer).build();
|
||||
List<WarnEntry> entryModels = testUnit.fromWarnings(Arrays.asList(firstNote, secondNote));
|
||||
Assert.assertEquals(2, entryModels.size());
|
||||
WarnEntry firstEntry = entryModels.get(0);
|
||||
when(botService.getMemberInServerAsync(warnedUser)).thenReturn(CompletableFuture.completedFuture(warnedMember));
|
||||
when(botService.getMemberInServerAsync(warningUser)).thenReturn(CompletableFuture.completedFuture(warningMember));
|
||||
Warning firstNote = Warning.builder().warnId(new ServerSpecificId(3L, 4L)).warnedUser(warnedUser).warningUser(warningUser).build();
|
||||
Warning secondNote = Warning.builder().warnId(new ServerSpecificId(3L, 5L)).warnedUser(warnedUser).warningUser(warningUser).build();
|
||||
testUnit.fromWarnings(Arrays.asList(firstNote, secondNote));
|
||||
verify(self, times(1)).loadFullWarnEntries(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLoadingFullNotes() {
|
||||
AUserInAServer warnedUser = Mockito.mock(AUserInAServer.class);
|
||||
AUserInAServer warningUser = Mockito.mock(AUserInAServer.class);
|
||||
Member warningMember = Mockito.mock(Member.class);
|
||||
Member warnedMember = Mockito.mock(Member.class);
|
||||
Warning warning1 = Mockito.mock(Warning.class);
|
||||
Warning warning2 = Mockito.mock(Warning.class);
|
||||
ServerSpecificId firstWarnId = new ServerSpecificId(SERVER_ID, WARN_ID_1);
|
||||
when(warning1.getWarnId()).thenReturn(firstWarnId);
|
||||
ServerSpecificId secondWarnId = new ServerSpecificId(SERVER_ID, WARN_ID_2);
|
||||
when(warning2.getWarnId()).thenReturn(secondWarnId);
|
||||
HashMap<ServerSpecificId, FutureMemberPair> map = new HashMap<>();
|
||||
FutureMemberPair memberPair = FutureMemberPair.builder().firstMember(CompletableFuture.completedFuture(warningMember)).secondMember(CompletableFuture.completedFuture(warnedMember)).build();
|
||||
map.put(firstWarnId, memberPair);
|
||||
map.put(secondWarnId, memberPair);
|
||||
when(warnManagementService.findById(WARN_ID_1, SERVER_ID)).thenReturn(warning1);
|
||||
when(warnManagementService.findById(WARN_ID_2, SERVER_ID)).thenReturn(warning2);
|
||||
when(userInServerManagementService.loadUser(warnedMember)).thenReturn(warnedUser);
|
||||
when(userInServerManagementService.loadUser(warningMember)).thenReturn(warningUser);
|
||||
List<WarnEntry> models = testUnit.loadFullWarnEntries(map);
|
||||
Assert.assertEquals(2, models.size());
|
||||
WarnEntry firstEntry = models.get(0);
|
||||
Assert.assertEquals(warningMember, firstEntry.getWarningUser().getMember());
|
||||
Assert.assertEquals(warnedMember, firstEntry.getWarnedUser().getMember());
|
||||
Assert.assertEquals(warningUserInAServer, firstEntry.getWarningUser().getAUserInAServer());
|
||||
Assert.assertEquals(warnedUserInAServer, firstEntry.getWarnedUser().getAUserInAServer());
|
||||
WarnEntry secondEntry = entryModels.get(1);
|
||||
Assert.assertEquals(warnedUser, firstEntry.getWarnedUser().getAUserInAServer());
|
||||
Assert.assertEquals(warningUser, firstEntry.getWarningUser().getAUserInAServer());
|
||||
Assert.assertEquals(WARN_ID_1, firstEntry.getWarning().getWarnId().getId());
|
||||
Assert.assertEquals(SERVER_ID, firstEntry.getWarning().getWarnId().getServerId());
|
||||
WarnEntry secondEntry = models.get(1);
|
||||
Assert.assertEquals(warningMember, secondEntry.getWarningUser().getMember());
|
||||
Assert.assertEquals(warnedMember, secondEntry.getWarnedUser().getMember());
|
||||
Assert.assertEquals(warningUserInAServer, secondEntry.getWarningUser().getAUserInAServer());
|
||||
Assert.assertEquals(warnedUserInAServer, secondEntry.getWarnedUser().getAUserInAServer());
|
||||
Assert.assertEquals(warnedUser, secondEntry.getWarnedUser().getAUserInAServer());
|
||||
Assert.assertEquals(warningUser, secondEntry.getWarningUser().getAUserInAServer());
|
||||
Assert.assertEquals(WARN_ID_2, secondEntry.getWarning().getWarnId().getId());
|
||||
Assert.assertEquals(SERVER_ID, secondEntry.getWarning().getWarnId().getServerId());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@ public class BanServiceBeanTest {
|
||||
when(mockedGuild.ban(userId.toString(), 0, REASON)).thenReturn(mockedAction);
|
||||
MessageToSend mockedMessage = Mockito.mock(MessageToSend.class);
|
||||
when(templateService.renderEmbedTemplate(BanServiceBean.BAN_ID_LOG_TEMPLATE, context)).thenReturn(mockedMessage);
|
||||
when(botService.getGuildById(serverId)).thenReturn(Optional.of(mockedGuild));
|
||||
when(botService.getGuildByIdOptional(serverId)).thenReturn(Optional.of(mockedGuild));
|
||||
testUnit.banMember(serverId, userId, REASON, context);
|
||||
verify(mockedGuild, times(1)).ban(userId.toString(), 0, REASON);
|
||||
verify(postTargetService, times(1)).sendEmbedInPostTarget(mockedMessage, ModerationPostTarget.BAN_LOG, serverId);
|
||||
@@ -81,7 +81,7 @@ public class BanServiceBeanTest {
|
||||
Long userId = 8L;
|
||||
Long serverId = 5L;
|
||||
ServerContext context = Mockito.mock(ServerContext.class);
|
||||
when(botService.getGuildById(serverId)).thenReturn(Optional.empty());
|
||||
when(botService.getGuildByIdOptional(serverId)).thenReturn(Optional.empty());
|
||||
testUnit.banMember(serverId, userId, REASON, context);
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,6 @@ import dev.sheldan.abstracto.scheduling.service.SchedulerService;
|
||||
import dev.sheldan.abstracto.templating.model.MessageToSend;
|
||||
import dev.sheldan.abstracto.templating.service.TemplateService;
|
||||
import dev.sheldan.abstracto.test.MockUtils;
|
||||
import dev.sheldan.abstracto.test.command.CommandTestUtilities;
|
||||
import net.dv8tion.jda.api.entities.*;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -43,6 +42,7 @@ import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
|
||||
import static dev.sheldan.abstracto.moderation.service.MuteServiceBean.MUTE_NOTIFICATION_TEMPLATE;
|
||||
import static dev.sheldan.abstracto.moderation.service.MuteServiceBean.UN_MUTE_LOG_TEMPLATE;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
@@ -234,24 +234,6 @@ public class MuteServiceBeanTest {
|
||||
verifyDirectMute();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMuteAUserInAServer() {
|
||||
when(botService.getMemberInServer(userBeingMuted)).thenReturn(memberBeingMuted);
|
||||
when(botService.getMemberInServer(userMuting)).thenReturn(memberMuting);
|
||||
Instant unMuteDate = shorterMute();
|
||||
when(memberBeingMuted.getGuild()).thenReturn(guild);
|
||||
when(memberBeingMuted.getUser()).thenReturn(jdaUserBeingMuted);
|
||||
when(muteRoleManagementService.muteRoleForServerExists(server)).thenReturn(true);
|
||||
when(muteRoleManagementService.retrieveMuteRoleForServer(server)).thenReturn(muteRole);
|
||||
|
||||
String notificationText = "text";
|
||||
when(templateService.renderTemplate(eq(MUTE_NOTIFICATION_TEMPLATE), any(MuteNotification.class))).thenReturn(notificationText);
|
||||
when(messageService.sendMessageToUser(memberBeingMuted.getUser(), notificationText)).thenReturn(CompletableFuture.completedFuture(null));
|
||||
when(roleService.addRoleToUserFuture(userBeingMuted, muteRole.getRole())).thenReturn(CompletableFuture.completedFuture(null));
|
||||
testUnit.muteAUserInAServer(userBeingMuted, userMuting, REASON, unMuteDate, cause);
|
||||
verifyDirectMute();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMuteMemberWithLog() {
|
||||
when(userInServerManagementService.loadUser(memberBeingMuted)).thenReturn(userBeingMuted);
|
||||
@@ -294,15 +276,30 @@ public class MuteServiceBeanTest {
|
||||
public void testEndMute() {
|
||||
setupUnMuteMocks(true);
|
||||
when(mute.getMutedUser()).thenReturn(userBeingMuted);
|
||||
when(mute.getMutingUser()).thenReturn(userMuting);
|
||||
when(mute.getServer()).thenReturn(server);
|
||||
when(muteManagementService.findMute(MUTE_ID, SERVER_ID)).thenReturn(Optional.of(mute));
|
||||
when(muteManagementService.findMuteOptional(MUTE_ID, SERVER_ID)).thenReturn(Optional.of(mute));
|
||||
when(roleService.removeRoleFromUserFuture(userBeingMuted, aRole)).thenReturn(CompletableFuture.completedFuture(null));
|
||||
when(botService.getMemberInServerAsync(userBeingMuted)).thenReturn(CompletableFuture.completedFuture(memberBeingMuted));
|
||||
when(botService.getMemberInServerAsync(userMuting)).thenReturn(CompletableFuture.completedFuture(memberMuting));
|
||||
testUnit.endMute(MUTE_ID, SERVER_ID);
|
||||
verify(self, times(1)).sendUnmuteLog(eq(MUTE_ID), any(Guild.class), any(CompletableFuture.class), any(CompletableFuture.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSendUnmuteLog() {
|
||||
when(guild.getIdLong()).thenReturn(SERVER_ID);
|
||||
when(muteManagementService.findMute(MUTE_ID, SERVER_ID)).thenReturn(mute);
|
||||
when(serverManagementService.loadServer(SERVER_ID)).thenReturn(server);
|
||||
when(templateService.renderEmbedTemplate(eq(UN_MUTE_LOG_TEMPLATE), any(UnMuteLog.class))).thenReturn(messageToSend);
|
||||
when(postTargetService.sendEmbedInPostTarget(eq(messageToSend), eq(MutingPostTarget.MUTE_LOG), anyLong())).thenReturn(Arrays.asList(CompletableFuture.completedFuture(null)));
|
||||
testUnit.sendUnmuteLog(MUTE_ID, guild, CompletableFuture.completedFuture(memberMuting), CompletableFuture.completedFuture(memberBeingMuted));
|
||||
verify(self, times(1)).endMuteInDatabase(MUTE_ID, SERVER_ID);
|
||||
}
|
||||
|
||||
@Test(expected = NoMuteFoundException.class)
|
||||
public void testEndNonExistingMute() {
|
||||
when(muteManagementService.findMute(MUTE_ID, SERVER_ID)).thenReturn(Optional.empty());
|
||||
when(muteManagementService.findMuteOptional(MUTE_ID, SERVER_ID)).thenReturn(Optional.empty());
|
||||
testUnit.endMute(MUTE_ID, SERVER_ID);
|
||||
}
|
||||
|
||||
@@ -373,10 +370,12 @@ public class MuteServiceBeanTest {
|
||||
|
||||
private void executeUnMuteWithLogTest(boolean stillInGuild) {
|
||||
when(mute.getMutedUser()).thenReturn(userBeingMuted);
|
||||
when(mute.getMutingUser()).thenReturn(userMuting);
|
||||
when(mute.getServer()).thenReturn(server);
|
||||
setupUnMuteMocks(stillInGuild);
|
||||
when(roleService.removeRoleFromUserFuture(userBeingMuted, aRole)).thenReturn(CompletableFuture.completedFuture(null));
|
||||
when(postTargetService.sendEmbedInPostTarget(messageToSend, MutingPostTarget.MUTE_LOG, server.getId())).thenReturn(CommandTestUtilities.messageFutureList());
|
||||
when(botService.getMemberInServerAsync(userBeingMuted)).thenReturn(CompletableFuture.completedFuture(memberBeingMuted));
|
||||
when(botService.getMemberInServerAsync(userMuting)).thenReturn(CompletableFuture.completedFuture(memberMuting));
|
||||
testUnit.unMuteUser(userBeingMuted);
|
||||
|
||||
}
|
||||
@@ -385,10 +384,8 @@ public class MuteServiceBeanTest {
|
||||
when(mute.getMuteId()).thenReturn(new ServerSpecificId(SERVER_ID, MUTE_ID));
|
||||
when(muteManagementService.getAMuteOf(userBeingMuted)).thenReturn(mute);
|
||||
when(muteRoleManagementService.retrieveMuteRoleForServer(server)).thenReturn(muteRole);
|
||||
when(botService.getGuildByIdNullable(server.getId())).thenReturn(guild);
|
||||
when(botService.getGuildById(server.getId())).thenReturn(guild);
|
||||
when(botService.isUserInGuild(guild, userBeingMuted)).thenReturn(stillInGuild);
|
||||
when(botService.getMemberInServer(userBeingMuted)).thenReturn(memberBeingMuted);
|
||||
when(templateService.renderEmbedTemplate(eq(MuteServiceBean.UN_MUTE_LOG_TEMPLATE), any(UnMuteLog.class))).thenReturn(messageToSend);
|
||||
}
|
||||
|
||||
private void verifyDirectMute() {
|
||||
|
||||
@@ -57,6 +57,9 @@ public class WarnServiceBeanTest {
|
||||
@Mock
|
||||
private ConfigService configService;
|
||||
|
||||
@Mock
|
||||
private WarnServiceBean self;
|
||||
|
||||
@Mock
|
||||
private Member warnedMember;
|
||||
|
||||
@@ -128,14 +131,14 @@ public class WarnServiceBeanTest {
|
||||
public void testDecayWarningsForServer() {
|
||||
setupWarnDecay();
|
||||
testUnit.decayWarningsForServer(server);
|
||||
verifyWarnDecayWithLog(true);
|
||||
verify(self, times(1)).renderAndSendWarnDecayLogs(eq(SERVER_ID), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDecayAllWarningsForServerWithLog() {
|
||||
setupWarnDecay();
|
||||
testUnit.decayAllWarningsForServer(server, true);
|
||||
verifyWarnDecayWithLog(true);
|
||||
verify(self, times(1)).renderAndSendWarnDecayLogs(eq(SERVER_ID), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -148,14 +151,10 @@ public class WarnServiceBeanTest {
|
||||
@Test
|
||||
public void testDecayAllWarningsWithoutWarnings() {
|
||||
List<Warning> warnings = Collections.emptyList();
|
||||
when(botService.getGuildByIdNullable(server.getId())).thenReturn(guild);
|
||||
when(templateService.renderEmbedTemplate(eq(WARN_DECAY_LOG_TEMPLATE_KEY), warnDecayLogModelArgumentCaptor.capture())).thenReturn(messageToSend);
|
||||
when(server.getId()).thenReturn(SERVER_ID);
|
||||
when(warnManagementService.getActiveWarningsInServerOlderThan(eq(server), any(Instant.class))).thenReturn(warnings);
|
||||
testUnit.decayAllWarningsForServer(server, true);
|
||||
verify(postTargetService, times(1)).sendEmbedInPostTarget(messageToSend, WarnDecayPostTarget.DECAY_LOG, server.getId());
|
||||
WarnDecayLogModel model = warnDecayLogModelArgumentCaptor.getValue();
|
||||
List<WarnDecayWarning> usedWarnings = model.getWarnings();
|
||||
Assert.assertEquals(0, usedWarnings.size());
|
||||
verify(self, times(1)).renderAndSendWarnDecayLogs(eq(SERVER_ID), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -218,11 +217,9 @@ public class WarnServiceBeanTest {
|
||||
setupWarnings();
|
||||
when(configService.getLongValue(WarningDecayFeature.DECAY_DAYS_KEY, server.getId())).thenReturn(5L);
|
||||
List<Warning> warnings = Arrays.asList(firstWarning, secondWarning);
|
||||
when(botService.getMemberInServer(warningUser)).thenReturn(warningMember);
|
||||
when(botService.getMemberInServer(firstWarnedUser)).thenReturn(warnedMember);
|
||||
when(botService.getMemberInServer(secondWarnedUser)).thenReturn(secondWarnedMember);
|
||||
when(botService.getGuildByIdNullable(server.getId())).thenReturn(guild);
|
||||
when(templateService.renderEmbedTemplate(eq(WARN_DECAY_LOG_TEMPLATE_KEY), warnDecayLogModelArgumentCaptor.capture())).thenReturn(messageToSend);
|
||||
when(botService.getMemberInServerAsync(warningUser)).thenReturn(CompletableFuture.completedFuture(warningMember));
|
||||
when(botService.getMemberInServerAsync(firstWarnedUser)).thenReturn(CompletableFuture.completedFuture(warnedMember));
|
||||
when(botService.getMemberInServerAsync(secondWarnedUser)).thenReturn(CompletableFuture.completedFuture(secondWarnedMember));
|
||||
when(warnManagementService.getActiveWarningsInServerOlderThan(eq(server), any(Instant.class))).thenReturn(warnings);
|
||||
}
|
||||
|
||||
|
||||
@@ -69,7 +69,7 @@ public class MuteManagementServiceBeanTest {
|
||||
Long serverId = 7L;
|
||||
Mute mute = Mute.builder().muteId(new ServerSpecificId(serverId, id)).build();
|
||||
when(muteRepository.findByMuteId_IdAndMuteId_ServerId(id, serverId)).thenReturn(Optional.of(mute));
|
||||
Optional<Mute> foundMuteOptional = testUnit.findMute(id, serverId);
|
||||
Optional<Mute> foundMuteOptional = testUnit.findMuteOptional(id, serverId);
|
||||
Assert.assertTrue(foundMuteOptional.isPresent());
|
||||
foundMuteOptional.ifPresent(foundMute -> Assert.assertEquals(id, foundMute.getMuteId().getId()));
|
||||
}
|
||||
@@ -79,7 +79,7 @@ public class MuteManagementServiceBeanTest {
|
||||
Long id = 5L;
|
||||
Long serverId = 7L;
|
||||
when(muteRepository.findByMuteId_IdAndMuteId_ServerId(id, serverId)).thenReturn(Optional.empty());
|
||||
Optional<Mute> foundMuteOptional = testUnit.findMute(id, serverId);
|
||||
Optional<Mute> foundMuteOptional = testUnit.findMuteOptional(id, serverId);
|
||||
Assert.assertFalse(foundMuteOptional.isPresent());
|
||||
}
|
||||
|
||||
|
||||
@@ -99,7 +99,7 @@ public class WarnManagementServiceBeanTest {
|
||||
Long serverId = 8L;
|
||||
Warning existingWarning = getWarning();
|
||||
when(warnRepository.findByWarnId_IdAndWarnId_ServerId(warnId, serverId)).thenReturn(Optional.ofNullable(existingWarning));
|
||||
Optional<Warning> warningOptional = testUnit.findById(warnId, serverId);
|
||||
Optional<Warning> warningOptional = testUnit.findByIdOptional(warnId, serverId);
|
||||
Assert.assertTrue(warningOptional.isPresent());
|
||||
warningOptional.ifPresent(foundWarning -> Assert.assertEquals(existingWarning, foundWarning));
|
||||
}
|
||||
@@ -109,7 +109,7 @@ public class WarnManagementServiceBeanTest {
|
||||
Long warnId = 6L;
|
||||
Long serverId = 8L;
|
||||
when(warnRepository.findByWarnId_IdAndWarnId_ServerId(warnId, serverId)).thenReturn(Optional.ofNullable(null));
|
||||
Optional<Warning> warningOptional = testUnit.findById(warnId, serverId);
|
||||
Optional<Warning> warningOptional = testUnit.findByIdOptional(warnId, serverId);
|
||||
Assert.assertFalse(warningOptional.isPresent());
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package dev.sheldan.abstracto.moderation.models.template.commands;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.context.UserInitiatedServerContext;
|
||||
import dev.sheldan.abstracto.core.models.context.SlimUserInitiatedServerContext;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
@@ -13,7 +13,7 @@ import java.util.List;
|
||||
@Getter
|
||||
@Setter
|
||||
@SuperBuilder
|
||||
public class WarningsModel extends UserInitiatedServerContext {
|
||||
public class WarningsModel extends SlimUserInitiatedServerContext {
|
||||
/**
|
||||
* A collection of {@link dev.sheldan.abstracto.moderation.models.database.Warning}s being rendered, might be all warnings of the server, or only the warnings of a specific user
|
||||
*/
|
||||
|
||||
@@ -12,7 +12,6 @@ import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public interface MuteService {
|
||||
CompletableFuture<Void> muteMember(Member memberToMute, Member userMuting, String reason, Instant unMuteDate, ServerChannelMessage message);
|
||||
CompletableFuture<Void> muteAUserInAServer(AUserInAServer member, AUserInAServer userMuting, String reason, Instant unMuteDate, ServerChannelMessage message);
|
||||
CompletableFuture<Void> muteUserInServer(FullUserInServer userToMute, FullUserInServer userMuting, String reason, Instant unMuteDate, ServerChannelMessage message);
|
||||
CompletableFuture<Void> applyMuteRole(AUserInAServer aUserInAServer);
|
||||
CompletableFuture<Void> muteMemberWithLog(MuteContext context);
|
||||
|
||||
@@ -31,7 +31,8 @@ public interface MuteManagementService {
|
||||
* @param muteId The id of the mute to search for
|
||||
* @return An optional containing a {@link Mute} if the ID exists, and null otherwise
|
||||
*/
|
||||
Optional<Mute> findMute(Long muteId, Long serverId);
|
||||
Optional<Mute> findMuteOptional(Long muteId, Long serverId);
|
||||
Mute findMute(Long muteId, Long serverId);
|
||||
|
||||
/**
|
||||
* Saves the given mute to the database.
|
||||
|
||||
@@ -9,6 +9,7 @@ import java.util.List;
|
||||
public interface UserNoteManagementService {
|
||||
UserNote createUserNote(AUserInAServer aUserInAServer, String note);
|
||||
void deleteNote(Long id, AServer server);
|
||||
UserNote loadNote(Long userNoteId, Long serverId);
|
||||
boolean noteExists(Long id, AServer server);
|
||||
List<UserNote> loadNotesForUser(AUserInAServer aUserInAServer);
|
||||
List<UserNote> loadNotesForServer(AServer server);
|
||||
|
||||
@@ -15,6 +15,7 @@ public interface WarnManagementService {
|
||||
List<Warning> getAllWarnsForUser(AUserInAServer aUserInAServer);
|
||||
List<Warning> getAllWarningsOfServer(AServer server);
|
||||
Long getActiveWarnsForUser(AUserInAServer aUserInAServer);
|
||||
Optional<Warning> findById(Long id, Long serverId);
|
||||
Optional<Warning> findByIdOptional(Long id, Long serverId);
|
||||
Warning findById(Long id, Long serverId);
|
||||
void deleteWarning(Warning warn);
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import dev.sheldan.abstracto.core.command.config.Parameter;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.config.FeatureEnum;
|
||||
import dev.sheldan.abstracto.core.service.BotService;
|
||||
import dev.sheldan.abstracto.modmail.condition.ModMailContextCondition;
|
||||
import dev.sheldan.abstracto.modmail.config.ModMailFeatures;
|
||||
import dev.sheldan.abstracto.modmail.models.database.ModMailThread;
|
||||
@@ -36,14 +37,19 @@ public class AnonReply extends AbstractConditionableCommand {
|
||||
@Autowired
|
||||
private ModMailThreadManagementService modMailThreadManagementService;
|
||||
|
||||
@Autowired
|
||||
private BotService botService;
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
|
||||
List<Object> parameters = commandContext.getParameters().getParameters();
|
||||
// text is optional, for example if only an attachment is sent
|
||||
String text = parameters.size() == 1 ? (String) parameters.get(0) : "";
|
||||
ModMailThread thread = modMailThreadManagementService.getByChannel(commandContext.getUserInitiatedContext().getChannel());
|
||||
return modMailThreadService.relayMessageToDm(thread, text, commandContext.getMessage(), true, commandContext.getChannel(), commandContext.getUndoActions())
|
||||
.thenApply(aVoid -> CommandResult.fromSuccess());
|
||||
Long threadId = thread.getId();
|
||||
return botService.getMemberInServerAsync(thread.getUser()).thenCompose(member ->
|
||||
modMailThreadService.relayMessageToDm(threadId, text, commandContext.getMessage(), true, commandContext.getChannel(), commandContext.getUndoActions(), member)
|
||||
).thenApply(aVoid -> CommandResult.fromSuccess());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -8,7 +8,6 @@ import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.command.execution.ContextConverter;
|
||||
import dev.sheldan.abstracto.core.config.FeatureEnum;
|
||||
import dev.sheldan.abstracto.core.models.FullUserInServer;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.core.service.ChannelService;
|
||||
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
||||
@@ -62,12 +61,7 @@ public class Contact extends AbstractConditionableCommand {
|
||||
List<CompletableFuture<Message>> futures = channelService.sendEmbedTemplateInChannel("modmail_thread_already_exists", model, commandContext.getChannel());
|
||||
return FutureUtils.toSingleFutureGeneric(futures).thenApply(aVoid -> CommandResult.fromSuccess());
|
||||
} else {
|
||||
FullUserInServer fullUser = FullUserInServer
|
||||
.builder()
|
||||
.aUserInAServer(user)
|
||||
.member(targetUser)
|
||||
.build();
|
||||
return modMailThreadService.createModMailThreadForUser(fullUser, null, commandContext.getChannel(), false, commandContext.getUndoActions())
|
||||
return modMailThreadService.createModMailThreadForUser(targetUser, null, commandContext.getChannel(), false, commandContext.getUndoActions())
|
||||
.thenApply(aVoid -> CommandResult.fromSuccess());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import dev.sheldan.abstracto.core.command.config.Parameter;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.config.FeatureEnum;
|
||||
import dev.sheldan.abstracto.core.service.BotService;
|
||||
import dev.sheldan.abstracto.modmail.condition.ModMailContextCondition;
|
||||
import dev.sheldan.abstracto.modmail.config.ModMailFeatures;
|
||||
import dev.sheldan.abstracto.modmail.models.database.ModMailThread;
|
||||
@@ -35,13 +36,18 @@ public class Reply extends AbstractConditionableCommand {
|
||||
@Autowired
|
||||
private ModMailThreadManagementService modMailThreadManagementService;
|
||||
|
||||
@Autowired
|
||||
private BotService botService;
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
|
||||
List<Object> parameters = commandContext.getParameters().getParameters();
|
||||
String text = parameters.size() == 1 ? (String) parameters.get(0) : "";
|
||||
ModMailThread thread = modMailThreadManagementService.getByChannel(commandContext.getUserInitiatedContext().getChannel());
|
||||
return modMailThreadService.relayMessageToDm(thread, text, commandContext.getMessage(), false, commandContext.getChannel(), commandContext.getUndoActions())
|
||||
.thenApply(aVoid -> CommandResult.fromSuccess());
|
||||
Long threadId = thread.getId();
|
||||
return botService.getMemberInServerAsync(thread.getUser()).thenCompose(member ->
|
||||
modMailThreadService.relayMessageToDm(threadId, text, commandContext.getMessage(), false, commandContext.getChannel(), commandContext.getUndoActions(), member)
|
||||
).thenApply(aVoid -> CommandResult.fromSuccess());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -41,13 +41,19 @@ public class ModMailMessageListener implements PrivateMessageReceivedListener {
|
||||
@Override
|
||||
@Transactional
|
||||
public void execute(Message message) {
|
||||
if(message.getAuthor().isBot()) {
|
||||
return;
|
||||
}
|
||||
AUser user = userManagementService.loadUser(message.getAuthor().getIdLong());
|
||||
if(modMailThreadManagementService.hasOpenModMailThread(user)) {
|
||||
log.trace("User {} has an open modmail thread. Forwarding message {}.", user.getId(), message.getId());
|
||||
// there is only one open mod mail thread for a user at a time, so we can select the first one
|
||||
// we cannot use the AUserInAServer directly, because a message in a private channel does not have a Member
|
||||
ModMailThread existingThread = modMailThreadManagementService.getOpenModMailThreadsForUser(user).get(0);
|
||||
modMailThreadService.relayMessageToModMailThread(existingThread, message, new ArrayList<>());
|
||||
modMailThreadService.relayMessageToModMailThread(existingThread, message, new ArrayList<>()).exceptionally(throwable -> {
|
||||
log.error("Error when relaying message from user {} in modmail listener.", message.getAuthor().getIdLong(), throwable);
|
||||
return null;
|
||||
});
|
||||
} else {
|
||||
log.info("User {} does not have an open modmail thread. Crating prompt.", user.getId());
|
||||
modMailThreadService.createModMailPrompt(user, message);
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
package dev.sheldan.abstracto.modmail.service;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.ServerChannelMessage;
|
||||
import dev.sheldan.abstracto.core.models.ServerChannelMessageUser;
|
||||
import dev.sheldan.abstracto.core.service.BotService;
|
||||
import dev.sheldan.abstracto.modmail.models.database.ModMailMessage;
|
||||
import dev.sheldan.abstracto.modmail.models.database.ModMailThread;
|
||||
import dev.sheldan.abstracto.modmail.models.dto.LoadedModmailThreadMessage;
|
||||
import dev.sheldan.abstracto.modmail.models.dto.LoadedModmailThreadMessageList;
|
||||
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;
|
||||
@@ -24,56 +27,75 @@ public class ModMailMessageServiceBean implements ModMailMessageService {
|
||||
private BotService botService;
|
||||
|
||||
@Override
|
||||
public List<CompletableFuture<Message>> loadModMailMessages(List<ModMailMessage> modMailMessages) {
|
||||
public LoadedModmailThreadMessageList loadModMailMessages(List<ModMailMessage> modMailMessages) {
|
||||
if(modMailMessages.isEmpty()) {
|
||||
return new ArrayList<>();
|
||||
return LoadedModmailThreadMessageList.builder().build();
|
||||
}
|
||||
// all message must be from the same thread
|
||||
ModMailThread thread = modMailMessages.get(0).getThreadReference();
|
||||
log.trace("Loading {} mod mail messages from thread {} in server {}.", modMailMessages.size(), thread.getId(), thread.getServer().getId());
|
||||
List<ServerChannelMessage> messageIds = new ArrayList<>();
|
||||
List<ServerChannelMessageUser> messageIds = new ArrayList<>();
|
||||
modMailMessages.forEach(modMailMessage -> {
|
||||
ServerChannelMessage.ServerChannelMessageBuilder serverChannelMessageBuilder = ServerChannelMessage
|
||||
ServerChannelMessageUser.ServerChannelMessageUserBuilder serverChannelMessageBuilder = ServerChannelMessageUser
|
||||
.builder()
|
||||
.messageId(modMailMessage.getMessageId());
|
||||
// if its not from a private chat, we need to set the server and channel ID in order to fetch the data
|
||||
.messageId(modMailMessage.getMessageId())
|
||||
.userId(modMailMessage.getAuthor().getUserReference().getId())
|
||||
.serverId(thread.getServer().getId());
|
||||
// if its not from a private chat, we need to set channel ID in order to fetch the data
|
||||
if(Boolean.FALSE.equals(modMailMessage.getDmChannel())) {
|
||||
log.trace("Message {} was from DM.", modMailMessage.getMessageId());
|
||||
serverChannelMessageBuilder
|
||||
.channelId(modMailMessage.getThreadReference().getChannel().getId())
|
||||
.serverId(modMailMessage.getThreadReference().getServer().getId());
|
||||
.channelId(modMailMessage.getThreadReference().getChannel().getId());
|
||||
}
|
||||
messageIds.add(serverChannelMessageBuilder.build());
|
||||
});
|
||||
List<CompletableFuture<Message>> messageFutures = new ArrayList<>();
|
||||
List<LoadedModmailThreadMessage> messageFutures = new ArrayList<>();
|
||||
// add the place holder futures, which are then resolved one by one
|
||||
// because we cannot directly fetch the messages, in case they are in a private channel
|
||||
// the opening of a private channel is a rest operation it itself, so we need
|
||||
// to create the promises here already, else the list is empty for example
|
||||
modMailMessages.forEach(modMailMessage -> messageFutures.add(new CompletableFuture<>()));
|
||||
modMailMessages.forEach(modMailMessage -> messageFutures.add(getLoadedModmailThreadMessage()));
|
||||
Optional<TextChannel> textChannelFromServer = botService.getTextChannelFromServerOptional(thread.getServer().getId(), thread.getChannel().getId());
|
||||
if(textChannelFromServer.isPresent()) {
|
||||
TextChannel modMailThread = textChannelFromServer.get();
|
||||
botService.getInstance().openPrivateChannelById(thread.getUser().getUserReference().getId()).queue(privateChannel -> {
|
||||
Iterator<CompletableFuture<Message>> iterator = messageFutures.iterator();
|
||||
Long userId = thread.getUser().getUserReference().getId();
|
||||
botService.getInstance().openPrivateChannelById(userId).queue(privateChannel -> {
|
||||
Iterator<LoadedModmailThreadMessage> iterator = messageFutures.iterator();
|
||||
messageIds.forEach(serverChannelMessage -> {
|
||||
log.trace("Loading message {}.", serverChannelMessage.getMessageId());
|
||||
// TODO fix out of order promises
|
||||
// depending what the source of the message is, we need to fetch the message from the correct channel
|
||||
CompletableFuture<Message> messageFuture;
|
||||
CompletableFuture<Member> memberFuture = botService.getMemberInServerAsync(serverChannelMessage.getServerId(), serverChannelMessage.getUserId());
|
||||
if(serverChannelMessage.getChannelId() == null){
|
||||
privateChannel.retrieveMessageById(serverChannelMessage.getMessageId()).queue(message -> iterator.next().complete(message), throwable -> {
|
||||
log.info("Failed to load message in private channel with user {}", thread.getUser().getUserReference().getId());
|
||||
iterator.next().complete(null);
|
||||
});
|
||||
messageFuture = privateChannel.retrieveMessageById(serverChannelMessage.getMessageId()).submit();
|
||||
} else {
|
||||
modMailThread.retrieveMessageById(serverChannelMessage.getMessageId()).queue(message -> iterator.next().complete(message), throwable -> {
|
||||
log.info("Failed to load message {} in thread {}", serverChannelMessage.getMessageId(), modMailThread.getIdLong());
|
||||
iterator.next().complete(null);
|
||||
});
|
||||
messageFuture = modMailThread.retrieveMessageById(serverChannelMessage.getMessageId()).submit();
|
||||
}
|
||||
CompletableFuture.allOf(messageFuture, memberFuture).whenComplete((aVoid, throwable) -> {
|
||||
LoadedModmailThreadMessage next = iterator.next();
|
||||
if(messageFuture.isCompletedExceptionally()) {
|
||||
log.warn("Message {} from user {} in server {} failed to load.", serverChannelMessage.getMessageId(), serverChannelMessage.getUserId(), serverChannelMessage.getServerId());
|
||||
messageFuture.exceptionally(throwable1 -> {
|
||||
log.warn("Failed with:", throwable1);
|
||||
return null;
|
||||
});
|
||||
next.getMessageFuture().complete(null);
|
||||
} else {
|
||||
next.getMessageFuture().complete(messageFuture.join());
|
||||
}
|
||||
|
||||
if(memberFuture.isCompletedExceptionally()) {
|
||||
next.getMemberFuture().complete(null);
|
||||
} else {
|
||||
next.getMemberFuture().complete(memberFuture.join());
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
return messageFutures;
|
||||
return LoadedModmailThreadMessageList.builder().messageList(messageFutures).build();
|
||||
}
|
||||
|
||||
public LoadedModmailThreadMessage getLoadedModmailThreadMessage() {
|
||||
return LoadedModmailThreadMessage.builder().memberFuture(new CompletableFuture<>()).messageFuture(new CompletableFuture<>()).build();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,13 +11,14 @@ import dev.sheldan.abstracto.core.models.UndoActionInstance;
|
||||
import dev.sheldan.abstracto.core.models.database.*;
|
||||
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.service.management.UserInServerService;
|
||||
import dev.sheldan.abstracto.core.utils.CompletableFutureList;
|
||||
import dev.sheldan.abstracto.core.utils.FutureUtils;
|
||||
import dev.sheldan.abstracto.modmail.config.*;
|
||||
import dev.sheldan.abstracto.modmail.exception.ModMailCategoryIdException;
|
||||
import dev.sheldan.abstracto.modmail.exception.ModMailThreadNotFoundException;
|
||||
import dev.sheldan.abstracto.modmail.models.dto.LoadedModmailThreadMessageList;
|
||||
import dev.sheldan.abstracto.modmail.models.database.*;
|
||||
import dev.sheldan.abstracto.modmail.models.dto.ServerChoice;
|
||||
import dev.sheldan.abstracto.modmail.models.template.*;
|
||||
@@ -41,6 +42,7 @@ import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
@Transactional
|
||||
public class ModMailThreadServiceBean implements ModMailThreadService {
|
||||
|
||||
/**
|
||||
@@ -89,9 +91,6 @@ public class ModMailThreadServiceBean implements ModMailThreadService {
|
||||
@Autowired
|
||||
private MessageService messageService;
|
||||
|
||||
@Autowired
|
||||
private UserInServerService userInServerService;
|
||||
|
||||
@Autowired
|
||||
private FeatureFlagService featureFlagService;
|
||||
|
||||
@@ -116,6 +115,9 @@ public class ModMailThreadServiceBean implements ModMailThreadService {
|
||||
@Autowired
|
||||
private ModMailFeatureValidator modMailFeatureValidator;
|
||||
|
||||
@Autowired
|
||||
private ServerManagementService serverManagementService;
|
||||
|
||||
@Autowired
|
||||
private ModMailThreadServiceBean self;
|
||||
|
||||
@@ -129,80 +131,81 @@ public class ModMailThreadServiceBean implements ModMailThreadService {
|
||||
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> createModMailThreadForUser(FullUserInServer aUserInAServer, Message initialMessage, MessageChannel feedBackChannel, boolean userInitiated, List<UndoActionInstance> undoActions) {
|
||||
Long serverId = aUserInAServer.getAUserInAServer().getServerReference().getId();
|
||||
public CompletableFuture<Void> createModMailThreadForUser(Member member, Message initialMessage, MessageChannel feedBackChannel, boolean userInitiated, List<UndoActionInstance> undoActions) {
|
||||
Long serverId = member.getGuild().getIdLong();
|
||||
Long categoryId = configService.getLongValue(MODMAIL_CATEGORY, serverId);
|
||||
User user = aUserInAServer.getMember().getUser();
|
||||
AServer server = serverManagementService.loadServer(member.getGuild().getIdLong());
|
||||
User user = member.getUser();
|
||||
log.info("Creating modmail channel for user {} in category {} on server {}.", user.getId(), categoryId, serverId);
|
||||
CompletableFuture<TextChannel> textChannelFuture = channelService.createTextChannel(user.getName() + user.getDiscriminator(), aUserInAServer.getAUserInAServer().getServerReference(), categoryId);
|
||||
|
||||
CompletableFuture<TextChannel> textChannelFuture = channelService.createTextChannel(user.getName() + user.getDiscriminator(), server, categoryId);
|
||||
return textChannelFuture.thenCompose(channel -> {
|
||||
undoActions.add(UndoActionInstance.getChannelDeleteAction(serverId, channel.getIdLong()));
|
||||
return self.performModMailThreadSetup(aUserInAServer, initialMessage, channel, userInitiated, undoActions);
|
||||
return self.performModMailThreadSetup(member, initialMessage, channel, userInitiated, undoActions);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is responsible for creating the instance in the database, sending the header in the newly created text channel and forwarding the initial message
|
||||
* by the user (if any), after this is complete, this method executes the method to perform the mod mail notification.
|
||||
* @param aUserInAServer The {@link FullUserInServer} for which a {@link ModMailThread} is being created
|
||||
* @param member The {@link Member} for which a {@link ModMailThread} is being created
|
||||
* @param initialMessage The {@link Message} which was sent by the user to open a thread, this is null, if the thread was opened via a command
|
||||
* @param channel The created {@link TextChannel} in which the mod mail thread is dealt with
|
||||
* @param userInitiated Whether or not the thread was initiated by a member
|
||||
* @param undoActions The list of actions to undo, in case an exception occurs
|
||||
*/
|
||||
@Transactional
|
||||
public CompletableFuture<Void> performModMailThreadSetup(FullUserInServer aUserInAServer, Message initialMessage, TextChannel channel, boolean userInitiated, List<UndoActionInstance> undoActions) {
|
||||
log.info("Performing modmail thread setup for channel {} for user {} in server {}. It was initiated by a user: {}.", channel.getIdLong(), aUserInAServer.getMember().getId(), channel.getGuild().getId(), userInitiated);
|
||||
Long userInServerId = aUserInAServer.getAUserInAServer().getUserInServerId();
|
||||
CompletableFuture<Void> headerFuture = sendModMailHeader(channel, aUserInAServer);
|
||||
CompletableFuture<Void> userReplyMessage;
|
||||
public CompletableFuture<Void> performModMailThreadSetup(Member member, Message initialMessage, TextChannel channel, boolean userInitiated, List<UndoActionInstance> undoActions) {
|
||||
log.info("Performing modmail thread setup for channel {} for user {} in server {}. It was initiated by a user: {}.", channel.getIdLong(), member.getId(), channel.getGuild().getId(), userInitiated);
|
||||
CompletableFuture<Void> headerFuture = sendModMailHeader(channel, member);
|
||||
CompletableFuture<Message> userReplyMessage;
|
||||
if(initialMessage != null){
|
||||
log.trace("Sending initial message {} of user {} to modmail thread {}.", initialMessage.getId(), aUserInAServer.getMember().getId(), channel.getId());
|
||||
userReplyMessage = self.sendUserReply(channel, null, initialMessage, aUserInAServer.getAUserInAServer());
|
||||
log.trace("Sending initial message {} of user {} to modmail thread {}.", initialMessage.getId(), member.getId(), channel.getId());
|
||||
userReplyMessage = self.sendUserReply(channel, 0L, initialMessage, member, false);
|
||||
} else {
|
||||
log.trace("No initial message to send.");
|
||||
userReplyMessage = CompletableFuture.completedFuture(null);
|
||||
}
|
||||
CompletableFuture notificationFuture;
|
||||
if (userInitiated) {
|
||||
notificationFuture = self.sendModMailNotification(aUserInAServer);
|
||||
notificationFuture = self.sendModMailNotification(member);
|
||||
} else {
|
||||
notificationFuture = CompletableFuture.completedFuture(null);
|
||||
}
|
||||
return CompletableFuture.allOf(headerFuture, notificationFuture, userReplyMessage).thenAccept(aVoid -> {
|
||||
undoActions.clear();
|
||||
self.setupModMailThreadInDB(initialMessage, channel, userInServerId);
|
||||
self.setupModMailThreadInDB(initialMessage, channel, member, userReplyMessage.join());
|
||||
});
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void setupModMailThreadInDB(Message initialMessage, TextChannel channel, Long userInServerId) {
|
||||
public void setupModMailThreadInDB(Message initialMessage, TextChannel channel, Member member, Message sendMessage) {
|
||||
log.info("Persisting info about modmail thread {} in database.", channel.getIdLong());
|
||||
AUserInAServer aUserInAServer = userInServerManagementService.loadUser(userInServerId);
|
||||
AUserInAServer aUserInAServer = userInServerManagementService.loadUser(member);
|
||||
ModMailThread thread = createThreadObject(channel, aUserInAServer);
|
||||
if(initialMessage != null) {
|
||||
log.trace("Adding initial message {} to modmail thread in channel {}.", initialMessage.getId(), channel.getId());
|
||||
modMailMessageManagementService.addMessageToThread(thread, initialMessage, aUserInAServer, false, false);
|
||||
modMailMessageManagementService.addMessageToThread(thread, sendMessage, aUserInAServer, false, false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the message containing the pings to notify the staff members to handle the opened {@link ModMailThread}
|
||||
* @param aUserInAServer The {@link FullUserInServer} which opened the thread
|
||||
* @param member The {@link FullUserInServer} which opened the thread
|
||||
*/
|
||||
@Transactional
|
||||
public CompletableFuture<Void> sendModMailNotification(FullUserInServer aUserInAServer) {
|
||||
log.info("Sending modmail notification for new modmail thread about user {} in server {}.", aUserInAServer.getMember().getId(), aUserInAServer.getMember().getGuild().getId());
|
||||
List<ModMailRole> rolesToPing = modMailRoleManagementService.getRolesForServer(aUserInAServer.getAUserInAServer().getServerReference());
|
||||
log.trace("Pinging {} roles to notify about modmail thread about user {} in server {}.", rolesToPing.size(), aUserInAServer.getMember().getId(), aUserInAServer.getMember().getGuild().getId());
|
||||
public CompletableFuture<Void> sendModMailNotification(Member member) {
|
||||
Long serverId = member.getGuild().getIdLong();
|
||||
log.info("Sending modmail notification for new modmail thread about user {} in server {}.", member.getId(), serverId);
|
||||
AServer server = serverManagementService.loadServer(serverId);
|
||||
List<ModMailRole> rolesToPing = modMailRoleManagementService.getRolesForServer(server);
|
||||
log.trace("Pinging {} roles to notify about modmail thread about user {} in server {}.", rolesToPing.size(), member.getId(), serverId);
|
||||
ModMailNotificationModel modMailNotificationModel = ModMailNotificationModel
|
||||
.builder()
|
||||
.threadUser(aUserInAServer)
|
||||
.member(member)
|
||||
.roles(rolesToPing)
|
||||
.build();
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate("modmail_notification_message", modMailNotificationModel);
|
||||
List<CompletableFuture<Message>> modmailping = postTargetService.sendEmbedInPostTarget(messageToSend, ModMailPostTargets.MOD_MAIL_PING, aUserInAServer.getMember().getGuild().getIdLong());
|
||||
List<CompletableFuture<Message>> modmailping = postTargetService.sendEmbedInPostTarget(messageToSend, ModMailPostTargets.MOD_MAIL_PING, serverId);
|
||||
return CompletableFuture.allOf(modmailping.toArray(new CompletableFuture[0]));
|
||||
}
|
||||
|
||||
@@ -237,7 +240,7 @@ public class ModMailThreadServiceBean implements ModMailThreadService {
|
||||
if(!knownServers.isEmpty()) {
|
||||
log.info("There are {} shared servers between user and abstracto.", knownServers.size());
|
||||
List<ServerChoice> availableGuilds = new ArrayList<>();
|
||||
HashMap<String, AUserInAServer> choices = new HashMap<>();
|
||||
HashMap<String, Long> choices = new HashMap<>();
|
||||
for (int i = 0; i < knownServers.size(); i++) {
|
||||
AUserInAServer aUserInAServer = knownServers.get(i);
|
||||
// only take the servers in which mod mail is actually enabled, would not make much sense to make the
|
||||
@@ -246,13 +249,13 @@ public class ModMailThreadServiceBean implements ModMailThreadService {
|
||||
AServer serverReference = aUserInAServer.getServerReference();
|
||||
FullGuild guild = FullGuild
|
||||
.builder()
|
||||
.guild(botService.getGuildByIdNullable(serverReference.getId()))
|
||||
.guild(botService.getGuildById(serverReference.getId()))
|
||||
.server(serverReference)
|
||||
.build();
|
||||
// TODO support more than this limited amount of servers
|
||||
String reactionEmote = NUMBER_EMOJI.get(i);
|
||||
ServerChoice serverChoice = ServerChoice.builder().guild(guild).reactionEmote(reactionEmote).build();
|
||||
choices.put(reactionEmote, aUserInAServer);
|
||||
choices.put(reactionEmote, aUserInAServer.getServerReference().getId());
|
||||
availableGuilds.add(serverChoice);
|
||||
}
|
||||
}
|
||||
@@ -269,28 +272,28 @@ public class ModMailThreadServiceBean implements ModMailThreadService {
|
||||
.setEventWaiter(eventWaiter)
|
||||
.setDescription(text)
|
||||
.setAction(reactionEmote -> {
|
||||
AUserInAServer chosenServer = choices.get(reactionEmote.getEmoji());
|
||||
log.trace("Executing action for creationg a modmail thread in server {} for user {}.", chosenServer.getServerReference().getId(), chosenServer.getUserReference().getId());
|
||||
Member memberInServer = botService.getMemberInServer(chosenServer);
|
||||
FullUserInServer fullUser = FullUserInServer.builder().member(memberInServer).aUserInAServer(chosenServer).build();
|
||||
self.createModMailThreadForUser(fullUser, initialMessage, initialMessage.getChannel(), true, new ArrayList<>()).exceptionally(throwable -> {
|
||||
log.error("Failed to setup thread correctly", throwable);
|
||||
return null;
|
||||
});
|
||||
Long chosenServerId = choices.get(reactionEmote.getEmoji());
|
||||
log.trace("Executing action for creationg a modmail thread in server {} for user {}.", chosenServerId, initialMessage.getAuthor().getIdLong());
|
||||
botService.getMemberInServerAsync(chosenServerId, initialMessage.getAuthor().getIdLong()).thenCompose(member ->
|
||||
self.createModMailThreadForUser(member, initialMessage, initialMessage.getChannel(), true, new ArrayList<>()).exceptionally(throwable -> {
|
||||
log.error("Failed to setup thread correctly", throwable);
|
||||
return null;
|
||||
})
|
||||
);
|
||||
})
|
||||
.build();
|
||||
log.trace("Displaying server choice message for user {} in channel {}.", user.getId(), initialMessage.getChannel().getId());
|
||||
menu.display(initialMessage.getChannel());
|
||||
} else if(availableGuilds.size() == 1) {
|
||||
// if exactly one server is available, open the thread directly
|
||||
AUserInAServer chosenServer = choices.get(availableGuilds.get(0).getReactionEmote());
|
||||
log.info("Only one server available to modmail. Directly opening modmail thread for user {} in server {}.", chosenServer.getUserReference().getId(), chosenServer.getServerReference().getId());
|
||||
Member memberInServer = botService.getMemberInServer(chosenServer);
|
||||
FullUserInServer fullUser = FullUserInServer.builder().member(memberInServer).aUserInAServer(chosenServer).build();
|
||||
self.createModMailThreadForUser(fullUser, initialMessage, initialMessage.getChannel(), true, new ArrayList<>()).exceptionally(throwable -> {
|
||||
log.error("Failed to setup thread correctly", throwable);
|
||||
return null;
|
||||
});
|
||||
Long chosenServerId = choices.get(availableGuilds.get(0).getReactionEmote());
|
||||
log.info("Only one server available to modmail. Directly opening modmail thread for user {} in server {}.", initialMessage.getAuthor().getId(), chosenServerId);
|
||||
botService.getMemberInServerAsync(chosenServerId, initialMessage.getAuthor().getIdLong()).thenCompose(member ->
|
||||
self.createModMailThreadForUser(member, initialMessage, initialMessage.getChannel(), true, new ArrayList<>()).exceptionally(throwable -> {
|
||||
log.error("Failed to setup thread correctly", throwable);
|
||||
return null;
|
||||
})
|
||||
);
|
||||
} else {
|
||||
log.info("No server available to open a modmail thread in.");
|
||||
// in case there is no server available, send an error message
|
||||
@@ -306,15 +309,16 @@ public class ModMailThreadServiceBean implements ModMailThreadService {
|
||||
* Method used to send the header of a newly created mod mail thread. This message contains information about
|
||||
* the user which the thread is about
|
||||
* @param channel The {@link TextChannel} in which the mod mail thread is present in
|
||||
* @param aUserInAServer The {@link AUserInAServer} which the {@link ModMailThread} is about
|
||||
* @param member The {@link Member} which the {@link ModMailThread} is about
|
||||
*/
|
||||
private CompletableFuture<Void> sendModMailHeader(TextChannel channel, FullUserInServer aUserInAServer) {
|
||||
private CompletableFuture<Void> sendModMailHeader(TextChannel channel, Member member) {
|
||||
log.trace("Sending modmail thread header for tread in channel {} on server {}.", channel.getIdLong(), channel.getGuild().getId());
|
||||
ModMailThread latestThread = modMailThreadManagementService.getLatestModMailThread(aUserInAServer.getAUserInAServer());
|
||||
List<ModMailThread> oldThreads = modMailThreadManagementService.getModMailThreadForUser(aUserInAServer.getAUserInAServer());
|
||||
AUserInAServer aUserInAServer = userInServerManagementService.loadUser(member);
|
||||
ModMailThread latestThread = modMailThreadManagementService.getLatestModMailThread(aUserInAServer);
|
||||
List<ModMailThread> oldThreads = modMailThreadManagementService.getModMailThreadForUser(aUserInAServer);
|
||||
ModMailThreaderHeader header = ModMailThreaderHeader
|
||||
.builder()
|
||||
.threadUser(aUserInAServer)
|
||||
.member(member)
|
||||
.latestModMailThread(latestThread)
|
||||
.pastModMailThreadCount((long)oldThreads.size())
|
||||
.build();
|
||||
@@ -323,19 +327,25 @@ public class ModMailThreadServiceBean implements ModMailThreadService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> relayMessageToModMailThread(ModMailThread modMailThread, Message message, List<UndoActionInstance> undoActions) {
|
||||
public CompletableFuture<Message> relayMessageToModMailThread(ModMailThread modMailThread, Message message, List<UndoActionInstance> undoActions) {
|
||||
Long serverId = modMailThread.getServer().getId();
|
||||
Long channelId = modMailThread.getChannel().getId();
|
||||
Long modmailThreadId = modMailThread.getId();
|
||||
log.trace("Relaying message {} to modmail thread {} for user {} to server {}.", message.getId(), modMailThread.getId(), message.getAuthor().getIdLong(), modMailThread.getServer().getId());
|
||||
Optional<TextChannel> textChannelFromServer = botService.getTextChannelFromServerOptional(modMailThread.getServer().getId(), modMailThread.getChannel().getId());
|
||||
if(textChannelFromServer.isPresent()) {
|
||||
TextChannel textChannel = textChannelFromServer.get();
|
||||
return self.sendUserReply(textChannel, modMailThread, message, modMailThread.getUser());
|
||||
} else {
|
||||
log.warn("Closing modmail thread {}, because it seems the channel {} in server {} got deleted.", modMailThread.getId(), modMailThread.getChannel().getId(), modMailThread.getServer().getId());
|
||||
// in this case there was no text channel on the server associated with the mod mail thread
|
||||
// close the existing one, so the user can start a new one
|
||||
self.closeModMailThreadInDb(modMailThread.getId());
|
||||
return message.getChannel().sendMessage(templateService.renderTemplate("modmail_failed_to_forward_message", new Object())).submit().thenApply(message1 -> null);
|
||||
}
|
||||
return botService.getMemberInServerAsync(modMailThread.getServer().getId(), message.getAuthor().getIdLong()).thenCompose(member -> {
|
||||
Optional<TextChannel> textChannelFromServer = botService.getTextChannelFromServerOptional(serverId, channelId);
|
||||
if(textChannelFromServer.isPresent()) {
|
||||
TextChannel textChannel = textChannelFromServer.get();
|
||||
return self.sendUserReply(textChannel, modmailThreadId, message, member, true);
|
||||
} else {
|
||||
log.warn("Closing modmail thread {}, because it seems the channel {} in server {} got deleted.", modmailThreadId, channelId, serverId);
|
||||
// in this case there was no text channel on the server associated with the mod mail thread
|
||||
// close the existing one, so the user can start a new one
|
||||
self.closeModMailThreadInDb(modmailThreadId);
|
||||
return message.getChannel().sendMessage(templateService.renderTemplate("modmail_failed_to_forward_message", new Object())).submit();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -343,50 +353,50 @@ public class ModMailThreadServiceBean implements ModMailThreadService {
|
||||
* the appropriate {@link ModMailThread} channel, the returned promise only returns if the message was dealt with on the user
|
||||
* side.
|
||||
* @param textChannel The {@link TextChannel} in which the {@link ModMailThread} is being handled
|
||||
* @param modMailThread The {@link ModMailThread} to which the received {@link Message} is a reply to, can be null, if it is null, its the initial message
|
||||
* @param modMailThreadId The id of the modmail thread to which the received {@link Message} is a reply to, can be null, if it is null, its the initial message
|
||||
* @param message The received message from the user
|
||||
* @param member The {@link Member} instance from the user the thread is about. It is used as author
|
||||
* @param modMailThreadExists Whether or not the modmail thread already exists and is persisted.
|
||||
* @return A {@link CompletableFuture} which resolves when the post processing of the message is completed (adding read notification, and storing messageIDs)
|
||||
*/
|
||||
public CompletableFuture<Void> sendUserReply(TextChannel textChannel, ModMailThread modMailThread, Message message, AUserInAServer userInServer) {
|
||||
boolean modMailThreadExists = modMailThread != null;
|
||||
FullUserInServer fullUser = FullUserInServer
|
||||
.builder()
|
||||
.aUserInAServer(userInServer)
|
||||
.member(botService.getMemberInServer(userInServer))
|
||||
.build();
|
||||
|
||||
List<FullUserInServer> subscribers = new ArrayList<>();
|
||||
public CompletableFuture<Message> sendUserReply(TextChannel textChannel, Long modMailThreadId, Message message, Member member, boolean modMailThreadExists) {
|
||||
List<CompletableFuture<Member>> subscriberMemberFutures = new ArrayList<>();
|
||||
if(modMailThreadExists) {
|
||||
ModMailThread modMailThread = modMailThreadManagementService.getById(modMailThreadId);
|
||||
List<ModMailThreadSubscriber> subscriberList = modMailSubscriberManagementService.getSubscribersForThread(modMailThread);
|
||||
subscriberList.forEach(modMailThreadSubscriber -> {
|
||||
FullUserInServer subscriber = FullUserInServer
|
||||
.builder()
|
||||
.aUserInAServer(modMailThreadSubscriber.getSubscriber())
|
||||
.member(botService.getMemberInServer(modMailThreadSubscriber.getSubscriber()))
|
||||
.build();
|
||||
subscribers.add(subscriber);
|
||||
});
|
||||
log.trace("Pinging {} subscribers for modmail thread {}.", subscriberList.size(), modMailThread.getId());
|
||||
subscriberList.forEach(modMailThreadSubscriber ->
|
||||
subscriberMemberFutures.add(botService.getMemberInServerAsync(modMailThreadSubscriber.getSubscriber()))
|
||||
);
|
||||
if(subscriberList.isEmpty()) {
|
||||
subscriberMemberFutures.add(CompletableFuture.completedFuture(null));
|
||||
}
|
||||
log.trace("Pinging {} subscribers for modmail thread {}.", subscriberList.size(), modMailThreadId);
|
||||
} else {
|
||||
subscriberMemberFutures.add(CompletableFuture.completedFuture(null));
|
||||
}
|
||||
ModMailUserReplyModel modMailUserReplyModel = ModMailUserReplyModel
|
||||
.builder()
|
||||
.modMailThread(modMailThread)
|
||||
.postedMessage(message)
|
||||
.threadUser(fullUser)
|
||||
.subscribers(subscribers)
|
||||
.build();
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate("modmail_user_message", modMailUserReplyModel);
|
||||
List<CompletableFuture<Message>> completableFutures = channelService.sendMessageToSendToChannel(messageToSend, textChannel);
|
||||
return CompletableFuture.allOf(completableFutures.toArray(new CompletableFuture[0]))
|
||||
.thenCompose(aVoid -> {
|
||||
log.trace("Adding read reaction to initial message for mod mail thread in channel {}.", textChannel.getGuild().getId());
|
||||
return messageService.addReactionToMessageWithFuture("readReaction", textChannel.getGuild().getIdLong(), message);
|
||||
})
|
||||
.thenAccept(aVoid -> {
|
||||
if(modMailThreadExists) {
|
||||
self.postProcessSendMessages(textChannel, completableFutures.get(0).join());
|
||||
}
|
||||
});
|
||||
return FutureUtils.toSingleFutureGeneric(subscriberMemberFutures).thenCompose(firstVoid -> {
|
||||
List<FullUserInServer> subscribers = new ArrayList<>();
|
||||
ModMailUserReplyModel modMailUserReplyModel = ModMailUserReplyModel
|
||||
.builder()
|
||||
.postedMessage(message)
|
||||
.member(member)
|
||||
.subscribers(subscribers)
|
||||
.build();
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate("modmail_user_message", modMailUserReplyModel);
|
||||
List<CompletableFuture<Message>> completableFutures = channelService.sendMessageToSendToChannel(messageToSend, textChannel);
|
||||
return CompletableFuture.allOf(completableFutures.toArray(new CompletableFuture[0]))
|
||||
.thenCompose(aVoid -> {
|
||||
log.trace("Adding read reaction to initial message for mod mail thread in channel {}.", textChannel.getGuild().getId());
|
||||
return messageService.addReactionToMessageWithFuture("readReaction", textChannel.getGuild().getIdLong(), message);
|
||||
})
|
||||
.thenApply(aVoid -> {
|
||||
if(modMailThreadExists) {
|
||||
self.postProcessSendMessages(textChannel, completableFutures.get(0).join());
|
||||
}
|
||||
return completableFutures.get(0).join();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -397,7 +407,7 @@ public class ModMailThreadServiceBean implements ModMailThreadService {
|
||||
*/
|
||||
@Transactional
|
||||
public void postProcessSendMessages(TextChannel textChannel, Message message) {
|
||||
Optional<ModMailThread> modMailThreadOpt = modMailThreadManagementService.getById(textChannel.getIdLong());
|
||||
Optional<ModMailThread> modMailThreadOpt = modMailThreadManagementService.getByIdOptional(textChannel.getIdLong());
|
||||
if(modMailThreadOpt.isPresent()) {
|
||||
ModMailThread modMailThread = modMailThreadOpt.get();
|
||||
log.trace("Adding message {} sent from user to modmail thread {} and setting status to {}.", message.getId(), modMailThread.getId(), ModMailThreadState.USER_REPLIED);
|
||||
@@ -410,39 +420,35 @@ public class ModMailThreadServiceBean implements ModMailThreadService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> relayMessageToDm(ModMailThread modMailThread, String text, Message message, boolean anonymous, MessageChannel feedBack, List<UndoActionInstance> undoActions) {
|
||||
Long modMailThreadId = modMailThread.getId();
|
||||
log.info("Relaying message {} to user {} in modmail thread {} on server {}.", message.getId(), modMailThread.getUser().getUserReference().getId(), modMailThread.getId(), modMailThread.getServer().getId());
|
||||
User userById = botService.getInstance().getUserById(modMailThread.getUser().getUserReference().getId());
|
||||
if(userById != null) {
|
||||
AUserInAServer moderator = userInServerManagementService.loadUser(message.getMember());
|
||||
Member userInGuild = botService.getMemberInServer(modMailThread.getUser());
|
||||
FullUserInServer fullThreadUser = FullUserInServer
|
||||
.builder()
|
||||
.aUserInAServer(modMailThread.getUser())
|
||||
.member(userInGuild)
|
||||
.build();
|
||||
ModMailModeratorReplyModel.ModMailModeratorReplyModelBuilder modMailModeratorReplyModelBuilder = ModMailModeratorReplyModel
|
||||
.builder()
|
||||
.text(text)
|
||||
.modMailThread(modMailThread)
|
||||
.postedMessage(message)
|
||||
.anonymous(anonymous)
|
||||
.threadUser(fullThreadUser);
|
||||
if(anonymous) {
|
||||
log.trace("Message is sent anonymous.");
|
||||
modMailModeratorReplyModelBuilder.moderator(botService.getBotInGuild(modMailThread.getServer()));
|
||||
} else {
|
||||
Member moderatorMember = botService.getMemberInServer(moderator);
|
||||
modMailModeratorReplyModelBuilder.moderator(moderatorMember);
|
||||
}
|
||||
ModMailModeratorReplyModel modMailUserReplyModel = modMailModeratorReplyModelBuilder.build();
|
||||
CompletableFuture<Message> future = messageService.sendEmbedToUserWithMessage(userById, "modmail_staff_message", modMailUserReplyModel);
|
||||
return future.thenAccept(sendMessage ->
|
||||
self.saveSendMessagesAndUpdateState(modMailThreadId, anonymous, moderator, sendMessage)
|
||||
);
|
||||
public CompletableFuture<Void> relayMessageToDm(Long modmailThreadId, String text, Message message, boolean anonymous, MessageChannel feedBack, List<UndoActionInstance> undoActions, Member targetMember) {
|
||||
log.info("Relaying message {} to user {} in modmail thread {} on server {}.", message.getId(), targetMember.getId(), modmailThreadId, targetMember.getGuild().getId());
|
||||
AUserInAServer moderator = userInServerManagementService.loadUser(message.getMember());
|
||||
ModMailThread modMailThread = modMailThreadManagementService.getById(modmailThreadId);
|
||||
FullUserInServer fullThreadUser = FullUserInServer
|
||||
.builder()
|
||||
.aUserInAServer(modMailThread.getUser())
|
||||
.member(targetMember)
|
||||
.build();
|
||||
ModMailModeratorReplyModel.ModMailModeratorReplyModelBuilder modMailModeratorReplyModelBuilder = ModMailModeratorReplyModel
|
||||
.builder()
|
||||
.text(text)
|
||||
.modMailThread(modMailThread)
|
||||
.postedMessage(message)
|
||||
.anonymous(anonymous)
|
||||
.threadUser(fullThreadUser);
|
||||
if(anonymous) {
|
||||
log.trace("Message is sent anonymous.");
|
||||
modMailModeratorReplyModelBuilder.moderator(botService.getBotInGuild(modMailThread.getServer()));
|
||||
} else {
|
||||
// should be loaded, because we are currently processing a command caused by the message
|
||||
Member moderatorMember = botService.getMemberInServer(moderator);
|
||||
modMailModeratorReplyModelBuilder.moderator(moderatorMember);
|
||||
}
|
||||
throw new AbstractoRunTimeException("User in server not found.");
|
||||
ModMailModeratorReplyModel modMailUserReplyModel = modMailModeratorReplyModelBuilder.build();
|
||||
CompletableFuture<Message> future = messageService.sendEmbedToUserWithMessage(targetMember.getUser(), "modmail_staff_message", modMailUserReplyModel);
|
||||
return future.thenAccept(sendMessage ->
|
||||
self.saveSendMessagesAndUpdateState(modmailThreadId, anonymous, moderator, sendMessage)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -457,17 +463,21 @@ public class ModMailThreadServiceBean implements ModMailThreadService {
|
||||
Long modMailThreadId = modMailThread.getId();
|
||||
log.info("Starting closing procedure for thread {}", modMailThread.getId());
|
||||
List<ModMailMessage> modMailMessages = modMailThread.getMessages();
|
||||
Long userId = modMailThread.getUser().getUserReference().getId();
|
||||
Long serverId = modMailThread.getServer().getId();
|
||||
if(logThread) {
|
||||
List<CompletableFuture<Message>> messages = modMailMessageService.loadModMailMessages(modMailMessages);
|
||||
CompletableFuture<Void> messagesFuture = FutureUtils.toSingleFutureGeneric(messages);
|
||||
LoadedModmailThreadMessageList messages = modMailMessageService.loadModMailMessages(modMailMessages);
|
||||
CompletableFuture<Void> messagesFuture = FutureUtils.toSingleFuture(messages.getAllFutures());
|
||||
|
||||
return messagesFuture.handle((aVoid, throwable) ->
|
||||
self.logMessagesToModMailLog(note, notifyUser, modMailThreadId, undoActions, messages)
|
||||
self.logMessagesToModMailLog(note, notifyUser, modMailThreadId, undoActions, messages, serverId, userId)
|
||||
).toCompletableFuture().thenCompose(o -> o);
|
||||
|
||||
} else {
|
||||
log.trace("Not logging modmail thread {}.", modMailThreadId);
|
||||
return self.afterSuccessfulLog(modMailThreadId, notifyUser, undoActions);
|
||||
return botService.getMemberInServerAsync(modMailThread.getUser()).thenCompose(member ->
|
||||
self.afterSuccessfulLog(modMailThreadId, notifyUser, member, undoActions)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -479,10 +489,12 @@ public class ModMailThreadServiceBean implements ModMailThreadService {
|
||||
* @param modMailThreadId The ID of the {@link ModMailThread} which is being closed
|
||||
* @param undoActions The list of {@link UndoActionInstance} to execute in case of exceptions
|
||||
* @param messages The list of loaded {@link Message} to log
|
||||
* @param serverId The ID of the {@link Guild} the {@link ModMailThread} is in
|
||||
* @param userId The ID of the user the {@link ModMailThread} is about
|
||||
*/
|
||||
@Transactional
|
||||
public CompletableFuture<Void> logMessagesToModMailLog(String note, Boolean notifyUser, Long modMailThreadId, List<UndoActionInstance> undoActions, List<CompletableFuture<Message>> messages) {
|
||||
log.trace("Logging {} modmail messages for modmail thread {}.", messages.size(), modMailThreadId);
|
||||
public CompletableFuture<Void> logMessagesToModMailLog(String note, Boolean notifyUser, Long modMailThreadId, List<UndoActionInstance> undoActions, LoadedModmailThreadMessageList messages, Long serverId, Long userId) {
|
||||
log.trace("Logging {} modmail messages for modmail thread {}.", messages.getMessageList().size(), modMailThreadId);
|
||||
try {
|
||||
CompletableFutureList<Message> list = self.logModMailThread(modMailThreadId, messages, note, undoActions);
|
||||
return list.getMainFuture().thenCompose(avoid -> {
|
||||
@@ -490,7 +502,9 @@ public class ModMailThreadServiceBean implements ModMailThreadService {
|
||||
Message message = messageCompletableFuture.join();
|
||||
undoActions.add(UndoActionInstance.getMessageDeleteAction(messageCompletableFuture.join().getChannel().getIdLong(), message.getIdLong()));
|
||||
});
|
||||
return self.afterSuccessfulLog(modMailThreadId, notifyUser, undoActions);
|
||||
return botService.getMemberInServerAsync(serverId, userId).thenCompose(member ->
|
||||
self.afterSuccessfulLog(modMailThreadId, notifyUser, member, undoActions)
|
||||
);
|
||||
});
|
||||
} catch (Exception e) {
|
||||
log.error("Failed to log mod mail messages", e);
|
||||
@@ -507,22 +521,21 @@ public class ModMailThreadServiceBean implements ModMailThreadService {
|
||||
* @throws ModMailThreadNotFoundException in case the {@link ModMailThread} is not found by the ID
|
||||
*/
|
||||
@Transactional
|
||||
public CompletableFuture<Void> afterSuccessfulLog(Long modMailThreadId, Boolean notifyUser, List<UndoActionInstance> undoActions) {
|
||||
public CompletableFuture<Void> afterSuccessfulLog(Long modMailThreadId, Boolean notifyUser, Member modMailThreaduser, List<UndoActionInstance> undoActions) {
|
||||
log.trace("Mod mail logging for thread {} has completed. Starting post logging activities.", modMailThreadId);
|
||||
Optional<ModMailThread> modMailThreadOpt = modMailThreadManagementService.getById(modMailThreadId);
|
||||
Optional<ModMailThread> modMailThreadOpt = modMailThreadManagementService.getByIdOptional(modMailThreadId);
|
||||
if(modMailThreadOpt.isPresent()) {
|
||||
if(notifyUser) {
|
||||
log.trace("Notifying user about the closed modmail thread {}.", modMailThreadId);
|
||||
log.info("Notifying user about the closed modmail thread {}.", modMailThreadId);
|
||||
ModMailThread modMailThread = modMailThreadOpt.get();
|
||||
User user = botService.getMemberInServer(modMailThread.getUser()).getUser();
|
||||
HashMap<String, String> closingMessage = new HashMap<>();
|
||||
String defaultValue = templateService.renderSimpleTemplate("modmail_closing_user_message_description");
|
||||
closingMessage.put("closingMessage", configService.getStringValue(MODMAIL_CLOSING_MESSAGE_TEXT, modMailThread.getServer().getId(), defaultValue));
|
||||
return messageService.sendEmbedToUser(user, "modmail_closing_user_message", closingMessage).thenAccept(message ->
|
||||
return messageService.sendEmbedToUser(modMailThreaduser.getUser(), "modmail_closing_user_message", closingMessage).thenAccept(message ->
|
||||
self.deleteChannelAndClose(modMailThreadId, undoActions)
|
||||
);
|
||||
} else {
|
||||
log.trace("NOT Notifying user about the closed modmail thread {}.", modMailThreadId);
|
||||
log.info("NOT Notifying user about the closed modmail thread {}.", modMailThreadId);
|
||||
return deleteChannelAndClose(modMailThreadId, undoActions);
|
||||
}
|
||||
} else {
|
||||
@@ -539,7 +552,7 @@ public class ModMailThreadServiceBean implements ModMailThreadService {
|
||||
*/
|
||||
@Transactional
|
||||
public CompletableFuture<Void> deleteChannelAndClose(Long modMailThreadId, List<UndoActionInstance> undoActions) {
|
||||
Optional<ModMailThread> modMailThreadOpt = modMailThreadManagementService.getById(modMailThreadId);
|
||||
Optional<ModMailThread> modMailThreadOpt = modMailThreadManagementService.getByIdOptional(modMailThreadId);
|
||||
if(modMailThreadOpt.isPresent()) {
|
||||
ModMailThread modMailThread = modMailThreadOpt.get();
|
||||
String failureMessage = "Failed to delete text channel containing mod mail thread {}";
|
||||
@@ -575,14 +588,15 @@ public class ModMailThreadServiceBean implements ModMailThreadService {
|
||||
* the result values of the individual futures after they are done.
|
||||
*/
|
||||
@Transactional
|
||||
public CompletableFutureList<Message> logModMailThread(Long modMailThreadId, List<CompletableFuture<Message>> messages, String note, List<UndoActionInstance> undoActions) {
|
||||
log.info("Logging mod mail thread {} with {} messages.", modMailThreadId, messages.size());
|
||||
Optional<ModMailThread> modMailThreadOpt = modMailThreadManagementService.getById(modMailThreadId);
|
||||
public CompletableFutureList<Message> logModMailThread(Long modMailThreadId, LoadedModmailThreadMessageList messages, String note, List<UndoActionInstance> undoActions) {
|
||||
log.info("Logging mod mail thread {} with {} messages.", modMailThreadId, messages.getMessageList().size());
|
||||
Optional<ModMailThread> modMailThreadOpt = modMailThreadManagementService.getByIdOptional(modMailThreadId);
|
||||
if(modMailThreadOpt.isPresent()) {
|
||||
ModMailThread modMailThread = modMailThreadOpt.get();
|
||||
List<ModMailLoggedMessageModel> loggedMessages = new ArrayList<>();
|
||||
messages.forEach(future -> {
|
||||
messages.getMessageList().forEach(futures -> {
|
||||
try {
|
||||
CompletableFuture<Message> future = futures.getMessageFuture();
|
||||
if(!future.isCompletedExceptionally()) {
|
||||
Message loadedMessage = future.join();
|
||||
if(loadedMessage != null) {
|
||||
@@ -591,12 +605,13 @@ public class ModMailThreadServiceBean implements ModMailThreadService {
|
||||
.stream()
|
||||
.filter(modMailMessage -> modMailMessage.getMessageId().equals(loadedMessage.getIdLong()))
|
||||
.findFirst().orElseThrow(() -> new AbstractoRunTimeException("Could not find desired message in list of messages in thread. This should not happen, as we just retrieved them from the same place."));
|
||||
Member author = futures.getMemberFuture().join();
|
||||
ModMailLoggedMessageModel modMailLoggedMessageModel =
|
||||
ModMailLoggedMessageModel
|
||||
.builder()
|
||||
.message(loadedMessage)
|
||||
.modMailMessage(modmailMessage)
|
||||
.author(userInServerService.getFullUser(modmailMessage.getAuthor()))
|
||||
.author(author) // doesnt work for the messages from the DM channel
|
||||
.build();
|
||||
loggedMessages.add(modMailLoggedMessageModel);
|
||||
}
|
||||
@@ -634,7 +649,7 @@ public class ModMailThreadServiceBean implements ModMailThreadService {
|
||||
*/
|
||||
@Transactional
|
||||
public void closeModMailThreadInDb(Long modMailThreadId) {
|
||||
Optional<ModMailThread> modMailThreadOpt = modMailThreadManagementService.getById(modMailThreadId);
|
||||
Optional<ModMailThread> modMailThreadOpt = modMailThreadManagementService.getByIdOptional(modMailThreadId);
|
||||
if(modMailThreadOpt.isPresent()) {
|
||||
ModMailThread modMailThread = modMailThreadOpt.get();
|
||||
log.info("Setting thread {} to closed in db.", modMailThread.getId());
|
||||
@@ -654,6 +669,7 @@ public class ModMailThreadServiceBean implements ModMailThreadService {
|
||||
*/
|
||||
public List<CompletableFuture<Message>> sendMessagesToPostTarget(ModMailThread modMailThread, List<ModMailLoggedMessageModel> loadedMessages) {
|
||||
List<CompletableFuture<Message>> messageFutures = new ArrayList<>();
|
||||
// TODO order messages
|
||||
loadedMessages.forEach(message -> {
|
||||
log.trace("Sending message {} of modmail thread {} to modmail log post target.", modMailThread.getId(), message.getMessage().getId());
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate("modmail_close_logged_message", message);
|
||||
@@ -673,7 +689,7 @@ public class ModMailThreadServiceBean implements ModMailThreadService {
|
||||
*/
|
||||
@Transactional
|
||||
public void saveSendMessagesAndUpdateState(Long modMailThreadId, Boolean anonymous, AUserInAServer moderator, Message message) {
|
||||
Optional<ModMailThread> modMailThreadOpt = modMailThreadManagementService.getById(modMailThreadId);
|
||||
Optional<ModMailThread> modMailThreadOpt = modMailThreadManagementService.getByIdOptional(modMailThreadId);
|
||||
if(modMailThreadOpt.isPresent()) {
|
||||
ModMailThread modMailThread = modMailThreadOpt.get();
|
||||
log.trace("Adding (anonymous: {}) message {} of moderator to modmail thread {} and setting state to {}.", anonymous, message.getId(), modMailThreadId, ModMailThreadState.MOD_REPLIED);
|
||||
|
||||
@@ -4,6 +4,7 @@ import dev.sheldan.abstracto.core.models.database.AChannel;
|
||||
import dev.sheldan.abstracto.core.models.database.AUser;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
|
||||
import dev.sheldan.abstracto.modmail.exception.ModMailThreadNotFoundException;
|
||||
import dev.sheldan.abstracto.modmail.models.database.ModMailThread;
|
||||
import dev.sheldan.abstracto.modmail.models.database.ModMailThreadState;
|
||||
import dev.sheldan.abstracto.modmail.repository.ModMailThreadRepository;
|
||||
@@ -32,10 +33,15 @@ public class ModMailThreadManagementServiceBean implements ModMailThreadManageme
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<ModMailThread> getById(Long modMailThreadId) {
|
||||
public Optional<ModMailThread> getByIdOptional(Long modMailThreadId) {
|
||||
return modMailThreadRepository.findById(modMailThreadId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModMailThread getById(Long modMailThreadId) {
|
||||
return getByIdOptional(modMailThreadId).orElseThrow(() -> new ModMailThreadNotFoundException(modMailThreadId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModMailThread getByChannel(AChannel channel) {
|
||||
return modMailThreadRepository.findByChannel(channel);
|
||||
|
||||
@@ -78,7 +78,7 @@ public class ModMailCategorySetupBean implements ModMailCategorySetup {
|
||||
.builder()
|
||||
.build();
|
||||
if(configManagementService.configExists(user.getGuildId(), ModMailThreadServiceBean.MODMAIL_CATEGORY)) {
|
||||
Guild guild = botService.getGuildByIdNullable(user.getGuildId());
|
||||
Guild guild = botService.getGuildById(user.getGuildId());
|
||||
Long categoryId = configService.getLongValue(ModMailThreadServiceBean.MODMAIL_CATEGORY, user.getGuildId());
|
||||
log.trace("Previous modmail category exists for server {}. Loading value {}.", guild.getId(), categoryId);
|
||||
Category category = guild.getCategoryById(categoryId);
|
||||
@@ -104,7 +104,7 @@ public class ModMailCategorySetupBean implements ModMailCategorySetup {
|
||||
String messageContent = event.getMessage().getContentRaw();
|
||||
// directly parse the long from the message, for *now*, only the category ID is supported
|
||||
Long categoryId = Long.parseLong(messageContent);
|
||||
Guild guild = botService.getGuildByIdNullable(user.getGuildId());
|
||||
Guild guild = botService.getGuildById(user.getGuildId());
|
||||
FeatureValidationResult featureValidationResult = FeatureValidationResult.builder().validationResult(true).build();
|
||||
// directly validate whether or not the given category ID is a valid value
|
||||
modMailFeatureValidator.validateModMailCategory(featureValidationResult, guild, categoryId);
|
||||
|
||||
@@ -42,7 +42,7 @@ public class ModMailFeatureValidatorBean implements ModMailFeatureValidator {
|
||||
*/
|
||||
@Override
|
||||
public void featureIsSetup(FeatureConfig featureConfig, AServer server, FeatureValidationResult validationResult) {
|
||||
Optional<Guild> guildById = botService.getGuildById(server.getId());
|
||||
Optional<Guild> guildById = botService.getGuildByIdOptional(server.getId());
|
||||
if(guildById.isPresent()) {
|
||||
Guild guild = guildById.get();
|
||||
boolean checkSucceeded = featureValidatorService.checkSystemConfig(ModMailThreadServiceBean.MODMAIL_CATEGORY, server, validationResult);
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package dev.sheldan.abstracto.modmail.models.dto;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
public class LoadedModmailThreadMessage {
|
||||
private CompletableFuture<Message> messageFuture;
|
||||
private CompletableFuture<Member> memberFuture;
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package dev.sheldan.abstracto.modmail.models.dto;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
public class LoadedModmailThreadMessageList {
|
||||
private List<LoadedModmailThreadMessage> messageList;
|
||||
public List<CompletableFuture> getAllFutures() {
|
||||
List<CompletableFuture> futures = new ArrayList<>();
|
||||
messageList.forEach(loadedModmailThreadMessage -> {
|
||||
futures.add(loadedModmailThreadMessage.getMemberFuture());
|
||||
futures.add(loadedModmailThreadMessage.getMessageFuture());
|
||||
});
|
||||
return futures;
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import dev.sheldan.abstracto.modmail.models.database.ModMailMessage;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
|
||||
/**
|
||||
@@ -26,7 +27,7 @@ public class ModMailLoggedMessageModel {
|
||||
/**
|
||||
* A reference to the {@link FullUserInServer} which is the author. The member part is null, if the member left the guild.
|
||||
*/
|
||||
private FullUserInServer author;
|
||||
private Member author;
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import dev.sheldan.abstracto.modmail.models.database.ModMailThread;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -25,7 +26,7 @@ public class ModMailNotificationModel extends ServerContext {
|
||||
/**
|
||||
* The {@link FullUserInServer} for which this thread is about
|
||||
*/
|
||||
private FullUserInServer threadUser;
|
||||
private Member member;
|
||||
/**
|
||||
* A list of roles which will be notified upon creation of the mod mail thread.
|
||||
*/
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package dev.sheldan.abstracto.modmail.models.template;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.FullUserInServer;
|
||||
import dev.sheldan.abstracto.modmail.models.database.ModMailThread;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
|
||||
/**
|
||||
* This is the model used when a new mod mail thread is opened and a message containing some information about the user
|
||||
@@ -15,9 +15,9 @@ import lombok.Setter;
|
||||
@Builder
|
||||
public class ModMailThreaderHeader {
|
||||
/**
|
||||
* A {@link FullUserInServer} instance to retrieve information from
|
||||
* A {@link Member} instance to retrieve information from
|
||||
*/
|
||||
private FullUserInServer threadUser;
|
||||
private Member member;
|
||||
/**
|
||||
* The latest {@link ModMailThread}, before the current opened one. This is null if there is no closed mod mail thread
|
||||
* for the user
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package dev.sheldan.abstracto.modmail.models.template;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.FullUserInServer;
|
||||
import dev.sheldan.abstracto.modmail.models.database.ModMailThread;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
|
||||
import java.util.List;
|
||||
@@ -17,17 +17,13 @@ import java.util.List;
|
||||
@Builder
|
||||
public class ModMailUserReplyModel {
|
||||
/**
|
||||
* The {@link FullUserInServer} from which the message is and whose mod mail thread it is
|
||||
* The {@link Member} from which the message is and whose mod mail thread it is
|
||||
*/
|
||||
private FullUserInServer threadUser;
|
||||
private Member member;
|
||||
/**
|
||||
* The {@link Message} which was posted, which contains all the possible information
|
||||
*/
|
||||
private Message postedMessage;
|
||||
/**
|
||||
* The {@link ModMailThread} for which the {@link Message} was a reply for
|
||||
*/
|
||||
private ModMailThread modMailThread;
|
||||
/**
|
||||
* List of {@link FullUserInServer} which are registered as subscribers for a particular mod mail thread and will be pinged
|
||||
* when the user sends a new message
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package dev.sheldan.abstracto.modmail.service;
|
||||
|
||||
import dev.sheldan.abstracto.modmail.models.database.ModMailMessage;
|
||||
import dev.sheldan.abstracto.modmail.models.dto.LoadedModmailThreadMessageList;
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
/**
|
||||
* Service to handle the messages of a {@link dev.sheldan.abstracto.modmail.models.database.ModMailThread}
|
||||
@@ -13,7 +13,7 @@ public interface ModMailMessageService {
|
||||
/**
|
||||
* Loads the given mod mail messages in the form of {@link Message} from Discord and returns the created promises, some of which might fail, if the message was already deleted
|
||||
* @param modMailMessages The list of {@link ModMailMessage} to load
|
||||
* @return A list of futures which contain the individual results of actively loading the {@link Message}
|
||||
* @return A instance of {@link LoadedModmailThreadMessageList} which contain the individual results of actively loading the {@link Message} and the {@link net.dv8tion.jda.api.entities.Member}
|
||||
*/
|
||||
List<CompletableFuture<Message>> loadModMailMessages(List<ModMailMessage> modMailMessages);
|
||||
LoadedModmailThreadMessageList loadModMailMessages(List<ModMailMessage> modMailMessages);
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package dev.sheldan.abstracto.modmail.service;
|
||||
|
||||
|
||||
import dev.sheldan.abstracto.core.models.FullUserInServer;
|
||||
import dev.sheldan.abstracto.core.models.UndoActionInstance;
|
||||
import dev.sheldan.abstracto.core.models.database.AUser;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.modmail.models.database.ModMailThread;
|
||||
import net.dv8tion.jda.api.entities.Guild;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
import net.dv8tion.jda.api.entities.MessageChannel;
|
||||
|
||||
@@ -21,12 +21,12 @@ public interface ModMailThreadService {
|
||||
* Creates a new mod mail thread for the given user. including: the {@link net.dv8tion.jda.api.entities.TextChannel}
|
||||
* in the appropriate {@link net.dv8tion.jda.api.entities.Category} and calls the methods responsible for storing
|
||||
* the necessary data in the database, notifying the users and sending messages related to the creation of the {@link ModMailThread}
|
||||
* @param userInAServer The {@link AUserInAServer} to create the mod mail thread for
|
||||
* @param member The {@link AUserInAServer} to create the mod mail thread for
|
||||
* @param initialMessage The initial message sparking this mod mail thread, null in case it was created by a command
|
||||
* @param feedBackChannel The {@link MessageChannel} in which feedback about exceptions should be posted to
|
||||
* @param userInitiated Whether or not the mod mail thread was initiated by a user
|
||||
*/
|
||||
CompletableFuture<Void> createModMailThreadForUser(FullUserInServer userInAServer, Message initialMessage, MessageChannel feedBackChannel, boolean userInitiated, List<UndoActionInstance> undoActions);
|
||||
CompletableFuture<Void> createModMailThreadForUser(Member member, Message initialMessage, MessageChannel feedBackChannel, boolean userInitiated, List<UndoActionInstance> undoActions);
|
||||
|
||||
/**
|
||||
* Changes the configuration value of the category used to create mod mail threads to the given ID.
|
||||
@@ -52,18 +52,20 @@ public interface ModMailThreadService {
|
||||
* @param modMailThread The {@link ModMailThread} on which the user answered
|
||||
* @param message The {@link Message} object which was sent by the user to answer with
|
||||
*/
|
||||
CompletableFuture<Void> relayMessageToModMailThread(ModMailThread modMailThread, Message message, List<UndoActionInstance> undoActions);
|
||||
CompletableFuture<Message> relayMessageToModMailThread(ModMailThread modMailThread, Message message, List<UndoActionInstance> undoActions);
|
||||
|
||||
/**
|
||||
* Forwards a message send by a moderator to the direct message channel opened with the user. If the message is
|
||||
* marked as anonymous, the bot will take the place of the author, in other case the author is shown in the embed.
|
||||
* @param modMailThread The {@link ModMailThread} to which the reply was sent to
|
||||
* @param threadId The id of the {@link ModMailThread} to which the reply was sent to
|
||||
* @param text The parsed text of the reply
|
||||
* @param message The pure {@link Message} containing the command which caused the reply
|
||||
* @param anonymous Whether or nor the message should be send anonymous
|
||||
* @param feedBack The {@link MessageChannel} in which feedback about possible exceptions should be sent to
|
||||
* @param undoActions list of {@link UndoActionInstance} to execute in case this fails
|
||||
* @param targetMember The {@link Member} the {@link ModMailThread} is about.
|
||||
*/
|
||||
CompletableFuture<Void> relayMessageToDm(ModMailThread modMailThread, String text, Message message, boolean anonymous, MessageChannel feedBack, List<UndoActionInstance> undoActions);
|
||||
CompletableFuture<Void> relayMessageToDm(Long threadId, String text, Message message, boolean anonymous, MessageChannel feedBack, List<UndoActionInstance> undoActions, Member targetMember);
|
||||
|
||||
/**
|
||||
* Closes the mod mail thread which means: deletes the {@link net.dv8tion.jda.api.entities.TextChannel} associated with the mod mail thread,
|
||||
|
||||
@@ -29,7 +29,14 @@ public interface ModMailThreadManagementService {
|
||||
* @param modMailThreadId The ID of the mod mail to search for
|
||||
* @return An {@link Optional} containing the mod mail thread or empty
|
||||
*/
|
||||
Optional<ModMailThread> getById(Long modMailThreadId);
|
||||
Optional<ModMailThread> getByIdOptional(Long modMailThreadId);
|
||||
|
||||
/**
|
||||
* Retrieves the {@link ModMailThread} by the given ID in an optional, if it exists, and an {@literal Optional#empty()} otherwise
|
||||
* @param modMailThreadId The ID of the mod mail to search for
|
||||
* @return An {@link Optional} containing the mod mail thread or empty
|
||||
*/
|
||||
ModMailThread getById(Long modMailThreadId);
|
||||
|
||||
/**
|
||||
* Retrieves a {@link ModMailThread} found in the {@link net.dv8tion.jda.api.entities.MessageChannel} given by the
|
||||
|
||||
@@ -11,7 +11,6 @@ import dev.sheldan.abstracto.core.config.FeatureEnum;
|
||||
import dev.sheldan.abstracto.core.service.ChannelService;
|
||||
import dev.sheldan.abstracto.core.utils.FutureUtils;
|
||||
import dev.sheldan.abstracto.utility.config.features.UtilityFeature;
|
||||
import dev.sheldan.abstracto.utility.models.template.commands.starboard.StarStatsModel;
|
||||
import dev.sheldan.abstracto.utility.service.StarboardService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
@@ -33,9 +32,10 @@ public class StarStats extends AbstractConditionableCommand {
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
|
||||
StarStatsModel result = starboardService.retrieveStarStats(commandContext.getGuild().getIdLong());
|
||||
return FutureUtils.toSingleFutureGeneric(channelService.sendEmbedTemplateInChannel(STARSTATS_RESPONSE_TEMPLATE, result, commandContext.getChannel()))
|
||||
.thenApply(aVoid -> CommandResult.fromSuccess());
|
||||
return starboardService.retrieveStarStats(commandContext.getGuild().getIdLong())
|
||||
.thenCompose(starStatsModel ->
|
||||
FutureUtils.toSingleFutureGeneric(channelService.sendEmbedTemplateInChannel(STARSTATS_RESPONSE_TEMPLATE, starStatsModel, commandContext.getChannel()))
|
||||
).thenApply(o -> CommandResult.fromSuccess());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -47,7 +47,7 @@ public class MessageEmbedListener implements MessageReceivedListener {
|
||||
continue;
|
||||
}
|
||||
messageRaw = messageRaw.replace(messageEmbedLink.getWholeUrl(), "");
|
||||
Consumer<CachedMessage> cachedMessageConsumer = cachedMessage ->self.loadUserAndEmbed(message, userEmbeddingUserInServerId, cachedMessage);
|
||||
Consumer<CachedMessage> cachedMessageConsumer = cachedMessage -> self.embedSingleLink(message, userEmbeddingUserInServerId, cachedMessage);
|
||||
messageCache.getMessageFromCache(messageEmbedLink.getServerId(), messageEmbedLink.getChannelId(), messageEmbedLink.getMessageId())
|
||||
.thenAccept(cachedMessageConsumer)
|
||||
.exceptionally(throwable -> {
|
||||
@@ -62,10 +62,14 @@ public class MessageEmbedListener implements MessageReceivedListener {
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void loadUserAndEmbed(Message message, Long cause, CachedMessage cachedMessage) {
|
||||
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);
|
||||
messageEmbedService.embedLink(cachedMessage, message.getTextChannel(), cause , message).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
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package dev.sheldan.abstracto.utility.repository;
|
||||
|
||||
public interface StarStatsUserResult {
|
||||
// this is the User in Server Id
|
||||
Long getUserId();
|
||||
Integer getStarCount();
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
package dev.sheldan.abstracto.utility.repository.converter;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.database.AUser;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.core.service.BotService;
|
||||
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
||||
import dev.sheldan.abstracto.utility.models.template.commands.starboard.StarStatsUser;
|
||||
import dev.sheldan.abstracto.utility.repository.StarStatsUserResult;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -9,6 +11,7 @@ import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Component
|
||||
public class StarStatsUserConverter {
|
||||
@@ -16,17 +19,26 @@ public class StarStatsUserConverter {
|
||||
@Autowired
|
||||
private BotService botService;
|
||||
|
||||
public List<StarStatsUser> convertToStarStatsUser(List<StarStatsUserResult> users, Long serverId) {
|
||||
List<StarStatsUser> result = new ArrayList<>();
|
||||
users.forEach(starStatsUserResult -> {
|
||||
StarStatsUser newUser = StarStatsUser
|
||||
.builder()
|
||||
.starCount(starStatsUserResult.getStarCount())
|
||||
.member(botService.getMemberInServer(serverId, starStatsUserResult.getUserId()))
|
||||
.user(AUser.builder().id(starStatsUserResult.getUserId()).build())
|
||||
.build();
|
||||
result.add(newUser);
|
||||
});
|
||||
@Autowired
|
||||
private UserInServerManagementService userInServerManagementService;
|
||||
|
||||
public List<CompletableFuture<StarStatsUser>> convertToStarStatsUser(List<StarStatsUserResult> users, Long serverId) {
|
||||
List<CompletableFuture<StarStatsUser>> result = new ArrayList<>();
|
||||
users.forEach(starStatsUserResult ->
|
||||
result.add(createStarStatsUser(serverId, starStatsUserResult))
|
||||
);
|
||||
return result;
|
||||
}
|
||||
|
||||
private CompletableFuture<StarStatsUser> createStarStatsUser(Long serverId, StarStatsUserResult starStatsUserResult) {
|
||||
AUserInAServer aUserInAServer = userInServerManagementService.loadUser(starStatsUserResult.getUserId());
|
||||
return botService.getMemberInServerAsync(serverId, aUserInAServer.getUserReference().getId()).thenApply(member ->
|
||||
StarStatsUser
|
||||
.builder()
|
||||
.starCount(starStatsUserResult.getStarCount())
|
||||
.member(member)
|
||||
.user(AUser.builder().id(starStatsUserResult.getUserId()).build())
|
||||
.build()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.CompletionStage;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@@ -60,7 +60,7 @@ public class MessageEmbedServiceBean implements MessageEmbedService {
|
||||
private ChannelService channelService;
|
||||
|
||||
@Autowired
|
||||
private MessageEmbedService self;
|
||||
private MessageEmbedServiceBean self;
|
||||
|
||||
@Autowired
|
||||
private MessageCache messageCache;
|
||||
@@ -102,7 +102,7 @@ public class MessageEmbedServiceBean implements MessageEmbedService {
|
||||
.thenAccept(cachedMessage -> self.embedLink(cachedMessage, target, userEmbeddingUserInServerId, embeddingMessage)
|
||||
|
||||
).exceptionally(throwable -> {
|
||||
log.error("Message retrieval from cache failed for message {}.", messageEmbedLink.getMessageId(), throwable);
|
||||
log.error("Message embedding from cache failed for message {}.", messageEmbedLink.getMessageId(), throwable);
|
||||
return null;
|
||||
})
|
||||
);
|
||||
@@ -110,42 +110,50 @@ public class MessageEmbedServiceBean implements MessageEmbedService {
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void embedLink(CachedMessage cachedMessage, TextChannel target, Long userEmbeddingUserInServerId, Message embeddingMessage) {
|
||||
public CompletableFuture<Void> embedLink(CachedMessage cachedMessage, TextChannel target, Long userEmbeddingUserInServerId, Message embeddingMessage) {
|
||||
Optional<AUserInAServer> causeOpt = userInServerManagementService.loadUserConditional(userEmbeddingUserInServerId);
|
||||
if(causeOpt.isPresent()) {
|
||||
AUserInAServer cause = causeOpt.get();
|
||||
MessageEmbeddedModel messageEmbeddedModel = buildTemplateParameter(embeddingMessage, cachedMessage);
|
||||
MessageToSend embed = templateService.renderEmbedTemplate(MESSAGE_EMBED_TEMPLATE, messageEmbeddedModel);
|
||||
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());
|
||||
Long userInServerId = cause.getUserInServerId();
|
||||
CompletableFuture.allOf(completableFutures.toArray(new CompletableFuture[0])).thenAccept(aVoid -> {
|
||||
try {
|
||||
Message createdMessage = completableFutures.get(0).get();
|
||||
Optional<AUserInAServer> innerCauseOpt = userInServerManagementService.loadUserConditional(userInServerId);
|
||||
innerCauseOpt.ifPresent(aUserInAServer -> {
|
||||
messageEmbedPostManagementService.createMessageEmbed(cachedMessage, createdMessage, aUserInAServer);
|
||||
messageService.addReactionToMessage(REMOVAL_EMOTE, cachedMessage.getServerId(), createdMessage);
|
||||
});
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
log.error("Failed to post message embed.", e);
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}).exceptionally(throwable -> {
|
||||
log.error("Failed to send message for embedding the link for message {} in channel {} in server {}",
|
||||
cachedMessage.getMessageId(), cachedMessage.getChannelId(), cachedMessage.getServerId(), throwable);
|
||||
return null;
|
||||
});
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
private MessageEmbeddedModel buildTemplateParameter(Message message, CachedMessage embeddedMessage) {
|
||||
@Transactional
|
||||
public CompletionStage<Void> sendEmbeddingMessage(CachedMessage cachedMessage, TextChannel target, Long userEmbeddingUserInServerId, MessageEmbeddedModel messageEmbeddedModel) {
|
||||
MessageToSend embed = templateService.renderEmbedTemplate(MESSAGE_EMBED_TEMPLATE, messageEmbeddedModel);
|
||||
AUserInAServer cause = userInServerManagementService.loadUser(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());
|
||||
Long userInServerId = cause.getUserInServerId();
|
||||
return CompletableFuture.allOf(completableFutures.toArray(new CompletableFuture[0])).thenCompose(aVoid -> {
|
||||
Message createdMessage = completableFutures.get(0).join();
|
||||
return messageService.addReactionToMessageWithFuture(REMOVAL_EMOTE, cachedMessage.getServerId(), createdMessage).thenAccept(aVoid1 ->
|
||||
self.loadUserAndPersistMessage(cachedMessage, userInServerId, createdMessage)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void loadUserAndPersistMessage(CachedMessage cachedMessage, Long userInServerId, Message createdMessage) {
|
||||
AUserInAServer innerCause = userInServerManagementService.loadUser(userInServerId);
|
||||
messageEmbedPostManagementService.createMessageEmbed(cachedMessage, createdMessage, innerCause);
|
||||
}
|
||||
|
||||
private CompletableFuture<MessageEmbeddedModel> buildTemplateParameter(Message message, CachedMessage embeddedMessage) {
|
||||
return botService.getMemberInServerAsync(embeddedMessage.getServerId(), embeddedMessage.getAuthorId()).thenApply(member ->
|
||||
self.loadMessageEmbedModel(message, embeddedMessage, member)
|
||||
);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public MessageEmbeddedModel loadMessageEmbedModel(Message message, CachedMessage embeddedMessage, Member member) {
|
||||
AServer server = serverManagementService.loadOrCreate(message.getGuild().getIdLong());
|
||||
AUserInAServer user = userInServerManagementService.loadUser(message.getMember());
|
||||
Member author = botService.getMemberInServer(embeddedMessage.getServerId(), embeddedMessage.getAuthorId());
|
||||
Optional<TextChannel> textChannelFromServer = botService.getTextChannelFromServerOptional(embeddedMessage.getServerId(), embeddedMessage.getChannelId());
|
||||
TextChannel sourceChannel = textChannelFromServer.orElse(null);
|
||||
AChannel channel = channelManagementService.loadChannel(message.getChannel().getIdLong());
|
||||
@@ -155,7 +163,7 @@ public class MessageEmbedServiceBean implements MessageEmbedService {
|
||||
.server(server)
|
||||
.member(message.getMember())
|
||||
.aUserInAServer(user)
|
||||
.author(author)
|
||||
.author(member)
|
||||
.sourceChannel(sourceChannel)
|
||||
.embeddingUser(message.getMember())
|
||||
.user(user.getUserReference())
|
||||
|
||||
@@ -5,8 +5,8 @@ import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
|
||||
import dev.sheldan.abstracto.core.models.AServerAChannelAUser;
|
||||
import dev.sheldan.abstracto.core.models.database.AChannel;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.core.models.database.AUser;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.core.utils.FutureUtils;
|
||||
import dev.sheldan.abstracto.templating.model.MessageToSend;
|
||||
import dev.sheldan.abstracto.core.service.BotService;
|
||||
import dev.sheldan.abstracto.scheduling.service.SchedulerService;
|
||||
@@ -36,6 +36,7 @@ import java.util.concurrent.*;
|
||||
@Slf4j
|
||||
public class RemindServiceBean implements ReminderService {
|
||||
|
||||
public static final String REMINDER_TEMPLATE_TEXT = "remind_reminder";
|
||||
@Autowired
|
||||
private ReminderManagementService reminderManagementService;
|
||||
|
||||
@@ -52,7 +53,7 @@ public class RemindServiceBean implements ReminderService {
|
||||
private BotService botService;
|
||||
|
||||
@Autowired
|
||||
private ReminderService self;
|
||||
private RemindServiceBean self;
|
||||
|
||||
@Autowired
|
||||
private ChannelService channelService;
|
||||
@@ -61,6 +62,7 @@ public class RemindServiceBean implements ReminderService {
|
||||
@Qualifier("reminderScheduler")
|
||||
private ScheduledExecutorService instantReminderScheduler;
|
||||
|
||||
|
||||
@Override
|
||||
public Reminder createReminderInForUser(AUserInAServer user, String remindText, Duration remindIn, Message message) {
|
||||
AChannel channel = channelManagementService.loadChannel(message.getChannel().getIdLong());
|
||||
@@ -99,7 +101,7 @@ public class RemindServiceBean implements ReminderService {
|
||||
@Override
|
||||
@Transactional
|
||||
public void executeReminder(Long reminderId) {
|
||||
Reminder reminderToRemindFor = reminderManagementService.loadReminder(reminderId).orElseThrow(() -> new ReminderNotFoundException(reminderId));
|
||||
Reminder reminderToRemindFor = reminderManagementService.loadReminder(reminderId);
|
||||
if(reminderToRemindFor.isReminded()) {
|
||||
return;
|
||||
}
|
||||
@@ -107,22 +109,15 @@ public class RemindServiceBean implements ReminderService {
|
||||
AChannel channel = reminderToRemindFor.getChannel();
|
||||
log.info("Executing reminder {} in channel {} in server {} for user {}.",
|
||||
reminderId, channel.getId(), server.getId(), reminderToRemindFor.getRemindedUser().getUserReference().getId());
|
||||
Optional<Guild> guildToAnswerIn = botService.getGuildById(server.getId());
|
||||
Optional<Guild> guildToAnswerIn = botService.getGuildByIdOptional(server.getId());
|
||||
if(guildToAnswerIn.isPresent()) {
|
||||
Optional<TextChannel> channelToAnswerIn = botService.getTextChannelFromServerOptional(server.getId(), channel.getId());
|
||||
// only send the message if the channel still exists, if not, only set the reminder to reminded.
|
||||
if(channelToAnswerIn.isPresent()) {
|
||||
AUser userReference = reminderToRemindFor.getRemindedUser().getUserReference();
|
||||
Member memberInServer = botService.getMemberInServer(server.getId(), userReference.getId());
|
||||
log.trace("Reminding user {}", userReference.getId());
|
||||
ExecutedReminderModel build = ExecutedReminderModel
|
||||
.builder()
|
||||
.reminder(reminderToRemindFor)
|
||||
.member(memberInServer)
|
||||
.duration(Duration.between(reminderToRemindFor.getReminderDate(), reminderToRemindFor.getTargetDate()))
|
||||
.build();
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate("remind_reminder", build);
|
||||
channelService.sendMessageToSendToChannel(messageToSend, channelToAnswerIn.get());
|
||||
botService.getMemberInServerAsync(server.getId(), reminderToRemindFor.getRemindedUser().getUserReference().getId()).thenAccept(member ->
|
||||
self.sendReminderText(reminderId, channelToAnswerIn.get(), member)
|
||||
);
|
||||
|
||||
} else {
|
||||
log.warn("Channel {} in server {} to remind user did not exist anymore. Ignoring reminder {}", channel.getId(), server.getId(), reminderId);
|
||||
}
|
||||
@@ -132,6 +127,20 @@ public class RemindServiceBean implements ReminderService {
|
||||
reminderManagementService.setReminded(reminderToRemindFor);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public CompletableFuture<Void> sendReminderText(Long reminderId, TextChannel channelToAnswerIn, Member member) {
|
||||
Reminder reminder = reminderManagementService.loadReminder(reminderId);
|
||||
log.trace("Sending remind message for reminder {} to user user {} in server {}.", reminderId, member.getIdLong(), member.getGuild().getIdLong());
|
||||
ExecutedReminderModel build = ExecutedReminderModel
|
||||
.builder()
|
||||
.reminder(reminder)
|
||||
.member(member)
|
||||
.duration(Duration.between(reminder.getReminderDate(), reminder.getTargetDate()))
|
||||
.build();
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate(REMINDER_TEMPLATE_TEXT, build);
|
||||
return FutureUtils.toSingleFutureGeneric(channelService.sendMessageToSendToChannel(messageToSend, channelToAnswerIn));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unRemind(Long reminderId, AUserInAServer aUserInAServer) {
|
||||
log.info("Trying to end reminder {} for user {} in server {}.", reminderId, aUserInAServer.getUserReference().getId(),aUserInAServer.getServerReference().getId());
|
||||
|
||||
@@ -8,6 +8,7 @@ import dev.sheldan.abstracto.core.models.AServerAChannelMessage;
|
||||
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
|
||||
import dev.sheldan.abstracto.core.models.database.*;
|
||||
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
||||
import dev.sheldan.abstracto.core.utils.FutureUtils;
|
||||
import dev.sheldan.abstracto.templating.model.MessageToSend;
|
||||
import dev.sheldan.abstracto.core.service.BotService;
|
||||
import dev.sheldan.abstracto.core.service.ConfigService;
|
||||
@@ -32,6 +33,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.CompletionStage;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
@@ -80,22 +82,24 @@ public class StarboardServiceBean implements StarboardService {
|
||||
private StarboardServiceBean self;
|
||||
|
||||
@Override
|
||||
public void createStarboardPost(CachedMessage message, List<AUserInAServer> userExceptAuthor, AUserInAServer userReacting, AUserInAServer starredUser) {
|
||||
StarboardPostModel starboardPostModel = buildStarboardPostModel(message, userExceptAuthor.size());
|
||||
List<Long> userExceptAuthorIds = new ArrayList<>();
|
||||
userExceptAuthor.forEach(aUserInAServer -> userExceptAuthorIds.add(aUserInAServer.getUserInServerId()));
|
||||
public CompletableFuture<Void> createStarboardPost(CachedMessage message, List<AUserInAServer> userExceptAuthor, AUserInAServer userReacting, AUserInAServer starredUser) {
|
||||
Long starredUserId = starredUser.getUserInServerId();
|
||||
List<Long> userExceptAuthorIds = userExceptAuthor.stream().map(AUserInAServer::getUserInServerId).collect(Collectors.toList());
|
||||
return buildStarboardPostModel(message, userExceptAuthor.size()).thenCompose(starboardPostModel ->
|
||||
self.sendStarboardPostAndStore(message, starredUserId, userExceptAuthorIds, starboardPostModel)
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public CompletionStage<Void> sendStarboardPostAndStore(CachedMessage message, Long starredUserId, List<Long> userExceptAuthorIds, StarboardPostModel starboardPostModel) {
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate(STARBOARD_POST_TEMPLATE, starboardPostModel);
|
||||
PostTarget starboard = postTargetManagement.getPostTarget(StarboardPostTarget.STARBOARD.getKey(), message.getServerId());
|
||||
List<CompletableFuture<Message>> completableFutures = postTargetService.sendEmbedInPostTarget(messageToSend, StarboardPostTarget.STARBOARD, message.getServerId());
|
||||
Long starboardChannelId = starboard.getChannelReference().getId();
|
||||
Long starredUserId = starredUser.getUserInServerId();
|
||||
CompletableFuture.allOf(completableFutures.toArray(new CompletableFuture[0])).thenAccept(aVoid ->
|
||||
self.persistPost(message, userExceptAuthorIds, completableFutures, starboardChannelId, starredUserId)
|
||||
) .exceptionally(throwable -> {
|
||||
log.error("Failed to create starboard post for message {} in channel {} in server {}", message.getMessageId(), message.getChannelId(), message.getServerId(), throwable);
|
||||
return null;
|
||||
});
|
||||
|
||||
return CompletableFuture.allOf(completableFutures.toArray(new CompletableFuture[0])).thenAccept(aVoid ->
|
||||
self.persistPost(message, userExceptAuthorIds, completableFutures, starboardChannelId, starredUserId)
|
||||
);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@@ -120,41 +124,41 @@ public class StarboardServiceBean implements StarboardService {
|
||||
});
|
||||
}
|
||||
|
||||
private StarboardPostModel buildStarboardPostModel(CachedMessage message, Integer starCount) {
|
||||
Member member = botService.getMemberInServer(message.getServerId(), message.getAuthorId());
|
||||
Optional<TextChannel> channel = botService.getTextChannelFromServerOptional(message.getServerId(), message.getChannelId());
|
||||
Optional<Guild> guild = botService.getGuildById(message.getServerId());
|
||||
AChannel aChannel = AChannel.builder().id(message.getChannelId()).build();
|
||||
AUser user = AUser.builder().id(message.getAuthorId()).build();
|
||||
AServer server = AServer.builder().id(message.getServerId()).build();
|
||||
String starLevelEmote = getAppropriateEmote(message.getServerId(), starCount);
|
||||
return StarboardPostModel
|
||||
.builder()
|
||||
.message(message)
|
||||
.author(member)
|
||||
.channel(channel.orElse(null))
|
||||
.aChannel(aChannel)
|
||||
.starCount(starCount)
|
||||
.guild(guild.orElse(null))
|
||||
.user(user)
|
||||
.server(server)
|
||||
.starLevelEmote(starLevelEmote)
|
||||
.build();
|
||||
private CompletableFuture<StarboardPostModel> buildStarboardPostModel(CachedMessage message, Integer starCount) {
|
||||
return botService.getMemberInServerAsync(message.getServerId(), message.getAuthorId()).thenApply(member -> {
|
||||
Optional<TextChannel> channel = botService.getTextChannelFromServerOptional(message.getServerId(), message.getChannelId());
|
||||
Optional<Guild> guild = botService.getGuildByIdOptional(message.getServerId());
|
||||
AChannel aChannel = AChannel.builder().id(message.getChannelId()).build();
|
||||
AUser user = AUser.builder().id(message.getAuthorId()).build();
|
||||
AServer server = AServer.builder().id(message.getServerId()).build();
|
||||
String starLevelEmote = getAppropriateEmote(message.getServerId(), starCount);
|
||||
return StarboardPostModel
|
||||
.builder()
|
||||
.message(message)
|
||||
.author(member)
|
||||
.channel(channel.orElse(null))
|
||||
.aChannel(aChannel)
|
||||
.starCount(starCount)
|
||||
.guild(guild.orElse(null))
|
||||
.user(user)
|
||||
.server(server)
|
||||
.starLevelEmote(starLevelEmote)
|
||||
.build();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateStarboardPost(StarboardPost post, CachedMessage message, List<AUserInAServer> userExceptAuthor) {
|
||||
log.info("Updating starboard post {} in server {} with reactors {}.", post.getId(), post.getSourceChanel().getServer().getId(), userExceptAuthor.size());
|
||||
StarboardPostModel starboardPostModel = buildStarboardPostModel(message, userExceptAuthor.size());
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate(STARBOARD_POST_TEMPLATE, starboardPostModel);
|
||||
List<CompletableFuture<Message>> futures = postTargetService.editOrCreatedInPostTarget(post.getStarboardMessageId(), messageToSend, StarboardPostTarget.STARBOARD, message.getServerId());
|
||||
Long starboardPostId = post.getId();
|
||||
CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).thenAccept(aVoid -> {
|
||||
Optional<StarboardPost> innerPost = starboardPostManagementService.findByStarboardPostId(starboardPostId);
|
||||
innerPost.ifPresent(starboardPost -> starboardPostManagementService.setStarboardPostMessageId(starboardPost, futures.get(0).join().getIdLong()));
|
||||
}).exceptionally(throwable -> {
|
||||
log.error("Failed to update starboard post {}.", post.getId(), throwable);
|
||||
return null;
|
||||
public CompletableFuture<Void> updateStarboardPost(StarboardPost post, CachedMessage message, List<AUserInAServer> userExceptAuthor) {
|
||||
int starCount = userExceptAuthor.size();
|
||||
log.info("Updating starboard post {} in server {} with reactors {}.", post.getId(), post.getSourceChanel().getServer().getId(), starCount);
|
||||
return buildStarboardPostModel(message, starCount).thenCompose(starboardPostModel -> {
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate(STARBOARD_POST_TEMPLATE, starboardPostModel);
|
||||
List<CompletableFuture<Message>> futures = postTargetService.editOrCreatedInPostTarget(post.getStarboardMessageId(), messageToSend, StarboardPostTarget.STARBOARD, message.getServerId());
|
||||
Long starboardPostId = post.getId();
|
||||
return CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).thenAccept(aVoid -> {
|
||||
Optional<StarboardPost> innerPost = starboardPostManagementService.findByStarboardPostId(starboardPostId);
|
||||
innerPost.ifPresent(starboardPost -> starboardPostManagementService.setStarboardPostMessageId(starboardPost, futures.get(0).join().getIdLong()));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -166,28 +170,35 @@ public class StarboardServiceBean implements StarboardService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public StarStatsModel retrieveStarStats(Long serverId) {
|
||||
public CompletableFuture<StarStatsModel> retrieveStarStats(Long serverId) {
|
||||
int count = 3;
|
||||
List<StarboardPost> starboardPosts = starboardPostManagementService.retrieveTopPosts(serverId, count);
|
||||
List<StarStatsUser> topStarGivers = starboardPostReactorManagementService.retrieveTopStarGiver(serverId, count);
|
||||
List<StarStatsPost> starStatsPosts = starboardPosts.stream().map(this::fromStarboardPost).collect(Collectors.toList());
|
||||
List<StarStatsUser> topStarReceiver = starboardPostReactorManagementService.retrieveTopStarReceiver(serverId, count);
|
||||
Integer postCount = starboardPostManagementService.getPostCount(serverId);
|
||||
Integer reactionCount = starboardPostReactorManagementService.getStarCount(serverId);
|
||||
List<String> emotes = new ArrayList<>();
|
||||
for (int i = 1; i < count + 1; i++) {
|
||||
emotes.add(getStarboardRankingEmote(serverId, i));
|
||||
}
|
||||
List<CompletableFuture<StarStatsUser>> topStarGiverFutures = starboardPostReactorManagementService.retrieveTopStarGiver(serverId, count);
|
||||
List<CompletableFuture<StarStatsUser>> topStarReceiverFutures = starboardPostReactorManagementService.retrieveTopStarReceiver(serverId, count);
|
||||
List<CompletableFuture> allFutures = new ArrayList<>();
|
||||
allFutures.addAll(topStarGiverFutures);
|
||||
allFutures.addAll(topStarReceiverFutures);
|
||||
return FutureUtils.toSingleFuture(allFutures).thenApply(aVoid -> {
|
||||
List<StarboardPost> starboardPosts = starboardPostManagementService.retrieveTopPosts(serverId, count);
|
||||
List<StarStatsPost> starStatsPosts = starboardPosts.stream().map(this::fromStarboardPost).collect(Collectors.toList());
|
||||
Integer postCount = starboardPostManagementService.getPostCount(serverId);
|
||||
Integer reactionCount = starboardPostReactorManagementService.getStarCount(serverId);
|
||||
List<String> emotes = new ArrayList<>();
|
||||
for (int i = 1; i < count + 1; i++) {
|
||||
emotes.add(getStarboardRankingEmote(serverId, i));
|
||||
}
|
||||
List<StarStatsUser> topStarGivers = topStarGiverFutures.stream().map(CompletableFuture::join).collect(Collectors.toList());
|
||||
List<StarStatsUser> topStarReceiver = topStarReceiverFutures.stream().map(CompletableFuture::join).collect(Collectors.toList());
|
||||
return StarStatsModel
|
||||
.builder()
|
||||
.badgeEmotes(emotes)
|
||||
.starGiver(topStarGivers)
|
||||
.starReceiver(topStarReceiver)
|
||||
.topPosts(starStatsPosts)
|
||||
.starredMessages(postCount)
|
||||
.totalStars(reactionCount)
|
||||
.build();
|
||||
});
|
||||
|
||||
return StarStatsModel
|
||||
.builder()
|
||||
.badgeEmotes(emotes)
|
||||
.starGiver(topStarGivers)
|
||||
.starReceiver(topStarReceiver)
|
||||
.topPosts(starStatsPosts)
|
||||
.starredMessages(postCount)
|
||||
.totalStars(reactionCount)
|
||||
.build();
|
||||
}
|
||||
|
||||
public StarStatsPost fromStarboardPost(StarboardPost starboardPost) {
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
package dev.sheldan.abstracto.utility.service;
|
||||
|
||||
import dev.sheldan.abstracto.core.exception.ChannelNotFoundException;
|
||||
import dev.sheldan.abstracto.core.exception.GuildNotFoundException;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.core.service.CounterService;
|
||||
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
||||
import dev.sheldan.abstracto.core.utils.FutureUtils;
|
||||
import dev.sheldan.abstracto.templating.model.MessageToSend;
|
||||
import dev.sheldan.abstracto.core.service.BotService;
|
||||
import dev.sheldan.abstracto.core.service.MessageService;
|
||||
@@ -73,7 +72,7 @@ public class SuggestionServiceBean implements SuggestionService {
|
||||
long guildId = member.getGuild().getIdLong();
|
||||
log.info("Creating suggestion with id {} in server {} from member {}.", newSuggestionId, member.getGuild().getId(), member.getId());
|
||||
List<CompletableFuture<Message>> completableFutures = postTargetService.sendEmbedInPostTarget(messageToSend, SuggestionPostTarget.SUGGESTION, guildId);
|
||||
return CompletableFuture.allOf(completableFutures.toArray(new CompletableFuture[0])).thenCompose(aVoid -> {
|
||||
return FutureUtils.toSingleFutureGeneric(completableFutures).thenCompose(aVoid -> {
|
||||
Message message = completableFutures.get(0).join();
|
||||
log.trace("Posted message, adding reaction for suggestion {} to message {}.", newSuggestionId, message.getId());
|
||||
CompletableFuture<Void> firstReaction = messageService.addReactionToMessageWithFuture(SUGGESTION_YES_EMOTE, guildId, message);
|
||||
@@ -110,26 +109,22 @@ public class SuggestionServiceBean implements SuggestionService {
|
||||
suggestionLog.setOriginalMessageId(originalMessageId);
|
||||
suggestionLog.setOriginalMessageUrl(MessageUtils.buildMessageUrl(serverId, channelId, originalMessageId));
|
||||
AUserInAServer suggester = suggestion.getSuggester();
|
||||
Optional<Guild> guildByIdOptional = botService.getGuildById(serverId);
|
||||
if(guildByIdOptional.isPresent()) {
|
||||
Guild guildById = guildByIdOptional.get();
|
||||
Member memberById = guildById.getMemberById(suggester.getUserReference().getId());
|
||||
suggestionLog.setSuggester(memberById);
|
||||
suggestionLog.setState(suggestion.getState());
|
||||
suggestionLog.setSuggestionId(suggestion.getId());
|
||||
TextChannel textChannelById = guildById.getTextChannelById(channelId);
|
||||
if(textChannelById != null) {
|
||||
return textChannelById.retrieveMessageById(originalMessageId).submit().thenCompose(message ->
|
||||
self.updateSuggestionMessageText(text, suggestionLog, message)
|
||||
);
|
||||
} else {
|
||||
log.warn("Not possible to update suggestion {}, because text channel {} was not found in guild {}.", suggestion.getId(), channelId, serverId);
|
||||
throw new ChannelNotFoundException(channelId);
|
||||
TextChannel textChannelById = botService.getTextChannelFromServer(serverId, channelId);
|
||||
CompletableFuture<Member> memberById = botService.getMemberInServerAsync(serverId, suggester.getUserReference().getId());
|
||||
suggestionLog.setState(suggestion.getState());
|
||||
suggestionLog.setSuggestionId(suggestion.getId());
|
||||
CompletableFuture<Void> finalFuture = new CompletableFuture<>();
|
||||
memberById.whenComplete((member, throwable) -> {
|
||||
if(throwable == null) {
|
||||
suggestionLog.setSuggester(member);
|
||||
}
|
||||
} else {
|
||||
log.warn("Not possible to update suggestion {}, because guild {} was not found.", suggestion.getId(), serverId);
|
||||
throw new GuildNotFoundException(serverId);
|
||||
}
|
||||
textChannelById.retrieveMessageById(originalMessageId).submit().thenCompose(message ->
|
||||
self.updateSuggestionMessageText(text, suggestionLog, message)
|
||||
).thenAccept(aVoid -> finalFuture.complete(null));
|
||||
});
|
||||
|
||||
return finalFuture;
|
||||
|
||||
}
|
||||
|
||||
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
||||
|
||||
@@ -2,6 +2,7 @@ package dev.sheldan.abstracto.utility.service.management;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.AServerAChannelAUser;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.utility.exception.ReminderNotFoundException;
|
||||
import dev.sheldan.abstracto.utility.models.database.Reminder;
|
||||
import dev.sheldan.abstracto.utility.repository.ReminderRepository;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -39,10 +40,15 @@ public class ReminderManagementServiceBean implements ReminderManagementService
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Reminder> loadReminder(Long reminderId) {
|
||||
public Optional<Reminder> loadReminderOptional(Long reminderId) {
|
||||
return reminderRepository.findById(reminderId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Reminder loadReminder(Long reminderId) {
|
||||
return loadReminderOptional(reminderId).orElseThrow(() -> new ReminderNotFoundException(reminderId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setReminded(Reminder reminder) {
|
||||
reminder.setReminded(true);
|
||||
|
||||
@@ -12,6 +12,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
@@ -52,13 +53,13 @@ public class StarboardPostReactorManagementServiceBean implements StarboardPostR
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<StarStatsUser> retrieveTopStarGiver(Long serverId, Integer count) {
|
||||
public List<CompletableFuture<StarStatsUser>> retrieveTopStarGiver(Long serverId, Integer count) {
|
||||
List<StarStatsUserResult> starGivers = repository.findTopStarGiverInServer(serverId, count);
|
||||
return converter.convertToStarStatsUser(starGivers, serverId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<StarStatsUser> retrieveTopStarReceiver(Long serverId, Integer count) {
|
||||
public List<CompletableFuture<StarStatsUser>> retrieveTopStarReceiver(Long serverId, Integer count) {
|
||||
List<StarStatsUserResult> starReceivers = repository.retrieveTopStarReceiverInServer(serverId, count);
|
||||
return converter.convertToStarStatsUser(starReceivers, serverId);
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ public class StarStatsTest {
|
||||
CommandContext noParameters = CommandTestUtilities.getNoParameters();
|
||||
when(noParameters.getGuild().getIdLong()).thenReturn(noParameters.getUserInitiatedContext().getChannel().getId());
|
||||
StarStatsModel starStatsModel = StarStatsModel.builder().build();
|
||||
when(starboardService.retrieveStarStats(noParameters.getGuild().getIdLong())).thenReturn(starStatsModel);
|
||||
when(starboardService.retrieveStarStats(noParameters.getGuild().getIdLong())).thenReturn(CompletableFuture.completedFuture(starStatsModel));
|
||||
CompletableFuture<CommandResult> result = testUnit.executeAsync(noParameters);
|
||||
verify(channelService, times(1)).sendEmbedTemplateInChannel(StarStats.STARSTATS_RESPONSE_TEMPLATE, starStatsModel, noParameters.getChannel());
|
||||
CommandTestUtilities.checkSuccessfulCompletionAsync(result);
|
||||
|
||||
@@ -83,7 +83,7 @@ public class MessageEmbedListenerTest {
|
||||
String linkText = "link";
|
||||
String text = linkText;
|
||||
executeLinkTestForOneLink(text, linkText, ORIGIN_GUILD_ID, ORIGIN_GUILD_ID);
|
||||
verify(self, times(1)).loadUserAndEmbed(eq(message), anyLong(), any(CachedMessage.class));
|
||||
verify(self, times(1)).embedSingleLink(eq(message), anyLong(), any(CachedMessage.class));
|
||||
verify(message, times(1)).delete();
|
||||
verify(deletionRestAction, times(1)).queue();
|
||||
}
|
||||
@@ -93,7 +93,7 @@ public class MessageEmbedListenerTest {
|
||||
String linkText = "link";
|
||||
String text = linkText + "more text";
|
||||
executeLinkTestForOneLink(text, linkText, ORIGIN_GUILD_ID, ORIGIN_GUILD_ID);
|
||||
verify(self, times(1)).loadUserAndEmbed(eq(message), anyLong(), any(CachedMessage.class));
|
||||
verify(self, times(1)).embedSingleLink(eq(message), anyLong(), any(CachedMessage.class));
|
||||
verify(message, times(0)).delete();
|
||||
verify(deletionRestAction, times(0)).queue();
|
||||
}
|
||||
@@ -105,7 +105,7 @@ public class MessageEmbedListenerTest {
|
||||
executeLinkTestForOneLink(text, linkText, ORIGIN_GUILD_ID, EMBEDDING_GUILD_ID);
|
||||
verify(message, times(0)).delete();
|
||||
verify(deletionRestAction, times(0)).queue();
|
||||
verify(self, times(0)).loadUserAndEmbed(eq(message), anyLong(), any(CachedMessage.class));
|
||||
verify(self, times(0)).embedSingleLink(eq(message), anyLong(), any(CachedMessage.class));
|
||||
verify(messageCache, times(0)).getMessageFromCache(anyLong(), anyLong(), anyLong());
|
||||
}
|
||||
|
||||
@@ -149,7 +149,7 @@ public class MessageEmbedListenerTest {
|
||||
testUnit.execute(message);
|
||||
verify(message, times(0)).delete();
|
||||
verify(deletionRestAction, times(0)).queue();
|
||||
verify(self, times(1)).loadUserAndEmbed(message, embeddingUser.getUserInServerId(), cachedMessage);
|
||||
verify(self, times(1)).embedSingleLink(message, embeddingUser.getUserInServerId(), cachedMessage);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -189,8 +189,8 @@ public class MessageEmbedListenerTest {
|
||||
testUnit.execute(message);
|
||||
verify(message, times(1)).delete();
|
||||
verify(deletionRestAction, times(1)).queue();
|
||||
verify(self, times(1)).loadUserAndEmbed(message, userInAServer.getUserInServerId(), cachedMessage);
|
||||
verify(self, times(1)).loadUserAndEmbed(message, userInAServer.getUserInServerId(), secondCachedMessage);
|
||||
verify(self, times(1)).embedSingleLink(message, userInAServer.getUserInServerId(), cachedMessage);
|
||||
verify(self, times(1)).embedSingleLink(message, userInAServer.getUserInServerId(), secondCachedMessage);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -198,8 +198,8 @@ public class MessageEmbedListenerTest {
|
||||
CachedMessage cachedMessage = CachedMessage.builder().build();
|
||||
long userId = 3L;
|
||||
when(message.getTextChannel()).thenReturn(textChannel);
|
||||
testUnit.loadUserAndEmbed(message, userId, cachedMessage);
|
||||
verify(messageEmbedService, times(1)).embedLink(cachedMessage, textChannel, userId, message);
|
||||
when(messageEmbedService.embedLink(cachedMessage, textChannel, userId, message)).thenReturn(CompletableFuture.completedFuture(null));
|
||||
testUnit.embedSingleLink(message, userId, cachedMessage);
|
||||
}
|
||||
|
||||
private void executeLinkTestForOneLink(String text, String linkText, Long originServerId, Long embeddingServerId) {
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
package dev.sheldan.abstracto.utility.repository.converter;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.database.AUser;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.core.service.BotService;
|
||||
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
||||
import dev.sheldan.abstracto.utility.models.template.commands.starboard.StarStatsUser;
|
||||
import dev.sheldan.abstracto.utility.repository.StarStatsUserResult;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
@@ -14,6 +17,7 @@ import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@@ -26,6 +30,8 @@ public class StarStatsUserConverterTest {
|
||||
@Mock
|
||||
private BotService botService;
|
||||
|
||||
@Mock
|
||||
private UserInServerManagementService userInServerManagementService;
|
||||
|
||||
@Test
|
||||
public void testConversionOfMultipleItems() {
|
||||
@@ -37,24 +43,34 @@ public class StarStatsUserConverterTest {
|
||||
List<StarStatsUserResult> results = new ArrayList<>();
|
||||
StarStatsUserResult firstResult = Mockito.mock(StarStatsUserResult.class);
|
||||
Member firstMember = Mockito.mock(Member.class);
|
||||
when(botService.getMemberInServer(serverId, firstUserId)).thenReturn(firstMember);
|
||||
AUserInAServer firstUser = Mockito.mock(AUserInAServer.class);
|
||||
AUser firstAUser = Mockito.mock(AUser.class);
|
||||
when(firstAUser.getId()).thenReturn(firstUserId);
|
||||
when(firstUser.getUserReference()).thenReturn(firstAUser);
|
||||
when(userInServerManagementService.loadUser(firstUserId)).thenReturn(firstUser);
|
||||
when(botService.getMemberInServerAsync(serverId, firstUserId)).thenReturn(CompletableFuture.completedFuture(firstMember));
|
||||
when(firstResult.getUserId()).thenReturn(firstUserId);
|
||||
when(firstResult.getStarCount()).thenReturn(firstStarCount);
|
||||
results.add(firstResult);
|
||||
StarStatsUserResult secondResult = Mockito.mock(StarStatsUserResult.class);
|
||||
Member secondMember = Mockito.mock(Member.class);
|
||||
when(botService.getMemberInServer(serverId, secondUserId)).thenReturn(secondMember);
|
||||
AUserInAServer secondUser = Mockito.mock(AUserInAServer.class);
|
||||
AUser secondAUser = Mockito.mock(AUser.class);
|
||||
when(secondAUser.getId()).thenReturn(secondUserId);
|
||||
when(secondUser.getUserReference()).thenReturn(secondAUser);
|
||||
when(userInServerManagementService.loadUser(secondUserId)).thenReturn(secondUser);
|
||||
when(botService.getMemberInServerAsync(serverId, secondUserId)).thenReturn(CompletableFuture.completedFuture(secondMember));
|
||||
|
||||
when(secondResult.getUserId()).thenReturn(secondUserId);
|
||||
when(secondResult.getStarCount()).thenReturn(secondStarCount);
|
||||
results.add(secondResult);
|
||||
|
||||
List<StarStatsUser> starStatsUsers = testUnit.convertToStarStatsUser(results, serverId);
|
||||
StarStatsUser firstConverted = starStatsUsers.get(0);
|
||||
List<CompletableFuture<StarStatsUser>> starStatsUsers = testUnit.convertToStarStatsUser(results, serverId);
|
||||
StarStatsUser firstConverted = starStatsUsers.get(0).join();
|
||||
Assert.assertEquals(firstStarCount, firstConverted.getStarCount());
|
||||
Assert.assertEquals(firstMember, firstConverted.getMember());
|
||||
Assert.assertEquals(firstUserId, firstConverted.getUser().getId());
|
||||
StarStatsUser secondConverted = starStatsUsers.get(1);
|
||||
StarStatsUser secondConverted = starStatsUsers.get(1).join();
|
||||
Assert.assertEquals(secondStarCount, secondConverted.getStarCount());
|
||||
Assert.assertEquals(secondMember, secondConverted.getMember());
|
||||
Assert.assertEquals(secondUserId, secondConverted.getUser().getId());
|
||||
@@ -66,7 +82,7 @@ public class StarStatsUserConverterTest {
|
||||
Long serverId = 5L;
|
||||
List<StarStatsUserResult> results = new ArrayList<>();
|
||||
|
||||
List<StarStatsUser> starStatsUsers = testUnit.convertToStarStatsUser(results, serverId);
|
||||
List<CompletableFuture<StarStatsUser>> starStatsUsers = testUnit.convertToStarStatsUser(results, serverId);
|
||||
verify(botService, times(0)).getMemberInServer(eq(serverId), anyLong());
|
||||
Assert.assertEquals(0, starStatsUsers.size());
|
||||
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package dev.sheldan.abstracto.utility.service;
|
||||
|
||||
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.models.template.listener.MessageEmbeddedModel;
|
||||
import dev.sheldan.abstracto.core.service.BotService;
|
||||
@@ -12,12 +10,9 @@ import dev.sheldan.abstracto.core.service.MessageService;
|
||||
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.templating.model.MessageToSend;
|
||||
import dev.sheldan.abstracto.templating.service.TemplateService;
|
||||
import dev.sheldan.abstracto.test.MockUtils;
|
||||
import dev.sheldan.abstracto.utility.models.MessageEmbedLink;
|
||||
import dev.sheldan.abstracto.utility.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;
|
||||
@@ -28,7 +23,6 @@ import org.mockito.*;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
@@ -60,7 +54,7 @@ public class MessageEmbedServiceBeanTest {
|
||||
private ChannelService channelService;
|
||||
|
||||
@Mock
|
||||
private MessageEmbedService self;
|
||||
private MessageEmbedServiceBean self;
|
||||
|
||||
@Mock
|
||||
private MessageCache messageCache;
|
||||
@@ -84,6 +78,16 @@ public class MessageEmbedServiceBeanTest {
|
||||
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 USER_ID = 9L;
|
||||
|
||||
@Mock
|
||||
private AUserInAServer embeddingUser;
|
||||
|
||||
@Mock
|
||||
private Member embeddingMember;
|
||||
|
||||
@Test
|
||||
public void testNoLinkInString(){
|
||||
String message = "test";
|
||||
@@ -182,38 +186,16 @@ public class MessageEmbedServiceBeanTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEmbeddingLink() {
|
||||
Long channelId = 6L;
|
||||
Long serverId = 4L;
|
||||
AServer server = MockUtils.getServer(serverId);
|
||||
AChannel aChannel = MockUtils.getTextChannel(server, channelId);
|
||||
Long userEmbeddingUserInServerId = 5L;
|
||||
AUserInAServer embeddingUser = MockUtils.getUserObject(userEmbeddingUserInServerId, server);
|
||||
Long authorId = 7L;
|
||||
AUserInAServer authorUser = MockUtils.getUserObject(authorId, server);
|
||||
Long firstMessageId = 6L;
|
||||
CachedMessage cachedMessage = CachedMessage.builder().serverId(serverId).channelId(channelId).messageId(firstMessageId).authorId(authorUser.getUserReference().getId()).build();
|
||||
Member embeddingMember = Mockito.mock(Member.class);
|
||||
Member author = Mockito.mock(Member.class);
|
||||
Guild guild = Mockito.mock(Guild.class);
|
||||
when(embeddingMessage.getMember()).thenReturn(embeddingMember);
|
||||
when(textChannel.getIdLong()).thenReturn(channelId);
|
||||
when(embeddingMessage.getGuild()).thenReturn(guild);
|
||||
when(guild.getIdLong()).thenReturn(serverId);
|
||||
when(embeddingMessage.getChannel()).thenReturn(textChannel);
|
||||
when(userInServerManagementService.loadUser(embeddingMember)).thenReturn(embeddingUser);
|
||||
when(userInServerManagementService.loadUserConditional(userEmbeddingUserInServerId)).thenReturn(Optional.of(embeddingUser));
|
||||
when(channelManagementService.loadChannel(channelId)).thenReturn(aChannel);
|
||||
when(serverManagementService.loadOrCreate(serverId)).thenReturn(server);
|
||||
when(botService.getMemberInServer(cachedMessage.getServerId(), cachedMessage.getAuthorId())).thenReturn(author);
|
||||
when(botService.getTextChannelFromServerOptional(cachedMessage.getServerId(), cachedMessage.getChannelId())).thenReturn(Optional.of(textChannel));
|
||||
MessageToSend messageToSend = MessageToSend.builder().build();
|
||||
when(templateService.renderEmbedTemplate(eq(MessageEmbedServiceBean.MESSAGE_EMBED_TEMPLATE), any(MessageEmbeddedModel.class))).thenReturn(messageToSend);
|
||||
Message messageContainingEmbed = Mockito.mock(Message.class);
|
||||
when(channelService.sendMessageToSendToChannel(messageToSend, textChannel)).thenReturn(Arrays.asList(CompletableFuture.completedFuture(messageContainingEmbed)));
|
||||
testUnit.embedLink(cachedMessage, textChannel, userEmbeddingUserInServerId, embeddingMessage);
|
||||
verify(messageEmbedPostManagementService, times(1)).createMessageEmbed(cachedMessage, messageContainingEmbed, embeddingUser);
|
||||
verify(messageService, times(1)).addReactionToMessage(MessageEmbedServiceBean.REMOVAL_EMOTE, cachedMessage.getServerId(), messageContainingEmbed);
|
||||
public void testLoadingEmbeddingModel() {
|
||||
CachedMessage cachedMessage = Mockito.mock(CachedMessage.class);
|
||||
when(cachedMessage.getServerId()).thenReturn(SERVER_ID);
|
||||
when(cachedMessage.getAuthorId()).thenReturn(USER_ID);
|
||||
when(userInServerManagementService.loadUserConditional(EMBEDDING_USER_IN_SERVER_ID)).thenReturn(Optional.of(embeddingUser));
|
||||
when(botService.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));
|
||||
testUnit.embedLink(cachedMessage, textChannel, EMBEDDING_USER_IN_SERVER_ID, embeddingMessage).join();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -14,7 +14,6 @@ import dev.sheldan.abstracto.templating.service.TemplateService;
|
||||
import dev.sheldan.abstracto.test.MockUtils;
|
||||
import dev.sheldan.abstracto.utility.exception.ReminderNotFoundException;
|
||||
import dev.sheldan.abstracto.utility.models.database.Reminder;
|
||||
import dev.sheldan.abstracto.utility.models.template.commands.reminder.ExecutedReminderModel;
|
||||
import dev.sheldan.abstracto.utility.service.management.ReminderManagementService;
|
||||
import net.dv8tion.jda.api.entities.Guild;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
@@ -32,10 +31,13 @@ import org.quartz.JobDataMap;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
|
||||
import static dev.sheldan.abstracto.utility.service.RemindServiceBean.REMINDER_TEMPLATE_TEXT;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
@@ -74,6 +76,8 @@ public class RemindServiceBeanTest {
|
||||
@Mock
|
||||
private ScheduledExecutorService instantReminderScheduler;
|
||||
|
||||
private static final Long REMINDER_ID = 5L;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
when(message.getIdLong()).thenReturn(5L);
|
||||
@@ -89,8 +93,7 @@ public class RemindServiceBeanTest {
|
||||
String remindText = "text";
|
||||
Duration duration = Duration.ofSeconds(62);
|
||||
when(channelManagementService.loadChannel(channel.getIdLong())).thenReturn(aChannel);
|
||||
Long reminderId = 5L;
|
||||
Reminder createdReminder = Reminder.builder().targetDate(Instant.now().plus(duration)).text(remindText).id(reminderId).build();
|
||||
Reminder createdReminder = Reminder.builder().targetDate(Instant.now().plus(duration)).text(remindText).id(REMINDER_ID).build();
|
||||
Long messageId = 5L;
|
||||
when(reminderManagementService.createReminder(any(AServerAChannelAUser.class), eq(remindText), any(Instant.class), eq(messageId))).thenReturn(createdReminder);
|
||||
String triggerKey = "trigger";
|
||||
@@ -111,8 +114,7 @@ public class RemindServiceBeanTest {
|
||||
String remindText = "text";
|
||||
Duration duration = Duration.ofSeconds(50);
|
||||
when(channelManagementService.loadChannel(channel.getIdLong())).thenReturn(aChannel);
|
||||
Long reminderId = 5L;
|
||||
Reminder createdReminder = Reminder.builder().targetDate(Instant.now().plus(duration)).text(remindText).id(reminderId).build();
|
||||
Reminder createdReminder = Reminder.builder().targetDate(Instant.now().plus(duration)).text(remindText).id(REMINDER_ID).build();
|
||||
Long messageId = 5L;
|
||||
when(reminderManagementService.createReminder(any(AServerAChannelAUser.class), eq(remindText), any(Instant.class), eq(messageId))).thenReturn(createdReminder);
|
||||
Reminder returnedReminder = testUnit.createReminderInForUser(user, remindText, duration, message);
|
||||
@@ -126,36 +128,31 @@ public class RemindServiceBeanTest {
|
||||
AServer server = MockUtils.getServer();
|
||||
AChannel aChannel = MockUtils.getTextChannel(server, 4L);
|
||||
AUserInAServer remindedUser = MockUtils.getUserObject(5L, server);
|
||||
Long reminderId = 5L;
|
||||
Reminder remindedReminder = Reminder.builder().reminded(false).remindedUser(remindedUser).reminderDate(Instant.now()).targetDate(Instant.now()).server(server).channel(aChannel).id(reminderId).build();
|
||||
when(reminderManagementService.loadReminder(reminderId)).thenReturn(Optional.of(remindedReminder));
|
||||
Reminder remindedReminder = Reminder.builder().reminded(false).remindedUser(remindedUser).reminderDate(Instant.now()).targetDate(Instant.now()).server(server).channel(aChannel).id(REMINDER_ID).build();
|
||||
when(reminderManagementService.loadReminder(REMINDER_ID)).thenReturn(remindedReminder);
|
||||
Guild guildMock = Mockito.mock(Guild.class);
|
||||
when(botService.getGuildById(server.getId())).thenReturn(Optional.of(guildMock));
|
||||
when(botService.getGuildByIdOptional(server.getId())).thenReturn(Optional.of(guildMock));
|
||||
when(botService.getTextChannelFromServerOptional(server.getId(), aChannel.getId())).thenReturn(Optional.of(channel));
|
||||
Member mockedMember = Mockito.mock(Member.class);
|
||||
when(botService.getMemberInServer(server.getId(), remindedUser.getUserReference().getId())).thenReturn(mockedMember);
|
||||
MessageToSend messageToSend = MessageToSend.builder().build();
|
||||
when(templateService.renderEmbedTemplate(eq("remind_reminder"), any(ExecutedReminderModel.class))).thenReturn(messageToSend);
|
||||
testUnit.executeReminder(reminderId);
|
||||
when(botService.getMemberInServerAsync(server.getId(), remindedUser.getUserReference().getId())).thenReturn(CompletableFuture.completedFuture(mockedMember));
|
||||
testUnit.executeReminder(REMINDER_ID);
|
||||
verify(reminderManagementService, times(1)).setReminded(remindedReminder);
|
||||
verify(channelService, times(1)).sendMessageToSendToChannel(messageToSend, channel);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExecuteReminderFromNotFoundChannel() {
|
||||
AServer server = MockUtils.getServer();
|
||||
AChannel aChannel = MockUtils.getTextChannel(server, 4L);
|
||||
Long reminderId = 5L;
|
||||
AUserInAServer remindedUser = Mockito.mock(AUserInAServer.class);
|
||||
AUser user = Mockito.mock(AUser.class);
|
||||
when(user.getId()).thenReturn(6L);
|
||||
when(remindedUser.getUserReference()).thenReturn(user);
|
||||
Reminder remindedReminder = Reminder.builder().reminded(false).server(server).remindedUser(remindedUser).channel(aChannel).id(reminderId).build();
|
||||
when(reminderManagementService.loadReminder(reminderId)).thenReturn(Optional.of(remindedReminder));
|
||||
Reminder remindedReminder = Reminder.builder().reminded(false).server(server).remindedUser(remindedUser).channel(aChannel).id(REMINDER_ID).build();
|
||||
when(reminderManagementService.loadReminder(REMINDER_ID)).thenReturn(remindedReminder);
|
||||
Guild guildMock = Mockito.mock(Guild.class);
|
||||
when(botService.getGuildById(server.getId())).thenReturn(Optional.of(guildMock));
|
||||
when(botService.getGuildByIdOptional(server.getId())).thenReturn(Optional.of(guildMock));
|
||||
when(botService.getTextChannelFromServerOptional(server.getId(), aChannel.getId())).thenReturn(Optional.empty());
|
||||
testUnit.executeReminder(reminderId);
|
||||
testUnit.executeReminder(REMINDER_ID);
|
||||
verify(reminderManagementService, times(1)).setReminded(remindedReminder);
|
||||
}
|
||||
|
||||
@@ -170,8 +167,8 @@ public class RemindServiceBeanTest {
|
||||
when(user.getId()).thenReturn(6L);
|
||||
when(remindedUser.getUserReference()).thenReturn(user);
|
||||
Reminder remindedReminder = Reminder.builder().reminded(false).server(server).channel(aChannel).remindedUser(remindedUser).id(reminderId).build();
|
||||
when(reminderManagementService.loadReminder(reminderId)).thenReturn(Optional.of(remindedReminder));
|
||||
when(botService.getGuildById(server.getId())).thenReturn(Optional.empty());
|
||||
when(reminderManagementService.loadReminder(reminderId)).thenReturn(remindedReminder);
|
||||
when(botService.getGuildByIdOptional(server.getId())).thenReturn(Optional.empty());
|
||||
testUnit.executeReminder(reminderId);
|
||||
verify(reminderManagementService, times(1)).setReminded(remindedReminder);
|
||||
}
|
||||
@@ -180,17 +177,9 @@ public class RemindServiceBeanTest {
|
||||
public void testExecuteRemindedReminder() {
|
||||
Long reminderId = 5L;
|
||||
Reminder remindedReminder = Reminder.builder().reminded(true).build();
|
||||
when(reminderManagementService.loadReminder(reminderId)).thenReturn(Optional.of(remindedReminder));
|
||||
when(reminderManagementService.loadReminder(reminderId)).thenReturn(remindedReminder);
|
||||
testUnit.executeReminder(reminderId);
|
||||
verify(botService, times(0)).getGuildById(anyLong());
|
||||
}
|
||||
|
||||
@Test(expected = ReminderNotFoundException.class)
|
||||
public void testExecuteIllegalReminderId() {
|
||||
Long reminderId = 5L;
|
||||
when(reminderManagementService.loadReminder(reminderId)).thenReturn(Optional.empty());
|
||||
testUnit.executeReminder(reminderId);
|
||||
verify(botService, times(0)).getGuildById(anyLong());
|
||||
verify(botService, times(0)).getGuildByIdOptional(anyLong());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -225,4 +214,21 @@ public class RemindServiceBeanTest {
|
||||
testUnit.unRemind(reminderId, remindedUser);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSendReminderText() {
|
||||
Member remindedMember = Mockito.mock(Member.class);
|
||||
Guild guild = Mockito.mock(Guild.class);
|
||||
when(remindedMember.getGuild()).thenReturn(guild);
|
||||
when(guild.getIdLong()).thenReturn(8L);
|
||||
when(remindedMember.getIdLong()).thenReturn(9L);
|
||||
Reminder remindedReminder = Mockito.mock(Reminder.class);
|
||||
when(remindedReminder.getTargetDate()).thenReturn(Instant.now());
|
||||
when(remindedReminder.getReminderDate()).thenReturn(Instant.now());
|
||||
when(reminderManagementService.loadReminder(REMINDER_ID)).thenReturn(remindedReminder);
|
||||
MessageToSend messageToSend = Mockito.mock(MessageToSend.class);
|
||||
when(templateService.renderEmbedTemplate(eq(REMINDER_TEMPLATE_TEXT), any())).thenReturn(messageToSend);
|
||||
when(channelService.sendMessageToSendToChannel(messageToSend, channel)).thenReturn(Arrays.asList(CompletableFuture.completedFuture(null)));
|
||||
testUnit.sendReminderText(REMINDER_ID, channel, remindedMember).join();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -40,6 +40,7 @@ import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import static dev.sheldan.abstracto.utility.service.StarboardServiceBean.STARBOARD_POST_TEMPLATE;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
@@ -93,6 +94,19 @@ public class StarboardServiceBeanTest {
|
||||
@Mock
|
||||
private TextChannel mockedTextChannel;
|
||||
|
||||
@Mock
|
||||
private Member starredMember;
|
||||
|
||||
@Mock
|
||||
private AChannel starboardChannel;
|
||||
|
||||
@Mock
|
||||
private MessageToSend messageToSend;
|
||||
|
||||
private static final Long STARRED_USER_ID = 5L;
|
||||
private static final Long SERVER_ID = 6L;
|
||||
private static final Long STARBOARD_CHANNEL_ID = 8L;
|
||||
|
||||
@Captor
|
||||
private ArgumentCaptor<AUserInAServer> userInAServerArgumentCaptor;
|
||||
|
||||
@@ -108,34 +122,40 @@ public class StarboardServiceBeanTest {
|
||||
AUserInAServer userReacting = MockUtils.getUserObject(4L, server);
|
||||
AUserInAServer starredUser = MockUtils.getUserObject(5L, server);
|
||||
Long channelId = 10L;
|
||||
Long starredUserId = starredUser.getUserReference().getId();
|
||||
CachedMessage message = CachedMessage
|
||||
.builder()
|
||||
.authorId(starredUser.getUserReference().getId())
|
||||
.authorId(starredUserId)
|
||||
.serverId(server.getId())
|
||||
.channelId(channelId)
|
||||
.build();
|
||||
Member authorMember = Mockito.mock(Member.class);
|
||||
when(botService.getMemberInServer(message.getServerId(), message.getAuthorId())).thenReturn(authorMember);
|
||||
when(botService.getMemberInServerAsync(message.getServerId(), message.getAuthorId())).thenReturn(CompletableFuture.completedFuture(authorMember));
|
||||
when(botService.getTextChannelFromServerOptional(server.getId(), channelId)).thenReturn(Optional.of(mockedTextChannel));
|
||||
when(botService.getGuildById(server.getId())).thenReturn(Optional.of(guild));
|
||||
MessageToSend postMessage = MessageToSend.builder().build();
|
||||
when(templateService.renderEmbedTemplate(eq(StarboardServiceBean.STARBOARD_POST_TEMPLATE), starboardPostModelArgumentCaptor.capture())).thenReturn(postMessage);
|
||||
AChannel channel = MockUtils.getTextChannel(server, channelId);
|
||||
PostTarget postTarget = PostTarget.builder().channelReference(channel).build();
|
||||
when(postTargetManagement.getPostTarget(StarboardPostTarget.STARBOARD.getKey(), server.getId())).thenReturn(postTarget);
|
||||
List<CompletableFuture<Message>> futures = Arrays.asList(CompletableFuture.completedFuture(sendPost));
|
||||
when(postTargetService.sendEmbedInPostTarget(postMessage, StarboardPostTarget.STARBOARD, server.getId())).thenReturn(futures);
|
||||
when(botService.getGuildByIdOptional(server.getId())).thenReturn(Optional.of(guild));
|
||||
ADefaultConfig config = ADefaultConfig.builder().longValue(3L).build();
|
||||
when(defaultConfigManagementService.getDefaultConfig(StarboardServiceBean.STAR_LEVELS_CONFIG_KEY)).thenReturn(config);
|
||||
when(configService.getLongValue("starLvl3", server.getId())).thenReturn(3L);
|
||||
when(configService.getLongValue("starLvl2", server.getId())).thenReturn(2L);
|
||||
when(emoteService.getUsableEmoteOrDefault(server.getId(), "star2")).thenReturn("b");
|
||||
testUnit.createStarboardPost(message, userExceptAuthor, userReacting, starredUser);
|
||||
verify(self, times(1)).persistPost(eq(message), anyList(), eq(futures), eq(channelId), eq(starredUser.getUserInServerId()));
|
||||
List<StarboardPostModel> starboardPostModels = starboardPostModelArgumentCaptor.getAllValues();
|
||||
Assert.assertEquals(1, starboardPostModels.size());
|
||||
StarboardPostModel usedModel = starboardPostModels.get(0);
|
||||
Assert.assertEquals("b", usedModel.getStarLevelEmote());
|
||||
when(self.sendStarboardPostAndStore(eq(message), eq(starredUserId), anyList(), any())).thenReturn(CompletableFuture.completedFuture(null));
|
||||
testUnit.createStarboardPost(message, userExceptAuthor, userReacting, starredUser).join();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSendStarboard() {
|
||||
CachedMessage message = Mockito.mock(CachedMessage.class);
|
||||
when(message.getServerId()).thenReturn(SERVER_ID);
|
||||
StarboardPostModel model = Mockito.mock(StarboardPostModel.class);
|
||||
when(templateService.renderEmbedTemplate(STARBOARD_POST_TEMPLATE, model)).thenReturn(messageToSend);
|
||||
PostTarget postTarget = Mockito.mock(PostTarget.class);
|
||||
when(postTarget.getChannelReference()).thenReturn(starboardChannel);
|
||||
when(starboardChannel.getId()).thenReturn(STARBOARD_CHANNEL_ID);
|
||||
when(postTargetManagement.getPostTarget(StarboardPostTarget.STARBOARD.getKey(), SERVER_ID)).thenReturn(postTarget);
|
||||
when(postTargetService.sendEmbedInPostTarget(messageToSend, StarboardPostTarget.STARBOARD, SERVER_ID)).thenReturn(Arrays.asList(CompletableFuture.completedFuture(null)));
|
||||
ArrayList<Long> userExceptAuthorIds = new ArrayList<>();
|
||||
testUnit.sendStarboardPostAndStore(message, STARRED_USER_ID, userExceptAuthorIds, model);
|
||||
verify(self, times(1)).persistPost(eq(message), eq(userExceptAuthorIds), any(), eq(STARBOARD_CHANNEL_ID), eq(STARRED_USER_ID));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -189,12 +209,13 @@ public class StarboardServiceBeanTest {
|
||||
Long starboardPostId = 47L;
|
||||
StarboardPost post = StarboardPost.builder().postMessageId(postMessageId).starboardMessageId(oldPostId).sourceChanel(sourceChannel).id(starboardPostId).build();
|
||||
MessageToSend postMessage = MessageToSend.builder().build();
|
||||
when(templateService.renderEmbedTemplate(eq(StarboardServiceBean.STARBOARD_POST_TEMPLATE), starboardPostModelArgumentCaptor.capture())).thenReturn(postMessage);
|
||||
when(templateService.renderEmbedTemplate(eq(STARBOARD_POST_TEMPLATE), starboardPostModelArgumentCaptor.capture())).thenReturn(postMessage);
|
||||
when(postTargetService.editOrCreatedInPostTarget(oldPostId, postMessage, StarboardPostTarget.STARBOARD, server.getId())).thenReturn(Arrays.asList(CompletableFuture.completedFuture(sendPost)));
|
||||
when(sendPost.getIdLong()).thenReturn(newPostId);
|
||||
ADefaultConfig config = ADefaultConfig.builder().longValue(4L).build();
|
||||
when(defaultConfigManagementService.getDefaultConfig(StarboardServiceBean.STAR_LEVELS_CONFIG_KEY)).thenReturn(config);
|
||||
when(starboardPostManagementService.findByStarboardPostId(starboardPostId)).thenReturn(Optional.of(post));
|
||||
when(botService.getMemberInServerAsync(server.getId(), starredUser.getUserReference().getId())).thenReturn(CompletableFuture.completedFuture(starredMember));
|
||||
List<AUserInAServer > userExceptAuthor = new ArrayList<>();
|
||||
testUnit.updateStarboardPost(post, message, userExceptAuthor);
|
||||
verify(postTargetService, times(1)).editOrCreatedInPostTarget(oldPostId, postMessage, StarboardPostTarget.STARBOARD, server.getId());
|
||||
@@ -237,9 +258,9 @@ public class StarboardServiceBeanTest {
|
||||
StarboardPost post2 = StarboardPost.builder().starboardChannel(channel).postMessageId(secondPostMessageId).reactions(new ArrayList<>()).build();
|
||||
List<StarboardPost> topPosts = Arrays.asList(post1, post2);
|
||||
when(starboardPostManagementService.retrieveTopPosts(server.getId(), limit)).thenReturn(topPosts);
|
||||
StarStatsUser statsUser = StarStatsUser.builder().build();
|
||||
StarStatsUser statsUser2 = StarStatsUser.builder().build();
|
||||
List<StarStatsUser> topGiver = Arrays.asList(statsUser, statsUser2);
|
||||
CompletableFuture<StarStatsUser> statsUser = CompletableFuture.completedFuture(Mockito.mock(StarStatsUser.class));
|
||||
CompletableFuture<StarStatsUser> statsUser2 = CompletableFuture.completedFuture(Mockito.mock(StarStatsUser.class));
|
||||
List<CompletableFuture<StarStatsUser>> topGiver = Arrays.asList(statsUser, statsUser2);
|
||||
when(starboardPostReactorManagementService.retrieveTopStarGiver(server.getId(), limit)).thenReturn(topGiver);
|
||||
when(starboardPostReactorManagementService.retrieveTopStarReceiver(server.getId(), limit)).thenReturn(topGiver);
|
||||
when(starboardPostManagementService.getPostCount(server.getId())).thenReturn(50);
|
||||
@@ -247,7 +268,8 @@ public class StarboardServiceBeanTest {
|
||||
when(emoteService.getUsableEmoteOrDefault(server.getId(), "starboardBadge1")).thenReturn("1");
|
||||
when(emoteService.getUsableEmoteOrDefault(server.getId(), "starboardBadge2")).thenReturn("2");
|
||||
when(emoteService.getUsableEmoteOrDefault(server.getId(), "starboardBadge3")).thenReturn("3");
|
||||
StarStatsModel model = testUnit.retrieveStarStats(server.getId());
|
||||
CompletableFuture<StarStatsModel> modelFuture = testUnit.retrieveStarStats(server.getId());
|
||||
StarStatsModel model = modelFuture.join();
|
||||
List<String> badgeEmotes = model.getBadgeEmotes();
|
||||
Assert.assertEquals(limit.intValue(), badgeEmotes.size());
|
||||
Assert.assertEquals("1", badgeEmotes.get(0));
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package dev.sheldan.abstracto.utility.service;
|
||||
|
||||
import dev.sheldan.abstracto.core.exception.ChannelNotFoundException;
|
||||
import dev.sheldan.abstracto.core.exception.GuildNotFoundException;
|
||||
import dev.sheldan.abstracto.core.models.database.AChannel;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.core.models.database.AUser;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.core.service.BotService;
|
||||
import dev.sheldan.abstracto.core.service.CounterService;
|
||||
@@ -11,7 +11,6 @@ import dev.sheldan.abstracto.core.service.MessageService;
|
||||
import dev.sheldan.abstracto.core.service.PostTargetService;
|
||||
import dev.sheldan.abstracto.templating.model.MessageToSend;
|
||||
import dev.sheldan.abstracto.templating.service.TemplateService;
|
||||
import dev.sheldan.abstracto.test.MockUtils;
|
||||
import dev.sheldan.abstracto.utility.config.posttargets.SuggestionPostTarget;
|
||||
import dev.sheldan.abstracto.utility.exception.SuggestionNotFoundException;
|
||||
import dev.sheldan.abstracto.utility.exception.SuggestionUpdateException;
|
||||
@@ -74,49 +73,64 @@ public class SuggestionServiceBeanTest {
|
||||
@Mock
|
||||
private CounterService counterService;
|
||||
|
||||
@Mock
|
||||
private AServer server;
|
||||
|
||||
@Mock
|
||||
private AChannel channel;
|
||||
|
||||
@Mock
|
||||
private AUserInAServer suggester;
|
||||
|
||||
@Mock
|
||||
private AUser suggesterUser;
|
||||
|
||||
@Mock
|
||||
private Member suggesterMember;
|
||||
|
||||
private static final Long SUGGESTER_ID = 8L;
|
||||
private static final Long SERVER_ID = 3L;
|
||||
private static final Long CHANNEL_ID = 7L;
|
||||
private static final Long SUGGESTION_ID = 5L;
|
||||
|
||||
@Test
|
||||
public void testCreateSuggestionMessage() {
|
||||
String suggestionText = "text";
|
||||
AServer server = MockUtils.getServer();
|
||||
SuggestionLog log = Mockito.mock(SuggestionLog.class);
|
||||
when(log.getServer()).thenReturn(server);
|
||||
Long suggestionId = 5L;
|
||||
when(suggestionCreator.getGuild()).thenReturn(guild);
|
||||
when(guild.getIdLong()).thenReturn(server.getId());
|
||||
when(guild.getIdLong()).thenReturn(SERVER_ID);
|
||||
when(guild.getIdLong()).thenReturn(SERVER_ID);
|
||||
MessageToSend messageToSend = MessageToSend.builder().build();
|
||||
when(templateService.renderEmbedTemplate(eq(SuggestionServiceBean.SUGGESTION_LOG_TEMPLATE), any(SuggestionLog.class))).thenReturn(messageToSend);
|
||||
Message suggestionMessage = Mockito.mock(Message.class);
|
||||
when(counterService.getNextCounterValue(server, SUGGESTION_COUNTER_KEY)).thenReturn(suggestionId);
|
||||
when(counterService.getNextCounterValue(server, SUGGESTION_COUNTER_KEY)).thenReturn(SUGGESTION_ID);
|
||||
List<CompletableFuture<Message>> postingFutures = Arrays.asList(CompletableFuture.completedFuture(suggestionMessage));
|
||||
when(postTargetService.sendEmbedInPostTarget(messageToSend, SuggestionPostTarget.SUGGESTION, server.getId())).thenReturn(postingFutures);
|
||||
when(postTargetService.sendEmbedInPostTarget(messageToSend, SuggestionPostTarget.SUGGESTION, SERVER_ID)).thenReturn(postingFutures);
|
||||
testUnit.createSuggestionMessage(suggestionCreator, suggestionText, log);
|
||||
verify( messageService, times(1)).addReactionToMessageWithFuture(SuggestionServiceBean.SUGGESTION_YES_EMOTE, server.getId(), suggestionMessage);
|
||||
verify( messageService, times(1)).addReactionToMessageWithFuture(SuggestionServiceBean.SUGGESTION_NO_EMOTE, server.getId(), suggestionMessage);
|
||||
verify( messageService, times(1)).addReactionToMessageWithFuture(SuggestionServiceBean.SUGGESTION_YES_EMOTE, SERVER_ID, suggestionMessage);
|
||||
verify( messageService, times(1)).addReactionToMessageWithFuture(SuggestionServiceBean.SUGGESTION_NO_EMOTE, SERVER_ID, suggestionMessage);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateSuggestion() {
|
||||
Member member = Mockito.mock(Member.class);
|
||||
when(member.getGuild()).thenReturn(guild);
|
||||
when(suggesterMember.getGuild()).thenReturn(guild);
|
||||
when(guild.getId()).thenReturn("5");
|
||||
String text = "text";
|
||||
Message message = Mockito.mock(Message.class);
|
||||
Long suggestionId = 3L;
|
||||
testUnit.persistSuggestionInDatabase(member, text, message, suggestionId);
|
||||
verify(suggestionManagementService, times(1)).createSuggestion(member, text, message, suggestionId);
|
||||
testUnit.persistSuggestionInDatabase(suggesterMember, text, message, SUGGESTION_ID);
|
||||
verify(suggestionManagementService, times(1)).createSuggestion(suggesterMember, text, message, SUGGESTION_ID);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAcceptExistingSuggestion() {
|
||||
Member suggesterMember = Mockito.mock(Member.class);
|
||||
executeAcceptWithMember(suggesterMember);
|
||||
}
|
||||
|
||||
@Test(expected = SuggestionNotFoundException.class)
|
||||
public void testAcceptNotExistingSuggestion() {
|
||||
Long suggestionId = 5L;
|
||||
when(suggestionManagementService.getSuggestion(suggestionId)).thenReturn(Optional.empty());
|
||||
testUnit.acceptSuggestion(suggestionId, CLOSING_TEXT, SuggestionLog.builder().build());
|
||||
when(suggestionManagementService.getSuggestion(SUGGESTION_ID)).thenReturn(Optional.empty());
|
||||
testUnit.acceptSuggestion(SUGGESTION_ID, CLOSING_TEXT, SuggestionLog.builder().build());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -126,38 +140,24 @@ public class SuggestionServiceBeanTest {
|
||||
|
||||
@Test(expected = ChannelNotFoundException.class)
|
||||
public void testAcceptSuggestionInNoTextChannel() {
|
||||
Long suggestionId = 5L;
|
||||
setupForNoTextChannel(suggestionId);
|
||||
testUnit.acceptSuggestion(suggestionId, CLOSING_TEXT, SuggestionLog.builder().build());
|
||||
setupForNoTextChannel();
|
||||
testUnit.acceptSuggestion(SUGGESTION_ID, CLOSING_TEXT, SuggestionLog.builder().build());
|
||||
}
|
||||
|
||||
private void setupForNoTextChannel(Long suggestionId) {
|
||||
AServer server = MockUtils.getServer();
|
||||
Long channelId = 5L;
|
||||
private void setupForNoTextChannel() {
|
||||
Long messageId = 7L;
|
||||
AChannel channel = MockUtils.getTextChannel(server, channelId);
|
||||
AUserInAServer suggester = MockUtils.getUserObject(4L, server);
|
||||
Suggestion suggestionToAccept = Suggestion
|
||||
.builder()
|
||||
.channel(channel)
|
||||
.server(server)
|
||||
.id(suggestionId)
|
||||
.id(SUGGESTION_ID)
|
||||
.suggester(suggester)
|
||||
.messageId(messageId)
|
||||
.build();
|
||||
|
||||
when(suggestionManagementService.getSuggestion(suggestionId)).thenReturn(Optional.of(suggestionToAccept));
|
||||
when(botService.getGuildById(server.getId())).thenReturn(Optional.of(guild));
|
||||
Member suggesterMember = Mockito.mock(Member.class);
|
||||
when(guild.getMemberById(suggester.getUserReference().getId())).thenReturn(suggesterMember);
|
||||
when(guild.getTextChannelById(channelId)).thenReturn(null);
|
||||
}
|
||||
|
||||
@Test(expected = GuildNotFoundException.class)
|
||||
public void testAcceptSuggestionInNoGuild() {
|
||||
Long suggestionId = 5L;
|
||||
setupForNoGuild(suggestionId);
|
||||
testUnit.acceptSuggestion(suggestionId, CLOSING_TEXT, SuggestionLog.builder().build());
|
||||
when(server.getId()).thenReturn(SERVER_ID);
|
||||
when(channel.getId()).thenReturn(CHANNEL_ID);
|
||||
when(botService.getTextChannelFromServer(SERVER_ID, CHANNEL_ID)).thenThrow(new ChannelNotFoundException(CHANNEL_ID));
|
||||
when(suggestionManagementService.getSuggestion(SUGGESTION_ID)).thenReturn(Optional.of(suggestionToAccept));
|
||||
}
|
||||
|
||||
@Test(expected = SuggestionUpdateException.class)
|
||||
@@ -169,7 +169,6 @@ public class SuggestionServiceBeanTest {
|
||||
|
||||
@Test
|
||||
public void testUpdateSuggestionMessageWithEmbed() {
|
||||
AServer server = MockUtils.getServer();
|
||||
SuggestionLog log = SuggestionLog.builder().server(server).build();
|
||||
MessageEmbed embed = Mockito.mock(MessageEmbed.class);
|
||||
when(embed.getDescription()).thenReturn("description");
|
||||
@@ -185,15 +184,13 @@ public class SuggestionServiceBeanTest {
|
||||
|
||||
@Test
|
||||
public void testRejectExistingSuggestion() {
|
||||
Member suggesterMember = Mockito.mock(Member.class);
|
||||
executeRejectWithMember(suggesterMember);
|
||||
}
|
||||
|
||||
@Test(expected = SuggestionNotFoundException.class)
|
||||
public void testRejectNotExistingSuggestion() {
|
||||
Long suggestionId = 5L;
|
||||
when(suggestionManagementService.getSuggestion(suggestionId)).thenReturn(Optional.empty());
|
||||
testUnit.rejectSuggestion(suggestionId, CLOSING_TEXT, SuggestionLog.builder().build());
|
||||
when(suggestionManagementService.getSuggestion(SUGGESTION_ID)).thenReturn(Optional.empty());
|
||||
testUnit.rejectSuggestion(SUGGESTION_ID, CLOSING_TEXT, SuggestionLog.builder().build());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -203,82 +200,51 @@ public class SuggestionServiceBeanTest {
|
||||
|
||||
@Test(expected = ChannelNotFoundException.class)
|
||||
public void testRejectSuggestionInNoTextChannel() {
|
||||
Long suggestionId = setupForNoTextChannel();
|
||||
testUnit.rejectSuggestion(suggestionId, CLOSING_TEXT, SuggestionLog.builder().build());
|
||||
setupForNoTextChannel();
|
||||
testUnit.rejectSuggestion(SUGGESTION_ID, CLOSING_TEXT, SuggestionLog.builder().build());
|
||||
}
|
||||
|
||||
@Test(expected = GuildNotFoundException.class)
|
||||
public void testRejectSuggestionInNoGuild() {
|
||||
Long suggestionId = 5L;
|
||||
setupForNoGuild(suggestionId);
|
||||
testUnit.rejectSuggestion(suggestionId, CLOSING_TEXT, SuggestionLog.builder().build());
|
||||
}
|
||||
|
||||
private Long setupForNoTextChannel() {
|
||||
Long suggestionId = 5L;
|
||||
setupForNoTextChannel(suggestionId);
|
||||
return suggestionId;
|
||||
}
|
||||
|
||||
private Long setupForNoGuild(Long suggestionId) {
|
||||
AServer server = MockUtils.getServer();
|
||||
Long channelId = 5L;
|
||||
AChannel channel = MockUtils.getTextChannel(server, channelId);
|
||||
Suggestion suggestionToAccept = Suggestion
|
||||
.builder()
|
||||
.server(server)
|
||||
.id(suggestionId)
|
||||
.channel(channel)
|
||||
.build();
|
||||
when(suggestionManagementService.getSuggestion(suggestionId)).thenReturn(Optional.of(suggestionToAccept));
|
||||
when(botService.getGuildById(server.getId())).thenReturn(Optional.empty());
|
||||
return suggestionId;
|
||||
}
|
||||
|
||||
private void executeAcceptWithMember(Member suggesterMember) {
|
||||
Long suggestionId = 5L;
|
||||
Long channelId = 5L;
|
||||
private void executeAcceptWithMember(Member actualMember) {
|
||||
Long messageId = 7L;
|
||||
SuggestionLog logParameter = SuggestionLog.builder().build();
|
||||
Suggestion suggestionToAccept = setupClosing(suggesterMember, suggestionId, channelId, messageId);
|
||||
Suggestion suggestionToAccept = setupClosing(messageId);
|
||||
RestAction<Message> retrievalAction = Mockito.mock(RestAction.class);
|
||||
when(textChannel.retrieveMessageById(messageId)).thenReturn(retrievalAction);
|
||||
Message suggestionMessage = Mockito.mock(Message.class);
|
||||
when(retrievalAction.submit()).thenReturn(CompletableFuture.completedFuture(suggestionMessage));
|
||||
testUnit.acceptSuggestion(suggestionId, CLOSING_TEXT, logParameter);
|
||||
when(botService.getMemberInServerAsync(SERVER_ID, SUGGESTER_ID)).thenReturn(CompletableFuture.completedFuture(actualMember));
|
||||
testUnit.acceptSuggestion(SUGGESTION_ID, CLOSING_TEXT, logParameter);
|
||||
verify(suggestionManagementService, times(1)).setSuggestionState(suggestionToAccept, SuggestionState.ACCEPTED);
|
||||
}
|
||||
|
||||
private void executeRejectWithMember(Member suggesterMember) {
|
||||
Long suggestionId = 5L;
|
||||
Long channelId = 5L;
|
||||
private void executeRejectWithMember(Member actualMember) {
|
||||
Long messageId = 7L;
|
||||
SuggestionLog logParameter = SuggestionLog.builder().build();
|
||||
Suggestion suggestionToAccept = setupClosing(suggesterMember, suggestionId, channelId, messageId);
|
||||
Suggestion suggestionToAccept = setupClosing(messageId);
|
||||
RestAction<Message> retrievalAction = Mockito.mock(RestAction.class);
|
||||
when(textChannel.retrieveMessageById(messageId)).thenReturn(retrievalAction);
|
||||
Message suggestionMessage = Mockito.mock(Message.class);
|
||||
when(retrievalAction.submit()).thenReturn(CompletableFuture.completedFuture(suggestionMessage));
|
||||
testUnit.rejectSuggestion(suggestionId, CLOSING_TEXT, logParameter);
|
||||
when(botService.getMemberInServerAsync(SERVER_ID, SUGGESTER_ID)).thenReturn(CompletableFuture.completedFuture(actualMember));
|
||||
testUnit.rejectSuggestion(SUGGESTION_ID, CLOSING_TEXT, logParameter);
|
||||
verify(suggestionManagementService, times(1)).setSuggestionState(suggestionToAccept, SuggestionState.REJECTED);
|
||||
}
|
||||
|
||||
private Suggestion setupClosing(Member suggesterMember, Long suggestionId, Long channelId, Long messageId) {
|
||||
AServer server = MockUtils.getServer();
|
||||
AChannel channel = MockUtils.getTextChannel(server, channelId);
|
||||
AUserInAServer suggester = MockUtils.getUserObject(4L, server);
|
||||
private Suggestion setupClosing(Long messageId) {
|
||||
Suggestion suggestionToAccept = Suggestion
|
||||
.builder()
|
||||
.channel(channel)
|
||||
.server(server)
|
||||
.id(suggestionId)
|
||||
.id(SUGGESTION_ID)
|
||||
.suggester(suggester)
|
||||
.messageId(messageId)
|
||||
.build();
|
||||
when(suggestionManagementService.getSuggestion(suggestionId)).thenReturn(Optional.of(suggestionToAccept));
|
||||
when(botService.getGuildById(server.getId())).thenReturn(Optional.of(guild));
|
||||
when(guild.getTextChannelById(channelId)).thenReturn(textChannel);
|
||||
when(guild.getMemberById(suggester.getUserReference().getId())).thenReturn(suggesterMember);
|
||||
when(server.getId()).thenReturn(SERVER_ID);
|
||||
when(channel.getId()).thenReturn(CHANNEL_ID);
|
||||
when(suggester.getUserReference()).thenReturn(suggesterUser);
|
||||
when(suggesterUser.getId()).thenReturn(SUGGESTER_ID);
|
||||
when(suggestionManagementService.getSuggestion(SUGGESTION_ID)).thenReturn(Optional.of(suggestionToAccept));
|
||||
when(botService.getTextChannelFromServer(SERVER_ID, CHANNEL_ID)).thenReturn(textChannel);
|
||||
return suggestionToAccept;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,7 +116,7 @@ public class ReminderManagementServiceBeanTest {
|
||||
Long reminderId = 5L;
|
||||
Reminder reminderToLoad = Reminder.builder().build();
|
||||
when(reminderRepository.findById(reminderId)).thenReturn(Optional.of(reminderToLoad));
|
||||
Optional<Reminder> returned = testUnit.loadReminder(reminderId);
|
||||
Optional<Reminder> returned = testUnit.loadReminderOptional(reminderId);
|
||||
Assert.assertTrue(returned.isPresent());
|
||||
returned.ifPresent(returnedReminder -> Assert.assertEquals(reminderToLoad, returnedReminder));
|
||||
}
|
||||
@@ -125,7 +125,7 @@ public class ReminderManagementServiceBeanTest {
|
||||
public void testLoadingReminderNotFound() {
|
||||
Long reminderId = 5L;
|
||||
when(reminderRepository.findById(reminderId)).thenReturn(Optional.empty());
|
||||
Optional<Reminder> returned = testUnit.loadReminder(reminderId);
|
||||
Optional<Reminder> returned = testUnit.loadReminderOptional(reminderId);
|
||||
Assert.assertFalse(returned.isPresent());
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ 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.*;
|
||||
|
||||
@@ -108,11 +109,11 @@ public class StarboardPostReactorManagementServiceBeanTest {
|
||||
StarStatsUser user1 = Mockito.mock(StarStatsUser.class);
|
||||
StarStatsUser user2 = Mockito.mock(StarStatsUser.class);
|
||||
setupStarStatsReceiverResult(amountToRetrieve, serverId, user1, user2);
|
||||
List<StarStatsUser> starStatsUsers = testUnit.retrieveTopStarReceiver(serverId, amountToRetrieve);
|
||||
List<CompletableFuture<StarStatsUser>> starStatsUsers = testUnit.retrieveTopStarReceiver(serverId, amountToRetrieve);
|
||||
Assert.assertEquals(expectedAmount, starStatsUsers.size());
|
||||
Assert.assertEquals(user1, starStatsUsers.get(0));
|
||||
Assert.assertEquals(user1, starStatsUsers.get(0).join());
|
||||
if(amountToRetrieve > 1) {
|
||||
Assert.assertEquals(user2, starStatsUsers.get(1));
|
||||
Assert.assertEquals(user2, starStatsUsers.get(1).join());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,11 +122,11 @@ public class StarboardPostReactorManagementServiceBeanTest {
|
||||
StarStatsUser user1 = Mockito.mock(StarStatsUser.class);
|
||||
StarStatsUser user2 = Mockito.mock(StarStatsUser.class);
|
||||
setupStarStatsGiverResult(amountToRetrieve, serverId, user1, user2);
|
||||
List<StarStatsUser> starStatsUsers = testUnit.retrieveTopStarGiver(serverId, amountToRetrieve);
|
||||
List<CompletableFuture<StarStatsUser>> starStatsUsers = testUnit.retrieveTopStarGiver(serverId, amountToRetrieve);
|
||||
Assert.assertEquals(expectedAmount, starStatsUsers.size());
|
||||
Assert.assertEquals(user1, starStatsUsers.get(0));
|
||||
Assert.assertEquals(user1, starStatsUsers.get(0).join());
|
||||
if(amountToRetrieve > 1) {
|
||||
Assert.assertEquals(user2, starStatsUsers.get(1));
|
||||
Assert.assertEquals(user2, starStatsUsers.get(1).join());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -134,10 +135,10 @@ public class StarboardPostReactorManagementServiceBeanTest {
|
||||
StarStatsUserResult result2 = Mockito.mock(StarStatsUserResult.class);
|
||||
List<StarStatsUserResult> results = Arrays.asList(result1, result2);
|
||||
when(repository.findTopStarGiverInServer(serverId, amountToRetrieve)).thenReturn(results);
|
||||
List<StarStatsUser> statsUser = new ArrayList<>();
|
||||
statsUser.add(user1);
|
||||
List<CompletableFuture<StarStatsUser>> statsUser = new ArrayList<>();
|
||||
statsUser.add(CompletableFuture.completedFuture(user1));
|
||||
if (amountToRetrieve > 1) {
|
||||
statsUser.add(user2);
|
||||
statsUser.add(CompletableFuture.completedFuture(user2));
|
||||
}
|
||||
when(converter.convertToStarStatsUser(results, serverId)).thenReturn(statsUser);
|
||||
}
|
||||
@@ -147,10 +148,10 @@ public class StarboardPostReactorManagementServiceBeanTest {
|
||||
StarStatsUserResult result2 = Mockito.mock(StarStatsUserResult.class);
|
||||
List<StarStatsUserResult> results = Arrays.asList(result1, result2);
|
||||
when(repository.retrieveTopStarReceiverInServer(serverId, amountToRetrieve)).thenReturn(results);
|
||||
List<StarStatsUser> statsUser = new ArrayList<>();
|
||||
statsUser.add(user1);
|
||||
List<CompletableFuture<StarStatsUser>> statsUser = new ArrayList<>();
|
||||
statsUser.add(CompletableFuture.completedFuture(user1));
|
||||
if (amountToRetrieve > 1) {
|
||||
statsUser.add(user2);
|
||||
statsUser.add(CompletableFuture.completedFuture(user2));
|
||||
}
|
||||
when(converter.convertToStarStatsUser(results, serverId)).thenReturn(statsUser);
|
||||
}
|
||||
|
||||
@@ -6,9 +6,10 @@ import net.dv8tion.jda.api.entities.Message;
|
||||
import net.dv8tion.jda.api.entities.TextChannel;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public interface MessageEmbedService {
|
||||
List<MessageEmbedLink> getLinksInMessage(String message);
|
||||
void embedLinks(List<MessageEmbedLink> linksToEmbed, TextChannel target, Long userEmbeddingUserInServerId, Message embeddingMessage);
|
||||
void embedLink(CachedMessage cachedMessage, TextChannel target, Long userEmbeddingUserInServerId, Message embeddingMessage);
|
||||
CompletableFuture<Void> embedLink(CachedMessage cachedMessage, TextChannel target, Long userEmbeddingUserInServerId, Message embeddingMessage);
|
||||
}
|
||||
|
||||
@@ -7,11 +7,12 @@ import dev.sheldan.abstracto.utility.models.template.commands.starboard.StarStat
|
||||
import dev.sheldan.abstracto.utility.models.template.commands.starboard.StarStatsPost;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public interface StarboardService {
|
||||
void createStarboardPost(CachedMessage message, List<AUserInAServer> userExceptAuthor, AUserInAServer userReacting, AUserInAServer starredUser);
|
||||
void updateStarboardPost(StarboardPost post, CachedMessage message, List<AUserInAServer> userExceptAuthor);
|
||||
CompletableFuture<Void> createStarboardPost(CachedMessage message, List<AUserInAServer> userExceptAuthor, AUserInAServer userReacting, AUserInAServer starredUser);
|
||||
CompletableFuture<Void> updateStarboardPost(StarboardPost post, CachedMessage message, List<AUserInAServer> userExceptAuthor);
|
||||
void deleteStarboardMessagePost(StarboardPost message);
|
||||
StarStatsModel retrieveStarStats(Long serverId);
|
||||
CompletableFuture<StarStatsModel> retrieveStarStats(Long serverId);
|
||||
StarStatsPost fromStarboardPost(StarboardPost starboardPost);
|
||||
}
|
||||
|
||||
@@ -10,7 +10,8 @@ import java.util.Optional;
|
||||
|
||||
public interface ReminderManagementService {
|
||||
Reminder createReminder(AServerAChannelAUser userToBeReminded, String text, Instant timeToBeRemindedAt, Long messageId);
|
||||
Optional<Reminder> loadReminder(Long reminderId);
|
||||
Optional<Reminder> loadReminderOptional(Long reminderId);
|
||||
Reminder loadReminder(Long reminderId);
|
||||
void setReminded(Reminder reminder);
|
||||
Reminder saveReminder(Reminder reminder);
|
||||
List<Reminder> getActiveRemindersForUser(AUserInAServer aUserInAServer);
|
||||
|
||||
@@ -5,12 +5,13 @@ import dev.sheldan.abstracto.utility.models.database.StarboardPost;
|
||||
import dev.sheldan.abstracto.utility.models.template.commands.starboard.StarStatsUser;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public interface StarboardPostReactorManagementService {
|
||||
void addReactor(StarboardPost post, AUserInAServer user);
|
||||
void removeReactor(StarboardPost post, AUserInAServer user);
|
||||
void removeReactors(StarboardPost post);
|
||||
Integer getStarCount(Long serverId);
|
||||
List<StarStatsUser> retrieveTopStarGiver(Long serverId, Integer count);
|
||||
List<StarStatsUser> retrieveTopStarReceiver(Long serverId, Integer count);
|
||||
List<CompletableFuture<StarStatsUser>> retrieveTopStarGiver(Long serverId, Integer count);
|
||||
List<CompletableFuture<StarStatsUser>> retrieveTopStarReceiver(Long serverId, Integer count);
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ import dev.sheldan.abstracto.core.service.EmoteService;
|
||||
import dev.sheldan.abstracto.core.service.RoleService;
|
||||
import dev.sheldan.abstracto.core.service.management.*;
|
||||
import dev.sheldan.abstracto.core.models.context.UserInitiatedServerContext;
|
||||
import dev.sheldan.abstracto.core.utils.FutureUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.entities.*;
|
||||
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
|
||||
@@ -30,6 +31,7 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static java.util.Comparator.comparing;
|
||||
@@ -106,27 +108,24 @@ public class CommandReceivedHandler extends ListenerAdapter {
|
||||
tryToExecuteFoundCommand(event, commandContextBuilder, foundCommand, unParsedParameter);
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("Exception when executing command.", e);
|
||||
CommandResult commandResult = CommandResult.fromError(e.getMessage(), e);
|
||||
CommandContext commandContext = commandContextBuilder.build();
|
||||
self.executePostCommandListener(null, commandContext, commandResult);
|
||||
reportException(commandContextBuilder, null, e, "Exception when executing command.");
|
||||
}
|
||||
}
|
||||
|
||||
private void tryToExecuteFoundCommand(@Nonnull MessageReceivedEvent event, CommandContext.CommandContextBuilder commandContextBuilder, Command foundCommand, UnParsedCommandParameter unParsedParameter) {
|
||||
try {
|
||||
Parameters parsedParameters = getParsedParameters(unParsedParameter, foundCommand, event.getMessage());
|
||||
CompletableFuture<Parameters> parsingFuture = getParsedParameters(unParsedParameter, foundCommand, event.getMessage());
|
||||
parsingFuture.thenAccept(parsedParameters -> {
|
||||
validateCommandParameters(parsedParameters, foundCommand);
|
||||
CommandContext commandContext = commandContextBuilder.parameters(parsedParameters).build();
|
||||
ConditionResult conditionResult = commandService.isCommandExecutable(foundCommand, commandContext);
|
||||
CommandResult commandResult = null;
|
||||
if(conditionResult.isResult()) {
|
||||
if(foundCommand.getConfiguration().isAsync()) {
|
||||
log.info("Executing async command {} for server {} in channel {} based on message {} by user {}.",
|
||||
foundCommand.getConfiguration().getName(), commandContext.getGuild().getId(), commandContext.getChannel().getId(), commandContext.getMessage().getId(), commandContext.getAuthor().getId());
|
||||
if(foundCommand.getConfiguration().isAsync()) {
|
||||
log.info("Executing async command {} for server {} in channel {} based on message {} by user {}.",
|
||||
foundCommand.getConfiguration().getName(), commandContext.getGuild().getId(), commandContext.getChannel().getId(), commandContext.getMessage().getId(), commandContext.getAuthor().getId());
|
||||
|
||||
foundCommand.executeAsync(commandContext).thenAccept(result ->
|
||||
executePostCommandListener(foundCommand, commandContext, result)
|
||||
foundCommand.executeAsync(commandContext).thenAccept(result ->
|
||||
executePostCommandListener(foundCommand, commandContext, result)
|
||||
).exceptionally(throwable -> {
|
||||
log.error("Asynchronous command {} failed.", foundCommand.getConfiguration().getName(), throwable);
|
||||
UserInitiatedServerContext rebuildUserContext = buildTemplateParameter(event);
|
||||
@@ -155,12 +154,21 @@ public class CommandReceivedHandler extends ListenerAdapter {
|
||||
if(commandResult != null) {
|
||||
self.executePostCommandListener(foundCommand, commandContext, commandResult);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("Exception when executing command.", e);
|
||||
CommandResult commandResult = CommandResult.fromError(e.getMessage(), e);
|
||||
CommandContext commandContext = commandContextBuilder.build();
|
||||
self.executePostCommandListener(foundCommand, commandContext, commandResult);
|
||||
}
|
||||
}).exceptionally(throwable -> {
|
||||
reportException(commandContextBuilder, foundCommand, throwable, "Exception when executing command.");
|
||||
return null;
|
||||
});
|
||||
parsingFuture.exceptionally(throwable -> {
|
||||
reportException(commandContextBuilder, foundCommand, throwable, "Exception when parsing command.");
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
private void reportException(CommandContext.CommandContextBuilder commandContextBuilder, Command foundCommand, Throwable throwable, String s) {
|
||||
log.error(s, throwable);
|
||||
CommandResult commandResult = CommandResult.fromError(throwable.getMessage(), throwable);
|
||||
CommandContext commandContext = commandContextBuilder.build();
|
||||
self.executePostCommandListener(foundCommand, commandContext, commandResult);
|
||||
}
|
||||
|
||||
private void validateCommandParameters(Parameters parameters, Command foundCommand) {
|
||||
@@ -210,10 +218,10 @@ public class CommandReceivedHandler extends ListenerAdapter {
|
||||
.build();
|
||||
}
|
||||
|
||||
public Parameters getParsedParameters(UnParsedCommandParameter unParsedCommandParameter, Command command, Message message){
|
||||
public CompletableFuture<Parameters> getParsedParameters(UnParsedCommandParameter unParsedCommandParameter, Command command, Message message){
|
||||
List<Object> parsedParameters = new ArrayList<>();
|
||||
if(command.getConfiguration().getParameters() == null || command.getConfiguration().getParameters().isEmpty()) {
|
||||
return Parameters.builder().parameters(parsedParameters).build();
|
||||
return CompletableFuture.completedFuture(Parameters.builder().parameters(parsedParameters).build());
|
||||
}
|
||||
log.trace("Parsing parameters for command {} based on message {}.", command.getConfiguration().getName(), message.getId());
|
||||
Iterator<TextChannel> channelIterator = message.getMentionedChannels().iterator();
|
||||
@@ -224,6 +232,7 @@ public class CommandReceivedHandler extends ListenerAdapter {
|
||||
CommandParameterIterators iterators = new CommandParameterIterators(channelIterator, emoteIterator, memberIterator, roleIterator);
|
||||
boolean reminderActive = false;
|
||||
List<CommandParameterHandler> orderedHandlers = parameterHandlers.stream().sorted(comparing(CommandParameterHandler::getPriority)).collect(Collectors.toList());
|
||||
List<CompletableFuture> futures = new ArrayList<>();
|
||||
for (int i = 0; i < unParsedCommandParameter.getParameters().size(); i++) {
|
||||
if(i < command.getConfiguration().getParameters().size() && !param.isRemainder()) {
|
||||
param = command.getConfiguration().getParameters().get(i);
|
||||
@@ -236,7 +245,13 @@ public class CommandReceivedHandler extends ListenerAdapter {
|
||||
try {
|
||||
if(handler.handles(param.getType())) {
|
||||
handlerMatched = true;
|
||||
parsedParameters.add(handler.handle(value, iterators, param.getType(), message));
|
||||
if(handler.async()) {
|
||||
CompletableFuture future = handler.handleAsync(value, iterators, param.getType(), message);
|
||||
futures.add(future);
|
||||
parsedParameters.add(future);
|
||||
} else {
|
||||
parsedParameters.add(handler.handle(value, iterators, param.getType(), message));
|
||||
}
|
||||
break;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
@@ -256,9 +271,22 @@ public class CommandReceivedHandler extends ListenerAdapter {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return Parameters.builder().parameters(parsedParameters).build();
|
||||
if(!futures.isEmpty()) {
|
||||
return FutureUtils.toSingleFuture(futures).thenApply(aVoid -> {
|
||||
List<Object> usableParameters = parsedParameters.stream().map(o -> {
|
||||
if(o instanceof CompletableFuture) {
|
||||
return ((CompletableFuture) o).join();
|
||||
} else {
|
||||
return o;
|
||||
}
|
||||
}).collect(Collectors.toList());
|
||||
return Parameters.builder().parameters(usableParameters).build();
|
||||
});
|
||||
} else {
|
||||
Parameters parameters = Parameters.builder().parameters(parsedParameters).build();
|
||||
return CompletableFuture.completedFuture(parameters);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import net.dv8tion.jda.api.entities.Member;
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
@Component
|
||||
@@ -15,14 +16,19 @@ public class MemberParameterHandler implements CommandParameterHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object handle(String input, CommandParameterIterators iterators, Class clazz, Message context) {
|
||||
public boolean async() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Object> handleAsync(String input, CommandParameterIterators iterators, Class clazz, Message context) {
|
||||
Matcher matcher = Message.MentionType.USER.getPattern().matcher(input);
|
||||
if(matcher.matches()) {
|
||||
return iterators.getMemberIterator().next();
|
||||
return CompletableFuture.completedFuture(iterators.getMemberIterator().next());
|
||||
} else {
|
||||
// TODO add handling for names
|
||||
long emoteId = Long.parseLong(input);
|
||||
return context.getGuild().getMemberById(emoteId);
|
||||
long userId = Long.parseLong(input);
|
||||
return context.getGuild().retrieveMemberById(userId).submit().thenApply(member -> member);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -76,24 +76,29 @@ public class MessageDeletedListenerBean extends ListenerAdapter {
|
||||
.channel(channelManagementService.loadChannel(cachedMessage.getChannelId()))
|
||||
.aUserInAServer(userInServerManagementService.loadUser(cachedMessage.getServerId(), cachedMessage.getAuthorId()))
|
||||
.build();
|
||||
|
||||
GuildChannelMember authorMember = GuildChannelMember
|
||||
.builder()
|
||||
.guild(botService.getGuildByIdNullable(cachedMessage.getServerId()))
|
||||
.textChannel(botService.getTextChannelFromServerOptional(cachedMessage.getServerId(), cachedMessage.getChannelId()).orElseThrow(() -> new ChannelNotFoundException(cachedMessage.getChannelId())))
|
||||
.member(botService.getMemberInServer(cachedMessage.getServerId(), cachedMessage.getAuthorId()))
|
||||
.build();
|
||||
listener.forEach(messageDeletedListener -> {
|
||||
FeatureConfig feature = featureConfigService.getFeatureDisplayForFeature(messageDeletedListener.getFeature());
|
||||
if(!featureFlagService.isFeatureEnabled(feature, cachedMessage.getServerId())) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
self.executeIndividualMessageDeletedListener(cachedMessage, authorUser, authorMember, messageDeletedListener);
|
||||
} catch (AbstractoRunTimeException e) {
|
||||
log.error("Listener {} failed with exception:", messageDeletedListener.getClass().getName(), e);
|
||||
}
|
||||
botService.getMemberInServerAsync(cachedMessage.getServerId(), cachedMessage.getAuthorId()).thenAccept(member -> {
|
||||
GuildChannelMember authorMember = GuildChannelMember
|
||||
.builder()
|
||||
.guild(botService.getGuildById(cachedMessage.getServerId()))
|
||||
.textChannel(botService.getTextChannelFromServerOptional(cachedMessage.getServerId(), cachedMessage.getChannelId()).orElseThrow(() -> new ChannelNotFoundException(cachedMessage.getChannelId())))
|
||||
.member(botService.getMemberInServer(cachedMessage.getServerId(), cachedMessage.getAuthorId()))
|
||||
.build();
|
||||
listener.forEach(messageDeletedListener -> {
|
||||
FeatureConfig feature = featureConfigService.getFeatureDisplayForFeature(messageDeletedListener.getFeature());
|
||||
if(!featureFlagService.isFeatureEnabled(feature, cachedMessage.getServerId())) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
self.executeIndividualMessageDeletedListener(cachedMessage, authorUser, authorMember, messageDeletedListener);
|
||||
} catch (AbstractoRunTimeException e) {
|
||||
log.error("Listener {} failed with exception:", messageDeletedListener.getClass().getName(), e);
|
||||
}
|
||||
});
|
||||
}).exceptionally(throwable -> {
|
||||
log.error("Message deleted listener failed.", throwable);
|
||||
return null;
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
||||
|
||||
@@ -50,9 +50,7 @@ public class BotServiceBean implements BotService {
|
||||
@Override
|
||||
public GuildChannelMember getServerChannelUser(Long serverId, Long channelId, Long userId) {
|
||||
log.trace("Trying to retrieve member {}, channel {} in server {} from cache.", userId, channelId, serverId);
|
||||
Optional<Guild> guildOptional = getGuildById(serverId);
|
||||
if(guildOptional.isPresent()) {
|
||||
Guild guild = guildOptional.get();
|
||||
Guild guild = getGuildById(serverId);
|
||||
Optional<TextChannel> textChannelOptional = this.getTextChannelFromServerOptional(guild, channelId);
|
||||
if(textChannelOptional.isPresent()) {
|
||||
TextChannel textChannel = textChannelOptional.get();
|
||||
@@ -61,10 +59,18 @@ public class BotServiceBean implements BotService {
|
||||
} else {
|
||||
throw new ChannelNotFoundException(channelId);
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw new GuildNotFoundException(serverId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<GuildChannelMember> getServerChannelUserAsync(Long serverId, Long channelId, Long userId) {
|
||||
log.trace("Trying to retrieve member {}, channel {} in server {} async.", userId, channelId, serverId);
|
||||
CompletableFuture<Member> memberFuture = getMemberInServerAsync(serverId, userId);
|
||||
|
||||
Guild guild = getGuildById(serverId);
|
||||
TextChannel textChannel = this.getTextChannelFromServer(guild, channelId);
|
||||
return memberFuture.thenApply(member ->
|
||||
GuildChannelMember.builder().guild(guild).textChannel(textChannel).member(member).build()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -78,6 +84,17 @@ public class BotServiceBean implements BotService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Member> getMemberInServerAsync(Long serverId, Long memberId) {
|
||||
log.trace("Retrieving member {} in server {} from cache.", memberId, serverId);
|
||||
Guild guildById = instance.getGuildById(serverId);
|
||||
if(guildById != null) {
|
||||
return guildById.retrieveMemberById(memberId).submit();
|
||||
} else {
|
||||
throw new GuildNotFoundException(serverId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUserInGuild(AUserInAServer aUserInAServer) {
|
||||
Guild guildById = instance.getGuildById(aUserInAServer.getServerReference().getId());
|
||||
@@ -98,6 +115,11 @@ public class BotServiceBean implements BotService {
|
||||
return getMemberInServer(aUserInAServer.getServerReference().getId(), aUserInAServer.getUserReference().getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Member> getMemberInServerAsync(AUserInAServer aUserInAServer) {
|
||||
return getMemberInServerAsync(aUserInAServer.getServerReference().getId(), aUserInAServer.getUserReference().getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Member getMemberInServer(AServer server, AUser member) {
|
||||
return getMemberInServer(server.getId(), member.getId());
|
||||
@@ -139,7 +161,7 @@ public class BotServiceBean implements BotService {
|
||||
if(Boolean.FALSE.equals(emote.getCustom())) {
|
||||
return Optional.empty();
|
||||
}
|
||||
Optional<Guild> guildById = getGuildById(serverId);
|
||||
Optional<Guild> guildById = getGuildByIdOptional(serverId);
|
||||
if(guildById.isPresent()) {
|
||||
Guild guild = guildById.get();
|
||||
Emote emoteById = guild.getEmoteById(emote.getEmoteId());
|
||||
@@ -168,7 +190,7 @@ public class BotServiceBean implements BotService {
|
||||
|
||||
@Override
|
||||
public Optional<TextChannel> getTextChannelFromServerOptional(Long serverId, Long textChannelId) {
|
||||
Optional<Guild> guildOptional = getGuildById(serverId);
|
||||
Optional<Guild> guildOptional = getGuildByIdOptional(serverId);
|
||||
if(guildOptional.isPresent()) {
|
||||
Guild guild = guildOptional.get();
|
||||
return Optional.ofNullable(guild.getTextChannelById(textChannelId));
|
||||
@@ -182,22 +204,22 @@ public class BotServiceBean implements BotService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Guild> getGuildById(Long serverId) {
|
||||
public Optional<Guild> getGuildByIdOptional(Long serverId) {
|
||||
return Optional.ofNullable(instance.getGuildById(serverId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Guild getGuildByIdNullable(Long serverId) {
|
||||
return instance.getGuildById(serverId);
|
||||
public Guild getGuildById(Long serverId) {
|
||||
Guild guildById = instance.getGuildById(serverId);
|
||||
if(guildById == null) {
|
||||
throw new GuildNotFoundException(serverId);
|
||||
}
|
||||
return guildById;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Member getBotInGuild(AServer server) {
|
||||
Optional<Guild> guildOptional = getGuildById(server.getId());
|
||||
if(guildOptional.isPresent()) {
|
||||
Guild guild = guildOptional.get();
|
||||
return guild.getMemberById(instance.getSelfUser().getId());
|
||||
}
|
||||
return null;
|
||||
Guild guild = getGuildById(server.getId());
|
||||
return guild.getMemberById(instance.getSelfUser().getId());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -252,7 +252,7 @@ public class ChannelServiceBean implements ChannelService {
|
||||
|
||||
@Override
|
||||
public CompletableFuture<TextChannel> createTextChannel(String name, AServer server, Long categoryId) {
|
||||
Optional<Guild> guildById = botService.getGuildById(server.getId());
|
||||
Optional<Guild> guildById = botService.getGuildByIdOptional(server.getId());
|
||||
if(guildById.isPresent()) {
|
||||
Guild guild = guildById.get();
|
||||
Category categoryById = guild.getCategoryById(categoryId);
|
||||
|
||||
@@ -76,7 +76,7 @@ public class MessageCacheBean implements MessageCache {
|
||||
@Override
|
||||
public CompletableFuture<CachedMessage> loadMessage(Long guildId, Long textChannelId, Long messageId) {
|
||||
CompletableFuture<CachedMessage> future = new CompletableFuture<>();
|
||||
Optional<Guild> guildOptional = botService.getGuildById(guildId);
|
||||
Optional<Guild> guildOptional = botService.getGuildByIdOptional(guildId);
|
||||
if(guildOptional.isPresent()) {
|
||||
Optional<TextChannel> textChannelByIdOptional = botService.getTextChannelFromServerOptional(guildOptional.get(), textChannelId);
|
||||
if(textChannelByIdOptional.isPresent()) {
|
||||
|
||||
@@ -13,6 +13,7 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.entities.*;
|
||||
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;
|
||||
@@ -47,7 +48,7 @@ public class MessageServiceBean implements MessageService {
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> addReactionToMessageWithFuture(String emoteKey, Long serverId, Message message) {
|
||||
Guild guild = botService.getGuildByIdNullable(serverId);
|
||||
Guild guild = botService.getGuildById(serverId);
|
||||
return addReactionToMessageWithFuture(emoteKey, guild, message);
|
||||
}
|
||||
|
||||
@@ -93,7 +94,7 @@ public class MessageServiceBean implements MessageService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> removeReactionFromMessageWithFuture(AEmote emote, Long serverId, Message message) {
|
||||
public CompletableFuture<Void> removeReactionFromMessageWithFuture(AEmote emote, Message message) {
|
||||
if(Boolean.TRUE.equals(emote.getCustom())) {
|
||||
Emote emoteById = botService.getInstance().getEmoteById(emote.getEmoteId());
|
||||
if(emoteById == null) {
|
||||
@@ -123,13 +124,13 @@ public class MessageServiceBean implements MessageService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> removeReactionFromMessageWithFuture(Integer emoteId, Long serverId, Message message) {
|
||||
public CompletableFuture<Void> removeReactionFromMessageWithFuture(Integer emoteId, Message message) {
|
||||
AEmote emote = emoteManagementService.loadEmote(emoteId);
|
||||
return removeReactionFromMessageWithFuture(emote, serverId, message);
|
||||
return removeReactionFromMessageWithFuture(emote, message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> clearReactionFromMessageWithFuture(Integer emoteId, Long serverId, Message message) {
|
||||
public CompletableFuture<Void> clearReactionFromMessageWithFuture(Integer emoteId, Message message) {
|
||||
AEmote emote = emoteManagementService.loadEmote(emoteId);
|
||||
return clearReactionFromMessageWithFuture(emote, message);
|
||||
}
|
||||
@@ -139,14 +140,22 @@ public class MessageServiceBean implements MessageService {
|
||||
TextChannel channel = botService.getTextChannelFromServer(serverId, channelId);
|
||||
Integer emoteId = emote.getId();
|
||||
return channel.retrieveMessageById(messageId).submit()
|
||||
.thenCompose(message1 -> removeReactionFromMessageWithFuture(emoteId, serverId, message1));
|
||||
.thenCompose(message -> self.removeReactionFromMessageWithFuture(emoteId, message));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> removeReactionOfUserFromMessageWithFuture(AEmote emote, Long serverId, Long channelId, Long messageId, Long userId) {
|
||||
Guild guild = botService.getGuildByIdNullable(serverId);
|
||||
Member memberById = guild.getMemberById(userId);
|
||||
return removeReactionOfUserFromMessageWithFuture(emote, serverId, channelId, messageId, memberById);
|
||||
Guild guild = botService.getGuildById(serverId);
|
||||
Integer emoteId = emote.getId();
|
||||
TextChannel textChannel = botService.getTextChannelFromServer(serverId, channelId);
|
||||
CompletableFuture<Member> memberFuture = guild.retrieveMemberById(userId).submit();
|
||||
CompletableFuture<Message> messageFuture = textChannel.retrieveMessageById(messageId).submit();
|
||||
|
||||
return CompletableFuture.allOf(memberFuture, messageFuture).thenCompose(aVoid ->
|
||||
memberFuture.thenCompose(member ->
|
||||
self.removeReactionOfUserFromMessageWithFuture(emoteId, messageFuture.join(), memberFuture.join())
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -154,7 +163,7 @@ public class MessageServiceBean implements MessageService {
|
||||
TextChannel channel = botService.getTextChannelFromServer(serverId, channelId);
|
||||
Integer emoteId = emote.getId();
|
||||
return channel.retrieveMessageById(messageId).submit()
|
||||
.thenCompose(message1 -> removeReactionOfUserFromMessageWithFuture(emoteId, message1, member));
|
||||
.thenCompose(message -> self.removeReactionOfUserFromMessageWithFuture(emoteId, message, member));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -173,6 +182,7 @@ public class MessageServiceBean implements MessageService {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public CompletableFuture<Void> removeReactionOfUserFromMessageWithFuture(Integer emoteId, Message message, Member member) {
|
||||
AEmote emote = emoteManagementService.loadEmote(emoteId);
|
||||
return removeReactionOfUserFromMessageWithFuture(emote, message, member);
|
||||
@@ -180,15 +190,17 @@ public class MessageServiceBean implements MessageService {
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> removeReactionOfUserFromMessageWithFuture(AEmote emote, Message message, Long userId) {
|
||||
Member memberById = message.getGuild().getMemberById(userId);
|
||||
return removeReactionOfUserFromMessageWithFuture(emote, message, memberById);
|
||||
Integer emoteId = emote.getId();
|
||||
return message.getGuild().retrieveMemberById(userId).submit().thenCompose(member ->
|
||||
self.removeReactionOfUserFromMessageWithFuture(emoteId, message, member)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> removeReactionOfUserFromMessageWithFuture(Integer emoteId, Message message, Long userId) {
|
||||
Member memberById = message.getGuild().getMemberById(userId);
|
||||
AEmote emote = emoteManagementService.loadEmote(emoteId);
|
||||
return removeReactionOfUserFromMessageWithFuture(emote, message, memberById);
|
||||
return message.getGuild().retrieveMemberById(userId).submit().thenCompose(member ->
|
||||
self.removeReactionOfUserFromMessageWithFuture(emoteId, message, member)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -196,7 +208,7 @@ public class MessageServiceBean implements MessageService {
|
||||
TextChannel channel = botService.getTextChannelFromServer(serverId, channelId);
|
||||
Integer emoteId = emote.getId();
|
||||
return channel.retrieveMessageById(messageId).submit()
|
||||
.thenCompose(message1 -> clearReactionFromMessageWithFuture(emoteId, serverId, message1));
|
||||
.thenCompose(message1 -> clearReactionFromMessageWithFuture(emoteId, message1));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -239,8 +251,9 @@ public class MessageServiceBean implements MessageService {
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Message> sendMessageToUser(AUserInAServer userInAServer, String text) {
|
||||
Member memberInServer = botService.getMemberInServer(userInAServer);
|
||||
return sendMessageToUser(memberInServer.getUser(), text);
|
||||
return botService.getMemberInServerAsync(userInAServer).thenCompose(member ->
|
||||
sendMessageToUser(member.getUser(), text)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -32,7 +32,7 @@ public class RoleServiceBean implements RoleService {
|
||||
|
||||
@Override
|
||||
public void addRoleToUser(AUserInAServer aUserInAServer, ARole role) {
|
||||
Optional<Guild> guildById = botService.getGuildById(aUserInAServer.getServerReference().getId());
|
||||
Optional<Guild> guildById = botService.getGuildByIdOptional(aUserInAServer.getServerReference().getId());
|
||||
if(guildById.isPresent()) {
|
||||
addRoleToUser(guildById.get(), role, aUserInAServer.getUserReference().getId());
|
||||
} else {
|
||||
@@ -42,7 +42,7 @@ public class RoleServiceBean implements RoleService {
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> addRoleToUserFuture(AUserInAServer aUserInAServer, ARole role) {
|
||||
Optional<Guild> guildById = botService.getGuildById(aUserInAServer.getServerReference().getId());
|
||||
Optional<Guild> guildById = botService.getGuildByIdOptional(aUserInAServer.getServerReference().getId());
|
||||
if(guildById.isPresent()) {
|
||||
return addRoleToUserFuture(guildById.get(), role, aUserInAServer.getUserReference().getId());
|
||||
} else {
|
||||
@@ -50,30 +50,46 @@ public class RoleServiceBean implements RoleService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> addRoleToMemberFuture(Member member, Long roleId) {
|
||||
Role role = member.getGuild().getRoleById(roleId);
|
||||
if(role == null) {
|
||||
throw new RoleNotFoundInGuildException(roleId, member.getGuild().getIdLong());
|
||||
}
|
||||
return member.getGuild().addRoleToMember(member, role).submit();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void addRoleToMember(Member member, ARole role) {
|
||||
Guild guild = member.getGuild();
|
||||
addRoleToUser(guild, role, member.getIdLong());
|
||||
addRoleToMemberFuture(member, role.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> addRoleToMemberFuture(Member member, ARole role) {
|
||||
Guild guild = member.getGuild();
|
||||
return addRoleToUserFuture(guild, role, member.getIdLong());
|
||||
return addRoleToMemberFuture(member, role.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeRoleFromMember(Member member, ARole role) {
|
||||
Guild guild = member.getGuild();
|
||||
removeRoleFromUser(guild, role, member.getIdLong());
|
||||
removeRoleFromMemberAsync(member, role.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> removeRoleFromMemberFuture(Member member, ARole role) {
|
||||
public CompletableFuture<Void> removeRoleFromMemberAsync(Member member, ARole role) {
|
||||
Guild guild = member.getGuild();
|
||||
return removeRoleFromUserFuture(guild, role, member.getIdLong());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> removeRoleFromMemberAsync(Member member, Long roleId) {
|
||||
Role role = member.getGuild().getRoleById(roleId);
|
||||
if(role == null) {
|
||||
throw new RoleNotFoundInGuildException(roleId, member.getGuild().getIdLong());
|
||||
}
|
||||
return member.getGuild().removeRoleFromMember(member, role).submit();
|
||||
}
|
||||
|
||||
private CompletableFuture<Void> addRoleToUserFuture(Guild guild, ARole role, Long userId) {
|
||||
if(role.getDeleted()) {
|
||||
log.warn("Not possible to add role to user. Role {} was marked as deleted.", role.getId());
|
||||
@@ -114,7 +130,7 @@ public class RoleServiceBean implements RoleService {
|
||||
|
||||
@Override
|
||||
public void removeRoleFromUser(AUserInAServer aUserInAServer, ARole role) {
|
||||
Optional<Guild> guildById = botService.getGuildById(aUserInAServer.getServerReference().getId());
|
||||
Optional<Guild> guildById = botService.getGuildByIdOptional(aUserInAServer.getServerReference().getId());
|
||||
if(guildById.isPresent()) {
|
||||
removeRoleFromUser(guildById.get(), role, aUserInAServer.getUserReference().getId());
|
||||
} else {
|
||||
@@ -124,7 +140,7 @@ public class RoleServiceBean implements RoleService {
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> removeRoleFromUserFuture(AUserInAServer aUserInAServer, ARole role) {
|
||||
Optional<Guild> guildById = botService.getGuildById(aUserInAServer.getServerReference().getId());
|
||||
Optional<Guild> guildById = botService.getGuildByIdOptional(aUserInAServer.getServerReference().getId());
|
||||
if(guildById.isPresent()) {
|
||||
return removeRoleFromUserFuture(guildById.get(), role, aUserInAServer.getUserReference().getId());
|
||||
} else {
|
||||
@@ -150,7 +166,7 @@ public class RoleServiceBean implements RoleService {
|
||||
log.warn("Trying to load role {} which is marked as deleted.", role.getId());
|
||||
throw new RoleDeletedException(role);
|
||||
}
|
||||
Optional<Guild> guildById = botService.getGuildById(role.getServer().getId());
|
||||
Optional<Guild> guildById = botService.getGuildByIdOptional(role.getServer().getId());
|
||||
if(guildById.isPresent()) {
|
||||
log.trace("Loading role {} from server {}.", role.getId(), role.getServer().getId());
|
||||
return guildById.get().getRoleById(role.getId());
|
||||
@@ -171,12 +187,17 @@ public class RoleServiceBean implements RoleService {
|
||||
|
||||
@Override
|
||||
public boolean memberHasRole(Member member, Role role) {
|
||||
return member.getRoles().stream().anyMatch(role1 -> role1.getIdLong() == role.getIdLong());
|
||||
return memberHasRole(member, role.getIdLong());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean memberHasRole(Member member, ARole role) {
|
||||
return member.getRoles().stream().anyMatch(role1 -> role1.getIdLong() == role.getId());
|
||||
return memberHasRole(member, role.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean memberHasRole(Member member, Long roleId) {
|
||||
return member.getRoles().stream().anyMatch(role1 -> role1.getIdLong() == roleId);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -10,7 +10,6 @@ import dev.sheldan.abstracto.core.models.template.commands.SetupCompletedNotific
|
||||
import dev.sheldan.abstracto.core.models.template.commands.SetupInitialMessageModel;
|
||||
import dev.sheldan.abstracto.templating.service.TemplateService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import net.dv8tion.jda.api.entities.TextChannel;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
@@ -141,8 +140,12 @@ public class SetupServiceBean implements SetupService {
|
||||
@Transactional
|
||||
public void showExceptionMessage(Throwable throwable, AServerChannelUserId aServerChannelUserId) {
|
||||
Optional<TextChannel> channelOptional = botService.getTextChannelFromServerOptional(aServerChannelUserId.getGuildId(), aServerChannelUserId.getChannelId());
|
||||
Member member = botService.getMemberInServer(aServerChannelUserId.getGuildId(), aServerChannelUserId.getUserId());
|
||||
channelOptional.ifPresent(textChannel -> exceptionService.reportExceptionToChannel(throwable, textChannel, member));
|
||||
botService.getMemberInServerAsync(aServerChannelUserId.getGuildId(), aServerChannelUserId.getUserId()).thenAccept(member ->
|
||||
channelOptional.ifPresent(textChannel -> exceptionService.reportExceptionToChannel(throwable, textChannel, member))
|
||||
).exceptionally(innserThrowable -> {
|
||||
log.error("Failed to report exception message for exception {} for user {} in channel {} in server {}.", throwable, aServerChannelUserId.getUserId(), aServerChannelUserId.getChannelId(), aServerChannelUserId.getGuildId(), innserThrowable);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
@Transactional
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
package dev.sheldan.abstracto.core.service;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.FullUserInServer;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.core.service.management.UserInServerService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class UserInServerServiceBean implements UserInServerService {
|
||||
|
||||
@Autowired
|
||||
private BotService botService;
|
||||
|
||||
@Override
|
||||
public FullUserInServer getFullUser(AUserInAServer aUserInAServer) {
|
||||
return FullUserInServer
|
||||
.builder()
|
||||
.member(botService.getMemberInServer(aUserInAServer))
|
||||
.aUserInAServer(aUserInAServer)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -1,15 +1,18 @@
|
||||
package dev.sheldan.abstracto.core.command.handler;
|
||||
|
||||
import net.dv8tion.jda.api.entities.*;
|
||||
import net.dv8tion.jda.api.requests.RestAction;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@@ -44,25 +47,27 @@ public class MemberParameterHandlerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testProperMemberMention() {
|
||||
oneMemberInIterator();
|
||||
String input = getUserMention();
|
||||
Member parsed = (Member) testUnit.handle(input, iterators, Member.class, null);
|
||||
Assert.assertEquals(parsed, member);
|
||||
CompletableFuture<Member> parsed = (CompletableFuture) testUnit.handleAsync(input, iterators, Member.class, null);
|
||||
Assert.assertEquals(parsed.join(), member);
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testMemberById() {
|
||||
setupMessage();
|
||||
String input = USER_ID.toString();
|
||||
Member parsed = (Member) testUnit.handle(input, null, Member.class, message);
|
||||
Assert.assertEquals(parsed, member);
|
||||
CompletableFuture<Member> parsed = (CompletableFuture) testUnit.handleAsync(input, null, Member.class, message);
|
||||
Assert.assertEquals(parsed.join(), member);
|
||||
}
|
||||
|
||||
@Test(expected = NumberFormatException.class)
|
||||
public void testInvalidMemberMention() {
|
||||
String input = "test";
|
||||
testUnit.handle(input, null, Member.class, null);
|
||||
testUnit.handleAsync(input, null, Member.class, null);
|
||||
}
|
||||
|
||||
private String getUserMention() {
|
||||
@@ -76,7 +81,9 @@ public class MemberParameterHandlerTest {
|
||||
|
||||
private void setupMessage() {
|
||||
when(message.getGuild()).thenReturn(guild);
|
||||
when(guild.getMemberById(USER_ID)).thenReturn(member);
|
||||
RestAction<Member> restAction = Mockito.mock(RestAction.class);
|
||||
when(restAction.submit()).thenReturn(CompletableFuture.completedFuture(member));
|
||||
when(guild.retrieveMemberById(USER_ID)).thenReturn(restAction);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -21,12 +21,19 @@ public class MinIntegerValueValidator implements ParameterValidator {
|
||||
if(value == null) {
|
||||
throw new IllegalArgumentException("Object to validate must not be null");
|
||||
}
|
||||
if(!(value instanceof Long)) {
|
||||
boolean isLong = value instanceof Long;
|
||||
boolean isInteger = value instanceof Integer;
|
||||
if(!isLong && !isInteger) {
|
||||
throw new ValidatorConfigException("Incorrect value passed to max value validator.");
|
||||
}
|
||||
SingleNumberValidatorParam param = (SingleNumberValidatorParam) getParameters().get(0);
|
||||
Long longValue = (Long) value;
|
||||
return longValue >= param.getNumber();
|
||||
if(isLong) {
|
||||
Long longValue = (Long) value;
|
||||
return longValue >= param.getNumber();
|
||||
} else {
|
||||
Integer integerValue = (Integer) value;
|
||||
return integerValue >= param.getNumber();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -3,8 +3,12 @@ package dev.sheldan.abstracto.core.command.handler;
|
||||
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public interface CommandParameterHandler {
|
||||
boolean handles(Class clazz);
|
||||
Object handle(String input, CommandParameterIterators iterators, Class clazz, Message context);
|
||||
default boolean async() { return false; }
|
||||
default Object handle(String input, CommandParameterIterators iterators, Class clazz, Message context) { return new Object();}
|
||||
default CompletableFuture handleAsync(String input, CommandParameterIterators iterators, Class clazz, Message context) { return CompletableFuture.completedFuture(null); }
|
||||
Integer getPriority();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package dev.sheldan.abstracto.core.models;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
public class FutureMemberPair {
|
||||
private CompletableFuture<Member> firstMember;
|
||||
private CompletableFuture<Member> secondMember;
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package dev.sheldan.abstracto.core.models;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
public class MemberPair {
|
||||
private Member firstMember;
|
||||
private Member secondMember;
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package dev.sheldan.abstracto.core.models;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
public class ServerChannelMessageUser {
|
||||
private Long serverId;
|
||||
private Long channelId;
|
||||
private Long messageId;
|
||||
private Long userId;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user