docs(gateway): gateway 剩余文件注释改中文(逐行 1:1,代码零字节改动)
主人 2026-10-03 拍板「注释一律中文」;gateway 至此整包注释中文化完成(本会话共 3 批: 已推库 16 个文件 + 本批剩余文件)。 校验:机械校验(非注释改动行)= 空;剥注释后代码文本逐行比对全等(不一致文件数 0); 全树 go test ./... 58 包 ok / 0 FAIL;交叉编译绿。
This commit is contained in:
1 parent
91e8d7a029
commit
074ffc4ebf
73 files changed
+2529
-2529
No files matched your search
@@ -11,13 +11,13 @@ import (
|
||||
"git.yeij.top/AskaEth/Cyrene_v2/internal/runtime/history"
|
||||
)
|
||||
|
||||
// These tests cover the D4 read-cursor contract (Android collaboration B3): the
|
||||
// unreadCount carried by GET /api/v1/sessions, the advance endpoint
|
||||
// POST /api/v1/sessions/{id}/read, and the `session_read` frame that clears the badge
|
||||
// on the account's other browsers.
|
||||
// 这些测试覆盖 D4 读游标契约(Android 协作 B3):
|
||||
// GET /api/v1/sessions 携带的 unreadCount、推进端点
|
||||
// POST /api/v1/sessions/{id}/read,以及为该账号其他浏览器清除角标的
|
||||
// `session_read` 帧。
|
||||
|
||||
// unreadBySession decodes GET /api/v1/sessions into a map of session id → unreadCount via
|
||||
// the wire key, so the test asserts the JSON contract rather than the in-package struct.
|
||||
// unreadBySession 经线上键把 GET /api/v1/sessions 解码为 session id → unreadCount 的
|
||||
// map,因此测试断言的是 JSON 契约,而不是包内结构体。
|
||||
func unreadBySession(t *testing.T, ts *httptest.Server, tok string) map[string]int {
|
||||
t.Helper()
|
||||
resp, body := doReq(t, http.MethodGet, ts.URL+"/api/v1/sessions", nil, tok)
|
||||
@@ -36,10 +36,10 @@ func unreadBySession(t *testing.T, ts *httptest.Server, tok string) map[string]i
|
||||
return out
|
||||
}
|
||||
|
||||
// TestSessionsUnreadCountAndMarkRead covers the happy path end to end: a session with
|
||||
// unread messages reports the count, POST /read moves the cursor and answers
|
||||
// {sessionId, readAt}, the list drops to the messages sent after the cursor, and a
|
||||
// body-less POST (mark everything seen) clears the badge.
|
||||
// TestSessionsUnreadCountAndMarkRead 端到端覆盖顺路径:有未读消息的
|
||||
// 会话报告计数,POST /read 推进游标并返回
|
||||
// {sessionId, readAt},列表降到游标之后发送的消息,而无请求体的
|
||||
// POST(全部标记为已见)清除角标。
|
||||
func TestSessionsUnreadCountAndMarkRead(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, ts, jwt, st := newHistoryEnv(t)
|
||||
@@ -61,12 +61,12 @@ func TestSessionsUnreadCountAndMarkRead(t *testing.T) {
|
||||
tok := signAny(t, jwt, "acct", auth.RoleOwner)
|
||||
base := ts.URL + "/api/v1/sessions/" + history.MainSessionID + "/read"
|
||||
|
||||
// Nothing read yet: the main session is fully unread, the sub session independently so.
|
||||
// 尚未读过任何内容:主会话全未读,子会话各自独立地同样如此。
|
||||
if got := unreadBySession(t, ts, tok); got[history.MainSessionID] != 3 || got[sub] != 1 {
|
||||
t.Fatalf("initial unread = %+v, want main 3 / sub 1", got)
|
||||
}
|
||||
|
||||
// Advance the main cursor to 2000: messages at or before it are read.
|
||||
// 把主游标推进到 2000:等于或早于它的消息即已读。
|
||||
resp, body := doReq(t, http.MethodPost, base, map[string]any{"before": 2000}, tok)
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
t.Fatalf("mark read status = %d, want 200 (body=%s)", resp.StatusCode, body)
|
||||
@@ -86,12 +86,12 @@ func TestSessionsUnreadCountAndMarkRead(t *testing.T) {
|
||||
t.Fatalf("read data = %+v, want sessionId %s readAt 2000", data, history.MainSessionID)
|
||||
}
|
||||
|
||||
// Only the later message stays unread, and the sub session is untouched.
|
||||
// 只有较晚那条消息保持未读,且子会话未被触碰。
|
||||
if got := unreadBySession(t, ts, tok); got[history.MainSessionID] != 1 || got[sub] != 1 {
|
||||
t.Fatalf("unread after cursor 2000 = %+v, want main 1 / sub 1", got)
|
||||
}
|
||||
|
||||
// No body = "mark everything I have seen read" (resolved to now server-side).
|
||||
// 无请求体 = 「把我已见的一切标记为已读」(服务端解析为 now)。
|
||||
resp, body = doReq(t, http.MethodPost, base, nil, tok)
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
t.Fatalf("body-less mark status = %d, want 200 (body=%s)", resp.StatusCode, body)
|
||||
@@ -107,7 +107,7 @@ func TestSessionsUnreadCountAndMarkRead(t *testing.T) {
|
||||
}
|
||||
markedNow := data.ReadAt
|
||||
|
||||
// The cursor only moves forward: re-posting a stale cursor must not re-open the badge.
|
||||
// 游标只向前移动:重发陈旧游标不得重新打开角标。
|
||||
resp, body = doReq(t, http.MethodPost, base, map[string]any{"before": 1000}, tok)
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
t.Fatalf("stale mark status = %d, want 200 (body=%s)", resp.StatusCode, body)
|
||||
@@ -123,9 +123,9 @@ func TestSessionsUnreadCountAndMarkRead(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestMarkSessionReadValidation covers the failure contract: a present but unusable
|
||||
// `before` answers 400, an unknown session 404, a viewer 403 and a missing HistoryStore
|
||||
// 501 — none of which may be mistaken for a successful read.
|
||||
// TestMarkSessionReadValidation 覆盖失败契约:存在但不可用的
|
||||
// `before` 返回 400,未知会话 404,viewer 403,HistoryStore
|
||||
// 缺失 501 —— 其中任何一个都不得被误认为读成功。
|
||||
func TestMarkSessionReadValidation(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, ts, jwt, _ := newHistoryEnv(t)
|
||||
@@ -150,34 +150,34 @@ func TestMarkSessionReadValidation(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
// An empty object means "now", not "no-op".
|
||||
// 空对象意味着「现在」,而不是「空操作」。
|
||||
resp, body := doReq(t, http.MethodPost, base, map[string]any{}, tok)
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
t.Fatalf("empty object status = %d, want 200 (body=%s)", resp.StatusCode, body)
|
||||
}
|
||||
|
||||
// Unknown session → 404; the session id is not auto-created.
|
||||
// 未知会话 → 404;会话 id 不会被自动创建。
|
||||
resp, body = doReq(t, http.MethodPost, ts.URL+"/api/v1/sessions/web:missing/read", map[string]any{"before": 1000}, tok)
|
||||
if resp.StatusCode != http.StatusNotFound {
|
||||
t.Fatalf("unknown session status = %d, want 404 (body=%s)", resp.StatusCode, body)
|
||||
}
|
||||
|
||||
// A viewer cannot write the cursor (owner/admin history write, like PATCH /sessions).
|
||||
// viewer 不能写游标(owner/admin 历史写,与 PATCH /sessions 同)。
|
||||
viewer := signAny(t, jwt, "acct", auth.RoleViewer)
|
||||
resp, body = doReq(t, http.MethodPost, base, map[string]any{"before": 1000}, viewer)
|
||||
if resp.StatusCode != http.StatusForbidden {
|
||||
t.Fatalf("viewer status = %d, want 403 (body=%s)", resp.StatusCode, body)
|
||||
}
|
||||
|
||||
// And no token at all is 401, not a silent success.
|
||||
// 而完全不带 token 是 401,不是静默成功。
|
||||
resp, body = doReq(t, http.MethodPost, base, map[string]any{"before": 1000}, "")
|
||||
if resp.StatusCode != http.StatusUnauthorized {
|
||||
t.Fatalf("anonymous status = %d, want 401 (body=%s)", resp.StatusCode, body)
|
||||
}
|
||||
}
|
||||
|
||||
// TestMarkSessionReadNotWired pins the honest degradation: with no HistoryStore injected
|
||||
// the endpoint answers 501 not_implemented rather than pretending the cursor moved.
|
||||
// TestMarkSessionReadNotWired 钉住诚实的退化:未注入 HistoryStore 时
|
||||
// 端点返回 501 not_implemented,而不是假装游标已移动。
|
||||
func TestMarkSessionReadNotWired(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, ts, jwt := buildEnv(t, cfgDefault(), Deps{})
|
||||
@@ -190,9 +190,9 @@ func TestMarkSessionReadNotWired(t *testing.T) {
|
||||
wantErrorShape(t, body)
|
||||
}
|
||||
|
||||
// TestMarkSessionReadBroadcasts asserts the cross-end sync frame: a successful advance
|
||||
// pushes exactly one `session_read` frame scoped to that session and carrying the new
|
||||
// cursor, while a failed one (404) pushes nothing.
|
||||
// TestMarkSessionReadBroadcasts 断言跨端同步帧:成功的推进恰好
|
||||
// 推送一个 `session_read` 帧,作用域为该会话并携带新的
|
||||
// 游标;而失败的推进(404)什么也不推。
|
||||
func TestMarkSessionReadBroadcasts(t *testing.T) {
|
||||
t.Parallel()
|
||||
srv, ts, jwt, _ := newHistoryEnv(t)
|
||||
@@ -222,7 +222,7 @@ func TestMarkSessionReadBroadcasts(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// A failed advance must not tell other ends the badge was cleared.
|
||||
// 失败的推进不得告诉其他端角标已被清除。
|
||||
resp, body = doReq(t, http.MethodPost, ts.URL+"/api/v1/sessions/web:missing/read", map[string]any{"before": 2000}, tok)
|
||||
if resp.StatusCode != http.StatusNotFound {
|
||||
t.Fatalf("unknown status = %d, want 404 (body=%s)", resp.StatusCode, body)
|
||||
|
||||
Reference in new issue
Block a user