From 7d1f4d1dff41c1a4015668395a4516264c42dba7 Mon Sep 17 00:00:00 2001 From: Quahu Date: Sat, 24 Mar 2018 01:22:25 +0100 Subject: [PATCH 01/16] Smh, Finitey --- src/Discord.Net.Commands/CommandParser.cs | 48 +++++++++++------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/src/Discord.Net.Commands/CommandParser.cs b/src/Discord.Net.Commands/CommandParser.cs index d65d99349..ffbf1ea93 100644 --- a/src/Discord.Net.Commands/CommandParser.cs +++ b/src/Discord.Net.Commands/CommandParser.cs @@ -33,30 +33,6 @@ namespace Discord.Commands else c = '\0'; - //If this character is escaped, skip it - if (isEscaping) - { - if (curPos != endPos) - { - argBuilder.Append(c); - isEscaping = false; - continue; - } - } - //Are we escaping the next character? - if (c == '\\' && (curParam == null || !curParam.IsRemainder)) - { - isEscaping = true; - continue; - } - - //If we're processing an remainder parameter, ignore all other logic - if (curParam != null && curParam.IsRemainder && curPos != endPos) - { - argBuilder.Append(c); - continue; - } - //If we're not currently processing one, are we starting the next argument yet? if (curPart == ParserPart.None) { @@ -83,6 +59,30 @@ namespace Discord.Commands } } + //If this character is escaped, skip it + if (isEscaping) + { + if (curPos != endPos) + { + argBuilder.Append(c); + isEscaping = false; + continue; + } + } + //Are we escaping the next character? + if (c == '\\' && (curParam == null || !curParam.IsRemainder)) + { + isEscaping = true; + continue; + } + + //If we're processing a remainder parameter, ignore all other logic + if (curParam != null && curParam.IsRemainder && curPos != endPos) + { + argBuilder.Append(c); + continue; + } + //Has this parameter ended yet? string argString = null; if (curPart == ParserPart.Parameter) From 7457847489cc6026d2304cc43554685f37ddd354 Mon Sep 17 00:00:00 2001 From: Quahu Date: Sun, 1 Apr 2018 00:28:11 +0200 Subject: [PATCH 02/16] I broke it even more with this PR, lol Remainder parameters weren't parsed properly. --- src/Discord.Net.Commands/CommandParser.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Discord.Net.Commands/CommandParser.cs b/src/Discord.Net.Commands/CommandParser.cs index ffbf1ea93..1d09a8b4b 100644 --- a/src/Discord.Net.Commands/CommandParser.cs +++ b/src/Discord.Net.Commands/CommandParser.cs @@ -33,6 +33,13 @@ namespace Discord.Commands else c = '\0'; + //If we're processing a remainder parameter, ignore all other logic + if (curParam != null && curParam.IsRemainder && curPos != endPos) + { + argBuilder.Append(c); + continue; + } + //If we're not currently processing one, are we starting the next argument yet? if (curPart == ParserPart.None) { @@ -76,13 +83,6 @@ namespace Discord.Commands continue; } - //If we're processing a remainder parameter, ignore all other logic - if (curParam != null && curParam.IsRemainder && curPos != endPos) - { - argBuilder.Append(c); - continue; - } - //Has this parameter ended yet? string argString = null; if (curPart == ParserPart.Parameter) From 1b54883896586968df25f0b5b99f932aded5044e Mon Sep 17 00:00:00 2001 From: Tiago Cabral Date: Tue, 4 Jun 2019 19:04:53 +0100 Subject: [PATCH 03/16] fix: Changed Emote GetHashCode to not include Name (#1317) Continuation of commit abf3e90 attempt to fix Emote comparisons, as Hash comparisons are done before Equals in Comparers --- src/Discord.Net.Core/Entities/Emotes/Emote.cs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/Discord.Net.Core/Entities/Emotes/Emote.cs b/src/Discord.Net.Core/Entities/Emotes/Emote.cs index 97fadbcc1..2eb47b080 100644 --- a/src/Discord.Net.Core/Entities/Emotes/Emote.cs +++ b/src/Discord.Net.Core/Entities/Emotes/Emote.cs @@ -54,13 +54,7 @@ namespace Discord } /// - public override int GetHashCode() - { - unchecked - { - return (Name.GetHashCode() * 397) ^ Id.GetHashCode(); - } - } + public override int GetHashCode() => Id.GetHashCode(); /// Parses an from its raw format. /// The raw encoding of an emote (e.g. <:dab:277855270321782784>). From 63ccd05faad63dce85e31d0d9c979cb6477ae92e Mon Sep 17 00:00:00 2001 From: Christopher Felegy Date: Tue, 4 Jun 2019 14:05:59 -0400 Subject: [PATCH 04/16] lint: newline on Emote#GetHashCode --- src/Discord.Net.Core/Entities/Emotes/Emote.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Discord.Net.Core/Entities/Emotes/Emote.cs b/src/Discord.Net.Core/Entities/Emotes/Emote.cs index 2eb47b080..6054b3f74 100644 --- a/src/Discord.Net.Core/Entities/Emotes/Emote.cs +++ b/src/Discord.Net.Core/Entities/Emotes/Emote.cs @@ -54,7 +54,8 @@ namespace Discord } /// - public override int GetHashCode() => Id.GetHashCode(); + public override int GetHashCode() + => Id.GetHashCode(); /// Parses an from its raw format. /// The raw encoding of an emote (e.g. <:dab:277855270321782784>). From 4433ca741b29fe37b4500cc46fac8bf61ae64bec Mon Sep 17 00:00:00 2001 From: Jyrka98 Date: Wed, 5 Jun 2019 18:55:50 +0300 Subject: [PATCH 05/16] fix: Update maximum value for SlowModeInterval (#1320) Discord allows the slow mode to be up to 6 hours. --- src/Discord.Net.Rest/DiscordRestApiClient.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Discord.Net.Rest/DiscordRestApiClient.cs b/src/Discord.Net.Rest/DiscordRestApiClient.cs index b1e04e9dc..777ed8e99 100644 --- a/src/Discord.Net.Rest/DiscordRestApiClient.cs +++ b/src/Discord.Net.Rest/DiscordRestApiClient.cs @@ -376,7 +376,7 @@ namespace Discord.API Preconditions.AtLeast(args.Position, 0, nameof(args.Position)); Preconditions.NotNullOrEmpty(args.Name, nameof(args.Name)); Preconditions.AtLeast(args.SlowModeInterval, 0, nameof(args.SlowModeInterval)); - Preconditions.AtMost(args.SlowModeInterval, 120, nameof(args.SlowModeInterval)); + Preconditions.AtMost(args.SlowModeInterval, 21600, nameof(args.SlowModeInterval)); options = RequestOptions.CreateOrClone(options); var ids = new BucketIds(channelId: channelId); From fc48c6606d293f1cd9d9a7df10f747e1e9fc93de Mon Sep 17 00:00:00 2001 From: Chris Johnston Date: Wed, 5 Jun 2019 10:41:18 -0700 Subject: [PATCH 06/16] feature: Disconnect guild members from voice channels (#1311) * Feature: Disconnect users from voice channels Updates GuildUserProperties to allow for setting either Channel or ChannelId to null, which will disconnect users from voice channels. The type of ChannelId has been updated from a ulong to ulong?, which matches the latest api documentation. * docs: update xmldoc wording * breaking workaround, revert ChannelId to ulong This is a workaround to prevent this PR from being a breaking change. Reverts the type of GuildUserProperties#ChannelId to a ulong from a ulong?. Guild Users may no longer be kicked by setting this property to null, but setting GuildUserProperties#Channel should still work. --- src/Discord.Net.Core/Entities/Users/GuildUserProperties.cs | 7 ++++--- src/Discord.Net.Rest/API/Rest/ModifyGuildMemberParams.cs | 4 ++-- src/Discord.Net.Rest/Entities/Users/UserHelper.cs | 4 ++-- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/Discord.Net.Core/Entities/Users/GuildUserProperties.cs b/src/Discord.Net.Core/Entities/Users/GuildUserProperties.cs index bea26e656..8f2d2111e 100644 --- a/src/Discord.Net.Core/Entities/Users/GuildUserProperties.cs +++ b/src/Discord.Net.Core/Entities/Users/GuildUserProperties.cs @@ -59,18 +59,19 @@ namespace Discord /// public Optional> RoleIds { get; set; } /// - /// Moves a user to a voice channel. + /// Moves a user to a voice channel. If null, this user will be disconnected from their current voice channel. /// /// /// This user MUST already be in a for this to work. + /// When set, this property takes precedence over . /// public Optional Channel { get; set; } /// - /// Moves a user to a voice channel. + /// Moves a user to a voice channel. Set to null to disconnect this user from their current voice channel. /// /// /// This user MUST already be in a for this to work. /// - public Optional ChannelId { get; set; } + public Optional ChannelId { get; set; } // TODO: v3 breaking change, change ChannelId to ulong? to allow for kicking users from voice } } diff --git a/src/Discord.Net.Rest/API/Rest/ModifyGuildMemberParams.cs b/src/Discord.Net.Rest/API/Rest/ModifyGuildMemberParams.cs index 159670afb..a381d6f8f 100644 --- a/src/Discord.Net.Rest/API/Rest/ModifyGuildMemberParams.cs +++ b/src/Discord.Net.Rest/API/Rest/ModifyGuildMemberParams.cs @@ -1,4 +1,4 @@ -#pragma warning disable CS1591 +#pragma warning disable CS1591 using Newtonsoft.Json; namespace Discord.API.Rest @@ -15,6 +15,6 @@ namespace Discord.API.Rest [JsonProperty("roles")] public Optional RoleIds { get; set; } [JsonProperty("channel_id")] - public Optional ChannelId { get; set; } + public Optional ChannelId { get; set; } } } diff --git a/src/Discord.Net.Rest/Entities/Users/UserHelper.cs b/src/Discord.Net.Rest/Entities/Users/UserHelper.cs index 3e7493ab5..58e8cd417 100644 --- a/src/Discord.Net.Rest/Entities/Users/UserHelper.cs +++ b/src/Discord.Net.Rest/Entities/Users/UserHelper.cs @@ -1,4 +1,4 @@ -using Discord.API.Rest; +using Discord.API.Rest; using System; using System.Collections.Generic; using System.Threading.Tasks; @@ -39,7 +39,7 @@ namespace Discord.Rest }; if (args.Channel.IsSpecified) - apiArgs.ChannelId = args.Channel.Value.Id; + apiArgs.ChannelId = args.Channel.Value?.Id; else if (args.ChannelId.IsSpecified) apiArgs.ChannelId = args.ChannelId.Value; From 46da3523d090ed3f99c44e9c755ac5e1cbb5c94b Mon Sep 17 00:00:00 2001 From: Christopher Felegy Date: Wed, 5 Jun 2019 16:37:55 -0400 Subject: [PATCH 07/16] docs: update TextChannelProperties to 6-hour slow mode --- src/Discord.Net.Core/Entities/Channels/TextChannelProperties.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Discord.Net.Core/Entities/Channels/TextChannelProperties.cs b/src/Discord.Net.Core/Entities/Channels/TextChannelProperties.cs index 6dcbf860a..821f358f5 100644 --- a/src/Discord.Net.Core/Entities/Channels/TextChannelProperties.cs +++ b/src/Discord.Net.Core/Entities/Channels/TextChannelProperties.cs @@ -36,7 +36,7 @@ namespace Discord /// will be exempt from slow-mode. /// /// - /// Thrown if the value does not fall within [0, 120]. + /// Thrown if the value does not fall within [0, 21600]. public Optional SlowModeInterval { get; set; } } } From 3e65e03b8583937057091d2ecb22c07162c2e4ca Mon Sep 17 00:00:00 2001 From: Christopher Felegy Date: Wed, 5 Jun 2019 16:47:57 -0400 Subject: [PATCH 08/16] meta: bump Ix.Net to 3.2.0 --- src/Discord.Net.Core/Discord.Net.Core.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Discord.Net.Core/Discord.Net.Core.csproj b/src/Discord.Net.Core/Discord.Net.Core.csproj index 72a958b4f..20e57d346 100644 --- a/src/Discord.Net.Core/Discord.Net.Core.csproj +++ b/src/Discord.Net.Core/Discord.Net.Core.csproj @@ -10,7 +10,7 @@ - + all From a8c853f1ec4deaa4116c25171fe4205936773d36 Mon Sep 17 00:00:00 2001 From: Christopher Felegy Date: Wed, 5 Jun 2019 17:11:06 -0400 Subject: [PATCH 09/16] Revert "Merge remote-tracking branch 'quahu/dev' into dev" This reverts commit 8fb0d5dc13613e1539aff09899b465e21308d64c, reversing changes made to 3e65e03b8583937057091d2ecb22c07162c2e4ca. --- src/Discord.Net.Commands/CommandParser.cs | 31 +++++------------------ 1 file changed, 7 insertions(+), 24 deletions(-) diff --git a/src/Discord.Net.Commands/CommandParser.cs b/src/Discord.Net.Commands/CommandParser.cs index fc44c0a42..96747ae96 100644 --- a/src/Discord.Net.Commands/CommandParser.cs +++ b/src/Discord.Net.Commands/CommandParser.cs @@ -53,13 +53,6 @@ namespace Discord.Commands else c = '\0'; - //If we're processing a remainder parameter, ignore all other logic - if (curParam != null && curParam.IsRemainder && curPos != endPos) - { - argBuilder.Append(c); - continue; - } - //If this character is escaped, skip it if (isEscaping) { @@ -86,6 +79,13 @@ namespace Discord.Commands continue; } + //If we're processing an remainder parameter, ignore all other logic + if (curParam != null && curParam.IsRemainder && curPos != endPos) + { + argBuilder.Append(c); + continue; + } + //If we're not currently processing one, are we starting the next argument yet? if (curPart == ParserPart.None) { @@ -114,23 +114,6 @@ namespace Discord.Commands } } - //If this character is escaped, skip it - if (isEscaping) - { - if (curPos != endPos) - { - argBuilder.Append(c); - isEscaping = false; - continue; - } - } - //Are we escaping the next character? - if (c == '\\' && (curParam == null || !curParam.IsRemainder)) - { - isEscaping = true; - continue; - } - //Has this parameter ended yet? string argString = null; if (curPart == ParserPart.Parameter) From 2e95c4913b2f60100f8867ecebbbcbfc2091480f Mon Sep 17 00:00:00 2001 From: Christopher Felegy Date: Wed, 5 Jun 2019 17:13:29 -0400 Subject: [PATCH 10/16] fix: ignore escape behavior on remainder parameters (#994) Co-authored-by: Quahu --- src/Discord.Net.Commands/CommandParser.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Discord.Net.Commands/CommandParser.cs b/src/Discord.Net.Commands/CommandParser.cs index 96747ae96..c77b56042 100644 --- a/src/Discord.Net.Commands/CommandParser.cs +++ b/src/Discord.Net.Commands/CommandParser.cs @@ -53,6 +53,13 @@ namespace Discord.Commands else c = '\0'; + //If we're processing an remainder parameter, ignore all other logic + if (curParam != null && curParam.IsRemainder && curPos != endPos) + { + argBuilder.Append(c); + continue; + } + //If this character is escaped, skip it if (isEscaping) { @@ -79,13 +86,6 @@ namespace Discord.Commands continue; } - //If we're processing an remainder parameter, ignore all other logic - if (curParam != null && curParam.IsRemainder && curPos != endPos) - { - argBuilder.Append(c); - continue; - } - //If we're not currently processing one, are we starting the next argument yet? if (curPart == ParserPart.None) { From 1cc5d7321b2d3912df8b18b74ee2cb76ac329ba3 Mon Sep 17 00:00:00 2001 From: Casino Boyale Date: Thu, 6 Jun 2019 21:22:34 +0100 Subject: [PATCH 11/16] fix: fixed optionals having IsSpecified true when objects weren't in cache (#1323) * Fixed optionals having IsSpecified true when objects weren't in cache * Removed double null check --- .../DiscordSocketClient.cs | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/Discord.Net.WebSocket/DiscordSocketClient.cs b/src/Discord.Net.WebSocket/DiscordSocketClient.cs index 60d5c73c9..41a0c5167 100644 --- a/src/Discord.Net.WebSocket/DiscordSocketClient.cs +++ b/src/Discord.Net.WebSocket/DiscordSocketClient.cs @@ -1295,7 +1295,16 @@ namespace Discord.WebSocket var cachedMsg = channel.GetCachedMessage(data.MessageId) as SocketUserMessage; bool isCached = cachedMsg != null; var user = await channel.GetUserAsync(data.UserId, CacheMode.CacheOnly).ConfigureAwait(false); - var reaction = SocketReaction.Create(data, channel, cachedMsg, Optional.Create(user)); + + var optionalMsg = !isCached + ? Optional.Create() + : Optional.Create(cachedMsg); + + var optionalUser = user is null + ? Optional.Create() + : Optional.Create(user); + + var reaction = SocketReaction.Create(data, channel, optionalMsg, optionalUser); var cacheable = new Cacheable(cachedMsg, data.MessageId, isCached, async () => await channel.GetMessageAsync(data.MessageId).ConfigureAwait(false) as IUserMessage); cachedMsg?.AddReaction(reaction); @@ -1319,7 +1328,16 @@ namespace Discord.WebSocket var cachedMsg = channel.GetCachedMessage(data.MessageId) as SocketUserMessage; bool isCached = cachedMsg != null; var user = await channel.GetUserAsync(data.UserId, CacheMode.CacheOnly).ConfigureAwait(false); - var reaction = SocketReaction.Create(data, channel, cachedMsg, Optional.Create(user)); + + var optionalMsg = !isCached + ? Optional.Create() + : Optional.Create(cachedMsg); + + var optionalUser = user is null + ? Optional.Create() + : Optional.Create(user); + + var reaction = SocketReaction.Create(data, channel, optionalMsg, optionalUser); var cacheable = new Cacheable(cachedMsg, data.MessageId, isCached, async () => await channel.GetMessageAsync(data.MessageId).ConfigureAwait(false) as IUserMessage); cachedMsg?.RemoveReaction(reaction); From d287ed1d4c2d2f0b96be1969a7b056da95cc2fc2 Mon Sep 17 00:00:00 2001 From: Christopher Felegy Date: Sat, 8 Jun 2019 19:38:31 -0400 Subject: [PATCH 12/16] fix: add EmbedTypeConverter with unknown handling Prevents messages with an unknown EmbedType from failing to unmarshal --- src/Discord.Net.Rest/API/Common/Embed.cs | 6 +- .../Net/Converters/DiscordContractResolver.cs | 2 + .../Net/Converters/EmbedTypeConverter.cs | 73 +++++++++++++++++++ 3 files changed, 78 insertions(+), 3 deletions(-) create mode 100644 src/Discord.Net.Rest/Net/Converters/EmbedTypeConverter.cs diff --git a/src/Discord.Net.Rest/API/Common/Embed.cs b/src/Discord.Net.Rest/API/Common/Embed.cs index 1c9fa34e2..fbf20d987 100644 --- a/src/Discord.Net.Rest/API/Common/Embed.cs +++ b/src/Discord.Net.Rest/API/Common/Embed.cs @@ -1,7 +1,7 @@ -#pragma warning disable CS1591 +#pragma warning disable CS1591 using System; using Newtonsoft.Json; -using Newtonsoft.Json.Converters; +using Discord.Net.Converters; namespace Discord.API { @@ -15,7 +15,7 @@ namespace Discord.API public string Url { get; set; } [JsonProperty("color")] public uint? Color { get; set; } - [JsonProperty("type"), JsonConverter(typeof(StringEnumConverter))] + [JsonProperty("type"), JsonConverter(typeof(EmbedTypeConverter))] public EmbedType Type { get; set; } [JsonProperty("timestamp")] public DateTimeOffset? Timestamp { get; set; } diff --git a/src/Discord.Net.Rest/Net/Converters/DiscordContractResolver.cs b/src/Discord.Net.Rest/Net/Converters/DiscordContractResolver.cs index 8a3c1037b..a1ed20c6f 100644 --- a/src/Discord.Net.Rest/Net/Converters/DiscordContractResolver.cs +++ b/src/Discord.Net.Rest/Net/Converters/DiscordContractResolver.cs @@ -77,6 +77,8 @@ namespace Discord.Net.Converters return PermissionTargetConverter.Instance; if (type == typeof(UserStatus)) return UserStatusConverter.Instance; + if (type == typeof(EmbedType)) + return EmbedTypeConverter.Instance; //Special if (type == typeof(API.Image)) diff --git a/src/Discord.Net.Rest/Net/Converters/EmbedTypeConverter.cs b/src/Discord.Net.Rest/Net/Converters/EmbedTypeConverter.cs new file mode 100644 index 000000000..1e03fb698 --- /dev/null +++ b/src/Discord.Net.Rest/Net/Converters/EmbedTypeConverter.cs @@ -0,0 +1,73 @@ +using System; +using Newtonsoft.Json; + +namespace Discord.Net.Converters +{ + internal class EmbedTypeConverter : JsonConverter + { + public static readonly EmbedTypeConverter Instance = new EmbedTypeConverter(); + + public override bool CanConvert(Type objectType) => true; + public override bool CanRead => true; + public override bool CanWrite => true; + + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + switch ((string)reader.Value) + { + case "rich": + return EmbedType.Rich; + case "link": + return EmbedType.Link; + case "video": + return EmbedType.Video; + case "image": + return EmbedType.Image; + case "gifv": + return EmbedType.Gifv; + case "article": + return EmbedType.Article; + case "tweet": + return EmbedType.Tweet; + case "html": + return EmbedType.Html; + case "application_news": // TODO 2.2 EmbedType.News + default: + return EmbedType.Unknown; + } + } + + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + switch ((EmbedType)value) + { + case EmbedType.Rich: + writer.WriteValue("rich"); + break; + case EmbedType.Link: + writer.WriteValue("link"); + break; + case EmbedType.Video: + writer.WriteValue("video"); + break; + case EmbedType.Image: + writer.WriteValue("image"); + break; + case EmbedType.Gifv: + writer.WriteValue("gifv"); + break; + case EmbedType.Article: + writer.WriteValue("article"); + break; + case EmbedType.Tweet: + writer.WriteValue("tweet"); + break; + case EmbedType.Html: + writer.WriteValue("html"); + break; + default: + throw new JsonSerializationException("Invalid embed type"); + } + } + } +} From dfd82a5ab7d06f77a2ad27321c7931891ca04e0d Mon Sep 17 00:00:00 2001 From: Christopher Felegy Date: Sat, 8 Jun 2019 20:14:45 -0400 Subject: [PATCH 13/16] meta: v2.1.1 --- Discord.Net.targets | 2 +- src/Discord.Net/Discord.Net.nuspec | 32 +++++++++++++++--------------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/Discord.Net.targets b/Discord.Net.targets index e785094cb..973691e0f 100644 --- a/Discord.Net.targets +++ b/Discord.Net.targets @@ -1,7 +1,7 @@ 2.1.1 - dev + RogueException discord;discordapp https://github.com/RogueException/Discord.Net diff --git a/src/Discord.Net/Discord.Net.nuspec b/src/Discord.Net/Discord.Net.nuspec index 2c440d2f4..20258160b 100644 --- a/src/Discord.Net/Discord.Net.nuspec +++ b/src/Discord.Net/Discord.Net.nuspec @@ -2,7 +2,7 @@ Discord.Net - 2.1.1-dev$suffix$ + 2.1.1$suffix$ Discord.Net Discord.Net Contributors RogueException @@ -14,25 +14,25 @@ https://github.com/RogueException/Discord.Net/raw/dev/docs/marketing/logo/PackageLogo.png - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + From 10463cfdd2a439aa96bde85ca83d01d3862cf612 Mon Sep 17 00:00:00 2001 From: Christopher Felegy Date: Sat, 8 Jun 2019 23:13:11 -0400 Subject: [PATCH 14/16] meta: bump version to v2.2.0-dev, update CHANGELOG --- CHANGELOG.md | 18 +++++++++++++++++ Discord.Net.targets | 4 ++-- src/Discord.Net/Discord.Net.nuspec | 32 +++++++++++++++--------------- 3 files changed, 36 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8336e2f4e..ac159d86f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,23 @@ # Changelog +## [2.1.1] - 2019-06-08 +### Fixed +- #994: Remainder parameters now ignore character escaping, as there is no reason to escape characters here (2e95c49) +- #1316: `Emote.Equals` now pays no respect to the Name property, since Discord's API does not care about an emote's name (abf3e90) +- #1317: `Emote.GetHashCode` now pays no respect to the Name property, see above (1b54883) +- #1323: Optionals will no longer claim to be specified when a reaction message was not cached (1cc5d73) +- Log messages sourcing from REST events will no longer be raised twice (c78a679) +- News embeds will be processed as `EmbedType.Unknown`, rather than throwing an error and dropping the message (d287ed1) + +### Changed +- #1311: Members may now be disconnected from voice channels by passing `null` as `GuildUserProperties.Channel` (fc48c66) +- #1313: `IMessage.Tags` now includes the EveryoneRole on @everyone and @here mentions (1f55f01) +- #1320: The maximum value for setting slow-mode has been updated to 6 hours, per the new API limit (4433ca7) + +### Misc +- This library's compatibility with Semantic Versioning has been clarified. Please see the README (4d7de17) +- The depency on System.Interactive.Async has been bumped to `3.2.0` (3e65e03) + ## [2.1.0] - 2019-05-18 ### Added - #1236: Bulk deletes (for messages) may now be accessed via the `MessagesBulkDeleted` event (dec353e) diff --git a/Discord.Net.targets b/Discord.Net.targets index 973691e0f..e7b45e52f 100644 --- a/Discord.Net.targets +++ b/Discord.Net.targets @@ -1,7 +1,7 @@ - 2.1.1 - + 2.2.0 + dev RogueException discord;discordapp https://github.com/RogueException/Discord.Net diff --git a/src/Discord.Net/Discord.Net.nuspec b/src/Discord.Net/Discord.Net.nuspec index 20258160b..3aa0d6add 100644 --- a/src/Discord.Net/Discord.Net.nuspec +++ b/src/Discord.Net/Discord.Net.nuspec @@ -2,7 +2,7 @@ Discord.Net - 2.1.1$suffix$ + 2.2.0-dev$suffix$ Discord.Net Discord.Net Contributors RogueException @@ -14,25 +14,25 @@ https://github.com/RogueException/Discord.Net/raw/dev/docs/marketing/logo/PackageLogo.png - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + From 40844b9e135adda3382cd250363442e318e52425 Mon Sep 17 00:00:00 2001 From: Chris Johnston Date: Wed, 12 Jun 2019 13:00:30 -0700 Subject: [PATCH 15/16] feature(binbrk): Add properties missing from User and Activity models (#1237) * WIP commit, update IActivity and IUser with missing types * incomplete implementation of interfaces * Add implementation of activity flags, and extension method to check flag * remove usings that were not required * clean up files and add documentation where missing * remove unused usings * Add remark saying that premium_type info may be inaccessible to bots it seems that this information can not be accessed by any user, and may require the identity oauth scope * Add locale property to the user model adds the locale property to the user model, which appears not to be specified for bots * rename ActivityFlags * Add incomplete xmldoc to ActivityFlag Added xmldoc to the ActivityFlag type, excluded flags that i was unsure about * rename the UserFlags file * Add incomplete xmldoc to UserFlag enum * Remove unnecessary extension methods and use built-in functionality * use tag for xmldoc 'null's * Add xmldoc for JoinRequest ActivityFlag * improve the PremiumType xmldoc * Add zero activityflag * Add summary tag verbs, example of IUser locale * Rename Flag enum types to use Properties suffix * Expose the details field in the Game model * update Activity extension methods to support Details field * Use inherited Details implementation in RichGame * lint: remove commented out code from debugging * Fix issue in previous commit * Move oauth-only user fields to SelfUser classes Moves the implementation of the Flags, PremiumType, and Locale user fields to ISelfUser classes. In testing, it seemed that normal bot accounts did not have this information supplied to them. When tested with a Bearer token in the Rest client, these fields are set. * remove old HypeSquadEvents flag that appears to have been replaced with the new HypeSquad flags --- .../Entities/Activities/ActivityProperties.cs | 38 +++++++++++++++++ .../Entities/Activities/Game.cs | 8 +++- .../Entities/Activities/IActivity.cs | 17 ++++++++ .../Entities/Activities/RichGame.cs | 4 -- .../Entities/Users/ISelfUser.cs | 28 +++++++++++++ .../Entities/Users/PremiumType.cs | 21 ++++++++++ .../Entities/Users/UserProperties.cs | 41 +++++++++++++++++++ src/Discord.Net.Rest/API/Common/Game.cs | 2 + src/Discord.Net.Rest/API/Common/User.cs | 8 +++- .../Entities/Users/RestSelfUser.cs | 12 ++++++ .../Entities/Users/SocketSelfUser.cs | 21 ++++++++++ .../Extensions/EntityExtensions.cs | 18 +++++--- 12 files changed, 207 insertions(+), 11 deletions(-) create mode 100644 src/Discord.Net.Core/Entities/Activities/ActivityProperties.cs create mode 100644 src/Discord.Net.Core/Entities/Users/PremiumType.cs create mode 100644 src/Discord.Net.Core/Entities/Users/UserProperties.cs diff --git a/src/Discord.Net.Core/Entities/Activities/ActivityProperties.cs b/src/Discord.Net.Core/Entities/Activities/ActivityProperties.cs new file mode 100644 index 000000000..a7d13235f --- /dev/null +++ b/src/Discord.Net.Core/Entities/Activities/ActivityProperties.cs @@ -0,0 +1,38 @@ +using System; + +namespace Discord +{ + /// + /// Flags for the property, that are ORd together. + /// These describe what the activity payload includes. + /// + [Flags] + public enum ActivityProperties + { + /// + /// Indicates that no actions on this activity can be taken. + /// + None = 0, + Instance = 1, + /// + /// Indicates that this activity can be joined. + /// + Join = 0b10, + /// + /// Indicates that this activity can be spectated. + /// + Spectate = 0b100, + /// + /// Indicates that a user may request to join an activity. + /// + JoinRequest = 0b1000, + /// + /// Indicates that a user can listen along in Spotify. + /// + Sync = 0b10000, + /// + /// Indicates that a user can play this song. + /// + Play = 0b100000 + } +} diff --git a/src/Discord.Net.Core/Entities/Activities/Game.cs b/src/Discord.Net.Core/Entities/Activities/Game.cs index f232cc5bf..8891e142c 100644 --- a/src/Discord.Net.Core/Entities/Activities/Game.cs +++ b/src/Discord.Net.Core/Entities/Activities/Game.cs @@ -12,6 +12,10 @@ namespace Discord public string Name { get; internal set; } /// public ActivityType Type { get; internal set; } + /// + public ActivityProperties Flags { get; internal set; } + /// + public string Details { get; internal set; } internal Game() { } /// @@ -19,10 +23,12 @@ namespace Discord /// /// The name of the game. /// The type of activity. - public Game(string name, ActivityType type = ActivityType.Playing) + public Game(string name, ActivityType type = ActivityType.Playing, ActivityProperties flags = ActivityProperties.None, string details = null) { Name = name; Type = type; + Flags = flags; + Details = details; } /// Returns the name of the . diff --git a/src/Discord.Net.Core/Entities/Activities/IActivity.cs b/src/Discord.Net.Core/Entities/Activities/IActivity.cs index ac0c1b5d7..96704b826 100644 --- a/src/Discord.Net.Core/Entities/Activities/IActivity.cs +++ b/src/Discord.Net.Core/Entities/Activities/IActivity.cs @@ -19,5 +19,22 @@ namespace Discord /// The type of activity. /// ActivityType Type { get; } + /// + /// Gets the flags that are relevant to this activity. + /// + /// + /// This value is determined by bitwise OR-ing values together. + /// + /// + /// The value of flags for this activity. + /// + ActivityProperties Flags { get; } + /// + /// Gets the details on what the player is currently doing. + /// + /// + /// A string describing what the player is doing. + /// + string Details { get; } } } diff --git a/src/Discord.Net.Core/Entities/Activities/RichGame.cs b/src/Discord.Net.Core/Entities/Activities/RichGame.cs index 2455fd557..2da8d741c 100644 --- a/src/Discord.Net.Core/Entities/Activities/RichGame.cs +++ b/src/Discord.Net.Core/Entities/Activities/RichGame.cs @@ -10,10 +10,6 @@ namespace Discord { internal RichGame() { } - /// - /// Gets what the player is currently doing. - /// - public string Details { get; internal set; } /// /// Gets the user's current party status. /// diff --git a/src/Discord.Net.Core/Entities/Users/ISelfUser.cs b/src/Discord.Net.Core/Entities/Users/ISelfUser.cs index c1d7874eb..04c655212 100644 --- a/src/Discord.Net.Core/Entities/Users/ISelfUser.cs +++ b/src/Discord.Net.Core/Entities/Users/ISelfUser.cs @@ -26,6 +26,34 @@ namespace Discord /// true if this user has enabled multi-factor authentication on their account; false if not. /// bool IsMfaEnabled { get; } + /// + /// Gets the flags that are applied to a user's account. + /// + /// + /// This value is determined by bitwise OR-ing values together. + /// + /// + /// The value of flags for this user. + /// + UserProperties Flags { get; } + /// + /// Gets the type of Nitro subscription that is active on this user's account. + /// + /// + /// This information may only be available with the identify OAuth scope. + /// + /// + /// The type of Nitro subscription the user subscribes to, if any. + /// + PremiumType PremiumType { get; } + /// + /// Gets the user's chosen language option. + /// + /// + /// The IETF language tag of the user's chosen region, if provided. + /// For example, a locale of "English, US" is "en-US", "Chinese (Taiwan)" is "zh-TW", etc. + /// + string Locale { get; } /// /// Modifies the user's properties. diff --git a/src/Discord.Net.Core/Entities/Users/PremiumType.cs b/src/Discord.Net.Core/Entities/Users/PremiumType.cs new file mode 100644 index 000000000..2b41e0b6a --- /dev/null +++ b/src/Discord.Net.Core/Entities/Users/PremiumType.cs @@ -0,0 +1,21 @@ +namespace Discord +{ + /// + /// Specifies the type of subscription a user is subscribed to. + /// + public enum PremiumType + { + /// + /// No subscription. + /// + None = 0, + /// + /// Nitro Classic subscription. Includes app perks like animated emojis and avatars, but not games. + /// + NitroClassic = 1, + /// + /// Nitro subscription. Includes app perks as well as the games subscription service. + /// + Nitro = 2 + } +} diff --git a/src/Discord.Net.Core/Entities/Users/UserProperties.cs b/src/Discord.Net.Core/Entities/Users/UserProperties.cs new file mode 100644 index 000000000..4f7272daa --- /dev/null +++ b/src/Discord.Net.Core/Entities/Users/UserProperties.cs @@ -0,0 +1,41 @@ +using System; + +namespace Discord +{ + [Flags] + public enum UserProperties + { + /// + /// Default value for flags, when none are given to an account. + /// + None = 0, + /// + /// Flag given to Discord staff. + /// + Staff = 0b1, + /// + /// Flag given to Discord partners. + /// + Partner = 0b10, + /// + /// Flag given to users who have participated in the bug report program. + /// + BugHunter = 0b1000, + /// + /// Flag given to users who are in the HypeSquad House of Bravery. + /// + HypeSquadBravery = 0b100_0000, + /// + /// Flag given to users who are in the HypeSquad House of Brilliance. + /// + HypeSquadBrilliance = 0b1000_0000, + /// + /// Flag given to users who are in the HypeSquad House of Balance. + /// + HypeSquadBalance = 0b1_0000_0000, + /// + /// Flag given to users who subscribed to Nitro before games were added. + /// + EarlySupporter = 0b10_0000_0000, + } +} diff --git a/src/Discord.Net.Rest/API/Common/Game.cs b/src/Discord.Net.Rest/API/Common/Game.cs index 4cde8444a..2ec1e3846 100644 --- a/src/Discord.Net.Rest/API/Common/Game.cs +++ b/src/Discord.Net.Rest/API/Common/Game.cs @@ -33,6 +33,8 @@ namespace Discord.API public Optional SyncId { get; set; } [JsonProperty("session_id")] public Optional SessionId { get; set; } + [JsonProperty("Flags")] + public Optional Flags { get; set; } [OnError] internal void OnError(StreamingContext context, ErrorContext errorContext) diff --git a/src/Discord.Net.Rest/API/Common/User.cs b/src/Discord.Net.Rest/API/Common/User.cs index d49d24623..2eff3753d 100644 --- a/src/Discord.Net.Rest/API/Common/User.cs +++ b/src/Discord.Net.Rest/API/Common/User.cs @@ -1,4 +1,4 @@ -#pragma warning disable CS1591 +#pragma warning disable CS1591 using Newtonsoft.Json; namespace Discord.API @@ -23,5 +23,11 @@ namespace Discord.API public Optional Email { get; set; } [JsonProperty("mfa_enabled")] public Optional MfaEnabled { get; set; } + [JsonProperty("flags")] + public Optional Flags { get; set; } + [JsonProperty("premium_type")] + public Optional PremiumType { get; set; } + [JsonProperty("locale")] + public Optional Locale { get; set; } } } diff --git a/src/Discord.Net.Rest/Entities/Users/RestSelfUser.cs b/src/Discord.Net.Rest/Entities/Users/RestSelfUser.cs index 7f3a3faa8..b5ef01c53 100644 --- a/src/Discord.Net.Rest/Entities/Users/RestSelfUser.cs +++ b/src/Discord.Net.Rest/Entities/Users/RestSelfUser.cs @@ -17,6 +17,12 @@ namespace Discord.Rest public bool IsVerified { get; private set; } /// public bool IsMfaEnabled { get; private set; } + /// + public UserProperties Flags { get; private set; } + /// + public PremiumType PremiumType { get; private set; } + /// + public string Locale { get; private set; } internal RestSelfUser(BaseDiscordClient discord, ulong id) : base(discord, id) @@ -39,6 +45,12 @@ namespace Discord.Rest IsVerified = model.Verified.Value; if (model.MfaEnabled.IsSpecified) IsMfaEnabled = model.MfaEnabled.Value; + if (model.Flags.IsSpecified) + Flags = (UserProperties)model.Flags.Value; + if (model.PremiumType.IsSpecified) + PremiumType = model.PremiumType.Value; + if (model.Locale.IsSpecified) + Locale = model.Locale.Value; } /// diff --git a/src/Discord.Net.WebSocket/Entities/Users/SocketSelfUser.cs b/src/Discord.Net.WebSocket/Entities/Users/SocketSelfUser.cs index ae705109c..7b11257a3 100644 --- a/src/Discord.Net.WebSocket/Entities/Users/SocketSelfUser.cs +++ b/src/Discord.Net.WebSocket/Entities/Users/SocketSelfUser.cs @@ -30,6 +30,12 @@ namespace Discord.WebSocket public override string AvatarId { get { return GlobalUser.AvatarId; } internal set { GlobalUser.AvatarId = value; } } /// internal override SocketPresence Presence { get { return GlobalUser.Presence; } set { GlobalUser.Presence = value; } } + /// + public UserProperties Flags { get; internal set; } + /// + public PremiumType PremiumType { get; internal set; } + /// + public string Locale { get; internal set; } /// public override bool IsWebhook => false; @@ -63,6 +69,21 @@ namespace Discord.WebSocket IsMfaEnabled = model.MfaEnabled.Value; hasGlobalChanges = true; } + if (model.Flags.IsSpecified && model.Flags.Value != Flags) + { + Flags = (UserProperties)model.Flags.Value; + hasGlobalChanges = true; + } + if (model.PremiumType.IsSpecified && model.PremiumType.Value != PremiumType) + { + PremiumType = model.PremiumType.Value; + hasGlobalChanges = true; + } + if (model.Locale.IsSpecified && model.Locale.Value != Locale) + { + Locale = model.Locale.Value; + hasGlobalChanges = true; + } return hasGlobalChanges; } diff --git a/src/Discord.Net.WebSocket/Extensions/EntityExtensions.cs b/src/Discord.Net.WebSocket/Extensions/EntityExtensions.cs index e8dc4b5f0..fd91ba987 100644 --- a/src/Discord.Net.WebSocket/Extensions/EntityExtensions.cs +++ b/src/Discord.Net.WebSocket/Extensions/EntityExtensions.cs @@ -25,7 +25,8 @@ namespace Discord.WebSocket Artists = model.State.GetValueOrDefault()?.Split(';').Select(x=>x?.Trim()).ToImmutableArray(), Duration = timestamps?.End - timestamps?.Start, AlbumArtUrl = albumArtId != null ? CDN.GetSpotifyAlbumArtUrl(albumArtId) : null, - Type = ActivityType.Listening + Type = ActivityType.Listening, + Flags = model.Flags.GetValueOrDefault(), }; } @@ -44,18 +45,25 @@ namespace Discord.WebSocket LargeAsset = assets?[1], Party = model.Party.IsSpecified ? model.Party.Value.ToEntity() : null, Secrets = model.Secrets.IsSpecified ? model.Secrets.Value.ToEntity() : null, - Timestamps = model.Timestamps.IsSpecified ? model.Timestamps.Value.ToEntity() : null + Timestamps = model.Timestamps.IsSpecified ? model.Timestamps.Value.ToEntity() : null, + Flags = model.Flags.GetValueOrDefault() }; } // Stream Game if (model.StreamUrl.IsSpecified) { return new StreamingGame( - model.Name, - model.StreamUrl.Value); + model.Name, + model.StreamUrl.Value) + { + Flags = model.Flags.GetValueOrDefault(), + Details = model.Details.GetValueOrDefault() + }; } // Normal Game - return new Game(model.Name, model.Type.GetValueOrDefault() ?? ActivityType.Playing); + return new Game(model.Name, model.Type.GetValueOrDefault() ?? ActivityType.Playing, + model.Flags.IsSpecified ? model.Flags.Value : ActivityProperties.None, + model.Details.GetValueOrDefault()); } // (Small, Large) From a797be9ca03005bc0fd451fee0a889e71b71ee15 Mon Sep 17 00:00:00 2001 From: Chris Johnston Date: Wed, 12 Jun 2019 13:08:03 -0700 Subject: [PATCH 16/16] test: Split Unit and Integration tests into separate projects (#1290) * Squashed commit of test rewrite changes fix missing priority speaker flag rewrite the TestChannelPermissionModify test add test for GuildPermission modify separate unit and integration tests, start writing channel and guild permission tests copy over the color tests copy over the emote tests copy the token utils tests make the mocked entities sealed classes copy the TypeReaderTests class properly dispose the CommandService in the TypeReaderTests start writing tests for EmbedBuilder and related classes test that properties throw ArgumentException when invalid add tests for the embed length property add withFooter tests finish adding tests to EmbedBuilder fix bug in value validation of EmbedFieldBuilder hey, these tests actually found a bug! add tests for the MentionUtils class add tests for the Format util class remove all of the old tests add analyzer tests (copied from old tests) add tests for the SnowflakeUtils class add integration tests these get around the issue of state persisting between tests by creating and deleting a guild for each set of tests. these shouldn't be run excessively because of the rate limits, but should be fine every now and then remove unnecessary launchSettings.json update outdated string don't create a new guild each time, as that can result in errors this can happen if a bot creates too many guilds without properly deleting them add some tests that show that guild can be modified await async assert add more measures that created channels are deleted when done remove "Test" prefix from test method names I think that this prefix when already displayed under a class with a suffix of "Tests" is redundant Remove mention of old test project fix an issue from forgetting to await Assert.ThrowsAsync explicitly disable parallelization on integration tests add test for GuildPermission modify separate unit and integration tests, start writing channel and guild permission tests copy over the color tests copy over the emote tests make the mocked entities sealed classes properly dispose the CommandService in the TypeReaderTests fix bug in value validation of EmbedFieldBuilder hey, these tests actually found a bug! add tests for the MentionUtils class add tests for the Format util class remove all of the old tests add analyzer tests (copied from old tests) add tests for the SnowflakeUtils class add integration tests these get around the issue of state persisting between tests by creating and deleting a guild for each set of tests. these shouldn't be run excessively because of the rate limits, but should be fine every now and then remove unnecessary launchSettings.json update outdated string don't create a new guild each time, as that can result in errors this can happen if a bot creates too many guilds without properly deleting them add more measures that created channels are deleted when done remove "Test" prefix from test method names I think that this prefix when already displayed under a class with a suffix of "Tests" is redundant Remove mention of old test project fix an issue from forgetting to await Assert.ThrowsAsync explicitly disable parallelization on integration tests update the azure CI build script separate execution of test projects so that if one fails the other will not pass one of the unit tests failed, but the analzyer tests passed fix test that would break in different timezones enable the integration tests (only on dev branch) * Squashed commit of test rewrite changes fix missing priority speaker flag rewrite the TestChannelPermissionModify test add test for GuildPermission modify separate unit and integration tests, start writing channel and guild permission tests copy over the color tests copy over the emote tests copy the token utils tests make the mocked entities sealed classes copy the TypeReaderTests class properly dispose the CommandService in the TypeReaderTests start writing tests for EmbedBuilder and related classes test that properties throw ArgumentException when invalid add tests for the embed length property add withFooter tests finish adding tests to EmbedBuilder fix bug in value validation of EmbedFieldBuilder hey, these tests actually found a bug! add tests for the MentionUtils class add tests for the Format util class remove all of the old tests add analyzer tests (copied from old tests) add tests for the SnowflakeUtils class add integration tests these get around the issue of state persisting between tests by creating and deleting a guild for each set of tests. these shouldn't be run excessively because of the rate limits, but should be fine every now and then remove unnecessary launchSettings.json update outdated string don't create a new guild each time, as that can result in errors this can happen if a bot creates too many guilds without properly deleting them add some tests that show that guild can be modified await async assert add more measures that created channels are deleted when done remove "Test" prefix from test method names I think that this prefix when already displayed under a class with a suffix of "Tests" is redundant Remove mention of old test project fix an issue from forgetting to await Assert.ThrowsAsync explicitly disable parallelization on integration tests add test for GuildPermission modify separate unit and integration tests, start writing channel and guild permission tests copy over the color tests copy over the emote tests make the mocked entities sealed classes properly dispose the CommandService in the TypeReaderTests fix bug in value validation of EmbedFieldBuilder hey, these tests actually found a bug! add tests for the MentionUtils class add tests for the Format util class remove all of the old tests add analyzer tests (copied from old tests) add tests for the SnowflakeUtils class add integration tests these get around the issue of state persisting between tests by creating and deleting a guild for each set of tests. these shouldn't be run excessively because of the rate limits, but should be fine every now and then remove unnecessary launchSettings.json update outdated string don't create a new guild each time, as that can result in errors this can happen if a bot creates too many guilds without properly deleting them add more measures that created channels are deleted when done remove "Test" prefix from test method names I think that this prefix when already displayed under a class with a suffix of "Tests" is redundant Remove mention of old test project fix an issue from forgetting to await Assert.ThrowsAsync explicitly disable parallelization on integration tests update the azure CI build script separate execution of test projects so that if one fails the other will not pass one of the unit tests failed, but the analzyer tests passed fix test that would break in different timezones enable the integration tests (only on dev branch) * Update mocked channels for changed SendFileAsync signature * comment out the integration tests from the build script no bot token is provided to this script, and use of integration tests in CI is questionable here * force rebuild because Azure linux build broke --- Discord.Net.sln | 87 +- azure/build.yml | 11 +- src/Discord.Net.Core/AssemblyInfo.cs | 4 +- .../Entities/Messages/EmbedBuilder.cs | 2 +- .../Discord.Net.Analyzers.Tests.csproj | 24 + .../Extensions/AppDomainPolyfill.cs | 0 .../GuildAccessTests.cs | 0 .../Helpers/CodeFixVerifier.Helper.cs | 0 .../Helpers/DiagnosticResult.cs | 0 .../Helpers/DiagnosticVerifier.Helper.cs | 0 .../Verifiers/CodeFixVerifier.cs | 0 .../Verifiers/DiagnosticVerifier.cs | 0 .../ChannelsTests.cs | 163 ++++ .../Discord.Net.Tests.Integration.csproj | 27 + .../DiscordRestClientFixture.cs | 34 + .../GuildTests.cs | 114 +++ .../RestGuildFixture.cs | 44 + .../ChannelPermissionsTests.cs | 223 +++++ .../ColorTests.cs} | 5 + .../Discord.Net.Tests.Unit.csproj | 21 + .../EmbedBuilderTests.cs | 467 +++++++++++ .../EmoteTests.cs} | 2 + test/Discord.Net.Tests.Unit/FormatTests.cs | 32 + .../GuildPermissionsTests.cs | 164 ++++ .../MentionUtilsTests.cs | 128 +++ .../MockedEntities/MockedCategoryChannel.cs | 84 ++ .../MockedEntities/MockedDMChannel.cs | 96 +++ .../MockedEntities/MockedGroupChannel.cs | 105 +++ .../MockedEntities/MockedInvalidChannel.cs | 29 + .../MockedEntities/MockedTextChannel.cs | 205 +++++ .../MockedEntities/MockedVoiceChannel.cs | 126 +++ .../SnowflakeUtilsTests.cs | 24 + .../TokenUtilsTests.cs} | 59 +- .../Discord.Net.Tests.Unit/TypeReaderTests.cs | 142 ++++ .../Discord.Net.Tests.csproj | 35 - test/Discord.Net.Tests/Net/CacheInfo.cs | 12 - .../Discord.Net.Tests/Net/CachedRestClient.cs | 123 --- .../Net/FilesystemProvider.cs | 128 --- test/Discord.Net.Tests/Net/HttpMixin.cs | 144 ---- test/Discord.Net.Tests/TestConfig.cs | 33 - .../Tests.ChannelPermissions.cs | 177 ---- test/Discord.Net.Tests/Tests.Channels.cs | 218 ----- test/Discord.Net.Tests/Tests.Guilds.cs | 342 -------- test/Discord.Net.Tests/Tests.Migrations.cs | 73 -- test/Discord.Net.Tests/Tests.Permissions.cs | 772 ------------------ test/Discord.Net.Tests/Tests.TypeReaders.cs | 133 --- test/Discord.Net.Tests/Tests.cs | 55 -- test/Discord.Net.Tests/config.json.example | 4 - test/Discord.Net.Tests/xunit.runner.json | 4 - 49 files changed, 2326 insertions(+), 2349 deletions(-) create mode 100644 test/Discord.Net.Analyzers.Tests/Discord.Net.Analyzers.Tests.csproj rename test/{Discord.Net.Tests/AnalyzerTests => Discord.Net.Analyzers.Tests}/Extensions/AppDomainPolyfill.cs (100%) rename test/{Discord.Net.Tests/AnalyzerTests => Discord.Net.Analyzers.Tests}/GuildAccessTests.cs (100%) rename test/{Discord.Net.Tests/AnalyzerTests => Discord.Net.Analyzers.Tests}/Helpers/CodeFixVerifier.Helper.cs (100%) rename test/{Discord.Net.Tests/AnalyzerTests => Discord.Net.Analyzers.Tests}/Helpers/DiagnosticResult.cs (100%) rename test/{Discord.Net.Tests/AnalyzerTests => Discord.Net.Analyzers.Tests}/Helpers/DiagnosticVerifier.Helper.cs (100%) rename test/{Discord.Net.Tests/AnalyzerTests => Discord.Net.Analyzers.Tests}/Verifiers/CodeFixVerifier.cs (100%) rename test/{Discord.Net.Tests/AnalyzerTests => Discord.Net.Analyzers.Tests}/Verifiers/DiagnosticVerifier.cs (100%) create mode 100644 test/Discord.Net.Tests.Integration/ChannelsTests.cs create mode 100644 test/Discord.Net.Tests.Integration/Discord.Net.Tests.Integration.csproj create mode 100644 test/Discord.Net.Tests.Integration/DiscordRestClientFixture.cs create mode 100644 test/Discord.Net.Tests.Integration/GuildTests.cs create mode 100644 test/Discord.Net.Tests.Integration/RestGuildFixture.cs create mode 100644 test/Discord.Net.Tests.Unit/ChannelPermissionsTests.cs rename test/{Discord.Net.Tests/Tests.Colors.cs => Discord.Net.Tests.Unit/ColorTests.cs} (96%) create mode 100644 test/Discord.Net.Tests.Unit/Discord.Net.Tests.Unit.csproj create mode 100644 test/Discord.Net.Tests.Unit/EmbedBuilderTests.cs rename test/{Discord.Net.Tests/Tests.Emotes.cs => Discord.Net.Tests.Unit/EmoteTests.cs} (97%) create mode 100644 test/Discord.Net.Tests.Unit/FormatTests.cs create mode 100644 test/Discord.Net.Tests.Unit/GuildPermissionsTests.cs create mode 100644 test/Discord.Net.Tests.Unit/MentionUtilsTests.cs create mode 100644 test/Discord.Net.Tests.Unit/MockedEntities/MockedCategoryChannel.cs create mode 100644 test/Discord.Net.Tests.Unit/MockedEntities/MockedDMChannel.cs create mode 100644 test/Discord.Net.Tests.Unit/MockedEntities/MockedGroupChannel.cs create mode 100644 test/Discord.Net.Tests.Unit/MockedEntities/MockedInvalidChannel.cs create mode 100644 test/Discord.Net.Tests.Unit/MockedEntities/MockedTextChannel.cs create mode 100644 test/Discord.Net.Tests.Unit/MockedEntities/MockedVoiceChannel.cs create mode 100644 test/Discord.Net.Tests.Unit/SnowflakeUtilsTests.cs rename test/{Discord.Net.Tests/Tests.TokenUtils.cs => Discord.Net.Tests.Unit/TokenUtilsTests.cs} (77%) create mode 100644 test/Discord.Net.Tests.Unit/TypeReaderTests.cs delete mode 100644 test/Discord.Net.Tests/Discord.Net.Tests.csproj delete mode 100644 test/Discord.Net.Tests/Net/CacheInfo.cs delete mode 100644 test/Discord.Net.Tests/Net/CachedRestClient.cs delete mode 100644 test/Discord.Net.Tests/Net/FilesystemProvider.cs delete mode 100644 test/Discord.Net.Tests/Net/HttpMixin.cs delete mode 100644 test/Discord.Net.Tests/TestConfig.cs delete mode 100644 test/Discord.Net.Tests/Tests.ChannelPermissions.cs delete mode 100644 test/Discord.Net.Tests/Tests.Channels.cs delete mode 100644 test/Discord.Net.Tests/Tests.Guilds.cs delete mode 100644 test/Discord.Net.Tests/Tests.Migrations.cs delete mode 100644 test/Discord.Net.Tests/Tests.Permissions.cs delete mode 100644 test/Discord.Net.Tests/Tests.TypeReaders.cs delete mode 100644 test/Discord.Net.Tests/Tests.cs delete mode 100644 test/Discord.Net.Tests/config.json.example delete mode 100644 test/Discord.Net.Tests/xunit.runner.json diff --git a/Discord.Net.sln b/Discord.Net.sln index c6fb7e7f1..cd53f25b6 100644 --- a/Discord.Net.sln +++ b/Discord.Net.sln @@ -18,8 +18,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Discord.Net.Providers.WS4Ne EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Extensions", "Extensions", "{CC3D4B1C-9DE0-448B-8AE7-F3F1F3EC5C3A}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Discord.Net.Tests", "test\Discord.Net.Tests\Discord.Net.Tests.csproj", "{C38E5BC1-11CB-4101-8A38-5B40A1BC6433}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Discord.Net.Webhook", "src\Discord.Net.Webhook\Discord.Net.Webhook.csproj", "{9AFAB80E-D2D3-4EDB-B58C-BACA78D1EA30}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Discord.Net.Analyzers", "src\Discord.Net.Analyzers\Discord.Net.Analyzers.csproj", "{BBA8E7FB-C834-40DC-822F-B112CB7F0140}" @@ -32,11 +30,13 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "02_commands_framework", "sa EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "03_sharded_client", "samples\03_sharded_client\03_sharded_client.csproj", "{9B4C4AFB-3D15-44C6-9E36-12ED625AAA26}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "04_webhook_client", "samples\04_webhook_client\04_webhook_client.csproj", "{88B77A5B-0BC0-4E99-8FD9-D83F6999F562}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Discord.Net.Tests.Unit", "test\Discord.Net.Tests.Unit\Discord.Net.Tests.Unit.csproj", "{DBF8B16E-5967-4480-8EDE-15D98A0DF0C4}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Discord.Net.Tests.Integration", "test\Discord.Net.Tests.Integration\Discord.Net.Tests.Integration.csproj", "{E169E15A-E82C-45BF-8C24-C2CADB7093AA}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Examples", "Examples", "{D1F0271E-0EE2-4B66-AC3D-9871B7E1C4CF}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{C7CF5621-7D36-433B-B337-5A2E3C101A71}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Discord.Net.Examples", "src\Discord.Net.Examples\Discord.Net.Examples.csproj", "{7EA96B2B-4D71-458D-9423-839362DC38BE}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Discord.Net.Analyzers.Tests", "test\Discord.Net.Analyzers.Tests\Discord.Net.Analyzers.Tests.csproj", "{FC67057C-E92F-4E1C-98BE-46F839C8AD71}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -108,18 +108,6 @@ Global {6BDEEC08-417B-459F-9CA3-FF8BAB18CAC7}.Release|x64.Build.0 = Release|Any CPU {6BDEEC08-417B-459F-9CA3-FF8BAB18CAC7}.Release|x86.ActiveCfg = Release|Any CPU {6BDEEC08-417B-459F-9CA3-FF8BAB18CAC7}.Release|x86.Build.0 = Release|Any CPU - {C38E5BC1-11CB-4101-8A38-5B40A1BC6433}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C38E5BC1-11CB-4101-8A38-5B40A1BC6433}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C38E5BC1-11CB-4101-8A38-5B40A1BC6433}.Debug|x64.ActiveCfg = Debug|Any CPU - {C38E5BC1-11CB-4101-8A38-5B40A1BC6433}.Debug|x64.Build.0 = Debug|Any CPU - {C38E5BC1-11CB-4101-8A38-5B40A1BC6433}.Debug|x86.ActiveCfg = Debug|Any CPU - {C38E5BC1-11CB-4101-8A38-5B40A1BC6433}.Debug|x86.Build.0 = Debug|Any CPU - {C38E5BC1-11CB-4101-8A38-5B40A1BC6433}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C38E5BC1-11CB-4101-8A38-5B40A1BC6433}.Release|Any CPU.Build.0 = Release|Any CPU - {C38E5BC1-11CB-4101-8A38-5B40A1BC6433}.Release|x64.ActiveCfg = Release|Any CPU - {C38E5BC1-11CB-4101-8A38-5B40A1BC6433}.Release|x64.Build.0 = Release|Any CPU - {C38E5BC1-11CB-4101-8A38-5B40A1BC6433}.Release|x86.ActiveCfg = Release|Any CPU - {C38E5BC1-11CB-4101-8A38-5B40A1BC6433}.Release|x86.Build.0 = Release|Any CPU {9AFAB80E-D2D3-4EDB-B58C-BACA78D1EA30}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {9AFAB80E-D2D3-4EDB-B58C-BACA78D1EA30}.Debug|Any CPU.Build.0 = Debug|Any CPU {9AFAB80E-D2D3-4EDB-B58C-BACA78D1EA30}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -180,30 +168,42 @@ Global {9B4C4AFB-3D15-44C6-9E36-12ED625AAA26}.Release|x64.Build.0 = Release|Any CPU {9B4C4AFB-3D15-44C6-9E36-12ED625AAA26}.Release|x86.ActiveCfg = Release|Any CPU {9B4C4AFB-3D15-44C6-9E36-12ED625AAA26}.Release|x86.Build.0 = Release|Any CPU - {88B77A5B-0BC0-4E99-8FD9-D83F6999F562}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {88B77A5B-0BC0-4E99-8FD9-D83F6999F562}.Debug|Any CPU.Build.0 = Debug|Any CPU - {88B77A5B-0BC0-4E99-8FD9-D83F6999F562}.Debug|x64.ActiveCfg = Debug|Any CPU - {88B77A5B-0BC0-4E99-8FD9-D83F6999F562}.Debug|x64.Build.0 = Debug|Any CPU - {88B77A5B-0BC0-4E99-8FD9-D83F6999F562}.Debug|x86.ActiveCfg = Debug|Any CPU - {88B77A5B-0BC0-4E99-8FD9-D83F6999F562}.Debug|x86.Build.0 = Debug|Any CPU - {88B77A5B-0BC0-4E99-8FD9-D83F6999F562}.Release|Any CPU.ActiveCfg = Release|Any CPU - {88B77A5B-0BC0-4E99-8FD9-D83F6999F562}.Release|Any CPU.Build.0 = Release|Any CPU - {88B77A5B-0BC0-4E99-8FD9-D83F6999F562}.Release|x64.ActiveCfg = Release|Any CPU - {88B77A5B-0BC0-4E99-8FD9-D83F6999F562}.Release|x64.Build.0 = Release|Any CPU - {88B77A5B-0BC0-4E99-8FD9-D83F6999F562}.Release|x86.ActiveCfg = Release|Any CPU - {88B77A5B-0BC0-4E99-8FD9-D83F6999F562}.Release|x86.Build.0 = Release|Any CPU - {7EA96B2B-4D71-458D-9423-839362DC38BE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {7EA96B2B-4D71-458D-9423-839362DC38BE}.Debug|Any CPU.Build.0 = Debug|Any CPU - {7EA96B2B-4D71-458D-9423-839362DC38BE}.Debug|x64.ActiveCfg = Debug|Any CPU - {7EA96B2B-4D71-458D-9423-839362DC38BE}.Debug|x64.Build.0 = Debug|Any CPU - {7EA96B2B-4D71-458D-9423-839362DC38BE}.Debug|x86.ActiveCfg = Debug|Any CPU - {7EA96B2B-4D71-458D-9423-839362DC38BE}.Debug|x86.Build.0 = Debug|Any CPU - {7EA96B2B-4D71-458D-9423-839362DC38BE}.Release|Any CPU.ActiveCfg = Release|Any CPU - {7EA96B2B-4D71-458D-9423-839362DC38BE}.Release|Any CPU.Build.0 = Release|Any CPU - {7EA96B2B-4D71-458D-9423-839362DC38BE}.Release|x64.ActiveCfg = Release|Any CPU - {7EA96B2B-4D71-458D-9423-839362DC38BE}.Release|x64.Build.0 = Release|Any CPU - {7EA96B2B-4D71-458D-9423-839362DC38BE}.Release|x86.ActiveCfg = Release|Any CPU - {7EA96B2B-4D71-458D-9423-839362DC38BE}.Release|x86.Build.0 = Release|Any CPU + {DBF8B16E-5967-4480-8EDE-15D98A0DF0C4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DBF8B16E-5967-4480-8EDE-15D98A0DF0C4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DBF8B16E-5967-4480-8EDE-15D98A0DF0C4}.Debug|x64.ActiveCfg = Debug|Any CPU + {DBF8B16E-5967-4480-8EDE-15D98A0DF0C4}.Debug|x64.Build.0 = Debug|Any CPU + {DBF8B16E-5967-4480-8EDE-15D98A0DF0C4}.Debug|x86.ActiveCfg = Debug|Any CPU + {DBF8B16E-5967-4480-8EDE-15D98A0DF0C4}.Debug|x86.Build.0 = Debug|Any CPU + {DBF8B16E-5967-4480-8EDE-15D98A0DF0C4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DBF8B16E-5967-4480-8EDE-15D98A0DF0C4}.Release|Any CPU.Build.0 = Release|Any CPU + {DBF8B16E-5967-4480-8EDE-15D98A0DF0C4}.Release|x64.ActiveCfg = Release|Any CPU + {DBF8B16E-5967-4480-8EDE-15D98A0DF0C4}.Release|x64.Build.0 = Release|Any CPU + {DBF8B16E-5967-4480-8EDE-15D98A0DF0C4}.Release|x86.ActiveCfg = Release|Any CPU + {DBF8B16E-5967-4480-8EDE-15D98A0DF0C4}.Release|x86.Build.0 = Release|Any CPU + {E169E15A-E82C-45BF-8C24-C2CADB7093AA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E169E15A-E82C-45BF-8C24-C2CADB7093AA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E169E15A-E82C-45BF-8C24-C2CADB7093AA}.Debug|x64.ActiveCfg = Debug|Any CPU + {E169E15A-E82C-45BF-8C24-C2CADB7093AA}.Debug|x64.Build.0 = Debug|Any CPU + {E169E15A-E82C-45BF-8C24-C2CADB7093AA}.Debug|x86.ActiveCfg = Debug|Any CPU + {E169E15A-E82C-45BF-8C24-C2CADB7093AA}.Debug|x86.Build.0 = Debug|Any CPU + {E169E15A-E82C-45BF-8C24-C2CADB7093AA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E169E15A-E82C-45BF-8C24-C2CADB7093AA}.Release|Any CPU.Build.0 = Release|Any CPU + {E169E15A-E82C-45BF-8C24-C2CADB7093AA}.Release|x64.ActiveCfg = Release|Any CPU + {E169E15A-E82C-45BF-8C24-C2CADB7093AA}.Release|x64.Build.0 = Release|Any CPU + {E169E15A-E82C-45BF-8C24-C2CADB7093AA}.Release|x86.ActiveCfg = Release|Any CPU + {E169E15A-E82C-45BF-8C24-C2CADB7093AA}.Release|x86.Build.0 = Release|Any CPU + {FC67057C-E92F-4E1C-98BE-46F839C8AD71}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FC67057C-E92F-4E1C-98BE-46F839C8AD71}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FC67057C-E92F-4E1C-98BE-46F839C8AD71}.Debug|x64.ActiveCfg = Debug|Any CPU + {FC67057C-E92F-4E1C-98BE-46F839C8AD71}.Debug|x64.Build.0 = Debug|Any CPU + {FC67057C-E92F-4E1C-98BE-46F839C8AD71}.Debug|x86.ActiveCfg = Debug|Any CPU + {FC67057C-E92F-4E1C-98BE-46F839C8AD71}.Debug|x86.Build.0 = Debug|Any CPU + {FC67057C-E92F-4E1C-98BE-46F839C8AD71}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FC67057C-E92F-4E1C-98BE-46F839C8AD71}.Release|Any CPU.Build.0 = Release|Any CPU + {FC67057C-E92F-4E1C-98BE-46F839C8AD71}.Release|x64.ActiveCfg = Release|Any CPU + {FC67057C-E92F-4E1C-98BE-46F839C8AD71}.Release|x64.Build.0 = Release|Any CPU + {FC67057C-E92F-4E1C-98BE-46F839C8AD71}.Release|x86.ActiveCfg = Release|Any CPU + {FC67057C-E92F-4E1C-98BE-46F839C8AD71}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -218,8 +218,9 @@ Global {F2FF84FB-F6AD-47E5-9EE5-18206CAE136E} = {BB59D5B5-E7B0-4BF4-8F82-D14431B2799B} {4E1F1F40-B1DD-40C9-A4B1-A2046A4C9C76} = {BB59D5B5-E7B0-4BF4-8F82-D14431B2799B} {9B4C4AFB-3D15-44C6-9E36-12ED625AAA26} = {BB59D5B5-E7B0-4BF4-8F82-D14431B2799B} - {88B77A5B-0BC0-4E99-8FD9-D83F6999F562} = {BB59D5B5-E7B0-4BF4-8F82-D14431B2799B} - {7EA96B2B-4D71-458D-9423-839362DC38BE} = {D1F0271E-0EE2-4B66-AC3D-9871B7E1C4CF} + {DBF8B16E-5967-4480-8EDE-15D98A0DF0C4} = {C7CF5621-7D36-433B-B337-5A2E3C101A71} + {E169E15A-E82C-45BF-8C24-C2CADB7093AA} = {C7CF5621-7D36-433B-B337-5A2E3C101A71} + {FC67057C-E92F-4E1C-98BE-46F839C8AD71} = {C7CF5621-7D36-433B-B337-5A2E3C101A71} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {D2404771-EEC8-45F2-9D71-F3373F6C1495} diff --git a/azure/build.yml b/azure/build.yml index ff32eae2d..412e4a823 100644 --- a/azure/build.yml +++ b/azure/build.yml @@ -5,9 +5,14 @@ steps: - script: dotnet build "Discord.Net.sln" --no-restore -v minimal -c $(buildConfiguration) /p:BuildNumber=$(buildNumber) /p:IsTagBuild=$(buildTag) displayName: Build projects -- script: dotnet test "test/Discord.Net.Tests/Discord.Net.Tests.csproj" --no-restore --no-build -v minimal -c $(buildConfiguration) --logger trx - # TODO: update this to support multiple tests - displayName: Test projects +- script: dotnet test "test/Discord.Net.Tests.Unit/Discord.Net.Tests.Unit.csproj" --no-restore --no-build -v minimal -c $(buildConfiguration) --logger trx + displayName: Unit Tests + +- script: dotnet test "test/Discord.Net.Analyzers.Tests/Discord.Net.Analyzers.Tests.csproj" --no-restore --no-build -v minimal -c $(buildConfiguration) --logger trx + displayName: Analyzer Tests + +# - script: dotnet test "test/Discord.Net.Tests.Integration/Discord.Net.Tests.Integration.csproj" --no-restore --no-build -v minimal -c $(buildConfiguration) --logger trx +# condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/dev')) - task: PublishTestResults@2 displayName: Publish test results diff --git a/src/Discord.Net.Core/AssemblyInfo.cs b/src/Discord.Net.Core/AssemblyInfo.cs index 116bc3850..41ea23859 100644 --- a/src/Discord.Net.Core/AssemblyInfo.cs +++ b/src/Discord.Net.Core/AssemblyInfo.cs @@ -1,4 +1,4 @@ -using System.Runtime.CompilerServices; +using System.Runtime.CompilerServices; [assembly: InternalsVisibleTo("Discord.Net.Relay")] [assembly: InternalsVisibleTo("Discord.Net.Rest")] @@ -6,4 +6,4 @@ [assembly: InternalsVisibleTo("Discord.Net.WebSocket")] [assembly: InternalsVisibleTo("Discord.Net.Webhook")] [assembly: InternalsVisibleTo("Discord.Net.Commands")] -[assembly: InternalsVisibleTo("Discord.Net.Tests")] \ No newline at end of file +[assembly: InternalsVisibleTo("Discord.Net.Tests.Unit")] diff --git a/src/Discord.Net.Core/Entities/Messages/EmbedBuilder.cs b/src/Discord.Net.Core/Entities/Messages/EmbedBuilder.cs index 39d24fa03..555fd95df 100644 --- a/src/Discord.Net.Core/Entities/Messages/EmbedBuilder.cs +++ b/src/Discord.Net.Core/Entities/Messages/EmbedBuilder.cs @@ -486,7 +486,7 @@ namespace Discord set { var stringValue = value?.ToString(); - if (string.IsNullOrEmpty(stringValue)) throw new ArgumentException(message: "Field value must not be null or empty.", paramName: nameof(Value)); + if (string.IsNullOrWhiteSpace(stringValue)) throw new ArgumentException(message: "Field value must not be null or empty.", paramName: nameof(Value)); if (stringValue.Length > MaxFieldValueLength) throw new ArgumentException(message: $"Field value length must be less than or equal to {MaxFieldValueLength}.", paramName: nameof(Value)); _value = stringValue; } diff --git a/test/Discord.Net.Analyzers.Tests/Discord.Net.Analyzers.Tests.csproj b/test/Discord.Net.Analyzers.Tests/Discord.Net.Analyzers.Tests.csproj new file mode 100644 index 000000000..1ee986e8a --- /dev/null +++ b/test/Discord.Net.Analyzers.Tests/Discord.Net.Analyzers.Tests.csproj @@ -0,0 +1,24 @@ + + + + netcoreapp2.1 + + false + + + + + + + + + + + + + + + + + + diff --git a/test/Discord.Net.Tests/AnalyzerTests/Extensions/AppDomainPolyfill.cs b/test/Discord.Net.Analyzers.Tests/Extensions/AppDomainPolyfill.cs similarity index 100% rename from test/Discord.Net.Tests/AnalyzerTests/Extensions/AppDomainPolyfill.cs rename to test/Discord.Net.Analyzers.Tests/Extensions/AppDomainPolyfill.cs diff --git a/test/Discord.Net.Tests/AnalyzerTests/GuildAccessTests.cs b/test/Discord.Net.Analyzers.Tests/GuildAccessTests.cs similarity index 100% rename from test/Discord.Net.Tests/AnalyzerTests/GuildAccessTests.cs rename to test/Discord.Net.Analyzers.Tests/GuildAccessTests.cs diff --git a/test/Discord.Net.Tests/AnalyzerTests/Helpers/CodeFixVerifier.Helper.cs b/test/Discord.Net.Analyzers.Tests/Helpers/CodeFixVerifier.Helper.cs similarity index 100% rename from test/Discord.Net.Tests/AnalyzerTests/Helpers/CodeFixVerifier.Helper.cs rename to test/Discord.Net.Analyzers.Tests/Helpers/CodeFixVerifier.Helper.cs diff --git a/test/Discord.Net.Tests/AnalyzerTests/Helpers/DiagnosticResult.cs b/test/Discord.Net.Analyzers.Tests/Helpers/DiagnosticResult.cs similarity index 100% rename from test/Discord.Net.Tests/AnalyzerTests/Helpers/DiagnosticResult.cs rename to test/Discord.Net.Analyzers.Tests/Helpers/DiagnosticResult.cs diff --git a/test/Discord.Net.Tests/AnalyzerTests/Helpers/DiagnosticVerifier.Helper.cs b/test/Discord.Net.Analyzers.Tests/Helpers/DiagnosticVerifier.Helper.cs similarity index 100% rename from test/Discord.Net.Tests/AnalyzerTests/Helpers/DiagnosticVerifier.Helper.cs rename to test/Discord.Net.Analyzers.Tests/Helpers/DiagnosticVerifier.Helper.cs diff --git a/test/Discord.Net.Tests/AnalyzerTests/Verifiers/CodeFixVerifier.cs b/test/Discord.Net.Analyzers.Tests/Verifiers/CodeFixVerifier.cs similarity index 100% rename from test/Discord.Net.Tests/AnalyzerTests/Verifiers/CodeFixVerifier.cs rename to test/Discord.Net.Analyzers.Tests/Verifiers/CodeFixVerifier.cs diff --git a/test/Discord.Net.Tests/AnalyzerTests/Verifiers/DiagnosticVerifier.cs b/test/Discord.Net.Analyzers.Tests/Verifiers/DiagnosticVerifier.cs similarity index 100% rename from test/Discord.Net.Tests/AnalyzerTests/Verifiers/DiagnosticVerifier.cs rename to test/Discord.Net.Analyzers.Tests/Verifiers/DiagnosticVerifier.cs diff --git a/test/Discord.Net.Tests.Integration/ChannelsTests.cs b/test/Discord.Net.Tests.Integration/ChannelsTests.cs new file mode 100644 index 000000000..3bf60772f --- /dev/null +++ b/test/Discord.Net.Tests.Integration/ChannelsTests.cs @@ -0,0 +1,163 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; +using Xunit; +using Xunit.Abstractions; + +namespace Discord +{ + /// + /// Tests that channels can be created and modified. + /// + [CollectionDefinition("ChannelsTests", DisableParallelization = true)] + public class ChannelsTests : IClassFixture + { + private IGuild guild; + private readonly ITestOutputHelper output; + + public ChannelsTests(RestGuildFixture guildFixture, ITestOutputHelper output) + { + guild = guildFixture.Guild; + this.output = output; + output.WriteLine($"RestGuildFixture using guild: {guild.Id}"); + // capture all console output + guildFixture.Client.Log += LogAsync; + } + private Task LogAsync(LogMessage message) + { + output.WriteLine(message.ToString()); + return Task.CompletedTask; + } + + /// + /// Checks that a text channel can be created and modified. + /// + [Fact] + public async Task ModifyTextChannel() + { + // create a text channel to modify + var channel = await guild.CreateTextChannelAsync("text"); + try + { + Assert.NotNull(channel); + // check that it can be modified + await channel.ModifyAsync(x => + { + x.IsNsfw = true; + x.Name = "updated"; + x.SlowModeInterval = 50; + x.Topic = "topic"; + x.CategoryId = null; + }); + // check the results of modifying this channel + Assert.True(channel.IsNsfw); + Assert.Equal("updated", channel.Name); + Assert.Equal(50, channel.SlowModeInterval); + Assert.Equal("topic", channel.Topic); + Assert.Null(channel.CategoryId); + } + finally + { + // delete the channel when finished + await channel?.DeleteAsync(); + } + } + + /// + /// Checks that a voice channel can be created, modified, and deleted. + /// + [Fact] + public async Task ModifyVoiceChannel() + { + var channel = await guild.CreateVoiceChannelAsync("voice"); + try + { + Assert.NotNull(channel); + // try to modify it + await channel.ModifyAsync(x => + { + x.Bitrate = 9001; + x.Name = "updated"; + x.UserLimit = 1; + }); + // check that these were updated + Assert.Equal(9001, channel.Bitrate); + Assert.Equal("updated", channel.Name); + Assert.Equal(1, channel.UserLimit); + } + finally + { + // delete the channel when done + await channel.DeleteAsync(); + } + } + + /// + /// Creates a category channel, a voice channel, and a text channel, then tries to assign them under that category. + /// + [Fact] + public async Task ModifyChannelCategories() + { + // util method for checking if a category is set + async Task CheckAsync(INestedChannel channel, ICategoryChannel cat) + { + // check that the category is not set + if (cat == null) + { + Assert.Null(channel.CategoryId); + Assert.Null(await channel.GetCategoryAsync()); + } + else + { + Assert.NotNull(channel.CategoryId); + Assert.Equal(cat.Id, channel.CategoryId); + var getCat = await channel.GetCategoryAsync(); + Assert.NotNull(getCat); + Assert.Equal(cat.Id, getCat.Id); + } + } + // initially create these not under the category + var category = await guild.CreateCategoryAsync("category"); + var text = await guild.CreateTextChannelAsync("text"); + var voice = await guild.CreateVoiceChannelAsync("voice"); + + try + { + Assert.NotNull(category); + Assert.NotNull(text); + Assert.NotNull(voice); + // check that the category is not set for either + await CheckAsync(text, null); + await CheckAsync(voice, null); + + // set the category + await text.ModifyAsync(x => x.CategoryId = category.Id); + await voice.ModifyAsync(x => x.CategoryId = category.Id); + + // check that this is set, and that it's the category that was created earlier + await CheckAsync(text, category); + await CheckAsync(voice, category); + + // create one more channel immediately under this category + var newText = await guild.CreateTextChannelAsync("new-text", x => x.CategoryId = category.Id); + try + { + Assert.NotNull(newText); + await CheckAsync(newText, category); + } + finally + { + await newText?.DeleteAsync(); + } + } + finally + { + // clean up + await category?.DeleteAsync(); + await text?.DeleteAsync(); + await voice?.DeleteAsync(); + } + } + } +} diff --git a/test/Discord.Net.Tests.Integration/Discord.Net.Tests.Integration.csproj b/test/Discord.Net.Tests.Integration/Discord.Net.Tests.Integration.csproj new file mode 100644 index 000000000..cd4aafac0 --- /dev/null +++ b/test/Discord.Net.Tests.Integration/Discord.Net.Tests.Integration.csproj @@ -0,0 +1,27 @@ + + + + netcoreapp2.1 + + false + + + + + + + + + + + + + + + + + + + + + diff --git a/test/Discord.Net.Tests.Integration/DiscordRestClientFixture.cs b/test/Discord.Net.Tests.Integration/DiscordRestClientFixture.cs new file mode 100644 index 000000000..b108e7b0f --- /dev/null +++ b/test/Discord.Net.Tests.Integration/DiscordRestClientFixture.cs @@ -0,0 +1,34 @@ +using Discord.Rest; +using System; +using Xunit; + +namespace Discord +{ + /// + /// Test fixture type for integration tests which sets up the client from + /// the token provided in environment variables. + /// + public class DiscordRestClientFixture : IDisposable + { + public DiscordRestClient Client { get; private set; } + + public DiscordRestClientFixture() + { + var token = Environment.GetEnvironmentVariable("DNET_TEST_TOKEN", EnvironmentVariableTarget.Machine); + if (string.IsNullOrWhiteSpace(token)) + throw new Exception("The DNET_TEST_TOKEN environment variable was not provided."); + Client = new DiscordRestClient(new DiscordRestConfig() + { + LogLevel = LogSeverity.Debug, + DefaultRetryMode = RetryMode.AlwaysRetry + }); + Client.LoginAsync(TokenType.Bot, token).Wait(); + } + + public void Dispose() + { + Client.LogoutAsync().Wait(); + Client.Dispose(); + } + } +} diff --git a/test/Discord.Net.Tests.Integration/GuildTests.cs b/test/Discord.Net.Tests.Integration/GuildTests.cs new file mode 100644 index 000000000..40394a3a0 --- /dev/null +++ b/test/Discord.Net.Tests.Integration/GuildTests.cs @@ -0,0 +1,114 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; +using Xunit; +using Xunit.Abstractions; + +namespace Discord +{ + [CollectionDefinition("GuildTests", DisableParallelization = true)] + public class GuildTests : IClassFixture + { + private IDiscordClient client; + private IGuild guild; + private readonly ITestOutputHelper output; + + public GuildTests(RestGuildFixture guildFixture, ITestOutputHelper output) + { + client = guildFixture.Client; + guild = guildFixture.Guild; + this.output = output; + output.WriteLine($"RestGuildFixture using guild: {guild.Id}"); + guildFixture.Client.Log += LogAsync; + } + private Task LogAsync(LogMessage message) + { + output.WriteLine(message.ToString()); + return Task.CompletedTask; + } + /// + /// Ensures that the CurrentUser is the owner of the guild. + /// + [Fact] + public void CheckOwner() + { + Assert.Equal(client.CurrentUser.Id, guild.OwnerId); + } + /// + /// Checks that a Guild can be modified to non-default values. + /// + [Fact] + public async Task ModifyGuild() + { + // set some initial properties of the guild that are not the defaults + await guild.ModifyAsync(x => + { + x.ExplicitContentFilter = ExplicitContentFilterLevel.AllMembers; + x.Name = "updated"; + x.DefaultMessageNotifications = DefaultMessageNotifications.MentionsOnly; + x.AfkTimeout = 900; // 15 minutes + x.VerificationLevel = VerificationLevel.None; + }); + // check that they were set + Assert.Equal("updated", guild.Name); + Assert.Equal(ExplicitContentFilterLevel.AllMembers, guild.ExplicitContentFilter); + Assert.Equal(DefaultMessageNotifications.MentionsOnly, guild.DefaultMessageNotifications); + Assert.Equal(VerificationLevel.None, guild.VerificationLevel); + Assert.Equal(900, guild.AFKTimeout); + } + /// + /// Checks that the SystemChannel property of a guild can be modified. + /// + [Fact] + public async Task ModifySystemChannel() + { + var systemChannel = await guild.CreateTextChannelAsync("system"); + // set using the Id + await guild.ModifyAsync(x => x.SystemChannelId = systemChannel.Id); + Assert.Equal(systemChannel.Id, guild.SystemChannelId); + // unset it + await guild.ModifyAsync(x => x.SystemChannelId = null); + Assert.Null(guild.SystemChannelId); + Assert.Null(await guild.GetSystemChannelAsync()); + + // set using the ITextChannel + await guild.ModifyAsync(x => { x.SystemChannel = new Optional(systemChannel); }); + Assert.Equal(systemChannel.Id, guild.SystemChannelId); + + await Assert.ThrowsAsync( async () => + { + await guild.ModifyAsync(x => x.SystemChannel = null); + }); + + await systemChannel.DeleteAsync(); + } + /// + /// Checks that the AFK channel of a guild can be set. + /// + [Fact] + public async Task ModifyAfkChannel() + { + var afkChannel = await guild.CreateVoiceChannelAsync("afk"); + // set using the Id + await guild.ModifyAsync(x => x.AfkChannelId = afkChannel.Id); + Assert.Equal(afkChannel.Id, guild.AFKChannelId); + + // unset using Id + await guild.ModifyAsync(x => x.AfkChannelId = null); + Assert.Null(guild.AFKChannelId); + Assert.Null(await guild.GetAFKChannelAsync()); + + // the same, but with the AfkChannel property + await guild.ModifyAsync(x => x.AfkChannel = new Optional(afkChannel)); + Assert.Equal(afkChannel.Id, guild.AFKChannelId); + + await Assert.ThrowsAsync( async () => + { + await guild.ModifyAsync(x => x.AfkChannel = null); + }); + + await afkChannel.DeleteAsync(); + } + } +} diff --git a/test/Discord.Net.Tests.Integration/RestGuildFixture.cs b/test/Discord.Net.Tests.Integration/RestGuildFixture.cs new file mode 100644 index 000000000..40b9ca9b2 --- /dev/null +++ b/test/Discord.Net.Tests.Integration/RestGuildFixture.cs @@ -0,0 +1,44 @@ +using Discord.Rest; +using System; +using System.Collections.Generic; +using System.Text; +using System.Linq; + +namespace Discord +{ + /// + /// Gets or creates a guild to use for testing. + /// + public class RestGuildFixture : DiscordRestClientFixture + { + public RestGuild Guild { get; private set; } + + public RestGuildFixture() : base() + { + var guilds = Client.GetGuildsAsync().Result.Where(x => x.OwnerId == Client.CurrentUser.Id).ToList(); + if (guilds.Count == 0) + { + // create a new guild if none exists already + var region = Client.GetOptimalVoiceRegionAsync().Result; + Guild = Client.CreateGuildAsync("DNET INTEGRATION TEST", region).Result; + RemoveAllChannels(); + } + else + { + // get the first one if there is a guild already created + Guild = guilds.First(); + } + } + + /// + /// Removes all channels in the guild. + /// + private void RemoveAllChannels() + { + foreach (var channel in Guild.GetChannelsAsync().Result) + { + channel.DeleteAsync().Wait(); + } + } + } +} diff --git a/test/Discord.Net.Tests.Unit/ChannelPermissionsTests.cs b/test/Discord.Net.Tests.Unit/ChannelPermissionsTests.cs new file mode 100644 index 000000000..2625c1e9b --- /dev/null +++ b/test/Discord.Net.Tests.Unit/ChannelPermissionsTests.cs @@ -0,0 +1,223 @@ +using System; +using System.Collections.Generic; +using Xunit; + +namespace Discord +{ + /// + /// Tests the behavior of the type and related functions. + /// + public class ChannelPermissionsTests + { + /// + /// Tests the default value of the constructor. + /// + [Fact] + public void DefaultConstructor() + { + var permission = new ChannelPermissions(); + Assert.Equal((ulong)0, permission.RawValue); + Assert.Equal(ChannelPermissions.None.RawValue, permission.RawValue); + } + + /// + /// Tests the behavior of the raw value constructor. + /// + [Fact] + public void RawValueConstructor() + { + // returns all of the values that will be tested + // a Theory cannot be used here, because these values are not all constants + IEnumerable GetTestValues() + { + yield return 0; + yield return ChannelPermissions.Category.RawValue; + yield return ChannelPermissions.DM.RawValue; + yield return ChannelPermissions.Group.RawValue; + yield return ChannelPermissions.None.RawValue; + yield return ChannelPermissions.Text.RawValue; + yield return ChannelPermissions.Voice.RawValue; + }; + + foreach (var rawValue in GetTestValues()) + { + var p = new ChannelPermissions(rawValue); + Assert.Equal(rawValue, p.RawValue); + } + } + + /// + /// Tests the behavior of the constructor for each + /// of it's flags. + /// + [Fact] + public void FlagsConstructor() + { + // util method for asserting that the constructor sets the given flag + void AssertFlag(Func cstr, ChannelPermission flag) + { + var p = cstr(); + // ensure that this flag is set to true + Assert.True(p.Has(flag)); + // ensure that only this flag is set + Assert.Equal((ulong)flag, p.RawValue); + } + + AssertFlag(() => new ChannelPermissions(createInstantInvite: true), ChannelPermission.CreateInstantInvite); + AssertFlag(() => new ChannelPermissions(manageChannel: true), ChannelPermission.ManageChannels); + AssertFlag(() => new ChannelPermissions(addReactions: true), ChannelPermission.AddReactions); + AssertFlag(() => new ChannelPermissions(viewChannel: true), ChannelPermission.ViewChannel); + AssertFlag(() => new ChannelPermissions(sendMessages: true), ChannelPermission.SendMessages); + AssertFlag(() => new ChannelPermissions(sendTTSMessages: true), ChannelPermission.SendTTSMessages); + AssertFlag(() => new ChannelPermissions(manageMessages: true), ChannelPermission.ManageMessages); + AssertFlag(() => new ChannelPermissions(embedLinks: true), ChannelPermission.EmbedLinks); + AssertFlag(() => new ChannelPermissions(attachFiles: true), ChannelPermission.AttachFiles); + AssertFlag(() => new ChannelPermissions(readMessageHistory: true), ChannelPermission.ReadMessageHistory); + AssertFlag(() => new ChannelPermissions(mentionEveryone: true), ChannelPermission.MentionEveryone); + AssertFlag(() => new ChannelPermissions(useExternalEmojis: true), ChannelPermission.UseExternalEmojis); + AssertFlag(() => new ChannelPermissions(connect: true), ChannelPermission.Connect); + AssertFlag(() => new ChannelPermissions(speak: true), ChannelPermission.Speak); + AssertFlag(() => new ChannelPermissions(muteMembers: true), ChannelPermission.MuteMembers); + AssertFlag(() => new ChannelPermissions(deafenMembers: true), ChannelPermission.DeafenMembers); + AssertFlag(() => new ChannelPermissions(moveMembers: true), ChannelPermission.MoveMembers); + AssertFlag(() => new ChannelPermissions(useVoiceActivation: true), ChannelPermission.UseVAD); + AssertFlag(() => new ChannelPermissions(prioritySpeaker: true), ChannelPermission.PrioritySpeaker); + AssertFlag(() => new ChannelPermissions(manageRoles: true), ChannelPermission.ManageRoles); + AssertFlag(() => new ChannelPermissions(manageWebhooks: true), ChannelPermission.ManageWebhooks); + } + + /// + /// Tests the behavior of + /// with each of the parameters. + /// + [Fact] + public void Modify() + { + // asserts that a channel permission flag value can be checked + // and that modify can set and unset each flag + // and that ToList performs as expected + void AssertUtil(ChannelPermission permission, + Func has, + Func modify) + { + var perm = new ChannelPermissions(); + // ensure permission initially false + // use both the function and Has to ensure that the GetPermission + // function is working + Assert.False(has(perm)); + Assert.False(perm.Has(permission)); + + // enable it, and ensure that it gets set + perm = modify(perm, true); + Assert.True(has(perm)); + Assert.True(perm.Has(permission)); + + // check ToList behavior + var list = perm.ToList(); + Assert.Contains(permission, list); + Assert.Single(list); + + // set it false again + perm = modify(perm, false); + Assert.False(has(perm)); + Assert.False(perm.Has(permission)); + + // ensure that no perms are set now + Assert.Equal(ChannelPermissions.None.RawValue, perm.RawValue); + } + + AssertUtil(ChannelPermission.CreateInstantInvite, x => x.CreateInstantInvite, (p, enable) => p.Modify(createInstantInvite: enable)); + AssertUtil(ChannelPermission.ManageChannels, x => x.ManageChannel, (p, enable) => p.Modify(manageChannel: enable)); + AssertUtil(ChannelPermission.AddReactions, x => x.AddReactions, (p, enable) => p.Modify(addReactions: enable)); + AssertUtil(ChannelPermission.ViewChannel, x => x.ViewChannel, (p, enable) => p.Modify(viewChannel: enable)); + AssertUtil(ChannelPermission.SendMessages, x => x.SendMessages, (p, enable) => p.Modify(sendMessages: enable)); + AssertUtil(ChannelPermission.SendTTSMessages, x => x.SendTTSMessages, (p, enable) => p.Modify(sendTTSMessages: enable)); + AssertUtil(ChannelPermission.ManageMessages, x => x.ManageMessages, (p, enable) => p.Modify(manageMessages: enable)); + AssertUtil(ChannelPermission.EmbedLinks, x => x.EmbedLinks, (p, enable) => p.Modify(embedLinks: enable)); + AssertUtil(ChannelPermission.AttachFiles, x => x.AttachFiles, (p, enable) => p.Modify(attachFiles: enable)); + AssertUtil(ChannelPermission.ReadMessageHistory, x => x.ReadMessageHistory, (p, enable) => p.Modify(readMessageHistory: enable)); + AssertUtil(ChannelPermission.MentionEveryone, x => x.MentionEveryone, (p, enable) => p.Modify(mentionEveryone: enable)); + AssertUtil(ChannelPermission.UseExternalEmojis, x => x.UseExternalEmojis, (p, enable) => p.Modify(useExternalEmojis: enable)); + AssertUtil(ChannelPermission.Connect, x => x.Connect, (p, enable) => p.Modify(connect: enable)); + AssertUtil(ChannelPermission.Speak, x => x.Speak, (p, enable) => p.Modify(speak: enable)); + AssertUtil(ChannelPermission.MuteMembers, x => x.MuteMembers, (p, enable) => p.Modify(muteMembers: enable)); + AssertUtil(ChannelPermission.DeafenMembers, x => x.DeafenMembers, (p, enable) => p.Modify(deafenMembers: enable)); + AssertUtil(ChannelPermission.MoveMembers, x => x.MoveMembers, (p, enable) => p.Modify(moveMembers: enable)); + AssertUtil(ChannelPermission.UseVAD, x => x.UseVAD, (p, enable) => p.Modify(useVoiceActivation: enable)); + AssertUtil(ChannelPermission.ManageRoles, x => x.ManageRoles, (p, enable) => p.Modify(manageRoles: enable)); + AssertUtil(ChannelPermission.ManageWebhooks, x => x.ManageWebhooks, (p, enable) => p.Modify(manageWebhooks: enable)); + AssertUtil(ChannelPermission.PrioritySpeaker, x => x.PrioritySpeaker, (p, enable) => p.Modify(prioritySpeaker: enable)); + } + + /// + /// Tests that for a null channel will throw an . + /// + [Fact] + public void ChannelTypeResolution_Null() + { + Assert.Throws(() => + { + ChannelPermissions.All(null); + }); + } + + /// + /// Tests that for an will return a value + /// equivalent to . + /// + [Fact] + public void ChannelTypeResolution_Text() + { + Assert.Equal(ChannelPermissions.Text.RawValue, ChannelPermissions.All(new MockedTextChannel()).RawValue); + } + + /// + /// Tests that for an will return a value + /// equivalent to . + /// + [Fact] + public void ChannelTypeResolution_Voice() + { + Assert.Equal(ChannelPermissions.Voice.RawValue, ChannelPermissions.All(new MockedVoiceChannel()).RawValue); + } + + /// + /// Tests that for an will return a value + /// equivalent to . + /// + [Fact] + public void ChannelTypeResolution_Category() + { + Assert.Equal(ChannelPermissions.Category.RawValue, ChannelPermissions.All(new MockedCategoryChannel()).RawValue); + } + + /// + /// Tests that for an will return a value + /// equivalent to . + /// + [Fact] + public void ChannelTypeResolution_DM() + { + Assert.Equal(ChannelPermissions.DM.RawValue, ChannelPermissions.All(new MockedDMChannel()).RawValue); + } + + /// + /// Tests that for an will return a value + /// equivalent to . + /// + [Fact] + public void ChannelTypeResolution_Group() + { + Assert.Equal(ChannelPermissions.Group.RawValue, ChannelPermissions.All(new MockedGroupChannel()).RawValue); + } + + /// + /// Tests that for an invalid channel will throw an . + /// + [Fact] + public void ChannelTypeResolution_Invalid() + { + Assert.Throws(() => ChannelPermissions.All(new MockedInvalidChannel())); + } + } +} diff --git a/test/Discord.Net.Tests/Tests.Colors.cs b/test/Discord.Net.Tests.Unit/ColorTests.cs similarity index 96% rename from test/Discord.Net.Tests/Tests.Colors.cs rename to test/Discord.Net.Tests.Unit/ColorTests.cs index 10b0bbdac..87c76e4e2 100644 --- a/test/Discord.Net.Tests/Tests.Colors.cs +++ b/test/Discord.Net.Tests.Unit/ColorTests.cs @@ -1,8 +1,13 @@ using System; +using System.Collections.Generic; +using System.Text; using Xunit; namespace Discord { + /// + /// Tests for the type. + /// public class ColorTests { [Fact] diff --git a/test/Discord.Net.Tests.Unit/Discord.Net.Tests.Unit.csproj b/test/Discord.Net.Tests.Unit/Discord.Net.Tests.Unit.csproj new file mode 100644 index 000000000..4a7898b14 --- /dev/null +++ b/test/Discord.Net.Tests.Unit/Discord.Net.Tests.Unit.csproj @@ -0,0 +1,21 @@ + + + + netcoreapp2.1 + + false + + + + + + + + + + + + + + + diff --git a/test/Discord.Net.Tests.Unit/EmbedBuilderTests.cs b/test/Discord.Net.Tests.Unit/EmbedBuilderTests.cs new file mode 100644 index 000000000..1623d94f2 --- /dev/null +++ b/test/Discord.Net.Tests.Unit/EmbedBuilderTests.cs @@ -0,0 +1,467 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Xunit; + +namespace Discord +{ + /// + /// Tests the class. + /// + public class EmbedBuilderTests + { + private const string name = "chrisj"; + private const string icon = "https://meowpuffygottem.fun/blob.png"; + private const string url = "https://meowpuffygottem.fun/"; + + /// + /// Tests the behavior of . + /// + [Fact] + public void WithAuthor_Strings() + { + var builder = new EmbedBuilder(); + // null by default + Assert.Null(builder.Author); + + builder = new EmbedBuilder() + .WithAuthor(name, icon, url); + + Assert.NotNull(builder.Author); + Assert.Equal(name, builder.Author.Name); + Assert.Equal(icon, builder.Author.IconUrl); + Assert.Equal(url, builder.Author.Url); + } + + /// + /// Tests the behavior of + /// + [Fact] + public void WithAuthor_AuthorBuilder() + { + var author = new EmbedAuthorBuilder() + .WithIconUrl(icon) + .WithName(name) + .WithUrl(url); + var builder = new EmbedBuilder() + .WithAuthor(author); + Assert.NotNull(builder.Author); + Assert.Equal(name, builder.Author.Name); + Assert.Equal(icon, builder.Author.IconUrl); + Assert.Equal(url, builder.Author.Url); + } + + /// + /// Tests the behavior of + /// + [Fact] + public void WithAuthor_ActionAuthorBuilder() + { + var builder = new EmbedBuilder() + .WithAuthor((author) => + author.WithIconUrl(icon) + .WithName(name) + .WithUrl(url)); + Assert.NotNull(builder.Author); + Assert.Equal(name, builder.Author.Name); + Assert.Equal(icon, builder.Author.IconUrl); + Assert.Equal(url, builder.Author.Url); + } + + /// + /// Tests the behavior of . + /// + [Fact] + public void EmbedAuthorBuilder() + { + var builder = new EmbedAuthorBuilder() + .WithIconUrl(icon) + .WithName(name) + .WithUrl(url); + Assert.Equal(icon, builder.IconUrl); + Assert.Equal(name, builder.Name); + Assert.Equal(url, builder.Url); + } + + /// + /// Tests that invalid titles throw an . + /// + /// The embed title to set. + [Theory] + // 257 chars + [InlineData("jVyLChmA7aBZozXQuZ3VDEcwW6zOq0nteOVYBZi31ny73rpXfSSBXR4Jw6FiplDKQseKskwRMuBZkUewrewqAbkBZpslHirvC5nEzRySoDIdTRnkVvTXZUXg75l3bQCjuuHxDd6DfrY8ihd6yZX1Y0XFeg239YBcYV4TpL9uQ8H3HFYxrWhLlG2PRVjUmiglP5iXkawszNwMVm1SZ5LZT4jkMZHxFegVi7170d16iaPWOovu50aDDHy087XBtLKVa")] + // 257 chars of whitespace + [InlineData(" ")] + public void Title_Invalid(string title) + { + Assert.Throws(() => + { + var builder = new EmbedBuilder(); + builder.Title = title; + }); + Assert.Throws(() => + { + new EmbedBuilder().WithTitle(title); + }); + } + + /// + /// Tests that valid titles do not throw any exceptions. + /// + /// The embed title to set. + [Theory] + // 256 chars + [InlineData("jVyLChmA7aBZozXQuZ3VDEcwW6zOq0nteOVYBZi31ny73rpXfSSBXR4Jw6FiplDKQseKskwRMuBZkUewrewqAbkBZpslHirvC5nEzRySoDIdTRnkVvTXZUXg75l3bQCjuuHxDd6DfrY8ihd6yZX1Y0XFeg239YBcYV4TpL9uQ8H3HFYxrWhLlG2PRVjUmiglP5iXkawszNwMVm1SZ5LZT4jkMZHxFegVi7170d16iaPWOovu50aDDHy087XBtLKV")] + public void Tile_Valid(string title) + { + var builder = new EmbedBuilder(); + builder.Title = title; + new EmbedBuilder().WithTitle(title); + } + + /// + /// Tests that invalid descriptions throw an . + /// + [Fact] + public void Description_Invalid() + { + IEnumerable GetInvalid() + { + yield return new string('a', 2049); + } + foreach (var description in GetInvalid()) + { + Assert.Throws(() => new EmbedBuilder().WithDescription(description)); + Assert.Throws(() => + { + var b = new EmbedBuilder(); + b.Description = description; + }); + } + } + + /// + /// Tests that valid descriptions do not throw any exceptions. + /// + [Fact] + public void Description_Valid() + { + IEnumerable GetValid() + { + yield return string.Empty; + yield return null; + yield return new string('a', 2048); + } + foreach (var description in GetValid()) + { + var b = new EmbedBuilder().WithDescription(description); + Assert.Equal(description, b.Description); + + b = new EmbedBuilder(); + b.Description = description; + Assert.Equal(description, b.Description); + } + } + + /// + /// Tests that valid urls do not throw any exceptions. + /// + /// The url to set. + [Theory] + [InlineData(null)] + [InlineData("")] + [InlineData("https://docs.stillu.cc")] + public void Url_Valid(string url) + { + // does not throw an exception + var result = new EmbedBuilder() + .WithUrl(url) + .WithImageUrl(url) + .WithThumbnailUrl(url); + Assert.Equal(result.Url, url); + Assert.Equal(result.ImageUrl, url); + Assert.Equal(result.ThumbnailUrl, url); + + result = new EmbedBuilder(); + result.Url = url; + result.ImageUrl = url; + result.ThumbnailUrl = url; + Assert.Equal(result.Url, url); + Assert.Equal(result.ImageUrl, url); + Assert.Equal(result.ThumbnailUrl, url); + } + + /// + /// Tests that invalid urls throw an . + /// + /// The url to set. + [Theory] + [InlineData(" ")] + [InlineData("not a url")] + public void Url_Invalid(string url) + { + Assert.Throws(() + => new EmbedBuilder() + .WithUrl(url)); + Assert.Throws(() + => new EmbedBuilder() + .WithImageUrl(url)); + Assert.Throws(() + => new EmbedBuilder() + .WithThumbnailUrl(url)); + + Assert.Throws(() => + { + var b = new EmbedBuilder(); + b.Url = url; + }); + Assert.Throws(() => + { + var b = new EmbedBuilder(); + b.ImageUrl = url; + }); + Assert.Throws(() => + { + var b = new EmbedBuilder(); + b.ThumbnailUrl = url; + }); + } + + /// + /// Tests the value of the property when there are no fields set. + /// + [Fact] + public void Length_Empty() + { + var empty = new EmbedBuilder(); + Assert.Equal(0, empty.Length); + } + + /// + /// Tests the value of the property when all fields are set. + /// + [Fact] + public void Length() + { + var e = new EmbedBuilder() + .WithAuthor(name, icon, url) + .WithColor(Color.Blue) + .WithDescription("This is the test description.") + .WithFooter("This is the footer", url) + .WithImageUrl(url) + .WithThumbnailUrl(url) + .WithTimestamp(DateTime.MinValue) + .WithTitle("This is the title") + .WithUrl(url) + .AddField("Field 1", "Inline", true) + .AddField("Field 2", "Not Inline", false); + Assert.Equal(100, e.Length); + } + + /// + /// Tests the behavior of . + /// + [Fact] + public void WithCurrentTimestamp() + { + var e = new EmbedBuilder() + .WithCurrentTimestamp(); + // ensure within a second of accuracy + Assert.Equal(DateTime.UtcNow, e.Timestamp.Value.UtcDateTime, TimeSpan.FromSeconds(1)); + } + + /// + /// Tests the behavior of . + /// + [Fact] + public void WithColor() + { + // use WithColor + var e = new EmbedBuilder().WithColor(Color.Red); + Assert.Equal(Color.Red.RawValue, e.Color.Value.RawValue); + } + + /// + /// Tests the behavior of + /// + [Fact] + public void WithFooter_ActionFooterBuilder() + { + var e = new EmbedBuilder() + .WithFooter(x => + { + x.IconUrl = url; + x.Text = name; + }); + Assert.Equal(url, e.Footer.IconUrl); + Assert.Equal(name, e.Footer.Text); + } + + /// + /// Tests the behavior of + /// + [Fact] + public void WithFooter_FooterBuilder() + { + var footer = new EmbedFooterBuilder() + { + IconUrl = url, + Text = name + }; + var e = new EmbedBuilder() + .WithFooter(footer); + Assert.Equal(url, e.Footer.IconUrl); + Assert.Equal(name, e.Footer.Text); + // use the property + e = new EmbedBuilder(); + e.Footer = footer; + Assert.Equal(url, e.Footer.IconUrl); + Assert.Equal(name, e.Footer.Text); + } + + /// + /// Tests the behavior of + /// + [Fact] + public void WithFooter_Strings() + { + var e = new EmbedBuilder() + .WithFooter(name, url); + Assert.Equal(url, e.Footer.IconUrl); + Assert.Equal(name, e.Footer.Text); + } + + /// + /// Tests the behavior of . + /// + [Fact] + public void EmbedFooterBuilder() + { + var footer = new EmbedFooterBuilder() + .WithIconUrl(url) + .WithText(name); + Assert.Equal(url, footer.IconUrl); + Assert.Equal(name, footer.Text); + } + /// + /// Tests that invalid URLs throw an . + /// + [Fact] + public void EmbedFooterBuilder_InvalidURL() + { + IEnumerable InvalidUrls() + { + yield return "not a url"; + } + foreach (var url in InvalidUrls()) + { + Assert.Throws(() => + { + new EmbedFooterBuilder().WithIconUrl(url); + }); + } + } + /// + /// Tests that invalid text throws an . + /// + [Fact] + public void EmbedFooterBuilder_InvalidText() + { + Assert.Throws(() => + { + new EmbedFooterBuilder().WithText(new string('a', 2049)); + }); + } + [Fact] + public void AddField_Strings() + { + var e = new EmbedBuilder() + .AddField("name", "value", true); + Assert.Equal("name", e.Fields[0].Name); + Assert.Equal("value", e.Fields[0].Value); + Assert.True(e.Fields[0].IsInline); + } + [Fact] + public void AddField_EmbedFieldBuilder() + { + var field = new EmbedFieldBuilder() + .WithIsInline(true) + .WithValue("value") + .WithName("name"); + var e = new EmbedBuilder() + .AddField(field); + Assert.Equal("name", e.Fields[0].Name); + Assert.Equal("value", e.Fields[0].Value); + Assert.True(e.Fields[0].IsInline); + } + [Fact] + public void AddField_ActionEmbedFieldBuilder() + { + var e = new EmbedBuilder() + .AddField(x => x + .WithName("name") + .WithValue("value") + .WithIsInline(true)); + Assert.Equal("name", e.Fields[0].Name); + Assert.Equal("value", e.Fields[0].Value); + Assert.True(e.Fields[0].IsInline); + } + [Fact] + public void AddField_TooManyFields() + { + var e = new EmbedBuilder(); + for (var i = 0; i < 25; i++) + { + e = e.AddField("name", "value", false); + } + Assert.Throws(() => + { + e = e.AddField("name", "value", false); + }); + } + [Fact] + public void EmbedFieldBuilder() + { + var e = new EmbedFieldBuilder() + .WithIsInline(true) + .WithName("name") + .WithValue("value"); + Assert.Equal("name", e.Name); + Assert.Equal("value", e.Value); + Assert.True(e.IsInline); + // use the properties + e = new EmbedFieldBuilder(); + e.IsInline = true; + e.Name = "name"; + e.Value = "value"; + Assert.Equal("name", e.Name); + Assert.Equal("value", e.Value); + Assert.True(e.IsInline); + } + [Theory] + [InlineData("")] + [InlineData(" ")] + [InlineData(null)] + // 257 chars + [InlineData("jVyLChmA7aBZozXQuZ3VDEcwW6zOq0nteOVYBZi31ny73rpXfSSBXR4Jw6FiplDKQseKskwRMuBZkUewrewqAbkBZpslHirvC5nEzRySoDIdTRnkVvTXZUXg75l3bQCjuuHxDd6DfrY8ihd6yZX1Y0XFeg239YBcYV4TpL9uQ8H3HFYxrWhLlG2PRVjUmiglP5iXkawszNwMVm1SZ5LZT4jkMZHxFegVi7170d16iaPWOovu50aDDHy087XBtLKVa")] + // 257 chars of whitespace + [InlineData(" ")] + public void EmbedFieldBuilder_InvalidName(string name) + { + Assert.Throws(() => new EmbedFieldBuilder().WithName(name)); + } + [Fact] + public void EmbedFieldBuilder_InvalidValue() + { + IEnumerable GetInvalidValue() + { + yield return null; + yield return string.Empty; + yield return " "; + yield return new string('a', 1025); + }; + foreach (var v in GetInvalidValue()) + Assert.Throws(() => new EmbedFieldBuilder().WithValue(v)); + } + } +} diff --git a/test/Discord.Net.Tests/Tests.Emotes.cs b/test/Discord.Net.Tests.Unit/EmoteTests.cs similarity index 97% rename from test/Discord.Net.Tests/Tests.Emotes.cs rename to test/Discord.Net.Tests.Unit/EmoteTests.cs index eeadbddf8..a4f44170a 100644 --- a/test/Discord.Net.Tests/Tests.Emotes.cs +++ b/test/Discord.Net.Tests.Unit/EmoteTests.cs @@ -1,4 +1,6 @@ using System; +using System.Collections.Generic; +using System.Text; using Xunit; namespace Discord diff --git a/test/Discord.Net.Tests.Unit/FormatTests.cs b/test/Discord.Net.Tests.Unit/FormatTests.cs new file mode 100644 index 000000000..d5ab82362 --- /dev/null +++ b/test/Discord.Net.Tests.Unit/FormatTests.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Xunit; + +namespace Discord +{ + public class FormatTests + { + [Theory] + [InlineData("@everyone", "@everyone")] + [InlineData(@"\", @"\\")] + [InlineData(@"*text*", @"\*text\*")] + [InlineData(@"~text~", @"\~text\~")] + [InlineData(@"`text`", @"\`text\`")] + [InlineData(@"_text_", @"\_text\_")] + public void Sanitize(string input, string expected) + { + Assert.Equal(expected, Format.Sanitize(input)); + } + [Fact] + public void Code() + { + // no language + Assert.Equal("`test`", Format.Code("test")); + Assert.Equal("```\nanother\none\n```", Format.Code("another\none")); + // language specified + Assert.Equal("```cs\ntest\n```", Format.Code("test", "cs")); + Assert.Equal("```cs\nanother\none\n```", Format.Code("another\none", "cs")); + } + } +} diff --git a/test/Discord.Net.Tests.Unit/GuildPermissionsTests.cs b/test/Discord.Net.Tests.Unit/GuildPermissionsTests.cs new file mode 100644 index 000000000..8213a8974 --- /dev/null +++ b/test/Discord.Net.Tests.Unit/GuildPermissionsTests.cs @@ -0,0 +1,164 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Xunit; + +namespace Discord +{ + /// + /// Tests the behavior of the type and related functions. + /// + public class GuildPermissionsTests + { + /// + /// Tests the default value of the constructor. + /// + [Fact] + public void DefaultConstructor() + { + var p = new GuildPermissions(); + Assert.Equal((ulong)0, p.RawValue); + Assert.Equal(GuildPermissions.None.RawValue, p.RawValue); + } + + /// + /// Tests the behavior of the raw value constructor. + /// + [Fact] + public void RawValueConstructor() + { + // returns all of the values that will be tested + // a Theory cannot be used here, because these values are not all constants + IEnumerable GetTestValues() + { + yield return 0; + yield return GuildPermissions.None.RawValue; + yield return GuildPermissions.All.RawValue; + yield return GuildPermissions.Webhook.RawValue; + }; + + foreach (var rawValue in GetTestValues()) + { + var p = new GuildPermissions(rawValue); + Assert.Equal(rawValue, p.RawValue); + } + } + + /// + /// Tests the behavior of the constructor for each + /// of it's flags. + /// + [Fact] + public void FlagsConstructor() + { + // util method for asserting that the constructor sets the given flag + void AssertFlag(Func cstr, GuildPermission flag) + { + var p = cstr(); + // ensure flag set to true + Assert.True(p.Has(flag)); + // ensure only this flag is set + Assert.Equal((ulong)flag, p.RawValue); + } + + AssertFlag(() => new GuildPermissions(createInstantInvite: true), GuildPermission.CreateInstantInvite); + AssertFlag(() => new GuildPermissions(kickMembers: true), GuildPermission.KickMembers); + AssertFlag(() => new GuildPermissions(banMembers: true), GuildPermission.BanMembers); + AssertFlag(() => new GuildPermissions(administrator: true), GuildPermission.Administrator); + AssertFlag(() => new GuildPermissions(manageChannels: true), GuildPermission.ManageChannels); + AssertFlag(() => new GuildPermissions(manageGuild: true), GuildPermission.ManageGuild); + AssertFlag(() => new GuildPermissions(addReactions: true), GuildPermission.AddReactions); + AssertFlag(() => new GuildPermissions(viewAuditLog: true), GuildPermission.ViewAuditLog); + AssertFlag(() => new GuildPermissions(viewChannel: true), GuildPermission.ViewChannel); + AssertFlag(() => new GuildPermissions(sendMessages: true), GuildPermission.SendMessages); + AssertFlag(() => new GuildPermissions(sendTTSMessages: true), GuildPermission.SendTTSMessages); + AssertFlag(() => new GuildPermissions(manageMessages: true), GuildPermission.ManageMessages); + AssertFlag(() => new GuildPermissions(embedLinks: true), GuildPermission.EmbedLinks); + AssertFlag(() => new GuildPermissions(attachFiles: true), GuildPermission.AttachFiles); + AssertFlag(() => new GuildPermissions(readMessageHistory: true), GuildPermission.ReadMessageHistory); + AssertFlag(() => new GuildPermissions(mentionEveryone: true), GuildPermission.MentionEveryone); + AssertFlag(() => new GuildPermissions(useExternalEmojis: true), GuildPermission.UseExternalEmojis); + AssertFlag(() => new GuildPermissions(connect: true), GuildPermission.Connect); + AssertFlag(() => new GuildPermissions(speak: true), GuildPermission.Speak); + AssertFlag(() => new GuildPermissions(muteMembers: true), GuildPermission.MuteMembers); + AssertFlag(() => new GuildPermissions(deafenMembers: true), GuildPermission.DeafenMembers); + AssertFlag(() => new GuildPermissions(moveMembers: true), GuildPermission.MoveMembers); + AssertFlag(() => new GuildPermissions(useVoiceActivation: true), GuildPermission.UseVAD); + AssertFlag(() => new GuildPermissions(prioritySpeaker: true), GuildPermission.PrioritySpeaker); + AssertFlag(() => new GuildPermissions(changeNickname: true), GuildPermission.ChangeNickname); + AssertFlag(() => new GuildPermissions(manageNicknames: true), GuildPermission.ManageNicknames); + AssertFlag(() => new GuildPermissions(manageRoles: true), GuildPermission.ManageRoles); + AssertFlag(() => new GuildPermissions(manageWebhooks: true), GuildPermission.ManageWebhooks); + AssertFlag(() => new GuildPermissions(manageEmojis: true), GuildPermission.ManageEmojis); + } + + /// + /// Tests the behavior of + /// with each of the parameters. + /// + [Fact] + public void Modify() + { + // asserts that flag values can be checked + // and that flag values can be toggled on and off + // and that the behavior of ToList works as expected + void AssertUtil(GuildPermission permission, + Func has, + Func modify) + { + var perm = new GuildPermissions(); + // ensure permission initially false + // use both the function and Has to ensure that the GetPermission + // function is working + Assert.False(has(perm)); + Assert.False(perm.Has(permission)); + + // enable it, and ensure that it gets set + perm = modify(perm, true); + Assert.True(has(perm)); + Assert.True(perm.Has(permission)); + + // check ToList behavior + var list = perm.ToList(); + Assert.Contains(permission, list); + Assert.Single(list); + + // set it false again + perm = modify(perm, false); + Assert.False(has(perm)); + Assert.False(perm.Has(permission)); + + // ensure that no perms are set now + Assert.Equal(GuildPermissions.None.RawValue, perm.RawValue); + } + + AssertUtil(GuildPermission.CreateInstantInvite, x => x.CreateInstantInvite, (p, enable) => p.Modify(createInstantInvite: enable)); + AssertUtil(GuildPermission.KickMembers, x => x.KickMembers, (p, enable) => p.Modify(kickMembers: enable)); + AssertUtil(GuildPermission.BanMembers, x => x.BanMembers, (p, enable) => p.Modify(banMembers: enable)); + AssertUtil(GuildPermission.Administrator, x => x.Administrator, (p, enable) => p.Modify(administrator: enable)); + AssertUtil(GuildPermission.ManageChannels, x => x.ManageChannels, (p, enable) => p.Modify(manageChannels: enable)); + AssertUtil(GuildPermission.ManageGuild, x => x.ManageGuild, (p, enable) => p.Modify(manageGuild: enable)); + AssertUtil(GuildPermission.AddReactions, x => x.AddReactions, (p, enable) => p.Modify(addReactions: enable)); + AssertUtil(GuildPermission.ViewAuditLog, x => x.ViewAuditLog, (p, enable) => p.Modify(viewAuditLog: enable)); + AssertUtil(GuildPermission.ViewChannel, x => x.ViewChannel, (p, enable) => p.Modify(viewChannel: enable)); + AssertUtil(GuildPermission.SendMessages, x => x.SendMessages, (p, enable) => p.Modify(sendMessages: enable)); + AssertUtil(GuildPermission.SendTTSMessages, x => x.SendTTSMessages, (p, enable) => p.Modify(sendTTSMessages: enable)); + AssertUtil(GuildPermission.ManageMessages, x => x.ManageMessages, (p, enable) => p.Modify(manageMessages: enable)); + AssertUtil(GuildPermission.EmbedLinks, x => x.EmbedLinks, (p, enable) => p.Modify(embedLinks: enable)); + AssertUtil(GuildPermission.AttachFiles, x => x.AttachFiles, (p, enable) => p.Modify(attachFiles: enable)); + AssertUtil(GuildPermission.ReadMessageHistory, x => x.ReadMessageHistory, (p, enable) => p.Modify(readMessageHistory: enable)); + AssertUtil(GuildPermission.MentionEveryone, x => x.MentionEveryone, (p, enable) => p.Modify(mentionEveryone: enable)); + AssertUtil(GuildPermission.UseExternalEmojis, x => x.UseExternalEmojis, (p, enable) => p.Modify(useExternalEmojis: enable)); + AssertUtil(GuildPermission.Connect, x => x.Connect, (p, enable) => p.Modify(connect: enable)); + AssertUtil(GuildPermission.Speak, x => x.Speak, (p, enable) => p.Modify(speak: enable)); + AssertUtil(GuildPermission.MuteMembers, x => x.MuteMembers, (p, enable) => p.Modify(muteMembers: enable)); + AssertUtil(GuildPermission.MoveMembers, x => x.MoveMembers, (p, enable) => p.Modify(moveMembers: enable)); + AssertUtil(GuildPermission.UseVAD, x => x.UseVAD, (p, enable) => p.Modify(useVoiceActivation: enable)); + AssertUtil(GuildPermission.ChangeNickname, x => x.ChangeNickname, (p, enable) => p.Modify(changeNickname: enable)); + AssertUtil(GuildPermission.ManageNicknames, x => x.ManageNicknames, (p, enable) => p.Modify(manageNicknames: enable)); + AssertUtil(GuildPermission.ManageRoles, x => x.ManageRoles, (p, enable) => p.Modify(manageRoles: enable)); + AssertUtil(GuildPermission.ManageWebhooks, x => x.ManageWebhooks, (p, enable) => p.Modify(manageWebhooks: enable)); + AssertUtil(GuildPermission.ManageEmojis, x => x.ManageEmojis, (p, enable) => p.Modify(manageEmojis: enable)); + } + } +} diff --git a/test/Discord.Net.Tests.Unit/MentionUtilsTests.cs b/test/Discord.Net.Tests.Unit/MentionUtilsTests.cs new file mode 100644 index 000000000..52f35fd9c --- /dev/null +++ b/test/Discord.Net.Tests.Unit/MentionUtilsTests.cs @@ -0,0 +1,128 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Xunit; + +namespace Discord +{ + /// + /// Tests the methods provided in . + /// + public class MentionUtilsTests + { + /// + /// Tests + /// + [Fact] + public void MentionUser() + { + Assert.Equal("<@!123>", MentionUtils.MentionUser(123u)); + Assert.Equal("<@!123>", MentionUtils.MentionUser("123")); + Assert.Equal("<@!123>", MentionUtils.MentionUser("123", true)); + Assert.Equal("<@123>", MentionUtils.MentionUser("123", false)); + } + /// + /// Tests + /// + [Fact] + public void MentionChannel() + { + Assert.Equal("<#123>", MentionUtils.MentionChannel(123u)); + Assert.Equal("<#123>", MentionUtils.MentionChannel("123")); + } + /// + /// Tests + /// + [Fact] + public void MentionRole() + { + Assert.Equal("<@&123>", MentionUtils.MentionRole(123u)); + Assert.Equal("<@&123>", MentionUtils.MentionRole("123")); + } + [Theory] + [InlineData("<@!123>", 123)] + [InlineData("<@123>", 123)] + public void ParseUser_Pass(string user, ulong id) + { + var parsed = MentionUtils.ParseUser(user); + Assert.Equal(id, parsed); + + // also check tryparse + ulong result; + Assert.True(MentionUtils.TryParseUser(user, out result)); + Assert.Equal(id, result); + } + [Theory] + [InlineData(" ")] + [InlineData("invalid")] + [InlineData("<12!3@>")] + [InlineData("<123>")] + public void ParseUser_Fail(string user) + { + Assert.Throws(() => MentionUtils.ParseUser(user)); + Assert.False(MentionUtils.TryParseUser(user, out _)); + } + [Fact] + public void ParseUser_Null() + { + Assert.Throws(() => MentionUtils.ParseUser(null)); + Assert.Throws(() => MentionUtils.TryParseUser(null, out _)); + } + [Theory] + [InlineData("<#123>", 123)] + public void ParseChannel_Pass(string channel, ulong id) + { + var parsed = MentionUtils.ParseChannel(channel); + Assert.Equal(id, parsed); + + // also check tryparse + ulong result; + Assert.True(MentionUtils.TryParseChannel(channel, out result)); + Assert.Equal(id, result); + } + [Theory] + [InlineData(" ")] + [InlineData("invalid")] + [InlineData("<12#3>")] + [InlineData("<123>")] + public void ParseChannel_Fail(string channel) + { + Assert.Throws(() => MentionUtils.ParseChannel(channel)); + Assert.False(MentionUtils.TryParseChannel(channel, out _)); + } + [Fact] + public void ParseChannel_Null() + { + Assert.Throws(() => MentionUtils.ParseChannel(null)); + Assert.Throws(() => MentionUtils.TryParseChannel(null, out _)); + } + [Theory] + [InlineData("<@&123>", 123)] + public void ParseRole_Pass(string role, ulong id) + { + var parsed = MentionUtils.ParseRole(role); + Assert.Equal(id, parsed); + + // also check tryparse + ulong result; + Assert.True(MentionUtils.TryParseRole(role, out result)); + Assert.Equal(id, result); + } + [Theory] + [InlineData(" ")] + [InlineData("invalid")] + [InlineData("<12@&3>")] + [InlineData("<123>")] + public void ParseRole_Fail(string role) + { + Assert.Throws(() => MentionUtils.ParseRole(role)); + Assert.False(MentionUtils.TryParseRole(role, out _)); + } + [Fact] + public void ParseRole_Null() + { + Assert.Throws(() => MentionUtils.ParseRole(null)); + Assert.Throws(() => MentionUtils.TryParseRole(null, out _)); + } + } +} diff --git a/test/Discord.Net.Tests.Unit/MockedEntities/MockedCategoryChannel.cs b/test/Discord.Net.Tests.Unit/MockedEntities/MockedCategoryChannel.cs new file mode 100644 index 000000000..712570467 --- /dev/null +++ b/test/Discord.Net.Tests.Unit/MockedEntities/MockedCategoryChannel.cs @@ -0,0 +1,84 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; + +namespace Discord +{ + internal sealed class MockedCategoryChannel : ICategoryChannel + { + public int Position => throw new NotImplementedException(); + + public IGuild Guild => throw new NotImplementedException(); + + public ulong GuildId => throw new NotImplementedException(); + + public IReadOnlyCollection PermissionOverwrites => throw new NotImplementedException(); + + public string Name => throw new NotImplementedException(); + + public DateTimeOffset CreatedAt => throw new NotImplementedException(); + + public ulong Id => throw new NotImplementedException(); + + public Task AddPermissionOverwriteAsync(IRole role, OverwritePermissions permissions, RequestOptions options = null) + { + throw new NotImplementedException(); + } + + public Task AddPermissionOverwriteAsync(IUser user, OverwritePermissions permissions, RequestOptions options = null) + { + throw new NotImplementedException(); + } + + public Task DeleteAsync(RequestOptions options = null) + { + throw new NotImplementedException(); + } + + public OverwritePermissions? GetPermissionOverwrite(IRole role) + { + throw new NotImplementedException(); + } + + public OverwritePermissions? GetPermissionOverwrite(IUser user) + { + throw new NotImplementedException(); + } + + public Task GetUserAsync(ulong id, CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null) + { + throw new NotImplementedException(); + } + + public IAsyncEnumerable> GetUsersAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null) + { + throw new NotImplementedException(); + } + + public Task ModifyAsync(Action func, RequestOptions options = null) + { + throw new NotImplementedException(); + } + + public Task RemovePermissionOverwriteAsync(IRole role, RequestOptions options = null) + { + throw new NotImplementedException(); + } + + public Task RemovePermissionOverwriteAsync(IUser user, RequestOptions options = null) + { + throw new NotImplementedException(); + } + + Task IChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options) + { + throw new NotImplementedException(); + } + + IAsyncEnumerable> IChannel.GetUsersAsync(CacheMode mode, RequestOptions options) + { + throw new NotImplementedException(); + } + } +} diff --git a/test/Discord.Net.Tests.Unit/MockedEntities/MockedDMChannel.cs b/test/Discord.Net.Tests.Unit/MockedEntities/MockedDMChannel.cs new file mode 100644 index 000000000..724bc84ef --- /dev/null +++ b/test/Discord.Net.Tests.Unit/MockedEntities/MockedDMChannel.cs @@ -0,0 +1,96 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; +using System.Threading.Tasks; + +namespace Discord +{ + internal sealed class MockedDMChannel : IDMChannel + { + public IUser Recipient => throw new NotImplementedException(); + + public IReadOnlyCollection Recipients => throw new NotImplementedException(); + + public string Name => throw new NotImplementedException(); + + public DateTimeOffset CreatedAt => throw new NotImplementedException(); + + public ulong Id => throw new NotImplementedException(); + + public Task CloseAsync(RequestOptions options = null) + { + throw new NotImplementedException(); + } + + public Task DeleteMessageAsync(ulong messageId, RequestOptions options = null) + { + throw new NotImplementedException(); + } + + public Task DeleteMessageAsync(IMessage message, RequestOptions options = null) + { + throw new NotImplementedException(); + } + + public IDisposable EnterTypingState(RequestOptions options = null) + { + throw new NotImplementedException(); + } + + public Task GetMessageAsync(ulong id, CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null) + { + throw new NotImplementedException(); + } + + public IAsyncEnumerable> GetMessagesAsync(int limit = 100, CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null) + { + throw new NotImplementedException(); + } + + public IAsyncEnumerable> GetMessagesAsync(ulong fromMessageId, Direction dir, int limit = 100, CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null) + { + throw new NotImplementedException(); + } + + public IAsyncEnumerable> GetMessagesAsync(IMessage fromMessage, Direction dir, int limit = 100, CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null) + { + throw new NotImplementedException(); + } + + public Task> GetPinnedMessagesAsync(RequestOptions options = null) + { + throw new NotImplementedException(); + } + + public Task GetUserAsync(ulong id, CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null) + { + throw new NotImplementedException(); + } + + public IAsyncEnumerable> GetUsersAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null) + { + throw new NotImplementedException(); + } + + public Task SendFileAsync(string filePath, string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false) + { + throw new NotImplementedException(); + } + + public Task SendFileAsync(Stream stream, string filename, string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false) + { + throw new NotImplementedException(); + } + + public Task SendMessageAsync(string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null) + { + throw new NotImplementedException(); + } + + public Task TriggerTypingAsync(RequestOptions options = null) + { + throw new NotImplementedException(); + } + } +} diff --git a/test/Discord.Net.Tests.Unit/MockedEntities/MockedGroupChannel.cs b/test/Discord.Net.Tests.Unit/MockedEntities/MockedGroupChannel.cs new file mode 100644 index 000000000..573ca57c3 --- /dev/null +++ b/test/Discord.Net.Tests.Unit/MockedEntities/MockedGroupChannel.cs @@ -0,0 +1,105 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; +using System.Threading.Tasks; +using Discord.Audio; + +namespace Discord +{ + internal sealed class MockedGroupChannel : IGroupChannel + { + public IReadOnlyCollection Recipients => throw new NotImplementedException(); + + public string Name => throw new NotImplementedException(); + + public DateTimeOffset CreatedAt => throw new NotImplementedException(); + + public ulong Id => throw new NotImplementedException(); + + public Task ConnectAsync(bool selfDeaf = false, bool selfMute = false, bool external = false) + { + throw new NotImplementedException(); + } + + public Task DeleteMessageAsync(ulong messageId, RequestOptions options = null) + { + throw new NotImplementedException(); + } + + public Task DeleteMessageAsync(IMessage message, RequestOptions options = null) + { + throw new NotImplementedException(); + } + + public Task DisconnectAsync() + { + throw new NotImplementedException(); + } + + public IDisposable EnterTypingState(RequestOptions options = null) + { + throw new NotImplementedException(); + } + + public Task GetMessageAsync(ulong id, CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null) + { + throw new NotImplementedException(); + } + + public IAsyncEnumerable> GetMessagesAsync(int limit = 100, CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null) + { + throw new NotImplementedException(); + } + + public IAsyncEnumerable> GetMessagesAsync(ulong fromMessageId, Direction dir, int limit = 100, CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null) + { + throw new NotImplementedException(); + } + + public IAsyncEnumerable> GetMessagesAsync(IMessage fromMessage, Direction dir, int limit = 100, CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null) + { + throw new NotImplementedException(); + } + + public Task> GetPinnedMessagesAsync(RequestOptions options = null) + { + throw new NotImplementedException(); + } + + public Task GetUserAsync(ulong id, CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null) + { + throw new NotImplementedException(); + } + + public IAsyncEnumerable> GetUsersAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null) + { + throw new NotImplementedException(); + } + + public Task LeaveAsync(RequestOptions options = null) + { + throw new NotImplementedException(); + } + + public Task SendFileAsync(string filePath, string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false) + { + throw new NotImplementedException(); + } + + public Task SendFileAsync(Stream stream, string filename, string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false) + { + throw new NotImplementedException(); + } + + public Task SendMessageAsync(string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null) + { + throw new NotImplementedException(); + } + + public Task TriggerTypingAsync(RequestOptions options = null) + { + throw new NotImplementedException(); + } + } +} diff --git a/test/Discord.Net.Tests.Unit/MockedEntities/MockedInvalidChannel.cs b/test/Discord.Net.Tests.Unit/MockedEntities/MockedInvalidChannel.cs new file mode 100644 index 000000000..362eeb979 --- /dev/null +++ b/test/Discord.Net.Tests.Unit/MockedEntities/MockedInvalidChannel.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; + +namespace Discord +{ + /// + /// Represents a channel that is of an unrecognized type. + /// + internal sealed class MockedInvalidChannel : IChannel + { + public string Name => throw new NotImplementedException(); + + public DateTimeOffset CreatedAt => throw new NotImplementedException(); + + public ulong Id => throw new NotImplementedException(); + + public Task GetUserAsync(ulong id, CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null) + { + throw new NotImplementedException(); + } + + public IAsyncEnumerable> GetUsersAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null) + { + throw new NotImplementedException(); + } + } +} diff --git a/test/Discord.Net.Tests.Unit/MockedEntities/MockedTextChannel.cs b/test/Discord.Net.Tests.Unit/MockedEntities/MockedTextChannel.cs new file mode 100644 index 000000000..ca84219fd --- /dev/null +++ b/test/Discord.Net.Tests.Unit/MockedEntities/MockedTextChannel.cs @@ -0,0 +1,205 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; +using System.Threading.Tasks; + +namespace Discord +{ + internal sealed class MockedTextChannel : ITextChannel + { + public bool IsNsfw => throw new NotImplementedException(); + + public string Topic => throw new NotImplementedException(); + + public int SlowModeInterval => throw new NotImplementedException(); + + public string Mention => throw new NotImplementedException(); + + public ulong? CategoryId => throw new NotImplementedException(); + + public int Position => throw new NotImplementedException(); + + public IGuild Guild => throw new NotImplementedException(); + + public ulong GuildId => throw new NotImplementedException(); + + public IReadOnlyCollection PermissionOverwrites => throw new NotImplementedException(); + + public string Name => throw new NotImplementedException(); + + public DateTimeOffset CreatedAt => throw new NotImplementedException(); + + public ulong Id => throw new NotImplementedException(); + + public Task AddPermissionOverwriteAsync(IRole role, OverwritePermissions permissions, RequestOptions options = null) + { + throw new NotImplementedException(); + } + + public Task AddPermissionOverwriteAsync(IUser user, OverwritePermissions permissions, RequestOptions options = null) + { + throw new NotImplementedException(); + } + + public Task CreateInviteAsync(int? maxAge = 86400, int? maxUses = null, bool isTemporary = false, bool isUnique = false, RequestOptions options = null) + { + throw new NotImplementedException(); + } + + public Task CreateWebhookAsync(string name, Stream avatar = null, RequestOptions options = null) + { + throw new NotImplementedException(); + } + + public Task DeleteAsync(RequestOptions options = null) + { + throw new NotImplementedException(); + } + + public Task DeleteMessageAsync(ulong messageId, RequestOptions options = null) + { + throw new NotImplementedException(); + } + + public Task DeleteMessageAsync(IMessage message, RequestOptions options = null) + { + throw new NotImplementedException(); + } + + public Task DeleteMessagesAsync(IEnumerable messages, RequestOptions options = null) + { + throw new NotImplementedException(); + } + + public Task DeleteMessagesAsync(IEnumerable messageIds, RequestOptions options = null) + { + throw new NotImplementedException(); + } + + public IDisposable EnterTypingState(RequestOptions options = null) + { + throw new NotImplementedException(); + } + + public Task GetCategoryAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null) + { + throw new NotImplementedException(); + } + + public Task> GetInvitesAsync(RequestOptions options = null) + { + throw new NotImplementedException(); + } + + public Task GetMessageAsync(ulong id, CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null) + { + throw new NotImplementedException(); + } + + public IAsyncEnumerable> GetMessagesAsync(int limit = 100, CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null) + { + throw new NotImplementedException(); + } + + public IAsyncEnumerable> GetMessagesAsync(ulong fromMessageId, Direction dir, int limit = 100, CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null) + { + throw new NotImplementedException(); + } + + public IAsyncEnumerable> GetMessagesAsync(IMessage fromMessage, Direction dir, int limit = 100, CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null) + { + throw new NotImplementedException(); + } + + public OverwritePermissions? GetPermissionOverwrite(IRole role) + { + throw new NotImplementedException(); + } + + public OverwritePermissions? GetPermissionOverwrite(IUser user) + { + throw new NotImplementedException(); + } + + public Task> GetPinnedMessagesAsync(RequestOptions options = null) + { + throw new NotImplementedException(); + } + + public Task GetUserAsync(ulong id, CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null) + { + throw new NotImplementedException(); + } + + public IAsyncEnumerable> GetUsersAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null) + { + throw new NotImplementedException(); + } + + public Task GetWebhookAsync(ulong id, RequestOptions options = null) + { + throw new NotImplementedException(); + } + + public Task> GetWebhooksAsync(RequestOptions options = null) + { + throw new NotImplementedException(); + } + + public Task ModifyAsync(Action func, RequestOptions options = null) + { + throw new NotImplementedException(); + } + + public Task ModifyAsync(Action func, RequestOptions options = null) + { + throw new NotImplementedException(); + } + + public Task RemovePermissionOverwriteAsync(IRole role, RequestOptions options = null) + { + throw new NotImplementedException(); + } + + public Task RemovePermissionOverwriteAsync(IUser user, RequestOptions options = null) + { + throw new NotImplementedException(); + } + + public Task SendFileAsync(string filePath, string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false) + { + throw new NotImplementedException(); + } + + public Task SendFileAsync(Stream stream, string filename, string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false) + { + throw new NotImplementedException(); + } + + public Task SendMessageAsync(string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null) + { + throw new NotImplementedException(); + } + + public Task SyncPermissionsAsync(RequestOptions options = null) + { + throw new NotImplementedException(); + } + + public Task TriggerTypingAsync(RequestOptions options = null) + { + throw new NotImplementedException(); + } + + Task IChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options) + { + throw new NotImplementedException(); + } + + IAsyncEnumerable> IChannel.GetUsersAsync(CacheMode mode, RequestOptions options) + { + throw new NotImplementedException(); + } + } +} diff --git a/test/Discord.Net.Tests.Unit/MockedEntities/MockedVoiceChannel.cs b/test/Discord.Net.Tests.Unit/MockedEntities/MockedVoiceChannel.cs new file mode 100644 index 000000000..eb617125d --- /dev/null +++ b/test/Discord.Net.Tests.Unit/MockedEntities/MockedVoiceChannel.cs @@ -0,0 +1,126 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; +using Discord.Audio; + +namespace Discord +{ + internal sealed class MockedVoiceChannel : IVoiceChannel + { + public int Bitrate => throw new NotImplementedException(); + + public int? UserLimit => throw new NotImplementedException(); + + public ulong? CategoryId => throw new NotImplementedException(); + + public int Position => throw new NotImplementedException(); + + public IGuild Guild => throw new NotImplementedException(); + + public ulong GuildId => throw new NotImplementedException(); + + public IReadOnlyCollection PermissionOverwrites => throw new NotImplementedException(); + + public string Name => throw new NotImplementedException(); + + public DateTimeOffset CreatedAt => throw new NotImplementedException(); + + public ulong Id => throw new NotImplementedException(); + + public Task AddPermissionOverwriteAsync(IRole role, OverwritePermissions permissions, RequestOptions options = null) + { + throw new NotImplementedException(); + } + + public Task AddPermissionOverwriteAsync(IUser user, OverwritePermissions permissions, RequestOptions options = null) + { + throw new NotImplementedException(); + } + + public Task ConnectAsync(bool selfDeaf = false, bool selfMute = false, bool external = false) + { + throw new NotImplementedException(); + } + + public Task CreateInviteAsync(int? maxAge = 86400, int? maxUses = null, bool isTemporary = false, bool isUnique = false, RequestOptions options = null) + { + throw new NotImplementedException(); + } + + public Task DeleteAsync(RequestOptions options = null) + { + throw new NotImplementedException(); + } + + public Task DisconnectAsync() + { + throw new NotImplementedException(); + } + + public Task GetCategoryAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null) + { + throw new NotImplementedException(); + } + + public Task> GetInvitesAsync(RequestOptions options = null) + { + throw new NotImplementedException(); + } + + public OverwritePermissions? GetPermissionOverwrite(IRole role) + { + throw new NotImplementedException(); + } + + public OverwritePermissions? GetPermissionOverwrite(IUser user) + { + throw new NotImplementedException(); + } + + public Task GetUserAsync(ulong id, CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null) + { + throw new NotImplementedException(); + } + + public IAsyncEnumerable> GetUsersAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null) + { + throw new NotImplementedException(); + } + + public Task ModifyAsync(Action func, RequestOptions options = null) + { + throw new NotImplementedException(); + } + + public Task ModifyAsync(Action func, RequestOptions options = null) + { + throw new NotImplementedException(); + } + + public Task RemovePermissionOverwriteAsync(IRole role, RequestOptions options = null) + { + throw new NotImplementedException(); + } + + public Task RemovePermissionOverwriteAsync(IUser user, RequestOptions options = null) + { + throw new NotImplementedException(); + } + + public Task SyncPermissionsAsync(RequestOptions options = null) + { + throw new NotImplementedException(); + } + + Task IChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options) + { + throw new NotImplementedException(); + } + + IAsyncEnumerable> IChannel.GetUsersAsync(CacheMode mode, RequestOptions options) + { + throw new NotImplementedException(); + } + } +} diff --git a/test/Discord.Net.Tests.Unit/SnowflakeUtilsTests.cs b/test/Discord.Net.Tests.Unit/SnowflakeUtilsTests.cs new file mode 100644 index 000000000..f7cbf9298 --- /dev/null +++ b/test/Discord.Net.Tests.Unit/SnowflakeUtilsTests.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Xunit; + +namespace Discord +{ + public class SnowflakeUtilsTests + { + [Fact] + public void FromSnowflake() + { + // snowflake from a userid + var id = 163184946742034432u; + Assert.Equal(new DateTime(2016, 3, 26, 7, 18, 43), SnowflakeUtils.FromSnowflake(id).UtcDateTime, TimeSpan.FromSeconds(1)); + } + [Fact] + public void ToSnowflake() + { + // most significant digits should match, but least significant digits cannot be determined from here + Assert.Equal(163184946184192000u, SnowflakeUtils.ToSnowflake(new DateTimeOffset(2016, 3, 26, 7, 18, 43, TimeSpan.Zero))); + } + } +} diff --git a/test/Discord.Net.Tests/Tests.TokenUtils.cs b/test/Discord.Net.Tests.Unit/TokenUtilsTests.cs similarity index 77% rename from test/Discord.Net.Tests/Tests.TokenUtils.cs rename to test/Discord.Net.Tests.Unit/TokenUtilsTests.cs index 428323c1d..bbfbfe754 100644 --- a/test/Discord.Net.Tests/Tests.TokenUtils.cs +++ b/test/Discord.Net.Tests.Unit/TokenUtilsTests.cs @@ -5,6 +5,9 @@ using Xunit; namespace Discord { + /// + /// Tests for the methods. + /// public class TokenUtilsTests { /// @@ -18,14 +21,14 @@ namespace Discord [InlineData(" ")] [InlineData(" ")] [InlineData("\t")] - public void TestNullOrWhitespaceToken(string token) + public void NullOrWhitespaceToken(string token) { // an ArgumentNullException should be thrown, regardless of the TokenType Assert.Throws(() => TokenUtils.ValidateToken(TokenType.Bearer, token)); Assert.Throws(() => TokenUtils.ValidateToken(TokenType.Bot, token)); Assert.Throws(() => TokenUtils.ValidateToken(TokenType.Webhook, token)); } - + /// /// Tests the behavior of /// to see that valid Webhook tokens do not throw Exceptions. @@ -39,7 +42,7 @@ namespace Discord [InlineData("6qrZcUqja7812RVdnEKjpzOL4CvHBFG")] // client secret [InlineData("937it3ow87i4ery69876wqire")] - public void TestWebhookTokenDoesNotThrowExceptions(string token) + public void WebhookTokenDoesNotThrowExceptions(string token) { TokenUtils.ValidateToken(TokenType.Webhook, token); } @@ -59,7 +62,7 @@ namespace Discord [InlineData("6qrZcUqja7812RVdnEKjpzOL4CvHBFG")] // client secret [InlineData("937it3ow87i4ery69876wqire")] - public void TestBearerTokenDoesNotThrowExceptions(string token) + public void BearerTokenDoesNotThrowExceptions(string token) { TokenUtils.ValidateToken(TokenType.Bearer, token); } @@ -77,9 +80,7 @@ namespace Discord // 59 char token [InlineData("MTk4NjIyNDgzNDcxOTI1MjQ4.Cl2FMQ.ZnCjm1XVW7vRze4b7Cq4se7kKWs")] [InlineData("MTk4NjIyNDgzNDcxOTI1MjQ4.Cl2FMQ.ZnCjm1XVW7vRze4b7Cq4se7kKWss")] - // simulated token with a very old user id - [InlineData("ODIzNjQ4MDEzNTAxMDcxMzY=.Cl2FMQ.ZnCjm1XVW7vRze4b7Cq4se7kKW")] - public void TestBotTokenDoesNotThrowExceptions(string token) + public void BotTokenDoesNotThrowExceptions(string token) { // This example token is pulled from the Discord Docs // https://discordapp.com/developers/docs/reference#authentication-example-bot-token-authorization-header @@ -112,7 +113,7 @@ namespace Discord [InlineData("This is an invalid token, but it passes the check for string length.")] // valid token, but passed in twice [InlineData("MTk4NjIyNDgzNDcxOTI1MjQ4.Cl2FMQ.ZnCjm1XVW7vRze4b7Cq4se7kKWsMTk4NjIyNDgzNDcxOTI1MjQ4.Cl2FMQ.ZnCjm1XVW7vRze4b7Cq4se7kKWs")] - public void TestBotTokenInvalidThrowsArgumentException(string token) + public void BotTokenInvalidThrowsArgumentException(string token) { Assert.Throws(() => TokenUtils.ValidateToken(TokenType.Bot, token)); } @@ -132,7 +133,7 @@ namespace Discord [InlineData(-1)] [InlineData(4)] [InlineData(7)] - public void TestUnrecognizedTokenType(int type) + public void UnrecognizedTokenType(int type) { Assert.Throws(() => TokenUtils.ValidateToken((TokenType)type, "MTk4NjIyNDgzNDcxOTI1MjQ4.Cl2FMQ.ZnCjm1XVW7vRze4b7Cq4se7kKWs")); @@ -154,7 +155,7 @@ namespace Discord // should not throw an unexpected exception [InlineData("", false)] [InlineData(null, false)] - public void TestCheckBotTokenValidity(string token, bool expected) + public void CheckBotTokenValidity(string token, bool expected) { Assert.Equal(expected, TokenUtils.CheckBotTokenValidity(token)); } @@ -163,16 +164,12 @@ namespace Discord // cannot pass a ulong? as a param in InlineData, so have to have a separate param // indicating if a value is null [InlineData("NDI4NDc3OTQ0MDA5MTk1NTIw", false, 428477944009195520)] - // user id that has base 64 '=' padding - [InlineData("ODIzNjQ4MDEzNTAxMDcxMzY=", false, 82364801350107136)] - // user id that does not have '=' padding, and needs it - [InlineData("ODIzNjQ4MDEzNTAxMDcxMzY", false, 82364801350107136)] // should return null w/o throwing other exceptions [InlineData("", true, 0)] [InlineData(" ", true, 0)] [InlineData(null, true, 0)] [InlineData("these chars aren't allowed @U#)*@#!)*", true, 0)] - public void TestDecodeBase64UserId(string encodedUserId, bool isNull, ulong expectedUserId) + public void DecodeBase64UserId(string encodedUserId, bool isNull, ulong expectedUserId) { var result = TokenUtils.DecodeBase64UserId(encodedUserId); if (isNull) @@ -180,37 +177,5 @@ namespace Discord else Assert.Equal(expectedUserId, result); } - - [Theory] - [InlineData("QQ", "QQ==")] // "A" encoded - [InlineData("QUE", "QUE=")] // "AA" - [InlineData("QUFB", "QUFB")] // "AAA" - [InlineData("QUFBQQ", "QUFBQQ==")] // "AAAA" - [InlineData("QUFBQUFB", "QUFBQUFB")] // "AAAAAA" - // strings that already contain padding will be returned, even if invalid - [InlineData("QUFBQQ==", "QUFBQQ==")] - [InlineData("QUFBQQ=", "QUFBQQ=")] - [InlineData("=", "=")] - public void TestPadBase64String(string input, string expected) - { - Assert.Equal(expected, TokenUtils.PadBase64String(input)); - } - - [Theory] - // no null, empty, or whitespace - [InlineData("", typeof(ArgumentNullException))] - [InlineData(" ", typeof(ArgumentNullException))] - [InlineData("\t", typeof(ArgumentNullException))] - [InlineData(null, typeof(ArgumentNullException))] - // cannot require 3 padding chars - [InlineData("A", typeof(FormatException))] - [InlineData("QUFBQ", typeof(FormatException))] - public void TestPadBase64StringException(string input, Type type) - { - Assert.Throws(type, () => - { - TokenUtils.PadBase64String(input); - }); - } } } diff --git a/test/Discord.Net.Tests.Unit/TypeReaderTests.cs b/test/Discord.Net.Tests.Unit/TypeReaderTests.cs new file mode 100644 index 000000000..59eb3136c --- /dev/null +++ b/test/Discord.Net.Tests.Unit/TypeReaderTests.cs @@ -0,0 +1,142 @@ +using Discord.Commands; +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; +using Xunit; + +namespace Discord +{ + public sealed class TypeReaderTests + { + [Fact] + public async Task TestNamedArgumentReader() + { + using (var commands = new CommandService()) + { + var module = await commands.AddModuleAsync(null); + + Assert.NotNull(module); + Assert.NotEmpty(module.Commands); + + var cmd = module.Commands[0]; + Assert.NotNull(cmd); + Assert.NotEmpty(cmd.Parameters); + + var param = cmd.Parameters[0]; + Assert.NotNull(param); + Assert.True(param.IsRemainder); + + var result = await param.ParseAsync(null, "bar: hello foo: 42"); + Assert.True(result.IsSuccess); + + var m = result.BestMatch as ArgumentType; + Assert.NotNull(m); + Assert.Equal(expected: 42, actual: m.Foo); + Assert.Equal(expected: "hello", actual: m.Bar); + } + } + + [Fact] + public async Task TestQuotedArgumentValue() + { + using (var commands = new CommandService()) + { + var module = await commands.AddModuleAsync(null); + + Assert.NotNull(module); + Assert.NotEmpty(module.Commands); + + var cmd = module.Commands[0]; + Assert.NotNull(cmd); + Assert.NotEmpty(cmd.Parameters); + + var param = cmd.Parameters[0]; + Assert.NotNull(param); + Assert.True(param.IsRemainder); + + var result = await param.ParseAsync(null, "foo: 42 bar: 《hello》"); + Assert.True(result.IsSuccess); + + var m = result.BestMatch as ArgumentType; + Assert.NotNull(m); + Assert.Equal(expected: 42, actual: m.Foo); + Assert.Equal(expected: "hello", actual: m.Bar); + } + } + + [Fact] + public async Task TestNonPatternInput() + { + using (var commands = new CommandService()) + { + var module = await commands.AddModuleAsync(null); + + Assert.NotNull(module); + Assert.NotEmpty(module.Commands); + + var cmd = module.Commands[0]; + Assert.NotNull(cmd); + Assert.NotEmpty(cmd.Parameters); + + var param = cmd.Parameters[0]; + Assert.NotNull(param); + Assert.True(param.IsRemainder); + + var result = await param.ParseAsync(null, "foobar"); + Assert.False(result.IsSuccess); + Assert.Equal(expected: CommandError.Exception, actual: result.Error); + } + } + + [Fact] + public async Task TestMultiple() + { + using (var commands = new CommandService()) + { + var module = await commands.AddModuleAsync(null); + + Assert.NotNull(module); + Assert.NotEmpty(module.Commands); + + var cmd = module.Commands[0]; + Assert.NotNull(cmd); + Assert.NotEmpty(cmd.Parameters); + + var param = cmd.Parameters[0]; + Assert.NotNull(param); + Assert.True(param.IsRemainder); + + var result = await param.ParseAsync(null, "manyints: \"1, 2, 3, 4, 5, 6, 7\""); + Assert.True(result.IsSuccess); + + var m = result.BestMatch as ArgumentType; + Assert.NotNull(m); + Assert.Equal(expected: new int[] { 1, 2, 3, 4, 5, 6, 7 }, actual: m.ManyInts); + } + } + } + + [NamedArgumentType] + public sealed class ArgumentType + { + public int Foo { get; set; } + + [OverrideTypeReader(typeof(CustomTypeReader))] + public string Bar { get; set; } + + public IEnumerable ManyInts { get; set; } + } + + public sealed class CustomTypeReader : TypeReader + { + public override Task ReadAsync(ICommandContext context, string input, IServiceProvider services) + => Task.FromResult(TypeReaderResult.FromSuccess(input)); + } + + public sealed class TestModule : ModuleBase + { + [Command("test")] + public Task TestCommand(ArgumentType arg) => Task.Delay(0); + } +} diff --git a/test/Discord.Net.Tests/Discord.Net.Tests.csproj b/test/Discord.Net.Tests/Discord.Net.Tests.csproj deleted file mode 100644 index d29a728b0..000000000 --- a/test/Discord.Net.Tests/Discord.Net.Tests.csproj +++ /dev/null @@ -1,35 +0,0 @@ - - - Exe - Discord - netcoreapp2.1 - portable - IDISP001,IDISP002,IDISP004,IDISP005 - - - - PreserveNewest - - - - - - - - - - - - - - - - - - - all - runtime; build; native; contentfiles; analyzers - - - - diff --git a/test/Discord.Net.Tests/Net/CacheInfo.cs b/test/Discord.Net.Tests/Net/CacheInfo.cs deleted file mode 100644 index ed2820b8e..000000000 --- a/test/Discord.Net.Tests/Net/CacheInfo.cs +++ /dev/null @@ -1,12 +0,0 @@ -using Newtonsoft.Json; - -namespace Discord.Net -{ - internal class CacheInfo - { - [JsonProperty("guild_id")] - public ulong? GuildId { get; set; } - [JsonProperty("version")] - public uint Version { get; set; } - } -} \ No newline at end of file diff --git a/test/Discord.Net.Tests/Net/CachedRestClient.cs b/test/Discord.Net.Tests/Net/CachedRestClient.cs deleted file mode 100644 index c465eaa01..000000000 --- a/test/Discord.Net.Tests/Net/CachedRestClient.cs +++ /dev/null @@ -1,123 +0,0 @@ -using Akavache; -using Akavache.Sqlite3; -using Discord.Net.Rest; -using System; -using System.Collections.Generic; -using System.IO; -using System.Net; -using System.Reactive.Concurrency; -using System.Reactive.Linq; -using System.Threading; -using System.Threading.Tasks; -using Splat; - -namespace Discord.Net -{ - internal class CachedRestClient : IRestClient - { - private readonly Dictionary _headers; - private IBlobCache _blobCache; - private string _baseUrl; - private CancellationTokenSource _cancelTokenSource; - private CancellationToken _cancelToken, _parentToken; - private bool _isDisposed; - - public CacheInfo Info { get; private set; } - - public CachedRestClient() - { - _headers = new Dictionary(); - - _cancelTokenSource = new CancellationTokenSource(); - _cancelToken = CancellationToken.None; - _parentToken = CancellationToken.None; - - Locator.CurrentMutable.Register(() => Scheduler.Default, typeof(IScheduler), "Taskpool"); - Locator.CurrentMutable.Register(() => new FilesystemProvider(), typeof(IFilesystemProvider), null); - Locator.CurrentMutable.Register(() => new HttpMixin(), typeof(IAkavacheHttpMixin), null); - //new Akavache.Sqlite3.Registrations().Register(Locator.CurrentMutable); - _blobCache = new SQLitePersistentBlobCache("cache.db"); - } - private void Dispose(bool disposing) - { - if (!_isDisposed) - { - if (disposing) - { - _blobCache.Dispose(); - _cancelTokenSource?.Dispose(); - } - _isDisposed = true; - } - } - public void Dispose() - { - Dispose(true); - } - - public void SetUrl(string url) - { - _baseUrl = url; - } - public void SetHeader(string key, string value) - { - _headers[key] = value; - } - public void SetCancelToken(CancellationToken cancelToken) - { - _parentToken = cancelToken; - _cancelToken = CancellationTokenSource.CreateLinkedTokenSource(_parentToken, _cancelTokenSource.Token).Token; - } - - public async Task SendAsync(string method, string endpoint, CancellationToken cancelToken, bool headerOnly, string reason = null) - { - if (method != "GET") - throw new InvalidOperationException("This RestClient only supports GET requests."); - - string uri = Path.Combine(_baseUrl, endpoint); - var bytes = await _blobCache.DownloadUrl(uri, _headers); - return new RestResponse(HttpStatusCode.OK, _headers, new MemoryStream(bytes)); - } - public Task SendAsync(string method, string endpoint, string json, CancellationToken cancelToken, bool headerOnly, string reason = null) - { - throw new InvalidOperationException("This RestClient does not support payloads."); - } - public Task SendAsync(string method, string endpoint, IReadOnlyDictionary multipartParams, CancellationToken cancelToken, bool headerOnly, string reason = null) - { - throw new InvalidOperationException("This RestClient does not support multipart requests."); - } - - public async Task ClearAsync() - { - await _blobCache.InvalidateAll(); - } - - public async Task LoadInfoAsync(ulong guildId) - { - if (Info != null) - return; - - bool needsReset = false; - try - { - Info = await _blobCache.GetObject("info"); - if (Info.GuildId != guildId) - needsReset = true; - } - catch (KeyNotFoundException) - { - needsReset = true; - } - if (needsReset) - { - Info = new CacheInfo() { GuildId = guildId, Version = 0 }; - await SaveInfoAsync().ConfigureAwait(false); - } - } - public async Task SaveInfoAsync() - { - await ClearAsync().ConfigureAwait(false); //Version changed, invalidate cache - await _blobCache.InsertObject("info", Info); - } - } -} diff --git a/test/Discord.Net.Tests/Net/FilesystemProvider.cs b/test/Discord.Net.Tests/Net/FilesystemProvider.cs deleted file mode 100644 index ae1b9a301..000000000 --- a/test/Discord.Net.Tests/Net/FilesystemProvider.cs +++ /dev/null @@ -1,128 +0,0 @@ -//From https://github.com/akavache/Akavache -//Copyright (c) 2012 GitHub -//TODO: Remove once netstandard support is added - -using Akavache; -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Linq; -using System.Reactive; -using System.Reactive.Concurrency; -using System.Reactive.Linq; -using System.Reactive.Subjects; -using System.Reflection; - -namespace Discord -{ - public class FilesystemProvider : IFilesystemProvider - { - public IObservable OpenFileForReadAsync(string path, IScheduler scheduler) - { - return SafeOpenFileAsync(path, FileMode.Open, FileAccess.Read, FileShare.Read, scheduler); - } - - public IObservable OpenFileForWriteAsync(string path, IScheduler scheduler) - { - return SafeOpenFileAsync(path, FileMode.Create, FileAccess.Write, FileShare.None, scheduler); - } - - public IObservable CreateRecursive(string path) - { - CreateRecursive(new DirectoryInfo(path)); - return Observable.Return(Unit.Default); - } - - public IObservable Delete(string path) - { - return Observable.Start(() => File.Delete(path), Scheduler.Default); - } - - public string GetDefaultRoamingCacheDirectory() - { - throw new NotSupportedException(); - } - - public string GetDefaultSecretCacheDirectory() - { - throw new NotSupportedException(); - } - - public string GetDefaultLocalMachineCacheDirectory() - { - throw new NotSupportedException(); - } - - protected static string GetAssemblyDirectoryName() - { - var assemblyDirectoryName = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location); - Debug.Assert(assemblyDirectoryName != null, "The directory name of the assembly location is null"); - return assemblyDirectoryName; - } - - private static IObservable SafeOpenFileAsync(string path, FileMode mode, FileAccess access, FileShare share, IScheduler scheduler = null) - { - scheduler = scheduler ?? Scheduler.Default; - var ret = new AsyncSubject(); - - Observable.Start(() => - { - try - { - var createModes = new[] - { - FileMode.Create, - FileMode.CreateNew, - FileMode.OpenOrCreate, - }; - - - // NB: We do this (even though it's incorrect!) because - // throwing lots of 1st chance exceptions makes debugging - // obnoxious, as well as a bug in VS where it detects - // exceptions caught by Observable.Start as Unhandled. - if (!createModes.Contains(mode) && !File.Exists(path)) - { - ret.OnError(new FileNotFoundException()); - return; - } - - Observable.Start(() => new FileStream(path, mode, access, share, 4096, false), scheduler).Cast().Subscribe(ret); - } - catch (Exception ex) - { - ret.OnError(ex); - } - }, scheduler); - - return ret; - } - private static void CreateRecursive(DirectoryInfo info) - { - SplitFullPath(info).Aggregate((parent, dir) => - { - var path = Path.Combine(parent, dir); - if (!Directory.Exists(path)) - Directory.CreateDirectory(path); - return path; - }); - } - - private static IEnumerable SplitFullPath(DirectoryInfo info) - { - var root = Path.GetPathRoot(info.FullName); - var components = new List(); - for (var path = info.FullName; path != root && path != null; path = Path.GetDirectoryName(path)) - { - var filename = Path.GetFileName(path); - if (String.IsNullOrEmpty(filename)) - continue; - components.Add(filename); - } - components.Add(root); - components.Reverse(); - return components; - } - } -} \ No newline at end of file diff --git a/test/Discord.Net.Tests/Net/HttpMixin.cs b/test/Discord.Net.Tests/Net/HttpMixin.cs deleted file mode 100644 index 6cde2776b..000000000 --- a/test/Discord.Net.Tests/Net/HttpMixin.cs +++ /dev/null @@ -1,144 +0,0 @@ -//From https://github.com/akavache/Akavache -//Copyright (c) 2012 GitHub -//TODO: Remove once netstandard support is added - -#pragma warning disable CS0618 - -using Akavache; -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Net; -using System.Reactive.Linq; -using System.Reactive.Subjects; -using System.Text; -using System.Reactive; -using System.Reactive.Threading.Tasks; - -namespace Discord.Net -{ - public class HttpMixin : IAkavacheHttpMixin - { - /// - /// Download data from an HTTP URL and insert the result into the - /// cache. If the data is already in the cache, this returns - /// a cached value. The URL itself is used as the key. - /// - /// The URL to download. - /// An optional Dictionary containing the HTTP - /// request headers. - /// Force a web request to always be issued, skipping the cache. - /// An optional expiration date. - /// The data downloaded from the URL. - public IObservable DownloadUrl(IBlobCache This, string url, IDictionary headers = null, bool fetchAlways = false, DateTimeOffset? absoluteExpiration = null) - { - return This.DownloadUrl(url, url, headers, fetchAlways, absoluteExpiration); - } - - /// - /// Download data from an HTTP URL and insert the result into the - /// cache. If the data is already in the cache, this returns - /// a cached value. An explicit key is provided rather than the URL itself. - /// - /// The key to store with. - /// The URL to download. - /// An optional Dictionary containing the HTTP - /// request headers. - /// Force a web request to always be issued, skipping the cache. - /// An optional expiration date. - /// The data downloaded from the URL. - public IObservable DownloadUrl(IBlobCache This, string key, string url, IDictionary headers = null, bool fetchAlways = false, DateTimeOffset? absoluteExpiration = null) - { - var doFetch = MakeWebRequest(new Uri(url), headers).SelectMany(x => ProcessWebResponse(x, url, absoluteExpiration)); - var fetchAndCache = doFetch.SelectMany(x => This.Insert(key, x, absoluteExpiration).Select(_ => x)); - - var ret = default(IObservable); - if (!fetchAlways) - { - ret = This.Get(key).Catch(fetchAndCache); - } - else - { - ret = fetchAndCache; - } - - var conn = ret.PublishLast(); - conn.Connect(); - return conn; - } - - IObservable ProcessWebResponse(WebResponse wr, string url, DateTimeOffset? absoluteExpiration) - { - var hwr = (HttpWebResponse)wr; - Debug.Assert(hwr != null, "The Web Response is somehow null but shouldn't be."); - if ((int)hwr.StatusCode >= 400) - { - return Observable.Throw(new WebException(hwr.StatusDescription)); - } - - var ms = new MemoryStream(); - using (var responseStream = hwr.GetResponseStream()) - { - Debug.Assert(responseStream != null, "The response stream is somehow null"); - responseStream.CopyTo(ms); - } - - var ret = ms.ToArray(); - return Observable.Return(ret); - } - - static IObservable MakeWebRequest( - Uri uri, - IDictionary headers = null, - string content = null, - int retries = 3, - TimeSpan? timeout = null) - { - IObservable request; - - request = Observable.Defer(() => - { - var hwr = CreateWebRequest(uri, headers); - - if (content == null) - return Observable.FromAsyncPattern(hwr.BeginGetResponse, hwr.EndGetResponse)(); - - var buf = Encoding.UTF8.GetBytes(content); - - // NB: You'd think that BeginGetResponse would never block, - // seeing as how it's asynchronous. You'd be wrong :-/ - var ret = new AsyncSubject(); - Observable.Start(() => - { - Observable.FromAsyncPattern(hwr.BeginGetRequestStream, hwr.EndGetRequestStream)() - .SelectMany(x => WriteAsyncRx(x, buf, 0, buf.Length)) - .SelectMany(_ => Observable.FromAsyncPattern(hwr.BeginGetResponse, hwr.EndGetResponse)()) - .Multicast(ret).Connect(); - }, BlobCache.TaskpoolScheduler); - - return ret; - }); - - return request.Timeout(timeout ?? TimeSpan.FromSeconds(15), BlobCache.TaskpoolScheduler).Retry(retries); - } - - private static WebRequest CreateWebRequest(Uri uri, IDictionary headers) - { - var hwr = WebRequest.Create(uri); - if (headers != null) - { - foreach (var x in headers) - { - hwr.Headers[x.Key] = x.Value; - } - } - return hwr; - } - - private static IObservable WriteAsyncRx(Stream stream, byte[] data, int start, int length) - { - return stream.WriteAsync(data, start, length).ToObservable(); - } - } -} diff --git a/test/Discord.Net.Tests/TestConfig.cs b/test/Discord.Net.Tests/TestConfig.cs deleted file mode 100644 index bdab13ea7..000000000 --- a/test/Discord.Net.Tests/TestConfig.cs +++ /dev/null @@ -1,33 +0,0 @@ -using Newtonsoft.Json; -using System.IO; -using System; - -namespace Discord -{ - internal class TestConfig - { - [JsonProperty("token")] - public string Token { get; private set; } - [JsonProperty("guild_id")] - public ulong GuildId { get; private set; } - - public static TestConfig LoadFile(string path) - { - if (File.Exists(path)) - { - using (var stream = new FileStream(path, FileMode.Open)) - using (var reader = new StreamReader(stream)) - using (var jsonReader = new JsonTextReader(reader)) - return new JsonSerializer().Deserialize(jsonReader); - } - else - { - return new TestConfig() - { - Token = Environment.GetEnvironmentVariable("DNET_TEST_TOKEN"), - GuildId = ulong.Parse(Environment.GetEnvironmentVariable("DNET_TEST_GUILDID")) - }; - } - } - } -} \ No newline at end of file diff --git a/test/Discord.Net.Tests/Tests.ChannelPermissions.cs b/test/Discord.Net.Tests/Tests.ChannelPermissions.cs deleted file mode 100644 index df3f2dbb4..000000000 --- a/test/Discord.Net.Tests/Tests.ChannelPermissions.cs +++ /dev/null @@ -1,177 +0,0 @@ -using System; -using System.Threading.Tasks; -using Xunit; - -namespace Discord -{ - public class ChannelPermissionsTests - { - // seems like all these tests are broken - /*[Fact] - public Task TestChannelPermission() - { - var perm = new ChannelPermissions(); - - // check initial values - Assert.Equal((ulong)0, perm.RawValue); - Assert.Equal(ChannelPermissions.None.RawValue, perm.RawValue); - - // permissions list empty by default - Assert.Empty(perm.ToList()); - - // test modify with no parameters - var copy = perm.Modify(); - Assert.Equal((ulong)0, copy.RawValue); - - // test modify with no parameters after using all - copy = ChannelPermissions.Text; - var modified = copy.Modify(); // no params should not change the result - Assert.Equal(ChannelPermissions.Text.RawValue, modified.RawValue); - - copy = ChannelPermissions.Voice; - modified = copy.Modify(); // no params should not change the result - Assert.Equal(ChannelPermissions.Voice.RawValue, modified.RawValue); - - copy = ChannelPermissions.Group; - modified = copy.Modify(); // no params should not change the result - Assert.Equal(ChannelPermissions.Group.RawValue, modified.RawValue); - - copy = ChannelPermissions.DM; - modified = copy.Modify(); // no params should not change the result - Assert.Equal(ChannelPermissions.DM.RawValue, modified.RawValue); - - copy = new ChannelPermissions(useExternalEmojis: true); - modified = copy.Modify(); - Assert.Equal(copy.RawValue, modified.RawValue); - - // test the values that are returned by ChannelPermission.All - Assert.Equal((ulong)0, ChannelPermissions.None.RawValue); - - // for text channels - ulong textChannel = (ulong)( ChannelPermission.CreateInstantInvite - | ChannelPermission.ManageChannels - | ChannelPermission.AddReactions - | ChannelPermission.ViewChannel - | ChannelPermission.SendMessages - | ChannelPermission.SendTTSMessages - | ChannelPermission.ManageMessages - | ChannelPermission.EmbedLinks - | ChannelPermission.AttachFiles - | ChannelPermission.ReadMessageHistory - | ChannelPermission.MentionEveryone - | ChannelPermission.UseExternalEmojis - | ChannelPermission.ManageRoles - | ChannelPermission.ManageWebhooks); - - Assert.Equal(textChannel, ChannelPermissions.Text.RawValue); - - // voice channels - ulong voiceChannel = (ulong)( - ChannelPermission.CreateInstantInvite - | ChannelPermission.ManageChannels - | ChannelPermission.ViewChannel - | ChannelPermission.Connect - | ChannelPermission.Speak - | ChannelPermission.MuteMembers - | ChannelPermission.DeafenMembers - | ChannelPermission.MoveMembers - | ChannelPermission.UseVAD - | ChannelPermission.ManageRoles - | ChannelPermission.PrioritySpeaker); - - Assert.Equal(voiceChannel, ChannelPermissions.Voice.RawValue); - - // DM Channels - ulong dmChannel = (ulong)( - ChannelPermission.ViewChannel - | ChannelPermission.SendMessages - | ChannelPermission.EmbedLinks - | ChannelPermission.AttachFiles - | ChannelPermission.ReadMessageHistory - | ChannelPermission.UseExternalEmojis - | ChannelPermission.Connect - | ChannelPermission.Speak - | ChannelPermission.UseVAD - ); - //Assert.Equal(dmChannel, ChannelPermissions.DM.RawValue); - // TODO: this test is failing and that's a bad thing - - // group channel - ulong groupChannel = (ulong)( - ChannelPermission.SendMessages - | ChannelPermission.EmbedLinks - | ChannelPermission.AttachFiles - | ChannelPermission.SendTTSMessages - | ChannelPermission.Connect - | ChannelPermission.Speak - | ChannelPermission.UseVAD - ); - // TODO: this test is also broken - //Assert.Equal(groupChannel, ChannelPermissions.Group.RawValue); - return Task.CompletedTask; - }*/ - [Fact] - public Task TestChannelPermissionModify() - { - // test that channel permissions could be modified correctly - var perm = new ChannelPermissions(); - - void Check(ChannelPermission permission, - Func has, - Func modify) - { - // ensure permission initially false - // use both the function and Has to ensure that the GetPermission - // function is working - Assert.False(has(perm)); - Assert.False(perm.Has(permission)); - - // enable it, and ensure that it gets set - perm = modify(perm, true); - Assert.True(has(perm)); - Assert.True(perm.Has(permission)); - - // set it false again - perm = modify(perm, false); - Assert.False(has(perm)); - Assert.False(perm.Has(permission)); - - // ensure that no perms are set now - Assert.Equal(ChannelPermissions.None.RawValue, perm.RawValue); - } - - Check(ChannelPermission.CreateInstantInvite, x => x.CreateInstantInvite, (p, enable) => p.Modify(createInstantInvite: enable)); - Check(ChannelPermission.ManageChannels, x => x.ManageChannel, (p, enable) => p.Modify(manageChannel: enable)); - Check(ChannelPermission.AddReactions, x => x.AddReactions, (p, enable) => p.Modify(addReactions: enable)); - Check(ChannelPermission.ViewChannel, x => x.ViewChannel, (p, enable) => p.Modify(viewChannel: enable)); - Check(ChannelPermission.SendMessages, x => x.SendMessages, (p, enable) => p.Modify(sendMessages: enable)); - Check(ChannelPermission.SendTTSMessages, x => x.SendTTSMessages, (p, enable) => p.Modify(sendTTSMessages: enable)); - Check(ChannelPermission.ManageMessages, x => x.ManageMessages, (p, enable) => p.Modify(manageMessages: enable)); - Check(ChannelPermission.EmbedLinks, x => x.EmbedLinks, (p, enable) => p.Modify(embedLinks: enable)); - Check(ChannelPermission.AttachFiles, x => x.AttachFiles, (p, enable) => p.Modify(attachFiles: enable)); - Check(ChannelPermission.ReadMessageHistory, x => x.ReadMessageHistory, (p, enable) => p.Modify(readMessageHistory: enable)); - Check(ChannelPermission.MentionEveryone, x => x.MentionEveryone, (p, enable) => p.Modify(mentionEveryone: enable)); - Check(ChannelPermission.UseExternalEmojis, x => x.UseExternalEmojis, (p, enable) => p.Modify(useExternalEmojis: enable)); - Check(ChannelPermission.Connect, x => x.Connect, (p, enable) => p.Modify(connect: enable)); - Check(ChannelPermission.Speak, x => x.Speak, (p, enable) => p.Modify(speak: enable)); - Check(ChannelPermission.MuteMembers, x => x.MuteMembers, (p, enable) => p.Modify(muteMembers: enable)); - Check(ChannelPermission.DeafenMembers, x => x.DeafenMembers, (p, enable) => p.Modify(deafenMembers: enable)); - Check(ChannelPermission.MoveMembers, x => x.MoveMembers, (p, enable) => p.Modify(moveMembers: enable)); - Check(ChannelPermission.UseVAD, x => x.UseVAD, (p, enable) => p.Modify(useVoiceActivation: enable)); - Check(ChannelPermission.ManageRoles, x => x.ManageRoles, (p, enable) => p.Modify(manageRoles: enable)); - Check(ChannelPermission.ManageWebhooks, x => x.ManageWebhooks, (p, enable) => p.Modify(manageWebhooks: enable)); - Check(ChannelPermission.PrioritySpeaker, x => x.PrioritySpeaker, (p, enable) => p.Modify(prioritySpeaker: enable)); - - return Task.CompletedTask; - } - - [Fact] - public Task TestChannelTypeResolution() - { - ITextChannel someChannel = null; - // null channels will throw exception - Assert.Throws(() => ChannelPermissions.All(someChannel)); - return Task.CompletedTask; - } - } -} diff --git a/test/Discord.Net.Tests/Tests.Channels.cs b/test/Discord.Net.Tests/Tests.Channels.cs deleted file mode 100644 index c7df76b2b..000000000 --- a/test/Discord.Net.Tests/Tests.Channels.cs +++ /dev/null @@ -1,218 +0,0 @@ -using Discord.Rest; -using System.Linq; -using System.Threading.Tasks; -using Xunit; -#if IXTEST -namespace Discord -{ - public partial class Tests - { - internal static async Task Migration_CreateTextChannels(DiscordRestClient client, RestGuild guild) - { - var text1 = await guild.GetDefaultChannelAsync(); - var text2 = await guild.CreateTextChannelAsync("text2"); - var text3 = await guild.CreateTextChannelAsync("text3"); - var text4 = await guild.CreateTextChannelAsync("text4"); - var text5 = await guild.CreateTextChannelAsync("text5"); - - // create a channel category - var cat1 = await guild.CreateCategoryChannelAsync("cat1"); - - if (text1 == null) - { - // the guild did not have a default channel, so make a new one - text1 = await guild.CreateTextChannelAsync("default"); - } - - //Modify #general - await text1.ModifyAsync(x => - { - x.Name = "text1"; - x.Position = 1; - x.Topic = "Topic1"; - x.CategoryId = cat1.Id; - }); - - await text2.ModifyAsync(x => - { - x.Position = 2; - x.CategoryId = cat1.Id; - }); - await text3.ModifyAsync(x => - { - x.Topic = "Topic2"; - }); - await text4.ModifyAsync(x => - { - x.Position = 3; - x.Topic = "Topic2"; - }); - await text5.ModifyAsync(x => - { - }); - - CheckTextChannels(guild, text1, text2, text3, text4, text5); - } - [Fact] - public async Task TestTextChannels() - { - CheckTextChannels(_guild, (await _guild.GetTextChannelsAsync()).ToArray()); - } - private static void CheckTextChannels(RestGuild guild, params RestTextChannel[] textChannels) - { - Assert.Equal(5, textChannels.Length); - Assert.All(textChannels, x => - { - Assert.NotNull(x); - Assert.NotEqual(0UL, x.Id); - Assert.True(x.Position >= 0); - }); - - var text1 = textChannels.FirstOrDefault(x => x.Name == "text1"); - var text2 = textChannels.FirstOrDefault(x => x.Name == "text2"); - var text3 = textChannels.FirstOrDefault(x => x.Name == "text3"); - var text4 = textChannels.FirstOrDefault(x => x.Name == "text4"); - var text5 = textChannels.FirstOrDefault(x => x.Name == "text5"); - - Assert.NotNull(text1); - //Assert.True(text1.Id == guild.DefaultChannelId); - Assert.Equal(1, text1.Position); - Assert.Equal("Topic1", text1.Topic); - - Assert.NotNull(text2); - Assert.Equal(2, text2.Position); - Assert.Null(text2.Topic); - - Assert.NotNull(text3); - Assert.Equal("Topic2", text3.Topic); - - Assert.NotNull(text4); - Assert.Equal(3, text4.Position); - Assert.Equal("Topic2", text4.Topic); - - Assert.NotNull(text5); - Assert.Null(text5.Topic); - } - - internal static async Task Migration_CreateVoiceChannels(DiscordRestClient client, RestGuild guild) - { - var voice1 = await guild.CreateVoiceChannelAsync("voice1"); - var voice2 = await guild.CreateVoiceChannelAsync("voice2"); - var voice3 = await guild.CreateVoiceChannelAsync("voice3"); - - var cat2 = await guild.CreateCategoryChannelAsync("cat2"); - - await voice1.ModifyAsync(x => - { - x.Bitrate = 96000; - x.Position = 1; - x.CategoryId = cat2.Id; - }); - await voice2.ModifyAsync(x => - { - x.UserLimit = null; - }); - await voice3.ModifyAsync(x => - { - x.Bitrate = 8000; - x.Position = 1; - x.UserLimit = 16; - x.CategoryId = cat2.Id; - }); - - CheckVoiceChannels(voice1, voice2, voice3); - } - [Fact] - public async Task TestVoiceChannels() - { - CheckVoiceChannels((await _guild.GetVoiceChannelsAsync()).ToArray()); - } - private static void CheckVoiceChannels(params RestVoiceChannel[] voiceChannels) - { - Assert.Equal(3, voiceChannels.Length); - Assert.All(voiceChannels, x => - { - Assert.NotNull(x); - Assert.NotEqual(0UL, x.Id); - Assert.NotEqual(0, x.UserLimit); - Assert.True(x.Bitrate > 0); - Assert.True(x.Position >= 0); - }); - - var voice1 = voiceChannels.FirstOrDefault(x => x.Name == "voice1"); - var voice2 = voiceChannels.FirstOrDefault(x => x.Name == "voice2"); - var voice3 = voiceChannels.FirstOrDefault(x => x.Name == "voice3"); - - Assert.NotNull(voice1); - Assert.Equal(96000, voice1.Bitrate); - Assert.Equal(1, voice1.Position); - - Assert.NotNull(voice2); - Assert.Null(voice2.UserLimit); - - Assert.NotNull(voice3); - Assert.Equal(8000, voice3.Bitrate); - Assert.Equal(1, voice3.Position); - Assert.Equal(16, voice3.UserLimit); - } - - [Fact] - public async Task TestChannelCategories() - { - // (await _guild.GetVoiceChannelsAsync()).ToArray() - var channels = await _guild.GetCategoryChannelsAsync(); - - await CheckChannelCategories(channels.ToArray(), (await _guild.GetChannelsAsync()).ToArray()); - } - - private async Task CheckChannelCategories(RestCategoryChannel[] categories, RestGuildChannel[] allChannels) - { - // 2 categories - Assert.Equal(2, categories.Length); - - var cat1 = categories.FirstOrDefault(x => x.Name == "cat1"); - var cat2 = categories.FirstOrDefault(x => x.Name == "cat2"); - - Assert.NotNull(cat1); - Assert.NotNull(cat2); - - // get text1, text2, ensure they have category id == cat1 - var text1 = allChannels.FirstOrDefault(x => x.Name == "text1") as RestTextChannel; - var text2 = allChannels.FirstOrDefault(x => x.Name == "text2") as RestTextChannel; - - Assert.NotNull(text1); - Assert.NotNull(text2); - - // check that CategoryID and .GetCategoryAsync work correctly - // for both of the text channels - Assert.Equal(text1.CategoryId, cat1.Id); - var text1Cat = await text1.GetCategoryAsync(); - Assert.Equal(text1Cat.Id, cat1.Id); - Assert.Equal(text1Cat.Name, cat1.Name); - - Assert.Equal(text2.CategoryId, cat1.Id); - var text2Cat = await text2.GetCategoryAsync(); - Assert.Equal(text2Cat.Id, cat1.Id); - Assert.Equal(text2Cat.Name, cat1.Name); - - // do the same for the voice channels - var voice1 = allChannels.FirstOrDefault(x => x.Name == "voice1") as RestVoiceChannel; - var voice3 = allChannels.FirstOrDefault(x => x.Name == "voice3") as RestVoiceChannel; - - Assert.NotNull(voice1); - Assert.NotNull(voice3); - - Assert.Equal(voice1.CategoryId, cat2.Id); - var voice1Cat = await voice1.GetCategoryAsync(); - Assert.Equal(voice1Cat.Id, cat2.Id); - Assert.Equal(voice1Cat.Name, cat2.Name); - - Assert.Equal(voice3.CategoryId, cat2.Id); - var voice3Cat = await voice3.GetCategoryAsync(); - Assert.Equal(voice3Cat.Id, cat2.Id); - Assert.Equal(voice3Cat.Name, cat2.Name); - - } - } -} -#endif diff --git a/test/Discord.Net.Tests/Tests.Guilds.cs b/test/Discord.Net.Tests/Tests.Guilds.cs deleted file mode 100644 index 0573fb2cb..000000000 --- a/test/Discord.Net.Tests/Tests.Guilds.cs +++ /dev/null @@ -1,342 +0,0 @@ -using System; -using System.Linq; -using System.Threading.Tasks; -using Xunit; -#if IXTEST -namespace Discord -{ - public partial class Tests - { - /// - /// Tests the behavior of modifying the ExplicitContentFilter property of a Guild. - /// - [Fact] - public async Task TestExplicitContentFilter() - { - foreach (var level in Enum.GetValues(typeof(ExplicitContentFilterLevel))) - { - await _guild.ModifyAsync(x => x.ExplicitContentFilter = (ExplicitContentFilterLevel)level); - await _guild.UpdateAsync(); - Assert.Equal(level, _guild.ExplicitContentFilter); - } - } - - /// - /// Tests the behavior of the GuildPermissions class. - /// - [Fact] - public Task TestGuildPermission() - { - // Test Guild Permission Constructors - var perm = new GuildPermissions(); - - // the default raw value is 0 - Assert.Equal((ulong)0, perm.RawValue); - // also check that it is the same as none - Assert.Equal(GuildPermissions.None.RawValue, perm.RawValue); - - // permissions list is empty by default - Assert.Empty(perm.ToList()); - Assert.NotNull(perm.ToList()); - - // Test modify with no parameters - var copy = perm.Modify(); - // ensure that the raw values match - Assert.Equal((ulong)0, copy.RawValue); - - // test modify with no parameters - copy = GuildPermissions.None.Modify(); - Assert.Equal(GuildPermissions.None.RawValue, copy.RawValue); - - // test modify with no parameters on all permissions - copy = GuildPermissions.All.Modify(); - Assert.Equal(GuildPermissions.All.RawValue, copy.RawValue); - - // test modify with no parameters on webhook permissions - copy = GuildPermissions.Webhook.Modify(); - Assert.Equal(GuildPermissions.Webhook.RawValue, copy.RawValue); - - // Get all distinct values (ReadMessages = ViewChannel) - var enumValues = (Enum.GetValues(typeof(GuildPermission)) as GuildPermission[]) - .Distinct() - .ToArray(); - // test GuildPermissions.All - ulong sumOfAllGuildPermissions = 0; - foreach(var v in enumValues) - { - sumOfAllGuildPermissions |= (ulong)v; - } - - // assert that the raw values match - Assert.Equal(sumOfAllGuildPermissions, GuildPermissions.All.RawValue); - Assert.Equal((ulong)0, GuildPermissions.None.RawValue); - - // assert that GuildPermissions.All contains the same number of permissions as the - // GuildPermissions enum - Assert.Equal(enumValues.Length, GuildPermissions.All.ToList().Count); - - // assert that webhook has the same raw value - ulong webHookPermissions = (ulong)( - GuildPermission.SendMessages | GuildPermission.SendTTSMessages | GuildPermission.EmbedLinks | - GuildPermission.AttachFiles); - Assert.Equal(webHookPermissions, GuildPermissions.Webhook.RawValue); - - return Task.CompletedTask; - } - - [Fact] - public Task TestGuildPermissionModify() - { - var perm = new GuildPermissions(); - - // tests each of the parameters of Modify one by one - - // test modify with each of the parameters - // test initially false state - Assert.False(perm.CreateInstantInvite); - - // ensure that when we modify it the parameter works - perm = perm.Modify(createInstantInvite: true); - Assert.True(perm.CreateInstantInvite); - Assert.Equal((ulong)GuildPermission.CreateInstantInvite, perm.RawValue); - - // set it false again, then move on to the next permission - perm = perm.Modify(createInstantInvite: false); - Assert.False(perm.CreateInstantInvite); - Assert.Equal(GuildPermissions.None.RawValue, perm.RawValue); - - // individual permission test - perm = perm.Modify(kickMembers: true); - Assert.True(perm.KickMembers); - Assert.Equal((ulong)GuildPermission.KickMembers, perm.RawValue); - - perm = perm.Modify(kickMembers: false); - Assert.False(perm.KickMembers); - Assert.Equal(GuildPermissions.None.RawValue, perm.RawValue); - - // individual permission test - perm = perm.Modify(banMembers: true); - Assert.True(perm.BanMembers); - Assert.Equal((ulong)GuildPermission.BanMembers, perm.RawValue); - - perm = perm.Modify(banMembers: false); - Assert.False(perm.BanMembers); - Assert.Equal(GuildPermissions.None.RawValue, perm.RawValue); - - // individual permission test - perm = perm.Modify(administrator: true); - Assert.True(perm.Administrator); - Assert.Equal((ulong)GuildPermission.Administrator, perm.RawValue); - - perm = perm.Modify(administrator: false); - Assert.False(perm.Administrator); - Assert.Equal(GuildPermissions.None.RawValue, perm.RawValue); - - // individual permission test - perm = perm.Modify(manageChannels: true); - Assert.True(perm.ManageChannels); - Assert.Equal((ulong)GuildPermission.ManageChannels, perm.RawValue); - - perm = perm.Modify(manageChannels: false); - Assert.False(perm.ManageChannels); - Assert.Equal(GuildPermissions.None.RawValue, perm.RawValue); - - // individual permission test - perm = perm.Modify(manageGuild: true); - Assert.True(perm.ManageGuild); - Assert.Equal((ulong)GuildPermission.ManageGuild, perm.RawValue); - - perm = perm.Modify(manageGuild: false); - Assert.False(perm.ManageGuild); - Assert.Equal(GuildPermissions.None.RawValue, perm.RawValue); - - - // individual permission test - perm = perm.Modify(addReactions: true); - Assert.True(perm.AddReactions); - Assert.Equal((ulong)GuildPermission.AddReactions, perm.RawValue); - - perm = perm.Modify(addReactions: false); - Assert.False(perm.AddReactions); - Assert.Equal(GuildPermissions.None.RawValue, perm.RawValue); - - - // individual permission test - perm = perm.Modify(viewAuditLog: true); - Assert.True(perm.ViewAuditLog); - Assert.Equal((ulong)GuildPermission.ViewAuditLog, perm.RawValue); - - perm = perm.Modify(viewAuditLog: false); - Assert.False(perm.ViewAuditLog); - Assert.Equal(GuildPermissions.None.RawValue, perm.RawValue); - - - // individual permission test - perm = perm.Modify(viewChannel: true); - Assert.True(perm.ViewChannel); - Assert.Equal((ulong)GuildPermission.ViewChannel, perm.RawValue); - - perm = perm.Modify(viewChannel: false); - Assert.False(perm.ViewChannel); - Assert.Equal(GuildPermissions.None.RawValue, perm.RawValue); - - - // individual permission test - perm = perm.Modify(sendMessages: true); - Assert.True(perm.SendMessages); - Assert.Equal((ulong)GuildPermission.SendMessages, perm.RawValue); - - perm = perm.Modify(sendMessages: false); - Assert.False(perm.SendMessages); - Assert.Equal(GuildPermissions.None.RawValue, perm.RawValue); - - // individual permission test - perm = perm.Modify(embedLinks: true); - Assert.True(perm.EmbedLinks); - Assert.Equal((ulong)GuildPermission.EmbedLinks, perm.RawValue); - - perm = perm.Modify(embedLinks: false); - Assert.False(perm.EmbedLinks); - Assert.Equal(GuildPermissions.None.RawValue, perm.RawValue); - - // individual permission test - perm = perm.Modify(attachFiles: true); - Assert.True(perm.AttachFiles); - Assert.Equal((ulong)GuildPermission.AttachFiles, perm.RawValue); - - perm = perm.Modify(attachFiles: false); - Assert.False(perm.AttachFiles); - Assert.Equal(GuildPermissions.None.RawValue, perm.RawValue); - - // individual permission test - perm = perm.Modify(readMessageHistory: true); - Assert.True(perm.ReadMessageHistory); - Assert.Equal((ulong)GuildPermission.ReadMessageHistory, perm.RawValue); - - perm = perm.Modify(readMessageHistory: false); - Assert.False(perm.ReadMessageHistory); - Assert.Equal(GuildPermissions.None.RawValue, perm.RawValue); - - // individual permission test - perm = perm.Modify(mentionEveryone: true); - Assert.True(perm.MentionEveryone); - Assert.Equal((ulong)GuildPermission.MentionEveryone, perm.RawValue); - - perm = perm.Modify(mentionEveryone: false); - Assert.False(perm.MentionEveryone); - Assert.Equal(GuildPermissions.None.RawValue, perm.RawValue); - - // individual permission test - perm = perm.Modify(useExternalEmojis: true); - Assert.True(perm.UseExternalEmojis); - Assert.Equal((ulong)GuildPermission.UseExternalEmojis, perm.RawValue); - - perm = perm.Modify(useExternalEmojis: false); - Assert.False(perm.UseExternalEmojis); - Assert.Equal(GuildPermissions.None.RawValue, perm.RawValue); - - // individual permission test - perm = perm.Modify(connect: true); - Assert.True(perm.Connect); - Assert.Equal((ulong)GuildPermission.Connect, perm.RawValue); - - perm = perm.Modify(connect: false); - Assert.False(perm.Connect); - Assert.Equal(GuildPermissions.None.RawValue, perm.RawValue); - - // individual permission test - perm = perm.Modify(speak: true); - Assert.True(perm.Speak); - Assert.Equal((ulong)GuildPermission.Speak, perm.RawValue); - - perm = perm.Modify(speak: false); - Assert.False(perm.Speak); - Assert.Equal(GuildPermissions.None.RawValue, perm.RawValue); - - // individual permission test - perm = perm.Modify(muteMembers: true); - Assert.True(perm.MuteMembers); - Assert.Equal((ulong)GuildPermission.MuteMembers, perm.RawValue); - - perm = perm.Modify(muteMembers: false); - Assert.False(perm.MuteMembers); - Assert.Equal(GuildPermissions.None.RawValue, perm.RawValue); - - // individual permission test - perm = perm.Modify(deafenMembers: true); - Assert.True(perm.DeafenMembers); - Assert.Equal((ulong)GuildPermission.DeafenMembers, perm.RawValue); - - perm = perm.Modify(deafenMembers: false); - Assert.False(perm.DeafenMembers); - Assert.Equal(GuildPermissions.None.RawValue, perm.RawValue); - - // individual permission test - perm = perm.Modify(moveMembers: true); - Assert.True(perm.MoveMembers); - Assert.Equal((ulong)GuildPermission.MoveMembers, perm.RawValue); - - perm = perm.Modify(moveMembers: false); - Assert.False(perm.MoveMembers); - Assert.Equal(GuildPermissions.None.RawValue, perm.RawValue); - - // individual permission test - perm = perm.Modify(useVoiceActivation: true); - Assert.True(perm.UseVAD); - Assert.Equal((ulong)GuildPermission.UseVAD, perm.RawValue); - - perm = perm.Modify(useVoiceActivation: false); - Assert.False(perm.UseVAD); - Assert.Equal(GuildPermissions.None.RawValue, perm.RawValue); - - // individual permission test - perm = perm.Modify(changeNickname: true); - Assert.True(perm.ChangeNickname); - Assert.Equal((ulong)GuildPermission.ChangeNickname, perm.RawValue); - - perm = perm.Modify(changeNickname: false); - Assert.False(perm.ChangeNickname); - Assert.Equal(GuildPermissions.None.RawValue, perm.RawValue); - - // individual permission test - perm = perm.Modify(manageNicknames: true); - Assert.True(perm.ManageNicknames); - Assert.Equal((ulong)GuildPermission.ManageNicknames, perm.RawValue); - - perm = perm.Modify(manageNicknames: false); - Assert.False(perm.ManageNicknames); - Assert.Equal(GuildPermissions.None.RawValue, perm.RawValue); - - // individual permission test - perm = perm.Modify(manageRoles: true); - Assert.True(perm.ManageRoles); - Assert.Equal((ulong)GuildPermission.ManageRoles, perm.RawValue); - - perm = perm.Modify(manageRoles: false); - Assert.False(perm.ManageRoles); - Assert.Equal(GuildPermissions.None.RawValue, perm.RawValue); - - // individual permission test - perm = perm.Modify(manageWebhooks: true); - Assert.True(perm.ManageWebhooks); - Assert.Equal((ulong)GuildPermission.ManageWebhooks, perm.RawValue); - - perm = perm.Modify(manageWebhooks: false); - Assert.False(perm.ManageWebhooks); - Assert.Equal(GuildPermissions.None.RawValue, perm.RawValue); - - // individual permission test - perm = perm.Modify(manageEmojis: true); - Assert.True(perm.ManageEmojis); - Assert.Equal((ulong)GuildPermission.ManageEmojis, perm.RawValue); - - perm = perm.Modify(manageEmojis: false); - Assert.False(perm.ManageEmojis); - Assert.Equal(GuildPermissions.None.RawValue, perm.RawValue); - - return Task.CompletedTask; - } - - } -} -#endif diff --git a/test/Discord.Net.Tests/Tests.Migrations.cs b/test/Discord.Net.Tests/Tests.Migrations.cs deleted file mode 100644 index 6b18708de..000000000 --- a/test/Discord.Net.Tests/Tests.Migrations.cs +++ /dev/null @@ -1,73 +0,0 @@ -using System; -using System.Threading.Tasks; -using Discord.Rest; -#if IXTEST -namespace Discord -{ - public partial class TestsFixture - { - public const uint MigrationCount = 3; - - public async Task MigrateAsync() - { - DiscordRestClient client = null; - RestGuild guild = null; - - await _cache.LoadInfoAsync(_config.GuildId).ConfigureAwait(false); - while (_cache.Info.Version != MigrationCount) - { - if (client == null) - { - client = new DiscordRestClient(); - await client.LoginAsync(TokenType.Bot, _config.Token).ConfigureAwait(false); - guild = await client.GetGuildAsync(_config.GuildId); - } - - uint nextVer = _cache.Info.Version + 1; - try - { - await DoMigrateAsync(client, guild, nextVer).ConfigureAwait(false); - _cache.Info.Version = nextVer; - await _cache.SaveInfoAsync().ConfigureAwait(false); - } - catch - { - await _cache.ClearAsync().ConfigureAwait(false); - throw; - } - } - } - - private static Task DoMigrateAsync(DiscordRestClient client, RestGuild guild, uint toVersion) - { - switch (toVersion) - { - case 1: return Migration_WipeGuild(client, guild); - case 2: return Tests.Migration_CreateTextChannels(client, guild); - case 3: return Tests.Migration_CreateVoiceChannels(client, guild); - default: throw new InvalidOperationException("Unknown migration: " + toVersion); - } - } - - private static async Task Migration_WipeGuild(DiscordRestClient client, RestGuild guild) - { - var textChannels = await guild.GetTextChannelsAsync(); - var voiceChannels = await guild.GetVoiceChannelsAsync(); - var roles = guild.Roles; - - foreach (var channel in textChannels) - { - //if (channel.Id != guild.DefaultChannelId) - await channel.DeleteAsync(); - } - foreach (var channel in voiceChannels) - await channel.DeleteAsync(); - foreach (var role in roles) - { - if (role.Id != guild.EveryoneRole.Id) - await role.DeleteAsync(); - } - } - } -} -#endif diff --git a/test/Discord.Net.Tests/Tests.Permissions.cs b/test/Discord.Net.Tests/Tests.Permissions.cs deleted file mode 100644 index 239d0862e..000000000 --- a/test/Discord.Net.Tests/Tests.Permissions.cs +++ /dev/null @@ -1,772 +0,0 @@ -using System.Threading.Tasks; -using Xunit; - -namespace Discord -{ - public class PermissionsTests - { - private void TestHelper(ChannelPermissions value, ChannelPermission permission, bool expected = false) - => TestHelper(value.RawValue, (ulong)permission, expected); - - private void TestHelper(GuildPermissions value, GuildPermission permission, bool expected = false) - => TestHelper(value.RawValue, (ulong)permission, expected); - - /// - /// Tests the flag of the given permissions value to the expected output - /// and then tries to toggle the flag on and off - /// - /// - /// - /// - private void TestHelper(ulong rawValue, ulong flagValue, bool expected) - { - Assert.Equal(expected, Permissions.GetValue(rawValue, flagValue)); - - // check that toggling the bit works - Permissions.UnsetFlag(ref rawValue, flagValue); - Assert.False(Permissions.GetValue(rawValue, flagValue)); - Permissions.SetFlag(ref rawValue, flagValue); - Assert.True(Permissions.GetValue(rawValue, flagValue)); - - // do the same, but with the SetValue method - Permissions.SetValue(ref rawValue, true, flagValue); - Assert.True(Permissions.GetValue(rawValue, flagValue)); - Permissions.SetValue(ref rawValue, false, flagValue); - Assert.False(Permissions.GetValue(rawValue, flagValue)); - } - - /// - /// Tests that flag of the given permissions value to be the expected output - /// and then tries cycling through the states of the allow and deny values - /// for that flag - /// - /// - /// - /// - private void TestHelper(OverwritePermissions value, ChannelPermission flag, PermValue expected) - { - // check that the value matches - Assert.Equal(expected, Permissions.GetValue(value.AllowValue, value.DenyValue, flag)); - - // check toggling bits for both allow and deny - // have to make copies to get around read only property - ulong allow = value.AllowValue; - ulong deny = value.DenyValue; - - // both unset should be inherit - Permissions.UnsetFlag(ref allow, (ulong)flag); - Permissions.UnsetFlag(ref deny, (ulong)flag); - Assert.Equal(PermValue.Inherit, Permissions.GetValue(allow, deny, flag)); - - // allow set should be allow - Permissions.SetFlag(ref allow, (ulong)flag); - Permissions.UnsetFlag(ref deny, (ulong)flag); - Assert.Equal(PermValue.Allow, Permissions.GetValue(allow, deny, flag)); - - // deny should be deny - Permissions.UnsetFlag(ref allow, (ulong)flag); - Permissions.SetFlag(ref deny, (ulong)flag); - Assert.Equal(PermValue.Deny, Permissions.GetValue(allow, deny, flag)); - - // allow takes precedence - Permissions.SetFlag(ref allow, (ulong)flag); - Permissions.SetFlag(ref deny, (ulong)flag); - Assert.Equal(PermValue.Allow, Permissions.GetValue(allow, deny, flag)); - } - - /// - /// Tests for the class. - /// - /// Tests that text channel permissions get the right value - /// from the Has method. - /// - /// - [Fact] - public Task TestPermissionsHasChannelPermissionText() - { - var value = ChannelPermissions.Text; - // check that the result of GetValue matches for all properties of text channel - TestHelper(value, ChannelPermission.CreateInstantInvite, true); - TestHelper(value, ChannelPermission.ManageChannels, true); - TestHelper(value, ChannelPermission.AddReactions, true); - TestHelper(value, ChannelPermission.ViewChannel, true); - TestHelper(value, ChannelPermission.SendMessages, true); - TestHelper(value, ChannelPermission.SendTTSMessages, true); - TestHelper(value, ChannelPermission.ManageMessages, true); - TestHelper(value, ChannelPermission.EmbedLinks, true); - TestHelper(value, ChannelPermission.AttachFiles, true); - TestHelper(value, ChannelPermission.ReadMessageHistory, true); - TestHelper(value, ChannelPermission.MentionEveryone, true); - TestHelper(value, ChannelPermission.UseExternalEmojis, true); - TestHelper(value, ChannelPermission.ManageRoles, true); - TestHelper(value, ChannelPermission.ManageWebhooks, true); - - TestHelper(value, ChannelPermission.Connect, false); - TestHelper(value, ChannelPermission.Speak, false); - TestHelper(value, ChannelPermission.MuteMembers, false); - TestHelper(value, ChannelPermission.DeafenMembers, false); - TestHelper(value, ChannelPermission.MoveMembers, false); - TestHelper(value, ChannelPermission.UseVAD, false); - - return Task.CompletedTask; - } - - /// - /// Tests for the class. - /// - /// Tests that no channel permissions get the right value - /// from the Has method. - /// - /// - [Fact] - public Task TestPermissionsHasChannelPermissionNone() - { - // check that none will fail all - var value = ChannelPermissions.None; - - TestHelper(value, ChannelPermission.CreateInstantInvite, false); - TestHelper(value, ChannelPermission.ManageChannels, false); - TestHelper(value, ChannelPermission.AddReactions, false); - TestHelper(value, ChannelPermission.ViewChannel, false); - TestHelper(value, ChannelPermission.SendMessages, false); - TestHelper(value, ChannelPermission.SendTTSMessages, false); - TestHelper(value, ChannelPermission.ManageMessages, false); - TestHelper(value, ChannelPermission.EmbedLinks, false); - TestHelper(value, ChannelPermission.AttachFiles, false); - TestHelper(value, ChannelPermission.ReadMessageHistory, false); - TestHelper(value, ChannelPermission.MentionEveryone, false); - TestHelper(value, ChannelPermission.UseExternalEmojis, false); - TestHelper(value, ChannelPermission.ManageRoles, false); - TestHelper(value, ChannelPermission.ManageWebhooks, false); - TestHelper(value, ChannelPermission.Connect, false); - TestHelper(value, ChannelPermission.Speak, false); - TestHelper(value, ChannelPermission.MuteMembers, false); - TestHelper(value, ChannelPermission.DeafenMembers, false); - TestHelper(value, ChannelPermission.MoveMembers, false); - TestHelper(value, ChannelPermission.UseVAD, false); - - return Task.CompletedTask; - } - - /// - /// Tests for the class. - /// - /// Tests that the dm channel permissions get the right value - /// from the Has method. - /// - /// - [Fact] - public Task TestPermissionsHasChannelPermissionDM() - { - // check that none will fail all - var value = ChannelPermissions.DM; - - TestHelper(value, ChannelPermission.CreateInstantInvite, false); - TestHelper(value, ChannelPermission.ManageChannels, false); - TestHelper(value, ChannelPermission.AddReactions, false); - TestHelper(value, ChannelPermission.ViewChannel, true); - TestHelper(value, ChannelPermission.SendMessages, true); - TestHelper(value, ChannelPermission.SendTTSMessages, false); - TestHelper(value, ChannelPermission.ManageMessages, false); - TestHelper(value, ChannelPermission.EmbedLinks, true); - TestHelper(value, ChannelPermission.AttachFiles, true); - TestHelper(value, ChannelPermission.ReadMessageHistory, true); - TestHelper(value, ChannelPermission.MentionEveryone, false); - TestHelper(value, ChannelPermission.UseExternalEmojis, true); - TestHelper(value, ChannelPermission.ManageRoles, false); - TestHelper(value, ChannelPermission.ManageWebhooks, false); - TestHelper(value, ChannelPermission.Connect, true); - TestHelper(value, ChannelPermission.Speak, true); - TestHelper(value, ChannelPermission.MuteMembers, false); - TestHelper(value, ChannelPermission.DeafenMembers, false); - TestHelper(value, ChannelPermission.MoveMembers, false); - TestHelper(value, ChannelPermission.UseVAD, true); - - return Task.CompletedTask; - } - - /// - /// Tests for the class. - /// - /// Tests that the group channel permissions get the right value - /// from the Has method. - /// - /// - [Fact] - public Task TestPermissionsHasChannelPermissionGroup() - { - var value = ChannelPermissions.Group; - - TestHelper(value, ChannelPermission.CreateInstantInvite, false); - TestHelper(value, ChannelPermission.ManageChannels, false); - TestHelper(value, ChannelPermission.AddReactions, false); - TestHelper(value, ChannelPermission.ViewChannel, false); - TestHelper(value, ChannelPermission.SendMessages, true); - TestHelper(value, ChannelPermission.SendTTSMessages, true); - TestHelper(value, ChannelPermission.ManageMessages, false); - TestHelper(value, ChannelPermission.EmbedLinks, true); - TestHelper(value, ChannelPermission.AttachFiles, true); - TestHelper(value, ChannelPermission.ReadMessageHistory, false); - TestHelper(value, ChannelPermission.MentionEveryone, false); - TestHelper(value, ChannelPermission.UseExternalEmojis, false); - TestHelper(value, ChannelPermission.ManageRoles, false); - TestHelper(value, ChannelPermission.ManageWebhooks, false); - TestHelper(value, ChannelPermission.Connect, true); - TestHelper(value, ChannelPermission.Speak, true); - TestHelper(value, ChannelPermission.MuteMembers, false); - TestHelper(value, ChannelPermission.DeafenMembers, false); - TestHelper(value, ChannelPermission.MoveMembers, false); - TestHelper(value, ChannelPermission.UseVAD, true); - - return Task.CompletedTask; - } - - - /// - /// Tests for the class. - /// - /// Tests that the voice channel permissions get the right value - /// from the Has method. - /// - /// - [Fact] - public Task TestPermissionsHasChannelPermissionVoice() - { - // make a flag with all possible values for Voice channel permissions - var value = ChannelPermissions.Voice; - - TestHelper(value, ChannelPermission.CreateInstantInvite, true); - TestHelper(value, ChannelPermission.ManageChannels, true); - TestHelper(value, ChannelPermission.AddReactions, false); - TestHelper(value, ChannelPermission.ViewChannel, true); - TestHelper(value, ChannelPermission.SendMessages, false); - TestHelper(value, ChannelPermission.SendTTSMessages, false); - TestHelper(value, ChannelPermission.ManageMessages, false); - TestHelper(value, ChannelPermission.EmbedLinks, false); - TestHelper(value, ChannelPermission.AttachFiles, false); - TestHelper(value, ChannelPermission.ReadMessageHistory, false); - TestHelper(value, ChannelPermission.MentionEveryone, false); - TestHelper(value, ChannelPermission.UseExternalEmojis, false); - TestHelper(value, ChannelPermission.ManageRoles, true); - TestHelper(value, ChannelPermission.ManageWebhooks, false); - TestHelper(value, ChannelPermission.Connect, true); - TestHelper(value, ChannelPermission.Speak, true); - TestHelper(value, ChannelPermission.MuteMembers, true); - TestHelper(value, ChannelPermission.DeafenMembers, true); - TestHelper(value, ChannelPermission.MoveMembers, true); - TestHelper(value, ChannelPermission.UseVAD, true); - - return Task.CompletedTask; - } - - /// - /// Tests for the class. - /// - /// Test that that the Has method of - /// returns the correct value when no permissions are set. - /// - /// - [Fact] - public Task TestPermissionsHasGuildPermissionNone() - { - var value = GuildPermissions.None; - - TestHelper(value, GuildPermission.CreateInstantInvite, false); - TestHelper(value, GuildPermission.KickMembers, false); - TestHelper(value, GuildPermission.BanMembers, false); - TestHelper(value, GuildPermission.Administrator, false); - TestHelper(value, GuildPermission.ManageChannels, false); - TestHelper(value, GuildPermission.ManageGuild, false); - TestHelper(value, GuildPermission.AddReactions, false); - TestHelper(value, GuildPermission.ViewAuditLog, false); - TestHelper(value, GuildPermission.ViewChannel, false); - TestHelper(value, GuildPermission.SendMessages, false); - TestHelper(value, GuildPermission.SendTTSMessages, false); - TestHelper(value, GuildPermission.ManageMessages, false); - TestHelper(value, GuildPermission.EmbedLinks, false); - TestHelper(value, GuildPermission.AttachFiles, false); - TestHelper(value, GuildPermission.ReadMessageHistory, false); - TestHelper(value, GuildPermission.MentionEveryone, false); - TestHelper(value, GuildPermission.UseExternalEmojis, false); - TestHelper(value, GuildPermission.Connect, false); - TestHelper(value, GuildPermission.Speak, false); - TestHelper(value, GuildPermission.MuteMembers, false); - TestHelper(value, GuildPermission.MoveMembers, false); - TestHelper(value, GuildPermission.UseVAD, false); - TestHelper(value, GuildPermission.ChangeNickname, false); - TestHelper(value, GuildPermission.ManageNicknames, false); - TestHelper(value, GuildPermission.ManageRoles, false); - TestHelper(value, GuildPermission.ManageWebhooks, false); - TestHelper(value, GuildPermission.ManageEmojis, false); - - return Task.CompletedTask; - } - - /// - /// Tests for the class. - /// - /// Test that that the Has method of - /// returns the correct value when all permissions are set. - /// - /// - [Fact] - public Task TestPermissionsHasGuildPermissionAll() - { - var value = GuildPermissions.All; - - TestHelper(value, GuildPermission.CreateInstantInvite, true); - TestHelper(value, GuildPermission.KickMembers, true); - TestHelper(value, GuildPermission.BanMembers, true); - TestHelper(value, GuildPermission.Administrator, true); - TestHelper(value, GuildPermission.ManageChannels, true); - TestHelper(value, GuildPermission.ManageGuild, true); - TestHelper(value, GuildPermission.AddReactions, true); - TestHelper(value, GuildPermission.ViewAuditLog, true); - TestHelper(value, GuildPermission.ViewChannel, true); - TestHelper(value, GuildPermission.SendMessages, true); - TestHelper(value, GuildPermission.SendTTSMessages, true); - TestHelper(value, GuildPermission.ManageMessages, true); - TestHelper(value, GuildPermission.EmbedLinks, true); - TestHelper(value, GuildPermission.AttachFiles, true); - TestHelper(value, GuildPermission.ReadMessageHistory, true); - TestHelper(value, GuildPermission.MentionEveryone, true); - TestHelper(value, GuildPermission.UseExternalEmojis, true); - TestHelper(value, GuildPermission.Connect, true); - TestHelper(value, GuildPermission.Speak, true); - TestHelper(value, GuildPermission.MuteMembers, true); - TestHelper(value, GuildPermission.MoveMembers, true); - TestHelper(value, GuildPermission.UseVAD, true); - TestHelper(value, GuildPermission.ChangeNickname, true); - TestHelper(value, GuildPermission.ManageNicknames, true); - TestHelper(value, GuildPermission.ManageRoles, true); - TestHelper(value, GuildPermission.ManageWebhooks, true); - TestHelper(value, GuildPermission.ManageEmojis, true); - - - return Task.CompletedTask; - } - - /// - /// Tests for the class. - /// - /// Test that that the Has method of - /// returns the correct value when webhook permissions are set. - /// - /// - [Fact] - public Task TestPermissionsHasGuildPermissionWebhook() - { - var value = GuildPermissions.Webhook; - - TestHelper(value, GuildPermission.CreateInstantInvite, false); - TestHelper(value, GuildPermission.KickMembers, false); - TestHelper(value, GuildPermission.BanMembers, false); - TestHelper(value, GuildPermission.Administrator, false); - TestHelper(value, GuildPermission.ManageChannels, false); - TestHelper(value, GuildPermission.ManageGuild, false); - TestHelper(value, GuildPermission.AddReactions, false); - TestHelper(value, GuildPermission.ViewAuditLog, false); - TestHelper(value, GuildPermission.ViewChannel, false); - TestHelper(value, GuildPermission.SendMessages, true); - TestHelper(value, GuildPermission.SendTTSMessages, true); - TestHelper(value, GuildPermission.ManageMessages, false); - TestHelper(value, GuildPermission.EmbedLinks, true); - TestHelper(value, GuildPermission.AttachFiles, true); - TestHelper(value, GuildPermission.ReadMessageHistory, false); - TestHelper(value, GuildPermission.MentionEveryone, false); - TestHelper(value, GuildPermission.UseExternalEmojis, false); - TestHelper(value, GuildPermission.Connect, false); - TestHelper(value, GuildPermission.Speak, false); - TestHelper(value, GuildPermission.MuteMembers, false); - TestHelper(value, GuildPermission.MoveMembers, false); - TestHelper(value, GuildPermission.UseVAD, false); - TestHelper(value, GuildPermission.ChangeNickname, false); - TestHelper(value, GuildPermission.ManageNicknames, false); - TestHelper(value, GuildPermission.ManageRoles, false); - TestHelper(value, GuildPermission.ManageWebhooks, false); - TestHelper(value, GuildPermission.ManageEmojis, false); - - return Task.CompletedTask; - } - - /// - /// Test - /// for when all text permissions are allowed and denied - /// - /// - [Fact] - public Task TestOverwritePermissionsText() - { - // allow all for text channel - var value = new OverwritePermissions(ChannelPermissions.Text.RawValue, ChannelPermissions.None.RawValue); - - TestHelper(value, ChannelPermission.CreateInstantInvite, PermValue.Allow); - TestHelper(value, ChannelPermission.ManageChannels, PermValue.Allow); - TestHelper(value, ChannelPermission.AddReactions, PermValue.Allow); - TestHelper(value, ChannelPermission.ViewChannel, PermValue.Allow); - TestHelper(value, ChannelPermission.SendMessages, PermValue.Allow); - TestHelper(value, ChannelPermission.SendTTSMessages, PermValue.Allow); - TestHelper(value, ChannelPermission.ManageMessages, PermValue.Allow); - TestHelper(value, ChannelPermission.EmbedLinks, PermValue.Allow); - TestHelper(value, ChannelPermission.AttachFiles, PermValue.Allow); - TestHelper(value, ChannelPermission.ReadMessageHistory, PermValue.Allow); - TestHelper(value, ChannelPermission.MentionEveryone, PermValue.Allow); - TestHelper(value, ChannelPermission.UseExternalEmojis, PermValue.Allow); - TestHelper(value, ChannelPermission.ManageRoles, PermValue.Allow); - TestHelper(value, ChannelPermission.ManageWebhooks, PermValue.Allow); - TestHelper(value, ChannelPermission.Connect, PermValue.Inherit); - TestHelper(value, ChannelPermission.Speak, PermValue.Inherit); - TestHelper(value, ChannelPermission.MuteMembers, PermValue.Inherit); - TestHelper(value, ChannelPermission.DeafenMembers, PermValue.Inherit); - TestHelper(value, ChannelPermission.MoveMembers, PermValue.Inherit); - TestHelper(value, ChannelPermission.UseVAD, PermValue.Inherit); - - value = new OverwritePermissions(ChannelPermissions.None.RawValue, ChannelPermissions.Text.RawValue); - - TestHelper(value, ChannelPermission.CreateInstantInvite, PermValue.Deny); - TestHelper(value, ChannelPermission.ManageChannels, PermValue.Deny); - TestHelper(value, ChannelPermission.AddReactions, PermValue.Deny); - TestHelper(value, ChannelPermission.ViewChannel, PermValue.Deny); - TestHelper(value, ChannelPermission.SendMessages, PermValue.Deny); - TestHelper(value, ChannelPermission.SendTTSMessages, PermValue.Deny); - TestHelper(value, ChannelPermission.ManageMessages, PermValue.Deny); - TestHelper(value, ChannelPermission.EmbedLinks, PermValue.Deny); - TestHelper(value, ChannelPermission.AttachFiles, PermValue.Deny); - TestHelper(value, ChannelPermission.ReadMessageHistory, PermValue.Deny); - TestHelper(value, ChannelPermission.MentionEveryone, PermValue.Deny); - TestHelper(value, ChannelPermission.UseExternalEmojis, PermValue.Deny); - TestHelper(value, ChannelPermission.ManageRoles, PermValue.Deny); - TestHelper(value, ChannelPermission.ManageWebhooks, PermValue.Deny); - TestHelper(value, ChannelPermission.Connect, PermValue.Inherit); - TestHelper(value, ChannelPermission.Speak, PermValue.Inherit); - TestHelper(value, ChannelPermission.MuteMembers, PermValue.Inherit); - TestHelper(value, ChannelPermission.DeafenMembers, PermValue.Inherit); - TestHelper(value, ChannelPermission.MoveMembers, PermValue.Inherit); - TestHelper(value, ChannelPermission.UseVAD, PermValue.Inherit); - - return Task.CompletedTask; - } - - /// - /// Test - /// for when none of the permissions are set. - /// - /// - [Fact] - public Task TestOverwritePermissionsNone() - { - // allow all for text channel - var value = new OverwritePermissions(ChannelPermissions.None.RawValue, ChannelPermissions.None.RawValue); - - TestHelper(value, ChannelPermission.CreateInstantInvite, PermValue.Inherit); - TestHelper(value, ChannelPermission.ManageChannels, PermValue.Inherit); - TestHelper(value, ChannelPermission.AddReactions, PermValue.Inherit); - TestHelper(value, ChannelPermission.ViewChannel, PermValue.Inherit); - TestHelper(value, ChannelPermission.SendMessages, PermValue.Inherit); - TestHelper(value, ChannelPermission.SendTTSMessages, PermValue.Inherit); - TestHelper(value, ChannelPermission.ManageMessages, PermValue.Inherit); - TestHelper(value, ChannelPermission.EmbedLinks, PermValue.Inherit); - TestHelper(value, ChannelPermission.AttachFiles, PermValue.Inherit); - TestHelper(value, ChannelPermission.ReadMessageHistory, PermValue.Inherit); - TestHelper(value, ChannelPermission.MentionEveryone, PermValue.Inherit); - TestHelper(value, ChannelPermission.UseExternalEmojis, PermValue.Inherit); - TestHelper(value, ChannelPermission.ManageRoles, PermValue.Inherit); - TestHelper(value, ChannelPermission.ManageWebhooks, PermValue.Inherit); - TestHelper(value, ChannelPermission.Connect, PermValue.Inherit); - TestHelper(value, ChannelPermission.Speak, PermValue.Inherit); - TestHelper(value, ChannelPermission.MuteMembers, PermValue.Inherit); - TestHelper(value, ChannelPermission.DeafenMembers, PermValue.Inherit); - TestHelper(value, ChannelPermission.MoveMembers, PermValue.Inherit); - TestHelper(value, ChannelPermission.UseVAD, PermValue.Inherit); - - value = new OverwritePermissions(); - - TestHelper(value, ChannelPermission.CreateInstantInvite, PermValue.Inherit); - TestHelper(value, ChannelPermission.ManageChannels, PermValue.Inherit); - TestHelper(value, ChannelPermission.AddReactions, PermValue.Inherit); - TestHelper(value, ChannelPermission.ViewChannel, PermValue.Inherit); - TestHelper(value, ChannelPermission.SendMessages, PermValue.Inherit); - TestHelper(value, ChannelPermission.SendTTSMessages, PermValue.Inherit); - TestHelper(value, ChannelPermission.ManageMessages, PermValue.Inherit); - TestHelper(value, ChannelPermission.EmbedLinks, PermValue.Inherit); - TestHelper(value, ChannelPermission.AttachFiles, PermValue.Inherit); - TestHelper(value, ChannelPermission.ReadMessageHistory, PermValue.Inherit); - TestHelper(value, ChannelPermission.MentionEveryone, PermValue.Inherit); - TestHelper(value, ChannelPermission.UseExternalEmojis, PermValue.Inherit); - TestHelper(value, ChannelPermission.ManageRoles, PermValue.Inherit); - TestHelper(value, ChannelPermission.ManageWebhooks, PermValue.Inherit); - TestHelper(value, ChannelPermission.Connect, PermValue.Inherit); - TestHelper(value, ChannelPermission.Speak, PermValue.Inherit); - TestHelper(value, ChannelPermission.MuteMembers, PermValue.Inherit); - TestHelper(value, ChannelPermission.DeafenMembers, PermValue.Inherit); - TestHelper(value, ChannelPermission.MoveMembers, PermValue.Inherit); - TestHelper(value, ChannelPermission.UseVAD, PermValue.Inherit); - - value = OverwritePermissions.InheritAll; - - TestHelper(value, ChannelPermission.CreateInstantInvite, PermValue.Inherit); - TestHelper(value, ChannelPermission.ManageChannels, PermValue.Inherit); - TestHelper(value, ChannelPermission.AddReactions, PermValue.Inherit); - TestHelper(value, ChannelPermission.ViewChannel, PermValue.Inherit); - TestHelper(value, ChannelPermission.SendMessages, PermValue.Inherit); - TestHelper(value, ChannelPermission.SendTTSMessages, PermValue.Inherit); - TestHelper(value, ChannelPermission.ManageMessages, PermValue.Inherit); - TestHelper(value, ChannelPermission.EmbedLinks, PermValue.Inherit); - TestHelper(value, ChannelPermission.AttachFiles, PermValue.Inherit); - TestHelper(value, ChannelPermission.ReadMessageHistory, PermValue.Inherit); - TestHelper(value, ChannelPermission.MentionEveryone, PermValue.Inherit); - TestHelper(value, ChannelPermission.UseExternalEmojis, PermValue.Inherit); - TestHelper(value, ChannelPermission.ManageRoles, PermValue.Inherit); - TestHelper(value, ChannelPermission.ManageWebhooks, PermValue.Inherit); - TestHelper(value, ChannelPermission.Connect, PermValue.Inherit); - TestHelper(value, ChannelPermission.Speak, PermValue.Inherit); - TestHelper(value, ChannelPermission.MuteMembers, PermValue.Inherit); - TestHelper(value, ChannelPermission.DeafenMembers, PermValue.Inherit); - TestHelper(value, ChannelPermission.MoveMembers, PermValue.Inherit); - TestHelper(value, ChannelPermission.UseVAD, PermValue.Inherit); - - return Task.CompletedTask; - } - - /// - /// Test - /// for when all dm permissions are allowed and denied - /// - /// - [Fact] - public Task TestOverwritePermissionsDM() - { - // allow all for text channel - var value = new OverwritePermissions(ChannelPermissions.DM.RawValue, ChannelPermissions.None.RawValue); - - TestHelper(value, ChannelPermission.CreateInstantInvite, PermValue.Inherit); - TestHelper(value, ChannelPermission.ManageChannels, PermValue.Inherit); - TestHelper(value, ChannelPermission.AddReactions, PermValue.Inherit); - TestHelper(value, ChannelPermission.ViewChannel, PermValue.Allow); - TestHelper(value, ChannelPermission.SendMessages, PermValue.Allow); - TestHelper(value, ChannelPermission.SendTTSMessages, PermValue.Inherit); - TestHelper(value, ChannelPermission.ManageMessages, PermValue.Inherit); - TestHelper(value, ChannelPermission.EmbedLinks, PermValue.Allow); - TestHelper(value, ChannelPermission.AttachFiles, PermValue.Allow); - TestHelper(value, ChannelPermission.ReadMessageHistory, PermValue.Allow); - TestHelper(value, ChannelPermission.MentionEveryone, PermValue.Inherit); - TestHelper(value, ChannelPermission.UseExternalEmojis, PermValue.Allow); - TestHelper(value, ChannelPermission.ManageRoles, PermValue.Inherit); - TestHelper(value, ChannelPermission.ManageWebhooks, PermValue.Inherit); - TestHelper(value, ChannelPermission.Connect, PermValue.Allow); - TestHelper(value, ChannelPermission.Speak, PermValue.Allow); - TestHelper(value, ChannelPermission.MuteMembers, PermValue.Inherit); - TestHelper(value, ChannelPermission.DeafenMembers, PermValue.Inherit); - TestHelper(value, ChannelPermission.MoveMembers, PermValue.Inherit); - TestHelper(value, ChannelPermission.UseVAD, PermValue.Allow); - - value = new OverwritePermissions(ChannelPermissions.None.RawValue, ChannelPermissions.DM.RawValue); - - TestHelper(value, ChannelPermission.CreateInstantInvite, PermValue.Inherit); - TestHelper(value, ChannelPermission.ManageChannels, PermValue.Inherit); - TestHelper(value, ChannelPermission.AddReactions, PermValue.Inherit); - TestHelper(value, ChannelPermission.ViewChannel, PermValue.Deny); - TestHelper(value, ChannelPermission.SendMessages, PermValue.Deny); - TestHelper(value, ChannelPermission.SendTTSMessages, PermValue.Inherit); - TestHelper(value, ChannelPermission.ManageMessages, PermValue.Inherit); - TestHelper(value, ChannelPermission.EmbedLinks, PermValue.Deny); - TestHelper(value, ChannelPermission.AttachFiles, PermValue.Deny); - TestHelper(value, ChannelPermission.ReadMessageHistory, PermValue.Deny); - TestHelper(value, ChannelPermission.MentionEveryone, PermValue.Inherit); - TestHelper(value, ChannelPermission.UseExternalEmojis, PermValue.Deny); - TestHelper(value, ChannelPermission.ManageRoles, PermValue.Inherit); - TestHelper(value, ChannelPermission.ManageWebhooks, PermValue.Inherit); - TestHelper(value, ChannelPermission.Connect, PermValue.Deny); - TestHelper(value, ChannelPermission.Speak, PermValue.Deny); - TestHelper(value, ChannelPermission.MuteMembers, PermValue.Inherit); - TestHelper(value, ChannelPermission.DeafenMembers, PermValue.Inherit); - TestHelper(value, ChannelPermission.MoveMembers, PermValue.Inherit); - TestHelper(value, ChannelPermission.UseVAD, PermValue.Deny); - - return Task.CompletedTask; - } - - /// - /// Test - /// for when all group permissions are allowed and denied - /// - /// - [Fact] - public Task TestOverwritePermissionsGroup() - { - // allow all for group channels - var value = new OverwritePermissions(ChannelPermissions.Group.RawValue, ChannelPermissions.None.RawValue); - - TestHelper(value, ChannelPermission.CreateInstantInvite, PermValue.Inherit); - TestHelper(value, ChannelPermission.ManageChannels, PermValue.Inherit); - TestHelper(value, ChannelPermission.AddReactions, PermValue.Inherit); - TestHelper(value, ChannelPermission.ViewChannel, PermValue.Inherit); - TestHelper(value, ChannelPermission.SendMessages, PermValue.Allow); - TestHelper(value, ChannelPermission.SendTTSMessages, PermValue.Allow); - TestHelper(value, ChannelPermission.ManageMessages, PermValue.Inherit); - TestHelper(value, ChannelPermission.EmbedLinks, PermValue.Allow); - TestHelper(value, ChannelPermission.AttachFiles, PermValue.Allow); - TestHelper(value, ChannelPermission.ReadMessageHistory, PermValue.Inherit); - TestHelper(value, ChannelPermission.MentionEveryone, PermValue.Inherit); - TestHelper(value, ChannelPermission.UseExternalEmojis, PermValue.Inherit); - TestHelper(value, ChannelPermission.ManageRoles, PermValue.Inherit); - TestHelper(value, ChannelPermission.ManageWebhooks, PermValue.Inherit); - TestHelper(value, ChannelPermission.Connect, PermValue.Allow); - TestHelper(value, ChannelPermission.Speak, PermValue.Allow); - TestHelper(value, ChannelPermission.MuteMembers, PermValue.Inherit); - TestHelper(value, ChannelPermission.DeafenMembers, PermValue.Inherit); - TestHelper(value, ChannelPermission.MoveMembers, PermValue.Inherit); - TestHelper(value, ChannelPermission.UseVAD, PermValue.Allow); - - value = new OverwritePermissions(ChannelPermissions.None.RawValue, ChannelPermissions.Group.RawValue); - - TestHelper(value, ChannelPermission.CreateInstantInvite, PermValue.Inherit); - TestHelper(value, ChannelPermission.ManageChannels, PermValue.Inherit); - TestHelper(value, ChannelPermission.AddReactions, PermValue.Inherit); - TestHelper(value, ChannelPermission.ViewChannel, PermValue.Inherit); - TestHelper(value, ChannelPermission.SendMessages, PermValue.Deny); - TestHelper(value, ChannelPermission.SendTTSMessages, PermValue.Deny); - TestHelper(value, ChannelPermission.ManageMessages, PermValue.Inherit); - TestHelper(value, ChannelPermission.EmbedLinks, PermValue.Deny); - TestHelper(value, ChannelPermission.AttachFiles, PermValue.Deny); - TestHelper(value, ChannelPermission.ReadMessageHistory, PermValue.Inherit); - TestHelper(value, ChannelPermission.MentionEveryone, PermValue.Inherit); - TestHelper(value, ChannelPermission.UseExternalEmojis, PermValue.Inherit); - TestHelper(value, ChannelPermission.ManageRoles, PermValue.Inherit); - TestHelper(value, ChannelPermission.ManageWebhooks, PermValue.Inherit); - TestHelper(value, ChannelPermission.Connect, PermValue.Deny); - TestHelper(value, ChannelPermission.Speak, PermValue.Deny); - TestHelper(value, ChannelPermission.MuteMembers, PermValue.Inherit); - TestHelper(value, ChannelPermission.DeafenMembers, PermValue.Inherit); - TestHelper(value, ChannelPermission.MoveMembers, PermValue.Inherit); - TestHelper(value, ChannelPermission.UseVAD, PermValue.Deny); - - return Task.CompletedTask; - } - - /// - /// Test - /// for when all group permissions are allowed and denied - /// - /// - [Fact] - public Task TestOverwritePermissionsVoice() - { - // allow all for group channels - var value = new OverwritePermissions(ChannelPermissions.Voice.RawValue, ChannelPermissions.None.RawValue); - - TestHelper(value, ChannelPermission.CreateInstantInvite, PermValue.Allow); - TestHelper(value, ChannelPermission.ManageChannels, PermValue.Allow); - TestHelper(value, ChannelPermission.AddReactions, PermValue.Inherit); - TestHelper(value, ChannelPermission.ViewChannel, PermValue.Allow); - TestHelper(value, ChannelPermission.SendMessages, PermValue.Inherit); - TestHelper(value, ChannelPermission.SendTTSMessages, PermValue.Inherit); - TestHelper(value, ChannelPermission.ManageMessages, PermValue.Inherit); - TestHelper(value, ChannelPermission.EmbedLinks, PermValue.Inherit); - TestHelper(value, ChannelPermission.AttachFiles, PermValue.Inherit); - TestHelper(value, ChannelPermission.ReadMessageHistory, PermValue.Inherit); - TestHelper(value, ChannelPermission.MentionEveryone, PermValue.Inherit); - TestHelper(value, ChannelPermission.UseExternalEmojis, PermValue.Inherit); - TestHelper(value, ChannelPermission.ManageRoles, PermValue.Allow); - TestHelper(value, ChannelPermission.ManageWebhooks, PermValue.Inherit); - TestHelper(value, ChannelPermission.Connect, PermValue.Allow); - TestHelper(value, ChannelPermission.Speak, PermValue.Allow); - TestHelper(value, ChannelPermission.MuteMembers, PermValue.Allow); - TestHelper(value, ChannelPermission.DeafenMembers, PermValue.Allow); - TestHelper(value, ChannelPermission.MoveMembers, PermValue.Allow); - TestHelper(value, ChannelPermission.UseVAD, PermValue.Allow); - - value = new OverwritePermissions(ChannelPermissions.None.RawValue, ChannelPermissions.Voice.RawValue); - - TestHelper(value, ChannelPermission.CreateInstantInvite, PermValue.Deny); - TestHelper(value, ChannelPermission.ManageChannels, PermValue.Deny); - TestHelper(value, ChannelPermission.AddReactions, PermValue.Inherit); - TestHelper(value, ChannelPermission.ViewChannel, PermValue.Deny); - TestHelper(value, ChannelPermission.SendMessages, PermValue.Inherit); - TestHelper(value, ChannelPermission.SendTTSMessages, PermValue.Inherit); - TestHelper(value, ChannelPermission.ManageMessages, PermValue.Inherit); - TestHelper(value, ChannelPermission.EmbedLinks, PermValue.Inherit); - TestHelper(value, ChannelPermission.AttachFiles, PermValue.Inherit); - TestHelper(value, ChannelPermission.ReadMessageHistory, PermValue.Inherit); - TestHelper(value, ChannelPermission.MentionEveryone, PermValue.Inherit); - TestHelper(value, ChannelPermission.UseExternalEmojis, PermValue.Inherit); - TestHelper(value, ChannelPermission.ManageRoles, PermValue.Deny); - TestHelper(value, ChannelPermission.ManageWebhooks, PermValue.Inherit); - TestHelper(value, ChannelPermission.Connect, PermValue.Deny); - TestHelper(value, ChannelPermission.Speak, PermValue.Deny); - TestHelper(value, ChannelPermission.MuteMembers, PermValue.Deny); - TestHelper(value, ChannelPermission.DeafenMembers, PermValue.Deny); - TestHelper(value, ChannelPermission.MoveMembers, PermValue.Deny); - TestHelper(value, ChannelPermission.UseVAD, PermValue.Deny); - - return Task.CompletedTask; - } - - /// - /// Tests for the - /// method to ensure that the default no-param call does not modify the resulting value - /// of the OverwritePermissions. - /// - /// - [Fact] - public Task TestOverwritePermissionModifyNoParam() - { - // test for all Text allowed, none denied - var original = new OverwritePermissions(ChannelPermissions.Text.RawValue, ChannelPermissions.None.RawValue); - Assert.Equal(original.AllowValue, original.Modify().AllowValue); - Assert.Equal(original.DenyValue, original.Modify().DenyValue); - - // none allowed, text denied - original = new OverwritePermissions(ChannelPermissions.None.RawValue, ChannelPermissions.Text.RawValue); - Assert.Equal(original.AllowValue, original.Modify().AllowValue); - Assert.Equal(original.DenyValue, original.Modify().DenyValue); - - // category allowed, none denied - original = new OverwritePermissions(ChannelPermissions.Category.RawValue, ChannelPermissions.None.RawValue); - Assert.Equal(original.AllowValue, original.Modify().AllowValue); - Assert.Equal(original.DenyValue, original.Modify().DenyValue); - - // none allowed, category denied - original = new OverwritePermissions(ChannelPermissions.None.RawValue, ChannelPermissions.Category.RawValue); - Assert.Equal(original.AllowValue, original.Modify().AllowValue); - Assert.Equal(original.DenyValue, original.Modify().DenyValue); - - // DM allowed, none denied - original = new OverwritePermissions(ChannelPermissions.DM.RawValue, ChannelPermissions.None.RawValue); - Assert.Equal(original.AllowValue, original.Modify().AllowValue); - Assert.Equal(original.DenyValue, original.Modify().DenyValue); - - // none allowed, DM denied - original = new OverwritePermissions(ChannelPermissions.None.RawValue, ChannelPermissions.DM.RawValue); - Assert.Equal(original.AllowValue, original.Modify().AllowValue); - Assert.Equal(original.DenyValue, original.Modify().DenyValue); - - // voice allowed, none denied - original = new OverwritePermissions(ChannelPermissions.Voice.RawValue, ChannelPermissions.None.RawValue); - Assert.Equal(original.AllowValue, original.Modify().AllowValue); - Assert.Equal(original.DenyValue, original.Modify().DenyValue); - - // none allowed, voice denied - original = new OverwritePermissions(ChannelPermissions.None.RawValue, ChannelPermissions.Voice.RawValue); - Assert.Equal(original.AllowValue, original.Modify().AllowValue); - Assert.Equal(original.DenyValue, original.Modify().DenyValue); - - // group allowed, none denied - original = new OverwritePermissions(ChannelPermissions.Group.RawValue, ChannelPermissions.None.RawValue); - Assert.Equal(original.AllowValue, original.Modify().AllowValue); - Assert.Equal(original.DenyValue, original.Modify().DenyValue); - - // none allowed, group denied - original = new OverwritePermissions(ChannelPermissions.None.RawValue, ChannelPermissions.Group.RawValue); - Assert.Equal(original.AllowValue, original.Modify().AllowValue); - Assert.Equal(original.DenyValue, original.Modify().DenyValue); - - // none allowed, none denied - original = new OverwritePermissions(ChannelPermissions.None.RawValue, ChannelPermissions.None.RawValue); - Assert.Equal(original.AllowValue, original.Modify().AllowValue); - Assert.Equal(original.DenyValue, original.Modify().DenyValue); - - return Task.CompletedTask; - } - } -} diff --git a/test/Discord.Net.Tests/Tests.TypeReaders.cs b/test/Discord.Net.Tests/Tests.TypeReaders.cs deleted file mode 100644 index 91514bfae..000000000 --- a/test/Discord.Net.Tests/Tests.TypeReaders.cs +++ /dev/null @@ -1,133 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Threading.Tasks; -using Discord.Commands; -using Xunit; - -namespace Discord -{ - public sealed class TypeReaderTests - { - [Fact] - public async Task TestNamedArgumentReader() - { - var commands = new CommandService(); - var module = await commands.AddModuleAsync(null); - - Assert.NotNull(module); - Assert.NotEmpty(module.Commands); - - var cmd = module.Commands[0]; - Assert.NotNull(cmd); - Assert.NotEmpty(cmd.Parameters); - - var param = cmd.Parameters[0]; - Assert.NotNull(param); - Assert.True(param.IsRemainder); - - var result = await param.ParseAsync(null, "bar: hello foo: 42"); - Assert.True(result.IsSuccess); - - var m = result.BestMatch as ArgumentType; - Assert.NotNull(m); - Assert.Equal(expected: 42, actual: m.Foo); - Assert.Equal(expected: "hello", actual: m.Bar); - } - - [Fact] - public async Task TestQuotedArgumentValue() - { - var commands = new CommandService(); - var module = await commands.AddModuleAsync(null); - - Assert.NotNull(module); - Assert.NotEmpty(module.Commands); - - var cmd = module.Commands[0]; - Assert.NotNull(cmd); - Assert.NotEmpty(cmd.Parameters); - - var param = cmd.Parameters[0]; - Assert.NotNull(param); - Assert.True(param.IsRemainder); - - var result = await param.ParseAsync(null, "foo: 42 bar: 《hello》"); - Assert.True(result.IsSuccess); - - var m = result.BestMatch as ArgumentType; - Assert.NotNull(m); - Assert.Equal(expected: 42, actual: m.Foo); - Assert.Equal(expected: "hello", actual: m.Bar); - } - - [Fact] - public async Task TestNonPatternInput() - { - var commands = new CommandService(); - var module = await commands.AddModuleAsync(null); - - Assert.NotNull(module); - Assert.NotEmpty(module.Commands); - - var cmd = module.Commands[0]; - Assert.NotNull(cmd); - Assert.NotEmpty(cmd.Parameters); - - var param = cmd.Parameters[0]; - Assert.NotNull(param); - Assert.True(param.IsRemainder); - - var result = await param.ParseAsync(null, "foobar"); - Assert.False(result.IsSuccess); - Assert.Equal(expected: CommandError.Exception, actual: result.Error); - } - - [Fact] - public async Task TestMultiple() - { - var commands = new CommandService(); - var module = await commands.AddModuleAsync(null); - - Assert.NotNull(module); - Assert.NotEmpty(module.Commands); - - var cmd = module.Commands[0]; - Assert.NotNull(cmd); - Assert.NotEmpty(cmd.Parameters); - - var param = cmd.Parameters[0]; - Assert.NotNull(param); - Assert.True(param.IsRemainder); - - var result = await param.ParseAsync(null, "manyints: \"1, 2, 3, 4, 5, 6, 7\""); - Assert.True(result.IsSuccess); - - var m = result.BestMatch as ArgumentType; - Assert.NotNull(m); - Assert.Equal(expected: new int[] { 1, 2, 3, 4, 5, 6, 7 }, actual: m.ManyInts); - } - } - - [NamedArgumentType] - public sealed class ArgumentType - { - public int Foo { get; set; } - - [OverrideTypeReader(typeof(CustomTypeReader))] - public string Bar { get; set; } - - public IEnumerable ManyInts { get; set; } - } - - public sealed class CustomTypeReader : TypeReader - { - public override Task ReadAsync(ICommandContext context, string input, IServiceProvider services) - => Task.FromResult(TypeReaderResult.FromSuccess(input)); - } - - public sealed class TestModule : ModuleBase - { - [Command("test")] - public Task TestCommand(ArgumentType arg) => Task.Delay(0); - } -} diff --git a/test/Discord.Net.Tests/Tests.cs b/test/Discord.Net.Tests/Tests.cs deleted file mode 100644 index a3d6bd95e..000000000 --- a/test/Discord.Net.Tests/Tests.cs +++ /dev/null @@ -1,55 +0,0 @@ -using System; -using Discord.Net; -using Discord.Rest; -using Xunit; -// TODO: re-enable ix testing at a later date -#if IXTEST -namespace Discord -{ - public partial class TestsFixture : IDisposable - { - private readonly TestConfig _config; - private readonly CachedRestClient _cache; - internal readonly DiscordRestClient _client; - internal readonly RestGuild _guild; - - public TestsFixture() - { - _cache = new CachedRestClient(); - - _config = TestConfig.LoadFile("./config.json"); - var config = new DiscordRestConfig - { - RestClientProvider = url => - { - _cache.SetUrl(url); - return _cache; - } - }; - _client = new DiscordRestClient(config); - _client.LoginAsync(TokenType.Bot, _config.Token).Wait(); - - MigrateAsync().Wait(); - _guild = _client.GetGuildAsync(_config.GuildId).Result; - } - - public void Dispose() - { - _client.Dispose(); - _cache.Dispose(); - } - } - - public partial class Tests : IClassFixture - { - private DiscordRestClient _client; - private RestGuild _guild; - - public Tests(TestsFixture fixture) - { - _client = fixture._client; - _guild = fixture._guild; - } - } -} -#endif diff --git a/test/Discord.Net.Tests/config.json.example b/test/Discord.Net.Tests/config.json.example deleted file mode 100644 index 403afa3bd..000000000 --- a/test/Discord.Net.Tests/config.json.example +++ /dev/null @@ -1,4 +0,0 @@ -{ - "token": "AAA.BBB.CCC", - "guild_id": 1234567890 -} \ No newline at end of file diff --git a/test/Discord.Net.Tests/xunit.runner.json b/test/Discord.Net.Tests/xunit.runner.json deleted file mode 100644 index ac3e63046..000000000 --- a/test/Discord.Net.Tests/xunit.runner.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "diagnosticMessages": true, - "methodDisplay": "classAndMethod" -} \ No newline at end of file