feat(cache): Tool lit/cache-clear zum gezielten Leeren des Caches

lit/cache-clear leert den Seiten-Cache von WP Super Cache für die ganze Website (scope all, Recht manage_options) oder einen Beitrag (scope post, Recht edit_post); Probelauf ohne confirm, Ausführen mit confirm: true. Das CapabilityGate sperrt das Tool, wenn WP Super Cache bricht; eine Sperre zur Laufzeit wird als Fehler gemeldet. Listener und Tool teilen die 30-s-Drosselung mit Nachlauf (SuperCachePurger); der Listener ignoriert die Einträge des Tools. Behoben vor dem Commit: die Verdrahtung des Purgers erfasste die Registry zu früh (immer gesperrt), jetzt per Referenz und mit Test über Plugin::integrations().

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Jan-Niclas Loosen
2026-11-06 19:05:21 +01:00
co-authored by Claude Opus 5.5
parent d3e5d4fac0
commit 1ac347e76f
12 changed files with 883 additions and 86 deletions
+41
View File
@@ -295,6 +295,47 @@ cache_file_gone || fail "the trailing purge did not empty the cache"
[ "$(wp transient get "$PURGED_AT")" -gt "$LAST" ] || fail "the trailing purge must store a new purge time"
pass "trailing purge by cron: cache emptied, event gone, purge time renewed"
# 8b. lit/cache-clear: the dry run changes nothing, confirm empties the post's page / the whole cache
fill_cache
for ARGS in "{\"scope\":\"post\",\"post_id\":$POST_ID}" '{"scope":"all"}'; do
DRY=$(ability lit/cache-clear "$ARGS")
[ "$(error_code "$DRY")" = confirm_required ] || fail "lit/cache-clear dry run $ARGS must ask for confirm: $DRY"
echo "$DRY" | jq -e '(.__error | fromjson | .cache_enabled) == true' >/dev/null || fail "dry run must report the cache as on: $DRY"
done
sleep 2
cache_file_exists || fail "the dry runs of lit/cache-clear emptied the cache"
[ "$(event_count)" = 0 ] || fail "a dry run must not schedule anything"
pass "lit/cache-clear without confirm: asks for confirmation, reports the cache as on, cache file stays"
CLEARED=$(ability lit/cache-clear "{\"scope\":\"post\",\"post_id\":$POST_ID,\"confirm\":true}")
echo "$CLEARED" | jq -e '.ok == true and .outcome == "purged" and .log_id != null' >/dev/null || fail "lit/cache-clear post: $CLEARED"
wait_for "the cache file of the post is gone after lit/cache-clear scope post" cache_file_gone
[ "$(event_count)" = 0 ] || fail "a single-post purge must not schedule a trailing purge"
pass "lit/cache-clear scope post with confirm: the page of the post is emptied"
# The whole-cache purge needs the lock time of the earlier steps to be over.
WAIT=$(($(wp transient get "$PURGED_AT") + 32 - $(date +%s))); [ "$WAIT" -gt 0 ] && sleep "$WAIT"
fill_cache
CLEARED=$(ability lit/cache-clear '{"scope":"all","confirm":true}')
echo "$CLEARED" | jq -e '.ok == true and .outcome == "purged" and .log_id != null' >/dev/null || fail "lit/cache-clear all: $CLEARED"
wait_for "the cache is empty after lit/cache-clear scope all" cache_file_gone
sleep 2
# Its own change log entry must not purge a second time (that would be throttled and leave a trailing event).
[ "$(event_count)" = 0 ] || fail "the change log entry of lit/cache-clear triggered a second purge"
LAST=$(wp transient get "$PURGED_AT")
pass "lit/cache-clear scope all with confirm: whole cache emptied once, own log entry purges nothing"
fill_cache
THROTTLED=$(ability lit/cache-clear '{"scope":"all","confirm":true}')
echo "$THROTTLED" | jq -e '.ok == true and .outcome == "throttled"' >/dev/null || fail "lit/cache-clear all inside the lock time: $THROTTLED"
[ "$(event_count)" = 1 ] || fail "a throttled lit/cache-clear must schedule exactly one trailing purge"
cache_file_exists || fail "throttled: the cache file must stay"
[ "$(wp transient get "$PURGED_AT")" = "$LAST" ] || fail "a throttled purge must not move the purge time"
WAIT=$((LAST + 32 - $(date +%s))); [ "$WAIT" -gt 0 ] && sleep "$WAIT"
wp cron event run "$TRAILING_HOOK" >/dev/null 2>&1 || fail "wp cron event run $TRAILING_HOOK"
cache_file_gone || fail "the trailing purge did not empty the cache"
pass "lit/cache-clear scope all inside 30 s: throttled, one trailing event, cron run empties the cache"
# 9. Everything back as before (the EXIT trap would do it too; here it is part of the verdict)
restore
verify_restored || fail "the state before the run was not restored"