Some more tests

This commit is contained in:
Tyrrrz 2021-09-15 00:33:53 +03:00
parent 402b5cc7d0
commit af11064a85
12 changed files with 513 additions and 101 deletions

View file

@ -1,4 +1,5 @@
using System; using System;
using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Text.Json; using System.Text.Json;
@ -23,9 +24,12 @@ namespace DiscordChatExporter.Cli.Tests.Fixtures
Guid.NewGuid().ToString() Guid.NewGuid().ToString()
); );
public async ValueTask<IHtmlDocument> ExportAsHtmlAsync(Snowflake channelId) public ExportWrapperFixture() => DirectoryEx.Reset(DirPath);
private async ValueTask<string> ExportAsync(Snowflake channelId, ExportFormat format)
{ {
var filePath = Path.Combine(DirPath, channelId + ".html"); var fileName = channelId.ToString() + '.' + format.GetFileExtension();
var filePath = Path.Combine(DirPath, fileName);
// Perform export only if it hasn't been done before // Perform export only if it hasn't been done before
if (!File.Exists(filePath)) if (!File.Exists(filePath))
@ -35,83 +39,61 @@ namespace DiscordChatExporter.Cli.Tests.Fixtures
TokenValue = Secrets.DiscordToken, TokenValue = Secrets.DiscordToken,
IsBotToken = Secrets.IsDiscordTokenBot, IsBotToken = Secrets.IsDiscordTokenBot,
ChannelIds = new[] { channelId }, ChannelIds = new[] { channelId },
ExportFormat = ExportFormat.HtmlDark, ExportFormat = format,
OutputPath = filePath OutputPath = filePath
}.ExecuteAsync(new FakeConsole()); }.ExecuteAsync(new FakeConsole());
} }
var data = await File.ReadAllTextAsync(filePath); return await File.ReadAllTextAsync(filePath);
}
public async ValueTask<IHtmlDocument> ExportAsHtmlAsync(Snowflake channelId)
{
var data = await ExportAsync(channelId, ExportFormat.HtmlDark);
return Html.Parse(data); return Html.Parse(data);
} }
public async ValueTask<JsonElement> ExportAsJsonAsync(Snowflake channelId) public async ValueTask<JsonElement> ExportAsJsonAsync(Snowflake channelId)
{ {
var filePath = Path.Combine(DirPath, channelId + ".json"); var data = await ExportAsync(channelId, ExportFormat.Json);
// Perform export only if it hasn't been done before
if (!File.Exists(filePath))
{
await new ExportChannelsCommand
{
TokenValue = Secrets.DiscordToken,
IsBotToken = Secrets.IsDiscordTokenBot,
ChannelIds = new[] { channelId },
ExportFormat = ExportFormat.Json,
OutputPath = filePath
}.ExecuteAsync(new FakeConsole());
}
var data = await File.ReadAllTextAsync(filePath);
return Json.Parse(data); return Json.Parse(data);
} }
public async ValueTask<string> ExportAsPlainTextAsync(Snowflake channelId) public async ValueTask<string> ExportAsPlainTextAsync(Snowflake channelId)
{ {
var filePath = Path.Combine(DirPath, channelId + ".txt"); var data = await ExportAsync(channelId, ExportFormat.PlainText);
return data;
// Perform export only if it hasn't been done before
if (!File.Exists(filePath))
{
await new ExportChannelsCommand
{
TokenValue = Secrets.DiscordToken,
IsBotToken = Secrets.IsDiscordTokenBot,
ChannelIds = new[] { channelId },
ExportFormat = ExportFormat.PlainText,
OutputPath = filePath
}.ExecuteAsync(new FakeConsole());
}
return await File.ReadAllTextAsync(filePath);
} }
public async ValueTask<string> ExportAsCsvAsync(Snowflake channelId) public async ValueTask<string> ExportAsCsvAsync(Snowflake channelId)
{ {
var filePath = Path.Combine(DirPath, channelId + ".csv"); var data = await ExportAsync(channelId, ExportFormat.Csv);
return data;
}
// Perform export only if it hasn't been done before public async ValueTask<IReadOnlyList<IElement>> GetMessagesAsHtmlAsync(Snowflake channelId)
if (!File.Exists(filePath)) {
{ var document = await ExportAsHtmlAsync(channelId);
await new ExportChannelsCommand return document.QuerySelectorAll("[data-message-id]").ToArray();
{ }
TokenValue = Secrets.DiscordToken,
IsBotToken = Secrets.IsDiscordTokenBot,
ChannelIds = new[] { channelId },
ExportFormat = ExportFormat.Csv,
OutputPath = filePath
}.ExecuteAsync(new FakeConsole());
}
return await File.ReadAllTextAsync(filePath); public async ValueTask<IReadOnlyList<JsonElement>> GetMessagesAsJsonAsync(Snowflake channelId)
{
var document = await ExportAsJsonAsync(channelId);
return document.GetProperty("messages").EnumerateArray().ToArray();
} }
public async ValueTask<IElement> GetMessageAsHtmlAsync(Snowflake channelId, Snowflake messageId) public async ValueTask<IElement> GetMessageAsHtmlAsync(Snowflake channelId, Snowflake messageId)
{ {
var document = await ExportAsHtmlAsync(channelId); var messages = await GetMessagesAsHtmlAsync(channelId);
var message = document.QuerySelector("#message-" + messageId); var message = messages.SingleOrDefault(e =>
string.Equals(
e.GetAttribute("data-message-id"),
messageId.ToString(),
StringComparison.OrdinalIgnoreCase
)
);
if (message is null) if (message is null)
{ {
@ -125,16 +107,15 @@ namespace DiscordChatExporter.Cli.Tests.Fixtures
public async ValueTask<JsonElement> GetMessageAsJsonAsync(Snowflake channelId, Snowflake messageId) public async ValueTask<JsonElement> GetMessageAsJsonAsync(Snowflake channelId, Snowflake messageId)
{ {
var document = await ExportAsJsonAsync(channelId); var messages = await GetMessagesAsJsonAsync(channelId);
var message = document var message = messages.FirstOrDefault(j =>
.GetProperty("messages") string.Equals(
.EnumerateArray()
.SingleOrDefault(j => string.Equals(
j.GetProperty("id").GetString(), j.GetProperty("id").GetString(),
messageId.ToString(), messageId.ToString(),
StringComparison.OrdinalIgnoreCase StringComparison.OrdinalIgnoreCase
)); )
);
if (message.ValueKind == JsonValueKind.Undefined) if (message.ValueKind == JsonValueKind.Undefined)
{ {
@ -146,15 +127,6 @@ namespace DiscordChatExporter.Cli.Tests.Fixtures
return message; return message;
} }
public void Dispose() public void Dispose() => DirectoryEx.DeleteIfExists(DirPath);
{
try
{
Directory.Delete(DirPath, true);
}
catch (DirectoryNotFoundException)
{
}
}
} }
} }

View file

@ -0,0 +1,23 @@
using System;
using System.IO;
using DiscordChatExporter.Cli.Tests.Utils;
namespace DiscordChatExporter.Cli.Tests.Fixtures
{
public class TempOutputFixture : IDisposable
{
public string DirPath { get; } = Path.Combine(
Path.GetDirectoryName(typeof(TempOutputFixture).Assembly.Location) ?? Directory.GetCurrentDirectory(),
"Temp",
Guid.NewGuid().ToString()
);
public TempOutputFixture() => DirectoryEx.Reset(DirPath);
public string GetTempFilePath(string fileName) => Path.Combine(DirPath, fileName);
public string GetTempFilePath() => GetTempFilePath(Guid.NewGuid() + ".tmp");
public void Dispose() => DirectoryEx.DeleteIfExists(DirPath);
}
}

View file

@ -6,7 +6,7 @@ using Xunit;
namespace DiscordChatExporter.Cli.Tests.Specs.CsvWriting namespace DiscordChatExporter.Cli.Tests.Specs.CsvWriting
{ {
public record GeneralSpecs(ExportWrapperFixture ExportWrapper) : IClassFixture<ExportWrapperFixture> public record ContentSpecs(ExportWrapperFixture ExportWrapper) : IClassFixture<ExportWrapperFixture>
{ {
[Fact] [Fact]
public async Task Messages_are_exported_correctly() public async Task Messages_are_exported_correctly()

View file

@ -0,0 +1,160 @@
using System;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using CliFx.Infrastructure;
using DiscordChatExporter.Cli.Commands;
using DiscordChatExporter.Cli.Tests.Fixtures;
using DiscordChatExporter.Cli.Tests.Infra;
using DiscordChatExporter.Cli.Tests.TestData;
using DiscordChatExporter.Core.Discord;
using DiscordChatExporter.Core.Exporting;
using FluentAssertions;
using JsonExtensions;
using Xunit;
namespace DiscordChatExporter.Cli.Tests.Specs
{
public record DateRangeSpecs(TempOutputFixture TempOutput) : IClassFixture<TempOutputFixture>
{
[Fact]
public async Task Messages_filtered_after_specific_date_only_include_messages_sent_after_that_date()
{
// Arrange
var after = new DateTimeOffset(2021, 07, 24, 0, 0, 0, TimeSpan.Zero);
var filePath = TempOutput.GetTempFilePath();
// Act
await new ExportChannelsCommand
{
TokenValue = Secrets.DiscordToken,
IsBotToken = Secrets.IsDiscordTokenBot,
ChannelIds = new[] { ChannelIds.DateRangeTestCases },
ExportFormat = ExportFormat.Json,
OutputPath = filePath,
After = Snowflake.FromDate(after)
}.ExecuteAsync(new FakeConsole());
var data = await File.ReadAllTextAsync(filePath);
var document = Json.Parse(data);
var timestamps = document
.GetProperty("messages")
.EnumerateArray()
.Select(j => j.GetProperty("timestamp").GetDateTimeOffset())
.ToArray();
// Assert
timestamps.All(t => t > after).Should().BeTrue();
timestamps.Should().BeEquivalentTo(new[]
{
new DateTimeOffset(2021, 07, 24, 13, 49, 13, TimeSpan.Zero),
new DateTimeOffset(2021, 07, 24, 14, 52, 38, TimeSpan.Zero),
new DateTimeOffset(2021, 07, 24, 14, 52, 39, TimeSpan.Zero),
new DateTimeOffset(2021, 07, 24, 14, 52, 40, TimeSpan.Zero),
new DateTimeOffset(2021, 09, 08, 14, 26, 35, TimeSpan.Zero)
}, o =>
{
return o
.Using<DateTimeOffset>(ctx =>
ctx.Subject.Should().BeCloseTo(ctx.Expectation, TimeSpan.FromSeconds(1))
)
.WhenTypeIs<DateTimeOffset>();
});
}
[Fact]
public async Task Messages_filtered_before_specific_date_only_include_messages_sent_before_that_date()
{
// Arrange
var before = new DateTimeOffset(2021, 07, 24, 0, 0, 0, TimeSpan.Zero);
var filePath = TempOutput.GetTempFilePath();
// Act
await new ExportChannelsCommand
{
TokenValue = Secrets.DiscordToken,
IsBotToken = Secrets.IsDiscordTokenBot,
ChannelIds = new[] { ChannelIds.DateRangeTestCases },
ExportFormat = ExportFormat.Json,
OutputPath = filePath,
Before = Snowflake.FromDate(before)
}.ExecuteAsync(new FakeConsole());
var data = await File.ReadAllTextAsync(filePath);
var document = Json.Parse(data);
var timestamps = document
.GetProperty("messages")
.EnumerateArray()
.Select(j => j.GetProperty("timestamp").GetDateTimeOffset())
.ToArray();
// Assert
timestamps.All(t => t < before).Should().BeTrue();
timestamps.Should().BeEquivalentTo(new[]
{
new DateTimeOffset(2021, 07, 19, 13, 34, 18, TimeSpan.Zero),
new DateTimeOffset(2021, 07, 19, 15, 58, 48, TimeSpan.Zero),
new DateTimeOffset(2021, 07, 19, 17, 23, 58, TimeSpan.Zero)
}, o =>
{
return o
.Using<DateTimeOffset>(ctx =>
ctx.Subject.Should().BeCloseTo(ctx.Expectation, TimeSpan.FromSeconds(1))
)
.WhenTypeIs<DateTimeOffset>();
});
}
[Fact]
public async Task Messages_filtered_between_specific_dates_only_include_messages_sent_between_those_dates()
{
// Arrange
var after = new DateTimeOffset(2021, 07, 24, 0, 0, 0, TimeSpan.Zero);
var before = new DateTimeOffset(2021, 08, 01, 0, 0, 0, TimeSpan.Zero);
var filePath = TempOutput.GetTempFilePath();
// Act
await new ExportChannelsCommand
{
TokenValue = Secrets.DiscordToken,
IsBotToken = Secrets.IsDiscordTokenBot,
ChannelIds = new[] { ChannelIds.DateRangeTestCases },
ExportFormat = ExportFormat.Json,
OutputPath = filePath,
Before = Snowflake.FromDate(before),
After = Snowflake.FromDate(after)
}.ExecuteAsync(new FakeConsole());
var data = await File.ReadAllTextAsync(filePath);
var document = Json.Parse(data);
var timestamps = document
.GetProperty("messages")
.EnumerateArray()
.Select(j => j.GetProperty("timestamp").GetDateTimeOffset())
.ToArray();
// Assert
timestamps.All(t => t < before && t > after).Should().BeTrue();
timestamps.Should().BeEquivalentTo(new[]
{
new DateTimeOffset(2021, 07, 24, 13, 49, 13, TimeSpan.Zero),
new DateTimeOffset(2021, 07, 24, 14, 52, 38, TimeSpan.Zero),
new DateTimeOffset(2021, 07, 24, 14, 52, 39, TimeSpan.Zero),
new DateTimeOffset(2021, 07, 24, 14, 52, 40, TimeSpan.Zero)
}, o =>
{
return o
.Using<DateTimeOffset>(ctx =>
ctx.Subject.Should().BeCloseTo(ctx.Expectation, TimeSpan.FromSeconds(1))
)
.WhenTypeIs<DateTimeOffset>();
});
}
}
}

View file

@ -0,0 +1,135 @@
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using CliFx.Infrastructure;
using DiscordChatExporter.Cli.Commands;
using DiscordChatExporter.Cli.Tests.Fixtures;
using DiscordChatExporter.Cli.Tests.Infra;
using DiscordChatExporter.Cli.Tests.TestData;
using DiscordChatExporter.Core.Exporting;
using DiscordChatExporter.Core.Exporting.Filtering;
using FluentAssertions;
using JsonExtensions;
using Xunit;
namespace DiscordChatExporter.Cli.Tests.Specs
{
public record FilterSpecs(TempOutputFixture TempOutput) : IClassFixture<TempOutputFixture>
{
[Fact]
public async Task Messages_filtered_by_text_only_include_messages_that_contain_that_text()
{
// Arrange
var filePath = TempOutput.GetTempFilePath();
// Act
await new ExportChannelsCommand
{
TokenValue = Secrets.DiscordToken,
IsBotToken = Secrets.IsDiscordTokenBot,
ChannelIds = new[] { ChannelIds.FilterTestCases },
ExportFormat = ExportFormat.Json,
OutputPath = filePath,
MessageFilter = MessageFilter.Parse("some text")
}.ExecuteAsync(new FakeConsole());
var data = await File.ReadAllTextAsync(filePath);
var document = Json.Parse(data);
// Assert
document
.GetProperty("messages")
.EnumerateArray()
.Select(j => j.GetProperty("content").GetString())
.Should()
.ContainSingle("Some random text");
}
[Fact]
public async Task Messages_filtered_by_author_only_include_messages_sent_by_that_author()
{
// Arrange
var filePath = TempOutput.GetTempFilePath();
// Act
await new ExportChannelsCommand
{
TokenValue = Secrets.DiscordToken,
IsBotToken = Secrets.IsDiscordTokenBot,
ChannelIds = new[] { ChannelIds.FilterTestCases },
ExportFormat = ExportFormat.Json,
OutputPath = filePath,
MessageFilter = MessageFilter.Parse("from:Tyrrrz")
}.ExecuteAsync(new FakeConsole());
var data = await File.ReadAllTextAsync(filePath);
var document = Json.Parse(data);
// Assert
document
.GetProperty("messages")
.EnumerateArray()
.Select(j => j.GetProperty("author").GetProperty("name").GetString())
.Should()
.AllBe("Tyrrrz");
}
[Fact]
public async Task Messages_filtered_by_content_only_include_messages_that_have_that_content()
{
// Arrange
var filePath = TempOutput.GetTempFilePath();
// Act
await new ExportChannelsCommand
{
TokenValue = Secrets.DiscordToken,
IsBotToken = Secrets.IsDiscordTokenBot,
ChannelIds = new[] { ChannelIds.FilterTestCases },
ExportFormat = ExportFormat.Json,
OutputPath = filePath,
MessageFilter = MessageFilter.Parse("has:image")
}.ExecuteAsync(new FakeConsole());
var data = await File.ReadAllTextAsync(filePath);
var document = Json.Parse(data);
// Assert
document
.GetProperty("messages")
.EnumerateArray()
.Select(j => j.GetProperty("content").GetString())
.Should()
.ContainSingle("This has image");
}
[Fact]
public async Task Messages_filtered_by_mention_only_include_messages_that_have_that_mention()
{
// Arrange
var filePath = TempOutput.GetTempFilePath();
// Act
await new ExportChannelsCommand
{
TokenValue = Secrets.DiscordToken,
IsBotToken = Secrets.IsDiscordTokenBot,
ChannelIds = new[] { ChannelIds.FilterTestCases },
ExportFormat = ExportFormat.Json,
OutputPath = filePath,
MessageFilter = MessageFilter.Parse("mentions:Tyrrrz")
}.ExecuteAsync(new FakeConsole());
var data = await File.ReadAllTextAsync(filePath);
var document = Json.Parse(data);
// Assert
document
.GetProperty("messages")
.EnumerateArray()
.Select(j => j.GetProperty("content").GetString())
.Should()
.ContainSingle("This has mention");
}
}
}

View file

@ -8,26 +8,16 @@ using Xunit;
namespace DiscordChatExporter.Cli.Tests.Specs.HtmlWriting namespace DiscordChatExporter.Cli.Tests.Specs.HtmlWriting
{ {
public record GeneralSpecs(ExportWrapperFixture ExportWrapper) : IClassFixture<ExportWrapperFixture> public record ContentSpecs(ExportWrapperFixture ExportWrapper) : IClassFixture<ExportWrapperFixture>
{ {
[Fact] [Fact]
public async Task Messages_are_exported_correctly() public async Task Messages_are_exported_correctly()
{ {
// Act // Act
var document = await ExportWrapper.ExportAsHtmlAsync(ChannelIds.DateRangeTestCases); var messages = await ExportWrapper.GetMessagesAsHtmlAsync(ChannelIds.DateRangeTestCases);
var messageIds = document
.QuerySelectorAll(".chatlog__message")
.Select(e => e.GetAttribute("data-message-id"))
.ToArray();
var messageTexts = document
.QuerySelectorAll(".chatlog__content")
.Select(e => e.Text().Trim())
.ToArray();
// Assert // Assert
messageIds.Should().Equal( messages.Select(e => e.GetAttribute("data-message-id")).Should().Equal(
"866674314627121232", "866674314627121232",
"866710679758045195", "866710679758045195",
"866732113319428096", "866732113319428096",
@ -38,7 +28,7 @@ namespace DiscordChatExporter.Cli.Tests.Specs.HtmlWriting
"885169254029213696" "885169254029213696"
); );
messageTexts.Should().Equal( messages.Select(e => e.QuerySelector(".chatlog__content")?.Text().Trim()).Should().Equal(
"Hello world", "Hello world",
"Goodbye world", "Goodbye world",
"Foo bar", "Foo bar",

View file

@ -7,28 +7,16 @@ using Xunit;
namespace DiscordChatExporter.Cli.Tests.Specs.JsonWriting namespace DiscordChatExporter.Cli.Tests.Specs.JsonWriting
{ {
public record GeneralSpecs(ExportWrapperFixture ExportWrapper) : IClassFixture<ExportWrapperFixture> public record ContentSpecs(ExportWrapperFixture ExportWrapper) : IClassFixture<ExportWrapperFixture>
{ {
[Fact] [Fact]
public async Task Messages_are_exported_correctly() public async Task Messages_are_exported_correctly()
{ {
// Act // Act
var document = await ExportWrapper.ExportAsJsonAsync(ChannelIds.DateRangeTestCases); var messages = await ExportWrapper.GetMessagesAsJsonAsync(ChannelIds.DateRangeTestCases);
var messageIds = document
.GetProperty("messages")
.EnumerateArray()
.Select(j => j.GetProperty("id").GetString())
.ToArray();
var messageTexts = document
.GetProperty("messages")
.EnumerateArray()
.Select(j => j.GetProperty("content").GetString())
.ToArray();
// Assert // Assert
messageIds.Should().Equal( messages.Select(j => j.GetProperty("id").GetString()).Should().Equal(
"866674314627121232", "866674314627121232",
"866710679758045195", "866710679758045195",
"866732113319428096", "866732113319428096",
@ -39,7 +27,7 @@ namespace DiscordChatExporter.Cli.Tests.Specs.JsonWriting
"885169254029213696" "885169254029213696"
); );
messageTexts.Should().Equal( messages.Select(j => j.GetProperty("content").GetString()).Should().Equal(
"Hello world", "Hello world",
"Goodbye world", "Goodbye world",
"Foo bar", "Foo bar",

View file

@ -0,0 +1,67 @@
using System.IO;
using System.Threading.Tasks;
using CliFx.Infrastructure;
using DiscordChatExporter.Cli.Commands;
using DiscordChatExporter.Cli.Tests.Fixtures;
using DiscordChatExporter.Cli.Tests.Infra;
using DiscordChatExporter.Cli.Tests.TestData;
using DiscordChatExporter.Core.Exporting;
using DiscordChatExporter.Core.Exporting.Partitioning;
using FluentAssertions;
using Xunit;
namespace DiscordChatExporter.Cli.Tests.Specs
{
public record PartitioningSpecs(TempOutputFixture TempOutput) : IClassFixture<TempOutputFixture>
{
[Fact]
public async Task Messages_partitioned_by_count_are_split_into_multiple_files_correctly()
{
// Arrange
var filePath = TempOutput.GetTempFilePath();
var fileNameWithoutExt = Path.GetFileNameWithoutExtension(filePath);
var dirPath = Path.GetDirectoryName(filePath) ?? Directory.GetCurrentDirectory();
// Act
await new ExportChannelsCommand
{
TokenValue = Secrets.DiscordToken,
IsBotToken = Secrets.IsDiscordTokenBot,
ChannelIds = new[] { ChannelIds.DateRangeTestCases },
ExportFormat = ExportFormat.HtmlDark,
OutputPath = filePath,
PartitionLimit = PartitionLimit.Parse("3")
}.ExecuteAsync(new FakeConsole());
// Assert
Directory.EnumerateFiles(dirPath, fileNameWithoutExt + "*")
.Should()
.HaveCount(3);
}
[Fact]
public async Task Messages_partitioned_by_file_size_are_split_into_multiple_files_correctly()
{
// Arrange
var filePath = TempOutput.GetTempFilePath();
var fileNameWithoutExt = Path.GetFileNameWithoutExtension(filePath);
var dirPath = Path.GetDirectoryName(filePath) ?? Directory.GetCurrentDirectory();
// Act
await new ExportChannelsCommand
{
TokenValue = Secrets.DiscordToken,
IsBotToken = Secrets.IsDiscordTokenBot,
ChannelIds = new[] { ChannelIds.DateRangeTestCases },
ExportFormat = ExportFormat.HtmlDark,
OutputPath = filePath,
PartitionLimit = PartitionLimit.Parse("20kb")
}.ExecuteAsync(new FakeConsole());
// Assert
Directory.EnumerateFiles(dirPath, fileNameWithoutExt + "*")
.Should()
.HaveCount(2);
}
}
}

View file

@ -6,7 +6,7 @@ using Xunit;
namespace DiscordChatExporter.Cli.Tests.Specs.PlainTextWriting namespace DiscordChatExporter.Cli.Tests.Specs.PlainTextWriting
{ {
public record GeneralSpecs(ExportWrapperFixture ExportWrapper) : IClassFixture<ExportWrapperFixture> public record ContentSpecs(ExportWrapperFixture ExportWrapper) : IClassFixture<ExportWrapperFixture>
{ {
[Fact] [Fact]
public async Task Messages_are_exported_correctly() public async Task Messages_are_exported_correctly()

View file

@ -0,0 +1,49 @@
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using CliFx.Infrastructure;
using DiscordChatExporter.Cli.Commands;
using DiscordChatExporter.Cli.Tests.Fixtures;
using DiscordChatExporter.Cli.Tests.Infra;
using DiscordChatExporter.Cli.Tests.TestData;
using DiscordChatExporter.Cli.Tests.Utils;
using DiscordChatExporter.Core.Exporting;
using FluentAssertions;
using Xunit;
namespace DiscordChatExporter.Cli.Tests.Specs
{
public record SelfContainedSpecs(TempOutputFixture TempOutput) : IClassFixture<TempOutputFixture>
{
[Fact]
public async Task Messages_in_self_contained_export_only_reference_local_file_resources()
{
// Arrange
var filePath = TempOutput.GetTempFilePath();
var dirPath = Path.GetDirectoryName(filePath) ?? Directory.GetCurrentDirectory();
// Act
await new ExportChannelsCommand
{
TokenValue = Secrets.DiscordToken,
IsBotToken = Secrets.IsDiscordTokenBot,
ChannelIds = new[] { ChannelIds.SelfContainedTestCases },
ExportFormat = ExportFormat.HtmlDark,
OutputPath = filePath,
ShouldDownloadMedia = true
}.ExecuteAsync(new FakeConsole());
var data = await File.ReadAllTextAsync(filePath);
var document = Html.Parse(data);
// Assert
document
.QuerySelectorAll("body [src]")
.Select(e => e.GetAttribute("src")!)
.Select(f => Path.GetFullPath(f, dirPath))
.All(File.Exists)
.Should()
.BeTrue();
}
}
}

View file

@ -10,8 +10,12 @@ namespace DiscordChatExporter.Cli.Tests.TestData
public static Snowflake EmbedTestCases { get; } = Snowflake.Parse("866472452459462687"); public static Snowflake EmbedTestCases { get; } = Snowflake.Parse("866472452459462687");
public static Snowflake FilterTestCases { get; } = Snowflake.Parse("866744075033641020");
public static Snowflake MentionTestCases { get; } = Snowflake.Parse("866458801389174794"); public static Snowflake MentionTestCases { get; } = Snowflake.Parse("866458801389174794");
public static Snowflake ReplyTestCases { get; } = Snowflake.Parse("866459871934677052"); public static Snowflake ReplyTestCases { get; } = Snowflake.Parse("866459871934677052");
public static Snowflake SelfContainedTestCases { get; } = Snowflake.Parse("887441432678379560");
} }
} }

View file

@ -0,0 +1,24 @@
using System.IO;
namespace DiscordChatExporter.Cli.Tests.Utils
{
internal static class DirectoryEx
{
public static void DeleteIfExists(string dirPath, bool recursive = true)
{
try
{
Directory.Delete(dirPath, recursive);
}
catch (DirectoryNotFoundException)
{
}
}
public static void Reset(string dirPath)
{
DeleteIfExists(dirPath);
Directory.CreateDirectory(dirPath);
}
}
}