Skip to content

Commit

Permalink
feat: add EntityId and ContentId on SmsWorkflow
Browse files Browse the repository at this point in the history
  • Loading branch information
Tr00d committed Feb 29, 2024
1 parent f9c7b06 commit 197513c
Show file tree
Hide file tree
Showing 6 changed files with 177 additions and 33 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"locale": "en-us",
"channel_timeout": 300,
"code_length": 4,
"brand": "ACME, Inc",
"workflow": [
{
"channel": "sms",
"to": "447700900000",
"app_hash": "12345678901",
"entity_id": "entity",
"content_id": "content"
}
]
}
12 changes: 10 additions & 2 deletions Vonage.Test/VerifyV2/StartVerification/E2ETest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
using Vonage.VerifyV2.StartVerification;
using Vonage.VerifyV2.StartVerification.Email;
using Vonage.VerifyV2.StartVerification.SilentAuth;
using Vonage.VerifyV2.StartVerification.Sms;
using Vonage.VerifyV2.StartVerification.Voice;
using Vonage.VerifyV2.StartVerification.WhatsApp;
using Vonage.VerifyV2.StartVerification.WhatsAppInteractive;
Expand Down Expand Up @@ -42,7 +41,16 @@ public async Task StartSilentAuthVerification()
public async Task StartSmsVerification()
{
this.InitializeWireMock(nameof(SerializationTest.ShouldSerializeSmsWorkflow));
var result = await this.StartVerificationAsyncWithWorkflow(SmsWorkflow.Parse("447700900000"));
var result = await this.StartVerificationAsyncWithWorkflow(SerializationTest.BuildSmsWorkflow());
VerifyResponseBody(result);
}

[Fact]
public async Task StartSmsVerificationWithOptionalValues()
{
this.InitializeWireMock(nameof(SerializationTest.ShouldSerializeSmsWorkflowWithOptionalValues));
var result =
await this.StartVerificationAsyncWithWorkflow(SerializationTest.BuildSmsWorkflowWithOptionalValues());
VerifyResponseBody(result);
}

Expand Down
17 changes: 16 additions & 1 deletion Vonage.Test/VerifyV2/StartVerification/SerializationTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -100,12 +100,27 @@ public void ShouldSerializeSilentAuthWorkflowWithRedirectUrl() =>
public void ShouldSerializeSmsWorkflow() =>
StartVerificationRequest.Build()
.WithBrand("ACME, Inc")
.WithWorkflow(SmsWorkflow.Parse("447700900000"))
.WithWorkflow(BuildSmsWorkflow())
.Create()
.GetStringContent()
.Should()
.BeSuccess(this.helper.GetRequestJson());

internal static Result<SmsWorkflow> BuildSmsWorkflow() => SmsWorkflow.Parse("447700900000");

[Fact]
public void ShouldSerializeSmsWorkflowWithOptionalValues() =>
StartVerificationRequest.Build()
.WithBrand("ACME, Inc")
.WithWorkflow(BuildSmsWorkflowWithOptionalValues())
.Create()
.GetStringContent()
.Should()
.BeSuccess(this.helper.GetRequestJson());

internal static Result<SmsWorkflow> BuildSmsWorkflowWithOptionalValues() =>
SmsWorkflow.Parse("447700900000", "12345678901", "entity", "content");

[Fact]
public void ShouldSerializeVoiceWorkflow() =>
StartVerificationRequest.Build()
Expand Down
89 changes: 73 additions & 16 deletions Vonage.Test/VerifyV2/StartVerification/Workflows/SmsWorkflowTest.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using FluentAssertions;
using Vonage.Common.Failures;
using Vonage.Common.Failures;
using Vonage.Test.Common.Extensions;
using Vonage.Test.Common.TestHelpers;
using Vonage.VerifyV2.StartVerification.Sms;
using Xunit;

Expand All @@ -21,6 +21,22 @@ public void Parse_ShouldReturnFailure_GivenHashIsProvidedButEmpty(string value)
.Should()
.BeFailure(ResultFailure.FromErrorMessage("Hash cannot be null or whitespace."));

[Theory]
[InlineData("")]
[InlineData(" ")]
public void Parse_ShouldReturnFailure_GivenEntityIdIsProvidedButEmpty(string value) =>
SmsWorkflow.Parse(ValidNumber, entityId: value)
.Should()
.BeFailure(ResultFailure.FromErrorMessage("EntityId cannot be null or whitespace."));

[Theory]
[InlineData("")]
[InlineData(" ")]
public void Parse_ShouldReturnFailure_GivenContentIdIsProvidedButEmpty(string value) =>
SmsWorkflow.Parse(ValidNumber, contentId: value)
.Should()
.BeFailure(ResultFailure.FromErrorMessage("ContentId cannot be null or whitespace."));

