* 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 brokepull/1329/head
@@ -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} | |||
@@ -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 | |||
@@ -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")] | |||
[assembly: InternalsVisibleTo("Discord.Net.Tests.Unit")] |
@@ -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; | |||
} | |||
@@ -0,0 +1,24 @@ | |||
<Project Sdk="Microsoft.NET.Sdk"> | |||
<PropertyGroup> | |||
<TargetFramework>netcoreapp2.1</TargetFramework> | |||
<IsPackable>false</IsPackable> | |||
</PropertyGroup> | |||
<ItemGroup> | |||
<ProjectReference Include="../../src/Discord.Net.Commands/Discord.Net.Commands.csproj" /> | |||
<ProjectReference Include="../../src/Discord.Net.Core/Discord.Net.Core.csproj" /> | |||
<ProjectReference Include="../../src/Discord.Net.Rest/Discord.Net.Rest.csproj" /> | |||
<ProjectReference Include="../../src/Discord.Net.Analyzers/Discord.Net.Analyzers.csproj" /> | |||
<ProjectReference Include="..\..\src\Discord.Net.WebSocket\Discord.Net.WebSocket.csproj" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<PackageReference Include="Microsoft.CodeAnalysis" Version="3.0.0-beta4-final" /> | |||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" /> | |||
<PackageReference Include="xunit" Version="2.4.0" /> | |||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.0" /> | |||
</ItemGroup> | |||
</Project> |
@@ -0,0 +1,163 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
using Xunit; | |||
using Xunit.Abstractions; | |||
namespace Discord | |||
{ | |||
/// <summary> | |||
/// Tests that channels can be created and modified. | |||
/// </summary> | |||
[CollectionDefinition("ChannelsTests", DisableParallelization = true)] | |||
public class ChannelsTests : IClassFixture<RestGuildFixture> | |||
{ | |||
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; | |||
} | |||
/// <summary> | |||
/// Checks that a text channel can be created and modified. | |||
/// </summary> | |||
[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(); | |||
} | |||
} | |||
/// <summary> | |||
/// Checks that a voice channel can be created, modified, and deleted. | |||
/// </summary> | |||
[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(); | |||
} | |||
} | |||
/// <summary> | |||
/// Creates a category channel, a voice channel, and a text channel, then tries to assign them under that category. | |||
/// </summary> | |||
[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(); | |||
} | |||
} | |||
} | |||
} |
@@ -0,0 +1,27 @@ | |||
<Project Sdk="Microsoft.NET.Sdk"> | |||
<PropertyGroup> | |||
<TargetFramework>netcoreapp2.1</TargetFramework> | |||
<IsPackable>false</IsPackable> | |||
</PropertyGroup> | |||
<ItemGroup> | |||
<ProjectReference Include="../../src/Discord.Net.Commands/Discord.Net.Commands.csproj" /> | |||
<ProjectReference Include="../../src/Discord.Net.Core/Discord.Net.Core.csproj" /> | |||
<ProjectReference Include="../../src/Discord.Net.Rest/Discord.Net.Rest.csproj" /> | |||
<ProjectReference Include="../../src/Discord.Net.Analyzers/Discord.Net.Analyzers.csproj" /> | |||
<ProjectReference Include="..\..\src\Discord.Net.WebSocket\Discord.Net.WebSocket.csproj" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" /> | |||
<PackageReference Include="xunit" Version="2.4.0" /> | |||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.0" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<Folder Include="Properties\" /> | |||
</ItemGroup> | |||
</Project> |
@@ -0,0 +1,34 @@ | |||
using Discord.Rest; | |||
using System; | |||
using Xunit; | |||
namespace Discord | |||
{ | |||
/// <summary> | |||
/// Test fixture type for integration tests which sets up the client from | |||
/// the token provided in environment variables. | |||
/// </summary> | |||
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(); | |||
} | |||
} | |||
} |
@@ -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<RestGuildFixture> | |||
{ | |||
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; | |||
} | |||
/// <summary> | |||
/// Ensures that the CurrentUser is the owner of the guild. | |||
/// </summary> | |||
[Fact] | |||
public void CheckOwner() | |||
{ | |||
Assert.Equal(client.CurrentUser.Id, guild.OwnerId); | |||
} | |||
/// <summary> | |||
/// Checks that a Guild can be modified to non-default values. | |||
/// </summary> | |||
[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); | |||
} | |||
/// <summary> | |||
/// Checks that the SystemChannel property of a guild can be modified. | |||
/// </summary> | |||
[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<ITextChannel>(systemChannel); }); | |||
Assert.Equal(systemChannel.Id, guild.SystemChannelId); | |||
await Assert.ThrowsAsync<NullReferenceException>( async () => | |||
{ | |||
await guild.ModifyAsync(x => x.SystemChannel = null); | |||
}); | |||
await systemChannel.DeleteAsync(); | |||
} | |||
/// <summary> | |||
/// Checks that the AFK channel of a guild can be set. | |||
/// </summary> | |||
[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<IVoiceChannel>(afkChannel)); | |||
Assert.Equal(afkChannel.Id, guild.AFKChannelId); | |||
await Assert.ThrowsAsync<NullReferenceException>( async () => | |||
{ | |||
await guild.ModifyAsync(x => x.AfkChannel = null); | |||
}); | |||
await afkChannel.DeleteAsync(); | |||
} | |||
} | |||
} |
@@ -0,0 +1,44 @@ | |||
using Discord.Rest; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Text; | |||
using System.Linq; | |||
namespace Discord | |||
{ | |||
/// <summary> | |||
/// Gets or creates a guild to use for testing. | |||
/// </summary> | |||
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(); | |||
} | |||
} | |||
/// <summary> | |||
/// Removes all channels in the guild. | |||
/// </summary> | |||
private void RemoveAllChannels() | |||
{ | |||
foreach (var channel in Guild.GetChannelsAsync().Result) | |||
{ | |||
channel.DeleteAsync().Wait(); | |||
} | |||
} | |||
} | |||
} |
@@ -0,0 +1,223 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using Xunit; | |||
namespace Discord | |||
{ | |||
/// <summary> | |||
/// Tests the behavior of the <see cref="Discord.ChannelPermissions"/> type and related functions. | |||
/// </summary> | |||
public class ChannelPermissionsTests | |||
{ | |||
/// <summary> | |||
/// Tests the default value of the <see cref="Discord.ChannelPermissions"/> constructor. | |||
/// </summary> | |||
[Fact] | |||
public void DefaultConstructor() | |||
{ | |||
var permission = new ChannelPermissions(); | |||
Assert.Equal((ulong)0, permission.RawValue); | |||
Assert.Equal(ChannelPermissions.None.RawValue, permission.RawValue); | |||
} | |||
/// <summary> | |||
/// Tests the behavior of the <see cref="Discord.ChannelPermission"/> raw value constructor. | |||
/// </summary> | |||
[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<ulong> 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); | |||
} | |||
} | |||
/// <summary> | |||
/// Tests the behavior of the <see cref="Discord.ChannelPermissions"/> constructor for each | |||
/// of it's flags. | |||
/// </summary> | |||
[Fact] | |||
public void FlagsConstructor() | |||
{ | |||
// util method for asserting that the constructor sets the given flag | |||
void AssertFlag(Func<ChannelPermissions> 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); | |||
} | |||
/// <summary> | |||
/// Tests the behavior of <see cref="Discord.ChannelPermissions.Modify(bool?, bool?, bool?, bool?, bool?, bool?, bool?, bool?, bool?, bool?, bool?, bool?, bool?, bool?, bool?, bool?, bool?, bool?, bool?, bool?, bool?)"/> | |||
/// with each of the parameters. | |||
/// </summary> | |||
[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<ChannelPermissions, bool> has, | |||
Func<ChannelPermissions, bool, ChannelPermissions> 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)); | |||
} | |||
/// <summary> | |||
/// Tests that <see cref="ChannelPermissions.All(IChannel)"/> for a null channel will throw an <see cref="ArgumentException"/>. | |||
/// </summary> | |||
[Fact] | |||
public void ChannelTypeResolution_Null() | |||
{ | |||
Assert.Throws<ArgumentException>(() => | |||
{ | |||
ChannelPermissions.All(null); | |||
}); | |||
} | |||
/// <summary> | |||
/// Tests that <see cref="ChannelPermissions.All(IChannel)"/> for an <see cref="ITextChannel"/> will return a value | |||
/// equivalent to <see cref="ChannelPermissions.Text"/>. | |||
/// </summary> | |||
[Fact] | |||
public void ChannelTypeResolution_Text() | |||
{ | |||
Assert.Equal(ChannelPermissions.Text.RawValue, ChannelPermissions.All(new MockedTextChannel()).RawValue); | |||
} | |||
/// <summary> | |||
/// Tests that <see cref="ChannelPermissions.All(IChannel)"/> for an <see cref="IVoiceChannel"/> will return a value | |||
/// equivalent to <see cref="ChannelPermissions.Voice"/>. | |||
/// </summary> | |||
[Fact] | |||
public void ChannelTypeResolution_Voice() | |||
{ | |||
Assert.Equal(ChannelPermissions.Voice.RawValue, ChannelPermissions.All(new MockedVoiceChannel()).RawValue); | |||
} | |||
/// <summary> | |||
/// Tests that <see cref="ChannelPermissions.All(IChannel)"/> for an <see cref="ICategoryChannel"/> will return a value | |||
/// equivalent to <see cref="ChannelPermissions.Category"/>. | |||
/// </summary> | |||
[Fact] | |||
public void ChannelTypeResolution_Category() | |||
{ | |||
Assert.Equal(ChannelPermissions.Category.RawValue, ChannelPermissions.All(new MockedCategoryChannel()).RawValue); | |||
} | |||
/// <summary> | |||
/// Tests that <see cref="ChannelPermissions.All(IChannel)"/> for an <see cref="IDMChannel"/> will return a value | |||
/// equivalent to <see cref="ChannelPermissions.DM"/>. | |||
/// </summary> | |||
[Fact] | |||
public void ChannelTypeResolution_DM() | |||
{ | |||
Assert.Equal(ChannelPermissions.DM.RawValue, ChannelPermissions.All(new MockedDMChannel()).RawValue); | |||
} | |||
/// <summary> | |||
/// Tests that <see cref="ChannelPermissions.All(IChannel)"/> for an <see cref="IGroupChannel"/> will return a value | |||
/// equivalent to <see cref="ChannelPermissions.Group"/>. | |||
/// </summary> | |||
[Fact] | |||
public void ChannelTypeResolution_Group() | |||
{ | |||
Assert.Equal(ChannelPermissions.Group.RawValue, ChannelPermissions.All(new MockedGroupChannel()).RawValue); | |||
} | |||
/// <summary> | |||
/// Tests that <see cref="ChannelPermissions.All(IChannel)"/> for an invalid channel will throw an <see cref="ArgumentException"/>. | |||
/// </summary> | |||
[Fact] | |||
public void ChannelTypeResolution_Invalid() | |||
{ | |||
Assert.Throws<ArgumentException>(() => ChannelPermissions.All(new MockedInvalidChannel())); | |||
} | |||
} | |||
} |
@@ -1,8 +1,13 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Text; | |||
using Xunit; | |||
namespace Discord | |||
{ | |||
/// <summary> | |||
/// Tests for the <see cref="Discord.Color"/> type. | |||
/// </summary> | |||
public class ColorTests | |||
{ | |||
[Fact] |
@@ -0,0 +1,21 @@ | |||
<Project Sdk="Microsoft.NET.Sdk"> | |||
<PropertyGroup> | |||
<TargetFramework>netcoreapp2.1</TargetFramework> | |||
<IsPackable>false</IsPackable> | |||
</PropertyGroup> | |||
<ItemGroup> | |||
<ProjectReference Include="../../src/Discord.Net.Commands/Discord.Net.Commands.csproj" /> | |||
<ProjectReference Include="../../src/Discord.Net.Core/Discord.Net.Core.csproj" /> | |||
<ProjectReference Include="../../src/Discord.Net.Rest/Discord.Net.Rest.csproj" /> | |||
<ProjectReference Include="../../src/Discord.Net.Analyzers/Discord.Net.Analyzers.csproj" /> | |||
<ProjectReference Include="..\..\src\Discord.Net.WebSocket\Discord.Net.WebSocket.csproj" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" /> | |||
<PackageReference Include="xunit" Version="2.4.0" /> | |||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.0" /> | |||
</ItemGroup> | |||
</Project> |
@@ -0,0 +1,467 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Text; | |||
using Xunit; | |||
namespace Discord | |||
{ | |||
/// <summary> | |||
/// Tests the <see cref="Discord.EmbedBuilder"/> class. | |||
/// </summary> | |||
public class EmbedBuilderTests | |||
{ | |||
private const string name = "chrisj"; | |||
private const string icon = "https://meowpuffygottem.fun/blob.png"; | |||
private const string url = "https://meowpuffygottem.fun/"; | |||
/// <summary> | |||
/// Tests the behavior of <see cref="EmbedBuilder.WithAuthor(string, string, string)"/>. | |||
/// </summary> | |||
[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); | |||
} | |||
/// <summary> | |||
/// Tests the behavior of <see cref="EmbedBuilder.WithAuthor(EmbedAuthorBuilder)"/> | |||
/// </summary> | |||
[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); | |||
} | |||
/// <summary> | |||
/// Tests the behavior of <see cref="EmbedBuilder.WithAuthor(Action{EmbedAuthorBuilder})"/> | |||
/// </summary> | |||
[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); | |||
} | |||
/// <summary> | |||
/// Tests the behavior of <see cref="EmbedAuthorBuilder"/>. | |||
/// </summary> | |||
[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); | |||
} | |||
/// <summary> | |||
/// Tests that invalid titles throw an <see cref="ArgumentException"/>. | |||
/// </summary> | |||
/// <param name="title">The embed title to set.</param> | |||
[Theory] | |||
// 257 chars | |||
[InlineData("jVyLChmA7aBZozXQuZ3VDEcwW6zOq0nteOVYBZi31ny73rpXfSSBXR4Jw6FiplDKQseKskwRMuBZkUewrewqAbkBZpslHirvC5nEzRySoDIdTRnkVvTXZUXg75l3bQCjuuHxDd6DfrY8ihd6yZX1Y0XFeg239YBcYV4TpL9uQ8H3HFYxrWhLlG2PRVjUmiglP5iXkawszNwMVm1SZ5LZT4jkMZHxFegVi7170d16iaPWOovu50aDDHy087XBtLKVa")] | |||
// 257 chars of whitespace | |||
[InlineData(" ")] | |||
public void Title_Invalid(string title) | |||
{ | |||
Assert.Throws<ArgumentException>(() => | |||
{ | |||
var builder = new EmbedBuilder(); | |||
builder.Title = title; | |||
}); | |||
Assert.Throws<ArgumentException>(() => | |||
{ | |||
new EmbedBuilder().WithTitle(title); | |||
}); | |||
} | |||
/// <summary> | |||
/// Tests that valid titles do not throw any exceptions. | |||
/// </summary> | |||
/// <param name="title">The embed title to set.</param> | |||
[Theory] | |||
// 256 chars | |||
[InlineData("jVyLChmA7aBZozXQuZ3VDEcwW6zOq0nteOVYBZi31ny73rpXfSSBXR4Jw6FiplDKQseKskwRMuBZkUewrewqAbkBZpslHirvC5nEzRySoDIdTRnkVvTXZUXg75l3bQCjuuHxDd6DfrY8ihd6yZX1Y0XFeg239YBcYV4TpL9uQ8H3HFYxrWhLlG2PRVjUmiglP5iXkawszNwMVm1SZ5LZT4jkMZHxFegVi7170d16iaPWOovu50aDDHy087XBtLKV")] | |||
public void Tile_Valid(string title) | |||
{ | |||
var builder = new EmbedBuilder(); | |||
builder.Title = title; | |||
new EmbedBuilder().WithTitle(title); | |||
} | |||
/// <summary> | |||
/// Tests that invalid descriptions throw an <see cref="ArgumentException"/>. | |||
/// </summary> | |||
[Fact] | |||
public void Description_Invalid() | |||
{ | |||
IEnumerable<string> GetInvalid() | |||
{ | |||
yield return new string('a', 2049); | |||
} | |||
foreach (var description in GetInvalid()) | |||
{ | |||
Assert.Throws<ArgumentException>(() => new EmbedBuilder().WithDescription(description)); | |||
Assert.Throws<ArgumentException>(() => | |||
{ | |||
var b = new EmbedBuilder(); | |||
b.Description = description; | |||
}); | |||
} | |||
} | |||
/// <summary> | |||
/// Tests that valid descriptions do not throw any exceptions. | |||
/// </summary> | |||
[Fact] | |||
public void Description_Valid() | |||
{ | |||
IEnumerable<string> 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); | |||
} | |||
} | |||
/// <summary> | |||
/// Tests that valid urls do not throw any exceptions. | |||
/// </summary> | |||
/// <param name="url">The url to set.</param> | |||
[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); | |||
} | |||
/// <summary> | |||
/// Tests that invalid urls throw an <see cref="ArgumentException"/>. | |||
/// </summary> | |||
/// <param name="url">The url to set.</param> | |||
[Theory] | |||
[InlineData(" ")] | |||
[InlineData("not a url")] | |||
public void Url_Invalid(string url) | |||
{ | |||
Assert.Throws<ArgumentException>(() | |||
=> new EmbedBuilder() | |||
.WithUrl(url)); | |||
Assert.Throws<ArgumentException>(() | |||
=> new EmbedBuilder() | |||
.WithImageUrl(url)); | |||
Assert.Throws<ArgumentException>(() | |||
=> new EmbedBuilder() | |||
.WithThumbnailUrl(url)); | |||
Assert.Throws<ArgumentException>(() => | |||
{ | |||
var b = new EmbedBuilder(); | |||
b.Url = url; | |||
}); | |||
Assert.Throws<ArgumentException>(() => | |||
{ | |||
var b = new EmbedBuilder(); | |||
b.ImageUrl = url; | |||
}); | |||
Assert.Throws<ArgumentException>(() => | |||
{ | |||
var b = new EmbedBuilder(); | |||
b.ThumbnailUrl = url; | |||
}); | |||
} | |||
/// <summary> | |||
/// Tests the value of the <see cref="EmbedBuilder.Length"/> property when there are no fields set. | |||
/// </summary> | |||
[Fact] | |||
public void Length_Empty() | |||
{ | |||
var empty = new EmbedBuilder(); | |||
Assert.Equal(0, empty.Length); | |||
} | |||
/// <summary> | |||
/// Tests the value of the <see cref="EmbedBuilder.Length"/> property when all fields are set. | |||
/// </summary> | |||
[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); | |||
} | |||
/// <summary> | |||
/// Tests the behavior of <see cref="EmbedBuilder.WithCurrentTimestamp"/>. | |||
/// </summary> | |||
[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)); | |||
} | |||
/// <summary> | |||
/// Tests the behavior of <see cref="EmbedBuilder.WithColor(Color)"/>. | |||
/// </summary> | |||
[Fact] | |||
public void WithColor() | |||
{ | |||
// use WithColor | |||
var e = new EmbedBuilder().WithColor(Color.Red); | |||
Assert.Equal(Color.Red.RawValue, e.Color.Value.RawValue); | |||
} | |||
/// <summary> | |||
/// Tests the behavior of <see cref="EmbedBuilder.WithFooter(Action{EmbedFooterBuilder})"/> | |||
/// </summary> | |||
[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); | |||
} | |||
/// <summary> | |||
/// Tests the behavior of <see cref="EmbedBuilder.WithFooter(EmbedFooterBuilder)"/> | |||
/// </summary> | |||
[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); | |||
} | |||
/// <summary> | |||
/// Tests the behavior of <see cref="EmbedBuilder.WithFooter(string, string)"/> | |||
/// </summary> | |||
[Fact] | |||
public void WithFooter_Strings() | |||
{ | |||
var e = new EmbedBuilder() | |||
.WithFooter(name, url); | |||
Assert.Equal(url, e.Footer.IconUrl); | |||
Assert.Equal(name, e.Footer.Text); | |||
} | |||
/// <summary> | |||
/// Tests the behavior of <see cref="EmbedFooterBuilder"/>. | |||
/// </summary> | |||
[Fact] | |||
public void EmbedFooterBuilder() | |||
{ | |||
var footer = new EmbedFooterBuilder() | |||
.WithIconUrl(url) | |||
.WithText(name); | |||
Assert.Equal(url, footer.IconUrl); | |||
Assert.Equal(name, footer.Text); | |||
} | |||
/// <summary> | |||
/// Tests that invalid URLs throw an <see cref="ArgumentException"/>. | |||
/// </summary> | |||
[Fact] | |||
public void EmbedFooterBuilder_InvalidURL() | |||
{ | |||
IEnumerable<string> InvalidUrls() | |||
{ | |||
yield return "not a url"; | |||
} | |||
foreach (var url in InvalidUrls()) | |||
{ | |||
Assert.Throws<ArgumentException>(() => | |||
{ | |||
new EmbedFooterBuilder().WithIconUrl(url); | |||
}); | |||
} | |||
} | |||
/// <summary> | |||
/// Tests that invalid text throws an <see cref="ArgumentException"/>. | |||
/// </summary> | |||
[Fact] | |||
public void EmbedFooterBuilder_InvalidText() | |||
{ | |||
Assert.Throws<ArgumentException>(() => | |||
{ | |||
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<ArgumentException>(() => | |||
{ | |||
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<ArgumentException>(() => new EmbedFieldBuilder().WithName(name)); | |||
} | |||
[Fact] | |||
public void EmbedFieldBuilder_InvalidValue() | |||
{ | |||
IEnumerable<string> GetInvalidValue() | |||
{ | |||
yield return null; | |||
yield return string.Empty; | |||
yield return " "; | |||
yield return new string('a', 1025); | |||
}; | |||
foreach (var v in GetInvalidValue()) | |||
Assert.Throws<ArgumentException>(() => new EmbedFieldBuilder().WithValue(v)); | |||
} | |||
} | |||
} |
@@ -1,4 +1,6 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Text; | |||
using Xunit; | |||
namespace Discord |
@@ -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")); | |||
} | |||
} | |||
} |
@@ -0,0 +1,164 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Text; | |||
using Xunit; | |||
namespace Discord | |||
{ | |||
/// <summary> | |||
/// Tests the behavior of the <see cref="Discord.GuildPermissions"/> type and related functions. | |||
/// </summary> | |||
public class GuildPermissionsTests | |||
{ | |||
/// <summary> | |||
/// Tests the default value of the <see cref="Discord.GuildPermissions"/> constructor. | |||
/// </summary> | |||
[Fact] | |||
public void DefaultConstructor() | |||
{ | |||
var p = new GuildPermissions(); | |||
Assert.Equal((ulong)0, p.RawValue); | |||
Assert.Equal(GuildPermissions.None.RawValue, p.RawValue); | |||
} | |||
/// <summary> | |||
/// Tests the behavior of the <see cref="Discord.GuildPermissions"/> raw value constructor. | |||
/// </summary> | |||
[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<ulong> 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); | |||
} | |||
} | |||
/// <summary> | |||
/// Tests the behavior of the <see cref="Discord.GuildPermissions"/> constructor for each | |||
/// of it's flags. | |||
/// </summary> | |||
[Fact] | |||
public void FlagsConstructor() | |||
{ | |||
// util method for asserting that the constructor sets the given flag | |||
void AssertFlag(Func<GuildPermissions> 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); | |||
} | |||
/// <summary> | |||
/// Tests the behavior of <see cref="Discord.GuildPermissions.Modify(bool?, bool?, bool?, bool?, bool?, bool?, bool?, bool?, bool?, bool?, bool?, bool?, bool?, bool?, bool?, bool?, bool?, bool?, bool?, bool?, bool?, bool?, bool?, bool?, bool?, bool?, bool?, bool?, bool?)"/> | |||
/// with each of the parameters. | |||
/// </summary> | |||
[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<GuildPermissions, bool> has, | |||
Func<GuildPermissions, bool, GuildPermissions> 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)); | |||
} | |||
} | |||
} |
@@ -0,0 +1,128 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Text; | |||
using Xunit; | |||
namespace Discord | |||
{ | |||
/// <summary> | |||
/// Tests the methods provided in <see cref="MentionUtils"/>. | |||
/// </summary> | |||
public class MentionUtilsTests | |||
{ | |||
/// <summary> | |||
/// Tests <see cref="MentionUtils.MentionUser(string, bool)"/> | |||
/// </summary> | |||
[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)); | |||
} | |||
/// <summary> | |||
/// Tests <see cref="MentionUtils.MentionChannel(string)"/> | |||
/// </summary> | |||
[Fact] | |||
public void MentionChannel() | |||
{ | |||
Assert.Equal("<#123>", MentionUtils.MentionChannel(123u)); | |||
Assert.Equal("<#123>", MentionUtils.MentionChannel("123")); | |||
} | |||
/// <summary> | |||
/// Tests <see cref="MentionUtils.MentionRole(string)"/> | |||
/// </summary> | |||
[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<ArgumentException>(() => MentionUtils.ParseUser(user)); | |||
Assert.False(MentionUtils.TryParseUser(user, out _)); | |||
} | |||
[Fact] | |||
public void ParseUser_Null() | |||
{ | |||
Assert.Throws<NullReferenceException>(() => MentionUtils.ParseUser(null)); | |||
Assert.Throws<NullReferenceException>(() => 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<ArgumentException>(() => MentionUtils.ParseChannel(channel)); | |||
Assert.False(MentionUtils.TryParseChannel(channel, out _)); | |||
} | |||
[Fact] | |||
public void ParseChannel_Null() | |||
{ | |||
Assert.Throws<NullReferenceException>(() => MentionUtils.ParseChannel(null)); | |||
Assert.Throws<NullReferenceException>(() => 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<ArgumentException>(() => MentionUtils.ParseRole(role)); | |||
Assert.False(MentionUtils.TryParseRole(role, out _)); | |||
} | |||
[Fact] | |||
public void ParseRole_Null() | |||
{ | |||
Assert.Throws<NullReferenceException>(() => MentionUtils.ParseRole(null)); | |||
Assert.Throws<NullReferenceException>(() => MentionUtils.TryParseRole(null, out _)); | |||
} | |||
} | |||
} |
@@ -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<Overwrite> 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<IGuildUser> GetUserAsync(ulong id, CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null) | |||
{ | |||
throw new NotImplementedException(); | |||
} | |||
public IAsyncEnumerable<IReadOnlyCollection<IGuildUser>> GetUsersAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null) | |||
{ | |||
throw new NotImplementedException(); | |||
} | |||
public Task ModifyAsync(Action<GuildChannelProperties> 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<IUser> IChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options) | |||
{ | |||
throw new NotImplementedException(); | |||
} | |||
IAsyncEnumerable<IReadOnlyCollection<IUser>> IChannel.GetUsersAsync(CacheMode mode, RequestOptions options) | |||
{ | |||
throw new NotImplementedException(); | |||
} | |||
} | |||
} |
@@ -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<IUser> 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<IMessage> GetMessageAsync(ulong id, CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null) | |||
{ | |||
throw new NotImplementedException(); | |||
} | |||
public IAsyncEnumerable<IReadOnlyCollection<IMessage>> GetMessagesAsync(int limit = 100, CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null) | |||
{ | |||
throw new NotImplementedException(); | |||
} | |||
public IAsyncEnumerable<IReadOnlyCollection<IMessage>> GetMessagesAsync(ulong fromMessageId, Direction dir, int limit = 100, CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null) | |||
{ | |||
throw new NotImplementedException(); | |||
} | |||
public IAsyncEnumerable<IReadOnlyCollection<IMessage>> GetMessagesAsync(IMessage fromMessage, Direction dir, int limit = 100, CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null) | |||
{ | |||
throw new NotImplementedException(); | |||
} | |||
public Task<IReadOnlyCollection<IMessage>> GetPinnedMessagesAsync(RequestOptions options = null) | |||
{ | |||
throw new NotImplementedException(); | |||
} | |||
public Task<IUser> GetUserAsync(ulong id, CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null) | |||
{ | |||
throw new NotImplementedException(); | |||
} | |||
public IAsyncEnumerable<IReadOnlyCollection<IUser>> GetUsersAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null) | |||
{ | |||
throw new NotImplementedException(); | |||
} | |||
public Task<IUserMessage> SendFileAsync(string filePath, string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false) | |||
{ | |||
throw new NotImplementedException(); | |||
} | |||
public Task<IUserMessage> 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<IUserMessage> 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(); | |||
} | |||
} | |||
} |
@@ -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<IUser> Recipients => throw new NotImplementedException(); | |||
public string Name => throw new NotImplementedException(); | |||
public DateTimeOffset CreatedAt => throw new NotImplementedException(); | |||
public ulong Id => throw new NotImplementedException(); | |||
public Task<IAudioClient> 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<IMessage> GetMessageAsync(ulong id, CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null) | |||
{ | |||
throw new NotImplementedException(); | |||
} | |||
public IAsyncEnumerable<IReadOnlyCollection<IMessage>> GetMessagesAsync(int limit = 100, CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null) | |||
{ | |||
throw new NotImplementedException(); | |||
} | |||
public IAsyncEnumerable<IReadOnlyCollection<IMessage>> GetMessagesAsync(ulong fromMessageId, Direction dir, int limit = 100, CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null) | |||
{ | |||
throw new NotImplementedException(); | |||
} | |||
public IAsyncEnumerable<IReadOnlyCollection<IMessage>> GetMessagesAsync(IMessage fromMessage, Direction dir, int limit = 100, CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null) | |||
{ | |||
throw new NotImplementedException(); | |||
} | |||
public Task<IReadOnlyCollection<IMessage>> GetPinnedMessagesAsync(RequestOptions options = null) | |||
{ | |||
throw new NotImplementedException(); | |||
} | |||
public Task<IUser> GetUserAsync(ulong id, CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null) | |||
{ | |||
throw new NotImplementedException(); | |||
} | |||
public IAsyncEnumerable<IReadOnlyCollection<IUser>> GetUsersAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null) | |||
{ | |||
throw new NotImplementedException(); | |||
} | |||
public Task LeaveAsync(RequestOptions options = null) | |||
{ | |||
throw new NotImplementedException(); | |||
} | |||
public Task<IUserMessage> SendFileAsync(string filePath, string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false) | |||
{ | |||
throw new NotImplementedException(); | |||
} | |||
public Task<IUserMessage> 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<IUserMessage> 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(); | |||
} | |||
} | |||
} |
@@ -0,0 +1,29 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
namespace Discord | |||
{ | |||
/// <summary> | |||
/// Represents a channel that is of an unrecognized type. | |||
/// </summary> | |||
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<IUser> GetUserAsync(ulong id, CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null) | |||
{ | |||
throw new NotImplementedException(); | |||
} | |||
public IAsyncEnumerable<IReadOnlyCollection<IUser>> GetUsersAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null) | |||
{ | |||
throw new NotImplementedException(); | |||
} | |||
} | |||
} |
@@ -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<Overwrite> 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<IInviteMetadata> CreateInviteAsync(int? maxAge = 86400, int? maxUses = null, bool isTemporary = false, bool isUnique = false, RequestOptions options = null) | |||
{ | |||
throw new NotImplementedException(); | |||
} | |||
public Task<IWebhook> 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<IMessage> messages, RequestOptions options = null) | |||
{ | |||
throw new NotImplementedException(); | |||
} | |||
public Task DeleteMessagesAsync(IEnumerable<ulong> messageIds, RequestOptions options = null) | |||
{ | |||
throw new NotImplementedException(); | |||
} | |||
public IDisposable EnterTypingState(RequestOptions options = null) | |||
{ | |||
throw new NotImplementedException(); | |||
} | |||
public Task<ICategoryChannel> GetCategoryAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null) | |||
{ | |||
throw new NotImplementedException(); | |||
} | |||
public Task<IReadOnlyCollection<IInviteMetadata>> GetInvitesAsync(RequestOptions options = null) | |||
{ | |||
throw new NotImplementedException(); | |||
} | |||
public Task<IMessage> GetMessageAsync(ulong id, CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null) | |||
{ | |||
throw new NotImplementedException(); | |||
} | |||
public IAsyncEnumerable<IReadOnlyCollection<IMessage>> GetMessagesAsync(int limit = 100, CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null) | |||
{ | |||
throw new NotImplementedException(); | |||
} | |||
public IAsyncEnumerable<IReadOnlyCollection<IMessage>> GetMessagesAsync(ulong fromMessageId, Direction dir, int limit = 100, CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null) | |||
{ | |||
throw new NotImplementedException(); | |||
} | |||
public IAsyncEnumerable<IReadOnlyCollection<IMessage>> 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<IReadOnlyCollection<IMessage>> GetPinnedMessagesAsync(RequestOptions options = null) | |||
{ | |||
throw new NotImplementedException(); | |||
} | |||
public Task<IGuildUser> GetUserAsync(ulong id, CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null) | |||
{ | |||
throw new NotImplementedException(); | |||
} | |||
public IAsyncEnumerable<IReadOnlyCollection<IGuildUser>> GetUsersAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null) | |||
{ | |||
throw new NotImplementedException(); | |||
} | |||
public Task<IWebhook> GetWebhookAsync(ulong id, RequestOptions options = null) | |||
{ | |||
throw new NotImplementedException(); | |||
} | |||
public Task<IReadOnlyCollection<IWebhook>> GetWebhooksAsync(RequestOptions options = null) | |||
{ | |||
throw new NotImplementedException(); | |||
} | |||
public Task ModifyAsync(Action<TextChannelProperties> func, RequestOptions options = null) | |||
{ | |||
throw new NotImplementedException(); | |||
} | |||
public Task ModifyAsync(Action<GuildChannelProperties> 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<IUserMessage> SendFileAsync(string filePath, string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false) | |||
{ | |||
throw new NotImplementedException(); | |||
} | |||
public Task<IUserMessage> 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<IUserMessage> 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<IUser> IChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options) | |||
{ | |||
throw new NotImplementedException(); | |||
} | |||
IAsyncEnumerable<IReadOnlyCollection<IUser>> IChannel.GetUsersAsync(CacheMode mode, RequestOptions options) | |||
{ | |||
throw new NotImplementedException(); | |||
} | |||
} | |||
} |
@@ -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<Overwrite> 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<IAudioClient> ConnectAsync(bool selfDeaf = false, bool selfMute = false, bool external = false) | |||
{ | |||
throw new NotImplementedException(); | |||
} | |||
public Task<IInviteMetadata> 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<ICategoryChannel> GetCategoryAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null) | |||
{ | |||
throw new NotImplementedException(); | |||
} | |||
public Task<IReadOnlyCollection<IInviteMetadata>> 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<IGuildUser> GetUserAsync(ulong id, CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null) | |||
{ | |||
throw new NotImplementedException(); | |||
} | |||
public IAsyncEnumerable<IReadOnlyCollection<IGuildUser>> GetUsersAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null) | |||
{ | |||
throw new NotImplementedException(); | |||
} | |||
public Task ModifyAsync(Action<VoiceChannelProperties> func, RequestOptions options = null) | |||
{ | |||
throw new NotImplementedException(); | |||
} | |||
public Task ModifyAsync(Action<GuildChannelProperties> 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<IUser> IChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options) | |||
{ | |||
throw new NotImplementedException(); | |||
} | |||
IAsyncEnumerable<IReadOnlyCollection<IUser>> IChannel.GetUsersAsync(CacheMode mode, RequestOptions options) | |||
{ | |||
throw new NotImplementedException(); | |||
} | |||
} | |||
} |
@@ -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))); | |||
} | |||
} | |||
} |
@@ -5,6 +5,9 @@ using Xunit; | |||
namespace Discord | |||
{ | |||
/// <summary> | |||
/// Tests for the <see cref="Discord.TokenUtils"/> methods. | |||
/// </summary> | |||
public class TokenUtilsTests | |||
{ | |||
/// <summary> | |||
@@ -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<ArgumentNullException>(() => TokenUtils.ValidateToken(TokenType.Bearer, token)); | |||
Assert.Throws<ArgumentNullException>(() => TokenUtils.ValidateToken(TokenType.Bot, token)); | |||
Assert.Throws<ArgumentNullException>(() => TokenUtils.ValidateToken(TokenType.Webhook, token)); | |||
} | |||
/// <summary> | |||
/// Tests the behavior of <see cref="TokenUtils.ValidateToken(TokenType, string)"/> | |||
/// 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<ArgumentException>(() => 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<ArgumentException>(() => | |||
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); | |||
}); | |||
} | |||
} | |||
} |
@@ -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<TestModule>(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<TestModule>(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<TestModule>(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<TestModule>(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<int> ManyInts { get; set; } | |||
} | |||
public sealed class CustomTypeReader : TypeReader | |||
{ | |||
public override Task<TypeReaderResult> 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); | |||
} | |||
} |
@@ -1,35 +0,0 @@ | |||
<Project Sdk="Microsoft.NET.Sdk"> | |||
<PropertyGroup> | |||
<OutputType>Exe</OutputType> | |||
<RootNamespace>Discord</RootNamespace> | |||
<TargetFramework>netcoreapp2.1</TargetFramework> | |||
<DebugType>portable</DebugType> | |||
<NoWarn>IDISP001,IDISP002,IDISP004,IDISP005</NoWarn> | |||
</PropertyGroup> | |||
<ItemGroup> | |||
<Content Include="xunit.runner.json"> | |||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | |||
</Content> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<None Include="Tests.Permissions.cs" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<ProjectReference Include="../../src/Discord.Net.Commands/Discord.Net.Commands.csproj" /> | |||
<ProjectReference Include="../../src/Discord.Net.Core/Discord.Net.Core.csproj" /> | |||
<ProjectReference Include="../../src/Discord.Net.Rest/Discord.Net.Rest.csproj" /> | |||
<ProjectReference Include="../../src/Discord.Net.Analyzers/Discord.Net.Analyzers.csproj" /> | |||
<ProjectReference Include="..\..\src\Discord.Net.Webhook\Discord.Net.Webhook.csproj" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<PackageReference Include="Akavache" Version="6.0.31" /> | |||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" /> | |||
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" /> | |||
<PackageReference Include="xunit" Version="2.4.1" /> | |||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1"> | |||
<PrivateAssets>all</PrivateAssets> | |||
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> | |||
</PackageReference> | |||
<PackageReference Include="xunit.runner.reporters" Version="2.4.1" /> | |||
</ItemGroup> | |||
</Project> |
@@ -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; } | |||
} | |||
} |
@@ -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<string, string> _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<string, string>(); | |||
_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<RestResponse> 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<RestResponse> 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<RestResponse> SendAsync(string method, string endpoint, IReadOnlyDictionary<string, object> 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<CacheInfo>("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<CacheInfo>("info", Info); | |||
} | |||
} | |||
} |
@@ -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<Stream> OpenFileForReadAsync(string path, IScheduler scheduler) | |||
{ | |||
return SafeOpenFileAsync(path, FileMode.Open, FileAccess.Read, FileShare.Read, scheduler); | |||
} | |||
public IObservable<Stream> OpenFileForWriteAsync(string path, IScheduler scheduler) | |||
{ | |||
return SafeOpenFileAsync(path, FileMode.Create, FileAccess.Write, FileShare.None, scheduler); | |||
} | |||
public IObservable<Unit> CreateRecursive(string path) | |||
{ | |||
CreateRecursive(new DirectoryInfo(path)); | |||
return Observable.Return(Unit.Default); | |||
} | |||
public IObservable<Unit> 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<Stream> SafeOpenFileAsync(string path, FileMode mode, FileAccess access, FileShare share, IScheduler scheduler = null) | |||
{ | |||
scheduler = scheduler ?? Scheduler.Default; | |||
var ret = new AsyncSubject<Stream>(); | |||
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<Stream>().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<string> SplitFullPath(DirectoryInfo info) | |||
{ | |||
var root = Path.GetPathRoot(info.FullName); | |||
var components = new List<string>(); | |||
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; | |||
} | |||
} | |||
} |
@@ -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 | |||
{ | |||
/// <summary> | |||
/// 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. | |||
/// </summary> | |||
/// <param name="url">The URL to download.</param> | |||
/// <param name="headers">An optional Dictionary containing the HTTP | |||
/// request headers.</param> | |||
/// <param name="fetchAlways">Force a web request to always be issued, skipping the cache.</param> | |||
/// <param name="absoluteExpiration">An optional expiration date.</param> | |||
/// <returns>The data downloaded from the URL.</returns> | |||
public IObservable<byte[]> DownloadUrl(IBlobCache This, string url, IDictionary<string, string> headers = null, bool fetchAlways = false, DateTimeOffset? absoluteExpiration = null) | |||
{ | |||
return This.DownloadUrl(url, url, headers, fetchAlways, absoluteExpiration); | |||
} | |||
/// <summary> | |||
/// 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. | |||
/// </summary> | |||
/// <param name="key">The key to store with.</param> | |||
/// <param name="url">The URL to download.</param> | |||
/// <param name="headers">An optional Dictionary containing the HTTP | |||
/// request headers.</param> | |||
/// <param name="fetchAlways">Force a web request to always be issued, skipping the cache.</param> | |||
/// <param name="absoluteExpiration">An optional expiration date.</param> | |||
/// <returns>The data downloaded from the URL.</returns> | |||
public IObservable<byte[]> DownloadUrl(IBlobCache This, string key, string url, IDictionary<string, string> 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<byte[]>); | |||
if (!fetchAlways) | |||
{ | |||
ret = This.Get(key).Catch(fetchAndCache); | |||
} | |||
else | |||
{ | |||
ret = fetchAndCache; | |||
} | |||
var conn = ret.PublishLast(); | |||
conn.Connect(); | |||
return conn; | |||
} | |||
IObservable<byte[]> 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<byte[]>(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<WebResponse> MakeWebRequest( | |||
Uri uri, | |||
IDictionary<string, string> headers = null, | |||
string content = null, | |||
int retries = 3, | |||
TimeSpan? timeout = null) | |||
{ | |||
IObservable<WebResponse> request; | |||
request = Observable.Defer(() => | |||
{ | |||
var hwr = CreateWebRequest(uri, headers); | |||
if (content == null) | |||
return Observable.FromAsyncPattern<WebResponse>(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<WebResponse>(); | |||
Observable.Start(() => | |||
{ | |||
Observable.FromAsyncPattern<Stream>(hwr.BeginGetRequestStream, hwr.EndGetRequestStream)() | |||
.SelectMany(x => WriteAsyncRx(x, buf, 0, buf.Length)) | |||
.SelectMany(_ => Observable.FromAsyncPattern<WebResponse>(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<string, string> 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<Unit> WriteAsyncRx(Stream stream, byte[] data, int start, int length) | |||
{ | |||
return stream.WriteAsync(data, start, length).ToObservable(); | |||
} | |||
} | |||
} |
@@ -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<TestConfig>(jsonReader); | |||
} | |||
else | |||
{ | |||
return new TestConfig() | |||
{ | |||
Token = Environment.GetEnvironmentVariable("DNET_TEST_TOKEN"), | |||
GuildId = ulong.Parse(Environment.GetEnvironmentVariable("DNET_TEST_GUILDID")) | |||
}; | |||
} | |||
} | |||
} | |||
} |
@@ -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<ChannelPermissions, bool> has, | |||
Func<ChannelPermissions, bool, ChannelPermissions> 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<ArgumentException>(() => ChannelPermissions.All(someChannel)); | |||
return Task.CompletedTask; | |||
} | |||
} | |||
} |
@@ -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 |
@@ -1,342 +0,0 @@ | |||
using System; | |||
using System.Linq; | |||
using System.Threading.Tasks; | |||
using Xunit; | |||
#if IXTEST | |||
namespace Discord | |||
{ | |||
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] | |||
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 |
@@ -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 |
@@ -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); | |||
/// <summary> | |||
/// Tests the flag of the given permissions value to the expected output | |||
/// and then tries to toggle the flag on and off | |||
/// </summary> | |||
/// <param name="rawValue"></param> | |||
/// <param name="flagValue"></param> | |||
/// <param name="expected"></param> | |||
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)); | |||
} | |||
/// <summary> | |||
/// 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 | |||
/// </summary> | |||
/// <param name="value"></param> | |||
/// <param name="flag"></param> | |||
/// <param name="expected"></param> | |||
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)); | |||
} | |||
/// <summary> | |||
/// Tests for the <see cref="Discord.Permissions"/> class. | |||
/// | |||
/// Tests that text channel permissions get the right value | |||
/// from the Has method. | |||
/// </summary> | |||
/// <returns></returns> | |||
[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; | |||
} | |||
/// <summary> | |||
/// Tests for the <see cref="Discord.Permissions"/> class. | |||
/// | |||
/// Tests that no channel permissions get the right value | |||
/// from the Has method. | |||
/// </summary> | |||
/// <returns></returns> | |||
[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; | |||
} | |||
/// <summary> | |||
/// Tests for the <see cref="Discord.Permissions"/> class. | |||
/// | |||
/// Tests that the dm channel permissions get the right value | |||
/// from the Has method. | |||
/// </summary> | |||
/// <returns></returns> | |||
[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; | |||
} | |||
/// <summary> | |||
/// Tests for the <see cref="Discord.Permissions"/> class. | |||
/// | |||
/// Tests that the group channel permissions get the right value | |||
/// from the Has method. | |||
/// </summary> | |||
/// <returns></returns> | |||
[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; | |||
} | |||
/// <summary> | |||
/// Tests for the <see cref="Discord.Permissions"/> class. | |||
/// | |||
/// Tests that the voice channel permissions get the right value | |||
/// from the Has method. | |||
/// </summary> | |||
/// <returns></returns> | |||
[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; | |||
} | |||
/// <summary> | |||
/// Tests for the <see cref="Discord.Permissions"/> class. | |||
/// | |||
/// Test that that the Has method of <see cref="Discord.GuildPermissions"/> | |||
/// returns the correct value when no permissions are set. | |||
/// </summary> | |||
/// <returns></returns> | |||
[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; | |||
} | |||
/// <summary> | |||
/// Tests for the <see cref="Discord.Permissions"/> class. | |||
/// | |||
/// Test that that the Has method of <see cref="Discord.GuildPermissions"/> | |||
/// returns the correct value when all permissions are set. | |||
/// </summary> | |||
/// <returns></returns> | |||
[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; | |||
} | |||
/// <summary> | |||
/// Tests for the <see cref="Discord.Permissions"/> class. | |||
/// | |||
/// Test that that the Has method of <see cref="Discord.GuildPermissions"/> | |||
/// returns the correct value when webhook permissions are set. | |||
/// </summary> | |||
/// <returns></returns> | |||
[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; | |||
} | |||
/// <summary> | |||
/// Test <see cref="Discord.OverwritePermissions"/> | |||
/// for when all text permissions are allowed and denied | |||
/// </summary> | |||
/// <returns></returns> | |||
[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; | |||
} | |||
/// <summary> | |||
/// Test <see cref="Discord.OverwritePermissions"/> | |||
/// for when none of the permissions are set. | |||
/// </summary> | |||
/// <returns></returns> | |||
[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; | |||
} | |||
/// <summary> | |||
/// Test <see cref="Discord.OverwritePermissions"/> | |||
/// for when all dm permissions are allowed and denied | |||
/// </summary> | |||
/// <returns></returns> | |||
[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; | |||
} | |||
/// <summary> | |||
/// Test <see cref="Discord.OverwritePermissions"/> | |||
/// for when all group permissions are allowed and denied | |||
/// </summary> | |||
/// <returns></returns> | |||
[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; | |||
} | |||
/// <summary> | |||
/// Test <see cref="Discord.OverwritePermissions"/> | |||
/// for when all group permissions are allowed and denied | |||
/// </summary> | |||
/// <returns></returns> | |||
[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; | |||
} | |||
/// <summary> | |||
/// Tests for the <see cref="OverwritePermissions.Modify(PermValue?, PermValue?, PermValue?, PermValue?, PermValue?, PermValue?, PermValue?, PermValue?, PermValue?, PermValue?, PermValue?, PermValue?, PermValue?, PermValue?, PermValue?, PermValue?, PermValue?, PermValue?, PermValue?, PermValue?)"/> | |||
/// method to ensure that the default no-param call does not modify the resulting value | |||
/// of the OverwritePermissions. | |||
/// </summary> | |||
/// <returns></returns> | |||
[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; | |||
} | |||
} | |||
} |
@@ -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<TestModule>(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<TestModule>(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<TestModule>(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<TestModule>(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<int> ManyInts { get; set; } | |||
} | |||
public sealed class CustomTypeReader : TypeReader | |||
{ | |||
public override Task<TypeReaderResult> 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); | |||
} | |||
} |
@@ -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<TestsFixture> | |||
{ | |||
private DiscordRestClient _client; | |||
private RestGuild _guild; | |||
public Tests(TestsFixture fixture) | |||
{ | |||
_client = fixture._client; | |||
_guild = fixture._guild; | |||
} | |||
} | |||
} | |||
#endif |
@@ -1,4 +0,0 @@ | |||
{ | |||
"token": "AAA.BBB.CCC", | |||
"guild_id": 1234567890 | |||
} |
@@ -1,4 +0,0 @@ | |||
{ | |||
"diagnosticMessages": true, | |||
"methodDisplay": "classAndMethod" | |||
} |