diff --git a/server/internal/library/imtenant/im_table_prefix_guard_test.go b/server/internal/library/imtenant/im_table_prefix_guard_test.go new file mode 100644 index 0000000..f73cbf0 --- /dev/null +++ b/server/internal/library/imtenant/im_table_prefix_guard_test.go @@ -0,0 +1,56 @@ +package imtenant + +import ( + "os" + "path/filepath" + "regexp" + "runtime" + "strings" + "testing" +) + +func TestNoDirectDefaultDBModelForIMTables(t *testing.T) { + _, file, _, ok := runtime.Caller(0) + if !ok { + t.Fatal("runtime caller unavailable") + } + serverRoot := filepath.Clean(filepath.Join(filepath.Dir(file), "..", "..", "..")) + internalRoot := filepath.Join(serverRoot, "internal") + patterns := []*regexp.Regexp{ + regexp.MustCompile(`g\.DB\(\)\.Model\(\s*"im_`), + regexp.MustCompile(`g\.DB\(\)\.Model\(\s*` + "`" + `im_`), + regexp.MustCompile(`g\.DB\(\)\.(Insert|InsertIgnore|Replace|Save|Update|Delete)\([^,\n]+,\s*"im_`), + regexp.MustCompile(`g\.DB\(\)\.(Insert|InsertIgnore|Replace|Save|Update|Delete)\([^,\n]+,\s*` + "`" + `im_`), + } + + var violations []string + err := filepath.WalkDir(internalRoot, func(path string, d os.DirEntry, err error) error { + if err != nil { + return err + } + if d.IsDir() { + return nil + } + if !strings.HasSuffix(path, ".go") || strings.HasSuffix(path, "_test.go") { + return nil + } + content, err := os.ReadFile(path) + if err != nil { + return err + } + for _, pattern := range patterns { + if pattern.Match(content) { + rel, _ := filepath.Rel(serverRoot, path) + violations = append(violations, rel) + break + } + } + return nil + }) + if err != nil { + t.Fatal(err) + } + if len(violations) > 0 { + t.Fatalf("IM public tables must not use default g.DB() model helpers because the default DB has table prefix: %s", strings.Join(violations, ", ")) + } +}