Skip to content

Commit

Permalink
Merge pull request #214 from DFE-Digital/feature/awarding-organisatio…
Browse files Browse the repository at this point in the history
…n-page

Feature/awarding organisation page
  • Loading branch information
DanielClarkeEducation authored Jun 24, 2024
2 parents 9e8431e + 4dde82d commit 958470b
Show file tree
Hide file tree
Showing 20 changed files with 683 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,11 @@ public static class QuestionPages
/// Entry ID for the "When was the qualification started" question page.
/// </summary>
public const string WhenWasTheQualificationStarted = "2o331MBr0R6nsZNBem4yvk";

//// Dropdown Pages

/// <summary>
/// Entry ID for the "What is the awarding organisation" question page.
/// </summary>
public const string WhatIsTheAwardingOrganisation = "7A9txhwSGFrgh3Ye9k5PJ9";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
namespace Dfe.EarlyYearsQualification.Content.Entities;

public class DropdownQuestionPage
{
public string Question { get; init; } = string.Empty;

public string CtaButtonText { get; init; } = string.Empty;

public string ErrorMessage { get; init; } = string.Empty;

public string DropdownHeading { get; init; } = string.Empty;

public string NotInListText { get; init; } = string.Empty;

public string DefaultText { get; init; } = string.Empty;
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ private readonly Dictionary<object, string> _contentTypes
{ typeof(CookiesPage), "cookiesPage" },
{ typeof(PhaseBanner), "phaseBanner" },
{ typeof(CookiesBanner), "cookiesBanner" },
{ typeof(DateQuestionPage), "dateQuestionPage" }
{ typeof(DateQuestionPage), "dateQuestionPage" },
{ typeof(DropdownQuestionPage), "dropdownQuestionPage" }
};

public async Task<StartPage?> GetStartPage()
Expand Down Expand Up @@ -126,10 +127,15 @@ private readonly Dictionary<object, string> _contentTypes
return await GetEntryById<RadioQuestionPage>(entryId);
}

public async Task<DateQuestionPage?> GetDateQuestionPage(string entryId)
{
return await GetEntryById<DateQuestionPage>(entryId);
}
public async Task<DateQuestionPage?> GetDateQuestionPage(string entryId)
{
return await GetEntryById<DateQuestionPage>(entryId);
}

public async Task<DropdownQuestionPage?> GetDropdownQuestionPage(string entryId)
{
return await GetEntryById<DropdownQuestionPage>(entryId);
}

public async Task<PhaseBanner?> GetPhaseBannerContent()
{
Expand All @@ -155,6 +161,12 @@ private readonly Dictionary<object, string> _contentTypes
return cookiesBannerEntry.First();
}

public async Task<List<Qualification>> GetQualifications()
{
var qualifications = await GetEntriesByType<Qualification>();
return qualifications!.ToList();
}

private async Task<T?> GetEntryById<T>(string entryId)
{
try
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,8 @@ public interface IContentService
Task<CookiesBanner?> GetCookiesBannerContent();

Task<DateQuestionPage?> GetDateQuestionPage(string entryId);

Task<DropdownQuestionPage?> GetDropdownQuestionPage(string entryId);

Task<List<Qualification>> GetQualifications();
}
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,38 @@ await Task.FromResult(CreateDateQuestionPage()),
};
}

public async Task<DropdownQuestionPage?> GetDropdownQuestionPage(string entryId)
{
return entryId switch
{
QuestionPages.WhatIsTheAwardingOrganisation =>
await Task.FromResult(CreateDropdownPage()),
_ => throw new NotImplementedException($"No dropdown question page mock for entry {entryId}")
};
}

public Task<List<Qualification>> GetQualifications()
{
return Task.FromResult(new List<Qualification>
{
new("1", "TEST",
"A awarding organisation", 123, null,
null, null, null, null),
new("2", "TEST",
"B awarding organisation", 123, null,
null, null, null, null),
new("3", "TEST",
"C awarding organisation", 123, null,
null, null, null, null),
new("4", "TEST",
"D awarding organisation", 123, null,
null, null, null, null),
new("5", "TEST",
"E awarding organisation", 123, null,
null, null, null, null)
});
}

