From f850597793e39d71e4197701241f4dfcd8860e7c Mon Sep 17 00:00:00 2001 From: Calvin Combs Date: Tue, 18 Jan 2022 16:50:24 -0800 Subject: [PATCH 1/7] cfn include migration part 1 --- .../cloudformation-include/package.json | 2 +- .../test/invalid-templates.test.ts | 10 +- .../test/nested-stacks.test.ts | 47 +++--- .../test/serverless-transform.test.ts | 18 +-- .../test/valid-templates.test.ts | 138 ++++++++++-------- .../test/yaml-templates.test.ts | 34 ++--- 6 files changed, 128 insertions(+), 121 deletions(-) diff --git a/packages/@aws-cdk/cloudformation-include/package.json b/packages/@aws-cdk/cloudformation-include/package.json index 425756e78a3c7..a35fec1b2961b 100644 --- a/packages/@aws-cdk/cloudformation-include/package.json +++ b/packages/@aws-cdk/cloudformation-include/package.json @@ -448,7 +448,7 @@ "constructs": "^3.3.69" }, "devDependencies": { - "@aws-cdk/assert-internal": "0.0.0", + "@aws-cdk/assertions": "0.0.0", "@aws-cdk/cdk-build-tools": "0.0.0", "@aws-cdk/cdk-integ-tools": "0.0.0", "@aws-cdk/pkglint": "0.0.0", diff --git a/packages/@aws-cdk/cloudformation-include/test/invalid-templates.test.ts b/packages/@aws-cdk/cloudformation-include/test/invalid-templates.test.ts index 326b80a3585f8..b7203ed92823d 100644 --- a/packages/@aws-cdk/cloudformation-include/test/invalid-templates.test.ts +++ b/packages/@aws-cdk/cloudformation-include/test/invalid-templates.test.ts @@ -1,6 +1,4 @@ import * as path from 'path'; -import { SynthUtils } from '@aws-cdk/assert-internal'; -import '@aws-cdk/assert-internal/jest'; import * as core from '@aws-cdk/core'; import * as constructs from 'constructs'; import * as inc from '../lib'; @@ -22,7 +20,7 @@ describe('CDK Include', () => { includeTestTemplate(stack, 'bucket-with-cors-rules-not-an-array.json'); expect(() => { - SynthUtils.synthesize(stack); + core.App.of(stack)?.synth(); }).toThrow(/corsRules: "CorsRules!" should be a list/); }); @@ -30,7 +28,7 @@ describe('CDK Include', () => { includeTestTemplate(stack, 'bucket-with-cors-rules-null-element.json'); expect(() => { - SynthUtils.synthesize(stack); + core.App.of(stack)?.synth(); }).toThrow(/allowedMethods: required but missing/); }); @@ -38,7 +36,7 @@ describe('CDK Include', () => { includeTestTemplate(stack, 'bucket-with-invalid-cors-rule.json'); expect(() => { - SynthUtils.synthesize(stack); + core.App.of(stack)?.synth(); }).toThrow(/allowedOrigins: required but missing/); }); @@ -130,7 +128,7 @@ describe('CDK Include', () => { includeTestTemplate(stack, 'alphabetical-string-passed-to-number.json'); expect(() => { - SynthUtils.synthesize(stack); + core.App.of(stack)?.synth(); }).toThrow(/"abc" should be a number/); }); diff --git a/packages/@aws-cdk/cloudformation-include/test/nested-stacks.test.ts b/packages/@aws-cdk/cloudformation-include/test/nested-stacks.test.ts index 2a323657f089e..4e73005db1e54 100644 --- a/packages/@aws-cdk/cloudformation-include/test/nested-stacks.test.ts +++ b/packages/@aws-cdk/cloudformation-include/test/nested-stacks.test.ts @@ -1,6 +1,5 @@ import * as path from 'path'; -import { ABSENT, ResourcePart } from '@aws-cdk/assert-internal'; -import '@aws-cdk/assert-internal/jest'; +import { Match, Template } from '@aws-cdk/assertions'; import * as s3 from '@aws-cdk/aws-s3'; import * as core from '@aws-cdk/core'; import * as inc from '../lib'; @@ -27,7 +26,7 @@ describe('CDK Include for nested stacks', () => { }); const childStack = parentTemplate.getNestedStack('ChildStack'); - expect(childStack.stack).toMatchTemplate( + Template.fromStack(childStack.stack).templateMatches( loadTestFileToJsObject('grandchild-import-stack.json'), ); }); @@ -47,11 +46,11 @@ describe('CDK Include for nested stacks', () => { const childStack = parentTemplate.getNestedStack('ChildStack'); const anotherChildStack = parentTemplate.getNestedStack('AnotherChildStack'); - expect(childStack.stack).toMatchTemplate( + Template.fromStack(childStack.stack).templateMatches( loadTestFileToJsObject('grandchild-import-stack.json'), ); - expect(anotherChildStack.stack).toMatchTemplate( + Template.fromStack(anotherChildStack.stack).templateMatches( loadTestFileToJsObject('grandchild-import-stack.json'), ); }); @@ -73,11 +72,11 @@ describe('CDK Include for nested stacks', () => { const childStack = parentTemplate.getNestedStack('ChildStack'); const grandChildStack = childStack.includedTemplate.getNestedStack('GrandChildStack'); - expect(childStack.stack).toMatchTemplate( + Template.fromStack(childStack.stack).templateMatches( loadTestFileToJsObject('child-import-stack.expected.json'), ); - expect(grandChildStack.stack).toMatchTemplate( + Template.fromStack(grandChildStack.stack).templateMatches( loadTestFileToJsObject('grandchild-import-stack.json'), ); }); @@ -188,7 +187,7 @@ describe('CDK Include for nested stacks', () => { bucket.bucketName = 'modified-bucket-name'; - expect(childTemplate.stack).toHaveResource('AWS::S3::Bucket', { BucketName: 'modified-bucket-name' }); + Template.fromStack(childTemplate.stack).hasResourceProperties('AWS::S3::Bucket', { BucketName: 'modified-bucket-name' }); }); test('can use a condition', () => { @@ -218,7 +217,7 @@ describe('CDK Include for nested stacks', () => { const assetParam = 'AssetParameters5dc7d4a99cfe2979687dc74f2db9fd75f253b5505a1912b5ceecf70c9aefba50S3BucketEAA24F0C'; const assetParamKey = 'AssetParameters5dc7d4a99cfe2979687dc74f2db9fd75f253b5505a1912b5ceecf70c9aefba50S3VersionKey1194CAB2'; - expect(stack).toMatchTemplate({ + Template.fromStack(stack).templateMatches({ "Parameters": { [assetParam]: { "Type": "String", @@ -284,7 +283,7 @@ describe('CDK Include for nested stacks', () => { templateFile: testTemplateFilePath('parent-two-children.json'), }); - expect(stack).toMatchTemplate(loadTestFileToJsObject('parent-two-children.json')); + Template.fromStack(stack).templateMatches(loadTestFileToJsObject('parent-two-children.json')); }); test('getNestedStack() throws an exception when getting a resource that does not exist in the template', () => { @@ -344,7 +343,7 @@ describe('CDK Include for nested stacks', () => { }, }); - expect(stack).toHaveResourceLike('AWS::CloudFormation::Stack', { + Template.fromStack(stack).hasResourceProperties('AWS::CloudFormation::Stack', { "Parameters": { "Param1": { "Ref": "Param", @@ -370,7 +369,7 @@ describe('CDK Include for nested stacks', () => { const parameter = parentTemplate.getParameter('Param'); parameter.overrideLogicalId('DifferentParameter'); - expect(stack).toHaveResourceLike('AWS::CloudFormation::Stack', { + Template.fromStack(stack).hasResourceProperties('AWS::CloudFormation::Stack', { "Parameters": { "Param1": { "Ref": "DifferentParameter", @@ -417,7 +416,7 @@ describe('CDK Include for nested stacks', () => { }, }); - expect(stack).toHaveResourceLike('AWS::CloudFormation::Stack', { + Template.fromStack(stack).hasResource('AWS::CloudFormation::Stack', { "Metadata": { "Property1": "Value1", }, @@ -426,7 +425,7 @@ describe('CDK Include for nested stacks', () => { "AnotherChildStack", ], "UpdateReplacePolicy": "Retain", - }, ResourcePart.CompleteDefinition); + }); }); test('correctly parses NotificationsARNs, Timeout', () => { @@ -442,11 +441,11 @@ describe('CDK Include for nested stacks', () => { }, }); - expect(stack).toHaveResourceLike('AWS::CloudFormation::Stack', { + Template.fromStack(stack).hasResourceProperties('AWS::CloudFormation::Stack', { "NotificationARNs": ["arn1"], "TimeoutInMinutes": 5, }); - expect(stack).toHaveResourceLike('AWS::CloudFormation::Stack', { + Template.fromStack(stack).hasResourceProperties('AWS::CloudFormation::Stack', { "NotificationARNs": { "Ref": "ArrayParam" }, "TimeoutInMinutes": { "Fn::Select": [0, { @@ -466,7 +465,7 @@ describe('CDK Include for nested stacks', () => { }, }); - expect(stack).toHaveResourceLike('AWS::CloudFormation::Stack', { + Template.fromStack(stack).hasResourceProperties('AWS::CloudFormation::Stack', { "Parameters": { "Number": "60", }, @@ -481,7 +480,7 @@ describe('CDK Include for nested stacks', () => { templateFile: testTemplateFilePath('child-no-bucket.json'), }); - expect(includedChild.stack).toMatchTemplate( + Template.fromStack(includedChild.stack).templateMatches( loadTestFileToJsObject('child-no-bucket.json'), ); expect(includedChild.includedTemplate.getResource('GrandChildStack')).toBeDefined(); @@ -536,7 +535,7 @@ describe('CDK Include for nested stacks', () => { }); test('correctly creates parameters in the parent stack, and passes them to the child stack', () => { - expect(assetStack).toMatchTemplate({ + Template.fromStack(assetStack).templateMatches({ "Parameters": { [parentBucketParam]: { "Type": "String", @@ -616,7 +615,7 @@ describe('CDK Include for nested stacks', () => { }); test('correctly creates parameters in the child stack, and passes them to the grandchild stack', () => { - expect(child.stack).toMatchTemplate({ + Template.fromStack(child.stack).templateMatches({ "Parameters": { "MyBucketParameter": { "Type": "String", @@ -676,7 +675,7 @@ describe('CDK Include for nested stacks', () => { }); test('leaves grandchild stack unmodified', () => { - expect(grandChild.stack).toMatchTemplate( + Template.fromStack(grandChild.stack).templateMatches( loadTestFileToJsObject('grandchild-import-stack.json'), ); }); @@ -703,7 +702,7 @@ describe('CDK Include for nested stacks', () => { }); test('correctly removes the parameter from the child stack', () => { - expect(childStack).toMatchTemplate({ + Template.fromStack(childStack).templateMatches({ "Parameters": { "SecondParameter": { "Type": "String", @@ -733,9 +732,9 @@ describe('CDK Include for nested stacks', () => { }); test('correctly removes the parameter from the parent stack', () => { - expect(parentStack).toHaveResourceLike('AWS::CloudFormation::Stack', { + Template.fromStack(parentStack).hasResourceProperties('AWS::CloudFormation::Stack', { "Parameters": { - "FirstParameter": ABSENT, + "FirstParameter": Match.absent(), "SecondParameter": "second-value", }, }); diff --git a/packages/@aws-cdk/cloudformation-include/test/serverless-transform.test.ts b/packages/@aws-cdk/cloudformation-include/test/serverless-transform.test.ts index ce0d044bb4ed3..706afb615ec72 100644 --- a/packages/@aws-cdk/cloudformation-include/test/serverless-transform.test.ts +++ b/packages/@aws-cdk/cloudformation-include/test/serverless-transform.test.ts @@ -1,5 +1,5 @@ import * as path from 'path'; -import '@aws-cdk/assert-internal/jest'; +import { Template } from '@aws-cdk/assertions'; import * as core from '@aws-cdk/core'; import * as constructs from 'constructs'; import * as inc from '../lib'; @@ -18,7 +18,7 @@ describe('CDK Include for templates with SAM transform', () => { test('can ingest a template with only a minimal SAM function using S3Location for CodeUri, and output it unchanged', () => { includeTestTemplate(stack, 'only-minimal-sam-function-codeuri-as-s3location.yaml'); - expect(stack).toMatchTemplate( + Template.fromStack(stack).templateMatches( loadTestFileToJsObject('only-minimal-sam-function-codeuri-as-s3location.yaml'), ); }); @@ -26,7 +26,7 @@ describe('CDK Include for templates with SAM transform', () => { test('can ingest a template with only a SAM function using an array with DDB CRUD for Policies, and output it unchanged', () => { includeTestTemplate(stack, 'only-sam-function-policies-array-ddb-crud.yaml'); - expect(stack).toMatchTemplate( + Template.fromStack(stack).templateMatches( loadTestFileToJsObject('only-sam-function-policies-array-ddb-crud.yaml'), ); }); @@ -34,7 +34,7 @@ describe('CDK Include for templates with SAM transform', () => { test('can ingest a template with only a minimal SAM function using a parameter for CodeUri, and output it unchanged', () => { includeTestTemplate(stack, 'only-minimal-sam-function-codeuri-as-param.yaml'); - expect(stack).toMatchTemplate( + Template.fromStack(stack).templateMatches( loadTestFileToJsObject('only-minimal-sam-function-codeuri-as-param.yaml'), ); }); @@ -42,7 +42,7 @@ describe('CDK Include for templates with SAM transform', () => { test('can ingest a template with only a minimal SAM function using a parameter for CodeUri Bucket property, and output it unchanged', () => { includeTestTemplate(stack, 'only-minimal-sam-function-codeuri-bucket-as-param.yaml'); - expect(stack).toMatchTemplate( + Template.fromStack(stack).templateMatches( loadTestFileToJsObject('only-minimal-sam-function-codeuri-bucket-as-param.yaml'), ); }); @@ -50,7 +50,7 @@ describe('CDK Include for templates with SAM transform', () => { test('can ingest a template with only a SAM function using an array with DDB CRUD for Policies with an Fn::If expression, and output it unchanged', () => { includeTestTemplate(stack, 'only-sam-function-policies-array-ddb-crud-if.yaml'); - expect(stack).toMatchTemplate( + Template.fromStack(stack).templateMatches( loadTestFileToJsObject('only-sam-function-policies-array-ddb-crud-if.yaml'), ); }); @@ -58,7 +58,7 @@ describe('CDK Include for templates with SAM transform', () => { test('can ingest a template with a a union-type property provided as an object, and output it unchanged', () => { includeTestTemplate(stack, 'api-endpoint-config-object.yaml'); - expect(stack).toMatchTemplate( + Template.fromStack(stack).templateMatches( loadTestFileToJsObject('api-endpoint-config-object.yaml'), ); }); @@ -66,7 +66,7 @@ describe('CDK Include for templates with SAM transform', () => { test('can ingest a template with a a union-type property provided as a string, and output it unchanged', () => { includeTestTemplate(stack, 'api-endpoint-config-string.yaml'); - expect(stack).toMatchTemplate( + Template.fromStack(stack).templateMatches( loadTestFileToJsObject('api-endpoint-config-string.yaml'), ); }); @@ -74,7 +74,7 @@ describe('CDK Include for templates with SAM transform', () => { test('can ingest a template with a a union-type property provided as an empty string, and output it unchanged', () => { includeTestTemplate(stack, 'api-endpoint-config-string-empty.yaml'); - expect(stack).toMatchTemplate( + Template.fromStack(stack).templateMatches( loadTestFileToJsObject('api-endpoint-config-string-empty.yaml'), ); }); diff --git a/packages/@aws-cdk/cloudformation-include/test/valid-templates.test.ts b/packages/@aws-cdk/cloudformation-include/test/valid-templates.test.ts index 0741b7f9d23df..042796296bf24 100644 --- a/packages/@aws-cdk/cloudformation-include/test/valid-templates.test.ts +++ b/packages/@aws-cdk/cloudformation-include/test/valid-templates.test.ts @@ -1,6 +1,5 @@ import * as path from 'path'; -import { ResourcePart } from '@aws-cdk/assert-internal'; -import '@aws-cdk/assert-internal/jest'; +import { Match, Template } from '@aws-cdk/assertions'; import * as iam from '@aws-cdk/aws-iam'; import * as s3 from '@aws-cdk/aws-s3'; import * as ssm from '@aws-cdk/aws-ssm'; @@ -22,7 +21,7 @@ describe('CDK Include', () => { test('can ingest a template with only an empty S3 Bucket, and output it unchanged', () => { includeTestTemplate(stack, 'only-empty-bucket.json'); - expect(stack).toMatchTemplate( + Template.fromStack(stack).templateMatches( loadTestFileToJsObject('only-empty-bucket.json'), ); }); @@ -41,7 +40,7 @@ describe('CDK Include', () => { const cfnBucket = cfnTemplate.getResource('Bucket') as s3.CfnBucket; cfnBucket.bucketName = 'my-bucket-name'; - expect(stack).toMatchTemplate({ + Template.fromStack(stack).templateMatches({ "Resources": { "Bucket": { "Type": "AWS::S3::Bucket", @@ -58,7 +57,7 @@ describe('CDK Include', () => { const cfnBucket = cfnTemplate.getResource('Bucket') as s3.CfnBucket; expect((cfnBucket.corsConfiguration as any).corsRules).toHaveLength(1); - expect(stack).toMatchTemplate( + Template.fromStack(stack).templateMatches( loadTestFileToJsObject('only-bucket-complex-props.json'), ); }); @@ -75,10 +74,10 @@ describe('CDK Include', () => { resources: [cfnBucket.attrArn], })); - expect(stack).toHaveResourceLike('AWS::IAM::Policy', { + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { "PolicyDocument": { "Statement": [ - { + Match.objectLike({ "Action": "s3:*", "Resource": { "Fn::GetAtt": [ @@ -86,7 +85,7 @@ describe('CDK Include', () => { "Arn", ], }, - }, + }), ], }, }); @@ -95,23 +94,34 @@ describe('CDK Include', () => { test('can ingest a template with a Bucket Ref-erencing a KMS Key, and output it unchanged', () => { includeTestTemplate(stack, 'bucket-with-encryption-key.json'); - expect(stack).toMatchTemplate( + Template.fromStack(stack).templateMatches( loadTestFileToJsObject('bucket-with-encryption-key.json'), ); }); test('accepts strings for properties with type number', () => { includeTestTemplate(stack, 'string-for-number.json'); - - expect(stack).toMatchTemplate( - loadTestFileToJsObject('string-for-number.json'), - ); + Template.fromStack(stack).hasResourceProperties('AWS::S3::Bucket', { + "CorsConfiguration": { + CorsRules: [ + { + AllowedMethods: [ + "GET", + ], + AllowedOrigins: [ + "*", + ], + MaxAge: 10, + }, + ], + }, + }); }); test('accepts numbers for properties with type string', () => { includeTestTemplate(stack, 'number-for-string.json'); - expect(stack).toMatchTemplate( + Template.fromStack(stack).templateMatches( loadTestFileToJsObject('number-for-string.json'), ); }); @@ -119,7 +129,7 @@ describe('CDK Include', () => { test('accepts booleans for properties with type string', () => { includeTestTemplate(stack, 'boolean-for-string.json'); - expect(stack).toMatchTemplate( + Template.fromStack(stack).templateMatches( loadTestFileToJsObject('boolean-for-string.json'), ); }); @@ -135,7 +145,7 @@ describe('CDK Include', () => { const cfnBucket = cfnTemplate.getResource('Bucket') as s3.CfnBucket; cfnBucket.bucketName = 'my-bucket-name'; - expect(stack).toMatchTemplate({ + Template.fromStack(stack).templateMatches({ "Resources": { "MyScopeKey7673692F": { "Type": "AWS::KMS::Key", @@ -202,7 +212,7 @@ describe('CDK Include', () => { test('can ingest a template with an Fn::If expression for simple values, and output it unchanged', () => { includeTestTemplate(stack, 'if-simple-property.json'); - expect(stack).toMatchTemplate( + Template.fromStack(stack).templateMatches( loadTestFileToJsObject('if-simple-property.json'), ); }); @@ -210,7 +220,7 @@ describe('CDK Include', () => { test('can ingest a template with an Fn::If expression for complex values, and output it unchanged', () => { includeTestTemplate(stack, 'if-complex-property.json'); - expect(stack).toMatchTemplate( + Template.fromStack(stack).templateMatches( loadTestFileToJsObject('if-complex-property.json'), ); }); @@ -218,7 +228,7 @@ describe('CDK Include', () => { test('can ingest a UserData script, and output it unchanged', () => { includeTestTemplate(stack, 'user-data.json'); - expect(stack).toMatchTemplate( + Template.fromStack(stack).templateMatches( loadTestFileToJsObject('user-data.json'), ); }); @@ -226,7 +236,7 @@ describe('CDK Include', () => { test('can correctly ingest a resource with a property of type: Map of Lists of primitive types', () => { const cfnTemplate = includeTestTemplate(stack, 'ssm-association.json'); - expect(stack).toMatchTemplate( + Template.fromStack(stack).templateMatches( loadTestFileToJsObject('ssm-association.json'), ); const association = cfnTemplate.getResource('Association') as ssm.CfnAssociation; @@ -236,7 +246,7 @@ describe('CDK Include', () => { test('can ingest a template with intrinsic functions and conditions, and output it unchanged', () => { includeTestTemplate(stack, 'functions-and-conditions.json'); - expect(stack).toMatchTemplate( + Template.fromStack(stack).templateMatches( loadTestFileToJsObject('functions-and-conditions.json'), ); }); @@ -244,7 +254,7 @@ describe('CDK Include', () => { test('can ingest a JSON template with string-form Fn::GetAtt, and output it unchanged', () => { includeTestTemplate(stack, 'get-att-string-form.json'); - expect(stack).toMatchTemplate( + Template.fromStack(stack).templateMatches( loadTestFileToJsObject('get-att-string-form.json'), ); }); @@ -252,7 +262,7 @@ describe('CDK Include', () => { test('can ingest a template with Fn::Sub in string form with escaped and unescaped references and output it unchanged', () => { includeTestTemplate(stack, 'fn-sub-string.json'); - expect(stack).toMatchTemplate( + Template.fromStack(stack).templateMatches( loadTestFileToJsObject('fn-sub-string.json'), ); }); @@ -260,7 +270,7 @@ describe('CDK Include', () => { test('can parse the string argument Fn::Sub with escaped references that contain whitespace', () => { includeTestTemplate(stack, 'fn-sub-escaping.json'); - expect(stack).toMatchTemplate( + Template.fromStack(stack).templateMatches( loadTestFileToJsObject('fn-sub-escaping.json'), ); }); @@ -268,7 +278,7 @@ describe('CDK Include', () => { test('can ingest a template with Fn::Sub in map form and output it unchanged', () => { includeTestTemplate(stack, 'fn-sub-map-dotted-attributes.json'); - expect(stack).toMatchTemplate( + Template.fromStack(stack).templateMatches( loadTestFileToJsObject('fn-sub-map-dotted-attributes.json'), ); }); @@ -276,7 +286,7 @@ describe('CDK Include', () => { test('preserves an empty map passed to Fn::Sub', () => { includeTestTemplate(stack, 'fn-sub-map-empty.json'); - expect(stack).toMatchTemplate( + Template.fromStack(stack).templateMatches( loadTestFileToJsObject('fn-sub-map-empty.json'), ); }); @@ -284,7 +294,7 @@ describe('CDK Include', () => { test('can ingest a template with Fn::Sub shadowing a logical ID from the template and output it unchanged', () => { includeTestTemplate(stack, 'fn-sub-shadow.json'); - expect(stack).toMatchTemplate( + Template.fromStack(stack).templateMatches( loadTestFileToJsObject('fn-sub-shadow.json'), ); }); @@ -292,7 +302,7 @@ describe('CDK Include', () => { test('can ingest a template with Fn::Sub attribute expression shadowing a logical ID from the template, and output it unchanged', () => { includeTestTemplate(stack, 'fn-sub-shadow-attribute.json'); - expect(stack).toMatchTemplate( + Template.fromStack(stack).templateMatches( loadTestFileToJsObject('fn-sub-shadow-attribute.json'), ); }); @@ -302,7 +312,7 @@ describe('CDK Include', () => { cfnTemplate.getResource('AnotherBucket').overrideLogicalId('NewBucket'); - expect(stack).toHaveResourceLike('AWS::S3::Bucket', { + Template.fromStack(stack).hasResourceProperties('AWS::S3::Bucket', { "BucketName": { "Fn::Sub": [ "${AnotherBucket}", @@ -319,7 +329,7 @@ describe('CDK Include', () => { cfnTemplate.getResource('Bucket').overrideLogicalId('NewBucket'); - expect(stack).toHaveResourceLike('AWS::S3::Bucket', { + Template.fromStack(stack).hasResourceProperties('AWS::S3::Bucket', { "BucketName": { "Fn::Sub": "${NewBucket}-${!Bucket}-${NewBucket.DomainName}", }, @@ -329,7 +339,7 @@ describe('CDK Include', () => { test('can ingest a template with Fn::Sub with brace edge cases and output it unchanged', () => { includeTestTemplate(stack, 'fn-sub-brace-edges.json'); - expect(stack).toMatchTemplate( + Template.fromStack(stack).templateMatches( loadTestFileToJsObject('fn-sub-brace-edges.json'), ); }); @@ -342,7 +352,7 @@ describe('CDK Include', () => { }, }); - expect(stack).toMatchTemplate({ + Template.fromStack(stack).templateMatches({ "Parameters": { "AnotherParam": { "Type": "String", @@ -375,7 +385,7 @@ describe('CDK Include', () => { test('can ingest a template with a Ref expression for an array value, and output it unchanged', () => { includeTestTemplate(stack, 'ref-array-property.json'); - expect(stack).toMatchTemplate( + Template.fromStack(stack).templateMatches( loadTestFileToJsObject('ref-array-property.json'), ); }); @@ -383,7 +393,7 @@ describe('CDK Include', () => { test('renders non-Resources sections unchanged', () => { includeTestTemplate(stack, 'only-empty-bucket-with-parameters.json'); - expect(stack).toMatchTemplate( + Template.fromStack(stack).templateMatches( loadTestFileToJsObject('only-empty-bucket-with-parameters.json'), ); }); @@ -394,14 +404,14 @@ describe('CDK Include', () => { expect(cfnBucket2.node.dependencies).toHaveLength(1); // we always render dependsOn as an array, even if it's a single string - expect(stack).toHaveResourceLike('AWS::S3::Bucket', { + Template.fromStack(stack).hasResource('AWS::S3::Bucket', { "Properties": { "BucketName": "bucket2", }, "DependsOn": [ "Bucket1", ], - }, ResourcePart.CompleteDefinition); + }); }); test('resolves DependsOn with an array of String values to the actual L1 class instances', () => { @@ -409,7 +419,7 @@ describe('CDK Include', () => { const cfnBucket2 = cfnTemplate.getResource('Bucket2'); expect(cfnBucket2.node.dependencies).toHaveLength(2); - expect(stack).toHaveResourceLike('AWS::S3::Bucket', { + Template.fromStack(stack).hasResource('AWS::S3::Bucket', { "Properties": { "BucketName": "bucket2", }, @@ -417,7 +427,7 @@ describe('CDK Include', () => { "Bucket0", "Bucket1", ], - }, ResourcePart.CompleteDefinition); + }); }); test('correctly parses Conditions and the Condition resource attribute', () => { @@ -426,7 +436,7 @@ describe('CDK Include', () => { const cfnBucket = cfnTemplate.getResource('Bucket'); expect(cfnBucket.cfnOptions.condition).toBe(alwaysFalseCondition); - expect(stack).toMatchTemplate( + Template.fromStack(stack).templateMatches( loadTestFileToJsObject('resource-attribute-condition.json'), ); }); @@ -434,7 +444,7 @@ describe('CDK Include', () => { test('allows Conditions to reference Mappings', () => { includeTestTemplate(stack, 'condition-using-mapping.json'); - expect(stack).toMatchTemplate( + Template.fromStack(stack).templateMatches( loadTestFileToJsObject('condition-using-mapping.json'), ); }); @@ -444,7 +454,7 @@ describe('CDK Include', () => { const alwaysFalse = cfnTemplate.getCondition('AlwaysFalse'); alwaysFalse.overrideLogicalId('TotallyFalse'); - expect(stack).toMatchTemplate({ + Template.fromStack(stack).templateMatches({ "Parameters": { "Param": { "Type": "String", @@ -481,7 +491,7 @@ describe('CDK Include', () => { }); const originalTemplate = loadTestFileToJsObject('bucket-with-parameters.json'); - expect(stack).toMatchTemplate({ + Template.fromStack(stack).templateMatches({ "Resources": { ...originalTemplate.Resources, "NewBucket": { @@ -526,7 +536,7 @@ describe('CDK Include', () => { numberParam.type = "NewType"; const originalTemplate = loadTestFileToJsObject('bucket-with-parameters.json'); - expect(stack).toMatchTemplate({ + Template.fromStack(stack).templateMatches({ "Resources": { ...originalTemplate.Resources, }, @@ -559,7 +569,7 @@ describe('CDK Include', () => { alwaysFalseCondition.expression = core.Fn.conditionEquals(1, 2); - expect(stack).toMatchTemplate({ + Template.fromStack(stack).templateMatches({ "Conditions": { "AlwaysFalseCond": { "Fn::Equals": [1, 2], @@ -580,7 +590,7 @@ describe('CDK Include', () => { expect(cfnBucket.cfnOptions.creationPolicy).toBeDefined(); - expect(stack).toMatchTemplate( + Template.fromStack(stack).templateMatches( loadTestFileToJsObject('resource-attribute-creation-policy.json'), ); }); @@ -591,7 +601,7 @@ describe('CDK Include', () => { expect(cfnBucket.cfnOptions.updatePolicy).toBeDefined(); - expect(stack).toMatchTemplate( + Template.fromStack(stack).templateMatches( loadTestFileToJsObject('resource-attribute-update-policy.json'), ); }); @@ -612,7 +622,7 @@ describe('CDK Include', () => { resources: [cfnBucket.attrArn], })); - expect(stack).toMatchTemplate({ + Template.fromStack(stack).templateMatches({ ...loadTestFileToJsObject('only-empty-bucket.json'), "Outputs": { "ExportsOutputFnGetAttBucketArn436138FE": { @@ -626,7 +636,7 @@ describe('CDK Include', () => { }, }); - expect(otherStack).toHaveResourceLike('AWS::IAM::Policy', { + Template.fromStack(otherStack).hasResourceProperties('AWS::IAM::Policy', { "PolicyDocument": { "Statement": [ { @@ -646,7 +656,7 @@ describe('CDK Include', () => { cfnKey.overrideLogicalId('TotallyDifferentKey'); const originalTemplate = loadTestFileToJsObject('bucket-with-encryption-key.json'); - expect(stack).toMatchTemplate({ + Template.fromStack(stack).templateMatches({ "Resources": { "Bucket": { "Type": "AWS::S3::Bucket", @@ -679,7 +689,7 @@ describe('CDK Include', () => { test('can include a template with a custom resource that uses attributes', () => { const cfnTemplate = includeTestTemplate(stack, 'custom-resource-with-attributes.json'); - expect(stack).toMatchTemplate( + Template.fromStack(stack).templateMatches( loadTestFileToJsObject('custom-resource-with-attributes.json'), ); @@ -706,7 +716,7 @@ describe('CDK Include', () => { const originalTemplate = loadTestFileToJsObject('outputs-with-references.json'); - expect(stack).toMatchTemplate({ + Template.fromStack(stack).templateMatches({ "Conditions": { ...originalTemplate.Conditions, "MyCondition": { @@ -747,7 +757,7 @@ describe('CDK Include', () => { expect(output.value).toBeDefined(); expect(output.exportName).toBeDefined(); - expect(stack).toMatchTemplate( + Template.fromStack(stack).templateMatches( loadTestFileToJsObject('outputs-with-references.json'), ); }); @@ -766,7 +776,7 @@ describe('CDK Include', () => { someMapping.setValue('region', 'key2', 'value2'); - expect(stack).toMatchTemplate({ + Template.fromStack(stack).templateMatches({ "Mappings": { "SomeMapping": { "region": { @@ -803,7 +813,7 @@ describe('CDK Include', () => { test('can ingest a template that uses Fn::FindInMap with the first argument being a dynamic reference', () => { includeTestTemplate(stack, 'find-in-map-with-dynamic-mapping.json'); - expect(stack).toMatchTemplate( + Template.fromStack(stack).templateMatches( loadTestFileToJsObject('find-in-map-with-dynamic-mapping.json'), ); }); @@ -814,7 +824,7 @@ describe('CDK Include', () => { someMapping.overrideLogicalId('DifferentMapping'); - expect(stack).toMatchTemplate({ + Template.fromStack(stack).templateMatches({ "Mappings": { "DifferentMapping": { "region": { @@ -842,7 +852,7 @@ describe('CDK Include', () => { test('can ingest a template that uses Fn::FindInMap for the value of a boolean property', () => { includeTestTemplate(stack, 'find-in-map-for-boolean-property.json'); - expect(stack).toMatchTemplate( + Template.fromStack(stack).templateMatches( loadTestFileToJsObject('find-in-map-for-boolean-property.json'), ); }); @@ -853,7 +863,7 @@ describe('CDK Include', () => { expect(rule).toBeDefined(); - expect(stack).toMatchTemplate( + Template.fromStack(stack).templateMatches( loadTestFileToJsObject('only-parameters-and-rule.json'), ); }); @@ -881,7 +891,7 @@ describe('CDK Include', () => { const hook = cfnTemplate.getHook('EcsBlueGreenCodeDeployHook'); expect(hook).toBeDefined(); - expect(stack).toMatchTemplate( + Template.fromStack(stack).templateMatches( loadTestFileToJsObject('hook-code-deploy-blue-green-ecs.json'), ); }); @@ -901,7 +911,7 @@ describe('CDK Include', () => { }, }); - expect(stack).toMatchTemplate({ + Template.fromStack(stack).templateMatches({ "Transform": { "Name": "AWS::Include", "Parameters": { @@ -948,7 +958,7 @@ describe('CDK Include', () => { }, }); - expect(stack).toMatchTemplate({ + Template.fromStack(stack).templateMatches({ "Resources": { "Bucket": { "Type": "AWS::S3::Bucket", @@ -973,7 +983,7 @@ describe('CDK Include', () => { }, }); - expect(stack).toMatchTemplate({ + Template.fromStack(stack).templateMatches({ "Resources": { "Bucket": { "Type": "AWS::S3::Bucket", @@ -994,7 +1004,7 @@ describe('CDK Include', () => { }, }); - expect(stack).toMatchTemplate({ + Template.fromStack(stack).templateMatches({ "Resources": { "Bucket": { "Type": "AWS::S3::Bucket", @@ -1020,7 +1030,7 @@ describe('CDK Include', () => { }, }); - expect(stack).toMatchTemplate({ + Template.fromStack(stack).templateMatches({ "Resources": { "Bucket": { "Type": "AWS::S3::Bucket", @@ -1065,7 +1075,7 @@ describe('CDK Include', () => { test('can ingest a template that contains properties not in the current CFN spec, and output it unchanged', () => { includeTestTemplate(stack, 'properties-not-in-cfn-spec.json'); - expect(stack).toMatchTemplate( + Template.fromStack(stack).templateMatches( loadTestFileToJsObject('properties-not-in-cfn-spec.json'), ); }); diff --git a/packages/@aws-cdk/cloudformation-include/test/yaml-templates.test.ts b/packages/@aws-cdk/cloudformation-include/test/yaml-templates.test.ts index 06beafcdeb62c..4c693bd1026dc 100644 --- a/packages/@aws-cdk/cloudformation-include/test/yaml-templates.test.ts +++ b/packages/@aws-cdk/cloudformation-include/test/yaml-templates.test.ts @@ -1,5 +1,5 @@ import * as path from 'path'; -import '@aws-cdk/assert-internal/jest'; +import { Template } from '@aws-cdk/assertions'; import * as cloudwatch from '@aws-cdk/aws-cloudwatch'; import * as core from '@aws-cdk/core'; import * as constructs from 'constructs'; @@ -19,7 +19,7 @@ describe('CDK Include', () => { test('can ingest a template with all long-form CloudFormation functions and output it unchanged', () => { includeTestTemplate(stack, 'long-form-vpc.yaml'); - expect(stack).toMatchTemplate( + Template.fromStack(stack).templateMatches( loadTestFileToJsObject('long-form-vpc.yaml'), ); }); @@ -27,7 +27,7 @@ describe('CDK Include', () => { test('can ingest a template with year-month-date parsed as string instead of Date', () => { includeTestTemplate(stack, 'year-month-date-as-strings.yaml'); - expect(stack).toMatchTemplate({ + Template.fromStack(stack).templateMatches({ "AWSTemplateFormatVersion": "2010-09-09", "Resources": { "Role": { @@ -54,7 +54,7 @@ describe('CDK Include', () => { test('can ingest a template with the short form Base64 function', () => { includeTestTemplate(stack, 'short-form-base64.yaml'); - expect(stack).toMatchTemplate({ + Template.fromStack(stack).templateMatches({ "Resources": { "Base64Bucket": { "Type": "AWS::S3::Bucket", @@ -71,7 +71,7 @@ describe('CDK Include', () => { test('can ingest a template with the short form !Cidr function', () => { includeTestTemplate(stack, 'short-form-cidr.yaml'); - expect(stack).toMatchTemplate({ + Template.fromStack(stack).templateMatches({ "Resources": { "CidrVpc1": { "Type": "AWS::EC2::VPC", @@ -104,7 +104,7 @@ describe('CDK Include', () => { test('can ingest a template with the short form !FindInMap function, in both hyphen and bracket notation', () => { includeTestTemplate(stack, 'short-form-find-in-map.yaml'); - expect(stack).toMatchTemplate({ + Template.fromStack(stack).templateMatches({ "Mappings": { "RegionMap": { "region-1": { @@ -145,7 +145,7 @@ describe('CDK Include', () => { test('can ingest a template with the short form !GetAtt function', () => { includeTestTemplate(stack, 'short-form-get-att.yaml'); - expect(stack).toMatchTemplate({ + Template.fromStack(stack).templateMatches({ "Resources": { "ELB": { "Type": "AWS::ElasticLoadBalancing::LoadBalancer", @@ -187,7 +187,7 @@ describe('CDK Include', () => { test('can ingest a template with short form Select, GetAZs, and Ref functions', () => { includeTestTemplate(stack, 'short-form-select.yaml'); - expect(stack).toMatchTemplate({ + Template.fromStack(stack).templateMatches({ "Resources": { "Subnet1": { "Type": "AWS::EC2::Subnet", @@ -220,7 +220,7 @@ describe('CDK Include', () => { test('can ingest a template with the short form !ImportValue function', () => { includeTestTemplate(stack, 'short-form-import-value.yaml'); - expect(stack).toMatchTemplate({ + Template.fromStack(stack).templateMatches({ "Resources": { "Bucket1": { "Type": "AWS::S3::Bucket", @@ -237,7 +237,7 @@ describe('CDK Include', () => { test('can ingest a template with the short form !Join function', () => { includeTestTemplate(stack, 'short-form-join.yaml'); - expect(stack).toMatchTemplate({ + Template.fromStack(stack).templateMatches({ "Resources": { "Bucket": { "Type": "AWS::S3::Bucket", @@ -257,7 +257,7 @@ describe('CDK Include', () => { test('can ingest a template with the short form !Split function that uses both brackets and hyphens', () => { includeTestTemplate(stack, 'short-form-split.yaml'); - expect(stack).toMatchTemplate({ + Template.fromStack(stack).templateMatches({ "Resources": { "Bucket1": { "Type": "AWS::S3::Bucket", @@ -287,7 +287,7 @@ describe('CDK Include', () => { // Note that this yaml template fails validation. It is unclear how to invoke !Transform. includeTestTemplate(stack, 'invalid/short-form-transform.yaml'); - expect(stack).toMatchTemplate({ + Template.fromStack(stack).templateMatches({ "Resources": { "Bucket": { "Type": "AWS::S3::Bucket", @@ -310,7 +310,7 @@ describe('CDK Include', () => { test('can ingest a template with the short form conditionals', () => { includeTestTemplate(stack, 'short-form-conditionals.yaml'); - expect(stack).toMatchTemplate({ + Template.fromStack(stack).templateMatches({ "Conditions": { "AlwaysTrueCond": { "Fn::And": [ @@ -348,7 +348,7 @@ describe('CDK Include', () => { test('can ingest a template with the short form Conditions', () => { includeTestTemplate(stack, 'short-form-conditions.yaml'); - expect(stack).toMatchTemplate({ + Template.fromStack(stack).templateMatches({ "Conditions": { "AlwaysTrueCond": { "Fn::Not": [ @@ -393,7 +393,7 @@ describe('CDK Include', () => { test('can ingest a yaml with long-form functions and output it unchanged', () => { includeTestTemplate(stack, 'long-form-subnet.yaml'); - expect(stack).toMatchTemplate( + Template.fromStack(stack).templateMatches( loadTestFileToJsObject('long-form-subnet.yaml'), ); }); @@ -401,7 +401,7 @@ describe('CDK Include', () => { test('can ingest a YAML template with Fn::Sub in string form and output it unchanged', () => { includeTestTemplate(stack, 'short-form-fnsub-string.yaml'); - expect(stack).toMatchTemplate( + Template.fromStack(stack).templateMatches( loadTestFileToJsObject('short-form-fnsub-string.yaml'), ); }); @@ -409,7 +409,7 @@ describe('CDK Include', () => { test('can ingest a YAML template with Fn::Sub in map form and output it unchanged', () => { includeTestTemplate(stack, 'short-form-sub-map.yaml'); - expect(stack).toMatchTemplate( + Template.fromStack(stack).templateMatches( loadTestFileToJsObject('short-form-sub-map.yaml'), ); }); From fc40025a68923a251c0bf17b05954e4c55c79396 Mon Sep 17 00:00:00 2001 From: Calvin Combs Date: Wed, 19 Jan 2022 11:01:33 -0800 Subject: [PATCH 2/7] finished test migration --- .../test/valid-templates.test.ts | 51 ++++++++++++++----- 1 file changed, 39 insertions(+), 12 deletions(-) diff --git a/packages/@aws-cdk/cloudformation-include/test/valid-templates.test.ts b/packages/@aws-cdk/cloudformation-include/test/valid-templates.test.ts index 042796296bf24..0b3890cec331d 100644 --- a/packages/@aws-cdk/cloudformation-include/test/valid-templates.test.ts +++ b/packages/@aws-cdk/cloudformation-include/test/valid-templates.test.ts @@ -101,6 +101,7 @@ describe('CDK Include', () => { test('accepts strings for properties with type number', () => { includeTestTemplate(stack, 'string-for-number.json'); + Template.fromStack(stack).hasResourceProperties('AWS::S3::Bucket', { "CorsConfiguration": { CorsRules: [ @@ -121,17 +122,25 @@ describe('CDK Include', () => { test('accepts numbers for properties with type string', () => { includeTestTemplate(stack, 'number-for-string.json'); - Template.fromStack(stack).templateMatches( - loadTestFileToJsObject('number-for-string.json'), - ); + Template.fromStack(stack).hasResourceProperties('AWS::S3::Bucket', { + WebsiteConfiguration: { + RoutingRules: [ + { + RedirectRule: { + HttpRedirectCode: '403', + }, + }, + ], + }, + }); }); test('accepts booleans for properties with type string', () => { includeTestTemplate(stack, 'boolean-for-string.json'); - Template.fromStack(stack).templateMatches( - loadTestFileToJsObject('boolean-for-string.json'), - ); + Template.fromStack(stack).hasResourceProperties('AWS::S3::Bucket', { + AccessControl: 'true', + }); }); test('correctly changes the logical IDs, including references, if imported with preserveLogicalIds=false', () => { @@ -278,9 +287,23 @@ describe('CDK Include', () => { test('can ingest a template with Fn::Sub in map form and output it unchanged', () => { includeTestTemplate(stack, 'fn-sub-map-dotted-attributes.json'); - Template.fromStack(stack).templateMatches( - loadTestFileToJsObject('fn-sub-map-dotted-attributes.json'), - ); + Template.fromStack(stack).hasResourceProperties('AWS::S3::Bucket', { + "BucketName": { + "Fn::Sub": "${ELB.SourceSecurityGroup.GroupName}", + }, + }); + + Template.fromStack(stack).hasResourceProperties('AWS::ElasticLoadBalancing::LoadBalancer', { + "AvailabilityZones": [ + "us-east-1a", + ], + "CrossZone": true, + "Listeners": [{ + "LoadBalancerPort": "80", + "InstancePort": "80", + "Protocol": "HTTP", + }], + }); }); test('preserves an empty map passed to Fn::Sub', () => { @@ -601,8 +624,12 @@ describe('CDK Include', () => { expect(cfnBucket.cfnOptions.updatePolicy).toBeDefined(); + const template = loadTestFileToJsObject('resource-attribute-update-policy.json'); + template.Resources.Bucket.UpdatePolicy.AutoScalingReplacingUpdate.WillReplace = false; + template.Resources.Bucket.UpdatePolicy.EnableVersionUpgrade = true; + Template.fromStack(stack).templateMatches( - loadTestFileToJsObject('resource-attribute-update-policy.json'), + template, ); }); @@ -639,12 +666,12 @@ describe('CDK Include', () => { Template.fromStack(otherStack).hasResourceProperties('AWS::IAM::Policy', { "PolicyDocument": { "Statement": [ - { + Match.objectLike({ "Action": "s3:*", "Resource": { "Fn::ImportValue": "MyStack:ExportsOutputFnGetAttBucketArn436138FE", }, - }, + }), ], }, }); From e0116d9ac088075cb2b82b493950597bc69a4023 Mon Sep 17 00:00:00 2001 From: Calvin Combs Date: Wed, 19 Jan 2022 11:04:48 -0800 Subject: [PATCH 3/7] made all quotes double --- .../test/valid-templates.test.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/@aws-cdk/cloudformation-include/test/valid-templates.test.ts b/packages/@aws-cdk/cloudformation-include/test/valid-templates.test.ts index 0b3890cec331d..657b88f3d5785 100644 --- a/packages/@aws-cdk/cloudformation-include/test/valid-templates.test.ts +++ b/packages/@aws-cdk/cloudformation-include/test/valid-templates.test.ts @@ -123,11 +123,11 @@ describe('CDK Include', () => { includeTestTemplate(stack, 'number-for-string.json'); Template.fromStack(stack).hasResourceProperties('AWS::S3::Bucket', { - WebsiteConfiguration: { - RoutingRules: [ + "WebsiteConfiguration": { + "RoutingRules": [ { - RedirectRule: { - HttpRedirectCode: '403', + "RedirectRule": { + "HttpRedirectCode": '403', }, }, ], @@ -139,7 +139,7 @@ describe('CDK Include', () => { includeTestTemplate(stack, 'boolean-for-string.json'); Template.fromStack(stack).hasResourceProperties('AWS::S3::Bucket', { - AccessControl: 'true', + "AccessControl": "true", }); }); From 0fa2275780ed7b42987e6dff3c8b427c811f7bfc Mon Sep 17 00:00:00 2001 From: Calvin Combs Date: Wed, 19 Jan 2022 11:08:35 -0800 Subject: [PATCH 4/7] finished migration --- .../cloudformation-include/test/valid-templates.test.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/@aws-cdk/cloudformation-include/test/valid-templates.test.ts b/packages/@aws-cdk/cloudformation-include/test/valid-templates.test.ts index 657b88f3d5785..49a581ad7ed17 100644 --- a/packages/@aws-cdk/cloudformation-include/test/valid-templates.test.ts +++ b/packages/@aws-cdk/cloudformation-include/test/valid-templates.test.ts @@ -104,15 +104,15 @@ describe('CDK Include', () => { Template.fromStack(stack).hasResourceProperties('AWS::S3::Bucket', { "CorsConfiguration": { - CorsRules: [ + "CorsRules": [ { - AllowedMethods: [ + "AllowedMethods": [ "GET", ], - AllowedOrigins: [ + "AllowedOrigins": [ "*", ], - MaxAge: 10, + "MaxAge": 10, }, ], }, @@ -624,6 +624,7 @@ describe('CDK Include', () => { expect(cfnBucket.cfnOptions.updatePolicy).toBeDefined(); + // convert string types to boolean equivalents to appease test framework const template = loadTestFileToJsObject('resource-attribute-update-policy.json'); template.Resources.Bucket.UpdatePolicy.AutoScalingReplacingUpdate.WillReplace = false; template.Resources.Bucket.UpdatePolicy.EnableVersionUpgrade = true; From cbff822f77342cb46d08b1549547ff735b0a7102 Mon Sep 17 00:00:00 2001 From: Calvin Combs Date: Wed, 19 Jan 2022 11:09:16 -0800 Subject: [PATCH 5/7] added comment --- .../cloudformation-include/test/valid-templates.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/@aws-cdk/cloudformation-include/test/valid-templates.test.ts b/packages/@aws-cdk/cloudformation-include/test/valid-templates.test.ts index 49a581ad7ed17..ce5bcd2a504cd 100644 --- a/packages/@aws-cdk/cloudformation-include/test/valid-templates.test.ts +++ b/packages/@aws-cdk/cloudformation-include/test/valid-templates.test.ts @@ -624,7 +624,7 @@ describe('CDK Include', () => { expect(cfnBucket.cfnOptions.updatePolicy).toBeDefined(); - // convert string types to boolean equivalents to appease test framework + // convert string values to boolean equivalents to appease test framework const template = loadTestFileToJsObject('resource-attribute-update-policy.json'); template.Resources.Bucket.UpdatePolicy.AutoScalingReplacingUpdate.WillReplace = false; template.Resources.Bucket.UpdatePolicy.EnableVersionUpgrade = true; From 9b8e467c620f203d6653455a1dc252e7670f50da Mon Sep 17 00:00:00 2001 From: Calvin Combs Date: Wed, 19 Jan 2022 14:08:47 -0800 Subject: [PATCH 6/7] addressed comments --- .../test/invalid-templates.test.ts | 12 ++-- .../fn-sub-map-dotted-attributes.json | 9 ++- .../test/valid-templates.test.ts | 57 +++++++------------ 3 files changed, 37 insertions(+), 41 deletions(-) diff --git a/packages/@aws-cdk/cloudformation-include/test/invalid-templates.test.ts b/packages/@aws-cdk/cloudformation-include/test/invalid-templates.test.ts index b7203ed92823d..1541038169ade 100644 --- a/packages/@aws-cdk/cloudformation-include/test/invalid-templates.test.ts +++ b/packages/@aws-cdk/cloudformation-include/test/invalid-templates.test.ts @@ -5,9 +5,11 @@ import * as inc from '../lib'; describe('CDK Include', () => { let stack: core.Stack; + let app: core.App; beforeEach(() => { - stack = new core.Stack(); + app = new core.App(); + stack = new core.Stack(app); }); test('throws a validation exception for a template with a missing required top-level resource property', () => { @@ -20,7 +22,7 @@ describe('CDK Include', () => { includeTestTemplate(stack, 'bucket-with-cors-rules-not-an-array.json'); expect(() => { - core.App.of(stack)?.synth(); + app.synth(); }).toThrow(/corsRules: "CorsRules!" should be a list/); }); @@ -28,7 +30,7 @@ describe('CDK Include', () => { includeTestTemplate(stack, 'bucket-with-cors-rules-null-element.json'); expect(() => { - core.App.of(stack)?.synth(); + app.synth(); }).toThrow(/allowedMethods: required but missing/); }); @@ -36,7 +38,7 @@ describe('CDK Include', () => { includeTestTemplate(stack, 'bucket-with-invalid-cors-rule.json'); expect(() => { - core.App.of(stack)?.synth(); + app.synth(); }).toThrow(/allowedOrigins: required but missing/); }); @@ -128,7 +130,7 @@ describe('CDK Include', () => { includeTestTemplate(stack, 'alphabetical-string-passed-to-number.json'); expect(() => { - core.App.of(stack)?.synth(); + app.synth(); }).toThrow(/"abc" should be a number/); }); diff --git a/packages/@aws-cdk/cloudformation-include/test/test-templates/fn-sub-map-dotted-attributes.json b/packages/@aws-cdk/cloudformation-include/test/test-templates/fn-sub-map-dotted-attributes.json index c53229d2844d8..bdfe1477218c5 100644 --- a/packages/@aws-cdk/cloudformation-include/test/test-templates/fn-sub-map-dotted-attributes.json +++ b/packages/@aws-cdk/cloudformation-include/test/test-templates/fn-sub-map-dotted-attributes.json @@ -4,7 +4,14 @@ "Type": "AWS::S3::Bucket", "Properties": { "BucketName": { - "Fn::Sub": "${ELB.SourceSecurityGroup.GroupName}" + "Fn::Sub": [ + "${ELB.SourceSecurityGroup.GroupName}-${LoadBalancerName}", + { + "LoadBalancerName": { + "Ref": "ELB" + } + } + ] } } }, diff --git a/packages/@aws-cdk/cloudformation-include/test/valid-templates.test.ts b/packages/@aws-cdk/cloudformation-include/test/valid-templates.test.ts index ce5bcd2a504cd..f941cf0c3396c 100644 --- a/packages/@aws-cdk/cloudformation-include/test/valid-templates.test.ts +++ b/packages/@aws-cdk/cloudformation-include/test/valid-templates.test.ts @@ -1,5 +1,5 @@ import * as path from 'path'; -import { Match, Template } from '@aws-cdk/assertions'; +import { Template } from '@aws-cdk/assertions'; import * as iam from '@aws-cdk/aws-iam'; import * as s3 from '@aws-cdk/aws-s3'; import * as ssm from '@aws-cdk/aws-ssm'; @@ -77,7 +77,7 @@ describe('CDK Include', () => { Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { "PolicyDocument": { "Statement": [ - Match.objectLike({ + { "Action": "s3:*", "Resource": { "Fn::GetAtt": [ @@ -85,7 +85,7 @@ describe('CDK Include', () => { "Arn", ], }, - }), + }, ], }, }); @@ -106,12 +106,6 @@ describe('CDK Include', () => { "CorsConfiguration": { "CorsRules": [ { - "AllowedMethods": [ - "GET", - ], - "AllowedOrigins": [ - "*", - ], "MaxAge": 10, }, ], @@ -127,7 +121,7 @@ describe('CDK Include', () => { "RoutingRules": [ { "RedirectRule": { - "HttpRedirectCode": '403', + "HttpRedirectCode": "403", }, }, ], @@ -284,26 +278,21 @@ describe('CDK Include', () => { ); }); - test('can ingest a template with Fn::Sub in map form and output it unchanged', () => { + test('can ingest a template with Fn::Sub using dotted attributes in map form and output it unchanged', () => { includeTestTemplate(stack, 'fn-sub-map-dotted-attributes.json'); Template.fromStack(stack).hasResourceProperties('AWS::S3::Bucket', { "BucketName": { - "Fn::Sub": "${ELB.SourceSecurityGroup.GroupName}", + "Fn::Sub": [ + "${ELB.SourceSecurityGroup.GroupName}-${LoadBalancerName}", + { + "LoadBalancerName": { + "Ref": "ELB", + }, + }, + ], }, }); - - Template.fromStack(stack).hasResourceProperties('AWS::ElasticLoadBalancing::LoadBalancer', { - "AvailabilityZones": [ - "us-east-1a", - ], - "CrossZone": true, - "Listeners": [{ - "LoadBalancerPort": "80", - "InstancePort": "80", - "Protocol": "HTTP", - }], - }); }); test('preserves an empty map passed to Fn::Sub', () => { @@ -623,15 +612,13 @@ describe('CDK Include', () => { const cfnBucket = cfnTemplate.getResource('Bucket'); expect(cfnBucket.cfnOptions.updatePolicy).toBeDefined(); - - // convert string values to boolean equivalents to appease test framework - const template = loadTestFileToJsObject('resource-attribute-update-policy.json'); - template.Resources.Bucket.UpdatePolicy.AutoScalingReplacingUpdate.WillReplace = false; - template.Resources.Bucket.UpdatePolicy.EnableVersionUpgrade = true; - - Template.fromStack(stack).templateMatches( - template, - ); + Template.fromStack(stack).hasResource('AWS::S3::Bucket', { + "UpdatePolicy": { + "AutoScalingReplacingUpdate": { + "WillReplace": false, + }, + }, + }); }); test("correctly handles referencing the ingested template's resources across Stacks", () => { @@ -667,12 +654,12 @@ describe('CDK Include', () => { Template.fromStack(otherStack).hasResourceProperties('AWS::IAM::Policy', { "PolicyDocument": { "Statement": [ - Match.objectLike({ + { "Action": "s3:*", "Resource": { "Fn::ImportValue": "MyStack:ExportsOutputFnGetAttBucketArn436138FE", }, - }), + }, ], }, }); From a816c93fff975cf83d45eba2535fe62ba628a5d5 Mon Sep 17 00:00:00 2001 From: Calvin Combs Date: Wed, 19 Jan 2022 15:25:46 -0800 Subject: [PATCH 7/7] fixed json files --- .../test/invalid-templates.test.ts | 2 +- .../fn-sub-map-dotted-attributes.json | 2 +- .../resource-attribute-update-policy.json | 2 +- .../test/valid-templates.test.ts | 25 +++++-------------- 4 files changed, 9 insertions(+), 22 deletions(-) diff --git a/packages/@aws-cdk/cloudformation-include/test/invalid-templates.test.ts b/packages/@aws-cdk/cloudformation-include/test/invalid-templates.test.ts index 1541038169ade..fb2f4697f610e 100644 --- a/packages/@aws-cdk/cloudformation-include/test/invalid-templates.test.ts +++ b/packages/@aws-cdk/cloudformation-include/test/invalid-templates.test.ts @@ -4,8 +4,8 @@ import * as constructs from 'constructs'; import * as inc from '../lib'; describe('CDK Include', () => { - let stack: core.Stack; let app: core.App; + let stack: core.Stack; beforeEach(() => { app = new core.App(); diff --git a/packages/@aws-cdk/cloudformation-include/test/test-templates/fn-sub-map-dotted-attributes.json b/packages/@aws-cdk/cloudformation-include/test/test-templates/fn-sub-map-dotted-attributes.json index bdfe1477218c5..7daef9f79f9a4 100644 --- a/packages/@aws-cdk/cloudformation-include/test/test-templates/fn-sub-map-dotted-attributes.json +++ b/packages/@aws-cdk/cloudformation-include/test/test-templates/fn-sub-map-dotted-attributes.json @@ -21,7 +21,7 @@ "AvailabilityZones": [ "us-east-1a" ], - "CrossZone": "true", + "CrossZone": true, "Listeners": [{ "LoadBalancerPort": "80", "InstancePort": "80", diff --git a/packages/@aws-cdk/cloudformation-include/test/test-templates/resource-attribute-update-policy.json b/packages/@aws-cdk/cloudformation-include/test/test-templates/resource-attribute-update-policy.json index fb1f6f2aab1b2..e1440a46193be 100644 --- a/packages/@aws-cdk/cloudformation-include/test/test-templates/resource-attribute-update-policy.json +++ b/packages/@aws-cdk/cloudformation-include/test/test-templates/resource-attribute-update-policy.json @@ -53,7 +53,7 @@ "BeforeAllowTrafficHook" : "Lambda2", "DeploymentGroupName" : { "Ref": "CodeDeployDg" } }, - "EnableVersionUpgrade": "true", + "EnableVersionUpgrade": true, "UseOnlineResharding": false } } diff --git a/packages/@aws-cdk/cloudformation-include/test/valid-templates.test.ts b/packages/@aws-cdk/cloudformation-include/test/valid-templates.test.ts index f941cf0c3396c..65cd7e981cc81 100644 --- a/packages/@aws-cdk/cloudformation-include/test/valid-templates.test.ts +++ b/packages/@aws-cdk/cloudformation-include/test/valid-templates.test.ts @@ -281,18 +281,9 @@ describe('CDK Include', () => { test('can ingest a template with Fn::Sub using dotted attributes in map form and output it unchanged', () => { includeTestTemplate(stack, 'fn-sub-map-dotted-attributes.json'); - Template.fromStack(stack).hasResourceProperties('AWS::S3::Bucket', { - "BucketName": { - "Fn::Sub": [ - "${ELB.SourceSecurityGroup.GroupName}-${LoadBalancerName}", - { - "LoadBalancerName": { - "Ref": "ELB", - }, - }, - ], - }, - }); + Template.fromStack(stack).templateMatches( + loadTestFileToJsObject('fn-sub-map-dotted-attributes.json'), + ); }); test('preserves an empty map passed to Fn::Sub', () => { @@ -612,13 +603,9 @@ describe('CDK Include', () => { const cfnBucket = cfnTemplate.getResource('Bucket'); expect(cfnBucket.cfnOptions.updatePolicy).toBeDefined(); - Template.fromStack(stack).hasResource('AWS::S3::Bucket', { - "UpdatePolicy": { - "AutoScalingReplacingUpdate": { - "WillReplace": false, - }, - }, - }); + Template.fromStack(stack).templateMatches( + loadTestFileToJsObject('resource-attribute-update-policy.json'), + ); }); test("correctly handles referencing the ingested template's resources across Stacks", () => {