Test improvements

pull/678/head
Tyrrrz 3 years ago
parent 7d9d3ca5fb
commit 63c92047a1

@ -1,5 +1,8 @@
using System.IO;
using System;
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;
@ -9,6 +12,7 @@ using DiscordChatExporter.Cli.Tests.Utils;
using DiscordChatExporter.Core.Discord;
using DiscordChatExporter.Core.Exporting;
using FluentAssertions;
using JsonExtensions;
using Xunit;
using Xunit.Abstractions;
@ -25,6 +29,116 @@ namespace DiscordChatExporter.Cli.Tests
_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());
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
.GetProperty("embeds")
.EnumerateArray()
.Single();
var embedAuthor = embed.GetProperty("author");
var embedThumbnail = embed.GetProperty("thumbnail");
var embedFooter = embed.GetProperty("footer");
var embedFields = embed.GetProperty("fields").EnumerateArray().ToArray();
// Assert
embed.GetProperty("title").GetString().Should().Be("Embed title");
embed.GetProperty("url").GetString().Should().Be("https://example.com");
embed.GetProperty("timestamp").GetString().Should().Be("2021-07-14T21:00:00+00:00");
embed.GetProperty("description").GetString().Should().Be("**Embed** _description_");
embed.GetProperty("color").GetString().Should().Be("#58B9FF");
embedAuthor.GetProperty("name").GetString().Should().Be("Embed author");
embedAuthor.GetProperty("url").GetString().Should().Be("https://example.com/author");
embedAuthor.GetProperty("iconUrl").GetString().Should().NotBeNullOrWhiteSpace();
embedThumbnail.GetProperty("url").GetString().Should().NotBeNullOrWhiteSpace();
embedThumbnail.GetProperty("width").GetInt32().Should().Be(120);
embedThumbnail.GetProperty("height").GetInt32().Should().Be(120);
embedFooter.GetProperty("text").GetString().Should().Be("Embed footer");
embedFooter.GetProperty("iconUrl").GetString().Should().NotBeNullOrWhiteSpace();
embedFields.Should().HaveCount(3);
embedFields[0].GetProperty("name").GetString().Should().Be("Field 1");
embedFields[0].GetProperty("value").GetString().Should().Be("Value 1");
embedFields[0].GetProperty("isInline").GetBoolean().Should().BeTrue();
embedFields[1].GetProperty("name").GetString().Should().Be("Field 2");
embedFields[1].GetProperty("value").GetString().Should().Be("Value 2");
embedFields[1].GetProperty("isInline").GetBoolean().Should().BeTrue();
embedFields[2].GetProperty("name").GetString().Should().Be("Field 3");
embedFields[2].GetProperty("value").GetString().Should().Be("Value 3");
embedFields[2].GetProperty("isInline").GetBoolean().Should().BeTrue();
}
[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();
// Assert
messageText.Should().ContainAll(
"Embed author",
"Embed title",
"Embed description",
"Field 1", "Value 1",
"Field 2", "Value 2",
"Field 3", "Value 3",
"Embed footer"
);
}
[Fact]
public async Task Message_with_YouTube_video_is_rendered_using_an_iframe_player_in_HTML()
{
@ -52,11 +166,10 @@ namespace DiscordChatExporter.Cli.Tests
var messageHtml = html.QuerySelector("#message-866472508588294165");
var iframeHtml = messageHtml?.QuerySelector("iframe");
var iframeSrc = iframeHtml?.GetAttribute("src");
// Assert
iframeHtml.Should().NotBeNull();
iframeSrc.Should().StartWithEquivalent("https://www.youtube.com/embed/qOWW4OlgbvE");
iframeHtml?.GetAttribute("src").Should().StartWithEquivalent("https://www.youtube.com/embed/qOWW4OlgbvE");
}
}
}

