/
invalid-templates.test.ts
125 lines (102 loc) · 5.42 KB
/
invalid-templates.test.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
import * as path from 'path';
import { SynthUtils } from '@aws-cdk/assert';
import '@aws-cdk/assert/jest';
import * as core from '@aws-cdk/core';
import * as inc from '../lib';
describe('CDK Include', () => {
let stack: core.Stack;
beforeEach(() => {
stack = new core.Stack();
});
test('throws a validation exception for a template with a missing required top-level resource property', () => {
expect(() => {
includeTestTemplate(stack, 'bucket-policy-without-bucket.json');
}).toThrow(/missing required property: bucket/);
});
test('throws a validation exception for a template with a resource property expecting an array assigned the wrong type', () => {
includeTestTemplate(stack, 'bucket-with-cors-rules-not-an-array.json');
expect(() => {
SynthUtils.synthesize(stack);
}).toThrow(/corsRules: "CorsRules!" should be a list/);
});
test('throws a validation exception for a template with a null array element of a complex type with required fields', () => {
includeTestTemplate(stack, 'bucket-with-cors-rules-null-element.json');
expect(() => {
SynthUtils.synthesize(stack);
}).toThrow(/allowedMethods: required but missing/);
});
test('throws a validation exception for a template with a missing nested resource property', () => {
includeTestTemplate(stack, 'bucket-with-invalid-cors-rule.json');
expect(() => {
SynthUtils.synthesize(stack);
}).toThrow(/allowedOrigins: required but missing/);
});
test("throws a validation exception for a template with a DependsOn that doesn't exist", () => {
expect(() => {
includeTestTemplate(stack, 'non-existent-depends-on.json');
}).toThrow(/Resource 'Bucket2' depends on 'Bucket1' that doesn't exist/);
});
test("throws a validation exception for a template referencing a Condition in the Conditions section that doesn't exist", () => {
expect(() => {
includeTestTemplate(stack, 'non-existent-condition-in-conditions.json');
}).toThrow(/Referenced Condition with name 'AlwaysFalse' was not found in the template/);
});
test('throws a validation exception for a template using Fn::GetAtt in the Conditions section', () => {
expect(() => {
includeTestTemplate(stack, 'getatt-in-conditions.json');
}).toThrow(/Using GetAtt in Condition definitions is not allowed/);
});
test("throws a validation exception for a template referencing a Condition resource attribute that doesn't exist", () => {
expect(() => {
includeTestTemplate(stack, 'non-existent-condition.json');
}).toThrow(/Resource 'Bucket' uses Condition 'AlwaysFalseCond' that doesn't exist/);
});
test("throws a validation exception for a template referencing a Condition in an If expression that doesn't exist", () => {
expect(() => {
includeTestTemplate(stack, 'non-existent-condition-in-if.json');
}).toThrow(/Condition 'AlwaysFalse' used in an Fn::If expression does not exist in the template/);
});
test("throws an exception when encountering a CFN function it doesn't support", () => {
expect(() => {
includeTestTemplate(stack, 'only-codecommit-repo-using-cfn-functions.json');
}).toThrow(/Unsupported CloudFormation function 'Fn::DoesNotExist'/);
});
test('throws a validation exception when encountering an unrecognized resource attribute', () => {
expect(() => {
includeTestTemplate(stack, 'non-existent-resource-attribute.json');
}).toThrow(/The NonExistentResourceAttribute resource attribute is not supported by cloudformation-include yet/);
});
test("throws a validation exception when encountering a Ref-erence to a template element that doesn't exist", () => {
expect(() => {
includeTestTemplate(stack, 'ref-ing-a-non-existent-element.json');
}).toThrow(/Element used in Ref expression with logical ID: 'DoesNotExist' not found/);
});
test("throws a validation exception when encountering a GetAtt reference to a resource that doesn't exist", () => {
expect(() => {
includeTestTemplate(stack, 'getting-attribute-of-a-non-existent-resource.json');
}).toThrow(/Resource used in GetAtt expression with logical ID: 'DoesNotExist' not found/);
});
test("throws a validation exception when an output references a condition that doesn't exist", () => {
expect(() => {
includeTestTemplate(stack, 'output-referencing-nonexistant-condition.json');
}).toThrow(/Output with name 'SomeOutput' refers to a Condition with name 'NonexistantCondition' which was not found in this template/);
});
test("throws a validation exception when Fn::Sub in string form uses a key that isn't in the template", () => {
expect(() => {
includeTestTemplate(stack, 'fn-sub-key-not-in-template-string.json');
}).toThrow(/Element referenced in Fn::Sub expression with logical ID: 'AFakeResource' was not found in the template/);
});
test('throws a validation exception when Fn::Sub has an empty ${} reference', () => {
expect(() => {
includeTestTemplate(stack, 'fn-sub-${}-only.json');
}).toThrow(/Element referenced in Fn::Sub expression with logical ID: '' was not found in the template/);
});
});
function includeTestTemplate(scope: core.Construct, testTemplate: string): inc.CfnInclude {
return new inc.CfnInclude(scope, 'MyScope', {
templateFile: _testTemplateFilePath(testTemplate),
});
}
function _testTemplateFilePath(testTemplate: string) {
return path.join(__dirname, 'test-templates', 'invalid', testTemplate);
}