This commit is contained in:
Tyrrrz 2021-12-08 23:50:21 +02:00
parent 8e7baee8a5
commit 880f400e2c
148 changed files with 14241 additions and 14396 deletions

View file

@ -14,119 +14,118 @@ using DiscordChatExporter.Core.Discord;
using DiscordChatExporter.Core.Exporting;
using JsonExtensions;
namespace DiscordChatExporter.Cli.Tests.Fixtures
namespace DiscordChatExporter.Cli.Tests.Fixtures;
public class ExportWrapperFixture : IDisposable
{
public class ExportWrapperFixture : IDisposable
private string DirPath { get; } = Path.Combine(
Path.GetDirectoryName(typeof(ExportWrapperFixture).Assembly.Location) ?? Directory.GetCurrentDirectory(),
"ExportCache",
Guid.NewGuid().ToString()
);
public ExportWrapperFixture() => DirectoryEx.Reset(DirPath);
private async ValueTask<string> ExportAsync(Snowflake channelId, ExportFormat format)
{
private string DirPath { get; } = Path.Combine(
Path.GetDirectoryName(typeof(ExportWrapperFixture).Assembly.Location) ?? Directory.GetCurrentDirectory(),
"ExportCache",
Guid.NewGuid().ToString()
var fileName = channelId.ToString() + '.' + format.GetFileExtension();
var filePath = Path.Combine(DirPath, fileName);
// 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 = format,
OutputPath = filePath
}.ExecuteAsync(new FakeConsole());
}
return await File.ReadAllTextAsync(filePath);
}
public async ValueTask<IHtmlDocument> ExportAsHtmlAsync(Snowflake channelId)
{
var data = await ExportAsync(channelId, ExportFormat.HtmlDark);
return Html.Parse(data);
}
public async ValueTask<JsonElement> ExportAsJsonAsync(Snowflake channelId)
{
var data = await ExportAsync(channelId, ExportFormat.Json);
return Json.Parse(data);
}
public async ValueTask<string> ExportAsPlainTextAsync(Snowflake channelId)
{
var data = await ExportAsync(channelId, ExportFormat.PlainText);
return data;
}
public async ValueTask<string> ExportAsCsvAsync(Snowflake channelId)
{
var data = await ExportAsync(channelId, ExportFormat.Csv);
return data;
}
public async ValueTask<IReadOnlyList<IElement>> GetMessagesAsHtmlAsync(Snowflake channelId)
{
var document = await ExportAsHtmlAsync(channelId);
return document.QuerySelectorAll("[data-message-id]").ToArray();
}
public async ValueTask<IReadOnlyList<JsonElement>> GetMessagesAsJsonAsync(Snowflake channelId)
{
var document = await ExportAsJsonAsync(channelId);
return document.GetProperty("messages").EnumerateArray().ToArray();
}
public async ValueTask<IElement> GetMessageAsHtmlAsync(Snowflake channelId, Snowflake messageId)
{
var messages = await GetMessagesAsHtmlAsync(channelId);
var message = messages.SingleOrDefault(e =>
string.Equals(
e.GetAttribute("data-message-id"),
messageId.ToString(),
StringComparison.OrdinalIgnoreCase
)
);
public ExportWrapperFixture() => DirectoryEx.Reset(DirPath);
private async ValueTask<string> ExportAsync(Snowflake channelId, ExportFormat format)
if (message is null)
{
var fileName = channelId.ToString() + '.' + format.GetFileExtension();
var filePath = Path.Combine(DirPath, fileName);
// 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 = format,
OutputPath = filePath
}.ExecuteAsync(new FakeConsole());
}
return await File.ReadAllTextAsync(filePath);
}
public async ValueTask<IHtmlDocument> ExportAsHtmlAsync(Snowflake channelId)
{
var data = await ExportAsync(channelId, ExportFormat.HtmlDark);
return Html.Parse(data);
}
public async ValueTask<JsonElement> ExportAsJsonAsync(Snowflake channelId)
{
var data = await ExportAsync(channelId, ExportFormat.Json);
return Json.Parse(data);
}
public async ValueTask<string> ExportAsPlainTextAsync(Snowflake channelId)
{
var data = await ExportAsync(channelId, ExportFormat.PlainText);
return data;
}
public async ValueTask<string> ExportAsCsvAsync(Snowflake channelId)
{
var data = await ExportAsync(channelId, ExportFormat.Csv);
return data;
}
public async ValueTask<IReadOnlyList<IElement>> GetMessagesAsHtmlAsync(Snowflake channelId)
{
var document = await ExportAsHtmlAsync(channelId);
return document.QuerySelectorAll("[data-message-id]").ToArray();
}
public async ValueTask<IReadOnlyList<JsonElement>> GetMessagesAsJsonAsync(Snowflake channelId)
{
var document = await ExportAsJsonAsync(channelId);
return document.GetProperty("messages").EnumerateArray().ToArray();
}
public async ValueTask<IElement> GetMessageAsHtmlAsync(Snowflake channelId, Snowflake messageId)
{
var messages = await GetMessagesAsHtmlAsync(channelId);
var message = messages.SingleOrDefault(e =>
string.Equals(
e.GetAttribute("data-message-id"),
messageId.ToString(),
StringComparison.OrdinalIgnoreCase
)
throw new InvalidOperationException(
$"Message '{messageId}' does not exist in export of channel '{channelId}'."
);
if (message is null)
{
throw new InvalidOperationException(
$"Message '{messageId}' does not exist in export of channel '{channelId}'."
);
}
return message;
}
public async ValueTask<JsonElement> 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
)
);
if (message.ValueKind == JsonValueKind.Undefined)
{
throw new InvalidOperationException(
$"Message '{messageId}' does not exist in export of channel '{channelId}'."
);
}
return message;
}
public void Dispose() => DirectoryEx.DeleteIfExists(DirPath);
return message;
}
public async ValueTask<JsonElement> 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
)
);
if (message.ValueKind == JsonValueKind.Undefined)
{
throw new InvalidOperationException(
$"Message '{messageId}' does not exist in export of channel '{channelId}'."
);
}
return message;
}
public void Dispose() => DirectoryEx.DeleteIfExists(DirPath);
}

