From 4f49b16079b27d7ce633619e4cddfdf2bffbc952 Mon Sep 17 00:00:00 2001 From: cashmere Date: Fri, 4 Sep 2026 09:05:24 +0200 Subject: initial commit --- tools/copland/tests/fixtures/org/all.html | 50 ++++++ tools/copland/tests/fixtures/org/all.org | 52 ++++++ tools/copland/tests/fixtures/org/all.txt | 66 ++++++++ tools/copland/tests/fixtures/org/security.html | 9 + tools/copland/tests/fixtures/org/security.org | 13 ++ tools/copland/tests/org-renderer.sh | 30 ++++ tools/copland/tests/serve-fixture.sh | 18 ++ tools/copland/tests/smoke.sh | 188 +++++++++++++++++++++ tools/copland/tests/visual.spec.mjs | 94 +++++++++++ .../visual.spec.mjs-snapshots/home-dark-linux.png | Bin 0 -> 21720 bytes .../visual.spec.mjs-snapshots/home-light-linux.png | Bin 0 -> 21117 bytes .../visual.spec.mjs-snapshots/login-dark-linux.png | Bin 0 -> 33606 bytes .../login-light-linux.png | Bin 0 -> 32850 bytes .../org-document-dark-linux.png | Bin 0 -> 68961 bytes .../org-document-light-linux.png | Bin 0 -> 67587 bytes .../org-document-mobile-linux.png | Bin 0 -> 53550 bytes .../org-wiki-dark-linux.png | Bin 0 -> 42595 bytes .../org-wiki-light-linux.png | Bin 0 -> 41174 bytes .../org-wiki-mobile-linux.png | Bin 0 -> 31636 bytes .../repository-list-dark-linux.png | Bin 0 -> 16492 bytes .../repository-list-light-linux.png | Bin 0 -> 15656 bytes .../timeline-dark-linux.png | Bin 0 -> 46898 bytes .../timeline-light-linux.png | Bin 0 -> 45662 bytes .../timeline-mobile-linux.png | Bin 0 -> 35066 bytes .../visual.spec.mjs-snapshots/tree-dark-linux.png | Bin 0 -> 50142 bytes .../visual.spec.mjs-snapshots/tree-light-linux.png | Bin 0 -> 48683 bytes 26 files changed, 520 insertions(+) create mode 100644 tools/copland/tests/fixtures/org/all.html create mode 100644 tools/copland/tests/fixtures/org/all.org create mode 100644 tools/copland/tests/fixtures/org/all.txt create mode 100644 tools/copland/tests/fixtures/org/security.html create mode 100644 tools/copland/tests/fixtures/org/security.org create mode 100755 tools/copland/tests/org-renderer.sh create mode 100755 tools/copland/tests/serve-fixture.sh create mode 100755 tools/copland/tests/smoke.sh create mode 100644 tools/copland/tests/visual.spec.mjs create mode 100644 tools/copland/tests/visual.spec.mjs-snapshots/home-dark-linux.png create mode 100644 tools/copland/tests/visual.spec.mjs-snapshots/home-light-linux.png create mode 100644 tools/copland/tests/visual.spec.mjs-snapshots/login-dark-linux.png create mode 100644 tools/copland/tests/visual.spec.mjs-snapshots/login-light-linux.png create mode 100644 tools/copland/tests/visual.spec.mjs-snapshots/org-document-dark-linux.png create mode 100644 tools/copland/tests/visual.spec.mjs-snapshots/org-document-light-linux.png create mode 100644 tools/copland/tests/visual.spec.mjs-snapshots/org-document-mobile-linux.png create mode 100644 tools/copland/tests/visual.spec.mjs-snapshots/org-wiki-dark-linux.png create mode 100644 tools/copland/tests/visual.spec.mjs-snapshots/org-wiki-light-linux.png create mode 100644 tools/copland/tests/visual.spec.mjs-snapshots/org-wiki-mobile-linux.png create mode 100644 tools/copland/tests/visual.spec.mjs-snapshots/repository-list-dark-linux.png create mode 100644 tools/copland/tests/visual.spec.mjs-snapshots/repository-list-light-linux.png create mode 100644 tools/copland/tests/visual.spec.mjs-snapshots/timeline-dark-linux.png create mode 100644 tools/copland/tests/visual.spec.mjs-snapshots/timeline-light-linux.png create mode 100644 tools/copland/tests/visual.spec.mjs-snapshots/timeline-mobile-linux.png create mode 100644 tools/copland/tests/visual.spec.mjs-snapshots/tree-dark-linux.png create mode 100644 tools/copland/tests/visual.spec.mjs-snapshots/tree-light-linux.png (limited to 'tools/copland/tests') diff --git a/tools/copland/tests/fixtures/org/all.html b/tools/copland/tests/fixtures/org/all.html new file mode 100644 index 0000000..33fc537 --- /dev/null +++ b/tools/copland/tests/fixtures/org/all.html @@ -0,0 +1,50 @@ +
+

