// Path: Backend/internal/posixproj/projector_test.go package posixproj import ( "encoding/json" "os" "path/filepath" "testing" ) func TestScanRootBuildsProjectedNodesFromBootstrapShape(t *testing.T) { root := filepath.Join(t.TempDir(), "POSIX") mustMkdirAll(t, filepath.Join(root, "catalog", "packs")) mustMkdirAll(t, filepath.Join(root, "catalog", "standalone")) mustMkdirAll(t, filepath.Join(root, "departments", "department-primary-department", "teams", "team-primary-team")) mustMkdirAll(t, filepath.Join(root, "projects", "project-primary-project", "children", "folder-design", "children", "project-web", "children")) mustMkdirAll(t, filepath.Join(root, "projects", "project-primary-project", "children", "folder-design", "children", "project-web", "tree")) mustMkdirAll(t, filepath.Join(root, "projects", "project-primary-project", "tree")) mustMkdirAll(t, filepath.Join(root, "projects", "project-primary-project", "tree", "folder-docs", "children")) mustMkdirAll(t, filepath.Join(root, "projects", "project-primary-project", "tree", "folder-docs", "item-roadmap")) mustMkdirAll(t, filepath.Join(root, "users", "personals")) mustWriteJSON(t, filepath.Join(root, "settings.json"), map[string]any{ "installation": map[string]any{ "id": "installation-1", "name": "MangoPig", "isBootstrapped": true, }, "organization": map[string]any{ "id": "org-1", "name": "Primary Organization", "slug": "primary-organization", }, }) mustWriteJSON(t, filepath.Join(root, "layout.json"), map[string]any{ "type": "tenant-layout", "home": map[string]any{"defaultProjectSlug": "primary-project"}, }) mustWriteJSON(t, filepath.Join(root, "departments", "department-primary-department", "settings.json"), map[string]any{ "id": "dept-1", "name": "Primary Department", "slug": "primary-department", "type": "department", }) mustWriteJSON(t, filepath.Join(root, "departments", "department-primary-department", "users.json"), map[string]any{ "users": []map[string]any{{"id": "admin-1"}}, }) mustWriteJSON(t, filepath.Join(root, "departments", "department-primary-department", "teams", "team-primary-team", "settings.json"), map[string]any{ "id": "team-1", "name": "Primary Team", "slug": "primary-team", "type": "team", }) mustWriteJSON(t, filepath.Join(root, "projects", "project-primary-project", "settings.json"), map[string]any{ "id": "project-1", "name": "Primary Project", "slug": "primary-project", "type": "project", }) mustWriteJSON(t, filepath.Join(root, "projects", "project-primary-project", "home.json"), map[string]any{ "type": "project-home", "project": "primary-project", }) mustWriteJSON(t, filepath.Join(root, "projects", "project-primary-project", "acl.json"), map[string]any{ "inherits": true, "rules": []any{}, }) mustWriteJSON(t, filepath.Join(root, "projects", "project-primary-project", "children", "folder-design", "folder.json"), map[string]any{ "name": "Design", "slug": "design", }) mustWriteJSON(t, filepath.Join(root, "projects", "project-primary-project", "children", "folder-design", "acl.json"), map[string]any{ "inherits": true, "rules": []any{}, }) mustWriteJSON(t, filepath.Join(root, "projects", "project-primary-project", "children", "folder-design", "children", "project-web", "settings.json"), map[string]any{ "id": "project-2", "name": "Web Project", "slug": "web", "type": "project", }) mustWriteJSON(t, filepath.Join(root, "projects", "project-primary-project", "children", "folder-design", "children", "project-web", "home.json"), map[string]any{ "type": "project-home", "project": "web", }) mustWriteJSON(t, filepath.Join(root, "projects", "project-primary-project", "children", "folder-design", "children", "project-web", "acl.json"), map[string]any{ "inherits": true, "rules": []any{}, }) mustWriteJSON(t, filepath.Join(root, "projects", "project-primary-project", "tree", "folder-docs", "folder.json"), map[string]any{ "name": "Docs", "slug": "docs", }) mustWriteJSON(t, filepath.Join(root, "projects", "project-primary-project", "tree", "folder-docs", "item-roadmap", "item.json"), map[string]any{ "id": "item-1", "name": "Roadmap", "slug": "roadmap", "type": "board", }) mustWriteJSON(t, filepath.Join(root, "projects", "project-primary-project", "tree", "folder-docs", "item-roadmap", "schema.json"), map[string]any{ "type": "object", }) mustWriteJSON(t, filepath.Join(root, "projects", "project-primary-project", "tree", "folder-docs", "item-roadmap", "data.json"), map[string]any{ "title": "Roadmap", }) mustWriteJSON(t, filepath.Join(root, "users", "settings.json"), map[string]any{ "primaryAdminId": "admin-1", }) mustWriteJSON(t, filepath.Join(root, "users", "data.json"), map[string]any{ "users": []map[string]any{{"id": "admin-1", "email": "ronald@example.com"}}, }) nodes, err := ScanRoot(root) if err != nil { t.Fatalf("ScanRoot() error = %v", err) } index := make(map[string]Node, len(nodes)) for _, node := range nodes { index[node.Path] = node } rootNode, ok := index[rootProjectionPath] if !ok { t.Fatalf("expected synthetic root node") } if rootNode.LogicalType != "tenant_root" { t.Fatalf("expected root logical type tenant_root, got %q", rootNode.LogicalType) } if rootNode.OrganizationSlug != "primary-organization" { t.Fatalf("expected root organization slug primary-organization, got %q", rootNode.OrganizationSlug) } tenantSettings := index["settings.json"] if tenantSettings.LogicalType != "tenant" || tenantSettings.FileRole != "settings" { t.Fatalf("unexpected tenant settings classification: %#v", tenantSettings) } if tenantSettings.InstallationID != "installation-1" { t.Fatalf("expected installation id installation-1, got %q", tenantSettings.InstallationID) } deptSettings := index["departments/department-primary-department/settings.json"] if deptSettings.DepartmentSlug != "primary-department" { t.Fatalf("expected department slug primary-department, got %q", deptSettings.DepartmentSlug) } if deptSettings.ResourceID != "dept-1" { t.Fatalf("expected department resource id dept-1, got %q", deptSettings.ResourceID) } teamSettings := index["departments/department-primary-department/teams/team-primary-team/settings.json"] if teamSettings.TeamSlug != "primary-team" { t.Fatalf("expected team slug primary-team, got %q", teamSettings.TeamSlug) } projectSettings := index["projects/project-primary-project/settings.json"] if projectSettings.ProjectSlug != "primary-project" { t.Fatalf("expected project slug primary-project, got %q", projectSettings.ProjectSlug) } if projectSettings.ResourceName != "Primary Project" { t.Fatalf("expected project resource name Primary Project, got %q", projectSettings.ResourceName) } projectTree := index["projects/project-primary-project/tree"] if projectTree.LogicalType != "project_tree" || projectTree.NodeKind != NodeKindDirectory { t.Fatalf("unexpected project tree node: %#v", projectTree) } projectChildren := index["projects/project-primary-project/children"] if projectChildren.LogicalType != "project_children" || projectChildren.NodeKind != NodeKindDirectory { t.Fatalf("unexpected project children node: %#v", projectChildren) } hierarchyFolder := index["projects/project-primary-project/children/folder-design"] if hierarchyFolder.LogicalType != "hierarchy_folder" || hierarchyFolder.ProjectSlug != "primary-project" { t.Fatalf("unexpected hierarchy folder node: %#v", hierarchyFolder) } hierarchyFolderACL := index["projects/project-primary-project/children/folder-design/acl.json"] if hierarchyFolderACL.LogicalType != "hierarchy_folder" || hierarchyFolderACL.FileRole != "acl" { t.Fatalf("unexpected hierarchy folder acl classification: %#v", hierarchyFolderACL) } childProjectSettings := index["projects/project-primary-project/children/folder-design/children/project-web/settings.json"] if childProjectSettings.LogicalType != "project" || childProjectSettings.ProjectSlug != "web" { t.Fatalf("unexpected child project classification: %#v", childProjectSettings) } treeFolder := index["projects/project-primary-project/tree/folder-docs"] if treeFolder.LogicalType != "hierarchy_folder" || treeFolder.ProjectSlug != "primary-project" { t.Fatalf("unexpected tree folder node: %#v", treeFolder) } treeFolderACL := index["projects/project-primary-project/tree/folder-docs/folder.json"] if treeFolderACL.LogicalType != "hierarchy_folder" || treeFolderACL.FileRole != "folder" { t.Fatalf("unexpected tree folder file classification: %#v", treeFolderACL) } treeItem := index["projects/project-primary-project/tree/folder-docs/item-roadmap/item.json"] if treeItem.LogicalType != "item" || treeItem.FileRole != "item" { t.Fatalf("unexpected tree item classification: %#v", treeItem) } if treeItem.ResourceSlug != "roadmap" { t.Fatalf("expected tree item resource slug roadmap, got %#v", treeItem.ResourceSlug) } usersData := index["users/data.json"] if usersData.LogicalType != "users" || usersData.FileRole != "data" { t.Fatalf("unexpected users data classification: %#v", usersData) } if usersData.Checksum == "" || usersData.SizeBytes == 0 { t.Fatalf("expected users/data.json checksum and size to be populated: %#v", usersData) } } func mustMkdirAll(t *testing.T, path string) { t.Helper() if err := os.MkdirAll(path, 0o755); err != nil { t.Fatalf("MkdirAll(%q) error = %v", path, err) } } func mustWriteJSON(t *testing.T, path string, payload any) { t.Helper() bytes, err := json.MarshalIndent(payload, "", " ") if err != nil { t.Fatalf("MarshalIndent(%q) error = %v", path, err) } bytes = append(bytes, '\n') if err := os.WriteFile(path, bytes, 0o644); err != nil { t.Fatalf("WriteFile(%q) error = %v", path, err) } }