2024-06-18 01:50:39 -07:00
import { nanoid } from 'nanoid' ;
2023-03-30 06:33:30 -07:00
2023-10-09 07:09:23 -07:00
import { InternalHooks } from '@/InternalHooks' ;
import { ImportWorkflowsCommand } from '@/commands/import/workflow' ;
import { LoadNodesAndCredentials } from '@/LoadNodesAndCredentials' ;
2023-11-10 06:04:26 -08:00
2024-06-18 01:50:39 -07:00
import { setupTestCommand } from '@test-integration/utils/testCommand' ;
2023-11-10 06:04:26 -08:00
import { mockInstance } from '../../shared/mocking' ;
2023-10-09 07:09:23 -07:00
import * as testDb from '../shared/testDb' ;
2024-04-12 08:25:59 -07:00
import { getAllSharedWorkflows , getAllWorkflows } from '../shared/db/workflows' ;
import { createMember , createOwner } from '../shared/db/users' ;
2024-05-17 01:53:15 -07:00
import { getPersonalProject } from '../shared/db/projects' ;
2024-01-22 09:25:36 -08:00
2024-06-18 01:50:39 -07:00
mockInstance ( InternalHooks ) ;
mockInstance ( LoadNodesAndCredentials ) ;
const command = setupTestCommand ( ImportWorkflowsCommand ) ;
2023-03-30 06:33:30 -07:00
beforeEach ( async ( ) = > {
2024-04-12 08:25:59 -07:00
await testDb . truncate ( [ 'Workflow' , 'SharedWorkflow' , 'User' ] ) ;
2023-03-30 06:33:30 -07:00
} ) ;
test ( 'import:workflow should import active workflow and deactivate it' , async ( ) = > {
2024-04-12 08:25:59 -07:00
//
// ARRANGE
//
const owner = await createOwner ( ) ;
2024-05-17 01:53:15 -07:00
const ownerProject = await getPersonalProject ( owner ) ;
2023-03-30 06:33:30 -07:00
2024-04-12 08:25:59 -07:00
//
// ACT
//
2024-06-18 01:50:39 -07:00
await command . run ( [ '--separate' , '--input=./test/integration/commands/importWorkflows/separate' ] ) ;
2024-04-12 08:25:59 -07:00
//
// ASSERT
//
const after = {
workflows : await getAllWorkflows ( ) ,
sharings : await getAllSharedWorkflows ( ) ,
} ;
expect ( after ) . toMatchObject ( {
workflows : [
expect . objectContaining ( { name : 'active-workflow' , active : false } ) ,
expect . objectContaining ( { name : 'inactive-workflow' , active : false } ) ,
] ,
sharings : [
2024-05-17 01:53:15 -07:00
expect . objectContaining ( {
workflowId : '998' ,
projectId : ownerProject.id ,
role : 'workflow:owner' ,
} ) ,
expect . objectContaining ( {
workflowId : '999' ,
projectId : ownerProject.id ,
role : 'workflow:owner' ,
} ) ,
2024-04-12 08:25:59 -07:00
] ,
} ) ;
2023-03-30 06:33:30 -07:00
} ) ;
test ( 'import:workflow should import active workflow from combined file and deactivate it' , async ( ) = > {
2024-04-12 08:25:59 -07:00
//
// ARRANGE
//
const owner = await createOwner ( ) ;
2024-05-17 01:53:15 -07:00
const ownerProject = await getPersonalProject ( owner ) ;
2024-04-12 08:25:59 -07:00
//
// ACT
//
2024-06-18 01:50:39 -07:00
await command . run ( [ '--input=./test/integration/commands/importWorkflows/combined/combined.json' ] ) ;
2024-04-12 08:25:59 -07:00
//
// ASSERT
//
const after = {
workflows : await getAllWorkflows ( ) ,
sharings : await getAllSharedWorkflows ( ) ,
} ;
expect ( after ) . toMatchObject ( {
workflows : [
expect . objectContaining ( { name : 'active-workflow' , active : false } ) ,
expect . objectContaining ( { name : 'inactive-workflow' , active : false } ) ,
] ,
sharings : [
2024-05-17 01:53:15 -07:00
expect . objectContaining ( {
workflowId : '998' ,
projectId : ownerProject.id ,
role : 'workflow:owner' ,
} ) ,
expect . objectContaining ( {
workflowId : '999' ,
projectId : ownerProject.id ,
role : 'workflow:owner' ,
} ) ,
2024-04-12 08:25:59 -07:00
] ,
} ) ;
} ) ;
test ( '`import:workflow --userId ...` should fail if the workflow exists already and is owned by somebody else' , async ( ) = > {
//
// ARRANGE
//
const owner = await createOwner ( ) ;
2024-05-17 01:53:15 -07:00
const ownerProject = await getPersonalProject ( owner ) ;
2024-04-12 08:25:59 -07:00
const member = await createMember ( ) ;
// Import workflow the first time, assigning it to a member.
2024-06-18 01:50:39 -07:00
await command . run ( [
2024-04-12 08:25:59 -07:00
'--input=./test/integration/commands/importWorkflows/combined-with-update/original.json' ,
` --userId= ${ owner . id } ` ,
] ) ;
const before = {
workflows : await getAllWorkflows ( ) ,
sharings : await getAllSharedWorkflows ( ) ,
} ;
// Make sure the workflow and sharing have been created.
expect ( before ) . toMatchObject ( {
workflows : [ expect . objectContaining ( { id : '998' , name : 'active-workflow' } ) ] ,
sharings : [
expect . objectContaining ( {
workflowId : '998' ,
2024-05-17 01:53:15 -07:00
projectId : ownerProject.id ,
2024-04-12 08:25:59 -07:00
role : 'workflow:owner' ,
} ) ,
] ,
} ) ;
//
// ACT
//
// Import the same workflow again, with another name but the same ID, and try
// to assign it to the member.
await expect (
2024-06-18 01:50:39 -07:00
command . run ( [
2024-04-12 08:25:59 -07:00
'--input=./test/integration/commands/importWorkflows/combined-with-update/updated.json' ,
` --userId= ${ member . id } ` ,
] ) ,
) . rejects . toThrowError (
2024-05-17 01:53:15 -07:00
` The credential with ID "998" is already owned by the user with the ID " ${ owner . id } ". It can't be re-owned by the user with the ID " ${ member . id } " ` ,
2023-03-30 06:33:30 -07:00
) ;
2024-04-12 08:25:59 -07:00
//
// ASSERT
//
const after = {
workflows : await getAllWorkflows ( ) ,
sharings : await getAllSharedWorkflows ( ) ,
} ;
// Make sure there is no new sharing and that the name DID NOT change.
expect ( after ) . toMatchObject ( {
workflows : [ expect . objectContaining ( { id : '998' , name : 'active-workflow' } ) ] ,
sharings : [
expect . objectContaining ( {
workflowId : '998' ,
2024-05-17 01:53:15 -07:00
projectId : ownerProject.id ,
2024-04-12 08:25:59 -07:00
role : 'workflow:owner' ,
} ) ,
] ,
2023-03-30 06:33:30 -07:00
} ) ;
2024-04-12 08:25:59 -07:00
} ) ;
2023-03-30 06:33:30 -07:00
2024-04-12 08:25:59 -07:00
test ( "only update the workflow, don't create or update the owner if `--userId` is not passed" , async ( ) = > {
//
// ARRANGE
//
await createOwner ( ) ;
const member = await createMember ( ) ;
2024-05-17 01:53:15 -07:00
const memberProject = await getPersonalProject ( member ) ;
2024-04-12 08:25:59 -07:00
// Import workflow the first time, assigning it to a member.
2024-06-18 01:50:39 -07:00
await command . run ( [
2024-04-12 08:25:59 -07:00
'--input=./test/integration/commands/importWorkflows/combined-with-update/original.json' ,
` --userId= ${ member . id } ` ,
] ) ;
const before = {
workflows : await getAllWorkflows ( ) ,
sharings : await getAllSharedWorkflows ( ) ,
} ;
// Make sure the workflow and sharing have been created.
expect ( before ) . toMatchObject ( {
workflows : [ expect . objectContaining ( { id : '998' , name : 'active-workflow' } ) ] ,
sharings : [
expect . objectContaining ( {
workflowId : '998' ,
2024-05-17 01:53:15 -07:00
projectId : memberProject.id ,
2024-04-12 08:25:59 -07:00
role : 'workflow:owner' ,
} ) ,
] ,
} ) ;
//
// ACT
//
// Import the same workflow again, with another name but the same ID.
2024-06-18 01:50:39 -07:00
await command . run ( [
2024-04-12 08:25:59 -07:00
'--input=./test/integration/commands/importWorkflows/combined-with-update/updated.json' ,
] ) ;
//
// ASSERT
//
const after = {
workflows : await getAllWorkflows ( ) ,
sharings : await getAllSharedWorkflows ( ) ,
} ;
// Make sure there is no new sharing and that the name changed.
expect ( after ) . toMatchObject ( {
workflows : [ expect . objectContaining ( { id : '998' , name : 'active-workflow updated' } ) ] ,
sharings : [
expect . objectContaining ( {
workflowId : '998' ,
2024-05-17 01:53:15 -07:00
projectId : memberProject.id ,
role : 'workflow:owner' ,
} ) ,
] ,
} ) ;
} ) ;
test ( '`import:workflow --projectId ...` should fail if the credential already exists and is owned by another project' , async ( ) = > {
//
// ARRANGE
//
const owner = await createOwner ( ) ;
const ownerProject = await getPersonalProject ( owner ) ;
const member = await createMember ( ) ;
const memberProject = await getPersonalProject ( member ) ;
// Import workflow the first time, assigning it to a member.
2024-06-18 01:50:39 -07:00
await command . run ( [
2024-05-17 01:53:15 -07:00
'--input=./test/integration/commands/importWorkflows/combined-with-update/original.json' ,
` --userId= ${ owner . id } ` ,
] ) ;
const before = {
workflows : await getAllWorkflows ( ) ,
sharings : await getAllSharedWorkflows ( ) ,
} ;
// Make sure the workflow and sharing have been created.
expect ( before ) . toMatchObject ( {
workflows : [ expect . objectContaining ( { id : '998' , name : 'active-workflow' } ) ] ,
sharings : [
expect . objectContaining ( {
workflowId : '998' ,
projectId : ownerProject.id ,
role : 'workflow:owner' ,
} ) ,
] ,
} ) ;
//
// ACT
//
// Import the same workflow again, with another name but the same ID, and try
// to assign it to the member.
await expect (
2024-06-18 01:50:39 -07:00
command . run ( [
2024-05-17 01:53:15 -07:00
'--input=./test/integration/commands/importWorkflows/combined-with-update/updated.json' ,
` --projectId= ${ memberProject . id } ` ,
] ) ,
) . rejects . toThrowError (
` The credential with ID "998" is already owned by the user with the ID " ${ owner . id } ". It can't be re-owned by the project with the ID " ${ memberProject . id } " ` ,
) ;
//
// ASSERT
//
const after = {
workflows : await getAllWorkflows ( ) ,
sharings : await getAllSharedWorkflows ( ) ,
} ;
// Make sure there is no new sharing and that the name DID NOT change.
expect ( after ) . toMatchObject ( {
workflows : [ expect . objectContaining ( { id : '998' , name : 'active-workflow' } ) ] ,
sharings : [
expect . objectContaining ( {
workflowId : '998' ,
projectId : ownerProject.id ,
2024-04-12 08:25:59 -07:00
role : 'workflow:owner' ,
} ) ,
] ,
} ) ;
2023-03-30 06:33:30 -07:00
} ) ;
2024-05-17 01:53:15 -07:00
test ( '`import:workflow --projectId ... --userId ...` fails explaining that only one of the options can be used at a time' , async ( ) = > {
await expect (
2024-06-18 01:50:39 -07:00
command . run ( [
2024-05-17 01:53:15 -07:00
'--input=./test/integration/commands/importWorkflows/combined-with-update/updated.json' ,
` --userId= ${ nanoid ( ) } ` ,
` --projectId= ${ nanoid ( ) } ` ,
] ) ,
) . rejects . toThrowError (
'You cannot use `--userId` and `--projectId` together. Use one or the other.' ,
) ;
} ) ;