package sms_test import ( "go/parser" "go/token" "io/fs" "os" "path/filepath" "strings" "testing" ) const ( demoModule = "atlas9.dev/c/demo" transportPkg = `"atlas9.dev/c/sms"` // import path, as it appears quoted in source ) // transportAllowed lists the packages permitted to import the raw SMS transport, // with the reason. Everything else must send through *sms.Sender so the egress // cap check (CapSmsSend) cannot be bypassed. Keep this list minimal — each entry // is a hole in the boundary. Test files are exempt (they legitimately inject fake // transports at the composition root). Mirrors lib/mail's boundary test. var transportAllowed = map[string]string{ demoModule + "/lib/sms": "the guarded sender — the sole production wrapper of the transport", demoModule + "/boot": "composition root: NewServer wraps the injected transport into *sms.Sender", demoModule: "composition root: main constructs the concrete transport (mock)", } // TestTransportNotImportedDirectly enforces the SMS egress boundary: only the // packages in transportAllowed may import the dumb transport (atlas9.dev/c/sms). // Any other package importing it could send SMS without the CapSmsSend check that // *sms.Sender performs. func TestTransportNotImportedDirectly(t *testing.T) { root := demoModuleRoot(t) fset := token.NewFileSet() err := filepath.WalkDir(root, func(path string, d fs.DirEntry, err error) error { if err != nil { return err } // Don't descend into nested modules (e.g. api/api_gen) — they aren't // part of the demo app. if d.IsDir() { if path != root && hasGoMod(path) { return filepath.SkipDir } return nil } // Test files may inject fake transports; the boundary is about // production send paths. if !strings.HasSuffix(path, ".go") || strings.HasSuffix(path, "_test.go") { return nil } f, err := parser.ParseFile(fset, path, nil, parser.ImportsOnly) if err != nil { return err } for _, imp := range f.Imports { if imp.Path.Value != transportPkg { continue } pkg := pkgImportPath(root, path) if _, ok := transportAllowed[pkg]; !ok { rel, _ := filepath.Rel(root, path) t.Errorf("%s imports the raw SMS transport %s; send through *sms.Sender instead "+ "(or add %s to transportAllowed with a reason)", rel, transportPkg, pkg) } } return nil }) if err != nil { t.Fatal(err) } } // pkgImportPath maps a file's location to its demo-module import path. func pkgImportPath(root, file string) string { rel, _ := filepath.Rel(root, filepath.Dir(file)) rel = filepath.ToSlash(rel) if rel == "." { return demoModule } return demoModule + "/" + rel } func hasGoMod(dir string) bool { _, err := os.Stat(filepath.Join(dir, "go.mod")) return err == nil } // demoModuleRoot ascends from the working directory to the go.mod that declares // the demo module. func demoModuleRoot(t *testing.T) string { dir, err := os.Getwd() if err != nil { t.Fatal(err) } for { if data, err := os.ReadFile(filepath.Join(dir, "go.mod")); err == nil { if declaresModule(string(data), demoModule) { return dir } } parent := filepath.Dir(dir) if parent == dir { t.Fatalf("demo module root (%s) not found above %s", demoModule, dir) } dir = parent } } func declaresModule(gomod, module string) bool { for line := range strings.SplitSeq(gomod, "\n") { if strings.TrimSpace(line) == "module "+module { return true } } return false }