Files
aiaa-notification-server/docs/superpowers/specs/2026-08-01-remote-e2e-notify-flow-design.md
T
ryan 39f3774940 feat: 配置列表分页与钉钉机器人分钟级排队限流
统一 sources/templates/channels/rules 列表为分页响应,避免配置增多时全量返回;按钉钉 access_token 限制每分钟发送并在超限时等待下一分钟,降低触发官方封禁风险。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-10 00:34:26 +08:00

3.7 KiB
Raw Blame History

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/<device_key>
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-<suffix>.

  1. Create SourcePOST /api/v1/sources

    • parse_mode: json, status: 1
    • Capture id, api_key, name
  2. Create ChannelsPOST /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 TemplatePOST /api/v1/templates

    • Content includes {{.symbol}} and {{.price}}
  4. Create RulePOST /api/v1/rules

    • source_name / template_name / channels by name
    • event: trade.open
    • enabled: 1
    • Conditions: symbol exists AND price gt 0
  5. NotifyPOST /api/v1/notify

    • Authorization: Bearer <source.api_key>
    • 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

E2E_DINGTALK_WEBHOOK='...' \
E2E_DINGTALK_SECRET='...' \
E2E_BARK_URL='https://api.day.app/<device_key>' \
E2E_EMAIL_TO='149516886@qq.com' \
go test -tags e2e ./test/e2e/ -v -count=1 -timeout 2m

Optional Makefile:

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.