# ITERAS cache-busting test harness

End-to-end tests for the `paywall_prevent_caching` feature added in 1.8.4.
The tests verify that the plugin emits the right HTTP cache-busting signals
(`Cache-Control`, `Pragma`, `Vary`, `X-LiteSpeed-Cache-Control`, `X-Accel-Expires`,
`DONOTCACHEPAGE`) on paywalled posts and feeds, and leaves unpaywalled responses
fully cacheable.

## Prerequisites

- A running WordPress install with this plugin active.
- `wp-cli` on `PATH`.
- `curl`, `php` (CLI), `bash`.
- Permalinks enabled (Settings → Permalinks, anything other than "Plain").
- For the cache-plugin matrix: write access to `wp-content/plugins/` and
  `wp-content/cache/`.

## Configuration

Either export environment variables before running, or create a
`tests/.env` file that `lib.sh` will source:

```sh
SITE_URL=http://localhost:8080
WP_PATH=/Users/lau/code/projects/iteras-plugin/wordpress-plugin-svn/trunk/wordpress
SIGNING_KEY=test-signing-key-1234567890abcdef
PAYWALL_ID=test-paywall
```

The harness backs up the existing `iteras_settings` option before overwriting
it, and restores it on exit (including SIGINT).

## Running

```sh
# Core scenarios only:
bash tests/test-cache-busting.sh

# Core scenarios plus the cache-plugin matrix:
bash tests/test-with-cache-plugin.sh
```

Exit status is non-zero if any scenario fails. Failure lines are summarised
at the end of the run.

## What is and isn't tested automatically

Automated:

- `Cache-Control` / `Pragma` / `Vary` / `X-LiteSpeed-Cache-Control` /
  `X-Accel-Expires` headers on paywalled and unpaywalled posts.
- Feeds: precise per-request handling (feed with no paywalled posts is
  cacheable; feed with one or more paywalled posts is not).
- The `iteras_override_content_paywall` filter is honored by both the early
  cache decision and the existing `the_content` truncation, and the filter
  is invoked exactly twice per GET (template_redirect + the_content).
- Body truncation behavior across SSV on/off, valid/expired/bad cookies,
  and empty signing key.
- Cache plugins: WP Super Cache, W3 Total Cache, Cache Enabler, WP Fastest
  Cache. Each is installed, activated, configured to cache pages, then we
  verify the unpaywalled control post lands in the cache directory while
  the paywalled post does not.

Not automated (verify manually):

- **WP Rocket** (paid). Run `test-cache-busting.sh` against a site with WP
  Rocket active and page caching enabled; verify the "not cached" debug
  footer comment reflects our `DONOTCACHEPAGE`.
- **LiteSpeed Cache** (needs a LiteSpeed-aware server, e.g. OpenLiteSpeed).
  Verify `X-LiteSpeed-Cache: miss` on every fetch of the paywalled post.
- **Cloudflare** in front of a staging site. Verify `cf-cache-status: BYPASS`
  or `DYNAMIC` on the paywalled URL.
- **Varnish** in front of a staging site. Default VCL respects
  `Cache-Control: private`; verify with `varnishlog`.

## File layout

```
tests/
  README.md
  lib.sh                    shared helpers (assertions, cookie generator,
                            fixtures, settings backup/restore, post fixtures)
  test-cache-busting.sh     main test runner
  test-with-cache-plugin.sh runs test-cache-busting.sh per cache plugin
  fixtures/
    override-filter.php     mu-plugin: counts iteras_override_content_paywall
                            invocations and forces "override-off" behavior on
                            one test post
```