@ -63,19 +63,14 @@ namespace DiscordChatExporter.Cli.Tests
StringComparison.OrdinalIgnoreCase
));
var content = messageJson
.GetProperty("content")
.GetString();
// Assert
messageJson.GetProperty("content").GetString().Should().Be("User mention: @Tyrrrz");
var mentionedUserIds = messageJson
messageJson
.GetProperty("mentions")
.EnumerateArray()
.Select(j => j.GetProperty("id").GetString())
.ToArray();
// Assert
content.Should().Be("User mention: @Tyrrrz");
mentionedUserIds.Should().Contain("128178626683338752");
.Should().Contain("128178626683338752");
}
[Fact]
@ -145,12 +140,8 @@ namespace DiscordChatExporter.Cli.Tests
StringComparison.OrdinalIgnoreCase
));
var content = messageJson
.GetProperty("content")
.GetString();
// Assert
content.Should().Be("Text channel mention: #mention-tests");
messageJson.GetProperty("content").GetString().Should().Be("Text channel mention: #mention-tests");
}
[Fact]
@ -219,12 +210,8 @@ namespace DiscordChatExporter.Cli.Tests
StringComparison.OrdinalIgnoreCase
));
var content = messageJson
.GetProperty("content")
.GetString();
// Assert
content.Should().Be("Voice channel mention: #chaos-vc [voice]");
messageJson.GetProperty("content").GetString().Should().Be("Voice channel mention: #chaos-vc [voice]");
}
[Fact]
@ -293,12 +280,8 @@ namespace DiscordChatExporter.Cli.Tests
StringComparison.OrdinalIgnoreCase
));
var content = messageJson
.GetProperty("content")
.GetString();
// Assert
content.Should().Be("Role mention: @Role 1");
messageJson.GetProperty("content").GetString().Should().Be("Role mention: @Role 1");
}
[Fact]

@ -52,12 +52,11 @@ namespace DiscordChatExporter.Cli.Tests
var html = Html.Parse(htmlData);
var messageHtml = html.QuerySelector("#message-866460738239725598");
var referenceHtml = messageHtml?.QuerySelector(".chatlog__reference-link");
// Assert
messageHtml.Should().NotBeNull();
messageHtml?.Text().Trim().Should().Be("reply to original");
referenceHtml?.Text().Trim().Should().Be("original");
messageHtml?.QuerySelector(".chatlog__reference-link")?.Text().Trim().Should().Be("original");
}
[Fact]
@ -86,12 +85,12 @@ namespace DiscordChatExporter.Cli.Tests
var html = Html.Parse(htmlData);
var messageHtml = html.QuerySelector("#message-866460975388819486");
var referenceHtml = messageHtml?.QuerySelector(".chatlog__reference-link");
// Assert
messageHtml.Should().NotBeNull();
messageHtml?.Text().Trim().Should().Be("reply to deleted");
referenceHtml?.Text().Trim().Should().Be("Original message was deleted or could not be loaded.");
messageHtml?.QuerySelector(".chatlog__reference-link")?.Text().Trim().Should()
.Be("Original message was deleted or could not be loaded.");
}
[Fact]
@ -120,12 +119,12 @@ namespace DiscordChatExporter.Cli.Tests
var html = Html.Parse(htmlData);
var messageHtml = html.QuerySelector("#message-866462470335627294");
var referenceHtml = messageHtml?.QuerySelector(".chatlog__reference-link");
// Assert
messageHtml.Should().NotBeNull();
messageHtml?.Text().Trim().Should().Be("reply to attachment");
referenceHtml?.Text().Trim().Should().Be("Click to see attachment 🖼️");
messageHtml?.QuerySelector(".chatlog__reference-link")?.Text().Trim().Should()
.Be("Click to see attachment 🖼️");
}
}
}

@ -1,4 +1,5 @@
using System.Net.Http.Headers;
using System.Diagnostics.CodeAnalysis;
using System.Net.Http.Headers;
namespace DiscordChatExporter.Core.Discord
{
@ -20,6 +21,7 @@ namespace DiscordChatExporter.Core.Discord
_ => new AuthenticationHeaderValue(Value)
};
[ExcludeFromCodeCoverage]
public override string ToString() => Value;
}
}

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Text.Json;
using DiscordChatExporter.Core.Discord.Data.Common;
@ -49,6 +50,7 @@ namespace DiscordChatExporter.Core.Discord.Data
FileSize = fileSize;
}
[ExcludeFromCodeCoverage]
public override string ToString() => FileName;
}

