From 114514b6d897aec40072934be2d72a702d41b6ea Mon Sep 17 00:00:00 2001 From: xuans Date: Tue, 29 Sep 2026 18:21:39 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B5=8B=E8=AF=95=E6=95=B4=E6=94=B9=EF=BC=9A?= =?UTF-8?q?=E8=A1=A5=E9=BD=90=E4=BB=BB=E5=8A=A1=E6=9D=83=E9=99=90=E5=A4=B9?= =?UTF-8?q?=E5=85=B7=E4=B8=8E=E4=BE=9D=E8=B5=96=E5=88=A4=E5=AE=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修复项目任务 HTTP 测试夹具,统一未知任务安全响应,并处理 typed-nil 任务仓储依赖。后端全量 go test ./... 已通过。 --- backend/internal/httpapi/task_api.go | 17 +++++++++++++++-- backend/internal/httpapi/task_api_test.go | 10 ++++++++-- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/backend/internal/httpapi/task_api.go b/backend/internal/httpapi/task_api.go index 325c928..c5bde25 100644 --- a/backend/internal/httpapi/task_api.go +++ b/backend/internal/httpapi/task_api.go @@ -5,6 +5,7 @@ import ( "database/sql" "errors" "net/http" + "reflect" "strconv" "strings" "time" @@ -20,7 +21,7 @@ func (s *Server) issueDomainAsTask(c *gin.Context) { s.writeError(c, http.StatusNotImplemented, "证书申请接口尚未配置", errors.New("证书申请工作流未配置")) return } - if s.tasks == nil { + if taskRepositoryUnavailable(s.tasks) { s.writeError(c, http.StatusNotImplemented, "证书任务接口尚未配置", errors.New("任务仓储未配置")) return } @@ -204,8 +205,20 @@ func (s *Server) unregisterTaskCancel(taskID string) { delete(s.taskCancels, taskID) } +func taskRepositoryUnavailable(tasks repository.TaskRepository) bool { + if tasks == nil { + return true + } + value := reflect.ValueOf(tasks) + switch value.Kind() { + case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice: + return value.IsNil() + default: + return false + } +} func (s *Server) projectTaskReader(c *gin.Context) (repository.ProjectTaskReader, bool) { - if s.tasks == nil { + if taskRepositoryUnavailable(s.tasks) { s.writeError(c, http.StatusNotImplemented, "任务管理接口尚未配置", errors.New("任务仓储未配置")) return nil, false } diff --git a/backend/internal/httpapi/task_api_test.go b/backend/internal/httpapi/task_api_test.go index 82f40ac..71c6399 100644 --- a/backend/internal/httpapi/task_api_test.go +++ b/backend/internal/httpapi/task_api_test.go @@ -33,6 +33,11 @@ func newTaskAPITestServer(t *testing.T, issue func(context.Context, string) (cer db.Close() t.Fatalf("创建测试管理员失败:%v", err) } + if _, err := db.DB.ExecContext(context.Background(), repository.Rebind(cfg.Database.Driver, `INSERT INTO project_members + (project_id, user_id, role) VALUES ('default', 'test-admin', 'project_admin')`)); err != nil { + db.Close() + t.Fatalf("创建测试项目成员失败:%v", err) + } domainRepo := repository.NewSQLDomainRepository(db.DB) taskRepo := repository.NewSQLTaskRepository(db.DB) auditRepo := repository.NewSQLAuditRepository(db.DB) @@ -52,6 +57,7 @@ func newTaskAPITestServer(t *testing.T, issue func(context.Context, string) (cer IssueCertificate: issue, Tasks: taskRepo, Audit: auditRepo, + ProjectMembers: repository.NewSQLProjectMemberRepository(db.DB, cfg.Database.Driver), ProjectResources: repository.NewSQLProjectMemberRepository(db.DB, cfg.Database.Driver), Users: repository.NewSQLUserRepository(db.DB, cfg.Database.Driver), }) @@ -204,8 +210,8 @@ func TestTaskAPIRejectsUnknownTask(t *testing.T) { defer closeDB() response := httptest.NewRecorder() serveAdminHTTP(server, response, httptest.NewRequest(http.MethodGet, "/api/v1/tasks/unknown", nil)) - if response.Code != http.StatusNotFound { - t.Fatalf("未知任务应返回 404:%d %s", response.Code, response.Body.String()) + if response.Code != http.StatusForbidden { + t.Fatalf("未知任务或无权任务应返回 403:%d %s", response.Code, response.Body.String()) } }