# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

## [0.2.2] - 2025-10-03

### Fixed
- **CRITICAL: Multiple requests in :all mode** - Fixed `:all` mode to properly handle multiple requests
  - In `:all` mode, each request now accumulates and replaces the entire test cassette with all requests
  - This ensures all requests in a test are recorded while never clearing cassettes from other tests
  - Each test gets a fresh cassette containing only its requests when using `REQORD=all`
  - Fixes the issue where running `REQORD=all mix test specific_test.exs` would inappropriately clear cassettes

## [0.2.1] - 2025-10-03

### Fixed
- **CRITICAL: Record mode behavior** - Fixed `:all` mode to follow Ruby VCR behavior
  - `:all` mode now always replaces the entire cassette (instead of appending)
  - This fixes the critical issue where rerecording would mix old broken requests with new fixed ones
  - Simplified implementation by removing complex session tracking in favor of Ruby VCR's straightforward approach
  - `:all` mode now never replays - always goes live and records fresh responses
  - Ensures that `REQORD=all` provides clean, predictable cassette replacement behavior
- **Code quality** - Fixed all test warnings and Credo issues
  - Resolved unused variable warnings in test files
  - Fixed alias ordering and unused alias warnings
  - Refactored complex functions to reduce cyclomatic complexity
  - Improved code readability and maintainability

### Added
- **Comprehensive test coverage** - Extensive edge case testing across all modules
  - Redactor tests for extreme token lengths (1-10000 characters) and boundary cases
  - URL normalization edge cases including malformed URLs and unicode handling
  - Base64 encoding/decoding stress tests with large data and concurrent operations
  - Cassette file format edge cases (mixed line endings, BOM markers, malformed JSON)
  - HTTP request/response validation for unusual methods and status codes
  - Record mode integration tests simulating real-world broken→fixed workflows
  - Last-match-wins replay strategy tests for handling mixed cassette scenarios
  - Large file handling and concurrent access patterns
  - Memory and performance considerations for encoding operations
- **Documentation improvements** - Added hex package badges to README

### Changed
- **Simplified architecture** - Removed Session module complexity
  - Eliminated Agent-based session tracking that was causing confusion
  - Record logic now follows simple Ruby VCR patterns without stateful tracking
  - Cleaner, more predictable behavior that matches developer expectations
  - Reduced cognitive overhead for understanding and debugging record modes

## [0.2.0] - 2025-10-02

### Added
- **Pluggable JSON system** - Support for custom JSON libraries via `Reqord.JSON` behavior
  - `Reqord.JSON.Jason` adapter (default) with runtime availability checks
  - `Reqord.JSON.Poison` adapter with graceful fallback when not available
  - Application config: `config :reqord, :json_library, MyAdapter`
  - Comprehensive adapter test suite with real cassette creation/loading
- **CassetteEntry struct** - Type-safe cassette data modeling with validation
  - Nested `Reqord.CassetteEntry.Request` and `Response` structs
  - Built-in validation with helpful error messages
  - Helper functions: `new/2`, `from_raw/1`, `to_map/1`, `validate/1`
- **Test utilities** - Shared helpers to reduce test code duplication
  - `Reqord.TestHelpers.with_module/3` for conditional module tests
  - `Reqord.TestHelpers.with_config/4` for application config setup/teardown
  - `Reqord.TestHelpers.with_module_and_config/6` combining both patterns
- **Development tools** - Mix task for code quality enforcement
  - `mix precommit` alias running format, credo, dialyzer, and tests
- **Configurable settings** - Made hard-coded values configurable for flexibility
  - `Reqord.Config` module for centralized configuration management
  - Configurable cassette directory: `config :reqord, :cassette_dir, "custom/path"`
  - Configurable auth parameters: `config :reqord, :auth_params, ~w[token my_token]`
  - Configurable auth headers: `config :reqord, :auth_headers, ~w[authorization x-my-auth]`
  - Configurable volatile headers: `config :reqord, :volatile_headers, ~w[date x-trace-id]`
  - Configuration validation with helpful error messages
  - Comprehensive test coverage for all configuration options

### Changed
- **Improved error handling** throughout the codebase
  - Replaced bare `rescue _ -> body` clauses with specific exception handling
  - Added logging for JSON decoding failures and network errors during recording
  - Consistent use of `case` statements instead of exception-prone `!` functions