@ -1,4 +1,5 @@
using System.Linq;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Text.Json;
using DiscordChatExporter.Core.Discord.Data.Common;
using DiscordChatExporter.Core.Utils.Extensions;
@ -51,6 +52,7 @@ namespace DiscordChatExporter.Core.Discord.Data
Topic = topic;
}
[ExcludeFromCodeCoverage]
public override string ToString() => Name;
}

@ -1,4 +1,5 @@
using System.Text.Json;
using System.Diagnostics.CodeAnalysis;
using System.Text.Json;
using DiscordChatExporter.Core.Discord.Data.Common;
using DiscordChatExporter.Core.Utils.Extensions;
using JsonExtensions.Reading;
@ -20,6 +21,7 @@ namespace DiscordChatExporter.Core.Discord.Data
Position = position;
}
[ExcludeFromCodeCoverage]
public override string ToString() => Name;
}

@ -1,4 +1,5 @@
using System;
using System.Diagnostics.CodeAnalysis;
namespace DiscordChatExporter.Core.Discord.Data.Common
{
@ -41,6 +42,7 @@ namespace DiscordChatExporter.Core.Discord.Data.Common
return "bytes";
}
[ExcludeFromCodeCoverage]
public override string ToString() => $"{GetLargestWholeNumberValue():0.##} {GetLargestWholeNumberSymbol()}";
}

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Drawing;
using System.Linq;
using System.Text.Json;
@ -57,6 +58,7 @@ namespace DiscordChatExporter.Core.Discord.Data
public YouTubeVideoEmbedProjection? TryGetYouTubeVideo() => YouTubeVideoEmbedProjection.TryResolve(this);
[ExcludeFromCodeCoverage]
public override string ToString() => Title ?? "<untitled embed>";
}

@ -1,3 +1,4 @@
using System.Diagnostics.CodeAnalysis;
using System.Text.Json;
using JsonExtensions.Reading;
@ -22,6 +23,7 @@ namespace DiscordChatExporter.Core.Discord.Data
IconProxyUrl = iconProxyUrl;
}
[ExcludeFromCodeCoverage]
public override string ToString() => Name ?? "<unnamed author>";
}

@ -1,3 +1,4 @@
using System.Diagnostics.CodeAnalysis;
using System.Text.Json;
using JsonExtensions.Reading;
@ -19,6 +20,7 @@ namespace DiscordChatExporter.Core.Discord.Data
IsInline = isInline;
}
[ExcludeFromCodeCoverage]
public override string ToString() => $"{Name} | {Value}";
}

@ -1,3 +1,4 @@
using System.Diagnostics.CodeAnalysis;
using System.Text.Json;
using JsonExtensions.Reading;
@ -19,6 +20,7 @@ namespace DiscordChatExporter.Core.Discord.Data
IconProxyUrl = iconProxyUrl;
}
[ExcludeFromCodeCoverage]
public override string ToString() => Text;
}

@ -1,4 +1,5 @@
using System.Linq;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Text.Json;
using DiscordChatExporter.Core.Utils;
using DiscordChatExporter.Core.Utils.Extensions;
@ -33,6 +34,7 @@ namespace DiscordChatExporter.Core.Discord.Data
ImageUrl = imageUrl;
}
[ExcludeFromCodeCoverage]
public override string ToString() => Name;
}

