fix(tests): re-enable TestResolveYAMLIncludes_RealMoleculeDev (RCA #1763) #1768
@@ -2,6 +2,7 @@ package handlers
|
||||
|
||||
import (
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
@@ -9,6 +10,16 @@ import (
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
// runCmd wraps exec.Command for convenience in tests.
|
||||
func runCmd(name string, args ...string) (exitCode int, stdout, stderr string) {
|
||||
cmd := exec.Command(name, args...)
|
||||
out, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
return -1, string(out), err.Error()
|
||||
}
|
||||
return 0, string(out), ""
|
||||
}
|
||||
|
||||
// resolveYAMLIncludes is the preprocessor Phase 3 uses to split org.yaml
|
||||
// into per-team / per-role files. These tests cover the happy path,
|
||||
// nested includes, path traversal defense, cycle detection, depth cap,
|
||||
@@ -191,31 +202,31 @@ func TestResolveYAMLIncludes_SiblingDirAccess(t *testing.T) {
|
||||
// resolves cleanly via !include and unmarshal into OrgTemplate produces
|
||||
// the full workspace tree. Guards against split regressions landing on
|
||||
// main before they can be caught by a deploy.
|
||||
//
|
||||
// Previously skipped because /org-templates/molecule-dev/ was a stale
|
||||
// in-tree copy with a broken !include graph. The extraction completed
|
||||
// and the canonical copy now lives at molecule-ai/molecule-ai-org-template-
|
||||
// molecule-dev. This test fetches it via HTTPS (no token needed — the repo
|
||||
// is public) to exercise the real include resolution on every CI run.
|
||||
func TestResolveYAMLIncludes_RealMoleculeDev(t *testing.T) {
|
||||
// The in-tree copy at /org-templates/molecule-dev/ is being removed
|
||||
// in favor of the standalone Molecule-AI/molecule-ai-org-template-
|
||||
// molecule-dev repo (see .gitignore comment). Until that removal
|
||||
// lands, the in-tree copy is stale and its !include graph is broken
|
||||
// (teams/dev.yaml references missing core-platform.yaml etc.), so
|
||||
// this integration test is skipped. Re-enable once the extraction
|
||||
// PR lands and this test is rewritten to fetch the standalone repo
|
||||
// or replaced with a self-contained fixture.
|
||||
t.Skip("org-templates/molecule-dev is being extracted to a standalone repo; see .gitignore comment")
|
||||
|
||||
// Locate the monorepo root from the test file location.
|
||||
// Test runs in platform/internal/handlers/; org template is at
|
||||
// ../../../org-templates/molecule-dev/org.yaml.
|
||||
here, err := os.Getwd()
|
||||
if err != nil {
|
||||
t.Fatalf("getwd: %v", err)
|
||||
if _, err := exec.LookPath("git"); err != nil {
|
||||
t.Skip("git not available in this runtime")
|
||||
}
|
||||
orgDir := filepath.Clean(filepath.Join(here, "..", "..", "..", "org-templates", "molecule-dev"))
|
||||
orgFile := filepath.Join(orgDir, "org.yaml")
|
||||
tmp := t.TempDir()
|
||||
// Clone the canonical standalone org template. No token needed — the
|
||||
// repo is public on the same Gitea instance.
|
||||
res, _, _ := runCmd("git", "clone", "--depth", "1",
|
||||
"https://git.moleculesai.app/molecule-ai/molecule-ai-org-template-molecule-dev.git",
|
||||
tmp)
|
||||
if res != 0 {
|
||||
t.Skipf("could not clone standalone org template (skipping integration test): exit %d", res)
|
||||
}
|
||||
orgFile := filepath.Join(tmp, "org.yaml")
|
||||
data, err := os.ReadFile(orgFile)
|
||||
if err != nil {
|
||||
t.Skipf("molecule-dev/org.yaml not found (skipping integration test): %v", err)
|
||||
t.Skipf("org.yaml not found in standalone clone (skipping integration test): %v", err)
|
||||
}
|
||||
expanded, err := resolveYAMLIncludes(data, orgDir)
|
||||
expanded, err := resolveYAMLIncludes(data, tmp)
|
||||
if err != nil {
|
||||
t.Fatalf("resolveYAMLIncludes on real org.yaml: %v", err)
|
||||
}
|
||||
@@ -223,17 +234,18 @@ func TestResolveYAMLIncludes_RealMoleculeDev(t *testing.T) {
|
||||
if err := yaml.Unmarshal(expanded, &tmpl); err != nil {
|
||||
t.Fatalf("unmarshal expanded yaml: %v", err)
|
||||
}
|
||||
// Sanity: should have PM + Marketing Lead at top, and PM should have
|
||||
// at least Research Lead, Dev Lead, Documentation Specialist, Triage
|
||||
// Operator as children (the Phase 3 split targets).
|
||||
if len(tmpl.Workspaces) < 2 {
|
||||
t.Fatalf("expected ≥2 top-level workspaces, got %d", len(tmpl.Workspaces))
|
||||
// Sanity: should have PM + Marketing Lead + Dev Lead (via !external) at
|
||||
// top. PM's direct children were slimmed in Phase 3d: Dev Lead and its
|
||||
// subtree moved to molecule-dev-department, so PM now has Research Lead
|
||||
// as its only direct child.
|
||||
if len(tmpl.Workspaces) < 3 {
|
||||
t.Fatalf("expected ≥3 top-level workspaces, got %d", len(tmpl.Workspaces))
|
||||
}
|
||||
names := map[string]bool{}
|
||||
for _, w := range tmpl.Workspaces {
|
||||
names[w.Name] = true
|
||||
}
|
||||
for _, want := range []string{"PM", "Marketing Lead"} {
|
||||
for _, want := range []string{"PM", "Marketing Lead", "Dev Lead"} {
|
||||
if !names[want] {
|
||||
t.Errorf("expected top-level workspace %q, not found", want)
|
||||
}
|
||||
@@ -245,8 +257,8 @@ func TestResolveYAMLIncludes_RealMoleculeDev(t *testing.T) {
|
||||
break
|
||||
}
|
||||
}
|
||||
if pm == nil || len(pm.Children) < 4 {
|
||||
t.Errorf("PM should have ≥4 children after include resolution, got %d", len(pm.Children))
|
||||
if pm == nil || len(pm.Children) < 1 {
|
||||
t.Errorf("PM should have ≥1 child after include resolution, got %d", len(pm.Children))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -270,3 +282,8 @@ workspaces:
|
||||
t.Errorf("no-op changed semantics; orig=%+v expanded=%+v", orig, expanded)
|
||||
}
|
||||
}
|
||||
|
||||
// TestResolveYAMLIncludes_RealMoleculeDev clones molecule-ai-org-template-molecule-dev
|
||||
// via HTTPS and validates the full org include resolution. The exec.LookPath guard
|
||||
// ensures the test skips gracefully when git is unavailable in the runtime.
|
||||
// CI trigger: 2026-05-25T06:07 UTC
|
||||
|
||||
Reference in New Issue
Block a user