diff --git a/Vonage.Test.Unit/VerifyV2/Cancel/RequestTest.cs b/Vonage.Test.Unit/VerifyV2/Cancel/RequestTest.cs new file mode 100644 index 000000000..d1a90505e --- /dev/null +++ b/Vonage.Test.Unit/VerifyV2/Cancel/RequestTest.cs @@ -0,0 +1,31 @@ +using System; +using Vonage.Common.Failures; +using Vonage.Common.Test.Extensions; +using Vonage.VerifyV2.Cancel; +using Xunit; + +namespace Vonage.Test.Unit.VerifyV2.Cancel +{ + public class RequestTest + { + [Fact] + public void Create_ShouldReturnFailure_GivenRequestIsEmpty() => + CancelRequest.Parse(Guid.Empty) + .Should() + .BeFailure(ResultFailure.FromErrorMessage("RequestId cannot be empty.")); + + [Fact] + public void Create_ShouldReturnSuccess() => + CancelRequest.Parse(new Guid("f3a065af-ac5a-47a4-8dfe-819561a7a287")) + .Map(request => request.RequestId) + .Should() + .BeSuccess(new Guid("f3a065af-ac5a-47a4-8dfe-819561a7a287")); + + [Fact] + public void GetEndpointPath_ShouldReturnApiEndpoint() => + CancelRequest.Parse(new Guid("f3a065af-ac5a-47a4-8dfe-819561a7a287")) + .Map(request => request.GetEndpointPath()) + .Should() + .BeSuccess("/v2/verify/f3a065af-ac5a-47a4-8dfe-819561a7a287"); + } +} \ No newline at end of file diff --git a/Vonage.Test.Unit/VerifyV2/Cancel/UseCaseTest.cs b/Vonage.Test.Unit/VerifyV2/Cancel/UseCaseTest.cs new file mode 100644 index 000000000..f953b0a94 --- /dev/null +++ b/Vonage.Test.Unit/VerifyV2/Cancel/UseCaseTest.cs @@ -0,0 +1,60 @@ +using System; +using System.Net.Http; +using System.Threading.Tasks; +using AutoFixture; +using AutoFixture.Kernel; +using FsCheck; +using FsCheck.Xunit; +using Vonage.Common.Client; +using Vonage.Common.Monads; +using Vonage.Common.Test; +using Vonage.Common.Test.TestHelpers; +using Vonage.VerifyV2; +using Vonage.VerifyV2.Cancel; +using Xunit; + +namespace Vonage.Test.Unit.VerifyV2.Cancel +{ + public class UseCaseTest : BaseUseCase, IUseCase + { + private Func>> Operation => + configuration => new VerifyV2Client(configuration).CancelAsync(this.request); + + private readonly Result request; + + public UseCaseTest() => this.request = BuildRequest(this.helper.Fixture); + + [Property] + public Property ShouldReturnFailure_GivenApiErrorCannotBeParsed() => + this.helper.VerifyReturnsFailureGivenErrorCannotBeParsed(this.BuildExpectedRequest(), this.Operation); + + [Property] + public Property ShouldReturnFailure_GivenApiResponseIsError() => + this.helper.VerifyReturnsFailureGivenApiResponseIsError(this.BuildExpectedRequest(), this.Operation); + + [Fact] + public async Task ShouldReturnFailure_GivenRequestIsFailure() => + await this.helper.VerifyReturnsFailureGivenRequestIsFailure( + (configuration, failureRequest) => new VerifyV2Client(configuration).CancelAsync(failureRequest)); + + [Fact] + public async Task ShouldReturnFailure_GivenTokenGenerationFailed() => + await this.helper.VerifyReturnsFailureGivenTokenGenerationFails(this.Operation); + + [Fact] + public async Task ShouldReturnSuccess_GivenApiResponseIsSuccess() => + await this.helper.VerifyReturnsExpectedValueGivenApiResponseIsSuccess(this.BuildExpectedRequest(), + this.Operation); + + private ExpectedRequest BuildExpectedRequest() => + new ExpectedRequest + { + Method = HttpMethod.Delete, + RequestUri = new Uri(UseCaseHelper.GetPathFromRequest(this.request), UriKind.Relative), + }; + + private static Result BuildRequest( + ISpecimenBuilder fixture) => + CancelRequest.Parse(fixture.Create()); + } +} \ No newline at end of file diff --git a/Vonage/VerifyV2/Cancel/CancelRequest.cs b/Vonage/VerifyV2/Cancel/CancelRequest.cs new file mode 100644 index 000000000..1ccb61aa8 --- /dev/null +++ b/Vonage/VerifyV2/Cancel/CancelRequest.cs @@ -0,0 +1,39 @@ +using System; +using System.Net.Http; +using Vonage.Common.Client; +using Vonage.Common.Monads; +using Vonage.Common.Validation; + +namespace Vonage.VerifyV2.Cancel; + +/// +public readonly struct CancelRequest : IVonageRequest +{ + private CancelRequest(Guid requestId) => this.RequestId = requestId; + + /// + /// ID of the verify request. + /// + public Guid RequestId { get; internal init; } + + /// + public HttpRequestMessage BuildRequestMessage() => VonageRequestBuilder + .Initialize(HttpMethod.Delete, this.GetEndpointPath()) + .Build(); + + /// + public string GetEndpointPath() => $"/v2/verify/{this.RequestId}"; + + /// + /// Parses the input into a CancelRequest. + /// + /// The verify request identifier. + /// A success state with the request if the parsing succeeded. A failure state with an error if it failed. + public static Result Parse(Guid requestId) => + Result + .FromSuccess(new CancelRequest(requestId)) + .Bind(VerifyRoomId); + + private static Result VerifyRoomId(CancelRequest request) => + InputValidation.VerifyNotEmpty(request, request.RequestId, nameof(RequestId)); +} \ No newline at end of file diff --git a/Vonage/VerifyV2/IVerifyV2Client.cs b/Vonage/VerifyV2/IVerifyV2Client.cs index e1fa5a5f2..7a52d5ea4 100644 --- a/Vonage/VerifyV2/IVerifyV2Client.cs +++ b/Vonage/VerifyV2/IVerifyV2Client.cs @@ -1,5 +1,6 @@ using System.Threading.Tasks; using Vonage.Common.Monads; +using Vonage.VerifyV2.Cancel; using Vonage.VerifyV2.StartVerification; using Vonage.VerifyV2.VerifyCode; @@ -10,6 +11,13 @@ namespace Vonage.VerifyV2; /// public interface IVerifyV2Client { + /// + /// Aborts the workflow if a verification request is still active. + /// + /// The request. + /// Success or Failure. + Task> CancelAsync(Result request); + /// /// Requests a verification to be sent to a user. /// diff --git a/Vonage/VerifyV2/VerifyV2Client.cs b/Vonage/VerifyV2/VerifyV2Client.cs index b91c70aaf..9bdfd7f95 100644 --- a/Vonage/VerifyV2/VerifyV2Client.cs +++ b/Vonage/VerifyV2/VerifyV2Client.cs @@ -2,6 +2,7 @@ using Vonage.Common; using Vonage.Common.Client; using Vonage.Common.Monads; +using Vonage.VerifyV2.Cancel; using Vonage.VerifyV2.StartVerification; using Vonage.VerifyV2.VerifyCode; @@ -19,6 +20,10 @@ internal class VerifyV2Client : IVerifyV2Client internal VerifyV2Client(VonageHttpClientConfiguration configuration) => this.vonageClient = new VonageHttpClient(configuration, JsonSerializer.BuildWithSnakeCase()); + /// + public Task> CancelAsync(Result request) => + this.vonageClient.SendAsync(request); + /// public Task> StartVerificationAsync(Result request) where T : IStartVerificationRequest =>