From 057902f919271bac93ac861c52b6ad99ec8833af Mon Sep 17 00:00:00 2001 From: Oleksii Holub <1935960+Tyrrrz@users.noreply.github.com> Date: Thu, 30 Jun 2022 19:07:11 +0300 Subject: [PATCH] More test stuff --- .../Fixtures/ExportWrapperFixture.cs | 87 ++++++++----------- .../Specs/HtmlWriting/AttachmentSpecs.cs | 8 +- .../Specs/HtmlWriting/EmbedSpecs.cs | 38 +++++++- .../Specs/HtmlWriting/GroupingSpecs.cs | 79 +++++++++++++++++ .../Specs/HtmlWriting/ReplySpecs.cs | 4 + .../Specs/JsonWriting/AttachmentSpecs.cs | 8 +- .../Specs/JsonWriting/MentionSpecs.cs | 3 +- .../Specs/PartitioningSpecs.cs | 4 +- .../TestData/ChannelIds.cs | 4 +- 9 files changed, 173 insertions(+), 62 deletions(-) create mode 100644 DiscordChatExporter.Cli.Tests/Specs/HtmlWriting/GroupingSpecs.cs diff --git a/DiscordChatExporter.Cli.Tests/Fixtures/ExportWrapperFixture.cs b/DiscordChatExporter.Cli.Tests/Fixtures/ExportWrapperFixture.cs index e8fbaea6..07f630dd 100644 --- a/DiscordChatExporter.Cli.Tests/Fixtures/ExportWrapperFixture.cs +++ b/DiscordChatExporter.Cli.Tests/Fixtures/ExportWrapperFixture.cs @@ -46,58 +46,46 @@ public class ExportWrapperFixture : IDisposable return await File.ReadAllTextAsync(filePath); } - public async ValueTask ExportAsHtmlAsync(Snowflake channelId) - { - var data = await ExportAsync(channelId, ExportFormat.HtmlDark); - return Html.Parse(data); - } + public async ValueTask ExportAsHtmlAsync(Snowflake channelId) => Html.Parse( + await ExportAsync(channelId, ExportFormat.HtmlDark) + ); - public async ValueTask ExportAsJsonAsync(Snowflake channelId) - { - var data = await ExportAsync(channelId, ExportFormat.Json); - return Json.Parse(data); - } + public async ValueTask ExportAsJsonAsync(Snowflake channelId) => Json.Parse( + await ExportAsync(channelId, ExportFormat.Json) + ); - public async ValueTask ExportAsPlainTextAsync(Snowflake channelId) - { - var data = await ExportAsync(channelId, ExportFormat.PlainText); - return data; - } + public async ValueTask ExportAsPlainTextAsync(Snowflake channelId) => + await ExportAsync(channelId, ExportFormat.PlainText); - public async ValueTask ExportAsCsvAsync(Snowflake channelId) - { - var data = await ExportAsync(channelId, ExportFormat.Csv); - return data; - } + public async ValueTask ExportAsCsvAsync(Snowflake channelId) => + await ExportAsync(channelId, ExportFormat.Csv); - public async ValueTask> GetMessagesAsHtmlAsync(Snowflake channelId) - { - var document = await ExportAsHtmlAsync(channelId); - return document.QuerySelectorAll("[data-message-id]").ToArray(); - } + public async ValueTask> GetMessagesAsHtmlAsync(Snowflake channelId) => + (await ExportAsHtmlAsync(channelId)) + .QuerySelectorAll("[data-message-id]") + .ToArray(); - public async ValueTask> GetMessagesAsJsonAsync(Snowflake channelId) - { - var document = await ExportAsJsonAsync(channelId); - return document.GetProperty("messages").EnumerateArray().ToArray(); - } + public async ValueTask> GetMessagesAsJsonAsync(Snowflake channelId) => + (await ExportAsJsonAsync(channelId)) + .GetProperty("messages") + .EnumerateArray() + .ToArray(); public async ValueTask GetMessageAsHtmlAsync(Snowflake channelId, Snowflake messageId) { - var messages = await GetMessagesAsHtmlAsync(channelId); - - var message = messages.SingleOrDefault(e => - string.Equals( - e.GetAttribute("data-message-id"), - messageId.ToString(), - StringComparison.OrdinalIgnoreCase - ) - ); + var message = (await GetMessagesAsHtmlAsync(channelId)) + .SingleOrDefault(e => + string.Equals( + e.GetAttribute("data-message-id"), + messageId.ToString(), + StringComparison.OrdinalIgnoreCase + ) + ); if (message is null) { throw new InvalidOperationException( - $"Message '{messageId}' does not exist in export of channel '{channelId}'." + $"Message '{messageId}' does not exist in the export of channel '{channelId}'." ); } @@ -106,20 +94,19 @@ public class ExportWrapperFixture : IDisposable public async ValueTask GetMessageAsJsonAsync(Snowflake channelId, Snowflake messageId) { - var messages = await GetMessagesAsJsonAsync(channelId); - - var message = messages.FirstOrDefault(j => - string.Equals( - j.GetProperty("id").GetString(), - messageId.ToString(), - StringComparison.OrdinalIgnoreCase - ) - ); + var message = (await GetMessagesAsJsonAsync(channelId)) + .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}'." + $"Message '{messageId}' does not exist in the export of channel '{channelId}'." ); } diff --git a/DiscordChatExporter.Cli.Tests/Specs/HtmlWriting/AttachmentSpecs.cs b/DiscordChatExporter.Cli.Tests/Specs/HtmlWriting/AttachmentSpecs.cs index 2db95926..9bc52fef 100644 --- a/DiscordChatExporter.Cli.Tests/Specs/HtmlWriting/AttachmentSpecs.cs +++ b/DiscordChatExporter.Cli.Tests/Specs/HtmlWriting/AttachmentSpecs.cs @@ -67,6 +67,8 @@ public class AttachmentSpecs : IClassFixture [Fact] public async Task Message_with_a_video_attachment_is_rendered_correctly() { + // https://github.com/Tyrrrz/DiscordChatExporter/issues/333 + // Act var message = await _exportWrapper.GetMessageAsHtmlAsync( ChannelIds.AttachmentTestCases, @@ -77,7 +79,7 @@ public class AttachmentSpecs : IClassFixture message.Text().Should().Contain("Video attachment"); var videoUrl = message.QuerySelector("video source")?.GetAttribute("src"); - videoUrl.Should().StartWith( + videoUrl.Should().Be( "https://cdn.discordapp.com/attachments/885587741654536192/885655761512968233/file_example_MP4_640_3MG.mp4" ); } @@ -85,6 +87,8 @@ public class AttachmentSpecs : IClassFixture [Fact] public async Task Message_with_an_audio_attachment_is_rendered_correctly() { + // https://github.com/Tyrrrz/DiscordChatExporter/issues/333 + // Act var message = await _exportWrapper.GetMessageAsHtmlAsync( ChannelIds.AttachmentTestCases, @@ -95,7 +99,7 @@ public class AttachmentSpecs : IClassFixture message.Text().Should().Contain("Audio attachment"); var audioUrl = message.QuerySelector("audio source")?.GetAttribute("src"); - audioUrl.Should().StartWith( + audioUrl.Should().Be( "https://cdn.discordapp.com/attachments/885587741654536192/885656175348187146/file_example_MP3_1MG.mp3" ); } diff --git a/DiscordChatExporter.Cli.Tests/Specs/HtmlWriting/EmbedSpecs.cs b/DiscordChatExporter.Cli.Tests/Specs/HtmlWriting/EmbedSpecs.cs index 45c5dd78..a4070d3c 100644 --- a/DiscordChatExporter.Cli.Tests/Specs/HtmlWriting/EmbedSpecs.cs +++ b/DiscordChatExporter.Cli.Tests/Specs/HtmlWriting/EmbedSpecs.cs @@ -42,6 +42,8 @@ public class EmbedSpecs : IClassFixture [Fact] public async Task Message_containing_an_image_link_is_rendered_with_an_image_embed() { + // https://github.com/Tyrrrz/DiscordChatExporter/issues/537 + // Act var message = await _exportWrapper.GetMessageAsHtmlAsync( ChannelIds.EmbedTestCases, @@ -59,6 +61,8 @@ public class EmbedSpecs : IClassFixture [Fact] public async Task Message_containing_an_image_link_and_nothing_else_is_rendered_without_text_content() { + // https://github.com/Tyrrrz/DiscordChatExporter/issues/682 + // Act var message = await _exportWrapper.GetMessageAsHtmlAsync( ChannelIds.EmbedTestCases, @@ -73,6 +77,8 @@ public class EmbedSpecs : IClassFixture [Fact] public async Task Message_containing_a_Spotify_track_link_is_rendered_with_a_track_embed() { + // https://github.com/Tyrrrz/DiscordChatExporter/issues/657 + // Act var message = await _exportWrapper.GetMessageAsHtmlAsync( ChannelIds.EmbedTestCases, @@ -81,12 +87,14 @@ public class EmbedSpecs : IClassFixture // Assert var iframeUrl = message.QuerySelector("iframe")?.GetAttribute("src"); - iframeUrl.Should().StartWith("https://open.spotify.com/embed/track/1LHZMWefF9502NPfArRfvP"); + iframeUrl.Should().Be("https://open.spotify.com/embed/track/1LHZMWefF9502NPfArRfvP"); } [Fact] public async Task Message_containing_a_YouTube_video_link_is_rendered_with_a_video_embed() { + // https://github.com/Tyrrrz/DiscordChatExporter/issues/570 + // Act var message = await _exportWrapper.GetMessageAsHtmlAsync( ChannelIds.EmbedTestCases, @@ -95,6 +103,32 @@ public class EmbedSpecs : IClassFixture // Assert var iframeUrl = message.QuerySelector("iframe")?.GetAttribute("src"); - iframeUrl.Should().StartWith("https://www.youtube.com/embed/qOWW4OlgbvE"); + iframeUrl.Should().Be("https://www.youtube.com/embed/qOWW4OlgbvE"); + } + + [Fact(Skip = "Unimplemented")] + public async Task Message_containing_a_Twitter_post_link_with_multiple_images_is_rendered_as_a_single_embed() + { + // https://github.com/Tyrrrz/DiscordChatExporter/issues/695 + + // Act + var message = await _exportWrapper.GetMessageAsHtmlAsync( + ChannelIds.EmbedTestCases, + Snowflake.Parse("991757444017557665") + ); + + // Assert + message + .QuerySelectorAll("img") + .Select(e => e.GetAttribute("src")) + .Should() + .ContainInOrder( + "https://images-ext-1.discordapp.net/external/-n--xW3EHH_3jlrheVkMXHCM7T86b5Ty4-MzXCT4m1Q/https/pbs.twimg.com/media/FVYIzYPWAAAMBqZ.png", + "https://images-ext-2.discordapp.net/external/z5nEmGeEldV-kswydGLhqUsFHbb5AWHtdvc9XT6N5rE/https/pbs.twimg.com/media/FVYJBWJWAAMNAx2.png", + "https://images-ext-2.discordapp.net/external/gnip03SawMB6uZLagN5sRDpA_1Ap1CcEhMbJfK1z6WQ/https/pbs.twimg.com/media/FVYJHiRX0AANZcz.png", + "https://images-ext-2.discordapp.net/external/jl1v6cCbLaGmiwmKU-ZkXnF4cFsJ39f9A3-oEdqPdZs/https/pbs.twimg.com/media/FVYJNZNXwAAPnVG.png" + ); + + message.QuerySelectorAll(".chatlog__embed").Should().ContainSingle(); } } \ No newline at end of file diff --git a/DiscordChatExporter.Cli.Tests/Specs/HtmlWriting/GroupingSpecs.cs b/DiscordChatExporter.Cli.Tests/Specs/HtmlWriting/GroupingSpecs.cs new file mode 100644 index 00000000..e021e740 --- /dev/null +++ b/DiscordChatExporter.Cli.Tests/Specs/HtmlWriting/GroupingSpecs.cs @@ -0,0 +1,79 @@ +using System.IO; +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.Exporting; +using FluentAssertions; +using Xunit; + +namespace DiscordChatExporter.Cli.Tests.Specs.HtmlWriting; + +public class GroupingSpecs : IClassFixture +{ + private readonly TempOutputFixture _tempOutput; + + public GroupingSpecs(TempOutputFixture tempOutput) + { + _tempOutput = tempOutput; + } + + [Fact] + public async Task Messages_are_grouped_correctly() + { + // https://github.com/Tyrrrz/DiscordChatExporter/issues/152 + + // Arrange + var filePath = _tempOutput.GetTempFilePath(); + + // Act + await new ExportChannelsCommand + { + Token = Secrets.DiscordToken, + ChannelIds = new[] { ChannelIds.GroupingTestCases }, + ExportFormat = ExportFormat.HtmlDark, + OutputPath = filePath + }.ExecuteAsync(new FakeConsole()); + + // Assert + var messageGroups = Html + .Parse(await File.ReadAllTextAsync(filePath)) + .QuerySelectorAll(".chatlog__message-group"); + + messageGroups.Should().HaveCount(2); + + messageGroups[0] + .QuerySelectorAll(".chatlog__content") + .Select(e => e.Text()) + .Should() + .ContainInOrder( + "First", + "Second", + "Third", + "Fourth", + "Fifth", + "Sixth", + "Seventh", + "Eighth", + "Ninth", + "Tenth" + ); + + messageGroups[1] + .QuerySelectorAll(".chatlog__content") + .Select(e => e.Text()) + .Should() + .ContainInOrder( + "Eleventh", + "Twelveth", + "Thirteenth", + "Fourteenth", + "Fifteenth" + ); + } +} \ No newline at end of file diff --git a/DiscordChatExporter.Cli.Tests/Specs/HtmlWriting/ReplySpecs.cs b/DiscordChatExporter.Cli.Tests/Specs/HtmlWriting/ReplySpecs.cs index 5568f900..3a38e04d 100644 --- a/DiscordChatExporter.Cli.Tests/Specs/HtmlWriting/ReplySpecs.cs +++ b/DiscordChatExporter.Cli.Tests/Specs/HtmlWriting/ReplySpecs.cs @@ -34,6 +34,8 @@ public class ReplySpecs : IClassFixture [Fact] public async Task Reply_to_a_deleted_message_is_rendered_correctly() { + // https://github.com/Tyrrrz/DiscordChatExporter/issues/645 + // Act var message = await _exportWrapper.GetMessageAsHtmlAsync( ChannelIds.ReplyTestCases, @@ -50,6 +52,8 @@ public class ReplySpecs : IClassFixture [Fact] public async Task Reply_to_an_empty_message_with_attachment_is_rendered_correctly() { + // https://github.com/Tyrrrz/DiscordChatExporter/issues/634 + // Act var message = await _exportWrapper.GetMessageAsHtmlAsync( ChannelIds.ReplyTestCases, diff --git a/DiscordChatExporter.Cli.Tests/Specs/JsonWriting/AttachmentSpecs.cs b/DiscordChatExporter.Cli.Tests/Specs/JsonWriting/AttachmentSpecs.cs index cdf0c946..a0d0c9a8 100644 --- a/DiscordChatExporter.Cli.Tests/Specs/JsonWriting/AttachmentSpecs.cs +++ b/DiscordChatExporter.Cli.Tests/Specs/JsonWriting/AttachmentSpecs.cs @@ -31,7 +31,7 @@ public class AttachmentSpecs : IClassFixture var attachments = message.GetProperty("attachments").EnumerateArray().ToArray(); attachments.Should().HaveCount(1); - attachments.Single().GetProperty("url").GetString().Should().StartWith( + attachments.Single().GetProperty("url").GetString().Should().Be( "https://cdn.discordapp.com/attachments/885587741654536192/885587844964417596/Test.txt" ); attachments.Single().GetProperty("fileName").GetString().Should().Be("Test.txt"); @@ -52,7 +52,7 @@ public class AttachmentSpecs : IClassFixture var attachments = message.GetProperty("attachments").EnumerateArray().ToArray(); attachments.Should().HaveCount(1); - attachments.Single().GetProperty("url").GetString().Should().StartWith( + attachments.Single().GetProperty("url").GetString().Should().Be( "https://cdn.discordapp.com/attachments/885587741654536192/885654862430359613/bird-thumbnail.png" ); attachments.Single().GetProperty("fileName").GetString().Should().Be("bird-thumbnail.png"); @@ -73,7 +73,7 @@ public class AttachmentSpecs : IClassFixture var attachments = message.GetProperty("attachments").EnumerateArray().ToArray(); attachments.Should().HaveCount(1); - attachments.Single().GetProperty("url").GetString().Should().StartWith( + attachments.Single().GetProperty("url").GetString().Should().Be( "https://cdn.discordapp.com/attachments/885587741654536192/885655761512968233/file_example_MP4_640_3MG.mp4" ); attachments.Single().GetProperty("fileName").GetString().Should().Be("file_example_MP4_640_3MG.mp4"); @@ -94,7 +94,7 @@ public class AttachmentSpecs : IClassFixture var attachments = message.GetProperty("attachments").EnumerateArray().ToArray(); attachments.Should().HaveCount(1); - attachments.Single().GetProperty("url").GetString().Should().StartWith( + attachments.Single().GetProperty("url").GetString().Should().Be( "https://cdn.discordapp.com/attachments/885587741654536192/885656175348187146/file_example_MP3_1MG.mp3" ); attachments.Single().GetProperty("fileName").GetString().Should().Be("file_example_MP3_1MG.mp3"); diff --git a/DiscordChatExporter.Cli.Tests/Specs/JsonWriting/MentionSpecs.cs b/DiscordChatExporter.Cli.Tests/Specs/JsonWriting/MentionSpecs.cs index 5bd7fbcd..bb01062a 100644 --- a/DiscordChatExporter.Cli.Tests/Specs/JsonWriting/MentionSpecs.cs +++ b/DiscordChatExporter.Cli.Tests/Specs/JsonWriting/MentionSpecs.cs @@ -33,7 +33,8 @@ public class MentionSpecs : IClassFixture .GetProperty("mentions") .EnumerateArray() .Select(j => j.GetProperty("id").GetString()) - .Should().Contain("128178626683338752"); + .Should() + .Contain("128178626683338752"); } [Fact] diff --git a/DiscordChatExporter.Cli.Tests/Specs/PartitioningSpecs.cs b/DiscordChatExporter.Cli.Tests/Specs/PartitioningSpecs.cs index 35597e4a..a02190db 100644 --- a/DiscordChatExporter.Cli.Tests/Specs/PartitioningSpecs.cs +++ b/DiscordChatExporter.Cli.Tests/Specs/PartitioningSpecs.cs @@ -22,7 +22,7 @@ public class PartitioningSpecs : IClassFixture } [Fact] - public async Task Messages_partitioned_by_count_are_split_into_multiple_files_correctly() + public async Task Messages_partitioned_by_count_are_split_into_a_corresponding_number_of_files() { // Arrange var filePath = _tempOutput.GetTempFilePath(); @@ -46,7 +46,7 @@ public class PartitioningSpecs : IClassFixture } [Fact] - public async Task Messages_partitioned_by_file_size_are_split_into_multiple_files_correctly() + public async Task Messages_partitioned_by_file_size_are_split_into_a_corresponding_number_of_files() { // Arrange var filePath = _tempOutput.GetTempFilePath(); diff --git a/DiscordChatExporter.Cli.Tests/TestData/ChannelIds.cs b/DiscordChatExporter.Cli.Tests/TestData/ChannelIds.cs index 94803354..e75f243c 100644 --- a/DiscordChatExporter.Cli.Tests/TestData/ChannelIds.cs +++ b/DiscordChatExporter.Cli.Tests/TestData/ChannelIds.cs @@ -10,7 +10,7 @@ public static class ChannelIds public static Snowflake EmbedTestCases { get; } = Snowflake.Parse("866472452459462687"); - public static Snowflake StickerTestCases { get; } = Snowflake.Parse("939668868253769729"); + public static Snowflake GroupingTestCases { get; } = Snowflake.Parse("992092091545034842"); public static Snowflake FilterTestCases { get; } = Snowflake.Parse("866744075033641020"); @@ -19,4 +19,6 @@ public static class ChannelIds public static Snowflake ReplyTestCases { get; } = Snowflake.Parse("866459871934677052"); public static Snowflake SelfContainedTestCases { get; } = Snowflake.Parse("887441432678379560"); + + public static Snowflake StickerTestCases { get; } = Snowflake.Parse("939668868253769729"); } \ No newline at end of file