From a04786640d8cc44caed4e0799f27791a0997b5f8 Mon Sep 17 00:00:00 2001 From: Francis Pion Date: Mon, 23 Dec 2024 20:07:52 -0500 Subject: [PATCH] Added unit tests. --- .../CustomIdentifierTests.cs | 73 +++++++++++++++++- .../DescriptionTests.cs | 50 +++++++++++- .../DisplayNameTests.cs | 73 +++++++++++++++++- .../IdentifierTests.cs | 73 +++++++++++++++++- .../LocaleTests.cs | 75 +++++++++++++++++- .../TimeZoneTests.cs | 72 ++++++++++++++++- .../UniqueNameTests.cs | 77 ++++++++++++++++++- .../UrlTests.cs | 74 +++++++++++++++++- 8 files changed, 551 insertions(+), 16 deletions(-) diff --git a/tests/Logitar.Identity.Core.UnitTests/CustomIdentifierTests.cs b/tests/Logitar.Identity.Core.UnitTests/CustomIdentifierTests.cs index c7a3278..25a92fe 100644 --- a/tests/Logitar.Identity.Core.UnitTests/CustomIdentifierTests.cs +++ b/tests/Logitar.Identity.Core.UnitTests/CustomIdentifierTests.cs @@ -1,7 +1,76 @@ -namespace Logitar.Identity.Core; +using FluentValidation; +using FluentValidation.Results; +using Logitar.Security.Cryptography; + +namespace Logitar.Identity.Core; [Trait(Traits.Category, Categories.Unit)] public class CustomIdentifierTests { - // TODO(fpion): implement + [Fact(DisplayName = "ctor: it should construct the correct instance given a valid value.")] + public void Given_ValidValue_When_ctor_Then_ConstructedCorrectly() + { + string value = " 1234567890 "; + CustomIdentifier displayName = new(value); + Assert.Equal(value.Trim(), displayName.Value); + } + + [Theory(DisplayName = "ctor: it should throw ValidationException given an empty or white-space value.")] + [InlineData("")] + [InlineData(" ")] + public void Given_EmptyOrWhiteSpace_When_ctor_Then_ValidationException(string value) + { + var exception = Assert.Throws(() => new CustomIdentifier(value)); + + ValidationFailure failure = Assert.Single(exception.Errors); + Assert.Equal("NotEmptyValidator", failure.ErrorCode); + Assert.Equal("Value", failure.PropertyName); + } + + [Fact(DisplayName = "ctor: it should throw ValidationException given an invalid value.")] + public void Given_InvalidValue_When_ctor_Then_ValidationException() + { + string value = RandomStringGenerator.GetString(999); + var exception = Assert.Throws(() => new CustomIdentifier(value)); + + ValidationFailure failure = Assert.Single(exception.Errors); + Assert.Equal("MaximumLengthValidator", failure.ErrorCode); + Assert.Equal("Value", failure.PropertyName); + } + + [Fact(DisplayName = "ToString: it should return the correct string representation.")] + public void Given_CustomIdentifier_When_ToString_Then_CorrectString() + { + CustomIdentifier displayName = new("1234567890"); + Assert.Equal(displayName.Value, displayName.ToString()); + } + + [Fact(DisplayName = "TryCreate: it should return a new instance given a valid value.")] + public void Given_ValidValue_When_TryCreate_Then_InstanceReturned() + { + string value = " 1234567890 "; + CustomIdentifier? displayName = CustomIdentifier.TryCreate(value); + Assert.NotNull(displayName); + Assert.Equal(value.Trim(), displayName.Value); + } + + [Theory(DisplayName = "TryCreate: it should return null given a null, empty, or white-space value.")] + [InlineData(null)] + [InlineData("")] + [InlineData(" ")] + public void Given_NullEmptyOrWhiteSpace_When_TryCreate_Then_NullReturned(string? value) + { + Assert.Null(CustomIdentifier.TryCreate(value)); + } + + [Fact(DisplayName = "TryCreate: it should throw ValidationException given an invalid value.")] + public void Given_InvalidValue_When_TryCreate_Then_ValidationException() + { + string value = RandomStringGenerator.GetString(999); + var exception = Assert.Throws(() => CustomIdentifier.TryCreate(value)); + + ValidationFailure failure = Assert.Single(exception.Errors); + Assert.Equal("MaximumLengthValidator", failure.ErrorCode); + Assert.Equal("Value", failure.PropertyName); + } } diff --git a/tests/Logitar.Identity.Core.UnitTests/DescriptionTests.cs b/tests/Logitar.Identity.Core.UnitTests/DescriptionTests.cs index e524727..f80c563 100644 --- a/tests/Logitar.Identity.Core.UnitTests/DescriptionTests.cs +++ b/tests/Logitar.Identity.Core.UnitTests/DescriptionTests.cs @@ -1,7 +1,53 @@ -namespace Logitar.Identity.Core; +using FluentValidation; +using FluentValidation.Results; + +namespace Logitar.Identity.Core; [Trait(Traits.Category, Categories.Unit)] public class DescriptionTests { - // TODO(fpion): implement + [Fact(DisplayName = "ctor: it should construct the correct instance given a valid value.")] + public void Given_ValidValue_When_ctor_Then_ConstructedCorrectly() + { + string value = " Hello World! "; + Description description = new(value); + Assert.Equal(value.Trim(), description.Value); + } + + [Theory(DisplayName = "ctor: it should throw ValidationException given an empty or white-space value.")] + [InlineData("")] + [InlineData(" ")] + public void Given_EmptyOrWhiteSpace_When_ctor_Then_ValidationException(string value) + { + var exception = Assert.Throws(() => new Description(value)); + + ValidationFailure failure = Assert.Single(exception.Errors); + Assert.Equal("NotEmptyValidator", failure.ErrorCode); + Assert.Equal("Value", failure.PropertyName); + } + + [Fact(DisplayName = "ToString: it should return the correct string representation.")] + public void Given_Description_When_ToString_Then_CorrectString() + { + Description description = new("Hello World!"); + Assert.Equal(description.Value, description.ToString()); + } + + [Fact(DisplayName = "TryCreate: it should return a new instance given a valid value.")] + public void Given_ValidValue_When_TryCreate_Then_InstanceReturned() + { + string value = " Hello World! "; + Description? description = Description.TryCreate(value); + Assert.NotNull(description); + Assert.Equal(value.Trim(), description.Value); + } + + [Theory(DisplayName = "TryCreate: it should return null given a null, empty, or white-space value.")] + [InlineData(null)] + [InlineData("")] + [InlineData(" ")] + public void Given_NullEmptyOrWhiteSpace_When_TryCreate_Then_NullReturned(string? value) + { + Assert.Null(Description.TryCreate(value)); + } } diff --git a/tests/Logitar.Identity.Core.UnitTests/DisplayNameTests.cs b/tests/Logitar.Identity.Core.UnitTests/DisplayNameTests.cs index 8ba2f3f..187214e 100644 --- a/tests/Logitar.Identity.Core.UnitTests/DisplayNameTests.cs +++ b/tests/Logitar.Identity.Core.UnitTests/DisplayNameTests.cs @@ -1,7 +1,76 @@ -namespace Logitar.Identity.Core; +using FluentValidation; +using FluentValidation.Results; +using Logitar.Security.Cryptography; + +namespace Logitar.Identity.Core; [Trait(Traits.Category, Categories.Unit)] public class DisplayNameTests { - // TODO(fpion): implement + [Fact(DisplayName = "ctor: it should construct the correct instance given a valid value.")] + public void Given_ValidValue_When_ctor_Then_ConstructedCorrectly() + { + string value = " Administrator "; + DisplayName displayName = new(value); + Assert.Equal(value.Trim(), displayName.Value); + } + + [Theory(DisplayName = "ctor: it should throw ValidationException given an empty, or white-space value.")] + [InlineData("")] + [InlineData(" ")] + public void Given_EmptyOrWhiteSpace_When_ctor_Then_ValidationException(string value) + { + var exception = Assert.Throws(() => new DisplayName(value)); + + ValidationFailure failure = Assert.Single(exception.Errors); + Assert.Equal("NotEmptyValidator", failure.ErrorCode); + Assert.Equal("Value", failure.PropertyName); + } + + [Fact(DisplayName = "ctor: it should throw ValidationException given an invalid value.")] + public void Given_InvalidValue_When_ctor_Then_ValidationException() + { + string value = RandomStringGenerator.GetString(999); + var exception = Assert.Throws(() => new DisplayName(value)); + + ValidationFailure failure = Assert.Single(exception.Errors); + Assert.Equal("MaximumLengthValidator", failure.ErrorCode); + Assert.Equal("Value", failure.PropertyName); + } + + [Fact(DisplayName = "ToString: it should return the correct string representation.")] + public void Given_DisplayName_When_ToString_Then_CorrectString() + { + DisplayName displayName = new("Administrator"); + Assert.Equal(displayName.Value, displayName.ToString()); + } + + [Fact(DisplayName = "TryCreate: it should return a new instance given a valid value.")] + public void Given_ValidValue_When_TryCreate_Then_InstanceReturned() + { + string value = " Administrator "; + DisplayName? displayName = DisplayName.TryCreate(value); + Assert.NotNull(displayName); + Assert.Equal(value.Trim(), displayName.Value); + } + + [Theory(DisplayName = "TryCreate: it should return null given a null, empty, or white-space value.")] + [InlineData(null)] + [InlineData("")] + [InlineData(" ")] + public void Given_NullEmptyOrWhiteSpace_When_TryCreate_Then_NullReturned(string? value) + { + Assert.Null(DisplayName.TryCreate(value)); + } + + [Fact(DisplayName = "TryCreate: it should throw ValidationException given an invalid value.")] + public void Given_InvalidValue_When_TryCreate_Then_ValidationException() + { + string value = RandomStringGenerator.GetString(999); + var exception = Assert.Throws(() => DisplayName.TryCreate(value)); + + ValidationFailure failure = Assert.Single(exception.Errors); + Assert.Equal("MaximumLengthValidator", failure.ErrorCode); + Assert.Equal("Value", failure.PropertyName); + } } diff --git a/tests/Logitar.Identity.Core.UnitTests/IdentifierTests.cs b/tests/Logitar.Identity.Core.UnitTests/IdentifierTests.cs index fdde4d7..969ff47 100644 --- a/tests/Logitar.Identity.Core.UnitTests/IdentifierTests.cs +++ b/tests/Logitar.Identity.Core.UnitTests/IdentifierTests.cs @@ -1,7 +1,76 @@ -namespace Logitar.Identity.Core; +using FluentValidation; +using FluentValidation.Results; +using Logitar.Security.Cryptography; + +namespace Logitar.Identity.Core; [Trait(Traits.Category, Categories.Unit)] public class IdentifierTests { - // TODO(fpion): implement + [Fact(DisplayName = "ctor: it should construct the correct instance given a valid value.")] + public void Given_ValidValue_When_ctor_Then_ConstructedCorrectly() + { + string value = " HealthInsuranceNumber "; + Identifier identifier = new(value); + Assert.Equal(value.Trim(), identifier.Value); + } + + [Theory(DisplayName = "ctor: it should throw ValidationException given an empty or white-space value.")] + [InlineData("")] + [InlineData(" ")] + public void Given_EmptyOrWhiteSpace_When_ctor_Then_ValidationException(string value) + { + var exception = Assert.Throws(() => new Identifier(value)); + + ValidationFailure failure = Assert.Single(exception.Errors); + Assert.Equal("NotEmptyValidator", failure.ErrorCode); + Assert.Equal("Value", failure.PropertyName); + } + + [Fact(DisplayName = "ctor: it should throw ValidationException given an invalid value.")] + public void Given_InvalidValue_When_ctor_Then_ValidationException() + { + string value = RandomStringGenerator.GetString(999); + var exception = Assert.Throws(() => new Identifier(value)); + + Assert.Equal(2, exception.Errors.Count()); + Assert.Contains(exception.Errors, e => e.ErrorCode == "IdentifierValidator" && e.PropertyName == "Value"); + Assert.Contains(exception.Errors, e => e.ErrorCode == "MaximumLengthValidator" && e.PropertyName == "Value"); + } + + [Fact(DisplayName = "ToString: it should return the correct string representation.")] + public void Given_Identifier_When_ToString_Then_CorrectString() + { + Identifier identifier = new("HealthInsuranceNumber"); + Assert.Equal(identifier.Value, identifier.ToString()); + } + + [Fact(DisplayName = "TryCreate: it should return a new instance given a valid value.")] + public void Given_ValidValue_When_TryCreate_Then_InstanceReturned() + { + string value = " HealthInsuranceNumber "; + Identifier? identifier = Identifier.TryCreate(value); + Assert.NotNull(identifier); + Assert.Equal(value.Trim(), identifier.Value); + } + + [Theory(DisplayName = "TryCreate: it should return null given a null, empty, or white-space value.")] + [InlineData(null)] + [InlineData("")] + [InlineData(" ")] + public void Given_NullEmptyOrWhiteSpace_When_TryCreate_Then_NullReturned(string? value) + { + Assert.Null(Identifier.TryCreate(value)); + } + + [Fact(DisplayName = "TryCreate: it should throw ValidationException given an invalid value.")] + public void Given_InvalidValue_When_TryCreate_Then_ValidationException() + { + string value = RandomStringGenerator.GetString(999); + var exception = Assert.Throws(() => Identifier.TryCreate(value)); + + Assert.Equal(2, exception.Errors.Count()); + Assert.Contains(exception.Errors, e => e.ErrorCode == "IdentifierValidator" && e.PropertyName == "Value"); + Assert.Contains(exception.Errors, e => e.ErrorCode == "MaximumLengthValidator" && e.PropertyName == "Value"); + } } diff --git a/tests/Logitar.Identity.Core.UnitTests/LocaleTests.cs b/tests/Logitar.Identity.Core.UnitTests/LocaleTests.cs index 4aafcb1..198d5ca 100644 --- a/tests/Logitar.Identity.Core.UnitTests/LocaleTests.cs +++ b/tests/Logitar.Identity.Core.UnitTests/LocaleTests.cs @@ -1,7 +1,78 @@ -namespace Logitar.Identity.Core; +using FluentValidation; +using Logitar.Security.Cryptography; +using System.Globalization; + +namespace Logitar.Identity.Core; [Trait(Traits.Category, Categories.Unit)] public class LocaleTests { - // TODO(fpion): implement + [Fact(DisplayName = "ctor: it should construct the correct instance given a valid value.")] + public void Given_ValidValue_When_ctor_Then_ConstructedCorrectly() + { + CultureInfo culture = CultureInfo.GetCultureInfo("fr-CA"); + Locale locale = new($" {culture} "); + Assert.Equal(culture.Name, locale.Code); + Assert.Equal(culture, locale.Culture); + } + + [Theory(DisplayName = "ctor: it should throw ValidationException given an empty or white-space value.")] + [InlineData("")] + [InlineData(" ")] + public void Given_EmptyOrWhiteSpace_When_ctor_Then_ValidationException(string value) + { + var exception = Assert.Throws(() => new Locale(value)); + + Assert.Equal(2, exception.Errors.Count()); + Assert.Contains(exception.Errors, e => e.ErrorCode == "LocaleValidator" && e.PropertyName == "Code"); + Assert.Contains(exception.Errors, e => e.ErrorCode == "NotEmptyValidator" && e.PropertyName == "Code"); + } + + [Fact(DisplayName = "ctor: it should throw ValidationException given an invalid value.")] + public void Given_InvalidValue_When_ctor_Then_ValidationException() + { + string value = RandomStringGenerator.GetString(999); + var exception = Assert.Throws(() => new Locale(value)); + + Assert.Equal(2, exception.Errors.Count()); + Assert.Contains(exception.Errors, e => e.ErrorCode == "LocaleValidator" && e.PropertyName == "Code"); + Assert.Contains(exception.Errors, e => e.ErrorCode == "MaximumLengthValidator" && e.PropertyName == "Code"); + } + + [Fact(DisplayName = "ToString: it should return the correct string representation.")] + public void Given_Locale_When_ToString_Then_CorrectString() + { + CultureInfo culture = CultureInfo.GetCultureInfo("fr-CA"); + Locale locale = new(culture); + Assert.Equal(string.Format("{0} ({1})", culture.DisplayName, culture.Name), locale.ToString()); + } + + [Fact(DisplayName = "TryCreate: it should return a new instance given a valid value.")] + public void Given_ValidValue_When_TryCreate_Then_InstanceReturned() + { + string value = " fr-CA "; + Locale? locale = Locale.TryCreate(value); + Assert.NotNull(locale); + Assert.Equal(value.Trim(), locale.Culture.Name); + } + + [Theory(DisplayName = "TryCreate: it should return null given a null, empty, or white-space value.")] + [InlineData(null)] + [InlineData("")] + [InlineData(" ")] + public void Given_NullEmptyOrWhiteSpace_When_TryCreate_Then_NullReturned(string? value) + { + Assert.Null(Locale.TryCreate(value)); + } + + [Fact(DisplayName = "TryCreate: it should throw ValidationException given an invalid value.")] + public void Given_InvalidValue_When_TryCreate_Then_ValidationException() + { + string value = RandomStringGenerator.GetString(999); + var exception = Assert.Throws(() => Locale.TryCreate(value)); + + Assert.Equal(2, exception.Errors.Count()); + Assert.Contains(exception.Errors, e => e.ErrorCode == "LocaleValidator" && e.PropertyName == "Code"); + Assert.Contains(exception.Errors, e => e.ErrorCode == "MaximumLengthValidator" && e.PropertyName == "Code"); + } } diff --git a/tests/Logitar.Identity.Core.UnitTests/TimeZoneTests.cs b/tests/Logitar.Identity.Core.UnitTests/TimeZoneTests.cs index e74732b..3a384c8 100644 --- a/tests/Logitar.Identity.Core.UnitTests/TimeZoneTests.cs +++ b/tests/Logitar.Identity.Core.UnitTests/TimeZoneTests.cs @@ -1,7 +1,75 @@ -namespace Logitar.Identity.Core; +using FluentValidation; +using Logitar.Security.Cryptography; + +namespace Logitar.Identity.Core; [Trait(Traits.Category, Categories.Unit)] public class TimeZoneTests { - // TODO(fpion): implement + [Fact(DisplayName = "ctor: it should construct the correct instance given a valid value.")] + public void Given_ValidValue_When_ctor_Then_ConstructedCorrectly() + { + string id = " America/Montreal "; + TimeZone timeZone = new(id); + Assert.Equal(id.Trim(), timeZone.Id); + } + + [Theory(DisplayName = "ctor: it should throw ValidationException given an empty or white-space value.")] + [InlineData("")] + [InlineData(" ")] + public void Given_EmptyOrWhiteSpace_When_ctor_Then_ValidationException(string value) + { + var exception = Assert.Throws(() => new TimeZone(value)); + + Assert.Equal(2, exception.Errors.Count()); + Assert.Contains(exception.Errors, e => e.ErrorCode == "NotEmptyValidator" && e.PropertyName == "Id"); + Assert.Contains(exception.Errors, e => e.ErrorCode == "TimeZoneValidator" && e.PropertyName == "Id"); + } + + [Fact(DisplayName = "ctor: it should throw ValidationException given an invalid value.")] + public void Given_InvalidValue_When_ctor_Then_ValidationException() + { + string value = RandomStringGenerator.GetString(999); + var exception = Assert.Throws(() => new TimeZone(value)); + + Assert.Equal(2, exception.Errors.Count()); + Assert.Contains(exception.Errors, e => e.ErrorCode == "MaximumLengthValidator" && e.PropertyName == "Id"); + Assert.Contains(exception.Errors, e => e.ErrorCode == "TimeZoneValidator" && e.PropertyName == "Id"); + } + + [Fact(DisplayName = "ToString: it should return the correct string representation.")] + public void Given_TimeZone_When_ToString_Then_CorrectString() + { + TimeZone timeZone = new("Asia/Singapore"); + Assert.Equal(timeZone.Id, timeZone.ToString()); + } + + [Fact(DisplayName = "TryCreate: it should return a new instance given a valid value.")] + public void Given_ValidValue_When_TryCreate_Then_InstanceReturned() + { + string id = " Europe/Paris "; + TimeZone? timeZone = TimeZone.TryCreate(id); + Assert.NotNull(timeZone); + Assert.Equal(id.Trim(), timeZone.Id); + } + + [Theory(DisplayName = "TryCreate: it should return null given a null, empty, or white-space value.")] + [InlineData(null)] + [InlineData("")] + [InlineData(" ")] + public void Given_NullEmptyOrWhiteSpace_When_TryCreate_Then_NullReturned(string? value) + { + Assert.Null(TimeZone.TryCreate(value)); + } + + [Fact(DisplayName = "TryCreate: it should throw ValidationException given an invalid value.")] + public void Given_InvalidValue_When_TryCreate_Then_ValidationException() + { + string value = RandomStringGenerator.GetString(999); + var exception = Assert.Throws(() => TimeZone.TryCreate(value)); + + Assert.Equal(2, exception.Errors.Count()); + Assert.Contains(exception.Errors, e => e.ErrorCode == "MaximumLengthValidator" && e.PropertyName == "Id"); + Assert.Contains(exception.Errors, e => e.ErrorCode == "TimeZoneValidator" && e.PropertyName == "Id"); + } } diff --git a/tests/Logitar.Identity.Core.UnitTests/UniqueNameTests.cs b/tests/Logitar.Identity.Core.UnitTests/UniqueNameTests.cs index 0603f03..a3a2fac 100644 --- a/tests/Logitar.Identity.Core.UnitTests/UniqueNameTests.cs +++ b/tests/Logitar.Identity.Core.UnitTests/UniqueNameTests.cs @@ -1,7 +1,80 @@ -namespace Logitar.Identity.Core; +using Bogus; +using FluentValidation.Results; +using Logitar.Identity.Core.Settings; +using Logitar.Security.Cryptography; + +namespace Logitar.Identity.Core; [Trait(Traits.Category, Categories.Unit)] public class UniqueNameTests { - // TODO(fpion): implement + private readonly Faker _faker = new(); + private readonly UniqueNameSettings _uniqueNameSettings = new(); + + [Fact(DisplayName = "ctor: it should construct the correct instance given a valid value.")] + public void Given_ValidValue_When_ctor_Then_ConstructedCorrectly() + { + string value = $" {_faker.Person.UserName} "; + UniqueName uniqueName = new(_uniqueNameSettings, value); + Assert.Equal(value.Trim(), uniqueName.Value); + } + + [Theory(DisplayName = "ctor: it should throw ValidationException given an empty, or white-space value.")] + [InlineData("")] + [InlineData(" ")] + public void Given_EmptyOrWhiteSpace_When_ctor_Then_ValidationException(string value) + { + var exception = Assert.Throws(() => new UniqueName(_uniqueNameSettings, value)); + + ValidationFailure failure = Assert.Single(exception.Errors); + Assert.Equal("NotEmptyValidator", failure.ErrorCode); + Assert.Equal("Value", failure.PropertyName); + } + + [Fact(DisplayName = "ctor: it should throw ValidationException given an invalid value.")] + public void Given_InvalidValue_When_ctor_Then_ValidationException() + { + string value = RandomStringGenerator.GetString(999); + var exception = Assert.Throws(() => new UniqueName(_uniqueNameSettings, value)); + + Assert.Equal(2, exception.Errors.Count()); + Assert.Contains(exception.Errors, e => e.ErrorCode == "AllowedCharactersValidator" && e.PropertyName == "Value"); + Assert.Contains(exception.Errors, e => e.ErrorCode == "MaximumLengthValidator" && e.PropertyName == "Value"); + } + + [Fact(DisplayName = "ToString: it should return the correct string representation.")] + public void Given_UniqueName_When_ToString_Then_CorrectString() + { + UniqueName uniqueName = new(_uniqueNameSettings, _faker.Person.UserName); + Assert.Equal(uniqueName.Value, uniqueName.ToString()); + } + + [Fact(DisplayName = "TryCreate: it should return a new instance given a valid value.")] + public void Given_ValidValue_When_TryCreate_Then_InstanceReturned() + { + string value = $" {_faker.Person.UserName} "; + UniqueName? uniqueName = UniqueName.TryCreate(value, _uniqueNameSettings); + Assert.NotNull(uniqueName); + Assert.Equal(value.Trim(), uniqueName.Value); + } + + [Theory(DisplayName = "TryCreate: it should return null given a null, empty, or white-space value.")] + [InlineData(null)] + [InlineData("")] + [InlineData(" ")] + public void Given_NullEmptyOrWhiteSpace_When_TryCreate_Then_NullReturned(string? value) + { + Assert.Null(UniqueName.TryCreate(value, _uniqueNameSettings)); + } + + [Fact(DisplayName = "TryCreate: it should throw ValidationException given an invalid value.")] + public void Given_InvalidValue_When_TryCreate_Then_ValidationException() + { + string value = RandomStringGenerator.GetString(999); + var exception = Assert.Throws(() => UniqueName.TryCreate(value, _uniqueNameSettings)); + + Assert.Equal(2, exception.Errors.Count()); + Assert.Contains(exception.Errors, e => e.ErrorCode == "AllowedCharactersValidator" && e.PropertyName == "Value"); + Assert.Contains(exception.Errors, e => e.ErrorCode == "MaximumLengthValidator" && e.PropertyName == "Value"); + } } diff --git a/tests/Logitar.Identity.Core.UnitTests/UrlTests.cs b/tests/Logitar.Identity.Core.UnitTests/UrlTests.cs index 9c107a6..b6b007f 100644 --- a/tests/Logitar.Identity.Core.UnitTests/UrlTests.cs +++ b/tests/Logitar.Identity.Core.UnitTests/UrlTests.cs @@ -1,7 +1,77 @@ -namespace Logitar.Identity.Core; +using FluentValidation; +using Logitar.Security.Cryptography; + +namespace Logitar.Identity.Core; [Trait(Traits.Category, Categories.Unit)] public class UrlTests { - // TODO(fpion): implement + [Fact(DisplayName = "ctor: it should construct the correct instance given a valid value.")] + public void Given_ValidValue_When_ctor_Then_ConstructedCorrectly() + { + string value = " https://www.test.com/ "; + Url url = new(value); + Assert.Equal(value.Trim(), url.Value); + Assert.Equal(value.Trim(), url.Uri.ToString()); + } + + [Theory(DisplayName = "ctor: it should throw ValidationException given an empty or white-space value.")] + [InlineData("")] + [InlineData(" ")] + public void Given_EmptyOrWhiteSpace_When_ctor_Then_ValidationException(string value) + { + var exception = Assert.Throws(() => new Url(value)); + + Assert.Equal(2, exception.Errors.Count()); + Assert.Contains(exception.Errors, e => e.ErrorCode == "NotEmptyValidator" && e.PropertyName == "Value"); + Assert.Contains(exception.Errors, e => e.ErrorCode == "UrlValidator" && e.PropertyName == "Value"); + } + + [Fact(DisplayName = "ctor: it should throw ValidationException given an invalid value.")] + public void Given_InvalidValue_When_ctor_Then_ValidationException() + { + string value = RandomStringGenerator.GetString(9999); + var exception = Assert.Throws(() => new Url(value)); + + Assert.Equal(2, exception.Errors.Count()); + Assert.Contains(exception.Errors, e => e.ErrorCode == "MaximumLengthValidator" && e.PropertyName == "Value"); + Assert.Contains(exception.Errors, e => e.ErrorCode == "UrlValidator" && e.PropertyName == "Value"); + } + + [Fact(DisplayName = "ToString: it should return the correct string representation.")] + public void Given_Url_When_ToString_Then_CorrectString() + { + Url url = new("https://www.test.com/"); + Assert.Equal(url.Value, url.ToString()); + } + + [Fact(DisplayName = "TryCreate: it should return a new instance given a valid value.")] + public void Given_ValidValue_When_TryCreate_Then_InstanceReturned() + { + string value = " https://www.test.com/ "; + Url? url = Url.TryCreate(value); + Assert.NotNull(url); + Assert.Equal(value.Trim(), url.Value); + Assert.Equal(value.Trim(), url.Uri.ToString()); + } + + [Theory(DisplayName = "TryCreate: it should return null given a null, empty, or white-space value.")] + [InlineData(null)] + [InlineData("")] + [InlineData(" ")] + public void Given_NullEmptyOrWhiteSpace_When_TryCreate_Then_NullReturned(string? value) + { + Assert.Null(Url.TryCreate(value)); + } + + [Fact(DisplayName = "TryCreate: it should throw ValidationException given an invalid value.")] + public void Given_InvalidValue_When_TryCreate_Then_ValidationException() + { + string value = RandomStringGenerator.GetString(9999); + var exception = Assert.Throws(() => Url.TryCreate(value)); + + Assert.Equal(2, exception.Errors.Count()); + Assert.Contains(exception.Errors, e => e.ErrorCode == "MaximumLengthValidator" && e.PropertyName == "Value"); + Assert.Contains(exception.Errors, e => e.ErrorCode == "UrlValidator" && e.PropertyName == "Value"); + } }