diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index eb1b47c98..78b33548a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -30,7 +30,7 @@ jobs: - name: Setup Java uses: actions/setup-java@v1 with: - java-version: 1.8 + java-version: 17 - name: Setup Gradle Cache uses: actions/cache@v2 diff --git a/.github/workflows/detekt.yml b/.github/workflows/detekt.yml index 1d82b5641..781c0e887 100644 --- a/.github/workflows/detekt.yml +++ b/.github/workflows/detekt.yml @@ -14,7 +14,7 @@ jobs: - name: Setup Java uses: actions/setup-java@v1 with: - java-version: 1.8 + java-version: 17 - name: Setup Gradle Cache uses: actions/cache@v2 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 430ed7057..2ba62db28 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -28,7 +28,7 @@ jobs: - name: Setup Java uses: actions/setup-java@v1 with: - java-version: 1.8 + java-version: 17 - name: Setup Gradle Cache uses: actions/cache@v2 @@ -44,7 +44,7 @@ jobs: SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} SNYK_ORG_NAME: ${{ secrets.SNYK_ORG_NAME }} run: | - ./gradlew test integTest verifyPlugin clean + ./gradlew test verifyPlugin clean git clean -d --force git reset --hard diff --git a/CHANGELOG.md b/CHANGELOG.md index a7acab370..6703dd556 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Snyk Changelog +## [2.5.0] + +### Changed + +- Fix compatibility issues; only support Jetbrains 2023.x for plugin versions > 2.5.0 + ## [2.4.63] ### Fixed diff --git a/build.gradle.kts b/build.gradle.kts index 0abb212b9..bc6f1baf0 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,6 +1,7 @@ import io.gitlab.arturbosch.detekt.Detekt import org.apache.tools.ant.filters.ReplaceTokens import org.gradle.api.tasks.testing.logging.TestExceptionFormat +import org.jetbrains.changelog.Changelog import org.jetbrains.changelog.markdownToHTML import org.jetbrains.kotlin.gradle.tasks.KotlinCompile @@ -8,10 +9,10 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile fun properties(key: String) = project.findProperty(key).toString() plugins { - id("org.jetbrains.changelog") version "1.2.1" - id("org.jetbrains.intellij") version "1.1.2" - id("org.jetbrains.kotlin.jvm") version "1.8.0" - id("io.gitlab.arturbosch.detekt") version ("1.21.0") + id("org.jetbrains.changelog") version "2.1.2" + id("org.jetbrains.intellij") version "1.15.0" + id("org.jetbrains.kotlin.jvm") version "1.9.0" + id("io.gitlab.arturbosch.detekt") version ("1.23.1") id("pl.allegro.tech.build.axion-release") version "1.13.6" } @@ -20,7 +21,7 @@ version = scmVersion.version group = properties("pluginGroup") description = properties("pluginName") -val jdk = "1.8" +val jdk = "17" repositories { mavenCentral() @@ -28,26 +29,35 @@ repositories { } dependencies { - implementation("org.commonmark:commonmark:0.19.0") - implementation("com.google.code.gson:gson:2.9.0") - implementation("com.segment.analytics.java:analytics:3.3.1") - implementation("io.sentry:sentry:6.4.2") + implementation(platform("com.squareup.okhttp3:okhttp-bom:4.10.0")) + implementation("org.commonmark:commonmark:0.21.0") + implementation("com.google.code.gson:gson:2.10.1") + implementation("com.segment.analytics.java:analytics:3.4.0") + implementation("io.sentry:sentry:6.27.0") + implementation("javax.xml.bind:jaxb-api:2.3.1") // necessary because since JDK 9 not included + implementation("com.squareup.retrofit2:retrofit:2.9.0") + implementation("com.squareup.okhttp3:okhttp") + implementation("com.squareup.okhttp3:logging-interceptor") implementation("ly.iterative.itly:plugin-iteratively:1.2.11") implementation("ly.iterative.itly:plugin-schema-validator:1.2.11") { exclude(group = "org.slf4j") } - implementation("ly.iterative.itly:sdk-jvm:1.2.11") - testImplementation("com.google.jimfs:jimfs:1.2") - testImplementation("com.squareup.okhttp3:mockwebserver:4.10.0") + implementation("ly.iterative.itly:sdk-jvm:1.2.11") { + exclude(group = "org.slf4j") + } + implementation("com.segment.analytics.java:analytics:3.4.0") + + testImplementation("com.google.jimfs:jimfs:1.3.0") + testImplementation("com.squareup.okhttp3:mockwebserver") + testImplementation("junit:junit:4.13.2") { exclude(group = "org.hamcrest") } testImplementation("org.hamcrest:hamcrest:2.2") - testImplementation("io.mockk:mockk:1.12.2") // updating this breaks tests + testImplementation("io.mockk:mockk:1.13.5") testImplementation("org.awaitility:awaitility:4.2.0") - runtimeOnly("org.jetbrains.kotlin:kotlin-reflect:1.4.32") - detektPlugins("io.gitlab.arturbosch.detekt:detekt-formatting:1.21.0") + detektPlugins("io.gitlab.arturbosch.detekt:detekt-formatting:1.23.1") } // configuration for gradle-intellij-plugin plugin. @@ -64,7 +74,7 @@ intellij { // configure for detekt plugin. // read more: https://detekt.github.io/detekt/kotlindsl.html detekt { - config = files("$projectDir/.github/detekt/detekt-config.yml") + config.setFrom("$projectDir/.github/detekt/detekt-config.yml") baseline = file("$projectDir/.github/detekt/detekt-baseline.xml") buildUponDefaultConfig = true } @@ -72,7 +82,7 @@ detekt { tasks { withType { kotlinOptions.jvmTarget = jdk - kotlinOptions.languageVersion = "1.3" + kotlinOptions.languageVersion = "1.9" } withType { @@ -136,7 +146,7 @@ tasks { }.joinToString("\n").run { markdownToHTML(this) } ) - changeNotes.set(provider { changelog.getLatest().toHTML() }) + changeNotes.set(provider { changelog.renderItem(changelog.getLatest(), Changelog.OutputType.HTML) }) } publishPlugin { @@ -160,27 +170,5 @@ tasks { org.jetbrains.intellij.tasks.RunPluginVerifierTask.FailureLevel.INVALID_PLUGIN ) ) - verificationReportsDir.set("$rootDir.path/reports/pluginVerifier") } } - -sourceSets { - create("integTest") { - compileClasspath += sourceSets.main.get().output - runtimeClasspath += sourceSets.main.get().output - } -} -val integTestImplementation: Configuration by configurations.getting { - extendsFrom(configurations.implementation.get(), configurations.testImplementation.get()) -} -configurations["integTestRuntimeOnly"].extendsFrom(configurations.runtimeOnly.get()) - -val integTest = task("integTest") { - description = "Runs the integration tests." - group = "verification" - - testClassesDirs = sourceSets["integTest"].output.classesDirs - classpath = sourceSets["integTest"].runtimeClasspath - shouldRunAfter("test") -} -tasks.check { dependsOn(integTest) } diff --git a/gradle.properties b/gradle.properties index f7b22d631..f97603b53 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,22 +3,18 @@ pluginName=Snyk Security - Code, Open Source, Container, IaC Configurations # for insight into build numbers and IntelliJ Platform versions # see https://plugins.jetbrains.com/docs/intellij/build-number-ranges.html -pluginSinceBuild=202 +pluginSinceBuild=231 pluginUntilBuild=232.* - -platformVersion=2020.2 +platformVersion=2023.1 platformDownloadSources=true # plugin dependencies (comma-separated) # example: platformPlugins = com.intellij.java, org.jetbrains.plugins.yaml # see https://plugins.jetbrains.com/docs/intellij/plugin-dependencies.html -platformPlugins=org.intellij.plugins.hcl:0.7.10,org.jetbrains.plugins.yaml,org.jetbrains.kotlin,com.intellij.java,org.intellij.groovy - +platformPlugins=org.intellij.plugins.hcl:231.8109.91,org.jetbrains.plugins.yaml,org.jetbrains.kotlin,com.intellij.java,org.intellij.groovy # list of versions for which to check the plugin for api compatibility -pluginVerifierIdeVersions=2020.3.1,2021.1.1,2021.3,2022.1 - +pluginVerifierIdeVersions=2023.1,2023.2 localIdeDirectory= - # opt-out flag for bundling Kotlin standard library # see https://plugins.jetbrains.com/docs/intellij/kotlin.html#kotlin-standard-library kotlin.stdlib.default.dependency=false diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 62d4c0535..943f0cbfa 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 070cb702f..17a8ddce2 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.2.1-bin.zip +networkTimeout=10000 zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index fbd7c5158..65dcd68d6 100755 --- a/gradlew +++ b/gradlew @@ -1,7 +1,7 @@ -#!/usr/bin/env sh +#!/bin/sh # -# Copyright 2015 the original author or authors. +# Copyright © 2015-2021 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,67 +17,101 @@ # ############################################################################## -## -## Gradle start up script for UN*X -## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# ############################################################################## # Attempt to set APP_HOME + # Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" +MAX_FD=maximum warn () { echo "$*" -} +} >&2 die () { echo echo "$*" echo exit 1 -} +} >&2 # OS specific support (must be 'true' or 'false'). cygwin=false msys=false darwin=false nonstop=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; - NONSTOP* ) - nonstop=true - ;; +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; esac CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar @@ -87,9 +121,9 @@ CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" + JAVACMD=$JAVA_HOME/jre/sh/java else - JAVACMD="$JAVA_HOME/bin/java" + JAVACMD=$JAVA_HOME/bin/java fi if [ ! -x "$JAVACMD" ] ; then die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME @@ -98,7 +132,7 @@ Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi else - JAVACMD="java" + JAVACMD=java which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the @@ -106,80 +140,105 @@ location of your Java installation." fi # Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac fi -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. # For Cygwin or MSYS, switch paths to Windows format before running java -if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) fi - i=`expr $i + 1` + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg done - case $i in - 0) set -- ;; - 1) set -- "$args0" ;; - 2) set -- "$args0" "$args1" ;; - 3) set -- "$args0" "$args1" "$args2" ;; - 4) set -- "$args0" "$args1" "$args2" "$args3" ;; - 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac fi -# Escape application args -save () { - for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done - echo " " -} -APP_ARGS=`save "$@"` +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# -# Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat index a9f778a7a..6689b85be 100755 --- a/gradlew.bat +++ b/gradlew.bat @@ -14,7 +14,7 @@ @rem limitations under the License. @rem -@if "%DEBUG%" == "" @echo off +@if "%DEBUG%"=="" @echo off @rem ########################################################################## @rem @rem Gradle startup script for Windows @@ -25,7 +25,8 @@ if "%OS%"=="Windows_NT" setlocal set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @@ -40,7 +41,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init +if %ERRORLEVEL% equ 0 goto execute echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. @@ -54,7 +55,7 @@ goto fail set JAVA_HOME=%JAVA_HOME:"=% set JAVA_EXE=%JAVA_HOME%/bin/java.exe -if exist "%JAVA_EXE%" goto init +if exist "%JAVA_EXE%" goto execute echo. echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% @@ -64,21 +65,6 @@ echo location of your Java installation. goto fail -:init -@rem Get command-line arguments, handling Windows variants - -if not "%OS%" == "Windows_NT" goto win9xME_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* - :execute @rem Setup the command line @@ -86,17 +72,19 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* :end @rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd +if %ERRORLEVEL% equ 0 goto mainEnd :fail rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% :mainEnd if "%OS%"=="Windows_NT" endlocal diff --git a/settings.gradle.kts b/settings.gradle.kts index bda28a4ff..8ef6ba01e 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1 +1,7 @@ rootProject.name = "snyk-intellij-plugin" +pluginManagement { + repositories { + maven("https://oss.sonatype.org/content/repositories/snapshots/") + gradlePluginPortal() + } +} diff --git a/src/integTest/kotlin/io/snyk/plugin/TestUtils.kt b/src/integTest/kotlin/io/snyk/plugin/TestUtils.kt deleted file mode 100644 index 89be37cc2..000000000 --- a/src/integTest/kotlin/io/snyk/plugin/TestUtils.kt +++ /dev/null @@ -1,54 +0,0 @@ -package io.snyk.plugin - -import com.intellij.openapi.application.ApplicationManager -import com.intellij.openapi.project.Project -import com.intellij.testFramework.replaceService -import com.intellij.util.io.RequestBuilder -import io.mockk.every -import io.mockk.justRun -import io.mockk.mockk -import io.mockk.mockkObject -import io.snyk.plugin.services.SnykApplicationSettingsStateService -import io.snyk.plugin.services.SnykProjectSettingsStateService -import io.snyk.plugin.services.download.CliDownloader -import io.snyk.plugin.services.download.HttpRequestHelper - -fun setupDummyCliFile() { - val cliFile = getCliFile() - - if (!cliFile.exists()) { - if (!cliFile.parentFile.exists()) cliFile.mkdirs() - cliFile.createNewFile() - } -} - -fun removeDummyCliFile() { - val cliFile = getCliFile() - if (cliFile.exists()) { - cliFile.delete() - } -} - -fun resetSettings(project: Project?) { - val application = ApplicationManager.getApplication() - application.replaceService( - SnykApplicationSettingsStateService::class.java, - SnykApplicationSettingsStateService(), - application - ) - project?.replaceService( - SnykProjectSettingsStateService::class.java, - SnykProjectSettingsStateService(), - project - ) -} - -/** low level avoiding download the CLI file */ -fun mockCliDownload(): RequestBuilder { - val requestBuilderMockk = mockk(relaxed = true) - justRun { requestBuilderMockk.saveToFile(any(), any()) } - mockkObject(HttpRequestHelper) - every { HttpRequestHelper.createRequest(CliDownloader.LATEST_RELEASE_DOWNLOAD_URL) } returns requestBuilderMockk - every { HttpRequestHelper.createRequest(CliDownloader.LATEST_RELEASES_URL) } returns requestBuilderMockk - return requestBuilderMockk -} diff --git a/src/main/kotlin/icons/SnykIcons.kt b/src/main/kotlin/icons/SnykIcons.kt index c8c1e70eb..44a1efd01 100644 --- a/src/main/kotlin/icons/SnykIcons.kt +++ b/src/main/kotlin/icons/SnykIcons.kt @@ -9,55 +9,56 @@ object SnykIcons { private fun getIconFromResources(name: String): ImageIcon = ImageIcon(this::class.java.getResource(name)) @JvmField - val TOOL_WINDOW = getIcon("/icons/snyk-dog.svg") + val TOOL_WINDOW = getIcon("/icons/snyk-dog.svg", SnykIcons::class.java) - val LOGO = getIcon("/icons/logo_snyk.png") + val LOGO = getIcon("/icons/logo_snyk.png", SnykIcons::class.java) - val VULNERABILITY_16 = getIconFromResources("/icons/vulnerability_16.png") - val VULNERABILITY_24 = getIconFromResources("/icons/vulnerability.png") + private val VULNERABILITY_16 = getIconFromResources("/icons/vulnerability_16.png") + private val VULNERABILITY_24 = getIconFromResources("/icons/vulnerability.png") - val OPEN_SOURCE_SECURITY = getIcon("/icons/oss.svg") - val OPEN_SOURCE_SECURITY_DISABLED = getIcon("/icons/oss_disabled.svg") - val SNYK_CODE = getIcon("/icons/code.svg") - val SNYK_CODE_DISABLED = getIcon("/icons/code_disabled.svg") - val IAC = getIcon("/icons/iac.svg") - val IAC_DISABLED = getIcon("/icons/iac_disabled.svg") + val OPEN_SOURCE_SECURITY = getIcon("/icons/oss.svg", SnykIcons::class.java) + val OPEN_SOURCE_SECURITY_DISABLED = getIcon("/icons/oss_disabled.svg", SnykIcons::class.java) + val SNYK_CODE = getIcon("/icons/code.svg", SnykIcons::class.java) + val SNYK_CODE_DISABLED = getIcon("/icons/code_disabled.svg", SnykIcons::class.java) + val IAC = getIcon("/icons/iac.svg", SnykIcons::class.java) + val IAC_DISABLED = getIcon("/icons/iac_disabled.svg", SnykIcons::class.java) val CONTAINER = getIcon("/icons/container.svg", SnykIcons::class.java) val CONTAINER_DISABLED = getIcon("/icons/container_disabled.svg", SnykIcons::class.java) + val CONTAINER_IMAGE = getIcon("/icons/container_image.svg", SnykIcons::class.java) val CONTAINER_IMAGE_24 = getIcon("/icons/container_image_24.svg", SnykIcons::class.java) - val GRADLE = getIcon("/icons/gradle.svg") - val MAVEN = getIcon("/icons/maven.svg") - val NPM = getIcon("/icons/npm.svg") - val PYTHON = getIcon("/icons/python.svg") - val RUBY_GEMS = getIcon("/icons/rubygems.svg") - val YARN = getIcon("/icons/yarn.svg") - val SBT = getIcon("/icons/sbt.svg") - val GOlANG_DEP = getIcon("/icons/golangdep.svg") - val GO_VENDOR = getIcon("/icons/govendor.svg") - val GOLANG = getIcon("/icons/golang.svg") - val NUGET = getIcon("/icons/nuget.svg") - val PAKET = getIcon("/icons/paket.svg") - val COMPOSER = getIcon("/icons/composer.svg") - val LINUX = getIcon("/icons/linux.svg") - val DEB = getIcon("/icons/deb.svg") - val APK = getIcon("/icons/apk.svg") - val COCOAPODS = getIcon("/icons/cocoapods.svg") - val RPM = getIcon("/icons/rpm.svg") - val DOCKER = getIcon("/icons/docker.svg") + val GRADLE = getIcon("/icons/gradle.svg", SnykIcons::class.java) + val MAVEN = getIcon("/icons/maven.svg", SnykIcons::class.java) + val NPM = getIcon("/icons/npm.svg", SnykIcons::class.java) + val PYTHON = getIcon("/icons/python.svg", SnykIcons::class.java) + val RUBY_GEMS = getIcon("/icons/rubygems.svg", SnykIcons::class.java) + val YARN = getIcon("/icons/yarn.svg", SnykIcons::class.java) + val SBT = getIcon("/icons/sbt.svg", SnykIcons::class.java) + val GOlANG_DEP = getIcon("/icons/golangdep.svg", SnykIcons::class.java) + val GO_VENDOR = getIcon("/icons/govendor.svg", SnykIcons::class.java) + val GOLANG = getIcon("/icons/golang.svg", SnykIcons::class.java) + val NUGET = getIcon("/icons/nuget.svg", SnykIcons::class.java) + val PAKET = getIcon("/icons/paket.svg", SnykIcons::class.java) + val COMPOSER = getIcon("/icons/composer.svg", SnykIcons::class.java) + val LINUX = getIcon("/icons/linux.svg", SnykIcons::class.java) + val DEB = getIcon("/icons/deb.svg", SnykIcons::class.java) + val APK = getIcon("/icons/apk.svg", SnykIcons::class.java) + val COCOAPODS = getIcon("/icons/cocoapods.svg", SnykIcons::class.java) + val RPM = getIcon("/icons/rpm.svg", SnykIcons::class.java) + val DOCKER = getIcon("/icons/docker.svg", SnykIcons::class.java) // copy of FeaturesTrainerIcons.Img.GreenCheckmark from https://jetbrains.github.io/ui/resources/icons_list/ - val CHECKMARK_GREEN = getIcon("/icons/greenCheckmark.svg") + val CHECKMARK_GREEN = getIcon("/icons/greenCheckmark.svg", SnykIcons::class.java) - private val CRITICAL_SEVERITY_16 = getIcon("/icons/severity_critical_16.svg") - private val CRITICAL_SEVERITY_32 = getIcon("/icons/severity_critical_32.svg") - private val HIGH_SEVERITY_16 = getIcon("/icons/severity_high_16.svg") - private val HIGH_SEVERITY_32 = getIcon("/icons/severity_high_32.svg") - private val LOW_SEVERITY_16 = getIcon("/icons/severity_low_16.svg") - private val LOW_SEVERITY_32 = getIcon("/icons/severity_low_32.svg") - private val MEDIUM_SEVERITY_16 = getIcon("/icons/severity_medium_16.svg") - private val MEDIUM_SEVERITY_32 = getIcon("/icons/severity_medium_32.svg") + private val CRITICAL_SEVERITY_16 = getIcon("/icons/severity_critical_16.svg", SnykIcons::class.java) + private val CRITICAL_SEVERITY_32 = getIcon("/icons/severity_critical_32.svg", SnykIcons::class.java) + private val HIGH_SEVERITY_16 = getIcon("/icons/severity_high_16.svg", SnykIcons::class.java) + private val HIGH_SEVERITY_32 = getIcon("/icons/severity_high_32.svg", SnykIcons::class.java) + private val LOW_SEVERITY_16 = getIcon("/icons/severity_low_16.svg", SnykIcons::class.java) + private val LOW_SEVERITY_32 = getIcon("/icons/severity_low_32.svg", SnykIcons::class.java) + private val MEDIUM_SEVERITY_16 = getIcon("/icons/severity_medium_16.svg", SnykIcons::class.java) + private val MEDIUM_SEVERITY_32 = getIcon("/icons/severity_medium_32.svg", SnykIcons::class.java) fun getSeverityIcon(severity: Severity, iconSize: IconSize = IconSize.SIZE16): Icon { return when (severity) { @@ -65,6 +66,7 @@ object SnykIcons { IconSize.SIZE16 -> CRITICAL_SEVERITY_16 IconSize.SIZE32 -> CRITICAL_SEVERITY_32 } + Severity.HIGH -> when (iconSize) { IconSize.SIZE16 -> HIGH_SEVERITY_16 IconSize.SIZE32 -> HIGH_SEVERITY_32 diff --git a/src/main/kotlin/io/snyk/plugin/Severity.kt b/src/main/kotlin/io/snyk/plugin/Severity.kt index c4d48f98b..88a4f0e16 100644 --- a/src/main/kotlin/io/snyk/plugin/Severity.kt +++ b/src/main/kotlin/io/snyk/plugin/Severity.kt @@ -15,7 +15,7 @@ enum class Severity { HIGH, CRITICAL; - override fun toString(): String = super.toString().toLowerCase() + override fun toString(): String = super.toString().lowercase() fun toPresentableString(): String = when (this) { diff --git a/src/main/kotlin/io/snyk/plugin/SnykPostStartupActivity.kt b/src/main/kotlin/io/snyk/plugin/SnykPostStartupActivity.kt index 777bc8275..db9098267 100644 --- a/src/main/kotlin/io/snyk/plugin/SnykPostStartupActivity.kt +++ b/src/main/kotlin/io/snyk/plugin/SnykPostStartupActivity.kt @@ -7,7 +7,7 @@ import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.diagnostic.logger import com.intellij.openapi.project.Project import com.intellij.openapi.project.ProjectManager -import com.intellij.openapi.startup.StartupActivity +import com.intellij.openapi.startup.ProjectActivity import com.intellij.openapi.vfs.VirtualFileManager import io.snyk.plugin.snykcode.SnykCodeBulkFileListener import io.snyk.plugin.snykcode.core.AnalysisData @@ -27,12 +27,12 @@ import java.util.Date private val LOG = logger() -class SnykPostStartupActivity : StartupActivity.DumbAware { +class SnykPostStartupActivity : ProjectActivity { private var listenersActivated = false val settings = pluginSettings() - override fun runActivity(project: Project) { + override suspend fun execute(project: Project) { PluginInstaller.addStateListener(UninstallListener()) // clean up left-overs in case project wasn't properly closed before diff --git a/src/main/kotlin/io/snyk/plugin/Utils.kt b/src/main/kotlin/io/snyk/plugin/Utils.kt index df7e45932..b6ca4031e 100644 --- a/src/main/kotlin/io/snyk/plugin/Utils.kt +++ b/src/main/kotlin/io/snyk/plugin/Utils.kt @@ -53,6 +53,7 @@ import snyk.oss.OssService import snyk.oss.OssTextRangeFinder import snyk.whoami.WhoamiService import java.io.File +import java.net.URI import java.net.URL import java.nio.file.Path import java.security.KeyStore @@ -136,7 +137,7 @@ private inline fun getApplicationService(): T { ?: throw RuntimeException("Cannot find service ${serviceClass.name} (classloader=${serviceClass.classLoader})") } -fun getSyncPublisher(project: Project, topic: Topic): L? { +fun getSyncPublisher(project: Project, topic: Topic): L? { val messageBus = project.messageBus if (messageBus.isDisposed) return null return messageBus.syncPublisher(topic) @@ -152,8 +153,8 @@ fun isUrlValid(url: String?): Boolean { url.isNullOrEmpty() && return true return try { - val uri = URL(url).toURI() - return uri.isSnykTenant() + val uri = url?.let { URI.create(it) } + return uri?.isSnykTenant() ?: false } catch (throwable: Throwable) { false } @@ -291,10 +292,9 @@ fun navigateToSource( selectionEndOffset: Int? = null ) { if (!virtualFile.isValid) return - val psiFile = RunUtils.computeInReadActionInSmartMode( - project, - Computable { PsiManager.getInstance(project).findFile(virtualFile) } - ) ?: return + val psiFile = RunUtils.computeInReadActionInSmartMode(project) { + PsiManager.getInstance(project).findFile(virtualFile) + } ?: return val textLength = psiFile.textLength if (selectionStartOffset in (0 until textLength)) { // jump to Source diff --git a/src/main/kotlin/io/snyk/plugin/cli/Platform.kt b/src/main/kotlin/io/snyk/plugin/cli/Platform.kt index 9778389ee..3f2aec301 100644 --- a/src/main/kotlin/io/snyk/plugin/cli/Platform.kt +++ b/src/main/kotlin/io/snyk/plugin/cli/Platform.kt @@ -2,7 +2,6 @@ package io.snyk.plugin.cli import java.io.IOException import java.nio.file.Paths -import java.util.Locale import java.util.Properties class Platform(val snykWrapperFileName: String) { @@ -18,7 +17,7 @@ class Platform(val snykWrapperFileName: String) { @Suppress("MoveVariableDeclarationIntoWhen") @Throws(PlatformDetectionException::class) fun detect(systemProperties: Properties): Platform { - val architectureName = (systemProperties["os.name"] as String).toLowerCase(Locale.ENGLISH) + val architectureName = (systemProperties["os.name"] as String).lowercase() return when (architectureName) { "linux" -> if (Paths.get("/etc/alpine-release").toFile().exists()) LINUX_ALPINE else LINUX "mac os x", "darwin", "osx" -> MAC_OS diff --git a/src/main/kotlin/io/snyk/plugin/net/SnykApiClient.kt b/src/main/kotlin/io/snyk/plugin/net/SnykApiClient.kt index c88bfeb0b..f8d268268 100644 --- a/src/main/kotlin/io/snyk/plugin/net/SnykApiClient.kt +++ b/src/main/kotlin/io/snyk/plugin/net/SnykApiClient.kt @@ -25,18 +25,18 @@ class SnykApiClient( private fun executeRequest(apiName: String, retrofitCall: Call, retryCounter: Int = 2): T? { if (retryCounter < 0) return null - try { + return try { log.debug("Executing request to $apiName") val response = retrofitCall.execute() if (!response.isSuccessful) { log.warn("Failed to execute `$apiName` call: ${response.errorBody()?.string()}") - return executeRequest(apiName, retrofitCall.clone(), retryCounter - 1) + executeRequest(apiName, retrofitCall.clone(), retryCounter - 1) } else { - return response.body() + response.body() } } catch (t: Throwable) { log.warn("Failed to execute '$apiName' network request: ${t.message}", t) - return executeRequest(apiName, retrofitCall.clone(), retryCounter - 1) + executeRequest(apiName, retrofitCall.clone(), retryCounter - 1) } } diff --git a/src/main/kotlin/io/snyk/plugin/services/SnykAnalyticsService.kt b/src/main/kotlin/io/snyk/plugin/services/SnykAnalyticsService.kt index bc4ff7fff..f51a1482a 100644 --- a/src/main/kotlin/io/snyk/plugin/services/SnykAnalyticsService.kt +++ b/src/main/kotlin/io/snyk/plugin/services/SnykAnalyticsService.kt @@ -17,7 +17,6 @@ import snyk.analytics.HealthScoreIsClicked import snyk.analytics.IssueInTreeIsClicked import snyk.analytics.PluginIsInstalled import snyk.analytics.PluginIsUninstalled -import snyk.analytics.ProductSelectionIsViewed import snyk.analytics.QuickFixIsDisplayed import snyk.analytics.QuickFixIsTriggered import snyk.analytics.WelcomeIsViewed @@ -36,7 +35,7 @@ class SnykAnalyticsService : Disposable { private var userId = "" init { - userId = obtainUserId(settings.token) + if (settings.usageAnalyticsEnabled) userId = obtainUserId(settings.token) } fun initAnalyticsReporter(project: Project) = project.messageBus.connect().subscribe( @@ -146,6 +145,9 @@ class SnykAnalyticsService : Disposable { } fun obtainUserId(token: String?): String { + if (!settings.usageAnalyticsEnabled) { + return "" + } if (token.isNullOrBlank()) { log.warn("Token is null or empty, user public id will not be obtained.") return "" @@ -176,16 +178,6 @@ class SnykAnalyticsService : Disposable { } } - fun logProductSelectionIsViewed(event: ProductSelectionIsViewed) { - if (!settings.usageAnalyticsEnabled || userId.isBlank()) { - return - } - - catchAll(log, "productSelectionIsViewed") { - itly.logProductSelectionIsViewed(userId, event) - } - } - fun logAnalysisIsTriggered(event: AnalysisIsTriggered) { if (!settings.usageAnalyticsEnabled || userId.isBlank()) { return diff --git a/src/main/kotlin/io/snyk/plugin/services/SnykTaskQueueService.kt b/src/main/kotlin/io/snyk/plugin/services/SnykTaskQueueService.kt index a3a0968a6..e6c84499c 100644 --- a/src/main/kotlin/io/snyk/plugin/services/SnykTaskQueueService.kt +++ b/src/main/kotlin/io/snyk/plugin/services/SnykTaskQueueService.kt @@ -76,7 +76,7 @@ class SnykTaskQueueService(val project: Project) { taskQueue.run(object : Task.Backgroundable(project, "Snyk wait for changed files to be saved on disk", true) { override fun run(indicator: ProgressIndicator) { project.basePath?.let { - if (!confirmScanningAndSetWorkspaceTrustedStateIfNeeded(Paths.get(it))) return + if (!confirmScanningAndSetWorkspaceTrustedStateIfNeeded(project, Paths.get(it))) return } ApplicationManager.getApplication().invokeAndWait { diff --git a/src/main/kotlin/io/snyk/plugin/services/download/CliDownloader.kt b/src/main/kotlin/io/snyk/plugin/services/download/CliDownloader.kt index 9cd0e68d5..962ba5e50 100644 --- a/src/main/kotlin/io/snyk/plugin/services/download/CliDownloader.kt +++ b/src/main/kotlin/io/snyk/plugin/services/download/CliDownloader.kt @@ -8,6 +8,7 @@ import java.nio.file.AtomicMoveNotSupportedException import java.nio.file.Files import java.nio.file.StandardCopyOption import java.security.MessageDigest +import java.util.Locale import javax.xml.bind.DatatypeConverter class CliDownloader { @@ -21,13 +22,13 @@ class CliDownloader { fun calculateSha256(bytes: ByteArray): String { return DatatypeConverter.printHexBinary( MessageDigest.getInstance("SHA-256").digest(bytes) - ).toLowerCase() + ).lowercase(Locale.getDefault()) } @Throws(ChecksumVerificationException::class) fun verifyChecksum(expectedSha: String, bytes: ByteArray) { val sha256 = calculateSha256(bytes) - if (sha256.toLowerCase() != expectedSha.toLowerCase()) { + if (sha256.lowercase(Locale.getDefault()) != expectedSha.lowercase(Locale.getDefault())) { throw ChecksumVerificationException("Expected $expectedSha, but downloaded file has $sha256") } } diff --git a/src/main/kotlin/io/snyk/plugin/settings/SnykProjectSettingsConfigurable.kt b/src/main/kotlin/io/snyk/plugin/settings/SnykProjectSettingsConfigurable.kt index 41d78da45..a6c1bac0e 100644 --- a/src/main/kotlin/io/snyk/plugin/settings/SnykProjectSettingsConfigurable.kt +++ b/src/main/kotlin/io/snyk/plugin/settings/SnykProjectSettingsConfigurable.kt @@ -101,11 +101,13 @@ class SnykProjectSettingsConfigurable(val project: Project) : SearchableConfigur getSyncPublisher(project, SnykProductsOrSeverityListener.SNYK_ENABLEMENT_TOPIC)?.enablementChanged() } - runBackgroundableTask("Identifying with Analytics service", project, true) { - val analytics = getSnykAnalyticsService() - val userId = analytics.obtainUserId(snykSettingsDialog.getToken()) - analytics.setUserId(userId) - getAmplitudeExperimentService().fetch(ExperimentUser(userId)) + if (pluginSettings().usageAnalyticsEnabled) { + runBackgroundableTask("Identifying with Analytics service", project, true) { + val analytics = getSnykAnalyticsService() + val userId = analytics.obtainUserId(snykSettingsDialog.getToken()) + analytics.setUserId(userId) + getAmplitudeExperimentService().fetch(ExperimentUser(userId)) + } } } diff --git a/src/main/kotlin/io/snyk/plugin/snykcode/SnykCodeResults.kt b/src/main/kotlin/io/snyk/plugin/snykcode/SnykCodeResults.kt index 465460737..fc9734164 100644 --- a/src/main/kotlin/io/snyk/plugin/snykcode/SnykCodeResults.kt +++ b/src/main/kotlin/io/snyk/plugin/snykcode/SnykCodeResults.kt @@ -11,15 +11,15 @@ class SnykCodeResults( private val files: Set by lazy { file2suggestions.keys } - val totalCount: Int by lazy { files.sumBy { getCount(it, null) } } + val totalCount: Int by lazy { files.sumOf { getCount(it, null) } } - val totalCriticalCount: Int by lazy { files.sumBy { criticalCount(it) } } + val totalCriticalCount: Int by lazy { files.sumOf { criticalCount(it) } } - val totalErrorsCount: Int by lazy { files.sumBy { errorsCount(it) } } + val totalErrorsCount: Int by lazy { files.sumOf { errorsCount(it) } } - val totalWarnsCount: Int by lazy { files.sumBy { warnsCount(it) } } + val totalWarnsCount: Int by lazy { files.sumOf { warnsCount(it) } } - val totalInfosCount: Int by lazy { files.sumBy { infosCount(it) } } + val totalInfosCount: Int by lazy { files.sumOf { infosCount(it) } } fun cloneFiltered(filter: (SuggestionForFile) -> Boolean): SnykCodeResults { return SnykCodeResults( @@ -65,7 +65,7 @@ class SnykCodeResults( private fun getCount(file: SnykCodeFile, severity: Severity?) = suggestions(file) .filter { severity == null || it.getSeverityAsEnum() == severity } - .sumBy { it.ranges.size } + .sumOf { it.ranges.size } override fun equals(other: Any?): Boolean { return other is SnykCodeResults && diff --git a/src/main/kotlin/io/snyk/plugin/ui/SnykBalloonNotificationHelper.kt b/src/main/kotlin/io/snyk/plugin/ui/SnykBalloonNotificationHelper.kt index 2bef11f9a..cb2501d29 100644 --- a/src/main/kotlin/io/snyk/plugin/ui/SnykBalloonNotificationHelper.kt +++ b/src/main/kotlin/io/snyk/plugin/ui/SnykBalloonNotificationHelper.kt @@ -2,8 +2,6 @@ package io.snyk.plugin.ui import com.intellij.icons.AllIcons import com.intellij.notification.Notification -import com.intellij.notification.NotificationDisplayType -import com.intellij.notification.NotificationGroup import com.intellij.notification.NotificationType import com.intellij.openapi.actionSystem.AnAction import com.intellij.openapi.actionSystem.AnActionEvent @@ -14,7 +12,9 @@ import com.intellij.openapi.project.ProjectManager import com.intellij.openapi.ui.MessageType import com.intellij.openapi.ui.popup.Balloon import com.intellij.openapi.ui.popup.JBPopupFactory +import com.intellij.openapi.updateSettings.impl.pluginsAdvertisement.notificationGroup import com.intellij.ui.awt.RelativePoint +import icons.SnykIcons import java.awt.Color import java.awt.Component import java.awt.Point @@ -24,9 +24,7 @@ object SnykBalloonNotificationHelper { private val logger = logger() const val title = "Snyk" - private const val groupNeedAction = "SnykNeedAction" private const val groupAutoHide = "SnykAutoHide" - val GROUP = NotificationGroup(groupNeedAction, NotificationDisplayType.STICKY_BALLOON) fun showError(message: String, project: Project?, vararg actions: AnAction) { showNotification(message, project, NotificationType.ERROR, *actions) @@ -52,10 +50,12 @@ object SnykBalloonNotificationHelper { val notification = if (actions.isEmpty()) { Notification(groupAutoHide, title, message, type) } else { - GROUP.createNotification(title, message, type).apply { + notificationGroup.createNotification(title, message, type).apply { actions.forEach { this.addAction(it) } } } + + notification.setIcon(SnykIcons.TOOL_WINDOW) // workaround for https://youtrack.jetbrains.com/issue/IDEA-220408/notifications-with-project=null-is-not-shown-anymore if (project != null) { notification.notify(project) diff --git a/src/main/kotlin/io/snyk/plugin/ui/SnykBalloonNotifications.kt b/src/main/kotlin/io/snyk/plugin/ui/SnykBalloonNotifications.kt index a34da9e7a..c3a61cbed 100644 --- a/src/main/kotlin/io/snyk/plugin/ui/SnykBalloonNotifications.kt +++ b/src/main/kotlin/io/snyk/plugin/ui/SnykBalloonNotifications.kt @@ -3,6 +3,7 @@ package io.snyk.plugin.ui import com.intellij.ide.BrowserUtil import com.intellij.notification.Notification import com.intellij.notification.NotificationAction +import com.intellij.notification.NotificationGroupManager import com.intellij.notification.NotificationType import com.intellij.openapi.diagnostic.logger import com.intellij.openapi.options.ShowSettingsUtil @@ -16,7 +17,6 @@ import io.snyk.plugin.pluginSettings import io.snyk.plugin.settings.SnykProjectSettingsConfigurable import io.snyk.plugin.snykToolWindow import io.snyk.plugin.startSastEnablementCheckLoop -import io.snyk.plugin.ui.SnykBalloonNotificationHelper.GROUP import snyk.common.toSnykCodeSettingsUrl import java.awt.event.MouseEvent @@ -30,14 +30,16 @@ object SnykBalloonNotifications { const val sastForOrgEnablementMessage = "Snyk Code is disabled by your organisation's configuration." const val networkErrorAlertMessage = "Not able to connect to Snyk server." + private val notificationGroup = NotificationGroupManager.getInstance().getNotificationGroup("Snyk") + fun showWelcomeNotification(project: Project) { val welcomeMessage = "Welcome to Snyk! Check out our tool window to start analyzing your code" logger.info(welcomeMessage) - val notification = GROUP.createNotification( + val notification = notificationGroup.createNotification( welcomeMessage, NotificationType.INFORMATION ).addAction( - NotificationAction.createSimpleExpiring("Configure Snyk\u2026") { + NotificationAction.createSimpleExpiring("CONFIGURE SNYK\u2026") { snykToolWindow(project)?.show() } ) @@ -48,7 +50,7 @@ object SnykBalloonNotifications { return SnykBalloonNotificationHelper.showInfo( sastForLocalCodeEngineMessage, project, - NotificationAction.createSimpleExpiring("Snyk Settings") { + NotificationAction.createSimpleExpiring("SNYK SETTINGS") { ShowSettingsUtil.getInstance() .showSettingsDialog(project, SnykProjectSettingsConfigurable::class.java) } @@ -59,9 +61,9 @@ object SnykBalloonNotifications { val notification = SnykBalloonNotificationHelper.showInfo( "$sastForOrgEnablementMessage To enable navigate to ", project, - NotificationAction.createSimpleExpiring("Snyk > Settings > Snyk Code") { + NotificationAction.createSimpleExpiring("SNYK > SETTINGS > SNYK CODE") { BrowserUtil.browse(toSnykCodeSettingsUrl(pluginSettings().customEndpointUrl)) - startSastEnablementCheckLoop(project) + startSastEnablementCheckLoop(parentDisposable = project) } ) var currentAttempt = 1 @@ -95,7 +97,7 @@ object SnykBalloonNotifications { fun showNetworkErrorAlert(project: Project) = SnykBalloonNotificationHelper.showError( "$networkErrorAlertMessage Check connection and network settings.", project, - NotificationAction.createSimpleExpiring("Snyk Settings") { + NotificationAction.createSimpleExpiring("SNYK SETTINGS") { ShowSettingsUtil.getInstance() .showSettingsDialog(project, SnykProjectSettingsConfigurable::class.java) } diff --git a/src/main/kotlin/io/snyk/plugin/ui/UIUtils.kt b/src/main/kotlin/io/snyk/plugin/ui/UIUtils.kt index 1369af5c3..7be40954d 100644 --- a/src/main/kotlin/io/snyk/plugin/ui/UIUtils.kt +++ b/src/main/kotlin/io/snyk/plugin/ui/UIUtils.kt @@ -9,6 +9,7 @@ import com.intellij.uiDesigner.core.GridConstraints import com.intellij.uiDesigner.core.GridLayoutManager import com.intellij.uiDesigner.core.Spacer import com.intellij.util.Alarm +import com.intellij.util.ui.HTMLEditorKitBuilder import com.intellij.util.ui.JBHtmlEditorKit import com.intellij.util.ui.JBUI import com.intellij.util.ui.UIUtil @@ -124,7 +125,7 @@ fun getReadOnlyClickableHtmlJEditorPaneFixedSize( // don't remove that! // Some magic (side-effect? customStyleSheet?) happens when JBHtmlEditorKit() initializing // that make html tags like ,

