using System; using System.Collections.Generic; using System.Threading.Tasks; using NSubstitute; using Octokit.Tests.Helpers; using Xunit; namespace Octokit.Tests.Clients { /// /// Client tests mostly just need to make sure they call the IApiConnection with the correct /// relative Uri. No need to fake up the response. All *those* tests are in ApiConnectionTests.cs. /// public class AuthorizationsClientTests { public class TheConstructor { [Fact] public void ThrowsForBadArgs() { Assert.Throws(() => new AuthorizationsClient(null)); } } public class TheGetAllMethod { [Fact] public void GetsAListOfAuthorizations() { var client = Substitute.For(); var authEndpoint = new AuthorizationsClient(client); authEndpoint.GetAll(); client.Received().GetAll(Arg.Is(u => u.ToString() == "/authorizations"), null); } } public class TheGetMethod { [Fact] public void GetsAnAuthorization() { var client = Substitute.For(); var authEndpoint = new AuthorizationsClient(client); authEndpoint.Get(1); client.Received().Get(Arg.Is(u => u.ToString() == "/authorizations/1"), null); } } public class TheUpdateAsyncMethod { [Fact] public void SendsUpdateToCorrectUrl() { var client = Substitute.For(); var authEndpoint = new AuthorizationsClient(client); authEndpoint.Update(1, new AuthorizationUpdate()); client.Received().Update(Arg.Is(u => u.ToString() == "/authorizations/1"), Args.AuthorizationUpdate); } } public class TheCreateAsyncMethod { [Fact] public void SendsCreateToCorrectUrl() { var client = Substitute.For(); var authEndpoint = new AuthorizationsClient(client); authEndpoint.Create(new NewAuthorization()); client.Received().Post(Arg.Is(u => u.ToString() == "/authorizations") , Args.NewAuthorization); } } public class TheDeleteAsyncMethod { [Fact] public void DeletesCorrectUrl() { var client = Substitute.For(); var authEndpoint = new AuthorizationsClient(client); authEndpoint.Delete(1); client.Received().Delete(Arg.Is(u => u.ToString() == "/authorizations/1")); } } public class TheGetOrCreateApplicationAuthenticationMethod { [Fact] public void GetsOrCreatesAuthenticationAtCorrectUrl() { var data = new NewAuthorization(); var client = Substitute.For(); var authEndpoint = new AuthorizationsClient(client); authEndpoint.GetOrCreateApplicationAuthentication("clientId", "secret", data); client.Received().Put(Arg.Is(u => u.ToString() == "/authorizations/clients/clientId"), Args.Object); } [Fact] public async Task WrapsTwoFactorFailureWithTwoFactorException() { var data = new NewAuthorization(); var client = Substitute.For(); client.Put(Args.Uri, Args.Object, Args.String).Returns(_ => { throw new AuthorizationException(); }); var authEndpoint = new AuthorizationsClient(client); AssertEx.Throws(async () => await authEndpoint.GetOrCreateApplicationAuthentication("clientId", "secret", data)); } [Fact] public async Task UsesCallbackToRetrieveTwoFactorCode() { var twoFactorChallengeResult = new TwoFactorChallengeResult("two-factor-code"); var data = new NewAuthorization { Note = "note" }; var client = Substitute.For(); client.GetOrCreateApplicationAuthentication("clientId", "secret", Arg.Any()) .Returns(_ => {throw new TwoFactorRequiredException();}); client.GetOrCreateApplicationAuthentication("clientId", "secret", Arg.Any(), "two-factor-code") .Returns(Task.Factory.StartNew(() => new Authorization {Token = "xyz"})); var result = await client.GetOrCreateApplicationAuthentication("clientId", "secret", data, e => Task.Factory.StartNew(() => twoFactorChallengeResult)); client.Received().GetOrCreateApplicationAuthentication("clientId", "secret", Arg.Is(u => u.Note == "note")); client.Received().GetOrCreateApplicationAuthentication("clientId", "secret", Arg.Any(), "two-factor-code"); Assert.Equal("xyz", result.Token); } [Fact] public async Task RetriesWhenResendRequested() { var challengeResults = new Queue(new [] { TwoFactorChallengeResult.RequestResendCode, new TwoFactorChallengeResult("two-factor-code") }); var data = new NewAuthorization(); var client = Substitute.For(); client.GetOrCreateApplicationAuthentication("clientId", "secret", Arg.Any()) .Returns(_ => { throw new TwoFactorRequiredException(); }); client.GetOrCreateApplicationAuthentication("clientId", "secret", Arg.Any(), "two-factor-code") .Returns(Task.Factory.StartNew(() => new Authorization { Token = "OAUTHSECRET" })); var result = await client.GetOrCreateApplicationAuthentication("clientId", "secret", data, e => Task.Factory.StartNew(() => challengeResults.Dequeue())); client.Received(2).GetOrCreateApplicationAuthentication("clientId", "secret", Args.NewAuthorization); client.Received().GetOrCreateApplicationAuthentication("clientId", "secret", Args.NewAuthorization, "two-factor-code"); Assert.Equal("OAUTHSECRET", result.Token); } [Fact] public async Task ThrowsTwoFactorChallengeFailedExceptionWhenProvidedCodeIsIncorrect() { var challengeResults = new Queue(new[] { TwoFactorChallengeResult.RequestResendCode, new TwoFactorChallengeResult("wrong-code"), }); var data = new NewAuthorization(); var client = Substitute.For(); client.GetOrCreateApplicationAuthentication("clientId", "secret", Arg.Any()) .Returns(_ => { throw new TwoFactorRequiredException(); }); client.GetOrCreateApplicationAuthentication("clientId", "secret", Arg.Any(), "wrong-code") .Returns(_ => { throw new TwoFactorChallengeFailedException(); }); var exception = AssertEx.Throws(async () => await client.GetOrCreateApplicationAuthentication( "clientId", "secret", data, e => Task.Factory.StartNew(() => challengeResults.Dequeue()))); Assert.NotNull(exception); client.Received().GetOrCreateApplicationAuthentication("clientId", "secret", Arg.Any()); client.Received().GetOrCreateApplicationAuthentication("clientId", "secret", Arg.Any(), "wrong-code"); } } } }