Ctrl K
ComunidadGuías…

themes/themes_test.go

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
package themes

import (
	"strings"
	"testing"
)

func TestOneLevelOfIndentation(t *testing.T) {
	data := []byte("html\n  head\n    title\n  body\n    h1\n")
	got := OneLevelOfIndentation(&data, "body")
	if got != "  " {
		t.Errorf("OneLevelOfIndentation = %q, want %q", got, "  ")
	}

	// keyword not present
	got = OneLevelOfIndentation(&data, "footer")
	if got != "" {
		t.Errorf("OneLevelOfIndentation (missing keyword) = %q, want empty", got)
	}

	// tabs
	tabData := []byte("html\n\thead\n\t\ttitle\n\tbody\n")
	got = OneLevelOfIndentation(&tabData, "body")
	if got != "\t" {
		t.Errorf("OneLevelOfIndentation (tabs) = %q, want %q", got, "\t")
	}
}

func TestStyleHead(t *testing.T) {
	// Built-in theme should produce a <style> block
	got := string(StyleHead("dark"))
	if !strings.Contains(got, "<style>") {
		t.Error("StyleHead(dark) should contain <style>")
	}
	if strings.Contains(got, "<link") {
		t.Error("StyleHead(dark) should not contain <link>")
	}

	// CSS file theme should produce a <link> tag
	got = string(StyleHead("custom.css"))
	if !strings.Contains(got, "<link") {
		t.Error("StyleHead(custom.css) should contain <link>")
	}
	if !strings.Contains(got, "custom.css") {
		t.Error("StyleHead(custom.css) should reference the filename")
	}
}

func TestMessagePage(t *testing.T) {
	got := MessagePage("Test Title", "<p>hello</p>", "dark")
	if !strings.Contains(got, "<title>Test Title</title>") {
		t.Error("MessagePage should contain the title")
	}
	if !strings.Contains(got, "<h1>Test Title</h1>") {
		t.Error("MessagePage should contain the title as h1")
	}
	if !strings.Contains(got, "<p>hello</p>") {
		t.Error("MessagePage should contain the body")
	}
}

func TestMessagePageBytes(t *testing.T) {
	got := MessagePageBytes("Title", []byte("body content"), "dark")
	s := string(got)
	if !strings.Contains(s, "<title>Title</title>") {
		t.Error("MessagePageBytes should contain the title")
	}
	if !strings.Contains(s, "body content") {
		t.Error("MessagePageBytes should contain the body")
	}
}

func TestSimpleHTMLPage(t *testing.T) {
	got := string(SimpleHTMLPage([]byte("My Title"), []byte("Headline"), nil, []byte("<p>content</p>"), []byte("en")))
	if !strings.Contains(got, `lang="en"`) {
		t.Error("SimpleHTMLPage should contain language attribute")
	}
	if !strings.Contains(got, "<title>My Title</title>") {
		t.Error("SimpleHTMLPage should contain title")
	}
	if !strings.Contains(got, "<h1>Headline</h1>") {
		t.Error("SimpleHTMLPage should contain headline")
	}

	// Without language
	got = string(SimpleHTMLPage([]byte("T"), nil, nil, []byte("b"), nil))
	if strings.Contains(got, "lang=") {
		t.Error("SimpleHTMLPage without language should not have lang attribute")
	}
}

func TestHTMLLink(t *testing.T) {
	got := HTMLLink("docs", "docs", true)
	if !strings.Contains(got, "docs/") {
		t.Error("HTMLLink for directory should append slash to text")
	}
	if !strings.Contains(got, `href="/docs/"`) {
		t.Error("HTMLLink for directory should append slash to URL")
	}

	got = HTMLLink("file.txt", "file.txt", false)
	if strings.HasSuffix(got, "/") {
		t.Error("HTMLLink for file should not append slash")
	}
}

// Filenames with newlines or spaces must produce a valid percent-encoded href, see issue #144.
func TestHTMLLinkWithBase(t *testing.T) {
	tests := []struct {
		baseURL string
		urlPath string
		want    string
	}{
		{"", "file.txt", "/file.txt"},
		{"/files", "file.txt", "/files/file.txt"},
		{"/files/", "file.txt", "/files/file.txt"},
		{"https://example.com/pub", "file.txt", "https://example.com/pub/file.txt"},
		{"https://example.com/", "sub/a b.txt", "https://example.com/sub/a%20b.txt"},
		{"/", "file.txt", "/file.txt"},
	}
	for _, tt := range tests {
		got := HTMLLinkWithBase("file.txt", tt.baseURL, tt.urlPath, false)
		want := "href=\"" + tt.want + "\""
		if !strings.Contains(got, want) {
			t.Errorf("HTMLLinkWithBase(baseURL=%q, urlPath=%q) = %q, want it to contain %q", tt.baseURL, tt.urlPath, got, want)
		}
	}
	// A base URL must not change the trailing slash for directories
	if got := HTMLLinkWithBase("docs", "/files", "docs", true); !strings.Contains(got, "href=\"/files/docs/\"") {
		t.Errorf("HTMLLinkWithBase for a directory = %q, want it to end the URL with a slash", got)
	}
}

func TestHTMLLinkEncodesSpecialBytes(t *testing.T) {
	got := HTMLLink("file\nname.txt", "file\nname.txt", false)
	if !strings.Contains(got, `href="/file%0Aname.txt"`) {
		t.Errorf("Expected newline to be percent-encoded in href, got: %s", got)
	}

	got = HTMLLink("a b.txt", "a b.txt", false)
	if !strings.Contains(got, `href="/a%20b.txt"`) {
		t.Errorf("Expected space to be percent-encoded in href, got: %s", got)
	}

	got = HTMLLink("sub/file.txt", "sub/file.txt", false)
	if !strings.Contains(got, `href="/sub/file.txt"`) {
		t.Errorf("Expected forward slashes to be preserved, got: %s", got)
	}
}

func TestStyleHTML(t *testing.T) {
	html := []byte("<html><head></head><body><p>hi</p></body></html>")
	got := StyleHTML(html, "style.css")
	if !strings.Contains(string(got), `href="style.css"`) {
		t.Error("StyleHTML should inject stylesheet link")
	}

	// Already present: should not duplicate
	got2 := StyleHTML(got, "style.css")
	if strings.Count(string(got2), "style.css") != 1 {
		t.Error("StyleHTML should not duplicate existing stylesheet")
	}
}

func TestInsertDoctype(t *testing.T) {
	// Missing doctype
	html := []byte("<html>\n<head>\n<title>hi</title>\n</head>\n<body></body></html>")
	got := InsertDoctype(html)
	if !strings.HasPrefix(string(got), "<!doctype html>") {
		t.Error("InsertDoctype should prepend doctype")
	}

	// Already has doctype
	html2 := []byte("<!DOCTYPE html>\n<html>\n<body></body></html>")
	got2 := InsertDoctype(html2)
	if strings.Count(string(got2), "doctype") > 1 && strings.Count(string(got2), "DOCTYPE") > 1 {
		t.Error("InsertDoctype should not add doctype if already present")
	}
}

func TestNoPage(t *testing.T) {
	got := string(NoPage("missing.html", "dark"))
	if !strings.Contains(got, "missing.html") {
		t.Error("NoPage should contain the filename")
	}
	if !strings.Contains(got, "Not found") {
		t.Error("NoPage should contain 'Not found'")
	}
}