package data import ( "testing" ) func TestMigrateLegacyAuthorityAPIsWithoutDeletedAt(t *testing.T) { db, err := openWithDriver("sqlite", "file:"+t.Name()+"?mode=memory&cache=shared") if err != nil { t.Fatal(err) } sqlDB, err := db.DB() if err != nil { t.Fatal(err) } t.Cleanup(func() { _ = sqlDB.Close() }) for _, statement := range []string{ `CREATE TABLE sys_apis (id integer primary key, path text, method text)`, `CREATE TABLE sys_authority_apis (authority_id integer, api_id integer)`, `INSERT INTO sys_apis (id, path, method) VALUES (1, '/legacy', 'GET')`, `INSERT INTO sys_authority_apis (authority_id, api_id) VALUES (888, 1)`, } { if err = db.Exec(statement).Error; err != nil { t.Fatal(err) } } if err = db.AutoMigrate(&casbinRulePO{}, &errorRecordPO{}); err != nil { t.Fatal(err) } legacyError := errorRecordPO{Status: "未解决"} if err = db.Create(&legacyError).Error; err != nil { t.Fatal(err) } if err = migrateLegacyAuthorityAPIsToCasbinRules(db); err != nil { t.Fatalf("legacy migration failed without sys_apis.deleted_at: %v", err) } if err = normalizeErrorRecordStatuses(db); err != nil { t.Fatalf("following migration inherited the legacy table alias: %v", err) } var count int64 if err = db.Model(&casbinRulePO{}). Where("ptype = ? AND v0 = ? AND v1 = ? AND v2 = ?", "p", "888", "/legacy", "GET"). Count(&count).Error; err != nil { t.Fatal(err) } if count != 1 { t.Fatalf("migrated policy count = %d, want 1", count) } if err = db.First(&legacyError, legacyError.ID).Error; err != nil { t.Fatal(err) } if legacyError.Status != "未处理" { t.Fatalf("normalized status = %q, want 未处理", legacyError.Status) } } func TestReconcileRootAuthorityAPIsUsesIndependentQueries(t *testing.T) { db, err := openWithDriver("sqlite", "file:"+t.Name()+"?mode=memory&cache=shared") if err != nil { t.Fatal(err) } sqlDB, err := db.DB() if err != nil { t.Fatal(err) } t.Cleanup(func() { _ = sqlDB.Close() }) if err = db.AutoMigrate(&authorityPO{}, &apiPO{}, &ignoredAPIPO{}, &casbinRulePO{}); err != nil { t.Fatal(err) } if err = db.Create(&authorityPO{AuthorityID: 888, AuthorityName: "root"}).Error; err != nil { t.Fatal(err) } if err = db.Create(&apiPO{Path: "/allowed", Method: "GET"}).Error; err != nil { t.Fatal(err) } if err = db.Create(&apiPO{Path: "/ignored", Method: "POST"}).Error; err != nil { t.Fatal(err) } if err = db.Create(&ignoredAPIPO{Path: "/ignored", Method: "POST"}).Error; err != nil { t.Fatal(err) } // Deliberately pass a handle carrying an unrelated model and predicate. // Migration queries must not inherit either state. dirty := db.Model(&authorityPO{}).Where("authority_id = ?", 999) if err = reconcileRootAuthorityAPIs(dirty); err != nil { t.Fatalf("reconcile root policies with dirty DB state: %v", err) } var rules []casbinRulePO if err = db.Where("ptype = ? AND v0 = ?", "p", "888").Find(&rules).Error; err != nil { t.Fatal(err) } if len(rules) != 1 || rules[0].V1 != "/allowed" || rules[0].V2 != "GET" { t.Fatalf("root rules = %#v, want only GET /allowed", rules) } } func TestMigrateLegacyAuthorityDepartmentColumns(t *testing.T) { db, err := openWithDriver("sqlite", "file:"+t.Name()+"?mode=memory&cache=shared") if err != nil { t.Fatal(err) } sqlDB, err := db.DB() if err != nil { t.Fatal(err) } t.Cleanup(func() { _ = sqlDB.Close() }) for _, statement := range []string{ `CREATE TABLE sys_authority_departments (authority_id integer, department_id integer, PRIMARY KEY (authority_id, department_id))`, `INSERT INTO sys_authority_departments (authority_id, department_id) VALUES (888, 7)`, } { if err = db.Exec(statement).Error; err != nil { t.Fatal(err) } } if err = migrateLegacyAuthorityDepartmentColumns(db); err != nil { t.Fatalf("migrate legacy authority-department columns: %v", err) } if err = db.AutoMigrate(&authorityDepartmentPO{}); err != nil { t.Fatal(err) } var relation authorityDepartmentPO if err = db.First(&relation).Error; err != nil { t.Fatal(err) } if relation.AuthorityID != 888 || relation.DepartmentID != 7 { t.Fatalf("migrated relation = %#v", relation) } for _, column := range []string{"sys_authority_authority_id", "sys_department_id"} { if !tableHasColumn(db, "sys_authority_departments", column) { t.Fatalf("missing compatible column %s", column) } } hasPrimaryKey, err := tableHasPrimaryKey(db, "sys_authority_departments") if err != nil { t.Fatal(err) } if hasPrimaryKey { t.Fatal("authority-department table retained the legacy primary key") } if err = db.Create(&authorityDepartmentPO{AuthorityID: 888, DepartmentID: 7}).Error; err != nil { t.Fatalf("duplicate administration relation was rejected: %v", err) } var count int64 if err = db.Model(&authorityDepartmentPO{}).Where("sys_authority_authority_id = ? AND sys_department_id = ?", 888, 7).Count(&count).Error; err != nil { t.Fatal(err) } if count != 2 { t.Fatalf("duplicate relation count = %d, want 2", count) } }