#!/usr/bin/env bash
# Checks the parts of scripts/lib/post.sh that are awkward to get right and
# expensive to get wrong: which commits a pair of release ids means, and how a
# changelog that does not fit in a post is broken into a thread. Run it by
# hand; it touches nothing outside a temporary directory and talks to no PDS.
#
# bash scripts/lib/post.test.sh
set -euo pipefail
source "$(dirname "$0")/post.sh"
failures=0
check() {
local what="$1" want="$2" got="$3"
if [ "$want" = "$got" ]; then
echo "ok - $what"
else
echo "FAIL - $what"
echo " want: $(printf '%q' "$want")"
echo " got: $(printf '%q' "$got")"
failures=$((failures + 1))
fi
}
# A commit id is the last dash-separated field of a release id, whatever the
# build put in front of it.
check "plain release id" "a7b1f59e8e3b" "$(release_commit main-a7b1f59e8e3b)"
check "arena's longer id" "b812ae202e32" \
"$(release_commit mm0.51.0-sur26.4.7-main-b812ae202e32)"
check "not a commit" "1" "$(release_commit v1.2.3 >/dev/null || echo 1)"
check "too short" "1" "$(release_commit main-abc >/dev/null || echo 1)"
check "api is headquarters" "headquarters" "$(repo_for api)"
check "an unknown key has no repo" "1" "$(repo_for proxy >/dev/null || echo 1)"
# A fixture repository, so the changelog is read the way a real one is.
work="$(mktemp -d)"
trap 'rm -rf "$work"' EXIT
git init -q "$work/headquarters"
git -C "$work/headquarters" config user.email test@example.invalid
git -C "$work/headquarters" config user.name test
for subject in "feat(hangar): one" "feat(camo): two" "fix(camo): three"; do
git -C "$work/headquarters" commit -q --allow-empty -m "$subject"
done
shas=()
while IFS= read -r sha; do shas+=("$sha"); done < <(
git -C "$work/headquarters" log --reverse --format=%h
)
changes="$(printf 'site\tmain-%s\tmain-%s\n' \
"$(git -C "$work/headquarters" rev-parse --short=12 "${shas[0]}")" \
"$(git -C "$work/headquarters" rev-parse --short=12 "${shas[2]}")")"
log="$(build_changelog "$work" "$changes")"
check "the header counts the range" "site: 2 commits in headquarters" \
"$(printf '%s\n' "$log" | head -1)"
check "newest commit first" "${shas[2]} fix(camo): three" \
"$(printf '%s\n' "$log" | sed -n 2p)"
# api and site move together on one headquarters build, and that is one range
# under both names rather than the same commits twice.
both="$(printf 'api\tmain-%s\tmain-%s\nsite\tmain-%s\tmain-%s\n' \
"$(git -C "$work/headquarters" rev-parse --short=12 "${shas[0]}")" \
"$(git -C "$work/headquarters" rev-parse --short=12 "${shas[2]}")" \
"$(git -C "$work/headquarters" rev-parse --short=12 "${shas[0]}")" \
"$(git -C "$work/headquarters" rev-parse --short=12 "${shas[2]}")")"
check "one range under both names" "api, site: 2 commits in headquarters" \
"$(build_changelog "$work" "$both" | head -1)"
check "a missing checkout is not fatal" "" \
"$(build_changelog "$work/nowhere" "$changes")"
# A short deploy is one post and no thread.
build_post "site: main-aaaaaaaaaaaa -> main-bbbbbbbbbbbb" "$log" ""
check "the changelog rides in the first post" "1" \
"$(printf '%s' "$ROOT_TEXT" | grep -c 'fix(camo): three')"
check "and there is no thread" "0" "${#CHUNKS[@]}"
# One repo alone can exceed a post, which is what the thread is for.
long="$(
echo "site: 40 commits in headquarters"
for i in $(seq 1 40); do
echo "abc123$i feat(hangar): a subject long enough to be realistic $i"
done
)"
build_post "site: main-aaaaaaaaaaaa -> main-bbbbbbbbbbbb" "$long" ""
check "the first post holds the summary alone" "Deployed lance.blue
site: main-aaaaaaaaaaaa -> main-bbbbbbbbbbbb" "$ROOT_TEXT"
[ "${#CHUNKS[@]}" -gt 1 ] &&
echo "ok - the changelog became a thread of ${#CHUNKS[@]}" ||
{ echo "FAIL - no thread"; failures=$((failures + 1)); }
for i in "${!CHUNKS[@]}"; do
fits "${CHUNKS[$i]}" ||
{ echo "FAIL - post $i is over the limit"; failures=$((failures + 1)); }
done
echo "ok - every post fits"
check "the thread says what it is reading" "site: 40 commits in headquarters" \
"$(printf '%s\n' "${CHUNKS[0]}" | head -1)"
check "and says so again after the break" "site (cont.)" \
"$(printf '%s\n' "${CHUNKS[1]}" | head -1)"
check "no commit is split across posts" "40" \
"$(printf '%s\n' "${CHUNKS[@]}" | grep -c '^abc123')"
# A runaway range is summarised rather than posted.
huge="$(
echo "site: 900 commits in headquarters"
for i in $(seq 1 900); do
echo "abc123$i feat(hangar): a subject long enough to be realistic $i"
done
)"
build_post "site: main-aaaaaaaaaaaa -> main-bbbbbbbbbbbb" "$huge" ""
check "a thread is capped" "$POST_MAX" "${#CHUNKS[@]}"
check "and says what it left out" "1" \
"$(printf '%s\n' "${CHUNKS[-1]}" | grep -c '^\.\.\. and .* more posts')"
# The og: tags the site actually serves, entity and all.
page=''
check "a tag is read" "lance.blue" "$(og_meta "$page" og:title)"
check "entities are decoded" "Salvage & scrap" "$(og_meta "$page" og:description)"
check "a missing tag is empty" "" "$(og_meta "$page" og:image)"
check "the stamp is a query" "https://lance.blue/?d=20260824" \
"$(stamped_link https://lance.blue/ 20260824)"
check "and joins an existing one" "https://lance.blue/?x=1&d=20260824" \
"$(stamped_link 'https://lance.blue/?x=1' 20260824)"
echo
if [ "$failures" -eq 0 ]; then
echo "all good"
else
echo "$failures failed"
exit 1
fi