> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mov-eat.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Testing

> Current test coverage, testing strategy and quality gaps for Platform and Agent.

# Testing

Testing in Moveat is used to protect business correctness, not only to increase a coverage number.

The highest-risk bugs are not visual. They are product-state bugs: duplicated meals, wrong calorie summaries, broken sessions, incorrect unit conversion, webhook retries that write twice, or Agent actions that bypass Platform validation.

<Info>
  Coverage numbers below were measured on 2026-06-13 from the local repositories.
</Info>

## Current snapshot

<CardGroup cols={2}>
  <Card title="Platform" icon="server">
    21 test files, 61 passing tests. Coverage exists but currently fails the configured 80% global threshold.
  </Card>

  <Card title="Agent" icon="bot">
    Go tests pass. Statement coverage is 59.5% and no global coverage threshold is enforced yet.
  </Card>
</CardGroup>

| Repository | Test runner | Current status                       | Current coverage                |
| ---------- | ----------- | ------------------------------------ | ------------------------------- |
| Platform   | Vitest      | Tests pass, coverage threshold fails | 74.15% statements, 74.23% lines |
| Agent      | Go test     | Tests pass                           | 59.5% statements                |

<Warning>
  Platform's regular test suite passes, but `yarn test:coverage` fails because the repository is configured with an 80% global threshold and current coverage is below that threshold.
</Warning>

## Testing philosophy

Moveat should prioritize tests in this order:

1. Business invariants that can corrupt user data.
2. Auth and authorization boundaries.
3. Agent-to-Platform contract behavior.
4. Unit conversion and time-zone handling.
5. External integration adapters.
6. Low-risk wiring and static helpers.

Coverage is useful, but it should not drive shallow tests. A lower coverage module with strong tests around its dangerous paths can be safer than a high-coverage module that only tests happy paths.

## Platform testing

Platform uses **Vitest** for TypeScript tests.

### Commands

```bash theme={null}
# Run tests
yarn test

# Run tests with coverage
yarn test:coverage

# Full local verification
yarn verify
```

`yarn verify` runs linting, typecheck, tests and build.

### Coverage result

| Metric     | Current | Required threshold | Status                |
| ---------- | ------: | -----------------: | --------------------- |
| Statements |  74.15% |                80% | Below target          |
| Branches   |  63.57% |                80% | Below target          |
| Functions  |  79.16% |                80% | Slightly below target |
| Lines      |  74.23% |                80% | Below target          |

### What Platform already tests

| Area           | What is covered                                            | Why it matters                                           |
| -------------- | ---------------------------------------------------------- | -------------------------------------------------------- |
| Configuration  | Environment schema validation.                             | Prevents booting with invalid runtime config.            |
| Auth           | Passwords, sessions, Google identity, controller behavior. | Protects login and session creation.                     |
| Guards         | Internal service token guard.                              | Protects Agent-only APIs.                                |
| Logging        | HTTP body redaction and log formatting.                    | Prevents leaking sensitive data in observability.        |
| Time and units | Local dates, time zones, metric/imperial conversion.       | Protects user-facing values and daily summaries.         |
| Channels       | Channel identifier normalization and link logic.           | Protects WhatsApp/Telegram account mapping.              |
| Onboarding     | Profile, goals and nutrition setup.                        | Protects the first business state created for a user.    |
| Users          | `/me` and internal user context services.                  | Protects frontend session reads and Agent context reads. |
| Meals          | Meal service, idempotency and summary increments.          | Protects nutrition logging correctness.                  |
| Weight         | Weight service and unit display behavior.                  | Protects progress tracking.                              |
| Workouts       | Basic workout service behavior.                            | Protects the training module foundation.                 |
| Coaching       | Coaching profile service.                                  | Protects personalized context storage.                   |
| Health         | Health service.                                            | Protects infrastructure health checks.                   |

### Main Platform gaps

| Gap                                           | Risk                                                                   |
| --------------------------------------------- | ---------------------------------------------------------------------- |
| Branch coverage is low                        | Conditional business rules may behave differently in edge cases.       |
| Workout coverage is still weak                | Training data can become inconsistent once the frontend depends on it. |
| Redis service coverage is low                 | Runtime cache/session failures may not be handled intentionally.       |
| Session guard coverage is thin                | Browser session bugs can appear as confusing frontend auth failures.   |
| Auth controller edge cases need more coverage | Login, logout, Google auth and error paths are sensitive.              |
| Prisma lifecycle is lightly tested            | Startup/shutdown issues can surface only in production containers.     |

### Recommended Platform tests

<CardGroup cols={2}>
  <Card title="Meal idempotency" icon="utensils">
    Replaying the same idempotency key should return the same entry and must not increment summaries twice.
  </Card>

  <Card title="Webhook race safety" icon="shuffle">
    Concurrent duplicate writes should safely handle unique conflicts and preserve exactly-once summary increments.
  </Card>

  <Card title="Onboarding gates" icon="shield-check">
    Meal, weight and workout actions that require profile context should fail cleanly when onboarding is incomplete.
  </Card>

  <Card title="Weight display contract" icon="scale">
    Latest and list responses should preserve the response-level `unitSystem` wrapper and server-side conversion.
  </Card>

  <Card title="Workout persistence" icon="dumbbell">
    Workout sessions should test exercises, sets, invalid payloads and future idempotency behavior.
  </Card>

  <Card title="Session guard" icon="lock">
    Missing, expired and malformed sessions should return predictable unauthorized errors.
  </Card>
