Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,6 @@ public void ValidateProfessionalRegistrationNumber_sets_error_when_hasPrn_is_not

[TestCase(null, ErrorMessagesTestHelper.MissingNumberError)]
[TestCase("", ErrorMessagesTestHelper.MissingNumberError)]
[TestCase("1234", ErrorMessagesTestHelper.LengthError)]
[TestCase("1234", ErrorMessagesTestHelper.LengthError)]
[TestCase("01234_", ErrorMessagesTestHelper.InvalidFormatError)]
[TestCase("01234 ", ErrorMessagesTestHelper.InvalidFormatError)]
[TestCase("01234$", ErrorMessagesTestHelper.InvalidFormatError)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,20 @@ namespace DigitalLearningSolutions.Web.Tests.TestHelpers
public static class ErrorMessagesTestHelper
{
public const string InvalidFormatError =
"Invalid professional registration number format. " +
"Valid formats include: 7 digits (e.g., 1234567), 1–2 letters followed by 6 digits (e.g., AB123456), " +
"4–8 digits, an optional 'P' plus 5–6 digits, 'C' or 'P' plus 6 digits, " +
"an optional letter plus 5–6 digits, 'L' plus 4–6 digits, " +
"or 2 digits followed by a hyphen and 4–5 alphanumeric characters (e.g., 12-AB123).";
@"The format you entered isn’t recognised. Please check and try again.
<br>Valid formats include:
<ul>
<li>7 digits - example, 1234567</li>
<li>1–2 letters followed by 6 digits - example, AB123456</li>
<li>‘P’ followed by 5–6 digits - example, P12345, P123456</li>
<li>‘C’ or ‘P’ followed by 6 digits - example, C123456, P123456</li>
<li>Optional letter followed by 5–6 digits - example, A12345, B123456</li>
<li>‘L’ followed by 4–6 digits - example, L1234, L123456</li>
<li>2 digits, hyphen, then 4–5 alphanumeric characters - example, 12-AB123</li>
</ul>";

public const string MissingNumberError = "Enter a professional registration number";
public const string LengthError = "Professional registration number must be between 5 and 20 characters";
public const string LengthError = "Professional registration number must be between 4 and 8 characters";

}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
namespace DigitalLearningSolutions.Web.Helpers
{

using Microsoft.AspNetCore.Mvc.ModelBinding;
using System.Text;
using System.Text.RegularExpressions;

public class ProfessionalRegistrationNumberHelper
Expand Down Expand Up @@ -39,28 +41,29 @@ public static void ValidateProfessionalRegistrationNumber(
modelState.AddModelError("ProfessionalRegistrationNumber", "Enter a professional registration number");
return;
}

if (prn.Length < 5 || prn.Length > 20)
{
modelState.AddModelError(
"ProfessionalRegistrationNumber",
"Professional registration number must be between 5 and 20 characters"
);
}

const string pattern = @"^(\d{7}|[A-Za-z]{1,2}\d{6}|\d{4,8}|P?\d{5,6}|[C|P]\d{6}|[A-Za-z]?\d{5,6}|L\d{4,6}|\d{2}-[A-Za-z\d]{4,5})$";
const string pattern = @"^(\d{7}|[A-Za-z]{1,2}\d{6}|\d{4,8}|P?\d{5,6}|[C|P]\d{6}|[A-Za-z]?\d{5,6}|L\d{4,6}|\d{2}-[A-Za-z\d]{4,5})$";
var rg = new Regex(pattern, RegexOptions.IgnoreCase);
if (!rg.Match(prn).Success)
{
modelState.AddModelError(
"ProfessionalRegistrationNumber",
"Invalid professional registration number format. " +
"Valid formats include: 7 digits (e.g., 1234567), 1–2 letters followed by 6 digits (e.g., AB123456), " +
"4–8 digits, an optional 'P' plus 5–6 digits, 'C' or 'P' plus 6 digits, " +
"an optional letter plus 5–6 digits, 'L' plus 4–6 digits, " +
"or 2 digits followed by a hyphen and 4–5 alphanumeric characters (e.g., 12-AB123)."
GetProfessionalRegistrationNumberErrorMessage()
);
}
}
public static string GetProfessionalRegistrationNumberErrorMessage()
{
return @"The format you entered isn’t recognised. Please check and try again.
<br>Valid formats include:
<ul>
<li>7 digits - example, 1234567</li>
<li>1–2 letters followed by 6 digits - example, AB123456</li>
<li>‘P’ followed by 5–6 digits - example, P12345, P123456</li>
<li>‘C’ or ‘P’ followed by 6 digits - example, C123456, P123456</li>
<li>Optional letter followed by 5–6 digits - example, A12345, B123456</li>
<li>‘L’ followed by 4–6 digits - example, L1234, L123456</li>
<li>2 digits, hyphen, then 4–5 alphanumeric characters - example, 12-AB123</li>
</ul>";
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@

var subject = Model.IsSelfRegistrationOrEdit ? "you" : "they";
var capitalisedSubject = Model.IsSelfRegistrationOrEdit ? "You" : "They";
var professionalRegistrationNumberError = ViewData.ModelState["ProfessionalRegistrationNumber"]?.Errors.FirstOrDefault()?.ErrorMessage;
if (ViewData.ModelState.ContainsKey("ProfessionalRegistrationNumber"))
{
ViewData.ModelState["ProfessionalRegistrationNumber"].Errors.Clear();
}
}

<input type="hidden" asp-for="IsSelfRegistrationOrEdit" />
Expand Down Expand Up @@ -53,7 +58,7 @@
No
</label>
</div>

<div class="nhsuk-radios__item">
<input name="@nameof(Model.HasProfessionalRegistrationNumber)"
class="nhsuk-radios__input"
Expand All @@ -66,9 +71,16 @@
Yes
</label>
</div>
<div class="nhsuk-radios__conditional @(optionYesSelected ? " " : " nhsuk-radios__conditional--hidden") @(professionalRegNumberErrorHasOccurred ? "form-group-wrapper--error" : "" )"
<div class="nhsuk-radios__conditional"
id="@professionalRegConditionalId">
<vc:text-input asp-for="@nameof(Model.ProfessionalRegistrationNumber)"
@if (professionalRegistrationNumberError != null)
{
<span class="nhsuk-error-message" id="ProfessionalRegistrationNumber-error">
<span class="nhsuk-u-visually-hidden">Error:</span>
@Html.Raw(professionalRegistrationNumberError)
</span>
}
<vc:text-input asp-for="@nameof(Model.ProfessionalRegistrationNumber)"
label="Professional Registration Number"
populate-with-current-value="true"
type="text"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@
<div class="nhsuk-grid-column-full">
@if (errorHasOccurred)
{
<vc:error-summary order-of-property-names="@(new[] {
var professionalRegistrationNumberError = ViewData.ModelState["ProfessionalRegistrationNumber"]?.Errors.FirstOrDefault();
if (professionalRegistrationNumberError == null)
{
<vc:error-summary order-of-property-names="@(new[] {
nameof(Model.FirstName),
nameof(Model.LastName),
nameof(Model.CentreSpecificEmail),
Expand All @@ -28,6 +31,23 @@
nameof(Model.Answer4),
nameof(Model.Answer5),
nameof(Model.Answer6) })" />
}
if (professionalRegistrationNumberError != null)
{
<div class="nhsuk-error-summary" aria-labelledby="error-summary-title" role="alert" tabindex="-1">
<h2 class="nhsuk-error-summary__title" id="error-summary-title">
There is a problem
</h2>
<div class="nhsuk-error-summary__body">
<span class="nhsuk-error-message" id="ProfessionalRegistrationNumber-error">
<span class="nhsuk-u-visually-hidden">Error:</span> <span class="nhsuk-error-message" id="ProfessionalRegistrationNumber-error">
<span class="nhsuk-u-visually-hidden">Error:</span>
@Html.Raw(professionalRegistrationNumberError.ErrorMessage)
</span>
</span>
</div>
</div>
}
}

<h1 class="nhsuk-heading-xl">Edit delegate details</h1>
Expand Down
Loading