using System.Xml.Linq; using DeepDrftModels.DTOs; using DeepDrftModels.Enums; using DeepDrftPublic.Client.Common; using DeepDrftPublic.Seo; namespace DeepDrftTests; /// /// Unit tests for — the pure sitemaps.org urlset composition (Phase 23 wave 23.2). /// The document is parsed back to an so each assertion checks real structure, not a /// substring: that every <loc> is absolute and built through (so it /// equals the page canonical), that <lastmod> tracks the release date, that the static roots are /// present and FramePlayer is absent, and that empty input still yields a well-formed roots-only document. /// [TestFixture] public class SitemapXmlTests { private const string BaseUrl = "https://deepdrft.com"; private static readonly XNamespace Ns = "http://www.sitemaps.org/schemas/sitemap/0.9"; private static ReleaseDto Release(string entryKey, ReleaseMedium medium, DateOnly? releaseDate = null) => new() { EntryKey = entryKey, Title = "Title", Artist = "Artist", Medium = medium, ReleaseDate = releaseDate, }; private static List Locs(string xml) { var doc = XDocument.Parse(xml); return doc.Root!.Elements(Ns + "url") .Select(u => u.Element(Ns + "loc")!.Value) .ToList(); } [Test] public void Build_EmptyReleases_YieldsWellFormedRootsOnlyDocument() { var xml = SitemapXml.Build(BaseUrl, []); var locs = Locs(xml); Assert.Multiple(() => { Assert.That(locs, Has.Count.EqualTo(SitemapXml.StaticRoots.Count)); Assert.That(locs, Does.Contain("https://deepdrft.com/")); Assert.That(locs, Does.Contain("https://deepdrft.com/about")); Assert.That(locs, Does.Contain("https://deepdrft.com/cuts")); Assert.That(locs, Does.Contain("https://deepdrft.com/sessions")); Assert.That(locs, Does.Contain("https://deepdrft.com/mixes")); Assert.That(locs, Does.Contain("https://deepdrft.com/archive")); }); } [Test] public void Build_IsWellFormedUrlsetWithSitemapsOrgNamespace() { var xml = SitemapXml.Build(BaseUrl, []); var doc = XDocument.Parse(xml); Assert.Multiple(() => { Assert.That(doc.Root!.Name, Is.EqualTo(Ns + "urlset")); Assert.That(xml, Does.Contain("utf-8").IgnoreCase); }); } [Test] public void Build_FramePlayerIsNeverAStaticRoot() { var xml = SitemapXml.Build(BaseUrl, []); Assert.That(Locs(xml), Has.None.Contains("FramePlayer")); } [TestCase(ReleaseMedium.Cut, "https://deepdrft.com/cuts/key-1")] [TestCase(ReleaseMedium.Session, "https://deepdrft.com/sessions/key-1")] [TestCase(ReleaseMedium.Mix, "https://deepdrft.com/mixes/key-1")] public void Build_ReleaseLoc_IsAbsoluteAndResolvedThroughReleaseRoutes(ReleaseMedium medium, string expectedLoc) { var xml = SitemapXml.Build(BaseUrl, [Release("key-1", medium)]); // The loc must equal BaseUrl + ReleaseRoutes.DetailHref — i.e. the page's SeoHead canonical, by construction. var expected = BaseUrl + ReleaseRoutes.DetailHref("key-1", medium); Assert.Multiple(() => { Assert.That(expected, Is.EqualTo(expectedLoc)); Assert.That(Locs(xml), Does.Contain(expectedLoc)); }); } [Test] public void Build_AllReleasesEnumerated_AppendedAfterStaticRoots() { var releases = new[] { Release("a", ReleaseMedium.Cut), Release("b", ReleaseMedium.Mix), Release("c", ReleaseMedium.Session), }; var xml = SitemapXml.Build(BaseUrl, releases); Assert.That(Locs(xml), Has.Count.EqualTo(SitemapXml.StaticRoots.Count + releases.Length)); } [Test] public void Build_ReleaseWithDate_EmitsW3CLastmod() { var xml = SitemapXml.Build(BaseUrl, [Release("key-1", ReleaseMedium.Cut, new DateOnly(2026, 5, 12))]); var doc = XDocument.Parse(xml); var releaseUrl = doc.Root!.Elements(Ns + "url") .Single(u => u.Element(Ns + "loc")!.Value.EndsWith("/cuts/key-1")); Assert.That(releaseUrl.Element(Ns + "lastmod")!.Value, Is.EqualTo("2026-05-12")); } [Test] public void Build_ReleaseWithoutDate_OmitsLastmod() { var xml = SitemapXml.Build(BaseUrl, [Release("key-1", ReleaseMedium.Cut)]); var doc = XDocument.Parse(xml); var releaseUrl = doc.Root!.Elements(Ns + "url") .Single(u => u.Element(Ns + "loc")!.Value.EndsWith("/cuts/key-1")); Assert.That(releaseUrl.Element(Ns + "lastmod"), Is.Null); } [Test] public void Build_StaticRoots_NeverCarryLastmod() { var xml = SitemapXml.Build(BaseUrl, []); var doc = XDocument.Parse(xml); Assert.That(doc.Root!.Elements(Ns + "url").All(u => u.Element(Ns + "lastmod") is null), Is.True); } [Test] public void Build_TrimsTrailingSlashOnBaseUrl() { var xml = SitemapXml.Build("https://deepdrft.com/", [Release("key-1", ReleaseMedium.Cut)]); Assert.Multiple(() => { // No doubled slash on the root or the release URL. Assert.That(Locs(xml), Does.Contain("https://deepdrft.com/")); Assert.That(Locs(xml), Does.Contain("https://deepdrft.com/cuts/key-1")); }); } }