Fix: persist folder drag and drop moves
This commit is contained in:
@@ -2,6 +2,7 @@ package bootstrap
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
@@ -310,6 +311,147 @@ func TestRenameProjectTreeFolderOnDiskRenamesFolderShape(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestMoveProjectHierarchyFolderOnDiskMovesFolderToNewParent(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)
|
||||
}
|
||||
|
||||
designPath, _, err := service.createProjectHierarchyFolderOnDisk("primary-project", "", "Design")
|
||||
if err != nil {
|
||||
t.Fatalf("create design folder: %v", err)
|
||||
}
|
||||
operationsPath, _, err := service.createProjectHierarchyFolderOnDisk("primary-project", "", "Operations")
|
||||
if err != nil {
|
||||
t.Fatalf("create operations folder: %v", err)
|
||||
}
|
||||
researchPath, _, err := service.createProjectHierarchyFolderOnDisk("primary-project", designPath, "Research")
|
||||
if err != nil {
|
||||
t.Fatalf("create research folder: %v", err)
|
||||
}
|
||||
nestedPath, _, err := service.createProjectHierarchyFolderOnDisk("primary-project", researchPath, "Interview Notes")
|
||||
if err != nil {
|
||||
t.Fatalf("create nested folder: %v", err)
|
||||
}
|
||||
|
||||
previousPath, movedPath, err := service.moveProjectHierarchyFolderOnDisk("primary-project", researchPath, operationsPath)
|
||||
if err != nil {
|
||||
t.Fatalf("moveProjectHierarchyFolderOnDisk: %v", err)
|
||||
}
|
||||
if previousPath != researchPath {
|
||||
t.Fatalf("expected previous path %s, got %s", researchPath, previousPath)
|
||||
}
|
||||
if movedPath != "projects/project-primary-project/children/folder-operations/children/folder-research" {
|
||||
t.Fatalf("unexpected moved path: %s", movedPath)
|
||||
}
|
||||
|
||||
if _, err := os.Stat(filepath.Join(rootPath, filepath.FromSlash(researchPath))); !os.IsNotExist(err) {
|
||||
t.Fatalf("expected previous folder path to be gone, got err=%v", err)
|
||||
}
|
||||
|
||||
movedFolderPath := filepath.Join(rootPath, filepath.FromSlash(movedPath))
|
||||
if _, err := os.Stat(filepath.Join(movedFolderPath, "children", filepath.Base(nestedPath))); err != nil {
|
||||
t.Fatalf("expected nested child folder to move with moved parent: %v", err)
|
||||
}
|
||||
|
||||
folderPayload := readJSONFileForTest[map[string]any](t, filepath.Join(movedFolderPath, "folder.json"))
|
||||
if folderPayload["name"] != "Research" {
|
||||
t.Fatalf("expected moved folder name Research, got %#v", folderPayload["name"])
|
||||
}
|
||||
if folderPayload["slug"] != "research" {
|
||||
t.Fatalf("expected moved folder slug research, got %#v", folderPayload["slug"])
|
||||
}
|
||||
if folderPayload["type"] != "folder" {
|
||||
t.Fatalf("expected moved folder type folder, got %#v", folderPayload["type"])
|
||||
}
|
||||
}
|
||||
|
||||
func TestMoveProjectTreeFolderOnDiskMovesFolderToNewParent(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)
|
||||
}
|
||||
|
||||
docsPath, _, err := service.createProjectTreeFolderOnDisk("primary-project", "", "Docs")
|
||||
if err != nil {
|
||||
t.Fatalf("create docs folder: %v", err)
|
||||
}
|
||||
archivePath, _, err := service.createProjectTreeFolderOnDisk("primary-project", "", "Archive")
|
||||
if err != nil {
|
||||
t.Fatalf("create archive folder: %v", err)
|
||||
}
|
||||
|
||||
previousPath, movedPath, err := service.moveProjectTreeFolderOnDisk("primary-project", docsPath, archivePath)
|
||||
if err != nil {
|
||||
t.Fatalf("moveProjectTreeFolderOnDisk: %v", err)
|
||||
}
|
||||
if previousPath != docsPath {
|
||||
t.Fatalf("expected previous path %s, got %s", docsPath, previousPath)
|
||||
}
|
||||
if movedPath != "projects/project-primary-project/tree/folder-archive/children/folder-docs" {
|
||||
t.Fatalf("unexpected moved path: %s", movedPath)
|
||||
}
|
||||
|
||||
folderPayload := readJSONFileForTest[map[string]any](t, filepath.Join(rootPath, filepath.FromSlash(movedPath), "folder.json"))
|
||||
if folderPayload["name"] != "Docs" {
|
||||
t.Fatalf("expected moved folder name Docs, got %#v", folderPayload["name"])
|
||||
}
|
||||
if folderPayload["slug"] != "docs" {
|
||||
t.Fatalf("expected moved folder slug docs, got %#v", folderPayload["slug"])
|
||||
}
|
||||
}
|
||||
|
||||
func TestMoveProjectHierarchyFolderOnDiskRejectsDescendantTarget(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)
|
||||
}
|
||||
|
||||
parentPath, _, err := service.createProjectHierarchyFolderOnDisk("primary-project", "", "Parent")
|
||||
if err != nil {
|
||||
t.Fatalf("create parent folder: %v", err)
|
||||
}
|
||||
childPath, _, err := service.createProjectHierarchyFolderOnDisk("primary-project", parentPath, "Child")
|
||||
if err != nil {
|
||||
t.Fatalf("create child folder: %v", err)
|
||||
}
|
||||
|
||||
_, _, err = service.moveProjectHierarchyFolderOnDisk("primary-project", parentPath, childPath)
|
||||
if !errors.Is(err, ErrInvalidProjectFolderMove) {
|
||||
t.Fatalf("expected ErrInvalidProjectFolderMove, got %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildProjectHierarchyFolderTreeBuildsNestedStructure(t *testing.T) {
|
||||
rows := []projectHierarchyFolderRow{
|
||||
{Path: "projects/project-primary-project/children/folder-design", ParentPath: projectHierarchyRootPath("primary-project"), Label: "Design"},
|
||||
|
||||
Reference in New Issue
Block a user