Feat: add persisted folder rename

This commit is contained in:
MangoPig
2026-06-24 17:07:08 +01:00
parent 268093d223
commit a5f0c41cba
7 changed files with 701 additions and 110 deletions
@@ -211,6 +211,105 @@ func TestCreateProjectTreeFolderOnDiskCreatesExpectedFolderShape(t *testing.T) {
}
}
func TestRenameProjectHierarchyFolderOnDiskRenamesFolderShape(t *testing.T) {
rootPath := filepath.Join(t.TempDir(), "POSIX")
service := NewService(nil, rootPath)
err := service.ensureBootstrapPOSIXSkeleton(
InstallationRecord{ID: "installation-1", Name: "MangoPig", Mode: "personal", Access: "local", Protocol: "http", Host: "localhost", IsBootstrapped: true},
AdminSummary{ID: "admin-1", Email: "ronald@example.com", DisplayName: "Ronald"},
namedRecord{ID: "org-1", Name: "Primary Organization", Slug: "primary-organization"},
namedRecord{ID: "dept-1", Name: "Primary Department", Slug: "primary-department"},
namedRecord{ID: "team-1", Name: "Primary Team", Slug: "primary-team"},
namedRecord{ID: "project-1", Name: "Primary Project", Slug: "primary-project"},
)
if err != nil {
t.Fatalf("ensure bootstrap POSIX skeleton: %v", err)
}
createdPath, _, err := service.createProjectHierarchyFolderOnDisk("primary-project", "", "Design System")
if err != nil {
t.Fatalf("createProjectHierarchyFolderOnDisk root folder: %v", err)
}
nestedPath, _, err := service.createProjectHierarchyFolderOnDisk("primary-project", createdPath, "Research")
if err != nil {
t.Fatalf("createProjectHierarchyFolderOnDisk nested folder: %v", err)
}
previousPath, renamedPath, err := service.renameProjectHierarchyFolderOnDisk("primary-project", createdPath, "Platform Design")
if err != nil {
t.Fatalf("renameProjectHierarchyFolderOnDisk: %v", err)
}
if previousPath != createdPath {
t.Fatalf("expected previous path %s, got %s", createdPath, previousPath)
}
if renamedPath != "projects/project-primary-project/children/folder-platform-design" {
t.Fatalf("unexpected renamed path: %s", renamedPath)
}
if _, err := os.Stat(filepath.Join(rootPath, filepath.FromSlash(createdPath))); !os.IsNotExist(err) {
t.Fatalf("expected previous folder path to be gone, got err=%v", err)
}
renamedFolderPath := filepath.Join(rootPath, filepath.FromSlash(renamedPath))
if _, err := os.Stat(filepath.Join(renamedFolderPath, "children", filepath.Base(nestedPath))); err != nil {
t.Fatalf("expected nested child folder to move with renamed parent: %v", err)
}
folderPayload := readJSONFileForTest[map[string]any](t, filepath.Join(renamedFolderPath, "folder.json"))
if folderPayload["name"] != "Platform Design" {
t.Fatalf("expected renamed folder name Platform Design, got %#v", folderPayload["name"])
}
if folderPayload["slug"] != "platform-design" {
t.Fatalf("expected renamed folder slug platform-design, got %#v", folderPayload["slug"])
}
if folderPayload["type"] != "folder" {
t.Fatalf("expected renamed folder type folder, got %#v", folderPayload["type"])
}
}
func TestRenameProjectTreeFolderOnDiskRenamesFolderShape(t *testing.T) {
rootPath := filepath.Join(t.TempDir(), "POSIX")
service := NewService(nil, rootPath)
err := service.ensureBootstrapPOSIXSkeleton(
InstallationRecord{ID: "installation-1", Name: "MangoPig", Mode: "personal", Access: "local", Protocol: "http", Host: "localhost", IsBootstrapped: true},
AdminSummary{ID: "admin-1", Email: "ronald@example.com", DisplayName: "Ronald"},
namedRecord{ID: "org-1", Name: "Primary Organization", Slug: "primary-organization"},
namedRecord{ID: "dept-1", Name: "Primary Department", Slug: "primary-department"},
namedRecord{ID: "team-1", Name: "Primary Team", Slug: "primary-team"},
namedRecord{ID: "project-1", Name: "Primary Project", Slug: "primary-project"},
)
if err != nil {
t.Fatalf("ensure bootstrap POSIX skeleton: %v", err)
}
createdPath, _, err := service.createProjectTreeFolderOnDisk("primary-project", "", "Docs")
if err != nil {
t.Fatalf("createProjectTreeFolderOnDisk root folder: %v", err)
}
previousPath, renamedPath, err := service.renameProjectTreeFolderOnDisk("primary-project", createdPath, "Specifications")
if err != nil {
t.Fatalf("renameProjectTreeFolderOnDisk: %v", err)
}
if previousPath != createdPath {
t.Fatalf("expected previous path %s, got %s", createdPath, previousPath)
}
if renamedPath != "projects/project-primary-project/tree/folder-specifications" {
t.Fatalf("unexpected renamed path: %s", renamedPath)
}
folderPayload := readJSONFileForTest[map[string]any](t, filepath.Join(rootPath, filepath.FromSlash(renamedPath), "folder.json"))
if folderPayload["name"] != "Specifications" {
t.Fatalf("expected renamed folder name Specifications, got %#v", folderPayload["name"])
}
if folderPayload["slug"] != "specifications" {
t.Fatalf("expected renamed folder slug specifications, got %#v", folderPayload["slug"])
}
}
func TestBuildProjectHierarchyFolderTreeBuildsNestedStructure(t *testing.T) {
rows := []projectHierarchyFolderRow{
{Path: "projects/project-primary-project/children/folder-design", ParentPath: projectHierarchyRootPath("primary-project"), Label: "Design"},