,

    etc. be treated properly inside JEditorPane - JBHtmlEditorKit() + HTMLEditorKitBuilder.simple() return JEditorPane( "text/html", @@ -137,7 +138,7 @@ fun getReadOnlyClickableHtmlJEditorPaneFixedSize( // instead of the value in javax.swing.text.html.default.css val fontColor = UIUtil.getTextFieldForeground() val bodyRule = UIUtil.displayPropertiesToCSS(font, fontColor) + - "a { color: #${ColorUtil.toHex(JBUI.CurrentTheme.Link.linkColor())}; }" + "a { color: #${ColorUtil.toHex(JBUI.CurrentTheme.Link.Foreground.ENABLED)}; }" (document as HTMLDocument).styleSheet.addRule(bodyRule) (document as HTMLDocument).styleSheet.addRule( diff --git a/src/main/kotlin/io/snyk/plugin/ui/settings/ScanTypesPanel.kt b/src/main/kotlin/io/snyk/plugin/ui/settings/ScanTypesPanel.kt index ee8669d74..ce23fd1b5 100644 --- a/src/main/kotlin/io/snyk/plugin/ui/settings/ScanTypesPanel.kt +++ b/src/main/kotlin/io/snyk/plugin/ui/settings/ScanTypesPanel.kt @@ -6,8 +6,8 @@ import com.intellij.openapi.progress.runBackgroundableTask import com.intellij.openapi.project.Project import com.intellij.openapi.ui.popup.Balloon import com.intellij.ui.HyperlinkLabel +import com.intellij.ui.components.ActionLink import com.intellij.ui.components.JBCheckBox -import com.intellij.ui.components.labels.LinkLabel import com.intellij.ui.layout.panel import com.intellij.util.Alarm import com.intellij.util.ui.JBUI @@ -45,7 +45,7 @@ class ScanTypesPanel( private var codeQualityCheckbox: JBCheckBox? = null private var snykCodeComment: JLabel? = null private var snykCodeAlertHyperLinkLabel = HyperlinkLabel() - private var snykCodeReCheckLinkLabel = LinkLabel.create("Check again") { + private var snykCodeReCheckLinkLabel = ActionLink("Check again") { runBackgroundableTask("Checking Snyk Code enablement in organisation", project, true) { checkSastEnabled() } diff --git a/src/main/kotlin/io/snyk/plugin/ui/toolwindow/SnykToolWindow.kt b/src/main/kotlin/io/snyk/plugin/ui/toolwindow/SnykToolWindow.kt index 034bcb964..1b9ef3598 100644 --- a/src/main/kotlin/io/snyk/plugin/ui/toolwindow/SnykToolWindow.kt +++ b/src/main/kotlin/io/snyk/plugin/ui/toolwindow/SnykToolWindow.kt @@ -46,7 +46,7 @@ class SnykToolWindow(private val project: Project) : SimpleToolWindowPanel(false val expandNodeChildActionsGroup = DefaultActionGroup() expandNodeChildActionsGroup.add(ExpandNodeChildAction(tree)) - PopupHandler.installPopupHandler(tree, expandNodeChildActionsGroup, "SnykTree", actionManager) + PopupHandler.installPopupMenu(tree, expandNodeChildActionsGroup, "SnykTree") actionGroup.addAll(actionManager.getAction("io.snyk.plugin.ScanActions") as DefaultActionGroup) actionGroup.addSeparator() @@ -56,6 +56,7 @@ class SnykToolWindow(private val project: Project) : SimpleToolWindowPanel(false actionGroup.addAll(actionManager.getAction("io.snyk.plugin.MiscActions") as DefaultActionGroup) actionToolbar = actionManager.createActionToolbar("Snyk Toolbar", actionGroup, false) + actionToolbar.targetComponent = this initialiseToolbarUpdater() toolbar = actionToolbar.component diff --git a/src/main/kotlin/io/snyk/plugin/ui/toolwindow/SnykTreeCellRenderer.kt b/src/main/kotlin/io/snyk/plugin/ui/toolwindow/SnykTreeCellRenderer.kt index e67f57a31..c6ed1d8d5 100644 --- a/src/main/kotlin/io/snyk/plugin/ui/toolwindow/SnykTreeCellRenderer.kt +++ b/src/main/kotlin/io/snyk/plugin/ui/toolwindow/SnykTreeCellRenderer.kt @@ -38,6 +38,7 @@ import snyk.iac.ui.toolwindow.IacFileTreeNode import snyk.iac.ui.toolwindow.IacIssueTreeNode import snyk.oss.OssVulnerabilitiesForFile import snyk.oss.Vulnerability +import java.util.Locale import javax.swing.Icon import javax.swing.JTree @@ -69,7 +70,7 @@ class SnykTreeCellRenderer : ColoredTreeCellRenderer() { } is FileTreeNode -> { val fileVulns = value.userObject as OssVulnerabilitiesForFile - nodeIcon = PackageManagerIconProvider.getIcon(fileVulns.packageManager.toLowerCase()) + nodeIcon = PackageManagerIconProvider.getIcon(fileVulns.packageManager.lowercase(Locale.getDefault())) text = fileVulns.sanitizedTargetFile + ProductType.OSS.getCountText(value.childCount) val snykCachedResults = getSnykCachedResults(value.project) @@ -106,7 +107,8 @@ class SnykTreeCellRenderer : ColoredTreeCellRenderer() { } is IacFileTreeNode -> { val iacVulnerabilitiesForFile = value.userObject as IacIssuesForFile - nodeIcon = PackageManagerIconProvider.getIcon(iacVulnerabilitiesForFile.packageManager.toLowerCase()) + nodeIcon = + PackageManagerIconProvider.getIcon(iacVulnerabilitiesForFile.packageManager.lowercase(Locale.getDefault())) text = iacVulnerabilitiesForFile.targetFile + ProductType.IAC.getCountText(value.childCount) val snykCachedResults = getSnykCachedResults(value.project) diff --git a/src/main/kotlin/io/snyk/plugin/ui/toolwindow/panels/SnykAuthPanel.kt b/src/main/kotlin/io/snyk/plugin/ui/toolwindow/panels/SnykAuthPanel.kt index 47314cba7..0890bfb7d 100644 --- a/src/main/kotlin/io/snyk/plugin/ui/toolwindow/panels/SnykAuthPanel.kt +++ b/src/main/kotlin/io/snyk/plugin/ui/toolwindow/panels/SnykAuthPanel.kt @@ -3,6 +3,7 @@ package io.snyk.plugin.ui.toolwindow.panels import com.intellij.openapi.Disposable import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.components.service +import com.intellij.openapi.progress.runBackgroundableTask import com.intellij.openapi.project.Project import com.intellij.uiDesigner.core.GridConstraints.ANCHOR_EAST import com.intellij.uiDesigner.core.GridConstraints.ANCHOR_NORTHWEST @@ -59,11 +60,15 @@ class SnykAuthPanel(val project: Project) : JPanel(), Disposable { service().addTrustedPath(Paths.get(it)) } - val userId = analytics.obtainUserId(token) - if (userId.isNotBlank()) { - analytics.setUserId(userId) - analytics.identify() - getAmplitudeExperimentService().fetch(ExperimentUser(userId)) + if (pluginSettings().usageAnalyticsEnabled) { + val userId = analytics.obtainUserId(token) + if (userId.isNotBlank()) { + runBackgroundableTask("Snyk: Fetching experiments", project, true) { + analytics.setUserId(userId) + analytics.identify() + getAmplitudeExperimentService().fetch(ExperimentUser(userId)) + } + } } getSyncPublisher(project, SnykSettingsListener.SNYK_SETTINGS_TOPIC)?.settingsChanged() } diff --git a/src/main/kotlin/io/snyk/plugin/ui/toolwindow/panels/SuggestionDescriptionPanel.kt b/src/main/kotlin/io/snyk/plugin/ui/toolwindow/panels/SuggestionDescriptionPanel.kt index 090dd6cd5..398c5e660 100644 --- a/src/main/kotlin/io/snyk/plugin/ui/toolwindow/panels/SuggestionDescriptionPanel.kt +++ b/src/main/kotlin/io/snyk/plugin/ui/toolwindow/panels/SuggestionDescriptionPanel.kt @@ -180,14 +180,14 @@ class SuggestionDescriptionPanel( val maxFilenameLength = markers.asSequence() .filter { it.file.isNotEmpty() } .map { it.file.substringAfterLast('/', "").length } - .max() + .maxOrNull() ?: 0 val allStepPanels = mutableListOf() markers.forEachIndexed { index, markerRange -> val stepPanel = stepPanel( index = index, markerRange = markerRange, - maxFilenameLength = max(snykCodeFile.virtualFile.name.length, maxFilenameLength ?: 0), + maxFilenameLength = max(snykCodeFile.virtualFile.name.length, maxFilenameLength), allStepPanels = allStepPanels ) @@ -290,10 +290,7 @@ class SuggestionDescriptionPanel( panel.add(tabbedPanel, panelGridConstraints(2, indent = 1)) - val maxRowCount = fixes.take(examplesCount) - .map { it.lines.size } - .max() - ?: 0 + val maxRowCount = fixes.take(examplesCount).maxOfOrNull { it.lines.size } ?: 0 fixes.take(examplesCount).forEach { exampleCommitFix -> val shortURL = exampleCommitFix.commitURL .removePrefix("https://") diff --git a/src/main/kotlin/io/snyk/plugin/ui/toolwindow/panels/TreePanel.kt b/src/main/kotlin/io/snyk/plugin/ui/toolwindow/panels/TreePanel.kt index 731a239e8..4f4115106 100644 --- a/src/main/kotlin/io/snyk/plugin/ui/toolwindow/panels/TreePanel.kt +++ b/src/main/kotlin/io/snyk/plugin/ui/toolwindow/panels/TreePanel.kt @@ -19,7 +19,9 @@ class TreePanel(tree: Tree) : SimpleToolWindowPanel(true, true) { name = "treePanel" val severityToolbarPanel = JPanel(BorderLayout()) severityToolbarPanel.add(JLabel(" Severity: "), BorderLayout.WEST) - severityToolbarPanel.add(getSeverityToolbar().component, BorderLayout.CENTER) + val severityToolbar = getSeverityToolbar() + severityToolbar.targetComponent = this + severityToolbarPanel.add(severityToolbar.component, BorderLayout.CENTER) val toolBarPanel = JPanel(BorderLayout()) toolBarPanel.add(severityToolbarPanel, BorderLayout.CENTER) diff --git a/src/main/kotlin/snyk/WelcomeNotifyActivity.kt b/src/main/kotlin/snyk/WelcomeNotifyActivity.kt index b583f7552..495d8d2ec 100644 --- a/src/main/kotlin/snyk/WelcomeNotifyActivity.kt +++ b/src/main/kotlin/snyk/WelcomeNotifyActivity.kt @@ -1,6 +1,7 @@ package snyk import com.intellij.openapi.project.Project +import com.intellij.openapi.startup.ProjectActivity import com.intellij.openapi.startup.StartupActivity import io.snyk.plugin.pluginSettings import io.snyk.plugin.services.SnykApplicationSettingsStateService @@ -10,8 +11,8 @@ import io.snyk.plugin.ui.SnykBalloonNotifications * Shows a welcome notification once when Snyk plugin is installed and * [SnykApplicationSettingsStateService.pluginFirstRun] property is `true`. */ -class WelcomeNotifyActivity : StartupActivity { - override fun runActivity(project: Project) { +class WelcomeNotifyActivity : ProjectActivity { + override suspend fun execute(project: Project) { val settings = pluginSettings() if (settings.pluginFirstRun) { diff --git a/src/main/kotlin/snyk/advisor/api/AdvisorApiClient.kt b/src/main/kotlin/snyk/advisor/api/AdvisorApiClient.kt index 629383d5a..b6fb108cf 100644 --- a/src/main/kotlin/snyk/advisor/api/AdvisorApiClient.kt +++ b/src/main/kotlin/snyk/advisor/api/AdvisorApiClient.kt @@ -2,11 +2,14 @@ package snyk.advisor.api import com.intellij.openapi.diagnostic.logger import io.snyk.plugin.net.RetrofitClientFactory +import io.snyk.plugin.pluginSettings +import io.snyk.plugin.services.SnykApplicationSettingsStateService import retrofit2.Retrofit import snyk.advisor.AdvisorPackageManager -class AdvisorApiClient constructor( - private val baseUrl: String = "https://api.snyk.io/unstable/advisor/" +class AdvisorApiClient( + private val baseUrl: String = "https://api.snyk.io/unstable/advisor/", + private val settings: SnykApplicationSettingsStateService = pluginSettings() ) { private lateinit var retrofit: Retrofit private lateinit var scoreServiceEndpoint: ScoreService @@ -32,14 +35,14 @@ class AdvisorApiClient constructor( internal fun scoreService(): ScoreService { if (!::scoreServiceEndpoint.isInitialized) { - scoreServiceEndpoint = createRetrofitIfNeeded().create(ScoreService::class.java) + scoreServiceEndpoint = createRetrofitIfNeeded(settings).create(ScoreService::class.java) } return scoreServiceEndpoint } - private fun createRetrofitIfNeeded(): Retrofit { + private fun createRetrofitIfNeeded(settings: SnykApplicationSettingsStateService): Retrofit { if (!::retrofit.isInitialized) { - retrofit = RetrofitClientFactory.getInstance().createRetrofit(baseUrl) + retrofit = RetrofitClientFactory.getInstance().createRetrofit(baseUrl, settings = settings) } return retrofit } diff --git a/src/main/kotlin/snyk/amplitude/api/AmplitudeExperimentApiClient.kt b/src/main/kotlin/snyk/amplitude/api/AmplitudeExperimentApiClient.kt index 998c39bb2..4b1c0bcb4 100644 --- a/src/main/kotlin/snyk/amplitude/api/AmplitudeExperimentApiClient.kt +++ b/src/main/kotlin/snyk/amplitude/api/AmplitudeExperimentApiClient.kt @@ -71,7 +71,8 @@ class AmplitudeExperimentApiClient private constructor( baseUrl: String = "https://api.lab.amplitude.com/", apiKey: String ): AmplitudeExperimentApiClient { - return AmplitudeExperimentApiClient(baseUrl, apiKey) + val client = AmplitudeExperimentApiClient(baseUrl, apiKey) + return client } } diff --git a/src/main/kotlin/snyk/container/ContainerResult.kt b/src/main/kotlin/snyk/container/ContainerResult.kt index 4dcd9d199..0d5dbab55 100644 --- a/src/main/kotlin/snyk/container/ContainerResult.kt +++ b/src/main/kotlin/snyk/container/ContainerResult.kt @@ -11,10 +11,10 @@ class ContainerResult( var rescanNeeded: Boolean = false - override val issuesCount: Int? get() = allCliIssues?.sumBy { it.uniqueCount } + override val issuesCount: Int? get() = allCliIssues?.sumOf { it.uniqueCount } override fun countBySeverity(severity: Severity): Int? { - return allCliIssues?.sumBy { issuesForFile -> + return allCliIssues?.sumOf { issuesForFile -> issuesForFile.vulnerabilities .filter { it.getSeverity() == severity } .distinctBy { it.id } diff --git a/src/main/kotlin/snyk/container/ContainerService.kt b/src/main/kotlin/snyk/container/ContainerService.kt index b43763953..9804fff1c 100644 --- a/src/main/kotlin/snyk/container/ContainerService.kt +++ b/src/main/kotlin/snyk/container/ContainerService.kt @@ -74,7 +74,7 @@ class ContainerService(project: Project) : CliAdapter jenkins/jenkins/jenkins // jenkins/jenkins:lts -> jenkins/jenkins:lts/jenkins // so for `jenkins/jenkins:lts/jenkins` we should choose latter (longest match) - nameCandidates.size > 1 -> nameCandidates.maxBy { it.length }!! + nameCandidates.size > 1 -> nameCandidates.maxByOrNull { it.length }!! // fallback in case our sanitizing fail else -> cliReturnedImageName } diff --git a/src/main/kotlin/snyk/container/KubernetesImageCache.kt b/src/main/kotlin/snyk/container/KubernetesImageCache.kt index 4951598e1..fbf4dec6b 100644 --- a/src/main/kotlin/snyk/container/KubernetesImageCache.kt +++ b/src/main/kotlin/snyk/container/KubernetesImageCache.kt @@ -1,12 +1,16 @@ package snyk.container +import com.intellij.openapi.application.ReadAction import com.intellij.openapi.components.Service import com.intellij.openapi.diagnostic.Logger -import com.intellij.openapi.progress.runBackgroundableTask -import com.intellij.openapi.project.DumbService +import com.intellij.openapi.progress.PerformInBackgroundOption +import com.intellij.openapi.progress.ProgressIndicator +import com.intellij.openapi.progress.Task import com.intellij.openapi.project.Project import com.intellij.openapi.roots.ProjectRootManager import com.intellij.openapi.vfs.VirtualFile +import com.intellij.util.RunnableCallable +import com.intellij.util.concurrency.NonUrgentExecutor import com.jetbrains.rd.util.concurrentMapOf @Service @@ -19,15 +23,23 @@ class KubernetesImageCache(val project: Project) { } fun scanProjectForKubernetesFiles() { - val title = "Snyk: Scanning For Kubernetes Files..." - runBackgroundableTask(title, project, true) { progress -> - DumbService.getInstance(project).runReadActionInSmartMode { - ProjectRootManager.getInstance(project).fileIndex.iterateContent { virtualFile -> - this.extractFromFile(virtualFile) - !progress.isCanceled - } + val callable = RunnableCallable { + ProjectRootManager.getInstance(project).fileIndex.iterateContent { virtualFile -> + extractFromFileAndAddToCache(virtualFile) + true } } + object : Task.Backgroundable( + project, + "Scanning project for Kubernetes files", + true, + PerformInBackgroundOption.ALWAYS_BACKGROUND + ) { + override fun run(indicator: ProgressIndicator) { + ReadAction.nonBlocking(callable).wrapProgress(indicator).submit(NonUrgentExecutor.getInstance()) + } + }.queue() + } fun getKubernetesWorkloadFilesFromCache(): Set = images.keys @@ -46,12 +58,12 @@ class KubernetesImageCache(val project: Project) { fun updateCache(files: Set) { files.forEach { file -> - extractFromFile(file) + extractFromFileAndAddToCache(file) } } /** public for Tests only */ - fun extractFromFile(file: VirtualFile) { + fun extractFromFileAndAddToCache(file: VirtualFile) { val extractFromFile = YAMLImageExtractor.extractFromFile(file, project) if (extractFromFile.isNotEmpty()) { logger.debug("${if (images.contains(file)) "updated" else "added"} $file in cache") diff --git a/src/main/kotlin/snyk/container/annotator/ContainerYamlAnnotator.kt b/src/main/kotlin/snyk/container/annotator/ContainerYamlAnnotator.kt index 4e7655654..338a14ecc 100644 --- a/src/main/kotlin/snyk/container/annotator/ContainerYamlAnnotator.kt +++ b/src/main/kotlin/snyk/container/annotator/ContainerYamlAnnotator.kt @@ -42,7 +42,7 @@ class ContainerYamlAnnotator : ExternalAnnotator() { .forEach { forImage -> val severityToShow = forImage.getSeverities() .filter { AnnotatorCommon.isSeverityToShow(it) } - .max() ?: Severity.UNKNOWN + .maxOrNull() ?: Severity.UNKNOWN val annotationMessage = annotationMessage(forImage) forImage.workloadImages .filter { it.virtualFile == psiFile.virtualFile } diff --git a/src/main/kotlin/snyk/container/ui/BaseImageRemediationDetailPanel.kt b/src/main/kotlin/snyk/container/ui/BaseImageRemediationDetailPanel.kt index f24d26ce6..87ab9a729 100644 --- a/src/main/kotlin/snyk/container/ui/BaseImageRemediationDetailPanel.kt +++ b/src/main/kotlin/snyk/container/ui/BaseImageRemediationDetailPanel.kt @@ -30,7 +30,7 @@ class BaseImageRemediationDetailPanel( private val imageIssues: ContainerIssuesForImage ) : IssueDescriptionPanelBase( title = imageIssues.imageName, - severity = imageIssues.getSeverities().max() ?: Severity.UNKNOWN + severity = imageIssues.getSeverities().maxOrNull() ?: Severity.UNKNOWN ) { private val targetImages: List = getKubernetesImageCache(project) diff --git a/src/main/kotlin/snyk/errorHandler/SentryErrorReporter.kt b/src/main/kotlin/snyk/errorHandler/SentryErrorReporter.kt index 9b1d2e999..40ea0dbac 100644 --- a/src/main/kotlin/snyk/errorHandler/SentryErrorReporter.kt +++ b/src/main/kotlin/snyk/errorHandler/SentryErrorReporter.kt @@ -59,7 +59,7 @@ object SentryErrorReporter { fun submitErrorReport( error: Throwable, - consumer: Consumer, + consumer: Consumer, attachments: List = emptyList(), description: String = "" ) { diff --git a/src/main/kotlin/snyk/errorHandler/SnykErrorReportSubmitter.kt b/src/main/kotlin/snyk/errorHandler/SnykErrorReportSubmitter.kt index d884fc1dc..8f9672eb8 100644 --- a/src/main/kotlin/snyk/errorHandler/SnykErrorReportSubmitter.kt +++ b/src/main/kotlin/snyk/errorHandler/SnykErrorReportSubmitter.kt @@ -18,7 +18,7 @@ class SnykErrorReportSubmitter : ErrorReportSubmitter() { events: Array, additionalInfo: String?, parentComponent: Component, - consumer: Consumer + consumer: Consumer ): Boolean { for (event in events) { var throwable = event.throwable diff --git a/src/main/kotlin/snyk/iac/IacResult.kt b/src/main/kotlin/snyk/iac/IacResult.kt index ce80b69b4..3f4ef49a6 100644 --- a/src/main/kotlin/snyk/iac/IacResult.kt +++ b/src/main/kotlin/snyk/iac/IacResult.kt @@ -22,10 +22,10 @@ class IacResult( var iacScanNeeded: Boolean = false - override val issuesCount get() = allCliIssues?.sumBy { it.uniqueCount } + override val issuesCount get() = allCliIssues?.sumOf { it.uniqueCount } override fun countBySeverity(severity: Severity): Int? { - return allCliIssues?.sumBy { issuesForFile -> + return allCliIssues?.sumOf { issuesForFile -> issuesForFile.infrastructureAsCodeIssues .filter { it.getSeverity() == severity } .distinctBy { it.id } diff --git a/src/main/kotlin/snyk/iac/annotator/IacHclAnnotator.kt b/src/main/kotlin/snyk/iac/annotator/IacHclAnnotator.kt index 314eadf02..e0eee8879 100644 --- a/src/main/kotlin/snyk/iac/annotator/IacHclAnnotator.kt +++ b/src/main/kotlin/snyk/iac/annotator/IacHclAnnotator.kt @@ -7,9 +7,9 @@ import com.intellij.psi.PsiFile import com.intellij.psi.PsiWhiteSpace import com.intellij.psi.impl.source.tree.LeafPsiElement import com.intellij.psi.util.elementType -import org.intellij.plugins.hcl.psi.HCLBlock -import org.intellij.plugins.hcl.psi.HCLElement -import org.intellij.plugins.hcl.psi.HCLProperty +import org.intellij.terraform.hcl.psi.HCLBlock +import org.intellij.terraform.hcl.psi.HCLElement +import org.intellij.terraform.hcl.psi.HCLProperty import snyk.iac.IacIssue private val LOG = logger() diff --git a/src/main/kotlin/snyk/oss/OssResult.kt b/src/main/kotlin/snyk/oss/OssResult.kt index 944fa0ff1..15fcd4c54 100644 --- a/src/main/kotlin/snyk/oss/OssResult.kt +++ b/src/main/kotlin/snyk/oss/OssResult.kt @@ -9,10 +9,10 @@ class OssResult( errors: List = emptyList() ) : CliResult(allOssVulnerabilities, errors) { - override val issuesCount = allOssVulnerabilities?.sumBy { it.uniqueCount } + override val issuesCount = allOssVulnerabilities?.sumOf { it.uniqueCount } override fun countBySeverity(severity: Severity): Int? { - return allCliIssues?.sumBy { vulnerabilitiesForFile -> + return allCliIssues?.sumOf { vulnerabilitiesForFile -> vulnerabilitiesForFile.vulnerabilities .filter { it.getSeverity() == severity } .distinctBy { it.id } diff --git a/src/main/kotlin/snyk/oss/annotator/AnnotatorHelper.kt b/src/main/kotlin/snyk/oss/annotator/AnnotatorHelper.kt index 9e70fdd47..00c01bfcc 100644 --- a/src/main/kotlin/snyk/oss/annotator/AnnotatorHelper.kt +++ b/src/main/kotlin/snyk/oss/annotator/AnnotatorHelper.kt @@ -1,5 +1,7 @@ package snyk.oss.annotator +import java.util.Locale + object AnnotatorHelper { fun isFileSupported(filePath: String): Boolean = @@ -28,5 +30,5 @@ object AnnotatorHelper { "poetry.lock", "mix.exs", "mix.lock" - ).any { filePath.toLowerCase().endsWith(it) } + ).any { filePath.lowercase(Locale.getDefault()).endsWith(it) } } diff --git a/src/main/kotlin/snyk/trust/TrustedProjects.kt b/src/main/kotlin/snyk/trust/TrustedProjects.kt index 2c548c61f..f23c6795b 100644 --- a/src/main/kotlin/snyk/trust/TrustedProjects.kt +++ b/src/main/kotlin/snyk/trust/TrustedProjects.kt @@ -4,6 +4,7 @@ package snyk.trust import com.intellij.openapi.application.invokeAndWaitIfNeeded import com.intellij.openapi.components.service import com.intellij.openapi.diagnostic.Logger +import com.intellij.openapi.project.Project import com.intellij.openapi.ui.MessageDialogBuilder import com.intellij.openapi.ui.Messages import snyk.SnykBundle @@ -18,14 +19,14 @@ private val LOG = Logger.getInstance("snyk.trust.TrustedProjects") * * @return `false` if the user chose not to scan the project at all; `true` otherwise */ -fun confirmScanningAndSetWorkspaceTrustedStateIfNeeded(projectFileOrDir: Path): Boolean { +fun confirmScanningAndSetWorkspaceTrustedStateIfNeeded(project: Project, projectFileOrDir: Path): Boolean { val projectDir = if (Files.isDirectory(projectFileOrDir)) projectFileOrDir else projectFileOrDir.parent val trustService = service() val trustedState = trustService.isPathTrusted(projectDir) if (!trustedState) { LOG.info("Asking user to trust the project ${projectDir.fileName}") - return when (confirmScanningUntrustedProject(projectDir)) { + return when (confirmScanningUntrustedProject(project, projectDir)) { ScanUntrustedProjectChoice.TRUST_AND_SCAN -> { trustService.addTrustedPath(projectDir) true @@ -38,7 +39,7 @@ fun confirmScanningAndSetWorkspaceTrustedStateIfNeeded(projectFileOrDir: Path): return true } -private fun confirmScanningUntrustedProject(projectDir: Path): ScanUntrustedProjectChoice { +private fun confirmScanningUntrustedProject(project: Project, projectDir: Path): ScanUntrustedProjectChoice { val fileName = projectDir.fileName ?: projectDir.toString() val title = SnykBundle.message("snyk.trust.dialog.warning.title", fileName) val message = SnykBundle.message("snyk.trust.dialog.warning.text") @@ -53,9 +54,9 @@ private fun confirmScanningUntrustedProject(projectDir: Path): ScanUntrustedProj .icon(Messages.getWarningIcon()) .yesText(trustButton) .noText(distrustButton) - .show() + .ask(project) - choice = if (result == Messages.YES) { + choice = if (result) { LOG.info("User trusts the project $fileName for scans") ScanUntrustedProjectChoice.TRUST_AND_SCAN } else { diff --git a/src/main/kotlin/snyk/whoami/WhoamiResult.kt b/src/main/kotlin/snyk/whoami/WhoamiResult.kt index 7c73ca140..d01550e31 100644 --- a/src/main/kotlin/snyk/whoami/WhoamiResult.kt +++ b/src/main/kotlin/snyk/whoami/WhoamiResult.kt @@ -9,7 +9,7 @@ class WhoamiResult( errors: List = emptyList() ) : CliResult(allWhoamiOutputs, errors) { - override val issuesCount = allWhoamiOutputs?.sumBy { it.uniqueCount } + override val issuesCount = allWhoamiOutputs?.sumOf { it.uniqueCount } override fun countBySeverity(severity: Severity): Int { return 0 diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index 0aac7015c..a030417dd 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -6,8 +6,8 @@ com.intellij.modules.lang com.intellij.modules.platform - com.intellij.modules.php-capable - com.intellij.modules.go + com.jetbrains.php + org.jetbrains.plugins.go org.jetbrains.kotlin com.intellij.java com.intellij.modules.rider @@ -50,6 +50,8 @@ description="Preview: Enable new refactored issues tree." restartRequired="true"/> + + diff --git a/src/main/resources/icons/code.svg b/src/main/resources/icons/code.svg index 00e339570..591681080 100644 --- a/src/main/resources/icons/code.svg +++ b/src/main/resources/icons/code.svg @@ -1,5 +1,20 @@ - - - + + + + + + + + + + + + diff --git a/src/main/resources/icons/code_dark.svg b/src/main/resources/icons/code_dark.svg deleted file mode 100644 index 165864e4e..000000000 --- a/src/main/resources/icons/code_dark.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/src/main/resources/icons/code_disabled.svg b/src/main/resources/icons/code_disabled.svg index c00628fa3..6a12ab798 100644 --- a/src/main/resources/icons/code_disabled.svg +++ b/src/main/resources/icons/code_disabled.svg @@ -1,7 +1,22 @@ - - - - + + + + + + + + + + + + + diff --git a/src/main/resources/icons/code_disabled_dark.svg b/src/main/resources/icons/code_disabled_dark.svg deleted file mode 100644 index 7b356df65..000000000 --- a/src/main/resources/icons/code_disabled_dark.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/src/main/resources/icons/container.svg b/src/main/resources/icons/container.svg index 28ba04c06..e276de5b9 100644 --- a/src/main/resources/icons/container.svg +++ b/src/main/resources/icons/container.svg @@ -1,5 +1,20 @@ - - - + + + + + + + + + + + + diff --git a/src/main/resources/icons/container_dark.svg b/src/main/resources/icons/container_dark.svg deleted file mode 100644 index 14e5ecf48..000000000 --- a/src/main/resources/icons/container_dark.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/src/main/resources/icons/container_disabled.svg b/src/main/resources/icons/container_disabled.svg index ee0678651..f5d947835 100644 --- a/src/main/resources/icons/container_disabled.svg +++ b/src/main/resources/icons/container_disabled.svg @@ -1,7 +1,22 @@ - - - - + + + + + + + + + + + + + diff --git a/src/main/resources/icons/container_disabled_dark.svg b/src/main/resources/icons/container_disabled_dark.svg deleted file mode 100644 index 0fe3e6d48..000000000 --- a/src/main/resources/icons/container_disabled_dark.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/src/main/resources/icons/iac.svg b/src/main/resources/icons/iac.svg index b27f3a5e6..8a7e1c284 100644 --- a/src/main/resources/icons/iac.svg +++ b/src/main/resources/icons/iac.svg @@ -1,6 +1,19 @@ - - - - + + + + + + + + + + + + diff --git a/src/main/resources/icons/iac_dark.svg b/src/main/resources/icons/iac_dark.svg deleted file mode 100644 index e44456566..000000000 --- a/src/main/resources/icons/iac_dark.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/src/main/resources/icons/iac_disabled.svg b/src/main/resources/icons/iac_disabled.svg index eb2f18cae..eb0bf78d1 100644 --- a/src/main/resources/icons/iac_disabled.svg +++ b/src/main/resources/icons/iac_disabled.svg @@ -1,8 +1,22 @@ - - - - - + + + + + + + + + + + + + diff --git a/src/main/resources/icons/iac_disabled_dark.svg b/src/main/resources/icons/iac_disabled_dark.svg deleted file mode 100644 index 667dcf457..000000000 --- a/src/main/resources/icons/iac_disabled_dark.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/src/main/resources/icons/oss.svg b/src/main/resources/icons/oss.svg index 417b8e622..f6a8adc0d 100644 --- a/src/main/resources/icons/oss.svg +++ b/src/main/resources/icons/oss.svg @@ -1,5 +1,20 @@ - - - + + + + + + + + + + + + diff --git a/src/main/resources/icons/oss_dark.svg b/src/main/resources/icons/oss_dark.svg deleted file mode 100644 index 5bc1c4833..000000000 --- a/src/main/resources/icons/oss_dark.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/src/main/resources/icons/oss_disabled.svg b/src/main/resources/icons/oss_disabled.svg index a7861e61f..68bdb0416 100644 --- a/src/main/resources/icons/oss_disabled.svg +++ b/src/main/resources/icons/oss_disabled.svg @@ -1,7 +1,22 @@ - - - - + + + + + + + + + + + + + diff --git a/src/main/resources/icons/oss_disabled_dark.svg b/src/main/resources/icons/oss_disabled_dark.svg deleted file mode 100644 index e971fd554..000000000 --- a/src/main/resources/icons/oss_disabled_dark.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/src/test/java/ai/deepcode/javaclient/core/AnalysisDataTest.java b/src/test/java/ai/deepcode/javaclient/core/AnalysisDataTest.java index 2c453bd3a..56623314b 100644 --- a/src/test/java/ai/deepcode/javaclient/core/AnalysisDataTest.java +++ b/src/test/java/ai/deepcode/javaclient/core/AnalysisDataTest.java @@ -17,11 +17,10 @@ import java.io.File; import java.io.IOException; -import java.nio.charset.StandardCharsets; import java.nio.file.Files; +import java.util.ArrayDeque; import java.util.Arrays; import java.util.Collections; -import java.util.LinkedList; import java.util.List; import java.util.Objects; import java.util.Queue; @@ -71,9 +70,6 @@ private static class RestApiMockWithBrokenFileUpload extends DeepCodeRestApiMock protected final CreateBundleResponse bundleResponseWithMissedFile = new CreateBundleResponse("bundleHash", Collections.singletonList("/filePath")); - protected final CreateBundleResponse bundleResponseWithoutMissedFile = - new CreateBundleResponse("bundleHash", Collections.emptyList()); - @Override public @NotNull CreateBundleResponse createBundle(String orgName, FileHashRequest files) { return bundleResponseWithMissedFile; @@ -186,7 +182,7 @@ public void reupload_files_if_initial_upload_does_not_succeed() throws IOExcepti File file = File.createTempFile("analysisDataTest", "tmp"); file.deleteOnExit(); - Files.write(file.toPath(), "testtestest".getBytes(StandardCharsets.UTF_8)); + Files.writeString(file.toPath(), "testtestest"); analysisData.updateCachedResultsForFiles(project, Collections.singleton(file), progress); @@ -237,7 +233,7 @@ public void getAnalysis_recover_during_polling_if_operation_sometimes_does_not_s nonCompleteAnalysisResponse.setStatusCode(200); nonCompleteAnalysisResponse.setStatusDescription("Fake non-complete getAnalysis"); - final Queue responses = new LinkedList<>(Arrays.asList( + final Queue responses = new ArrayDeque<>(Arrays.asList( nonCompleteAnalysisResponse, nonCompleteAnalysisResponse, failed404AnalysisResponse, diff --git a/src/test/java/ai/deepcode/javaclient/core/DeepCodeIgnoreInfoHolderTest.java b/src/test/java/ai/deepcode/javaclient/core/DeepCodeIgnoreInfoHolderTest.java index db72812a7..6ce8547fc 100644 --- a/src/test/java/ai/deepcode/javaclient/core/DeepCodeIgnoreInfoHolderTest.java +++ b/src/test/java/ai/deepcode/javaclient/core/DeepCodeIgnoreInfoHolderTest.java @@ -15,12 +15,10 @@ public class DeepCodeIgnoreInfoHolderTest { - private final File basicIgnoreFile = - new File(getClass().getClassLoader().getResource("basic/.dcignore").getPath()); + private final File basicIgnoreFile = new File("src/test/resources/basic/.dcignore"); private final File basicProject = basicIgnoreFile.getParentFile(); - private final File fullDcignoreFile = - new File(getClass().getClassLoader().getResource("full/.dcignore").getPath()); + private final File fullDcignoreFile = new File("src/test/resources/full/.dcignore"); private final File fullDcignoreProject = fullDcignoreFile.getParentFile(); @Test diff --git a/src/test/kotlin/io/snyk/plugin/TestUtils.kt b/src/test/kotlin/io/snyk/plugin/TestUtils.kt index 9d0bcd57d..107a96942 100644 --- a/src/test/kotlin/io/snyk/plugin/TestUtils.kt +++ b/src/test/kotlin/io/snyk/plugin/TestUtils.kt @@ -1,17 +1,57 @@ package io.snyk.plugin +import com.intellij.openapi.application.ApplicationManager +import com.intellij.openapi.project.Project +import com.intellij.testFramework.replaceService import com.intellij.util.io.RequestBuilder import io.mockk.every import io.mockk.justRun import io.mockk.mockk import io.mockk.mockkObject +import io.snyk.plugin.services.SnykApplicationSettingsStateService +import io.snyk.plugin.services.SnykProjectSettingsStateService import io.snyk.plugin.services.download.CliDownloader import io.snyk.plugin.services.download.HttpRequestHelper +import java.io.File +import java.nio.file.Path + +fun setupDummyCliFile() { + val cliFile = getCliFile() + + if (!cliFile.exists()) { + if (!cliFile.parentFile.exists()) cliFile.mkdirs() + cliFile.createNewFile() + } +} + +fun removeDummyCliFile() { + val cliFile = getCliFile() + if (cliFile.exists()) { + cliFile.delete() + } +} + +fun resetSettings(project: Project?) { + val application = ApplicationManager.getApplication() + application.replaceService( + SnykApplicationSettingsStateService::class.java, + SnykApplicationSettingsStateService(), + application + ) + project?.replaceService( + SnykProjectSettingsStateService::class.java, + SnykProjectSettingsStateService(), + project + ) +} /** low level avoiding download the CLI file */ -fun mockCliDownload() { +fun mockCliDownload(): RequestBuilder { val requestBuilderMockk = mockk(relaxed = true) - justRun { requestBuilderMockk.saveToFile(any(), any()) } + justRun { requestBuilderMockk.saveToFile(any(), any()) } + justRun { requestBuilderMockk.saveToFile(any(), any()) } mockkObject(HttpRequestHelper) every { HttpRequestHelper.createRequest(CliDownloader.LATEST_RELEASE_DOWNLOAD_URL) } returns requestBuilderMockk + every { HttpRequestHelper.createRequest(CliDownloader.LATEST_RELEASES_URL) } returns requestBuilderMockk + return requestBuilderMockk } diff --git a/src/integTest/kotlin/io/snyk/plugin/cli/ConsoleCommandRunnerTest.kt b/src/test/kotlin/io/snyk/plugin/cli/ConsoleCommandRunnerTest.kt similarity index 97% rename from src/integTest/kotlin/io/snyk/plugin/cli/ConsoleCommandRunnerTest.kt rename to src/test/kotlin/io/snyk/plugin/cli/ConsoleCommandRunnerTest.kt index 86e5d4319..e415c146b 100644 --- a/src/integTest/kotlin/io/snyk/plugin/cli/ConsoleCommandRunnerTest.kt +++ b/src/test/kotlin/io/snyk/plugin/cli/ConsoleCommandRunnerTest.kt @@ -28,15 +28,13 @@ import io.snyk.plugin.removeDummyCliFile import io.snyk.plugin.resetSettings import io.snyk.plugin.services.download.SnykCliDownloaderService import io.snyk.plugin.setupDummyCliFile -import org.junit.After -import org.junit.Before -import org.junit.Test import snyk.PLUGIN_ID import snyk.common.isOauth import snyk.errorHandler.SentryErrorReporter import snyk.oss.OssService import java.net.URI import java.net.URLEncoder +import java.util.Locale import java.util.UUID import java.util.concurrent.TimeUnit @@ -45,7 +43,6 @@ class ConsoleCommandRunnerTest : LightPlatformTestCase() { private val ossService: OssService get() = getOssService(project) ?: throw IllegalStateException("OSS service should be available") - @Before override fun setUp() { super.setUp() unmockkAll() @@ -56,7 +53,6 @@ class ConsoleCommandRunnerTest : LightPlatformTestCase() { every { SentryErrorReporter.captureException(any()) } returns SentryId() } - @After override fun tearDown() { unmockkAll() resetSettings(project) @@ -64,7 +60,6 @@ class ConsoleCommandRunnerTest : LightPlatformTestCase() { super.tearDown() } - @Test fun testSetupCliEnvironmentVariablesWithCustomEndpoint() { val oldEndpoint = pluginSettings().customEndpointUrl try { @@ -80,7 +75,6 @@ class ConsoleCommandRunnerTest : LightPlatformTestCase() { } } - @Test fun testSetupCliEnvironmentVariablesWithOAuthEndpoint() { val oldEndpoint = pluginSettings().customEndpointUrl try { @@ -103,7 +97,6 @@ class ConsoleCommandRunnerTest : LightPlatformTestCase() { } } - @Test fun testSetupCliEnvironmentVariablesWithNonOAuthEndpoint() { val oldEndpoint = pluginSettings().customEndpointUrl try { @@ -126,7 +119,6 @@ class ConsoleCommandRunnerTest : LightPlatformTestCase() { } } - @Test fun testSetupCliEnvironmentVariablesWithCustomEndpointNoTrailingSlash() { val oldEndpoint = pluginSettings().customEndpointUrl try { @@ -142,7 +134,6 @@ class ConsoleCommandRunnerTest : LightPlatformTestCase() { } } - @Test fun testSetupCliEnvironmentVariablesWithDisabledUsageAnalytics() { val originalUsageAnalyticsEnabled = pluginSettings().usageAnalyticsEnabled try { @@ -156,7 +147,6 @@ class ConsoleCommandRunnerTest : LightPlatformTestCase() { } } - @Test fun testSetupCliEnvironmentVariablesWithProxyWithoutAuth() { val httpConfigurable = HttpConfigurable.getInstance() val originalProxyHost = httpConfigurable.PROXY_HOST @@ -180,7 +170,6 @@ class ConsoleCommandRunnerTest : LightPlatformTestCase() { } } - @Test fun testSetupCliEnvironmentVariablesWithProxyWithAuth() { val httpConfigurable = HttpConfigurable.getInstance() val originalProxyHost = httpConfigurable.PROXY_HOST @@ -201,7 +190,8 @@ class ConsoleCommandRunnerTest : LightPlatformTestCase() { val generalCommandLine = GeneralCommandLine("") val expectedProxy = - "http://${encodedLogin}:${encodedPassword}@${httpConfigurable.PROXY_HOST}:${httpConfigurable.PROXY_PORT}" + "http://${encodedLogin}:${encodedPassword}@" + + "${httpConfigurable.PROXY_HOST}:${httpConfigurable.PROXY_PORT}" ConsoleCommandRunner().setupCliEnvironmentVariables(generalCommandLine, "") @@ -216,7 +206,6 @@ class ConsoleCommandRunnerTest : LightPlatformTestCase() { } } - @Test fun testSetupCliEnvironmentVariablesWithProxyWithCancelledAuth() { val httpConfigurable = HttpConfigurable.getInstance() val originalProxyHost = httpConfigurable.PROXY_HOST @@ -251,7 +240,6 @@ class ConsoleCommandRunnerTest : LightPlatformTestCase() { } } - @Test fun testSetupCliEnvironmentVariables() { val generalCommandLine = GeneralCommandLine("") val snykPluginVersion = PluginManagerCore.getPlugin(PluginId.getId(PLUGIN_ID))?.version ?: "UNKNOWN" @@ -262,11 +250,10 @@ class ConsoleCommandRunnerTest : LightPlatformTestCase() { assertEquals("JETBRAINS_IDE", generalCommandLine.environment["SNYK_INTEGRATION_NAME"]) assertEquals(snykPluginVersion, generalCommandLine.environment["SNYK_INTEGRATION_VERSION"]) assertEquals("INTELLIJ IDEA IC", generalCommandLine.environment["SNYK_INTEGRATION_ENVIRONMENT"]) - assertEquals("2020.2", generalCommandLine.environment["SNYK_INTEGRATION_ENVIRONMENT_VERSION"]) + assertEquals("2023.1", generalCommandLine.environment["SNYK_INTEGRATION_ENVIRONMENT_VERSION"]) } @Suppress("SwallowedException") - @Test fun testCommandExecutionRequestWhileCliIsDownloading() { val cliFile = getCliFile() cliFile.delete() @@ -325,14 +312,13 @@ class ConsoleCommandRunnerTest : LightPlatformTestCase() { verify(exactly = 0) { SentryErrorReporter.captureException(any()) } } - @Test fun testErrorReportedWhenExecutionTimeoutExpire() { val registryValue = Registry.get("snyk.timeout.results.waiting") val defaultValue = registryValue.asInteger() assertEquals(DEFAULT_TIMEOUT_FOR_SCAN_WAITING_MS, defaultValue) registryValue.setValue(100) val seconds = "3" - val sleepCommand = if (System.getProperty("os.name").toLowerCase().contains("win")) { + val sleepCommand = if (System.getProperty("os.name").lowercase(Locale.getDefault()).contains("win")) { // see https://www.ibm.com/support/pages/timeout-command-run-batch-job-exits-immediately-and-returns-error-input-redirection-not-supported-exiting-process-immediately listOf("ping", "-n", seconds, "localhost") } else { diff --git a/src/integTest/kotlin/io/snyk/plugin/snykcode/core/IgnoreInfoHolderPlatformTestCase.kt b/src/test/kotlin/io/snyk/plugin/core/IgnoreInfoHolderPlatformTestCase.kt similarity index 82% rename from src/integTest/kotlin/io/snyk/plugin/snykcode/core/IgnoreInfoHolderPlatformTestCase.kt rename to src/test/kotlin/io/snyk/plugin/core/IgnoreInfoHolderPlatformTestCase.kt index 3e622eee2..9dab77fdc 100644 --- a/src/integTest/kotlin/io/snyk/plugin/snykcode/core/IgnoreInfoHolderPlatformTestCase.kt +++ b/src/test/kotlin/io/snyk/plugin/core/IgnoreInfoHolderPlatformTestCase.kt @@ -1,16 +1,24 @@ -package io.snyk.plugin.snykcode.core +package io.snyk.plugin.core import com.intellij.openapi.application.ApplicationManager +import com.intellij.openapi.fileEditor.FileDocumentManager import com.intellij.openapi.project.Project import com.intellij.openapi.roots.ModuleRootModificationUtil +import com.intellij.openapi.util.io.FileUtil import com.intellij.openapi.vfs.StandardFileSystems import com.intellij.openapi.vfs.VirtualFileManager import com.intellij.testFramework.HeavyPlatformTestCase import com.intellij.testFramework.PlatformTestUtil import io.snyk.plugin.getSnykCode import io.snyk.plugin.resetSettings +import io.snyk.plugin.snykcode.core.SnykCodeFile +import io.snyk.plugin.snykcode.core.SnykCodeIgnoreInfoHolder +import io.snyk.plugin.snykcode.core.SnykCodeUtils +import org.awaitility.Awaitility.await import java.io.File import java.io.FileNotFoundException +import java.io.IOException +import java.util.concurrent.TimeUnit // `Heavy` tests should be used due to Project partial re-usage/erasure: // .dcignore is deleted between calls but Project is not reopened in BasePlatformTestCase @@ -20,6 +28,9 @@ class IgnoreInfoHolderPlatformTestCase : HeavyPlatformTestCase() { override fun setUp() { super.setUp() resetSettings(project) + if (!FileUtil.exists(project.basePath)) { + project.basePath?.let { File(it) }?.let { FileUtil.createDirectory(it) } + } ModuleRootModificationUtil.addContentRoot(module, project.basePath!!) } @@ -55,6 +66,7 @@ class IgnoreInfoHolderPlatformTestCase : HeavyPlatformTestCase() { private fun refreshVirtualFileSystem() { ApplicationManager.getApplication().runWriteAction { + FileDocumentManager.getInstance().saveAllDocuments() VirtualFileManager.getInstance().syncRefresh() } } @@ -83,10 +95,11 @@ class IgnoreInfoHolderPlatformTestCase : HeavyPlatformTestCase() { File(dcignoreFilePath).writeText("2.js") // trigger BulkFileListener to proceed .dcignore file change refreshVirtualFileSystem() - assertTrue( - "File $filePathToCheck should be excluded(ignored) by updated .dcignore", + PlatformTestUtil.dispatchAllInvocationEventsInIdeEventQueue() + + await().atMost(5, TimeUnit.SECONDS).until { SnykCodeIgnoreInfoHolder.instance.isIgnoredFile(file) - ) + } } fun testIgnoreCacheUpdateOnProjectClose() { @@ -103,8 +116,9 @@ class IgnoreInfoHolderPlatformTestCase : HeavyPlatformTestCase() { private fun setUpTest(): SnykCodeFile { val filePathToCheck = project.basePath + "/node_modules/1.js" - File(filePathToCheck).parentFile.mkdir() - File(filePathToCheck).createNewFile() + File(filePathToCheck).parentFile.mkdirs() + && File(filePathToCheck).createNewFile() + || throw IOException("Failed to create file $filePathToCheck") val fileToCheck = findFile(project, filePathToCheck) initiateAllMissedIgnoreFilesRescan() diff --git a/src/integTest/kotlin/io/snyk/plugin/snykcode/core/PDUTest.kt b/src/test/kotlin/io/snyk/plugin/core/PDUTest.kt similarity index 91% rename from src/integTest/kotlin/io/snyk/plugin/snykcode/core/PDUTest.kt rename to src/test/kotlin/io/snyk/plugin/core/PDUTest.kt index 6122dce09..4fe7f4938 100644 --- a/src/integTest/kotlin/io/snyk/plugin/snykcode/core/PDUTest.kt +++ b/src/test/kotlin/io/snyk/plugin/core/PDUTest.kt @@ -1,9 +1,11 @@ -package io.snyk.plugin.snykcode.core +package io.snyk.plugin.core import com.intellij.openapi.util.io.FileUtil import com.intellij.openapi.vfs.LocalFileSystem import com.intellij.testFramework.LightPlatformTestCase import com.intellij.testFramework.PlatformTestUtil +import io.snyk.plugin.snykcode.core.PDU +import io.snyk.plugin.snykcode.core.SnykCodeFile import java.io.File @Suppress("FunctionName") diff --git a/src/test/kotlin/io/snyk/plugin/net/SnykApiClientTest.kt b/src/test/kotlin/io/snyk/plugin/net/SnykApiClientTest.kt index d4d37c020..5806780a7 100644 --- a/src/test/kotlin/io/snyk/plugin/net/SnykApiClientTest.kt +++ b/src/test/kotlin/io/snyk/plugin/net/SnykApiClientTest.kt @@ -4,21 +4,19 @@ import junit.framework.TestCase.assertFalse import junit.framework.TestCase.assertTrue import okhttp3.mockwebserver.MockWebServer import org.junit.Before -import org.junit.Rule import org.junit.Test import retrofit2.Retrofit import retrofit2.converter.gson.GsonConverterFactory import snyk.net.HttpClient class SnykApiClientTest { - @JvmField - @Rule - val server: MockWebServer = MockWebServer() + private lateinit var server: MockWebServer private lateinit var apiClientUnderTest: SnykApiClient @Before fun setUp() { + server = MockWebServer() val httpClient = HttpClient().apply { connectTimeout = 1 readTimeout = 1 diff --git a/src/integTest/kotlin/io/snyk/plugin/services/CliAdapterTest.kt b/src/test/kotlin/io/snyk/plugin/services/CliAdapterTest.kt similarity index 97% rename from src/integTest/kotlin/io/snyk/plugin/services/CliAdapterTest.kt rename to src/test/kotlin/io/snyk/plugin/services/CliAdapterTest.kt index 73142ebe3..d519349b2 100644 --- a/src/integTest/kotlin/io/snyk/plugin/services/CliAdapterTest.kt +++ b/src/test/kotlin/io/snyk/plugin/services/CliAdapterTest.kt @@ -7,7 +7,6 @@ import io.snyk.plugin.pluginSettings import io.snyk.plugin.removeDummyCliFile import io.snyk.plugin.resetSettings import io.snyk.plugin.setupDummyCliFile -import org.junit.Test import snyk.common.SnykError class CliAdapterTest : LightPlatformTestCase() { @@ -38,7 +37,6 @@ class CliAdapterTest : LightPlatformTestCase() { super.tearDown() } - @Test fun testBuildCliCommandsListWithInsecureParameter() { setupDummyCliFile() @@ -49,7 +47,6 @@ class CliAdapterTest : LightPlatformTestCase() { assertTrue(defaultCommands.contains("--insecure")) } - @Test fun testBuildCliCommandsListWithOrganizationParameter() { setupDummyCliFile() diff --git a/src/integTest/kotlin/io/snyk/plugin/services/SnykTaskQueueServiceHeavyTest.kt b/src/test/kotlin/io/snyk/plugin/services/SnykTaskQueueServiceHeavyTest.kt similarity index 94% rename from src/integTest/kotlin/io/snyk/plugin/services/SnykTaskQueueServiceHeavyTest.kt rename to src/test/kotlin/io/snyk/plugin/services/SnykTaskQueueServiceHeavyTest.kt index 439460eb1..8b23ccfa1 100644 --- a/src/integTest/kotlin/io/snyk/plugin/services/SnykTaskQueueServiceHeavyTest.kt +++ b/src/test/kotlin/io/snyk/plugin/services/SnykTaskQueueServiceHeavyTest.kt @@ -5,9 +5,7 @@ import com.intellij.testFramework.PlatformTestUtil import io.mockk.unmockkAll import io.snyk.plugin.getSnykTaskQueueService import io.snyk.plugin.resetSettings -import org.junit.Test -@Suppress("FunctionName") class SnykTaskQueueServiceHeavyTest : HeavyPlatformTestCase() { override fun setUp() { @@ -22,7 +20,6 @@ class SnykTaskQueueServiceHeavyTest : HeavyPlatformTestCase() { super.tearDown() } - @Test fun `test service request for disposed project`() { PlatformTestUtil.forceCloseProjectWithoutSaving(project) diff --git a/src/integTest/kotlin/io/snyk/plugin/services/SnykTaskQueueServiceTest.kt b/src/test/kotlin/io/snyk/plugin/services/SnykTaskQueueServiceTest.kt similarity index 92% rename from src/integTest/kotlin/io/snyk/plugin/services/SnykTaskQueueServiceTest.kt rename to src/test/kotlin/io/snyk/plugin/services/SnykTaskQueueServiceTest.kt index df0f86e3e..60902bed4 100644 --- a/src/integTest/kotlin/io/snyk/plugin/services/SnykTaskQueueServiceTest.kt +++ b/src/test/kotlin/io/snyk/plugin/services/SnykTaskQueueServiceTest.kt @@ -32,7 +32,6 @@ import io.snyk.plugin.setupDummyCliFile import org.awaitility.Awaitility.await import org.hamcrest.CoreMatchers.equalTo import org.hamcrest.MatcherAssert.assertThat -import org.junit.Test import snyk.container.ContainerResult import snyk.iac.IacResult import snyk.oss.OssResult @@ -60,7 +59,7 @@ class SnykTaskQueueServiceTest : LightPlatformTestCase() { "testTag" ) every { getSnykCliDownloaderService() } returns downloaderServiceMock - every { confirmScanningAndSetWorkspaceTrustedStateIfNeeded(any()) } returns true + every { confirmScanningAndSetWorkspaceTrustedStateIfNeeded(any(), any()) } returns true } private fun mockSnykApiServiceSastEnabled() { @@ -84,24 +83,23 @@ class SnykTaskQueueServiceTest : LightPlatformTestCase() { super.tearDown() } - @Test fun testSnykTaskQueueService() { setupDummyCliFile() val snykTaskQueueService = project.service() snykTaskQueueService.scan() + PlatformTestUtil.dispatchAllInvocationEventsInIdeEventQueue() assertTrue(snykTaskQueueService.getTaskQueue().isEmpty) snykTaskQueueService.downloadLatestRelease() + PlatformTestUtil.dispatchAllInvocationEventsInIdeEventQueue() assertTrue(snykTaskQueueService.getTaskQueue().isEmpty) - assertNull(snykTaskQueueService.ossScanProgressIndicator) } - @Test fun testCliDownloadBeforeScanIfNeeded() { val cliFile = getCliFile() val downloaderMock = setupMockForDownloadTest() @@ -111,13 +109,13 @@ class SnykTaskQueueServiceTest : LightPlatformTestCase() { val snykTaskQueueService = project.service() snykTaskQueueService.scan() + PlatformTestUtil.dispatchAllInvocationEventsInIdeEventQueue() assertTrue(snykTaskQueueService.getTaskQueue().isEmpty) verify { downloaderMock.downloadFile(any(), any(), any()) } } - @Test fun testDontDownloadCLIIfUpdatesDisabled() { val downloaderMock = setupMockForDownloadTest() val settings = setupAppSettingsForDownloadTests() @@ -125,6 +123,7 @@ class SnykTaskQueueServiceTest : LightPlatformTestCase() { val snykTaskQueueService = project.service() snykTaskQueueService.scan() + PlatformTestUtil.dispatchAllInvocationEventsInIdeEventQueue() assertTrue(snykTaskQueueService.getTaskQueue().isEmpty) @@ -152,7 +151,6 @@ class SnykTaskQueueServiceTest : LightPlatformTestCase() { return downloaderMock } - @Test fun testProjectClosedWhileTaskRunning() { val snykTaskQueueService = project.service() @@ -163,7 +161,6 @@ class SnykTaskQueueServiceTest : LightPlatformTestCase() { snykTaskQueueService.downloadLatestRelease() } - @Test fun testSastEnablementCheckInScan() { val snykTaskQueueService = project.service() val settings = pluginSettings() @@ -173,30 +170,30 @@ class SnykTaskQueueServiceTest : LightPlatformTestCase() { settings.token = "testToken" snykTaskQueueService.scan() + PlatformTestUtil.dispatchAllInvocationEventsInIdeEventQueue() verify { snykApiServiceMock.getSastSettings() } } - @Test fun `test reportFalsePositivesEnabled should be unknown in initial settings state`() { val settings = pluginSettings() assertNull(settings.reportFalsePositivesEnabled) } - @Test fun `test LCE should be unknown in initial settings state`() { val settings = pluginSettings() assertNull(settings.localCodeEngineEnabled) } - @Test fun `test should disable Code settings when LCE is enabled`() { val snykTaskQueueService = project.service() val settings = pluginSettings() settings.sastOnServerEnabled = true settings.localCodeEngineEnabled = true + settings.snykCodeQualityIssuesScanEnable = true + settings.snykCodeSecurityIssuesScanEnable = true settings.token = "testToken" // overwrite default setup snykApiServiceMock = mockk(relaxed = true) @@ -208,6 +205,7 @@ class SnykTaskQueueServiceTest : LightPlatformTestCase() { ) snykTaskQueueService.scan() + PlatformTestUtil.dispatchAllInvocationEventsInIdeEventQueue() assertThat(settings.snykCodeSecurityIssuesScanEnable, equalTo(false)) assertThat(settings.snykCodeQualityIssuesScanEnable, equalTo(false)) @@ -218,7 +216,6 @@ class SnykTaskQueueServiceTest : LightPlatformTestCase() { application.replaceService(SnykApiService::class.java, snykApiServiceMock, application) } - @Test fun testIacScanTriggeredAndProduceResults() { val snykTaskQueueService = project.service() val settings = pluginSettings() @@ -236,11 +233,11 @@ class SnykTaskQueueServiceTest : LightPlatformTestCase() { every { getIacService(project)?.scan() } returns fakeIacResult snykTaskQueueService.scan() + PlatformTestUtil.dispatchAllInvocationEventsInIdeEventQueue() assertEquals(fakeIacResult, getSnykCachedResults(project)?.currentIacResult) } - @Test fun testContainerScanTriggeredAndProduceResults() { mockkStatic("io.snyk.plugin.UtilsKt") every { isContainerEnabled() } returns true @@ -259,6 +256,7 @@ class SnykTaskQueueServiceTest : LightPlatformTestCase() { getSnykCachedResults(project)?.currentContainerResult = null snykTaskQueueService.scan() + PlatformTestUtil.dispatchAllInvocationEventsInIdeEventQueue() await().atMost(2, TimeUnit.SECONDS).until { getSnykCachedResults(project)?.currentContainerResult != null diff --git a/src/integTest/kotlin/io/snyk/plugin/services/download/CliDownloaderErrorHandlerIntegTest.kt b/src/test/kotlin/io/snyk/plugin/services/download/CliDownloaderErrorHandlerIntegTest.kt similarity index 100% rename from src/integTest/kotlin/io/snyk/plugin/services/download/CliDownloaderErrorHandlerIntegTest.kt rename to src/test/kotlin/io/snyk/plugin/services/download/CliDownloaderErrorHandlerIntegTest.kt diff --git a/src/integTest/kotlin/io/snyk/plugin/services/download/CliDownloaderServiceIntegTest.kt b/src/test/kotlin/io/snyk/plugin/services/download/CliDownloaderServiceIntegTest.kt similarity index 100% rename from src/integTest/kotlin/io/snyk/plugin/services/download/CliDownloaderServiceIntegTest.kt rename to src/test/kotlin/io/snyk/plugin/services/download/CliDownloaderServiceIntegTest.kt diff --git a/src/integTest/kotlin/io/snyk/plugin/ui/toolwindow/ReportFalsePositiveDialogIntegTest.kt b/src/test/kotlin/io/snyk/plugin/ui/toolwindow/ReportFalsePositiveDialogIntegTest.kt similarity index 100% rename from src/integTest/kotlin/io/snyk/plugin/ui/toolwindow/ReportFalsePositiveDialogIntegTest.kt rename to src/test/kotlin/io/snyk/plugin/ui/toolwindow/ReportFalsePositiveDialogIntegTest.kt index 06ff547d9..ed40299f3 100644 --- a/src/integTest/kotlin/io/snyk/plugin/ui/toolwindow/ReportFalsePositiveDialogIntegTest.kt +++ b/src/test/kotlin/io/snyk/plugin/ui/toolwindow/ReportFalsePositiveDialogIntegTest.kt @@ -1,6 +1,5 @@ package io.snyk.plugin.ui.toolwindow -import snyk.common.UIComponentFinder import com.intellij.CommonBundle import com.intellij.openapi.ui.DialogWrapper.CLOSE_EXIT_CODE import com.intellij.testFramework.fixtures.BasePlatformTestCase @@ -9,6 +8,7 @@ import io.snyk.plugin.ui.toolwindow.ReportFalsePositiveDialog.Companion.REPORT_F import io.snyk.plugin.ui.toolwindow.ReportFalsePositiveDialog.Companion.TITLE_TEXT import io.snyk.plugin.ui.toolwindow.ReportFalsePositiveDialog.Companion.WARN_MESSAGE_TEXT import org.junit.Test +import snyk.common.UIComponentFinder import javax.swing.Action import javax.swing.JPanel diff --git a/src/integTest/kotlin/io/snyk/plugin/ui/toolwindow/SnykAuthPanelIntegTest.kt b/src/test/kotlin/io/snyk/plugin/ui/toolwindow/SnykAuthPanelIntegTest.kt similarity index 99% rename from src/integTest/kotlin/io/snyk/plugin/ui/toolwindow/SnykAuthPanelIntegTest.kt rename to src/test/kotlin/io/snyk/plugin/ui/toolwindow/SnykAuthPanelIntegTest.kt index 4a5cf6195..1cf52633f 100644 --- a/src/integTest/kotlin/io/snyk/plugin/ui/toolwindow/SnykAuthPanelIntegTest.kt +++ b/src/test/kotlin/io/snyk/plugin/ui/toolwindow/SnykAuthPanelIntegTest.kt @@ -1,6 +1,5 @@ package io.snyk.plugin.ui.toolwindow -import snyk.common.UIComponentFinder import com.intellij.openapi.application.ApplicationManager import com.intellij.testFramework.LightPlatform4TestCase import com.intellij.testFramework.replaceService @@ -13,6 +12,7 @@ import io.snyk.plugin.services.SnykAnalyticsService import io.snyk.plugin.services.SnykCliAuthenticationService import io.snyk.plugin.ui.toolwindow.panels.SnykAuthPanel import org.junit.Test +import snyk.common.UIComponentFinder import snyk.trust.WorkspaceTrustService import snyk.trust.confirmScanningAndSetWorkspaceTrustedStateIfNeeded import javax.swing.JButton @@ -28,7 +28,7 @@ class SnykAuthPanelIntegTest : LightPlatform4TestCase() { super.setUp() unmockkAll() mockkStatic("snyk.trust.TrustedProjectsKt") - every { confirmScanningAndSetWorkspaceTrustedStateIfNeeded(any()) } returns true + every { confirmScanningAndSetWorkspaceTrustedStateIfNeeded(any(), any()) } returns true val application = ApplicationManager.getApplication() application.replaceService(SnykAnalyticsService::class.java, analyticsService, application) application.replaceService(WorkspaceTrustService::class.java, workspaceTrustServiceMock, application) diff --git a/src/integTest/kotlin/io/snyk/plugin/ui/toolwindow/SnykToolWindowPanelIntegTest.kt b/src/test/kotlin/io/snyk/plugin/ui/toolwindow/SnykToolWindowPanelIntegTest.kt similarity index 98% rename from src/integTest/kotlin/io/snyk/plugin/ui/toolwindow/SnykToolWindowPanelIntegTest.kt rename to src/test/kotlin/io/snyk/plugin/ui/toolwindow/SnykToolWindowPanelIntegTest.kt index b22c33f8f..a759928d0 100644 --- a/src/integTest/kotlin/io/snyk/plugin/ui/toolwindow/SnykToolWindowPanelIntegTest.kt +++ b/src/test/kotlin/io/snyk/plugin/ui/toolwindow/SnykToolWindowPanelIntegTest.kt @@ -1,10 +1,8 @@ package io.snyk.plugin.ui.toolwindow import ai.deepcode.javaclient.core.SuggestionForFile -import snyk.common.UIComponentFinder import com.intellij.mock.MockVirtualFile import com.intellij.openapi.actionSystem.ActionManager -import com.intellij.openapi.application.impl.ApplicationInfoImpl import com.intellij.openapi.components.service import com.intellij.testFramework.HeavyPlatformTestCase import com.intellij.testFramework.PlatformTestUtil @@ -47,6 +45,7 @@ import io.snyk.plugin.ui.toolwindow.panels.SuggestionDescriptionPanel import io.snyk.plugin.ui.toolwindow.panels.VulnerabilityDescriptionPanel import org.junit.Test import snyk.common.SnykError +import snyk.common.UIComponentFinder import snyk.container.ContainerIssue import snyk.container.ContainerIssuesForImage import snyk.container.ContainerResult @@ -102,7 +101,7 @@ class SnykToolWindowPanelIntegTest : HeavyPlatformTestCase() { // also we MUST do it *before* any actual test code due to initialisation of SnykScanListener in init{} toolWindowPanel = project.service() setupDummyCliFile() - every { confirmScanningAndSetWorkspaceTrustedStateIfNeeded(any()) } returns true + every { confirmScanningAndSetWorkspaceTrustedStateIfNeeded(any(), any()) } returns true } override fun tearDown() { @@ -556,7 +555,7 @@ class SnykToolWindowPanelIntegTest : HeavyPlatformTestCase() { val mediumSeverityFilterAction = ActionManager.getInstance().getAction("io.snyk.plugin.ui.actions.SnykTreeMediumSeverityFilterAction") as SnykTreeMediumSeverityFilterAction - mediumSeverityFilterAction.setSelected(TestActionEvent(), false) + mediumSeverityFilterAction.setSelected(TestActionEvent.createTestEvent(), false) PlatformTestUtil.waitWhileBusy(toolWindowPanel.getTree()) @@ -885,15 +884,7 @@ class SnykToolWindowPanelIntegTest : HeavyPlatformTestCase() { private fun waitWhileTreeBusy() { val tree = toolWindowPanel.getTree() - // hack to avoid "File accessed outside allowed roots" check in tests - // needed due to com.intellij.openapi.vfs.newvfs.impl.VfsRootAccess.assertAccessInTests - val prevIsInStressTest = ApplicationInfoImpl.isInStressTest() - ApplicationInfoImpl.setInStressTest(true) - try { - PlatformTestUtil.waitWhileBusy(tree) - } finally { - ApplicationInfoImpl.setInStressTest(prevIsInStressTest) - } + PlatformTestUtil.waitWhileBusy(tree) } @Test diff --git a/src/integTest/kotlin/io/snyk/plugin/ui/toolwindow/SuggestionDescriptionPanelIntegTest.kt b/src/test/kotlin/io/snyk/plugin/ui/toolwindow/SuggestionDescriptionPanelIntegTest.kt similarity index 100% rename from src/integTest/kotlin/io/snyk/plugin/ui/toolwindow/SuggestionDescriptionPanelIntegTest.kt rename to src/test/kotlin/io/snyk/plugin/ui/toolwindow/SuggestionDescriptionPanelIntegTest.kt index f923cb3ed..c65ddd77e 100644 --- a/src/integTest/kotlin/io/snyk/plugin/ui/toolwindow/SuggestionDescriptionPanelIntegTest.kt +++ b/src/test/kotlin/io/snyk/plugin/ui/toolwindow/SuggestionDescriptionPanelIntegTest.kt @@ -1,6 +1,5 @@ package io.snyk.plugin.ui.toolwindow -import snyk.common.UIComponentFinder import ai.deepcode.javaclient.core.SuggestionForFile import com.intellij.openapi.util.registry.Registry import com.intellij.testFramework.fixtures.BasePlatformTestCase @@ -9,6 +8,7 @@ import io.snyk.plugin.snykcode.core.SnykCodeFile import io.snyk.plugin.ui.toolwindow.ReportFalsePositiveDialog.Companion.REPORT_FALSE_POSITIVE_TEXT import io.snyk.plugin.ui.toolwindow.panels.SuggestionDescriptionPanel import org.junit.Test +import snyk.common.UIComponentFinder import javax.swing.JButton @Suppress("FunctionName") diff --git a/src/integTest/kotlin/io/snyk/plugin/ui/toolwindow/settings/ScanTypesPanelTest.kt b/src/test/kotlin/io/snyk/plugin/ui/toolwindow/settings/ScanTypesPanelTest.kt similarity index 100% rename from src/integTest/kotlin/io/snyk/plugin/ui/toolwindow/settings/ScanTypesPanelTest.kt rename to src/test/kotlin/io/snyk/plugin/ui/toolwindow/settings/ScanTypesPanelTest.kt index 6083b6ecf..d8de9549c 100644 --- a/src/integTest/kotlin/io/snyk/plugin/ui/toolwindow/settings/ScanTypesPanelTest.kt +++ b/src/test/kotlin/io/snyk/plugin/ui/toolwindow/settings/ScanTypesPanelTest.kt @@ -1,6 +1,5 @@ package io.snyk.plugin.ui.toolwindow.settings -import snyk.common.UIComponentFinder.getComponentByName import com.intellij.openapi.Disposable import com.intellij.openapi.util.Disposer import com.intellij.testFramework.LightPlatform4TestCase @@ -17,6 +16,7 @@ import io.snyk.plugin.resetSettings import io.snyk.plugin.ui.settings.ScanTypesPanel import org.junit.Test import snyk.common.ProductType +import snyk.common.UIComponentFinder.getComponentByName import snyk.common.isSnykCodeAvailable import snyk.container.KubernetesImageCache diff --git a/src/integTest/kotlin/snyk/advisor/PackageNameProviderTest.kt b/src/test/kotlin/snyk/advisor/PackageNameProviderTest.kt similarity index 100% rename from src/integTest/kotlin/snyk/advisor/PackageNameProviderTest.kt rename to src/test/kotlin/snyk/advisor/PackageNameProviderTest.kt diff --git a/src/integTest/kotlin/snyk/advisor/SnykAdvisorModelTest.kt b/src/test/kotlin/snyk/advisor/SnykAdvisorModelTest.kt similarity index 100% rename from src/integTest/kotlin/snyk/advisor/SnykAdvisorModelTest.kt rename to src/test/kotlin/snyk/advisor/SnykAdvisorModelTest.kt diff --git a/src/test/kotlin/snyk/advisor/api/AdvisorApiClientTest.kt b/src/test/kotlin/snyk/advisor/api/AdvisorApiClientTest.kt index d3e95cdf4..a0db908ee 100644 --- a/src/test/kotlin/snyk/advisor/api/AdvisorApiClientTest.kt +++ b/src/test/kotlin/snyk/advisor/api/AdvisorApiClientTest.kt @@ -1,30 +1,42 @@ package snyk.advisor.api import com.google.gson.Gson +import io.mockk.every +import io.mockk.mockkStatic +import io.mockk.unmockkAll +import io.snyk.plugin.services.SnykApplicationSettingsStateService import okhttp3.mockwebserver.MockResponse import okhttp3.mockwebserver.MockWebServer import okio.buffer import okio.source -import org.hamcrest.collection.IsCollectionWithSize.hasSize -import org.hamcrest.core.IsEqual.equalTo -import org.hamcrest.core.IsNull.notNullValue -import org.hamcrest.core.IsNull.nullValue -import org.junit.Assert.assertThat +import org.junit.Assert.assertEquals +import org.junit.Assert.assertNotNull +import org.junit.Assert.assertNull import org.junit.Before -import org.junit.Rule import org.junit.Test +import snyk.PluginInformation import snyk.advisor.AdvisorPackageManager +import snyk.pluginInfo import java.nio.charset.StandardCharsets class AdvisorApiClientTest { - @JvmField - @Rule - val server: MockWebServer = MockWebServer() - private lateinit var clientUnderTest: AdvisorApiClient + private val server = MockWebServer() + private lateinit var settings: SnykApplicationSettingsStateService + @Before fun setUp() { - clientUnderTest = AdvisorApiClient(server.url("/").toString()) + unmockkAll() + mockkStatic("snyk.PluginInformationKt") + val pluginInformation = PluginInformation( + "testIntegrationName", + "testIntegrationVersion", + "testIntegrationEnvironment", + "testIntegrationEnvironmentVersion" + ) + every { pluginInfo } returns pluginInformation + settings = SnykApplicationSettingsStateService() + clientUnderTest = AdvisorApiClient(server.url("/").toString(), settings) } @Test @@ -34,7 +46,7 @@ class AdvisorApiClientTest { val response = advisorScoreService.scoresNpmPackages(listOf()).execute() - assertThat(response.code(), equalTo(404)) + assertEquals(404, response.code()) } @Test @@ -51,25 +63,25 @@ class AdvisorApiClientTest { val response = advisorScoreService.scoresNpmPackages(listOf()).execute() // asserts - assertThat(response.code(), equalTo(200)) + assertEquals(200, response.code()) val npmPackagesInfo = response.body() - assertThat(npmPackagesInfo, notNullValue()) - assertThat(npmPackagesInfo, hasSize(2)) + assertNotNull(npmPackagesInfo) + assertEquals(2, npmPackagesInfo?.size) val jqueryPackageInfo = npmPackagesInfo?.first() - assertThat(jqueryPackageInfo?.name, equalTo("jquery")) - assertThat(jqueryPackageInfo?.score, equalTo(0.97142857)) - assertThat(jqueryPackageInfo?.pending, equalTo(false)) - assertThat(jqueryPackageInfo?.error, nullValue()) - assertThat(jqueryPackageInfo?.labels, equalTo(expectedPackageInfoLabels)) + assertEquals("jquery", jqueryPackageInfo?.name) + assertEquals(0.97142857, jqueryPackageInfo?.score) + assertEquals(false, jqueryPackageInfo?.pending) + assertNull(jqueryPackageInfo?.error) + assertEquals(expectedPackageInfoLabels, jqueryPackageInfo?.labels) val vuePackageInfo = npmPackagesInfo?.last() - assertThat(vuePackageInfo?.name, equalTo("vue")) - assertThat(vuePackageInfo?.score, equalTo(0.9475)) - assertThat(vuePackageInfo?.pending, equalTo(true)) - assertThat(vuePackageInfo?.error, nullValue()) - assertThat(vuePackageInfo?.labels, equalTo(expectedPackageInfoLabels)) + assertEquals("vue", vuePackageInfo?.name) + assertEquals(0.9475, vuePackageInfo?.score) + assertEquals(true, vuePackageInfo?.pending) + assertNull(vuePackageInfo?.error) + assertEquals(expectedPackageInfoLabels, vuePackageInfo?.labels) } @Test @@ -80,15 +92,15 @@ class AdvisorApiClientTest { val response = advisorScoreService.scoresPythonPackages(listOf("non-existing-package")).execute() // asserts - assertThat(response.code(), equalTo(200)) + assertEquals(200, response.code()) val npmPackagesInfo = response.body() - assertThat(npmPackagesInfo, notNullValue()) - assertThat(npmPackagesInfo, hasSize(1)) + assertNotNull(npmPackagesInfo) + assertEquals(1, npmPackagesInfo?.size) val nonExistingPackageInfo = npmPackagesInfo?.first() - assertThat(nonExistingPackageInfo?.name, equalTo("non-existing-package")) - assertThat(nonExistingPackageInfo?.error, equalTo("not found")) + assertEquals("non-existing-package", nonExistingPackageInfo?.name) + assertEquals("not found", nonExistingPackageInfo?.error) } @Test @@ -98,7 +110,7 @@ class AdvisorApiClientTest { val response = advisorScoreService.scoresPythonPackages(listOf()).execute() - assertThat(response.code(), equalTo(404)) + assertEquals(404, response.code()) } @Test @@ -115,25 +127,25 @@ class AdvisorApiClientTest { val response = advisorScoreService.scoresNpmPackages(listOf()).execute() // asserts - assertThat(response.code(), equalTo(200)) + assertEquals(200, response.code()) val pythonPackageInfo = response.body() - assertThat(pythonPackageInfo, notNullValue()) - assertThat(pythonPackageInfo, hasSize(2)) + assertNotNull(pythonPackageInfo) + assertEquals(2, pythonPackageInfo?.size) val djangoPackageInfo = pythonPackageInfo?.first() - assertThat(djangoPackageInfo?.name, equalTo("django")) - assertThat(djangoPackageInfo?.score, equalTo(0.9114285714285715)) - assertThat(djangoPackageInfo?.pending, equalTo(false)) - assertThat(djangoPackageInfo?.error, nullValue()) - assertThat(djangoPackageInfo?.labels, equalTo(expectedPackageInfoLabels)) + assertEquals("django", djangoPackageInfo?.name) + assertEquals(0.9114285714285715, djangoPackageInfo?.score) + assertEquals(false, djangoPackageInfo?.pending) + assertNull(djangoPackageInfo?.error) + assertEquals(expectedPackageInfoLabels, djangoPackageInfo?.labels) val tomlPackageInfo = pythonPackageInfo?.last() - assertThat(tomlPackageInfo?.name, equalTo("toml")) - assertThat(tomlPackageInfo?.score, equalTo(0.8678571428571429)) - assertThat(tomlPackageInfo?.pending, equalTo(true)) - assertThat(tomlPackageInfo?.error, nullValue()) - assertThat(tomlPackageInfo?.labels, equalTo(expectedPackageInfoLabels)) + assertEquals("toml", tomlPackageInfo?.name) + assertEquals(0.8678571428571429, tomlPackageInfo?.score) + assertEquals(true, tomlPackageInfo?.pending) + assertNull(tomlPackageInfo?.error) + assertEquals(expectedPackageInfoLabels, tomlPackageInfo?.labels) } @Test @@ -144,15 +156,15 @@ class AdvisorApiClientTest { val response = advisorScoreService.scoresPythonPackages(listOf("non-existing-package")).execute() // asserts - assertThat(response.code(), equalTo(200)) + assertEquals(200, response.code()) val pythonPackagesInfo = response.body() - assertThat(pythonPackagesInfo, notNullValue()) - assertThat(pythonPackagesInfo, hasSize(1)) + assertNotNull(pythonPackagesInfo) + assertEquals(1, pythonPackagesInfo?.size) val nonExistingPackageInfo = pythonPackagesInfo?.first() - assertThat(nonExistingPackageInfo?.name, equalTo("non-existing-package")) - assertThat(nonExistingPackageInfo?.error, equalTo("not found")) + assertEquals("non-existing-package", nonExistingPackageInfo?.name) + assertEquals("not found", nonExistingPackageInfo?.error) } @Test @@ -175,11 +187,11 @@ class AdvisorApiClientTest { } private fun assertInfos(expectedInfos: List, actualInfos: List?) { - assertThat(actualInfos, notNullValue()) - assertThat(actualInfos, hasSize(expectedInfos.size)) + assertNotNull(actualInfos) + assertEquals(expectedInfos.size, actualInfos?.size) actualInfos?.forEachIndexed { index, actual -> - assertThat(actual, equalTo(expectedInfos[index])) + assertEquals(expectedInfos[index], actual) } } } diff --git a/src/integTest/kotlin/snyk/code/annotator/SnykCodeAnnotatorTest.kt b/src/test/kotlin/snyk/code/annotator/SnykCodeAnnotatorTest.kt similarity index 100% rename from src/integTest/kotlin/snyk/code/annotator/SnykCodeAnnotatorTest.kt rename to src/test/kotlin/snyk/code/annotator/SnykCodeAnnotatorTest.kt diff --git a/src/integTest/kotlin/snyk/common/AnnotatorCommonIntegTest.kt b/src/test/kotlin/snyk/common/AnnotatorCommonIntegTest.kt similarity index 100% rename from src/integTest/kotlin/snyk/common/AnnotatorCommonIntegTest.kt rename to src/test/kotlin/snyk/common/AnnotatorCommonIntegTest.kt diff --git a/src/integTest/kotlin/snyk/common/intentionactions/AlwaysAvailableReplacementIntentionActionTest.kt b/src/test/kotlin/snyk/common/intentionactions/AlwaysAvailableReplacementIntentionActionTest.kt similarity index 100% rename from src/integTest/kotlin/snyk/common/intentionactions/AlwaysAvailableReplacementIntentionActionTest.kt rename to src/test/kotlin/snyk/common/intentionactions/AlwaysAvailableReplacementIntentionActionTest.kt diff --git a/src/integTest/kotlin/snyk/container/ContainerBulkFileListenerTest.kt b/src/test/kotlin/snyk/container/ContainerBulkFileListenerTest.kt similarity index 89% rename from src/integTest/kotlin/snyk/container/ContainerBulkFileListenerTest.kt rename to src/test/kotlin/snyk/container/ContainerBulkFileListenerTest.kt index ae8cc69b9..8bcd70fc0 100644 --- a/src/integTest/kotlin/snyk/container/ContainerBulkFileListenerTest.kt +++ b/src/test/kotlin/snyk/container/ContainerBulkFileListenerTest.kt @@ -10,22 +10,23 @@ import com.intellij.openapi.vfs.newvfs.events.VFileEvent import com.intellij.psi.PsiDocumentManager import com.intellij.psi.PsiFile import com.intellij.psi.PsiManager +import com.intellij.testFramework.PlatformTestUtil import com.intellij.testFramework.fixtures.BasePlatformTestCase import com.intellij.util.io.createDirectories import com.intellij.util.io.delete -import com.intellij.util.io.exists import io.mockk.unmockkAll import io.snyk.plugin.getKubernetesImageCache import io.snyk.plugin.getSnykCachedResults import io.snyk.plugin.resetSettings import io.snyk.plugin.ui.toolwindow.SnykToolWindowPanel import org.awaitility.Awaitility.await -import org.junit.Test import snyk.container.ui.ContainerImageTreeNode import java.io.File import java.nio.file.Files +import java.nio.file.LinkOption import java.nio.file.Paths import java.util.concurrent.TimeUnit +import kotlin.io.path.notExists @Suppress("FunctionName") class ContainerBulkFileListenerTest : BasePlatformTestCase() { @@ -50,13 +51,12 @@ class ContainerBulkFileListenerTest : BasePlatformTestCase() { private fun createNewFileInProjectRoot(name: String): File { val projectPath = Paths.get(project.basePath!!) - if (!projectPath.exists()) { + if (projectPath.notExists(LinkOption.NOFOLLOW_LINKS)) { projectPath.createDirectories() } return File(project.basePath + File.separator + name).apply { createNewFile() } } - @Test fun `test Container should update image cache when yaml file is changed`() { setUpContainerTest() val path = createNewFileInProjectRoot("kubernetes-test.yaml").toPath() @@ -71,10 +71,13 @@ class ContainerBulkFileListenerTest : BasePlatformTestCase() { ?.setText(TestYamls.podYaml()) } FileDocumentManager.getInstance().saveAllDocuments() + PlatformTestUtil.dispatchAllInvocationEventsInIdeEventQueue() - val kubernetesWorkloadImages = imageCache.getKubernetesWorkloadImages() - - assertNotNull(kubernetesWorkloadImages) + var kubernetesWorkloadImages = imageCache.getKubernetesWorkloadImages() + await().atMost(5, TimeUnit.SECONDS).until { + kubernetesWorkloadImages = imageCache.getKubernetesWorkloadImages() + kubernetesWorkloadImages.isNotEmpty() + } assertNotEmpty(kubernetesWorkloadImages) assertEquals(1, kubernetesWorkloadImages.size) assertEquals(path, kubernetesWorkloadImages.first().virtualFile.toNioPath()) @@ -82,7 +85,6 @@ class ContainerBulkFileListenerTest : BasePlatformTestCase() { virtualFile.toNioPath().delete(true) } - @Test fun `test Container should delete images from cache when yaml file is deleted`() { setUpContainerTest() val file = myFixture.addFileToProject("kubernetes-test.yaml", "") @@ -92,13 +94,23 @@ class ContainerBulkFileListenerTest : BasePlatformTestCase() { ?.setText(TestYamls.podYaml()) } FileDocumentManager.getInstance().saveAllDocuments() - assertNotEmpty(imageCache.getKubernetesWorkloadImages()) + PlatformTestUtil.dispatchAllInvocationEventsInIdeEventQueue() + + var kubernetesWorkloadImages: Set + await().atMost(5, TimeUnit.SECONDS).until { + kubernetesWorkloadImages = imageCache.getKubernetesWorkloadImages() + kubernetesWorkloadImages.isNotEmpty() + } ApplicationManager.getApplication().runWriteAction { file.virtualFile.delete(null) } FileDocumentManager.getInstance().saveAllDocuments() - assertEmpty(imageCache.getKubernetesWorkloadImages()) + PlatformTestUtil.dispatchAllInvocationEventsInIdeEventQueue() + + await().atMost(5, TimeUnit.SECONDS).until { + imageCache.getKubernetesWorkloadImages().isEmpty() + } } /** @@ -132,20 +144,21 @@ class ContainerBulkFileListenerTest : BasePlatformTestCase() { uniqueCount = 1, error = null, imageName = "nginx", - workloadImages = listOf(KubernetesWorkloadImage( - image = "nginx", - virtualFile = addedPsiFile.virtualFile - )) + workloadImages = listOf( + KubernetesWorkloadImage( + image = "nginx", + virtualFile = addedPsiFile.virtualFile + ) + ) ) val fakeContainerResult = ContainerResult(listOf(issuesForImage)) val toolWindowPanel = project.service() getSnykCachedResults(project)?.currentContainerResult = fakeContainerResult toolWindowPanel.getRootContainerIssuesTreeNode().add(ContainerImageTreeNode(issuesForImage, project) {}) - getKubernetesImageCache(project)?.extractFromFile(addedPsiFile.virtualFile) + getKubernetesImageCache(project)?.extractFromFileAndAddToCache(addedPsiFile.virtualFile) } - @Test fun `test ContainerResults should drop cache and mark rescanNeeded when Container supported file CHANGED`() { setUpContainerTest() val psiFile = myFixture.configureByText("existing.yaml", TestYamls.podYaml()) @@ -162,7 +175,6 @@ class ContainerBulkFileListenerTest : BasePlatformTestCase() { await().atMost(2, TimeUnit.SECONDS).until { containerCacheInvalidatedForFile(psiFile) } } - @Test fun `test ContainerResults should mark rescanNeeded when Container supported file CREATED`() { setUpContainerTest() createFakeContainerResultInCache() @@ -178,7 +190,6 @@ class ContainerBulkFileListenerTest : BasePlatformTestCase() { ) } - @Test fun `test ContainerResults should mark rescanNeeded when Container supported file COPIED`() { setUpContainerTest() val originalFile = myFixture.addFileToProject("existing.yaml", TestYamls.podYaml()) @@ -199,7 +210,6 @@ class ContainerBulkFileListenerTest : BasePlatformTestCase() { ) } - @Test fun `test ContainerResults should drop cache and mark rescanNeeded when Container supported file MOVED`() { setUpContainerTest() val originalFile = myFixture.addFileToProject("existing.yaml", TestYamls.podYaml()) @@ -219,7 +229,6 @@ class ContainerBulkFileListenerTest : BasePlatformTestCase() { ) } - @Test fun `test ContainerResults should drop cache and mark rescanNeeded when Container supported file RENAMED`() { setUpContainerTest() val originalFile = myFixture.addFileToProject("existing.yaml", TestYamls.podYaml()) @@ -238,7 +247,6 @@ class ContainerBulkFileListenerTest : BasePlatformTestCase() { ) } - @Test fun `test ContainerResults should drop cache and mark rescanNeeded when Container supported file DELETED`() { setUpContainerTest() val originalFile = myFixture.addFileToProject("existing.yaml", TestYamls.podYaml()) @@ -257,7 +265,6 @@ class ContainerBulkFileListenerTest : BasePlatformTestCase() { ) } - @Test fun `test ContainerResults should drop cache and mark rescanNeeded when cached file wiped it content`() { setUpContainerTest() val psiFile = myFixture.addFileToProject("existing.yaml", TestYamls.podYaml()) @@ -276,7 +283,6 @@ class ContainerBulkFileListenerTest : BasePlatformTestCase() { ) } - @Test fun `test Container should update cache even if any other cache update fail with Exception`() { setUpContainerTest() val psiFile = myFixture.configureByText("existing.yaml", TestYamls.podYaml()) @@ -294,7 +300,7 @@ class ContainerBulkFileListenerTest : BasePlatformTestCase() { exceptionThrown = try { FileDocumentManager.getInstance().saveAllDocuments() false - } catch (e: ControlException) { + } catch (e: RuntimeException) { true } } finally { diff --git a/src/integTest/kotlin/snyk/container/ContainerServiceIntegTest.kt b/src/test/kotlin/snyk/container/ContainerServiceIntegTest.kt similarity index 98% rename from src/integTest/kotlin/snyk/container/ContainerServiceIntegTest.kt rename to src/test/kotlin/snyk/container/ContainerServiceIntegTest.kt index 0ba4f3c9a..03949b80a 100644 --- a/src/integTest/kotlin/snyk/container/ContainerServiceIntegTest.kt +++ b/src/test/kotlin/snyk/container/ContainerServiceIntegTest.kt @@ -101,7 +101,7 @@ class ContainerServiceIntegTest : LightPlatform4TestCase() { verify { cache.getKubernetesWorkloadImages() } assertEquals( expectedContainerResult.issuesCount, - scanResult.allCliIssues?.sumBy { it.groupedVulnsById.size } + scanResult.allCliIssues?.sumOf { it.groupedVulnsById.size } ) return Pair(expectedContainerResult, scanResult) } @@ -111,7 +111,7 @@ class ContainerServiceIntegTest : LightPlatform4TestCase() { val file = createFile(fileName, podYaml()) val cache = spyk(KubernetesImageCache(project)) cut.setKubernetesImageCache(cache) - cache.extractFromFile(file.virtualFile) + cache.extractFromFileAndAddToCache(file.virtualFile) return cache } diff --git a/src/integTest/kotlin/snyk/container/KubernetesImageCacheIntegTest.kt b/src/test/kotlin/snyk/container/KubernetesImageCacheIntegTest.kt similarity index 92% rename from src/integTest/kotlin/snyk/container/KubernetesImageCacheIntegTest.kt rename to src/test/kotlin/snyk/container/KubernetesImageCacheIntegTest.kt index b1bba33bc..af7a85968 100644 --- a/src/integTest/kotlin/snyk/container/KubernetesImageCacheIntegTest.kt +++ b/src/test/kotlin/snyk/container/KubernetesImageCacheIntegTest.kt @@ -51,7 +51,7 @@ class KubernetesImageCacheIntegTest : LightPlatform4TestCase() { @Test fun `extractFromFile should find yaml files and extract images`() { val file = createFile(fileName, podYaml()).virtualFile - cut.extractFromFile(file) + cut.extractFromFileAndAddToCache(file) val images = cut.getKubernetesWorkloadImages() assertEquals(1, images.size) @@ -149,7 +149,7 @@ class KubernetesImageCacheIntegTest : LightPlatform4TestCase() { fun `should return Kubernetes Workload Files`() { val file = createFile(fileName, podYaml()).virtualFile - cut.extractFromFile(file) + cut.extractFromFileAndAddToCache(file) val files: Set = cut.getKubernetesWorkloadFilesFromCache() assertEquals(1, files.size) @@ -160,7 +160,7 @@ class KubernetesImageCacheIntegTest : LightPlatform4TestCase() { fun `should not parse non yaml files`() { val file = createFile("not-a-yaml-file.zaml", podYaml()).virtualFile - cut.extractFromFile(file) + cut.extractFromFileAndAddToCache(file) val files: Set = cut.getKubernetesWorkloadFilesFromCache() assertEmpty(files) @@ -170,7 +170,7 @@ class KubernetesImageCacheIntegTest : LightPlatform4TestCase() { fun `should return Kubernetes Workload Image Names`() { val file = createFile(fileName, podYaml()).virtualFile - cut.extractFromFile(file) + cut.extractFromFileAndAddToCache(file) val images: Set = cut.getKubernetesWorkloadImageNamesFromCache() assertEquals(1, images.size) @@ -181,7 +181,7 @@ class KubernetesImageCacheIntegTest : LightPlatform4TestCase() { fun `should return Kubernetes Workload Images with correct line number`() { val file = createFile(fileName, podYaml()).virtualFile - cut.extractFromFile(file) + cut.extractFromFileAndAddToCache(file) val images: Set = cut.getKubernetesWorkloadImages() assertEquals(1, images.size) @@ -192,7 +192,7 @@ class KubernetesImageCacheIntegTest : LightPlatform4TestCase() { fun `should remove file from cache when all images from file (cached before) been removed`() { val psiFile = createFile(fileName, podYaml()) val virtualFile = psiFile.virtualFile - cut.extractFromFile(virtualFile) + cut.extractFromFileAndAddToCache(virtualFile) val controlImages: Set = cut.getKubernetesWorkloadImages() assertEquals(1, controlImages.size) @@ -201,7 +201,7 @@ class KubernetesImageCacheIntegTest : LightPlatform4TestCase() { ?.setText("") } FileDocumentManager.getInstance().saveAllDocuments() - cut.extractFromFile(virtualFile) + cut.extractFromFileAndAddToCache(virtualFile) val images = cut.getKubernetesWorkloadImages() assertEquals(0, images.size) @@ -212,14 +212,14 @@ class KubernetesImageCacheIntegTest : LightPlatform4TestCase() { private fun executeExtract(yaml: String): Set { val file = createFile(fileName, yaml).virtualFile - cut.extractFromFile(file) + cut.extractFromFileAndAddToCache(file) return cut.getKubernetesWorkloadImageNamesFromCache() } @Test fun `extract images from Helm generated yaml with image names inside quotes`() { val file = createFile(fileName, helmYaml()).virtualFile - cut.extractFromFile(file) + cut.extractFromFileAndAddToCache(file) val images = cut.getKubernetesWorkloadImages() assertEquals(1, images.size) @@ -229,7 +229,7 @@ class KubernetesImageCacheIntegTest : LightPlatform4TestCase() { @Test fun `no images extracted from yaml with invalid image names`() { val file = createFile(fileName, singleQuoteImageNameBrokenYaml()).virtualFile - cut.extractFromFile(file) + cut.extractFromFileAndAddToCache(file) val images = cut.getKubernetesWorkloadImages() assertEquals(0, images.size) @@ -239,7 +239,7 @@ class KubernetesImageCacheIntegTest : LightPlatform4TestCase() { fun `distinct Kubernetes Workload Image Names for calling CLI`() { val file = createFile(fileName, duplicatedImageNameYaml()).virtualFile - cut.extractFromFile(file) + cut.extractFromFileAndAddToCache(file) val images: Set = cut.getKubernetesWorkloadImageNamesFromCache() assertEquals(1, images.size) @@ -250,7 +250,7 @@ class KubernetesImageCacheIntegTest : LightPlatform4TestCase() { fun `image Path followed by comment is extracted`() { val file = createFile(fileName, imagePathFollowedByCommentYaml()).virtualFile - cut.extractFromFile(file) + cut.extractFromFileAndAddToCache(file) val images: Set = cut.getKubernetesWorkloadImageNamesFromCache() assertEquals(1, images.size) @@ -261,7 +261,7 @@ class KubernetesImageCacheIntegTest : LightPlatform4TestCase() { fun `image Path commented is NOT extracted`() { val file = createFile(fileName, imagePathCommentedYaml()).virtualFile - cut.extractFromFile(file) + cut.extractFromFileAndAddToCache(file) val images: Set = cut.getKubernetesWorkloadImageNamesFromCache() assertEquals(0, images.size) @@ -271,7 +271,7 @@ class KubernetesImageCacheIntegTest : LightPlatform4TestCase() { fun `image Path with port and tag is extracted`() { val file = createFile(fileName, imagePathWithPortAndTagYaml()).virtualFile - cut.extractFromFile(file) + cut.extractFromFileAndAddToCache(file) val images: Set = cut.getKubernetesWorkloadImageNamesFromCache() assertEquals(1, images.size) @@ -282,7 +282,7 @@ class KubernetesImageCacheIntegTest : LightPlatform4TestCase() { fun `image Path with digest is extracted`() { val file = createFile(fileName, imagePathWithDigestYaml()).virtualFile - cut.extractFromFile(file) + cut.extractFromFileAndAddToCache(file) val images: Set = cut.getKubernetesWorkloadImageNamesFromCache() assertEquals(1, images.size) diff --git a/src/integTest/kotlin/snyk/container/TestYamls.kt b/src/test/kotlin/snyk/container/TestYamls.kt similarity index 100% rename from src/integTest/kotlin/snyk/container/TestYamls.kt rename to src/test/kotlin/snyk/container/TestYamls.kt diff --git a/src/integTest/kotlin/snyk/container/annotator/BaseImageRemediationFixTest.kt b/src/test/kotlin/snyk/container/annotator/BaseImageRemediationFixTest.kt similarity index 100% rename from src/integTest/kotlin/snyk/container/annotator/BaseImageRemediationFixTest.kt rename to src/test/kotlin/snyk/container/annotator/BaseImageRemediationFixTest.kt diff --git a/src/integTest/kotlin/snyk/container/annotator/ContainerYamlAnnotatorTest.kt b/src/test/kotlin/snyk/container/annotator/ContainerYamlAnnotatorTest.kt similarity index 100% rename from src/integTest/kotlin/snyk/container/annotator/ContainerYamlAnnotatorTest.kt rename to src/test/kotlin/snyk/container/annotator/ContainerYamlAnnotatorTest.kt diff --git a/src/integTest/kotlin/snyk/iac/IacBulkFileListenerTest.kt b/src/test/kotlin/snyk/iac/IacBulkFileListenerTest.kt similarity index 100% rename from src/integTest/kotlin/snyk/iac/IacBulkFileListenerTest.kt rename to src/test/kotlin/snyk/iac/IacBulkFileListenerTest.kt diff --git a/src/integTest/kotlin/snyk/iac/IacServiceTest.kt b/src/test/kotlin/snyk/iac/IacServiceTest.kt similarity index 100% rename from src/integTest/kotlin/snyk/iac/IacServiceTest.kt rename to src/test/kotlin/snyk/iac/IacServiceTest.kt diff --git a/src/integTest/kotlin/snyk/iac/annotator/IacBaseAnnotatorCase.kt b/src/test/kotlin/snyk/iac/annotator/IacBaseAnnotatorCase.kt similarity index 100% rename from src/integTest/kotlin/snyk/iac/annotator/IacBaseAnnotatorCase.kt rename to src/test/kotlin/snyk/iac/annotator/IacBaseAnnotatorCase.kt diff --git a/src/integTest/kotlin/snyk/iac/annotator/IacHclAnnotatorTest.kt b/src/test/kotlin/snyk/iac/annotator/IacHclAnnotatorTest.kt similarity index 100% rename from src/integTest/kotlin/snyk/iac/annotator/IacHclAnnotatorTest.kt rename to src/test/kotlin/snyk/iac/annotator/IacHclAnnotatorTest.kt diff --git a/src/integTest/kotlin/snyk/iac/annotator/IacJsonAnnotatorTest.kt b/src/test/kotlin/snyk/iac/annotator/IacJsonAnnotatorTest.kt similarity index 100% rename from src/integTest/kotlin/snyk/iac/annotator/IacJsonAnnotatorTest.kt rename to src/test/kotlin/snyk/iac/annotator/IacJsonAnnotatorTest.kt diff --git a/src/integTest/kotlin/snyk/iac/annotator/IacYamlAnnotatorTest.kt b/src/test/kotlin/snyk/iac/annotator/IacYamlAnnotatorTest.kt similarity index 100% rename from src/integTest/kotlin/snyk/iac/annotator/IacYamlAnnotatorTest.kt rename to src/test/kotlin/snyk/iac/annotator/IacYamlAnnotatorTest.kt diff --git a/src/integTest/kotlin/snyk/oss/OssBulkFileListenerTest.kt b/src/test/kotlin/snyk/oss/OssBulkFileListenerTest.kt similarity index 100% rename from src/integTest/kotlin/snyk/oss/OssBulkFileListenerTest.kt rename to src/test/kotlin/snyk/oss/OssBulkFileListenerTest.kt diff --git a/src/integTest/kotlin/snyk/oss/OssServiceTest.kt b/src/test/kotlin/snyk/oss/OssServiceTest.kt similarity index 100% rename from src/integTest/kotlin/snyk/oss/OssServiceTest.kt rename to src/test/kotlin/snyk/oss/OssServiceTest.kt diff --git a/src/integTest/kotlin/snyk/oss/annotator/OSSGoModAnnotatorTest.kt b/src/test/kotlin/snyk/oss/annotator/OSSGoModAnnotatorTest.kt similarity index 97% rename from src/integTest/kotlin/snyk/oss/annotator/OSSGoModAnnotatorTest.kt rename to src/test/kotlin/snyk/oss/annotator/OSSGoModAnnotatorTest.kt index a0d2b34f6..90488cdb8 100644 --- a/src/integTest/kotlin/snyk/oss/annotator/OSSGoModAnnotatorTest.kt +++ b/src/test/kotlin/snyk/oss/annotator/OSSGoModAnnotatorTest.kt @@ -18,8 +18,6 @@ import org.hamcrest.collection.IsCollectionWithSize import org.junit.Assert import org.junit.Assert.assertNotEquals import org.junit.Assert.assertThat -import org.junit.Before -import org.junit.Test import snyk.common.SnykCachedResults import snyk.common.intentionactions.AlwaysAvailableReplacementIntentionAction import snyk.oss.OssResult @@ -47,7 +45,6 @@ class OSSGoModAnnotatorTest : BasePlatformTestCase() { override fun isWriteActionRequired(): Boolean = true - @Before override fun setUp() { super.setUp() unmockkAll() @@ -64,14 +61,12 @@ class OSSGoModAnnotatorTest : BasePlatformTestCase() { super.tearDown() } - @Test fun `test getPackageName`() { val issue = createOssResultWithIssues().allCliIssues!!.first().vulnerabilities[0] val actualPackageName = cut.getIntroducingPackage(issue) assertEquals("github.com/gin-gonic/gin", actualPackageName) } - @Test fun `test getIssues should not return any issue if no oss issue exists`() { every { snykCachedResults.currentOssResults } returns null @@ -80,7 +75,6 @@ class OSSGoModAnnotatorTest : BasePlatformTestCase() { Assert.assertEquals(null, issues) } - @Test fun `test getIssues should return issues if they exist`() { every { snykCachedResults.currentOssResults } returns createOssResultWithIssues() @@ -90,7 +84,6 @@ class OSSGoModAnnotatorTest : BasePlatformTestCase() { assertThat(issues!!.vulnerabilities, IsCollectionWithSize.hasSize(11)) } - @Test fun `test apply should trigger newAnnotation call`() { every { snykCachedResults.currentOssResults } returns createOssResultWithIssues() @@ -99,7 +92,6 @@ class OSSGoModAnnotatorTest : BasePlatformTestCase() { verify { annotationHolderMock.newAnnotation(any(), any()) } } - @Test fun `test textRange`() { val ossResult = createOssResultWithIssues() val issue = ossResult.allCliIssues!!.first().vulnerabilities[0] @@ -112,7 +104,6 @@ class OSSGoModAnnotatorTest : BasePlatformTestCase() { assertEquals(expectedRange, actualRange) } - @Test fun `test annotation message should contain issue title`() { val vulnerability = createOssResultWithIssues().allCliIssues!!.first().vulnerabilities[0] @@ -121,7 +112,6 @@ class OSSGoModAnnotatorTest : BasePlatformTestCase() { assertTrue(actual.contains(vulnerability.title) && actual.contains(vulnerability.name)) } - @Test fun `test apply should not add a quickfix`() { val builderMock = mockk(relaxed = true) val result = createOssResultWithIssues() diff --git a/src/integTest/kotlin/snyk/oss/annotator/OSSGradleAnnotatorTest.kt b/src/test/kotlin/snyk/oss/annotator/OSSGradleAnnotatorTest.kt similarity index 99% rename from src/integTest/kotlin/snyk/oss/annotator/OSSGradleAnnotatorTest.kt rename to src/test/kotlin/snyk/oss/annotator/OSSGradleAnnotatorTest.kt index 1d44002c3..f1ef0aa80 100644 --- a/src/integTest/kotlin/snyk/oss/annotator/OSSGradleAnnotatorTest.kt +++ b/src/test/kotlin/snyk/oss/annotator/OSSGradleAnnotatorTest.kt @@ -1,7 +1,6 @@ package snyk.oss.annotator import com.google.gson.Gson -import com.intellij.codeInsight.intention.IntentionAction import com.intellij.lang.annotation.AnnotationBuilder import com.intellij.lang.annotation.AnnotationHolder import com.intellij.openapi.util.TextRange diff --git a/src/integTest/kotlin/snyk/oss/annotator/OSSMavenAnnotatorTest.kt b/src/test/kotlin/snyk/oss/annotator/OSSMavenAnnotatorTest.kt similarity index 98% rename from src/integTest/kotlin/snyk/oss/annotator/OSSMavenAnnotatorTest.kt rename to src/test/kotlin/snyk/oss/annotator/OSSMavenAnnotatorTest.kt index 9d3f8e881..70652e834 100644 --- a/src/integTest/kotlin/snyk/oss/annotator/OSSMavenAnnotatorTest.kt +++ b/src/test/kotlin/snyk/oss/annotator/OSSMavenAnnotatorTest.kt @@ -1,7 +1,6 @@ package snyk.oss.annotator import com.google.gson.Gson -import com.intellij.codeInsight.intention.IntentionAction import com.intellij.lang.annotation.AnnotationBuilder import com.intellij.lang.annotation.AnnotationHolder import com.intellij.openapi.application.WriteAction diff --git a/src/integTest/kotlin/snyk/oss/annotator/OSSNpmAnnotatorTest.kt b/src/test/kotlin/snyk/oss/annotator/OSSNpmAnnotatorTest.kt similarity index 100% rename from src/integTest/kotlin/snyk/oss/annotator/OSSNpmAnnotatorTest.kt rename to src/test/kotlin/snyk/oss/annotator/OSSNpmAnnotatorTest.kt diff --git a/src/integTest/kotlin/snyk/trust/WorkspaceTrustServiceTest.kt b/src/test/kotlin/snyk/trust/WorkspaceTrustServiceIntegrationTest.kt similarity index 95% rename from src/integTest/kotlin/snyk/trust/WorkspaceTrustServiceTest.kt rename to src/test/kotlin/snyk/trust/WorkspaceTrustServiceIntegrationTest.kt index f7e033817..03dbf5b7e 100644 --- a/src/integTest/kotlin/snyk/trust/WorkspaceTrustServiceTest.kt +++ b/src/test/kotlin/snyk/trust/WorkspaceTrustServiceIntegrationTest.kt @@ -15,7 +15,7 @@ import org.junit.Before import org.junit.Test import java.nio.file.Paths -class WorkspaceTrustServiceTest : BasePlatformTestCase() { +class WorkspaceTrustServiceIntegrationTest : BasePlatformTestCase() { private val workspaceTrustSettingsMock = mockk() private lateinit var cut: WorkspaceTrustService diff --git a/src/integTest/resources/AnnotatorTest.java b/src/test/resources/AnnotatorTest.java similarity index 100% rename from src/integTest/resources/AnnotatorTest.java rename to src/test/resources/AnnotatorTest.java diff --git a/src/integTest/resources/advisor-build-files/package.json b/src/test/resources/advisor-build-files/package.json similarity index 100% rename from src/integTest/resources/advisor-build-files/package.json rename to src/test/resources/advisor-build-files/package.json diff --git a/src/integTest/resources/advisor-build-files/requirements.txt b/src/test/resources/advisor-build-files/requirements.txt similarity index 100% rename from src/integTest/resources/advisor-build-files/requirements.txt rename to src/test/resources/advisor-build-files/requirements.txt diff --git a/src/integTest/resources/container-test-results/container-double-jenkins-with-path.json b/src/test/resources/container-test-results/container-double-jenkins-with-path.json similarity index 100% rename from src/integTest/resources/container-test-results/container-double-jenkins-with-path.json rename to src/test/resources/container-test-results/container-double-jenkins-with-path.json diff --git a/src/integTest/resources/container-test-results/debian-nginx-fake_critical_only.json b/src/test/resources/container-test-results/debian-nginx-fake_critical_only.json similarity index 100% rename from src/integTest/resources/container-test-results/debian-nginx-fake_critical_only.json rename to src/test/resources/container-test-results/debian-nginx-fake_critical_only.json diff --git a/src/integTest/resources/container-test-results/nginx-no-remediation.json b/src/test/resources/container-test-results/nginx-no-remediation.json similarity index 100% rename from src/integTest/resources/container-test-results/nginx-no-remediation.json rename to src/test/resources/container-test-results/nginx-no-remediation.json diff --git a/src/integTest/resources/container-test-results/nginx-with-remediation.json b/src/test/resources/container-test-results/nginx-with-remediation.json similarity index 100% rename from src/integTest/resources/container-test-results/nginx-with-remediation.json rename to src/test/resources/container-test-results/nginx-with-remediation.json diff --git a/src/integTest/resources/group-vulnerabilities-goof-test.json b/src/test/resources/group-vulnerabilities-goof-test.json similarity index 100% rename from src/integTest/resources/group-vulnerabilities-goof-test.json rename to src/test/resources/group-vulnerabilities-goof-test.json diff --git a/src/integTest/resources/group-vulnerabilities-test.json b/src/test/resources/group-vulnerabilities-test.json similarity index 100% rename from src/integTest/resources/group-vulnerabilities-test.json rename to src/test/resources/group-vulnerabilities-test.json diff --git a/src/integTest/resources/iac-test-results/fargate.json b/src/test/resources/iac-test-results/fargate.json similarity index 100% rename from src/integTest/resources/iac-test-results/fargate.json rename to src/test/resources/iac-test-results/fargate.json diff --git a/src/integTest/resources/iac-test-results/infrastructure-as-code-goof.json b/src/test/resources/iac-test-results/infrastructure-as-code-goof.json similarity index 100% rename from src/integTest/resources/iac-test-results/infrastructure-as-code-goof.json rename to src/test/resources/iac-test-results/infrastructure-as-code-goof.json diff --git a/src/integTest/resources/licence-vulnerabilities.json b/src/test/resources/licence-vulnerabilities.json similarity index 100% rename from src/integTest/resources/licence-vulnerabilities.json rename to src/test/resources/licence-vulnerabilities.json diff --git a/src/integTest/resources/misformed-vulnerabilities-test.json b/src/test/resources/misformed-vulnerabilities-test.json similarity index 100% rename from src/integTest/resources/misformed-vulnerabilities-test.json rename to src/test/resources/misformed-vulnerabilities-test.json diff --git a/src/integTest/resources/mockito-extensions/org.mockito.plugins.MockMaker b/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker similarity index 100% rename from src/integTest/resources/mockito-extensions/org.mockito.plugins.MockMaker rename to src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker diff --git a/src/integTest/resources/oss-test-results/oss-result-go-mod.json b/src/test/resources/oss-test-results/oss-result-go-mod.json similarity index 100% rename from src/integTest/resources/oss-test-results/oss-result-go-mod.json rename to src/test/resources/oss-test-results/oss-result-go-mod.json diff --git a/src/integTest/resources/oss-test-results/oss-result-gradle-kts.json b/src/test/resources/oss-test-results/oss-result-gradle-kts.json similarity index 100% rename from src/integTest/resources/oss-test-results/oss-result-gradle-kts.json rename to src/test/resources/oss-test-results/oss-result-gradle-kts.json diff --git a/src/integTest/resources/oss-test-results/oss-result-gradle.json b/src/test/resources/oss-test-results/oss-result-gradle.json similarity index 100% rename from src/integTest/resources/oss-test-results/oss-result-gradle.json rename to src/test/resources/oss-test-results/oss-result-gradle.json diff --git a/src/integTest/resources/oss-test-results/oss-result-maven.json b/src/test/resources/oss-test-results/oss-result-maven.json similarity index 100% rename from src/integTest/resources/oss-test-results/oss-result-maven.json rename to src/test/resources/oss-test-results/oss-result-maven.json diff --git a/src/integTest/resources/oss-test-results/oss-result-package-no-remediation.json b/src/test/resources/oss-test-results/oss-result-package-no-remediation.json similarity index 100% rename from src/integTest/resources/oss-test-results/oss-result-package-no-remediation.json rename to src/test/resources/oss-test-results/oss-result-package-no-remediation.json diff --git a/src/integTest/resources/oss-test-results/oss-result-package.json b/src/test/resources/oss-test-results/oss-result-package.json similarity index 100% rename from src/integTest/resources/oss-test-results/oss-result-package.json rename to src/test/resources/oss-test-results/oss-result-package.json diff --git a/src/integTest/resources/test-fixtures/code/annotator/app.js b/src/test/resources/test-fixtures/code/annotator/app.js similarity index 100% rename from src/integTest/resources/test-fixtures/code/annotator/app.js rename to src/test/resources/test-fixtures/code/annotator/app.js diff --git a/src/integTest/resources/test-fixtures/container/annotator/kubernetes-deployment.yaml b/src/test/resources/test-fixtures/container/annotator/kubernetes-deployment.yaml similarity index 100% rename from src/integTest/resources/test-fixtures/container/annotator/kubernetes-deployment.yaml rename to src/test/resources/test-fixtures/container/annotator/kubernetes-deployment.yaml diff --git a/src/integTest/resources/test-fixtures/iac/annotator/cloudformation-deployment.yaml b/src/test/resources/test-fixtures/iac/annotator/cloudformation-deployment.yaml similarity index 100% rename from src/integTest/resources/test-fixtures/iac/annotator/cloudformation-deployment.yaml rename to src/test/resources/test-fixtures/iac/annotator/cloudformation-deployment.yaml diff --git a/src/integTest/resources/test-fixtures/iac/annotator/kubernetes-deployment.yaml b/src/test/resources/test-fixtures/iac/annotator/kubernetes-deployment.yaml similarity index 100% rename from src/integTest/resources/test-fixtures/iac/annotator/kubernetes-deployment.yaml rename to src/test/resources/test-fixtures/iac/annotator/kubernetes-deployment.yaml diff --git a/src/integTest/resources/test-fixtures/iac/annotator/terraform-main.tf b/src/test/resources/test-fixtures/iac/annotator/terraform-main.tf similarity index 100% rename from src/integTest/resources/test-fixtures/iac/annotator/terraform-main.tf rename to src/test/resources/test-fixtures/iac/annotator/terraform-main.tf diff --git a/src/integTest/resources/test-fixtures/oss/annotator/build.gradle b/src/test/resources/test-fixtures/oss/annotator/build.gradle similarity index 100% rename from src/integTest/resources/test-fixtures/oss/annotator/build.gradle rename to src/test/resources/test-fixtures/oss/annotator/build.gradle diff --git a/src/integTest/resources/test-fixtures/oss/annotator/build.gradle.kts b/src/test/resources/test-fixtures/oss/annotator/build.gradle.kts similarity index 100% rename from src/integTest/resources/test-fixtures/oss/annotator/build.gradle.kts rename to src/test/resources/test-fixtures/oss/annotator/build.gradle.kts diff --git a/src/integTest/resources/test-fixtures/oss/annotator/go.mod b/src/test/resources/test-fixtures/oss/annotator/go.mod similarity index 100% rename from src/integTest/resources/test-fixtures/oss/annotator/go.mod rename to src/test/resources/test-fixtures/oss/annotator/go.mod diff --git a/src/integTest/resources/test-fixtures/oss/annotator/package.json b/src/test/resources/test-fixtures/oss/annotator/package.json similarity index 100% rename from src/integTest/resources/test-fixtures/oss/annotator/package.json rename to src/test/resources/test-fixtures/oss/annotator/package.json diff --git a/src/integTest/resources/test-fixtures/oss/annotator/pom.xml b/src/test/resources/test-fixtures/oss/annotator/pom.xml similarity index 100% rename from src/integTest/resources/test-fixtures/oss/annotator/pom.xml rename to src/test/resources/test-fixtures/oss/annotator/pom.xml diff --git a/src/integTest/resources/vulnerabilities-array-cli-result.json b/src/test/resources/vulnerabilities-array-cli-result.json similarity index 100% rename from src/integTest/resources/vulnerabilities-array-cli-result.json rename to src/test/resources/vulnerabilities-array-cli-result.json diff --git a/src/integTest/resources/vulnerabilities-array-with-error-and-result-test.json b/src/test/resources/vulnerabilities-array-with-error-and-result-test.json similarity index 100% rename from src/integTest/resources/vulnerabilities-array-with-error-and-result-test.json rename to src/test/resources/vulnerabilities-array-with-error-and-result-test.json