2024-01-22 09:25:36 -08:00
import { Config } from '@oclif/core' ;
2023-10-31 05:15:09 -07:00
import { InternalHooks } from '@/InternalHooks' ;
import { ImportCredentialsCommand } from '@/commands/import/credentials' ;
import { LoadNodesAndCredentials } from '@/LoadNodesAndCredentials' ;
2023-11-10 06:04:26 -08:00
import { mockInstance } from '../../shared/mocking' ;
2023-10-31 05:15:09 -07:00
import * as testDb from '../shared/testDb' ;
2024-04-12 08:25:59 -07:00
import { getAllCredentials , getAllSharedCredentials } from '../shared/db/credentials' ;
import { createMember , createOwner } from '../shared/db/users' ;
2024-05-17 01:53:15 -07:00
import { getPersonalProject } from '../shared/db/projects' ;
import { nanoid } from 'nanoid' ;
2023-10-31 05:15:09 -07:00
2024-01-22 09:25:36 -08:00
const oclifConfig = new Config ( { root : __dirname } ) ;
2024-04-12 08:25:59 -07:00
async function importCredential ( argv : string [ ] ) {
const importer = new ImportCredentialsCommand ( argv , oclifConfig ) ;
await importer . init ( ) ;
await importer . run ( ) ;
}
2023-10-31 05:15:09 -07:00
beforeAll ( async ( ) = > {
mockInstance ( InternalHooks ) ;
mockInstance ( LoadNodesAndCredentials ) ;
await testDb . init ( ) ;
2024-05-30 04:54:29 -07:00
await oclifConfig . load ( ) ;
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
} ) ;
afterAll ( async ( ) = > {
await testDb . terminate ( ) ;
} ) ;
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
//
await importCredential ( [
'--input=./test/integration/commands/importCredentials/credentials.json' ,
] ) ;
//
// 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
await importCredential ( [
'--separate' ,
'--input=./test/integration/commands/importCredentials/separate' ,
] ) ;
//
// 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
await importCredential ( [
'--input=./test/integration/commands/importCredentials/credentials.json' ,
` --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 (
importCredential ( [
'--input=./test/integration/commands/importCredentials/credentials-updated.json' ,
` --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
await importCredential ( [
'--input=./test/integration/commands/importCredentials/credentials.json' ,
` --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`
await importCredential ( [
'--input=./test/integration/commands/importCredentials/credentials-updated.json' ,
] ) ;
//
// 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
await importCredential ( [
'--input=./test/integration/commands/importCredentials/credentials.json' ,
` --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 (
importCredential ( [
'--input=./test/integration/commands/importCredentials/credentials-updated.json' ,
` --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 (
importCredential ( [
'--input=./test/integration/commands/importCredentials/credentials-updated.json' ,
` --projectId= ${ nanoid ( ) } ` ,
` --userId= ${ nanoid ( ) } ` ,
] ) ,
) . rejects . toThrowError (
'You cannot use `--userId` and `--projectId` together. Use one or the other.' ,
) ;
} ) ;