diff --git a/DiscordChatExporter.Cli.Tests/DiscordChatExporter.Cli.Tests.csproj b/DiscordChatExporter.Cli.Tests/DiscordChatExporter.Cli.Tests.csproj
index e7c03aa3..b93b6e13 100644
--- a/DiscordChatExporter.Cli.Tests/DiscordChatExporter.Cli.Tests.csproj
+++ b/DiscordChatExporter.Cli.Tests/DiscordChatExporter.Cli.Tests.csproj
@@ -5,6 +5,7 @@
true
true
opencover
+ $(NoWarn);xUnit1013
diff --git a/DiscordChatExporter.Cli.Tests/EmbedSpecs.cs b/DiscordChatExporter.Cli.Tests/EmbedSpecs.cs
index 2ffee94a..529c3588 100644
--- a/DiscordChatExporter.Cli.Tests/EmbedSpecs.cs
+++ b/DiscordChatExporter.Cli.Tests/EmbedSpecs.cs
@@ -1,69 +1,26 @@
-using System;
-using System.IO;
-using System.Linq;
+using System.Linq;
using System.Threading.Tasks;
using AngleSharp.Dom;
-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.Discord;
-using DiscordChatExporter.Core.Exporting;
using FluentAssertions;
-using JsonExtensions;
using Xunit;
-using Xunit.Abstractions;
namespace DiscordChatExporter.Cli.Tests
{
- public class EmbedSpecs : IClassFixture
+ public record EmbedSpecs(ExportWrapperFixture ExportWrapper) : IClassFixture
{
- private readonly ITestOutputHelper _testOutput;
- private readonly TempOutputFixture _tempOutput;
-
- public EmbedSpecs(ITestOutputHelper testOutput, TempOutputFixture tempOutput)
- {
- _testOutput = testOutput;
- _tempOutput = tempOutput;
- }
-
[Fact]
public async Task Message_with_an_embed_is_rendered_correctly_in_JSON()
{
- // Arrange
- var outputFilePath = _tempOutput.GetTempFilePath("json");
-
// Act
- var jsonData = await GlobalCache.WrapAsync("embed-specs-output-json", async () =>
- {
- await new ExportChannelsCommand
- {
- TokenValue = Secrets.DiscordToken,
- IsBotToken = Secrets.IsDiscordTokenBot,
- ChannelIds = new[] {Snowflake.Parse(ChannelIds.EmbedTestCases)},
- ExportFormat = ExportFormat.Json,
- OutputPath = outputFilePath
- }.ExecuteAsync(new FakeConsole());
+ var message = await ExportWrapper.GetMessageAsJsonAsync(
+ ChannelIds.EmbedTestCases,
+ Snowflake.Parse("866769910729146400")
+ );
- 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")
.EnumerateArray()
.Single();
@@ -102,33 +59,14 @@ namespace DiscordChatExporter.Cli.Tests
[Fact]
public async Task Message_with_an_embed_is_rendered_correctly_in_HTML()
{
- // Arrange
- var outputFilePath = _tempOutput.GetTempFilePath("html");
-
// Act
- var htmlData = await GlobalCache.WrapAsync("embed-specs-output-html", async () =>
- {
- await new ExportChannelsCommand
- {
- 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();
+ var message = await ExportWrapper.GetMessageAsHtmlAsync(
+ ChannelIds.EmbedTestCases,
+ Snowflake.Parse("866769910729146400")
+ );
// Assert
- messageText.Should().ContainAll(
+ message.Text().Should().ContainAll(
"Embed author",
"Embed title",
"Embed description",
@@ -142,30 +80,13 @@ namespace DiscordChatExporter.Cli.Tests
[Fact]
public async Task Message_with_a_Spotify_track_is_rendered_using_an_iframe_in_HTML()
{
- // Arrange
- var outputFilePath = _tempOutput.GetTempFilePath("html");
-
// Act
- var htmlData = await GlobalCache.WrapAsync("embed-specs-output-html", async () =>
- {
- await new ExportChannelsCommand
- {
- TokenValue = Secrets.DiscordToken,
- IsBotToken = Secrets.IsDiscordTokenBot,
- ChannelIds = new[] {Snowflake.Parse(ChannelIds.EmbedTestCases)},
- ExportFormat = ExportFormat.HtmlDark,
- OutputPath = outputFilePath
- }.ExecuteAsync(new FakeConsole());
+ var message = await ExportWrapper.GetMessageAsHtmlAsync(
+ ChannelIds.EmbedTestCases,
+ Snowflake.Parse("867886632203976775")
+ );
- return await File.ReadAllTextAsync(outputFilePath);
- });
-
- _testOutput.WriteLine(htmlData);
-
- var html = Html.Parse(htmlData);
-
- var messageHtml = html.QuerySelector("#message-867886632203976775");
- var iframeHtml = messageHtml?.QuerySelector("iframe");
+ var iframeHtml = message.QuerySelector("iframe");
// Assert
iframeHtml.Should().NotBeNull();
@@ -176,30 +97,13 @@ namespace DiscordChatExporter.Cli.Tests
[Fact]
public async Task Message_with_a_YouTube_video_is_rendered_using_an_iframe_in_HTML()
{
- // Arrange
- var outputFilePath = _tempOutput.GetTempFilePath("html");
-
// Act
- var htmlData = await GlobalCache.WrapAsync("embed-specs-output-html", async () =>
- {
- await new ExportChannelsCommand
- {
- TokenValue = Secrets.DiscordToken,
- IsBotToken = Secrets.IsDiscordTokenBot,
- ChannelIds = new[] {Snowflake.Parse(ChannelIds.EmbedTestCases)},
- ExportFormat = ExportFormat.HtmlDark,
- OutputPath = outputFilePath
- }.ExecuteAsync(new FakeConsole());
+ var message = await ExportWrapper.GetMessageAsHtmlAsync(
+ ChannelIds.EmbedTestCases,
+ Snowflake.Parse("866472508588294165")
+ );
- return await File.ReadAllTextAsync(outputFilePath);
- });
-
- _testOutput.WriteLine(htmlData);
-
- var html = Html.Parse(htmlData);
-
- var messageHtml = html.QuerySelector("#message-866472508588294165");
- var iframeHtml = messageHtml?.QuerySelector("iframe");
+ var iframeHtml = message.QuerySelector("iframe");
// Assert
iframeHtml.Should().NotBeNull();
diff --git a/DiscordChatExporter.Cli.Tests/Fixtures/ExportWrapperFixture.cs b/DiscordChatExporter.Cli.Tests/Fixtures/ExportWrapperFixture.cs
new file mode 100644
index 00000000..27cfb75e
--- /dev/null
+++ b/DiscordChatExporter.Cli.Tests/Fixtures/ExportWrapperFixture.cs
@@ -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 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 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 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 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)
+ {
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/DiscordChatExporter.Cli.Tests/Fixtures/TempOutputFixture.cs b/DiscordChatExporter.Cli.Tests/Fixtures/TempOutputFixture.cs
deleted file mode 100644
index f2991e08..00000000
--- a/DiscordChatExporter.Cli.Tests/Fixtures/TempOutputFixture.cs
+++ /dev/null
@@ -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)
- {
- }
- }
- }
-}
\ No newline at end of file
diff --git a/DiscordChatExporter.Cli.Tests/MentionSpecs.cs b/DiscordChatExporter.Cli.Tests/MentionSpecs.cs
index 06716ce8..9c214a6e 100644
--- a/DiscordChatExporter.Cli.Tests/MentionSpecs.cs
+++ b/DiscordChatExporter.Cli.Tests/MentionSpecs.cs
@@ -1,72 +1,29 @@
-using System;
-using System.IO;
-using System.Linq;
+using System.Linq;
using System.Threading.Tasks;
using AngleSharp.Dom;
-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.Discord;
-using DiscordChatExporter.Core.Exporting;
using FluentAssertions;
-using JsonExtensions;
using Xunit;
-using Xunit.Abstractions;
namespace DiscordChatExporter.Cli.Tests
{
- public class MentionSpecs : IClassFixture
+ public record MentionSpecs(ExportWrapperFixture ExportWrapper) : IClassFixture
{
- private readonly ITestOutputHelper _testOutput;
- private readonly TempOutputFixture _tempOutput;
-
- public MentionSpecs(ITestOutputHelper testOutput, TempOutputFixture tempOutput)
- {
- _testOutput = testOutput;
- _tempOutput = tempOutput;
- }
-
[Fact]
public async Task User_mention_is_rendered_correctly_in_JSON()
{
- // Arrange
- var outputFilePath = _tempOutput.GetTempFilePath("json");
-
// Act
- var jsonData = await GlobalCache.WrapAsync("mention-specs-output-json", async () =>
- {
- await new ExportChannelsCommand
- {
- 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
- ));
+ var message = await ExportWrapper.GetMessageAsJsonAsync(
+ ChannelIds.MentionTestCases,
+ Snowflake.Parse("866458840245076028")
+ );
// Assert
- messageJson.GetProperty("content").GetString().Should().Be("User mention: @Tyrrrz");
+ message.GetProperty("content").GetString().Should().Be("User mention: @Tyrrrz");
- messageJson
+ message
.GetProperty("mentions")
.EnumerateArray()
.Select(j => j.GetProperty("id").GetString())
@@ -76,244 +33,93 @@ namespace DiscordChatExporter.Cli.Tests
[Fact]
public async Task User_mention_is_rendered_correctly_in_HTML()
{
- // Arrange
- var outputFilePath = _tempOutput.GetTempFilePath("html");
-
// Act
- var htmlData = await GlobalCache.WrapAsync("mention-specs-output-html", async () =>
- {
- await new ExportChannelsCommand
- {
- 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");
+ var message = await ExportWrapper.GetMessageAsHtmlAsync(
+ ChannelIds.MentionTestCases,
+ Snowflake.Parse("866458840245076028")
+ );
// Assert
- messageHtml.Should().NotBeNull();
- messageHtml?.Text().Trim().Should().Be("User mention: @Tyrrrz");
- messageHtml?.InnerHtml.Should().Contain("Tyrrrz#5447");
+ message.Text().Trim().Should().Be("User mention: @Tyrrrz");
+ message.InnerHtml.Should().Contain("Tyrrrz#5447");
}
[Fact]
public async Task Text_channel_mention_is_rendered_correctly_in_JSON()
{
- // Arrange
- var outputFilePath = _tempOutput.GetTempFilePath("json");
-
// Act
- var jsonData = await GlobalCache.WrapAsync("mention-specs-output-json", async () =>
- {
- await new ExportChannelsCommand
- {
- 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
- ));
+ var message = await ExportWrapper.GetMessageAsJsonAsync(
+ ChannelIds.MentionTestCases,
+ Snowflake.Parse("866459040480624680")
+ );
// Assert
- messageJson.GetProperty("content").GetString().Should().Be("Text channel mention: #mention-tests");
+ message.GetProperty("content").GetString().Should().Be("Text channel mention: #mention-tests");
}
[Fact]
public async Task Text_channel_mention_is_rendered_correctly_in_HTML()
{
- // Arrange
- var outputFilePath = _tempOutput.GetTempFilePath("html");
-
// Act
- var htmlData = await GlobalCache.WrapAsync("mention-specs-output-html", async () =>
- {
- await new ExportChannelsCommand
- {
- 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");
+ var message = await ExportWrapper.GetMessageAsHtmlAsync(
+ ChannelIds.MentionTestCases,
+ Snowflake.Parse("866459040480624680")
+ );
// Assert
- messageHtml.Should().NotBeNull();
- messageHtml?.Text().Trim().Should().Be("Text channel mention: #mention-tests");
+ message.Text().Trim().Should().Be("Text channel mention: #mention-tests");
}
[Fact]
public async Task Voice_channel_mention_is_rendered_correctly_in_JSON()
{
- // Arrange
- var outputFilePath = _tempOutput.GetTempFilePath("json");
-
// Act
- var jsonData = await GlobalCache.WrapAsync("mention-specs-output-json", async () =>
- {
- await new ExportChannelsCommand
- {
- 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
- ));
+ var message = await ExportWrapper.GetMessageAsJsonAsync(
+ ChannelIds.MentionTestCases,
+ Snowflake.Parse("866459175462633503")
+ );
// 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]
public async Task Voice_channel_mention_is_rendered_correctly_in_HTML()
{
- // Arrange
- var outputFilePath = _tempOutput.GetTempFilePath("html");
-
// Act
- var htmlData = await GlobalCache.WrapAsync("mention-specs-output-html", async () =>
- {
- await new ExportChannelsCommand
- {
- 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");
+ var message = await ExportWrapper.GetMessageAsHtmlAsync(
+ ChannelIds.MentionTestCases,
+ Snowflake.Parse("866459175462633503")
+ );
// Assert
- messageHtml.Should().NotBeNull();
- messageHtml?.Text().Trim().Should().Be("Voice channel mention: 🔊chaos-vc");
+ message.Text().Trim().Should().Be("Voice channel mention: 🔊chaos-vc");
}
[Fact]
public async Task Role_mention_is_rendered_correctly_in_JSON()
{
- // Arrange
- var outputFilePath = _tempOutput.GetTempFilePath("json");
-
// Act
- var jsonData = await GlobalCache.WrapAsync("mention-specs-output-json", async () =>
- {
- await new ExportChannelsCommand
- {
- 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
- ));
+ var message = await ExportWrapper.GetMessageAsJsonAsync(
+ ChannelIds.MentionTestCases,
+ Snowflake.Parse("866459254693429258")
+ );
// Assert
- messageJson.GetProperty("content").GetString().Should().Be("Role mention: @Role 1");
+ message.GetProperty("content").GetString().Should().Be("Role mention: @Role 1");
}
[Fact]
public async Task Role_mention_is_rendered_correctly_in_HTML()
{
- // Arrange
- var outputFilePath = _tempOutput.GetTempFilePath("html");
-
// Act
- var htmlData = await GlobalCache.WrapAsync("mention-specs-output-html", async () =>
- {
- await new ExportChannelsCommand
- {
- 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");
+ var message = await ExportWrapper.GetMessageAsHtmlAsync(
+ ChannelIds.MentionTestCases,
+ Snowflake.Parse("866459254693429258")
+ );
// Assert
- messageHtml.Should().NotBeNull();
- messageHtml?.Text().Trim().Should().Be("Role mention: @Role 1");
+ message.Text().Trim().Should().Be("Role mention: @Role 1");
}
}
}
\ No newline at end of file
diff --git a/DiscordChatExporter.Cli.Tests/ReplySpecs.cs b/DiscordChatExporter.Cli.Tests/ReplySpecs.cs
index 42e7bf81..ab6a27f0 100644
--- a/DiscordChatExporter.Cli.Tests/ReplySpecs.cs
+++ b/DiscordChatExporter.Cli.Tests/ReplySpecs.cs
@@ -1,129 +1,56 @@
-using System.IO;
-using System.Threading.Tasks;
+using System.Threading.Tasks;
using AngleSharp.Dom;
-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.Discord;
-using DiscordChatExporter.Core.Exporting;
using FluentAssertions;
using Xunit;
-using Xunit.Abstractions;
namespace DiscordChatExporter.Cli.Tests
{
- public class ReplySpecs : IClassFixture
+ public record ReplySpecs(ExportWrapperFixture ExportWrapper) : IClassFixture
{
- private readonly ITestOutputHelper _testOutput;
- private readonly TempOutputFixture _tempOutput;
-
- public ReplySpecs(ITestOutputHelper testOutput, TempOutputFixture tempOutput)
- {
- _testOutput = testOutput;
- _tempOutput = tempOutput;
- }
-
[Fact]
public async Task Reply_to_a_normal_message_is_rendered_correctly_in_HTML()
{
- // Arrange
- var outputFilePath = _tempOutput.GetTempFilePath("html");
-
// Act
- var htmlData = await GlobalCache.WrapAsync("reply-specs-output-html", async () =>
- {
- await new ExportChannelsCommand
- {
- 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");
+ var message = await ExportWrapper.GetMessageAsHtmlAsync(
+ ChannelIds.ReplyTestCases,
+ Snowflake.Parse("866460738239725598")
+ );
// Assert
- messageHtml.Should().NotBeNull();
- messageHtml?.Text().Trim().Should().Be("reply to original");
- messageHtml?.QuerySelector(".chatlog__reference-link")?.Text().Trim().Should().Be("original");
+ message.Text().Trim().Should().Be("reply to original");
+ message.QuerySelector(".chatlog__reference-link")?.Text().Trim().Should().Be("original");
}
[Fact]
public async Task Reply_to_a_deleted_message_is_rendered_correctly_in_HTML()
{
- // Arrange
- var outputFilePath = _tempOutput.GetTempFilePath("html");
-
// Act
- var htmlData = await GlobalCache.WrapAsync("reply-specs-output-html", async () =>
- {
- await new ExportChannelsCommand
- {
- 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");
+ var message = await ExportWrapper.GetMessageAsHtmlAsync(
+ ChannelIds.ReplyTestCases,
+ Snowflake.Parse("866460975388819486")
+ );
// Assert
- messageHtml.Should().NotBeNull();
- messageHtml?.Text().Trim().Should().Be("reply to deleted");
- messageHtml?.QuerySelector(".chatlog__reference-link")?.Text().Trim().Should()
+ message.Text().Trim().Should().Be("reply to deleted");
+ message.QuerySelector(".chatlog__reference-link")?.Text().Trim().Should()
.Be("Original message was deleted or could not be loaded.");
}
[Fact]
public async Task Reply_to_a_empty_message_with_attachment_is_rendered_correctly_in_HTML()
{
- // Arrange
- var outputFilePath = _tempOutput.GetTempFilePath("html");
-
// Act
- var htmlData = await GlobalCache.WrapAsync("reply-specs-output-html", async () =>
- {
- await new ExportChannelsCommand
- {
- 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");
+ var message = await ExportWrapper.GetMessageAsHtmlAsync(
+ ChannelIds.ReplyTestCases,
+ Snowflake.Parse("866462470335627294")
+ );
// Assert
- messageHtml.Should().NotBeNull();
- messageHtml?.Text().Trim().Should().Be("reply to attachment");
- messageHtml?.QuerySelector(".chatlog__reference-link")?.Text().Trim().Should()
+ message.Text().Trim().Should().Be("reply to attachment");
+ message.QuerySelector(".chatlog__reference-link")?.Text().Trim().Should()
.Be("Click to see attachment 🖼️");
}
}
diff --git a/DiscordChatExporter.Cli.Tests/TestData/ChannelIds.cs b/DiscordChatExporter.Cli.Tests/TestData/ChannelIds.cs
index e06fed13..582a6bf0 100644
--- a/DiscordChatExporter.Cli.Tests/TestData/ChannelIds.cs
+++ b/DiscordChatExporter.Cli.Tests/TestData/ChannelIds.cs
@@ -1,11 +1,13 @@
-namespace DiscordChatExporter.Cli.Tests.TestData
+using DiscordChatExporter.Core.Discord;
+
+namespace DiscordChatExporter.Cli.Tests.TestData
{
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");
}
}
\ No newline at end of file
diff --git a/DiscordChatExporter.Cli.Tests/Utils/GlobalCache.cs b/DiscordChatExporter.Cli.Tests/Utils/GlobalCache.cs
deleted file mode 100644
index 5e357b9d..00000000
--- a/DiscordChatExporter.Cli.Tests/Utils/GlobalCache.cs
+++ /dev/null
@@ -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 Dictionary = new();
-
- public static async Task WrapAsync(string key, Func> getAsync)
- {
- if (Dictionary.TryGetValue(key, out var value) && value is T existing)
- return existing;
-
- var result = await getAsync();
- Dictionary[key] = result;
-
- return result;
- }
- }
-}
\ No newline at end of file
diff --git a/DiscordChatExporter.Cli.Tests/Utils/Pollyfills.cs b/DiscordChatExporter.Cli.Tests/Utils/Pollyfills.cs
new file mode 100644
index 00000000..2e592b8d
--- /dev/null
+++ b/DiscordChatExporter.Cli.Tests/Utils/Pollyfills.cs
@@ -0,0 +1,9 @@
+// ReSharper disable CheckNamespace
+// TODO: remove after moving to .NET 5
+
+namespace System.Runtime.CompilerServices
+{
+ internal static class IsExternalInit
+ {
+ }
+}
\ No newline at end of file
diff --git a/DiscordChatExporter.Cli/Utils/Extensions/ConsoleExtensions.cs b/DiscordChatExporter.Cli/Utils/Extensions/ConsoleExtensions.cs
index 6f85b079..40d0d777 100644
--- a/DiscordChatExporter.Cli/Utils/Extensions/ConsoleExtensions.cs
+++ b/DiscordChatExporter.Cli/Utils/Extensions/ConsoleExtensions.cs
@@ -22,15 +22,13 @@ namespace DiscordChatExporter.Cli.Utils.Extensions
? new NoopExclusivityMode()
: null;
- return AnsiConsole.Create(
- new AnsiConsoleSettings
- {
- Ansi = AnsiSupport.Detect,
- ColorSystem = ColorSystemSupport.Detect,
- Out = new AnsiConsoleOutput(console.Output),
- ExclusivityMode = exclusivityMode
- }
- );
+ return AnsiConsole.Create(new AnsiConsoleSettings
+ {
+ Ansi = AnsiSupport.Detect,
+ ColorSystem = ColorSystemSupport.Detect,
+ Out = new AnsiConsoleOutput(console.Output),
+ ExclusivityMode = exclusivityMode
+ });
}
public static Progress CreateProgressTicker(this IConsole console) => console