diff --git a/packages/@aws-cdk/aws-ecr/package.json b/packages/@aws-cdk/aws-ecr/package.json index e8e9c3402eed3..e2b8bccc7c29f 100644 --- a/packages/@aws-cdk/aws-ecr/package.json +++ b/packages/@aws-cdk/aws-ecr/package.json @@ -83,7 +83,7 @@ }, "license": "Apache-2.0", "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/cfn2ts": "0.0.0", diff --git a/packages/@aws-cdk/aws-ecr/test/auth-token.test.ts b/packages/@aws-cdk/aws-ecr/test/auth-token.test.ts index f9be93b1e15d0..421ba7c2f6645 100644 --- a/packages/@aws-cdk/aws-ecr/test/auth-token.test.ts +++ b/packages/@aws-cdk/aws-ecr/test/auth-token.test.ts @@ -1,4 +1,4 @@ -import { expect as expectCDK, haveResourceLike } from '@aws-cdk/assert-internal'; +import { Template } from '@aws-cdk/assertions'; import * as iam from '@aws-cdk/aws-iam'; import { Stack } from '@aws-cdk/core'; import { AuthorizationToken, PublicGalleryAuthorizationToken } from '../lib'; @@ -13,7 +13,7 @@ describe('auth-token', () => { AuthorizationToken.grantRead(user); // THEN - expectCDK(stack).to(haveResourceLike('AWS::IAM::Policy', { + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { PolicyDocument: { Statement: [ { @@ -23,7 +23,7 @@ describe('auth-token', () => { }, ], }, - })); + }); }); test('PublicGalleryAuthorizationToken.grantRead()', () => { @@ -35,7 +35,7 @@ describe('auth-token', () => { PublicGalleryAuthorizationToken.grantRead(user); // THEN - expectCDK(stack).to(haveResourceLike('AWS::IAM::Policy', { + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { PolicyDocument: { Statement: [ { @@ -48,6 +48,6 @@ describe('auth-token', () => { }, ], }, - })); + }); }); }); diff --git a/packages/@aws-cdk/aws-ecr/test/repository.test.ts b/packages/@aws-cdk/aws-ecr/test/repository.test.ts index 37cc58a8485eb..470638d89355e 100644 --- a/packages/@aws-cdk/aws-ecr/test/repository.test.ts +++ b/packages/@aws-cdk/aws-ecr/test/repository.test.ts @@ -1,5 +1,5 @@ import { EOL } from 'os'; -import { expect as expectCDK, haveResource, haveResourceLike, ResourcePart } from '@aws-cdk/assert-internal'; +import { Template } from '@aws-cdk/assertions'; import * as iam from '@aws-cdk/aws-iam'; import * as cdk from '@aws-cdk/core'; import * as ecr from '../lib'; @@ -15,7 +15,7 @@ describe('repository', () => { new ecr.Repository(stack, 'Repo'); // THEN - expectCDK(stack).toMatch({ + Template.fromStack(stack).templateMatches({ Resources: { Repo02AC86CF: { Type: 'AWS::ECR::Repository', @@ -34,11 +34,11 @@ describe('repository', () => { new ecr.Repository(stack, 'Repo', { imageScanOnPush: true }); // THEN - expectCDK(stack).to(haveResource('AWS::ECR::Repository', { + Template.fromStack(stack).hasResourceProperties('AWS::ECR::Repository', { ImageScanningConfiguration: { ScanOnPush: true, }, - })); + }); }); test('tag-based lifecycle policy', () => { @@ -50,12 +50,12 @@ describe('repository', () => { repo.addLifecycleRule({ tagPrefixList: ['abc'], maxImageCount: 1 }); // THEN - expectCDK(stack).to(haveResource('AWS::ECR::Repository', { + Template.fromStack(stack).hasResourceProperties('AWS::ECR::Repository', { LifecyclePolicy: { // eslint-disable-next-line max-len LifecyclePolicyText: '{"rules":[{"rulePriority":1,"selection":{"tagStatus":"tagged","tagPrefixList":["abc"],"countType":"imageCountMoreThan","countNumber":1},"action":{"type":"expire"}}]}', }, - })); + }); }); test('image tag mutability can be set', () => { @@ -64,9 +64,9 @@ describe('repository', () => { new ecr.Repository(stack, 'Repo', { imageTagMutability: ecr.TagMutability.IMMUTABLE }); // THEN - expectCDK(stack).to(haveResource('AWS::ECR::Repository', { + Template.fromStack(stack).hasResourceProperties('AWS::ECR::Repository', { ImageTagMutability: 'IMMUTABLE', - })); + }); }); test('add day-based lifecycle policy', () => { @@ -80,12 +80,12 @@ describe('repository', () => { }); // THEN - expectCDK(stack).to(haveResource('AWS::ECR::Repository', { + Template.fromStack(stack).hasResourceProperties('AWS::ECR::Repository', { LifecyclePolicy: { // eslint-disable-next-line max-len LifecyclePolicyText: '{"rules":[{"rulePriority":1,"selection":{"tagStatus":"any","countType":"sinceImagePushed","countNumber":5,"countUnit":"days"},"action":{"type":"expire"}}]}', }, - })); + }); }); test('add count-based lifecycle policy', () => { @@ -99,12 +99,12 @@ describe('repository', () => { }); // THEN - expectCDK(stack).to(haveResource('AWS::ECR::Repository', { + Template.fromStack(stack).hasResourceProperties('AWS::ECR::Repository', { LifecyclePolicy: { // eslint-disable-next-line max-len LifecyclePolicyText: '{"rules":[{"rulePriority":1,"selection":{"tagStatus":"any","countType":"imageCountMoreThan","countNumber":5},"action":{"type":"expire"}}]}', }, - })); + }); }); test('mixing numbered and unnumbered rules', () => { @@ -117,12 +117,12 @@ describe('repository', () => { repo.addLifecycleRule({ rulePriority: 10, tagStatus: ecr.TagStatus.TAGGED, tagPrefixList: ['b'], maxImageCount: 5 }); // THEN - expectCDK(stack).to(haveResource('AWS::ECR::Repository', { + Template.fromStack(stack).hasResourceProperties('AWS::ECR::Repository', { LifecyclePolicy: { // eslint-disable-next-line max-len LifecyclePolicyText: '{"rules":[{"rulePriority":10,"selection":{"tagStatus":"tagged","tagPrefixList":["b"],"countType":"imageCountMoreThan","countNumber":5},"action":{"type":"expire"}},{"rulePriority":11,"selection":{"tagStatus":"tagged","tagPrefixList":["a"],"countType":"imageCountMoreThan","countNumber":5},"action":{"type":"expire"}}]}', }, - })); + }); }); test('tagstatus Any is automatically sorted to the back', () => { @@ -135,12 +135,12 @@ describe('repository', () => { repo.addLifecycleRule({ tagStatus: ecr.TagStatus.TAGGED, tagPrefixList: ['important'], maxImageCount: 999 }); // THEN - expectCDK(stack).to(haveResource('AWS::ECR::Repository', { + Template.fromStack(stack).hasResourceProperties('AWS::ECR::Repository', { LifecyclePolicy: { // eslint-disable-next-line max-len LifecyclePolicyText: '{"rules":[{"rulePriority":1,"selection":{"tagStatus":"tagged","tagPrefixList":["important"],"countType":"imageCountMoreThan","countNumber":999},"action":{"type":"expire"}},{"rulePriority":2,"selection":{"tagStatus":"any","countType":"imageCountMoreThan","countNumber":5},"action":{"type":"expire"}}]}', }, - })); + }); }); test('lifecycle rules can be added upon initialization', () => { @@ -155,12 +155,12 @@ describe('repository', () => { }); // THEN - expectCDK(stack).to(haveResource('AWS::ECR::Repository', { + Template.fromStack(stack).hasResourceProperties('AWS::ECR::Repository', { 'LifecyclePolicy': { // eslint-disable-next-line max-len 'LifecyclePolicyText': '{"rules":[{"rulePriority":1,"selection":{"tagStatus":"any","countType":"imageCountMoreThan","countNumber":3},"action":{"type":"expire"}}]}', }, - })); + }); }); test('calculate repository URI', () => { @@ -168,21 +168,24 @@ describe('repository', () => { const stack = new cdk.Stack(); const repo = new ecr.Repository(stack, 'Repo'); - // WHEN - const uri = repo.repositoryUri; + new cdk.CfnOutput(stack, 'RepoUri', { + value: repo.repositoryUri, + }); // THEN const arnSplit = { 'Fn::Split': [':', { 'Fn::GetAtt': ['Repo02AC86CF', 'Arn'] }] }; - expectCDK(stack.resolve(uri)).toMatch({ - 'Fn::Join': ['', [ - { 'Fn::Select': [4, arnSplit] }, - '.dkr.ecr.', - { 'Fn::Select': [3, arnSplit] }, - '.', - { Ref: 'AWS::URLSuffix' }, - '/', - { Ref: 'Repo02AC86CF' }, - ]], + Template.fromStack(stack).hasOutput('*', { + 'Value': { + 'Fn::Join': ['', [ + { 'Fn::Select': [4, arnSplit] }, + '.dkr.ecr.', + { 'Fn::Select': [3, arnSplit] }, + '.', + { Ref: 'AWS::URLSuffix' }, + '/', + { Ref: 'Repo02AC86CF' }, + ]], + }, }); }); @@ -217,10 +220,20 @@ describe('repository', () => { repositoryArn: cdk.Fn.getAtt('Boom', 'Arn').toString(), repositoryName: cdk.Fn.getAtt('Boom', 'Name').toString(), }); + new cdk.CfnOutput(stack, 'RepoArn', { + value: repo.repositoryArn, + }); + new cdk.CfnOutput(stack, 'RepoName', { + value: repo.repositoryName, + }); // THEN - expectCDK(stack.resolve(repo.repositoryArn)).toMatch({ 'Fn::GetAtt': ['Boom', 'Arn'] }); - expectCDK(stack.resolve(repo.repositoryName)).toMatch({ 'Fn::GetAtt': ['Boom', 'Name'] }); + Template.fromStack(stack).hasOutput('*', { + Value: { 'Fn::GetAtt': ['Boom', 'Arn'] }, + }); + Template.fromStack(stack).hasOutput('*', { + Value: { 'Fn::GetAtt': ['Boom', 'Name'] }, + }); }); test('import only with a repository name (arn is deduced)', () => { @@ -229,20 +242,30 @@ describe('repository', () => { // WHEN const repo = ecr.Repository.fromRepositoryName(stack, 'just-name', 'my-repo'); + new cdk.CfnOutput(stack, 'RepoArn', { + value: repo.repositoryArn, + }); + new cdk.CfnOutput(stack, 'RepoName', { + value: repo.repositoryName, + }); // THEN - expectCDK(stack.resolve(repo.repositoryArn)).toMatch({ - 'Fn::Join': ['', [ - 'arn:', - { Ref: 'AWS::Partition' }, - ':ecr:', - { Ref: 'AWS::Region' }, - ':', - { Ref: 'AWS::AccountId' }, - ':repository/my-repo', - ]], - }); - expect(stack.resolve(repo.repositoryName)).toBe('my-repo'); + Template.fromStack(stack).hasOutput('*', { + Value: { + 'Fn::Join': ['', [ + 'arn:', + { Ref: 'AWS::Partition' }, + ':ecr:', + { Ref: 'AWS::Region' }, + ':', + { Ref: 'AWS::AccountId' }, + ':repository/my-repo', + ]], + }, + }); + Template.fromStack(stack).hasOutput('*', { + Value: 'my-repo', + }); }); test('arnForLocalRepository can be used to render an ARN for a local repository', () => { @@ -255,20 +278,30 @@ describe('repository', () => { repositoryArn: ecr.Repository.arnForLocalRepository(repoName, stack), repositoryName: repoName, }); + new cdk.CfnOutput(stack, 'RepoArn', { + value: repo.repositoryArn, + }); + new cdk.CfnOutput(stack, 'RepoName', { + value: repo.repositoryName, + }); // THEN - expectCDK(stack.resolve(repo.repositoryName)).toMatch({ 'Fn::GetAtt': ['Boom', 'Name'] }); - expectCDK(stack.resolve(repo.repositoryArn)).toMatch({ - 'Fn::Join': ['', [ - 'arn:', - { Ref: 'AWS::Partition' }, - ':ecr:', - { Ref: 'AWS::Region' }, - ':', - { Ref: 'AWS::AccountId' }, - ':repository/', - { 'Fn::GetAtt': ['Boom', 'Name'] }, - ]], + Template.fromStack(stack).hasOutput('*', { + Value: { 'Fn::GetAtt': ['Boom', 'Name'] }, + }); + Template.fromStack(stack).hasOutput('*', { + Value: { + 'Fn::Join': ['', [ + 'arn:', + { Ref: 'AWS::Partition' }, + ':ecr:', + { Ref: 'AWS::Region' }, + ':', + { Ref: 'AWS::AccountId' }, + ':repository/', + { 'Fn::GetAtt': ['Boom', 'Name'] }, + ]], + }, }); }); @@ -284,7 +317,7 @@ describe('repository', () => { })); // THEN - expectCDK(stack).to(haveResource('AWS::ECR::Repository', { + Template.fromStack(stack).hasResourceProperties('AWS::ECR::Repository', { RepositoryPolicyText: { Statement: [ { @@ -295,7 +328,7 @@ describe('repository', () => { ], Version: '2012-10-17', }, - })); + }); }); test('fails if repository policy has no actions', () => { @@ -341,7 +374,7 @@ describe('repository', () => { }, }); - expectCDK(stack).to(haveResourceLike('AWS::Events::Rule', { + Template.fromStack(stack).hasResourceProperties('AWS::Events::Rule', { 'EventPattern': { 'source': [ 'aws.ecr', @@ -360,7 +393,7 @@ describe('repository', () => { }, }, 'State': 'ENABLED', - })); + }); }); test('onImageScanCompleted without imageTags creates the correct event', () => { @@ -373,7 +406,7 @@ describe('repository', () => { }, }); - expectCDK(stack).to(haveResourceLike('AWS::Events::Rule', { + Template.fromStack(stack).hasResourceProperties('AWS::Events::Rule', { 'EventPattern': { 'source': [ 'aws.ecr', @@ -390,7 +423,7 @@ describe('repository', () => { }, }, 'State': 'ENABLED', - })); + }); }); test('onImageScanCompleted with one imageTag creates the correct event', () => { @@ -404,7 +437,7 @@ describe('repository', () => { }, }); - expectCDK(stack).to(haveResourceLike('AWS::Events::Rule', { + Template.fromStack(stack).hasResourceProperties('AWS::Events::Rule', { 'EventPattern': { 'source': [ 'aws.ecr', @@ -424,7 +457,7 @@ describe('repository', () => { }, }, 'State': 'ENABLED', - })); + }); }); test('onImageScanCompleted with multiple imageTags creates the correct event', () => { @@ -438,7 +471,7 @@ describe('repository', () => { }, }); - expectCDK(stack).to(haveResourceLike('AWS::Events::Rule', { + Template.fromStack(stack).hasResourceProperties('AWS::Events::Rule', { 'EventPattern': { 'source': [ 'aws.ecr', @@ -460,7 +493,7 @@ describe('repository', () => { }, }, 'State': 'ENABLED', - })); + }); }); test('removal policy is "Retain" by default', () => { @@ -471,10 +504,10 @@ describe('repository', () => { new ecr.Repository(stack, 'Repo'); // THEN - expectCDK(stack).to(haveResource('AWS::ECR::Repository', { + Template.fromStack(stack).hasResource('AWS::ECR::Repository', { 'Type': 'AWS::ECR::Repository', 'DeletionPolicy': 'Retain', - }, ResourcePart.CompleteDefinition)); + }); }); test('"Delete" removal policy can be set explicitly', () => { @@ -487,10 +520,10 @@ describe('repository', () => { }); // THEN - expectCDK(stack).to(haveResource('AWS::ECR::Repository', { + Template.fromStack(stack).hasResource('AWS::ECR::Repository', { 'Type': 'AWS::ECR::Repository', 'DeletionPolicy': 'Delete', - }, ResourcePart.CompleteDefinition)); + }); }); test('grant adds appropriate resource-*', () => { @@ -502,7 +535,7 @@ describe('repository', () => { repo.grantPull(new iam.AnyPrincipal()); // THEN - expectCDK(stack).to(haveResource('AWS::ECR::Repository', { + Template.fromStack(stack).hasResourceProperties('AWS::ECR::Repository', { 'RepositoryPolicyText': { 'Statement': [ { @@ -512,12 +545,12 @@ describe('repository', () => { 'ecr:BatchGetImage', ], 'Effect': 'Allow', - 'Principal': { AWS: '*' }, + 'Principal': { 'AWS': '*' }, }, ], 'Version': '2012-10-17', }, - })); + }); }); });