Skip to content

Commit

Permalink
Makes this solution testable (bypassing EssentialCSharp.Common)
Browse files Browse the repository at this point in the history
  • Loading branch information
Joshua-Lester3 committed Nov 17, 2024
1 parent 4b75631 commit 710418c
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 5 deletions.
4 changes: 2 additions & 2 deletions EssentialCSharp.Web/Controllers/HomeController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public HomeController(ILogger<HomeController> logger, IWebHostEnvironment hostin
public IActionResult Index(string key)
{
// if no key (default case), then load up home page
SiteMapping? siteMapping = _SiteMappingService.SiteMappings.Find(key);
Services.SiteMapping? siteMapping = _SiteMappingService.SiteMappings.Find(key);

if (string.IsNullOrEmpty(key))
{
Expand Down Expand Up @@ -107,7 +107,7 @@ private string FlipPage(int currentChapter, int currentPage, bool next)
page = 1;
}

SiteMapping? siteMap = _SiteMappingService.SiteMappings.FirstOrDefault(f => f.ChapterNumber == currentChapter && f.PageNumber == currentPage + page);
Services.SiteMapping? siteMap = _SiteMappingService.SiteMappings.FirstOrDefault(f => f.ChapterNumber == currentChapter && f.PageNumber == currentPage + page);

if (siteMap is null)
{
Expand Down
8 changes: 5 additions & 3 deletions EssentialCSharp.Web/Extensions/SiteMappingListExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
namespace EssentialCSharp.Web.Extensions;
using EssentialCSharp.Web.Services;

namespace EssentialCSharp.Web.Extensions;

public static class SiteMappingListExtensions
{
Expand All @@ -8,15 +10,15 @@ public static class SiteMappingListExtensions
/// <param name="siteMappings">IList of SiteMappings</param>
/// <param name="key">If null, uses the first key in the list</param>
/// <returns>If found, the site mapping that matches the key, otherwise null.</returns>
public static SiteMapping? Find(this IList<SiteMapping> siteMappings, string? key)
public static Services.SiteMapping? Find(this IList<Services.SiteMapping> siteMappings, string? key)
{
if (string.IsNullOrWhiteSpace(key))
{
return siteMappings.FirstOrDefault();
}
foreach (string? potentialMatch in key.GetPotentialMatches())
{
if (siteMappings.FirstOrDefault(x => x.Keys.Any(x => x == potentialMatch)) is { } siteMap)
if (siteMappings.FirstOrDefault(x => x.Keys.Any(k => k == potentialMatch)) is { } siteMap)
{
return siteMap;
}
Expand Down
125 changes: 125 additions & 0 deletions EssentialCSharp.Web/Services/SiteMappingService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,128 @@ private static IEnumerable<SiteMappingDto> GetItems(IEnumerable<SiteMapping> cha
});
}
}

/// <summary>
/// A model for a site mapping to transport between the tooling and the web app so the web app knows where to find the content a user is looking for.
/// </summary>
public class SiteMapping
{
/// <param name="keys">The key for the site mapping.</param>
/// <param name="pagePath">The path to the actual HTML page.</param>
/// <param name="chapterNumber">The chapter number of the content.</param>
/// <param name="pageNumber">The page number of the content.</param>
/// <param name="orderOnPage">A number indicating order on a page.</param>
/// <param name="chapterTitle">The title of the chapter.</param>
/// <param name="rawHeading">The raw heading of the content.</param>
/// <param name="anchorId">The anchor ID of the content. This allows you to know what anchors are on a page and get to that specific area.</param>
/// <param name="indentLevel">The indent level of the content. This is used to determine how the content is displayed in the table of contents.</param>
/// <param name="contentHash">A hash of the content. This is used to determine if the content has changed and needs to be updated.</param>
/// <param name="includeInSitemapXml"><see cref="IncludeInSitemapXml"/></param>
public SiteMapping(List<string> keys, string[] pagePath, int chapterNumber, int pageNumber, int orderOnPage, string chapterTitle, string rawHeading, string? anchorId,
int indentLevel, string? contentHash = null, bool includeInSitemapXml = true)
{
Keys = keys;
PagePath = pagePath;
ChapterNumber = chapterNumber;
PageNumber = pageNumber;
OrderOnPage = orderOnPage;
ChapterTitle = chapterTitle;
RawHeading = rawHeading;
ContentHash = contentHash;
AnchorId = anchorId;
IndentLevel = indentLevel;
IncludeInSitemapXml = includeInSitemapXml;
}

/// <summary>
/// The key for the site mapping.
/// </summary>
public List<string> Keys { get; }
/// <summary>
/// The path to the actual HTML page.
/// </summary>
public string[] PagePath { get; }
/// <summary>
/// The chapter number of the content.
/// </summary>
public int ChapterNumber { get; }
/// <summary>
/// The page number of the content.
/// </summary>
public int PageNumber { get; }
/// <summary>
/// A number indicating order on a page.
/// </summary>
public int OrderOnPage { get; set; }
/// <summary>
/// The title of the chapter.
/// </summary>
public string ChapterTitle { get; }
/// <summary>
/// The raw heading of the content.
/// </summary>
public string RawHeading { get; set; }
/// <summary>
/// The hash of the content. This is used to determine if the content has changed and needs to be updated.
/// This should be a base64 encoded string of the hash.
/// This should not be null by the time parsing is complete.
/// </summary>
public string? ContentHash { get; set; }
/// <summary>
/// The anchor ID of the content. This allows you to know what anchors are on a page and get to that specific area.
/// </summary>
public string? AnchorId { get; }
/// <summary>
/// The indent level of the content. This is used to determine how the content is displayed in the table of contents.
/// </summary>
public int IndentLevel { get; }
/// <summary>
/// Whether or not to include this in the sitemap. This is used to determine if a page should be included in the sitemap XML file.
/// Only the top most heading of a page should be included in the sitemap, and the rest will be canonical links.
/// This is only used to parse the Sitemap XML file.
/// </summary>
public bool IncludeInSitemapXml { get; }

/// <inheritdoc/>
public override bool Equals(object? obj)
{
if (obj is SiteMapping other)
{
return Keys == other.Keys &&
PagePath?.SequenceEqual(other.PagePath) == true &&
ChapterNumber == other.ChapterNumber &&
PageNumber == other.PageNumber &&
OrderOnPage == other.OrderOnPage &&
ChapterTitle == other.ChapterTitle &&
RawHeading == other.RawHeading &&
AnchorId == other.AnchorId &&
IndentLevel == other.IndentLevel &&
IncludeInSitemapXml == other.IncludeInSitemapXml;
}
return false;
}

/// <inheritdoc/>
public override int GetHashCode()
{
// HashCode.Combine doesn't work for more than 8 items.
HashCode hash = new();
hash.Add(Keys);
hash.Add(PagePath);
hash.Add(ChapterNumber);
hash.Add(PageNumber);
hash.Add(OrderOnPage);
hash.Add(ChapterTitle);
hash.Add(RawHeading);
hash.Add(AnchorId);
hash.Add(IndentLevel);
hash.Add(IncludeInSitemapXml);
return hash.ToHashCode();
}

/// <inheritdoc/>
public override string ToString()
{
return $"{ChapterNumber}.{PageNumber} - {ChapterTitle} - Raw Heading: {RawHeading} - Hash: {ContentHash} {Environment.NewLine} {string.Join(", ", Keys)}";
}
}

0 comments on commit 710418c

Please sign in to comment.