public async Task<StartPage?> GetStartPage()
{
var preCtaButtonContent =
Expand Down Expand Up @@ -251,6 +283,19 @@ private static DateQuestionPage CreateDateQuestionPage()
QuestionHint = "Test Question Hint"
};
}

private static DropdownQuestionPage CreateDropdownPage()
{
return new DropdownQuestionPage
{
Question = "Test Dropdown Question",
ErrorMessage = "Test Error Message",
CtaButtonText = "Test Button Text",
DefaultText = "Test Default Dropdown Text",
DropdownHeading = "Test Dropdown Heading",
NotInListText = "Test Not In The List"
};
}

private static AdvicePage CreateAdvicePage(string heading, Document body)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using Dfe.EarlyYearsQualification.Web.Models.Content.QuestionModels;
using Dfe.EarlyYearsQualification.Web.Services.UserJourneyCookieService;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;

namespace Dfe.EarlyYearsQualification.Web.Controllers;

Expand Down Expand Up @@ -113,6 +114,47 @@ public async Task<IActionResult> WhatLevelIsTheQualification(RadioQuestionModel

userJourneyCookieService.SetLevelOfQualification(model.Option!);

return RedirectToAction(nameof(this.WhatIsTheAwardingOrganisation));
}

[HttpGet("what-is-the-awarding-organisation")]
public async Task<IActionResult> WhatIsTheAwardingOrganisation()
{
var questionPage = await contentService.GetDropdownQuestionPage(QuestionPages.WhatIsTheAwardingOrganisation);
if (questionPage is null)
{
logger.LogError("No content for the question page");
return RedirectToAction("Index", "Error");
}

var qualifications = await contentService.GetQualifications();

var model = MapDropdownModel(new DropdownQuestionModel(), questionPage, qualifications, nameof(this.WhatIsTheAwardingOrganisation),
Questions);

return View("Dropdown", model);
}

[HttpPost("what-is-the-awarding-organisation")]
public async Task<IActionResult> WhatIsTheAwardingOrganisation(DropdownQuestionModel model)
{
if (!ModelState.IsValid || (string.IsNullOrEmpty(model.SelectedValue) && !model.NotInTheList))
{
var questionPage = await contentService.GetDropdownQuestionPage(QuestionPages.WhatIsTheAwardingOrganisation);
if (questionPage is not null)
{
var qualifications = await contentService.GetQualifications();

model = MapDropdownModel(model, questionPage, qualifications, nameof(this.WhatIsTheAwardingOrganisation),
Questions);
model.HasErrors = true;
}

return View("Dropdown", model);
}

userJourneyCookieService.SetAwardingOrganisation(model.NotInTheList ? string.Empty : model.SelectedValue);

return RedirectToAction("Get", "QualificationDetails");
}

Expand Down Expand Up @@ -157,4 +199,35 @@ private static DateQuestionModel MapDateModel(DateQuestionModel model, DateQuest
model.YearLabel = question.YearLabel;
return model;
}

