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.Coverage numbers below were measured on 2026-06-13 from the local repositories.
Current snapshot
Platform
21 test files, 61 passing tests. Coverage exists but currently fails the configured 80% global threshold.
Agent
Go tests pass. Statement coverage is 59.5% and no global coverage threshold is enforced yet.
| 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 |
Testing philosophy
Moveat should prioritize tests in this order:- Business invariants that can corrupt user data.
- Auth and authorization boundaries.
- Agent-to-Platform contract behavior.
- Unit conversion and time-zone handling.
- External integration adapters.
- Low-risk wiring and static helpers.
Platform testing
Platform uses Vitest for TypeScript tests.Commands
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
Meal idempotency
Replaying the same idempotency key should return the same entry and must not increment summaries twice.
Webhook race safety
Concurrent duplicate writes should safely handle unique conflicts and preserve exactly-once summary increments.
Onboarding gates
Meal, weight and workout actions that require profile context should fail cleanly when onboarding is incomplete.
Weight display contract
Latest and list responses should preserve the response-level
unitSystem wrapper and server-side conversion.Workout persistence
Workout sessions should test exercises, sets, invalid payloads and future idempotency behavior.
Session guard
Missing, expired and malformed sessions should return predictable unauthorized errors.
Agent testing
Agent uses the standard Go test runner.Commands
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
- Platform client attaches internal auth token, timeout, correlation ID and idempotency key.
- Platform client maps non-2xx responses into typed errors.
- Channel resolution caches safely but never becomes source of truth.
- Register meal flow derives idempotency from the WhatsApp message ID.
- LLM parser handles incomplete, malformed and partially valid JSON.
- Media download validates MIME type and handles Meta API failures.
- Startup fails fast when required LLM or Platform configuration is missing.
Deploy readiness policy
Before deploying Platform:- Platform tests pass.
- Agent tests pass.
- Swagger/OpenAPI reflects the Platform contract.
- Agent DTO/client code matches the internal API contract.
- Idempotency and auth behavior are manually verified in a local or staging-like environment.
- Grafana dashboards are ready to inspect errors after deploy.
