package middleware import ( "context" "net/http/httptest" "strings" "testing" "github.com/Tencent/WeKnora/internal/accesspolicy" "github.com/Tencent/WeKnora/internal/types" "github.com/gin-gonic/gin" ) func TestKnowledgeVersionTransferPreservesProvenance(t *testing.T) { gin.SetMode(gin.TestMode) for _, tc := range []struct { name, body string admin, blocked bool }{ {"global copy", `{"source_id":"global"}`, false, true}, {"personal move", `{"source_kb_id":"personal"}`, false, true}, {"ordinary copy", `{"source_id":"owned"}`, false, false}, {"admin copy", `{"source_id":"global"}`, true, false}, } { t.Run(tc.name, func(t *testing.T) { router := gin.New() called := false router.POST("/transfer", func(c *gin.Context) { ctx := context.WithValue(c.Request.Context(), types.TenantRoleContextKey, types.TenantRoleContributor) if tc.admin { ctx = context.WithValue(ctx, types.TenantRoleContextKey, types.TenantRoleAdmin) } ctx = accesspolicy.WithSnapshot(ctx, &accesspolicy.Snapshot{Publications: map[string]bool{"knowledge:global": true}, NoExport: map[string]bool{"knowledge:personal": true}}) c.Request = c.Request.WithContext(ctx) c.Next() }, RequireKnowledgeVersionTransfer(), func(c *gin.Context) { var body map[string]string if err := c.ShouldBindJSON(&body); err != nil { t.Error("middleware consumed request body", err) } called = true c.Status(204) }) req := httptest.NewRequest("POST", "/transfer", strings.NewReader(tc.body)) req.Header.Set("Content-Type", "application/json") router.ServeHTTP(httptest.NewRecorder(), req) if called == tc.blocked { t.Fatal("incorrect transfer authorization") } }) } }