# WireMock Runner Example

Demonstrates WireMock Runner integration with Aspire for container-based API mocking suitable for integration tests and CI/CD environments.

## 📋 Overview

This example shows how to:

- Set up an Aspire AppHost with WireMock Runner for orchestrated API mocking
- Auto-provision new mock APIs in WireMock Cloud with seed stubs
- Pull mock definitions from WireMock Cloud using API tokens
- Iterate on stubs using the inner loop (edit → re-run → auto-restart)
- Wire mock services with ASP.NET Core APIs using service discovery

## 🏗️ Architecture

```mermaid
flowchart LR
    Cloud["WireMock Cloud"]
    Seeds["seeds/new-service/stubs.json"]

    subgraph AppHost["Aspire AppHost"]
        ProvPull["wiremock-provision-and-pull"]
        Runner["WireMock Runner Container"]
        Mock1["aspire-wiremockcli :8080"]
        Mock2["people-test :8081"]
        Mock3["new-service :8082"]
        API["PeopleApi"]
        AnimalsAPI["AnimalsApi"]
    end

    Cloud -.->|Provision and Pull| ProvPull
    Seeds -.->|Import| ProvPull
    ProvPull -->|completes| Runner
    Runner --> Mock1
    Runner --> Mock2
    Runner --> Mock3
    API -->|HttpClient| Mock1
    AnimalsAPI -->|HttpClient| Mock3
```

## 🧩 Components

| Project                           | Description                               |
| --------------------------------- | ----------------------------------------- |
| `WireMockRunner.AppHost`          | Aspire orchestration with WireMock Runner |
| `PeopleApi`                       | ASP.NET Core API consuming mock services  |
| `AnimalsApi`                      | ASP.NET Core API consuming seeded mock    |
| `WireMockRunner.ServiceDefaults`  | Shared Aspire service defaults            |
| `WireMockRunner.IntegrationTests` | Integration tests using WireMock Runner   |

## 🔑 Key Features

- **WireMock Runner Integration**: Uses Forge's `AddWiremockRunner()` Aspire extension (experimental)
- **Container-Based**: Runs mocks in a container suitable for CI/CD environments
- **Auto-Provisioning**: Creates new mock APIs in WireMock Cloud with organization-wide access
- **Seed Stubs**: Pre-populates auto-provisioned mocks with initial data via `WithSeeds()`
- **Inner Loop**: Edit seed stubs and re-run provision-and-pull — the runner container restarts automatically
- **Multi-Mock Orchestration**: Single runner manages multiple mock services
- **Service Discovery**: Automatic endpoint resolution between Aspire resources
- **Integration Test Ready**: Designed for integration tests that run in CI pipelines

## 📂 Project Structure

```
foundry/dotnet/aspire-wiremockrunner/
├── wiremock-runner.sln
├── WireMockRunner.AppHost/
│   ├── AppHost.cs                    # Runner configuration
│   ├── seeds/
│   │   └── new-service/
│   │       └── stubs.json            # Seed stubs (WireMock export format)
│   └── .wiremock/                    # Generated by provision-and-pull
│       ├── .manifest.json
│       ├── .provisioned.json
│       ├── wiremock.yaml
│       ├── aspire-wiremockcli/
│       ├── people-test/
│       └── new-service/
├── PeopleApi/
│   └── Program.cs                    # API using HttpClient with service discovery
├── AnimalsApi/
│   └── Program.cs                    # API consuming seeded new-service mock
├── WireMockRunner.IntegrationTests/
│   └── PeopleApiTests.cs             # Tests using WireMock Runner
└── WireMockRunner.ServiceDefaults/
    └── Extensions.cs                 # Shared Aspire defaults
```

## 🚀 Getting Started

### Prerequisites

- .NET 10.0 SDK
- Aspire 13.x
- Docker Desktop (for WireMock Runner container)
- Node.js / npm (for the WireMock CLI, installed automatically)
- WireMock Cloud account and API token
- Visual Studio 2022 or VS Code

### Configuration

