@friggframework/devtools 2.0.0--canary.474.86c5119.0 → 2.0.0--canary.474.898a56c.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/infrastructure/domains/health/application/use-cases/__tests__/mismatch-analyzer-method-name.test.js +167 -0
- package/infrastructure/domains/health/application/use-cases/__tests__/repair-via-import-use-case.test.js +762 -0
- package/infrastructure/domains/health/application/use-cases/repair-via-import-use-case.js +154 -1
- package/infrastructure/domains/health/application/use-cases/run-health-check-use-case.js +20 -5
- package/infrastructure/domains/health/application/use-cases/run-health-check-use-case.test.js +3 -3
- package/infrastructure/domains/health/docs/ACME-DEV-DRIFT-ANALYSIS.md +267 -0
- package/infrastructure/domains/health/docs/BUILD-VS-DEPLOYED-TEMPLATE-ANALYSIS.md +324 -0
- package/infrastructure/domains/health/docs/ORPHAN-DETECTION-ANALYSIS.md +386 -0
- package/infrastructure/domains/health/docs/SPEC-CLEANUP-COMMAND.md +1419 -0
- package/infrastructure/domains/health/docs/TDD-IMPLEMENTATION-SUMMARY.md +391 -0
- package/infrastructure/domains/health/docs/TEMPLATE-COMPARISON-IMPLEMENTATION.md +551 -0
- package/infrastructure/domains/health/domain/services/__tests__/health-score-percentage-based.test.js +380 -0
- package/infrastructure/domains/health/domain/services/__tests__/logical-id-mapper.test.js +645 -0
- package/infrastructure/domains/health/domain/services/__tests__/template-parser.test.js +496 -0
- package/infrastructure/domains/health/domain/services/health-score-calculator.js +174 -91
- package/infrastructure/domains/health/domain/services/health-score-calculator.test.js +332 -228
- package/infrastructure/domains/health/domain/services/logical-id-mapper.js +330 -0
- package/infrastructure/domains/health/domain/services/template-parser.js +245 -0
- package/infrastructure/domains/health/infrastructure/adapters/__tests__/orphan-detection-cfn-tagged.test.js +312 -0
- package/infrastructure/domains/health/infrastructure/adapters/__tests__/orphan-detection-multi-stack.test.js +367 -0
- package/infrastructure/domains/health/infrastructure/adapters/__tests__/orphan-detection-relationship-analysis.test.js +432 -0
- package/infrastructure/domains/health/infrastructure/adapters/aws-resource-detector.js +108 -14
- package/infrastructure/domains/health/infrastructure/adapters/aws-resource-detector.test.js +69 -12
- package/package.json +6 -6
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TDD Test for MismatchAnalyzer Method Name Bug
|
|
3
|
+
*
|
|
4
|
+
* Bug: RunHealthCheckUseCase calls this.mismatchAnalyzer.analyzePropertyMismatches()
|
|
5
|
+
* but the actual method is analyze()
|
|
6
|
+
*
|
|
7
|
+
* This test ensures the correct method name is used.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
const RunHealthCheckUseCase = require('../run-health-check-use-case');
|
|
11
|
+
const StackIdentifier = require('../../../domain/value-objects/stack-identifier');
|
|
12
|
+
const MismatchAnalyzer = require('../../../domain/services/mismatch-analyzer');
|
|
13
|
+
const HealthScore = require('../../../domain/value-objects/health-score');
|
|
14
|
+
|
|
15
|
+
describe('MismatchAnalyzer Method Name Bug Fix', () => {
|
|
16
|
+
let useCase;
|
|
17
|
+
let mockStackRepository;
|
|
18
|
+
let mockResourceDetector;
|
|
19
|
+
let mockHealthScoreCalculator;
|
|
20
|
+
let realMismatchAnalyzer;
|
|
21
|
+
|
|
22
|
+
beforeEach(() => {
|
|
23
|
+
// Use REAL MismatchAnalyzer to catch method name errors
|
|
24
|
+
realMismatchAnalyzer = new MismatchAnalyzer();
|
|
25
|
+
|
|
26
|
+
mockStackRepository = {
|
|
27
|
+
getStack: jest.fn(),
|
|
28
|
+
listResources: jest.fn(),
|
|
29
|
+
detectStackDrift: jest.fn(),
|
|
30
|
+
getResourceDrift: jest.fn(),
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
mockResourceDetector = {
|
|
34
|
+
detectResources: jest.fn(),
|
|
35
|
+
findOrphanedResources: jest.fn(),
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
mockHealthScoreCalculator = {
|
|
39
|
+
calculate: jest.fn().mockReturnValue(new HealthScore(100)),
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
useCase = new RunHealthCheckUseCase({
|
|
43
|
+
stackRepository: mockStackRepository,
|
|
44
|
+
resourceDetector: mockResourceDetector,
|
|
45
|
+
mismatchAnalyzer: realMismatchAnalyzer, // Use REAL analyzer
|
|
46
|
+
healthScoreCalculator: mockHealthScoreCalculator,
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
test('should call MismatchAnalyzer.analyze() method correctly when resource has drifted properties', async () => {
|
|
51
|
+
// Arrange
|
|
52
|
+
const stackIdentifier = new StackIdentifier({
|
|
53
|
+
stackName: 'test-stack',
|
|
54
|
+
region: 'us-east-1',
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
// Mock stack with drift
|
|
58
|
+
mockStackRepository.getStack.mockResolvedValue({
|
|
59
|
+
stackName: 'test-stack',
|
|
60
|
+
stackId: 'arn:aws:cloudformation:us-east-1:123456789012:stack/test-stack/guid',
|
|
61
|
+
status: 'UPDATE_COMPLETE',
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
mockStackRepository.detectStackDrift.mockResolvedValue({
|
|
65
|
+
stackDriftStatus: 'DRIFTED',
|
|
66
|
+
driftedResourcesCount: 1,
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
// Resource with drift
|
|
70
|
+
mockStackRepository.listResources.mockResolvedValue([
|
|
71
|
+
{
|
|
72
|
+
logicalId: 'MyBucket',
|
|
73
|
+
physicalId: 's3-bucket-123',
|
|
74
|
+
resourceType: 'AWS::S3::Bucket',
|
|
75
|
+
driftStatus: 'MODIFIED',
|
|
76
|
+
},
|
|
77
|
+
]);
|
|
78
|
+
|
|
79
|
+
// Resource drift details
|
|
80
|
+
mockStackRepository.getResourceDrift.mockResolvedValue({
|
|
81
|
+
logicalId: 'MyBucket',
|
|
82
|
+
physicalId: 's3-bucket-123',
|
|
83
|
+
resourceType: 'AWS::S3::Bucket',
|
|
84
|
+
driftStatus: 'MODIFIED',
|
|
85
|
+
propertyDifferences: [
|
|
86
|
+
{
|
|
87
|
+
propertyPath: 'BucketEncryption.Rules[0].BucketKeyEnabled',
|
|
88
|
+
expectedValue: true,
|
|
89
|
+
actualValue: false,
|
|
90
|
+
differenceType: 'NOT_EQUAL',
|
|
91
|
+
},
|
|
92
|
+
],
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
mockResourceDetector.detectResources.mockResolvedValue([]);
|
|
96
|
+
mockResourceDetector.findOrphanedResources.mockResolvedValue([]);
|
|
97
|
+
|
|
98
|
+
// Spy on the MismatchAnalyzer to ensure correct method is called
|
|
99
|
+
const analyzeSpy = jest.spyOn(realMismatchAnalyzer, 'analyze');
|
|
100
|
+
|
|
101
|
+
// Act
|
|
102
|
+
// This will FAIL if the use case calls analyzePropertyMismatches() instead of analyze()
|
|
103
|
+
const report = await useCase.execute({ stackIdentifier });
|
|
104
|
+
|
|
105
|
+
// Assert
|
|
106
|
+
expect(analyzeSpy).toHaveBeenCalled();
|
|
107
|
+
expect(report).toBeDefined();
|
|
108
|
+
expect(report.getDriftedResourceCount()).toBe(1);
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
test('should successfully execute when using correct analyze() method', async () => {
|
|
112
|
+
// Arrange
|
|
113
|
+
const stackIdentifier = new StackIdentifier({
|
|
114
|
+
stackName: 'test-stack',
|
|
115
|
+
region: 'us-east-1',
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
mockStackRepository.getStack.mockResolvedValue({
|
|
119
|
+
stackName: 'test-stack',
|
|
120
|
+
stackId: 'arn:aws:cloudformation:us-east-1:123456789012:stack/test-stack/guid',
|
|
121
|
+
status: 'UPDATE_COMPLETE',
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
mockStackRepository.detectStackDrift.mockResolvedValue({
|
|
125
|
+
stackDriftStatus: 'DRIFTED',
|
|
126
|
+
driftedResourcesCount: 1,
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
mockStackRepository.listResources.mockResolvedValue([
|
|
130
|
+
{
|
|
131
|
+
logicalId: 'MyBucket',
|
|
132
|
+
physicalId: 's3-bucket-123',
|
|
133
|
+
resourceType: 'AWS::S3::Bucket',
|
|
134
|
+
driftStatus: 'MODIFIED',
|
|
135
|
+
},
|
|
136
|
+
]);
|
|
137
|
+
|
|
138
|
+
mockStackRepository.getResourceDrift.mockResolvedValue({
|
|
139
|
+
logicalId: 'MyBucket',
|
|
140
|
+
physicalId: 's3-bucket-123',
|
|
141
|
+
resourceType: 'AWS::S3::Bucket',
|
|
142
|
+
driftStatus: 'MODIFIED',
|
|
143
|
+
expectedProperties: { BucketEncryption: { enabled: true } },
|
|
144
|
+
actualProperties: { BucketEncryption: { enabled: false } },
|
|
145
|
+
propertyDifferences: [
|
|
146
|
+
{
|
|
147
|
+
propertyPath: 'BucketEncryption.enabled',
|
|
148
|
+
expectedValue: true,
|
|
149
|
+
actualValue: false,
|
|
150
|
+
differenceType: 'NOT_EQUAL',
|
|
151
|
+
},
|
|
152
|
+
],
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
mockResourceDetector.detectResources.mockResolvedValue([]);
|
|
156
|
+
mockResourceDetector.findOrphanedResources.mockResolvedValue([]);
|
|
157
|
+
|
|
158
|
+
// Act
|
|
159
|
+
// This succeeds because we're using the correct analyze() method
|
|
160
|
+
const report = await useCase.execute({ stackIdentifier });
|
|
161
|
+
|
|
162
|
+
// Assert
|
|
163
|
+
expect(report).toBeDefined();
|
|
164
|
+
expect(report.getDriftedResourceCount()).toBe(1);
|
|
165
|
+
expect(report.resources[0].state.value).toBe('DRIFTED');
|
|
166
|
+
});
|
|
167
|
+
});
|