2024-06-18 01:50:39 -07:00
import { nanoid } from 'nanoid' ;
2023-10-31 05:15:09 -07:00
import { ImportCredentialsCommand } from '@/commands/import/credentials' ;
2024-08-22 02:10:37 -07:00
import { LoadNodesAndCredentials } from '@/load-nodes-and-credentials' ;
2024-08-28 04:59:27 -07:00
import { setupTestCommand } from '@test-integration/utils/test-command' ;
2024-09-12 09:07:18 -07:00
2023-11-10 06:04:26 -08:00
import { mockInstance } from '../../shared/mocking' ;
2024-04-12 08:25:59 -07:00
import { getAllCredentials , getAllSharedCredentials } from '../shared/db/credentials' ;
2024-05-17 01:53:15 -07:00
import { getPersonalProject } from '../shared/db/projects' ;
2024-09-12 09:07:18 -07:00
import { createMember , createOwner } from '../shared/db/users' ;
import * as testDb from '../shared/test-db' ;
2024-01-22 09:25:36 -08:00
2024-06-18 01:50:39 -07:00
mockInstance ( LoadNodesAndCredentials ) ;
const command = setupTestCommand ( ImportCredentialsCommand ) ;
2023-10-31 05:15:09 -07:00
beforeEach ( async ( ) = > {
2024-04-12 08:25:59 -07:00
await testDb . truncate ( [ 'Credentials' , 'SharedCredentials' , 'User' ] ) ;
2023-10-31 05:15:09 -07:00
} ) ;
test ( 'import:credentials should import a credential' , 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-08-28 04:59:27 -07:00
await command . run ( [ '--input=./test/integration/commands/import-credentials/credentials.json' ] ) ;
2024-04-12 08:25:59 -07:00
//
// ASSERT
//
const after = {
credentials : await getAllCredentials ( ) ,
sharings : await getAllSharedCredentials ( ) ,
} ;
expect ( after ) . toMatchObject ( {
credentials : [ expect . objectContaining ( { id : '123' , name : 'cred-aws-test' } ) ] ,
sharings : [
2024-05-17 01:53:15 -07:00
expect . objectContaining ( {
credentialsId : '123' ,
projectId : ownerProject.id ,
role : 'credential:owner' ,
} ) ,
2024-04-12 08:25:59 -07:00
] ,
} ) ;
} ) ;
test ( 'import:credentials should import a credential from separated files' , 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
//
// ACT
//
// import credential the first time, assigning it to the owner
2024-06-18 01:50:39 -07:00
await command . run ( [
2024-04-12 08:25:59 -07:00
'--separate' ,
2024-08-28 04:59:27 -07:00
'--input=./test/integration/commands/import-credentials/separate' ,
2024-04-12 08:25:59 -07:00
] ) ;
//
// ASSERT
//
const after = {
credentials : await getAllCredentials ( ) ,
sharings : await getAllSharedCredentials ( ) ,
} ;
expect ( after ) . toMatchObject ( {
credentials : [
expect . objectContaining ( {
id : '123' ,
name : 'cred-aws-test' ,
} ) ,
] ,
sharings : [
expect . objectContaining ( {
credentialsId : '123' ,
2024-05-17 01:53:15 -07:00
projectId : ownerProject.id ,
2024-04-12 08:25:59 -07:00
role : 'credential:owner' ,
} ) ,
] ,
} ) ;
} ) ;
test ( '`import:credentials --userId ...` should fail if the credential 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 credential the first time, assigning it to the owner
2024-06-18 01:50:39 -07:00
await command . run ( [
2024-08-28 04:59:27 -07:00
'--input=./test/integration/commands/import-credentials/credentials.json' ,
2024-04-12 08:25:59 -07:00
` --userId= ${ owner . id } ` ,
] ) ;
// making sure the import worked
const before = {
credentials : await getAllCredentials ( ) ,
sharings : await getAllSharedCredentials ( ) ,
} ;
expect ( before ) . toMatchObject ( {
credentials : [ expect . objectContaining ( { id : '123' , name : 'cred-aws-test' } ) ] ,
sharings : [
expect . objectContaining ( {
credentialsId : '123' ,
2024-05-17 01:53:15 -07:00
projectId : ownerProject.id ,
2024-04-12 08:25:59 -07:00
role : 'credential:owner' ,
} ) ,
] ,
} ) ;
//
// ACT
//
// Import again while updating the name we try to assign the
// credential to another user.
await expect (
2024-06-18 01:50:39 -07:00
command . run ( [
2024-08-28 04:59:27 -07:00
'--input=./test/integration/commands/import-credentials/credentials-updated.json' ,
2024-04-12 08:25:59 -07:00
` --userId= ${ member . id } ` ,
] ) ,
) . rejects . toThrowError (
2024-05-17 01:53:15 -07:00
` The credential with ID "123" 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-10-31 05:15:09 -07:00
) ;
2024-04-12 08:25:59 -07:00
//
// ASSERT
//
const after = {
credentials : await getAllCredentials ( ) ,
sharings : await getAllSharedCredentials ( ) ,
} ;
expect ( after ) . toMatchObject ( {
credentials : [
expect . objectContaining ( {
id : '123' ,
// only the name was updated
name : 'cred-aws-test' ,
} ) ,
] ,
sharings : [
expect . objectContaining ( {
credentialsId : '123' ,
2024-05-17 01:53:15 -07:00
projectId : ownerProject.id ,
2024-04-12 08:25:59 -07:00
role : 'credential:owner' ,
} ) ,
] ,
2023-10-31 05:15:09 -07:00
} ) ;
2024-04-12 08:25:59 -07:00
} ) ;
2023-10-31 05:15:09 -07:00
2024-05-17 01:53:15 -07:00
test ( "only update credential, don't create or update owner if neither `--userId` nor `--projectId` is passed" , async ( ) = > {
2024-04-12 08:25:59 -07:00
//
// 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 credential the first time, assigning it to a member
2024-06-18 01:50:39 -07:00
await command . run ( [
2024-08-28 04:59:27 -07:00
'--input=./test/integration/commands/import-credentials/credentials.json' ,
2024-04-12 08:25:59 -07:00
` --userId= ${ member . id } ` ,
] ) ;
// making sure the import worked
const before = {
credentials : await getAllCredentials ( ) ,
sharings : await getAllSharedCredentials ( ) ,
} ;
expect ( before ) . toMatchObject ( {
credentials : [ expect . objectContaining ( { id : '123' , name : 'cred-aws-test' } ) ] ,
sharings : [
expect . objectContaining ( {
credentialsId : '123' ,
2024-05-17 01:53:15 -07:00
projectId : memberProject.id ,
2024-04-12 08:25:59 -07:00
role : 'credential:owner' ,
} ) ,
] ,
} ) ;
//
// ACT
//
// Import again only updating the name and omitting `--userId`
2024-06-18 01:50:39 -07:00
await command . run ( [
2024-08-28 04:59:27 -07:00
'--input=./test/integration/commands/import-credentials/credentials-updated.json' ,
2024-04-12 08:25:59 -07:00
] ) ;
//
// ASSERT
//
const after = {
credentials : await getAllCredentials ( ) ,
sharings : await getAllSharedCredentials ( ) ,
} ;
expect ( after ) . toMatchObject ( {
credentials : [
expect . objectContaining ( {
id : '123' ,
// only the name was updated
name : 'cred-aws-prod' ,
} ) ,
] ,
sharings : [
expect . objectContaining ( {
credentialsId : '123' ,
2024-05-17 01:53:15 -07:00
projectId : memberProject.id ,
2024-04-12 08:25:59 -07:00
role : 'credential:owner' ,
} ) ,
] ,
} ) ;
2023-10-31 05:15:09 -07:00
} ) ;
2024-05-17 01:53:15 -07:00
test ( '`import:credential --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 credential the first time, assigning it to the owner
2024-06-18 01:50:39 -07:00
await command . run ( [
2024-08-28 04:59:27 -07:00
'--input=./test/integration/commands/import-credentials/credentials.json' ,
2024-05-17 01:53:15 -07:00
` --userId= ${ owner . id } ` ,
] ) ;
// making sure the import worked
const before = {
credentials : await getAllCredentials ( ) ,
sharings : await getAllSharedCredentials ( ) ,
} ;
expect ( before ) . toMatchObject ( {
credentials : [ expect . objectContaining ( { id : '123' , name : 'cred-aws-test' } ) ] ,
sharings : [
expect . objectContaining ( {
credentialsId : '123' ,
projectId : ownerProject.id ,
role : 'credential:owner' ,
} ) ,
] ,
} ) ;
//
// ACT
//
// Import again while updating the name we try to assign the
// credential to another user.
await expect (
2024-06-18 01:50:39 -07:00
command . run ( [
2024-08-28 04:59:27 -07:00
'--input=./test/integration/commands/import-credentials/credentials-updated.json' ,
2024-05-17 01:53:15 -07:00
` --projectId= ${ memberProject . id } ` ,
] ) ,
) . rejects . toThrowError (
` The credential with ID "123" 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 = {
credentials : await getAllCredentials ( ) ,
sharings : await getAllSharedCredentials ( ) ,
} ;
expect ( after ) . toMatchObject ( {
credentials : [
expect . objectContaining ( {
id : '123' ,
// only the name was updated
name : 'cred-aws-test' ,
} ) ,
] ,
sharings : [
expect . objectContaining ( {
credentialsId : '123' ,
projectId : ownerProject.id ,
role : 'credential:owner' ,
} ) ,
] ,
} ) ;
} ) ;
test ( '`import:credential --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-08-28 04:59:27 -07:00
'--input=./test/integration/commands/import-credentials/credentials-updated.json' ,
2024-05-17 01:53:15 -07:00
` --projectId= ${ nanoid ( ) } ` ,
` --userId= ${ nanoid ( ) } ` ,
] ) ,
) . rejects . toThrowError (
'You cannot use `--userId` and `--projectId` together. Use one or the other.' ,
) ;
} ) ;