Skip to content

Commit

Permalink
feat: implement CreateTemplateFragment for VerifyV2
Browse files Browse the repository at this point in the history
  • Loading branch information
Tr00d committed Sep 16, 2024
1 parent af7cd63 commit 31ebebb
Show file tree
Hide file tree
Showing 12 changed files with 450 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,5 @@
{
"channel": "sms",
"locale": "en-us",
"text": "The authentication code for your ${brand} is: ${code}"
}
33 changes: 33 additions & 0 deletions Vonage.Test/VerifyV2/CreateTemplateFragment/E2ETest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#region
using System.Net;
using System.Threading.Tasks;
using Vonage.Test.Common.Extensions;
using WireMock.ResponseBuilders;
using Xunit;
#endregion

namespace Vonage.Test.VerifyV2.CreateTemplateFragment;

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

[Fact]
public async Task CreateTemplateFragment()
{
this.Helper.Server.Given(WireMock.RequestBuilders.Request.Create()
.WithPath("/v2/verify/templates/8f35a1a7-eb2f-4552-8fdf-fffdaee41bc9/template_fragments")
.WithHeader("Authorization", this.Helper.ExpectedAuthorizationHeaderValue)
.WithBody(this.Serialization.GetRequestJson(nameof(SerializationTest.ShouldSerialize)))
.UsingPost())
.RespondWith(Response.Create()
.WithStatusCode(HttpStatusCode.OK)
.WithBody(this.Serialization.GetResponseJson(nameof(SerializationTest.ShouldDeserialize200))));
await this.Helper.VonageClient.VerifyV2Client.CreateTemplateFragmentAsync(SerializationTest.BuildRequest())
.Should()
.BeSuccessAsync(SerializationTest.VerifyExpectedResponse);
}
}
107 changes: 107 additions & 0 deletions Vonage.Test/VerifyV2/CreateTemplateFragment/RequestBuilderTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
#region
using System;
using Vonage.Test.Common.Extensions;
using Vonage.VerifyV2;
using Vonage.VerifyV2.CreateTemplateFragment;
using Vonage.VerifyV2.StartVerification;
using Xunit;
#endregion

namespace Vonage.Test.VerifyV2.CreateTemplateFragment;

[Trait("Category", "Request")]
public class RequestBuilderTest
{
private const string ValidName = "my-fragment";
private static readonly Guid ValidTemplateId = new Guid("f3a065af-ac5a-47a4-8dfe-819561a7a287");

[Theory]
[InlineData("")]
[InlineData(" ")]
[InlineData(null)]
public void Create_ShouldReturnFailure_GivenTextIsNullOrWhitespace(string value) =>
CreateTemplateFragmentRequest.Build()
.WithTemplateId(ValidTemplateId)
.WithText(value)
.WithLocale(Locale.EnUs)
.WithChannel(VerificationChannel.Sms)
.Create()
.Should()
.BeParsingFailure("Text cannot be null or whitespace.");

[Fact]
public void Create_ShouldReturnFailure_GivenTemplateIdIsEmpty() =>
CreateTemplateFragmentRequest.Build()
.WithTemplateId(Guid.Empty)
.WithText(ValidName)
.WithLocale(Locale.EnUs)
.WithChannel(VerificationChannel.Sms)
.Create()
.Should()
.BeParsingFailure("TemplateId cannot be empty.");

[Theory]
[InlineData(VerificationChannel.SilentAuth)]
[InlineData(VerificationChannel.WhatsApp)]
[InlineData(VerificationChannel.WhatsAppInteractive)]
public void Create_ShouldReturnFailure_GivenChannelIsNotSupported(VerificationChannel channel) =>
CreateTemplateFragmentRequest.Build()
.WithTemplateId(ValidTemplateId)
.WithText(ValidName)
.WithLocale(Locale.EnUs)
.WithChannel(channel)
.Create()
.Should()
.BeParsingFailure("Channel must be one of Sms, Voice or Email.");

[Fact]
public void Create_ShouldSetName() =>
CreateTemplateFragmentRequest.Build()
.WithTemplateId(ValidTemplateId)
.WithText("my-fragment")
.WithLocale(Locale.EnUs)
.WithChannel(VerificationChannel.Sms)
.Create()
.Map(request => request.Text)
.Should()
.BeSuccess("my-fragment");

[Fact]
public void Create_ShouldSetTemplateId() =>
CreateTemplateFragmentRequest.Build()
.WithTemplateId(ValidTemplateId)
.WithText("my-fragment")
.WithLocale(Locale.EnUs)
.WithChannel(VerificationChannel.Sms)
.Create()
.Map(request => request.TemplateId)
.Should()
.BeSuccess(ValidTemplateId);

[Fact]
public void Create_ShouldSetLocale() =>
CreateTemplateFragmentRequest.Build()
.WithTemplateId(ValidTemplateId)
.WithText("my-fragment")
.WithLocale(Locale.EnUs)
.WithChannel(VerificationChannel.Sms)
.Create()
.Map(request => request.Locale)
.Should()
.BeSuccess(Locale.EnUs);

[Theory]
[InlineData(VerificationChannel.Sms)]
[InlineData(VerificationChannel.Voice)]
[InlineData(VerificationChannel.Email)]
public void Create_ShouldSetChannel(VerificationChannel channel) =>
CreateTemplateFragmentRequest.Build()
.WithTemplateId(ValidTemplateId)
.WithText(ValidName)
.WithLocale(Locale.EnUs)
.WithChannel(channel)
.Create()
.Map(request => request.Channel)
.Should()
.BeSuccess(channel);
}
26 changes: 26 additions & 0 deletions Vonage.Test/VerifyV2/CreateTemplateFragment/RequestTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#region
using System;
using Vonage.Test.Common.Extensions;
using Vonage.VerifyV2;
using Vonage.VerifyV2.CreateTemplateFragment;
using Vonage.VerifyV2.StartVerification;
using Xunit;
#endregion

