Skip to content

Commit

Permalink
Fix phone number validation (#167)
Browse files Browse the repository at this point in the history
* Add Lib.Tests project

* Modify regex for phone number validation

* Add tests for valid phone numbers

* Add check for valid phone number
  • Loading branch information
Smalls1652 authored Jan 21, 2025
1 parent c438857 commit 7a35836
Show file tree
Hide file tree
Showing 7 changed files with 100 additions and 9 deletions.
2 changes: 2 additions & 0 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
<PackageVersion Include="Microsoft.Extensions.Logging" Version="9.0.1" />
<PackageVersion Include="Microsoft.Extensions.Logging.Console" Version="9.0.1" />
<PackageVersion Include="Microsoft.Identity.Client" Version="4.67.2" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
<PackageVersion Include="MSTest" Version="3.7.2" />
<PackageVersion Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.11.0" />
<PackageVersion Include="OpenTelemetry.Extensions.Hosting" Version="1.11.0" />
<PackageVersion Include="OpenTelemetry.Instrumentation.Http" Version="1.10.0" />
Expand Down
7 changes: 7 additions & 0 deletions EntraMfaPrefillinator.sln
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CsvImporter.Database", "src
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CsvImporter.ConfigTool", "src\Tools\CsvImporter.ConfigTool\CsvImporter.ConfigTool.csproj", "{D4335382-BB08-4B22-96B5-5F8E5EC849B0}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lib.Tests", "src\Lib.Tests\Lib.Tests.csproj", "{98466E5C-BDDD-4FE3-AE1E-E92EAD621AE9}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -58,6 +60,10 @@ Global
{D4335382-BB08-4B22-96B5-5F8E5EC849B0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D4335382-BB08-4B22-96B5-5F8E5EC849B0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D4335382-BB08-4B22-96B5-5F8E5EC849B0}.Release|Any CPU.Build.0 = Release|Any CPU
{98466E5C-BDDD-4FE3-AE1E-E92EAD621AE9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{98466E5C-BDDD-4FE3-AE1E-E92EAD621AE9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{98466E5C-BDDD-4FE3-AE1E-E92EAD621AE9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{98466E5C-BDDD-4FE3-AE1E-E92EAD621AE9}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{F96FD9F1-4FBB-4235-AE62-D7055DECC6AD} = {FC60D7C4-F0D8-4E64-BB51-416F222F5D1B}
Expand All @@ -66,5 +72,6 @@ Global
{AD068759-4FE6-44D0-BB5A-068131066D6F} = {FC60D7C4-F0D8-4E64-BB51-416F222F5D1B}
{5EE841B5-3982-4FE9-8737-E287092DBD9C} = {33DE40FB-A917-4A86-AA79-5BAB5CC8E66A}
{D4335382-BB08-4B22-96B5-5F8E5EC849B0} = {33DE40FB-A917-4A86-AA79-5BAB5CC8E66A}
{98466E5C-BDDD-4FE3-AE1E-E92EAD621AE9} = {FC60D7C4-F0D8-4E64-BB51-416F222F5D1B}
EndGlobalSection
EndGlobal
32 changes: 32 additions & 0 deletions src/Lib.Tests/Lib.Tests.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<Project Sdk="Microsoft.NET.Sdk">
<!-- Core properties -->
<PropertyGroup>
<RootNamespace>EntraMfaPrefillinator.Lib.Tests</RootNamespace>
<AssemblyName>EntraMfaPrefillinator.Lib.Tests</AssemblyName>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<!-- Package properties -->
<PropertyGroup>
<PackageId>EntraMfaPrefillinator.Lib.Tests</PackageId>
<Description>
Tests for the lass library for EntraMfaPrefillinator.
</Description>
<Authors>Timothy Small</Authors>
<Company>Smalls.Online</Company>
<Copyright>© Smalls.Online</Copyright>
<RepositoryUrl>https://github.com/Smalls1652/EntraMfaPrefillinator</RepositoryUrl>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
</PropertyGroup>
<!-- Dependencies -->
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" />
<PackageReference Include="MSTest" />
<ProjectReference Include="../Lib/Lib.csproj" />
</ItemGroup>
<!-- Additional settings -->
<ItemGroup>
<Using Include="Microsoft.VisualStudio.TestTools.UnitTesting" />
</ItemGroup>
</Project>
1 change: 1 addition & 0 deletions src/Lib.Tests/MSTestSettings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[assembly: Parallelize(Scope = ExecutionScope.MethodLevel)]
31 changes: 31 additions & 0 deletions src/Lib.Tests/Regex/CsvDataRegexTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using EntraMfaPrefillinator.Lib.Utilities;

namespace EntraMfaPrefillinator.Lib.Tests.Regex;

[TestClass]
public sealed class CsvDataRegexTests
{
[TestMethod]
[DataRow("(555) 555-5555")]
[DataRow("(555) 5555555")]
[DataRow("(555)-5555555")]
[DataRow("555 555-5555")]
[DataRow("555-555-5555")]
public void IsValidPhoneNumber_ReturnTrue(string value)
{
bool result = CsvDataRegexTools.IsValidPhoneNumber(value);

Assert.IsTrue(result, $"{value} should be true");
}

[TestMethod]
[DataRow("(555) 5555-5555")]
[DataRow("(5555) 5555-5555")]
[DataRow("[555] 555-55555")]
public void IsValidPhoneNumber_ReturnFalse(string value)
{
bool result = CsvDataRegexTools.IsValidPhoneNumber(value);

Assert.IsFalse(result, message: $"{value} should be false");
}
}
17 changes: 14 additions & 3 deletions src/Lib/Models/UserDetails.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Text.RegularExpressions;

using EntraMfaPrefillinator.Lib.Utilities;

namespace EntraMfaPrefillinator.Lib.Models;
Expand All @@ -15,7 +16,7 @@ public sealed class UserDetails
/// Initializes a new instance of the <see cref="UserDetails"/> class.
/// </summary>
public UserDetails()
{}
{ }

/// <summary>
/// Initializes a new instance of the <see cref="UserDetails"/> class.
Expand Down Expand Up @@ -154,6 +155,11 @@ public UserDetails(string csvLine)
return null;
}

if (!CsvDataRegexTools.IsValidPhoneNumber(phoneNumber))
{
return null;
}

if (CsvDataRegexTools.PhoneNumberHasAreaCodeParentheses(phoneNumber))
{
phoneNumber = CsvDataRegexTools.NormalizePhoneNumberAreaCodeParentheses(phoneNumber);
Expand All @@ -164,7 +170,7 @@ public UserDetails(string csvLine)
phoneNumber = $"+1 {phoneNumber}";
}

if (!CsvDataRegexTools.IsValidPhoneNumberFormat(phoneNumber))
if (!CsvDataRegexTools.IsValidNormalizedPhoneNumberFormat(phoneNumber))
{
return null;
}
Expand All @@ -184,6 +190,11 @@ public UserDetails(string csvLine)
return null;
}

if (!CsvDataRegexTools.IsValidPhoneNumber(homePhoneNumber))
{
return null;
}

if (CsvDataRegexTools.PhoneNumberHasAreaCodeParentheses(homePhoneNumber))
{
homePhoneNumber = CsvDataRegexTools.NormalizePhoneNumberAreaCodeParentheses(homePhoneNumber);
Expand All @@ -194,7 +205,7 @@ public UserDetails(string csvLine)
homePhoneNumber = $"+1 {homePhoneNumber}";
}

if (!CsvDataRegexTools.IsValidPhoneNumberFormat(homePhoneNumber))
if (!CsvDataRegexTools.IsValidNormalizedPhoneNumberFormat(homePhoneNumber))
{
return null;
}
Expand Down
19 changes: 13 additions & 6 deletions src/Lib/Utilities/CsvDataRegexTools.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,19 @@ public static partial class CsvDataRegexTools
)]
private static partial Regex PhoneNumberHasCountryCodeRegex();