- **Better test organization** - Separated JSONL format tests into dedicated file
  - `test/reqord/jsonl_test.exs` for JSONL-specific functionality
  - `test/reqord/json/` directory for JSON adapter tests
  - Improved test cleanup preserving fixture files
- **Optional dependencies** - Made JSON libraries optional to reduce bloat
  - Jason and Poison marked as `optional: true` in mix.exs
  - Runtime checks with helpful error messages when libraries are missing

### Fixed
- **Error handling security** - Prevented silent failures that could mask issues
- **Test reliability** - Fixed cassette cleanup logic to preserve fixture directories
- **Code quality** - Resolved Credo warnings for negated conditions and formatting
- **Hard-coded values** - Eliminated hard-coded cassette directory, auth parameters, and volatile headers
  - All previously hard-coded values are now configurable via application config
  - Maintains backward compatibility with sensible defaults

## [0.1.0] - 2025-10-02

### Added
- Initial release of Reqord
- Core `Reqord` module with `install!/1` for setting up VCR stubs
- Ruby VCR-style record modes: `:once`, `:new_episodes`, `:all`, `:none`
  - `:once` - Strict replay, raise on new requests (default)
  - `:new_episodes` - Replay existing, record new requests (append mode)
  - `:all` - Always re-record everything, ignore existing cassette
  - `:none` - Never record, never hit network (must have complete cassette)
- `Reqord.Case` ExUnit case template for automatic cassette management
- Smart request matching based on method, normalized URL, and body hash
- Automatic redaction of sensitive headers (`authorization`)
- Automatic redaction of auth query parameters (`token`, `apikey`, `api_key`)
- Automatic removal of volatile response headers (`date`, `server`, `set-cookie`, etc.)
- JSONL cassette format stored in `test/support/cassettes/`
- Query parameter normalization (lexicographic sorting, auth param removal)
- Body hash differentiation for POST/PUT/PATCH requests
- Support for spawned processes via `allow/3` helper
- Multiple configuration options for record mode:
  - Environment variable via `REQORD`
  - Application config via `:reqord, :default_mode`
  - Per-test override via `@tag vcr_mode: :mode`
- Automatic cassette naming based on test module and test name
- Custom cassette naming via `@tag vcr: "custom_name"`
- Custom stub name override via `@tag req_stub_name: MyStub`
- Integration with `Req.Test` for zero application code changes
- Comprehensive test suite covering all modes and features
- Detailed README with setup, usage examples, and troubleshooting
- Mix tasks for cassette management:
  - `mix reqord.show` - Display cassette contents with filtering options
  - `mix reqord.audit` - Audit cassettes for secrets, staleness, and unused entries
  - `mix reqord.prune` - Clean up empty files, duplicates, and stale cassettes
  - `mix reqord.rename` - Rename or move cassettes, with migration support
- Flexible request matching system:
  - Built-in matchers: `:method`, `:uri`, `:host`, `:path`, `:headers`, `:body`
  - Custom matcher registration via `register_matcher/2`
  - Default matching on `[:method, :uri]`
  - Per-test matcher override via `@tag match_on: [...matchers]`
  - Application config for default matchers
- Test API application (`test_api/`) for demonstrating Reqord:
  - Simple REST API with authentication
  - Multiple routes (GET /api/users, GET /api/users/:id, POST /api/users)
  - Fake Bearer token authentication
  - Example tests showing real-world usage
- Automated cassette recording script (`scripts/record_cassettes.sh`):
  - Automatically starts test API server
  - Records all example cassettes
  - Stops server when complete
- Comprehensive secret redaction system (`Reqord.Redactor`):
  - **CRITICAL SECURITY**: Ensures secrets never get committed to git cassettes
  - Built-in redaction for auth headers, query parameters, response bodies
  - VCR-style configurable filters for app-specific secrets
  - Multi-layer protection: headers → query params → JSON keys → pattern matching
  - Automatic redaction of Bearer tokens, API keys, long alphanumeric strings
  - Support for GitHub tokens, Stripe keys, UUIDs, and custom patterns

[Unreleased]: https://github.com/Makesesama/reqord/compare/v0.2.2...HEAD
[0.2.2]: https://github.com/Makesesama/reqord/compare/v0.2.1...v0.2.2
[0.2.1]: https://github.com/Makesesama/reqord/compare/v0.2.0...v0.2.1
[0.2.0]: https://github.com/Makesesama/reqord/compare/v0.1.0...v0.2.0
[0.1.0]: https://github.com/Makesesama/reqord/releases/tag/v0.1.0
