Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exclusions - Adding an exclusion - authority website #675

Merged
merged 9 commits into from
Oct 2, 2024
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" class="govuk-button">Confirm and get share code</button>
Expand Down
Loading