diff --git a/Vonage.Test/Video/ExperienceComposer/Stop/E2ETest.cs b/Vonage.Test/Video/ExperienceComposer/Stop/E2ETest.cs new file mode 100644 index 00000000..0a93cf88 --- /dev/null +++ b/Vonage.Test/Video/ExperienceComposer/Stop/E2ETest.cs @@ -0,0 +1,31 @@ +using System; +using System.Net; +using System.Threading.Tasks; +using Vonage.Test.Common.Extensions; +using Vonage.Video.ExperienceComposer.Stop; +using WireMock.ResponseBuilders; +using Xunit; + +namespace Vonage.Test.Video.ExperienceComposer.Stop; + +[Trait("Category", "E2E")] +public class E2ETest : E2EBase +{ + public E2ETest() : base(typeof(E2ETest).Namespace) + { + } + + [Fact] + public async Task Stop() + { + this.Helper.Server.Given(WireMock.RequestBuilders.Request.Create() + .WithPath("/v2/project/e3e78a75-221d-41ec-8846-25ae3db1943a/render/EXP-123") + .WithHeader("Authorization", this.Helper.ExpectedAuthorizationHeaderValue) + .UsingDelete()) + .RespondWith(Response.Create().WithStatusCode(HttpStatusCode.OK)); + await this.Helper.VonageClient.VideoClient.ExperienceComposerClient + .StopAsync(StopRequest.Parse(new Guid("e3e78a75-221d-41ec-8846-25ae3db1943a"), "EXP-123")) + .Should() + .BeSuccessAsync(); + } +} \ No newline at end of file diff --git a/Vonage.Test/Video/ExperienceComposer/Stop/RequestTest.cs b/Vonage.Test/Video/ExperienceComposer/Stop/RequestTest.cs new file mode 100644 index 00000000..c5fef3e3 --- /dev/null +++ b/Vonage.Test/Video/ExperienceComposer/Stop/RequestTest.cs @@ -0,0 +1,49 @@ +using System; +using Vonage.Test.Common.Extensions; +using Vonage.Video.ExperienceComposer.Stop; +using Xunit; + +namespace Vonage.Test.Video.ExperienceComposer.Stop; + +[Trait("Category", "Request")] +public class RequestTest +{ + private const string ValidExperienceComposerId = "EXP-123"; + private readonly Guid validApplicationId = Guid.NewGuid(); + + [Fact] + public void GetEndpointPath_ShouldReturnApiEndpoint() => + StopRequest.Parse(this.validApplicationId, ValidExperienceComposerId) + .Map(request => request.GetEndpointPath()) + .Should() + .BeSuccess($"/v2/project/{this.validApplicationId}/render/EXP-123"); + + [Theory] + [InlineData("")] + [InlineData(" ")] + [InlineData(null)] + public void Parse_ShouldReturnFailure_GivenExperienceComposerIdIsEmpty(string invalidId) => + StopRequest.Parse(Guid.NewGuid(), invalidId) + .Should() + .BeParsingFailure("ExperienceComposerId cannot be null or whitespace."); + + [Fact] + public void Parse_ShouldReturnFailure_GivenApplicationIdIsEmpty() => + StopRequest.Parse(Guid.Empty, ValidExperienceComposerId) + .Should() + .BeParsingFailure("ApplicationId cannot be empty."); + + [Fact] + public void Parse_ShouldSetApplicationId() => + StopRequest.Parse(this.validApplicationId, ValidExperienceComposerId) + .Map(request => request.ApplicationId) + .Should() + .BeSuccess(this.validApplicationId); + + [Fact] + public void Parse_ShouldSetExperienceComposerId() => + StopRequest.Parse(this.validApplicationId, ValidExperienceComposerId) + .Map(request => request.ExperienceComposerId) + .Should() + .BeSuccess(ValidExperienceComposerId); +} \ No newline at end of file diff --git a/Vonage/Video/ExperienceComposer/ExperienceComposerClient.cs b/Vonage/Video/ExperienceComposer/ExperienceComposerClient.cs index e4c98708..040d7a0f 100644 --- a/Vonage/Video/ExperienceComposer/ExperienceComposerClient.cs +++ b/Vonage/Video/ExperienceComposer/ExperienceComposerClient.cs @@ -4,6 +4,7 @@ using Vonage.Serialization; using Vonage.Video.ExperienceComposer.GetSession; using Vonage.Video.ExperienceComposer.GetSessions; +using Vonage.Video.ExperienceComposer.Stop; namespace Vonage.Video.ExperienceComposer; @@ -28,6 +29,17 @@ internal ExperienceComposerClient(VonageHttpClientConfiguration configuration) = public Task> GetSessionAsync(Result request) => this.vonageClient.SendWithResponseAsync(request); + /// + /// Stops an Experience Composer session. + /// + /// The request. + /// + /// A success state with the archive if the operation succeeded. A failure state with the error message if it + /// failed. + /// + public Task> StopAsync(Result request) => + this.vonageClient.SendAsync(request); + /// /// Retrieves all experience composer sessions in an application. /// diff --git a/Vonage/Video/ExperienceComposer/GetSession/GetSessionRequest.cs b/Vonage/Video/ExperienceComposer/GetSession/GetSessionRequest.cs index d337acdc..e8f18c03 100644 --- a/Vonage/Video/ExperienceComposer/GetSession/GetSessionRequest.cs +++ b/Vonage/Video/ExperienceComposer/GetSession/GetSessionRequest.cs @@ -32,13 +32,13 @@ public HttpRequestMessage BuildRequestMessage() => /// /// Parses the input into a GetEventRequest. /// - /// The application Id. + /// The application Id. /// The experience composer Id. /// A success state with the request if the parsing succeeded. A failure state with an error if it failed. - public static Result Parse(Guid application, string experienceComposerId) => + public static Result Parse(Guid applicationId, string experienceComposerId) => Result .FromSuccess(new GetSessionRequest - {ApplicationId = application, ExperienceComposerId = experienceComposerId}) + {ApplicationId = applicationId, ExperienceComposerId = experienceComposerId}) .Map(InputEvaluation.Evaluate) .Bind(evaluation => evaluation.WithRules(VerifyExperienceComposerId, VerifyApplicationId)); diff --git a/Vonage/Video/ExperienceComposer/Stop/StopRequest.cs b/Vonage/Video/ExperienceComposer/Stop/StopRequest.cs new file mode 100644 index 00000000..7a8e7caa --- /dev/null +++ b/Vonage/Video/ExperienceComposer/Stop/StopRequest.cs @@ -0,0 +1,50 @@ +using System; +using System.Net.Http; +using Vonage.Common.Client; +using Vonage.Common.Client.Builders; +using Vonage.Common.Monads; +using Vonage.Common.Validation; + +namespace Vonage.Video.ExperienceComposer.Stop; + +/// +/// Represents a request to retrieve a session. +/// +public readonly struct StopRequest : IVonageRequest, IHasApplicationId +{ + /// + public Guid ApplicationId { get; internal init; } + + /// + /// ID of the Experience Composer instance + /// + public string ExperienceComposerId { get; internal init; } + + /// + public HttpRequestMessage BuildRequestMessage() => + VonageRequestBuilder + .Initialize(HttpMethod.Delete, this.GetEndpointPath()) + .Build(); + + /// + public string GetEndpointPath() => $"/v2/project/{this.ApplicationId}/render/{this.ExperienceComposerId}"; + + /// + /// Parses the input into a GetEventRequest. + /// + /// The application Id. + /// The experience composer Id. + /// A success state with the request if the parsing succeeded. A failure state with an error if it failed. + public static Result Parse(Guid applicationId, string experienceComposerId) => + Result + .FromSuccess(new StopRequest + {ApplicationId = applicationId, ExperienceComposerId = experienceComposerId}) + .Map(InputEvaluation.Evaluate) + .Bind(evaluation => evaluation.WithRules(VerifyExperienceComposerId, VerifyApplicationId)); + + private static Result VerifyExperienceComposerId(StopRequest request) => + InputValidation.VerifyNotEmpty(request, request.ExperienceComposerId, nameof(ExperienceComposerId)); + + private static Result VerifyApplicationId(StopRequest request) => + InputValidation.VerifyNotEmpty(request, request.ApplicationId, nameof(ApplicationId)); +} \ No newline at end of file