Skip to content

Commit

Permalink
test: add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
teodora-sandu committed Mar 27, 2024
1 parent a394881 commit 197b2e5
Show file tree
Hide file tree
Showing 4 changed files with 170 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,13 @@ abstract class IssueDescriptionPanelBase(
private val details: String?
) : JPanel(BorderLayout()), IssueDescriptionPanel {
private val unexpectedErrorMessage = "Snyk encountered an issue while rendering the vulnerability description. Please try again, or contact support if the problem persists. We apologize for any inconvenience caused.";

/**
* **MUST** be invoked in derived class to actually create the UI elements.
* Can't be part of constructor due to `state` usage in underling abstract/open methods/props:
*/
protected fun createUI() {
if (pluginSettings().isGlobalIgnoresFeatureEnabled) {
if (pluginSettings().isGlobalIgnoresFeatureEnabled && details != null) {
if (!JBCefApp.isSupported()) {
val statePanel = StatePanel(SnykToolWindowPanel.SELECT_ISSUE_TEXT)
this.add(wrapWithScrollPane(statePanel), BorderLayout.CENTER)
Expand All @@ -56,11 +56,6 @@ abstract class IssueDescriptionPanelBase(
BorderLayout.CENTER
)

if (this.details == null) {
SnykBalloonNotificationHelper.showError("Something went wrong.", null)
return
}

jbCefBrowser.loadHTML(this.details, jbCefBrowser.cefBrowser.url)

} else {
Expand Down
2 changes: 1 addition & 1 deletion src/main/kotlin/snyk/common/lsp/Types.kt
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ data class IssueData(
@SerializedName("priorityScore") val priorityScore: Int,
@SerializedName("hasAIFix") val hasAIFix: Boolean,
@SerializedName("dataFlow") val dataFlow: List<DataFlow>,
@SerializedName("details") val details: String,
@SerializedName("details") val details: String?,
) {
override fun equals(other: Any?): Boolean {
if (this === other) return true
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
@file:Suppress("FunctionName")
package io.snyk.plugin.ui.toolwindow

import com.google.gson.Gson
import com.intellij.codeInsight.daemon.DaemonCodeAnalyzerSettings
import com.intellij.openapi.application.Application
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.application.ModalityState
import com.intellij.openapi.application.WriteAction
import com.intellij.openapi.command.undo.UndoManager
import com.intellij.openapi.progress.impl.CoreProgressManager
import com.intellij.openapi.util.registry.Registry
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.openapi.vfs.newvfs.RefreshQueue
import com.intellij.openapi.vfs.pointers.VirtualFilePointerManager
import com.intellij.psi.PsiFile
import com.intellij.psi.codeStyle.CodeStyleSchemes
import com.intellij.psi.impl.DocumentCommitProcessor
import com.intellij.psi.stubs.StubIndex
import com.intellij.testFramework.fixtures.BasePlatformTestCase
import com.intellij.ui.components.ActionLink
import com.intellij.util.indexing.FileBasedIndex
import io.mockk.every
import io.mockk.mockk
import io.mockk.mockkStatic
import io.mockk.unmockkAll
import io.snyk.plugin.DEFAULT_TIMEOUT_FOR_SCAN_WAITING_MS
import io.snyk.plugin.Severity
import io.snyk.plugin.pluginSettings
import io.snyk.plugin.resetSettings
import io.snyk.plugin.services.SnykApplicationSettingsStateService
import io.snyk.plugin.snykcode.core.SnykCodeFile
import io.snyk.plugin.ui.toolwindow.panels.SuggestionDescriptionPanelFromLS
import io.snyk.plugin.ui.toolwindow.panels.VulnerabilityDescriptionPanel
import junit.framework.TestCase.assertEquals
import junit.framework.TestCase.assertNotNull
import org.eclipse.lsp4j.Position
import org.eclipse.lsp4j.Range
import org.junit.Before
import org.junit.Ignore
import org.junit.Test
import snyk.UIComponentFinder.getJBCEFBrowser
import snyk.UIComponentFinder.getJButtonByText
import snyk.UIComponentFinder.getJLabelByText
import snyk.code.annotator.SnykCodeAnnotator
import snyk.common.lsp.CommitChangeLine
import snyk.common.lsp.DataFlow
import snyk.common.lsp.ExampleCommitFix
import snyk.common.lsp.ScanIssue
import snyk.oss.Vulnerability
import java.io.FileReader
import java.nio.file.Paths

class SuggestionDescriptionPanelFromLSTest : BasePlatformTestCase() {
private lateinit var cut: SuggestionDescriptionPanelFromLS
private val fileName = "app.js"
private lateinit var snykCodeFile: SnykCodeFile
private lateinit var issue: ScanIssue

private lateinit var file: VirtualFile
private lateinit var psiFile: PsiFile

override fun getTestDataPath(): String {
val resource = SnykCodeAnnotator::class.java.getResource("/test-fixtures/code/annotator")
requireNotNull(resource) { "Make sure that the resource $resource exists!" }
return Paths.get(resource.toURI()).toString()
}

@Before
override fun setUp() {
super.setUp()
unmockkAll()
resetSettings(project)

file = myFixture.copyFileToProject(fileName)
psiFile = WriteAction.computeAndWait<PsiFile, Throwable> { psiManager.findFile(file)!! }
snykCodeFile = SnykCodeFile(psiFile.project, psiFile.virtualFile)

issue = mockk<ScanIssue>()
every { issue.additionalData.message } returns "Test message"
every { issue.additionalData.isSecurityType } returns true
every { issue.additionalData.cwe } returns null
every { issue.additionalData.repoDatasetSize } returns 1
every { issue.additionalData.exampleCommitFixes } returns listOf(ExampleCommitFix("https://commit-url", listOf(
CommitChangeLine("1", 1, "lineChange")
)))
every { issue.additionalData.dataFlow } returns listOf(DataFlow(0, getTestDataPath(), Range(Position(1, 1), Position(1, 1)), ""))
every { issue.title } returns "Test title"
every { issue.getSeverityAsEnum() } returns Severity.CRITICAL
}

@Test
fun `test createUI should build panel with issue message as overview label if the feature flag is not enabled`() {
every { issue.additionalData.details } returns "<html>HTML message</html>"
every { issue.additionalData.details } returns null
cut = SuggestionDescriptionPanelFromLS(snykCodeFile, issue)

val actual = getJLabelByText(cut, "<html>Test message</html>")
assertNotNull(actual)

val actualBrowser = getJBCEFBrowser(cut)
assertNull(actualBrowser)
}

@Test
fun `test createUI should build panel with issue message as overview label if the details are empty even if feature flag is enabled`() {
pluginSettings().isGlobalIgnoresFeatureEnabled = true

every { issue.additionalData.details } returns null
cut = SuggestionDescriptionPanelFromLS(snykCodeFile, issue)

val actual = getJLabelByText(cut, "<html>Test message</html>")
assertNotNull(actual)

val actualBrowser = getJBCEFBrowser(cut)
assertNull(actualBrowser)
}

@Test
fun `test createUI should show nothing if feature flag is enabled but JCEF is not`() {
pluginSettings().isGlobalIgnoresFeatureEnabled = true

every { issue.additionalData.details } returns "<html>HTML message</html>"
cut = SuggestionDescriptionPanelFromLS(snykCodeFile, issue)

Registry.get("ide.browser.jcef.enabled").setValue("false")

val actual = getJLabelByText(cut, "<html>Test message</html>")
assertNull(actual)

val actualBrowser = getJBCEFBrowser(cut)
assertNull(actualBrowser)
}

@Test
fun `test createUI should build panel with HTML from details if feature flag is enabled`() {
pluginSettings().isGlobalIgnoresFeatureEnabled = true

every { issue.additionalData.details } returns "<html>HTML message</html>"
cut = SuggestionDescriptionPanelFromLS(snykCodeFile, issue)

Registry.get("ide.browser.jcef.enabled").setValue("true")

val actual = getJLabelByText(cut, "<html>Test message</html>")
assertNull(actual)

val actualBrowser = getJBCEFBrowser(cut)
assertNotNull(actualBrowser)
}
}
17 changes: 17 additions & 0 deletions src/test/kotlin/snyk/UIComponentFinder.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package snyk

import com.intellij.ui.jcef.JBCefBrowser
import java.awt.Container
import javax.swing.JButton
import javax.swing.JLabel
Expand Down Expand Up @@ -53,4 +54,20 @@ object UIComponentFinder {
}
return found
}

fun getJBCEFBrowser(parent: Container): JBCefBrowser.MyPanel? {
val components = parent.components
var found: JBCefBrowser.MyPanel? = null
for (component in components) {
if (component is JBCefBrowser.MyPanel) {
found = component
} else if (component is Container) {
found = getJBCEFBrowser(component)
}
if (found != null) {
break
}
}
return found
}
}

0 comments on commit 197b2e5

Please sign in to comment.