private static DropdownQuestionModel MapDropdownModel(DropdownQuestionModel model, DropdownQuestionPage question, List<Qualification> qualifications, string actionName,
string controllerName)
{
var uniqueAwardingOrganisations = qualifications.Select(x => x.AwardingOrganisationTitle).Distinct().Order().ToList();

model.ActionName = actionName;
model.ControllerName = controllerName;
model.CtaButtonText = question.CtaButtonText;
model.ErrorMessage = question.ErrorMessage;
model.Question = question.Question;
model.DropdownHeading = question.DropdownHeading;
model.NotInListText = question.NotInListText;

model.Values.Add(new SelectListItem()
{
Text = question.DefaultText,
Value = ""
});

foreach (var awardingOrg in uniqueAwardingOrganisations)
{
model.Values.Add(new SelectListItem()
{
Value = awardingOrg,
Text = awardingOrg
});
}

return model;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,4 @@ public abstract class BaseQuestionModel
public string ErrorMessage { get; set; } = string.Empty;

public bool HasErrors { get; set; }


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using Microsoft.AspNetCore.Mvc.Rendering;

namespace Dfe.EarlyYearsQualification.Web.Models.Content.QuestionModels;

public class DropdownQuestionModel : BaseQuestionModel
{
public string SelectedValue { get; init; } = string.Empty;

public List<SelectListItem> Values { get; init; } = [];

public string DropdownHeading { get; set; } = string.Empty;

public string NotInListText { get; set; } = string.Empty;

public string DropdownId { get; init; } = "awarding-organisation-select";

public string CheckboxId { get; init; } = "awarding-organisation-not-in-list";

public bool NotInTheList { get; init; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ public class UserJourneyModel
public string WhereWasQualificationAwarded { get; set; } = string.Empty;
public string WhenWasQualificationAwarded { get; set; } = string.Empty;
public string LevelOfQualification { get; set; } = string.Empty;
public string WhatIsTheAwardingOrganisation { get; set; } = string.Empty;
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,12 @@ public static SecureHeadersMiddlewareConfiguration CustomConfiguration()
CommandType = CspCommandType.Directive,
DirectiveOrUri = "sha256-l5MP+9OapFXGxjKMNj/89ExAW2TvAFFoADrbsmtSJXo="
};

var dropdownPageCheckbox = new ContentSecurityPolicyElement
{
CommandType = CspCommandType.Directive,
DirectiveOrUri = "sha256-pwrEcsLN2o+4gQQDR/0sGCITSf0nhhLAzP4h73+5foc="
};

var unsafeHashesElement = new ContentSecurityPolicyElement
{ CommandType = CspCommandType.Directive, DirectiveOrUri = "unsafe-hashes" };
Expand All @@ -64,6 +70,7 @@ public static SecureHeadersMiddlewareConfiguration CustomConfiguration()
configuration.ContentSecurityPolicyConfiguration.ScriptSrc.Add(govukFrontendSupportedElement);
configuration.ContentSecurityPolicyConfiguration.ScriptSrc.Add(govukAllMinifiedElement);
configuration.ContentSecurityPolicyConfiguration.FrameAncestors.Add(contentfulCspElement);
configuration.ContentSecurityPolicyConfiguration.ScriptSrc.Add(dropdownPageCheckbox);

return configuration;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ public interface IUserJourneyCookieService
public void SetWhereWasQualificationAwarded(string location);
public void SetWhenWasQualificationAwarded(string date);
public void SetLevelOfQualification(string level);
public void SetAwardingOrganisation(string awardingOrganisation);
public UserJourneyModel GetUserJourneyModelFromCookie();
public void ResetUserJourneyCookie();
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,15 @@ public void SetLevelOfQualification(string level)
SetJourneyCookie(model);
}

public void SetAwardingOrganisation(string awardingOrganisation)
{
var model = GetUserJourneyModelFromCookie();

model.WhatIsTheAwardingOrganisation = awardingOrganisation;

SetJourneyCookie(model);
}

public UserJourneyModel GetUserJourneyModelFromCookie()
{
var cookie = context.HttpContext?.Request.Cookies[CookieKeyNames.UserJourneyKey];
Expand All @@ -51,13 +60,8 @@ public UserJourneyModel GetUserJourneyModelFromCookie()

try
{
var journeyCookie = JsonSerializer.Deserialize<UserJourneyModel>(cookie);

if (journeyCookie != null) return journeyCookie;

ResetUserJourneyCookie();
return new UserJourneyModel();

var toReturn = JsonSerializer.Deserialize<UserJourneyModel>(cookie);
return toReturn!;
}
catch
{
Expand All @@ -73,14 +77,7 @@ public void ResetUserJourneyCookie()

private void SetJourneyCookie(UserJourneyModel model)
{
try
{
var serializedCookie = JsonSerializer.Serialize(model);
context.HttpContext?.Response.Cookies.Append(CookieKeyNames.UserJourneyKey, serializedCookie, _options);
}
catch
{
logger.LogError("Failed to serialize user journey model");
}
var serializedCookie = JsonSerializer.Serialize(model);
context.HttpContext?.Response.Cookies.Append(CookieKeyNames.UserJourneyKey, serializedCookie, _options);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@
{
<li>@Model.LevelOfQualification</li>
}

@if (!string.IsNullOrEmpty(Model.WhatIsTheAwardingOrganisation))
{
<li>@Model.WhatIsTheAwardingOrganisation</li>
}
</ul>

<p class="govuk-body">
Expand Down
Loading

0 comments on commit 958470b

Please sign in to comment.