import Foundation import Testing @testable import Hutch struct ReadmeViewTests { @Test func sanitizedReadmeLinkURLStringRejectsUnexpectedSchemes() { #expect(sanitizedReadmeLinkURLString("javascript:alert(1)") == nil) #expect(sanitizedReadmeLinkURLString("file:///tmp/readme") == nil) #expect(sanitizedReadmeLinkURLString("data:text/html;base64,SGVsbG8=") == nil) } @Test func processInlineDropsUnsafeMarkdownLinks() { let rendered = processInline("[click me](javascript:alert)") #expect(rendered == "click me") #expect(!rendered.contains("href=")) #expect(!rendered.contains("javascript:")) } @Test func sanitizedReadmeLinkURLStringAllowsExpectedDestinations() { #expect(sanitizedReadmeLinkURLString("https://example.com/docs?q=1") == "https://example.com/docs?q=1") #expect(sanitizedReadmeLinkURLString("mailto:test@example.com") == "mailto:test@example.com") #expect(sanitizedReadmeLinkURLString("#readme") == "#readme") } } struct MarkdownRenderingTests { @Test func markdownOrderedList() { let html = markdownToHTML("1. First\n2. Second") #expect(html.contains("
")) } @Test func markdownTable() { let input = "| A | B |\n|---|---|\n| 1 | 2 |" let html = markdownToHTML(input) #expect(html.contains("")) #expect(html.contains("
")) } @Test func markdownTableAlignment() { let input = "| Left | Center | Right |\n|:-----|:------:|------:|\n| a | b | c |" let html = markdownToHTML(input) #expect(html.contains("text-align: left;")) #expect(html.contains("text-align: center;")) #expect(html.contains("text-align: right;")) } @Test func markdownStrikethrough() { let html = markdownToHTML("~~deleted~~") #expect(html.contains(" ")) } @Test func markdownDeepHeadings() { let html = markdownToHTML("#### Level 4") #expect(html.contains("")) } @Test func markdownHardWrapNormalization() { let html = markdownToHTML("line one\nline two") #expect(!html.contains("line one\nline two")) #expect(html.contains("line one")) #expect(html.contains("line two")) } @Test func markdownSoftBreakIsSpace() { let html = markdownToHTML("word one\nword two") #expect(html.contains("word one word two") || (html.contains("word one") && html.contains("word two"))) #expect(!html.contains("
")) } @Test func markdownUnsafeLinkDropped() { let html = markdownToHTML("[click](javascript:alert(1))") #expect(!html.contains("href=")) #expect(!html.contains("javascript:")) } @Test func markdownImageRenders() { let html = markdownToHTML("") #expect(html.contains("")) #expect(!html.contains(#"\"#)) } @Test func markdownLinkedImageRendersAnchor() { let html = markdownToHTML("[](https://example.com/build)") #expect(html.contains("")) #expect(html.contains("
")) #expect(!html.contains(#"\"#)) } @Test func markdownInlineCodeEscaping() { let html = processInline("``") #expect(html.contains("
")) #expect(html.contains("<b>")) #expect(!html.contains("")) } @Test func markdownPlainEmailAutolinks() { let html = processInline("Contact hello@cleberg.net") #expect(html.contains(#"href="mailto:hello@cleberg.net""#)) #expect(html.contains(">hello@cleberg.net")) } @Test func markdownImageQueryStringPreservesAmpersands() { let html = processInline("") #expect(html.contains("metric=security_rating")) #expect(!html.contains("amp;metric")) #expect(html.contains("Bold Link"#) #expect(html.contains("Bold")) #expect(html.contains(#"Link"#)) } @Test func markdownProtectedTokensDoNotLeak() { let html = processInline(#"Back to top `yoshi [ARG]
`"#) #expect(!html.contains("ZZPROTECTED")) #expect(html.contains(#"Back to top"#)) #expect(html.contains(" yoshi [ARG] <FILE>")) } } struct OrgRenderingTests { @Test func orgDeepHeading() { let html = orgToHTML("**** Level 4 Heading") #expect(html.contains("")) } @Test func orgCommentLinesIgnored() { let html = orgToHTML("# This is a comment\nNormal text") #expect(!html.contains("This is a comment")) #expect(html.contains("Normal text")) } @Test func orgStrikethrough() { let html = orgToHTML("+deleted text+") #expect(html.contains("
")) } @Test func orgExampleBlock() { let html = orgToHTML("#+begin_example\nhello world\n#+end_example") #expect(html.contains("")) #expect(html.contains("hello world")) } @Test func orgTitleKeyword() { let html = orgToHTML("#+TITLE: My Document\nBody text") #expect(html.contains("org-title")) #expect(html.contains("My Document")) } @Test func orgItalicDoesNotMatchURLPaths() { let html = orgToHTML("[[https://example.com/path/to/file]]") #expect(!html.contains("")) } @Test func orgWrappedBulletNormalizesLines() { let html = orgToHTML("- First line\n continues here") #expect(html.contains("- First line continues here
")) } } struct RepositoryAssetURLTests { @Test func repositoryAssetURLPercentEncodesImagePaths() { let url = resolveRepositoryAssetURL( "images/My Logo.png", owner: "~ccleberg", repositoryName: "Hutch", readmePath: "README.md" ) #expect(url == "https://git.sr.ht/~ccleberg/Hutch/blob/HEAD/images/My%20Logo.png") } }