Skip to content

fix(e2e): mock gutendex.com to fix flaky E2E write tests#608

Merged
vincentchalamon merged 8 commits into4.3from
fix/mock-gutendex-e2e
Mar 18, 2026
Merged

fix(e2e): mock gutendex.com to fix flaky E2E write tests#608
vincentchalamon merged 8 commits into4.3from
fix/mock-gutendex-e2e

Conversation

@vincentchalamon
Copy link
Contributor

Summary

  • The BookCreate and BookEdit E2E @write tests intermittently fail because they depend on the external gutendex.com API (both browser-side for autocomplete and server-side for book URL validation via BookUrlValidatorGutendexBookRepository)
  • When gutendex.com is slow or unreachable, the PHP backend returns a validation error → React Admin stays on the form → the expect(page.getByLabel("Book Reference")).not.toBeAttached() assertion fails
  • This was already observable on 4.3 push runs #605 and #606, as well as multiple scheduled runs

Changes

Adds gutendex.com mocking following the same pattern already used for openlibrary.org:

  • compose.e2e.yaml: add gutendex.com as a Docker network alias to the mock server + disable TLS peer verification for the PHP container via HTTP_CLIENT_VERIFY_PEER=0
  • e2e/mock-server/server.js: add gutendex.com to the self-signed certificate SAN + add routing for gutendex search endpoint (/books?search=)
  • e2e/tests/admin/pages/AbstractPage.ts: add Playwright page.route() browser-level mocks for gutendex search and individual book URLs
  • e2e/tests/mocks/gutendex.com/: mock JSON fixtures for Asimov search results and individual book data
  • api/config/packages/framework.yaml + api/.env: parameterize verify_peer/verify_host on open_library.client and gutendex.client via HTTP_CLIENT_VERIFY_PEER env var (defaults to 1 / enabled)

Test plan

  • E2E @write tests pass in CI (no more dependency on external gutendex.com)
  • E2E @read tests still pass
  • PHP unit tests still pass
  • Lint still passes

🤖 Generated with Claude Code

vincentchalamon and others added 8 commits March 18, 2026 10:10
The BookCreate and BookEdit E2E tests depend on the external
gutendex.com API for both browser-side autocomplete and server-side
book URL validation. When gutendex.com is slow or unreachable,
the tests fail intermittently.

This adds gutendex.com mocking following the same pattern already
used for openlibrary.org:
- Docker network alias in compose.e2e.yaml
- HTTPS mock server routing for gutendex search/book endpoints
- Playwright browser-level route mocks in AbstractPage
- Mock JSON fixtures for Asimov search results
- Parameterized TLS verify_peer for PHP scoped HTTP clients

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
MUI Autocomplete triggers onInputChange with the full selected label
(e.g. "Let's Get Together - Asimov, Isaac") which fires a new search.
Return the same Asimov results for any gutendex search query.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The %env(bool:...)% approach doesn't work because the Symfony DI
container is compiled at Docker build time with verify_peer: true.

Instead, mount the mock server's self-signed certificate into the
PHP container and append it to the system CA bundle via SSL_CERT_FILE.
This lets PHP's cURL trust the mock gutendex.com without changing
any Symfony configuration.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The mock server generates the cert at startup. The PHP container
needs to wait for it to exist before concatenating it to the CA bundle.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Instead of overriding the PHP entrypoint (which broke the container),
generate the mock server certificate on the CI host before starting
services, then run update-ca-certificates inside the PHP container
after it's up. The mock server reuses the pre-generated cert.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
BookRemoveProcessor now deletes bookmarks and reviews referencing the
book before removing it, preventing a ForeignKeyConstraintViolation
on the bookmark table.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The Bookmark entity has onDelete: 'CASCADE' on the book relation but
the migration never added ON DELETE CASCADE to the actual FK constraint.
This caused a ForeignKeyConstraintViolationException when deleting a
book that had bookmarks.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@vincentchalamon vincentchalamon merged commit 723e25f into 4.3 Mar 18, 2026
7 checks passed
@vincentchalamon vincentchalamon deleted the fix/mock-gutendex-e2e branch March 18, 2026 11:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant