Skip to content

Commit

Permalink
Exclusions - Adding an exclusion - authority website (#675)
Browse files Browse the repository at this point in the history
* Exclusions - Adding an exclusion - authority website

* Added unit test

* PR comment fix

* PR comment update

* PR comment update

* pr comments resolved
  • Loading branch information
dharmverma authored Oct 2, 2024
1 parent c12e7bb commit ff6adec
Show file tree
Hide file tree
Showing 18 changed files with 2,312 additions and 131 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
using CO.CDP.OrganisationApp.Models;
using CO.CDP.OrganisationApp.Pages.Forms;
using FluentAssertions;
using System.ComponentModel.DataAnnotations;

namespace CO.CDP.OrganisationApp.Tests.Pages.Forms;

public class FormElementUrlInputModelTests
{
[Fact]
public void GetAnswer_ShouldReturnNull_WhenIsNotRequiredAndHasNoValue()
{
var model = new FormElementUrlInputModel
{
IsRequired = false,
HasValue = false
};

var result = model.GetAnswer();

result.Should().BeNull();
}

[Fact]
public void GetAnswer_ShouldReturnAnswer_WhenTextInputIsProvided()
{
var model = new FormElementUrlInputModel
{
IsRequired = true,
TextInput = "https://example.com",
HasValue = true
};

var result = model.GetAnswer();

result.Should().NotBeNull();
result?.TextValue.Should().Be("https://example.com");
}

[Fact]
public void SetAnswer_ShouldSetTextInputAndHasValue_WhenAnswerIsProvided()
{
var model = new FormElementUrlInputModel();
var answer = new FormAnswer { TextValue = "https://example.com" };

model.SetAnswer(answer);

model.TextInput.Should().Be("https://example.com");
model.HasValue.Should().BeTrue();
}

[Fact]
public void SetAnswer_ShouldSetHasValueToFalse_WhenAnswerIsNullAndRedirectFromCheckYourAnswerPage()
{
var model = new FormElementUrlInputModel();
model.Initialize(new FormQuestion { IsRequired = false }, true);

model.SetAnswer(null);

model.HasValue.Should().BeFalse();
}

[Fact]
public void Validate_ShouldReturnError_WhenHasValueIsNullAndIsNotRequired()
{
var model = new FormElementUrlInputModel
{
IsRequired = false,
HasValue = null
};

var validationResults = new List<ValidationResult>();
var context = new ValidationContext(model);
Validator.TryValidateObject(model, context, validationResults, true);

validationResults.Should().ContainSingle();
validationResults[0].ErrorMessage.Should().Be("Select an option");
}

[Fact]
public void Validate_ShouldReturnError_WhenTextInputIsMissingAndIsRequired()
{
var model = new FormElementUrlInputModel
{
IsRequired = true,
HasValue = true,
TextInput = null
};

var validationResults = new List<ValidationResult>();
var context = new ValidationContext(model);
Validator.TryValidateObject(model, context, validationResults, true);

validationResults.Should().ContainSingle();
validationResults[0].ErrorMessage.Should().Be("Enter a website address");
}

[Fact]
public void Validate_ShouldReturnError_WhenTextInputIsInvalidUrl()
{
var model = new FormElementUrlInputModel
{
IsRequired = true,
HasValue = true,
TextInput = "invalid-url"
};

var validationResults = new List<ValidationResult>();
var context = new ValidationContext(model);
Validator.TryValidateObject(model, context, validationResults, true);

validationResults.Should().ContainSingle();
validationResults[0].ErrorMessage.Should().Be("Enter a valid website address in the correct format");
}

[Fact]
public void Validate_ShouldPass_WhenValidUrlIsProvidedAndIsRequired()
{
var model = new FormElementUrlInputModel
{
IsRequired = true,
HasValue = true,
TextInput = "https://example.com"
};

var validationResults = new List<ValidationResult>();
var context = new ValidationContext(model);
var isValid = Validator.TryValidateObject(model, context, validationResults, true);

isValid.Should().BeTrue();
validationResults.Should().BeEmpty();
}
}
3 changes: 2 additions & 1 deletion Frontend/CO.CDP.OrganisationApp/Models/DynamicForms.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,5 +78,6 @@ public enum FormQuestionType
Date,
CheckBox,
Address,
MultiLine
MultiLine,
Url
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,6 @@ public override void SetAnswer(FormAnswer? answer)

public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if (CurrentFormQuestionType != FormQuestionType.FileUpload)
{
yield break;
}

var validateField = IsRequired;

if (IsRequired == false)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,6 @@ public override void SetAnswer(FormAnswer? answer)

public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if (CurrentFormQuestionType != FormQuestionType.Text)
{
yield break;
}

var validateTextField = IsRequired;

if (IsRequired == false)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
using CO.CDP.OrganisationApp.Models;
using Microsoft.AspNetCore.Mvc;
using System.ComponentModel.DataAnnotations;

namespace CO.CDP.OrganisationApp.Pages.Forms;

public class FormElementUrlInputModel : FormElementModel, IValidatableObject
{
[BindProperty]
public string? TextInput { get; set; }

[BindProperty]
public bool? HasValue { get; set; }


public override FormAnswer? GetAnswer()
{
if (IsRequired == false && HasValue == false)
{
return null;
}

return string.IsNullOrWhiteSpace(TextInput) ? null : new FormAnswer { TextValue = TextInput };
}

public override void SetAnswer(FormAnswer? answer)
{
if (answer?.TextValue != null)
{
TextInput = answer.TextValue;
HasValue = true;
}
else if (RedirectFromCheckYourAnswerPage && IsRequired == false)
{
HasValue = false;
}
}

public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
var validateTextField = IsRequired;

if (IsRequired == false)
{
if (HasValue == null)
{
yield return new ValidationResult("Select an option", [nameof(HasValue)]);
}
else if (HasValue == true)
{
validateTextField = true;
}
}

if (validateTextField)
{
if (string.IsNullOrWhiteSpace(TextInput))
{
yield return new ValidationResult("Enter a website address", [nameof(TextInput)]);
}
else if (Uri.TryCreate(TextInput, UriKind.Absolute, out var _) == false)
{
yield return new ValidationResult("Enter a valid website address in the correct format", [nameof(TextInput)]);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -181,12 +181,13 @@ private async Task<bool> InitAndVerifyPage()
{
FormQuestionType.Text => answer.TextValue ?? "",
FormQuestionType.FileUpload => answer.TextValue ?? "",
FormQuestionType.YesOrNo => answer.BoolValue.HasValue ? (answer.BoolValue == true ? "yes" : "no") : "",
FormQuestionType.YesOrNo => answer.BoolValue.HasValue ? (answer.BoolValue == true ? "Yes" : "No") : "",
FormQuestionType.SingleChoice => answer.OptionValue ?? "",
FormQuestionType.Date => answer.DateValue.HasValue ? answer.DateValue.Value.ToString("dd/MM/yyyy") : "",
FormQuestionType.CheckBox => answer.BoolValue.HasValue ? question.Options.Choices?.FirstOrDefault()?.Title ?? "" : "",
FormQuestionType.Address => answer.AddressValue != null ? $"{answer.AddressValue.StreetAddress}, {answer.AddressValue.Locality}, {answer.AddressValue.PostalCode}, {answer.AddressValue.CountryName}" : "",
FormQuestionType.SingleChoice => answer.OptionValue ?? "",
FormQuestionType.MultiLine => answer.TextValue ?? "",
FormQuestionType.Url => answer.TextValue ?? "",
_ => ""
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
@model FormsQuestionPageModel

@{
var isCheckYourAnswersPage = Model.CurrentFormQuestionType == Models.FormQuestionType.CheckYourAnswers;
var backUrl = $"/organisation/{Model.OrganisationId}/supplier-information";
var fromCheckAnswerPage = Model.RedirectFromCheckYourAnswerPage == true;

Expand All @@ -28,45 +29,41 @@

<main class="govuk-main-wrapper">
<div class="govuk-grid-row">
<div class="govuk-grid-column-two-thirds">
<div class="@(isCheckYourAnswersPage ? "govuk-grid-column-full" : "govuk-grid-column-two-thirds")">
<partial name="_ErrorSummary" model="@ModelState" />

<form method="post" enctype="@Model.EncType">
<fieldset class="govuk-fieldset">
@if (Model.PartialViewName != null && Model.PartialViewModel != null)
{
@await Html.PartialAsync(Model.PartialViewName, Model.PartialViewModel)
}

@if (Model.CurrentFormQuestionType == Models.FormQuestionType.CheckYourAnswers)
{
var answers = await Model.GetAnswers();
@if (Model.PartialViewName != null && Model.PartialViewModel != null)
{
@await Html.PartialAsync(Model.PartialViewName, Model.PartialViewModel)
}

<h1 class="govuk-heading-l">Check your answers</h1>
<dl class="govuk-summary-list govuk-!-margin-bottom-9">
@foreach (var answer in answers)
{
<div class="govuk-summary-list__row">
<dt class="govuk-summary-list__key">
@answer.Title
</dt>
<dd class="govuk-summary-list__value">
@Html.Raw(answer.Answer)
</dd>
<dd class="govuk-summary-list__actions">
<a class="govuk-link" href="@answer.ChangeLink">
Change<span class="govuk-visually-hidden">
@($"the {answer.Title?.ToLower()}")
</span>
</a>
</dd>
</div>
}
</dl>
}
</fieldset>
@if (Model.CurrentFormQuestionType == Models.FormQuestionType.CheckYourAnswers)
@if (isCheckYourAnswersPage)
{
var answers = await Model.GetAnswers();

<h1 class="govuk-heading-l">Check your answers</h1>
<dl class="govuk-summary-list govuk-!-margin-bottom-9">
@foreach (var answer in answers)
{
<div class="govuk-summary-list__row">
<dt class="govuk-summary-list__key">
@answer.Title
</dt>
<dd class="govuk-summary-list__value">
@Html.Raw(answer.Answer)
</dd>
<dd class="govuk-summary-list__actions">
<a class="govuk-link" href="@answer.ChangeLink">
Change<span class="govuk-visually-hidden">
@($"the {answer.Title?.ToLower()}")
</span>
</a>
</dd>
</div>
}
</dl>

if (Model.FormSectionType == Models.FormSectionType.Declaration)
{
<button type="submit" data-prevent-double-click="true" class="govuk-button">Confirm and get share code</button>
Expand Down
Loading

0 comments on commit ff6adec

Please sign in to comment.