From 7d5ca0607c091f76aa29cd6fa8c76cfeb1e02ac8 Mon Sep 17 00:00:00 2001 From: Christian Cleberg Date: Wed, 15 Apr 2026 16:07:09 -0500 Subject: fix: fixes dead relative links in md/org with a new single-file viewer when tapped Fixes: https://todo.sr.ht/~ccleberg/hutch/63 --- HutchTests/ReadmeViewTests.swift | 101 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) (limited to 'HutchTests') diff --git a/HutchTests/ReadmeViewTests.swift b/HutchTests/ReadmeViewTests.swift index f338525..3b9d80b 100644 --- a/HutchTests/ReadmeViewTests.swift +++ b/HutchTests/ReadmeViewTests.swift @@ -103,6 +103,44 @@ struct MarkdownRenderingTests { #expect(!html.contains("javascript:")) } + @Test + func markdownRelativeLinkWithoutResolverDropped() { + let html = markdownToHTML("[LICENSE](LICENSE)") + + #expect(!html.contains("href=")) + #expect(html.contains("LICENSE")) + } + + @Test + func markdownRelativeLinkWithResolverRendersAnchor() { + let html = markdownToHTML( + "[LICENSE](LICENSE)", + linkURLResolver: { source in + source == "LICENSE" ? "https://git.sr.ht/~ccleberg/Hutch/blob/HEAD/LICENSE" : nil + } + ) + + #expect(html.contains(#"href="https://git.sr.ht/~ccleberg/Hutch/blob/HEAD/LICENSE""#)) + #expect(html.contains(">LICENSE")) + } + + @Test + func markdownFragmentLinkWithResolverPreservesFragment() { + let html = markdownToHTML( + "[section](#install)", + linkURLResolver: { source in + resolveRepositoryLinkURL( + source, + owner: "~ccleberg", + repositoryName: "Hutch", + readmePath: "README.md" + ) + } + ) + + #expect(html.contains("href=\"#install\"")) + } + @Test func markdownImageRenders() { let html = markdownToHTML("![logo](https://example.com/logo.png)") @@ -349,3 +387,66 @@ struct RepositoryAssetURLTests { #expect(url == "https://git.sr.ht/~ccleberg/Hutch/blob/HEAD/images/My%20Logo.png") } } + +struct RepositoryLinkURLTests { + + @Test + func repositoryLinkURLResolvesRelativePath() { + let url = resolveRepositoryLinkURL( + "LICENSE", + owner: "~ccleberg", + repositoryName: "Hutch", + readmePath: "README.md" + ) + + #expect(url == "https://git.sr.ht/~ccleberg/Hutch/blob/HEAD/LICENSE") + } + + @Test + func repositoryLinkURLPassesThroughAbsoluteURL() { + let url = resolveRepositoryLinkURL( + "https://example.com/page", + owner: "~ccleberg", + repositoryName: "Hutch", + readmePath: "README.md" + ) + + #expect(url == "https://example.com/page") + } + + @Test + func repositoryLinkURLPassesThroughFragment() { + let url = resolveRepositoryLinkURL( + "#install", + owner: "~ccleberg", + repositoryName: "Hutch", + readmePath: "README.md" + ) + + #expect(url == "#install") + } + + @Test + func repositoryLinkURLPassesThroughMailto() { + let url = resolveRepositoryLinkURL( + "mailto:hello@example.com", + owner: "~ccleberg", + repositoryName: "Hutch", + readmePath: "README.md" + ) + + #expect(url == "mailto:hello@example.com") + } + + @Test + func repositoryLinkURLResolvesSubdirectoryRelativePath() { + let url = resolveRepositoryLinkURL( + "docs/SECURITY.md", + owner: "~ccleberg", + repositoryName: "Hutch", + readmePath: "README.md" + ) + + #expect(url == "https://git.sr.ht/~ccleberg/Hutch/blob/HEAD/docs/SECURITY.md") + } +} -- cgit v1.2.3