diff --git a/tests/converters/app-converter.test.ts b/tests/converters/app-converter.test.ts index de16f4c1..a48fcb52 100644 --- a/tests/converters/app-converter.test.ts +++ b/tests/converters/app-converter.test.ts @@ -5,13 +5,13 @@ import * as path from 'path'; import * as mockfs from 'mock-fs'; import * as pulumi from '@pulumi/pulumi'; import { BucketPolicy } from '@pulumi/aws-native/s3'; -import { Policy } from '@pulumi/aws/iam' +import { Policy } from '@pulumi/aws/iam'; import { createStackManifest } from '../utils'; import { promiseOf, setMocks, MockAppComponent, MockSynth } from '../mocks'; import { StackManifest, StackManifestProps } from '../../src/assembly'; import { MockResourceArgs } from '@pulumi/pulumi/runtime'; import { Stack as CdkStack } from 'aws-cdk-lib/core'; -import { NestedStackConstruct } from '../../src/interop'; +import { NestedStackConstruct } from '../../src/internal/interop'; let resources: MockResourceArgs[] = []; beforeAll(() => { @@ -601,7 +601,8 @@ describe('Stack Converter', () => { const subnet = converter.resources.get({ stackPath: manifest.id, id: 'other' })?.resource as native.ec2.Subnet; const cidrBlock = await promiseOf(subnet.ipv6CidrBlock); expect(cidrBlock).toEqual('cidr_ipv6AddressAttribute'); - const subnet2 = converter.resources.get({ stackPath: manifest.id, id: 'other2' })?.resource as native.ec2.Subnet; + const subnet2 = converter.resources.get({ stackPath: manifest.id, id: 'other2' }) + ?.resource as native.ec2.Subnet; const cidrBlock2 = await promiseOf(subnet2.ipv6CidrBlock); expect(cidrBlock2).toEqual('cidr_ipv6AddressAttribute_2'); }); @@ -623,7 +624,10 @@ describe('Stack Converter', () => { const converter = new StackConverter(app, manifest); converter.convert(new Set()); - const customResource = converter.resources.get({ stackPath: manifest.id, id: 'DeployWebsiteCustomResourceD116527B' }); + const customResource = converter.resources.get({ + stackPath: manifest.id, + id: 'DeployWebsiteCustomResourceD116527B', + }); expect(customResource).toBeDefined(); const customResourceEmulator = customResource!.resource! as native.cloudformation.CustomResourceEmulator; @@ -632,7 +636,10 @@ describe('Stack Converter', () => { expect(customResourceEmulator.serviceToken).toBeDefined(); // This uses GetAtt to get the destination bucket from the custom resource - const customResourceRole = converter.resources.get({ stackPath: manifest.id, id: 'CustomResourceRoleAB1EF463' }); + const customResourceRole = converter.resources.get({ + stackPath: manifest.id, + id: 'CustomResourceRoleAB1EF463', + }); expect(customResourceRole).toBeDefined(); }); @@ -652,27 +659,36 @@ describe('Stack Converter', () => { const converter = new StackConverter(app, manifest); converter.convert(new Set()); - const rootBucket = converter.resources.get({ stackPath: manifest.id, id: 'bucket' })?.resource as native.s3.Bucket; + const rootBucket = converter.resources.get({ stackPath: manifest.id, id: 'bucket' }) + ?.resource as native.s3.Bucket; expect(rootBucket).toBeDefined(); const rootBucketName = await promiseOf(rootBucket.bucketName); // nested stack resource should be mapped - const nestedStackResource = converter.resources.get({ stackPath: manifest.id, id: 'nestyNestedStacknestyNestedStackResource' }); + const nestedStackResource = converter.resources.get({ + stackPath: manifest.id, + id: 'nestyNestedStacknestyNestedStackResource', + }); expect(nestedStackResource).toBeDefined(); expect(nestedStackResource?.resourceType).toEqual('AWS::CloudFormation::Stack'); expect(NestedStackConstruct.isNestedStackConstruct(nestedStackResource?.resource)).toBeTruthy(); // resources of the nested stack should be mapped // this tests that properties are correctly passed to the nested stack - const nestedBucket = converter.resources.get({ stackPath: `${manifest.id}/nesty`, id: 'bucket43879C71' })?.resource as native.s3.Bucket; + const nestedBucket = converter.resources.get({ stackPath: `${manifest.id}/nesty`, id: 'bucket43879C71' }) + ?.resource as native.s3.Bucket; expect(nestedBucket).toBeDefined(); const nestedBucketName = await promiseOf(nestedBucket.bucketName); expect(nestedBucketName).toEqual(`${rootBucketName}-nested`); - - const policy = converter.resources.get({ stackPath: manifest.id, id: 'CustomCDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756CServiceRoleDefaultPolicy' })?.resource as Policy; - const policyDocument = await promiseOf(policy.policy) as any; - expect(policyDocument.Statement[1].Resource).toEqual(expect.arrayContaining(['bucket43879c71_arn', 'bucket43879c71_arn/*'])); + const policy = converter.resources.get({ + stackPath: manifest.id, + id: 'CustomCDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756CServiceRoleDefaultPolicy', + })?.resource as Policy; + const policyDocument = (await promiseOf(policy.policy)) as any; + expect(policyDocument.Statement[1].Resource).toEqual( + expect.arrayContaining(['bucket43879c71_arn', 'bucket43879c71_arn/*']), + ); }); describe('asOutputValue', () => { @@ -726,7 +742,7 @@ describe('Stack Converter', () => { }, dependencies: [], }); - + const app = new MockAppComponent('/tmp/foo/bar/does/not/exist'); const stagingBucket = 'my-bucket'; const customResourcePrefix = 'my-prefix'; @@ -739,11 +755,11 @@ describe('Stack Converter', () => { } as unknown as CdkStack; const converter = new StackConverter(app, manifest); converter.convert(new Set()); - - const result = await promiseOf(converter.asOutputValue("DUMMY") as any); - expect(result).toEqual("vpc_id"); + + const result = await promiseOf(converter.asOutputValue('DUMMY') as any); + expect(result).toEqual('vpc_id'); }); - + test('throws if token is not found in any stack', async () => { const manifest = new StackManifest({ id: 'stack', @@ -751,7 +767,10 @@ describe('Stack Converter', () => { metadata: { 'stack/vpc': { stackPath: 'stack', id: 'vpc' }, 'stack/cidr': { stackPath: 'stack', id: 'cidr' }, - 'stack/nested.NestedStack/nested.NestedStackResource': { stackPath: 'stack', id: 'nested.NestedStackResource' }, + 'stack/nested.NestedStack/nested.NestedStackResource': { + stackPath: 'stack', + id: 'nested.NestedStackResource', + }, 'stack/nested/vpc': { stackPath: 'stack/nested', id: 'vpc' }, 'stack/nested/cidr': { stackPath: 'stack/nested', id: 'cidr' }, }, @@ -793,7 +812,7 @@ describe('Stack Converter', () => { }, }, }, - "nested.NestedStack": { + 'nested.NestedStack': { id: 'nested.NestedStack', path: 'stack/nested.NestedStack', children: { @@ -804,7 +823,7 @@ describe('Stack Converter', () => { 'aws:cdk:cloudformation:type': 'AWS::CloudFormation::Stack', }, }, - } + }, }, }, constructInfo: { @@ -843,7 +862,7 @@ describe('Stack Converter', () => { Ipv6CidrBlock: 'cidr_ipv6AddressAttribute', }, }, - "nested.NestedStackResource": { + 'nested.NestedStackResource': { Type: 'AWS::CloudFormation::Stack', Properties: {}, }, @@ -851,7 +870,7 @@ describe('Stack Converter', () => { }, dependencies: [], }); - + const app = new MockAppComponent('/tmp/foo/bar/does/not/exist'); const stagingBucket = 'my-bucket'; const customResourcePrefix = 'my-prefix'; @@ -864,10 +883,12 @@ describe('Stack Converter', () => { } as unknown as CdkStack; const converter = new StackConverter(app, manifest); converter.convert(new Set()); - - expect(() => converter.asOutputValue("DUMMY")).toThrow("Ref intrinsic unable to resolve not-found in stack stack: not a known logical resource or parameter reference"); + + expect(() => converter.asOutputValue('DUMMY')).toThrow( + 'Ref intrinsic unable to resolve not-found in stack stack: not a known logical resource or parameter reference', + ); }); - + test('finds value in correct nested stack', async () => { const manifest = new StackManifest({ id: 'stack', @@ -875,10 +896,16 @@ describe('Stack Converter', () => { metadata: { 'stack/vpc': { stackPath: 'stack', id: 'vpc' }, 'stack/cidr': { stackPath: 'stack', id: 'cidr' }, - 'stack/nested.NestedStack/nested.NestedStackResource': { stackPath: 'stack', id: 'nested.NestedStackResource' }, + 'stack/nested.NestedStack/nested.NestedStackResource': { + stackPath: 'stack', + id: 'nested.NestedStackResource', + }, 'stack/nested/nestedVpc': { stackPath: 'stack/nested', id: 'nestedVpc' }, 'stack/nested/cidr': { stackPath: 'stack/nested', id: 'cidr' }, - 'stack/otherNested.NestedStack/otherNested.NestedStackResource': { stackPath: 'stack', id: 'otherNested.NestedStackResource' }, + 'stack/otherNested.NestedStack/otherNested.NestedStackResource': { + stackPath: 'stack', + id: 'otherNested.NestedStackResource', + }, 'stack/otherNested/nestedVpc2': { stackPath: 'stack/otherNested', id: 'nestedVpc2' }, 'stack/otherNested/cidr': { stackPath: 'stack/otherNested', id: 'cidr' }, }, @@ -920,7 +947,7 @@ describe('Stack Converter', () => { }, }, }, - "nested.NestedStack": { + 'nested.NestedStack': { id: 'nested.NestedStack', path: 'stack/nested.NestedStack', children: { @@ -931,7 +958,7 @@ describe('Stack Converter', () => { 'aws:cdk:cloudformation:type': 'AWS::CloudFormation::Stack', }, }, - } + }, }, otherNested: { id: 'otherNested', @@ -951,9 +978,9 @@ describe('Stack Converter', () => { 'aws:cdk:cloudformation:type': 'AWS::EC2::VPCCidrBlock', }, }, - } + }, }, - "otherNested.NestedStack": { + 'otherNested.NestedStack': { id: 'otherNested.NestedStack', path: 'stack/otherNested.NestedStack', children: { @@ -964,8 +991,8 @@ describe('Stack Converter', () => { 'aws:cdk:cloudformation:type': 'AWS::CloudFormation::Stack', }, }, - } - } + }, + }, }, constructInfo: { fqn: 'aws-cdk-lib.Stack', @@ -1004,7 +1031,7 @@ describe('Stack Converter', () => { }, }, }, - } + }, }, template: { Resources: { @@ -1019,11 +1046,11 @@ describe('Stack Converter', () => { Ipv6CidrBlock: 'cidr_ipv6AddressAttribute', }, }, - "nested.NestedStackResource": { + 'nested.NestedStackResource': { Type: 'AWS::CloudFormation::Stack', Properties: {}, }, - "otherNested.NestedStackResource": { + 'otherNested.NestedStackResource': { Type: 'AWS::CloudFormation::Stack', Properties: {}, }, @@ -1031,7 +1058,7 @@ describe('Stack Converter', () => { }, dependencies: [], }); - + const app = new MockAppComponent('/tmp/foo/bar/does/not/exist'); const stagingBucket = 'my-bucket'; const customResourcePrefix = 'my-prefix'; @@ -1044,11 +1071,11 @@ describe('Stack Converter', () => { } as unknown as CdkStack; const converter = new StackConverter(app, manifest); converter.convert(new Set()); - - const result = await promiseOf(converter.asOutputValue("DUMMY") as any); - expect(result).toEqual("nestedVpc_id"); + + const result = await promiseOf(converter.asOutputValue('DUMMY') as any); + expect(result).toEqual('nestedVpc_id'); }); - + test('throws if token is found in multiple stacks', async () => { const manifest = new StackManifest({ id: 'stack', @@ -1056,10 +1083,16 @@ describe('Stack Converter', () => { metadata: { 'stack/vpc': { stackPath: 'stack', id: 'vpc' }, 'stack/cidr': { stackPath: 'stack', id: 'cidr' }, - 'stack/nested.NestedStack/nested.NestedStackResource': { stackPath: 'stack', id: 'nested.NestedStackResource' }, + 'stack/nested.NestedStack/nested.NestedStackResource': { + stackPath: 'stack', + id: 'nested.NestedStackResource', + }, 'stack/nested/nestedVpc': { stackPath: 'stack/nested', id: 'nestedVpc' }, 'stack/nested/cidr': { stackPath: 'stack/nested', id: 'cidr' }, - 'stack/otherNested.NestedStack/otherNested.NestedStackResource': { stackPath: 'stack', id: 'otherNested.NestedStackResource' }, + 'stack/otherNested.NestedStack/otherNested.NestedStackResource': { + stackPath: 'stack', + id: 'otherNested.NestedStackResource', + }, 'stack/otherNested/nestedVpc': { stackPath: 'stack/otherNested', id: 'nestedVpc' }, 'stack/otherNested/cidr': { stackPath: 'stack/otherNested', id: 'cidr' }, }, @@ -1101,7 +1134,7 @@ describe('Stack Converter', () => { }, }, }, - "nested.NestedStack": { + 'nested.NestedStack': { id: 'nested.NestedStack', path: 'stack/nested.NestedStack', children: { @@ -1112,7 +1145,7 @@ describe('Stack Converter', () => { 'aws:cdk:cloudformation:type': 'AWS::CloudFormation::Stack', }, }, - } + }, }, otherNested: { id: 'otherNested', @@ -1132,9 +1165,9 @@ describe('Stack Converter', () => { 'aws:cdk:cloudformation:type': 'AWS::EC2::VPCCidrBlock', }, }, - } + }, }, - "otherNested.NestedStack": { + 'otherNested.NestedStack': { id: 'otherNested.NestedStack', path: 'stack/otherNested.NestedStack', children: { @@ -1145,8 +1178,8 @@ describe('Stack Converter', () => { 'aws:cdk:cloudformation:type': 'AWS::CloudFormation::Stack', }, }, - } - } + }, + }, }, constructInfo: { fqn: 'aws-cdk-lib.Stack', @@ -1185,7 +1218,7 @@ describe('Stack Converter', () => { }, }, }, - } + }, }, template: { Resources: { @@ -1200,11 +1233,11 @@ describe('Stack Converter', () => { Ipv6CidrBlock: 'cidr_ipv6AddressAttribute', }, }, - "nested.NestedStackResource": { + 'nested.NestedStackResource': { Type: 'AWS::CloudFormation::Stack', Properties: {}, }, - "otherNested.NestedStackResource": { + 'otherNested.NestedStackResource': { Type: 'AWS::CloudFormation::Stack', Properties: {}, }, @@ -1212,7 +1245,7 @@ describe('Stack Converter', () => { }, dependencies: [], }); - + const app = new MockAppComponent('/tmp/foo/bar/does/not/exist'); const stagingBucket = 'my-bucket'; const customResourcePrefix = 'my-prefix'; @@ -1225,7 +1258,9 @@ describe('Stack Converter', () => { } as unknown as CdkStack; const converter = new StackConverter(app, manifest); converter.convert(new Set()); - expect(() => converter.asOutputValue("DUMMY")).toThrow("[CDK Adapter] Value found in multiple stacks: stack/nested and stack/otherNested. Pulumi cannot resolve this value."); + expect(() => converter.asOutputValue('DUMMY')).toThrow( + '[CDK Adapter] Value found in multiple stacks: stack/nested and stack/otherNested. Pulumi cannot resolve this value.', + ); }); }); });