View file

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

View file

@ -1,46 +1,45 @@
using System;
using System.IO;
namespace DiscordChatExporter.Cli.Tests.Infra
namespace DiscordChatExporter.Cli.Tests.Infra;
internal static class Secrets
{
internal static class Secrets
private static readonly Lazy<string> DiscordTokenLazy = new(() =>
{
private static readonly Lazy<string> DiscordTokenLazy = new(() =>
{
var fromEnvironment = Environment.GetEnvironmentVariable("DISCORD_TOKEN");
if (!string.IsNullOrWhiteSpace(fromEnvironment))
return fromEnvironment;
var fromEnvironment = Environment.GetEnvironmentVariable("DISCORD_TOKEN");
if (!string.IsNullOrWhiteSpace(fromEnvironment))
return fromEnvironment;
var secretFilePath = Path.Combine(
Path.GetDirectoryName(typeof(Secrets).Assembly.Location) ?? Directory.GetCurrentDirectory(),
"DiscordToken.secret"
);
var secretFilePath = Path.Combine(
Path.GetDirectoryName(typeof(Secrets).Assembly.Location) ?? Directory.GetCurrentDirectory(),
"DiscordToken.secret"
);
if (File.Exists(secretFilePath))
return File.ReadAllText(secretFilePath);
if (File.Exists(secretFilePath))
return File.ReadAllText(secretFilePath);
throw new InvalidOperationException("Discord token not provided for tests.");
});
throw new InvalidOperationException("Discord token not provided for tests.");
});
private static readonly Lazy<bool> IsDiscordTokenBotLazy = new(() =>
{
var fromEnvironment = Environment.GetEnvironmentVariable("DISCORD_TOKEN_BOT");
if (!string.IsNullOrWhiteSpace(fromEnvironment))
return string.Equals(fromEnvironment, "true", StringComparison.OrdinalIgnoreCase);
private static readonly Lazy<bool> IsDiscordTokenBotLazy = new(() =>
{
var fromEnvironment = Environment.GetEnvironmentVariable("DISCORD_TOKEN_BOT");
if (!string.IsNullOrWhiteSpace(fromEnvironment))
return string.Equals(fromEnvironment, "true", StringComparison.OrdinalIgnoreCase);
var secretFilePath = Path.Combine(
Path.GetDirectoryName(typeof(Secrets).Assembly.Location) ?? Directory.GetCurrentDirectory(),
"DiscordTokenBot.secret"
);
var secretFilePath = Path.Combine(
Path.GetDirectoryName(typeof(Secrets).Assembly.Location) ?? Directory.GetCurrentDirectory(),
"DiscordTokenBot.secret"
);
if (File.Exists(secretFilePath))
return true;
if (File.Exists(secretFilePath))
return true;
return false;
});
return false;
});
public static string DiscordToken => DiscordTokenLazy.Value;
public static string DiscordToken => DiscordTokenLazy.Value;
public static bool IsDiscordTokenBot => IsDiscordTokenBotLazy.Value;
}
public static bool IsDiscordTokenBot => IsDiscordTokenBotLazy.Value;
}

View file