1. **Get WireMock Cloud API Token**:
   - Log in to [WireMock Cloud](https://app.wiremock.cloud)
   - Navigate to **Settings** → **API Tokens**
   - Create or copy an API token

2. **Set API Token**:
   - **Local Development**: Run the AppHost and enter the API token when prompted in the Aspire dashboard
   - **CI/CD**: Set the `WMC_API_TOKEN` environment variable

### Running the Example

```bash
cd foundry/dotnet/aspire-wiremockrunner
dotnet run --project WireMockRunner.AppHost
```

On first run, the `wiremock-provision-and-pull` resource will:

1. Create the `new-service` mock API in WireMock Cloud (idempotent)
2. Import seed stubs from `seeds/new-service/stubs.json`
3. Pull all mock stubs to the `.wiremock/` directory
4. Fix ports in `wiremock.yaml` to match the configured values
5. Start the runner container, which serves all mocks

### Editing Stubs (Inner Loop)

To iterate on mock responses without restarting the entire AppHost:

1. Edit `seeds/new-service/stubs.json` (e.g., add a new animal)
2. In the Aspire dashboard, click **Start** on the `wiremock-provision-and-pull` resource
3. The seed stubs are re-imported, pulled, and the runner container restarts automatically
4. Your API now returns the updated data

### Seed Stub Format

Seed files use the WireMock export format with stable UUIDs for idempotent imports:

```json title="seeds/new-service/stubs.json"
{
  "mappings": [
    {
      "id": "a1b2c3d4-0001-4000-8000-000000000001",
      "name": "Animals",
      "request": { "method": "GET", "url": "/animals" },
      "response": {
        "status": 200,
        "jsonBody": [
          { "name": "dog", "type": "domestic" },
          { "name": "lion", "type": "wild" },
          { "name": "penguin", "type": "wild" },
          { "name": "cat", "type": "domestic" }
        ]
      }
    }
  ]
}
```

## 📡 API Endpoints

The People API provides:

| Endpoint       | Method | Description                  |
| -------------- | ------ | ---------------------------- |
| `/`            | GET    | Hello World                  |
| `/people`      | GET    | List all people (from mock)  |
| `/people/{id}` | GET    | Get person by ID (from mock) |

The Animals API provides:

| Endpoint        | Method | Description                  |
| --------------- | ------ | ---------------------------- |
| `/animals`      | GET    | List all animals (from mock) |
| `/animals/{id}` | GET    | Get animal by ID (from mock) |

The mock services are configured from WireMock Cloud projects:

- **aspire-wiremockcli** (Port 8080): Project ID `k325y` (existing)
- **people-test** (Port 8081): Project ID `dkl1v` (existing)
- **new-service** (Port 8082): Auto-provisioned with seed stubs

## 🧪 Running Integration Tests

The example includes integration tests that demonstrate WireMock Runner usage:

```bash
cd foundry/dotnet/aspire-wiremockrunner
dotnet test
```

These tests:

- Run WireMock Runner in a container
- Configure mock services for testing
- Verify API behavior against mocks
- Work in CI/CD environments (unlike WireMock CLI)

## 🔍 Key Differences from WireMock CLI

| Feature               | WireMock Runner (This Example)  | WireMock CLI          |
| --------------------- | ------------------------------- | --------------------- |
| **Runtime**           | Container (Docker)              | Executable            |
| **Integration Tests** | ✅ Supported                    | ❌ Not supported      |
| **Seed Stubs**        | ✅ WithSeeds()                  | ❌ N/A                |
| **Inner Loop**        | ✅ Edit → re-run → auto-restart | ❌ Restart required   |
| **Orchestration**     | Single runner, multiple mocks   | One resource per mock |
| **CI/CD Ready**       | ✅ Yes                          | ❌ No                 |

## 🔗 Related Documentation

- [Host WireMock Runner Guide](../guides/development/mocking/host-wiremock-runner.md)
- [SAIFMOCK001 Experimental Diagnostic](../reference/diagnostics/SAIFMOCK001.md)
- [WireMock CLI Example](aspire-wiremockcli.md)

## 📍 Source Code

**Location:** [`foundry/dotnet/aspire-wiremockrunner/`](https://dev.azure.com/SAIFCorporation/Platform/_git/forge?path=/foundry/dotnet/aspire-wiremockrunner)

## ⚠️ Important Notes

- **Experimental Feature**: WireMock Runner is experimental (`SAIFMOCK001`)
- **Requires Docker**: Container-based mocks require Docker Desktop
- **Seed Stubs**: Use stable UUIDs in `stubs.json` for idempotent imports
- **Inner Loop**: Re-run `wiremock-provision-and-pull` from the dashboard to pick up stub changes — the runner container restarts automatically
- **API Token Required**: WireMock Cloud API token is required for pulling and provisioning mocks

!!! info "Foundry Example: Auto-Cleanup"

    This foundry example automatically **deletes provisioned mock APIs** from WireMock Cloud and removes `.provisioned.json` when the AppHost is stopped (CTRL+C). This prevents orphaned mocks from accumulating across example sessions. Auto-cleanup is **not** a built-in WireMock Runner feature — in regular local development, provisioned mocks persist so they can be shared and pulled by other team members.
