diff --git a/Vonage.Test/Conversations/DeleteEvent/E2ETest.cs b/Vonage.Test/Conversations/DeleteEvent/E2ETest.cs new file mode 100644 index 00000000..7064edf1 --- /dev/null +++ b/Vonage.Test/Conversations/DeleteEvent/E2ETest.cs @@ -0,0 +1,29 @@ +using System.Net; +using System.Threading.Tasks; +using Vonage.Test.Common.Extensions; +using WireMock.ResponseBuilders; +using Xunit; + +namespace Vonage.Test.Conversations.DeleteEvent; + +[Trait("Category", "E2E")] +public class E2ETest : E2EBase +{ + public E2ETest() : base(typeof(E2ETest).Namespace) + { + } + + [Fact] + public async Task DeleteEvent() + { + this.Helper.Server.Given(WireMock.RequestBuilders.Request.Create() + .WithPath("/v1/conversations/CON-123/events/EVE-123") + .WithHeader("Authorization", this.Helper.ExpectedAuthorizationHeaderValue) + .UsingDelete()) + .RespondWith(Response.Create().WithStatusCode(HttpStatusCode.OK)); + await this.Helper.VonageClient.ConversationsClient + .DeleteEventAsync(RequestTest.BuildRequest()) + .Should() + .BeSuccessAsync(); + } +} \ No newline at end of file diff --git a/Vonage.Test/Conversations/DeleteEvent/RequestTest.cs b/Vonage.Test/Conversations/DeleteEvent/RequestTest.cs new file mode 100644 index 00000000..5d550076 --- /dev/null +++ b/Vonage.Test/Conversations/DeleteEvent/RequestTest.cs @@ -0,0 +1,55 @@ +using Vonage.Common.Monads; +using Vonage.Conversations.DeleteEvent; +using Vonage.Test.Common.Extensions; +using Xunit; + +namespace Vonage.Test.Conversations.DeleteEvent; + +[Trait("Category", "Request")] +public class RequestTest +{ + private const string ValidConversationId = "CON-123"; + private const string ValidEventId = "EVE-123"; + + [Fact] + public void GetEndpointPath_ShouldReturnApiEndpoint() => + BuildRequest() + .Map(request => request.GetEndpointPath()) + .Should() + .BeSuccess("/v1/conversations/CON-123/events/EVE-123"); + + internal static Result BuildRequest() => + DeleteEventRequest.Parse(ValidConversationId, ValidEventId); + + [Theory] + [InlineData("")] + [InlineData(" ")] + [InlineData(null)] + public void Parse_ShouldReturnFailure_GivenConversationIdIsEmpty(string invalidId) => + DeleteEventRequest.Parse(invalidId, ValidEventId) + .Should() + .BeParsingFailure("ConversationId cannot be null or whitespace."); + + [Theory] + [InlineData("")] + [InlineData(" ")] + [InlineData(null)] + public void Parse_ShouldReturnFailure_GivenEventIdIsEmpty(string invalidId) => + DeleteEventRequest.Parse(ValidConversationId, invalidId) + .Should() + .BeParsingFailure("EventId cannot be null or whitespace."); + + [Fact] + public void Parse_ShouldSetConversationId() => + BuildRequest() + .Map(request => request.ConversationId) + .Should() + .BeSuccess("CON-123"); + + [Fact] + public void Parse_ShouldSetEventId() => + BuildRequest() + .Map(request => request.EventId) + .Should() + .BeSuccess("EVE-123"); +} \ No newline at end of file diff --git a/Vonage/Conversations/ConversationsClient.cs b/Vonage/Conversations/ConversationsClient.cs index 47ff19a2..52439ce3 100644 --- a/Vonage/Conversations/ConversationsClient.cs +++ b/Vonage/Conversations/ConversationsClient.cs @@ -4,6 +4,7 @@ using Vonage.Conversations.CreateConversation; using Vonage.Conversations.CreateMember; using Vonage.Conversations.DeleteConversation; +using Vonage.Conversations.DeleteEvent; using Vonage.Conversations.GetConversation; using Vonage.Conversations.GetConversations; using Vonage.Conversations.GetMember; @@ -35,6 +36,10 @@ public Task> public Task> DeleteConversationAsync(Result request) => this.vonageClient.SendAsync(request); + /// + public Task> DeleteEventAsync(Result request) => + this.vonageClient.SendAsync(request); + /// public Task> GetConversationAsync(Result request) => this.vonageClient.SendWithResponseAsync(request); diff --git a/Vonage/Conversations/DeleteEvent/DeleteEventRequest.cs b/Vonage/Conversations/DeleteEvent/DeleteEventRequest.cs new file mode 100644 index 00000000..9c21c6c9 --- /dev/null +++ b/Vonage/Conversations/DeleteEvent/DeleteEventRequest.cs @@ -0,0 +1,46 @@ +using System.Net.Http; +using Vonage.Common.Client; +using Vonage.Common.Monads; +using Vonage.Common.Validation; + +namespace Vonage.Conversations.DeleteEvent; + +/// +public readonly struct DeleteEventRequest : IVonageRequest +{ + /// + /// The conversation Id. + /// + public string ConversationId { get; private init; } + + /// + /// The event Id. + /// + public string EventId { get; private init; } + + /// + public HttpRequestMessage BuildRequestMessage() => VonageRequestBuilder + .Initialize(HttpMethod.Delete, this.GetEndpointPath()) + .Build(); + + /// + public string GetEndpointPath() => $"/v1/conversations/{this.ConversationId}/events/{this.EventId}"; + + /// + /// Parses the input into a DeleteEventRequest. + /// + /// The conversation Id. + /// The event Id. + /// A success state with the request if the parsing succeeded. A failure state with an error if it failed. + public static Result Parse(string conversationId, string eventId) => + Result + .FromSuccess(new DeleteEventRequest {ConversationId = conversationId, EventId = eventId}) + .Map(InputEvaluation.Evaluate) + .Bind(evaluation => evaluation.WithRules(VerifyConversationId, VerifyEventId)); + + private static Result VerifyConversationId(DeleteEventRequest request) => + InputValidation.VerifyNotEmpty(request, request.ConversationId, nameof(ConversationId)); + + private static Result VerifyEventId(DeleteEventRequest request) => + InputValidation.VerifyNotEmpty(request, request.EventId, nameof(EventId)); +} \ No newline at end of file diff --git a/Vonage/Conversations/IConversationsClient.cs b/Vonage/Conversations/IConversationsClient.cs index 90c2bb7d..0c621b44 100644 --- a/Vonage/Conversations/IConversationsClient.cs +++ b/Vonage/Conversations/IConversationsClient.cs @@ -3,6 +3,7 @@ using Vonage.Conversations.CreateConversation; using Vonage.Conversations.CreateMember; using Vonage.Conversations.DeleteConversation; +using Vonage.Conversations.DeleteEvent; using Vonage.Conversations.GetConversation; using Vonage.Conversations.GetConversations; using Vonage.Conversations.GetMember; @@ -32,6 +33,13 @@ public interface IConversationsClient /// Success or Failure. Task> DeleteConversationAsync(Result request); + /// + /// Deletes an event. + /// + /// The request. + /// Success or Failure. + Task> DeleteEventAsync(Result request); + /// /// Retrieves a conversation. ///