diff --git a/Discord.Net.sln b/Discord.Net.sln
index 11960606b0..94259e2a75 100644
--- a/Discord.Net.sln
+++ b/Discord.Net.sln
@@ -1,12 +1,14 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
-VisualStudioVersion = 14.0.25123.0
+VisualStudioVersion = 14.0.25420.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Discord.Net", "src\Discord.Net\Discord.Net.xproj", "{91E9E7BD-75C9-4E98-84AA-2C271922E5C2}"
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Discord.Net.Commands", "src\Discord.Net.Commands\Discord.Net.Commands.xproj", "{078DD7E6-943D-4D09-AFC2-D2BA58B76C9C}"
EndProject
+Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Discord.Net.Tests", "test\Discord.Net.Tests\Discord.Net.Tests.xproj", "{69EECB8D-8705-424F-9202-F7F4051EE403}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -21,6 +23,10 @@ Global
{078DD7E6-943D-4D09-AFC2-D2BA58B76C9C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{078DD7E6-943D-4D09-AFC2-D2BA58B76C9C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{078DD7E6-943D-4D09-AFC2-D2BA58B76C9C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {69EECB8D-8705-424F-9202-F7F4051EE403}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {69EECB8D-8705-424F-9202-F7F4051EE403}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {69EECB8D-8705-424F-9202-F7F4051EE403}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {69EECB8D-8705-424F-9202-F7F4051EE403}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/test/Discord.Net.Tests/Discord.Net.Tests.csproj b/test/Discord.Net.Tests/Discord.Net.Tests.csproj
deleted file mode 100644
index 2a50610cc8..0000000000
--- a/test/Discord.Net.Tests/Discord.Net.Tests.csproj
+++ /dev/null
@@ -1,97 +0,0 @@
-
-
-
- Debug
- AnyCPU
- {855D6B1D-847B-42DA-BE6A-23683EA89511}
- Library
- Properties
- Discord.Tests
- Discord.Net.Tests
- v4.6.1
- 512
- {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
- 10.0
- $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
- $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages
- False
- UnitTest
-
-
-
- true
- full
- false
- bin\Debug\
- DEBUG;TRACE
- prompt
- 4
-
-
- pdbonly
- true
- bin\Release\
- TRACE
- prompt
- 4
-
-
-
- ..\..\packages\Newtonsoft.Json.8.0.2\lib\net45\Newtonsoft.Json.dll
- True
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {c6a50d24-cbd3-4e76-852c-4dca60bbd608}
- Discord.Net.Net45
-
-
-
-
-
-
- False
-
-
- False
-
-
- False
-
-
- False
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/test/Discord.Net.Tests/Discord.Net.Tests.xproj b/test/Discord.Net.Tests/Discord.Net.Tests.xproj
new file mode 100644
index 0000000000..1c291ddb03
--- /dev/null
+++ b/test/Discord.Net.Tests/Discord.Net.Tests.xproj
@@ -0,0 +1,21 @@
+
+
+
+ 14.0.25420
+ $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
+
+
+
+ 69eecb8d-8705-424f-9202-f7f4051ee403
+ Discord.Tests
+ .\obj
+ .\bin\
+
+
+ 2.0
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test/Discord.Net.Tests/Framework/MockRestClient.cs b/test/Discord.Net.Tests/Framework/MockRestClient.cs
new file mode 100644
index 0000000000..1203ee5254
--- /dev/null
+++ b/test/Discord.Net.Tests/Framework/MockRestClient.cs
@@ -0,0 +1,45 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Threading;
+using System.Threading.Tasks;
+using Discord.Net.Rest;
+using System.Collections.ObjectModel;
+
+namespace Discord.Tests.Framework
+{
+ public class MockRestClient : IRestClient
+ {
+ public MockRestClient(string baseUrl)
+ {
+ _requestHandler = new RequestHandler();
+ }
+
+ private Dictionary _headers = new Dictionary();
+ public IReadOnlyDictionary Headers =>
+ new ReadOnlyDictionary(_headers);
+ private RequestHandler _requestHandler;
+
+ public Task SendAsync(string method, string endpoint, bool headerOnly = false) =>
+ SendAsync(method, endpoint, "", headerOnly);
+
+ public Task SendAsync(string method, string endpoint, IReadOnlyDictionary multipartParams, bool headerOnly = false)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task SendAsync(string method, string endpoint, string json, bool headerOnly = false)
+ {
+ return Task.FromResult(_requestHandler.GetMock(method, endpoint, json, Headers));
+ }
+
+ public void SetCancelToken(CancellationToken cancelToken) { }
+
+ public void SetHeader(string key, string value)
+ {
+ if (_headers.ContainsKey(key))
+ _headers.Remove(key);
+ _headers.Add(key, value);
+ }
+ }
+}
diff --git a/test/Discord.Net.Tests/Framework/Mocks/Rest/Guilds.cs b/test/Discord.Net.Tests/Framework/Mocks/Rest/Guilds.cs
new file mode 100644
index 0000000000..c95e69b561
--- /dev/null
+++ b/test/Discord.Net.Tests/Framework/Mocks/Rest/Guilds.cs
@@ -0,0 +1,23 @@
+using Discord.API;
+
+namespace Discord.Tests.Framework.Mocks.Rest
+{
+ public static class Guilds
+ {
+ public static Guild DiscordApi => new Guild()
+ {
+ Id = 81384788765712384,
+ Name = "Discord API",
+ OwnerId = 53905483156684800,
+ MfaLevel = 0,
+ VerificationLevel = 0,
+ Roles = new Role[] { Roles.Everyone(81384788765712384), Roles.DiscordEmployee, Roles.LibraryDevs },
+ AFKTimeout = 3600,
+ Region = "us-east",
+ DefaultMessageNotifications = (DefaultMessageNotifications)1,
+ EmbedChannelId = 81384788765712384,
+ EmbedEnabled = true,
+ Icon = "2aab26934e72b4ec300c5aa6cf67c7b3"
+ };
+ }
+}
diff --git a/test/Discord.Net.Tests/Framework/Mocks/Rest/Roles.cs b/test/Discord.Net.Tests/Framework/Mocks/Rest/Roles.cs
new file mode 100644
index 0000000000..676661eeff
--- /dev/null
+++ b/test/Discord.Net.Tests/Framework/Mocks/Rest/Roles.cs
@@ -0,0 +1,43 @@
+using Discord.API;
+
+namespace Discord.Tests.Framework.Mocks.Rest
+{
+ public static class Roles
+ {
+ // TODO: These mocks need to include 'mentionable' when the library implements it.
+
+ public static Role Everyone(ulong guildId) => new Role()
+ {
+ Id = guildId,
+ Name = "@everyone",
+ Color = 0,
+ Hoist = false,
+ Permissions = 104324097,
+ Position = 0,
+ Managed = false
+ };
+
+ public static Role LibraryDevs => new Role()
+ {
+ Id = 81793792671232000,
+ Name = "Library Devs",
+ Color = 42607,
+ Hoist = true,
+ Permissions = 268435456,
+ Position = 17,
+ Managed = false
+ };
+
+ public static Role DiscordEmployee => new Role()
+ {
+ Id = 103548914652696576,
+ Name = "Discord Employee",
+ Color = 10181046,
+ Hoist = false,
+ Permissions = 29368358,
+ Position = 20,
+ Managed = false
+ };
+
+ }
+}
diff --git a/test/Discord.Net.Tests/Framework/Mocks/Rest/Users.cs b/test/Discord.Net.Tests/Framework/Mocks/Rest/Users.cs
new file mode 100644
index 0000000000..69bfb26300
--- /dev/null
+++ b/test/Discord.Net.Tests/Framework/Mocks/Rest/Users.cs
@@ -0,0 +1,38 @@
+using Discord.API;
+
+namespace Discord.Tests.Framework.Mocks.Rest
+{
+ public static class Users
+ {
+ public static User SelfUser => new User()
+ {
+ Id = 103559217914318848,
+ Username = "Jake",
+ Discriminator = "0001",
+ Email = "SelfUser@mocks.foxbot.me",
+ MfaEnabled = true,
+ Verified = true,
+ Avatar = "cdd7ae679ef37ce03e097221c70aeed6"
+ };
+
+ public static User BotSelfUser => new User()
+ {
+ Id = 145584102551060480,
+ Username = "foxboat",
+ Discriminator = "8888",
+ Email = null,
+ MfaEnabled = true,
+ Verified = true,
+ Avatar = "5f0be46cea584d2225e6c15e8418fb52",
+ Bot = true
+ };
+
+ public static User PublicUser => new User()
+ {
+ Id = 66078337084162048,
+ Username = "foxbot",
+ Discriminator = "0282",
+ Avatar = "cdd7ae679ef37ce03e097221c70aeed6"
+ };
+ }
+}
diff --git a/test/Discord.Net.Tests/Framework/RequestHandler.cs b/test/Discord.Net.Tests/Framework/RequestHandler.cs
new file mode 100644
index 0000000000..ad54f3997b
--- /dev/null
+++ b/test/Discord.Net.Tests/Framework/RequestHandler.cs
@@ -0,0 +1,47 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Threading.Tasks;
+using System.Net;
+using System.Text;
+using UserRoutes = Discord.Tests.Framework.Routes.Users;
+using GuildRoutes = Discord.Tests.Framework.Routes.Guilds;
+using Contracts = Discord.Tests.Framework.Routes.Contracts;
+using Newtonsoft.Json;
+using Discord.Net.Converters;
+using Discord.Net;
+
+namespace Discord.Tests.Framework
+{
+ public class RequestHandler
+ {
+ public delegate object Response(string json, IReadOnlyDictionary requestHeaders);
+
+ internal static JsonSerializerSettings SerializerSettings = new JsonSerializerSettings() { ContractResolver = new DiscordContractResolver() };
+
+ internal Dictionary Routes = new Dictionary()
+ {
+ // --- USERS
+ // Get Current User
+ ["GET users/@me"] = new Response(UserRoutes.Me),
+ // Get User by ID
+ ["GET users/66078337084162048"] = new Response(UserRoutes.Public),
+ // Get User by Tag
+ ["GET users?q=foxbot%230282&limit=1"] = new Response(UserRoutes.Query),
+ // --- GUILDS
+ ["GET guilds/81384788765712384"] = new Response(GuildRoutes.DiscordApi)
+ };
+
+ internal Stream GetMock(string method, string endpoint, string json, IReadOnlyDictionary requestHeaders)
+ {
+ var key = string.Format("{0} {1}", method.ToUpperInvariant(), endpoint.ToLowerInvariant());
+ if (!Routes.ContainsKey(key))
+ throw new HttpException(HttpStatusCode.NotFound, $"{key}: {json}");
+ Contracts.EnsureAuthorization(requestHeaders);
+ var model = Routes[key].Invoke(json, requestHeaders);
+ var textResponse = JsonConvert.SerializeObject(model, SerializerSettings);
+ return new MemoryStream(Encoding.UTF8.GetBytes(textResponse));
+ }
+ }
+}
diff --git a/test/Discord.Net.Tests/Framework/Routes/Contracts.cs b/test/Discord.Net.Tests/Framework/Routes/Contracts.cs
new file mode 100644
index 0000000000..ceac0df691
--- /dev/null
+++ b/test/Discord.Net.Tests/Framework/Routes/Contracts.cs
@@ -0,0 +1,24 @@
+using Discord.Net;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net;
+using System.Threading.Tasks;
+
+namespace Discord.Tests.Framework.Routes
+{
+ public static class Contracts
+ {
+ public static readonly string UserToken = "token.user";
+ public static readonly string BotToken = "token.bot";
+ public static readonly string BearerToken = "token.bearer";
+
+ public static void EnsureAuthorization(IReadOnlyDictionary requestHeaders)
+ {
+ if (!requestHeaders.ContainsKey("authorization")) throw new HttpException(HttpStatusCode.Forbidden);
+ if (requestHeaders["authorization"] != UserToken
+ && requestHeaders["authorization"] != $"Bot {BotToken}"
+ && requestHeaders["authorization"] != $"Bearer {BearerToken}") throw new HttpException(HttpStatusCode.Forbidden);
+ }
+ }
+}
diff --git a/test/Discord.Net.Tests/Framework/Routes/Guilds.cs b/test/Discord.Net.Tests/Framework/Routes/Guilds.cs
new file mode 100644
index 0000000000..69ab8068fa
--- /dev/null
+++ b/test/Discord.Net.Tests/Framework/Routes/Guilds.cs
@@ -0,0 +1,11 @@
+using System.Collections.Generic;
+using GuildMocks = Discord.Tests.Framework.Mocks.Rest.Guilds;
+
+namespace Discord.Tests.Framework.Routes
+{
+ public static class Guilds
+ {
+ public static object DiscordApi(string json, IReadOnlyDictionary requestHeaders) =>
+ GuildMocks.DiscordApi;
+ }
+}
diff --git a/test/Discord.Net.Tests/Framework/Routes/Users.cs b/test/Discord.Net.Tests/Framework/Routes/Users.cs
new file mode 100644
index 0000000000..271aa3a729
--- /dev/null
+++ b/test/Discord.Net.Tests/Framework/Routes/Users.cs
@@ -0,0 +1,22 @@
+using UserMocks = Discord.Tests.Framework.Mocks.Rest.Users;
+using System.Collections.Generic;
+using System.Collections.Immutable;
+
+namespace Discord.Tests.Framework.Routes
+{
+ public static class Users
+ {
+ public static object Me(string json, IReadOnlyDictionary requestHeaders)
+ {
+ if (requestHeaders["authorization"] == Contracts.UserToken || requestHeaders["authorization"] == $"Bearer {Contracts.BearerToken}")
+ return UserMocks.SelfUser;
+ else
+ return UserMocks.BotSelfUser;
+ }
+
+ public static object Public(string json, IReadOnlyDictionary requestHeaders) =>
+ UserMocks.PublicUser;
+ public static object Query(string json, IReadOnlyDictionary requestHeaders) =>
+ ImmutableArray.Create(UserMocks.PublicUser);
+ }
+}
diff --git a/test/Discord.Net.Tests/Properties/AssemblyInfo.cs b/test/Discord.Net.Tests/Properties/AssemblyInfo.cs
deleted file mode 100644
index 5b1c7b1252..0000000000
--- a/test/Discord.Net.Tests/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("Discord.Net.Tests")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("Discord.Net.Tests")]
-[assembly: AssemblyCopyright("Copyright © 2015")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
-
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("855d6b1d-847b-42da-be6a-23683ea89511")]
-
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/test/Discord.Net.Tests/Rest/GuildTests.cs b/test/Discord.Net.Tests/Rest/GuildTests.cs
new file mode 100644
index 0000000000..bfeef9bab7
--- /dev/null
+++ b/test/Discord.Net.Tests/Rest/GuildTests.cs
@@ -0,0 +1,42 @@
+using System.Threading.Tasks;
+using Xunit;
+using Discord.Rest;
+using Contracts = Discord.Tests.Framework.Routes.Contracts;
+using Mocks = Discord.Tests.Framework.Mocks.Rest.Guilds;
+using RoleMocks = Discord.Tests.Framework.Mocks.Rest.Roles;
+
+namespace Discord.Tests.Rest
+{
+ public class GuildTests : IClassFixture
+ {
+ public GuildTests(RestFixture fixture)
+ {
+ _client = fixture.Client;
+ _client.LoginAsync(TokenType.Bot, Contracts.BotToken).GetAwaiter().GetResult();
+ }
+
+ private DiscordRestClient _client;
+
+ [Fact]
+ public async Task GetGuild()
+ {
+ var guild = await _client.GetGuildAsync(81384788765712384);
+ Assert.Equal(Mocks.DiscordApi.Id, guild.Id);
+ Assert.Equal(Mocks.DiscordApi.Name, guild.Name);
+ Assert.Equal(Mocks.DiscordApi.OwnerId, guild.OwnerId);
+ Assert.Equal(Mocks.DiscordApi.MfaLevel, guild.MfaLevel);
+ Assert.Equal(Mocks.DiscordApi.VerificationLevel, guild.VerificationLevel);
+ Assert.Equal(Mocks.DiscordApi.Roles.Length, guild.Roles.Count);
+ Assert.Equal(Mocks.DiscordApi.AFKTimeout, guild.AFKTimeout);
+ Assert.Equal(Mocks.DiscordApi.DefaultMessageNotifications, guild.DefaultMessageNotifications);
+ Assert.Equal(Mocks.DiscordApi.EmbedChannelId.GetValueOrDefault(), guild.EmbedChannelId);
+ Assert.Equal(Mocks.DiscordApi.EmbedEnabled, guild.IsEmbeddable);
+ }
+ [Fact]
+ public async Task GetInvalidGuild()
+ {
+ var guild = await _client.GetGuildAsync(1);
+ Assert.Null(guild);
+ }
+ }
+}
diff --git a/test/Discord.Net.Tests/Rest/LoginTests.cs b/test/Discord.Net.Tests/Rest/LoginTests.cs
new file mode 100644
index 0000000000..06c442a399
--- /dev/null
+++ b/test/Discord.Net.Tests/Rest/LoginTests.cs
@@ -0,0 +1,60 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Xunit;
+using Discord;
+using Discord.Rest;
+using Routes = Discord.Tests.Framework.Routes.Users;
+using Contracts = Discord.Tests.Framework.Routes.Contracts;
+using Discord.Net;
+
+namespace Discord.Tests.Rest
+{
+ public class LoginTests : IClassFixture
+ {
+ RestFixture fixture;
+
+ public LoginTests(RestFixture fixture)
+ {
+ this.fixture = fixture;
+ }
+
+ [Fact]
+ public async Task LoginAsUser()
+ {
+ var client = fixture.Client;
+ await client.LoginAsync(TokenType.User, Contracts.UserToken);
+ }
+ [Fact]
+ public async Task LoginAsUserWithInvalidToken()
+ {
+ var client = fixture.Client;
+ await Assert.ThrowsAsync(async () => await client.LoginAsync(TokenType.User, "token.invalid"));
+ }
+ [Fact]
+ public async Task LoginAsBot()
+ {
+ var client = fixture.Client;
+ await client.LoginAsync(TokenType.Bot, Contracts.BotToken);
+ }
+ [Fact]
+ public async Task LoginAsBotWithInvalidToken()
+ {
+ var client = fixture.Client;
+ await Assert.ThrowsAsync(async () => await client.LoginAsync(TokenType.Bot, "token.invalid"));
+ }
+ [Fact]
+ public async Task LoginAsBearer()
+ {
+ var client = fixture.Client;
+ await client.LoginAsync(TokenType.Bearer, Contracts.BearerToken);
+ }
+ [Fact]
+ public async Task LoginAsBearerWithInvalidToken()
+ {
+ var client = fixture.Client;
+ await Assert.ThrowsAsync(async () => await client.LoginAsync(TokenType.Bearer, "token.invalid"));
+ }
+ }
+}
diff --git a/test/Discord.Net.Tests/Rest/RestFixture.cs b/test/Discord.Net.Tests/Rest/RestFixture.cs
new file mode 100644
index 0000000000..7c40bb96e7
--- /dev/null
+++ b/test/Discord.Net.Tests/Rest/RestFixture.cs
@@ -0,0 +1,25 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Discord.Rest;
+using Discord.Net.Rest;
+using Discord.Tests.Framework;
+
+namespace Discord.Tests.Rest
+{
+ public class RestFixture
+ {
+ public DiscordRestClient Client
+ {
+ get
+ {
+ var Config = new DiscordRestConfig()
+ {
+ RestClientProvider = new RestClientProvider(baseUrl => new MockRestClient(baseUrl))
+ };
+ return new DiscordRestClient(Config);
+ }
+ }
+ }
+}
diff --git a/test/Discord.Net.Tests/Rest/UserTests.cs b/test/Discord.Net.Tests/Rest/UserTests.cs
new file mode 100644
index 0000000000..118294df72
--- /dev/null
+++ b/test/Discord.Net.Tests/Rest/UserTests.cs
@@ -0,0 +1,60 @@
+using System.Threading.Tasks;
+using Xunit;
+using Discord.Rest;
+using Contracts = Discord.Tests.Framework.Routes.Contracts;
+using Mocks = Discord.Tests.Framework.Mocks.Rest.Users;
+
+namespace Discord.Tests.Rest
+{
+ public class UserTests : IClassFixture
+ {
+ public UserTests(RestFixture fixture)
+ {
+ _client = fixture.Client;
+ _client.LoginAsync(TokenType.Bot, Contracts.BotToken).GetAwaiter().GetResult();
+ }
+
+ private DiscordRestClient _client;
+
+ [Fact]
+ public async Task GetCurrentUser()
+ {
+ var user = await _client.GetCurrentUserAsync();
+ Assert.Equal(Mocks.BotSelfUser.Id, user.Id);
+ Assert.Equal(Mocks.BotSelfUser.Username.GetValueOrDefault(), user.Username);
+ Assert.Equal(Mocks.BotSelfUser.Discriminator.GetValueOrDefault(), user.Discriminator);
+ Assert.Equal(Mocks.BotSelfUser.Bot.GetValueOrDefault(), user.IsBot);
+ Assert.Equal(Mocks.BotSelfUser.Email.GetValueOrDefault(), user.Email);
+ Assert.Equal(Mocks.BotSelfUser.MfaEnabled.GetValueOrDefault(), user.IsMfaEnabled);
+ Assert.Equal(Mocks.BotSelfUser.Verified.GetValueOrDefault(), user.IsVerified);
+ }
+ [Fact]
+ public async Task GetUserById()
+ {
+ var user = await _client.GetUserAsync(66078337084162048);
+ Assert.Equal(Mocks.PublicUser.Id, user.Id);
+ Assert.Equal(Mocks.PublicUser.Username.GetValueOrDefault(), user.Username);
+ Assert.Equal(Mocks.PublicUser.Discriminator.GetValueOrDefault(), user.Discriminator);
+ }
+ [Fact]
+ public async Task GetInvalidUserById()
+ {
+ var user = await _client.GetUserAsync(1);
+ Assert.Null(user);
+ }
+ [Fact]
+ public async Task GetUserByTag()
+ {
+ var user = await _client.GetUserAsync("foxbot", "0282");
+ Assert.Equal(Mocks.PublicUser.Id, user.Id);
+ Assert.Equal(Mocks.PublicUser.Username.GetValueOrDefault(), user.Username);
+ Assert.Equal(Mocks.PublicUser.Discriminator.GetValueOrDefault(), user.Discriminator);
+ }
+ [Fact]
+ public async Task GetInvalidUserByTag()
+ {
+ var user = await _client.GetUserAsync("Voltana", "8252");
+ Assert.Null(user);
+ }
+ }
+}
diff --git a/test/Discord.Net.Tests/Tests.cs b/test/Discord.Net.Tests/Tests.cs
deleted file mode 100644
index d8d09cd3dd..0000000000
--- a/test/Discord.Net.Tests/Tests.cs
+++ /dev/null
@@ -1,494 +0,0 @@
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace Discord.Tests
-{
- //TODO: Tests are massively incomplete and out of date, needing a full rewrite
-
- [TestClass]
- public class Tests
- {
- private const int EventTimeout = 10000; //Max time in milliseconds to wait for an event response from our test actions
-
- private static DiscordSocketClient _hostBot, _targetBot, _observerBot;
- private static Guild _testGuild;
- private static TextChannel _testGuildChannel;
- private static Random _random;
- private static PublicInvite _testGuildInvite;
-
- private static TestContext _context;
-
- private static string _hostToken;
- private static string _observerToken;
- private static string _targetToken;
-
- private static string GetRandomText()
- {
- lock (_random)
- return $"test_{_random.Next()}";
- }
-
- #region Initialization
-
- [ClassInitialize]
- public static void Initialize(TestContext testContext)
- {
- _context = testContext;
-
- _hostToken = Environment.GetEnvironmentVariable("discord-unit-host_token");
- _observerToken = Environment.GetEnvironmentVariable("discord-unit-observer_token");
- _targetToken = Environment.GetEnvironmentVariable("discord-unit-target_token");
- }
-
- [TestMethod]
- [Priority(1)]
- public async Task TestInitialize()
- {
- _context.WriteLine("Initializing.");
-
- _random = new Random();
-
- _hostBot = new DiscordSocketClient(_hostToken);
- _targetBot = new DiscordSocketClient(_targetToken);
- _observerBot = new DiscordSocketClient(_observerToken);
-
- await _hostBot.Login();
-
- await Task.Delay(3000);
-
- //Cleanup existing Guilds
- (await _hostBot.GetGuilds()).Select(x => x.Owner.Id == _hostBot.CurrentUser.Id ? x.Delete() : x.Leave());
-
- //Create new Guild and invite the other bots to it
-
- _testGuild = await _hostBot.CreateGuild("Discord.Net Testing", _hostBot.GetOptimalVoiceRegion());
-
- await Task.Delay(1000);
-
- PublicInvite invite = await _testGuild.CreateInvite(60, 3, false, false);
- _testGuildInvite = invite;
-
- _context.WriteLine($"Host: {_hostBot.CurrentUser.Username} in {(await _hostBot.GetGuilds()).Count()}");
- }
-
- [TestMethod]
- [Priority(2)]
- public async Task TestTokenLogin_Ready()
- {
- AssertEvent(
- "READY never received",
- async () => await _observerBot.Login(),
- x => _observerBot.Connected += x,
- x => _observerBot.Connected -= x,
- null,
- true);
- (await _observerBot.GetGuilds()).Select(x => x.Owner.Id == _observerBot.CurrentUser.Id ? x.Delete() : x.Leave());
- await _observerBot.RestClient.Send(new API.Rest.AcceptInviteRequest(_testGuildInvite.Code));
- }
-
- [TestMethod]
- [Priority(2)]
- public async Task TestReady()
- {
- AssertEvent(
- "READY never received",
- async () => await _targetBot.Login(),
- x => _targetBot.Connected += x,
- x => _targetBot.Connected -= x,
- null,
- true);
-
- (await _targetBot.GetGuilds()).Select(x => x.Owner.Id == _targetBot.CurrentUser.Id ? x.Delete() : x.Leave());
- _testGuildChannel = _testGuild.DefaultChannel;
- }
-
- #endregion
-
- // Guilds
-
- #region Guild Tests
-
- [TestMethod]
- [Priority(3)]
- public void TestJoinedGuild()
- {
- AssertEvent(
- "Never Got JoinedGuild",
- async () => await _targetBot.RestClient.Send(new API.Rest.AcceptInviteRequest(_testGuildInvite.Code)),
- x => _targetBot.JoinedGuild += x,
- x => _targetBot.JoinedGuild -= x);
- }
-
- #endregion
-
- #region Channel Tests
-
- //Channels
- [TestMethod]
- public void TestCreateTextChannel()
- {
- GuildChannel channel = null;
- string name = GetRandomText();
- AssertEvent(
- "ChannelCreated event never received",
- async () => channel = await _testGuild.CreateTextChannel(name),
- x => _targetBot.ChannelCreated += x,
- x => _targetBot.ChannelCreated -= x,
- (s, e) => e.Channel.Id == channel.Id);
-
- AssertEvent(
- "ChannelDestroyed event never received",
- async () => await channel.Delete(),
- x => _targetBot.ChannelDestroyed += x,
- x => _targetBot.ChannelDestroyed -= x,
- (s, e) => e.Channel.Id == channel.Id);
- }
- [TestMethod]
- public void TestCreateVoiceChannel()
- {
- GuildChannel channel = null;
- string name = GetRandomText();
- AssertEvent(
- "ChannelCreated event never received",
- async () => channel = await _testGuild.CreateVoiceChannel(name),
- x => _targetBot.ChannelCreated += x,
- x => _targetBot.ChannelCreated -= x,
- (s, e) => e.Channel.Id == channel.Id);
-
- AssertEvent(
- "ChannelDestroyed event never received",
- async () => await channel.Delete(),
- x => _targetBot.ChannelDestroyed += x,
- x => _targetBot.ChannelDestroyed -= x,
- (s, e) => e.Channel.Id == channel.Id);
- }
-
- [TestMethod]
- [ExpectedException(typeof(Net.HttpException))]
- public async Task TestCreateChannel_NoName()
- {
- await _testGuild.CreateTextChannel($"");
- }
- [TestMethod]
- public async Task Test_CreateGetChannel()
- {
- var name = GetRandomText();
- var channel = await _testGuild.CreateTextChannel(name);
- var get_channel = _testGuild.GetChannel(channel.Id);
- Assert.AreEqual(channel.Id, get_channel.Id, "ID of Channel and GetChannel were not equal.");
- }
- [TestMethod]
- public void TestSendTyping()
- {
- var channel = _testGuildChannel;
- AssertEvent(
- "UserUpdated event never fired.",
- async () => await channel.TriggerTyping(),
- x => _targetBot.UserIsTyping += x,
- x => _targetBot.UserIsTyping -= x);
- }
- [TestMethod]
- public void TestEditChannel()
- {
- var channel = _testGuildChannel;
- AssertEvent(
- "ChannelUpdated Never Received",
- async () => await channel.Modify(x =>
- {
- x.Name = GetRandomText();
- x.Topic = $"topic - {GetRandomText()}";
- x.Position = 26;
- }),
- x => _targetBot.ChannelUpdated += x,
- x => _targetBot.ChannelUpdated -= x);
- }
- [TestMethod]
- public void TestChannelMention()
- {
- var channel = _testGuildChannel;
- Assert.AreEqual($"<#{channel.Id}>", channel.Mention, "Generated channel mention was not the expected channel mention.");
- }
- [TestMethod]
- public void TestChannelUserCount()
- {
- Assert.AreEqual(3, _testGuildChannel.Users.Count(), "Read an incorrect number of users in a channel");
- }
-
- #endregion
-
- #region Message Tests
-
- //Messages
- [TestMethod]
- public async Task TestMessageEvents()
- {
- string name = GetRandomText();
- var channel = await _testGuild.CreateTextChannel(name);
- _context.WriteLine($"Channel Name: {channel.Name} / {channel.Guild.Name}");
- string text = GetRandomText();
- Message message = null;
- AssertEvent(
- "MessageCreated event never received",
- async () => message = await channel.SendMessage(text),
- x => _targetBot.MessageReceived += x,
- x => _targetBot.MessageReceived -= x,
- (s, e) => e.Message.Text == text);
-
- AssertEvent(
- "MessageUpdated event never received",
- async () => await message.Modify(x =>
- {
- x.Content = text + " updated";
- }),
- x => _targetBot.MessageUpdated += x,
- x => _targetBot.MessageUpdated -= x,
- (s, e) => e.Before.Text == text && e.After.Text == text + " updated");
-
- AssertEvent(
- "MessageDeleted event never received",
- async () => await message.Delete(),
- x => _targetBot.MessageDeleted += x,
- x => _targetBot.MessageDeleted -= x,
- (s, e) => e.Message.Id == message.Id);
- }
- [TestMethod]
- public async Task TestDownloadMessages()
- {
- string name = GetRandomText();
- var channel = await _testGuild.CreateTextChannel(name);
- for (var i = 0; i < 10; i++) await channel.SendMessage(GetRandomText());
- while (channel.Discord.MessageQueue.Count > 0) await Task.Delay(100);
- var messages = await channel.GetMessages(10);
- Assert.AreEqual(10, messages.Count(), "Expected 10 messages in downloaded array, did not see 10.");
- }
- [TestMethod]
- public async Task TestSendTTSMessage()
- {
- var channel = await _testGuild.CreateTextChannel(GetRandomText());
- AssertEvent(
- "MessageCreated event never fired",
- async () => await channel.SendMessage(GetRandomText(), true),
- x => _targetBot.MessageReceived += x,
- x => _targetBot.MessageReceived -= x,
- (s, e) => e.Message.IsTTS);
- }
-
- #endregion
-
- #region User Tests
-
- [TestMethod]
- public async Task TestUserMentions()
- {
- var user = (await _targetBot.GetGuild(_testGuild.Id)).CurrentUser;
- Assert.AreEqual($"<@{user.Id}>", user.Mention);
- }
- [TestMethod]
- public void TestUserEdit()
- {
- var user = _testGuild.GetUser(_targetBot.CurrentUser.Id);
- AssertEvent(
- "UserUpdated never fired",
- async () => await user.Modify(x =>
- {
- x.Deaf = true;
- x.Mute = true;
- }),
- x => _targetBot.UserUpdated += x,
- x => _targetBot.UserUpdated -= x);
- }
- [TestMethod]
- public void TestEditSelf()
- {
- throw new NotImplementedException();
- /*var name = RandomText
- AssertEvent(
- "UserUpdated never fired",
- async () => await _targetBot.CurrentUser.Modify(TargetPassword, name),
- x => _obGuildBot.UserUpdated += x,
- x => _obGuildBot.UserUpdated -= x,
- (s, e) => e.After.Username == name);*/
- }
- [TestMethod]
- public void TestSetStatus()
- {
- AssertEvent(
- "UserUpdated never fired",
- async () => await SetStatus(_targetBot, UserStatus.Idle),
- x => _observerBot.UserUpdated += x,
- x => _observerBot.UserUpdated -= x,
- (s, e) => e.After.Status == UserStatus.Idle);
- }
- private Task SetStatus(DiscordClient _client, UserStatus status)
- {
- throw new NotImplementedException();
- /*_client.SetStatus(status);
- await Task.Delay(50);*/
- }
- [TestMethod]
- public void TestSetGame()
- {
- AssertEvent(
- "UserUpdated never fired",
- async () => await SetGame(_targetBot, "test game"),
- x => _observerBot.UserUpdated += x,
- x => _observerBot.UserUpdated -= x,
- (s, e) => _targetBot.CurrentUser.CurrentGame == "test game");
-
- }
- private Task SetGame(DiscordClient _client, string game)
- {
- throw new NotImplementedException();
- //_client.SetGame(game);
- //await Task.Delay(5);
- }
-
- #endregion
-
- #region Permission Tests
-
- // Permissions
- [TestMethod]
- public async Task Test_AddGet_PermissionsRule()
- {
- var channel = await _testGuild.CreateTextChannel(GetRandomText());
- var user = _testGuild.GetUser(_targetBot.CurrentUser.Id);
- var perms = new OverwritePermissions(sendMessages: PermValue.Deny);
- await channel.UpdatePermissionOverwrite(user, perms);
- var resultPerms = channel.GetPermissionOverwrite(user);
- Assert.IsNotNull(resultPerms, "Perms retrieved from Guild were null.");
- }
- [TestMethod]
- public async Task Test_AddRemove_PermissionsRule()
- {
- var channel = await _testGuild.CreateTextChannel(GetRandomText());
- var user = _testGuild.GetUser(_targetBot.CurrentUser.Id);
- var perms = new OverwritePermissions(sendMessages: PermValue.Deny);
- await channel.UpdatePermissionOverwrite(user, perms);
- await channel.RemovePermissionOverwrite(user);
- await Task.Delay(200);
- Assert.AreEqual(PermValue.Inherit, channel.GetPermissionOverwrite(user)?.SendMessages);
- }
- [TestMethod]
- public async Task Test_Permissions_Event()
- {
- var channel = await _testGuild.CreateTextChannel(GetRandomText());
- var user = _testGuild.GetUser(_targetBot.CurrentUser.Id);
- var perms = new OverwritePermissions(sendMessages: PermValue.Deny);
- AssertEvent
- ("ChannelUpdatedEvent never fired.",
- async () => await channel.UpdatePermissionOverwrite(user, perms),
- x => _targetBot.ChannelUpdated += x,
- x => _targetBot.ChannelUpdated -= x,
- (s, e) => e.Channel == channel && (e.After as GuildChannel).PermissionOverwrites.Count() != (e.Before as GuildChannel).PermissionOverwrites.Count());
- }
- [TestMethod]
- [ExpectedException(typeof(Net.HttpException))]
- public async Task Test_Affect_Permissions_Invalid_Channel()
- {
- var channel = await _testGuild.CreateTextChannel(GetRandomText());
- var user = _testGuild.GetUser(_targetBot.CurrentUser.Id);
- var perms = new OverwritePermissions(sendMessages: PermValue.Deny);
- await channel.Delete();
- await channel.UpdatePermissionOverwrite(user, perms);
- }
-
- #endregion
-
-
- [ClassCleanup]
- public static async Task Cleanup()
- {
- WaitMany(
- (await _hostBot.GetGuilds()).Select(x => x.Owner.Id == _hostBot.CurrentUser.Id ? x.Delete() : x.Leave()),
- (await _targetBot.GetGuilds()).Select(x => x.Owner.Id == _targetBot.CurrentUser.Id ? x.Delete() : x.Leave()),
- (await _observerBot.GetGuilds()).Select(x => x.Owner.Id == _observerBot.CurrentUser.Id ? x.Delete() : x.Leave()));
-
- WaitAll(
- _hostBot.Disconnect(),
- _targetBot.Disconnect(),
- _observerBot.Disconnect());
- }
-
- #region Helpers
-
- // Task Helpers
-
- private static void AssertEvent(string msg, Func action, Action> addEvent, Action> removeEvent, Func