# BTG Mock Endpoints Guide

This document explains exactly how to test Break-the-Glass (BTG) with dev mock endpoints.

## What Is Mocked

- `GlassBreakerController:verifyProtection`
- `GlassBreakerController:breakTheGlass`

Not mocked:

- `GlassBreakerController:getProtectedMrnList`

That means patients shown in the BTG table still come from backend data.  
For example, from:

```bash
php bin/generate_btg_mock_data.php --project-id=20 --count=5 --type=operation_outcome --clear
```

## Quick Start (Project 20)

1. Generate patients (backend source of patient list):
```bash
php bin/generate_btg_mock_data.php --project-id=20 --count=5 --type=operation_outcome --clear
```
2. Start Vue dev server with mock mode:
```bash
cd redcap_v999.0.0/Resources/js/vue/components
npm run dev:mock
```
3. Open the Vite app and launch `Break the Glass`.
4. Confirm your URL/query has `pid=20`.
5. Use the BTG UI:
- Click key icon to run `verifyProtection`.
- Submit form to run `breakTheGlass`.

## Config File Used by Mock

- Default file: `dev-mocks/btg-verify-protection.json`
- File sections:
  - `defaults.verifyProtection`
  - `defaults.breakTheGlass`
  - `defaults.state`
  - `projects.<pid>.*` overrides

Project-specific behavior:

- For project 20, put overrides under `projects.20`.

## verifyProtection Outcomes

Route: `GlassBreakerController:verifyProtection`

Supported statuses:

- `breakable`
- `not_protected`
- `no_token`
- `skipped`
- `error`

Example override for one MRN:

```json
{
  "projects": {
    "20": {
      "verifyProtection": {
        "patients": {
          "TEST30631": {
            "status": "no_token",
            "message": "Simulated no token"
          }
        }
      }
    }
  }
}
```

When `status = breakable`, the mock issues a token and stores it in memory for later `breakTheGlass` validation.

## breakTheGlass Outcomes

Route: `GlassBreakerController:breakTheGlass`

Supported statuses:

- `accepted`
- `not accepted`
- `skipped`

Default behavior:

- Requires a valid mock token from a prior `verifyProtection` call.
- Missing token -> `skipped`
- Invalid token -> `not accepted`
- Expired token -> `not accepted`

Per-MRN override example:

```json
{
  "projects": {
    "20": {
      "breakTheGlass": {
        "patients": {
          "TEST30631": {
            "status": "not accepted",
            "details": "Simulated remote rejection"
          }
        }
      }
    }
  }
}
```

## Token TTL / Expiration Test

Set short TTL:

```json
{
  "projects": {
    "20": {
      "state": {
        "tokenTtlSeconds": 2
      }
    }
  }
}
```

Test:

1. Click key icon to get token (`breakable`).
2. Wait more than 2 seconds.
3. Submit BTG form.
4. Expected `not accepted` with expired-token details.

## Invalid Token Test (No Code Changes)

Force duplicate token for two MRNs:

```json
{
  "projects": {
    "20": {
      "verifyProtection": {
        "patients": {
          "TESTA": { "status": "breakable", "token": "shared-token" },
          "TESTB": { "status": "breakable", "token": "shared-token" }
        }
      }
    }
  }
}
```

Test:

1. Retrieve tokens for both patients.
2. Submit both in one BTG request.
3. Expected:
- First MRN consumes token and can be `accepted`.
- Second MRN gets `not accepted` (token no longer valid).

## Common Confusions

`I only see patients generated by script`
- Expected. Patient list endpoint is backend-driven, not mocked.

`verifyProtection still returns backend fields like verificationMethod`
- That means request bypassed Vite mock and hit backend.
- Ensure you are running `npm run dev:mock` and using the Vite app.

`I edited JSON but nothing changed`
- Ensure JSON is valid.
- Ensure request is to Vite `/api`.
- Retry action; mock config is read per request.
