[AB-93] changing how MessageToSend handles attached plaintext files

This commit is contained in:
Sheldan
2023-05-18 22:32:56 +02:00
parent ca530949c6
commit 3df688571f
9 changed files with 64 additions and 155 deletions

View File

@@ -7,7 +7,6 @@ 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.FeatureDefinition;
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
import dev.sheldan.abstracto.core.exception.UploadFileTooLargeException;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.service.ChannelService;
@@ -25,8 +24,6 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.io.File;
import java.io.IOException;
import java.time.Duration;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
@@ -46,8 +43,6 @@ import java.util.concurrent.CompletableFuture;
public class ExportEmoteStats extends AbstractConditionableCommand {
public static final String DOWNLOAD_EMOTE_STATS_NO_STATS_AVAILABLE_RESPONSE_TEMPLATE_KEY = "downloadEmoteStats_no_stats_available_response";
public static final String DOWNLOAD_EMOTE_STATS_FILE_NAME_TEMPLATE_KEY = "downloadEmoteStats_file_name";
public static final String DOWNLOAD_EMOTE_STATS_FILE_CONTENT_TEMPLATE_KEY = "downloadEmoteStats_file_content";
public static final String DOWNLOAD_EMOTE_STATS_RESPONSE_TEMPLATE_KEY = "downloadEmoteStats_response";
@Autowired
private ServerManagementService serverManagementService;
@@ -93,30 +88,10 @@ public class ExportEmoteStats extends AbstractConditionableCommand {
.requester(commandContext.getAuthor())
.statsSince(toUseForModel)
.build();
String fileName = templateService.renderTemplate(DOWNLOAD_EMOTE_STATS_FILE_NAME_TEMPLATE_KEY, model);
String fileContent = templateService.renderTemplate(DOWNLOAD_EMOTE_STATS_FILE_CONTENT_TEMPLATE_KEY, model);
model.setEmoteStatsFileName(fileName);
File tempFile = fileService.createTempFile(fileName);
try {
fileService.writeContentToFile(tempFile, fileContent);
long maxFileSize = commandContext.getGuild().getMaxFileSize();
// in this case, we cannot upload the file, so we need to fail
if(tempFile.length() > maxFileSize) {
throw new UploadFileTooLargeException(tempFile.length(), maxFileSize);
}
MessageToSend messageToSend = templateService.renderEmbedTemplate(DOWNLOAD_EMOTE_STATS_RESPONSE_TEMPLATE_KEY, model, actualServer.getId());
messageToSend.getAttachedFiles().get(0).setFile(tempFile.getAbsoluteFile());
return FutureUtils.toSingleFutureGeneric(channelService.sendMessageToSendToChannel(messageToSend, commandContext.getChannel()))
.thenApply(unused -> CommandResult.fromIgnored());
} catch (IOException e) {
throw new AbstractoRunTimeException(e);
} finally {
try {
fileService.safeDelete(tempFile);
} catch (IOException e) {
log.error("Failed to delete temporary export emote statistics file {}.", tempFile.getAbsoluteFile(), e);
}
}
MessageToSend messageToSend = templateService.renderEmbedTemplate(DOWNLOAD_EMOTE_STATS_RESPONSE_TEMPLATE_KEY, model, actualServer.getId());
return FutureUtils.toSingleFutureGeneric(channelService.sendMessageToSendToChannel(messageToSend, commandContext.getChannel()))
.thenAccept(unused -> fileService.safeDeleteIgnoreException(messageToSend.getAttachedFiles().get(0).getFile()))
.thenApply(unused -> CommandResult.fromIgnored());
}
@Override

View File

@@ -2,8 +2,6 @@ package dev.sheldan.abstracto.statistic.emote.command;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
import dev.sheldan.abstracto.core.exception.UploadFileTooLargeException;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
@@ -14,7 +12,6 @@ import dev.sheldan.abstracto.statistic.config.StatisticFeatureDefinition;
import dev.sheldan.abstracto.statistic.emote.model.DownloadEmoteStatsModel;
import dev.sheldan.abstracto.statistic.emote.model.database.UsedEmote;
import dev.sheldan.abstracto.statistic.emote.service.management.UsedEmoteManagementService;
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
import dev.sheldan.abstracto.core.templating.service.TemplateService;
import org.junit.Assert;
import org.junit.Test;
@@ -22,11 +19,8 @@ import org.junit.runner.RunWith;
import org.mockito.*;
import org.mockito.junit.MockitoJUnitRunner;
import java.io.File;
import java.io.IOException;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
@@ -77,53 +71,11 @@ public class ExportEmoteStatsTest {
verify(channelService, times(1)).sendEmbedTemplateInTextChannelList(eq(DOWNLOAD_EMOTE_STATS_NO_STATS_AVAILABLE_RESPONSE_TEMPLATE_KEY), any(), eq(commandContext.getChannel()));
}
@Test(expected = AbstractoRunTimeException.class)
public void testFileIOException() throws IOException {
CommandContext commandContext = CommandTestUtilities.getNoParameters();
mockServerAndFileRendering(commandContext);
File file = Mockito.mock(File.class);
when(fileService.createTempFile(FILE_NAME)).thenReturn(file);
doThrow(new IOException()).when(fileService).writeContentToFile(file, FILE_CONTENT);
testUnit.executeAsync(commandContext);
}
@Test(expected = UploadFileTooLargeException.class)
public void testExportAllEmoteStatsTooBig() throws IOException {
CommandContext commandContext = CommandTestUtilities.getNoParameters();
when(commandContext.getGuild().getMaxFileSize()).thenReturn(2L);
mockServerAndFileRendering(commandContext);
File file = Mockito.mock(File.class);
when(fileService.createTempFile(FILE_NAME)).thenReturn(file);
when(file.length()).thenReturn(3L);
MessageToSend messageToSend = Mockito.mock(MessageToSend.class);
CompletableFuture<CommandResult> asyncResult = testUnit.executeAsync(commandContext);
CommandTestUtilities.checkSuccessfulCompletionAsync(asyncResult);
verify(fileService, times(1)).writeContentToFile(file, FILE_CONTENT);
verify(fileService, times(1)).safeDelete(file);
verifyModel();
}
@Test
public void testFeature() {
Assert.assertEquals(StatisticFeatureDefinition.EMOTE_TRACKING, testUnit.getFeature());
}
private void verifyModel() {
DownloadEmoteStatsModel model = modelArgumentCaptor.getValue();
Assert.assertEquals(1, model.getEmotes().size());
Assert.assertEquals(usedEmote, model.getEmotes().get(0));
}
private void mockServerAndFileRendering(CommandContext commandContext) {
when(commandContext.getGuild().getIdLong()).thenReturn(SERVER_ID);
AServer server = Mockito.mock(AServer.class);
when(serverManagementService.loadServer(SERVER_ID)).thenReturn(server);
List<UsedEmote> usedEmotes = Arrays.asList(usedEmote);
when(usedEmoteManagementService.loadEmoteUsagesForServerSince(server, Instant.EPOCH)).thenReturn(usedEmotes);
when(templateService.renderTemplate(eq(DOWNLOAD_EMOTE_STATS_FILE_NAME_TEMPLATE_KEY), modelArgumentCaptor.capture())).thenReturn(FILE_NAME);
when(templateService.renderTemplate(eq(DOWNLOAD_EMOTE_STATS_FILE_CONTENT_TEMPLATE_KEY), any())).thenReturn(FILE_CONTENT);
}
@Test
public void validateCommand() {
CommandConfigValidator.validateCommandConfiguration(testUnit.getConfiguration());