diff --git a/EssentialCSharp.Web.Tests/SiteMappingTests.cs b/EssentialCSharp.Web.Tests/SiteMappingTests.cs index 91b4e7d9..a1287bbd 100644 --- a/EssentialCSharp.Web.Tests/SiteMappingTests.cs +++ b/EssentialCSharp.Web.Tests/SiteMappingTests.cs @@ -1,4 +1,9 @@ -using EssentialCSharp.Web.Extensions; +using System.Globalization; +using System.Text.Json; +using EssentialCSharp.Web.Extensions; +using EssentialCSharp.Web.Services; +using Microsoft.AspNetCore.Hosting; +using Moq; namespace EssentialCSharp.Web.Tests; @@ -146,4 +151,78 @@ public async Task FindPercentComplete_KeyNotFound_ReturnsZeroPercent() // Assert await Assert.That(percent).IsEqualTo("0.00"); } + + [Test] + public async Task GetTocData_OrdersChaptersAndBuildsNestedItems() + { + // Arrange + string contentRoot = Path.Combine(Path.GetTempPath(), $"essential-csharp-{Guid.NewGuid():N}"); + string chaptersDirectory = Path.Combine(contentRoot, "Chapters"); + Directory.CreateDirectory(chaptersDirectory); + + List siteMappings = + [ + CreateSiteMapping(2, 1, 1, 0, "chapter-two", "Chapter Two"), + CreateSiteMapping(1, 2, 1, 0, "chapter-one-page-two", "Page Two"), + CreateSiteMapping(1, 1, 1, 0, "chapter-one", "Chapter One"), + CreateSiteMapping(1, 1, 2, 1, "chapter-one-topic", "Topic"), + CreateSiteMapping(1, 1, 3, 2, "chapter-one-subtopic", "Subtopic"), + CreateSiteMapping(1, 1, 4, 1, "chapter-one-second-topic", "Second Topic") + ]; + + await File.WriteAllTextAsync( + Path.Combine(chaptersDirectory, "sitemap.json"), + JsonSerializer.Serialize(siteMappings)); + + Mock environment = new(); + environment.SetupGet(x => x.ContentRootPath).Returns(contentRoot); + + try + { + // Act + SiteMappingService service = new(environment.Object); + List chapters = service.GetTocData().ToList(); + + // Assert + using (Assert.Multiple()) + { + await Assert.That(chapters.Select(x => x.Key).ToArray()).IsEqualTo(["chapter-one", "chapter-two"]); + await Assert.That(chapters[0].Title).IsEqualTo("Chapter 1: Chapter One"); + await Assert.That(chapters[0].Items.Select(x => x.Key).ToArray()) + .IsEqualTo(["chapter-one-topic", "chapter-one-second-topic"]); + await Assert.That(chapters[0].Items.First().Items.Select(x => x.Key).ToArray()) + .IsEqualTo(["chapter-one-subtopic"]); + await Assert.That(chapters[1].Title).IsEqualTo("Chapter 2: Chapter Two"); + } + } + finally + { + Directory.Delete(contentRoot, recursive: true); + } + } + + private static SiteMapping CreateSiteMapping( + int chapterNumber, + int pageNumber, + int orderOnPage, + int indentLevel, + string key, + string heading) => + new( + keys: [key], + primaryKey: key, + pagePath: + [ + "Chapters", + chapterNumber.ToString("D2", CultureInfo.InvariantCulture), + "Pages", + $"{pageNumber:D2}.html" + ], + chapterNumber: chapterNumber, + pageNumber: pageNumber, + orderOnPage: orderOnPage, + chapterTitle: heading, + rawHeading: heading, + anchorId: key, + indentLevel: indentLevel); } \ No newline at end of file