@ -1,4 +1,5 @@
using System.Text.Json;
using System.Diagnostics.CodeAnalysis;
using System.Text.Json;
using DiscordChatExporter.Core.Discord.Data.Common;
using DiscordChatExporter.Core.Utils.Extensions;
@ -20,6 +21,7 @@ namespace DiscordChatExporter.Core.Discord.Data
IconUrl = iconUrl;
}
[ExcludeFromCodeCoverage]
public override string ToString() => Name;
}

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Text.Json;
using DiscordChatExporter.Core.Discord.Data.Common;
@ -26,6 +27,7 @@ namespace DiscordChatExporter.Core.Discord.Data
RoleIds = roleIds;
}
[ExcludeFromCodeCoverage]
public override string ToString() => Nick;
}

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Text.Json;
using DiscordChatExporter.Core.Discord.Data.Common;
@ -85,6 +86,7 @@ namespace DiscordChatExporter.Core.Discord.Data
ReferencedMessage = referencedMessage;
}
[ExcludeFromCodeCoverage]
public override string ToString() => Content;
}

@ -1,3 +1,4 @@
using System.Diagnostics.CodeAnalysis;
using System.Text.Json;
using DiscordChatExporter.Core.Utils.Extensions;
using JsonExtensions.Reading;
@ -20,6 +21,7 @@ namespace DiscordChatExporter.Core.Discord.Data
GuildId = guildId;
}
[ExcludeFromCodeCoverage]
public override string ToString() => MessageId?.ToString() ?? "<unknown reference>";
}

@ -1,4 +1,5 @@
using System.Text.Json;
using System.Diagnostics.CodeAnalysis;
using System.Text.Json;
using DiscordChatExporter.Core.Utils.Extensions;
namespace DiscordChatExporter.Core.Discord.Data
@ -16,6 +17,7 @@ namespace DiscordChatExporter.Core.Discord.Data
Count = count;
}
[ExcludeFromCodeCoverage]
public override string ToString() => $"{Emoji} ({Count})";
}

@ -1,4 +1,5 @@
using System.Drawing;
using System.Diagnostics.CodeAnalysis;
using System.Drawing;
using System.Text.Json;
using DiscordChatExporter.Core.Discord.Data.Common;
using DiscordChatExporter.Core.Utils.Extensions;
@ -29,6 +30,7 @@ namespace DiscordChatExporter.Core.Discord.Data
Color = color;
}
[ExcludeFromCodeCoverage]
public override string ToString() => Name;
}

@ -1,4 +1,5 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.Text.Json;
using DiscordChatExporter.Core.Discord.Data.Common;
using DiscordChatExporter.Core.Utils.Extensions;
@ -37,6 +38,7 @@ namespace DiscordChatExporter.Core.Discord.Data
AvatarUrl = avatarUrl;
}
[ExcludeFromCodeCoverage]
public override string ToString() => FullName;
}

@ -1,4 +1,5 @@
using System.Text.RegularExpressions;
using System.Diagnostics.CodeAnalysis;
using System.Text.RegularExpressions;
namespace DiscordChatExporter.Core.Discord.Data
{
@ -6,14 +7,11 @@ namespace DiscordChatExporter.Core.Discord.Data
{
public string VideoId { get; }
public string Url { get; }
public string Url => $"https://www.youtube.com/embed/{VideoId}";
public YouTubeVideoEmbedProjection(string videoId, string url)
{
VideoId = videoId;
Url = url;
}
public YouTubeVideoEmbedProjection(string videoId) => VideoId = videoId;
[ExcludeFromCodeCoverage]
public override string ToString() => Url;
}
@ -53,9 +51,7 @@ namespace DiscordChatExporter.Core.Discord.Data
if (string.IsNullOrWhiteSpace(videoId))
return null;
var url = $"https://www.youtube.com/embed/{videoId}";
return new YouTubeVideoEmbedProjection(videoId, url);
return new YouTubeVideoEmbedProjection(videoId);
}
}
}

@ -1,4 +1,5 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Text.RegularExpressions;
@ -14,6 +15,7 @@ namespace DiscordChatExporter.Core.Discord
(long) ((Value >> 22) + 1420070400000UL)
).ToLocalTime();
[ExcludeFromCodeCoverage]
public override string ToString() => Value.ToString(CultureInfo.InvariantCulture);
}

