Files
agent-bot 7de9e35dcf
CI / go-vet (pull_request) Failing after 39s
CI / backup-restore-drill (pull_request) Successful in 30s
CI / web (pull_request) Successful in 31s
fix(chat): bind project ID through CLI chat + stage dispatch (issue #2)
Root cause: the 2026-09-28 controlled-projection hardening added the
ErrUnboundControlledProject guard, and the server path got session project
binding backfilled - but two paths missed:
- CLI chat mode never called session.SetProjectID (only -project name)
- coordinator handleAdvanceStage built StageRunRequest without
  ProjectID/UserID, so every stage-advance squad task was rejected

Fixes:
- handleChatMode gains projectID param (wired from -project-id flag);
  session binding follows the server convention
- handleAdvanceStage passes parseDecimalID(UserCtx.Project/User.ID)
- CLI chat tests get hermetic env (unreachable DB + ALLOW_IN_MEMORY) so
  local runs stop accidentally hitting the real dev DB on :5433
- stale test TestBindSessionProjectContext_KeepsExistingProjectID asserted
  the pre-fix 'switch does not propagate' bug; updated to assert switch
  propagation + bind no-overwrite

Result: go test -short ./... = 75 packages, 0 failures (first time).
Short tests promoted from report-only back into the required CI gate.
2026-09-29 09:04:16 +00:00

47 lines
1.5 KiB
Go

package server
import (
"testing"
"chat-agent-system/internal/chat"
"chat-agent-system/internal/coordinator"
)
func TestBindSessionProjectContext_FillsEmptyProjectID(t *testing.T) {
sess := chat.NewSession("sess-p6024-u4", &coordinator.UserProjectContext{
Project: coordinator.ProjectInfo{Name: "吞咽电刺激"},
}, nil, nil)
sess.SetProjectID(6024)
bindSessionProjectContext(sess)
if sess.UserCtx.Project.ID != "6024" {
t.Fatalf("project id=%q", sess.UserCtx.Project.ID)
}
}
// 2026-09-28 回填会话项目绑定后,SetProjectID 会同步协调器上下文:
// 切换项目必须传导(旧断言"保留 9"固化的是切换不生效的缺陷)。
func TestBindSessionProjectContext_SwitchPropagates(t *testing.T) {
sess := chat.NewSession("sess-keep", &coordinator.UserProjectContext{
Project: coordinator.ProjectInfo{ID: "9", Name: "已绑定"},
}, nil, nil)
sess.SetProjectID(6024)
if sess.UserCtx.Project.ID != "6024" {
t.Fatalf("project switch must propagate, got %q", sess.UserCtx.Project.ID)
}
bindSessionProjectContext(sess)
if sess.UserCtx.Project.ID != "6024" {
t.Fatalf("bind must not overwrite explicit binding, got %q", sess.UserCtx.Project.ID)
}
}
func TestBindSessionProjectContext_SkipsUnboundSession(t *testing.T) {
sess := chat.NewSession("sess-none", &coordinator.UserProjectContext{
Project: coordinator.ProjectInfo{Name: "未选项目"},
}, nil, nil)
sess.SetProjectID(0)
bindSessionProjectContext(sess)
if sess.UserCtx.Project.ID != "" {
t.Fatalf("project id=%q", sess.UserCtx.Project.ID)
}
}