Reqord.CassetteEntry (reqord v0.4.0)

View Source

Represents a single cassette entry with request, response, and timestamp data.

This struct provides type safety and validation for cassette entries, ensuring consistency across the application. All entries now include microsecond-precision timestamps for chronological ordering.

Structure

A CassetteEntry contains:

  • req: The HTTP request details (method, URL, headers, body hash)
  • resp: The HTTP response details (status, headers, base64-encoded body)
  • recorded_at: Microsecond timestamp when the request was initiated

Timestamp Ordering

The recorded_at field enables chronological replay even when concurrent requests complete out of order:

# Concurrent requests might complete as: POST(t=200), DELETE(t=100)
# But will be replayed as: DELETE(t=100), POST(t=200)

This solves ID mismatch errors in concurrent testing scenarios where resource creation and deletion happen in parallel.

JSON Format

When serialized to cassette files, entries have this format:

{
  "req": {
    "method": "POST",
    "url": "https://api.example.com/users",
    "headers": {"authorization": "<REDACTED>"},
    "body_hash": "abc123..."
  },
  "resp": {
    "status": 201,
    "headers": {"content-type": "application/json"},
    "body_b64": "eyJpZCI6MSwidXNlciI6IkFsaWNlIn0="
  },
  "recorded_at": 1759657159025077
}

Summary

Functions

Creates a CassetteEntry from raw data with validation.

Creates a new CassetteEntry struct with validation.

Converts a CassetteEntry to a map suitable for JSON encoding.

Validates that a CassetteEntry has all required fields and valid data.

Types

headers()

@type headers() :: %{required(String.t()) => String.t()}

t()

@type t() :: %Reqord.CassetteEntry{
  recorded_at: integer() | nil,
  req: Reqord.CassetteEntry.Request.t(),
  resp: Reqord.CassetteEntry.Response.t()
}

Functions

from_raw(data)

@spec from_raw(map()) :: {:ok, t()} | {:error, String.t()}

Creates a CassetteEntry from raw data with validation.

This is useful when loading from JSON or creating from HTTP data.

new(req, resp, recorded_at \\ nil)

@spec new(
  Reqord.CassetteEntry.Request.t(),
  Reqord.CassetteEntry.Response.t(),
  integer() | nil
) ::
  {:ok, t()} | {:error, String.t()}

Creates a new CassetteEntry struct with validation.

Examples

iex> {:ok, req} = Reqord.CassetteEntry.Request.new("GET", "https://api.example.com", %{}, "-")
iex> {:ok, resp} = Reqord.CassetteEntry.Response.new(200, %{}, "dGVzdA==")
iex> Reqord.CassetteEntry.new(req, resp)
{:ok, %Reqord.CassetteEntry{...}}

to_map(cassette_entry)

@spec to_map(t()) :: map()

Converts a CassetteEntry to a map suitable for JSON encoding.

validate(entry)

@spec validate(t()) :: {:ok, t()} | {:error, String.t()}

Validates that a CassetteEntry has all required fields and valid data.