@ -1,4 +1,5 @@
using DiscordChatExporter.Core.Utils;
using System.Diagnostics.CodeAnalysis;
using DiscordChatExporter.Core.Utils;
namespace DiscordChatExporter.Core.Markdown
{
@ -31,6 +32,7 @@ namespace DiscordChatExporter.Core.Markdown
{
}
[ExcludeFromCodeCoverage]
public override string ToString() => $"<Emoji> {Name}";
}
}

@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
namespace DiscordChatExporter.Core.Markdown
{
@ -14,6 +15,7 @@ namespace DiscordChatExporter.Core.Markdown
Children = children;
}
[ExcludeFromCodeCoverage]
public override string ToString() => $"<{Formatting}> (+{Children.Count})";
}
}

@ -1,4 +1,6 @@
namespace DiscordChatExporter.Core.Markdown
using System.Diagnostics.CodeAnalysis;
namespace DiscordChatExporter.Core.Markdown
{
internal class InlineCodeBlockNode : MarkdownNode
{
@ -9,6 +11,7 @@
Code = code;
}
[ExcludeFromCodeCoverage]
public override string ToString() => $"<Code> {Code}";
}
}

@ -1,4 +1,6 @@
namespace DiscordChatExporter.Core.Markdown
using System.Diagnostics.CodeAnalysis;
namespace DiscordChatExporter.Core.Markdown
{
internal class LinkNode : MarkdownNode
{
@ -17,6 +19,7 @@
{
}
[ExcludeFromCodeCoverage]
public override string ToString() => $"<Link> {Title}";
}
}

@ -1,4 +1,6 @@
namespace DiscordChatExporter.Core.Markdown
using System.Diagnostics.CodeAnalysis;
namespace DiscordChatExporter.Core.Markdown
{
internal class MentionNode : MarkdownNode
{
@ -12,6 +14,7 @@
Kind = kind;
}
[ExcludeFromCodeCoverage]
public override string ToString() => $"<{Kind} mention> {Id}";
}
}

@ -1,4 +1,6 @@
namespace DiscordChatExporter.Core.Markdown
using System.Diagnostics.CodeAnalysis;
namespace DiscordChatExporter.Core.Markdown
{
internal class MultiLineCodeBlockNode : MarkdownNode
{
@ -12,6 +14,7 @@
Code = code;
}
[ExcludeFromCodeCoverage]
public override string ToString() => $"<{Language}> {Code}";
}
}

@ -1,4 +1,6 @@
namespace DiscordChatExporter.Core.Markdown
using System.Diagnostics.CodeAnalysis;
namespace DiscordChatExporter.Core.Markdown
{
internal class TextNode : MarkdownNode
{
@ -9,6 +11,7 @@
Text = text;
}
[ExcludeFromCodeCoverage]
public override string ToString() => Text;
}
}

@ -1,4 +1,5 @@
using System;
using System.Diagnostics.CodeAnalysis;
namespace DiscordChatExporter.Core.Markdown
{
@ -8,6 +9,7 @@ namespace DiscordChatExporter.Core.Markdown
public UnixTimestampNode(DateTimeOffset value) => Value = value;
[ExcludeFromCodeCoverage]
public override string ToString() => Value.ToString();
}
}

@ -1,4 +1,5 @@
using System;
using System.Diagnostics.CodeAnalysis;
using Superpower;
using Superpower.Parsers;
@ -12,7 +13,9 @@ namespace DiscordChatExporter.Core.Utils.Extensions
public static TextParser<T> Token<T>(this TextParser<T> parser) =>
parser.Between(Character.WhiteSpace.IgnoreMany(), Character.WhiteSpace.IgnoreMany());
// From: https://twitter.com/nblumhardt/status/1389349059786264578
// Only used for debugging while writing Superpower parsers.
// From https://twitter.com/nblumhardt/status/1389349059786264578
[ExcludeFromCodeCoverage]
public static TextParser<T> Log<T>(this TextParser<T> parser, string description) => i =>
{
Console.WriteLine($"Trying {description} ->");

Loading…
Cancel
Save