diff --git a/Childrens-Social-Care-CPD-Tests/Controllers/ResourcesControllerTests.cs b/Childrens-Social-Care-CPD-Tests/Controllers/ResourcesControllerTests.cs index bf011a98..16ca995e 100644 --- a/Childrens-Social-Care-CPD-Tests/Controllers/ResourcesControllerTests.cs +++ b/Childrens-Social-Care-CPD-Tests/Controllers/ResourcesControllerTests.cs @@ -1,4 +1,5 @@ -using Childrens_Social_Care_CPD.Controllers; +using Childrens_Social_Care_CPD.Configuration; +using Childrens_Social_Care_CPD.Controllers; using Childrens_Social_Care_CPD.Core.Resources; using Childrens_Social_Care_CPD.Models; using FluentAssertions; @@ -14,6 +15,7 @@ namespace Childrens_Social_Care_CPD_Tests.Controllers; public class ResourcesControllerTests { + private IFeaturesConfig _featuresConfig; private IResourcesSearchStrategy _searchStrategy; private ResourcesController _resourcesController; private IRequestCookieCollection _cookies; @@ -32,8 +34,10 @@ public void SetUp() _httpContext.Request.Returns(_httpRequest); controllerContext.HttpContext = _httpContext; + _featuresConfig = Substitute.For(); + _featuresConfig.IsEnabled(Features.ResourcesAndLearning).Returns(true); _searchStrategy = Substitute.For(); - _resourcesController = new ResourcesController(_searchStrategy) + _resourcesController = new ResourcesController(_featuresConfig, _searchStrategy) { ControllerContext = controllerContext, TempData = Substitute.For() @@ -53,4 +57,19 @@ public async Task Search_Returns_Strategy_Model() // assert actual.Model.Should().Be(model); } + + [Test] + public async Task Disabling_Resources_Feature_Returns_NotFoundResult() + { + // arrange + _featuresConfig.IsEnabled(Features.ResourcesAndLearning).Returns(false); + var model = new ResourcesListViewModel(null, null, null, null); + _searchStrategy.SearchAsync(Arg.Any(), Arg.Any()).Returns(model); + + // act + var actual = await _resourcesController.Search(query: null); + + // assert + actual.Should().BeOfType(); + } } \ No newline at end of file diff --git a/Childrens-Social-Care-CPD/Configuration/Features.cs b/Childrens-Social-Care-CPD/Configuration/Features.cs index 772980a5..8bc52dc5 100644 --- a/Childrens-Social-Care-CPD/Configuration/Features.cs +++ b/Childrens-Social-Care-CPD/Configuration/Features.cs @@ -2,5 +2,6 @@ public static class Features { + public const string ResourcesAndLearning = "resources-learning"; public const string ResourcesUseDynamicTags = "resources-search-use-dynamic-tags"; } diff --git a/Childrens-Social-Care-CPD/Controllers/ResourcesController.cs b/Childrens-Social-Care-CPD/Controllers/ResourcesController.cs index f8e26575..7fdb0aa5 100644 --- a/Childrens-Social-Care-CPD/Controllers/ResourcesController.cs +++ b/Childrens-Social-Care-CPD/Controllers/ResourcesController.cs @@ -1,4 +1,5 @@ -using Childrens_Social_Care_CPD.Core.Resources; +using Childrens_Social_Care_CPD.Configuration; +using Childrens_Social_Care_CPD.Core.Resources; using Childrens_Social_Care_CPD.Models; using Microsoft.AspNetCore.Mvc; @@ -17,19 +18,25 @@ public ResourcesQuery() public class ResourcesController : Controller { + private readonly IFeaturesConfig _featuresConfig; private readonly IResourcesSearchStrategy _strategy; - public ResourcesController(IResourcesSearchStrategy strategy) + public ResourcesController(IFeaturesConfig featuresConfig, IResourcesSearchStrategy strategy) { ArgumentNullException.ThrowIfNull(strategy); - + _featuresConfig = featuresConfig; _strategy = strategy; } - [Route("resources", Name = "Resource")] + [Route("resources-learning")] [HttpGet] public async Task Search([FromQuery] ResourcesQuery query, bool preferencesSet = false, CancellationToken cancellationToken = default) { + if (!_featuresConfig.IsEnabled(Features.ResourcesAndLearning)) + { + return NotFound(); + } + var contextModel = new ContextModel(string.Empty, "Resources", "Resources", "Resources", true, preferencesSet); ViewData["ContextModel"] = contextModel; diff --git a/Childrens-Social-Care-CPD/Core/Resources/ResourcesDynamicTagsSearchStategy.cs b/Childrens-Social-Care-CPD/Core/Resources/ResourcesDynamicTagsSearchStategy.cs index 28878085..75feef4e 100644 --- a/Childrens-Social-Care-CPD/Core/Resources/ResourcesDynamicTagsSearchStategy.cs +++ b/Childrens-Social-Care-CPD/Core/Resources/ResourcesDynamicTagsSearchStategy.cs @@ -44,10 +44,10 @@ private static string GetPagingFormatString(IEnumerable tags) { var tagStrings = tags.Select(x => $"tags={x}"); var allTags = string.Join("&", tagStrings); - return $"/resources?page={{0}}&{allTags}"; + return $"/resources-learning?page={{0}}&{allTags}"; } - return $"/resources?page={{0}}"; + return $"/resources-learning?page={{0}}"; } public async Task SearchAsync(ResourcesQuery query, CancellationToken cancellationToken = default) diff --git a/Childrens-Social-Care-CPD/Core/Resources/ResourcesFixedTagsSearchStrategy.cs b/Childrens-Social-Care-CPD/Core/Resources/ResourcesFixedTagsSearchStrategy.cs index d94ec47a..2d755568 100644 --- a/Childrens-Social-Care-CPD/Core/Resources/ResourcesFixedTagsSearchStrategy.cs +++ b/Childrens-Social-Care-CPD/Core/Resources/ResourcesFixedTagsSearchStrategy.cs @@ -57,10 +57,10 @@ private static string GetPagingFormatString(int[] tags) { var tagStrings = tags.Select(x => $"tags={x}"); var allTags = string.Join("&", tagStrings); - return $"/resources?page={{0}}&{allTags}"; + return $"/resources-learning?page={{0}}&{allTags}"; } - return $"/resources?page={{0}}"; + return $"/resources-learning?page={{0}}"; } public async Task SearchAsync(ResourcesQuery query, CancellationToken cancellationToken = default) diff --git a/Childrens-Social-Care-CPD/Views/Resources/Search.cshtml b/Childrens-Social-Care-CPD/Views/Resources/Search.cshtml index 36ae7916..7f85f23b 100644 --- a/Childrens-Social-Care-CPD/Views/Resources/Search.cshtml +++ b/Childrens-Social-Care-CPD/Views/Resources/Search.cshtml @@ -18,7 +18,7 @@ @if (featuresConfig.IsEnabled(Features.ResourcesUseDynamicTags)) { - + @{ var groups = Model.TagInfos.GroupBy(x => x.Category); var index = 1; // gov uk js requires starting at 1 for this control @@ -41,7 +41,7 @@ else { var tagsDict = new Dictionary(Model.TagInfos.Select((tagInfo, index) => KeyValuePair.Create(index, tagInfo))); - + @{ var groupsx = tagsDict.GroupBy(kvp => kvp.Value.Category); var index = 1; // gov uk js requires starting at 1 for this control @@ -65,7 +65,7 @@ @{ var resultString = Model.TotalResults == 1 ? "result" : "results"; -

+

@Model.TotalResults @resultString


diff --git a/Childrens-Social-Care-CPD/Views/Resources/_SearchResult.cshtml b/Childrens-Social-Care-CPD/Views/Resources/_SearchResult.cshtml index 447b97af..f8bb5c4c 100644 --- a/Childrens-Social-Care-CPD/Views/Resources/_SearchResult.cshtml +++ b/Childrens-Social-Care-CPD/Views/Resources/_SearchResult.cshtml @@ -4,7 +4,7 @@ @model SearchResourcesByTags.SearchResult
-

@Model.Title

+

@Model.Title

@Model.SearchSummary

  • From: @Model.From
  • diff --git a/Childrens-Social-Care-CPD/Views/Shared/_ErrorLayout.cshtml b/Childrens-Social-Care-CPD/Views/Shared/_ErrorLayout.cshtml index 0ca54d9e..8fcef21b 100644 --- a/Childrens-Social-Care-CPD/Views/Shared/_ErrorLayout.cshtml +++ b/Childrens-Social-Care-CPD/Views/Shared/_ErrorLayout.cshtml @@ -1,4 +1,7 @@ -@inject ICookieHelper _cookieHelper; +@using Childrens_Social_Care_CPD.Configuration; + +@inject ICookieHelper cookieHelper; +@inject IFeaturesConfig featuresConfig; @@ -6,7 +9,7 @@ @ViewBag.Title - @if (_cookieHelper.GetRequestAnalyticsCookieState(Context) == AnalyticsConsentState.Accepted) + @if (cookieHelper.GetRequestAnalyticsCookieState(Context) == AnalyticsConsentState.Accepted) { } @@ -78,14 +81,17 @@ -
  • - - Resources - - -
  • + @if (featuresConfig.IsEnabled(Features.ResourcesAndLearning)) + { +
  • + + Resources and learning + + +
  • + }
diff --git a/Childrens-Social-Care-CPD/Views/Shared/_Header.cshtml b/Childrens-Social-Care-CPD/Views/Shared/_Header.cshtml index 10fabfc9..7f84090c 100644 --- a/Childrens-Social-Care-CPD/Views/Shared/_Header.cshtml +++ b/Childrens-Social-Care-CPD/Views/Shared/_Header.cshtml @@ -1,4 +1,8 @@ -@{ +@using Childrens_Social_Care_CPD.Configuration; + +@inject IFeaturesConfig featuresConfig + +@{ ContextModel viewModel = ViewBag.ContextModel; var category = viewModel.Category ?? "Home"; } @@ -53,8 +57,11 @@ RenderMenuItem("career", "Career stages", "career-stages", category == "Career information"); RenderMenuItem("developmentProgrammes", "Development programmes", "development-programmes", category == "Development programmes"); RenderMenuItem("exploreRoles", "Explore roles", "explore-roles", category == "Explore roles"); - RenderMenuItem("resources", "Resources", "resources", category == "Resources"); - + + if (featuresConfig.IsEnabled(Features.ResourcesAndLearning)) + { + RenderMenuItem("resources", "Resources and learning", "resources-learning", category == "Resources"); + } } diff --git a/browser-tests/content-regression-tests/tests/header.spec.ts b/browser-tests/content-regression-tests/tests/header.spec.ts index da310da2..8168eef7 100644 --- a/browser-tests/content-regression-tests/tests/header.spec.ts +++ b/browser-tests/content-regression-tests/tests/header.spec.ts @@ -11,7 +11,7 @@ test.describe('Header', () => { ['Career stages', '/career-stages'], ['Development programmes', '/development-programmes'], ['Explore roles', '/explore-roles'], - ['Resources', '/training-resources'], + ['Resources and learning', '/resources-learning'], ] for (const link of links) { diff --git a/browser-tests/content-regression-tests/tests/resources-learning/search.spec.ts b/browser-tests/content-regression-tests/tests/resources-learning/search.spec.ts new file mode 100644 index 00000000..1bb7a1de --- /dev/null +++ b/browser-tests/content-regression-tests/tests/resources-learning/search.spec.ts @@ -0,0 +1,38 @@ +import { test, expect } from '@playwright/test' + +test.describe('Resources and learning', () => { + test.beforeEach(async ({ page }) => { + await page.goto('/resources-learning') + }) + + test.describe('Filter accordian @accordian', () => { + test('All sections are collapsed when you arrive on page' , async ({ page }) => { + const sections = await page.locator('.govuk-accordion__section-content').all() + expect(sections.length).toBeGreaterThan(1) + for (const section of sections) + { + await expect(section).toHaveAttribute('hidden', 'until-found') + } + }) + + test('Clicking expand all, expands the sections' , async ({ page }) => { + await page.getByRole('button', { name: 'Show all sections', exact: true }).click() + + const sections = await page.locator('.govuk-accordion__section-content').all() + expect(sections.length).toBeGreaterThan(1) + for (const section of sections) + { + await expect(section).not.toHaveAttribute('hidden', 'until-found') + } + }) + }) + + test('Filter by tags performs search' , async ({ page }) => { + await page.getByRole('button', { name: 'Show all sections', exact: true }).click() + const beforeText = await page.getByTestId("results-count").textContent() + await page.locator('.govuk-checkboxes__label').first().click() + await page.getByRole('button', { name: 'Apply filter', exact: true }).click() + const afterText = await page.getByTestId("results-count").textContent() + expect(beforeText).not.toEqual(afterText) + }) +}) \ No newline at end of file