[Theory]
[InlineData("1234567890")]
[InlineData("123456789012")]
Expand All @@ -39,24 +55,65 @@ public void Parse_ShouldReturnFailure_GivenNumberIsNullOrWhitespace(string value
.BeFailure(ResultFailure.FromErrorMessage("Number cannot be null or whitespace."));

[Fact]
public void Parse_ShouldReturnSuccess() =>
public void Parse_ShouldReturnFailure_GivenEntityIdLengthIsHigherThan200Characters() =>
SmsWorkflow.Parse(ValidNumber, entityId: StringHelper.GenerateString(201))
.Map(workflow => workflow.EntityId)
.Should()
.BeFailure(ResultFailure.FromErrorMessage("EntityId length cannot be higher than 200."));

[Fact]
public void Parse_ShouldReturnFailure_GivenContentIdLengthIsHigherThan200Characters() =>
SmsWorkflow.Parse(ValidNumber, contentId: StringHelper.GenerateString(201))
.Map(workflow => workflow.ContentId)
.Should()
.BeFailure(ResultFailure.FromErrorMessage("ContentId length cannot be higher than 200."));

[Fact]
public void Parse_ShouldSetTo() =>
SmsWorkflow.Parse(ValidNumber)
.Map(workflow => workflow.To.Number)
.Should()
.BeSuccess(workflow =>
{
workflow.Channel.Should().Be(ExpectedChannel);
workflow.To.Number.Should().Be(ValidNumber);
workflow.Hash.Should().BeNone();
});
.BeSuccess(ValidNumber);

[Fact]
public void Parse_ShouldReturnSuccessWithHash() =>
public void Parse_ShouldSetSmsChannel() =>
SmsWorkflow.Parse(ValidNumber)
.Map(workflow => workflow.Channel)
.Should()
.BeSuccess(ExpectedChannel);

[Fact]
public void Parse_ShouldSetHash() =>
SmsWorkflow.Parse(ValidNumber, ValidHash)
.Map(workflow => workflow.Hash)
.Should()
.BeSuccess(ValidHash);

[Fact]
public void Parse_ShouldHaveEmptyHash_GivenDefault() =>
SmsWorkflow.Parse(ValidNumber)
.Map(workflow => workflow.Hash)
.Should()
.BeSuccess(hash => hash.Should().BeNone());

[Fact]
public void Parse_ShouldHaveEmptyEntityId_GivenDefault() =>
SmsWorkflow.Parse(ValidNumber)
.Map(workflow => workflow.EntityId)
.Should()
.BeSuccess(hash => hash.Should().BeNone());

[Fact]
public void Parse_ShouldSetEntityId_GivenLengthIsLowerThan200Characters() =>
SmsWorkflow.Parse(ValidNumber, entityId: StringHelper.GenerateString(200))
.Map(workflow => workflow.EntityId)
.Should()
.BeSuccess(hash => hash.Should().BeSome(StringHelper.GenerateString(200)));

[Fact]
public void Parse_ShouldHaveEmptyContentId_GivenDefault() =>
SmsWorkflow.Parse(ValidNumber)
.Map(workflow => workflow.ContentId)
.Should()
.BeSuccess(workflow =>
{
workflow.Channel.Should().Be(ExpectedChannel);
workflow.To.Number.Should().Be(ValidNumber);
workflow.Hash.Should().BeSome(ValidHash);
});
.BeSuccess(hash => hash.Should().BeNone());
}
3 changes: 3 additions & 0 deletions Vonage.Test/Vonage.Test.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -1092,6 +1092,9 @@
<None Update="Conversations\GetUserConversations\Data\ShouldDeserialize200-response.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="VerifyV2\StartVerification\Data\ShouldSerializeSmsWorkflowWithOptionalValues-request.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<Target Name="PreBuild" BeforeTargets="PreBuildEvent">
<Exec Command="node ../.scripts/init.js"/>
Expand Down
74 changes: 60 additions & 14 deletions Vonage/VerifyV2/StartVerification/Sms/SmsWorkflow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,14 @@ namespace Vonage.VerifyV2.StartVerification.Sms;
/// </summary>
public readonly struct SmsWorkflow : IVerificationWorkflow
{
private SmsWorkflow(PhoneNumber to, Maybe<string> hash)
private const int MaxEntityIdLength = 200;
private const int MaxContentIdLength = 200;

private SmsWorkflow(PhoneNumber to, Maybe<string> hash, Maybe<string> entityId, Maybe<string> contentId)
{
this.Hash = hash;
this.EntityId = entityId;
this.ContentId = contentId;
this.To = to;
}

Expand All @@ -24,7 +29,7 @@ private SmsWorkflow(PhoneNumber to, Maybe<string> hash)
/// <summary>
/// Optional Android Application Hash Key for automatic code detection on a user's device.
/// </summary>
[JsonPropertyOrder(3)]
[JsonPropertyOrder(2)]
[JsonPropertyName("app_hash")]
[JsonConverter(typeof(MaybeJsonConverter<string>))]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]
Expand All @@ -39,27 +44,44 @@ private SmsWorkflow(PhoneNumber to, Maybe<string> hash)
public PhoneNumber To { get; }

