diff --git a/SAPData/GenerateViews.cs b/SAPData/GenerateViews.cs
index 5e224cc55..e7b07867c 100644
--- a/SAPData/GenerateViews.cs
+++ b/SAPData/GenerateViews.cs
@@ -531,6 +531,7 @@ private static string GenerateEstablishmentDimensionView(
sb.AppendLine(" to_tsvector('english', normalize_text(coalesce(t.\"establishmentname\", ''))) AS \"EstablishmentNameFTS\",");
sb.AppendLine(" ST_Transform(\r\n ST_SetSRID(ST_MakePoint(clean_int(t.\"easting\"), clean_int(t.\"northing\")), 27700), 4326\r\n)::geography AS \"geom\",");
sb.AppendLine($" {BuildSenTypes()} AS \"SenTypes\",");
+ sb.AppendLine(" t.\"nurseryprovision__name_\" AS \"NurseryProvisionName\",");
bool hasWraparound = TryResolveRawTable(tableMap, "ks2_wraparound_care", out var wraparoundTable) && !string.IsNullOrWhiteSpace(wraparoundTable);
if (hasWraparound)
diff --git a/SAPPub.Core/Entities/Establishment.cs b/SAPPub.Core/Entities/Establishment.cs
index 01a8388ef..41738478c 100644
--- a/SAPPub.Core/Entities/Establishment.cs
+++ b/SAPPub.Core/Entities/Establishment.cs
@@ -109,6 +109,10 @@ public class Establishment
public string? KS2WraparoundCare { get; set; } = string.Empty;
+ public bool FreeBreakfastClubProgramme { get; set; }
+
+ public string? NurseryProvisionName { get; set; }
+
[IgnoreDataMember]
public bool IsKS2 { get; set; }
@@ -175,7 +179,9 @@ public static EstablishmentServiceModel MapToServiceModel(Establishment e)
IsKS2 = e.IsKS2,
IsKS4 = e.IsKS4,
IsKS5 = e.IsKS5,
- KS2WraparoundCare = e.KS2WraparoundCare
+ KS2WraparoundCare = e.KS2WraparoundCare,
+ FreeBreakfastClubProgramme = e.FreeBreakfastClubProgramme,
+ NurseryProvisionName = e.NurseryProvisionName
};
}
}
diff --git a/SAPPub.Core/ServiceModels/EstablishmentServiceModel.cs b/SAPPub.Core/ServiceModels/EstablishmentServiceModel.cs
index 810108c87..4a426160b 100644
--- a/SAPPub.Core/ServiceModels/EstablishmentServiceModel.cs
+++ b/SAPPub.Core/ServiceModels/EstablishmentServiceModel.cs
@@ -111,6 +111,12 @@ public class EstablishmentServiceModel
public string? KS2WraparoundCare { get; set; } = string.Empty;
+ public bool FreeBreakfastClubProgramme { get; set; }
+
+ public string? NurseryProvisionName { get; set; } = string.Empty;
+
+ public bool HasNurseryProvision => NurseryProvisionName == "Has Nursery Classes";
+
public bool IsKS2 { get; set; }
public bool IsKS4 { get; set; }
@@ -130,6 +136,7 @@ TypeOfEstablishment.FreeSchoolsSpecial or
TypeOfEstablishment.OtherIndependentSchool or
TypeOfEstablishment.OtherIndependentSpecialSchool;
+
public EstablishmentPerformance KS4Performance { get; set; } = new();
public LAPerformance LAPerformance { get; set; } = new();
diff --git a/SAPPub.Core/ServiceModels/KS4/AboutSchool/AboutSchoolModel.cs b/SAPPub.Core/ServiceModels/KS4/AboutSchool/AboutSchoolModel.cs
index 2ca099950..11fd8a994 100644
--- a/SAPPub.Core/ServiceModels/KS4/AboutSchool/AboutSchoolModel.cs
+++ b/SAPPub.Core/ServiceModels/KS4/AboutSchool/AboutSchoolModel.cs
@@ -56,6 +56,12 @@ public class AboutSchoolModel
public string? SenTypes { get; set; }
+ public string? KS2WraparoundCare { get; set; }
+
+ public bool FreeBreakfastClubProgramme { get; set; }
+
+ public bool HasNurseryProvision { get; set; }
+
public bool IsKS2 { get; set; }
public bool IsKS4 { get; set; }
diff --git a/SAPPub.Core/Services/KS4/AboutSchool/AboutSchoolService.cs b/SAPPub.Core/Services/KS4/AboutSchool/AboutSchoolService.cs
index 9072eda69..ed18d7f9b 100644
--- a/SAPPub.Core/Services/KS4/AboutSchool/AboutSchoolService.cs
+++ b/SAPPub.Core/Services/KS4/AboutSchool/AboutSchoolService.cs
@@ -80,6 +80,9 @@ public async Task GetAboutSchoolDetailsAsync(string urn, Cance
SenTypes = establishment.SenTypes,
Predecessors = predecessorLinks,
Successors = sucessorLinks,
+ KS2WraparoundCare = establishment.KS2WraparoundCare,
+ FreeBreakfastClubProgramme = establishment.FreeBreakfastClubProgramme,
+ HasNurseryProvision = establishment.HasNurseryProvision,
IsKS2 = establishment.IsKS2,
IsKS4 = establishment.IsKS4,
IsKS5 = establishment.IsKS5
diff --git a/SAPPub.Infrastructure/Repositories/Helpers/DapperHelpers.cs b/SAPPub.Infrastructure/Repositories/Helpers/DapperHelpers.cs
index dfe6ac66d..287ff96b1 100644
--- a/SAPPub.Infrastructure/Repositories/Helpers/DapperHelpers.cs
+++ b/SAPPub.Infrastructure/Repositories/Helpers/DapperHelpers.cs
@@ -68,7 +68,9 @@ public static class DapperHelpers
"ISKS2",
"ISKS4",
"ISKS5",
- "KS2WraparoundCare"
+ "KS2WraparoundCare",
+ "FreeBreakfastClubProgramme",
+ "NurseryProvisionName"
""";
private const string EstablishmentAbsenceColumns = """
diff --git a/SAPPub.Web/Areas/Profiles/Controllers/AdmissionsController.cs b/SAPPub.Web/Areas/Profiles/Controllers/AdmissionsController.cs
index 7616790ef..0b1895846 100644
--- a/SAPPub.Web/Areas/Profiles/Controllers/AdmissionsController.cs
+++ b/SAPPub.Web/Areas/Profiles/Controllers/AdmissionsController.cs
@@ -47,7 +47,7 @@ public async Task KS2(
CancellationToken ct)
{
var admissionsDetails = await admissionsService.GetAdmissionsDetailsAsync(urn, ct);
- var model = AdmissionsViewModel.MapFrom(admissionsDetails, urn, true);
+ var model = AdmissionsViewModel.MapFrom(admissionsDetails, urn);
return View(model);
}
@@ -60,8 +60,7 @@ public async Task KS4(
CancellationToken ct)
{
var admissionsDetails = await admissionsService.GetAdmissionsDetailsAsync(urn, ct);
- var isPrimaryFeatureEnabled = await featureManager.IsEnabledAsync(Constants.Constants.EnablePrimary);
- var model = AdmissionsViewModel.MapFrom(admissionsDetails, urn, isPrimaryFeatureEnabled);
+ var model = AdmissionsViewModel.MapFrom(admissionsDetails, urn);
return View(model);
}
}
diff --git a/SAPPub.Web/Areas/Profiles/Controllers/CurriculumController.cs b/SAPPub.Web/Areas/Profiles/Controllers/CurriculumController.cs
index d558ac159..0a98b02c4 100644
--- a/SAPPub.Web/Areas/Profiles/Controllers/CurriculumController.cs
+++ b/SAPPub.Web/Areas/Profiles/Controllers/CurriculumController.cs
@@ -55,8 +55,7 @@ public async Task KS4(
string urn, string schoolName, CancellationToken ct)
{
var establishmentDetails = await establishmentService.GetEstablishmentAsync(urn, ct);
- var isPrimaryFeatureEnabled = await featureManager.IsEnabledAsync(Constants.Constants.EnablePrimary);
- var model = ViewModels.KS4.CurriculumAndExtraCurricularActivitiesViewModel.Map(establishmentDetails, isPrimaryFeatureEnabled);
+ var model = ViewModels.KS4.CurriculumAndExtraCurricularActivitiesViewModel.Map(establishmentDetails);
return View(model);
}
}
diff --git a/SAPPub.Web/Areas/Profiles/ViewModels/AboutSchool/AboutSchoolViewModel.cs b/SAPPub.Web/Areas/Profiles/ViewModels/AboutSchool/AboutSchoolViewModel.cs
index da371692d..d31a30719 100644
--- a/SAPPub.Web/Areas/Profiles/ViewModels/AboutSchool/AboutSchoolViewModel.cs
+++ b/SAPPub.Web/Areas/Profiles/ViewModels/AboutSchool/AboutSchoolViewModel.cs
@@ -13,7 +13,6 @@ public class AboutSchoolViewModel : ProfileBaseViewModel
private const string SENUnit = "SEN unit";
private const string ResourcedProvisionAndSENUnit = "Resourced provision and SEN unit";
private const string ResourcedProvisionText = "Resourced provision";
- private const int LocalAuthorityEstablishmentGroupTypeId = 4;
private const int AcademyOpenReasonId = 10;
public record School(string Name, double Lat, double Lon);
@@ -79,6 +78,11 @@ public record School(string Name, double Lat, double Lon);
public string? EducationPhase { get; set; }
+ public required DisplayField KS2WraparoundCare { get; set; }
+
+ public required DisplayField FreeBreakfastClubProgramme { get; set; }
+
+ public required DisplayField HasNurseryProvision { get; set; }
public static AboutSchoolViewModel Map(AboutSchoolModel schoolDetails)
{
@@ -117,6 +121,9 @@ public static AboutSchoolViewModel Map(AboutSchoolModel schoolDetails)
Predecessors = schoolDetails.Predecessors?.Select(p => SuccessorOrPredecessorDetailsModel.Map(p)).ToList(),
Successors = schoolDetails.Successors?.Select(s => SuccessorOrPredecessorDetailsModel.Map(s)).ToList(),
EducationPhase = EducationPhaseFormatter.Format(schoolDetails.IsKS2, schoolDetails.IsKS4, schoolDetails.IsKS5),
+ KS2WraparoundCare = schoolDetails.KS2WraparoundCare.ToDisplayField(),
+ FreeBreakfastClubProgramme = schoolDetails.FreeBreakfastClubProgramme.ToDisplayField(),
+ HasNurseryProvision = schoolDetails.HasNurseryProvision.ToDisplayField(),
IsKS2 = schoolDetails.IsKS2,
IsKS4 = schoolDetails.IsKS4,
IsKS5 = schoolDetails.IsKS5
diff --git a/SAPPub.Web/Areas/Profiles/ViewModels/Admissions/AdmissionsViewModel.cs b/SAPPub.Web/Areas/Profiles/ViewModels/Admissions/AdmissionsViewModel.cs
index 4ad303f57..096e05267 100644
--- a/SAPPub.Web/Areas/Profiles/ViewModels/Admissions/AdmissionsViewModel.cs
+++ b/SAPPub.Web/Areas/Profiles/ViewModels/Admissions/AdmissionsViewModel.cs
@@ -15,12 +15,9 @@ public class AdmissionsViewModel : BaseViewModel
public bool IsSchoolClosed { get; init; }
- public bool IsIndependentSchool { get; init; }
- public bool IsPrimaryFeatureEnabled { get; set; }
- // Computed property - show sub-navigation only when school has both KS2 & KS4 AND primary feature is enabled
- public bool ShowSubNavigation => IsKS2 && IsKS4 && IsPrimaryFeatureEnabled;
+ public bool IsIndependentSchool { get; init; }
- public static AdmissionsViewModel MapFrom(AdmissionsServiceModel serviceModel, string urn, bool isPrimaryFeatureEnabled)
+ public static AdmissionsViewModel MapFrom(AdmissionsServiceModel serviceModel, string urn)
{
return new AdmissionsViewModel
{
@@ -33,8 +30,7 @@ public static AdmissionsViewModel MapFrom(AdmissionsServiceModel serviceModel, s
IsIndependentSchool = serviceModel.IsIndependentSchool,
IsKS2 = serviceModel.IsKS2,
IsKS4 = serviceModel.IsKS4,
- IsKS5 = serviceModel.IsKS5,
- IsPrimaryFeatureEnabled = isPrimaryFeatureEnabled
+ IsKS5 = serviceModel.IsKS5
};
}
}
diff --git a/SAPPub.Web/Areas/Profiles/ViewModels/KS4/CurriculumAndExtraCurricularActivitiesViewModel.cs b/SAPPub.Web/Areas/Profiles/ViewModels/KS4/CurriculumAndExtraCurricularActivitiesViewModel.cs
index 121d9ec86..733b5a129 100644
--- a/SAPPub.Web/Areas/Profiles/ViewModels/KS4/CurriculumAndExtraCurricularActivitiesViewModel.cs
+++ b/SAPPub.Web/Areas/Profiles/ViewModels/KS4/CurriculumAndExtraCurricularActivitiesViewModel.cs
@@ -7,12 +7,8 @@ namespace SAPPub.Web.Areas.Profiles.ViewModels.KS4;
public class CurriculumAndExtraCurricularActivitiesViewModel : BaseViewModel
{
public required DisplayField SchoolWebsite { get; set; }
- public bool IsPrimaryFeatureEnabled { get; set; }
- // Computed property - show sub-navigation only when school has both KS2 & KS4 AND primary feature is enabled
- public bool ShowSubNavigation => IsKS2 && IsKS4 && IsPrimaryFeatureEnabled;
-
- public static CurriculumAndExtraCurricularActivitiesViewModel Map(EstablishmentServiceModel establishment, bool isPrimaryFeatureEnabled)
+ public static CurriculumAndExtraCurricularActivitiesViewModel Map(EstablishmentServiceModel establishment)
{
return new CurriculumAndExtraCurricularActivitiesViewModel
{
@@ -21,8 +17,7 @@ public static CurriculumAndExtraCurricularActivitiesViewModel Map(EstablishmentS
SchoolWebsite = establishment.Website.ToDisplayField(),
IsKS2 = establishment.IsKS2,
IsKS4 = establishment.IsKS4,
- IsKS5 = establishment.IsKS5,
- IsPrimaryFeatureEnabled = isPrimaryFeatureEnabled
+ IsKS5 = establishment.IsKS5
};
}
}
diff --git a/SAPPub.Web/Areas/Profiles/Views/About/AboutSchool.cshtml b/SAPPub.Web/Areas/Profiles/Views/About/AboutSchool.cshtml
index 3803b1380..a07a70522 100644
--- a/SAPPub.Web/Areas/Profiles/Views/About/AboutSchool.cshtml
+++ b/SAPPub.Web/Areas/Profiles/Views/About/AboutSchool.cshtml
@@ -362,8 +362,56 @@
+
+ @if (Model.IsKS2)
+ {
+ Primary school features
+
+
+ Nursery
+
+ @Model.HasNurseryProvision.DisplayText(formatter: value => value ? Yes : NotAvailable)
+
+
+
+ Free breakfast club programme
+
+ @Model.FreeBreakfastClubProgramme.DisplayText(formatter: value => value ? Yes : NotAvailable)
+
+
+
+ Wraparound care
+
+ @Model.KS2WraparoundCare.DisplayText(notAvailableText: NotRecorded)
+
+
+
+
+
+ What is wraparound care and the free breakfast club programme?
+
+
+ Wraparound care
+ Wraparound childcare is before and after school care for primary school aged children in England during term time delivered on or near the school site.
+
+ Wraparound care is different from out-of-school activities, or school clubs, which are less frequent and can be a one-off activity.
+
+ Contact the school for more information about what they provide.
-
+ Free breakfast club programme
+ The free breakfast club programme is a government-funded initiative being introduced in all state-funded schools with primary-aged children in England. Schools will join the programme in stages between 2026 and 2028.
+ These clubs are:
+
+ open to all pupils on roll at the school in reception to year 6
+ at least 30 minutes in duration, immediately before the start of each compulsory school day
+ free to access
+ offering a breakfast that adheres to the school food standards for England
+ on, or in the vicinity of, the school site
+
+
+
+ }
+
@if (Model.IsExclusivelyKS5)
{
diff --git a/SAPPub.Web/Areas/Profiles/Views/Admissions/KS2.cshtml b/SAPPub.Web/Areas/Profiles/Views/Admissions/KS2.cshtml
index 0ed042825..46b122f03 100644
--- a/SAPPub.Web/Areas/Profiles/Views/Admissions/KS2.cshtml
+++ b/SAPPub.Web/Areas/Profiles/Views/Admissions/KS2.cshtml
@@ -15,7 +15,7 @@
{
URN = Model.URN,
SchoolName = Model.SchoolName,
- ActivePage = RouteConstants.PrimaryAdmissions,
+ ActivePage = RouteConstants.AdmissionsRoot,
IsKS2 = Model.IsKS2,
IsKS4 = Model.IsKS4,
IsKS5 = Model.IsKS5
diff --git a/SAPPub.Web/Areas/Profiles/Views/Admissions/KS4.cshtml b/SAPPub.Web/Areas/Profiles/Views/Admissions/KS4.cshtml
index 9f6304839..5fa72e8f3 100644
--- a/SAPPub.Web/Areas/Profiles/Views/Admissions/KS4.cshtml
+++ b/SAPPub.Web/Areas/Profiles/Views/Admissions/KS4.cshtml
@@ -15,7 +15,7 @@
{
URN = Model.URN,
SchoolName = Model.SchoolName,
- ActivePage = RouteConstants.SecondaryAdmissions,
+ ActivePage = RouteConstants.AdmissionsRoot,
IsKS2 = Model.IsKS2,
IsKS4 = Model.IsKS4,
IsKS5 = Model.IsKS5
@@ -24,9 +24,10 @@
@Model.SchoolName
@ViewData["Header"]
- @if (Model.ShowSubNavigation)
+
+ @if (Model.IsKS2)
{
-
+
}
+
Moving from primary to secondary school
diff --git a/SAPPub.Web/Areas/Profiles/Views/Curriculum/KS2.cshtml b/SAPPub.Web/Areas/Profiles/Views/Curriculum/KS2.cshtml
index 9ee3935e1..8647371b7 100644
--- a/SAPPub.Web/Areas/Profiles/Views/Curriculum/KS2.cshtml
+++ b/SAPPub.Web/Areas/Profiles/Views/Curriculum/KS2.cshtml
@@ -15,7 +15,7 @@
{
URN = Model.URN,
SchoolName = Model.SchoolName,
- ActivePage = RouteConstants.PrimaryCurriculum,
+ ActivePage = RouteConstants.CurriculumRoot,
IsKS2 = Model.IsKS2,
IsKS4 = Model.IsKS4,
IsKS5 = Model.IsKS5
diff --git a/SAPPub.Web/Areas/Profiles/Views/Curriculum/KS4.cshtml b/SAPPub.Web/Areas/Profiles/Views/Curriculum/KS4.cshtml
index e05102d2a..43ae4bbaf 100644
--- a/SAPPub.Web/Areas/Profiles/Views/Curriculum/KS4.cshtml
+++ b/SAPPub.Web/Areas/Profiles/Views/Curriculum/KS4.cshtml
@@ -15,7 +15,7 @@
{
URN = Model.URN,
SchoolName = Model.SchoolName,
- ActivePage = RouteConstants.SecondaryCurriculumAndExtraCurricularActivities,
+ ActivePage = RouteConstants.CurriculumRoot,
IsKS2 = Model.IsKS2,
IsKS4 = Model.IsKS4,
IsKS5 = Model.IsKS5
@@ -24,7 +24,8 @@
@Model.SchoolName
@ViewData["Header"]
- @if (Model.ShowSubNavigation)
+
+ @if (Model.IsKS2)
{
}
+
Curriculum
diff --git a/SAPPub.Web/Helpers/DisplayField.cs b/SAPPub.Web/Helpers/DisplayField.cs
index 49d307f0b..a00da30ab 100644
--- a/SAPPub.Web/Helpers/DisplayField.cs
+++ b/SAPPub.Web/Helpers/DisplayField.cs
@@ -49,4 +49,15 @@ private static string FormatValue(
_ => formatter?.Invoke(value) ?? value?.ToString() ?? string.Empty
};
}
+
+ public string DisplayBool(string trueText = "Yes", string falseText = "Not available")
+ {
+ return Status switch
+ {
+ FieldStatus.Available when Value is bool boolValue => boolValue ? trueText : falseText,
+ FieldStatus.Available => falseText,
+ FieldStatus.NotAvailable => falseText,
+ _ => falseText
+ };
+ }
}
diff --git a/SAPPub.Web/ViewComponents/VerticalNavigation/Default.cshtml b/SAPPub.Web/ViewComponents/VerticalNavigation/Default.cshtml
index c42155d85..ab2886629 100644
--- a/SAPPub.Web/ViewComponents/VerticalNavigation/Default.cshtml
+++ b/SAPPub.Web/ViewComponents/VerticalNavigation/Default.cshtml
@@ -25,31 +25,19 @@
- @if (await FeatureManager.IsEnabledAsync(EnablePrimary) && Model.IsKS2)
+ @if ((await FeatureManager.IsEnabledAsync(EnablePrimary) && Model.IsKS2) || Model.IsKS4)
{
-
- Admissions
+
+ Admissions
- }
- else if (Model.IsKS4)
- {
-
- Admissions
-
- }
+ }
- @if (await FeatureManager.IsEnabledAsync(EnablePrimary) && Model.IsKS2)
+ @if ((await FeatureManager.IsEnabledAsync(EnablePrimary) && Model.IsKS2) || Model.IsKS4)
{
-
- Curriculum and extra-curricular activities
+
+ Curriculum and extra-curricular activities
- }
- else if (Model.IsKS4)
- {
-
- Curriculum and extra-curricular activities
-
- }
+ }
@if (await FeatureManager.IsEnabledAsync(EnablePrimary) && Model.IsKS2 || Model.IsKS4)
{
diff --git a/Tests/SAPPub.Core.Tests/ServiceModels/EstablishmentServiceModelTests.cs b/Tests/SAPPub.Core.Tests/ServiceModels/EstablishmentServiceModelTests.cs
new file mode 100644
index 000000000..ba296b2ac
--- /dev/null
+++ b/Tests/SAPPub.Core.Tests/ServiceModels/EstablishmentServiceModelTests.cs
@@ -0,0 +1,19 @@
+using SAPPub.Core.ServiceModels;
+
+namespace SAPPub.Core.Tests.ServiceModels;
+
+public class EstablishmentServiceModelTests
+{
+ [Theory]
+ [InlineData("Has Nursery Classes", true)]
+ [InlineData("No Nursery Classes", false)]
+ [InlineData("Not Applicable", false)]
+ [InlineData("", false)]
+ [InlineData(null, false)]
+ public void HasNurseryProvision_ReturnsExpected(string? nurseryProvisionName, bool expected)
+ {
+ var model = new EstablishmentServiceModel { NurseryProvisionName = nurseryProvisionName };
+
+ Assert.Equal(expected, model.HasNurseryProvision);
+ }
+}
\ No newline at end of file
diff --git a/Tests/SAPPub.Core.Tests/Services/KS4/AboutSchool/AboutSchoolServiceTests.cs b/Tests/SAPPub.Core.Tests/Services/KS4/AboutSchool/AboutSchoolServiceTests.cs
index 0b1f0be76..64dc373e7 100644
--- a/Tests/SAPPub.Core.Tests/Services/KS4/AboutSchool/AboutSchoolServiceTests.cs
+++ b/Tests/SAPPub.Core.Tests/Services/KS4/AboutSchool/AboutSchoolServiceTests.cs
@@ -44,7 +44,13 @@ public class AboutSchoolServiceTests
OfficialSixthFormId = "No",
ResourcedProvisionName = "Resourced provision",
EstablishmentTypeGroup = EstablishmentTypeGroup.LocalAuthorityMaintainedSchools,
- SenTypes = "SLCN - Speech, language and Communication, ASD - Autistic Spectrum Disorder, SEMH - Social"
+ SenTypes = "SLCN - Speech, language and Communication, ASD - Autistic Spectrum Disorder, SEMH - Social",
+ NurseryProvisionName = "Has Nursery Classes",
+ KS2WraparoundCare = "Wraparound care",
+ FreeBreakfastClubProgramme = true,
+ IsKS2 = true,
+ IsKS4 = true,
+ IsKS5 = false
};
private readonly List
fakeEstablishments =
@@ -137,6 +143,12 @@ public async Task GetAboutSchoolDetailsAsync_ShouldReturnData()
Assert.Equal(fakeEstablishment.ResourcedProvisionName, result.ResourcedProvisionName);
Assert.Equal(fakeEstablishment.EstablishmentTypeGroup, result.EstablishmentTypeGroup);
Assert.Equal(fakeEstablishment.SenTypes, result.SenTypes);
+ Assert.Equal(fakeEstablishment.HasNurseryProvision, result.HasNurseryProvision);
+ Assert.Equal(fakeEstablishment.FreeBreakfastClubProgramme, result.FreeBreakfastClubProgramme);
+ Assert.Equal(fakeEstablishment.KS2WraparoundCare, result.KS2WraparoundCare);
+ Assert.Equal(fakeEstablishment.IsKS2, result.IsKS2);
+ Assert.Equal(fakeEstablishment.IsKS4, result.IsKS4);
+ Assert.Equal(fakeEstablishment.IsKS5, result.IsKS5);
}
[Theory]
diff --git a/Tests/SAPPub.Core.Tests/Services/Search/SchoolSearchServiceTests.cs b/Tests/SAPPub.Core.Tests/Services/Search/SchoolSearchServiceTests.cs
index 235357aea..0ce4e37f6 100644
--- a/Tests/SAPPub.Core.Tests/Services/Search/SchoolSearchServiceTests.cs
+++ b/Tests/SAPPub.Core.Tests/Services/Search/SchoolSearchServiceTests.cs
@@ -73,7 +73,7 @@ public async Task SearchAsync_ByName_ReturnsExpectedServiceModel()
var schoolSearchResults = ToSchoolSearchResults(establishments);
_mockSchoolSearchIndexReader
- .Setup(s => s.SearchAsync(It.IsAny(), Constants.PageSize))
+ .Setup(s => s.SearchAsync(It.IsAny(), Constants.PageSize))
.ReturnsAsync(schoolSearchResults);
var service = new SchoolSearchService(_mockSchoolSearchIndexReader.Object, _mockPostcodeLookupService.Object);
@@ -243,7 +243,7 @@ public async Task SearchAsync_ResultsFieldsNull_ReturnsExpectedServiceModel()
var schoolSearchResults = ToSchoolSearchResults(establishments);
_mockSchoolSearchIndexReader
- .Setup(s => s.SearchAsync(It.IsAny(), Constants.PageSize))
+ .Setup(s => s.SearchAsync(It.IsAny(), Constants.PageSize))
.ReturnsAsync(schoolSearchResults);
var service = new SchoolSearchService(_mockSchoolSearchIndexReader.Object, _mockPostcodeLookupService.Object);
diff --git a/Tests/SAPPub.Web.Tests/UI/Areas/KS2/AdmissionsTests.cs b/Tests/SAPPub.Web.Tests/UI/Areas/KS2/AdmissionsTests.cs
index 6d9722a70..dd6a69888 100644
--- a/Tests/SAPPub.Web.Tests/UI/Areas/KS2/AdmissionsTests.cs
+++ b/Tests/SAPPub.Web.Tests/UI/Areas/KS2/AdmissionsTests.cs
@@ -78,6 +78,6 @@ public async Task AdmissionsPage_Displays_VerticalNavigation(string schoolUrn, i
await nav.ShouldBeVisibleAsync();
await nav.ShouldHaveItemsCountAsync(expectedItemCount);
await nav.ShouldHaveOneActiveItemAsync();
- await nav.ShouldHaveActiveHrefAsync(_schoolUrnToUrlMap[schoolUrn]);
+ await nav.ShouldHaveActiveHrefAsync(_schoolUrnToUrlMap[schoolUrn].Replace("/primary", ""));
}
}
diff --git a/Tests/SAPPub.Web.Tests/UI/Areas/KS2/CurriculumAndExtraCurricularActivitiesTests.cs b/Tests/SAPPub.Web.Tests/UI/Areas/KS2/CurriculumAndExtraCurricularActivitiesTests.cs
index 8e3f124be..a73fb265f 100644
--- a/Tests/SAPPub.Web.Tests/UI/Areas/KS2/CurriculumAndExtraCurricularActivitiesTests.cs
+++ b/Tests/SAPPub.Web.Tests/UI/Areas/KS2/CurriculumAndExtraCurricularActivitiesTests.cs
@@ -6,7 +6,6 @@ namespace SAPPub.Web.Tests.UI.Areas.KS2;
[Collection("Playwright Tests")]
public class CurriculumAndExtraCurricularActivitiesTests(WebApplicationSetupFixture fixture) : BasePageTest(fixture)
{
- private string _pageUrl = "school/143034/st-pauls-church-of-england-academy/curriculum/primary";
private Dictionary _schoolUrnToUrlMap = new Dictionary
{
@@ -78,7 +77,7 @@ public async Task CurriculumAndExtraCurricularActivitiesPage_Displays_VerticalNa
await nav.ShouldBeVisibleAsync();
await nav.ShouldHaveOneActiveItemAsync();
- await nav.ShouldHaveActiveHrefAsync(_pageUrl);
+ await nav.ShouldHaveActiveHrefAsync(_schoolUrnToUrlMap["143034"].Replace("/primary", ""));
}
}
diff --git a/Tests/SAPPub.Web.Tests/UI/KS4/AdmissionsTests.cs b/Tests/SAPPub.Web.Tests/UI/KS4/AdmissionsTests.cs
index 5bb59c51f..694225c7b 100644
--- a/Tests/SAPPub.Web.Tests/UI/KS4/AdmissionsTests.cs
+++ b/Tests/SAPPub.Web.Tests/UI/KS4/AdmissionsTests.cs
@@ -6,7 +6,6 @@ namespace SAPPub.Web.Tests.UI.KS4;
[Collection("Playwright Tests")]
public class AdmissionsPageTests(WebApplicationSetupFixture fixture) : BasePageTest(fixture)
{
- private string _pageUrl = "school/105574/loreto-high-school-chorlton/admissions/secondary";
private Dictionary _schoolUrnToUrlMap = new Dictionary
{
@@ -79,7 +78,7 @@ public async Task AdmissionsPage_Displays_VerticalNavigation()
await nav.ShouldBeVisibleAsync();
await nav.ShouldHaveItemsCountAsync(6);
await nav.ShouldHaveOneActiveItemAsync();
- await nav.ShouldHaveActiveHrefAsync(_pageUrl);
+ await nav.ShouldHaveActiveHrefAsync(_schoolUrnToUrlMap["105574"].Replace("/secondary", ""));
}
[Fact]
@@ -224,7 +223,7 @@ public async Task AdmissionsPage_DoesNotDisplay_SubNavigation_WhenOnlyKS4()
await Page.GotoAsync(_schoolUrnToUrlMap["105574"]);
// Act
- var subNav = Page.Locator("#sub-navigation-academic-performance");
+ var subNav = Page.Locator("#sub-navigation-admissions");
var isVisible = await subNav.IsVisibleAsync();
// Assert
@@ -238,7 +237,7 @@ public async Task AdmissionsPage_Displays_SubNavigation_WhenMultiplePhases()
await Page.GotoAsync(_schoolUrnToUrlMap["150009"]);
// Act
- var subNav = Page.Locator("#sub-navigation-academic-performance");
+ var subNav = Page.Locator("#sub-navigation-admissions");
var isVisible = await subNav.IsVisibleAsync();
// Assert
@@ -252,8 +251,8 @@ public async Task AdmissionsPage_SubNavigation_HasCorrectLinks_WhenMultiplePhase
await Page.GotoAsync(_schoolUrnToUrlMap["150009"]);
// Act
- var primaryLink = Page.Locator("#sub-navigation-academic-performance a:not([aria-current='page'])");
- var secondaryLink = Page.Locator("#sub-navigation-academic-performance a[aria-current='page']");
+ var primaryLink = Page.Locator("#sub-navigation-admissions a:not([aria-current='page'])");
+ var secondaryLink = Page.Locator("#sub-navigation-admissions a[aria-current='page']");
var primaryLinkText = await primaryLink.TextContentAsync();
var secondaryLinkText = await secondaryLink.TextContentAsync();
diff --git a/Tests/SAPPub.Web.Tests/UI/KS4/CurriculumAndExtraCurricularActivitiesTests.cs b/Tests/SAPPub.Web.Tests/UI/KS4/CurriculumAndExtraCurricularActivitiesTests.cs
index 8fde92020..e17c5ca78 100644
--- a/Tests/SAPPub.Web.Tests/UI/KS4/CurriculumAndExtraCurricularActivitiesTests.cs
+++ b/Tests/SAPPub.Web.Tests/UI/KS4/CurriculumAndExtraCurricularActivitiesTests.cs
@@ -6,7 +6,6 @@ namespace SAPPub.Web.Tests.UI.KS4;
[Collection("Playwright Tests")]
public class CurriculumAndExtraCurricularActivitiesTests(WebApplicationSetupFixture fixture) : BasePageTest(fixture)
{
- private string _pageUrl = "school/105574/loreto-high-school-chorlton/curriculum/secondary";
private Dictionary _schoolUrnToUrlMap = new Dictionary
{
@@ -96,7 +95,7 @@ public async Task CurriculumAndExtraCurricularActivitiesPage_Displays_VerticalNa
await nav.ShouldBeVisibleAsync();
await nav.ShouldHaveOneActiveItemAsync();
- await nav.ShouldHaveActiveHrefAsync(_pageUrl);
+ await nav.ShouldHaveActiveHrefAsync(_schoolUrnToUrlMap["105574"].Replace("/secondary", ""));
}
[Fact]
diff --git a/Tests/SAPPub.Web.Tests/Unit/Areas/Profiles/Controllers/AboutControllerTests.cs b/Tests/SAPPub.Web.Tests/Unit/Areas/Profiles/Controllers/AboutControllerTests.cs
index 55f0d5859..4dacee13e 100644
--- a/Tests/SAPPub.Web.Tests/Unit/Areas/Profiles/Controllers/AboutControllerTests.cs
+++ b/Tests/SAPPub.Web.Tests/Unit/Areas/Profiles/Controllers/AboutControllerTests.cs
@@ -48,8 +48,12 @@ private AboutSchoolModel SchoolDetails()
ClosedDate = fakeEstablishment.ClosedDate.ToDateOnly(),
OpenReasonId = fakeEstablishment.OpenReasonId,
OpenDate = fakeEstablishment.OpenDate.ToDateOnly(),
+ KS2WraparoundCare = "Wraparound care",
+ FreeBreakfastClubProgramme = true,
+ HasNurseryProvision = true,
IsKS2 = true,
- IsKS4 = true
+ IsKS4 = true,
+ IsKS5 = false
};
}
@@ -99,7 +103,11 @@ public async Task Get_AboutSchool_Info_ReturnsExpected()
Assert.Equal(expectedResult.OpenReasonId, model.OpenReasonId);
Assert.Equal(expectedResult.SenTypes, model.SenTypes.Value);
Assert.Equal("Primary and Secondary", model.EducationPhase);
+ Assert.Equal(expectedResult.KS2WraparoundCare, model.KS2WraparoundCare.Value);
+ Assert.Equal(expectedResult.FreeBreakfastClubProgramme, model.FreeBreakfastClubProgramme.Value);
+ Assert.Equal(expectedResult.HasNurseryProvision, model.HasNurseryProvision.Value);
Assert.Equal(expectedResult.IsKS4, model.IsKS4);
+ Assert.Equal(expectedResult.IsKS5, model.IsKS5);
}
[Fact]
diff --git a/Tests/SAPPub.Web.Tests/Unit/Areas/Profiles/Controllers/AdmissionsControllerTests.cs b/Tests/SAPPub.Web.Tests/Unit/Areas/Profiles/Controllers/AdmissionsControllerTests.cs
index 64db2476f..9cb61fa82 100644
--- a/Tests/SAPPub.Web.Tests/Unit/Areas/Profiles/Controllers/AdmissionsControllerTests.cs
+++ b/Tests/SAPPub.Web.Tests/Unit/Areas/Profiles/Controllers/AdmissionsControllerTests.cs
@@ -205,51 +205,4 @@ public async Task Get_KS4_Info_IsSchoolClosed(EstablishmentStatus? statusCode, b
Assert.Equal(expectedResult, model.IsSchoolClosed);
}
- [Theory]
- [InlineData(true, true, true, true)] // Multi-phase school + feature enabled = show sub-nav
- [InlineData(true, true, false, false)] // Multi-phase school + feature disabled = no sub-nav
- [InlineData(false, true, true, false)] // KS4-only school + feature enabled = no sub-nav
- [InlineData(true, false, true, false)] // KS2-only school + feature enabled = no sub-nav
- public async Task KS4_ShowSubNavigation_DependsOnPhaseAndFeatureFlag(bool isKS2, bool isKS4, bool featureEnabled, bool expectedShowSubNav)
- {
- // Arrange
- _fakeEstablishment.IsKS2 = isKS2;
- _fakeEstablishment.IsKS4 = isKS4;
-
- var lASchoolAdmissionsUrl = "https://www.example.com/school-admissions";
- var laName = "Example Local Authority";
-
- _mockFeatureManager
- .Setup(f => f.IsEnabledAsync(Constants.Constants.EnablePrimary))
- .ReturnsAsync(featureEnabled);
-
- _mockAdmissionsService
- .Setup(s => s.GetAdmissionsDetailsAsync(_fakeEstablishment.URN, It.IsAny()))
- .ReturnsAsync(new AdmissionsServiceModel
- {
- SchoolName = _fakeEstablishment.EstablishmentName,
- SchoolWebsite = _fakeEstablishment.Website,
- LAName = laName,
- LASchoolAdmissionsUrl = lASchoolAdmissionsUrl,
- EstablishmentStatus = EstablishmentStatus.Open,
- IsKS2 = _fakeEstablishment.IsKS2,
- IsKS4 = _fakeEstablishment.IsKS4,
- IsKS5 = _fakeEstablishment.IsKS5,
- IsIndependentSchool = _fakeEstablishment.IsIndependentSchool
- });
-
- // Act
- var result = await _controller.KS4(
- _mockAdmissionsService.Object,
- _fakeEstablishment.URN,
- _fakeEstablishment.EstablishmentName,
- CancellationToken.None) as ViewResult;
-
- // Assert
- Assert.NotNull(result);
- var model = result.Model as AdmissionsViewModel;
- Assert.NotNull(model);
- Assert.Equal(expectedShowSubNav, model.ShowSubNavigation);
- Assert.Equal(featureEnabled, model.IsPrimaryFeatureEnabled);
- }
}
diff --git a/Tests/SAPPub.Web.Tests/Unit/Areas/Profiles/Controllers/CurriculumControllerTests.cs b/Tests/SAPPub.Web.Tests/Unit/Areas/Profiles/Controllers/CurriculumControllerTests.cs
index 7d6a9980b..a50209179 100644
--- a/Tests/SAPPub.Web.Tests/Unit/Areas/Profiles/Controllers/CurriculumControllerTests.cs
+++ b/Tests/SAPPub.Web.Tests/Unit/Areas/Profiles/Controllers/CurriculumControllerTests.cs
@@ -122,35 +122,4 @@ public async Task Get_KS4_Info_SchoolWebsite(string? website, FieldStatus fieldS
Assert.Equal("Not available", model.SchoolWebsite.DisplayText());
}
}
-
- [Theory]
- [InlineData(true, true, true, true)] // Multi-phase school + feature enabled = show sub-nav
- [InlineData(true, true, false, false)] // Multi-phase school + feature disabled = no sub-nav
- [InlineData(false, true, true, false)] // KS4-only school + feature enabled = no sub-nav
- [InlineData(true, false, true, false)] // KS2-only school + feature enabled = no sub-nav
- public async Task KS4_ShowSubNavigation_DependsOnPhaseAndFeatureFlag(bool isKS2, bool isKS4, bool featureEnabled, bool expectedShowSubNav)
- {
- // Arrange
- _fakeEstablishment.IsKS2 = isKS2;
- _fakeEstablishment.IsKS4 = isKS4;
-
- _mockFeatureManager
- .Setup(f => f.IsEnabledAsync(Constants.Constants.EnablePrimary))
- .ReturnsAsync(featureEnabled);
-
- // Act
- var result = await _controller.KS4(
- _mockEstablishmentService.Object,
- _fakeEstablishment.URN,
- _fakeEstablishment.EstablishmentName,
- CancellationToken.None) as ViewResult;
-
- // Assert
- Assert.NotNull(result);
- var model = result.Model as CurriculumAndExtraCurricularActivitiesViewModel;
- Assert.NotNull(model);
- Assert.Equal(expectedShowSubNav, model.ShowSubNavigation);
- Assert.Equal(featureEnabled, model.IsPrimaryFeatureEnabled);
- }
-
}
diff --git a/Tests/SAPPub.Web.Tests/Unit/Page/Areas/Profiles/AboutPageTests.cs b/Tests/SAPPub.Web.Tests/Unit/Page/Areas/Profiles/AboutPageTests.cs
index 14d15edad..805a3551e 100644
--- a/Tests/SAPPub.Web.Tests/Unit/Page/Areas/Profiles/AboutPageTests.cs
+++ b/Tests/SAPPub.Web.Tests/Unit/Page/Areas/Profiles/AboutPageTests.cs
@@ -1,4 +1,5 @@
-using Moq;
+using Microsoft.FeatureManagement;
+using Moq;
using SAPPub.Core.Enums;
using SAPPub.Core.Extensions;
using SAPPub.Core.Interfaces.Services;
@@ -380,4 +381,123 @@ public async Task AboutPage_ShowsKS5OnlyElements()
Assert.Equal("Key features", h2Elements[2].TextContent);
Assert.Equal("Policies", h2Elements[3].TextContent);
}
+
+ [Fact]
+ public async Task AboutPage_ShowsKS2OnlyElements()
+ {
+ // Arrange
+ var aboutSchoolModel = new AboutSchoolModel()
+ {
+ Urn = "143034",
+ SchoolName = "St David's Church of England Academy",
+ Address = "Some address",
+ LocalAuthority = "Bury",
+ IsKS4 = false,
+ IsKS5 = false,
+ IsKS2 = true,
+ HasNurseryProvision = true,
+ FreeBreakfastClubProgramme = true,
+ KS2WraparoundCare = "Wraparound care"
+ };
+ _about
+ .Setup(service => service.GetAboutSchoolDetailsAsync(
+ It.IsAny(),
+ It.IsAny()))
+ .ReturnsAsync(aboutSchoolModel);
+
+ // Act
+ var doc = await Fixture.BrowseToPage(BuildUrl(aboutSchoolModel.Urn, aboutSchoolModel.SchoolName, _pageRoute));
+
+ // Assert
+ var h3Elements = doc.GetElementsByTagName("h3");
+ Assert.Equal("Primary school features", h3Elements[0].TextContent);
+ Assert.Contains("Yes", doc.GetRowContentByIdAndKey("primary-school-features-summary", "Nursery"));
+ Assert.Contains("Yes", doc.GetRowContentByIdAndKey("primary-school-features-summary", "Free breakfast club programme"));
+ Assert.Contains("Wraparound care", doc.GetRowContentByIdAndKey("primary-school-features-summary", "Wraparound care"));
+ var primaryFeaturesDetails = doc.QuerySelector("#details-primary-features");
+ Assert.NotNull(primaryFeaturesDetails);
+ }
+
+ [Fact]
+ public async Task AboutPage_HidesPrimarySchoolFeatures_WhenNotKS2()
+ {
+ // Arrange
+ var aboutSchoolModel = new AboutSchoolModel()
+ {
+ Urn = "143034",
+ SchoolName = "St David's Church of England Academy",
+ IsKS2 = false,
+ IsKS4 = true,
+ HasNurseryProvision = true,
+ FreeBreakfastClubProgramme = true,
+ KS2WraparoundCare = "Wraparound care"
+ };
+ _about
+ .Setup(service => service.GetAboutSchoolDetailsAsync(
+ It.IsAny(),
+ It.IsAny()))
+ .ReturnsAsync(aboutSchoolModel);
+
+ // Act
+ var doc = await Fixture.BrowseToPage(BuildUrl(aboutSchoolModel.Urn, aboutSchoolModel.SchoolName, _pageRoute));
+
+ // Assert
+ Assert.Null(doc.GetElementById("primary-school-features-summary"));
+ }
+
+ [Fact]
+ public async Task AboutPage_ShowsPrimarySchoolFeatures_WithNotAvailableValues_WhenAllFalseOrEmpty()
+ {
+ // Arrange
+ var notAvailableContent = "Not available";
+ var notRecordedContent = "Not recorded";
+ var aboutSchoolModel = new AboutSchoolModel()
+ {
+ Urn = "143034",
+ SchoolName = "St David's Church of England Academy",
+ IsKS2 = true,
+ HasNurseryProvision = false,
+ FreeBreakfastClubProgramme = false,
+ KS2WraparoundCare = null
+ };
+ _about
+ .Setup(service => service.GetAboutSchoolDetailsAsync(
+ It.IsAny(),
+ It.IsAny()))
+ .ReturnsAsync(aboutSchoolModel);
+
+ // Act
+ var doc = await Fixture.BrowseToPage(BuildUrl(aboutSchoolModel.Urn, aboutSchoolModel.SchoolName, _pageRoute));
+
+ // Assert
+ Assert.Contains(notAvailableContent, doc.GetRowContentByIdAndKey("primary-school-features-summary", "Nursery"));
+ Assert.Contains(notAvailableContent, doc.GetRowContentByIdAndKey("primary-school-features-summary", "Free breakfast club programme"));
+ Assert.Contains(notRecordedContent, doc.GetRowContentByIdAndKey("primary-school-features-summary", "Wraparound care"));
+ }
+
+ [Fact]
+ public async Task AboutPage_HidesPrimarySchoolFeatures_WhenFeatureFlagDisabled()
+ {
+ // Arrange
+ var featureManagerMock = UseMock();
+ featureManagerMock
+ .Setup(f => f.IsEnabledAsync(Constants.Constants.EnablePrimary))
+ .ReturnsAsync(false);
+
+ var aboutSchoolModel = new AboutSchoolModel
+ {
+ Urn = "143034",
+ SchoolName = "St David's Church of England Academy",
+ IsKS2 = true
+ };
+ _about
+ .Setup(service => service.GetAboutSchoolDetailsAsync(It.IsAny(), It.IsAny()))
+ .ReturnsAsync(aboutSchoolModel);
+
+ // Act
+ var doc = await Fixture.BrowseToPage(BuildUrl(aboutSchoolModel.Urn, aboutSchoolModel.SchoolName, _pageRoute));
+
+ // Assert
+ Assert.Null(doc.GetElementById("primary-school-features-summary"));
+ }
}
diff --git a/Tests/SAPPub.Web.Tests/Unit/Page/AttendancePageTests.cs b/Tests/SAPPub.Web.Tests/Unit/Page/Areas/Profiles/AttendancePageTests.cs
similarity index 100%
rename from Tests/SAPPub.Web.Tests/Unit/Page/AttendancePageTests.cs
rename to Tests/SAPPub.Web.Tests/Unit/Page/Areas/Profiles/AttendancePageTests.cs
diff --git a/Tests/SAPPub.Web.Tests/Unit/Page/Areas/Profiles/KS2AdditionalMeasuresPageTests.cs b/Tests/SAPPub.Web.Tests/Unit/Page/Areas/Profiles/KS2/KS2AdditionalMeasuresPageTests.cs
similarity index 99%
rename from Tests/SAPPub.Web.Tests/Unit/Page/Areas/Profiles/KS2AdditionalMeasuresPageTests.cs
rename to Tests/SAPPub.Web.Tests/Unit/Page/Areas/Profiles/KS2/KS2AdditionalMeasuresPageTests.cs
index be75a1892..98482f520 100644
--- a/Tests/SAPPub.Web.Tests/Unit/Page/Areas/Profiles/KS2AdditionalMeasuresPageTests.cs
+++ b/Tests/SAPPub.Web.Tests/Unit/Page/Areas/Profiles/KS2/KS2AdditionalMeasuresPageTests.cs
@@ -8,8 +8,7 @@
using SAPPub.Core.ValueObjects;
using SAPPub.Web.Tests.Unit.Page.Infrastructure;
-
-namespace SAPPub.Web.Tests.Unit.Page.Areas.Profiles;
+namespace SAPPub.Web.Tests.Unit.Page.Areas.Profiles.KS2;
[Collection("WebAppCollection")]
public class KS2AdditionalMeasuresPageTests : PageTestsBase
diff --git a/Tests/SAPPub.Web.Tests/Unit/Page/Areas/Profiles/ScaledScoreAcademicPerformacePageTests.cs b/Tests/SAPPub.Web.Tests/Unit/Page/Areas/Profiles/KS2/ScaledScoreAcademicPerformacePageTests.cs
similarity index 100%
rename from Tests/SAPPub.Web.Tests/Unit/Page/Areas/Profiles/ScaledScoreAcademicPerformacePageTests.cs
rename to Tests/SAPPub.Web.Tests/Unit/Page/Areas/Profiles/KS2/ScaledScoreAcademicPerformacePageTests.cs
diff --git a/Tests/SAPPub.Web.Tests/Unit/Page/Areas/Profiles/KS4/AdmissionsPageTests.cs b/Tests/SAPPub.Web.Tests/Unit/Page/Areas/Profiles/KS4/AdmissionsPageTests.cs
new file mode 100644
index 000000000..5bbe004d6
--- /dev/null
+++ b/Tests/SAPPub.Web.Tests/Unit/Page/Areas/Profiles/KS4/AdmissionsPageTests.cs
@@ -0,0 +1,231 @@
+using Microsoft.FeatureManagement;
+using Moq;
+using SAPPub.Core.Enums;
+using SAPPub.Core.Interfaces.Services;
+using SAPPub.Core.Interfaces.Services.KS4.Admissions;
+using SAPPub.Core.ServiceModels;
+using SAPPub.Core.ServiceModels.KS4.Admissions;
+using SAPPub.Core.Tests.TestBuilders;
+using SAPPub.Web.Tests.Unit.Page.Infrastructure;
+
+namespace SAPPub.Web.Tests.Unit.Page.Areas.Profiles.KS4;
+
+[Collection("WebAppCollection")]
+public class AdmissionsPageTests : PageTestsBase
+{
+ private string _pageRoute = "/admissions/secondary";
+ private string _urn = "143034";
+ private string _schoolName = "St Paul's Church of England Academy";
+ private string _schoolNameMultiPhase = "Abraham Moss Community School";
+ private string _urnMultiPhase = "150009";
+ private readonly EstablishmentServiceModel _establishment = new();
+ private readonly Mock _mockEstablishmentService;
+
+ private readonly AdmissionsServiceModel _admissionsServiceModel;
+ private readonly Mock _mockAdmissionsService;
+
+
+ public AdmissionsPageTests(WebAppFixture fixture) : base(fixture)
+ {
+ _mockEstablishmentService = UseMock();
+ _mockAdmissionsService = UseMock();
+
+ _establishment = new EstablishmentTestBuilder()
+ .WithURN(_urn)
+ .WithEstablishmentName(_schoolName)
+ .WithIsKeyStage2(false)
+ .WithIsKeyStage4(true)
+ .WithWebsite("https://www.stpaulsacademy.co.uk")
+ .WithEstablishmentTypeGroupId((int)EstablishmentTypeGroup.Academies)
+ .BuildServiceModel();
+
+ _mockEstablishmentService
+ .Setup(a => a.GetEstablishmentAsync(_urn, It.IsAny()))
+ .ReturnsAsync(_establishment);
+
+ _admissionsServiceModel = GetAdmissionsServiceModel(_schoolName, isKs2: false, isKs4: true, _establishment.Website);
+
+ _mockAdmissionsService
+ .Setup(s => s.GetAdmissionsDetailsAsync(_urn, It.IsAny()))
+ .ReturnsAsync(_admissionsServiceModel);
+ }
+
+ [Fact]
+ public async Task AdmissionsPage_HasCorrectTitle()
+ {
+ // Arrange
+ var url = BuildUrl(_urn, _schoolName, _pageRoute);
+
+ // Act
+ var doc = await Fixture.BrowseToPage(url);
+
+ // Assert
+ var title = doc.QuerySelector("title");
+ Assert.NotNull(title);
+ Assert.Contains("Secondary Admissions", title.TextContent.Trim());
+ }
+
+ [Fact]
+ public async Task AdmissionsPage_DisplaysMainHeading()
+ {
+ // Arrange
+ var url = BuildUrl(_urn, _schoolName, _pageRoute);
+
+ // Act
+ var doc = await Fixture.BrowseToPage(url);
+
+ // Assert
+ var heading = doc.QuerySelector("h1");
+ Assert.NotNull(heading);
+ Assert.NotEmpty(heading.TextContent.Trim());
+ }
+
+ [Theory]
+ [InlineData("143034", "St Paul's Church of England Academy", 6)]
+ [InlineData("150009", "Abraham Moss Community School", 7)]
+ public async Task AdmissionsPage_Displays_VerticalNavigation(string urn, string schoolName, int expectedItemCount)
+ {
+ // Arrange
+ if (urn == _urnMultiPhase)
+ {
+ ConfigureMultiPhaseSchool();
+ }
+
+ var url = BuildUrl(urn, schoolName, _pageRoute);
+
+ // Act
+ var doc = await Fixture.BrowseToPage(url);
+
+ // Assert
+ Assert.NotNull(doc.QuerySelector(".moj-side-navigation"));
+ Assert.Equal(expectedItemCount, doc.QuerySelectorAll(".moj-side-navigation__item").Length);
+ Assert.Single(doc.QuerySelectorAll(".moj-side-navigation__item--active"));
+ }
+
+ [Fact]
+ public async Task AdmissionsPage_Displays_SchoolName_Caption()
+ {
+ // Arrange
+ var url = BuildUrl(_urn, _schoolName, _pageRoute);
+
+ // Act
+ var doc = await Fixture.BrowseToPage(url);
+
+ // Assert
+ var schoolNameCaption = doc.QuerySelector("#school-name-caption");
+ Assert.NotNull(schoolNameCaption);
+ Assert.Equal(_schoolName, schoolNameCaption.TextContent.Trim());
+ }
+
+ [Fact]
+ public async Task AdmissionsPage_DoesNotDisplay_SubNavigation_WhenOnlyKS4()
+ {
+ // Arrange
+ var url = BuildUrl(_urn, _schoolName, _pageRoute);
+
+ // Act
+ var doc = await Fixture.BrowseToPage(url);
+
+ // Assert
+ var subNav = doc.QuerySelector("#sub-navigation-admissions");
+ Assert.Null(subNav);
+ }
+
+ [Fact]
+ public async Task AdmissionsPage_Displays_SubNavigation_WhenMultiplePhases()
+ {
+ // Arrange
+ ConfigureMultiPhaseSchool();
+ var url = BuildUrl(_urnMultiPhase, _schoolNameMultiPhase, _pageRoute);
+
+ // Act
+ var doc = await Fixture.BrowseToPage(url);
+
+ // Assert
+ var subNav = doc.QuerySelector("#sub-navigation-admissions");
+ Assert.NotNull(subNav);
+ }
+
+ [Fact]
+ public async Task AdmissionsPage_SubNavigation_HasCorrectLinks_WhenMultiplePhases()
+ {
+ // Arrange
+ ConfigureMultiPhaseSchool();
+ var url = BuildUrl(_urnMultiPhase, _schoolNameMultiPhase, _pageRoute);
+
+ // Act
+ var doc = await Fixture.BrowseToPage(url);
+
+ // Assert
+ var subNav = doc.QuerySelector("#sub-navigation-admissions");
+ Assert.NotNull(subNav);
+
+ var secondaryLink = subNav.QuerySelector("a[aria-current='page']");
+ var primaryLink = subNav.QuerySelector("a:not([aria-current='page'])");
+
+ Assert.NotNull(primaryLink);
+ Assert.NotNull(secondaryLink);
+ Assert.Contains("Primary Admissions", primaryLink.TextContent.Trim());
+ Assert.Contains("Secondary Admissions", secondaryLink.TextContent.Trim());
+ }
+
+ [Fact]
+ public async Task AdmissionsPage_DoesNotDisplay_SubNavigation_WhenFeatureFlagDisabled()
+ {
+ // Arrange
+ var featureManagerMock = UseMock();
+ featureManagerMock
+ .Setup(f => f.IsEnabledAsync(Constants.Constants.EnablePrimary))
+ .ReturnsAsync(false);
+
+ ConfigureMultiPhaseSchool();
+ var url = BuildUrl(_urnMultiPhase, _schoolNameMultiPhase, _pageRoute);
+
+ // Act
+ var doc = await Fixture.BrowseToPage(url);
+
+ // Assert
+ var subNav = doc.QuerySelector("#sub-navigation-admissions");
+ Assert.Null(subNav);
+ }
+
+
+ private void ConfigureMultiPhaseSchool()
+ {
+ var multiPhaseEstablishment = new EstablishmentTestBuilder()
+ .WithURN(_urnMultiPhase)
+ .WithEstablishmentName(_schoolNameMultiPhase)
+ .WithIsKeyStage2(true)
+ .WithIsKeyStage4(true)
+ .BuildServiceModel();
+
+ _mockEstablishmentService
+ .Setup(a => a.GetEstablishmentAsync(_urnMultiPhase, It.IsAny()))
+ .ReturnsAsync(multiPhaseEstablishment);
+
+ _mockAdmissionsService
+ .Setup(s => s.GetAdmissionsDetailsAsync(_urnMultiPhase, It.IsAny()))
+ .ReturnsAsync(GetAdmissionsServiceModel(_schoolNameMultiPhase, isKs2: true, isKs4: true, multiPhaseEstablishment.Website));
+ }
+
+ private AdmissionsServiceModel GetAdmissionsServiceModel(
+ string schoolName,
+ bool isKs2,
+ bool isKs4,
+ string? schoolWebsite,
+ bool isIndependentSchool = false)
+ {
+ return new AdmissionsServiceModel
+ {
+ SchoolName = schoolName,
+ IsKS2 = isKs2,
+ IsKS4 = isKs4,
+ IsKS5 = false,
+ LAName = "Test LA",
+ EstablishmentStatus = EstablishmentStatus.Open,
+ IsIndependentSchool = isIndependentSchool,
+ SchoolWebsite = schoolWebsite,
+ LASchoolAdmissionsUrl = "https://www.testla.gov.uk/admissions"
+ };
+ }
+}
diff --git a/Tests/SAPPub.Web.Tests/Unit/Page/Areas/Profiles/KS4/CurriculumAndExtraCurricularActivitiesPageTests.cs b/Tests/SAPPub.Web.Tests/Unit/Page/Areas/Profiles/KS4/CurriculumAndExtraCurricularActivitiesPageTests.cs
new file mode 100644
index 000000000..3d9bdfb5f
--- /dev/null
+++ b/Tests/SAPPub.Web.Tests/Unit/Page/Areas/Profiles/KS4/CurriculumAndExtraCurricularActivitiesPageTests.cs
@@ -0,0 +1,213 @@
+using AngleSharp.Dom;
+using Microsoft.FeatureManagement;
+using Moq;
+using SAPPub.Core.Interfaces.Services;
+using SAPPub.Core.ServiceModels;
+using SAPPub.Core.Tests.TestBuilders;
+using SAPPub.Web.Tests.Unit.Page.Infrastructure;
+
+namespace SAPPub.Web.Tests.Unit.Page.Areas.Profiles.KS4;
+
+[Collection("WebAppCollection")]
+public class CurriculumAndExtraCurricularActivitiesPageTests : PageTestsBase
+{
+ private string _pageRoute = "/curriculum/secondary";
+ private string _urn = "143034";
+ private string _schoolName = "St Paul's Church of England Academy";
+ private string _schoolNameMultiPhase = "Abraham Moss Community School";
+ private string _urnMultiPhase = "150009";
+ private readonly EstablishmentServiceModel _establishment = new();
+ private readonly Mock _mockEstablishmentService;
+
+ public CurriculumAndExtraCurricularActivitiesPageTests(WebAppFixture fixture) : base(fixture)
+ {
+ _mockEstablishmentService = UseMock();
+
+ _establishment = new EstablishmentTestBuilder()
+ .WithURN(_urn)
+ .WithEstablishmentName(_schoolName)
+ .WithIsKeyStage2(false)
+ .WithIsKeyStage4(true)
+ .BuildServiceModel();
+
+ _mockEstablishmentService
+ .Setup(a => a.GetEstablishmentAsync(_urn, It.IsAny()))
+ .ReturnsAsync(_establishment);
+ }
+
+ [Fact]
+ public async Task CurriculumAndExtraCurricularActivitiesPage_HasCorrectTitle()
+ {
+ // Arrange
+ var url = BuildUrl(_urn, _schoolName, _pageRoute);
+
+ // Act
+ var doc = await Fixture.BrowseToPage(url);
+
+ // Assert
+ var title = doc.QuerySelector("title");
+ Assert.NotNull(title);
+ Assert.Contains("Secondary Curriculum", title.TextContent.Trim());
+ }
+
+ [Fact]
+ public async Task CurriculumAndExtraCurricularActivitiesPage_DisplaysMainHeading()
+ {
+ // Arrange
+ var url = BuildUrl(_urn, _schoolName, _pageRoute);
+
+ // Act
+ var doc = await Fixture.BrowseToPage(url);
+
+ // Assert
+ var heading = doc.QuerySelector("h1");
+ Assert.NotNull(heading);
+ Assert.NotEmpty(heading.TextContent.Trim());
+ }
+
+ [Theory]
+ [InlineData(true, true, 7)] // Multi-phase school (KS2 and KS4)
+ [InlineData(true, false, 6)] // ks4 only school
+ public async Task CurriculumAndExtraCurricularActivitiesPage_Displays_VerticalNavigation(bool isKs4, bool isKs2, int expectedItemCount)
+ {
+ var establishment = new EstablishmentTestBuilder()
+ .WithURN(_urnMultiPhase)
+ .WithEstablishmentName(_schoolNameMultiPhase)
+ .WithIsKeyStage2(isKs2)
+ .WithIsKeyStage4(isKs4)
+ .BuildServiceModel();
+
+ _mockEstablishmentService
+ .Setup(a => a.GetEstablishmentAsync(_urnMultiPhase, It.IsAny()))
+ .ReturnsAsync(establishment);
+
+ var url = BuildUrl(_urnMultiPhase, _schoolNameMultiPhase, _pageRoute);
+
+ // Act
+ var doc = await Fixture.BrowseToPage(url);
+
+ // Assert
+ Assert.NotNull(doc.QuerySelector(".moj-side-navigation"));
+ var list = doc.QuerySelectorAll(".moj-side-navigation__item");
+ Assert.Equal(expectedItemCount, doc.QuerySelectorAll(".moj-side-navigation__item").Length);
+ Assert.Single(doc.QuerySelectorAll(".moj-side-navigation__item--active"));
+ }
+
+ [Fact]
+ public async Task CurriculumAndExtraCurricularActivitiesPage_Displays_SchoolName_Caption()
+ {
+ // Arrange
+ var url = BuildUrl(_urn, _schoolName, _pageRoute);
+
+ // Act
+ var doc = await Fixture.BrowseToPage(url);
+
+ // Assert
+ var schoolNameCaption = doc.QuerySelector("#school-name-caption");
+ Assert.NotNull(schoolNameCaption);
+ Assert.Equal(_schoolName, schoolNameCaption.TextContent.Trim());
+ }
+
+ [Fact]
+ public async Task CurriculumPage_DoesNotDisplay_SubNavigation_WhenOnlyKS4()
+ {
+ // Arrange
+ var url = BuildUrl(_urn, _schoolName, _pageRoute);
+
+ // Act
+ var doc = await Fixture.BrowseToPage(url);
+
+ // Assert
+ var subNav = doc.QuerySelector("#sub-navigation-academic-performance");
+ Assert.Null(subNav);
+ }
+
+ [Fact]
+ public async Task CurriculumPage_Displays_SubNavigation_WhenMultiplePhases()
+ {
+ // Arrange
+ var multiPhaseEstablishment = new EstablishmentTestBuilder()
+ .WithURN(_urnMultiPhase)
+ .WithEstablishmentName(_schoolNameMultiPhase)
+ .WithIsKeyStage2(true)
+ .WithIsKeyStage4(true)
+ .BuildServiceModel();
+
+ _mockEstablishmentService
+ .Setup(a => a.GetEstablishmentAsync(_urnMultiPhase, It.IsAny()))
+ .ReturnsAsync(multiPhaseEstablishment);
+
+ var url = BuildUrl(_urnMultiPhase, _schoolNameMultiPhase, _pageRoute);
+
+ // Act
+ var doc = await Fixture.BrowseToPage(url);
+
+ // Assert
+ var subNav = doc.QuerySelector("#sub-navigation-academic-performance");
+ Assert.NotNull(subNav);
+ }
+
+ [Fact]
+ public async Task AdmissionsPage_DoesNotDisplay_SubNavigation_WhenFeatureFlagDisabled()
+ {
+ // Arrange
+ var featureManagerMock = UseMock();
+ featureManagerMock
+ .Setup(f => f.IsEnabledAsync(Constants.Constants.EnablePrimary))
+ .ReturnsAsync(false);
+
+ var multiPhaseEstablishment = new EstablishmentTestBuilder()
+ .WithURN(_urnMultiPhase)
+ .WithEstablishmentName(_schoolNameMultiPhase)
+ .WithIsKeyStage2(true)
+ .WithIsKeyStage4(true)
+ .BuildServiceModel();
+
+ _mockEstablishmentService
+ .Setup(a => a.GetEstablishmentAsync(_urnMultiPhase, It.IsAny()))
+ .ReturnsAsync(multiPhaseEstablishment);
+
+ var url = BuildUrl(_urnMultiPhase, _schoolNameMultiPhase, _pageRoute);
+
+ // Act
+ var doc = await Fixture.BrowseToPage(url);
+
+ // Assert
+ var subNav = doc.QuerySelector("#sub-navigation-academic-performance");
+ Assert.Null(subNav);
+ }
+
+
+ [Fact]
+ public async Task CurriculumPage_SubNavigation_HasCorrectLinks_WhenMultiplePhases()
+ {
+ // Arrange
+ var multiPhaseEstablishment = new EstablishmentTestBuilder()
+ .WithURN(_urnMultiPhase)
+ .WithEstablishmentName(_schoolNameMultiPhase)
+ .WithIsKeyStage2(true)
+ .WithIsKeyStage4(true)
+ .BuildServiceModel();
+
+ _mockEstablishmentService
+ .Setup(a => a.GetEstablishmentAsync(_urnMultiPhase, It.IsAny()))
+ .ReturnsAsync(multiPhaseEstablishment);
+
+ var url = BuildUrl(_urnMultiPhase, _schoolNameMultiPhase, _pageRoute);
+
+ // Act
+ var doc = await Fixture.BrowseToPage(url);
+
+ // Assert
+ var subNav = doc.QuerySelector("#sub-navigation-academic-performance");
+ Assert.NotNull(subNav);
+
+ var secondaryLink = subNav.QuerySelector("a[aria-current='page']");
+ var primaryLink = subNav.QuerySelector("a:not([aria-current='page'])");
+
+ Assert.NotNull(primaryLink);
+ Assert.NotNull(secondaryLink);
+ Assert.Contains("Primary Curriculum", primaryLink.TextContent.Trim());
+ Assert.Contains("Secondary Curriculum", secondaryLink.TextContent.Trim());
+ }
+}
diff --git a/Tests/SAPPub.Web.Tests/Unit/Page/Areas/Profiles/EnglishMathsAcademicPerformancePageTests.cs b/Tests/SAPPub.Web.Tests/Unit/Page/Areas/Profiles/KS5/EnglishMathsAcademicPerformancePageTests.cs
similarity index 100%
rename from Tests/SAPPub.Web.Tests/Unit/Page/Areas/Profiles/EnglishMathsAcademicPerformancePageTests.cs
rename to Tests/SAPPub.Web.Tests/Unit/Page/Areas/Profiles/KS5/EnglishMathsAcademicPerformancePageTests.cs
diff --git a/Tests/SAPPub.Web.Tests/Unit/Page/Areas/Profiles/KS5DestinationsTests.cs b/Tests/SAPPub.Web.Tests/Unit/Page/Areas/Profiles/KS5/KS5DestinationsTests.cs
similarity index 98%
rename from Tests/SAPPub.Web.Tests/Unit/Page/Areas/Profiles/KS5DestinationsTests.cs
rename to Tests/SAPPub.Web.Tests/Unit/Page/Areas/Profiles/KS5/KS5DestinationsTests.cs
index 9bcba7a75..70dcb69c7 100644
--- a/Tests/SAPPub.Web.Tests/Unit/Page/Areas/Profiles/KS5DestinationsTests.cs
+++ b/Tests/SAPPub.Web.Tests/Unit/Page/Areas/Profiles/KS5/KS5DestinationsTests.cs
@@ -4,7 +4,7 @@
using SAPPub.Web.Tests.Unit.Page.Infrastructure;
using System.Text.Json;
-namespace SAPPub.Web.Tests.Unit.Page.Areas.Profiles;
+namespace SAPPub.Web.Tests.Unit.Page.Areas.Profiles.KS5;
[Collection("WebAppCollection")]
public class KS5DestinationsTests : PageTestsBase
diff --git a/Tests/SAPPub.Web.Tests/Unit/Page/Areas/Profiles/Level3QualificationsPageTests.cs b/Tests/SAPPub.Web.Tests/Unit/Page/Areas/Profiles/KS5/Level3QualificationsPageTests.cs
similarity index 99%
rename from Tests/SAPPub.Web.Tests/Unit/Page/Areas/Profiles/Level3QualificationsPageTests.cs
rename to Tests/SAPPub.Web.Tests/Unit/Page/Areas/Profiles/KS5/Level3QualificationsPageTests.cs
index f64a44022..71ff21501 100644
--- a/Tests/SAPPub.Web.Tests/Unit/Page/Areas/Profiles/Level3QualificationsPageTests.cs
+++ b/Tests/SAPPub.Web.Tests/Unit/Page/Areas/Profiles/KS5/Level3QualificationsPageTests.cs
@@ -9,7 +9,7 @@
using SAPPub.Web.Helpers;
using SAPPub.Web.Tests.Unit.Page.Infrastructure;
-namespace SAPPub.Web.Tests.Unit.Page.Areas.Profiles;
+namespace SAPPub.Web.Tests.Unit.Page.Areas.Profiles.KS5;
[Collection("WebAppCollection")]
public class Level3QualificationsPageTests : PageTestsBase
diff --git a/Tests/SAPPub.Web.Tests/Unit/Page/Infrastructure/CustomWebApplicationFactory.cs b/Tests/SAPPub.Web.Tests/Unit/Page/Infrastructure/CustomWebApplicationFactory.cs
index 7ae84aaa1..12a4d6122 100644
--- a/Tests/SAPPub.Web.Tests/Unit/Page/Infrastructure/CustomWebApplicationFactory.cs
+++ b/Tests/SAPPub.Web.Tests/Unit/Page/Infrastructure/CustomWebApplicationFactory.cs
@@ -3,6 +3,8 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Hosting;
+using Microsoft.FeatureManagement;
+using Moq;
using SAPPub.Core.Interfaces;
using SAPPub.Core.Interfaces.Repositories;
using SAPPub.Core.Interfaces.Services;
@@ -58,6 +60,8 @@ protected override void ConfigureWebHost(IWebHostBuilder builder)
services.RemoveAll(typeof(ILevel2QualificationsService));
services.RemoveAll(typeof(IKS2ScaledScoreService));
services.RemoveAll(typeof(IKS2AdditionalMeasuresService));
+ services.RemoveAll(typeof(IFeatureManager));
+
services.AddSingleton>();
services.AddSingleton>();
@@ -82,6 +86,8 @@ protected override void ConfigureWebHost(IWebHostBuilder builder)
services.AddSingleton>();
services.AddSingleton>();
services.AddSingleton>();
+ services.AddSingleton>();
+
services.AddTransient(provider =>
{
@@ -176,6 +182,22 @@ protected override void ConfigureWebHost(IWebHostBuilder builder)
{
return provider.GetRequiredService>().Get()?.Object!;
});
+ services.AddTransient(provider =>
+ {
+ var accessor = provider.GetRequiredService>();
+
+ if (accessor.Get() is null)
+ {
+ // Default: all features enabled unless a test explicitly overrides via UseMock()
+ var defaultMock = new Mock();
+ defaultMock
+ .Setup(f => f.IsEnabledAsync(It.IsAny()))
+ .ReturnsAsync(true);
+ accessor.Set(defaultMock);
+ }
+
+ return accessor.Object;
+ });
});
}
}