/// <summary>
/// Check if the phone number is valid.
/// </summary>
/// <param name="phoneNumber">The phone number to check.</param>
/// <returns>True if the phone number is valid; otherwise, false.</returns>
public static bool IsValidPhoneNumber(string phoneNumber) => PhoneNumberRegex().IsMatch(phoneNumber);

/// <summary>
/// Checks if the phone number has an area code in parentheses.
/// </summary>
/// <param name="phoneNumber">The phone number to check.</param>
/// <returns>True if the phone number has an area code in parentheses; otherwise, false.</returns>
public static bool PhoneNumberHasAreaCodeParentheses(string phoneNumber) => PhoneNumberAreaCodeParenthesesRegex().IsMatch(phoneNumber);
public static bool PhoneNumberHasAreaCodeParentheses(string phoneNumber) => PhoneNumberRegex().Match(phoneNumber).Groups["areaCodeWithParentheses"].Success;

/// <summary>
/// Normalizes a phone number with an area code in parentheses.
Expand All @@ -50,15 +57,15 @@ public static partial class CsvDataRegexTools
/// <returns>A normalized phone number in the format <c>###-###-####</c>.</returns>
public static string NormalizePhoneNumberAreaCodeParentheses(string phoneNumber)
{
Match phoneNumberMatch = PhoneNumberAreaCodeParenthesesRegex().Match(phoneNumber);
Match phoneNumberMatch = PhoneNumberRegex().Match(phoneNumber);

return $"{phoneNumberMatch.Groups["areaCode"].Value}-{phoneNumberMatch.Groups["phonePrefix"].Value}-{phoneNumberMatch.Groups["lineNumber"].Value}";
}

[GeneratedRegex(
pattern: @"\((?'areaCode'\d{3})\)(?>\s|(?>-|))(?'phonePrefix'\d{3})(?>-|)(?'lineNumber'\d{4})"
pattern: @"(?'areaCodeWithParentheses'(?>\(|)(?'areaCode'\d{3})(?>\)|))(?>\s|(?>-|))(?'phonePrefix'\d{3})(?>-|)(?'lineNumber'\d{4})"
)]
private static partial Regex PhoneNumberAreaCodeParenthesesRegex();
private static partial Regex PhoneNumberRegex();

/// <summary>
/// Checks if the phone number is in the correct format.
Expand All @@ -68,12 +75,12 @@ public static string NormalizePhoneNumberAreaCodeParentheses(string phoneNumber)
/// </remarks>
/// <param name="phoneNumber">The phone number to check.</param>
/// <returns>True if the phone number is in the correct format; otherwise, false.</returns>
public static bool IsValidPhoneNumberFormat(string phoneNumber) => ValidPhoneNumberFormatRegex().IsMatch(phoneNumber);
public static bool IsValidNormalizedPhoneNumberFormat(string phoneNumber) => ValidNormalizedPhoneNumberFormatRegex().IsMatch(phoneNumber);

[GeneratedRegex(
pattern: @"(?'countryCode'\+\d{1,}) (?'areaCode'\d{3})-(?'phonePrefix'\d{3})-(?'lineNumber'\d{4})"
)]
private static partial Regex ValidPhoneNumberFormatRegex();
private static partial Regex ValidNormalizedPhoneNumberFormatRegex();

/// <summary>
/// Checks if the provided email address is valid.
Expand Down

0 comments on commit 7a35836

Please sign in to comment.