# Remote E2E Notify Flow Test Design **Date:** 2026-08-01 **Status:** Approved (pending final user review of this doc) ## Goal Add a Go end-to-end test that hits a **deployed** notification service over HTTP and exercises the full configuration → send path: `source → channel(s) → template → rule → POST /notify` Channels under test: **DingTalk**, **Bark**, **Email**. Real notifications are sent. ## Non-goals - Local `httptest` / in-process server tests - Mocking `ChannelSender` - CI by default (opt-in via build tag + env vars) - Committing secrets to the repo ## Placement | Item | Path | |------|------| | Test | `test/e2e/notify_flow_test.go` | | Build tag | `//go:build e2e` | | Make target | `test-e2e` (optional helper) | Default `make test` / `go test ./internal/...` must **not** run this suite. ## Target environment | Setting | Default / source | |---------|------------------| | Base URL | `E2E_BASE_URL` → default `http://82.157.251.93:8080` | | Admin auth | `E2E_ADMIN_KEY` → default `admin-sk-change-me` | ## Required env vars (channels) If any of these are missing, the test **Skips** (does not fail): | Variable | Purpose | |----------|---------| | `E2E_DINGTALK_WEBHOOK` | DingTalk robot webhook URL | | `E2E_DINGTALK_SECRET` | DingTalk sign secret | | `E2E_BARK_URL` | Bark base URL, e.g. `https://api.day.app/` | | `E2E_EMAIL_TO` | Email recipient | Secrets live only in the runner environment / local shell, never in source or this spec. ## Flow Resource names use a unique suffix (unix timestamp or random) to avoid collisions, e.g. `e2e-src-`. 1. **Create Source** — `POST /api/v1/sources` - `parse_mode: json`, `status: 1` - Capture `id`, `api_key`, `name` 2. **Create Channels** — `POST /api/v1/channels` ×3 - DingTalk: `type=dingtalk`, config `{webhook_url, secret}` - Bark: `type=bark`, config `{url}` - Email: `type=email`, config `{to: [E2E_EMAIL_TO]}` - All `status: 1` 3. **Create Template** — `POST /api/v1/templates` - Content includes `{{.symbol}}` and `{{.price}}` 4. **Create Rule** — `POST /api/v1/rules` - `source_name` / `template_name` / `channels` by name - `event: trade.open` - `enabled: 1` - Conditions: `symbol` exists AND `price` gt `0` 5. **Notify** — `POST /api/v1/notify` - `Authorization: Bearer ` - Body: `{"event":"trade.open","data":{"symbol":"BTC","price":65000}}` 6. **Assert notify response** - `matched == true` - `accepted == true` - `channels` length == 3 7. **Message-log check** - Poll `GET /api/v1/message-logs?source=...&event=trade.open` for up to ~15s - Assert at least one log entry appears (fail if none within timeout) 8. **Cleanup** via `t.Cleanup` (reverse order) - Delete rule → template → channels → source - Cleanup errors: log only, do not fail the test after a successful assertion path ## Run command ```bash E2E_DINGTALK_WEBHOOK='...' \ E2E_DINGTALK_SECRET='...' \ E2E_BARK_URL='https://api.day.app/' \ E2E_EMAIL_TO='149516886@qq.com' \ go test -tags e2e ./test/e2e/ -v -count=1 -timeout 2m ``` Optional Makefile: ```make test-e2e: go test -tags e2e ./test/e2e/ -v -count=1 -timeout 2m ``` ## Implementation notes - Use `net/http` + `encoding/json` (stdlib); no new test deps required. - Helper for admin JSON requests and source-authed notify. - Failures must include HTTP status + response body for debugging. - Do not hardcode channel secrets in the test file. ## Success criteria - With env vars set and remote healthy: test passes; DingTalk, Bark, and Email receive a message. - Without channel env vars: test skips cleanly. - Without `-tags e2e`: suite is not compiled/run.