Discovery is the three PROPFINDs RFC 4791 describes rather than a walk through likely URLs. Queries use time-range, which v1 never did -- it fetched whole calendars and filtered in the browser on every view change. Every write states a precondition, so a stale ETag produces a Conflict a caller can act on instead of silently destroying somebody's edit. XML goes through quick-xml with namespace resolution. v1 matched prefixes with six regexes tried in sequence and recompiled inside the loop; there is a fixture here that is the same document under different prefixes, and it parses identically. Protocol parsing is split from transport so it can be tested against responses recorded from a real Baikal -- including the second propstat carrying 404s, which is what makes "this calendar has no colour" different from "this calendar has an empty colour". Live tests run against a real server, never a mock. tests/baikal/run.sh starts a container, walks Baikal's install wizard, and runs them; each test builds and destroys its own collection, so pointing it at a real server touches nothing that was already there. They cover discovery, round-trip, stale-ETag conflict, duplicate create, delete, time-range filtering, a series returned whole with its override, and writing every synthetic golden fixture to the server and reading it back. libdav was evaluated first, as planned. Not adopted: its HttpClient trait is defined over hyper::body::Incoming, so using it means replacing reqwest everywhere, plus a DNS resolver for service discovery we do not do and a second XML parser. Its precondition design is where Precondition's shape comes from. Reasons are recorded in the crate docs.
54 lines
1.6 KiB
Bash
Executable File
54 lines
1.6 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Run the CalDAV integration tests against a throwaway Baikal.
|
|
#
|
|
# Starts a container, walks it through the install wizard, runs the live test
|
|
# suite against it, and tears it down again. Nothing touches a real calendar.
|
|
#
|
|
# crates/runway-caldav/tests/baikal/run.sh # start, test, stop
|
|
# KEEP=1 crates/runway-caldav/tests/baikal/run.sh # leave it running
|
|
set -euo pipefail
|
|
|
|
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
NAME="${NAME:-runway-baikal}"
|
|
PORT="${PORT:-8800}"
|
|
IMAGE="${IMAGE:-docker.io/ckulka/baikal:nginx}"
|
|
USERNAME="testuser"
|
|
PASSWORD="testpassword"
|
|
|
|
runtime() {
|
|
if command -v podman >/dev/null 2>&1; then echo podman
|
|
elif command -v docker >/dev/null 2>&1; then echo docker
|
|
else echo "need podman or docker" >&2; exit 1
|
|
fi
|
|
}
|
|
RUNTIME="$(runtime)"
|
|
|
|
cleanup() {
|
|
if [ "${KEEP:-0}" != "1" ]; then
|
|
"$RUNTIME" rm -f "$NAME" >/dev/null 2>&1 || true
|
|
else
|
|
echo "container $NAME left running on port $PORT"
|
|
fi
|
|
}
|
|
trap cleanup EXIT
|
|
|
|
"$RUNTIME" rm -f "$NAME" >/dev/null 2>&1 || true
|
|
"$RUNTIME" run -d --rm --name "$NAME" -p "$PORT:80" "$IMAGE" >/dev/null
|
|
echo "started $NAME ($IMAGE) on port $PORT"
|
|
|
|
# Baikal needs a moment before PHP answers.
|
|
for _ in $(seq 1 60); do
|
|
if [ "$(curl -sS -o /dev/null -w '%{http_code}' -L "http://localhost:$PORT/" 2>/dev/null)" = "200" ]; then
|
|
break
|
|
fi
|
|
sleep 1
|
|
done
|
|
|
|
python3 "$HERE/setup.py" "http://localhost:$PORT" "$USERNAME" "$PASSWORD"
|
|
|
|
export RUNWAY_CALDAV_URL="http://localhost:$PORT/dav.php/"
|
|
export RUNWAY_CALDAV_USER="$USERNAME"
|
|
export RUNWAY_CALDAV_PASSWORD="$PASSWORD"
|
|
|
|
cargo test -p runway-caldav --test live -- --test-threads=1 "$@"
|