# `PolarExpress.Test`
[🔗](https://github.com/jeffhuen/polar_express/blob/main/lib/polar_express/test.ex#L1)

Test helpers for stubbing PolarExpress HTTP requests.

Uses ownership-based stubs (via NimbleOwnership) so stubs are scoped to
the test process and work correctly with `async: true` tests.

## Setup

In your `test/test_helper.exs`:

    PolarExpress.Test.start()
    ExUnit.start()

## Stubbing Requests

    test "creates a charge" do
      PolarExpress.Test.stub(fn %{method: :post, url: url} ->
        assert url =~ "/v1/charges"
        {200, [], ~s({"id": "ch_123", "object": "charge"})}
      end)

      client = PolarExpress.client("pk_test_123")

      {:ok, data} =
        PolarExpress.Client.request(client, :post, "/v1/charges",
          params: %{amount: 2000, currency: "usd"}
        )

      assert data["id"] == "ch_123"
    end

## Async Tests

Stubs are automatically scoped to the calling process. For async tests that
spawn processes (Tasks, GenServers), use `allow/2` to grant access:

    test "works from a spawned task" do
      PolarExpress.Test.stub(fn _req -> {200, [], ~s({"ok": true})} end)
      test_pid = self()

      Task.async(fn ->
        PolarExpress.Test.allow(test_pid, self())
        PolarExpress.Client.request(client, :get, "/v1/balance")
      end)
      |> Task.await()
    end

## Stub Function

The stub function receives a map with:

  * `:method` - HTTP method atom (`:get`, `:post`, etc.)
  * `:url` - Full URL string
  * `:headers` - List of `{name, value}` tuples
  * `:body` - Request body (string or nil)

And must return a `{status, headers, body}` tuple:

  * `status` - HTTP status code (integer)
  * `headers` - Response headers as `[{name, value}]`
  * `body` - Response body (string)

# `allow`

```elixir
@spec allow(pid(), pid()) :: :ok
```

Allow `child_pid` to use the stub registered by `owner_pid`.

Use this when your test spawns processes that make Polar API calls.

# `start`

```elixir
@spec start() :: {:ok, pid()}
```

Start the test stub server. Call this in `test/test_helper.exs`.

# `stub`

```elixir
@spec stub((map() -&gt; {integer(), list(), binary()})) :: :ok
```

Register an HTTP stub for the current test process.

The stub function will be called instead of making real HTTP requests
for any `PolarExpress.Client.request/4` call from this process.

Ownership is automatically cleaned up when the test exits.

---

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