diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 14564fd..5d4bc73 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -31,7 +31,7 @@ jobs: - name: Set up Maven Central Repository uses: actions/setup-java@v5 with: - java-version: 8 + java-version: 21 distribution: 'temurin' - name: Bump version for deployment @@ -59,7 +59,7 @@ jobs: - name: Set up Maven Central Repository uses: actions/setup-java@v5 with: - java-version: 8 + java-version: 21 distribution: 'temurin' server-id: central server-username: MAVEN_USERNAME @@ -89,7 +89,7 @@ jobs: - name: Set up Maven Central Repository uses: actions/setup-java@v5 with: - java-version: 8 + java-version: 21 distribution: 'temurin' - name: Bump version & push to git diff --git a/.github/workflows/sdk_ci.yml b/.github/workflows/sdk_ci.yml index d5a8305..076558d 100644 --- a/.github/workflows/sdk_ci.yml +++ b/.github/workflows/sdk_ci.yml @@ -19,7 +19,7 @@ jobs: - name: Set up Maven Central Repository uses: actions/setup-java@v5 with: - java-version: 8 + java-version: 21 distribution: 'temurin' # Execute unit tests. diff --git a/README.md b/README.md index ceef49a..78cb9da 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ This SDK contains methods for interacting easily with ZeroBounce API. More information about ZeroBounce you can find in the [official documentation](https://www.zerobounce.net/docs/).\ -This SDK is built using the Java 1.8 version. +This SDK is built using the Java 21 version. ### Installation diff --git a/pom.xml b/pom.xml index 77015f6..aeb36d5 100644 --- a/pom.xml +++ b/pom.xml @@ -10,11 +10,11 @@ zero-bounce-java-sdk-setup-master - 1.8 + 21 UTF-8 - 5.9.1 - 1.8 - 1.8 + 5.14.1 + 21 + 21 diff --git a/zero-bounce-sdk/.mvn/wrapper/MavenWrapperDownloader.java b/zero-bounce-sdk/.mvn/wrapper/MavenWrapperDownloader.java deleted file mode 100644 index c32394f..0000000 --- a/zero-bounce-sdk/.mvn/wrapper/MavenWrapperDownloader.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright 2007-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import java.net.*; -import java.io.*; -import java.nio.channels.*; -import java.util.Properties; - -public class MavenWrapperDownloader { - - private static final String WRAPPER_VERSION = "0.5.5"; - /** - * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. - */ - private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/" - + WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar"; - - /** - * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to - * use instead of the default one. - */ - private static final String MAVEN_WRAPPER_PROPERTIES_PATH = - ".mvn/wrapper/maven-wrapper.properties"; - - /** - * Path where the maven-wrapper.jar will be saved to. - */ - private static final String MAVEN_WRAPPER_JAR_PATH = - ".mvn/wrapper/maven-wrapper.jar"; - - /** - * Name of the property which should be used to override the default download url for the wrapper. - */ - private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; - - public static void main(String args[]) { - System.out.println("- Downloader started"); - File baseDirectory = new File(args[0]); - System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); - - // If the maven-wrapper.properties exists, read it and check if it contains a custom - // wrapperUrl parameter. - File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); - String url = DEFAULT_DOWNLOAD_URL; - if(mavenWrapperPropertyFile.exists()) { - FileInputStream mavenWrapperPropertyFileInputStream = null; - try { - mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); - Properties mavenWrapperProperties = new Properties(); - mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream); - url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url); - } catch (IOException e) { - System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); - } finally { - try { - if(mavenWrapperPropertyFileInputStream != null) { - mavenWrapperPropertyFileInputStream.close(); - } - } catch (IOException e) { - // Ignore ... - } - } - } - System.out.println("- Downloading from: " + url); - - File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); - if(!outputFile.getParentFile().exists()) { - if(!outputFile.getParentFile().mkdirs()) { - System.out.println( - "- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'"); - } - } - System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); - try { - downloadFileFromURL(url, outputFile); - System.out.println("Done"); - System.exit(0); - } catch (Throwable e) { - System.out.println("- Error downloading"); - e.printStackTrace(); - System.exit(1); - } - } - - private static void downloadFileFromURL(String urlString, File destination) throws Exception { - if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) { - String username = System.getenv("MVNW_USERNAME"); - char[] password = System.getenv("MVNW_PASSWORD").toCharArray(); - Authenticator.setDefault(new Authenticator() { - @Override - protected PasswordAuthentication getPasswordAuthentication() { - return new PasswordAuthentication(username, password); - } - }); - } - URL website = new URL(urlString); - ReadableByteChannel rbc; - rbc = Channels.newChannel(website.openStream()); - FileOutputStream fos = new FileOutputStream(destination); - fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); - fos.close(); - rbc.close(); - } - -} diff --git a/zero-bounce-sdk/.mvn/wrapper/maven-wrapper.jar b/zero-bounce-sdk/.mvn/wrapper/maven-wrapper.jar index 41c70a7..cb28b0e 100644 Binary files a/zero-bounce-sdk/.mvn/wrapper/maven-wrapper.jar and b/zero-bounce-sdk/.mvn/wrapper/maven-wrapper.jar differ diff --git a/zero-bounce-sdk/.mvn/wrapper/maven-wrapper.properties b/zero-bounce-sdk/.mvn/wrapper/maven-wrapper.properties index 54ab0bc..524ccf2 100644 --- a/zero-bounce-sdk/.mvn/wrapper/maven-wrapper.properties +++ b/zero-bounce-sdk/.mvn/wrapper/maven-wrapper.properties @@ -1,3 +1,18 @@ -distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.1/apache-maven-3.6.1-bin.zip -wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar - +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.11/apache-maven-3.9.11-bin.zip +wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar diff --git a/zero-bounce-sdk/mvnw b/zero-bounce-sdk/mvnw index a3925bb..8d937f4 100755 --- a/zero-bounce-sdk/mvnw +++ b/zero-bounce-sdk/mvnw @@ -19,7 +19,7 @@ # ---------------------------------------------------------------------------- # ---------------------------------------------------------------------------- -# Maven Start Up Batch script +# Apache Maven Wrapper startup batch script, version 3.2.0 # # Required ENV vars: # ------------------ @@ -27,7 +27,6 @@ # # Optional ENV vars # ----------------- -# M2_HOME - location of maven2's installed home dir # MAVEN_OPTS - parameters passed to the Java VM when running Maven # e.g. to debug Maven itself, use # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 @@ -36,6 +35,10 @@ if [ -z "$MAVEN_SKIP_RC" ] ; then + if [ -f /usr/local/etc/mavenrc ] ; then + . /usr/local/etc/mavenrc + fi + if [ -f /etc/mavenrc ] ; then . /etc/mavenrc fi @@ -50,7 +53,7 @@ fi cygwin=false; darwin=false; mingw=false -case "`uname`" in +case "$(uname)" in CYGWIN*) cygwin=true ;; MINGW*) mingw=true;; Darwin*) darwin=true @@ -58,9 +61,9 @@ case "`uname`" in # See https://developer.apple.com/library/mac/qa/qa1170/_index.html if [ -z "$JAVA_HOME" ]; then if [ -x "/usr/libexec/java_home" ]; then - export JAVA_HOME="`/usr/libexec/java_home`" + JAVA_HOME="$(/usr/libexec/java_home)"; export JAVA_HOME else - export JAVA_HOME="/Library/Java/Home" + JAVA_HOME="/Library/Java/Home"; export JAVA_HOME fi fi ;; @@ -68,68 +71,38 @@ esac if [ -z "$JAVA_HOME" ] ; then if [ -r /etc/gentoo-release ] ; then - JAVA_HOME=`java-config --jre-home` + JAVA_HOME=$(java-config --jre-home) fi fi -if [ -z "$M2_HOME" ] ; then - ## resolve links - $0 may be a link to maven's home - 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 - done - - saveddir=`pwd` - - M2_HOME=`dirname "$PRG"`/.. - - # make it fully qualified - M2_HOME=`cd "$M2_HOME" && pwd` - - cd "$saveddir" - # echo Using m2 at $M2_HOME -fi - # For Cygwin, ensure paths are in UNIX format before anything is touched if $cygwin ; then - [ -n "$M2_HOME" ] && - M2_HOME=`cygpath --unix "$M2_HOME"` [ -n "$JAVA_HOME" ] && - JAVA_HOME=`cygpath --unix "$JAVA_HOME"` + JAVA_HOME=$(cygpath --unix "$JAVA_HOME") [ -n "$CLASSPATH" ] && - CLASSPATH=`cygpath --path --unix "$CLASSPATH"` + CLASSPATH=$(cygpath --path --unix "$CLASSPATH") fi # For Mingw, ensure paths are in UNIX format before anything is touched if $mingw ; then - [ -n "$M2_HOME" ] && - M2_HOME="`(cd "$M2_HOME"; pwd)`" - [ -n "$JAVA_HOME" ] && - JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" + [ -n "$JAVA_HOME" ] && [ -d "$JAVA_HOME" ] && + JAVA_HOME="$(cd "$JAVA_HOME" || (echo "cannot cd into $JAVA_HOME."; exit 1); pwd)" fi if [ -z "$JAVA_HOME" ]; then - javaExecutable="`which javac`" - if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then + javaExecutable="$(which javac)" + if [ -n "$javaExecutable" ] && ! [ "$(expr "\"$javaExecutable\"" : '\([^ ]*\)')" = "no" ]; then # readlink(1) is not available as standard on Solaris 10. - readLink=`which readlink` - if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then + readLink=$(which readlink) + if [ ! "$(expr "$readLink" : '\([^ ]*\)')" = "no" ]; then if $darwin ; then - javaHome="`dirname \"$javaExecutable\"`" - javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" + javaHome="$(dirname "\"$javaExecutable\"")" + javaExecutable="$(cd "\"$javaHome\"" && pwd -P)/javac" else - javaExecutable="`readlink -f \"$javaExecutable\"`" + javaExecutable="$(readlink -f "\"$javaExecutable\"")" fi - javaHome="`dirname \"$javaExecutable\"`" - javaHome=`expr "$javaHome" : '\(.*\)/bin'` + javaHome="$(dirname "\"$javaExecutable\"")" + javaHome=$(expr "$javaHome" : '\(.*\)/bin') JAVA_HOME="$javaHome" export JAVA_HOME fi @@ -145,7 +118,7 @@ if [ -z "$JAVACMD" ] ; then JAVACMD="$JAVA_HOME/bin/java" fi else - JAVACMD="`which java`" + JAVACMD="$(\unset -f command 2>/dev/null; \command -v java)" fi fi @@ -159,12 +132,9 @@ if [ -z "$JAVA_HOME" ] ; then echo "Warning: JAVA_HOME environment variable is not set." fi -CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher - # traverses directory structure from process work directory to filesystem root # first directory with .mvn subdirectory is considered project base directory find_maven_basedir() { - if [ -z "$1" ] then echo "Path not specified to find_maven_basedir" @@ -180,96 +150,99 @@ find_maven_basedir() { fi # workaround for JBEAP-8937 (on Solaris 10/Sparc) if [ -d "${wdir}" ]; then - wdir=`cd "$wdir/.."; pwd` + wdir=$(cd "$wdir/.." || exit 1; pwd) fi # end of workaround done - echo "${basedir}" + printf '%s' "$(cd "$basedir" || exit 1; pwd)" } # concatenates all lines of a file concat_lines() { if [ -f "$1" ]; then - echo "$(tr -s '\n' ' ' < "$1")" + # Remove \r in case we run on Windows within Git Bash + # and check out the repository with auto CRLF management + # enabled. Otherwise, we may read lines that are delimited with + # \r\n and produce $'-Xarg\r' rather than -Xarg due to word + # splitting rules. + tr -s '\r\n' ' ' < "$1" + fi +} + +log() { + if [ "$MVNW_VERBOSE" = true ]; then + printf '%s\n' "$1" fi } -BASE_DIR=`find_maven_basedir "$(pwd)"` +BASE_DIR=$(find_maven_basedir "$(dirname "$0")") if [ -z "$BASE_DIR" ]; then exit 1; fi +MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}; export MAVEN_PROJECTBASEDIR +log "$MAVEN_PROJECTBASEDIR" + ########################################################################################## # Extension to allow automatically downloading the maven-wrapper.jar from Maven-central # This allows using the maven wrapper in projects that prohibit checking in binary data. ########################################################################################## -if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then - if [ "$MVNW_VERBOSE" = true ]; then - echo "Found .mvn/wrapper/maven-wrapper.jar" - fi +wrapperJarPath="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" +if [ -r "$wrapperJarPath" ]; then + log "Found $wrapperJarPath" else - if [ "$MVNW_VERBOSE" = true ]; then - echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." - fi + log "Couldn't find $wrapperJarPath, downloading it ..." + if [ -n "$MVNW_REPOURL" ]; then - jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar" + wrapperUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar" else - jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar" + wrapperUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar" fi - while IFS="=" read key value; do - case "$key" in (wrapperUrl) jarUrl="$value"; break ;; + while IFS="=" read -r key value; do + # Remove '\r' from value to allow usage on windows as IFS does not consider '\r' as a separator ( considers space, tab, new line ('\n'), and custom '=' ) + safeValue=$(echo "$value" | tr -d '\r') + case "$key" in (wrapperUrl) wrapperUrl="$safeValue"; break ;; esac - done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" - if [ "$MVNW_VERBOSE" = true ]; then - echo "Downloading from: $jarUrl" - fi - wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" + done < "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties" + log "Downloading from: $wrapperUrl" + if $cygwin; then - wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` + wrapperJarPath=$(cygpath --path --windows "$wrapperJarPath") fi if command -v wget > /dev/null; then - if [ "$MVNW_VERBOSE" = true ]; then - echo "Found wget ... using wget" - fi + log "Found wget ... using wget" + [ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--quiet" if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then - wget "$jarUrl" -O "$wrapperJarPath" + wget $QUIET "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" else - wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" + wget $QUIET --http-user="$MVNW_USERNAME" --http-password="$MVNW_PASSWORD" "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" fi elif command -v curl > /dev/null; then - if [ "$MVNW_VERBOSE" = true ]; then - echo "Found curl ... using curl" - fi + log "Found curl ... using curl" + [ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--silent" if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then - curl -o "$wrapperJarPath" "$jarUrl" -f + curl $QUIET -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath" else - curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f + curl $QUIET --user "$MVNW_USERNAME:$MVNW_PASSWORD" -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath" fi - else - if [ "$MVNW_VERBOSE" = true ]; then - echo "Falling back to using Java to download" - fi - javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" + log "Falling back to using Java to download" + javaSource="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.java" + javaClass="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.class" # For Cygwin, switch paths to Windows format before running javac if $cygwin; then - javaClass=`cygpath --path --windows "$javaClass"` + javaSource=$(cygpath --path --windows "$javaSource") + javaClass=$(cygpath --path --windows "$javaClass") fi - if [ -e "$javaClass" ]; then - if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then - if [ "$MVNW_VERBOSE" = true ]; then - echo " - Compiling MavenWrapperDownloader.java ..." - fi - # Compiling the Java class - ("$JAVA_HOME/bin/javac" "$javaClass") + if [ -e "$javaSource" ]; then + if [ ! -e "$javaClass" ]; then + log " - Compiling MavenWrapperDownloader.java ..." + ("$JAVA_HOME/bin/javac" "$javaSource") fi - if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then - # Running the downloader - if [ "$MVNW_VERBOSE" = true ]; then - echo " - Running MavenWrapperDownloader.java ..." - fi - ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") + if [ -e "$javaClass" ]; then + log " - Running MavenWrapperDownloader.java ..." + ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$wrapperUrl" "$wrapperJarPath") || rm -f "$wrapperJarPath" fi fi fi @@ -278,33 +251,58 @@ fi # End of extension ########################################################################################## -export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} -if [ "$MVNW_VERBOSE" = true ]; then - echo $MAVEN_PROJECTBASEDIR +# If specified, validate the SHA-256 sum of the Maven wrapper jar file +wrapperSha256Sum="" +while IFS="=" read -r key value; do + case "$key" in (wrapperSha256Sum) wrapperSha256Sum=$value; break ;; + esac +done < "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties" +if [ -n "$wrapperSha256Sum" ]; then + wrapperSha256Result=false + if command -v sha256sum > /dev/null; then + if echo "$wrapperSha256Sum $wrapperJarPath" | sha256sum -c > /dev/null 2>&1; then + wrapperSha256Result=true + fi + elif command -v shasum > /dev/null; then + if echo "$wrapperSha256Sum $wrapperJarPath" | shasum -a 256 -c > /dev/null 2>&1; then + wrapperSha256Result=true + fi + else + echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." + echo "Please install either command, or disable validation by removing 'wrapperSha256Sum' from your maven-wrapper.properties." + exit 1 + fi + if [ $wrapperSha256Result = false ]; then + echo "Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised." >&2 + echo "Investigate or delete $wrapperJarPath to attempt a clean download." >&2 + echo "If you updated your Maven version, you need to update the specified wrapperSha256Sum property." >&2 + exit 1 + fi fi + MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" # For Cygwin, switch paths to Windows format before running java if $cygwin; then - [ -n "$M2_HOME" ] && - M2_HOME=`cygpath --path --windows "$M2_HOME"` [ -n "$JAVA_HOME" ] && - JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` + JAVA_HOME=$(cygpath --path --windows "$JAVA_HOME") [ -n "$CLASSPATH" ] && - CLASSPATH=`cygpath --path --windows "$CLASSPATH"` + CLASSPATH=$(cygpath --path --windows "$CLASSPATH") [ -n "$MAVEN_PROJECTBASEDIR" ] && - MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` + MAVEN_PROJECTBASEDIR=$(cygpath --path --windows "$MAVEN_PROJECTBASEDIR") fi # Provide a "standardized" way to retrieve the CLI args that will # work with both Windows and non-Windows executions. -MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" +MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $*" export MAVEN_CMD_LINE_ARGS WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain +# shellcheck disable=SC2086 # safe args exec "$JAVACMD" \ $MAVEN_OPTS \ + $MAVEN_DEBUG_OPTS \ -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ - "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/zero-bounce-sdk/mvnw.cmd b/zero-bounce-sdk/mvnw.cmd index 9ef116e..f80fbad 100644 --- a/zero-bounce-sdk/mvnw.cmd +++ b/zero-bounce-sdk/mvnw.cmd @@ -1,182 +1,205 @@ -@REM ---------------------------------------------------------------------------- -@REM Licensed to the Apache Software Foundation (ASF) under one -@REM or more contributor license agreements. See the NOTICE file -@REM distributed with this work for additional information -@REM regarding copyright ownership. The ASF licenses this file -@REM to you under the Apache License, Version 2.0 (the -@REM "License"); you may not use this file except in compliance -@REM with the License. You may obtain a copy of the License at -@REM -@REM http://www.apache.org/licenses/LICENSE-2.0 -@REM -@REM Unless required by applicable law or agreed to in writing, -@REM software distributed under the License is distributed on an -@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -@REM KIND, either express or implied. See the License for the -@REM specific language governing permissions and limitations -@REM under the License. -@REM ---------------------------------------------------------------------------- - -@REM ---------------------------------------------------------------------------- -@REM Maven Start Up Batch script -@REM -@REM Required ENV vars: -@REM JAVA_HOME - location of a JDK home dir -@REM -@REM Optional ENV vars -@REM M2_HOME - location of maven2's installed home dir -@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands -@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending -@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven -@REM e.g. to debug Maven itself, use -@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 -@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files -@REM ---------------------------------------------------------------------------- - -@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' -@echo off -@REM set title of command window -title %0 -@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' -@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% - -@REM set %HOME% to equivalent of $HOME -if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") - -@REM Execute a user defined script before this one -if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre -@REM check for pre script, once with legacy .bat ending and once with .cmd ending -if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" -if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" -:skipRcPre - -@setlocal - -set ERROR_CODE=0 - -@REM To isolate internal variables from possible post scripts, we use another setlocal -@setlocal - -@REM ==== START VALIDATION ==== -if not "%JAVA_HOME%" == "" goto OkJHome - -echo. -echo Error: JAVA_HOME not found in your environment. >&2 -echo Please set the JAVA_HOME variable in your environment to match the >&2 -echo location of your Java installation. >&2 -echo. -goto error - -:OkJHome -if exist "%JAVA_HOME%\bin\java.exe" goto init - -echo. -echo Error: JAVA_HOME is set to an invalid directory. >&2 -echo JAVA_HOME = "%JAVA_HOME%" >&2 -echo Please set the JAVA_HOME variable in your environment to match the >&2 -echo location of your Java installation. >&2 -echo. -goto error - -@REM ==== END VALIDATION ==== - -:init - -@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". -@REM Fallback to current working directory if not found. - -set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% -IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir - -set EXEC_DIR=%CD% -set WDIR=%EXEC_DIR% -:findBaseDir -IF EXIST "%WDIR%"\.mvn goto baseDirFound -cd .. -IF "%WDIR%"=="%CD%" goto baseDirNotFound -set WDIR=%CD% -goto findBaseDir - -:baseDirFound -set MAVEN_PROJECTBASEDIR=%WDIR% -cd "%EXEC_DIR%" -goto endDetectBaseDir - -:baseDirNotFound -set MAVEN_PROJECTBASEDIR=%EXEC_DIR% -cd "%EXEC_DIR%" - -:endDetectBaseDir - -IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig - -@setlocal EnableExtensions EnableDelayedExpansion -for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a -@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% - -:endReadAdditionalConfig - -SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" -set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" -set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain - -set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar" - -FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( - IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B -) - -@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central -@REM This allows using the maven wrapper in projects that prohibit checking in binary data. -if exist %WRAPPER_JAR% ( - if "%MVNW_VERBOSE%" == "true" ( - echo Found %WRAPPER_JAR% - ) -) else ( - if not "%MVNW_REPOURL%" == "" ( - SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar" - ) - if "%MVNW_VERBOSE%" == "true" ( - echo Couldn't find %WRAPPER_JAR%, downloading it ... - echo Downloading from: %DOWNLOAD_URL% - ) - - powershell -Command "&{"^ - "$webclient = new-object System.Net.WebClient;"^ - "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ - "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ - "}"^ - "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ - "}" - if "%MVNW_VERBOSE%" == "true" ( - echo Finished downloading %WRAPPER_JAR% - ) -) -@REM End of extension - -@REM Provide a "standardized" way to retrieve the CLI args that will -@REM work with both Windows and non-Windows executions. -set MAVEN_CMD_LINE_ARGS=%* - -%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* -if ERRORLEVEL 1 goto error -goto end - -:error -set ERROR_CODE=1 - -:end -@endlocal & set ERROR_CODE=%ERROR_CODE% - -if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost -@REM check for post script, once with legacy .bat ending and once with .cmd ending -if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" -if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" -:skipRcPost - -@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' -if "%MAVEN_BATCH_PAUSE%" == "on" pause - -if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% - -exit /B %ERROR_CODE% +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Apache Maven Wrapper startup batch script, version 3.2.0 +@REM +@REM Required ENV vars: +@REM JAVA_HOME - location of a JDK home dir +@REM +@REM Optional ENV vars +@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending +@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven +@REM e.g. to debug Maven itself, use +@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files +@REM ---------------------------------------------------------------------------- + +@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' +@echo off +@REM set title of command window +title %0 +@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' +@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% + +@REM set %HOME% to equivalent of $HOME +if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") + +@REM Execute a user defined script before this one +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre +@REM check for pre script, once with legacy .bat ending and once with .cmd ending +if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %* +if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %* +:skipRcPre + +@setlocal + +set ERROR_CODE=0 + +@REM To isolate internal variables from possible post scripts, we use another setlocal +@setlocal + +@REM ==== START VALIDATION ==== +if not "%JAVA_HOME%" == "" goto OkJHome + +echo. +echo Error: JAVA_HOME not found in your environment. >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +:OkJHome +if exist "%JAVA_HOME%\bin\java.exe" goto init + +echo. +echo Error: JAVA_HOME is set to an invalid directory. >&2 +echo JAVA_HOME = "%JAVA_HOME%" >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +@REM ==== END VALIDATION ==== + +:init + +@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". +@REM Fallback to current working directory if not found. + +set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% +IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir + +set EXEC_DIR=%CD% +set WDIR=%EXEC_DIR% +:findBaseDir +IF EXIST "%WDIR%"\.mvn goto baseDirFound +cd .. +IF "%WDIR%"=="%CD%" goto baseDirNotFound +set WDIR=%CD% +goto findBaseDir + +:baseDirFound +set MAVEN_PROJECTBASEDIR=%WDIR% +cd "%EXEC_DIR%" +goto endDetectBaseDir + +:baseDirNotFound +set MAVEN_PROJECTBASEDIR=%EXEC_DIR% +cd "%EXEC_DIR%" + +:endDetectBaseDir + +IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig + +@setlocal EnableExtensions EnableDelayedExpansion +for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a +@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% + +:endReadAdditionalConfig + +SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" +set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" +set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +set WRAPPER_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar" + +FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( + IF "%%A"=="wrapperUrl" SET WRAPPER_URL=%%B +) + +@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +@REM This allows using the maven wrapper in projects that prohibit checking in binary data. +if exist %WRAPPER_JAR% ( + if "%MVNW_VERBOSE%" == "true" ( + echo Found %WRAPPER_JAR% + ) +) else ( + if not "%MVNW_REPOURL%" == "" ( + SET WRAPPER_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar" + ) + if "%MVNW_VERBOSE%" == "true" ( + echo Couldn't find %WRAPPER_JAR%, downloading it ... + echo Downloading from: %WRAPPER_URL% + ) + + powershell -Command "&{"^ + "$webclient = new-object System.Net.WebClient;"^ + "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ + "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ + "}"^ + "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%WRAPPER_URL%', '%WRAPPER_JAR%')"^ + "}" + if "%MVNW_VERBOSE%" == "true" ( + echo Finished downloading %WRAPPER_JAR% + ) +) +@REM End of extension + +@REM If specified, validate the SHA-256 sum of the Maven wrapper jar file +SET WRAPPER_SHA_256_SUM="" +FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( + IF "%%A"=="wrapperSha256Sum" SET WRAPPER_SHA_256_SUM=%%B +) +IF NOT %WRAPPER_SHA_256_SUM%=="" ( + powershell -Command "&{"^ + "$hash = (Get-FileHash \"%WRAPPER_JAR%\" -Algorithm SHA256).Hash.ToLower();"^ + "If('%WRAPPER_SHA_256_SUM%' -ne $hash){"^ + " Write-Output 'Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised.';"^ + " Write-Output 'Investigate or delete %WRAPPER_JAR% to attempt a clean download.';"^ + " Write-Output 'If you updated your Maven version, you need to update the specified wrapperSha256Sum property.';"^ + " exit 1;"^ + "}"^ + "}" + if ERRORLEVEL 1 goto error +) + +@REM Provide a "standardized" way to retrieve the CLI args that will +@REM work with both Windows and non-Windows executions. +set MAVEN_CMD_LINE_ARGS=%* + +%MAVEN_JAVA_EXE% ^ + %JVM_CONFIG_MAVEN_PROPS% ^ + %MAVEN_OPTS% ^ + %MAVEN_DEBUG_OPTS% ^ + -classpath %WRAPPER_JAR% ^ + "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^ + %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* +if ERRORLEVEL 1 goto error +goto end + +:error +set ERROR_CODE=1 + +:end +@endlocal & set ERROR_CODE=%ERROR_CODE% + +if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost +@REM check for post script, once with legacy .bat ending and once with .cmd ending +if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat" +if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd" +:skipRcPost + +@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' +if "%MAVEN_BATCH_PAUSE%"=="on" pause + +if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE% + +cmd /C exit /B %ERROR_CODE% diff --git a/zero-bounce-sdk/pom.xml b/zero-bounce-sdk/pom.xml index ae01d8b..bdcf77e 100644 --- a/zero-bounce-sdk/pom.xml +++ b/zero-bounce-sdk/pom.xml @@ -34,36 +34,37 @@ - 1.8 + 21 + 21 + 21 UTF-8 UTF-8 - 1.8 - 1.8 + 5.20.0 org.jetbrains annotations - 24.0.1 + 26.0.2-1 commons-codec commons-codec - 1.15 + 1.19.0 com.google.code.gson gson - 2.10.1 + 2.13.2 org.apache.httpcomponents.client5 httpclient5 - 5.2.1 + 5.5.1 @@ -75,28 +76,60 @@ - junit - junit - 4.13.2 + org.junit.jupiter + junit-jupiter-api + 5.14.1 test - - org.powermock - powermock-module-junit4 - 2.0.9 + org.junit.jupiter + junit-jupiter-engine + 5.14.1 test - org.powermock - powermock-api-mockito2 - 2.0.9 + org.mockito + mockito-core + ${mockito.version} + test + + + org.mockito + mockito-junit-jupiter + ${mockito.version} test + + + + org.apache.maven.plugins + maven-dependency-plugin + + + + properties + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 3.5.4 + + + -javaagent:${settings.localRepository}/org/mockito/mockito-core/${mockito.version}/mockito-core-${mockito.version}.jar + -Xshare:off + + + + + + release diff --git a/zero-bounce-sdk/src/main/java/com/zerobounce/ZeroBounceSDK.java b/zero-bounce-sdk/src/main/java/com/zerobounce/ZeroBounceSDK.java index 866cb4d..e15bac3 100644 --- a/zero-bounce-sdk/src/main/java/com/zerobounce/ZeroBounceSDK.java +++ b/zero-bounce-sdk/src/main/java/com/zerobounce/ZeroBounceSDK.java @@ -22,6 +22,8 @@ import java.io.*; import java.lang.reflect.Type; import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URI; import java.net.URL; import java.nio.charset.StandardCharsets; import java.text.SimpleDateFormat; @@ -444,7 +446,7 @@ private void _sendFile( } } catch (Exception e) { - e.printStackTrace(); + logError("ZeroBounceSDK::sendFile failed", e); ErrorResponse errorResponse = ErrorResponse.parseError(e.getMessage()); errorCallback.onError(errorResponse); } @@ -596,7 +598,7 @@ private void _getFile( } } } catch (Exception e) { - e.printStackTrace(); + logError("ZeroBounceSDK::getFile failed", e); ErrorResponse errorResponse = ErrorResponse.parseError(e.getMessage()); errorCallback.onError(errorResponse); } @@ -755,7 +757,7 @@ private void sendRequest( } } - URL url = new URL(ub.toString()); + URL url = createUrlFrom(ub.toString()); HttpURLConnection con = (HttpURLConnection) url.openConnection(); con.setRequestProperty("Accept", "application/json"); // con.setRequestProperty("Content-Type", "application/json"); @@ -818,7 +820,16 @@ private void sendRequest( ErrorResponse errorResponse = ErrorResponse.parseError(e.getMessage()); errorCallback.onError(errorResponse); } + } + /** + * Creates and returns a URL object based on the given [url] parameter. + * + * @param url a url + * @return a URL object + */ + URL createUrlFrom(String url) throws MalformedURLException { + return URI.create(url).toURL(); } private static void logDebug(String message) { diff --git a/zero-bounce-sdk/src/test/java/com/zerobounce/ErrorResponseTest.java b/zero-bounce-sdk/src/test/java/com/zerobounce/ErrorResponseTest.java index 2649873..5ab0abb 100644 --- a/zero-bounce-sdk/src/test/java/com/zerobounce/ErrorResponseTest.java +++ b/zero-bounce-sdk/src/test/java/com/zerobounce/ErrorResponseTest.java @@ -1,11 +1,11 @@ package com.zerobounce; -import org.junit.Test; +import org.junit.jupiter.api.Test; import java.util.ArrayList; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; public class ErrorResponseTest { diff --git a/zero-bounce-sdk/src/test/java/com/zerobounce/GsonDateDeserializerTest.java b/zero-bounce-sdk/src/test/java/com/zerobounce/GsonDateDeserializerTest.java index 5d8bdcc..7936a02 100644 --- a/zero-bounce-sdk/src/test/java/com/zerobounce/GsonDateDeserializerTest.java +++ b/zero-bounce-sdk/src/test/java/com/zerobounce/GsonDateDeserializerTest.java @@ -3,7 +3,7 @@ import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.JsonParseException; -import org.junit.Test; +import org.junit.jupiter.api.Test; import java.time.LocalDateTime; import java.time.ZoneId; @@ -12,8 +12,8 @@ import java.time.format.DateTimeFormatter; import java.util.Date; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.fail; public class GsonDateDeserializerTest { diff --git a/zero-bounce-sdk/src/test/java/com/zerobounce/ThrowingRunnable.java b/zero-bounce-sdk/src/test/java/com/zerobounce/ThrowingRunnable.java new file mode 100644 index 0000000..35969c7 --- /dev/null +++ b/zero-bounce-sdk/src/test/java/com/zerobounce/ThrowingRunnable.java @@ -0,0 +1,12 @@ +package com.zerobounce; + +/** + * A custom interface that acts as a [Runnable] but whose run method can throw exceptions. + */ +@FunctionalInterface +interface ThrowingRunnable { + /** + * The run method, which is permitted to throw a general checked Exception. + */ + void run() throws Exception; +} \ No newline at end of file diff --git a/zero-bounce-sdk/src/test/java/com/zerobounce/ZeroBounceSDKTest.java b/zero-bounce-sdk/src/test/java/com/zerobounce/ZeroBounceSDKTest.java index df6405f..b1a9cf3 100644 --- a/zero-bounce-sdk/src/test/java/com/zerobounce/ZeroBounceSDKTest.java +++ b/zero-bounce-sdk/src/test/java/com/zerobounce/ZeroBounceSDKTest.java @@ -14,39 +14,40 @@ import org.apache.http.impl.client.HttpClients; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.powermock.api.mockito.PowerMockito; -import org.powermock.core.classloader.annotations.PowerMockIgnore; -import org.powermock.core.classloader.annotations.PrepareForTest; -import org.powermock.modules.junit4.PowerMockRunner; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.PrintStream; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.MockedConstruction; +import org.mockito.MockedStatic; +import org.mockito.Mockito; +import org.mockito.Spy; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.io.*; import java.net.HttpURLConnection; import java.net.URISyntaxException; import java.net.URL; import java.text.SimpleDateFormat; import java.util.*; -import static org.junit.Assert.*; +import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.AssertionsKt.assertNotNull; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.*; -@RunWith(PowerMockRunner.class) -@PrepareForTest({URL.class, HttpClients.class, ZeroBounceSDK.class}) -@PowerMockIgnore({"javax.net.ssl.*"}) +@ExtendWith(MockitoExtension.class) public class ZeroBounceSDKTest { + @Spy + private ZeroBounceSDK zeroBounceSDK; + private Gson gson; private final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd", Locale.US); private static final String API_KEY = "some-api-key"; - @Before + @BeforeEach public void setUp() { GsonBuilder gsonBuilder = new GsonBuilder(); gsonBuilder.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES); @@ -54,39 +55,40 @@ public void setUp() { gsonBuilder.registerTypeAdapter(Date.class, new GsonDateDeserializer()); gson = gsonBuilder.create(); - ZeroBounceSDK.getInstance().initialize(API_KEY); + zeroBounceSDK.initialize(API_KEY); } @Test public void validateEmail_ReturnsSuccess() throws Exception { // Prepare mock response and add it to the server - String responseJson = "{\n" + - " \"address\":\"flowerjill@aol.com\",\n" + - " \"status\":\"valid\",\n" + - " \"sub_status\":\"\",\n" + - " \"free_email\":true,\n" + - " \"did_you_mean\":null,\n" + - " \"account\":\"flowerjill\",\n" + - " \"domain\":\"aol.com\",\n" + - " \"domain_age_days\": \"8426\",\n" + - " \"smtp_provider\":\"yahoo\",\n" + - " \"mx_record\":\"mx-aol.mail.gm0.yahoodns.net\",\n" + - " \"mx_found\": \"true\",\n" + - " \"firstname\":\"Jill\",\n" + - " \"lastname\":\"Stein\",\n" + - " \"gender\":\"female\",\n" + - " \"country\":\"United States\",\n" + - " \"region\":\"Florida\",\n" + - " \"city\":\"West Palm Beach\",\n" + - " \"zipcode\":\"33401\",\n" + - " \"processed_at\":\"2017-04-01 02:48:02.592\"\n" + - " }"; + String responseJson = """ + { + "address":"flowerjill@aol.com", + "status":"valid", + "sub_status":"", + "free_email":true, + "did_you_mean":null, + "account":"flowerjill", + "domain":"aol.com", + "domain_age_days": "8426", + "smtp_provider":"yahoo", + "mx_record":"mx-aol.mail.gm0.yahoodns.net", + "mx_found": "true", + "firstname":"Jill", + "lastname":"Stein", + "gender":"female", + "country":"United States", + "region":"Florida", + "city":"West Palm Beach", + "zipcode":"33401", + "processed_at":"2017-04-01 02:48:02.592" + }"""; ZBValidateResponse expectedResponse = gson.fromJson(responseJson, ZBValidateResponse.class); String email = "flowerjill@aol.com"; String urlPath = getEncodedUrl( "https://api.zerobounce.net/v2/validate", - new HashMap() { + new HashMap<>() { { put("api_key", API_KEY); put("email", email); @@ -94,16 +96,18 @@ public void validateEmail_ReturnsSuccess() throws Exception { } } ); - mockRequest(urlPath, 200, responseJson, ""); - - ZeroBounceSDK.getInstance().validate( - email, - null, - response -> { - assertEquals(expectedResponse, response); - }, errorResponse -> { - fail(errorResponse.toString()); - }); + mockRequest( + urlPath, + 200, + responseJson, + "", + () -> zeroBounceSDK.validate( + email, + null, + response -> assertEquals(expectedResponse, response), + errorResponse -> fail(errorResponse.toString()) + ) + ); } @Test @@ -115,7 +119,7 @@ public void validateEmail_ReturnsError() throws Exception { String email = "flowerjill@aol.com"; String urlPath = getEncodedUrl( "https://api.zerobounce.net/v2/validate", - new HashMap() { + new HashMap<>() { { put("api_key", API_KEY); put("email", email); @@ -123,186 +127,196 @@ public void validateEmail_ReturnsError() throws Exception { } } ); - mockRequest(urlPath, 400, "", responseJson); - - ZeroBounceSDK.getInstance().validate( - email, - null, - response -> { - fail(response.toString()); - }, errorResponse -> { - assertEquals(expectedResponse, errorResponse); - }); + mockRequest( + urlPath, + 400, + "", + responseJson, + () -> zeroBounceSDK.validate( + email, + null, + response -> fail(response.toString()), + errorResponse -> assertEquals(expectedResponse, errorResponse)) + ); } @Test public void validateBatchEmails_ReturnsSuccess() throws Exception { // Prepare mock response and add it to the server - String responseJson = "{\n" + - " \"email_batch\": [\n" + - " {\n" + - " \"address\": \"valid@example.com\",\n" + - " \"status\": \"valid\",\n" + - " \"sub_status\": \"\",\n" + - " \"free_email\": false,\n" + - " \"did_you_mean\": null,\n" + - " \"account\": null,\n" + - " \"domain\": null,\n" + - " \"domain_age_days\": \"9692\",\n" + - " \"smtp_provider\": \"example\",\n" + - " \"mx_found\": \"true\",\n" + - " \"mx_record\": \"mx.example.com\",\n" + - " \"firstname\": \"zero\",\n" + - " \"lastname\": \"bounce\",\n" + - " \"gender\": \"male\",\n" + - " \"country\": null,\n" + - " \"region\": null,\n" + - " \"city\": null,\n" + - " \"zipcode\": null,\n" + - " \"processed_at\": \"2020-09-17 17:43:11.829\"\n" + - " },\n" + - " {\n" + - " \"address\": \"invalid@example.com\",\n" + - " \"status\": \"invalid\",\n" + - " \"sub_status\": \"mailbox_not_found\",\n" + - " \"free_email\": false,\n" + - " \"did_you_mean\": null,\n" + - " \"account\": null,\n" + - " \"domain\": null,\n" + - " \"domain_age_days\": \"9692\",\n" + - " \"smtp_provider\": \"example\",\n" + - " \"mx_found\": \"true\",\n" + - " \"mx_record\": \"mx.example.com\",\n" + - " \"firstname\": \"zero\",\n" + - " \"lastname\": \"bounce\",\n" + - " \"gender\": \"male\",\n" + - " \"country\": null,\n" + - " \"region\": null,\n" + - " \"city\": null,\n" + - " \"zipcode\": null,\n" + - " \"processed_at\": \"2020-09-17 17:43:11.830\"\n" + - " },\n" + - " {\n" + - " \"address\": \"disposable@example.com\",\n" + - " \"status\": \"do_not_mail\",\n" + - " \"sub_status\": \"disposable\",\n" + - " \"free_email\": false,\n" + - " \"did_you_mean\": null,\n" + - " \"account\": null,\n" + - " \"domain\": null,\n" + - " \"domain_age_days\": \"9692\",\n" + - " \"smtp_provider\": \"example\",\n" + - " \"mx_found\": \"true\",\n" + - " \"mx_record\": \"mx.example.com\",\n" + - " \"firstname\": \"zero\",\n" + - " \"lastname\": \"bounce\",\n" + - " \"gender\": \"male\",\n" + - " \"country\": null,\n" + - " \"region\": null,\n" + - " \"city\": null,\n" + - " \"zipcode\": null,\n" + - " \"processed_at\": \"2020-09-17 17:43:11.830\"\n" + - " }\n" + - " ],\n" + - " \"errors\": []\n" + - " }"; + String responseJson = """ + { + "email_batch": [ + { + "address": "valid@example.com", + "status": "valid", + "sub_status": "", + "free_email": false, + "did_you_mean": null, + "account": null, + "domain": null, + "domain_age_days": "9692", + "smtp_provider": "example", + "mx_found": "true", + "mx_record": "mx.example.com", + "firstname": "zero", + "lastname": "bounce", + "gender": "male", + "country": null, + "region": null, + "city": null, + "zipcode": null, + "processed_at": "2020-09-17 17:43:11.829" + }, + { + "address": "invalid@example.com", + "status": "invalid", + "sub_status": "mailbox_not_found", + "free_email": false, + "did_you_mean": null, + "account": null, + "domain": null, + "domain_age_days": "9692", + "smtp_provider": "example", + "mx_found": "true", + "mx_record": "mx.example.com", + "firstname": "zero", + "lastname": "bounce", + "gender": "male", + "country": null, + "region": null, + "city": null, + "zipcode": null, + "processed_at": "2020-09-17 17:43:11.830" + }, + { + "address": "disposable@example.com", + "status": "do_not_mail", + "sub_status": "disposable", + "free_email": false, + "did_you_mean": null, + "account": null, + "domain": null, + "domain_age_days": "9692", + "smtp_provider": "example", + "mx_found": "true", + "mx_record": "mx.example.com", + "firstname": "zero", + "lastname": "bounce", + "gender": "male", + "country": null, + "region": null, + "city": null, + "zipcode": null, + "processed_at": "2020-09-17 17:43:11.830" + } + ], + "errors": [] + }"""; ZBValidateBatchResponse expectedResponse = gson.fromJson(responseJson, ZBValidateBatchResponse.class); - String urlPath = "https://api.zerobounce.net/v2/validatebatch"; - mockRequest(urlPath, 200, responseJson, ""); - - List emailsData = new ArrayList(); + List emailsData = new ArrayList<>(); emailsData.add(new ZBValidateBatchData("valid@example.com", "1.1.1.1")); emailsData.add(new ZBValidateBatchData("invalid@example.com", "1.1.1.1")); emailsData.add(new ZBValidateBatchData("disposable@example.com", null)); - ZeroBounceSDK.getInstance().validateBatch( - emailsData, - response -> { - assertEquals(expectedResponse, response); - }, errorResponse -> { - fail(errorResponse.toString()); - }); + String urlPath = "https://api.zerobounce.net/v2/validatebatch"; + mockRequest( + urlPath, + 200, + responseJson, + "", + () -> zeroBounceSDK.validateBatch( + emailsData, + response -> assertEquals(expectedResponse, response), + errorResponse -> fail(errorResponse.toString()) + ) + ); } @Test public void validateBatchEmails_ReturnsError() throws Exception { // Prepare mock response and add it to the server - String responseJson = "{\n" + - " \"email_batch\": [],\n" + - " \"errors\": [\n" + - " {\n" + - " \"error\": \"Invalid API Key or your account ran out of credits\",\n" + - " \"email_address\": \"all\"\n" + - " }\n" + - " ]\n" + - " }"; + String responseJson = """ + { + "email_batch": [], + "errors": [ + { + "error": "Invalid API Key or your account ran out of credits", + "email_address": "all" + } + ] + }"""; ErrorResponse expectedResponse = ErrorResponse.parseError(responseJson); - String urlPath = "https://api.zerobounce.net/v2/validatebatch"; - mockRequest(urlPath, 400, "", responseJson); - - List emailsData = new ArrayList(); + List emailsData = new ArrayList<>(); emailsData.add(new ZBValidateBatchData("valid@example.com", "1.1.1.1")); emailsData.add(new ZBValidateBatchData("invalid@example.com", "1.1.1.1")); emailsData.add(new ZBValidateBatchData("disposable@example.com", null)); - ZeroBounceSDK.getInstance().validateBatch( - emailsData, - response -> { - fail(response.toString()); - }, errorResponse -> { - assertEquals(expectedResponse, errorResponse); - }); + String urlPath = "https://api.zerobounce.net/v2/validatebatch"; + mockRequest( + urlPath, + 400, + "", + responseJson, + () -> zeroBounceSDK.validateBatch( + emailsData, + response -> fail(response.toString()), + errorResponse -> assertEquals(expectedResponse, errorResponse) + ) + ); } @Test public void guessFormat_ReturnsSuccess() throws Exception { // Prepare mock response and add it to the server - String responseJson = "{\n" + - " \"email\": \"john.doe@example.com\",\n" + - " \"domain\": \"example.com\",\n" + - " \"format\": \"first.last\",\n" + - " \"status\": \"valid\",\n" + - " \"sub_status\": \"\",\n" + - " \"confidence\": \"HIGH\",\n" + - " \"did_you_mean\": \"\",\n" + - " \"failure_reason\": \"\",\n" + - " \"other_domain_formats\": [\n" + - " {\n" + - " \"format\": \"first_last\",\n" + - " \"confidence\": \"HIGH\"\n" + - " },\n" + - " {\n" + - " \"format\": \"first\",\n" + - " \"confidence\": \"MEDIUM\"\n" + - " }\n" + - " ]\n" + - " }"; + String responseJson = """ + { + "email": "john.doe@example.com", + "domain": "example.com", + "format": "first.last", + "status": "valid", + "sub_status": "", + "confidence": "HIGH", + "did_you_mean": "", + "failure_reason": "", + "other_domain_formats": [ + { + "format": "first_last", + "confidence": "HIGH" + }, + { + "format": "first", + "confidence": "MEDIUM" + } + ] + }"""; ZBEmailFinderResponse expectedResponse = gson.fromJson(responseJson, ZBEmailFinderResponse.class); String domain = "example.com"; String urlPath = getEncodedUrl( "https://api.zerobounce.net/v2/guessformat", - new HashMap() { + new HashMap<>() { { put("api_key", API_KEY); put("domain", domain); } } ); - mockRequest(urlPath, 200, responseJson, ""); - - ZeroBounceSDK.getInstance().guessFormat( - domain, - null, - null, - null, - response -> { - assertEquals(expectedResponse, response); - }, errorResponse -> { - fail(errorResponse.toString()); - }); + mockRequest( + urlPath, + 200, + responseJson, + "", + () -> zeroBounceSDK.guessFormat( + domain, + null, + null, + null, + response -> assertEquals(expectedResponse, response), + errorResponse -> fail(errorResponse.toString()) + ) + ); } @Test @@ -314,25 +328,27 @@ public void guessFormat_ReturnsError() throws Exception { String domain = "example.com"; String urlPath = getEncodedUrl( "https://api.zerobounce.net/v2/guessformat", - new HashMap() { + new HashMap<>() { { put("api_key", API_KEY); put("domain", domain); } } ); - mockRequest(urlPath, 400, "", responseJson); - - ZeroBounceSDK.getInstance().guessFormat( - domain, - null, - null, - null, - response -> { - fail(response.toString()); - }, errorResponse -> { - assertEquals(expectedResponse, errorResponse); - }); + mockRequest( + urlPath, + 400, + "", + responseJson, + () -> zeroBounceSDK.guessFormat( + domain, + null, + null, + null, + response -> fail(response.toString()), + errorResponse -> assertEquals(expectedResponse, errorResponse) + ) + ); } @Test @@ -343,20 +359,22 @@ public void getCredits_ReturnsSuccess() throws Exception { String urlPath = getEncodedUrl( "https://api.zerobounce.net/v2/getcredits", - new HashMap() { + new HashMap<>() { { put("api_key", API_KEY); } } ); - mockRequest(urlPath, 200, responseJson, ""); - - ZeroBounceSDK.getInstance().getCredits( - response -> { - assertEquals(expectedResponse, response); - }, errorResponse -> { - fail(errorResponse.toString()); - }); + mockRequest( + urlPath, + 200, + responseJson, + "", + () -> zeroBounceSDK.getCredits( + response -> assertEquals(expectedResponse, response), + errorResponse -> fail(errorResponse.toString()) + ) + ); } @Test @@ -367,57 +385,60 @@ public void getCredits_ReturnsError() throws Exception { String urlPath = getEncodedUrl( "https://api.zerobounce.net/v2/getcredits", - new HashMap() { + new HashMap<>() { { put("api_key", API_KEY); } } ); - mockRequest(urlPath, 400, "", responseJson); - - ZeroBounceSDK.getInstance().getCredits( - response -> { - fail(response.toString()); - }, errorResponse -> { - assertEquals(expectedResponse, errorResponse); - }); + mockRequest( + urlPath, + 400, + "", + responseJson, + () -> zeroBounceSDK.getCredits( + response -> fail(response.toString()), + errorResponse -> assertEquals(expectedResponse, errorResponse) + ) + ); } @Test public void getApiUsage_ReturnSuccess() throws Exception { // Prepare mock response and add it to the server - String responseJson = "{\n" + - " \"total\": 3,\n" + - " \"status_valid\": 1,\n" + - " \"status_invalid\": 2,\n" + - " \"status_catch_all\": 0,\n" + - " \"status_do_not_mail\": 0,\n" + - " \"status_spamtrap\": 0,\n" + - " \"status_unknown\": 0,\n" + - " \"sub_status_toxic\": 0,\n" + - " \"sub_status_disposable\": 0,\n" + - " \"sub_status_role_based\": 0,\n" + - " \"sub_status_possible_trap\": 0,\n" + - " \"sub_status_global_suppression\": 0,\n" + - " \"sub_status_timeout_exceeded\": 0,\n" + - " \"sub_status_mail_server_temporary_error\": 0,\n" + - " \"sub_status_mail_server_did_not_respond\": 0,\n" + - " \"sub_status_greylisted\": 0,\n" + - " \"sub_status_antispam_system\": 0,\n" + - " \"sub_status_does_not_accept_mail\": 0,\n" + - " \"sub_status_exception_occurred\": 0,\n" + - " \"sub_status_failed_syntax_check\": 0,\n" + - " \"sub_status_mailbox_not_found\": 2,\n" + - " \"sub_status_unroutable_ip_address\": 0,\n" + - " \"sub_status_possible_typo\": 0,\n" + - " \"sub_status_no_dns_entries\": 0,\n" + - " \"sub_status_role_based_catch_all\": 0,\n" + - " \"sub_status_mailbox_quota_exceeded\": 0,\n" + - " \"sub_status_forcible_disconnect\": 0,\n" + - " \"sub_status_failed_smtp_connection\": 0,\n" + - " \"start_date\": \"1/1/2018\",\n" + - " \"end_date\": \"12/12/2019\"\n" + - " }"; + String responseJson = """ + { + "total": 3, + "status_valid": 1, + "status_invalid": 2, + "status_catch_all": 0, + "status_do_not_mail": 0, + "status_spamtrap": 0, + "status_unknown": 0, + "sub_status_toxic": 0, + "sub_status_disposable": 0, + "sub_status_role_based": 0, + "sub_status_possible_trap": 0, + "sub_status_global_suppression": 0, + "sub_status_timeout_exceeded": 0, + "sub_status_mail_server_temporary_error": 0, + "sub_status_mail_server_did_not_respond": 0, + "sub_status_greylisted": 0, + "sub_status_antispam_system": 0, + "sub_status_does_not_accept_mail": 0, + "sub_status_exception_occurred": 0, + "sub_status_failed_syntax_check": 0, + "sub_status_mailbox_not_found": 2, + "sub_status_unroutable_ip_address": 0, + "sub_status_possible_typo": 0, + "sub_status_no_dns_entries": 0, + "sub_status_role_based_catch_all": 0, + "sub_status_mailbox_quota_exceeded": 0, + "sub_status_forcible_disconnect": 0, + "sub_status_failed_smtp_connection": 0, + "start_date": "1/1/2018", + "end_date": "12/12/2019" + }"""; ZBGetApiUsageResponse expectedResponse = gson.fromJson(responseJson, ZBGetApiUsageResponse.class); Date startDate = new Date(); @@ -426,7 +447,7 @@ public void getApiUsage_ReturnSuccess() throws Exception { String urlPath = getEncodedUrl( "https://api.zerobounce.net/v2/getapiusage", - new HashMap() { + new HashMap<>() { { put("api_key", API_KEY); put("start_date", dateFormat.format(startDate)); @@ -434,16 +455,18 @@ public void getApiUsage_ReturnSuccess() throws Exception { } } ); - mockRequest(urlPath, 200, responseJson, ""); - - ZeroBounceSDK.getInstance().getApiUsage( - startDate, - endDate, - response -> { - assertEquals(expectedResponse, response); - }, errorResponse -> { - fail(errorResponse.toString()); - }); + mockRequest( + urlPath, + 200, + responseJson, + "", + () -> zeroBounceSDK.getApiUsage( + startDate, + endDate, + response -> assertEquals(expectedResponse, response), + errorResponse -> fail(errorResponse.toString()) + ) + ); } @Test @@ -458,7 +481,7 @@ public void getApiUsage_ReturnsError() throws Exception { String urlPath = getEncodedUrl( "https://api.zerobounce.net/v2/getapiusage", - new HashMap() { + new HashMap<>() { { put("api_key", API_KEY); put("start_date", dateFormat.format(startDate)); @@ -466,80 +489,86 @@ public void getApiUsage_ReturnsError() throws Exception { } } ); - mockRequest(urlPath, 400, "", responseJson); - - ZeroBounceSDK.getInstance().getApiUsage( - startDate, - endDate, - response -> { - fail(response.toString()); - }, errorResponse -> { - assertEquals(expectedResponse, errorResponse); - }); + mockRequest( + urlPath, + 400, + "", + responseJson, + () -> zeroBounceSDK.getApiUsage( + startDate, + endDate, + response -> fail(response.toString()), + errorResponse -> assertEquals(expectedResponse, errorResponse) + ) + ); } @Test public void sendFile_FileStatus_GetFile_DeleteFile_ReturnSuccess() throws Exception { // Prepare mock response and add it to the server - String responseJson = "{\n" + - " \"success\": true,\n" + - " \"message\": \"File Accepted\",\n" + - " \"file_name\": \"email_file.csv\",\n" + - " \"file_id\": \"b222a0fd-90d5-416c-8f1a-9cc3851fc823\"\n" + - " }"; + String responseJson = """ + { + "success": true, + "message": "File Accepted", + "file_name": "email_file.csv", + "file_id": "b222a0fd-90d5-416c-8f1a-9cc3851fc823" + }"""; ZBSendFileResponse expectedResponse = gson.fromJson(responseJson, ZBSendFileResponse.class); File file = new File("../email_file.csv"); String urlPath = "https://bulkapi.zerobounce.net/v2/sendfile"; - mockMultipartRequest(urlPath, 200, ContentType.APPLICATION_JSON.getMimeType(), responseJson); - - ZeroBounceSDK.getInstance().sendFile( - file, - 1, - null, - response -> { - assertEquals(expectedResponse, response); - }, - errorResponse -> { - fail(errorResponse.toString()); - } + mockMultipartRequest( + urlPath, + 200, + ContentType.APPLICATION_JSON.getMimeType(), + responseJson, + () -> zeroBounceSDK.sendFile( + file, + 1, + null, + response -> assertEquals(expectedResponse, response), + errorResponse -> fail(errorResponse.toString()) + ) ); + // ----------------------------------- // Prepare to check that the file status request works - String fileStatusJson = "{\n" + - " \"success\": true,\n" + - " \"file_id\": \"b222a0fd-90d5-416c-8f1a-9cc3851fc823\",\n" + - " \"file_name\": \"email_file.csv\",\n" + - " \"upload_date\": \"10/20/2018 4:35:58 PM\",\n" + - " \"file_status\": \"Complete\",\n" + - " \"complete_percentage\": \"100%\",\n" + - " \"return_url\": \"Your return URL if provided when calling sendfile API\"\n" + - " }"; + String fileStatusJson = """ + { + "success": true, + "file_id": "b222a0fd-90d5-416c-8f1a-9cc3851fc823", + "file_name": "email_file.csv", + "upload_date": "10/20/2018 4:35:58 PM", + "file_status": "Complete", + "complete_percentage": "100%", + "return_url": "Your return URL if provided when calling sendfile API" + }"""; ZBFileStatusResponse fileStatusResponse = gson.fromJson(fileStatusJson, ZBFileStatusResponse.class); String fileId = expectedResponse.getFileId(); String fileStatusUrlPath = getEncodedUrl( "https://bulkapi.zerobounce.net/v2/filestatus", - new HashMap() { + new HashMap<>() { { put("api_key", API_KEY); put("file_id", fileId); } } ); - mockRequest(fileStatusUrlPath, 200, fileStatusJson, ""); - assertNotNull(fileId); - - ZeroBounceSDK.getInstance().fileStatus( - fileId, - response -> { - assertEquals(fileStatusResponse, response); - }, errorResponse -> { - fail(errorResponse.toString()); - }); + mockRequest( + fileStatusUrlPath, + 200, + fileStatusJson, + "", + () -> zeroBounceSDK.fileStatus( + fileId, + response -> assertEquals(fileStatusResponse, response), + errorResponse -> fail(errorResponse.toString()) + ) + ); // ----------------------------------- // Prepare to get the file we just uploaded @@ -549,117 +578,127 @@ public void sendFile_FileStatus_GetFile_DeleteFile_ReturnSuccess() throws Except String getFileUrlPath = getEncodedUrl( "https://bulkapi.zerobounce.net/v2/getfile", - new HashMap() { + new HashMap<>() { { put("api_key", API_KEY); put("file_id", fileId); } } ); - mockMultipartRequest(getFileUrlPath, 200, ContentType.DEFAULT_BINARY.getMimeType(), responseJson); - - ZeroBounceSDK.getInstance().getFile( - fileId, - "./downloads/b222a0fd-90d5-416c-8f1a-9cc3851fc823.csv", - response -> { - assertEquals(getFileResponse, response); - }, errorResponse -> { - fail(errorResponse.toString()); - }); + mockMultipartRequest( + getFileUrlPath, + 200, + ContentType.DEFAULT_BINARY.getMimeType(), + responseJson, + () -> zeroBounceSDK.getFile( + fileId, + "./downloads/b222a0fd-90d5-416c-8f1a-9cc3851fc823.csv", + response -> assertEquals(getFileResponse, response), + errorResponse -> fail(errorResponse.toString()) + ) + ); // ----------------------------------- // Prepare to delete the file we just uploaded - String deleteFileJson = "{\n" + - " \"success\": true,\n" + - " \"message\": \"File Deleted\",\n" + - " \"file_name\": \"test2\",\n" + - " \"file_id\": \"b222a0fd-90d5-416c-8f1a-9cc3851fc823\"\n" + - "}"; + String deleteFileJson = """ + { + "success": true, + "message": "File Deleted", + "file_name": "test2", + "file_id": "b222a0fd-90d5-416c-8f1a-9cc3851fc823" + }"""; ZBDeleteFileResponse deleteFileResponse = gson.fromJson(deleteFileJson, ZBDeleteFileResponse.class); String deleteFileUrlPath = getEncodedUrl( "https://bulkapi.zerobounce.net/v2/deletefile", - new HashMap() { + new HashMap<>() { { put("api_key", API_KEY); put("file_id", fileId); } } ); - mockRequest(deleteFileUrlPath, 200, deleteFileJson, ""); - - ZeroBounceSDK.getInstance().deleteFile( - fileId, - response -> { - assertEquals(deleteFileResponse, response); - }, errorResponse -> { - fail(errorResponse.toString()); - }); + mockRequest( + deleteFileUrlPath, + 200, + deleteFileJson, + "", + () -> zeroBounceSDK.deleteFile( + fileId, + response -> assertEquals(deleteFileResponse, response), + errorResponse -> fail(errorResponse.toString()) + ) + ); } @Test public void scoringSendFile_ScoringFileStatus_ScoringGetFile_ScoringDeleteFile_ReturnSuccess() throws Exception { // Prepare mock response and add it to the server - String responseJson = "{\n" + - " \"success\": true,\n" + - " \"message\": \"File Accepted\",\n" + - " \"file_name\": \"email_file.csv\",\n" + - " \"file_id\": \"b222a0fd-90d5-416c-8f1a-9cc3851fc823\"\n" + - " }"; + String responseJson = """ + { + "success": true, + "message": "File Accepted", + "file_name": "email_file.csv", + "file_id": "b222a0fd-90d5-416c-8f1a-9cc3851fc823" + }"""; ZBSendFileResponse expectedResponse = gson.fromJson(responseJson, ZBSendFileResponse.class); File file = new File("../email_file.csv"); String urlPath = "https://bulkapi.zerobounce.net/v2/scoring/sendfile"; - mockMultipartRequest(urlPath, 200, ContentType.APPLICATION_JSON.getMimeType(), responseJson); - - ZeroBounceSDK.getInstance().scoringSendFile( - file, - 1, - null, - response -> { - assertEquals(expectedResponse, response); - }, - errorResponse -> { - fail(errorResponse.toString()); - } + mockMultipartRequest( + urlPath, + 200, + ContentType.APPLICATION_JSON.getMimeType(), + responseJson, + () -> zeroBounceSDK.scoringSendFile( + file, + 1, + null, + response -> assertEquals(expectedResponse, response), + errorResponse -> fail(errorResponse.toString()) + ) ); + // ----------------------------------- // Prepare to check that the file status request works - String fileStatusJson = "{\n" + - " \"success\": true,\n" + - " \"file_id\": \"b222a0fd-90d5-416c-8f1a-9cc3851fc823\",\n" + - " \"file_name\": \"email_file.csv\",\n" + - " \"upload_date\": \"10/20/2018 4:35:58 PM\",\n" + - " \"file_status\": \"Complete\",\n" + - " \"complete_percentage\": \"100%\",\n" + - " \"return_url\": \"Your return URL if provided when calling sendfile API\"\n" + - " }"; + String fileStatusJson = """ + { + "success": true, + "file_id": "b222a0fd-90d5-416c-8f1a-9cc3851fc823", + "file_name": "email_file.csv", + "upload_date": "10/20/2018 4:35:58 PM", + "file_status": "Complete", + "complete_percentage": "100%", + "return_url": "Your return URL if provided when calling sendfile API" + }"""; ZBFileStatusResponse fileStatusResponse = gson.fromJson(fileStatusJson, ZBFileStatusResponse.class); String fileId = expectedResponse.getFileId(); String fileStatusUrlPath = getEncodedUrl( "https://bulkapi.zerobounce.net/v2/scoring/filestatus", - new HashMap() { + new HashMap<>() { { put("api_key", API_KEY); put("file_id", fileId); } } ); - mockRequest(fileStatusUrlPath, 200, fileStatusJson, ""); - assertNotNull(fileId); - ZeroBounceSDK.getInstance().scoringFileStatus( - fileId, - response -> { - assertEquals(fileStatusResponse, response); - }, errorResponse -> { - fail(errorResponse.toString()); - }); + mockRequest( + fileStatusUrlPath, + 200, + fileStatusJson, + "", + () -> zeroBounceSDK.scoringFileStatus( + fileId, + response -> assertEquals(fileStatusResponse, response), + errorResponse -> fail(errorResponse.toString()) + ) + ); // ----------------------------------- // Prepare to get the file we just uploaded @@ -669,351 +708,385 @@ public void scoringSendFile_ScoringFileStatus_ScoringGetFile_ScoringDeleteFile_R String getFileUrlPath = getEncodedUrl( "https://bulkapi.zerobounce.net/v2/scoring/getfile", - new HashMap() { + new HashMap<>() { { put("api_key", API_KEY); put("file_id", fileId); } } ); - mockMultipartRequest(getFileUrlPath, 200, ContentType.DEFAULT_BINARY.getMimeType(), responseJson); + mockMultipartRequest( + getFileUrlPath, + 200, + ContentType.DEFAULT_BINARY.getMimeType(), + responseJson, + () -> zeroBounceSDK.scoringGetFile( + fileId, + "./downloads/b222a0fd-90d5-416c-8f1a-9cc3851fc823.csv", + response -> assertEquals(getFileResponse, response), + errorResponse -> fail(errorResponse.toString()) + ) + ); - ZeroBounceSDK.getInstance().scoringGetFile( - fileId, - "./downloads/b222a0fd-90d5-416c-8f1a-9cc3851fc823.csv", - response -> { - assertEquals(getFileResponse, response); - }, errorResponse -> { - fail(errorResponse.toString()); - }); // ----------------------------------- // Prepare to delete the file we just uploaded - String deleteFileJson = "{\n" + - " \"success\": true,\n" + - " \"message\": \"File Deleted\",\n" + - " \"file_name\": \"test2\",\n" + - " \"file_id\": \"b222a0fd-90d5-416c-8f1a-9cc3851fc823\"\n" + - "}"; + String deleteFileJson = """ + { + "success": true, + "message": "File Deleted", + "file_name": "test2", + "file_id": "b222a0fd-90d5-416c-8f1a-9cc3851fc823" + }"""; ZBDeleteFileResponse deleteFileResponse = gson.fromJson(deleteFileJson, ZBDeleteFileResponse.class); String deleteFileUrlPath = getEncodedUrl( "https://bulkapi.zerobounce.net/v2/scoring/deletefile", - new HashMap() { + new HashMap<>() { { put("api_key", API_KEY); put("file_id", fileId); } } ); - mockRequest(deleteFileUrlPath, 200, deleteFileJson, ""); - - ZeroBounceSDK.getInstance().scoringDeleteFile( - fileId, - response -> { - assertEquals(deleteFileResponse, response); - }, errorResponse -> { - fail(errorResponse.toString()); - }); + mockRequest( + deleteFileUrlPath, + 200, + deleteFileJson, + "", + () -> zeroBounceSDK.scoringDeleteFile( + fileId, + response -> assertEquals(deleteFileResponse, response), + errorResponse -> fail(errorResponse.toString()) + ) + ); } @Test public void sendFile_ReturnsError() throws Exception { // Prepare mock response and add it to the server - String responseJson = "{\n" + - " \"success\": false,\n" + - " \"message\": [\n" + - " \"Error messages\"\n" + - " ]\n" + - " }"; + String responseJson = """ + { + "success": false, + "message": [ + "Error messages" + ] + }"""; ErrorResponse expectedResponse = ErrorResponse.parseError(responseJson); File file = new File("../email_file.csv"); String urlPath = "https://bulkapi.zerobounce.net/v2/sendfile"; - mockMultipartRequest(urlPath, 400, ContentType.APPLICATION_JSON.getMimeType(), responseJson); - - ZeroBounceSDK.getInstance().sendFile( - file, - 1, - null, - response -> { - fail(response.toString()); - }, - errorResponse -> { - assertEquals(expectedResponse, errorResponse); - } + mockMultipartRequest( + urlPath, + 400, + ContentType.APPLICATION_JSON.getMimeType(), + responseJson, + () -> zeroBounceSDK.sendFile( + file, + 1, + null, + response -> fail(response.toString()), + errorResponse -> assertEquals(expectedResponse, errorResponse) + ) ); + + } @Test public void scoringSendFile_ReturnsError() throws Exception { // Prepare mock response and add it to the server - String responseJson = "{\n" + - " \"success\": false,\n" + - " \"message\": [\n" + - " \"Error messages\"\n" + - " ]\n" + - " }"; + String responseJson = """ + { + "success": false, + "message": [ + "Error messages" + ] + }"""; ErrorResponse expectedResponse = ErrorResponse.parseError(responseJson); File file = new File("../email_file.csv"); String urlPath = "https://bulkapi.zerobounce.net/v2/scoring/sendfile"; - mockMultipartRequest(urlPath, 400, ContentType.APPLICATION_JSON.getMimeType(), responseJson); - - ZeroBounceSDK.getInstance().scoringSendFile( - file, - 1, - null, - response -> { - fail(response.toString()); - }, - errorResponse -> { - assertEquals(expectedResponse, errorResponse); - } + mockMultipartRequest( + urlPath, + 400, + ContentType.APPLICATION_JSON.getMimeType(), + responseJson, + () -> zeroBounceSDK.scoringSendFile( + file, + 1, + null, + response -> fail(response.toString()), + errorResponse -> assertEquals(expectedResponse, errorResponse) + ) ); } @Test public void fileStatus_ReturnsError() throws Exception { // Prepare mock response and add it to the server - String responseJson = "{\n" + - " \"success\": false,\n" + - " \"message\": \"Error messages\"\n" + - " }"; + String responseJson = """ + { + "success": false, + "message": "Error messages" + }"""; ErrorResponse expectedResponse = ErrorResponse.parseError(responseJson); String fileId = "some-id"; String urlPath = getEncodedUrl( "https://bulkapi.zerobounce.net/v2/filestatus", - new HashMap() { + new HashMap<>() { { put("api_key", API_KEY); put("file_id", fileId); } } ); - mockRequest(urlPath, 400, "", responseJson); - - ZeroBounceSDK.getInstance().fileStatus( - fileId, - response -> { - fail(response.toString()); - }, errorResponse -> { - assertEquals(expectedResponse, errorResponse); - }); + mockRequest( + urlPath, + 400, + "", + responseJson, + () -> zeroBounceSDK.fileStatus( + fileId, + response -> fail(response.toString()), + errorResponse -> assertEquals(expectedResponse, errorResponse) + ) + ); } @Test public void scoringFileStatus_ReturnsError() throws Exception { // Prepare mock response and add it to the server - String responseJson = "{\n" + - " \"success\": false,\n" + - " \"message\": \"Error messages\"\n" + - " }"; + String responseJson = """ + { + "success": false, + "message": "Error messages" + }"""; ErrorResponse expectedResponse = ErrorResponse.parseError(responseJson); String fileId = "some-id"; String urlPath = getEncodedUrl( "https://bulkapi.zerobounce.net/v2/scoring/filestatus", - new HashMap() { + new HashMap<>() { { put("api_key", API_KEY); put("file_id", fileId); } } ); - mockRequest(urlPath, 400, "", responseJson); - - ZeroBounceSDK.getInstance().scoringFileStatus( - fileId, - response -> { - fail(response.toString()); - }, errorResponse -> { - assertEquals(expectedResponse, errorResponse); - }); + mockRequest( + urlPath, + 400, + "", + responseJson, + () -> zeroBounceSDK.scoringFileStatus( + fileId, + response -> fail(response.toString()), + errorResponse -> assertEquals(expectedResponse, errorResponse) + ) + ); } @Test public void getFile_ReturnsError() throws Exception { // Prepare mock response and add it to the server - String responseJson = "{\n" + - " \"success\": false,\n" + - " \"message\": \"Error messages\"\n" + - "}"; + String responseJson = """ + { + "success": false, + "message": "Error messages" + }"""; ErrorResponse expectedResponse = ErrorResponse.parseError(responseJson); String fileId = "some-id"; String urlPath = getEncodedUrl( "https://bulkapi.zerobounce.net/v2/getfile", - new HashMap() { + new HashMap<>() { { put("api_key", API_KEY); put("file_id", fileId); } } ); - mockMultipartRequest(urlPath, 400, ContentType.APPLICATION_JSON.getMimeType(), responseJson); - - ZeroBounceSDK.getInstance().getFile( - fileId, - "./downloads/file.csv", - response -> { - fail(response.toString()); - }, errorResponse -> { - assertEquals(expectedResponse, errorResponse); - }); + mockMultipartRequest( + urlPath, + 400, + ContentType.APPLICATION_JSON.getMimeType(), + responseJson, + () -> zeroBounceSDK.getFile( + fileId, + "./downloads/file.csv", + response -> fail(response.toString()), + errorResponse -> assertEquals(expectedResponse, errorResponse) + ) + ); } @Test public void scoringGetFile_ReturnsError() throws Exception { // Prepare mock response and add it to the server - String responseJson = "{\n" + - " \"success\": false,\n" + - " \"message\": \"Error messages\"\n" + - "}"; + String responseJson = """ + { + "success": false, + "message": "Error messages" + }"""; ErrorResponse expectedResponse = ErrorResponse.parseError(responseJson); String fileId = "some-id"; String urlPath = getEncodedUrl( "https://bulkapi.zerobounce.net/v2/scoring/getfile", - new HashMap() { + new HashMap<>() { { put("api_key", API_KEY); put("file_id", fileId); } } ); - mockMultipartRequest(urlPath, 400, ContentType.APPLICATION_JSON.getMimeType(), responseJson); - - ZeroBounceSDK.getInstance().scoringGetFile( - fileId, - "./downloads/file.csv", - response -> { - fail(response.toString()); - }, errorResponse -> { - assertEquals(expectedResponse, errorResponse); - }); + mockMultipartRequest( + urlPath, + 400, + ContentType.APPLICATION_JSON.getMimeType(), + responseJson, + () -> zeroBounceSDK.scoringGetFile( + fileId, + "./downloads/file.csv", + response -> fail(response.toString()), + errorResponse -> assertEquals(expectedResponse, errorResponse) + ) + ); } @Test public void deleteFile_ReturnsError() throws Exception { // Prepare mock response and add it to the server - String responseJson = "{\n" + - " \"success\": false,\n" + - " \"message\": \"File cannot be found.\"\n" + - "}"; + String responseJson = """ + { + "success": false, + "message": "File cannot be found." + }"""; ErrorResponse expectedResponse = ErrorResponse.parseError(responseJson); String fileId = "some-id"; String urlPath = getEncodedUrl( "https://bulkapi.zerobounce.net/v2/deletefile", - new HashMap() { + new HashMap<>() { { put("api_key", API_KEY); put("file_id", fileId); } } ); - mockRequest(urlPath, 400, "", responseJson); - - ZeroBounceSDK.getInstance().deleteFile( - fileId, - response -> { - fail(response.toString()); - }, errorResponse -> { - assertEquals(expectedResponse, errorResponse); - }); + mockRequest( + urlPath, + 400, + "", + responseJson, + () -> zeroBounceSDK.deleteFile( + fileId, + response -> fail(response.toString()), + errorResponse -> assertEquals(expectedResponse, errorResponse) + ) + ); } @Test public void scoringDeleteFile_ReturnsError() throws Exception { // Prepare mock response and add it to the server - String responseJson = "{\n" + - " \"success\": false,\n" + - " \"message\": \"File cannot be found.\"\n" + - "}"; + String responseJson = """ + { + "success": false, + "message": "File cannot be found." + }"""; ErrorResponse expectedResponse = ErrorResponse.parseError(responseJson); String fileId = "some-id"; String urlPath = getEncodedUrl( "https://bulkapi.zerobounce.net/v2/scoring/deletefile", - new HashMap() { + new HashMap<>() { { put("api_key", API_KEY); put("file_id", fileId); } } ); - mockRequest(urlPath, 400, "", responseJson); - - ZeroBounceSDK.getInstance().scoringDeleteFile( - fileId, - response -> { - fail(response.toString()); - }, errorResponse -> { - assertEquals(expectedResponse, errorResponse); - }); + mockRequest( + urlPath, + 400, + "", + responseJson, + () -> zeroBounceSDK.scoringDeleteFile( + fileId, + response -> fail(response.toString()), + errorResponse -> assertEquals(expectedResponse, errorResponse) + ) + ); } @Test public void getActivityData_ReturnsSuccess() throws Exception { // Prepare mock response and add it to the server - String responseJson = "{\n" + - " \"found\": true,\n" + - " \"active_in_days\": 60\n" + - "}"; + String responseJson = """ + { + "found": true, + "active_in_days": 60 + }"""; ZBActivityDataResponse expectedResponse = gson.fromJson(responseJson, ZBActivityDataResponse.class); String email = "flowerjill@aol.com"; String urlPath = getEncodedUrl( "https://api.zerobounce.net/v2/activity", - new HashMap() { + new HashMap<>() { { put("api_key", API_KEY); put("email", email); } } ); - mockRequest(urlPath, 200, responseJson, ""); - - ZeroBounceSDK.getInstance().getActivityData( - email, - response -> { - assertEquals(expectedResponse, response); - }, errorResponse -> { - fail(errorResponse.toString()); - }); + mockRequest( + urlPath, + 200, + responseJson, + "", + () -> zeroBounceSDK.getActivityData( + email, + response -> assertEquals(expectedResponse, response), + errorResponse -> fail(errorResponse.toString()) + ) + ); } @Test public void getActivityData_ReturnsError() throws Exception { // Prepare mock response and add it to the server - String responseJson = "{\n" + - " \"found\": false,\n" + - " \"active_in_days\": null\n" + - "}"; + String responseJson = """ + { + "found": false, + "active_in_days": null + }"""; ErrorResponse expectedResponse = ErrorResponse.parseError(responseJson); String email = "flowerjill@aol.com"; String urlPath = getEncodedUrl( "https://api.zerobounce.net/v2/activity", - new HashMap() { + new HashMap<>() { { put("api_key", API_KEY); put("email", email); } } ); - mockRequest(urlPath, 400, "", responseJson); - - ZeroBounceSDK.getInstance().getActivityData( - email, - response -> { - fail(response.toString()); - }, errorResponse -> { - assertEquals(expectedResponse, errorResponse); - }); + mockRequest( + urlPath, + 400, + "", + responseJson, + () -> zeroBounceSDK.getActivityData( + email, + response -> fail(response.toString()), + errorResponse -> assertEquals(expectedResponse, errorResponse) + ) + ); } @Test @@ -1021,7 +1094,7 @@ public void defaultLoggerEmitsNoConsoleOutput() throws Exception { String responseJson = "{\"Credits\":2375323}"; String urlPath = getEncodedUrl( "https://api.zerobounce.net/v2/getcredits", - new HashMap() { + new HashMap<>() { { put("api_key", API_KEY); } @@ -1036,10 +1109,18 @@ public void defaultLoggerEmitsNoConsoleOutput() throws Exception { ZeroBounceSDK.setLogPayloads(false); try { - mockRequest(urlPath, 200, responseJson, ""); - ZeroBounceSDK.getInstance().getCredits( - response -> { - }, errorResponse -> fail(errorResponse.toString())); + mockRequest( + urlPath, + 200, + responseJson, + "", + () -> zeroBounceSDK.getCredits( + response -> { + }, + errorResponse -> fail(errorResponse.toString()) + ) + ); + } finally { System.setOut(originalOut); ZeroBounceSDK.setLogger(null); @@ -1054,7 +1135,7 @@ public void payloadLoggingUsesConfiguredLoggerOnly() throws Exception { String responseJson = "{\"Credits\":2375323}"; String urlPath = getEncodedUrl( "https://api.zerobounce.net/v2/getcredits", - new HashMap() { + new HashMap<>() { { put("api_key", API_KEY); } @@ -1077,10 +1158,17 @@ public void debug(String msg) { ZeroBounceSDK.setLogPayloads(true); try { - mockRequest(urlPath, 200, responseJson, ""); - ZeroBounceSDK.getInstance().getCredits( - response -> { - }, errorResponse -> fail(errorResponse.toString())); + mockRequest( + urlPath, + 200, + responseJson, + "", + () -> zeroBounceSDK.getCredits( + response -> { + }, errorResponse -> fail(errorResponse.toString()) + ) + ); + } finally { System.setOut(originalOut); ZeroBounceSDK.setLogger(null); @@ -1108,41 +1196,50 @@ private void mockRequest( @NotNull String urlPath, int statusCode, @NotNull String response, - @NotNull String errorResponse - ) throws Exception { - URL url = PowerMockito.mock(URL.class); - PowerMockito.whenNew(URL.class).withArguments(urlPath).thenReturn(url); - HttpURLConnection con = PowerMockito.mock(HttpURLConnection.class); - PowerMockito.when(url.openConnection()).thenReturn(con); - PowerMockito.when(con.getResponseCode()).thenReturn(statusCode); - PowerMockito.when(con.getOutputStream()).thenReturn(new ByteArrayOutputStream()); - PowerMockito.when(con.getInputStream()).thenReturn(new ByteArrayInputStream(response.getBytes())); - PowerMockito.when(con.getErrorStream()).thenReturn(new ByteArrayInputStream(errorResponse.getBytes())); + @NotNull String errorResponse, + Runnable block + ) throws IOException { + URL url = mock(URL.class, withSettings().useConstructor(urlPath)); + HttpURLConnection con = mock(HttpURLConnection.class); + lenient().when(url.openConnection()).thenReturn(con); + lenient().when(con.getResponseCode()).thenReturn(statusCode); + lenient().when(con.getOutputStream()).thenReturn(new ByteArrayOutputStream()); + lenient().when(con.getInputStream()).thenReturn(new ByteArrayInputStream(response.getBytes())); + lenient().when(con.getErrorStream()).thenReturn(new ByteArrayInputStream(errorResponse.getBytes())); + lenient().doReturn(url).when(zeroBounceSDK).createUrlFrom(anyString()); + block.run(); } private void mockMultipartRequest( @NotNull String urlPath, int statusCode, String contentType, - @NotNull String response + @NotNull String response, + ThrowingRunnable block ) throws Exception { - HttpPost httpPost = PowerMockito.mock(HttpPost.class); - PowerMockito.whenNew(HttpPost.class).withArguments(urlPath).thenReturn(httpPost); - - CloseableHttpClient httpClient = PowerMockito.mock(CloseableHttpClient.class); - CloseableHttpResponse mockedResponse = PowerMockito.mock(CloseableHttpResponse.class); - HttpEntity mockedEntity = PowerMockito.mock(HttpEntity.class); - StatusLine statusLine = PowerMockito.mock(StatusLine.class); - Header header = PowerMockito.mock(Header.class); - - PowerMockito.mockStatic(HttpClients.class); - PowerMockito.when(HttpClients.createDefault()).thenReturn(httpClient); - PowerMockito.when(httpClient.execute(any())).thenReturn(mockedResponse); - PowerMockito.when(mockedResponse.getEntity()).thenReturn(mockedEntity); - PowerMockito.when(mockedResponse.getStatusLine()).thenReturn(statusLine); - PowerMockito.when(mockedResponse.getFirstHeader("Content-Type")).thenReturn(header); - PowerMockito.when(header.getValue()).thenReturn(contentType); - PowerMockito.when(statusLine.getStatusCode()).thenReturn(statusCode); - PowerMockito.when(mockedEntity.getContent()).thenReturn(new ByteArrayInputStream(response.getBytes())); + CloseableHttpClient httpClient = mock(CloseableHttpClient.class); + CloseableHttpResponse mockedResponse = mock(CloseableHttpResponse.class); + HttpEntity mockedEntity = mock(HttpEntity.class); + StatusLine statusLine = mock(StatusLine.class); + Header header = mock(Header.class); + + try ( + MockedConstruction ignored = Mockito.mockConstruction( + HttpPost.class, + withSettings().useConstructor(urlPath) + ); + MockedStatic ignored1 = Mockito.mockStatic(HttpClients.class) + ) { + lenient().when(HttpClients.createDefault()).thenReturn(httpClient); + lenient().when(httpClient.execute(any())).thenReturn(mockedResponse); + lenient().when(mockedResponse.getEntity()).thenReturn(mockedEntity); + lenient().when(mockedResponse.getStatusLine()).thenReturn(statusLine); + lenient().when(mockedResponse.getFirstHeader("Content-Type")).thenReturn(header); + lenient().when(header.getValue()).thenReturn(contentType); + lenient().when(statusLine.getStatusCode()).thenReturn(statusCode); + lenient().when(mockedEntity.getContent()).thenReturn(new ByteArrayInputStream(response.getBytes())); + + block.run(); + } } } \ No newline at end of file