diff --git a/packages/@aws-cdk/custom-resources/test/aws-custom-resource/aws-custom-resource.test.ts b/packages/@aws-cdk/custom-resources/test/aws-custom-resource/aws-custom-resource.test.ts index 700b707629abd..ff3dcb2e5bde5 100644 --- a/packages/@aws-cdk/custom-resources/test/aws-custom-resource/aws-custom-resource.test.ts +++ b/packages/@aws-cdk/custom-resources/test/aws-custom-resource/aws-custom-resource.test.ts @@ -36,42 +36,42 @@ test('aws sdk js custom resource with onCreate and onDelete', () => { // THEN Template.fromStack(stack).hasResourceProperties('Custom::LogRetentionPolicy', { - 'Create': JSON.stringify({ - 'service': 'CloudWatchLogs', - 'action': 'putRetentionPolicy', - 'parameters': { - 'logGroupName': '/aws/lambda/loggroup', - 'retentionInDays': 90, + Create: JSON.stringify({ + service: 'CloudWatchLogs', + action: 'putRetentionPolicy', + parameters: { + logGroupName: '/aws/lambda/loggroup', + retentionInDays: 90, }, - 'physicalResourceId': { - 'id': 'loggroup', + physicalResourceId: { + id: 'loggroup', }, }), - 'Delete': JSON.stringify({ - 'service': 'CloudWatchLogs', - 'action': 'deleteRetentionPolicy', - 'parameters': { - 'logGroupName': '/aws/lambda/loggroup', + Delete: JSON.stringify({ + service: 'CloudWatchLogs', + action: 'deleteRetentionPolicy', + parameters: { + logGroupName: '/aws/lambda/loggroup', }, }), - 'InstallLatestAwsSdk': true, + InstallLatestAwsSdk: true, }); Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { - 'PolicyDocument': { - 'Statement': [ + PolicyDocument: { + Statement: [ { - 'Action': 'logs:PutRetentionPolicy', - 'Effect': 'Allow', - 'Resource': '*', + Action: 'logs:PutRetentionPolicy', + Effect: 'Allow', + Resource: '*', }, { - 'Action': 'logs:DeleteRetentionPolicy', - 'Effect': 'Allow', - 'Resource': '*', + Action: 'logs:DeleteRetentionPolicy', + Effect: 'Allow', + Resource: '*', }, ], - 'Version': '2012-10-17', + Version: '2012-10-17', }, }); }); @@ -98,28 +98,28 @@ test('onCreate defaults to onUpdate', () => { // THEN Template.fromStack(stack).hasResourceProperties('Custom::S3PutObject', { - 'Create': JSON.stringify({ - 'service': 's3', - 'action': 'putObject', - 'parameters': { - 'Bucket': 'my-bucket', - 'Key': 'my-key', - 'Body': 'my-body', + Create: JSON.stringify({ + service: 's3', + action: 'putObject', + parameters: { + Bucket: 'my-bucket', + Key: 'my-key', + Body: 'my-body', }, - 'physicalResourceId': { - 'responsePath': 'ETag', + physicalResourceId: { + responsePath: 'ETag', }, }), - 'Update': JSON.stringify({ - 'service': 's3', - 'action': 'putObject', - 'parameters': { - 'Bucket': 'my-bucket', - 'Key': 'my-key', - 'Body': 'my-body', + Update: JSON.stringify({ + service: 's3', + action: 'putObject', + parameters: { + Bucket: 'my-bucket', + Key: 'my-key', + Body: 'my-body', }, - 'physicalResourceId': { - 'responsePath': 'ETag', + physicalResourceId: { + responsePath: 'ETag', }, }), }); @@ -151,40 +151,335 @@ test('with custom policyStatements', () => { // THEN Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { - 'PolicyDocument': { - 'Statement': [ + PolicyDocument: { + Statement: [ { - 'Action': 's3:PutObject', - 'Effect': 'Allow', - 'Resource': 'arn:aws:s3:::my-bucket/my-key', + Action: 's3:PutObject', + Effect: 'Allow', + Resource: 'arn:aws:s3:::my-bucket/my-key', }, ], - 'Version': '2012-10-17', + Version: '2012-10-17', }, }); }); test('fails when no calls are specified', () => { const stack = new cdk.Stack(); - expect(() => new AwsCustomResource(stack, 'AwsSdk', { - policy: AwsCustomResourcePolicy.fromSdkCalls({ resources: AwsCustomResourcePolicy.ANY_RESOURCE }), - })).toThrow(/`onCreate`.+`onUpdate`.+`onDelete`/); + expect( + () => + new AwsCustomResource(stack, 'AwsSdk', { + policy: AwsCustomResourcePolicy.fromSdkCalls({ resources: AwsCustomResourcePolicy.ANY_RESOURCE }), + }), + ).toThrow(/`onCreate`.+`onUpdate`.+`onDelete`/); }); -test('fails when no physical resource method is specified', () => { - const stack = new cdk.Stack(); +// test patterns for physicalResourceId +// | # | onCreate.physicalResourceId | onUpdate.physicalResourceId | Error thrown? | +// |---|-----------------------------------|----------------------------------|---------------| +// | 1 | ANY_VALUE | ANY_VALUE | no | +// | 2 | ANY_VALUE | undefined | no | +// | 3 | undefined | ANY_VALLUE | yes | +// | 4 | undefined | undefined | yes | +// | 5 | ANY_VALUE | undefined (*omit whole onUpdate) | no | +// | 6 | undefined | undefined (*omit whole onUpdate) | yes | +// | 7 | ANY_VALUE (*copied from onUpdate) | ANY_VALUE | no | +// | 8 | undefined (*copied from onUpdate) | undefined | yes | +describe('physicalResourceId patterns', () => { + // physicalResourceId pattern #1 + test('physicalResourceId is specified both in onCreate and onUpdate then success', () => { + // GIVEN + const stack = new cdk.Stack(); + + // WHEN + new AwsCustomResource(stack, 'AwsSdk', { + resourceType: 'Custom::AthenaNotebook', + onCreate: { + service: 'Athena', + action: 'createNotebook', + physicalResourceId: PhysicalResourceId.of('id'), + parameters: { + WorkGroup: 'WorkGroupA', + Name: 'Notebook1', + }, + }, + onUpdate: { + service: 'Athena', + action: 'updateNotebookMetadata', + physicalResourceId: PhysicalResourceId.of('id'), + parameters: { + Name: 'Notebook1', + NotebookId: new PhysicalResourceIdReference(), + }, + }, + policy: AwsCustomResourcePolicy.fromSdkCalls({ resources: AwsCustomResourcePolicy.ANY_RESOURCE }), + }); - expect(() => new AwsCustomResource(stack, 'AwsSdk', { - onUpdate: { - service: 'CloudWatchLogs', - action: 'putRetentionPolicy', - parameters: { - logGroupName: '/aws/lambda/loggroup', - retentionInDays: 90, + // THEN + Template.fromStack(stack).hasResourceProperties('Custom::AthenaNotebook', { + Create: JSON.stringify({ + service: 'Athena', + action: 'createNotebook', + physicalResourceId: { + id: 'id', + }, + parameters: { + WorkGroup: 'WorkGroupA', + Name: 'Notebook1', + }, + }), + Update: JSON.stringify({ + service: 'Athena', + action: 'updateNotebookMetadata', + physicalResourceId: { + id: 'id', + }, + parameters: { + Name: 'Notebook1', + NotebookId: 'PHYSICAL:RESOURCEID:', + }, + }), + }); + }); + + // physicalResourceId pattern #2 + test('physicalResourceId is specified in onCreate, is not in onUpdate then absent', () => { + // GIVEN + const stack = new cdk.Stack(); + + // WHEN + new AwsCustomResource(stack, 'AwsSdk', { + resourceType: 'Custom::AthenaNotebook', + onCreate: { + service: 'Athena', + action: 'createNotebook', + physicalResourceId: PhysicalResourceId.fromResponse('NotebookId'), + parameters: { + WorkGroup: 'WorkGroupA', + Name: 'Notebook1', + }, }, - }, - policy: AwsCustomResourcePolicy.fromSdkCalls({ resources: AwsCustomResourcePolicy.ANY_RESOURCE }), - })).toThrow(/`physicalResourceId`/); + onUpdate: { + service: 'Athena', + action: 'updateNotebookMetadata', + parameters: { + Name: 'Notebook1', + NotebookId: new PhysicalResourceIdReference(), + }, + }, + policy: AwsCustomResourcePolicy.fromSdkCalls({ resources: AwsCustomResourcePolicy.ANY_RESOURCE }), + }); + + // THEN + Template.fromStack(stack).hasResourceProperties('Custom::AthenaNotebook', { + Create: JSON.stringify({ + service: 'Athena', + action: 'createNotebook', + physicalResourceId: { + responsePath: 'NotebookId', + }, + parameters: { + WorkGroup: 'WorkGroupA', + Name: 'Notebook1', + }, + }), + Update: JSON.stringify({ + service: 'Athena', + action: 'updateNotebookMetadata', + parameters: { + Name: 'Notebook1', + NotebookId: 'PHYSICAL:RESOURCEID:', + }, + }), + }); + }); + + // physicalResourceId pattern #3 + test('physicalResourceId is not specified in onCreate but onUpdate then fail', () => { + // GIVEN + const stack = new cdk.Stack(); + + // WHEN + expect(() => { + new AwsCustomResource(stack, 'AwsSdk', { + resourceType: 'Custom::AthenaNotebook', + onCreate: { + service: 'Athena', + action: 'createNotebook', + parameters: { + WorkGroup: 'WorkGroupA', + Name: 'Notebook1', + }, + }, + onUpdate: { + service: 'Athena', + action: 'updateNotebookMetadata', + physicalResourceId: PhysicalResourceId.of('id'), + parameters: { + Name: 'Notebook1', + NotebookId: new PhysicalResourceIdReference(), + }, + }, + policy: AwsCustomResourcePolicy.fromSdkCalls({ resources: AwsCustomResourcePolicy.ANY_RESOURCE }), + }); + }).toThrow(/`physicalResourceId` must be specified for onCreate call./); + }); + + // physicalResourceId pattern #4 + test('physicalResourceId is not specified both in onCreate and onUpdate then fail', () => { + // GIVEN + const stack = new cdk.Stack(); + + // WHEN + expect(() => { + new AwsCustomResource(stack, 'AwsSdk', { + resourceType: 'Custom::AthenaNotebook', + onCreate: { + service: 'Athena', + action: 'createNotebook', + parameters: { + WorkGroup: 'WorkGroupA', + Name: 'Notebook1', + }, + }, + onUpdate: { + service: 'Athena', + action: 'updateNotebookMetadata', + parameters: { + Name: 'Notebook1', + NotebookId: new PhysicalResourceIdReference(), + }, + }, + policy: AwsCustomResourcePolicy.fromSdkCalls({ resources: AwsCustomResourcePolicy.ANY_RESOURCE }), + }); + }).toThrow(/`physicalResourceId` must be specified for onCreate call./); + }); + + // physicalResourceId pattern #5 + test('physicalResourceId is specified in onCreate with empty onUpdate then success', () => { + // GIVEN + const stack = new cdk.Stack(); + + // WHEN + new AwsCustomResource(stack, 'AwsSdk', { + resourceType: 'Custom::AthenaNotebook', + onCreate: { + service: 'Athena', + action: 'createNotebook', + physicalResourceId: PhysicalResourceId.of('id'), + parameters: { + WorkGroup: 'WorkGroupA', + Name: 'Notebook1', + }, + }, + policy: AwsCustomResourcePolicy.fromSdkCalls({ resources: AwsCustomResourcePolicy.ANY_RESOURCE }), + }); + + // THEN + Template.fromStack(stack).hasResourceProperties('Custom::AthenaNotebook', { + Create: JSON.stringify({ + service: 'Athena', + action: 'createNotebook', + physicalResourceId: { + id: 'id', + }, + parameters: { + WorkGroup: 'WorkGroupA', + Name: 'Notebook1', + }, + }), + }); + }); + + // physicalResourceId pattern #6 + test('physicalResourceId is not specified onCreate with empty onUpdate then fail', () => { + // GIVEN + const stack = new cdk.Stack(); + + // WHEN + expect(() => { + new AwsCustomResource(stack, 'AwsSdk', { + resourceType: 'Custom::AthenaNotebook', + onCreate: { + service: 'Athena', + action: 'createNotebook', + parameters: { + WorkGroup: 'WorkGroupA', + Name: 'Notebook1', + }, + }, + policy: AwsCustomResourcePolicy.fromSdkCalls({ resources: AwsCustomResourcePolicy.ANY_RESOURCE }), + }); + }).toThrow(/`physicalResourceId` must be specified for onCreate call./); + }); + + // physicalResourceId pattern #7 + test('physicalResourceId is specified in onUpdate with empty onCreate then success', () => { + // GIVEN + const stack = new cdk.Stack(); + + // WHEN + new AwsCustomResource(stack, 'AwsSdk', { + resourceType: 'Custom::AthenaNotebook', + onUpdate: { + service: 'Athena', + action: 'updateNotebookMetadata', + physicalResourceId: PhysicalResourceId.of('id'), + parameters: { + Name: 'Notebook1', + NotebookId: 'XXXX', + }, + }, + policy: AwsCustomResourcePolicy.fromSdkCalls({ resources: AwsCustomResourcePolicy.ANY_RESOURCE }), + }); + + Template.fromStack(stack).hasResourceProperties('Custom::AthenaNotebook', { + Create: JSON.stringify({ + service: 'Athena', + action: 'updateNotebookMetadata', + physicalResourceId: { + id: 'id', + }, + parameters: { + Name: 'Notebook1', + NotebookId: 'XXXX', + }, + }), + Update: JSON.stringify({ + service: 'Athena', + action: 'updateNotebookMetadata', + physicalResourceId: { + id: 'id', + }, + parameters: { + Name: 'Notebook1', + NotebookId: 'XXXX', + }, + }), + }); + }); + + // physicalResourceId pattern #8 + test('physicalResourceId is not specified onCreate with empty onUpdate then fail', () => { + // GIVEN + const stack = new cdk.Stack(); + + // WHEN + expect(() => { + new AwsCustomResource(stack, 'AwsSdk', { + resourceType: 'Custom::AthenaNotebook', + onUpdate: { + service: 'Athena', + action: 'updateNotebookMetadata', + parameters: { + Name: 'Notebook1', + NotebookId: 'XXXX', + }, + }, + policy: AwsCustomResourcePolicy.fromSdkCalls({ resources: AwsCustomResourcePolicy.ANY_RESOURCE }), + }); + }).toThrow(/`physicalResourceId` must be specified for onUpdate call when onCreate is omitted./); + }); }); test('booleans are encoded in the stringified parameters object', () => { @@ -210,17 +505,17 @@ test('booleans are encoded in the stringified parameters object', () => { // THEN Template.fromStack(stack).hasResourceProperties('Custom::ServiceAction', { - 'Create': JSON.stringify({ - 'service': 'service', - 'action': 'action', - 'parameters': { - 'trueBoolean': true, - 'trueString': 'true', - 'falseBoolean': false, - 'falseString': 'false', + Create: JSON.stringify({ + service: 'service', + action: 'action', + parameters: { + trueBoolean: true, + trueString: 'true', + falseBoolean: false, + falseString: 'false', }, - 'physicalResourceId': { - 'id': 'id', + physicalResourceId: { + id: 'id', }, }), }); @@ -228,18 +523,21 @@ test('booleans are encoded in the stringified parameters object', () => { test('fails PhysicalResourceIdReference is passed to onCreate parameters', () => { const stack = new cdk.Stack(); - expect(() => new AwsCustomResource(stack, 'AwsSdk', { - resourceType: 'Custom::ServiceAction', - onCreate: { - service: 'service', - action: 'action', - parameters: { - physicalResourceIdReference: new PhysicalResourceIdReference(), - }, - physicalResourceId: PhysicalResourceId.of('id'), - }, - policy: AwsCustomResourcePolicy.fromSdkCalls({ resources: AwsCustomResourcePolicy.ANY_RESOURCE }), - })).toThrow('`PhysicalResourceIdReference` must not be specified in `onCreate` parameters.'); + expect( + () => + new AwsCustomResource(stack, 'AwsSdk', { + resourceType: 'Custom::ServiceAction', + onCreate: { + service: 'service', + action: 'action', + parameters: { + physicalResourceIdReference: new PhysicalResourceIdReference(), + }, + physicalResourceId: PhysicalResourceId.of('id'), + }, + policy: AwsCustomResourcePolicy.fromSdkCalls({ resources: AwsCustomResourcePolicy.ANY_RESOURCE }), + }), + ).toThrow('`PhysicalResourceIdReference` must not be specified in `onCreate` parameters.'); }); test('encodes physical resource id reference', () => { @@ -266,18 +564,18 @@ test('encodes physical resource id reference', () => { // THEN Template.fromStack(stack).hasResourceProperties('Custom::ServiceAction', { - 'Create': JSON.stringify({ - 'service': 'service', - 'action': 'action', - 'parameters': { - 'trueBoolean': true, - 'trueString': 'true', - 'falseBoolean': false, - 'falseString': 'false', - 'physicalResourceIdReference': 'PHYSICAL:RESOURCEID:', + Create: JSON.stringify({ + service: 'service', + action: 'action', + parameters: { + trueBoolean: true, + trueString: 'true', + falseBoolean: false, + falseString: 'false', + physicalResourceIdReference: 'PHYSICAL:RESOURCEID:', }, - 'physicalResourceId': { - 'id': 'id', + physicalResourceId: { + id: 'id', }, }), }); @@ -349,10 +647,7 @@ test('implements IGrantable', () => { Action: 'iam:PassRole', Effect: 'Allow', Resource: { - 'Fn::GetAtt': [ - 'Role1ABCC5F0', - 'Arn', - ], + 'Fn::GetAtt': ['Role1ABCC5F0', 'Arn'], }, }, ], @@ -402,15 +697,11 @@ test('getData', () => { // THEN expect(stack.resolve(token)).toEqual({ - 'Fn::GetAtt': [ - 'AwsSdkE966FE43', - 'Data', - ], + 'Fn::GetAtt': ['AwsSdkE966FE43', 'Data'], }); }); test('fails when getData is used with `ignoreErrorCodesMatching`', () => { - const stack = new cdk.Stack(); const resource = new AwsCustomResource(stack, 'AwsSdk', { @@ -428,11 +719,9 @@ test('fails when getData is used with `ignoreErrorCodesMatching`', () => { }); expect(() => resource.getResponseFieldReference('ShouldFail')).toThrow(/`getData`.+`ignoreErrorCodesMatching`/); - }); test('fails when getDataString is used with `ignoreErrorCodesMatching`', () => { - const stack = new cdk.Stack(); const resource = new AwsCustomResource(stack, 'AwsSdk', { @@ -450,54 +739,60 @@ test('fails when getDataString is used with `ignoreErrorCodesMatching`', () => { }); expect(() => resource.getResponseField('ShouldFail')).toThrow(/`getDataString`.+`ignoreErrorCodesMatching`/); - }); test('fail when `PhysicalResourceId.fromResponse` is used with `ignoreErrorCodesMatching', () => { - const stack = new cdk.Stack(); - expect(() => new AwsCustomResource(stack, 'AwsSdkOnUpdate', { - onUpdate: { - service: 'CloudWatchLogs', - action: 'putRetentionPolicy', - parameters: { - logGroupName: '/aws/lambda/loggroup', - retentionInDays: 90, - }, - ignoreErrorCodesMatching: '.*', - physicalResourceId: PhysicalResourceId.fromResponse('Response'), - }, - policy: AwsCustomResourcePolicy.fromSdkCalls({ resources: AwsCustomResourcePolicy.ANY_RESOURCE }), - })).toThrow(/`PhysicalResourceId.fromResponse`.+`ignoreErrorCodesMatching`/); - - expect(() => new AwsCustomResource(stack, 'AwsSdkOnCreate', { - onCreate: { - service: 'CloudWatchLogs', - action: 'putRetentionPolicy', - parameters: { - logGroupName: '/aws/lambda/loggroup', - retentionInDays: 90, - }, - ignoreErrorCodesMatching: '.*', - physicalResourceId: PhysicalResourceId.fromResponse('Response'), - }, - policy: AwsCustomResourcePolicy.fromSdkCalls({ resources: AwsCustomResourcePolicy.ANY_RESOURCE }), - })).toThrow(/`PhysicalResourceId.fromResponse`.+`ignoreErrorCodesMatching`/); - - expect(() => new AwsCustomResource(stack, 'AwsSdkOnDelete', { - onDelete: { - service: 'CloudWatchLogs', - action: 'putRetentionPolicy', - parameters: { - logGroupName: '/aws/lambda/loggroup', - retentionInDays: 90, - }, - ignoreErrorCodesMatching: '.*', - physicalResourceId: PhysicalResourceId.fromResponse('Response'), - }, - policy: AwsCustomResourcePolicy.fromSdkCalls({ resources: AwsCustomResourcePolicy.ANY_RESOURCE }), - })).toThrow(/`PhysicalResourceId.fromResponse`.+`ignoreErrorCodesMatching`/); - + expect( + () => + new AwsCustomResource(stack, 'AwsSdkOnUpdate', { + onUpdate: { + service: 'CloudWatchLogs', + action: 'putRetentionPolicy', + parameters: { + logGroupName: '/aws/lambda/loggroup', + retentionInDays: 90, + }, + ignoreErrorCodesMatching: '.*', + physicalResourceId: PhysicalResourceId.fromResponse('Response'), + }, + policy: AwsCustomResourcePolicy.fromSdkCalls({ resources: AwsCustomResourcePolicy.ANY_RESOURCE }), + }), + ).toThrow(/`PhysicalResourceId.fromResponse`.+`ignoreErrorCodesMatching`/); + + expect( + () => + new AwsCustomResource(stack, 'AwsSdkOnCreate', { + onCreate: { + service: 'CloudWatchLogs', + action: 'putRetentionPolicy', + parameters: { + logGroupName: '/aws/lambda/loggroup', + retentionInDays: 90, + }, + ignoreErrorCodesMatching: '.*', + physicalResourceId: PhysicalResourceId.fromResponse('Response'), + }, + policy: AwsCustomResourcePolicy.fromSdkCalls({ resources: AwsCustomResourcePolicy.ANY_RESOURCE }), + }), + ).toThrow(/`PhysicalResourceId.fromResponse`.+`ignoreErrorCodesMatching`/); + + expect( + () => + new AwsCustomResource(stack, 'AwsSdkOnDelete', { + onDelete: { + service: 'CloudWatchLogs', + action: 'putRetentionPolicy', + parameters: { + logGroupName: '/aws/lambda/loggroup', + retentionInDays: 90, + }, + ignoreErrorCodesMatching: '.*', + physicalResourceId: PhysicalResourceId.fromResponse('Response'), + }, + policy: AwsCustomResourcePolicy.fromSdkCalls({ resources: AwsCustomResourcePolicy.ANY_RESOURCE }), + }), + ).toThrow(/`PhysicalResourceId.fromResponse`.+`ignoreErrorCodesMatching`/); }); test('getDataString', () => { @@ -533,10 +828,7 @@ test('getDataString', () => { [ '{"service":"service","action":"action","parameters":{"a":"', { - 'Fn::GetAtt': [ - 'AwsSdk155B91071', - 'Data', - ], + 'Fn::GetAtt': ['AwsSdk155B91071', 'Data'], }, '"},"physicalResourceId":{"id":"id"}}', ], @@ -594,7 +886,7 @@ test('disable AWS SDK installation', () => { // THEN Template.fromStack(stack).hasResourceProperties('Custom::AWS', { - 'InstallLatestAwsSdk': false, + InstallLatestAwsSdk: false, }); }); @@ -699,14 +991,11 @@ test('tokens can be used as dictionary keys', () => { [ '{"service":"service1","action":"action1","physicalResourceId":{"id":"id1"},"parameters":{"', { - 'Ref': 'MyResource', + Ref: 'MyResource', }, '":{"Foo":1234,"Bar":"', { - 'Fn::GetAtt': [ - 'MyResource', - 'Foorz', - ], + 'Fn::GetAtt': ['MyResource', 'Foorz'], }, '"}}}', ], @@ -748,16 +1037,19 @@ test('assumedRoleArn adds statement for sts:assumeRole', () => { test('fails when at least one of policy or role is not specified', () => { const stack = new cdk.Stack(); - expect(() => new AwsCustomResource(stack, 'AwsSdk', { - onUpdate: { - service: 'service', - action: 'action', - physicalResourceId: PhysicalResourceId.of('id'), - parameters: { - param: 'param', - }, - }, - })).toThrow(/`policy`.+`role`/); + expect( + () => + new AwsCustomResource(stack, 'AwsSdk', { + onUpdate: { + service: 'service', + action: 'action', + physicalResourceId: PhysicalResourceId.of('id'), + parameters: { + param: 'param', + }, + }, + }), + ).toThrow(/`policy`.+`role`/); }); test('can provide no policy if using existing role', () => { @@ -798,7 +1090,7 @@ test('can specify VPC', () => { // THEN Template.fromStack(stack).hasResourceProperties('AWS::Lambda::Function', { VpcConfig: { - SubnetIds: stack.resolve(vpc.privateSubnets.map(subnet => subnet.subnetId)), + SubnetIds: stack.resolve(vpc.privateSubnets.map((subnet) => subnet.subnetId)), }, }); }); @@ -868,7 +1160,7 @@ test('vpcSubnets filter is not required when only isolated subnets exist', () => // THEN Template.fromStack(stack).hasResourceProperties('AWS::Lambda::Function', { VpcConfig: { - SubnetIds: stack.resolve(vpc.isolatedSubnets.map(subnet => subnet.subnetId)), + SubnetIds: stack.resolve(vpc.isolatedSubnets.map((subnet) => subnet.subnetId)), }, }); }); @@ -892,7 +1184,7 @@ test('vpcSubnets filter is not required for the default VPC configuration', () = // THEN Template.fromStack(stack).hasResourceProperties('AWS::Lambda::Function', { VpcConfig: { - SubnetIds: stack.resolve(vpc.privateSubnets.map(subnet => subnet.subnetId)), + SubnetIds: stack.resolve(vpc.privateSubnets.map((subnet) => subnet.subnetId)), }, }); }); @@ -902,15 +1194,18 @@ test('vpcSubnets without vpc results in an error', () => { const stack = new cdk.Stack(); // WHEN - expect(() => new AwsCustomResource(stack, 'AwsSdk', { - onCreate: { - service: 'service', - action: 'action', - physicalResourceId: PhysicalResourceId.of('id'), - }, - policy: AwsCustomResourcePolicy.fromSdkCalls({ resources: AwsCustomResourcePolicy.ANY_RESOURCE }), - vpcSubnets: { subnetType: ec2.SubnetType.PRIVATE_ISOLATED }, - })).toThrow('Cannot configure \'vpcSubnets\' without configuring a VPC'); + expect( + () => + new AwsCustomResource(stack, 'AwsSdk', { + onCreate: { + service: 'service', + action: 'action', + physicalResourceId: PhysicalResourceId.of('id'), + }, + policy: AwsCustomResourcePolicy.fromSdkCalls({ resources: AwsCustomResourcePolicy.ANY_RESOURCE }), + vpcSubnets: { subnetType: ec2.SubnetType.PRIVATE_ISOLATED }, + }), + ).toThrow("Cannot configure 'vpcSubnets' without configuring a VPC"); }); test.each([ @@ -943,6 +1238,6 @@ test.each([ // THEN Template.fromStack(stack).hasResourceProperties('Custom::LogRetentionPolicy', { - 'InstallLatestAwsSdk': expected, + InstallLatestAwsSdk: expected, }); -}); \ No newline at end of file +});