namespace Vonage.Test.VerifyV2.CreateTemplateFragment;

[Trait("Category", "Request")]
public class RequestTest
{
[Fact]
public void GetEndpointPath_ShouldReturnApiEndpoint() =>
CreateTemplateFragmentRequest.Build()
.WithTemplateId(new Guid("f3a065af-ac5a-47a4-8dfe-819561a7a287"))
.WithText("my-fragment")
.WithLocale(Locale.EnUs)
.WithChannel(VerificationChannel.Sms)
.Create()
.Map(request => request.GetEndpointPath())
.Should()
.BeSuccess("/v2/verify/templates/f3a065af-ac5a-47a4-8dfe-819561a7a287/template_fragments");
}
52 changes: 52 additions & 0 deletions Vonage.Test/VerifyV2/CreateTemplateFragment/SerializationTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#region
using System;
using FluentAssertions;
using Vonage.Common.Monads;
using Vonage.Serialization;
using Vonage.Test.Common;
using Vonage.Test.Common.Extensions;
using Vonage.VerifyV2;
using Vonage.VerifyV2.CreateTemplateFragment;
using Vonage.VerifyV2.StartVerification;
using Xunit;
#endregion

namespace Vonage.Test.VerifyV2.CreateTemplateFragment;

[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() => BuildRequest()
.GetStringContent()
.Should()
.BeSuccess(this.helper.GetRequestJson());

internal static Result<CreateTemplateFragmentRequest> BuildRequest() =>
CreateTemplateFragmentRequest.Build()
.WithTemplateId(new Guid("8f35a1a7-eb2f-4552-8fdf-fffdaee41bc9"))
.WithText("The authentication code for your ${brand} is: ${code}")
.WithLocale(Locale.EnUs)
.WithChannel(VerificationChannel.Sms)
.Create();
}
6 changes: 6 additions & 0 deletions Vonage.Test/Vonage.Test.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -1325,6 +1325,12 @@
<None Update="VerifyV2\GetTemplates\Data\ShouldDeserialize200-response.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="VerifyV2\CreateTemplateFragment\Data\ShouldDeserialize200-response.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="VerifyV2\CreateTemplateFragment\Data\ShouldSerialize-request.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<Target Name="PreBuild" BeforeTargets="PreBuildEvent">
<Exec Command="node ../.scripts/init.js"/>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#region
using System;
using System.Net.Http;
using System.Text;
using System.Text.Json.Serialization;
using Vonage.Common.Client;
using Vonage.Common.Serialization;
using Vonage.Serialization;
using Vonage.VerifyV2.StartVerification;
#endregion

namespace Vonage.VerifyV2.CreateTemplateFragment;

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

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

/// <summary>
/// The locale code.
/// </summary>
[JsonPropertyOrder(1)]
public Locale Locale { get; internal init; }

/// <summary>
/// The channel name.
/// </summary>
[JsonPropertyOrder(0)]
[JsonConverter(typeof(EnumDescriptionJsonConverter<VerificationChannel>))]
public VerificationChannel Channel { get; internal init; }

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

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

private StringContent GetRequestContent() =>
new StringContent(JsonSerializerBuilder.BuildWithSnakeCase().SerializeObject(this), Encoding.UTF8,
"application/json");

/// <summary>
/// Initializes a builder.
/// </summary>
/// <returns></returns>
public static IBuilderForTemplateId Build() => new CreateTemplateFragmentRequestBuilder();
}
Loading

0 comments on commit 31ebebb

Please sign in to comment.