优化结构
This commit is contained in:
@@ -1,106 +0,0 @@
|
||||
package data
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
"kra/internal/biz"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type dataScopeRecord struct {
|
||||
ID uint `gorm:"primaryKey"`
|
||||
DeptID uint
|
||||
CreatedBy uint
|
||||
Name string
|
||||
}
|
||||
|
||||
func (dataScopeRecord) TableName() string { return "business_scope_records" }
|
||||
|
||||
func newDataScopeTestDB(t *testing.T) *gorm.DB {
|
||||
t.Helper()
|
||||
db, err := openWithDriver("sqlite", "file:"+t.Name()+"?mode=memory&cache=shared")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := db.AutoMigrate(&dataScopeRecord{}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
registerDataScopeCallbacks(db, nil)
|
||||
sqlDB, err := db.DB()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Cleanup(func() { _ = sqlDB.Close() })
|
||||
return db
|
||||
}
|
||||
|
||||
func TestDataScopeCallbacksFailClosedAndAllowExplicitSystemBypass(t *testing.T) {
|
||||
db := newDataScopeTestDB(t)
|
||||
seed := []dataScopeRecord{
|
||||
{DeptID: 10, CreatedBy: 7, Name: "visible"},
|
||||
{DeptID: 20, CreatedBy: 8, Name: "hidden"},
|
||||
{DeptID: 0, CreatedBy: 9, Name: "unassigned"},
|
||||
}
|
||||
if err := db.Set("data_scope:skip", true).Create(&seed).Error; err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
var rows []dataScopeRecord
|
||||
if err := db.WithContext(context.Background()).Find(&rows).Error; !errors.Is(err, errDataScopeRequired) {
|
||||
t.Fatalf("query without data scope error = %v", err)
|
||||
}
|
||||
|
||||
invalidCtx := biz.NewDataScopeContext(context.Background(), biz.DataScope{UserID: 7, AuthorityID: 1, Scope: 1, All: false})
|
||||
if err := db.WithContext(invalidCtx).Find(&rows).Error; !errors.Is(err, errInvalidDataScope) {
|
||||
t.Fatalf("query with invalid data scope error = %v", err)
|
||||
}
|
||||
|
||||
scopedCtx := biz.NewDataScopeContext(context.Background(), biz.DataScope{UserID: 7, AuthorityID: 1, Scope: 3, DepartmentIDs: []uint{10}})
|
||||
rows = nil
|
||||
if err := db.WithContext(scopedCtx).Order("id").Find(&rows).Error; err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(rows) != 1 || rows[0].Name != "visible" {
|
||||
t.Fatalf("scoped query rows = %+v", rows)
|
||||
}
|
||||
|
||||
emptyCtx := biz.NewDataScopeContext(context.Background(), biz.DataScope{UserID: 7, AuthorityID: 1, Scope: 5})
|
||||
rows = nil
|
||||
if err := db.WithContext(emptyCtx).Find(&rows).Error; err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(rows) != 0 {
|
||||
t.Fatalf("empty custom scope exposed rows: %+v", rows)
|
||||
}
|
||||
|
||||
rows = nil
|
||||
if err := db.Set("data_scope:skip", true).Order("id").Find(&rows).Error; err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(rows) != len(seed) {
|
||||
t.Fatalf("explicit system bypass rows = %d, want %d", len(rows), len(seed))
|
||||
}
|
||||
}
|
||||
|
||||
func TestDataScopeCreateRequiresIdentityAndStampsOwnership(t *testing.T) {
|
||||
db := newDataScopeTestDB(t)
|
||||
if err := db.Create(&dataScopeRecord{Name: "missing"}).Error; !errors.Is(err, errDataScopeRequired) {
|
||||
t.Fatalf("create without data scope error = %v", err)
|
||||
}
|
||||
|
||||
ctx := biz.NewDataScopeContext(context.Background(), biz.DataScope{UserID: 7, AuthorityID: 1, Scope: 3, PrimaryDeptID: 10, DepartmentIDs: []uint{10}})
|
||||
created := dataScopeRecord{Name: "owned", DeptID: 999, CreatedBy: 999}
|
||||
if err := db.WithContext(ctx).Create(&created).Error; err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var stored dataScopeRecord
|
||||
if err := db.Set("data_scope:skip", true).First(&stored, created.ID).Error; err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if stored.DeptID != 10 || stored.CreatedBy != 7 {
|
||||
t.Fatalf("stamped ownership = dept:%d user:%d, want 10/7", stored.DeptID, stored.CreatedBy)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user