Über & <Fossil>

+ + +

Intro & safety

+

A paragraph with bold, italic, underline, strike, <code>, and verbatim & text. Words_like_this and paths/like/this stay literal.

+ +
    +
  1. one
  2. +
  3. two
  4. +
+ + + + + + + + +
NameValue
α<tag>
twobold
+
{ pkgs, ... }: <unsafe> & value
+
example <script>alert(1)</script>
+

external relative internal unsafe

+

Duplicate

+

Text.

+

Duplicate

+

More.

+

日本語

+

Unicode heading.

+
+ diff --git a/tools/copland/tests/fixtures/org/all.org b/tools/copland/tests/fixtures/org/all.org new file mode 100644 index 0000000..f5c644a --- /dev/null +++ b/tools/copland/tests/fixtures/org/all.org @@ -0,0 +1,52 @@ +#+TITLE: Über & +#+AUTHOR: Ada +#+DATE: 2026-08-21 +#+OPTIONS: toc:2 num:nil +#+STARTUP: overview + +:PROPERTIES: +:ID: hidden +:END: + +* Intro & safety + +A paragraph with *bold*, /italic/, _underline_, +strike+, ~~, and +=verbatim & text=. Words_like_this and paths/like/this stay literal. + +- first + - nested *item* + 1. nested ordered +- second + +1. one +2. two + +| Name | Value | +|------+-------| +| α | | +| two | *bold* | + +#+begin_src nix +{ pkgs, ... }: & value +#+end_src + +#+begin_example +example +#+end_example + +[[https://example.test/a?x=1&y=2][external]] +[[file:guide.org][relative]] +[[*Intro & safety][internal]] +[[javascript:alert(1)][unsafe]] + +** Duplicate + +Text. + +* Duplicate + +More. + +* 日本語 + +Unicode heading. diff --git a/tools/copland/tests/fixtures/org/all.txt b/tools/copland/tests/fixtures/org/all.txt new file mode 100644 index 0000000..266ab90 --- /dev/null +++ b/tools/copland/tests/fixtures/org/all.txt @@ -0,0 +1,66 @@ +Über & + + + +AuthorAda +Date2026-08-21 + + + +Contents + +Intro & safety +Duplicate +Duplicate +日本語 + + + +Intro & safety + +A paragraph with bold, italic, underline, strike, , and verbatim & text. Words_like_this and paths/like/this stay literal. + +first +nested item + + +nested ordered + + +second + + +one +two + + + + + +NameValue + + + +α +twobold + + + +{ pkgs, ... }: & value + +example + +external relative internal unsafe + +Duplicate + +Text. + +Duplicate + +More. + +日本語 + +Unicode heading. + diff --git a/tools/copland/tests/fixtures/org/security.html b/tools/copland/tests/fixtures/org/security.html new file mode 100644 index 0000000..38707e0 --- /dev/null +++ b/tools/copland/tests/fixtures/org/security.html @@ -0,0 +1,9 @@ +
+

<img src=x onerror=alert(1)>

+

Raw <script>alert(1)</script> and "quotes".

+

attribute file scheme confusion

