Skip to content

Commit

Permalink
feat: implement builder for Name & DisplayName in CreateConversation
Browse files Browse the repository at this point in the history
  • Loading branch information
Tr00d committed Dec 6, 2023
1 parent 16bcd1b commit 5b1b575
Show file tree
Hide file tree
Showing 3 changed files with 168 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
using Vonage.Common.Test.Extensions;
using Vonage.Conversations.CreateConversation;
using Xunit;

namespace Vonage.Test.Unit.Conversations.CreateConversation
{
public class RequestBuilderTest
{
[Fact]
public void Build_ShouldReturnDefaultValues_GivenNoValuesHaveBeenSet() =>
CreateConversationRequest.Build()
.Create()
.Should()
.BeSuccess();

[Theory]
[InlineData("")]
[InlineData(" ")]
public void Build_ShouldReturnFailure_GivenDisplayNameIsProvidedButEmpty(string invalidDisplayName) =>
CreateConversationRequest.Build()
.WithDisplayName(invalidDisplayName)
.Create()
.Map(request => request.DisplayName)
.Should()
.BeParsingFailure("DisplayName cannot be null or whitespace.");

[Fact]
public void Build_ShouldReturnFailure_GivenDisplayNameLengthIsAbove50Characters() =>
CreateConversationRequest.Build()
.WithDisplayName(new string('a', 51))
.Create()
.Map(request => request.DisplayName)
.Should()
.BeParsingFailure("DisplayName length cannot be higher than 50.");

[Theory]
[InlineData("")]
[InlineData(" ")]
public void Build_ShouldReturnFailure_GivenNameIsProvidedButEmpty(string invalidName) =>
CreateConversationRequest.Build()
.WithName(invalidName)
.Create()
.Map(request => request.Name)
.Should()
.BeParsingFailure("Name cannot be null or whitespace.");

[Fact]
public void Build_ShouldReturnFailure_GivenNameLengthIsAbove100Characters() =>
CreateConversationRequest.Build()
.WithName(new string('a', 101))
.Create()
.Map(request => request.Name)
.Should()
.BeParsingFailure("Name length cannot be higher than 100.");

[Fact]
public void Build_ShouldSetDisplayName() =>
CreateConversationRequest.Build()
.WithDisplayName(new string('a', 50))
.Create()
.Map(request => request.DisplayName)
.Should()
.BeSuccess(new string('a', 50));

[Fact]
public void Build_ShouldSetName() =>
CreateConversationRequest.Build()
.WithName(new string('a', 100))
.Create()
.Map(request => request.Name)
.Should()
.BeSuccess(new string('a', 100));
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,27 @@
using System;
using System.Net.Http;
using Vonage.Common.Client;
using Vonage.Common.Monads;

namespace Vonage.Conversations.CreateConversation;

/// <inheritdoc />
public readonly struct CreateConversationRequest : IVonageRequest
{
/// <summary>
/// </summary>
public Maybe<string> DisplayName { get; internal init; }

/// <summary>
/// </summary>
public Maybe<string> Name { get; internal init; }

/// <summary>
/// Initializes a builder for CreateConversationRequest.
/// </summary>
/// <returns>The builder.</returns>
public static IBuilderForOptional Build() => new CreateConversationRequestBuilder();

/// <inheritdoc />
public HttpRequestMessage BuildRequestMessage() => throw new NotImplementedException();

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
using Vonage.Common.Client;
using Vonage.Common.Monads;
using Vonage.Common.Validation;

namespace Vonage.Conversations.CreateConversation;

internal class CreateConversationRequestBuilder : IBuilderForOptional
{
private const int DisplayNameMaxLength = 50;
private const int NameMaxLength = 100;
private Maybe<string> name;
private Maybe<string> displayName;

public Result<CreateConversationRequest> Create() => Result<CreateConversationRequest>.FromSuccess(
new CreateConversationRequest
{
Name = this.name,
DisplayName = this.displayName,
})
.Map(InputEvaluation<CreateConversationRequest>.Evaluate)
.Bind(evaluation => evaluation.WithRules(
VerifyName,
VerifyNameLength,
VerifyDisplayName,
VerifyDisplayNameLength));

public IBuilderForOptional WithDisplayName(string value)
{
this.displayName = value;
return this;
}

public IBuilderForOptional WithName(string value)
{
this.name = value;
return this;
}

private static Result<CreateConversationRequest> VerifyDisplayName(CreateConversationRequest request) =>
request.DisplayName.Match(
some => InputValidation.VerifyNotEmpty(request, some, nameof(request.DisplayName)),
() => request);

private static Result<CreateConversationRequest> VerifyDisplayNameLength(CreateConversationRequest request) =>
request.DisplayName.Match(
some => InputValidation.VerifyLengthLowerOrEqualThan(request, some, DisplayNameMaxLength,
nameof(request.DisplayName)),
() => request);

private static Result<CreateConversationRequest> VerifyName(CreateConversationRequest request) =>
request.Name.Match(
some => InputValidation.VerifyNotEmpty(request, some, nameof(request.Name)),
() => request);

private static Result<CreateConversationRequest> VerifyNameLength(CreateConversationRequest request) =>
request.Name.Match(
some => InputValidation.VerifyLengthLowerOrEqualThan(request, some, NameMaxLength, nameof(request.Name)),
() => request);
}

/// <summary>
/// Represents a builder for optional values.
/// </summary>
public interface IBuilderForOptional : IVonageRequestBuilder<CreateConversationRequest>
{
/// <summary>
/// Sets the Display Name.
/// </summary>
/// <param name="value">The display name.</param>
/// <returns>The builder.</returns>
IBuilderForOptional WithDisplayName(string value);

/// <summary>
/// Sets the Name
/// </summary>
/// <param name="value">The name.</param>
/// <returns>The builder.</returns>
IBuilderForOptional WithName(string value);
}

0 comments on commit 5b1b575

Please sign in to comment.