Skip to content

Commit

Permalink
feat: implement UpdateTemplateFragmentRequest for VerifyV2
Browse files Browse the repository at this point in the history
  • Loading branch information
Tr00d committed Sep 16, 2024
1 parent 31ebebb commit 427435f
Show file tree
Hide file tree
Showing 11 changed files with 366 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"template_fragment_id": "c70f446e-997a-4313-a081-60a02a31dc19",
"channel": "sms",
"locale": "en-us",
"text": "Text content of the template. May contain 4 reserved variables: `${code}`, `${brand}`, `${time-limit}` and `${time-limit-unit}`",
"date_updated": "2023-08-30T15:20:15.178Z",
"date_created": "2021-08-30T20:12:15.178Z",
"_links": {
"self": {
"href": "https://api.nexmo.com/v2/verify/templates/8f35a1a7-eb2f-4552-8fdf-fffdaee41bc9/template_fragments/c70f446e-997a-4313-a081-60a02a31dc19"
},
"template": {
"href": "https://api.nexmo.com/v2/verify/templates/8f35a1a7-eb2f-4552-8fdf-fffdaee41bc9"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"text": "The authentication code for your ${brand} is: ${code}"
}
39 changes: 39 additions & 0 deletions Vonage.Test/VerifyV2/UpdateTemplateFragment/E2ETest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#region
using System.Net;
using System.Threading.Tasks;
using Vonage.Test.Common.Extensions;
using Vonage.VerifyV2.UpdateTemplateFragment;
using WireMock.ResponseBuilders;
using Xunit;
#endregion

namespace Vonage.Test.VerifyV2.UpdateTemplateFragment;

[Trait("Category", "E2E")]
public class E2ETest : E2EBase
{
public E2ETest() : base(typeof(E2ETest).Namespace)
{
}

[Fact]
public async Task UpdateTemplateFragment()
{
this.Helper.Server.Given(WireMock.RequestBuilders.Request.Create()
.WithPath(
"/v2/verify/templates/68c2b32e-55ba-4a8e-b3fa-43b3ae6cd1fb/template_fragments/c41a9862-93d6-4c15-b5eb-d5ea6d574654")
.WithHeader("Authorization", this.Helper.ExpectedAuthorizationHeaderValue)
.WithBody(this.Serialization.GetRequestJson(nameof(SerializationTest.ShouldSerialize)))
.UsingPatch())
.RespondWith(Response.Create()
.WithStatusCode(HttpStatusCode.OK)
.WithBody(this.Serialization.GetResponseJson(nameof(SerializationTest.ShouldDeserialize200))));
await this.Helper.VonageClient.VerifyV2Client.UpdateTemplateFragmentAsync(UpdateTemplateFragmentRequest.Build()
.WithId(RequestBuilderTest.ValidTemplateId)
.WithFragmentId(RequestBuilderTest.ValidTemplateFragmentId)
.WithText(RequestBuilderTest.ValidText)
.Create())
.Should()
.BeSuccessAsync(SerializationTest.VerifyExpectedResponse);
}
}
82 changes: 82 additions & 0 deletions Vonage.Test/VerifyV2/UpdateTemplateFragment/RequestBuilderTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
#region
using System;
using Vonage.Test.Common.Extensions;
using Vonage.VerifyV2.UpdateTemplateFragment;
using Xunit;
#endregion

namespace Vonage.Test.VerifyV2.UpdateTemplateFragment;

[Trait("Category", "Request")]
public class RequestBuilderTest
{
internal static readonly Guid ValidTemplateId = new Guid("68c2b32e-55ba-4a8e-b3fa-43b3ae6cd1fb");
internal static readonly Guid ValidTemplateFragmentId = new Guid("c41a9862-93d6-4c15-b5eb-d5ea6d574654");
internal static readonly string ValidText = "The authentication code for your ${brand} is: ${code}";

[Fact]
public void Create_ShouldReturnFailure_GivenTemplateIdIsEmpty() =>
UpdateTemplateFragmentRequest.Build()
.WithId(Guid.Empty)
.WithFragmentId(ValidTemplateFragmentId)
.WithText(ValidText)
.Create()
.Should()
.BeParsingFailure("TemplateId cannot be empty.");

[Fact]
public void Create_ShouldReturnFailure_GivenTemplateFragmentIdIsEmpty() =>
UpdateTemplateFragmentRequest.Build()
.WithId(ValidTemplateId)
.WithFragmentId(Guid.Empty)
.WithText(ValidText)
.Create()
.Should()
.BeParsingFailure("TemplateFragmentId cannot be empty.");

[Theory]
[InlineData("")]
[InlineData(" ")]
[InlineData(null)]
public void Create_ShouldReturnFailure_GivenTextIsNullOrWhitespace(string value) =>
UpdateTemplateFragmentRequest.Build()
.WithId(ValidTemplateId)
.WithFragmentId(ValidTemplateFragmentId)
.WithText(value)
.Create()
.Should()
.BeParsingFailure("Text cannot be null or whitespace.");

[Fact]
public void Create_ShouldSetId() =>
UpdateTemplateFragmentRequest.Build()
.WithId(ValidTemplateId)
.WithFragmentId(ValidTemplateFragmentId)
.WithText(ValidText)
.Create()
.Map(request => request.TemplateId)
.Should()
.BeSuccess(ValidTemplateId);

[Fact]
public void Create_ShouldSetFragmentId() =>
UpdateTemplateFragmentRequest.Build()
.WithId(ValidTemplateId)
.WithFragmentId(ValidTemplateFragmentId)
.WithText(ValidText)
.Create()
.Map(request => request.TemplateFragmentId)
.Should()
.BeSuccess(ValidTemplateFragmentId);

[Fact]
public void Create_ShouldSetText() =>
UpdateTemplateFragmentRequest.Build()
.WithId(ValidTemplateId)
.WithFragmentId(ValidTemplateFragmentId)
.WithText(ValidText)
.Create()
.Map(request => request.Text)
.Should()
.BeSuccess(ValidText);
}
23 changes: 23 additions & 0 deletions Vonage.Test/VerifyV2/UpdateTemplateFragment/RequestTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#region
using Vonage.Test.Common.Extensions;
using Vonage.VerifyV2.UpdateTemplateFragment;
using Xunit;
#endregion

namespace Vonage.Test.VerifyV2.UpdateTemplateFragment;

[Trait("Category", "Request")]
public class RequestTest
{
[Fact]
public void GetEndpointPath_ShouldReturnApiEndpoint() =>
UpdateTemplateFragmentRequest.Build()
.WithId(RequestBuilderTest.ValidTemplateId)
.WithFragmentId(RequestBuilderTest.ValidTemplateFragmentId)
.WithText(RequestBuilderTest.ValidText)
.Create()
.Map(request => request.GetEndpointPath())
.Should()
.BeSuccess(
"/v2/verify/templates/68c2b32e-55ba-4a8e-b3fa-43b3ae6cd1fb/template_fragments/c41a9862-93d6-4c15-b5eb-d5ea6d574654");
}
47 changes: 47 additions & 0 deletions Vonage.Test/VerifyV2/UpdateTemplateFragment/SerializationTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#region
using System;
using FluentAssertions;
using Vonage.Serialization;
using Vonage.Test.Common;
using Vonage.Test.Common.Extensions;
using Vonage.VerifyV2;
using Vonage.VerifyV2.StartVerification;
using Vonage.VerifyV2.UpdateTemplateFragment;
using Xunit;
#endregion

namespace Vonage.Test.VerifyV2.UpdateTemplateFragment;

[Trait("Category", "Serialization")]
public class SerializationTest
{
private readonly SerializationTestHelper helper = new SerializationTestHelper(
typeof(SerializationTest).Namespace,
JsonSerializerBuilder.BuildWithSnakeCase());

[Fact]
public void ShouldDeserialize200() =>
this.helper.Serializer
.DeserializeObject<TemplateFragment>(this.helper.GetResponseJson())
.Should()
.BeSuccess(VerifyExpectedResponse);

internal static void VerifyExpectedResponse(TemplateFragment response) =>
response.Should().Be(new TemplateFragment(
new Guid("c70f446e-997a-4313-a081-60a02a31dc19"),
VerificationChannel.Sms,
Locale.EnUs,
"Text content of the template. May contain 4 reserved variables: `${code}`, `${brand}`, `${time-limit}` and `${time-limit-unit}`",
DateTimeOffset.Parse("2021-08-30T20:12:15.178Z"),
DateTimeOffset.Parse("2023-08-30T15:20:15.178Z")));

[Fact]
public void ShouldSerialize() => UpdateTemplateFragmentRequest.Build()
.WithId(RequestBuilderTest.ValidTemplateId)
.WithFragmentId(RequestBuilderTest.ValidTemplateFragmentId)
.WithText(RequestBuilderTest.ValidText)
.Create()
.GetStringContent()
.Should()
.BeSuccess(this.helper.GetRequestJson());
}
6 changes: 6 additions & 0 deletions Vonage.Test/Vonage.Test.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -1331,6 +1331,12 @@
<None Update="VerifyV2\CreateTemplateFragment\Data\ShouldSerialize-request.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="VerifyV2\UpdateTemplateFragment\Data\ShouldDeserialize200-response.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="VerifyV2\UpdateTemplateFragment\Data\ShouldSerialize-request.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<Target Name="PreBuild" BeforeTargets="PreBuildEvent">
<Exec Command="node ../.scripts/init.js"/>
Expand Down
8 changes: 8 additions & 0 deletions Vonage/VerifyV2/IVerifyV2Client.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
using Vonage.VerifyV2.NextWorkflow;
using Vonage.VerifyV2.StartVerification;
using Vonage.VerifyV2.UpdateTemplate;
using Vonage.VerifyV2.UpdateTemplateFragment;
using Vonage.VerifyV2.VerifyCode;
#endregion

Expand Down Expand Up @@ -84,6 +85,13 @@ public interface IVerifyV2Client
/// <returns>Success or Failure.</returns>
Task<Result<Template>> UpdateTemplateAsync(Result<UpdateTemplateRequest> request);

/// <summary>
/// Updates a template fragment.
/// </summary>
/// <param name="request">The request.</param>
/// <returns>Success or Failure.</returns>
Task<Result<TemplateFragment>> UpdateTemplateFragmentAsync(Result<UpdateTemplateFragmentRequest> request);

/// <summary>
/// Retrieves a template.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#region
using System;
using System.Net.Http;
using System.Text;
using System.Text.Json.Serialization;
using Vonage.Common.Client;
using Vonage.Serialization;
#endregion

namespace Vonage.VerifyV2.UpdateTemplateFragment;

/// <inheritdoc />
public readonly struct UpdateTemplateFragmentRequest : IVonageRequest
{
/// <summary>
/// The template text. There are 4 reserved variables available to use: ${code}, ${brand}, ${time-limit} and
/// ${time-limit-unit}
/// </summary>
public string Text { get; internal init; }

/// <summary>
/// ID of the template.
/// </summary>
[JsonIgnore]
public Guid TemplateId { get; internal init; }

/// <summary>
/// ID of the template fragment.
/// </summary>
[JsonIgnore]
public Guid TemplateFragmentId { get; internal init; }

/// <inheritdoc />
public HttpRequestMessage BuildRequestMessage() => VonageRequestBuilder
.Initialize(new HttpMethod("PATCH"), this.GetEndpointPath())
.WithContent(this.GetRequestContent())
.Build();

/// <inheritdoc />
public string GetEndpointPath() =>
$"/v2/verify/templates/{this.TemplateId}/template_fragments/{this.TemplateFragmentId}";

/// <summary>
/// Initializes a builder.
/// </summary>
/// <returns></returns>
public static IBuilderForId Build() => new UpdateTemplateFragmentRequestBuilder();

private StringContent GetRequestContent() =>
new StringContent(JsonSerializerBuilder.BuildWithSnakeCase().SerializeObject(this), Encoding.UTF8,
"application/json");
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
#region
using System;
using Vonage.Common.Client;
using Vonage.Common.Monads;
using Vonage.Common.Validation;
#endregion

namespace Vonage.VerifyV2.UpdateTemplateFragment;

internal struct UpdateTemplateFragmentRequestBuilder : IBuilderForId, IBuilderForFragmentId, IBuilderForText,
IVonageRequestBuilder<UpdateTemplateFragmentRequest>
{
private Guid templateFragmentId;
private Guid templateId;
private string text;

public IBuilderForText WithFragmentId(Guid value) => this with {templateFragmentId = value};
public IBuilderForFragmentId WithId(Guid value) => this with {templateId = value};

public IVonageRequestBuilder<UpdateTemplateFragmentRequest> WithText(string value) => this with {text = value};

public Result<UpdateTemplateFragmentRequest> Create() => Result<UpdateTemplateFragmentRequest>.FromSuccess(
new UpdateTemplateFragmentRequest
{
TemplateId = this.templateId,
TemplateFragmentId = this.templateFragmentId,
Text = this.text,
})
.Map(InputEvaluation<UpdateTemplateFragmentRequest>.Evaluate)
.Bind(evaluation => evaluation.WithRules(
VerifyTemplateIdNotEmpty,
VerifyTemplateFragmentIdNotEmpty,
VerifyTextNotEmpty));

private static Result<UpdateTemplateFragmentRequest> VerifyTemplateIdNotEmpty(
UpdateTemplateFragmentRequest request) =>
InputValidation.VerifyNotEmpty(request, request.TemplateId, nameof(request.TemplateId));

private static Result<UpdateTemplateFragmentRequest> VerifyTemplateFragmentIdNotEmpty(
UpdateTemplateFragmentRequest request) =>
InputValidation.VerifyNotEmpty(request, request.TemplateFragmentId, nameof(request.TemplateFragmentId));

private static Result<UpdateTemplateFragmentRequest> VerifyTextNotEmpty(
UpdateTemplateFragmentRequest request) =>
InputValidation.VerifyNotEmpty(request, request.Text, nameof(request.Text));
}

/// <summary>
/// Represents a builder to set the Id.
/// </summary>
public interface IBuilderForId
{
/// <summary>
/// Sets the Id.
/// </summary>
/// <param name="value">The template id.</param>
/// <returns>The builder.</returns>
IBuilderForFragmentId WithId(Guid value);
}

/// <summary>
/// Represents a builder to set the template fragment Id.
/// </summary>
public interface IBuilderForFragmentId
{
/// <summary>
/// Sets the Id.
/// </summary>
/// <param name="value">The template fragment id.</param>
/// <returns>The builder.</returns>
IBuilderForText WithFragmentId(Guid value);
}

/// <summary>
/// Represents a builder to set the Text.
/// </summary>
public interface IBuilderForText
{
/// <summary>
/// Sets the Text.
/// </summary>
/// <param name="value">The text.</param>
/// <returns>The builder.</returns>
IVonageRequestBuilder<UpdateTemplateFragmentRequest> WithText(string value);
}
Loading

0 comments on commit 427435f

Please sign in to comment.