+
<img src=x onerror=alert(1)>
+
echo "unterminated and escaped <tag>"
+
+
+ diff --git a/tools/copland/tests/fixtures/org/security.org b/tools/copland/tests/fixtures/org/security.org new file mode 100644 index 0000000..3e7280a --- /dev/null +++ b/tools/copland/tests/fixtures/org/security.org @@ -0,0 +1,13 @@ +#+TITLE: + +Raw and "quotes". + +[[https://example.test/" onmouseover="alert(1)][attribute]] +[[file:javascript:alert(1)][file scheme confusion]] + +#+begin_export html + +#+end_export + +#+begin_src sh +echo "unterminated and escaped " diff --git a/tools/copland/tests/org-renderer.sh b/tools/copland/tests/org-renderer.sh new file mode 100755 index 0000000..1822d52 --- /dev/null +++ b/tools/copland/tests/org-renderer.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash +set -euo pipefail + +root_dir=$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd) +source "$root_dir/scripts/fossil-env.sh" +fixture_dir="$root_dir/tests/fixtures/org" +output_dir=$(mktemp -d -t copland-org-renderer.XXXXXX) + +for fixture in all security; do + "$FOSSIL" test-org-render "$fixture_dir/$fixture.org" >"$output_dir/$fixture.html" + diff -u "$fixture_dir/$fixture.html" "$output_dir/$fixture.html" +done + +"$FOSSIL" test-org-render --text "$fixture_dir/all.org" >"$output_dir/all.txt" +diff -u "$fixture_dir/all.txt" "$output_dir/all.txt" + +sed 's/$/\r/' "$fixture_dir/all.org" >"$output_dir/all-crlf.org" +"$FOSSIL" test-org-render "$output_dir/all-crlf.org" >"$output_dir/all-crlf.html" +diff -u "$fixture_dir/all.html" "$output_dir/all-crlf.html" + +if rg -n ']*onerror|href="javascript:' "$output_dir"/*.html; then + printf 'Unsafe active HTML escaped into Org renderer output.\n' >&2 + exit 1 +fi +if ! rg -q '<script>|<img' "$output_dir/security.html"; then + printf 'Escaped security fixture content is missing.\n' >&2 + exit 1 +fi + +printf 'Org renderer golden and security tests passed.\n' diff --git a/tools/copland/tests/serve-fixture.sh b/tools/copland/tests/serve-fixture.sh new file mode 100755 index 0000000..7f2bc8d --- /dev/null +++ b/tools/copland/tests/serve-fixture.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash +set -euo pipefail + +root_dir=$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd) +source "$root_dir/scripts/fossil-env.sh" +fixture_dir=$(mktemp -d -t copland-visual.XXXXXX) +port=${COPLAND_TEST_PORT:-18082} + +require_org_fossil +"$root_dir/scripts/create-demo.sh" "$fixture_dir" +verify_org_mime "$fixture_dir/repositories/alpha.fossil" + +FOSSIL_REPOLIST_TITLE=Copland exec "$FOSSIL" server \ + --localhost \ + --localauth \ + --port "$port" \ + --repolist \ + "$fixture_dir/repositories" diff --git a/tools/copland/tests/smoke.sh b/tools/copland/tests/smoke.sh new file mode 100755 index 0000000..bd54bab --- /dev/null +++ b/tools/copland/tests/smoke.sh @@ -0,0 +1,188 @@ +#!/usr/bin/env bash +set -euo pipefail + +root_dir=$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd) +source "$root_dir/scripts/fossil-env.sh" +test_dir=$(mktemp -d -t copland-smoke.XXXXXX) +port=${COPLAND_TEST_PORT:-18081} +server_pid="" + +finish() { + if [[ -n "$server_pid" ]]; then + kill "$server_pid" 2>/dev/null || true + wait "$server_pid" 2>/dev/null || true + fi +} +trap finish EXIT INT TERM + +require_org_fossil +"$root_dir/scripts/create-demo.sh" "$test_dir" +verify_org_mime "$test_dir/repositories/alpha.fossil" +"$FOSSIL" sql -R "$test_dir/repositories/alpha.fossil" \ + "REPLACE INTO config(name,value,mtime) VALUES('doc-glob','*.org',unixepoch());" +"$FOSSIL" fts-config enable document -R "$test_dir/repositories/alpha.fossil" >/dev/null +"$FOSSIL" fts-config enable wiki -R "$test_dir/repositories/alpha.fossil" >/dev/null +"$FOSSIL" fts-config index on -R "$test_dir/repositories/alpha.fossil" >/dev/null +"$FOSSIL" fts-config reindex -R "$test_dir/repositories/alpha.fossil" >/dev/null + +FOSSIL_REPOLIST_TITLE=Copland "$FOSSIL" server \ + --localhost \ + --localauth \ + --port "$port" \ + --repolist \ + "$test_dir/repositories" >"$test_dir/server.log" 2>&1 & +server_pid=$! + +base_url="http://127.0.0.1:$port" +for attempt in $(seq 1 50); do + if curl --fail --location --silent "$base_url/" >/dev/null; then + break + fi + if [[ "$attempt" -eq 50 ]]; then + printf 'Fossil server did not start.\n' >&2 + sed -n '1,120p' "$test_dir/server.log" >&2 + exit 1 + fi + sleep 0.1 +done + +paths=( + "/" + "/alpha/home" + "/alpha/timeline" + "/alpha/tree?ci=tip" + "/alpha/dir?ci=tip" + "/alpha/brlist" + "/alpha/taglist" + "/alpha/wiki" + "/alpha/wiki?name=Org%20Wiki" + "/alpha/wikiedit?name=New%20Org%20Page" + "/alpha/whistory?name=Org%20Wiki" + "/alpha/reportlist" + "/alpha/forum" + "/alpha/login" + "/alpha/sitemap" + "/alpha/doc/tip/docs/org-support.org" + "/alpha/file?name=docs/org-support.org&ci=tip" + "/alpha/file?name=docs/org-support.org&ci=tip&txt=1" + "/alpha/search?s=Native%20Org%20preview&y=d" + "/alpha/search?s=deployment%20guide&y=w" +) + +for path in "${paths[@]}"; do + body=$(curl --fail --location --silent --show-error "$base_url$path") + if [[ "$body" != *"Copland"* ]]; then + printf 'Copland marker missing from %s\n' "$path" >&2 + exit 1 + fi + if [[ "$body" == *"thmainError"* ]]; then + printf 'TH1 template error on %s\n' "$path" >&2 + exit 1 + fi + if [[ "$path" == "/" && ("$body" != *"Alpha"* || "$body" != *"Beta"*) ]]; then + printf 'Demo repositories missing from repository list\n' >&2 + exit 1 + fi + if [[ "$path" == "/alpha/home" ]]; then + mainmenu=${body#*'