Scert/backend/internal/httpapi/resource_scope_test.go
xuans 5180c7d73f 开发检查点:完成项目域名权限与事务审计接线
提交 P0-07 当前开发检查点,包含项目域名事务仓储、HTTP 路由接线、生产应用依赖及测试夹具调整。
2026-09-29 16:27:36 +08:00

84 lines
3.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package httpapi
import (
"encoding/json"
"fmt"
"net/http"
"net/http/httptest"
"strings"
"testing"
"git.pcux.cn/xuans/Scert/backend/internal/database"
"git.pcux.cn/xuans/Scert/backend/internal/domain"
"git.pcux.cn/xuans/Scert/backend/internal/repository"
"github.com/gin-gonic/gin"
)
func TestDomainResourceScopeAPI(t *testing.T) {
cfg := readyTestConfig(t.TempDir())
db, err := database.Open(t.Context(), cfg.Database)
if err != nil {
t.Fatal(err)
}
defer db.Close()
if err := database.Migrate(t.Context(), db.DB, "sqlite"); err != nil {
t.Fatal(err)
}
for _, userID := range []string{"creator", "editor"} {
if _, err := db.DB.ExecContext(t.Context(), `INSERT INTO users (id, username, password_hash, role, status) VALUES (?, ?, 'test-only-no-login', 'super_admin', 'active')`, userID, userID); err != nil {
t.Fatal(err)
}
}
repo := repository.NewSQLDomainRepository(db.DB)
server := New(Dependencies{Config: cfg, Repository: repo, ProjectDomains: repository.NewSQLProjectMemberRepository(db.DB)})
request := func(method, path, body, user string) *httptest.ResponseRecorder {
req := httptest.NewRequest(method, path, strings.NewReader(body))
req.Header.Set("Content-Type", "application/json")
req.AddCookie(httpUserSessionCookie(server, user, repository.UserRoleAdmin))
response := httptest.NewRecorder()
server.Handler().ServeHTTP(response, req)
return response
}
for _, field := range []string{"project_id", "owner_id", "created_by", "updated_by"} {
body := fmt.Sprintf(`{"name":"forged.example.test","certificate_type":"single","%s":"forged"}`, field)
response := request(http.MethodPost, "/api/v1/domains", body, "creator")
if response.Code != http.StatusBadRequest {
t.Fatalf("客户端不应提供 %s:%d", field, response.Code)
}
}
response := request(http.MethodPost, "/api/v1/domains", `{"name":"scope.example.test","certificate_type":"single"}`, "creator")
if response.Code != http.StatusCreated {
t.Fatalf("创建失败:%d,%s", response.Code, response.Body.String())
}
var created domain.Domain
if err := json.Unmarshal(response.Body.Bytes(), &created); err != nil {
t.Fatal(err)
}
want := domain.ResourceScope{ProjectID: "default", OwnerID: "creator", CreatedBy: "creator", UpdatedBy: "creator"}
if created.ResourceScope != want {
t.Fatalf("创建响应归属错误:%+v", created.ResourceScope)
}
response = request(http.MethodPut, "/api/v1/domains/"+created.ID, `{"name":"edited.example.test","certificate_type":"single"}`, "editor")
if response.Code != http.StatusOK {
t.Fatalf("更新失败:%d,%s", response.Code, response.Body.String())
}
loaded, err := repo.GetByID(t.Context(), created.ID)
want.UpdatedBy = "editor"
if err != nil || loaded.ResourceScope != want {
t.Fatalf("更新后归属错误:%+v,%v", loaded.ResourceScope, err)
}
}
func TestResourceScopePreservesProjectAndCreator(t *testing.T) {
server := New(Dependencies{Config: readyTestConfig(t.TempDir())})
recorder := httptest.NewRecorder()
ctx, _ := gin.CreateTestContext(recorder)
ctx.Request = httptest.NewRequest(http.MethodPut, "/", nil)
ctx.Request.AddCookie(httpUserSessionCookie(server, "editor", repository.UserRoleAdmin))
existing := domain.ResourceScope{ProjectID: "project-a", OwnerID: "owner", CreatedBy: "creator", UpdatedBy: "previous"}
updated := server.updatedResourceScope(ctx, existing)
if updated.ProjectID != existing.ProjectID || updated.OwnerID != existing.OwnerID || updated.CreatedBy != existing.CreatedBy || updated.UpdatedBy != "editor" {
t.Fatalf("更新操作者时丢失原资源归属:%+v", updated)
}
}