| @@ -1,12 +1,14 @@ | |||||
| | | ||||
| Microsoft Visual Studio Solution File, Format Version 12.00 | Microsoft Visual Studio Solution File, Format Version 12.00 | ||||
| # Visual Studio 14 | # Visual Studio 14 | ||||
| VisualStudioVersion = 14.0.25123.0 | |||||
| VisualStudioVersion = 14.0.25420.1 | |||||
| MinimumVisualStudioVersion = 10.0.40219.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}" | Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Discord.Net", "src\Discord.Net\Discord.Net.xproj", "{91E9E7BD-75C9-4E98-84AA-2C271922E5C2}" | ||||
| EndProject | EndProject | ||||
| Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Discord.Net.Commands", "src\Discord.Net.Commands\Discord.Net.Commands.xproj", "{078DD7E6-943D-4D09-AFC2-D2BA58B76C9C}" | Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Discord.Net.Commands", "src\Discord.Net.Commands\Discord.Net.Commands.xproj", "{078DD7E6-943D-4D09-AFC2-D2BA58B76C9C}" | ||||
| EndProject | 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 | Global | ||||
| GlobalSection(SolutionConfigurationPlatforms) = preSolution | GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||||
| Debug|Any CPU = Debug|Any CPU | 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}.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.ActiveCfg = Release|Any CPU | ||||
| {078DD7E6-943D-4D09-AFC2-D2BA58B76C9C}.Release|Any CPU.Build.0 = 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 | EndGlobalSection | ||||
| GlobalSection(SolutionProperties) = preSolution | GlobalSection(SolutionProperties) = preSolution | ||||
| HideSolutionNode = FALSE | HideSolutionNode = FALSE | ||||
| @@ -11,9 +11,11 @@ | |||||
| <BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">.\obj</BaseIntermediateOutputPath> | <BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">.\obj</BaseIntermediateOutputPath> | ||||
| <OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath> | <OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath> | ||||
| </PropertyGroup> | </PropertyGroup> | ||||
| <PropertyGroup> | <PropertyGroup> | ||||
| <SchemaVersion>2.0</SchemaVersion> | <SchemaVersion>2.0</SchemaVersion> | ||||
| </PropertyGroup> | </PropertyGroup> | ||||
| <ItemGroup> | |||||
| <Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" /> | |||||
| </ItemGroup> | |||||
| <Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" /> | <Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" /> | ||||
| </Project> | </Project> | ||||
| @@ -4,37 +4,42 @@ using System.IO; | |||||
| using System.Threading; | using System.Threading; | ||||
| using System.Threading.Tasks; | using System.Threading.Tasks; | ||||
| using Discord.Net.Rest; | using Discord.Net.Rest; | ||||
| using System.Collections.ObjectModel; | |||||
| namespace Discord.Tests.Framework | namespace Discord.Tests.Framework | ||||
| { | { | ||||
| public class MockRestClient : IRestClient | public class MockRestClient : IRestClient | ||||
| { | { | ||||
| public MockRestClient(string baseUrl) | public MockRestClient(string baseUrl) | ||||
| { } | |||||
| Task<Stream> IRestClient.SendAsync(string method, string endpoint, bool headerOnly) | |||||
| { | { | ||||
| throw new NotImplementedException(); | |||||
| _requestHandler = new RequestHandler(); | |||||
| } | } | ||||
| Task<Stream> IRestClient.SendAsync(string method, string endpoint, IReadOnlyDictionary<string, object> multipartParams, bool headerOnly) | |||||
| { | |||||
| throw new NotImplementedException(); | |||||
| } | |||||
| private Dictionary<string, string> _headers = new Dictionary<string, string>(); | |||||
| public IReadOnlyDictionary<string, string> Headers => | |||||
| new ReadOnlyDictionary<string, string>(_headers); | |||||
| private RequestHandler _requestHandler; | |||||
| Task<Stream> IRestClient.SendAsync(string method, string endpoint, string json, bool headerOnly) | |||||
| public Task<Stream> SendAsync(string method, string endpoint, bool headerOnly = false) => | |||||
| SendAsync(method, endpoint, "", headerOnly); | |||||
| public Task<Stream> SendAsync(string method, string endpoint, IReadOnlyDictionary<string, object> multipartParams, bool headerOnly = false) | |||||
| { | { | ||||
| throw new NotImplementedException(); | throw new NotImplementedException(); | ||||
| } | } | ||||
| void IRestClient.SetCancelToken(CancellationToken cancelToken) | |||||
| public Task<Stream> 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); | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -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" | |||||
| }; | |||||
| } | |||||
| } | |||||
| @@ -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<string, string> requestHeaders); | |||||
| internal static JsonSerializerSettings SerializerSettings = new JsonSerializerSettings() { ContractResolver = new DiscordContractResolver() }; | |||||
| internal Dictionary<string, Response> Routes = new Dictionary<string, Response>() | |||||
| { | |||||
| ["GET users/@me"] = new Response(UserRoutes.Me) | |||||
| }; | |||||
| internal Stream GetMock(string method, string endpoint, string json, IReadOnlyDictionary<string, string> 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)); | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -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<string, string> requestHeaders) | |||||
| { | |||||
| if (!requestHeaders.ContainsKey("authorization")) throw new HttpException(HttpStatusCode.Forbidden); | |||||
| if (requestHeaders["authorization"] != UserToken) throw new HttpException(HttpStatusCode.Forbidden); | |||||
| return UserMocks.SelfUser; | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -5,16 +5,31 @@ using System.Threading.Tasks; | |||||
| using Xunit; | using Xunit; | ||||
| using Discord; | using Discord; | ||||
| using Discord.Rest; | using Discord.Rest; | ||||
| using Routes = Discord.Tests.Framework.Routes.Users; | |||||
| using Discord.Net; | |||||
| namespace Discord.Tests.Rest | namespace Discord.Tests.Rest | ||||
| { | { | ||||
| public class LoginTests : IClassFixture<RestFixture> | public class LoginTests : IClassFixture<RestFixture> | ||||
| { | { | ||||
| DiscordRestClient client; | |||||
| RestFixture fixture; | |||||
| public LoginTests(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<ArgumentException>(async () => await client.LoginAsync(TokenType.User, "token.invalid")); | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -10,15 +10,16 @@ namespace Discord.Tests.Rest | |||||
| { | { | ||||
| public class RestFixture | 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); | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -1,14 +0,0 @@ | |||||
| using System; | |||||
| using Xunit; | |||||
| namespace Tests | |||||
| { | |||||
| public class Tests | |||||
| { | |||||
| [Fact] | |||||
| public void Test1() | |||||
| { | |||||
| Assert.True(true); | |||||
| } | |||||
| } | |||||
| } | |||||