Clean up tests

pull/710/head
Tyrrrz 3 years ago
parent 301bca0633
commit 67313f2b22

@ -5,6 +5,7 @@
<IsTestProject>true</IsTestProject> <IsTestProject>true</IsTestProject>
<CollectCoverage>true</CollectCoverage> <CollectCoverage>true</CollectCoverage>
<CoverletOutputFormat>opencover</CoverletOutputFormat> <CoverletOutputFormat>opencover</CoverletOutputFormat>
<NoWarn>$(NoWarn);xUnit1013</NoWarn>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>

@ -1,69 +1,26 @@
using System; using System.Linq;
using System.IO;
using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using AngleSharp.Dom; using AngleSharp.Dom;
using CliFx.Infrastructure;
using DiscordChatExporter.Cli.Commands;
using DiscordChatExporter.Cli.Tests.Fixtures; using DiscordChatExporter.Cli.Tests.Fixtures;
using DiscordChatExporter.Cli.Tests.Infra;
using DiscordChatExporter.Cli.Tests.TestData; using DiscordChatExporter.Cli.Tests.TestData;
using DiscordChatExporter.Cli.Tests.Utils;
using DiscordChatExporter.Core.Discord; using DiscordChatExporter.Core.Discord;
using DiscordChatExporter.Core.Exporting;
using FluentAssertions; using FluentAssertions;
using JsonExtensions;
using Xunit; using Xunit;
using Xunit.Abstractions;
namespace DiscordChatExporter.Cli.Tests namespace DiscordChatExporter.Cli.Tests
{ {
public class EmbedSpecs : IClassFixture<TempOutputFixture> public record EmbedSpecs(ExportWrapperFixture ExportWrapper) : IClassFixture<ExportWrapperFixture>
{ {
private readonly ITestOutputHelper _testOutput;
private readonly TempOutputFixture _tempOutput;
public EmbedSpecs(ITestOutputHelper testOutput, TempOutputFixture tempOutput)
{
_testOutput = testOutput;
_tempOutput = tempOutput;
}
[Fact] [Fact]
public async Task Message_with_an_embed_is_rendered_correctly_in_JSON() public async Task Message_with_an_embed_is_rendered_correctly_in_JSON()
{ {
// Arrange
var outputFilePath = _tempOutput.GetTempFilePath("json");
// Act // Act
var jsonData = await GlobalCache.WrapAsync("embed-specs-output-json", async () => var message = await ExportWrapper.GetMessageAsJsonAsync(
{ ChannelIds.EmbedTestCases,
await new ExportChannelsCommand Snowflake.Parse("866769910729146400")
{ );
TokenValue = Secrets.DiscordToken,
IsBotToken = Secrets.IsDiscordTokenBot,
ChannelIds = new[] {Snowflake.Parse(ChannelIds.EmbedTestCases)},
ExportFormat = ExportFormat.Json,
OutputPath = outputFilePath
}.ExecuteAsync(new FakeConsole());
return await File.ReadAllTextAsync(outputFilePath);
});
_testOutput.WriteLine(jsonData);
var json = Json.Parse(jsonData);
var messageJson = json
.GetProperty("messages")
.EnumerateArray()
.Single(j => string.Equals(
j.GetProperty("id").GetString(),
"866769910729146400",
StringComparison.OrdinalIgnoreCase
));
var embed = messageJson var embed = message
.GetProperty("embeds") .GetProperty("embeds")
.EnumerateArray() .EnumerateArray()
.Single(); .Single();
@ -102,33 +59,14 @@ namespace DiscordChatExporter.Cli.Tests
[Fact] [Fact]
public async Task Message_with_an_embed_is_rendered_correctly_in_HTML() public async Task Message_with_an_embed_is_rendered_correctly_in_HTML()
{ {
// Arrange
var outputFilePath = _tempOutput.GetTempFilePath("html");
// Act // Act
var htmlData = await GlobalCache.WrapAsync("embed-specs-output-html", async () => var message = await ExportWrapper.GetMessageAsHtmlAsync(
{ ChannelIds.EmbedTestCases,
await new ExportChannelsCommand Snowflake.Parse("866769910729146400")
{ );
TokenValue = Secrets.DiscordToken,
IsBotToken = Secrets.IsDiscordTokenBot,
ChannelIds = new[] {Snowflake.Parse(ChannelIds.EmbedTestCases)},
ExportFormat = ExportFormat.HtmlDark,
OutputPath = outputFilePath
}.ExecuteAsync(new FakeConsole());
return await File.ReadAllTextAsync(outputFilePath);
});
_testOutput.WriteLine(htmlData);
var html = Html.Parse(htmlData);
var messageHtml = html.QuerySelector("#message-866769910729146400");
var messageText = messageHtml?.Text();
// Assert // Assert
messageText.Should().ContainAll( message.Text().Should().ContainAll(
"Embed author", "Embed author",
"Embed title", "Embed title",
"Embed description", "Embed description",
@ -142,30 +80,13 @@ namespace DiscordChatExporter.Cli.Tests
[Fact] [Fact]
public async Task Message_with_a_Spotify_track_is_rendered_using_an_iframe_in_HTML() public async Task Message_with_a_Spotify_track_is_rendered_using_an_iframe_in_HTML()
{ {
// Arrange
var outputFilePath = _tempOutput.GetTempFilePath("html");
// Act // Act
var htmlData = await GlobalCache.WrapAsync("embed-specs-output-html", async () => var message = await ExportWrapper.GetMessageAsHtmlAsync(
{ ChannelIds.EmbedTestCases,
await new ExportChannelsCommand Snowflake.Parse("867886632203976775")
{ );
TokenValue = Secrets.DiscordToken,
IsBotToken = Secrets.IsDiscordTokenBot,
ChannelIds = new[] {Snowflake.Parse(ChannelIds.EmbedTestCases)},
ExportFormat = ExportFormat.HtmlDark,
OutputPath = outputFilePath
}.ExecuteAsync(new FakeConsole());
return await File.ReadAllTextAsync(outputFilePath);
});
_testOutput.WriteLine(htmlData);
var html = Html.Parse(htmlData);
var messageHtml = html.QuerySelector("#message-867886632203976775"); var iframeHtml = message.QuerySelector("iframe");
var iframeHtml = messageHtml?.QuerySelector("iframe");
// Assert // Assert
iframeHtml.Should().NotBeNull(); iframeHtml.Should().NotBeNull();
@ -176,30 +97,13 @@ namespace DiscordChatExporter.Cli.Tests
[Fact] [Fact]
public async Task Message_with_a_YouTube_video_is_rendered_using_an_iframe_in_HTML() public async Task Message_with_a_YouTube_video_is_rendered_using_an_iframe_in_HTML()
{ {
// Arrange
var outputFilePath = _tempOutput.GetTempFilePath("html");
// Act // Act
var htmlData = await GlobalCache.WrapAsync("embed-specs-output-html", async () => var message = await ExportWrapper.GetMessageAsHtmlAsync(
{ ChannelIds.EmbedTestCases,
await new ExportChannelsCommand Snowflake.Parse("866472508588294165")
{ );
TokenValue = Secrets.DiscordToken,
IsBotToken = Secrets.IsDiscordTokenBot,
ChannelIds = new[] {Snowflake.Parse(ChannelIds.EmbedTestCases)},
ExportFormat = ExportFormat.HtmlDark,
OutputPath = outputFilePath
}.ExecuteAsync(new FakeConsole());
return await File.ReadAllTextAsync(outputFilePath);
});
_testOutput.WriteLine(htmlData);
var html = Html.Parse(htmlData);
var messageHtml = html.QuerySelector("#message-866472508588294165"); var iframeHtml = message.QuerySelector("iframe");
var iframeHtml = messageHtml?.QuerySelector("iframe");
// Assert // Assert
iframeHtml.Should().NotBeNull(); iframeHtml.Should().NotBeNull();

@ -0,0 +1,120 @@
using System;
using System.IO;
using System.Linq;
using System.Text.Json;
using System.Threading.Tasks;
using AngleSharp.Dom;
using AngleSharp.Html.Dom;
using CliFx.Infrastructure;
using DiscordChatExporter.Cli.Commands;
using DiscordChatExporter.Cli.Tests.Infra;
using DiscordChatExporter.Cli.Tests.Utils;
using DiscordChatExporter.Core.Discord;
using DiscordChatExporter.Core.Exporting;
using JsonExtensions;
namespace DiscordChatExporter.Cli.Tests.Fixtures
{
public class ExportWrapperFixture : IDisposable
{
private string DirPath { get; } = Path.Combine(
Path.GetDirectoryName(typeof(ExportWrapperFixture).Assembly.Location) ?? Directory.GetCurrentDirectory(),
"ExportCache",
Guid.NewGuid().ToString()
);
public async ValueTask<IHtmlDocument> ExportAsHtmlAsync(Snowflake channelId)
{
var filePath = Path.Combine(DirPath, channelId + ".html");
// 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.HtmlDark,
OutputPath = filePath
}.ExecuteAsync(new FakeConsole());
}
var data = await File.ReadAllTextAsync(filePath);
return Html.Parse(data);
}
public async ValueTask<IElement> GetMessageAsHtmlAsync(Snowflake channelId, Snowflake messageId)
{
var document = await ExportAsHtmlAsync(channelId);
var message = document.QuerySelector("#message-" + messageId);
if (message is null)
{
throw new InvalidOperationException(
$"Message '{messageId}' does not exist in export of channel '{channelId}'."
);
}
return message;
}
public async ValueTask<JsonElement> ExportAsJsonAsync(Snowflake channelId)
{
var filePath = Path.Combine(DirPath, channelId + ".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);
}
public async ValueTask<JsonElement> GetMessageAsJsonAsync(Snowflake channelId, Snowflake messageId)
{
var document = await ExportAsJsonAsync(channelId);
var message = document
.GetProperty("messages")
.EnumerateArray()
.SingleOrDefault(j => string.Equals(
j.GetProperty("id").GetString(),
messageId.ToString(),
StringComparison.OrdinalIgnoreCase
));
if (message.ValueKind == JsonValueKind.Undefined)
{
throw new InvalidOperationException(
$"Message '{messageId}' does not exist in export of channel '{channelId}'."
);
}
return message;
}
public void Dispose()
{
try
{
Directory.Delete(DirPath, true);
}
catch (DirectoryNotFoundException)
{
}
}
}
}

@ -1,31 +0,0 @@
using System;
using System.IO;
namespace DiscordChatExporter.Cli.Tests.Fixtures
{
public class TempOutputFixture : IDisposable
{
public string DirPath => Path.Combine(
Path.GetDirectoryName(typeof(TempOutputFixture).Assembly.Location) ?? Directory.GetCurrentDirectory(),
"Temp",
Guid.NewGuid().ToString()
);
public TempOutputFixture() => Directory.CreateDirectory(DirPath);
public string GetTempFilePath() => Path.Combine(DirPath, Guid.NewGuid().ToString());
public string GetTempFilePath(string extension) => Path.ChangeExtension(GetTempFilePath(), extension);
public void Dispose()
{
try
{
Directory.Delete(DirPath, true);
}
catch (DirectoryNotFoundException)
{
}
}
}
}

@ -1,72 +1,29 @@
using System; using System.Linq;
using System.IO;
using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using AngleSharp.Dom; using AngleSharp.Dom;
using CliFx.Infrastructure;
using DiscordChatExporter.Cli.Commands;
using DiscordChatExporter.Cli.Tests.Fixtures; using DiscordChatExporter.Cli.Tests.Fixtures;
using DiscordChatExporter.Cli.Tests.Infra;
using DiscordChatExporter.Cli.Tests.TestData; using DiscordChatExporter.Cli.Tests.TestData;
using DiscordChatExporter.Cli.Tests.Utils;
using DiscordChatExporter.Core.Discord; using DiscordChatExporter.Core.Discord;
using DiscordChatExporter.Core.Exporting;
using FluentAssertions; using FluentAssertions;
using JsonExtensions;
using Xunit; using Xunit;
using Xunit.Abstractions;
namespace DiscordChatExporter.Cli.Tests namespace DiscordChatExporter.Cli.Tests
{ {
public class MentionSpecs : IClassFixture<TempOutputFixture> public record MentionSpecs(ExportWrapperFixture ExportWrapper) : IClassFixture<ExportWrapperFixture>
{ {
private readonly ITestOutputHelper _testOutput;
private readonly TempOutputFixture _tempOutput;
public MentionSpecs(ITestOutputHelper testOutput, TempOutputFixture tempOutput)
{
_testOutput = testOutput;
_tempOutput = tempOutput;
}
[Fact] [Fact]
public async Task User_mention_is_rendered_correctly_in_JSON() public async Task User_mention_is_rendered_correctly_in_JSON()
{ {
// Arrange
var outputFilePath = _tempOutput.GetTempFilePath("json");
// Act // Act
var jsonData = await GlobalCache.WrapAsync("mention-specs-output-json", async () => var message = await ExportWrapper.GetMessageAsJsonAsync(
{ ChannelIds.MentionTestCases,
await new ExportChannelsCommand Snowflake.Parse("866458840245076028")
{ );
TokenValue = Secrets.DiscordToken,
IsBotToken = Secrets.IsDiscordTokenBot,
ChannelIds = new[] {Snowflake.Parse(ChannelIds.MentionTestCases)},
ExportFormat = ExportFormat.Json,
OutputPath = outputFilePath
}.ExecuteAsync(new FakeConsole());
return await File.ReadAllTextAsync(outputFilePath);
});
_testOutput.WriteLine(jsonData);
var json = Json.Parse(jsonData);
var messageJson = json
.GetProperty("messages")
.EnumerateArray()
.Single(j => string.Equals(
j.GetProperty("id").GetString(),
"866458840245076028",
StringComparison.OrdinalIgnoreCase
));
// Assert // Assert
messageJson.GetProperty("content").GetString().Should().Be("User mention: @Tyrrrz"); message.GetProperty("content").GetString().Should().Be("User mention: @Tyrrrz");
messageJson message
.GetProperty("mentions") .GetProperty("mentions")
.EnumerateArray() .EnumerateArray()
.Select(j => j.GetProperty("id").GetString()) .Select(j => j.GetProperty("id").GetString())
@ -76,244 +33,93 @@ namespace DiscordChatExporter.Cli.Tests
[Fact] [Fact]
public async Task User_mention_is_rendered_correctly_in_HTML() public async Task User_mention_is_rendered_correctly_in_HTML()
{ {
// Arrange
var outputFilePath = _tempOutput.GetTempFilePath("html");
// Act // Act
var htmlData = await GlobalCache.WrapAsync("mention-specs-output-html", async () => var message = await ExportWrapper.GetMessageAsHtmlAsync(
{ ChannelIds.MentionTestCases,
await new ExportChannelsCommand Snowflake.Parse("866458840245076028")
{ );
TokenValue = Secrets.DiscordToken,
IsBotToken = Secrets.IsDiscordTokenBot,
ChannelIds = new[] {Snowflake.Parse(ChannelIds.MentionTestCases)},
ExportFormat = ExportFormat.HtmlDark,
OutputPath = outputFilePath
}.ExecuteAsync(new FakeConsole());
return await File.ReadAllTextAsync(outputFilePath);
});
_testOutput.WriteLine(htmlData);
var html = Html.Parse(htmlData);
var messageHtml = html.QuerySelector("#message-866458840245076028");
// Assert // Assert
messageHtml.Should().NotBeNull(); message.Text().Trim().Should().Be("User mention: @Tyrrrz");
messageHtml?.Text().Trim().Should().Be("User mention: @Tyrrrz"); message.InnerHtml.Should().Contain("Tyrrrz#5447");
messageHtml?.InnerHtml.Should().Contain("Tyrrrz#5447");
} }
[Fact] [Fact]
public async Task Text_channel_mention_is_rendered_correctly_in_JSON() public async Task Text_channel_mention_is_rendered_correctly_in_JSON()
{ {
// Arrange
var outputFilePath = _tempOutput.GetTempFilePath("json");
// Act // Act
var jsonData = await GlobalCache.WrapAsync("mention-specs-output-json", async () => var message = await ExportWrapper.GetMessageAsJsonAsync(
{ ChannelIds.MentionTestCases,
await new ExportChannelsCommand Snowflake.Parse("866459040480624680")
{ );
TokenValue = Secrets.DiscordToken,
IsBotToken = Secrets.IsDiscordTokenBot,
ChannelIds = new[] {Snowflake.Parse(ChannelIds.MentionTestCases)},
ExportFormat = ExportFormat.Json,
OutputPath = outputFilePath
}.ExecuteAsync(new FakeConsole());
return await File.ReadAllTextAsync(outputFilePath);
});
_testOutput.WriteLine(jsonData);
var json = Json.Parse(jsonData);
var messageJson = json
.GetProperty("messages")
.EnumerateArray()
.Single(j => string.Equals(
j.GetProperty("id").GetString(),
"866459040480624680",
StringComparison.OrdinalIgnoreCase
));
// Assert // Assert
messageJson.GetProperty("content").GetString().Should().Be("Text channel mention: #mention-tests"); message.GetProperty("content").GetString().Should().Be("Text channel mention: #mention-tests");
} }
[Fact] [Fact]
public async Task Text_channel_mention_is_rendered_correctly_in_HTML() public async Task Text_channel_mention_is_rendered_correctly_in_HTML()
{ {
// Arrange
var outputFilePath = _tempOutput.GetTempFilePath("html");
// Act // Act
var htmlData = await GlobalCache.WrapAsync("mention-specs-output-html", async () => var message = await ExportWrapper.GetMessageAsHtmlAsync(
{ ChannelIds.MentionTestCases,
await new ExportChannelsCommand Snowflake.Parse("866459040480624680")
{ );
TokenValue = Secrets.DiscordToken,
IsBotToken = Secrets.IsDiscordTokenBot,
ChannelIds = new[] {Snowflake.Parse(ChannelIds.MentionTestCases)},
ExportFormat = ExportFormat.HtmlDark,
OutputPath = outputFilePath
}.ExecuteAsync(new FakeConsole());
return await File.ReadAllTextAsync(outputFilePath);
});
_testOutput.WriteLine(htmlData);
var html = Html.Parse(htmlData);
var messageHtml = html.QuerySelector("#message-866459040480624680");
// Assert // Assert
messageHtml.Should().NotBeNull(); message.Text().Trim().Should().Be("Text channel mention: #mention-tests");
messageHtml?.Text().Trim().Should().Be("Text channel mention: #mention-tests");
} }
[Fact] [Fact]
public async Task Voice_channel_mention_is_rendered_correctly_in_JSON() public async Task Voice_channel_mention_is_rendered_correctly_in_JSON()
{ {
// Arrange
var outputFilePath = _tempOutput.GetTempFilePath("json");
// Act // Act
var jsonData = await GlobalCache.WrapAsync("mention-specs-output-json", async () => var message = await ExportWrapper.GetMessageAsJsonAsync(
{ ChannelIds.MentionTestCases,
await new ExportChannelsCommand Snowflake.Parse("866459175462633503")
{ );
TokenValue = Secrets.DiscordToken,
IsBotToken = Secrets.IsDiscordTokenBot,
ChannelIds = new[] {Snowflake.Parse(ChannelIds.MentionTestCases)},
ExportFormat = ExportFormat.Json,
OutputPath = outputFilePath
}.ExecuteAsync(new FakeConsole());
return await File.ReadAllTextAsync(outputFilePath);
});
_testOutput.WriteLine(jsonData);
var json = Json.Parse(jsonData);
var messageJson = json
.GetProperty("messages")
.EnumerateArray()
.Single(j => string.Equals(
j.GetProperty("id").GetString(),
"866459175462633503",
StringComparison.OrdinalIgnoreCase
));
// Assert // Assert
messageJson.GetProperty("content").GetString().Should().Be("Voice channel mention: #chaos-vc [voice]"); message.GetProperty("content").GetString().Should().Be("Voice channel mention: #chaos-vc [voice]");
} }
[Fact] [Fact]
public async Task Voice_channel_mention_is_rendered_correctly_in_HTML() public async Task Voice_channel_mention_is_rendered_correctly_in_HTML()
{ {
// Arrange
var outputFilePath = _tempOutput.GetTempFilePath("html");
// Act // Act
var htmlData = await GlobalCache.WrapAsync("mention-specs-output-html", async () => var message = await ExportWrapper.GetMessageAsHtmlAsync(
{ ChannelIds.MentionTestCases,
await new ExportChannelsCommand Snowflake.Parse("866459175462633503")
{ );
TokenValue = Secrets.DiscordToken,
IsBotToken = Secrets.IsDiscordTokenBot,
ChannelIds = new[] {Snowflake.Parse(ChannelIds.MentionTestCases)},
ExportFormat = ExportFormat.HtmlDark,
OutputPath = outputFilePath
}.ExecuteAsync(new FakeConsole());
return await File.ReadAllTextAsync(outputFilePath);
});
_testOutput.WriteLine(htmlData);
var html = Html.Parse(htmlData);
var messageHtml = html.QuerySelector("#message-866459175462633503");
// Assert // Assert
messageHtml.Should().NotBeNull(); message.Text().Trim().Should().Be("Voice channel mention: 🔊chaos-vc");
messageHtml?.Text().Trim().Should().Be("Voice channel mention: 🔊chaos-vc");
} }
[Fact] [Fact]
public async Task Role_mention_is_rendered_correctly_in_JSON() public async Task Role_mention_is_rendered_correctly_in_JSON()
{ {
// Arrange
var outputFilePath = _tempOutput.GetTempFilePath("json");
// Act // Act
var jsonData = await GlobalCache.WrapAsync("mention-specs-output-json", async () => var message = await ExportWrapper.GetMessageAsJsonAsync(
{ ChannelIds.MentionTestCases,
await new ExportChannelsCommand Snowflake.Parse("866459254693429258")
{ );
TokenValue = Secrets.DiscordToken,
IsBotToken = Secrets.IsDiscordTokenBot,
ChannelIds = new[] {Snowflake.Parse(ChannelIds.MentionTestCases)},
ExportFormat = ExportFormat.Json,
OutputPath = outputFilePath
}.ExecuteAsync(new FakeConsole());
return await File.ReadAllTextAsync(outputFilePath);
});
_testOutput.WriteLine(jsonData);
var json = Json.Parse(jsonData);
var messageJson = json
.GetProperty("messages")
.EnumerateArray()
.Single(j => string.Equals(
j.GetProperty("id").GetString(),
"866459254693429258",
StringComparison.OrdinalIgnoreCase
));
// Assert // Assert
messageJson.GetProperty("content").GetString().Should().Be("Role mention: @Role 1"); message.GetProperty("content").GetString().Should().Be("Role mention: @Role 1");
} }
[Fact] [Fact]
public async Task Role_mention_is_rendered_correctly_in_HTML() public async Task Role_mention_is_rendered_correctly_in_HTML()
{ {
// Arrange
var outputFilePath = _tempOutput.GetTempFilePath("html");
// Act // Act
var htmlData = await GlobalCache.WrapAsync("mention-specs-output-html", async () => var message = await ExportWrapper.GetMessageAsHtmlAsync(
{ ChannelIds.MentionTestCases,
await new ExportChannelsCommand Snowflake.Parse("866459254693429258")
{ );
TokenValue = Secrets.DiscordToken,
IsBotToken = Secrets.IsDiscordTokenBot,
ChannelIds = new[] {Snowflake.Parse(ChannelIds.MentionTestCases)},
ExportFormat = ExportFormat.HtmlDark,
OutputPath = outputFilePath
}.ExecuteAsync(new FakeConsole());
return await File.ReadAllTextAsync(outputFilePath);
});
_testOutput.WriteLine(htmlData);
var html = Html.Parse(htmlData);
var messageHtml = html.QuerySelector("#message-866459254693429258");
// Assert // Assert
messageHtml.Should().NotBeNull(); message.Text().Trim().Should().Be("Role mention: @Role 1");
messageHtml?.Text().Trim().Should().Be("Role mention: @Role 1");
} }
} }
} }

@ -1,129 +1,56 @@
using System.IO; using System.Threading.Tasks;
using System.Threading.Tasks;
using AngleSharp.Dom; using AngleSharp.Dom;
using CliFx.Infrastructure;
using DiscordChatExporter.Cli.Commands;
using DiscordChatExporter.Cli.Tests.Fixtures; using DiscordChatExporter.Cli.Tests.Fixtures;
using DiscordChatExporter.Cli.Tests.Infra;
using DiscordChatExporter.Cli.Tests.TestData; using DiscordChatExporter.Cli.Tests.TestData;
using DiscordChatExporter.Cli.Tests.Utils;
using DiscordChatExporter.Core.Discord; using DiscordChatExporter.Core.Discord;
using DiscordChatExporter.Core.Exporting;
using FluentAssertions; using FluentAssertions;
using Xunit; using Xunit;
using Xunit.Abstractions;
namespace DiscordChatExporter.Cli.Tests namespace DiscordChatExporter.Cli.Tests
{ {
public class ReplySpecs : IClassFixture<TempOutputFixture> public record ReplySpecs(ExportWrapperFixture ExportWrapper) : IClassFixture<ExportWrapperFixture>
{ {
private readonly ITestOutputHelper _testOutput;
private readonly TempOutputFixture _tempOutput;
public ReplySpecs(ITestOutputHelper testOutput, TempOutputFixture tempOutput)
{
_testOutput = testOutput;
_tempOutput = tempOutput;
}
[Fact] [Fact]
public async Task Reply_to_a_normal_message_is_rendered_correctly_in_HTML() public async Task Reply_to_a_normal_message_is_rendered_correctly_in_HTML()
{ {
// Arrange
var outputFilePath = _tempOutput.GetTempFilePath("html");
// Act // Act
var htmlData = await GlobalCache.WrapAsync("reply-specs-output-html", async () => var message = await ExportWrapper.GetMessageAsHtmlAsync(
{ ChannelIds.ReplyTestCases,
await new ExportChannelsCommand Snowflake.Parse("866460738239725598")
{ );
TokenValue = Secrets.DiscordToken,
IsBotToken = Secrets.IsDiscordTokenBot,
ChannelIds = new[] {Snowflake.Parse(ChannelIds.ReplyTestCases)},
ExportFormat = ExportFormat.HtmlDark,
OutputPath = outputFilePath
}.ExecuteAsync(new FakeConsole());
return await File.ReadAllTextAsync(outputFilePath);
});
_testOutput.WriteLine(htmlData);
var html = Html.Parse(htmlData);
var messageHtml = html.QuerySelector("#message-866460738239725598");
// Assert // Assert
messageHtml.Should().NotBeNull(); message.Text().Trim().Should().Be("reply to original");
messageHtml?.Text().Trim().Should().Be("reply to original"); message.QuerySelector(".chatlog__reference-link")?.Text().Trim().Should().Be("original");
messageHtml?.QuerySelector(".chatlog__reference-link")?.Text().Trim().Should().Be("original");
} }
[Fact] [Fact]
public async Task Reply_to_a_deleted_message_is_rendered_correctly_in_HTML() public async Task Reply_to_a_deleted_message_is_rendered_correctly_in_HTML()
{ {
// Arrange
var outputFilePath = _tempOutput.GetTempFilePath("html");
// Act // Act
var htmlData = await GlobalCache.WrapAsync("reply-specs-output-html", async () => var message = await ExportWrapper.GetMessageAsHtmlAsync(
{ ChannelIds.ReplyTestCases,
await new ExportChannelsCommand Snowflake.Parse("866460975388819486")
{ );
TokenValue = Secrets.DiscordToken,
IsBotToken = Secrets.IsDiscordTokenBot,
ChannelIds = new[] {Snowflake.Parse(ChannelIds.ReplyTestCases)},
ExportFormat = ExportFormat.HtmlDark,
OutputPath = outputFilePath
}.ExecuteAsync(new FakeConsole());
return await File.ReadAllTextAsync(outputFilePath);
});
_testOutput.WriteLine(htmlData);
var html = Html.Parse(htmlData);
var messageHtml = html.QuerySelector("#message-866460975388819486");
// Assert // Assert
messageHtml.Should().NotBeNull(); message.Text().Trim().Should().Be("reply to deleted");
messageHtml?.Text().Trim().Should().Be("reply to deleted"); message.QuerySelector(".chatlog__reference-link")?.Text().Trim().Should()
messageHtml?.QuerySelector(".chatlog__reference-link")?.Text().Trim().Should()
.Be("Original message was deleted or could not be loaded."); .Be("Original message was deleted or could not be loaded.");
} }
[Fact] [Fact]
public async Task Reply_to_a_empty_message_with_attachment_is_rendered_correctly_in_HTML() public async Task Reply_to_a_empty_message_with_attachment_is_rendered_correctly_in_HTML()
{ {
// Arrange
var outputFilePath = _tempOutput.GetTempFilePath("html");
// Act // Act
var htmlData = await GlobalCache.WrapAsync("reply-specs-output-html", async () => var message = await ExportWrapper.GetMessageAsHtmlAsync(
{ ChannelIds.ReplyTestCases,
await new ExportChannelsCommand Snowflake.Parse("866462470335627294")
{ );
TokenValue = Secrets.DiscordToken,
IsBotToken = Secrets.IsDiscordTokenBot,
ChannelIds = new[] {Snowflake.Parse(ChannelIds.ReplyTestCases)},
ExportFormat = ExportFormat.HtmlDark,
OutputPath = outputFilePath
}.ExecuteAsync(new FakeConsole());
return await File.ReadAllTextAsync(outputFilePath);
});
_testOutput.WriteLine(htmlData);
var html = Html.Parse(htmlData);
var messageHtml = html.QuerySelector("#message-866462470335627294");
// Assert // Assert
messageHtml.Should().NotBeNull(); message.Text().Trim().Should().Be("reply to attachment");
messageHtml?.Text().Trim().Should().Be("reply to attachment"); message.QuerySelector(".chatlog__reference-link")?.Text().Trim().Should()
messageHtml?.QuerySelector(".chatlog__reference-link")?.Text().Trim().Should()
.Be("Click to see attachment 🖼️"); .Be("Click to see attachment 🖼️");
} }
} }

@ -1,11 +1,13 @@
namespace DiscordChatExporter.Cli.Tests.TestData using DiscordChatExporter.Core.Discord;
namespace DiscordChatExporter.Cli.Tests.TestData
{ {
public static class ChannelIds public static class ChannelIds
{ {
public static string EmbedTestCases => "866472452459462687"; public static Snowflake EmbedTestCases { get; } = Snowflake.Parse("866472452459462687");
public static string MentionTestCases => "866458801389174794"; public static Snowflake MentionTestCases { get; } = Snowflake.Parse("866458801389174794");
public static string ReplyTestCases => "866459871934677052"; public static Snowflake ReplyTestCases { get; } = Snowflake.Parse("866459871934677052");
} }
} }

@ -1,22 +0,0 @@
using System;
using System.Collections.Concurrent;
using System.Threading.Tasks;
namespace DiscordChatExporter.Cli.Tests.Utils
{
internal static class GlobalCache
{
private static readonly ConcurrentDictionary<string, object?> Dictionary = new();
public static async Task<T> WrapAsync<T>(string key, Func<Task<T>> getAsync)
{
if (Dictionary.TryGetValue(key, out var value) && value is T existing)
return existing;
var result = await getAsync();
Dictionary[key] = result;
return result;
}
}
}

@ -0,0 +1,9 @@
// ReSharper disable CheckNamespace
// TODO: remove after moving to .NET 5
namespace System.Runtime.CompilerServices
{
internal static class IsExternalInit
{
}
}

@ -22,15 +22,13 @@ namespace DiscordChatExporter.Cli.Utils.Extensions
? new NoopExclusivityMode() ? new NoopExclusivityMode()
: null; : null;
return AnsiConsole.Create( return AnsiConsole.Create(new AnsiConsoleSettings
new AnsiConsoleSettings {
{ Ansi = AnsiSupport.Detect,
Ansi = AnsiSupport.Detect, ColorSystem = ColorSystemSupport.Detect,
ColorSystem = ColorSystemSupport.Detect, Out = new AnsiConsoleOutput(console.Output),
Out = new AnsiConsoleOutput(console.Output), ExclusivityMode = exclusivityMode
ExclusivityMode = exclusivityMode });
}
);
} }
public static Progress CreateProgressTicker(this IConsole console) => console public static Progress CreateProgressTicker(this IConsole console) => console

Loading…
Cancel
Save