</CardGroup>

## Agent testing

Agent uses the standard Go test runner.

### Commands

```bash theme={null}
# Run tests
make test

# Equivalent direct command
GOCACHE=/tmp/go-build GOMODCACHE=/tmp/go-mod go test ./...

# Run with coverage profile
GOCACHE=/tmp/go-build GOMODCACHE=/tmp/go-mod go test ./... -coverprofile=/tmp/moveat-agent-cover.out

go tool cover -func=/tmp/moveat-agent-cover.out
```

The Makefile sets `GOCACHE` and `GOMODCACHE` to `/tmp` so local runs do not depend on user-level cache directories.

### Package-level coverage

| Package                    | Coverage | Interpretation                                                      |
| -------------------------- | -------: | ------------------------------------------------------------------- |
| WhatsApp Cloud API adapter |    83.3% | Good coverage around outbound WhatsApp replies.                     |
| WhatsApp webhook adapter   |    84.1% | Good coverage around verification, signatures and mapping.          |
| LLM core                   |    76.8% | Solid foundation for interpreter/parser behavior.                   |
| Orchestration              |    78.0% | Good early coverage of incoming message flow.                       |
| Session store              |    71.9% | Reasonable, but failure and TTL behavior should keep improving.     |
| App wiring                 |    55.5% | Acceptable but startup validation can be stronger.                  |
| Gemini adapter             |     6.1% | Low because external provider behavior is not deeply mocked/tested. |
| Telegram adapter           |     0.0% | Placeholder/future adapter.                                         |
| HTTP health adapter        |     0.0% | Low risk but easy to cover.                                         |
| `cmd/server`               |     0.0% | Usually better covered indirectly through config/app tests.         |
| `tools/dev-chat`           |     0.0% | Development utility, not product-critical.                          |

### What Agent already tests

| Area               | What is covered                                                           | Why it matters                             |
| ------------------ | ------------------------------------------------------------------------- | ------------------------------------------ |
| WhatsApp webhook   | Verification, signature validation, payload mapping and handler behavior. | Protects incoming channel correctness.     |
| WhatsApp Cloud API | Recipient formatting and sender behavior.                                 | Protects replies to users.                 |
| LLM parsing        | Structured response parsing and interpreter behavior.                     | Protects intent and decision extraction.   |
| Orchestration      | Incoming message handling and decision rules.                             | Protects channel-neutral business flow.    |
| Session storage    | In-memory and Redis-backed stores.                                        | Protects clarification state.              |
| App config/server  | Configuration loading and basic server wiring.                            | Protects startup behavior.                 |
| Gemini adapter     | Basic provider behavior.                                                  | Protects initial LLM provider integration. |

### Main Agent gaps

| Gap                                             | Risk                                                                            |
| ----------------------------------------------- | ------------------------------------------------------------------------------- |
| Platform client tests are missing or incomplete | Agent may call Platform without required auth, idempotency or timeout behavior. |
| Gemini adapter coverage is low                  | Provider failures and malformed model responses can break orchestration.        |
| Fallback provider behavior is not fully defined | Future multi-provider support needs predictable failure handling.               |
| Media handling needs stronger tests             | Food images/audio will introduce external API and MIME validation risk.         |
| Dev chat appears in aggregate coverage          | Coverage number is pulled down by a non-production utility.                     |

### Recommended Agent tests

1. Platform client attaches internal auth token, timeout, correlation ID and idempotency key.
2. Platform client maps non-2xx responses into typed errors.
3. Channel resolution caches safely but never becomes source of truth.
4. Register meal flow derives idempotency from the WhatsApp message ID.
5. LLM parser handles incomplete, malformed and partially valid JSON.
6. Media download validates MIME type and handles Meta API failures.
7. Startup fails fast when required LLM or Platform configuration is missing.

## Deploy readiness policy

Before deploying Platform:

```bash theme={null}
yarn verify
```

Before deploying Agent:

```bash theme={null}
make test
```

Before deploying a contract change between Agent and Platform:

1. Platform tests pass.
2. Agent tests pass.
3. Swagger/OpenAPI reflects the Platform contract.
4. Agent DTO/client code matches the internal API contract.
5. Idempotency and auth behavior are manually verified in a local or staging-like environment.
6. Grafana dashboards are ready to inspect errors after deploy.

## Coverage target recommendation

Platform already has an 80% threshold. The practical next step is not lowering it; it is adding tests for the modules that represent real product risk.

Agent should eventually add a coverage target, but only after excluding low-value command/dev-tool packages from the aggregate or separating them from product packages. Otherwise the number will encourage testing the wrong code.
