User request
Add proper end-to-end tests for the Reminders app, using real services (no mocks).
Additional requirement (clarification): cover the agent-mediated lifecycle:
thread → agent → (agent schedules reminder) → timer fires → thread gets reminder message → agent wakes + responds.
Specification (research)
Source of truth: agynio/architecture (Centralized E2E + CI integration).
Location + suite
- All E2E tests must live in
agynio/e2e (no per-service test/e2e directories).
- Implement in Go under
suites/go-core (Go testing + testify/require).
Tagging / selection
- Introduce service tag:
svc_reminders (suite + tests).
- Reminders is invoked via Gateway app-proxy and depends on Gateway for delivery; tag the tests to run for either service:
//go:build e2e && (svc_reminders || svc_gateway)
“Real” E2E path (no mocks)
- Invoke Reminders through Gateway’s app-proxy (NOT directly hitting the reminders service) to cover:
- Identity propagation
- Gateway routing
- App networking path
Gateway app-proxy contract
- Base URL:
AGYN_BASE_URL
- Required headers:
Authorization: Bearer <AGYN_API_TOKEN>
x-organization-id: <AGYN_ORGANIZATION_ID>
Content-Type: application/json (POST)
- Endpoints (via Gateway):
GET /apps/reminders/healthz
POST /apps/reminders/create-reminder
POST /apps/reminders/cancel-reminder
POST /apps/reminders/list-reminders
POST /apps/reminders/get-reminder
Seeding + validation (real dependencies)
Seed required data via real services (no DB seeding, no mocks):
- Apps gRPC (
apps:50051, insecure):
AppsService.GetAppBySlug({ slug: \"reminders\" }) → app.identity_id
- Threads gRPC (
threads:50051, insecure):
ThreadsService.CreateThread({ participant_ids: [...] }) → thread.id
ThreadsService.GetMessages({ thread_id, ... }) to assert delivery
Cleanup requirements
- Any test creating reminders must ensure no long-lived pending reminders:
- Use
t.Cleanup to cancel reminders that are not expected to complete quickly.
- Tests must archive any created threads.
- Tests must delete any created agents.
Test cases (critical user journeys)
Implement the following E2E tests (all real, no mocks):
- Gateway→App wiring health:
GET /apps/reminders/healthz via Gateway returns 200.
- Create + Get roundtrip: create reminder (delay ~60s), then get reminder and assert fields are stable; cleanup cancels.
- List filters: create 2 reminders, cancel 1, validate list default/pending/cancelled/all behavior.
- Cancel semantics: cancel pending reminder, verify state transition; second cancel returns
409; random UUID returns 404.
- Delivery happy path: create thread with app participant, create reminder with
delay_seconds=0, poll until completed, verify Threads has exactly one message with body Reminder: <note> and sender = appIdentityID.
- Delivery failure doesn’t mark completed: create reminder for non-existent thread ID, wait briefly, assert still
pending and completed_at == null; cleanup cancels.
- Agent-mediated full loop:
- Create thread with caller identity + an agent as participants (same org where Reminders is installed).
- Send a message that triggers the agent to schedule a short reminder (no mocks).
- Verify sequence:
- agent sends a "scheduled" response
- reminders app posts
Reminder: <note> into the thread
- agent sends a follow-up response after the reminder arrives
- Use a deterministic TestLLM script so the agent reliably executes the scheduling step (shell tool) and produces deterministic messages.
Required e2e repo plumbing
- Update
suites/go-core/suite.yaml tags to include svc_reminders.
- Ensure Go suite can generate/use Apps + Threads gRPC clients (update
buf.gen.yaml inputs if agynio/api/apps/v1 isn’t currently included).
- Add/extend TestLLM suite definitions as needed so the agent can deterministically run the reminder-scheduling shell command and respond to the reminder message.
User request
Add proper end-to-end tests for the Reminders app, using real services (no mocks).
Additional requirement (clarification): cover the agent-mediated lifecycle:
thread → agent → (agent schedules reminder) → timer fires → thread gets reminder message → agent wakes + responds.
Specification (research)
Source of truth: agynio/architecture (Centralized E2E + CI integration).
Location + suite
agynio/e2e(no per-servicetest/e2edirectories).suites/go-core(Gotesting+testify/require).Tagging / selection
svc_reminders(suite + tests).//go:build e2e && (svc_reminders || svc_gateway)“Real” E2E path (no mocks)
Gateway app-proxy contract
AGYN_BASE_URLAuthorization: Bearer <AGYN_API_TOKEN>x-organization-id: <AGYN_ORGANIZATION_ID>Content-Type: application/json(POST)GET /apps/reminders/healthzPOST /apps/reminders/create-reminderPOST /apps/reminders/cancel-reminderPOST /apps/reminders/list-remindersPOST /apps/reminders/get-reminderSeeding + validation (real dependencies)
Seed required data via real services (no DB seeding, no mocks):
apps:50051, insecure):AppsService.GetAppBySlug({ slug: \"reminders\" })→app.identity_idthreads:50051, insecure):ThreadsService.CreateThread({ participant_ids: [...] })→thread.idThreadsService.GetMessages({ thread_id, ... })to assert deliveryCleanup requirements
t.Cleanupto cancel reminders that are not expected to complete quickly.Test cases (critical user journeys)
Implement the following E2E tests (all real, no mocks):
GET /apps/reminders/healthzvia Gateway returns200.409; random UUID returns404.delay_seconds=0, poll untilcompleted, verify Threads has exactly one message with bodyReminder: <note>and sender = appIdentityID.pendingandcompleted_at == null; cleanup cancels.Reminder: <note>into the threadRequired e2e repo plumbing
suites/go-core/suite.yamltags to includesvc_reminders.buf.gen.yamlinputs ifagynio/api/apps/v1isn’t currently included).