Skip to content

Commit

Permalink
Added optional option to form date and file upload control (#672)
Browse files Browse the repository at this point in the history
* Added optional option to form date and file upload control

* Fix broken test

* fix typo
  • Loading branch information
dharmverma authored Sep 27, 2024
1 parent bd36d24 commit 50919a1
Show file tree
Hide file tree
Showing 13 changed files with 2,059 additions and 125 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ public void Validate_ReturnsError_WhenFileIsRequiredButNotUploaded()
public void Validate_ReturnsError_WhenUploadedFileExceedsMaxSize()
{
var formFileMock = new Mock<IFormFile>();
formFileMock.Setup(f => f.Length).Returns(11 * 1024 * 1024); // 11 MB
formFileMock.Setup(f => f.Length).Returns(26 * 1024 * 1024); // 26 MB
formFileMock.Setup(f => f.FileName).Returns("testfile.txt");

_model.IsRequired = true;
Expand All @@ -108,7 +108,7 @@ public void Validate_ReturnsError_WhenUploadedFileExceedsMaxSize()
var validationResults = _model.Validate(new ValidationContext(_model)).ToList();

validationResults.Should().ContainSingle();
validationResults.First().ErrorMessage.Should().Be("The file size must not exceed 10MB.");
validationResults.First().ErrorMessage.Should().Be("The file size must not exceed 25MB.");
}

[Fact]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,16 @@ public class FormElementDateInputModel : FormElementModel, IValidatableObject
[BindProperty]
public string? Year { get; set; }

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

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

if (!string.IsNullOrWhiteSpace(Day) && !string.IsNullOrWhiteSpace(Month) && !string.IsNullOrWhiteSpace(Year))
{
var dateString = $"{Year}-{Month!.PadLeft(2, '0')}-{Day!.PadLeft(2, '0')}";
Expand All @@ -42,11 +50,34 @@ public override void SetAnswer(FormAnswer? answer)
Month = answer.DateValue.Value.Month.ToString();
Year = answer.DateValue.Value.Year.ToString();
}
else if (RedirectFromCheckYourAnswerPage && IsRequired == false)
{
HasValue = false;
}
}

public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if (CurrentFormQuestionType == FormQuestionType.Date && IsRequired == true && string.IsNullOrWhiteSpace(DateString))
if (CurrentFormQuestionType != FormQuestionType.Date)
{
yield break;
}

var validateField = IsRequired;

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

if (validateField)
{
if (string.IsNullOrWhiteSpace(Day))
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,24 @@ namespace CO.CDP.OrganisationApp.Pages.Forms;

public class FormElementFileUploadModel : FormElementModel, IValidatableObject
{
private const int AllowedMaxFileSizeMB = 10;
private const int AllowedMaxFileSizeMB = 25;
private readonly string[] AllowedExtensions = [".jpg", ".jpeg", ".png", ".pdf", ".txt", ".xls", ".xlsx", ".csv", ".docx", ".doc"];

[BindProperty]
public IFormFile? UploadedFile { get; set; }

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

public string? UploadedFileName { get; set; }

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

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

Expand All @@ -26,6 +34,11 @@ public override void SetAnswer(FormAnswer? answer)
if (answer?.TextValue != null)
{
UploadedFileName = answer.TextValue;
HasValue = true;
}
else if (RedirectFromCheckYourAnswerPage && IsRequired == false)
{
HasValue = false;
}
}

Expand All @@ -46,23 +59,45 @@ public override void SetAnswer(FormAnswer? answer)

public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if (CurrentFormQuestionType == FormQuestionType.FileUpload && IsRequired == true && string.IsNullOrWhiteSpace(UploadedFileName))
if (CurrentFormQuestionType != FormQuestionType.FileUpload)
{
if (UploadedFile == null)
yield break;
}

var validateField = IsRequired;

if (IsRequired == false)
{
if (HasValue == null)
{
yield return new ValidationResult("Select an option", [nameof(HasValue)]);
}
else if (HasValue == true)
{
yield return new ValidationResult("No file selected.", [nameof(UploadedFile)]);
validateField = true;
}
else
}

if (validateField)
{
if (string.IsNullOrWhiteSpace(UploadedFileName))
{
if (UploadedFile.Length > AllowedMaxFileSizeMB * 1024 * 1024)
if (UploadedFile == null)
{
yield return new ValidationResult($"The file size must not exceed {AllowedMaxFileSizeMB}MB.", [nameof(UploadedFile)]);
yield return new ValidationResult("No file selected.", [nameof(UploadedFile)]);
}

var fileExtension = Path.GetExtension(UploadedFile.FileName).ToLowerInvariant();
if (!AllowedExtensions.Contains(fileExtension))
else
{
yield return new ValidationResult($"Please upload a file which has one of the following extensions: {string.Join(", ", AllowedExtensions)}", [nameof(UploadedFile)]);
if (UploadedFile.Length > AllowedMaxFileSizeMB * 1024 * 1024)
{
yield return new ValidationResult($"The file size must not exceed {AllowedMaxFileSizeMB}MB.", [nameof(UploadedFile)]);
}

var fileExtension = Path.GetExtension(UploadedFile.FileName).ToLowerInvariant();
if (!AllowedExtensions.Contains(fileExtension))
{
yield return new ValidationResult($"Please upload a file which has one of the following extensions: {string.Join(", ", AllowedExtensions)}", [nameof(UploadedFile)]);
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@ public class FormElementTextInputModel : FormElementModel, IValidatableObject

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

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

Expand All @@ -35,6 +39,11 @@ 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
Expand Up @@ -180,12 +180,13 @@ private async Task<bool> InitAndVerifyPage()
var answerString = question.Type switch
{
FormQuestionType.Text => answer.TextValue ?? "",
FormQuestionType.CheckBox => answer.BoolValue.HasValue ? question.Options.Choices?.FirstOrDefault()?.Title ?? "" : "",
FormQuestionType.FileUpload => answer.TextValue ?? "",
FormQuestionType.YesOrNo => answer.BoolValue.HasValue ? (answer.BoolValue == true ? "yes" : "no") : "",
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 ?? "",
_ => ""
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -250,13 +250,13 @@ public bool PreviousQuestionHasNonUKAddressAnswer()
{
FormQuestionType.NoInput => NoInputModel ?? new FormElementNoInputModel(),
FormQuestionType.Text => TextInputModel ?? new FormElementTextInputModel(),
FormQuestionType.MultiLine => MultiLineInputModel ?? new FormElementMultiLineInputModel(),
FormQuestionType.FileUpload => FileUploadModel ?? new FormElementFileUploadModel(),
FormQuestionType.YesOrNo => YesNoInputModel ?? new FormElementYesNoInputModel(),
FormQuestionType.Date => DateInputModel ?? new FormElementDateInputModel(),
FormQuestionType.CheckBox => CheckBoxModel ?? new FormElementCheckBoxInputModel(),
FormQuestionType.Address => AddressModel ?? new FormElementAddressModel(),
FormQuestionType.SingleChoice => SingleChoiceModel ?? new FormElementSingleChoiceModel(),
FormQuestionType.MultiLine => MultiLineInputModel ?? new FormElementMultiLineInputModel(),
_ => throw new NotImplementedException($"Forms question: {question.Type} is not supported"),
};

Expand Down
Loading

0 comments on commit 50919a1

Please sign in to comment.