feat(core): Transfer folder structure when deleting a project (no-changelog) (#13865)

This commit is contained in:
Ricardo Espinoza
2025-03-12 09:54:13 -04:00
committed by GitHub
parent 2275b1780a
commit f760d4f21f
3 changed files with 51 additions and 5 deletions

View File

@@ -6,6 +6,7 @@ import { EntityNotFoundError } from '@n8n/typeorm';
import { ActiveWorkflowManager } from '@/active-workflow-manager';
import type { Project } from '@/databases/entities/project';
import type { GlobalRole } from '@/databases/entities/user';
import { FolderRepository } from '@/databases/repositories/folder.repository';
import { ProjectRelationRepository } from '@/databases/repositories/project-relation.repository';
import { ProjectRepository } from '@/databases/repositories/project.repository';
import { SharedCredentialsRepository } from '@/databases/repositories/shared-credentials.repository';
@@ -13,6 +14,7 @@ import { SharedWorkflowRepository } from '@/databases/repositories/shared-workfl
import { getWorkflowById } from '@/public-api/v1/handlers/workflows/workflows.service';
import { CacheService } from '@/services/cache/cache.service';
import { RoleService } from '@/services/role.service';
import { createFolder } from '@test-integration/db/folders';
import {
getCredentialById,
@@ -1048,7 +1050,7 @@ describe('DELETE /project/:projectId', () => {
.expect(404);
});
test('migrates workflows and credentials to another project if `migrateToProject` is passed', async () => {
test('migrates folders, workflows and credentials to another project if `migrateToProject` is passed', async () => {
//
// ARRANGE
//
@@ -1071,6 +1073,11 @@ describe('DELETE /project/:projectId', () => {
{ project: otherProject, role: 'workflow:editor' },
]);
await createFolder(projectToBeDeleted, { name: 'folder1' });
await createFolder(projectToBeDeleted, { name: 'folder2' });
await createFolder(targetProject, { name: 'folder1' });
await createFolder(otherProject, { name: 'folder3' });
//
// ACT
//
@@ -1128,6 +1135,22 @@ describe('DELETE /project/:projectId', () => {
role: 'credential:user',
}),
).resolves.toBeDefined();
// folders are in the target project
const foldersInTargetProject = await Container.get(FolderRepository).findBy({
homeProject: { id: targetProject.id },
});
const foldersInDeletedProject = await Container.get(FolderRepository).findBy({
homeProject: { id: projectToBeDeleted.id },
});
expect(foldersInDeletedProject).toHaveLength(0);
expect(foldersInTargetProject).toHaveLength(3);
expect(foldersInTargetProject.map((f) => f.name)).toEqual(
expect.arrayContaining(['folder1', 'folder1', 'folder2']),
);
});
// This test is testing behavior that is explicitly not enabled right now,