[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/fabwebdev/httpsms/main/tests/README.md [Back]  [Original]

# Integration Tests

End-to-end integration tests for the httpSMS API. These tests validate the complete SMS lifecycle by running the full application stack in Docker alongside a phone emulator service.

## Architecture

```
     HTTP      
  Test Runner    API (Go)   
   (Go test)                  Port 8000   
              
                                     
                          FCM Push      Events
                          (HTTP)        (HTTP)
                                     
                              
                                 Emulator   
                                (Fiber v3)  
                                Port 9090   
                              
                                     
                              
                               CockroachDB         Redis    
                                Port 26257       Port 6379  
                                 
```

### Components

| Component       | Description                                              |
| --------------- | -------------------------------------------------------- |
| **API**         | The httpSMS Go API server running in Docker              |
| **Emulator**    | A Fiber v3 Go service that simulates an Android phone    |
| **CockroachDB** | Database for the API (single-node, insecure mode)        |
| **Redis**       | Cache and queue backend                                  |
| **Seed**        | One-shot container that seeds test data into CockroachDB |
| **Test Runner** | Go test binary that runs on the host machine             |

### How It Works

1. **Send SMS flow**: Test sends `POST /v1/messages/send`  API pushes FCM notification to emulator  Emulator calls `GET /v1/messages/outstanding`  Emulator fires `SENT` and `DELIVERED` events  Test polls `GET /v1/messages/{id}` until status is `delivered`

2. **Receive SMS flow**: Test sends `POST /v1/messages/receive` (as the phone)  API stores message  Test verifies via `GET /v1/messages/{id}`

### FCM Redirect

The API's Firebase SDK is configured (via `FCM_ENDPOINT` env var) to redirect all FCM HTTP requests to the emulator instead of Google's servers. The emulator serves:

- `/token`  Fake OAuth2 token endpoint (Firebase SDK requests tokens before sending)
- `/v1/projects/:project/messages:send`  Fake FCM push endpoint

## Test Coverage

- [x] **Send SMS E2E**  Full send lifecycle: API  FCM push  emulator responds with SENT/DELIVERED events  message reaches `delivered` status
- [x] **Receive SMS E2E**  Phone submits received message to API  message is stored and retrievable via GET endpoint

## Prerequisites

- [Docker](https://docs.docker.com/get-docker/) with Docker Compose
- [Go 1.22+](https://go.dev/dl/)
- [jq](https://jqlang.github.io/jq/download/) (for Firebase credentials generation)
- [OpenSSL](https://www.openssl.org/) (for RSA key generation)

## Running Locally

### 1. Generate Firebase Credentials

The integration tests use a fake Firebase service account. Generate it with:

```bash
cd tests
bash generate-firebase-credentials.sh
```

This creates `firebase-credentials.json` with a throwaway RSA key (the emulator doesn't validate tokens).

### 2. Set Environment Variable

```bash
export FIREBASE_CREDENTIALS=$(jq -c . firebase-credentials.json)
```

### 3. Start the Stack

```bash
docker compose up -d --build --wait
```

This starts CockroachDB, Redis, the API, and the emulator. The `--wait` flag blocks until all health checks pass.

### 4. Wait for Seeding

```bash
docker compose wait seed
sleep 2
```

The seed container inserts test users, phones, and API keys into CockroachDB after the API has run its GORM migrations.

### 5. Run Tests

```bash
go test -v -timeout 120s ./...
```

### 6. Tear Down

```bash
docker compose down -v
```

The `-v` flag removes volumes (database data) for a clean slate next run.

### One-Liner

```bash
cd tests && \
  bash generate-firebase-credentials.sh && \
  export FIREBASE_CREDENTIALS=$(jq -c . firebase-credentials.json) && \
  docker compose up -d --build --wait && \
  docker compose wait seed && \
  sleep 2 && \
  go test -v -timeout 120s ./... ; \
  docker compose down -v
```

## CI/CD

Integration tests run automatically via GitHub Actions (`.github/workflows/integration-test.yml`):

- **Trigger**: Push to `main` or pull request targeting `main`
- **Flow**: Generates credentials  Starts Docker stack  Seeds DB  Runs tests  Collects logs on failure  Tears down
- **Gate**: Deployment should only proceed if integration tests pass

## Test Data

| Entity         | Value                                  |
| -------------- | -------------------------------------- |
| User API Key   | `test-user-api-key`                    |
| Phone API Key  | `pk_test-phone-api-key`                |
| Phone Number   | `+18005550199`                         |
| Contact Number | `+18005550100`                         |
| User ID        | `test-user-id`                         |
| Phone ID       | `a1b2c3d4-e5f6-7890-abcd-ef1234567890` |

See [`seed.sql`](./seed.sql) for the complete seed data.

## Project Structure

```
tests/
 docker-compose.yml       # Full stack orchestration
 seed.sql                 # Database seed data
 .env.test                # API environment variables
 generate-firebase-credentials.sh  # Generates fake Firebase credentials
 go.mod                   # Test runner Go module
 go.sum
 helpers_test.go          # Test utilities (HTTP client, polling)
 integration_test.go      # E2E test cases
 emulator/                # Phone emulator service
     Dockerfile
     go.mod
     go.sum
     main.go              # Fiber v3 entry point
     emulator.go          # Emulator struct and config
     token_handler.go     # Fake OAuth2 token endpoint
     fcm_handler.go       # Fake FCM push receiver
     events.go            # Event firing logic (SENT/DELIVERED)
```

## Troubleshooting

### API fails to start

Check the API logs:

```bash
docker compose logs api
```

Common issues:

- `FIREBASE_CREDENTIALS` env var not set or malformed
- CockroachDB not ready (increase `start_period` in healthcheck)

### Tests timeout waiting for `delivered` status

Check the emulator logs:

```bash
docker compose logs emulator
```

The emulator should show:

1. `[FCM]`  Receiving the push notification
2. `[EVENTS]`  Fetching outstanding messages and firing events

If no `[FCM]` entries appear, the API isn't reaching the emulator (check `FCM_ENDPOINT` in `.env.test`).

### Seed container fails

```bash
docker compose logs seed
```

If you see "relation does not exist" errors, the API hasn't finished GORM migrations yet. Increase the API's `start_period` in `docker-compose.yml`.

## Adding New Tests

1. Add test functions to `integration_test.go` (or create new `*_test.go` files)
2. Use `doRequest()` helper for authenticated HTTP calls
3. Use `pollMessageStatus()` to wait for async state changes
4. Update the test coverage checklist in this README

Web Proxy Viewer  |  New URL  |  Original Page