# `PaperTiger`
[🔗](https://github.com/EnaiaInc/paper_tiger/blob/v1.2.2/lib/paper_tiger.ex#L1)

PaperTiger - A stateful mock Stripe server for testing.

## Quick Start

    # Start the server
    {:ok, _pid} = PaperTiger.start()

    # Make API calls via HTTP
    response = HTTP.post!("/v1/customers", ...)

    # Clean up between tests
    PaperTiger.flush()

## Time Control

PaperTiger supports three clock modes for deterministic testing:

- `:real` - Use system time (default)
- `:accelerated` - Time moves faster (useful for subscription billing tests)
- `:manual` - Freeze time and advance manually

## Examples

    # Manual time control
    PaperTiger.set_clock_mode(:manual, timestamp: 1234567890)
    PaperTiger.advance_time(3600)  # Advance 1 hour

    # Accelerated time (10x speed)
    PaperTiger.set_clock_mode(:accelerated, multiplier: 10)

## Resource Cleanup

    # Flush specific resource
    PaperTiger.flush(:customers)

    # Flush all resources
    PaperTiger.flush()

# `advance_time`

```elixir
@spec advance_time(integer() | keyword()) :: :ok
```

Advances time in manual mode.

## Examples

    PaperTiger.advance_time(seconds: 3600)
    PaperTiger.advance_time(days: 30)
    PaperTiger.advance_time(86400)  # 1 day

# `clock_mode`

```elixir
@spec clock_mode() :: atom()
```

Returns the current clock mode.

## Examples

    PaperTiger.clock_mode()
    #=> :real

# `flush`

```elixir
@spec flush() :: :ok
```

Flushes (clears) all resources or a specific resource type.

PaperTiger supports namespace-based isolation (used by `PaperTiger.Test`) so
multiple test suites can run concurrently. `flush/0` clears data **only for
the current namespace** (default `:global`).

If you need to wipe *all* namespaces, use `flush_all/0`.

## Examples

    PaperTiger.flush()  # Clear all resources in current namespace
    PaperTiger.flush(:customers)  # Clear only customers

# `flush`

```elixir
@spec flush(atom()) :: :ok | {:error, :unknown_resource}
```

# `flush_all`

```elixir
@spec flush_all() :: :ok
```

Flushes (clears) all resources across all namespaces.

This is the legacy behavior of `flush/0`. Prefer `flush/0` when running tests
concurrently with `PaperTiger.Test` sandboxing.

# `get_port`

```elixir
@spec get_port() :: integer()
```

Returns the port PaperTiger will use.

If PaperTiger is already running, returns the actual port in use.
If not started yet, it resolves and caches the port so config and runtime stay consistent.

## Examples

    PaperTiger.get_port()
    #=> 59342

# `now`

```elixir
@spec now() :: integer()
```

Returns the current Unix timestamp according to the configured clock.

## Examples

    PaperTiger.now()
    #=> 1234567890

# `register_configured_webhooks`

```elixir
@spec register_configured_webhooks() :: {:ok, [map()]}
```

Registers webhook endpoints from application configuration.

This function reads webhook endpoints from the `:paper_tiger, :webhooks` config
and registers them automatically. Useful for setting up test webhooks at startup.

## Configuration

    # In config/test.exs
    config :paper_tiger,
      webhooks: [
        [url: "http://localhost:4000/webhooks/stripe"],
        [url: "http://localhost:4000/webhooks/events", events: ["invoice.paid"]]
      ]

## Examples

    # Register all configured webhooks
    PaperTiger.register_configured_webhooks()
    #=> {:ok, [%{id: "we_..."}, %{id: "we_..."}]}

## Returns

`{:ok, webhooks}` where webhooks is a list of registered webhook maps.

# `register_webhook`

```elixir
@spec register_webhook(keyword()) :: {:ok, map()}
```

Registers a webhook endpoint for test orchestration.

This is used by the `POST /_config/webhooks` endpoint for test setup.

## Parameters

- `:url` - Webhook endpoint URL (required)
- `:secret` - Webhook signing secret (default: "whsec_paper_tiger_test")
- `:events` - List of event types to subscribe to (default: ["*"] for all events)

## Examples

    # Register with all events
    PaperTiger.register_webhook(url: "http://localhost:4000/webhooks/stripe")

    # Register with specific events
    PaperTiger.register_webhook(
      url: "http://localhost:4000/webhooks/stripe",
      secret: "whsec_custom",
      events: ["customer.created", "invoice.paid"]
    )

# `set_clock_mode`

```elixir
@spec set_clock_mode(
  atom(),
  keyword()
) :: :ok
```

Sets the clock mode.

## Modes

- `:real` - Use system time
- `:accelerated` - Time runs faster (specify `:multiplier` option)
- `:manual` - Manual control (specify `:timestamp` option)

## Examples

    PaperTiger.set_clock_mode(:real)
    PaperTiger.set_clock_mode(:accelerated, multiplier: 10)
    PaperTiger.set_clock_mode(:manual, timestamp: 1234567890)

# `start`

```elixir
@spec start(keyword()) :: {:ok, pid()} | {:error, term()}
```

Starts the PaperTiger application.

## Options

- `:port` - HTTP port (default: random port 59000-60000, reserved before startup)
- `:transport_options` - TCP listen options passed to Thousand Island (default: `[]`)
- `:clock_mode` - Time mode (default: `:real`)

## Examples

    {:ok, _pid} = PaperTiger.start()
    {:ok, _pid} = PaperTiger.start(port: 4002, clock_mode: :manual)

# `stripity_stripe_config`

```elixir
@spec stripity_stripe_config(keyword()) :: keyword()
```

Returns configuration for stripity_stripe to use PaperTiger as the Stripe API backend.

This helper generates the configuration needed to point stripity_stripe at
PaperTiger instead of the real Stripe API. Use this in your config files or
test setup to simplify integration.

## Options

- `:port` - PaperTiger port (default: resolve and cache before startup)
- `:host` - PaperTiger host (default: "localhost")
- `:webhook_secret` - Webhook signing secret (default: "whsec_paper_tiger_test")
- `:sandbox` - Enable sandbox isolation for concurrent tests (default: true)

## Sandbox Mode

When `sandbox: true` (the default), the returned config includes
`http_module: PaperTiger.StripityStripeHackney`, which injects namespace
headers for test isolation. This allows tests to run concurrently without
data leakage between tests.

Set `sandbox: false` if you want global (non-isolated) mode, though this
is rarely needed.

## Examples

    # In config/test.exs (recommended)
    config :stripity_stripe, PaperTiger.stripity_stripe_config()

    # With custom options
    config :stripity_stripe, PaperTiger.stripity_stripe_config(port: 4002)

    # Disable sandbox (not recommended for concurrent tests)
    config :stripity_stripe, PaperTiger.stripity_stripe_config(sandbox: false)

## Returns

Keyword list with:
- `:api_key` - Mock API key
- `:public_key` - Mock publishable key
- `:api_base_url` - URL pointing to PaperTiger
- `:webhook_signing_key` - Webhook signing secret
- `:http_module` - Custom HTTP module for sandbox isolation (when sandbox: true)

---

*Consult [api-reference.md](api-reference.md) for complete listing*
