Skip to content

Commit

Permalink
added UI test
Browse files Browse the repository at this point in the history
  • Loading branch information
BenAlvo1 committed Nov 4, 2024
1 parent cb5a588 commit e18b27b
Show file tree
Hide file tree
Showing 8 changed files with 99 additions and 8 deletions.
1 change: 1 addition & 0 deletions src/main/java/com/checkmarx/intellij/Resource.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ public enum Resource {
ASCA_CHECKBOX,
ASCA_DESCRIPTION,
ASCA_SCAN_WARNING,
ASCA_STARTED_MSG,
VALIDATE_BUTTON,
VALIDATE_IN_PROGRESS,
VALIDATE_SUCCESS,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import com.intellij.codeInspection.*;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.Strings;
import com.intellij.psi.*;
import org.jetbrains.annotations.NotNull;

Expand All @@ -24,6 +23,8 @@
public class AscaInspection extends LocalInspectionTool {
private final GlobalSettingsState settings = GlobalSettingsState.getInstance();
private Map<String, ProblemHighlightType> severityToHighlightMap;
public static String ASCA_INSPECTION_ID = "ASCA";


/**
* Checks the file for ASCA issues.
Expand Down Expand Up @@ -94,13 +95,32 @@ private ProblemDescriptor[] createProblemDescriptors(@NotNull PsiFile file, @Not
*/
private ProblemDescriptor createProblemDescriptor(@NotNull PsiFile file, @NotNull InspectionManager manager, ScanDetail detail, Document document, int lineNumber, boolean isOnTheFly) {
TextRange problemRange = getTextRangeForLine(document, lineNumber);
String description = Strings.join(detail.getRuleName(), " - ", detail.getRemediationAdvise());
String description = formatDescription(detail.getRuleName(), detail.getRemediationAdvise());
ProblemHighlightType highlightType = determineHighlightType(detail);

return manager.createProblemDescriptor(
file, problemRange, description, highlightType, isOnTheFly, new AscaQuickFix(detail));
}

public String formatDescription(String ruleName, String remediationAdvise) {
return String.format(
"<html><b>%s</b> - %s<br><font color='gray'>%s</font></html>",
escapeHtml(ruleName), escapeHtml(remediationAdvise), escapeHtml(ASCA_INSPECTION_ID)
);
}

// Helper method to escape HTML special characters for safety
private String escapeHtml(String text) {
if (text == null) {
return "";
}
return text.replace("&", "&amp;")
.replace("<", "&lt;")
.replace(">", "&gt;")
.replace("\"", "&quot;")
.replace("'", "&#39;");
}

/**
* Gets the text range for a specific line in the document.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.checkmarx.intellij.inspections.quickfixes;

import com.checkmarx.intellij.Constants;
import com.intellij.notification.Notification;
import com.intellij.notification.NotificationGroupManager;
import com.intellij.notification.NotificationType;
Expand All @@ -14,6 +15,8 @@
import java.awt.*;
import java.awt.datatransfer.StringSelection;

import static com.checkmarx.intellij.inspections.AscaInspection.ASCA_INSPECTION_ID;

/**
* Quick fix implementation for ASCA issues.
*/
Expand Down Expand Up @@ -75,12 +78,39 @@ private void showNotification(Project project, String message, NotificationType
final String FIX_PROMPT_COPY_FAIL_MSG = "Fix prompt copied";
ApplicationManager.getApplication().invokeLater(() -> {
Notification notification = NotificationGroupManager.getInstance()
.getNotificationGroup("Checkmarx.Notifications")
.getNotificationGroup(Constants.NOTIFICATION_GROUP_ID)
.createNotification(FIX_PROMPT_COPY_FAIL_MSG, message, type);
notification.notify(project);
});
}

public String stripHtml(String htmlText) {
if (htmlText == null) {
return "";
}
// Remove HTML tags
String plainText = htmlText.replaceAll("<[^>]*>", "");

// Remove "ASCA" suffix, if it exists
if (plainText.endsWith(ASCA_INSPECTION_ID)) {
plainText = plainText.substring(0, plainText.length() - 4).trim(); // Remove "ASCA" and trim any trailing space
}

return unescapeHtml(plainText);
}

private String unescapeHtml(String text) {
if (text == null) {
return "";
}
return text.replace("&amp;", "&")
.replace("&lt;", "<")
.replace("&gt;", ">")
.replace("&quot;", "\"")
.replace("&#39;", "'");
}


/**
* Generates a fix prompt based on the problematic line and description.
*
Expand All @@ -93,7 +123,7 @@ private String generateFixPrompt(String problematicLine, String description) {
"Code snippet with potential issue:\n%s\n\n" +
"Issue description:\n%s\n\n" +
"Provide a fix to make this code safer and more secure.";
return String.format(FIX_PROMPT, problematicLine.trim(), description.trim()
return String.format(FIX_PROMPT, problematicLine.trim(), stripHtml(description.trim())
);
}

Expand Down
1 change: 1 addition & 0 deletions src/main/resources/messages/CxBundle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ VALIDATE_IN_PROGRESS=Validating...
ASCA_DESCRIPTION=Checkmarx AI Secure Coding Assistant (ASCA): Activate ASCA
ASCA_CHECKBOX=Scan your file as you code
ASCA_SCAN_WARNING=ASCA Warning: {0}
ASCA_STARTED_MSG=AI Secure Coding Assistant started.
VALIDATE_SUCCESS=Successfully authenticated to Checkmarx One server
VALIDATE_FAIL=Failed authentication: {0}
VALIDATE_ERROR=Error in authentication
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.checkmarx.ast.asca.ScanResult;
import com.checkmarx.intellij.ASCA.AscaService;
import com.checkmarx.intellij.Constants;
import com.checkmarx.intellij.standard.BaseTest;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.project.Project;
Expand Down Expand Up @@ -68,7 +69,7 @@ public void testRunAscaScan_FileWithNoVulnerabilities_Success() {
public void testRunAscaScan_FileWithoutExtension_Fail() {
PsiFile psiFile = createPsiFileFromPath("src/test/java/com/checkmarx/intellij/standard/data/file");
Project project = ProjectManager.getInstance().getDefaultProject();
ScanResult ascaResult = ascaService.runAscaScan(psiFile, project, true, "Jetbrains");
ScanResult ascaResult = ascaService.runAscaScan(psiFile, project, true, Constants.JET_BRAINS_AGENT_NAME);

assert ascaResult != null;
Assertions.assertNull(ascaResult.getScanDetails());
Expand Down
7 changes: 4 additions & 3 deletions src/test/java/com/checkmarx/intellij/ui/BaseUITest.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import com.intellij.remoterobot.utils.RepeatUtilsKt;
import com.intellij.remoterobot.utils.WaitForConditionTimeoutException;
import org.apache.commons.lang3.StringUtils;
import org.assertj.swing.fixture.JCheckBoxFixture;
import org.intellij.lang.annotations.Language;
import org.jetbrains.annotations.NotNull;
import org.junit.jupiter.api.Assertions;
Expand Down Expand Up @@ -101,7 +102,7 @@ private static void trustClonedProject() {
}
}

private static void setField(String fieldName, String value) {
static void setField(String fieldName, String value) {
log("Setting field " + fieldName);
@Language("XPath") String fieldXpath = String.format(FIELD_NAME, fieldName);
waitFor(() -> hasAnyComponent(fieldXpath) && find(fieldXpath).isShowing());
Expand Down Expand Up @@ -165,7 +166,7 @@ protected static void testASTConnection(boolean validCredentials) {
}
}

private static void openSettings() {
static void openSettings() {
waitFor(() -> {
focusCxWindow();
if (hasAnyComponent(SETTINGS_ACTION)) {
Expand Down Expand Up @@ -279,7 +280,7 @@ && hasAnyComponent(NO_SCAN_SELECTED)
});
}

private static void focusCxWindow() {
static void focusCxWindow() {
boolean cxPluginOpened = find(BASE_LABEL).hasText("Checkmarx");
System.out.println("Plugin opened: " + cxPluginOpened);

Expand Down
34 changes: 34 additions & 0 deletions src/test/java/com/checkmarx/intellij/ui/TestAsca.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.checkmarx.intellij.ui;

import com.checkmarx.intellij.ASCA.AscaService;
import com.checkmarx.intellij.Constants;
import com.checkmarx.intellij.Environment;
import org.junit.jupiter.api.Assertions;

import static com.checkmarx.intellij.ui.utils.RemoteRobotUtils.click;
import static com.checkmarx.intellij.ui.utils.RemoteRobotUtils.hasAnyComponent;
import static com.checkmarx.intellij.ui.utils.Xpath.*;
import static com.checkmarx.intellij.ui.utils.Xpath.CANCEL_SCAN_BTN;

public class TestAsca extends BaseUITest{
public static void testASTAscaWithValidateConnections(boolean validCredentials) {
openSettings();

setField(Constants.FIELD_NAME_API_KEY, validCredentials ? Environment.API_KEY : "invalidAPIKey");
setField(Constants.FIELD_NAME_ADDITIONAL_PARAMETERS, "--debug");


click(VALIDATE_BUTTON);

waitFor(() -> !hasAnyComponent(ASCA_INSTALL_SUCCESS));

Assertions.assertTrue(hasAnyComponent(ASCA_INSTALL_SUCCESS));
click(OK_BTN);
// Ensure that start scan button and cancel scan button are visible with valid credentials
waitFor(() -> {
focusCxWindow();
return hasAnyComponent(START_SCAN_BTN) && hasAnyComponent(CANCEL_SCAN_BTN);
});
}

}
3 changes: 3 additions & 0 deletions src/test/java/com/checkmarx/intellij/ui/utils/Xpath.java
Original file line number Diff line number Diff line change
Expand Up @@ -164,4 +164,7 @@ public class Xpath {
public static final String HAS_SELECTION = "//div[@class='ActionButtonWithText' and starts-with(@visible_text,'%s: ')]";
@Language("XPath")
public static final String SCAN_ID_SELECTION = "//div[@class='ActionButtonWithText' and substring(@visible_text, string-length(@visible_text) - string-length('%s') + 1) = '%s']";
@Language("XPath")
public
static final String ASCA_INSTALL_SUCCESS = "//div[@accessiblename.key='AI Secure Coding Assistant started.']";
}

0 comments on commit e18b27b

Please sign in to comment.