Skip to content

Commit a4bc012

Browse files
authored
test: IamPolicyChecks #5570
## Problem IamPolicyChecks currently has no unit tests. This makes the feature fragile to changes and at risk to breaking changes. ## Solution Implement unit tests for IamPolicyChecks feature.
1 parent 762b7b4 commit a4bc012

File tree

2 files changed

+785
-23
lines changed

2 files changed

+785
-23
lines changed

packages/core/src/awsService/accessanalyzer/vue/iamPolicyChecks.ts

Lines changed: 28 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import * as fs from 'fs'
88
import * as path from 'path'
99
import { getLogger, Logger } from '../../../shared/logger'
1010
import { localize } from '../../../shared/utilities/vsCodeUtils'
11-
import { VueWebview } from '../../../webviews/main'
11+
import { VueWebview, VueWebviewPanel } from '../../../webviews/main'
1212
import { ExtContext } from '../../../shared/extensions'
1313
import { telemetry } from '../../../shared/telemetry/telemetry'
1414
import { AccessAnalyzer, SharedIniFileCredentials } from 'aws-sdk'
@@ -31,8 +31,8 @@ import { ExpiredTokenException } from '@aws-sdk/client-sso-oidc'
3131

3232
const defaultTerraformConfigPath = 'resources/policychecks-tf-default.yaml'
3333
// Diagnostics for Custom checks are shared
34-
const customPolicyCheckDiagnosticCollection = vscode.languages.createDiagnosticCollection('customPolicyCheck')
35-
const validatePolicyDiagnosticCollection = vscode.languages.createDiagnosticCollection('validatePolicy')
34+
export const customPolicyCheckDiagnosticCollection = vscode.languages.createDiagnosticCollection('customPolicyCheck')
35+
export const validatePolicyDiagnosticCollection = vscode.languages.createDiagnosticCollection('validatePolicy')
3636

