fix(e2e): authenticate multi-role docgov steps in pi-agent lifecycle test
Align seeded user IDs and use per-role Bearer tokens so review reject/approve actions run as the assigned reviewer instead of the legacy fallback principal. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
committed by
weichen
co-authored by
Cursor
parent
7c5f8deeb1
commit
2795af2d09
@@ -75,13 +75,41 @@ func TestPiAgent_FullLifecycle_MultiRole_RealWorld_E2E(t *testing.T) {
|
||||
intendedUse := "神经外科与肝胆外科精密手术中利用 24kHz-35kHz 超声微幅振动选择性粉碎并吸引病灶组织,保留邻近大血管与神经"
|
||||
targetMarket := "中国NMPA三类创新医疗器械"
|
||||
|
||||
authorID := int64(1)
|
||||
// 与 dev 种子账号对齐(internal/auth/store.go)
|
||||
authorID := int64(2) // zhanggong / 张工
|
||||
authorName := "张工"
|
||||
reviewerID := int64(2)
|
||||
reviewerID := int64(3) // lizhuguan / 李主管
|
||||
reviewerName := "李主管"
|
||||
approverID := int64(3)
|
||||
approverID := int64(4) // wangzong / 王总监
|
||||
approverName := "王总监"
|
||||
|
||||
authorToken := loginTestUser(t, ts.Config.Handler, "zhanggong", "123456")
|
||||
reviewerToken := loginTestUser(t, ts.Config.Handler, "lizhuguan", "123456")
|
||||
approverToken := loginTestUser(t, ts.Config.Handler, "wangzong", "123456")
|
||||
|
||||
authedPost := func(path, token string, payload any) (*http.Response, error) {
|
||||
b, _ := json.Marshal(payload)
|
||||
req, err := http.NewRequest(http.MethodPost, ts.URL+path, bytes.NewReader(b))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
withBearerAuth(req, token)
|
||||
return client.Do(req)
|
||||
}
|
||||
expectOK := func(label string, resp *http.Response, err error) {
|
||||
t.Helper()
|
||||
if err != nil {
|
||||
t.Fatalf("%s: %v", label, err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
var buf bytes.Buffer
|
||||
_, _ = buf.ReadFrom(resp.Body)
|
||||
t.Fatalf("%s: HTTP %d body=%s", label, resp.StatusCode, buf.String())
|
||||
}
|
||||
}
|
||||
|
||||
sessionID := fmt.Sprintf("sess_cusa_%d", time.Now().UnixNano())
|
||||
|
||||
// 4. 【编制人·张工】登录与立项阶段对话 (穿插非工作流问答 + 行业标准咨询)
|
||||
@@ -319,12 +347,8 @@ func TestPiAgent_FullLifecycle_MultiRole_RealWorld_E2E(t *testing.T) {
|
||||
"user_id": authorID,
|
||||
"user_name": authorName,
|
||||
}
|
||||
cb, _ := json.Marshal(claimReq)
|
||||
respClaim, err := client.Post(ts.URL+"/api/v1/docgov/claim", "application/json", bytes.NewReader(cb))
|
||||
if err != nil || respClaim.StatusCode != http.StatusOK {
|
||||
t.Fatalf("claim failed: %v", err)
|
||||
}
|
||||
respClaim.Body.Close()
|
||||
respClaim, err := authedPost("/api/v1/docgov/claim", authorToken, claimReq)
|
||||
expectOK("claim", respClaim, err)
|
||||
t.Logf("✓ [张工] 成功认领受控文档: DocID=%s", targetDocID)
|
||||
|
||||
// 8.2 编制人【张工】送审 (进入 StateReviewing)
|
||||
@@ -333,12 +357,8 @@ func TestPiAgent_FullLifecycle_MultiRole_RealWorld_E2E(t *testing.T) {
|
||||
"author_id": authorID,
|
||||
"note": "初稿编制完成,已包含 24kHz/35kHz 双频超声与灌注吸引合规说明,请主管审核。",
|
||||
}
|
||||
sb, _ := json.Marshal(submitReq)
|
||||
respSub, err := client.Post(ts.URL+"/api/v1/docgov/submit-review", "application/json", bytes.NewReader(sb))
|
||||
if err != nil || respSub.StatusCode != http.StatusOK {
|
||||
t.Fatalf("submit-review failed: %v", err)
|
||||
}
|
||||
respSub.Body.Close()
|
||||
respSub, err := authedPost("/api/v1/docgov/submit-review", authorToken, submitReq)
|
||||
expectOK("submit-review", respSub, err)
|
||||
t.Logf("✓ [张工] 提交审核成功,文档进入锁定审核态")
|
||||
|
||||
// 8.3 【审核人·李主管】介入并添加批注
|
||||
@@ -367,12 +387,8 @@ func TestPiAgent_FullLifecycle_MultiRole_RealWorld_E2E(t *testing.T) {
|
||||
"action": "reject",
|
||||
"reason": "缺少高频电刀共模互扰防范机制论证,打回草稿态由编制人张工补充后重新送审。",
|
||||
}
|
||||
rjb, _ := json.Marshal(rejReq)
|
||||
respRej, err := client.Post(ts.URL+"/api/v1/docgov/review-decision", "application/json", bytes.NewReader(rjb))
|
||||
if err != nil || respRej.StatusCode != http.StatusOK {
|
||||
t.Fatalf("review reject failed: %v", err)
|
||||
}
|
||||
respRej.Body.Close()
|
||||
respRej, err := authedPost("/api/v1/docgov/review-decision", reviewerToken, rejReq)
|
||||
expectOK("review reject", respRej, err)
|
||||
t.Logf("✓ [李主管] 驳回成功,受控文档自动解锁并退回 drafting 状态")
|
||||
|
||||
// 8.5 编制人【张工】再次送审
|
||||
@@ -381,12 +397,8 @@ func TestPiAgent_FullLifecycle_MultiRole_RealWorld_E2E(t *testing.T) {
|
||||
"author_id": authorID,
|
||||
"note": "已补充 GB 9706.202 绝缘隔离与高频消磁屏蔽方案,重新送审。",
|
||||
}
|
||||
sb2, _ := json.Marshal(submitReq2)
|
||||
respSub2, err := client.Post(ts.URL+"/api/v1/docgov/submit-review", "application/json", bytes.NewReader(sb2))
|
||||
if err != nil || respSub2.StatusCode != http.StatusOK {
|
||||
t.Fatalf("resubmit failed: %v", err)
|
||||
}
|
||||
respSub2.Body.Close()
|
||||
respSub2, err := authedPost("/api/v1/docgov/submit-review", authorToken, submitReq2)
|
||||
expectOK("resubmit", respSub2, err)
|
||||
t.Logf("✓ [张工] 补充材料后再次送审成功")
|
||||
|
||||
// 8.6 【审核人·李主管】第二次审核 -> 审核通过 (Pass)
|
||||
@@ -397,12 +409,8 @@ func TestPiAgent_FullLifecycle_MultiRole_RealWorld_E2E(t *testing.T) {
|
||||
"action": "approve",
|
||||
"comment": "方案已完善,GB 9706.202 及 YY 0644 检验项齐备,同意流转至王总监终审。",
|
||||
}
|
||||
pb, _ := json.Marshal(passReq)
|
||||
respPass, err := client.Post(ts.URL+"/api/v1/docgov/review-decision", "application/json", bytes.NewReader(pb))
|
||||
if err != nil || respPass.StatusCode != http.StatusOK {
|
||||
t.Fatalf("review approve failed: %v", err)
|
||||
}
|
||||
respPass.Body.Close()
|
||||
respPass, err := authedPost("/api/v1/docgov/review-decision", reviewerToken, passReq)
|
||||
expectOK("review approve", respPass, err)
|
||||
t.Logf("✓ [李主管] 审核通过,文档流转至待批准态 (StateApproving)")
|
||||
|
||||
// 8.7 【批准人·王总监】最终批准 (Approve)
|
||||
@@ -413,12 +421,8 @@ func TestPiAgent_FullLifecycle_MultiRole_RealWorld_E2E(t *testing.T) {
|
||||
"action": "approve",
|
||||
"comment": "符合创新微创手术吸引系统三年规划,同意立项并进入工程实施与核价锁定。",
|
||||
}
|
||||
apb, _ := json.Marshal(apprReq)
|
||||
respAppr, err := client.Post(ts.URL+"/api/v1/docgov/approver-decision", "application/json", bytes.NewReader(apb))
|
||||
if err != nil || respAppr.StatusCode != http.StatusOK {
|
||||
t.Fatalf("approver decision failed: %v", err)
|
||||
}
|
||||
respAppr.Body.Close()
|
||||
respAppr, err := authedPost("/api/v1/docgov/approver-decision", approverToken, apprReq)
|
||||
expectOK("approver decision", respAppr, err)
|
||||
t.Logf("✓ [王总监] 最终批准成功,文档彻底锁定生效归档 (StateApproved)")
|
||||
|
||||
// 9. 验证全生命周期数据落盘与审计追溯
|
||||
|
||||
Reference in New Issue
Block a user