From 67254b6b88ddff0c913e00028dc50720b6002571 Mon Sep 17 00:00:00 2001 From: simonjfirth Date: Tue, 20 Aug 2024 16:24:18 +0100 Subject: [PATCH] Feature/tag filtering (#133) * Added default page to handle base route * Created the ability to filter content by tags * Fixed empty reference aria label * Updated controller to support page type * Tidy up * Removed spacing * Fixed unit tests * Moved iD --- .../Controllers/ContentController.cs | 6 ++- .../Controllers/SitemapController.cs | 1 - .../Dfe.ContentSupport.Web.csproj | 26 ++++-------- .../Models/ContentBase.cs | 3 +- .../Models/ContentItemBase.cs | 3 +- .../Models/Mapped/CsPage.cs | 2 +- .../Models/Mapped/RichTextContentItem.cs | 1 + .../Services/ModelMapper.cs | 24 ++++++++--- .../Views/Shared/RichText/_RichText.cshtml | 41 +++++++++++-------- src/Dfe.ContentSupport.Web/appsettings.json | 20 --------- .../Mapped/Custom/CustomAccordionTests.cs | 9 ++-- .../Mapped/Custom/CustomAttachmentTests.cs | 7 ++-- .../Models/Mapped/Custom/CustomCardTests.cs | 12 +++--- .../Mapped/Custom/CustomGridContainerTests.cs | 18 ++++---- .../Mapped/Standard/EmbeddedEntryTests.cs | 5 ++- .../Services/ContentServiceTests.cs | 6 +-- .../Services/ModelMapperTests.cs | 18 ++++---- 17 files changed, 100 insertions(+), 102 deletions(-) delete mode 100644 src/Dfe.ContentSupport.Web/appsettings.json diff --git a/src/Dfe.ContentSupport.Web/Controllers/ContentController.cs b/src/Dfe.ContentSupport.Web/Controllers/ContentController.cs index 681091a..210f61f 100644 --- a/src/Dfe.ContentSupport.Web/Controllers/ContentController.cs +++ b/src/Dfe.ContentSupport.Web/Controllers/ContentController.cs @@ -28,8 +28,10 @@ public async Task Home() return View(defaultModel); } + + [HttpGet("{slug}/{page?}")] - public async Task Index(string slug, string page = "", bool isPreview = false) + public async Task Index(string slug, string page = "", bool isPreview = false, [FromQuery] List? tags = null) { if (!ModelState.IsValid) return RedirectToAction("error"); if (string.IsNullOrEmpty(slug)) return RedirectToAction("error"); @@ -38,10 +40,12 @@ public async Task Index(string slug, string page = "", bool isPre if (resp is null) return RedirectToAction("error"); resp = layoutService.GenerateLayout(resp, Request, page); + ViewBag.tags = tags; return View("CsIndex", resp); } + public IActionResult Privacy() { return View(); diff --git a/src/Dfe.ContentSupport.Web/Controllers/SitemapController.cs b/src/Dfe.ContentSupport.Web/Controllers/SitemapController.cs index 0af6280..fb8338d 100644 --- a/src/Dfe.ContentSupport.Web/Controllers/SitemapController.cs +++ b/src/Dfe.ContentSupport.Web/Controllers/SitemapController.cs @@ -10,7 +10,6 @@ namespace Dfe.ContentSupport.Web.Controllers; public class SitemapController(IContentService contentfulService) : Controller { - [HttpGet] [Route("/sitemap.xml")] public async Task Sitemap() diff --git a/src/Dfe.ContentSupport.Web/Dfe.ContentSupport.Web.csproj b/src/Dfe.ContentSupport.Web/Dfe.ContentSupport.Web.csproj index 056b476..c927a0e 100644 --- a/src/Dfe.ContentSupport.Web/Dfe.ContentSupport.Web.csproj +++ b/src/Dfe.ContentSupport.Web/Dfe.ContentSupport.Web.csproj @@ -8,24 +8,12 @@ - - - - - - Never - true - Never - - - - - - - - - - - + + + + + + + diff --git a/src/Dfe.ContentSupport.Web/Models/ContentBase.cs b/src/Dfe.ContentSupport.Web/Models/ContentBase.cs index c1b04e3..86ad154 100644 --- a/src/Dfe.ContentSupport.Web/Models/ContentBase.cs +++ b/src/Dfe.ContentSupport.Web/Models/ContentBase.cs @@ -1,9 +1,8 @@ using System.Diagnostics.CodeAnalysis; - namespace Dfe.ContentSupport.Web.Models; [ExcludeFromCodeCoverage] -public class ContentBase : ContentType +public class ContentBase : Contentful.Core.Models.Entry { public string InternalName { get; set; } = null!; diff --git a/src/Dfe.ContentSupport.Web/Models/ContentItemBase.cs b/src/Dfe.ContentSupport.Web/Models/ContentItemBase.cs index a33cad6..4450612 100644 --- a/src/Dfe.ContentSupport.Web/Models/ContentItemBase.cs +++ b/src/Dfe.ContentSupport.Web/Models/ContentItemBase.cs @@ -1,4 +1,5 @@ -using System.Diagnostics.CodeAnalysis; +using Contentful.Core.Models; +using System.Diagnostics.CodeAnalysis; namespace Dfe.ContentSupport.Web.Models; diff --git a/src/Dfe.ContentSupport.Web/Models/Mapped/CsPage.cs b/src/Dfe.ContentSupport.Web/Models/Mapped/CsPage.cs index 24863d3..fe6206f 100644 --- a/src/Dfe.ContentSupport.Web/Models/Mapped/CsPage.cs +++ b/src/Dfe.ContentSupport.Web/Models/Mapped/CsPage.cs @@ -17,5 +17,5 @@ public class CsPage public DateTime? UpdatedAt { get; init; } public bool HasFeedbackBanner { get; set; } public List? MenuItems { get; set; } - + public List Tags { get;set; } = null!; } \ No newline at end of file diff --git a/src/Dfe.ContentSupport.Web/Models/Mapped/RichTextContentItem.cs b/src/Dfe.ContentSupport.Web/Models/Mapped/RichTextContentItem.cs index c38f1a5..d65671d 100644 --- a/src/Dfe.ContentSupport.Web/Models/Mapped/RichTextContentItem.cs +++ b/src/Dfe.ContentSupport.Web/Models/Mapped/RichTextContentItem.cs @@ -9,4 +9,5 @@ public class RichTextContentItem : CsContentItem public List Content { get; set; } = null!; public RichTextNodeType NodeType { get; set; } = RichTextNodeType.Unknown; public string Value { get; set; } = null!; + public List Tags { get; set; } = []; } \ No newline at end of file diff --git a/src/Dfe.ContentSupport.Web/Services/ModelMapper.cs b/src/Dfe.ContentSupport.Web/Services/ModelMapper.cs index d976b76..0bd9aed 100644 --- a/src/Dfe.ContentSupport.Web/Services/ModelMapper.cs +++ b/src/Dfe.ContentSupport.Web/Services/ModelMapper.cs @@ -1,4 +1,5 @@ -using Dfe.ContentSupport.Web.Common; +using Contentful.Core.Models; +using Dfe.ContentSupport.Web.Common; using Dfe.ContentSupport.Web.Configuration; using Dfe.ContentSupport.Web.Models; using Dfe.ContentSupport.Web.Models.Mapped; @@ -29,12 +30,20 @@ public CsPage MapToCsPage(ContentSupportPage incoming) HasPrint = incoming.HasPrint, Content = MapEntriesToContent(incoming.Content), ShowVerticalNavigation = incoming.ShowVerticalNavigation, - CreatedAt = incoming.Sys.CreatedAt, - UpdatedAt = incoming.Sys.UpdatedAt + CreatedAt = incoming.SystemProperties.CreatedAt, + UpdatedAt = incoming.SystemProperties.UpdatedAt, + Tags = FlattenMetadata(incoming.Metadata) }; return result; } + private List FlattenMetadata(ContentfulMetadata item) + { + if (item is null) return new(); + + return item.Tags.Select(_ => _.Sys.Id).ToList(); + } + private List MapEntriesToContent(List entries) { return entries.Select(ConvertEntryToContentItem).ToList(); @@ -59,6 +68,7 @@ public CsContentItem ConvertEntryToContentItem(Entry entry) Subtitle = entry.Subtitle, NodeType = ConvertToRichTextNodeType(richText.NodeType), Content = MapRichTextNodes(richText.Content), + Tags = FlattenMetadata(entry.Metadata) }; return item; } @@ -69,11 +79,14 @@ public List MapRichTextNodes(List nodes) { NodeType = RichTextNodeType.Unknown, InternalName = node.InternalName }).ToList(); } + public RichTextContentItem? MapContent(ContentItem contentItem) { RichTextContentItem? item; var nodeType = ConvertToRichTextNodeType(contentItem.NodeType); var internalName = contentItem.InternalName; + + switch (nodeType) { case RichTextNodeType.Text: @@ -84,7 +97,7 @@ public List MapRichTextNodes(List nodes) break; case RichTextNodeType.Hyperlink: var uri = contentItem.Data.Uri.ToString(); - item = new Hyperlink + item = new Models.Mapped.Standard.Hyperlink { Uri = uri, IsVimeo = uri.Contains("vimeo.com") @@ -137,12 +150,13 @@ public List MapRichTextNodes(List nodes) item.Content = MapRichTextNodes(contentItem.Content); item.Value = contentItem.Value; item.InternalName = internalName; + item.Tags = FlattenMetadata(contentItem.Metadata); return item; } public CustomComponent? GenerateCustomComponent(Target target) { - var contentType = target.Sys.ContentType?.Sys.Id; + var contentType = target.SystemProperties.ContentType?.SystemProperties.Id; if (contentType is null) return null; return contentType switch { diff --git a/src/Dfe.ContentSupport.Web/Views/Shared/RichText/_RichText.cshtml b/src/Dfe.ContentSupport.Web/Views/Shared/RichText/_RichText.cshtml index 5133429..2b45ff4 100644 --- a/src/Dfe.ContentSupport.Web/Views/Shared/RichText/_RichText.cshtml +++ b/src/Dfe.ContentSupport.Web/Views/Shared/RichText/_RichText.cshtml @@ -1,61 +1,66 @@ @model RichTextContentItem - @{ + var tags = ViewBag.tags ?? new List(); +} + + +@if (tags.Count == 0 || (Model.Tags.Count == 0 || Model.Tags.Exists(el => tags.Contains(el)))) +{ var nodeType = Model.NodeType; switch (nodeType) { case RichTextNodeType.Document: - + break; case RichTextNodeType.Paragraph: - + break; case RichTextNodeType.Heading2: case RichTextNodeType.Heading3: case RichTextNodeType.Heading4: case RichTextNodeType.Heading5: case RichTextNodeType.Heading6: - + break; case RichTextNodeType.UnorderedList: - + break; case RichTextNodeType.OrderedList: - + break; case RichTextNodeType.ListItem: - + break; case RichTextNodeType.Hyperlink: - + break; case RichTextNodeType.Table: - + break; case RichTextNodeType.TableRow: - + break; case RichTextNodeType.TableHeaderCell: - + break; case RichTextNodeType.TableCell: - + break; case RichTextNodeType.Hr: -
+
break; case RichTextNodeType.EmbeddedAsset: - + break; case RichTextNodeType.Text: - + break; case RichTextNodeType.EmbeddedEntry: - + break; default: - + break; } -} \ No newline at end of file +} diff --git a/src/Dfe.ContentSupport.Web/appsettings.json b/src/Dfe.ContentSupport.Web/appsettings.json deleted file mode 100644 index 169b3df..0000000 --- a/src/Dfe.ContentSupport.Web/appsettings.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "CacheTimeOutMs": 30000, - "Logging": { - "LogLevel": { - "Default": "Information", - "Microsoft.AspNetCore": "Warning" - } - }, - "AllowedHosts": "*", - "cs:supportedAssetTypes": { - "ImageTypes": [ - "image/jpeg", - "image/png" - ], - "VideoTypes": [ - "video/mp4", - "video/quicktime" - ] - } -} \ No newline at end of file diff --git a/tests/Dfe.ContentSupport.Web.Tests/Models/Mapped/Custom/CustomAccordionTests.cs b/tests/Dfe.ContentSupport.Web.Tests/Models/Mapped/Custom/CustomAccordionTests.cs index dd1b845..1beccdc 100644 --- a/tests/Dfe.ContentSupport.Web.Tests/Models/Mapped/Custom/CustomAccordionTests.cs +++ b/tests/Dfe.ContentSupport.Web.Tests/Models/Mapped/Custom/CustomAccordionTests.cs @@ -1,4 +1,5 @@ -using Dfe.ContentSupport.Web.Common; +using Contentful.Core.Models; +using Dfe.ContentSupport.Web.Common; using Dfe.ContentSupport.Web.Configuration; using Dfe.ContentSupport.Web.Models; using Dfe.ContentSupport.Web.Models.Mapped; @@ -28,11 +29,11 @@ public class CustomAccordionTests InternalName = InternalName, Title = Title, SummaryLine = SummaryLine, - Sys = new Sys + SystemProperties = new SystemProperties { - ContentType = new ContentType + ContentType = new Contentful.Core.Models.ContentType { - Sys = new Sys + SystemProperties = new SystemProperties { Id = ContentId } diff --git a/tests/Dfe.ContentSupport.Web.Tests/Models/Mapped/Custom/CustomAttachmentTests.cs b/tests/Dfe.ContentSupport.Web.Tests/Models/Mapped/Custom/CustomAttachmentTests.cs index 7b2ffdf..da395a0 100644 --- a/tests/Dfe.ContentSupport.Web.Tests/Models/Mapped/Custom/CustomAttachmentTests.cs +++ b/tests/Dfe.ContentSupport.Web.Tests/Models/Mapped/Custom/CustomAttachmentTests.cs @@ -31,11 +31,12 @@ public class CustomAttachmentTests { InternalName = InternalName, Title = Title, - Sys = new Sys + SystemProperties = new SystemProperties { - ContentType = new ContentType + ContentType = new Contentful.Core.Models.ContentType { - Sys = new Sys + + SystemProperties = new SystemProperties { Id = ContentId } diff --git a/tests/Dfe.ContentSupport.Web.Tests/Models/Mapped/Custom/CustomCardTests.cs b/tests/Dfe.ContentSupport.Web.Tests/Models/Mapped/Custom/CustomCardTests.cs index c90df3a..f368f3c 100644 --- a/tests/Dfe.ContentSupport.Web.Tests/Models/Mapped/Custom/CustomCardTests.cs +++ b/tests/Dfe.ContentSupport.Web.Tests/Models/Mapped/Custom/CustomCardTests.cs @@ -34,11 +34,11 @@ public class CustomCardTests Meta = Meta, ImageAlt = ImageAlt, Description = Description, - Sys = new Sys + SystemProperties = new Contentful.Core.Models.SystemProperties { - ContentType = new ContentType + ContentType = new Contentful.Core.Models.ContentType { - Sys = new Sys + SystemProperties = new Contentful.Core.Models.SystemProperties { Id = ContentId } @@ -52,10 +52,10 @@ public class CustomCardTests { Url = ImageUri } - } + }, } - } - } + }, + }, }; [Fact] diff --git a/tests/Dfe.ContentSupport.Web.Tests/Models/Mapped/Custom/CustomGridContainerTests.cs b/tests/Dfe.ContentSupport.Web.Tests/Models/Mapped/Custom/CustomGridContainerTests.cs index 0bab7f3..cd74279 100644 --- a/tests/Dfe.ContentSupport.Web.Tests/Models/Mapped/Custom/CustomGridContainerTests.cs +++ b/tests/Dfe.ContentSupport.Web.Tests/Models/Mapped/Custom/CustomGridContainerTests.cs @@ -1,4 +1,5 @@ -using Dfe.ContentSupport.Web.Common; +using Contentful.Core.Models; +using Dfe.ContentSupport.Web.Common; using Dfe.ContentSupport.Web.Configuration; using Dfe.ContentSupport.Web.Models; using Dfe.ContentSupport.Web.Models.Mapped.Custom; @@ -31,11 +32,12 @@ public class CustomGridContainerTests Meta = CardMeta, ImageAlt = CardImageAlt, Description = CardDescription, - Sys = new Sys + SystemProperties = new SystemProperties { - ContentType = new ContentType + ContentType = new Contentful.Core.Models.ContentType { - Sys = new Sys + + SystemProperties = new SystemProperties { Id = CardContentId } @@ -45,7 +47,7 @@ public class CustomGridContainerTests { Fields = new Fields { - File = new FileDetails + File = new Web.Models.FileDetails { Url = CardImageUri } @@ -61,11 +63,11 @@ public class CustomGridContainerTests Target = new Target { InternalName = ContainerInternalName, - Sys = new Sys + SystemProperties = new Contentful.Core.Models.SystemProperties { - ContentType = new ContentType + ContentType = new Contentful.Core.Models.ContentType { - Sys = new Sys + SystemProperties = new Contentful.Core.Models.SystemProperties { Id = ContainerContentId } diff --git a/tests/Dfe.ContentSupport.Web.Tests/Models/Mapped/Standard/EmbeddedEntryTests.cs b/tests/Dfe.ContentSupport.Web.Tests/Models/Mapped/Standard/EmbeddedEntryTests.cs index 23f8ca5..c285b58 100644 --- a/tests/Dfe.ContentSupport.Web.Tests/Models/Mapped/Standard/EmbeddedEntryTests.cs +++ b/tests/Dfe.ContentSupport.Web.Tests/Models/Mapped/Standard/EmbeddedEntryTests.cs @@ -1,4 +1,5 @@ -using Dfe.ContentSupport.Web.Common; +using Contentful.Core.Models; +using Dfe.ContentSupport.Web.Common; using Dfe.ContentSupport.Web.Configuration; using Dfe.ContentSupport.Web.Models; using Dfe.ContentSupport.Web.Models.Mapped.Standard; @@ -22,7 +23,7 @@ public class EmbeddedEntryTests { InternalName = InternalName, JumpIdentifier = JumpIdentifier, - Sys = new Sys() + SystemProperties = new SystemProperties() } } }; diff --git a/tests/Dfe.ContentSupport.Web.Tests/Services/ContentServiceTests.cs b/tests/Dfe.ContentSupport.Web.Tests/Services/ContentServiceTests.cs index 704f487..135cfba 100644 --- a/tests/Dfe.ContentSupport.Web.Tests/Services/ContentServiceTests.cs +++ b/tests/Dfe.ContentSupport.Web.Tests/Services/ContentServiceTests.cs @@ -19,9 +19,9 @@ public class ContentServiceTests { Items = new List { - new() { Slug = "slug1", IsSitemap = true, Sys = new Sys() }, - new() { Slug = "slug2", IsSitemap = false, Sys = new Sys() }, - new() { Slug = "slug3", IsSitemap = true, Sys = new Sys() } + new() { Slug = "slug1", IsSitemap = true, SystemProperties = new SystemProperties() }, + new() { Slug = "slug2", IsSitemap = false, SystemProperties = new SystemProperties() }, + new() { Slug = "slug3", IsSitemap = true, SystemProperties = new SystemProperties() } } }; diff --git a/tests/Dfe.ContentSupport.Web.Tests/Services/ModelMapperTests.cs b/tests/Dfe.ContentSupport.Web.Tests/Services/ModelMapperTests.cs index 9f6b38b..e5dffba 100644 --- a/tests/Dfe.ContentSupport.Web.Tests/Services/ModelMapperTests.cs +++ b/tests/Dfe.ContentSupport.Web.Tests/Services/ModelMapperTests.cs @@ -1,4 +1,5 @@ -using Dfe.ContentSupport.Web.Common; +using Contentful.Core.Models; +using Dfe.ContentSupport.Web.Common; using Dfe.ContentSupport.Web.Configuration; using Dfe.ContentSupport.Web.Models; using Dfe.ContentSupport.Web.Models.Mapped; @@ -22,15 +23,15 @@ public void MapToCsPages_Return_Correct_Amount() { new() { - Sys = new Sys() + SystemProperties = new SystemProperties() }, new() { - Sys = new Sys() + SystemProperties = new SystemProperties() }, new() - { - Sys = new Sys() + { + SystemProperties = new SystemProperties() } }; @@ -132,11 +133,12 @@ public void UnknownCustom_Returns_Null() { var testValue = new Target { - Sys = new Sys + SystemProperties = new SystemProperties { - ContentType = new ContentType + ContentType = new Contentful.Core.Models.ContentType { - Sys = new Sys + + SystemProperties = new SystemProperties { Id = "DUMMY" }