3737
export interface IamPolicyChecksInitialData {
3838
checkNoNewAccessFilePath: string
@@ -56,7 +56,7 @@ export class IamPolicyChecksWebview extends VueWebview {
5656
public static readonly sourcePath: string = 'src/awsService/accessanalyzer/vue/index.js'
5757
public readonly id = 'iamPolicyChecks'
5858
private static editedDocumentUri: vscode.Uri
59-
private static editedDocumentFileName: string
59+
public static editedDocumentFileName: string
6060
private static editedDocument: string
6161

6262
public constructor(
@@ -119,14 +119,18 @@ export class IamPolicyChecksWebview extends VueWebview {
119119
// Send the current active text editor to Webview to show what is being targeted by the user
120120
vscode.window.onDidChangeActiveTextEditor((message: any) => {
121121
const editedFile = vscode.window.activeTextEditor?.document
122-
IamPolicyChecksWebview.editedDocumentFileName = editedFile!.uri.path
123-
IamPolicyChecksWebview.editedDocument = editedFile!.getText()
124-
IamPolicyChecksWebview.editedDocumentUri = editedFile!.uri
125-
this.onChangeInputPath.fire(editedFile!.uri.path)
122+
if (editedFile !== undefined) {
123+
IamPolicyChecksWebview.editedDocumentFileName = editedFile.uri.path
124+
IamPolicyChecksWebview.editedDocument = editedFile.getText()
125+
IamPolicyChecksWebview.editedDocumentUri = editedFile.uri
126+
this.onChangeInputPath.fire(editedFile.uri.path)
127+
}
126128
})
127129
vscode.workspace.onDidChangeTextDocument((message: any) => {
128130
const editedFile = vscode.window.activeTextEditor?.document
129-
IamPolicyChecksWebview.editedDocument = editedFile!.getText()
131+
if (editedFile !== undefined) {
132+
IamPolicyChecksWebview.editedDocument = editedFile.getText()
133+
}
130134
})
131135
}
132136

@@ -715,10 +719,10 @@ export class IamPolicyChecksWebview extends VueWebview {
715719
}
716720

717721
public pushCustomCheckDiagnostic(diagnostics: vscode.Diagnostic[], finding: any, isBlocking: boolean) {
718-
const message = `${finding.findingType}: ${finding.message} - Resource name: ${finding.resourceName}, Policy name: ${finding.policyName}`
719-
if (message.includes('existingPolicyDocument')) {
720-
message.replace('existingPolicyDocument', 'reference document')
721-
}
722+
const findingMessage: string = finding.message.includes('existingPolicyDocument')
723+
? finding.message.replace('existingPolicyDocument', 'reference document')
724+
: finding.message
725+
const message = `${finding.findingType}: ${findingMessage} - Resource name: ${finding.resourceName}, Policy name: ${finding.policyName}`
722726
if (finding.details.reasons) {
723727
finding.details.reasons.forEach((reason: any) => {
724728
diagnostics.push(
@@ -744,7 +748,7 @@ export class IamPolicyChecksWebview extends VueWebview {
744748

745749
const Panel = VueWebview.compilePanel(IamPolicyChecksWebview)
746750

747-
export async function renderIamPolicyChecks(context: ExtContext): Promise<void> {
751+
export async function renderIamPolicyChecks(context: ExtContext): Promise<VueWebviewPanel | undefined> {
748752
const logger: Logger = getLogger()
749753
try {
750754
const client = new AccessAnalyzer({ region: context.regionProvider.defaultRegionId })
@@ -795,13 +799,14 @@ export async function renderIamPolicyChecks(context: ExtContext): Promise<void>
795799
viewColumn: vscode.ViewColumn.Beside,
796800
title: localize('AWS.iamPolicyChecks.title', 'IAM Policy Checks'),
797801
})
802+
return wv
798803
} catch (err) {
799804
logger.error(err as Error)
800805
}
801806
}
802807

803808
// Helper function to get document contents from a path
804-
async function _readCustomChecksFile(input: string): Promise<string> {
809+
export async function _readCustomChecksFile(input: string): Promise<string> {
805810
if (fs.existsSync(input)) {
806811
return fs.readFileSync(input).toString()
807812
} else {
@@ -823,7 +828,7 @@ async function _readCustomChecksFile(input: string): Promise<string> {
823828
}
824829

825830
//Check if Cfn and Tf tools are installed
826-
function arePythonToolsInstalled(): boolean {
831+
export function arePythonToolsInstalled(): boolean {
827832
const logger: Logger = getLogger()
828833
let cfnToolInstalled = true
829834
let tfToolInstalled = true
@@ -846,12 +851,12 @@ function arePythonToolsInstalled(): boolean {
846851
return cfnToolInstalled && tfToolInstalled
847852
}
848853

849-
function isProcessNotFoundErr(errMsg: string) {
854+
export function isProcessNotFoundErr(errMsg: string) {
850855
return errMsg.includes('command not found') || errMsg.includes('ENOENT')
851856
}
852857

853858
// Since TypeScript can only get the CLI tool's error output as a string, we have to parse and sanitize it ourselves
854-
function parseCliErrorMessage(message: string, documentType: PolicyChecksDocumentType): string {
859+
export function parseCliErrorMessage(message: string, documentType: PolicyChecksDocumentType): string {
855860
const cfnMatch = message.match(/ERROR: .*/)
856861
const botoMatch = message.match(/(?<=botocore\.exceptions\.).*/) // Boto errors have a special match
857862
const terraformMatch = message.match(/AttributeError:.*/) // Terraform CLI responds with a different error schema... this catches invalid .json plans
@@ -876,7 +881,7 @@ function parseCliErrorMessage(message: string, documentType: PolicyChecksDocumen
876881
return message
877882
}
878883

879-
function getCheckNoNewAccessErrorMessage(finding: any) {
884+
export function getCheckNoNewAccessErrorMessage(finding: any) {
880885
if (finding.findingType === 'ERROR') {
881886
if (
882887
finding.message.includes(
@@ -888,7 +893,7 @@ function getCheckNoNewAccessErrorMessage(finding: any) {
888893
}
889894
}
890895

891-
function getResultCssColor(resultType: PolicyChecksResult): string {
896+
export function getResultCssColor(resultType: PolicyChecksResult): string {
892897
switch (resultType) {
893898
case 'Success':
894899
return 'var(--vscode-terminal-ansiGreen)'
@@ -899,17 +904,17 @@ function getResultCssColor(resultType: PolicyChecksResult): string {
899904
}
900905
}
901906

902-
function isCloudFormationTemplate(document: string): boolean {
907+
export function isCloudFormationTemplate(document: string): boolean {
903908
const cfnFileTypes = ['.yaml', '.yml', '.json']
904909
return cfnFileTypes.some((t) => document.endsWith(t))
905910
}
906911

907-
function isTerraformPlan(document: string) {
912+
export function isTerraformPlan(document: string) {
908913
const terraformPlanFileTypes = ['.json']
909914
return terraformPlanFileTypes.some((t) => document.endsWith(t))
910915
}
911916

912-
function isJsonPolicyLanguage(document: string) {
917+
export function isJsonPolicyLanguage(document: string) {
913918
const policyLanguageFileTypes = ['.json']
914919
return policyLanguageFileTypes.some((t) => document.endsWith(t))
915920
}

0 commit comments

Comments
 (0)