Files
CASAN/packages/casan-devkit/tests/adoption-install-tests.sh
T

84 lines
3.4 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
DEVKIT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
WORK="$(mktemp -d)"
trap 'rm -rf "$WORK"' EXIT
TARGET="$WORK/existing-project"
mkdir -p "$TARGET/.github"
printf '# Existing agent rules\n' > "$TARGET/AGENTS.md"
printf '# Existing Claude rules\n' > "$TARGET/CLAUDE.md"
printf '# Existing Copilot rules\n' > "$TARGET/.github/copilot-instructions.md"
install_project() {
bash "$DEVKIT_ROOT/install.sh" \
--target "$TARGET" \
--project sample-project \
--domain "Sample Project" >/dev/null
}
install_project
python3 - "$TARGET" <<'PY'
import json, pathlib, sys
root = pathlib.Path(sys.argv[1])
policy = json.loads((root / ".casan/prompt-policy.json").read_text(encoding="utf-8"))
assert policy["mode"] == "enforced"
assert policy["project_id"] == "sample-project"
assert policy["domain_root"] == "apps/sample-project/domain"
for relative in ("AGENTS.md", "CLAUDE.md", ".github/copilot-instructions.md"):
text = (root / relative).read_text(encoding="utf-8")
assert "Existing" in text
assert text.count("CASAN_PROMPT_ENFORCEMENT_START") == 1
workflow = (root / ".gitea/workflows/casan-prompt-enforcement.yml").read_text(encoding="utf-8")
assert "CASAN prompt enforcement contract" in workflow
assert 'CASAN_PROJECT_ID: "sample-project"' in workflow
assert "__PROJECT_ID__" not in workflow
assert (root / "bin/casan-chat").exists()
assert (root / "bin/casan-chat.ps1").exists()
assert not (root / "packages/casan-harness/tests").exists()
assert not (root / "packages/casan-harness/level5").exists()
assert not (root / "packages/casan-harness/scripts/bash/ci-harness-gate.sh").exists()
for relative in ("docs/casan/CASAN_ADOPTION_WINDOWS.md", "docs/casan/CASAN_PROMPT_ENFORCEMENT.md"):
text = (root / relative).read_text(encoding="utf-8")
assert "sample-project" in text
assert "Sample Project" in text or relative.endswith("CASAN_PROMPT_ENFORCEMENT.md")
assert "__PROJECT_ID__" not in text and "__PROJECT_NAME__" not in text
PY
(cd "$TARGET" && bin/casan prompt verify) | grep -q 'CASAN_PROMPT_ENFORCEMENT_VALID project=sample-project'
# A second adoption run upgrades managed files without duplicating instruction blocks.
install_project
python3 - "$TARGET" <<'PY'
import pathlib, sys
root = pathlib.Path(sys.argv[1])
for relative in ("AGENTS.md", "CLAUDE.md", ".github/copilot-instructions.md"):
assert (root / relative).read_text(encoding="utf-8").count("CASAN_PROMPT_ENFORCEMENT_START") == 1
PY
# Managed-file tampering must fail closed before a prompt reaches chat-turn.
python3 - "$TARGET/CLAUDE.md" <<'PY'
import pathlib, sys
path = pathlib.Path(sys.argv[1])
path.write_text(path.read_text(encoding="utf-8").replace("CASAN_PROMPT_ENFORCEMENT_START", "REMOVED_MARKER"), encoding="utf-8")
PY
set +e
(cd "$TARGET" && bin/casan prompt verify >"$WORK/tamper.out" 2>&1)
TAMPER_RC=$?
set -e
if [[ "$TAMPER_RC" -ne 2 ]] || ! grep -q 'managed_marker_missing:CLAUDE.md' "$WORK/tamper.out"; then
echo "adoption-install-tests: tampered contract was accepted" >&2
cat "$WORK/tamper.out" >&2
exit 1
fi
# New-project scaffolding must continue into the same enforcement installation.
FRESH="$WORK/fresh-project"
bash "$DEVKIT_ROOT/install.sh" --target "$FRESH" --project fresh-app \
--domain "Fresh App" --template nestjs-react >/dev/null
(cd "$FRESH" && bin/casan prompt verify) | grep -q 'CASAN_PROMPT_ENFORCEMENT_VALID project=fresh-app'
test -f "$FRESH/apps/fresh-app/frontend/package.json"
echo "ADOPTION_INSTALL_TESTS_PASS"