@ -4,28 +4,27 @@ using DiscordChatExporter.Cli.Tests.TestData;
using FluentAssertions;
using Xunit;
namespace DiscordChatExporter.Cli.Tests.Specs.CsvWriting
{
public record ContentSpecs(ExportWrapperFixture ExportWrapper) : IClassFixture<ExportWrapperFixture>
{
[Fact]
public async Task Messages_are_exported_correctly()
{
// Act
var document = await ExportWrapper.ExportAsCsvAsync(ChannelIds.DateRangeTestCases);
namespace DiscordChatExporter.Cli.Tests.Specs.CsvWriting;
// Assert
document.Should().ContainAll(
"Tyrrrz#5447",
"Hello world",
"Goodbye world",
"Foo bar",
"Hurdle Durdle",
"One",
"Two",
"Three",
"Yeet"
);
}
public record ContentSpecs(ExportWrapperFixture ExportWrapper) : IClassFixture<ExportWrapperFixture>
{
[Fact]
public async Task Messages_are_exported_correctly()
{
// Act
var document = await ExportWrapper.ExportAsCsvAsync(ChannelIds.DateRangeTestCases);
// Assert
document.Should().ContainAll(
"Tyrrrz#5447",
"Hello world",
"Goodbye world",
"Foo bar",
"Hurdle Durdle",
"One",
"Two",
"Three",
"Yeet"
);
}
}

View file

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

View file

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

View file

@ -6,88 +6,87 @@ using DiscordChatExporter.Core.Discord;
using FluentAssertions;
using Xunit;
namespace DiscordChatExporter.Cli.Tests.Specs.HtmlWriting
namespace DiscordChatExporter.Cli.Tests.Specs.HtmlWriting;
public record AttachmentSpecs(ExportWrapperFixture ExportWrapper) : IClassFixture<ExportWrapperFixture>
{
public record AttachmentSpecs(ExportWrapperFixture ExportWrapper) : IClassFixture<ExportWrapperFixture>
[Fact]
public async Task Message_with_a_generic_attachment_is_rendered_correctly()
{
[Fact]
public async Task Message_with_a_generic_attachment_is_rendered_correctly()
{
// Act
var message = await ExportWrapper.GetMessageAsHtmlAsync(
ChannelIds.AttachmentTestCases,
Snowflake.Parse("885587844989612074")
);
// Act
var message = await ExportWrapper.GetMessageAsHtmlAsync(
ChannelIds.AttachmentTestCases,
Snowflake.Parse("885587844989612074")
);
var fileUrl = message.QuerySelector("a")?.GetAttribute("href");
var fileUrl = message.QuerySelector("a")?.GetAttribute("href");
// Assert
message.Text().Should().ContainAll(
"Generic file attachment",
"Test.txt",
"11 bytes"
);
// Assert
message.Text().Should().ContainAll(
"Generic file attachment",
"Test.txt",
"11 bytes"
);
fileUrl.Should().StartWithEquivalentOf(
"https://cdn.discordapp.com/attachments/885587741654536192/885587844964417596/Test.txt"
);
}
fileUrl.Should().StartWithEquivalentOf(
"https://cdn.discordapp.com/attachments/885587741654536192/885587844964417596/Test.txt"
);
}
[Fact]
public async Task Message_with_an_image_attachment_is_rendered_correctly()
{
// Act
var message = await ExportWrapper.GetMessageAsHtmlAsync(
ChannelIds.AttachmentTestCases,
Snowflake.Parse("885654862656843786")
);
[Fact]
public async Task Message_with_an_image_attachment_is_rendered_correctly()
{
// Act
var message = await ExportWrapper.GetMessageAsHtmlAsync(
ChannelIds.AttachmentTestCases,
Snowflake.Parse("885654862656843786")
);
var imageUrl = message.QuerySelector("img")?.GetAttribute("src");
var imageUrl = message.QuerySelector("img")?.GetAttribute("src");
// Assert
message.Text().Should().Contain("Image attachment");
// Assert
message.Text().Should().Contain("Image attachment");
imageUrl.Should().StartWithEquivalentOf(
"https://cdn.discordapp.com/attachments/885587741654536192/885654862430359613/bird-thumbnail.png"
);
}
imageUrl.Should().StartWithEquivalentOf(
"https://cdn.discordapp.com/attachments/885587741654536192/885654862430359613/bird-thumbnail.png"
);
}
[Fact]
public async Task Message_with_a_video_attachment_is_rendered_correctly()
{
// Act
var message = await ExportWrapper.GetMessageAsHtmlAsync(
ChannelIds.AttachmentTestCases,
Snowflake.Parse("885655761919836171")
);
[Fact]
public async Task Message_with_a_video_attachment_is_rendered_correctly()
{
// Act
var message = await ExportWrapper.GetMessageAsHtmlAsync(
ChannelIds.AttachmentTestCases,
Snowflake.Parse("885655761919836171")
);
var videoUrl = message.QuerySelector("video source")?.GetAttribute("src");
var videoUrl = message.QuerySelector("video source")?.GetAttribute("src");
// Assert
message.Text().Should().Contain("Video attachment");
// Assert
message.Text().Should().Contain("Video attachment");
videoUrl.Should().StartWithEquivalentOf(
"https://cdn.discordapp.com/attachments/885587741654536192/885655761512968233/file_example_MP4_640_3MG.mp4"
);
}
videoUrl.Should().StartWithEquivalentOf(
"https://cdn.discordapp.com/attachments/885587741654536192/885655761512968233/file_example_MP4_640_3MG.mp4"
);
}
[Fact]
public async Task Message_with_an_audio_attachment_is_rendered_correctly()
{
// Act
var message = await ExportWrapper.GetMessageAsHtmlAsync(
ChannelIds.AttachmentTestCases,
Snowflake.Parse("885656175620808734")
);
[Fact]
public async Task Message_with_an_audio_attachment_is_rendered_correctly()
{
// Act
var message = await ExportWrapper.GetMessageAsHtmlAsync(
ChannelIds.AttachmentTestCases,
Snowflake.Parse("885656175620808734")
);
var audioUrl = message.QuerySelector("audio source")?.GetAttribute("src");
var audioUrl = message.QuerySelector("audio source")?.GetAttribute("src");
// Assert
message.Text().Should().Contain("Audio attachment");
// Assert
message.Text().Should().Contain("Audio attachment");
audioUrl.Should().StartWithEquivalentOf(
"https://cdn.discordapp.com/attachments/885587741654536192/885656175348187146/file_example_MP3_1MG.mp3"
);
}
audioUrl.Should().StartWithEquivalentOf(
"https://cdn.discordapp.com/attachments/885587741654536192/885656175348187146/file_example_MP3_1MG.mp3"
);
}
}

View file

@ -6,38 +6,37 @@ using DiscordChatExporter.Cli.Tests.TestData;
using FluentAssertions;
using Xunit;
namespace DiscordChatExporter.Cli.Tests.Specs.HtmlWriting
namespace DiscordChatExporter.Cli.Tests.Specs.HtmlWriting;
public record ContentSpecs(ExportWrapperFixture ExportWrapper) : IClassFixture<ExportWrapperFixture>
{
public record ContentSpecs(ExportWrapperFixture ExportWrapper) : IClassFixture<ExportWrapperFixture>
[Fact]
public async Task Messages_are_exported_correctly()
{
[Fact]
public async Task Messages_are_exported_correctly()
{
// Act
var messages = await ExportWrapper.GetMessagesAsHtmlAsync(ChannelIds.DateRangeTestCases);
// Act
var messages = await ExportWrapper.GetMessagesAsHtmlAsync(ChannelIds.DateRangeTestCases);
// Assert
messages.Select(e => e.GetAttribute("data-message-id")).Should().Equal(
"866674314627121232",
"866710679758045195",
"866732113319428096",
"868490009366396958",
"868505966528835604",
"868505969821364245",
"868505973294268457",
"885169254029213696"
);
// Assert
messages.Select(e => e.GetAttribute("data-message-id")).Should().Equal(
"866674314627121232",
"866710679758045195",
"866732113319428096",
"868490009366396958",
"868505966528835604",
"868505969821364245",
"868505973294268457",
"885169254029213696"
);
messages.Select(e => e.QuerySelector(".chatlog__content")?.Text().Trim()).Should().Equal(
"Hello world",
"Goodbye world",
"Foo bar",
"Hurdle Durdle",
"One",
"Two",
"Three",
"Yeet"
);
}
messages.Select(e => e.QuerySelector(".chatlog__content")?.Text().Trim()).Should().Equal(
"Hello world",
"Goodbye world",
"Foo bar",
"Hurdle Durdle",
"One",
"Two",
"Three",
"Yeet"
);
}
}

View file

@ -6,59 +6,58 @@ using DiscordChatExporter.Core.Discord;
using FluentAssertions;
using Xunit;
namespace DiscordChatExporter.Cli.Tests.Specs.HtmlWriting
namespace DiscordChatExporter.Cli.Tests.Specs.HtmlWriting;
public record EmbedSpecs(ExportWrapperFixture ExportWrapper) : IClassFixture<ExportWrapperFixture>
{
public record EmbedSpecs(ExportWrapperFixture ExportWrapper) : IClassFixture<ExportWrapperFixture>
[Fact]
public async Task Message_with_an_embed_is_rendered_correctly()
{
[Fact]
public async Task Message_with_an_embed_is_rendered_correctly()
{
// Act
var message = await ExportWrapper.GetMessageAsHtmlAsync(
ChannelIds.EmbedTestCases,
Snowflake.Parse("866769910729146400")
);
// Act
var message = await ExportWrapper.GetMessageAsHtmlAsync(
ChannelIds.EmbedTestCases,
Snowflake.Parse("866769910729146400")
);
// Assert
message.Text().Should().ContainAll(
"Embed author",
"Embed title",
"Embed description",
"Field 1", "Value 1",
"Field 2", "Value 2",
"Field 3", "Value 3",
"Embed footer"
);
}
// Assert
message.Text().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_a_Spotify_track_is_rendered_using_an_iframe()
{
// Act
var message = await ExportWrapper.GetMessageAsHtmlAsync(
ChannelIds.EmbedTestCases,
Snowflake.Parse("867886632203976775")
);
[Fact]
public async Task Message_with_a_Spotify_track_is_rendered_using_an_iframe()
{
// Act
var message = await ExportWrapper.GetMessageAsHtmlAsync(
ChannelIds.EmbedTestCases,
Snowflake.Parse("867886632203976775")
);
var iframeSrc = message.QuerySelector("iframe")?.GetAttribute("src");
var iframeSrc = message.QuerySelector("iframe")?.GetAttribute("src");
// Assert
iframeSrc.Should().StartWithEquivalentOf("https://open.spotify.com/embed/track/1LHZMWefF9502NPfArRfvP");
}
// Assert
iframeSrc.Should().StartWithEquivalentOf("https://open.spotify.com/embed/track/1LHZMWefF9502NPfArRfvP");
}
[Fact]
public async Task Message_with_a_YouTube_video_is_rendered_using_an_iframe()
{
// Act
var message = await ExportWrapper.GetMessageAsHtmlAsync(
ChannelIds.EmbedTestCases,
Snowflake.Parse("866472508588294165")
);
[Fact]
public async Task Message_with_a_YouTube_video_is_rendered_using_an_iframe()
{
// Act
var message = await ExportWrapper.GetMessageAsHtmlAsync(
ChannelIds.EmbedTestCases,
Snowflake.Parse("866472508588294165")
);
var iframeSrc = message.QuerySelector("iframe")?.GetAttribute("src");
var iframeSrc = message.QuerySelector("iframe")?.GetAttribute("src");
// Assert
iframeSrc.Should().StartWithEquivalentOf("https://www.youtube.com/embed/qOWW4OlgbvE");
}
// Assert
iframeSrc.Should().StartWithEquivalentOf("https://www.youtube.com/embed/qOWW4OlgbvE");
}
}

View file

@ -6,61 +6,60 @@ using DiscordChatExporter.Core.Discord;
using FluentAssertions;
using Xunit;
namespace DiscordChatExporter.Cli.Tests.Specs.HtmlWriting
namespace DiscordChatExporter.Cli.Tests.Specs.HtmlWriting;
public record MentionSpecs(ExportWrapperFixture ExportWrapper) : IClassFixture<ExportWrapperFixture>
{
public record MentionSpecs(ExportWrapperFixture ExportWrapper) : IClassFixture<ExportWrapperFixture>
[Fact]
public async Task User_mention_is_rendered_correctly()
{
[Fact]
public async Task User_mention_is_rendered_correctly()
{
// Act
var message = await ExportWrapper.GetMessageAsHtmlAsync(
ChannelIds.MentionTestCases,
Snowflake.Parse("866458840245076028")
);
// Act
var message = await ExportWrapper.GetMessageAsHtmlAsync(
ChannelIds.MentionTestCases,
Snowflake.Parse("866458840245076028")
);
// Assert
message.Text().Trim().Should().Be("User mention: @Tyrrrz");
message.InnerHtml.Should().Contain("Tyrrrz#5447");
}
// Assert
message.Text().Trim().Should().Be("User mention: @Tyrrrz");
message.InnerHtml.Should().Contain("Tyrrrz#5447");
}
[Fact]
public async Task Text_channel_mention_is_rendered_correctly()
{
// Act
var message = await ExportWrapper.GetMessageAsHtmlAsync(
ChannelIds.MentionTestCases,
Snowflake.Parse("866459040480624680")
);
[Fact]
public async Task Text_channel_mention_is_rendered_correctly()
{
// Act
var message = await ExportWrapper.GetMessageAsHtmlAsync(
ChannelIds.MentionTestCases,
Snowflake.Parse("866459040480624680")
);
// Assert
message.Text().Trim().Should().Be("Text channel mention: #mention-tests");
}
// Assert
message.Text().Trim().Should().Be("Text channel mention: #mention-tests");
}
[Fact]
public async Task Voice_channel_mention_is_rendered_correctly()
{
// Act
var message = await ExportWrapper.GetMessageAsHtmlAsync(
ChannelIds.MentionTestCases,
Snowflake.Parse("866459175462633503")
);
[Fact]
public async Task Voice_channel_mention_is_rendered_correctly()
{
// Act
var message = await ExportWrapper.GetMessageAsHtmlAsync(
ChannelIds.MentionTestCases,
Snowflake.Parse("866459175462633503")
);
// Assert
message.Text().Trim().Should().Be("Voice channel mention: 🔊chaos-vc");
}
// Assert
message.Text().Trim().Should().Be("Voice channel mention: 🔊chaos-vc");
}
[Fact]
public async Task Role_mention_is_rendered_correctly()
{
// Act
var message = await ExportWrapper.GetMessageAsHtmlAsync(
ChannelIds.MentionTestCases,
Snowflake.Parse("866459254693429258")
);
[Fact]
public async Task Role_mention_is_rendered_correctly()
{
// Act
var message = await ExportWrapper.GetMessageAsHtmlAsync(
ChannelIds.MentionTestCases,
Snowflake.Parse("866459254693429258")
);
// Assert
message.Text().Trim().Should().Be("Role mention: @Role 1");
}
// Assert
message.Text().Trim().Should().Be("Role mention: @Role 1");
}
}

View file

@ -6,52 +6,51 @@ using DiscordChatExporter.Core.Discord;
using FluentAssertions;
using Xunit;
namespace DiscordChatExporter.Cli.Tests.Specs.HtmlWriting
namespace DiscordChatExporter.Cli.Tests.Specs.HtmlWriting;
public record ReplySpecs(ExportWrapperFixture ExportWrapper) : IClassFixture<ExportWrapperFixture>
{
public record ReplySpecs(ExportWrapperFixture ExportWrapper) : IClassFixture<ExportWrapperFixture>
[Fact]
public async Task Reply_to_a_normal_message_is_rendered_correctly()
{
[Fact]
public async Task Reply_to_a_normal_message_is_rendered_correctly()
{
// Act
var message = await ExportWrapper.GetMessageAsHtmlAsync(
ChannelIds.ReplyTestCases,
Snowflake.Parse("866460738239725598")
);
// Act
var message = await ExportWrapper.GetMessageAsHtmlAsync(
ChannelIds.ReplyTestCases,
Snowflake.Parse("866460738239725598")
);
// Assert
message.Text().Trim().Should().Be("reply to original");
message.QuerySelector(".chatlog__reference-link")?.Text().Trim().Should().Be("original");
}
// Assert
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()
{
// Act
var message = await ExportWrapper.GetMessageAsHtmlAsync(
ChannelIds.ReplyTestCases,
Snowflake.Parse("866460975388819486")
);
[Fact]
public async Task Reply_to_a_deleted_message_is_rendered_correctly()
{
// Act
var message = await ExportWrapper.GetMessageAsHtmlAsync(
ChannelIds.ReplyTestCases,
Snowflake.Parse("866460975388819486")
);
// Assert
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.");
}
// Assert
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()
{
// Act
var message = await ExportWrapper.GetMessageAsHtmlAsync(
ChannelIds.ReplyTestCases,
Snowflake.Parse("866462470335627294")
);
[Fact]
public async Task Reply_to_a_empty_message_with_attachment_is_rendered_correctly()
{
// Act
var message = await ExportWrapper.GetMessageAsHtmlAsync(
ChannelIds.ReplyTestCases,
Snowflake.Parse("866462470335627294")
);
// Assert
message.Text().Trim().Should().Be("reply to attachment");
message.QuerySelector(".chatlog__reference-link")?.Text().Trim().Should()
.Be("Click to see attachment 🖼️");
}
// Assert
message.Text().Trim().Should().Be("reply to attachment");
message.QuerySelector(".chatlog__reference-link")?.Text().Trim().Should()
.Be("Click to see attachment 🖼️");
}
}

View file

@ -6,96 +6,95 @@ using DiscordChatExporter.Core.Discord;
using FluentAssertions;
using Xunit;
namespace DiscordChatExporter.Cli.Tests.Specs.JsonWriting
namespace DiscordChatExporter.Cli.Tests.Specs.JsonWriting;
public record AttachmentSpecs(ExportWrapperFixture ExportWrapper) : IClassFixture<ExportWrapperFixture>
{
public record AttachmentSpecs(ExportWrapperFixture ExportWrapper) : IClassFixture<ExportWrapperFixture>
[Fact]
public async Task Message_with_a_generic_attachment_is_rendered_correctly()
{
[Fact]
public async Task Message_with_a_generic_attachment_is_rendered_correctly()
{
// Act
var message = await ExportWrapper.GetMessageAsJsonAsync(
ChannelIds.AttachmentTestCases,
Snowflake.Parse("885587844989612074")
);
// Act
var message = await ExportWrapper.GetMessageAsJsonAsync(
ChannelIds.AttachmentTestCases,
Snowflake.Parse("885587844989612074")
);
var attachments = message.GetProperty("attachments").EnumerateArray().ToArray();
var attachments = message.GetProperty("attachments").EnumerateArray().ToArray();
// Assert
message.GetProperty("content").GetString().Should().Be("Generic file attachment");
// Assert
message.GetProperty("content").GetString().Should().Be("Generic file attachment");
attachments.Should().HaveCount(1);
attachments.Single().GetProperty("url").GetString().Should().StartWithEquivalentOf(
"https://cdn.discordapp.com/attachments/885587741654536192/885587844964417596/Test.txt"
);
attachments.Single().GetProperty("fileName").GetString().Should().Be("Test.txt");
attachments.Single().GetProperty("fileSizeBytes").GetInt64().Should().Be(11);
}
attachments.Should().HaveCount(1);
attachments.Single().GetProperty("url").GetString().Should().StartWithEquivalentOf(
"https://cdn.discordapp.com/attachments/885587741654536192/885587844964417596/Test.txt"
);
attachments.Single().GetProperty("fileName").GetString().Should().Be("Test.txt");
attachments.Single().GetProperty("fileSizeBytes").GetInt64().Should().Be(11);
}
[Fact]
public async Task Message_with_an_image_attachment_is_rendered_correctly()
{
// Act
var message = await ExportWrapper.GetMessageAsJsonAsync(
ChannelIds.AttachmentTestCases,
Snowflake.Parse("885654862656843786")
);
[Fact]
public async Task Message_with_an_image_attachment_is_rendered_correctly()
{
// Act
var message = await ExportWrapper.GetMessageAsJsonAsync(
ChannelIds.AttachmentTestCases,
Snowflake.Parse("885654862656843786")
);
var attachments = message.GetProperty("attachments").EnumerateArray().ToArray();
var attachments = message.GetProperty("attachments").EnumerateArray().ToArray();
// Assert
message.GetProperty("content").GetString().Should().Be("Image attachment");
// Assert
message.GetProperty("content").GetString().Should().Be("Image attachment");
attachments.Should().HaveCount(1);
attachments.Single().GetProperty("url").GetString().Should().StartWithEquivalentOf(
"https://cdn.discordapp.com/attachments/885587741654536192/885654862430359613/bird-thumbnail.png"
);
attachments.Single().GetProperty("fileName").GetString().Should().Be("bird-thumbnail.png");
attachments.Single().GetProperty("fileSizeBytes").GetInt64().Should().Be(466335);
}
attachments.Should().HaveCount(1);
attachments.Single().GetProperty("url").GetString().Should().StartWithEquivalentOf(
"https://cdn.discordapp.com/attachments/885587741654536192/885654862430359613/bird-thumbnail.png"
);
attachments.Single().GetProperty("fileName").GetString().Should().Be("bird-thumbnail.png");
attachments.Single().GetProperty("fileSizeBytes").GetInt64().Should().Be(466335);
}
[Fact]
public async Task Message_with_a_video_attachment_is_rendered_correctly()
{
// Act
var message = await ExportWrapper.GetMessageAsJsonAsync(
ChannelIds.AttachmentTestCases,
Snowflake.Parse("885655761919836171")
);
[Fact]
public async Task Message_with_a_video_attachment_is_rendered_correctly()
{
// Act
var message = await ExportWrapper.GetMessageAsJsonAsync(
ChannelIds.AttachmentTestCases,
Snowflake.Parse("885655761919836171")
);
var attachments = message.GetProperty("attachments").EnumerateArray().ToArray();
var attachments = message.GetProperty("attachments").EnumerateArray().ToArray();
// Assert
message.GetProperty("content").GetString().Should().Be("Video attachment");
// Assert
message.GetProperty("content").GetString().Should().Be("Video attachment");
attachments.Should().HaveCount(1);
attachments.Single().GetProperty("url").GetString().Should().StartWithEquivalentOf(
"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");
attachments.Single().GetProperty("fileSizeBytes").GetInt64().Should().Be(3114374);
}
attachments.Should().HaveCount(1);
attachments.Single().GetProperty("url").GetString().Should().StartWithEquivalentOf(
"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");
attachments.Single().GetProperty("fileSizeBytes").GetInt64().Should().Be(3114374);
}
[Fact]
public async Task Message_with_an_audio_attachment_is_rendered_correctly()
{
// Act
var message = await ExportWrapper.GetMessageAsJsonAsync(
ChannelIds.AttachmentTestCases,
Snowflake.Parse("885656175620808734")
);
[Fact]
public async Task Message_with_an_audio_attachment_is_rendered_correctly()
{
// Act
var message = await ExportWrapper.GetMessageAsJsonAsync(
ChannelIds.AttachmentTestCases,
Snowflake.Parse("885656175620808734")
);
var attachments = message.GetProperty("attachments").EnumerateArray().ToArray();
var attachments = message.GetProperty("attachments").EnumerateArray().ToArray();
// Assert
message.GetProperty("content").GetString().Should().Be("Audio attachment");
// Assert
message.GetProperty("content").GetString().Should().Be("Audio attachment");
attachments.Should().HaveCount(1);
attachments.Single().GetProperty("url").GetString().Should().StartWithEquivalentOf(
"https://cdn.discordapp.com/attachments/885587741654536192/885656175348187146/file_example_MP3_1MG.mp3"
);
attachments.Single().GetProperty("fileName").GetString().Should().Be("file_example_MP3_1MG.mp3");
attachments.Single().GetProperty("fileSizeBytes").GetInt64().Should().Be(1087849);
}
attachments.Should().HaveCount(1);
attachments.Single().GetProperty("url").GetString().Should().StartWithEquivalentOf(
"https://cdn.discordapp.com/attachments/885587741654536192/885656175348187146/file_example_MP3_1MG.mp3"
);
attachments.Single().GetProperty("fileName").GetString().Should().Be("file_example_MP3_1MG.mp3");
attachments.Single().GetProperty("fileSizeBytes").GetInt64().Should().Be(1087849);
}
}

View file

@ -5,38 +5,37 @@ using DiscordChatExporter.Cli.Tests.TestData;
using FluentAssertions;
using Xunit;
namespace DiscordChatExporter.Cli.Tests.Specs.JsonWriting
namespace DiscordChatExporter.Cli.Tests.Specs.JsonWriting;
public record ContentSpecs(ExportWrapperFixture ExportWrapper) : IClassFixture<ExportWrapperFixture>
{
public record ContentSpecs(ExportWrapperFixture ExportWrapper) : IClassFixture<ExportWrapperFixture>
[Fact]
public async Task Messages_are_exported_correctly()
{
[Fact]
public async Task Messages_are_exported_correctly()
{
// Act
var messages = await ExportWrapper.GetMessagesAsJsonAsync(ChannelIds.DateRangeTestCases);
// Act
var messages = await ExportWrapper.GetMessagesAsJsonAsync(ChannelIds.DateRangeTestCases);
// Assert
messages.Select(j => j.GetProperty("id").GetString()).Should().Equal(
"866674314627121232",
"866710679758045195",
"866732113319428096",
"868490009366396958",
"868505966528835604",
"868505969821364245",
"868505973294268457",
"885169254029213696"
);
// Assert
messages.Select(j => j.GetProperty("id").GetString()).Should().Equal(
"866674314627121232",
"866710679758045195",
"866732113319428096",
"868490009366396958",
"868505966528835604",
"868505969821364245",
"868505973294268457",
"885169254029213696"
);
messages.Select(j => j.GetProperty("content").GetString()).Should().Equal(
"Hello world",
"Goodbye world",
"Foo bar",
"Hurdle Durdle",
"One",
"Two",
"Three",
"Yeet"
);
}
messages.Select(j => j.GetProperty("content").GetString()).Should().Equal(
"Hello world",
"Goodbye world",
"Foo bar",
"Hurdle Durdle",
"One",
"Two",
"Three",
"Yeet"
);
}
}

View file

@ -6,53 +6,52 @@ using DiscordChatExporter.Core.Discord;
using FluentAssertions;
using Xunit;
namespace DiscordChatExporter.Cli.Tests.Specs.JsonWriting
namespace DiscordChatExporter.Cli.Tests.Specs.JsonWriting;
public record EmbedSpecs(ExportWrapperFixture ExportWrapper) : IClassFixture<ExportWrapperFixture>
{
public record EmbedSpecs(ExportWrapperFixture ExportWrapper) : IClassFixture<ExportWrapperFixture>
[Fact]
public async Task Message_with_an_embed_is_rendered_correctly()
{
[Fact]
public async Task Message_with_an_embed_is_rendered_correctly()
{
// Act
var message = await ExportWrapper.GetMessageAsJsonAsync(
ChannelIds.EmbedTestCases,
Snowflake.Parse("866769910729146400")
);
// Act
var message = await ExportWrapper.GetMessageAsJsonAsync(
ChannelIds.EmbedTestCases,
Snowflake.Parse("866769910729146400")
);
var embed = message
.GetProperty("embeds")
.EnumerateArray()
.Single();
var embed = message
.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();
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();
}
// 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();
}
}

View file

@ -6,66 +6,65 @@ using DiscordChatExporter.Core.Discord;
using FluentAssertions;
using Xunit;
namespace DiscordChatExporter.Cli.Tests.Specs.JsonWriting
namespace DiscordChatExporter.Cli.Tests.Specs.JsonWriting;
public record MentionSpecs(ExportWrapperFixture ExportWrapper) : IClassFixture<ExportWrapperFixture>
{
public record MentionSpecs(ExportWrapperFixture ExportWrapper) : IClassFixture<ExportWrapperFixture>
[Fact]
public async Task User_mention_is_rendered_correctly()
{
[Fact]
public async Task User_mention_is_rendered_correctly()
{
// Act
var message = await ExportWrapper.GetMessageAsJsonAsync(
ChannelIds.MentionTestCases,
Snowflake.Parse("866458840245076028")
);
// Act
var message = await ExportWrapper.GetMessageAsJsonAsync(
ChannelIds.MentionTestCases,
Snowflake.Parse("866458840245076028")
);
// Assert
message.GetProperty("content").GetString().Should().Be("User mention: @Tyrrrz");
// Assert
message.GetProperty("content").GetString().Should().Be("User mention: @Tyrrrz");
message
.GetProperty("mentions")
.EnumerateArray()
.Select(j => j.GetProperty("id").GetString())
.Should().Contain("128178626683338752");
}
message
.GetProperty("mentions")
.EnumerateArray()
.Select(j => j.GetProperty("id").GetString())
.Should().Contain("128178626683338752");
}
[Fact]
public async Task Text_channel_mention_is_rendered_correctly()
{
// Act
var message = await ExportWrapper.GetMessageAsJsonAsync(
ChannelIds.MentionTestCases,
Snowflake.Parse("866459040480624680")
);
[Fact]
public async Task Text_channel_mention_is_rendered_correctly()
{
// Act
var message = await ExportWrapper.GetMessageAsJsonAsync(
ChannelIds.MentionTestCases,
Snowflake.Parse("866459040480624680")
);
// Assert
message.GetProperty("content").GetString().Should().Be("Text channel mention: #mention-tests");
}
// Assert
message.GetProperty("content").GetString().Should().Be("Text channel mention: #mention-tests");
}
[Fact]
public async Task Voice_channel_mention_is_rendered_correctly()
{
// Act
var message = await ExportWrapper.GetMessageAsJsonAsync(
ChannelIds.MentionTestCases,
Snowflake.Parse("866459175462633503")
);
[Fact]
public async Task Voice_channel_mention_is_rendered_correctly()
{
// Act
var message = await ExportWrapper.GetMessageAsJsonAsync(
ChannelIds.MentionTestCases,
Snowflake.Parse("866459175462633503")
);
// Assert
message.GetProperty("content").GetString().Should().Be("Voice channel mention: #chaos-vc [voice]");
}
// Assert
message.GetProperty("content").GetString().Should().Be("Voice channel mention: #chaos-vc [voice]");
}
[Fact]
public async Task Role_mention_is_rendered_correctly()
{
// Act
var message = await ExportWrapper.GetMessageAsJsonAsync(
ChannelIds.MentionTestCases,
Snowflake.Parse("866459254693429258")
);
[Fact]
public async Task Role_mention_is_rendered_correctly()
{
// Act
var message = await ExportWrapper.GetMessageAsJsonAsync(
ChannelIds.MentionTestCases,
Snowflake.Parse("866459254693429258")
);
// Assert
message.GetProperty("content").GetString().Should().Be("Role mention: @Role 1");
}
// Assert
message.GetProperty("content").GetString().Should().Be("Role mention: @Role 1");
}
}

View file

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

View file

@ -4,28 +4,27 @@ using DiscordChatExporter.Cli.Tests.TestData;
using FluentAssertions;
using Xunit;
namespace DiscordChatExporter.Cli.Tests.Specs.PlainTextWriting
{
public record ContentSpecs(ExportWrapperFixture ExportWrapper) : IClassFixture<ExportWrapperFixture>
{
[Fact]
public async Task Messages_are_exported_correctly()
{
// Act
var document = await ExportWrapper.ExportAsPlainTextAsync(ChannelIds.DateRangeTestCases);
namespace DiscordChatExporter.Cli.Tests.Specs.PlainTextWriting;
// Assert
document.Should().ContainAll(
"Tyrrrz#5447",
"Hello world",
"Goodbye world",
"Foo bar",
"Hurdle Durdle",
"One",
"Two",
"Three",
"Yeet"
);
}
public record ContentSpecs(ExportWrapperFixture ExportWrapper) : IClassFixture<ExportWrapperFixture>
{
[Fact]
public async Task Messages_are_exported_correctly()
{
// Act
var document = await ExportWrapper.ExportAsPlainTextAsync(ChannelIds.DateRangeTestCases);
// Assert
document.Should().ContainAll(
"Tyrrrz#5447",
"Hello world",
"Goodbye world",
"Foo bar",
"Hurdle Durdle",
"One",
"Two",
"Three",
"Yeet"
);
}
}

View file

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

View file

@ -1,21 +1,20 @@
using DiscordChatExporter.Core.Discord;
namespace DiscordChatExporter.Cli.Tests.TestData
namespace DiscordChatExporter.Cli.Tests.TestData;
public static class ChannelIds
{
public static class ChannelIds
{
public static Snowflake AttachmentTestCases { get; } = Snowflake.Parse("885587741654536192");
public static Snowflake AttachmentTestCases { get; } = Snowflake.Parse("885587741654536192");
public static Snowflake DateRangeTestCases { get; } = Snowflake.Parse("866674248747319326");
public static Snowflake DateRangeTestCases { get; } = Snowflake.Parse("866674248747319326");
public static Snowflake EmbedTestCases { get; } = Snowflake.Parse("866472452459462687");
public static Snowflake EmbedTestCases { get; } = Snowflake.Parse("866472452459462687");
public static Snowflake FilterTestCases { get; } = Snowflake.Parse("866744075033641020");
public static Snowflake FilterTestCases { get; } = Snowflake.Parse("866744075033641020");
public static Snowflake MentionTestCases { get; } = Snowflake.Parse("866458801389174794");
public static Snowflake MentionTestCases { get; } = Snowflake.Parse("866458801389174794");
public static Snowflake ReplyTestCases { get; } = Snowflake.Parse("866459871934677052");
public static Snowflake ReplyTestCases { get; } = Snowflake.Parse("866459871934677052");
public static Snowflake SelfContainedTestCases { get; } = Snowflake.Parse("887441432678379560");
}
public static Snowflake SelfContainedTestCases { get; } = Snowflake.Parse("887441432678379560");
}

View file

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

View file

@ -1,12 +1,11 @@
using AngleSharp.Html.Dom;
using AngleSharp.Html.Parser;
namespace DiscordChatExporter.Cli.Tests.Utils
{
internal static class Html
{
private static readonly IHtmlParser Parser = new HtmlParser();
namespace DiscordChatExporter.Cli.Tests.Utils;
public static IHtmlDocument Parse(string source) => Parser.ParseDocument(source);
}
internal static class Html
{
private static readonly IHtmlParser Parser = new HtmlParser();
public static IHtmlDocument Parse(string source) => Parser.ParseDocument(source);
}