Replace Rust E2E mock tests with Bun lifecycle test books#14
Conversation
Remove 103 wiremock-based Rust E2E tests and replace with 7 Bun test books that exercise full resource lifecycles (create → get → list → update → delete) against the live bunny.net API with snapshot testing. Test books: auth, pull-zone, dns-zone, storage-zone, stream, script, shield — covering all CLI commands and flags except containers (deferred) and stream video (requires real video files). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix cleanupFns.reverse() mutating in place — use spread copy - Document shared cleanup singleton assumption in helpers.ts - Remove empty [dev-dependencies] section from Cargo.toml - Pin @types/bun to ^1.3.11 instead of "latest" - Add trailing newline to Bugs.md - Sync roadmap per-test-book checklists with implementation Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR replaces the prior Rust wiremock-based CLI E2E suite with Bun “test books” that run ordered, stateful lifecycle tests against the live bunny.net API, using snapshots to lock output shapes while keeping crate-level wiremock tests intact.
Changes:
- Removed the Rust E2E harness (wiremock + assert_cmd + predicates), its helpers, and the report script.
- Added Bun-based lifecycle “test books” in
testbooks/with a shared CLI runner + cleanup registry and initial snapshots. - Updated roadmap/knowledgebase docs and trimmed Rust dev-dependencies accordingly.
Reviewed changes
Copilot reviewed 30 out of 33 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| tools/e2e-report.sh | Removed mock E2E report generator script. |
| tests/e2e_support/server.rs | Removed wiremock server helper. |
| tests/e2e_support/mod.rs | Removed E2E support module and live-mode skip macro. |
| tests/e2e_support/cmd.rs | Removed assert_cmd-based CLI runner for mock server/live mode. |
| tests/e2e_stream.rs | Removed stream CLI mock E2E tests. |
| tests/e2e_storage_zone.rs | Removed storage-zone CLI mock E2E tests. |
| tests/e2e_storage.rs | Removed storage file-operation CLI mock E2E tests. |
| tests/e2e_shield.rs | Removed shield CLI mock E2E tests. |
| tests/e2e_script.rs | Removed script CLI mock E2E tests. |
| tests/e2e_pull_zone.rs | Removed pull-zone CLI mock E2E tests. |
| tests/e2e_global.rs | Removed global CLI mock tests (help/version/errors). |
| tests/e2e_dns.rs | Removed DNS CLI mock E2E tests. |
| tests/e2e_container.rs | Removed container CLI mock E2E tests. |
| tests/e2e_auth.rs | Removed auth CLI mock E2E tests. |
| testbooks/tsconfig.json | Added TypeScript config for Bun testbooks. |
| testbooks/stream.test.ts | Added live lifecycle tests for Stream libraries/collections. |
| testbooks/storage-zone.test.ts | Added live lifecycle tests for storage zones + file ops. |
| testbooks/shield.test.ts | Added live lifecycle tests for shield (zone/WAF/rate-limit/access-list/bot-detection). |
| testbooks/script.test.ts | Added live lifecycle tests for scripts + variables + secrets + releases. |
| testbooks/pull-zone.test.ts | Added live lifecycle tests + basic error cases for pull zones. |
| testbooks/package.json | Added Bun testbooks package metadata and scripts. |
| testbooks/helpers.ts | Added shared Bun harness for invoking the built hoppy binary + cleanup helpers. |
| testbooks/dns-zone.test.ts | Added live lifecycle tests for DNS zones and records (incl. MX). |
| testbooks/bun.lock | Added Bun lockfile for testbooks dependencies. |
| testbooks/auth.test.ts | Added live auth check testbook. |
| testbooks/snapshots/pull-zone.test.ts.snap | Added initial Bun snapshot for pull-zone create response. |
| testbooks/.gitignore | Added testbooks-local ignores (node_modules, caches, env files, etc.). |
| hoppy-knowledgebase/development-roadmap.md | Documented the transition from mock E2E to Bun testbooks and how to run them. |
| hoppy-knowledgebase/Bugs.md | Added a knowledgebase note about a container-app decode error and debug expectations. |
| Cargo.toml | Removed Rust dev-dependencies used only by the deleted mock E2E suite. |
| Cargo.lock | Updated lockfile to reflect removed Rust dev-dependencies. |
| .gitignore | Removed ignores for outputs produced by the deleted E2E report script. |
| .claude/agents/bun-test-engineer.md | Added a Claude agent profile for Bun test engineering. |
You can also share your feedback on Copilot code review. Take the survey.
- Add monotonic counter to testName() to prevent same-millisecond collisions - Add --timeout 60000 to test scripts for live API calls - Move typescript from peerDependencies to devDependencies - Support HOPPY_BIN env var and Windows binary name in helpers - Fix stream.test.ts architecture description to note video is deferred - Update pull-zone error cases checklist entry Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Move 95 JSON fixture files from crate-local tests/fixtures/ to shared
fixtures/{core,storage,stream,shield,compute,containers}/ directory
- Update all include_str! paths in 10 test files to use shared fixtures
- Add read_body() helper to all 6 API client crates that buffers the
response and logs status + body to stderr when --debug is enabled
- Add CAPTURE_FIXTURES=1 mode to Bun test helpers that captures raw API
responses from --debug output and writes them as fixture files
- Add adding-a-feature.md checklist to knowledgebase
- Update development roadmap with fixtures architecture and capture docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Documents the three-layer test architecture (wiremock unit, wiremock CLI, live E2E), shared fixture/mock setup, implementation phases, and test patterns using assert_cmd + insta + wiremock. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Implements phases 1-4 of the Rust E2E rewrite plan: infrastructure (assert_cmd, insta, wiremock dev-deps), shared test helpers, and 88 wiremock-backed integration tests across 8 test files covering auth, pull-zone, storage-zone, storage, DNS, stream, script, and shield. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Delete 3 fabricated fixture files (pullzone_create, shield_zone_create, dnsrecord_add_mx) and update tests to use only real captured fixtures. Add 7 missing tests to match Bun coverage: MX record with priority, pull-zone update 404, script variable list/update/upsert, and script secret update/upsert. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add global --record=<dir> flag that records API response bodies to JSON fixture files. The flag threads through CLI → commands → auth → all 6 client crates, piggy-backing on the existing debug logging path. Add 15 live API lifecycle tests gated behind #[cfg(feature = "live-api")] covering auth, pull-zone, DNS, storage-zone, storage, stream, script, and shield. Tests use run_lifecycle() with CleanupStack for panic-safe resource cleanup. Delete testbooks/ (Bun-based tests) now fully replaced by Rust tests. Update knowledgebase docs to reflect the new test architecture. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add camelCase serde aliases to Stream API types (Collection, PaginatedList, StatusMessage) to handle inconsistent API casing - Fix paginated list assertions across all test files to access ["Items"] instead of treating response as bare array - Add Id field to UpdateEdgeScript and skip_serializing_if for optional fields to match compute API requirements - Implement read-modify-write pattern for Shield WAF/rate-limit updates (API requires all fields on PATCH) - Remove skip_serializing_if from Shield WAF/rate-limit rule types where API requires fields even when empty - Handle free-plan limitations in Shield tests (skip WAF custom rules and rate limits when plan returns id=0) - Update test snapshots for Shield WAF and rate-limit responses Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add 50 tests (49 wiremock mock + 1 live API lifecycle) covering all container subcommands: app, template, endpoint, volume, registry, region, node, pod, limits, and log-forwarding - Fix --format flag conflict on log-forwarding create/update by renaming to --syslog-format - Add --image-name/--image-namespace/--image-tag/--registry-id flags to container app create (API requires at least one container template) - Fix nullable fields in containers types: imageDigest (null -> ""), exposedPort (null -> None) - Live test exercises endpoint creation to cover exposedPort:null deserialization path Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Suppress dead_code warnings for shared test helpers that are only used by some test binaries, and remove unnecessary mut in hoppy_live_cmd. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR refactors the project’s end-to-end/CLI testing approach by removing the old tests/e2e_*.rs wiremock suite and introducing a new snapshot-based CLI testing setup with shared fixtures, plus adds a --record flag to capture live API responses for fixture generation.
Changes:
- Removed legacy Rust E2E harness (
tests/e2e_*,tests/e2e_support/*) and thetools/e2e-report.shreport generator. - Added a global
--record <DIR>CLI flag and plumbed it through command handlers into API clients to record successful JSON responses. - Centralized fixture JSON under top-level
fixtures/and added/updated manyinstasnapshots for CLI output; added alive-apitest feature.
Reviewed changes
Copilot reviewed 153 out of 250 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
tools/e2e-report.sh |
Removed obsolete E2E report script. |
src/cli.rs |
Adds global --record flag; extends container CLI options and renames syslog flag field to avoid format ambiguity. |
src/main.rs |
Threads record into all command dispatch paths. |
src/auth.rs |
Extends client constructors to accept record and call client .with_record(...). |
src/commands/auth.rs |
Passes record through to core client usage. |
src/commands/pull_zone.rs |
Passes record through to core client usage. |
src/commands/storage_zone.rs |
Passes record through to core client usage. |
src/commands/storage.rs |
Passes record into storage client builder and applies .with_record(...). |
src/commands/dns.rs |
Passes record through to core client usage. |
src/commands/stream.rs |
Passes record through; resolves stream client with optional recording. |
src/commands/script.rs |
Passes record through to compute client usage. |
src/commands/shield.rs |
Passes record through; adjusts create/update payload construction for Shield PATCH requirements. |
tests/e2e_support/{mod.rs,cmd.rs,server.rs} |
Removed legacy E2E support module. |
tests/e2e_{global,auth,storage,storage_zone}.rs |
Removed legacy E2E tests. |
tests/cli_auth.rs |
Adds snapshot-based CLI tests using wiremock + insta. |
tests/support/mod.rs |
Adds shared helpers for mock/live CLI runs and fixtures loading. |
Cargo.toml |
Adds live-api feature and insta dev-dependency. |
README.md |
Documents mock vs live API testing and env overrides. |
.gitignore |
Removes ignores for the deleted E2E report outputs. |
hoppy-knowledgebase/adding-a-feature.md |
Adds a feature checklist including --record fixture capture guidance. |
hoppy-knowledgebase/Bugs.md |
Adds a bug note about missing debug JSON on decode failure. |
crates/bunny-api-storage/src/client.rs |
Refactors response handling to read bytes once and adds response recording support. |
crates/bunny-api-shield/src/client.rs |
Refactors response handling to read bytes once and adds response recording support. |
crates/bunny-api-containers/src/client.rs |
Refactors response handling to read bytes once and adds response recording support. |
crates/bunny-api-containers/src/types.rs |
Makes image_digest null-tolerant; makes exposed_port optional. |
crates/bunny-api-stream/src/types.rs |
Adds serde aliases to accept alternate casing from fixtures/responses. |
crates/bunny-api-compute/src/types.rs |
Adds id field to UpdateEdgeScript payload. |
crates/*/tests/*_api.rs |
Updates test fixtures to load from shared top-level fixtures/ paths. |
crates/*/Cargo.toml |
Adds bytes dependency to support body buffering/recording changes. |
fixtures/** |
Adds many shared JSON fixtures for core/storage/stream/shield/compute/containers. |
tests/snapshots/** |
Adds many insta snapshots for CLI output across services. |
- Extract duplicated recording logic into shared bunny-api-recording crate, fixing Mutex poisoning (unwrap_or_else) and adding eprintln on write errors - Restore skip_serializing_if on shield request types (CreateCustomWafRule, UpdateCustomWafRule, CreateRateLimitRule, UpdateRateLimitRule, WafRuleConfiguration, RateLimitRuleConfiguration) to avoid sending nulls - Restore body text in stream client parse_response error context - Fix compute update_script test to expect new Id field - Fix clippy warnings: assert_eq!(x, true), unnecessary to_string, too_many_arguments Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Summary
tests/e2e_*.rs,tests/e2e_support/,tools/e2e-report.sh) and associated dev-dependencies (assert_cmd,wiremock,predicates)testbooks/that exercise full resource lifecycles (create → get → list → update → verify → delete) against the live bunny.net API with snapshot testingTest books
auth.test.tspull-zone.test.tsdns-zone.test.tsstorage-zone.test.tsstream.test.tsscript.test.tsshield.test.tsNot covered (intentional)
script statistics— needs actual traffic datascript rotate-deployment-key— destructive, not reversibleRunning
Test plan
bun run typecheckpasses (TypeScript compilation)cargo buildsucceeds (no Rust regressions from removed dev-deps)cargo test --workspacepasses (crate-level wiremock tests unaffected)BUNNY_API_KEY=xxx bun test testbooks/passes against live API🤖 Generated with Claude Code