* Add ExplicitContentFilter property to Guild * re-order properties to match order listed on api docs * re-order SystemChannelId to match api docs * Implement ApplicationId in Guild model * Add ExplicitContentFilter property to Guild * re-order properties to match order listed on api docs * re-order SystemChannelId to match api docs * Implement ApplicationId in Guild model * Improve xmldoc for IGuild ExplicitContentFilter * Update xmldoc * docs "Id" -> "ID" * rename Test.GuildPermissions to a more general Test.Guilds * Add ExplicitContentFilter to GuildProperties * Add a test for ExplicitContentFilterLevel modification behavior * Implement ModifyAsync behavior * simplify ExplicitContentFilter test * Add RestGuild ApplicationId inheritdoc * Implement message Activity and Application model update * RestMessage Application and Activity implementation * add ToString to MessageApplication * Add IconUrl property to MessageApplication * clean up whitespace * another excessive whitespace removaltags/2.0
| @@ -0,0 +1,13 @@ | |||||
| namespace Discord | |||||
| { | |||||
| public enum ExplicitContentFilterLevel | |||||
| { | |||||
| /// <summary> No messages will be scanned. </summary> | |||||
| Disabled = 0, | |||||
| /// <summary> Scans messages from all guild members that do not have a role. </summary> | |||||
| /// <remarks> Recommented option for servers that use roles for trusted membership. </remarks> | |||||
| MembersWithoutRoles = 1, | |||||
| /// <summary> Scan messages sent by all guild members. </summary> | |||||
| AllMembers = 2 | |||||
| } | |||||
| } | |||||
| @@ -66,5 +66,9 @@ namespace Discord | |||||
| /// Gets or sets the ID of the owner of this guild. | /// Gets or sets the ID of the owner of this guild. | ||||
| /// </summary> | /// </summary> | ||||
| public Optional<ulong> OwnerId { get; set; } | public Optional<ulong> OwnerId { get; set; } | ||||
| /// <summary> | |||||
| /// Gets or sets the explicit content filter level of this guild. | |||||
| /// </summary> | |||||
| public Optional<ExplicitContentFilterLevel> ExplicitContentFilter { get; set; } | |||||
| } | } | ||||
| } | } | ||||
| @@ -53,6 +53,13 @@ namespace Discord | |||||
| /// </returns> | /// </returns> | ||||
| VerificationLevel VerificationLevel { get; } | VerificationLevel VerificationLevel { get; } | ||||
| /// <summary> | /// <summary> | ||||
| /// Gets the level of content filtering applied to user's content in a Guild. | |||||
| /// </summary> | |||||
| /// <returns> | |||||
| /// The level of explicit content filtering. | |||||
| /// </returns> | |||||
| ExplicitContentFilterLevel ExplicitContentFilter { get; } | |||||
| /// <summary> | |||||
| /// Gets the ID of this guild's icon. | /// Gets the ID of this guild's icon. | ||||
| /// </summary> | /// </summary> | ||||
| /// <returns> | /// <returns> | ||||
| @@ -141,6 +148,13 @@ namespace Discord | |||||
| /// </returns> | /// </returns> | ||||
| ulong OwnerId { get; } | ulong OwnerId { get; } | ||||
| /// <summary> | /// <summary> | ||||
| /// Gets the application ID of the guild creator if it is bot-created. | |||||
| /// </summary> | |||||
| /// <returns> | |||||
| /// A <see cref="ulong"/> representing the snowflake identifier of the application ID that created this guild, or <c>null</c> if it was not bot-created. | |||||
| /// </returns> | |||||
| ulong? ApplicationId { get; } | |||||
| /// <summary> | |||||
| /// Gets the ID of the region hosting this guild's voice channels. | /// Gets the ID of the region hosting this guild's voice channels. | ||||
| /// </summary> | /// </summary> | ||||
| /// <returns> | /// <returns> | ||||
| @@ -100,5 +100,25 @@ namespace Discord | |||||
| /// A read-only collection of user IDs. | /// A read-only collection of user IDs. | ||||
| /// </returns> | /// </returns> | ||||
| IReadOnlyCollection<ulong> MentionedUserIds { get; } | IReadOnlyCollection<ulong> MentionedUserIds { get; } | ||||
| /// <summary> | |||||
| /// Returns the Activity associated with a message. | |||||
| /// </summary> | |||||
| /// <remarks> | |||||
| /// Sent with Rich Presence-related chat embeds. | |||||
| /// </remarks> | |||||
| /// <returns> | |||||
| /// A message's activity, if any is associated. | |||||
| /// </returns> | |||||
| MessageActivity Activity { get; } | |||||
| /// <summary> | |||||
| /// Returns the Application associated with a messsage. | |||||
| /// </summary> | |||||
| /// <remarks> | |||||
| /// Sent with Rich-Presence-related chat embeds. | |||||
| /// </remarks> | |||||
| /// <returns> | |||||
| /// A message's application, if any is associated. | |||||
| /// </returns> | |||||
| MessageApplication Application { get; } | |||||
| } | } | ||||
| } | } | ||||
| @@ -0,0 +1,27 @@ | |||||
| using System; | |||||
| using System.Collections.Generic; | |||||
| using System.Diagnostics; | |||||
| using System.Linq; | |||||
| using System.Text; | |||||
| using System.Threading.Tasks; | |||||
| namespace Discord | |||||
| { | |||||
| [DebuggerDisplay(@"{DebuggerDisplay,nq}")] | |||||
| public class MessageActivity | |||||
| { | |||||
| /// <summary> | |||||
| /// Gets the type of activity of this message. | |||||
| /// </summary> | |||||
| public MessageActivityType Type { get; set; } | |||||
| /// <summary> | |||||
| /// Gets the party ID of this activity, if any. | |||||
| /// </summary> | |||||
| public string PartyId { get; set; } | |||||
| private string DebuggerDisplay | |||||
| => $"{Type}{(string.IsNullOrWhiteSpace(PartyId) ? "" : $" {PartyId}")}"; | |||||
| public override string ToString() => DebuggerDisplay; | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,16 @@ | |||||
| using System; | |||||
| using System.Collections.Generic; | |||||
| using System.Linq; | |||||
| using System.Text; | |||||
| using System.Threading.Tasks; | |||||
| namespace Discord | |||||
| { | |||||
| public enum MessageActivityType | |||||
| { | |||||
| Join = 1, | |||||
| Spectate = 2, | |||||
| Listen = 3, | |||||
| JoinRequest = 5 | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,43 @@ | |||||
| using System; | |||||
| using System.Collections.Generic; | |||||
| using System.Diagnostics; | |||||
| using System.Linq; | |||||
| using System.Text; | |||||
| using System.Threading.Tasks; | |||||
| namespace Discord | |||||
| { | |||||
| [DebuggerDisplay(@"{DebuggerDisplay,nq}")] | |||||
| public class MessageApplication | |||||
| { | |||||
| /// <summary> | |||||
| /// Gets the snowflake ID of the application. | |||||
| /// </summary> | |||||
| public ulong Id { get; set; } | |||||
| /// <summary> | |||||
| /// Gets the ID of the embed's image asset. | |||||
| /// </summary> | |||||
| public string CoverImage { get; set; } | |||||
| /// <summary> | |||||
| /// Gets the application's description. | |||||
| /// </summary> | |||||
| public string Description { get; set; } | |||||
| /// <summary> | |||||
| /// Gets the ID of the application's icon. | |||||
| /// </summary> | |||||
| public string Icon { get; set; } | |||||
| /// <summary> | |||||
| /// Gets the Url of the application's icon. | |||||
| /// </summary> | |||||
| public string IconUrl | |||||
| => $"https://cdn.discordapp.com/app-icons/{Id}/{Icon}"; | |||||
| /// <summary> | |||||
| /// Gets the name of the application. | |||||
| /// </summary> | |||||
| public string Name { get; set; } | |||||
| private string DebuggerDisplay | |||||
| => $"{Name} ({Id}): {Description}"; | |||||
| public override string ToString() | |||||
| => DebuggerDisplay; | |||||
| } | |||||
| } | |||||
| @@ -1,4 +1,4 @@ | |||||
| #pragma warning disable CS1591 | |||||
| #pragma warning disable CS1591 | |||||
| using Newtonsoft.Json; | using Newtonsoft.Json; | ||||
| namespace Discord.API | namespace Discord.API | ||||
| @@ -25,10 +25,12 @@ namespace Discord.API | |||||
| public bool EmbedEnabled { get; set; } | public bool EmbedEnabled { get; set; } | ||||
| [JsonProperty("embed_channel_id")] | [JsonProperty("embed_channel_id")] | ||||
| public ulong? EmbedChannelId { get; set; } | public ulong? EmbedChannelId { get; set; } | ||||
| [JsonProperty("system_channel_id")] | |||||
| public ulong? SystemChannelId { get; set; } | |||||
| [JsonProperty("verification_level")] | [JsonProperty("verification_level")] | ||||
| public VerificationLevel VerificationLevel { get; set; } | public VerificationLevel VerificationLevel { get; set; } | ||||
| [JsonProperty("default_message_notifications")] | |||||
| public DefaultMessageNotifications DefaultMessageNotifications { get; set; } | |||||
| [JsonProperty("explicit_content_filter")] | |||||
| public ExplicitContentFilterLevel ExplicitContentFilter { get; set; } | |||||
| [JsonProperty("voice_states")] | [JsonProperty("voice_states")] | ||||
| public VoiceState[] VoiceStates { get; set; } | public VoiceState[] VoiceStates { get; set; } | ||||
| [JsonProperty("roles")] | [JsonProperty("roles")] | ||||
| @@ -39,7 +41,9 @@ namespace Discord.API | |||||
| public string[] Features { get; set; } | public string[] Features { get; set; } | ||||
| [JsonProperty("mfa_level")] | [JsonProperty("mfa_level")] | ||||
| public MfaLevel MfaLevel { get; set; } | public MfaLevel MfaLevel { get; set; } | ||||
| [JsonProperty("default_message_notifications")] | |||||
| public DefaultMessageNotifications DefaultMessageNotifications { get; set; } | |||||
| [JsonProperty("application_id")] | |||||
| public ulong? ApplicationId { get; set; } | |||||
| [JsonProperty("system_channel_id")] | |||||
| public ulong? SystemChannelId { get; set; } | |||||
| } | } | ||||
| } | } | ||||
| @@ -44,5 +44,11 @@ namespace Discord.API | |||||
| public Optional<bool> Pinned { get; set; } | public Optional<bool> Pinned { get; set; } | ||||
| [JsonProperty("reactions")] | [JsonProperty("reactions")] | ||||
| public Optional<Reaction[]> Reactions { get; set; } | public Optional<Reaction[]> Reactions { get; set; } | ||||
| // sent with Rich Presence-related chat embeds | |||||
| [JsonProperty("activity")] | |||||
| public Optional<MessageActivity> Activity { get; set; } | |||||
| // sent with Rich Presence-related chat embeds | |||||
| [JsonProperty("application")] | |||||
| public Optional<MessageApplication> Application { get; set; } | |||||
| } | } | ||||
| } | } | ||||
| @@ -0,0 +1,17 @@ | |||||
| using Newtonsoft.Json; | |||||
| using System; | |||||
| using System.Collections.Generic; | |||||
| using System.Linq; | |||||
| using System.Text; | |||||
| using System.Threading.Tasks; | |||||
| namespace Discord.API | |||||
| { | |||||
| public class MessageActivity | |||||
| { | |||||
| [JsonProperty("type")] | |||||
| public Optional<MessageActivityType> Type { get; set; } | |||||
| [JsonProperty("party_id")] | |||||
| public Optional<string> PartyId { get; set; } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,38 @@ | |||||
| using Newtonsoft.Json; | |||||
| using System; | |||||
| using System.Collections.Generic; | |||||
| using System.Linq; | |||||
| using System.Text; | |||||
| using System.Threading.Tasks; | |||||
| namespace Discord.API | |||||
| { | |||||
| public class MessageApplication | |||||
| { | |||||
| /// <summary> | |||||
| /// Gets the snowflake ID of the application. | |||||
| /// </summary> | |||||
| [JsonProperty("id")] | |||||
| public ulong Id { get; set; } | |||||
| /// <summary> | |||||
| /// Gets the ID of the embed's image asset. | |||||
| /// </summary> | |||||
| [JsonProperty("cover_image")] | |||||
| public string CoverImage { get; set; } | |||||
| /// <summary> | |||||
| /// Gets the application's description. | |||||
| /// </summary> | |||||
| [JsonProperty("description")] | |||||
| public string Description { get; set; } | |||||
| /// <summary> | |||||
| /// Gets the ID of the application's icon. | |||||
| /// </summary> | |||||
| [JsonProperty("icon")] | |||||
| public string Icon { get; set; } | |||||
| /// <summary> | |||||
| /// Gets the name of the application. | |||||
| /// </summary> | |||||
| [JsonProperty("name")] | |||||
| public string Name { get; set; } | |||||
| } | |||||
| } | |||||
| @@ -1,4 +1,4 @@ | |||||
| #pragma warning disable CS1591 | |||||
| #pragma warning disable CS1591 | |||||
| using Newtonsoft.Json; | using Newtonsoft.Json; | ||||
| namespace Discord.API.Rest | namespace Discord.API.Rest | ||||
| @@ -28,5 +28,7 @@ namespace Discord.API.Rest | |||||
| public Optional<ulong?> AfkChannelId { get; set; } | public Optional<ulong?> AfkChannelId { get; set; } | ||||
| [JsonProperty("owner_id")] | [JsonProperty("owner_id")] | ||||
| public Optional<ulong> OwnerId { get; set; } | public Optional<ulong> OwnerId { get; set; } | ||||
| [JsonProperty("explicit_content_filter")] | |||||
| public Optional<ExplicitContentFilterLevel> ExplicitContentFilter { get; set; } | |||||
| } | } | ||||
| } | } | ||||
| @@ -32,7 +32,8 @@ namespace Discord.Rest | |||||
| Icon = args.Icon.IsSpecified ? args.Icon.Value?.ToModel() : Optional.Create<ImageModel?>(), | Icon = args.Icon.IsSpecified ? args.Icon.Value?.ToModel() : Optional.Create<ImageModel?>(), | ||||
| Name = args.Name, | Name = args.Name, | ||||
| Splash = args.Splash.IsSpecified ? args.Splash.Value?.ToModel() : Optional.Create<ImageModel?>(), | Splash = args.Splash.IsSpecified ? args.Splash.Value?.ToModel() : Optional.Create<ImageModel?>(), | ||||
| VerificationLevel = args.VerificationLevel | |||||
| VerificationLevel = args.VerificationLevel, | |||||
| ExplicitContentFilter = args.ExplicitContentFilter | |||||
| }; | }; | ||||
| if (args.AfkChannel.IsSpecified) | if (args.AfkChannel.IsSpecified) | ||||
| @@ -60,6 +61,9 @@ namespace Discord.Rest | |||||
| if (!apiArgs.Icon.IsSpecified && guild.IconId != null) | if (!apiArgs.Icon.IsSpecified && guild.IconId != null) | ||||
| apiArgs.Icon = new ImageModel(guild.IconId); | apiArgs.Icon = new ImageModel(guild.IconId); | ||||
| if (args.ExplicitContentFilter.IsSpecified) | |||||
| apiArgs.ExplicitContentFilter = args.ExplicitContentFilter.Value; | |||||
| return await client.ApiClient.ModifyGuildAsync(guild.Id, apiArgs, options).ConfigureAwait(false); | return await client.ApiClient.ModifyGuildAsync(guild.Id, apiArgs, options).ConfigureAwait(false); | ||||
| } | } | ||||
| /// <exception cref="ArgumentNullException"><paramref name="func"/> is <c>null</c>.</exception> | /// <exception cref="ArgumentNullException"><paramref name="func"/> is <c>null</c>.</exception> | ||||
| @@ -32,6 +32,8 @@ namespace Discord.Rest | |||||
| public MfaLevel MfaLevel { get; private set; } | public MfaLevel MfaLevel { get; private set; } | ||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| public DefaultMessageNotifications DefaultMessageNotifications { get; private set; } | public DefaultMessageNotifications DefaultMessageNotifications { get; private set; } | ||||
| /// <inheritdoc /> | |||||
| public ExplicitContentFilterLevel ExplicitContentFilter { get; private set; } | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| public ulong? AFKChannelId { get; private set; } | public ulong? AFKChannelId { get; private set; } | ||||
| @@ -48,6 +50,8 @@ namespace Discord.Rest | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| public string SplashId { get; private set; } | public string SplashId { get; private set; } | ||||
| internal bool Available { get; private set; } | internal bool Available { get; private set; } | ||||
| /// <inheritdoc /> | |||||
| public ulong? ApplicationId { get; private set; } | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| public DateTimeOffset CreatedAt => SnowflakeUtils.FromSnowflake(Id); | public DateTimeOffset CreatedAt => SnowflakeUtils.FromSnowflake(Id); | ||||
| @@ -98,6 +102,8 @@ namespace Discord.Rest | |||||
| VerificationLevel = model.VerificationLevel; | VerificationLevel = model.VerificationLevel; | ||||
| MfaLevel = model.MfaLevel; | MfaLevel = model.MfaLevel; | ||||
| DefaultMessageNotifications = model.DefaultMessageNotifications; | DefaultMessageNotifications = model.DefaultMessageNotifications; | ||||
| ExplicitContentFilter = model.ExplicitContentFilter; | |||||
| ApplicationId = model.ApplicationId; | |||||
| if (model.Emojis != null) | if (model.Emojis != null) | ||||
| { | { | ||||
| @@ -55,6 +55,10 @@ namespace Discord.Rest | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| public DateTimeOffset Timestamp => DateTimeUtils.FromTicks(_timestampTicks); | public DateTimeOffset Timestamp => DateTimeUtils.FromTicks(_timestampTicks); | ||||
| /// <inheritdoc /> | |||||
| public MessageActivity Activity { get; private set; } | |||||
| /// <inheritdoc /> | |||||
| public MessageApplication Application { get; private set; } | |||||
| internal RestMessage(BaseDiscordClient discord, ulong id, IMessageChannel channel, IUser author, MessageSource source) | internal RestMessage(BaseDiscordClient discord, ulong id, IMessageChannel channel, IUser author, MessageSource source) | ||||
| : base(discord, id) | : base(discord, id) | ||||
| @@ -77,6 +81,29 @@ namespace Discord.Rest | |||||
| if (model.Content.IsSpecified) | if (model.Content.IsSpecified) | ||||
| Content = model.Content.Value; | Content = model.Content.Value; | ||||
| if (model.Application.IsSpecified) | |||||
| { | |||||
| // create a new Application from the API model | |||||
| Application = new MessageApplication() | |||||
| { | |||||
| Id = model.Application.Value.Id, | |||||
| CoverImage = model.Application.Value.CoverImage, | |||||
| Description = model.Application.Value.Description, | |||||
| Icon = model.Application.Value.Icon, | |||||
| Name = model.Application.Value.Name | |||||
| }; | |||||
| } | |||||
| if (model.Activity.IsSpecified) | |||||
| { | |||||
| // create a new Activity from the API model | |||||
| Activity = new MessageActivity() | |||||
| { | |||||
| Type = model.Activity.Value.Type.Value, | |||||
| PartyId = model.Activity.Value.PartyId.Value | |||||
| }; | |||||
| } | |||||
| } | } | ||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| @@ -50,6 +50,8 @@ namespace Discord.WebSocket | |||||
| public MfaLevel MfaLevel { get; private set; } | public MfaLevel MfaLevel { get; private set; } | ||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| public DefaultMessageNotifications DefaultMessageNotifications { get; private set; } | public DefaultMessageNotifications DefaultMessageNotifications { get; private set; } | ||||
| /// <inheritdoc /> | |||||
| public ExplicitContentFilterLevel ExplicitContentFilter { get; private set; } | |||||
| /// <summary> | /// <summary> | ||||
| /// Gets the number of members. | /// Gets the number of members. | ||||
| /// </summary> | /// </summary> | ||||
| @@ -73,6 +75,8 @@ namespace Discord.WebSocket | |||||
| internal bool IsAvailable { get; private set; } | internal bool IsAvailable { get; private set; } | ||||
| /// <summary> Indicates whether the client is connected to this guild. </summary> | /// <summary> Indicates whether the client is connected to this guild. </summary> | ||||
| public bool IsConnected { get; internal set; } | public bool IsConnected { get; internal set; } | ||||
| /// <inheritdoc /> | |||||
| public ulong? ApplicationId { get; internal set; } | |||||
| internal ulong? AFKChannelId { get; private set; } | internal ulong? AFKChannelId { get; private set; } | ||||
| internal ulong? EmbedChannelId { get; private set; } | internal ulong? EmbedChannelId { get; private set; } | ||||
| @@ -346,6 +350,8 @@ namespace Discord.WebSocket | |||||
| VerificationLevel = model.VerificationLevel; | VerificationLevel = model.VerificationLevel; | ||||
| MfaLevel = model.MfaLevel; | MfaLevel = model.MfaLevel; | ||||
| DefaultMessageNotifications = model.DefaultMessageNotifications; | DefaultMessageNotifications = model.DefaultMessageNotifications; | ||||
| ExplicitContentFilter = model.ExplicitContentFilter; | |||||
| ApplicationId = model.ApplicationId; | |||||
| if (model.Emojis != null) | if (model.Emojis != null) | ||||
| { | { | ||||
| @@ -43,6 +43,13 @@ namespace Discord.WebSocket | |||||
| public virtual bool IsPinned => false; | public virtual bool IsPinned => false; | ||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| public virtual DateTimeOffset? EditedTimestamp => null; | public virtual DateTimeOffset? EditedTimestamp => null; | ||||
| /// <inheritdoc /> | |||||
| public MessageActivity Activity { get; private set; } | |||||
| /// <inheritdoc /> | |||||
| public MessageApplication Application { get; private set; } | |||||
| /// <summary> | /// <summary> | ||||
| /// Returns all attachments included in this message. | /// Returns all attachments included in this message. | ||||
| /// </summary> | /// </summary> | ||||
| @@ -105,6 +112,29 @@ namespace Discord.WebSocket | |||||
| if (model.Content.IsSpecified) | if (model.Content.IsSpecified) | ||||
| Content = model.Content.Value; | Content = model.Content.Value; | ||||
| if (model.Application.IsSpecified) | |||||
| { | |||||
| // create a new Application from the API model | |||||
| Application = new MessageApplication() | |||||
| { | |||||
| Id = model.Application.Value.Id, | |||||
| CoverImage = model.Application.Value.CoverImage, | |||||
| Description = model.Application.Value.Description, | |||||
| Icon = model.Application.Value.Icon, | |||||
| Name = model.Application.Value.Name | |||||
| }; | |||||
| } | |||||
| if (model.Activity.IsSpecified) | |||||
| { | |||||
| // create a new Activity from the API model | |||||
| Activity = new MessageActivity() | |||||
| { | |||||
| Type = model.Activity.Value.Type.Value, | |||||
| PartyId = model.Activity.Value.PartyId.Value | |||||
| }; | |||||
| } | |||||
| } | } | ||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| @@ -5,8 +5,25 @@ using Xunit; | |||||
| namespace Discord | namespace Discord | ||||
| { | { | ||||
| public class GuidPermissionsTests | |||||
| public partial class Tests | |||||
| { | { | ||||
| /// <summary> | |||||
| /// Tests the behavior of modifying the ExplicitContentFilter property of a Guild. | |||||
| /// </summary> | |||||
| [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); | |||||
| } | |||||
| } | |||||
| /// <summary> | |||||
| /// Tests the behavior of the GuildPermissions class. | |||||
| /// </summary> | |||||
| [Fact] | [Fact] | ||||
| public Task TestGuildPermission() | public Task TestGuildPermission() | ||||
| { | { | ||||