/// <summary>
/// Parses the input into a SmsWorkflow.
/// Optional PEID required for SMS delivery using Indian Carriers
/// </summary>
/// <param name="to">The phone number to contact.</param>
/// <param name="hash">The Android application hash key.</param>
/// <returns>Success or failure.</returns>
public static Result<SmsWorkflow> Parse(string to, string hash) =>
PhoneNumber.Parse(to)
.Map(phoneNumber => new SmsWorkflow(phoneNumber, hash))
.Bind(VerifyWorkflowHashNotEmpty)
.Bind(VerifyWorkflowHashLength);
[JsonPropertyOrder(3)]
[JsonPropertyName("entity_id")]
[JsonConverter(typeof(MaybeJsonConverter<string>))]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]
public Maybe<string> EntityId { get; }

/// <summary>
/// Optional value corresponding to a TemplateID for SMS delivery using Indian Carriers
/// </summary>
[JsonPropertyOrder(4)]
[JsonPropertyName("content_id")]
[JsonConverter(typeof(MaybeJsonConverter<string>))]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]
public Maybe<string> ContentId { get; }

/// <summary>
/// Parses the input into a SmsWorkflow.
/// </summary>
/// <param name="to">The phone number to contact.</param>
/// <param name="hash">The Android application hash key.</param>
/// <param name="entityId">Optional PEID required for SMS delivery using Indian Carriers</param>
/// <param name="contentId">Optional value corresponding to a TemplateID for SMS delivery using Indian Carriers</param>
/// <returns>Success or failure.</returns>
public static Result<SmsWorkflow> Parse(string to) =>
public static Result<SmsWorkflow> Parse(string to, string hash = null, string entityId = null,
string contentId = null) =>
PhoneNumber.Parse(to)
.Map(phoneNumber => new SmsWorkflow(phoneNumber, Maybe<string>.None))
.Map(phoneNumber => new SmsWorkflow(phoneNumber,
hash ?? Maybe<string>.None,
entityId ?? Maybe<string>.None,
contentId ?? Maybe<string>.None))
.Bind(VerifyWorkflowHashNotEmpty)
.Bind(VerifyWorkflowHashLength);
.Bind(VerifyWorkflowHashLength)
.Bind(VerifyWorkflowEntityIdNotEmpty)
.Bind(VerifyWorkflowEntityIdLength)
.Bind(VerifyWorkflowContentIdNotEmpty)
.Bind(VerifyWorkflowContentIdLength);

/// <inheritdoc />
public string Serialize(IJsonSerializer serializer) => serializer.SerializeObject(this);
Expand All @@ -72,4 +94,28 @@ private static Result<SmsWorkflow> VerifyWorkflowHashLength(
private static Result<SmsWorkflow> VerifyWorkflowHashNotEmpty(
SmsWorkflow request) =>
request.Hash.Match(some => InputValidation.VerifyNotEmpty(request, some, nameof(request.Hash)), () => request);

private static Result<SmsWorkflow> VerifyWorkflowEntityIdNotEmpty(
SmsWorkflow request) =>
request.EntityId.Match(some => InputValidation.VerifyNotEmpty(request, some, nameof(request.EntityId)),
() => request);

private static Result<SmsWorkflow> VerifyWorkflowEntityIdLength(
SmsWorkflow request) =>
request.EntityId.Match(
some => InputValidation.VerifyLengthLowerOrEqualThan(request, some, MaxEntityIdLength,
nameof(request.EntityId)),
() => request);

private static Result<SmsWorkflow> VerifyWorkflowContentIdLength(
SmsWorkflow request) =>
request.ContentId.Match(
some => InputValidation.VerifyLengthLowerOrEqualThan(request, some, MaxContentIdLength,
nameof(request.ContentId)),
() => request);

private static Result<SmsWorkflow> VerifyWorkflowContentIdNotEmpty(
SmsWorkflow request) =>
request.ContentId.Match(some => InputValidation.VerifyNotEmpty(request, some, nameof(request.ContentId)),
() => request);
}

0 comments on commit 197513c

Please sign in to comment.