From ea1c882fdb0b26a2bc2feaba70bd1996d17d2cfe Mon Sep 17 00:00:00 2001 From: Christopher F Date: Wed, 7 Sep 2016 20:32:31 -0400 Subject: [PATCH] Finish implementing REST framework, implement mocks for Login Testing --- Discord.Net.sln | 8 ++++- .../Discord.Net.Tests/Discord.Net.Tests.xproj | 4 ++- .../Framework/MockRestClient.cs | 31 ++++++++++------- .../Framework/Mocks/Rest/Users.cs | 18 ++++++++++ .../Framework/RequestHandler.cs | 34 +++++++++++++++++++ .../Framework/Routes/Users.cs | 23 +++++++++++++ test/Discord.Net.Tests/Rest/LoginTests.cs | 19 +++++++++-- test/Discord.Net.Tests/Rest/RestFixture.cs | 15 ++++---- test/Discord.Net.Tests/Tests.cs | 14 -------- 9 files changed, 128 insertions(+), 38 deletions(-) create mode 100644 test/Discord.Net.Tests/Framework/Mocks/Rest/Users.cs create mode 100644 test/Discord.Net.Tests/Framework/RequestHandler.cs create mode 100644 test/Discord.Net.Tests/Framework/Routes/Users.cs delete mode 100644 test/Discord.Net.Tests/Tests.cs diff --git a/Discord.Net.sln b/Discord.Net.sln index 11960606b..94259e2a7 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.xproj b/test/Discord.Net.Tests/Discord.Net.Tests.xproj index 1177c8fb2..46ce007f6 100644 --- a/test/Discord.Net.Tests/Discord.Net.Tests.xproj +++ b/test/Discord.Net.Tests/Discord.Net.Tests.xproj @@ -11,9 +11,11 @@ .\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 index 3450f0f94..1203ee525 100644 --- a/test/Discord.Net.Tests/Framework/MockRestClient.cs +++ b/test/Discord.Net.Tests/Framework/MockRestClient.cs @@ -4,37 +4,42 @@ 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) - { } - - Task IRestClient.SendAsync(string method, string endpoint, bool headerOnly) { - throw new NotImplementedException(); + _requestHandler = new RequestHandler(); } - Task IRestClient.SendAsync(string method, string endpoint, IReadOnlyDictionary multipartParams, bool headerOnly) - { - throw new NotImplementedException(); - } + private Dictionary _headers = new Dictionary(); + public IReadOnlyDictionary Headers => + new ReadOnlyDictionary(_headers); + private RequestHandler _requestHandler; - Task IRestClient.SendAsync(string method, string endpoint, string json, bool headerOnly) + 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(); } - void IRestClient.SetCancelToken(CancellationToken cancelToken) + public Task SendAsync(string method, string endpoint, string json, bool headerOnly = false) { - throw new NotImplementedException(); + return Task.FromResult(_requestHandler.GetMock(method, endpoint, json, Headers)); } - void IRestClient.SetHeader(string key, string value) + public void SetCancelToken(CancellationToken cancelToken) { } + + public void SetHeader(string key, string value) { - throw new NotImplementedException(); + if (_headers.ContainsKey(key)) + _headers.Remove(key); + _headers.Add(key, value); } } } 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 000000000..8009b420d --- /dev/null +++ b/test/Discord.Net.Tests/Framework/Mocks/Rest/Users.cs @@ -0,0 +1,18 @@ +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" + }; + } +} diff --git a/test/Discord.Net.Tests/Framework/RequestHandler.cs b/test/Discord.Net.Tests/Framework/RequestHandler.cs new file mode 100644 index 000000000..2a2ed98a9 --- /dev/null +++ b/test/Discord.Net.Tests/Framework/RequestHandler.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using System.Text; +using UserRoutes = Discord.Tests.Framework.Routes.Users; +using Newtonsoft.Json; +using Discord.Net.Converters; + +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() + { + ["GET users/@me"] = new Response(UserRoutes.Me) + }; + + 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 NotImplementedException($"{key}: {json}"); + 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/Users.cs b/test/Discord.Net.Tests/Framework/Routes/Users.cs new file mode 100644 index 000000000..29d6183e1 --- /dev/null +++ b/test/Discord.Net.Tests/Framework/Routes/Users.cs @@ -0,0 +1,23 @@ +using UserMocks = Discord.Tests.Framework.Mocks.Rest.Users; +using Newtonsoft.Json; +using System.IO; +using System.Collections.Generic; +using Discord.Net; +using System.Net; + +namespace Discord.Tests.Framework.Routes +{ + public static class Users + { + public static readonly string UserToken = "token.user"; + public static readonly string BotToken = "token.bot"; + public static readonly string BearerToken = "token.bearer"; + + public static object Me(string json, IReadOnlyDictionary requestHeaders) + { + if (!requestHeaders.ContainsKey("authorization")) throw new HttpException(HttpStatusCode.Forbidden); + if (requestHeaders["authorization"] != UserToken) throw new HttpException(HttpStatusCode.Forbidden); + return UserMocks.SelfUser; + } + } +} diff --git a/test/Discord.Net.Tests/Rest/LoginTests.cs b/test/Discord.Net.Tests/Rest/LoginTests.cs index 1655b654d..bb1c0287f 100644 --- a/test/Discord.Net.Tests/Rest/LoginTests.cs +++ b/test/Discord.Net.Tests/Rest/LoginTests.cs @@ -5,16 +5,31 @@ using System.Threading.Tasks; using Xunit; using Discord; using Discord.Rest; +using Routes = Discord.Tests.Framework.Routes.Users; +using Discord.Net; namespace Discord.Tests.Rest { public class LoginTests : IClassFixture { - DiscordRestClient client; + RestFixture fixture; public LoginTests(RestFixture fixture) { - client = fixture.Client; + this.fixture = fixture; + } + + [Fact] + public async Task LoginAsUser() + { + var client = fixture.Client; + await client.LoginAsync(TokenType.User, Routes.UserToken); + } + [Fact] + public async Task LoginAsUserWithInvalidToken() + { + var client = fixture.Client; + await Assert.ThrowsAsync(async () => await client.LoginAsync(TokenType.User, "token.invalid")); } } } diff --git a/test/Discord.Net.Tests/Rest/RestFixture.cs b/test/Discord.Net.Tests/Rest/RestFixture.cs index 7959696f9..7c40bb96e 100644 --- a/test/Discord.Net.Tests/Rest/RestFixture.cs +++ b/test/Discord.Net.Tests/Rest/RestFixture.cs @@ -10,15 +10,16 @@ namespace Discord.Tests.Rest { public class RestFixture { - public DiscordRestClient Client { get; set; } - - public RestFixture() + public DiscordRestClient Client { - var Config = new DiscordRestConfig() + get { - RestClientProvider = new RestClientProvider(baseUrl => new MockRestClient(baseUrl)) - }; - Client = new DiscordRestClient(); + var Config = new DiscordRestConfig() + { + RestClientProvider = new RestClientProvider(baseUrl => new MockRestClient(baseUrl)) + }; + return new DiscordRestClient(Config); + } } } } diff --git a/test/Discord.Net.Tests/Tests.cs b/test/Discord.Net.Tests/Tests.cs deleted file mode 100644 index 1bd5ced4f..000000000 --- a/test/Discord.Net.Tests/Tests.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; -using Xunit; - -namespace Tests -{ - public class Tests - { - [Fact] - public void Test1() - { - Assert.True(true); - } - } -}