mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-18 02:21:13 +00:00
refactor(core): Introduce import service (no-changelog) (#8001)
Consolidate import logic into import service. Also fixes: - https://linear.app/n8n/issue/PAY-1086 - https://github.com/n8n-io/n8n/issues/7881 - https://community.n8n.io/t/cli-workflow-imports-failing-after-upgrade-to-v1-18-0/33780 - https://linear.app/n8n/issue/PAY-221 - https://github.com/n8n-io/n8n/issues/5477 - https://community.n8n.io/t/export-workflows-with-tags-got-created/6161
This commit is contained in:
185
packages/cli/test/integration/import.service.test.ts
Normal file
185
packages/cli/test/integration/import.service.test.ts
Normal file
@@ -0,0 +1,185 @@
|
||||
import Container from 'typedi';
|
||||
import { mock } from 'jest-mock-extended';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
import type { INode } from 'n8n-workflow';
|
||||
|
||||
import { CredentialsRepository } from '@/databases/repositories/credentials.repository';
|
||||
import { TagRepository } from '@/databases/repositories/tag.repository';
|
||||
import { ImportService } from '@/services/import.service';
|
||||
import { RoleService } from '@/services/role.service';
|
||||
import { TagEntity } from '@/databases/entities/TagEntity';
|
||||
import { WorkflowRepository } from '@/databases/repositories/workflow.repository';
|
||||
import { SharedWorkflowRepository } from '@/databases/repositories/sharedWorkflow.repository';
|
||||
|
||||
import * as testDb from './shared/testDb';
|
||||
import { mockInstance } from '../shared/mocking';
|
||||
import { createOwner } from './shared/db/users';
|
||||
import { createWorkflow, getWorkflowById } from './shared/db/workflows';
|
||||
|
||||
import type { User } from '@db/entities/User';
|
||||
|
||||
describe('ImportService', () => {
|
||||
let importService: ImportService;
|
||||
let tagRepository: TagRepository;
|
||||
let owner: User;
|
||||
|
||||
beforeAll(async () => {
|
||||
await testDb.init();
|
||||
|
||||
owner = await createOwner();
|
||||
|
||||
tagRepository = Container.get(TagRepository);
|
||||
|
||||
const credentialsRepository = mockInstance(CredentialsRepository);
|
||||
|
||||
credentialsRepository.find.mockResolvedValue([]);
|
||||
|
||||
importService = new ImportService(
|
||||
mock(),
|
||||
credentialsRepository,
|
||||
tagRepository,
|
||||
Container.get(RoleService),
|
||||
);
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await testDb.truncate(['Workflow', 'SharedWorkflow', 'Tag', 'WorkflowTagMapping']);
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await testDb.terminate();
|
||||
});
|
||||
|
||||
test('should import credless and tagless workflow', async () => {
|
||||
const workflowToImport = await createWorkflow();
|
||||
|
||||
await importService.importWorkflows([workflowToImport], owner.id);
|
||||
|
||||
const dbWorkflow = await getWorkflowById(workflowToImport.id);
|
||||
|
||||
if (!dbWorkflow) fail('Expected to find workflow');
|
||||
|
||||
expect(dbWorkflow.id).toBe(workflowToImport.id);
|
||||
});
|
||||
|
||||
test('should make user owner of imported workflow', async () => {
|
||||
const workflowToImport = await createWorkflow();
|
||||
|
||||
await importService.importWorkflows([workflowToImport], owner.id);
|
||||
|
||||
const workflowOwnerRole = await Container.get(RoleService).findWorkflowOwnerRole();
|
||||
|
||||
const dbSharing = await Container.get(SharedWorkflowRepository).findOneOrFail({
|
||||
where: { workflowId: workflowToImport.id, userId: owner.id, roleId: workflowOwnerRole.id },
|
||||
});
|
||||
|
||||
expect(dbSharing.userId).toBe(owner.id);
|
||||
});
|
||||
|
||||
test('should deactivate imported workflow if active', async () => {
|
||||
const workflowToImport = await createWorkflow({ active: true });
|
||||
|
||||
await importService.importWorkflows([workflowToImport], owner.id);
|
||||
|
||||
const dbWorkflow = await getWorkflowById(workflowToImport.id);
|
||||
|
||||
if (!dbWorkflow) fail('Expected to find workflow');
|
||||
|
||||
expect(dbWorkflow.active).toBe(false);
|
||||
});
|
||||
|
||||
test('should leave intact new-format credentials', async () => {
|
||||
const credential = {
|
||||
n8nApi: { id: '123', name: 'n8n API' },
|
||||
};
|
||||
|
||||
const nodes: INode[] = [
|
||||
{
|
||||
id: uuid(),
|
||||
name: 'n8n',
|
||||
parameters: {},
|
||||
position: [0, 0],
|
||||
type: 'n8n-nodes-base.n8n',
|
||||
typeVersion: 1,
|
||||
credentials: credential,
|
||||
},
|
||||
];
|
||||
|
||||
const workflowToImport = await createWorkflow({ nodes });
|
||||
|
||||
await importService.importWorkflows([workflowToImport], owner.id);
|
||||
|
||||
const dbWorkflow = await getWorkflowById(workflowToImport.id);
|
||||
|
||||
if (!dbWorkflow) fail('Expected to find workflow');
|
||||
|
||||
expect(dbWorkflow.nodes.at(0)?.credentials).toMatchObject(credential);
|
||||
});
|
||||
|
||||
test('should set tag by identical match', async () => {
|
||||
const tag = Object.assign(new TagEntity(), {
|
||||
id: '123',
|
||||
createdAt: new Date(),
|
||||
name: 'Test',
|
||||
});
|
||||
|
||||
await tagRepository.save(tag); // tag stored
|
||||
|
||||
const workflowToImport = await createWorkflow({ tags: [tag] });
|
||||
|
||||
await importService.importWorkflows([workflowToImport], owner.id);
|
||||
|
||||
const dbWorkflow = await Container.get(WorkflowRepository).findOneOrFail({
|
||||
where: { id: workflowToImport.id },
|
||||
relations: ['tags'],
|
||||
});
|
||||
|
||||
expect(dbWorkflow.tags).toStrictEqual([tag]); // workflow tagged
|
||||
|
||||
const dbTags = await tagRepository.find();
|
||||
|
||||
expect(dbTags).toStrictEqual([tag]); // tag matched
|
||||
});
|
||||
|
||||
test('should set tag by name match', async () => {
|
||||
const tag = Object.assign(new TagEntity(), { name: 'Test' });
|
||||
|
||||
await tagRepository.save(tag); // tag stored
|
||||
|
||||
const workflowToImport = await createWorkflow({ tags: [tag] });
|
||||
|
||||
await importService.importWorkflows([workflowToImport], owner.id);
|
||||
|
||||
const dbWorkflow = await Container.get(WorkflowRepository).findOneOrFail({
|
||||
where: { id: workflowToImport.id },
|
||||
relations: ['tags'],
|
||||
});
|
||||
|
||||
expect(dbWorkflow.tags).toStrictEqual([tag]); // workflow tagged
|
||||
|
||||
const dbTags = await tagRepository.find();
|
||||
|
||||
expect(dbTags).toStrictEqual([tag]); // tag matched
|
||||
});
|
||||
|
||||
test('should set tag by creating if no match', async () => {
|
||||
const tag = Object.assign(new TagEntity(), { name: 'Test' }); // tag not stored
|
||||
|
||||
const workflowToImport = await createWorkflow({ tags: [tag] });
|
||||
|
||||
await importService.importWorkflows([workflowToImport], owner.id);
|
||||
|
||||
const dbWorkflow = await Container.get(WorkflowRepository).findOneOrFail({
|
||||
where: { id: workflowToImport.id },
|
||||
relations: ['tags'],
|
||||
});
|
||||
|
||||
if (!dbWorkflow.tags) fail('No tags found on workflow');
|
||||
|
||||
expect(dbWorkflow.tags.at(0)?.name).toBe(tag.name); // workflow tagged
|
||||
|
||||
const dbTag = await tagRepository.findOneOrFail({ where: { name: tag.name } });
|
||||
|
||||
expect(dbTag.name).toBe(tag.name); // tag created
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user