From: David ‘Bombe’ Roden Date: Wed, 26 Oct 2016 16:48:04 +0000 (+0200) Subject: Merge branch 'release-0.9.6' X-Git-Tag: 0.9.6^0 X-Git-Url: https://git.pterodactylus.net/?p=Sone.git;a=commitdiff_plain;h=7b55e0be6a3283e43a9bbab98f82aebdd948eb33;hp=c4ae226ec5052116cefc542ae2017036a7bc6332 Merge branch 'release-0.9.6' --- diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..9221dd3 --- /dev/null +++ b/build.gradle @@ -0,0 +1,94 @@ +group = 'net.pterodactylus' +version = '0.9.6' + +buildscript { + repositories { + mavenCentral() + } + dependencies { + classpath group: 'info.solidsoft.gradle.pitest', name: 'gradle-pitest-plugin', version: '1.1.10' + } +} + +repositories { + maven { url "http://maven.pterodactylus.net/" } + mavenCentral() +} + +apply plugin: 'java' + +sourceCompatibility = 1.7 +targetCompatibility = 1.7 + +tasks.withType(JavaCompile) { + options.encoding = 'UTF-8' +} + +configurations { + provided { + dependencies.all { dep -> + configurations.default.exclude group: dep.group, module: dep.name + } + } + compile.extendsFrom provided +} + +dependencies { + provided group: 'org.freenetproject', name: 'fred', version: '0.7.5.1475' + provided group: 'org.freenetproject', name: 'freenet-ext', version: '29' + provided group: 'org.bouncycastle', name: 'bcprov-jdk15on', version: '1.54' + + compile group: 'net.pterodactylus', name: 'utils', version: '0.12.4' + compile group: 'com.google.inject', name: 'guice', version: '3.0' + compile group: 'com.google.guava', name: 'guava', version: '14.0.1' + compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.1.2' + compile group: 'com.google.code.findbugs', name: 'jsr305', version: '2.0.1' + + testCompile group: 'junit', name: 'junit', version: '4.11' + testCompile group: 'org.mockito', name: 'mockito-core', version: '2.1.0' + testCompile group: 'org.jsoup', name: 'jsoup', version: '1.7.1' + testCompile group: 'org.hamcrest', name: 'hamcrest-all', version: '1.3' +} + +task fatJar(type: Jar) { + archiveName = project.name + '-jar-with-dependencies.jar' + from { (configurations.runtime - configurations.provided).collect { it.isDirectory() ? it : zipTree(it) } } + manifest { + attributes('Plugin-Main-Class': 'net.pterodactylus.sone.main.SonePlugin') + } + with jar +} + +javadoc { + options { + quiet() + showFromPrivate() + footer('© 2010–2013 David ‘Bombe’ Roden') + links('http://docs.oracle.com/javase/7/docs/api/') + } + failOnError = false +} + +apply plugin: 'jacoco' + +jacoco { + toolVersion = '0.7.7.201606060606' +} + +jacocoTestReport.dependsOn test + +apply plugin: 'info.solidsoft.pitest' + +pitest { + outputFormats = ['HTML', 'XML'] + timestampedReports = false + timeoutFactor = 3.0 +} + +apply plugin: 'findbugs' + +findbugs { + ignoreFailures = true +} + +apply plugin: 'idea' diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..6ffa237 Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..92781d4 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Wed Oct 19 20:11:35 CEST 2016 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-3.1-bin.zip diff --git a/gradlew b/gradlew new file mode 100755 index 0000000..9aa616c --- /dev/null +++ b/gradlew @@ -0,0 +1,169 @@ +#!/usr/bin/env bash + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# 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 +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn ( ) { + echo "$*" +} + +die ( ) { + echo + echo "$*" + echo + exit 1 +} + +# 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 + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +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" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + 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 +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 +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 + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; 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 + # 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\"" + fi + i=$((i+1)) + 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 + +# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules +function splitJvmOpts() { + JVM_OPTS=("$@") +} +eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS +JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [[ "$(uname)" == "Darwin" ]] && [[ "$HOME" == "$PWD" ]]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..e95643d --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,84 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +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 + +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% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="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 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/pom.xml b/pom.xml deleted file mode 100644 index 1799801..0000000 --- a/pom.xml +++ /dev/null @@ -1,212 +0,0 @@ - - 4.0.0 - net.pterodactylus - sone - 0.9.5 - - - net.pterodactylus - utils - ${version.utils} - - - junit - junit - 4.11 - test - - - org.mockito - mockito-all - 1.9.5 - test - - - org.hamcrest - hamcrest-all - 1.3 - - - org.jsoup - jsoup - 1.7.1 - test - - - org.freenetproject - fred - 0.7.5.1467.99.3 - provided - - - org.freenetproject - freenet-ext - 29 - provided - - - com.google.inject - guice - 3.0 - - - com.google.guava - guava - 14.0.1 - - - commons-lang - commons-lang - 2.6 - - - com.fasterxml.jackson.core - jackson-databind - 2.1.2 - - - com.google.code.findbugs - jsr305 - 2.0.1 - - - - - pterodactylus - http://maven.pterodactylus.net/ - - - - UTF-8 - 0.12.4 - 600000 - - - - - org.codehaus.mojo - findbugs-maven-plugin - 2.5.2 - - ${findbugs.timeout} - - - - org.apache.maven.plugins - maven-compiler-plugin - 2.0.2 - - 1.6 - 1.6 - UTF-8 - - - - org.apache.maven.plugins - maven-jar-plugin - 2.2 - - - - net.pterodactylus.sone.main.SonePlugin - - - - - - org.apache.maven.plugins - maven-assembly-plugin - 2.2-beta-5 - - sone - - jar-with-dependencies - - - skip - - - - net.pterodactylus.sone.main.SonePlugin - - - - - - make-assembly - package - - single - - - - - - org.apache.maven.plugins - maven-javadoc-plugin - 2.7 - - true - true - private -
© 2010–2013 David ‘Bombe’ Roden
-
-
- - org.jacoco - jacoco-maven-plugin - 0.7.6.201602180812 - - - default-prepare-agent - - prepare-agent - - - - default-report - prepare-package - - report - - - - default-check - - check - - - - - - BUNDLE - - - - COMPLEXITY - COVEREDRATIO - 0.60 - - - - - - - - - - org.pitest - pitest-maven - 1.1.10 - - - net.pterodactylus.sone.* - - - net.pterodactylus.sone.* - - - -
-
-
diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..e60d974 --- /dev/null +++ b/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'sone' diff --git a/src/main/java/net/pterodactylus/sone/core/Core.java b/src/main/java/net/pterodactylus/sone/core/Core.java index 3b958f1..91825a6 100644 --- a/src/main/java/net/pterodactylus/sone/core/Core.java +++ b/src/main/java/net/pterodactylus/sone/core/Core.java @@ -643,7 +643,7 @@ public class Core extends AbstractService implements SoneProvider, PostProvider, Sone sone = database.newSoneBuilder().local().from(ownIdentity).build(); String property = fromNullable(ownIdentity.getProperty("Sone.LatestEdition")).or("0"); sone.setLatestEdition(fromNullable(tryParse(property)).or(0L)); - sone.setClient(new Client("Sone", SonePlugin.VERSION.toString())); + sone.setClient(new Client("Sone", SonePlugin.getPluginVersion())); sone.setKnown(true); SoneInserter soneInserter = new SoneInserter(this, eventBus, freenetInterface, ownIdentity.getId()); eventBus.register(soneInserter); diff --git a/src/main/java/net/pterodactylus/sone/core/SoneInserter.java b/src/main/java/net/pterodactylus/sone/core/SoneInserter.java index 46558ab..26135ea 100644 --- a/src/main/java/net/pterodactylus/sone/core/SoneInserter.java +++ b/src/main/java/net/pterodactylus/sone/core/SoneInserter.java @@ -307,7 +307,7 @@ public class SoneInserter extends AbstractService { soneProperties.put("time", currentTimeMillis()); soneProperties.put("requestUri", sone.getRequestUri()); soneProperties.put("profile", sone.getProfile()); - soneProperties.put("posts", Ordering.from(Post.TIME_COMPARATOR).sortedCopy(sone.getPosts())); + soneProperties.put("posts", Ordering.from(Post.NEWEST_FIRST).sortedCopy(sone.getPosts())); soneProperties.put("replies", Ordering.from(Reply.TIME_COMPARATOR).reverse().sortedCopy(sone.getReplies())); soneProperties.put("likedPostIds", new HashSet(sone.getLikedPostIds())); soneProperties.put("likedReplyIds", new HashSet(sone.getLikedReplyIds())); @@ -393,7 +393,7 @@ public class SoneInserter extends AbstractService { templateContext.set("core", core); templateContext.set("currentSone", soneProperties); templateContext.set("currentEdition", core.getUpdateChecker().getLatestEdition()); - templateContext.set("version", SonePlugin.VERSION); + templateContext.set("version", SonePlugin.getPluginVersion()); StringWriter writer = new StringWriter(); try { template.render(templateContext, writer); diff --git a/src/main/java/net/pterodactylus/sone/data/Post.java b/src/main/java/net/pterodactylus/sone/data/Post.java index 990e20d..5a1c2c5 100644 --- a/src/main/java/net/pterodactylus/sone/data/Post.java +++ b/src/main/java/net/pterodactylus/sone/data/Post.java @@ -33,7 +33,7 @@ import com.google.common.base.Predicate; public interface Post extends Identified { /** Comparator for posts, sorts descending by time. */ - public static final Comparator TIME_COMPARATOR = new Comparator() { + public static final Comparator NEWEST_FIRST = new Comparator() { @Override public int compare(Post leftPost, Post rightPost) { diff --git a/src/main/java/net/pterodactylus/sone/data/impl/AbstractPostBuilder.java b/src/main/java/net/pterodactylus/sone/data/impl/AbstractPostBuilder.java index f33a446..9e2c50a 100644 --- a/src/main/java/net/pterodactylus/sone/data/impl/AbstractPostBuilder.java +++ b/src/main/java/net/pterodactylus/sone/data/impl/AbstractPostBuilder.java @@ -19,8 +19,6 @@ package net.pterodactylus.sone.data.impl; import static com.google.common.base.Preconditions.checkState; -import org.apache.commons.lang.StringUtils; - import net.pterodactylus.sone.data.Post; import net.pterodactylus.sone.database.PostBuilder; import net.pterodactylus.sone.database.SoneProvider; @@ -163,7 +161,7 @@ public abstract class AbstractPostBuilder implements PostBuilder { checkState((randomId && (id == null)) || (!randomId && (id != null)), "exactly one of random ID or custom ID must be set"); checkState(senderId != null, "sender must not be null"); checkState((currentTime && (time == 0)) || (!currentTime && (time > 0)), "one of current time or custom time must be set"); - checkState(!StringUtils.isBlank(text), "text must not be empty"); + checkState((text != null) && !text.trim().isEmpty(), "text must not be empty"); checkState((recipientId == null) || !recipientId.equals(senderId), "sender and recipient must not be the same"); } diff --git a/src/main/java/net/pterodactylus/sone/data/impl/AbstractPostReplyBuilder.java b/src/main/java/net/pterodactylus/sone/data/impl/AbstractPostReplyBuilder.java index 10bdf76..bd8090f 100644 --- a/src/main/java/net/pterodactylus/sone/data/impl/AbstractPostReplyBuilder.java +++ b/src/main/java/net/pterodactylus/sone/data/impl/AbstractPostReplyBuilder.java @@ -19,8 +19,6 @@ package net.pterodactylus.sone.data.impl; import static com.google.common.base.Preconditions.checkState; -import org.apache.commons.lang.StringUtils; - import net.pterodactylus.sone.database.PostReplyBuilder; /** @@ -58,7 +56,7 @@ public abstract class AbstractPostReplyBuilder extends AbstractReplyBuilder= 0)), "either current time or custom time must be set"); - checkState(!StringUtils.isBlank(text), "text must not be empty"); + checkState((text != null) && !text.trim().isEmpty(), "text must not be empty"); checkState(postId != null, "post must not be null"); } diff --git a/src/main/java/net/pterodactylus/sone/data/impl/PostReplyBuilderImpl.java b/src/main/java/net/pterodactylus/sone/data/impl/PostReplyBuilderImpl.java index 30f32fc..7235bc9 100644 --- a/src/main/java/net/pterodactylus/sone/data/impl/PostReplyBuilderImpl.java +++ b/src/main/java/net/pterodactylus/sone/data/impl/PostReplyBuilderImpl.java @@ -26,8 +26,6 @@ import net.pterodactylus.sone.database.PostProvider; import net.pterodactylus.sone.database.PostReplyBuilder; import net.pterodactylus.sone.database.SoneProvider; -import org.apache.commons.lang.StringUtils; - /** * {@link PostReplyBuilder} implementation that creates {@link PostReplyImpl} * objects. @@ -63,7 +61,7 @@ public class PostReplyBuilderImpl extends AbstractPostReplyBuilder { checkState((randomId && (id == null)) || (!randomId && (id != null)), "either random ID nor custom ID must be set"); checkState(senderId != null, "sender must not be null"); checkState((currentTime && (time == 0)) || (!currentTime && (time >= 0)), "either current time or custom time must be set"); - checkState(!StringUtils.isBlank(text), "text must not be empty"); + checkState((text != null) && !text.trim().isEmpty(), "text must not be empty"); checkState(postId != null, "post must not be null"); /* create new post reply. */ diff --git a/src/main/java/net/pterodactylus/sone/data/impl/SoneImpl.java b/src/main/java/net/pterodactylus/sone/data/impl/SoneImpl.java index 8a6dd80..04a5bcc 100644 --- a/src/main/java/net/pterodactylus/sone/data/impl/SoneImpl.java +++ b/src/main/java/net/pterodactylus/sone/data/impl/SoneImpl.java @@ -368,7 +368,7 @@ public class SoneImpl implements Sone { synchronized (this) { sortedPosts = new ArrayList(posts); } - Collections.sort(sortedPosts, Post.TIME_COMPARATOR); + Collections.sort(sortedPosts, Post.NEWEST_FIRST); return sortedPosts; } diff --git a/src/main/java/net/pterodactylus/sone/fcp/GetPostFeedCommand.java b/src/main/java/net/pterodactylus/sone/fcp/GetPostFeedCommand.java index bbff5ed..dea5156 100644 --- a/src/main/java/net/pterodactylus/sone/fcp/GetPostFeedCommand.java +++ b/src/main/java/net/pterodactylus/sone/fcp/GetPostFeedCommand.java @@ -74,7 +74,7 @@ public class GetPostFeedCommand extends AbstractSoneCommand { allPosts = Collections2.filter(allPosts, Post.FUTURE_POSTS_FILTER); List sortedPosts = new ArrayList(allPosts); - Collections.sort(sortedPosts, Post.TIME_COMPARATOR); + Collections.sort(sortedPosts, Post.NEWEST_FIRST); if (sortedPosts.size() < startPost) { return new Response("PostFeed", encodePosts(Collections. emptyList(), "Posts.", false)); diff --git a/src/main/java/net/pterodactylus/sone/fcp/VersionCommand.java b/src/main/java/net/pterodactylus/sone/fcp/VersionCommand.java index b887926..ee0f2e5 100644 --- a/src/main/java/net/pterodactylus/sone/fcp/VersionCommand.java +++ b/src/main/java/net/pterodactylus/sone/fcp/VersionCommand.java @@ -45,7 +45,7 @@ public class VersionCommand extends AbstractSoneCommand { */ @Override public Response execute(SimpleFieldSet parameters, Bucket data, AccessType accessType) { - return new Response("Version", new SimpleFieldSetBuilder().put("Version", SonePlugin.VERSION.toString()).put("ProtocolVersion", 1).get()); + return new Response("Version", new SimpleFieldSetBuilder().put("Version", SonePlugin.getPluginVersion()).put("ProtocolVersion", 1).get()); } } diff --git a/src/main/java/net/pterodactylus/sone/main/SonePlugin.java b/src/main/java/net/pterodactylus/sone/main/SonePlugin.java index bff0a49..61bd6ce 100644 --- a/src/main/java/net/pterodactylus/sone/main/SonePlugin.java +++ b/src/main/java/net/pterodactylus/sone/main/SonePlugin.java @@ -116,12 +116,12 @@ public class SonePlugin implements FredPlugin, FredPluginFCP, FredPluginL10n, Fr } /** The version. */ - public static final Version VERSION = new Version(0, 9, 5); + private static final Version VERSION = new Version(0, 9, 6); /** The current year at time of release. */ private static final int YEAR = 2016; private static final String SONE_HOMEPAGE = "USK@nwa8lHa271k2QvJ8aa0Ov7IHAV-DFOCFgmDt3X6BpCI,DuQSUZiI~agF8c-6tjsFFGuZ8eICrzWCILB60nT8KKo,AQACAAE/sone/"; - private static final int LATEST_EDITION = 72; + private static final int LATEST_EDITION = 73; /** The logger. */ private static final Logger logger = getLogger(SonePlugin.class.getName()); @@ -175,6 +175,10 @@ public class SonePlugin implements FredPlugin, FredPluginFCP, FredPluginL10n, Fr return l10n; } + public static String getPluginVersion() { + return VERSION.toString(); + } + public static int getYear() { return YEAR; } diff --git a/src/main/java/net/pterodactylus/sone/template/ImageLinkFilter.java b/src/main/java/net/pterodactylus/sone/template/ImageLinkFilter.java index 2f1526f..511baf8 100644 --- a/src/main/java/net/pterodactylus/sone/template/ImageLinkFilter.java +++ b/src/main/java/net/pterodactylus/sone/template/ImageLinkFilter.java @@ -45,7 +45,7 @@ import com.google.common.base.Optional; public class ImageLinkFilter implements Filter { /** The template to render for the <img> tag. */ - private static final Template linkTemplate = TemplateParser.parse(new StringReader(" class=\"<%class|css>\"<%/if> src=\"<%src|html><%if forceDownload>?forcedownload=true<%/if>\" alt=\"<%alt|html>\" title=\"<%title|html>\" width=\"<%width|html>\" height=\"<%height|html>\" style=\"position: relative;<%ifnull ! top>top: <% top|html>;<%/if><%ifnull ! left>left: <% left|html>;<%/if>\"/>")); + private static final Template linkTemplate = TemplateParser.parse(new StringReader(" class=\"<%class|css>\"<%/if> src=\"<%src|html>\" alt=\"<%alt|html>\" title=\"<%title|html>\" width=\"<%width|html>\" height=\"<%height|html>\" style=\"position: relative;<%ifnull ! top>top: <% top|html>;<%/if><%ifnull ! left>left: <% left|html>;<%/if>\"/>")); /** The core. */ private final Core core; @@ -90,7 +90,6 @@ public class ImageLinkFilter implements Filter { linkTemplateContext.set("class", imageClass); if (image.isInserted()) { linkTemplateContext.set("src", "/" + image.getKey()); - linkTemplateContext.set("forceDownload", true); } else { linkTemplateContext.set("src", "getImage.html?image=" + image.getId()); } diff --git a/src/main/java/net/pterodactylus/sone/template/ParserFilter.java b/src/main/java/net/pterodactylus/sone/template/ParserFilter.java index 479b3b2..7cf8c70 100644 --- a/src/main/java/net/pterodactylus/sone/template/ParserFilter.java +++ b/src/main/java/net/pterodactylus/sone/template/ParserFilter.java @@ -39,7 +39,6 @@ import net.pterodactylus.sone.text.PostPart; import net.pterodactylus.sone.text.SonePart; import net.pterodactylus.sone.text.SoneTextParser; import net.pterodactylus.sone.text.SoneTextParserContext; -import net.pterodactylus.sone.web.page.FreenetRequest; import net.pterodactylus.util.template.Filter; import net.pterodactylus.util.template.Template; import net.pterodactylus.util.template.TemplateContext; @@ -97,8 +96,7 @@ public class ParserFilter implements Filter { if (sone instanceof String) { sone = core.getSone((String) sone).orNull(); } - FreenetRequest request = (FreenetRequest) templateContext.get("request"); - SoneTextParserContext context = new SoneTextParserContext(request, (Sone) sone); + SoneTextParserContext context = new SoneTextParserContext((Sone) sone); StringWriter parsedTextWriter = new StringWriter(); Iterable parts = soneTextParser.parse(text, context); if (length > -1) { @@ -246,7 +244,7 @@ public class ParserFilter implements Filter { */ private void render(Writer writer, PostPart postPart) { SoneTextParser parser = new SoneTextParser(core, core); - SoneTextParserContext parserContext = new SoneTextParserContext(null, postPart.getPost().getSone()); + SoneTextParserContext parserContext = new SoneTextParserContext(postPart.getPost().getSone()); Iterable parts = parser.parse(postPart.getPost().getText(), parserContext); StringBuilder excerpt = new StringBuilder(); for (Part part : parts) { diff --git a/src/main/java/net/pterodactylus/sone/text/FreenetLinkPart.java b/src/main/java/net/pterodactylus/sone/text/FreenetLinkPart.java index 829bf0f..493880f 100644 --- a/src/main/java/net/pterodactylus/sone/text/FreenetLinkPart.java +++ b/src/main/java/net/pterodactylus/sone/text/FreenetLinkPart.java @@ -17,6 +17,8 @@ package net.pterodactylus.sone.text; +import javax.annotation.Nonnull; + /** * {@link LinkPart} implementation that stores an additional attribute: if the * link is an SSK or USK link and the post was created by an identity that owns @@ -26,49 +28,17 @@ package net.pterodactylus.sone.text; */ public class FreenetLinkPart extends LinkPart { - /** Whether the link is trusted. */ private final boolean trusted; - /** - * Creates a new freenet link part. - * - * @param link - * The link of the part - * @param text - * The text of the part - * @param trusted - * {@code true} if the link is trusted, {@code false} otherwise - */ - public FreenetLinkPart(String link, String text, boolean trusted) { + public FreenetLinkPart(@Nonnull String link, @Nonnull String text, boolean trusted) { this(link, text, text, trusted); } - /** - * Creates a new freenet link part. - * - * @param link - * The link of the part - * @param text - * The text of the part - * @param title - * The title of the part - * @param trusted - * {@code true} if the link is trusted, {@code false} otherwise - */ - public FreenetLinkPart(String link, String text, String title, boolean trusted) { + public FreenetLinkPart(@Nonnull String link, @Nonnull String text, @Nonnull String title, boolean trusted) { super(link, text, title); this.trusted = trusted; } - // - // ACCESSORS - // - - /** - * Returns whether the link is trusted. - * - * @return {@code true} if the link is trusted, {@code false} otherwise - */ public boolean isTrusted() { return trusted; } diff --git a/src/main/java/net/pterodactylus/sone/text/LinkPart.java b/src/main/java/net/pterodactylus/sone/text/LinkPart.java index 6764328..9f889ef 100644 --- a/src/main/java/net/pterodactylus/sone/text/LinkPart.java +++ b/src/main/java/net/pterodactylus/sone/text/LinkPart.java @@ -17,6 +17,10 @@ package net.pterodactylus.sone.text; +import java.util.Objects; + +import javax.annotation.Nonnull; + /** * {@link Part} implementation that can hold a link. A link contains of three * attributes: the link itself, the text that is shown instead of the link, and @@ -26,75 +30,32 @@ package net.pterodactylus.sone.text; */ public class LinkPart implements Part { - /** The link of this part. */ private final String link; - - /** The text of this part. */ private final String text; - - /** The title of this part. */ private final String title; - /** - * Creates a new link part. - * - * @param link - * The link of the link part - * @param text - * The text of the link part - */ - public LinkPart(String link, String text) { + public LinkPart(@Nonnull String link, @Nonnull String text) { this(link, text, text); } - /** - * Creates a new link part. - * - * @param link - * The link of the link part - * @param text - * The text of the link part - * @param title - * The title of the link part - */ - public LinkPart(String link, String text, String title) { - this.link = link; - this.text = text; - this.title = title; + public LinkPart(@Nonnull String link, @Nonnull String text, @Nonnull String title) { + this.link = Objects.requireNonNull(link); + this.text = Objects.requireNonNull(text); + this.title = Objects.requireNonNull(title); } - // - // ACCESSORS - // - - /** - * Returns the link of this part. - * - * @return The link of this part - */ + @Nonnull public String getLink() { return link; } - /** - * Returns the title of this part. - * - * @return The title of this part - */ + @Nonnull public String getTitle() { return title; } - // - // PART METHODS - // - - /** - * Returns the text of this part. - * - * @return The text of this part - */ @Override + @Nonnull public String getText() { return text; } diff --git a/src/main/java/net/pterodactylus/sone/text/PartContainer.java b/src/main/java/net/pterodactylus/sone/text/PartContainer.java index d1c89b3..3444d19 100644 --- a/src/main/java/net/pterodactylus/sone/text/PartContainer.java +++ b/src/main/java/net/pterodactylus/sone/text/PartContainer.java @@ -23,6 +23,9 @@ import java.util.Deque; import java.util.Iterator; import java.util.List; import java.util.NoSuchElementException; +import java.util.Objects; + +import javax.annotation.Nonnull; /** * Part implementation that can contain an arbitrary amount of other parts. @@ -33,61 +36,27 @@ import java.util.NoSuchElementException; */ public class PartContainer implements Part, Iterable { - /** The parts to render. */ private final List parts = new ArrayList(); - // - // ACCESSORS - // - - /** - * Adds a part to render. - * - * @param part - * The part to add - */ - public void add(Part part) { - parts.add(part); + public void add(@Nonnull Part part) { + parts.add(Objects.requireNonNull(part)); } - /** - * Returns the part at the given index. - * - * @param index - * The index of the part - * @return The part - */ + @Nonnull public Part getPart(int index) { return parts.get(index); } - /** - * Removes the part at the given index. - * - * @param index - * The index of the part to remove - */ public void removePart(int index) { parts.remove(index); } - /** - * Returns the number of parts. - * - * @return The number of parts - */ public int size() { return parts.size(); } - // - // PART METHODS - // - - /** - * {@inheritDoc} - */ @Override + @Nonnull public String getText() { StringBuilder partText = new StringBuilder(); for (Part part : parts) { @@ -96,14 +65,8 @@ public class PartContainer implements Part, Iterable { return partText.toString(); } - // - // ITERABLE METHODS - // - - /** - * {@inheritDoc} - */ @Override + @Nonnull @SuppressWarnings("synthetic-access") public Iterator iterator() { return new Iterator() { diff --git a/src/main/java/net/pterodactylus/sone/text/PlainTextPart.java b/src/main/java/net/pterodactylus/sone/text/PlainTextPart.java index 4f15a73..7bdbee9 100644 --- a/src/main/java/net/pterodactylus/sone/text/PlainTextPart.java +++ b/src/main/java/net/pterodactylus/sone/text/PlainTextPart.java @@ -17,6 +17,10 @@ package net.pterodactylus.sone.text; +import java.util.Objects; + +import javax.annotation.Nonnull; + /** * {@link Part} implementation that holds a single piece of text. * @@ -24,29 +28,14 @@ package net.pterodactylus.sone.text; */ public class PlainTextPart implements Part { - /** The text of the part. */ private final String text; - /** - * Creates a new plain-text part. - * - * @param text - * The text of the part - */ - public PlainTextPart(String text) { - this.text = text; + public PlainTextPart(@Nonnull String text) { + this.text = Objects.requireNonNull(text); } - // - // PART METHODS - // - - /** - * Returns the text of this part. - * - * @return The text of this part - */ @Override + @Nonnull public String getText() { return text; } diff --git a/src/main/java/net/pterodactylus/sone/text/PostPart.java b/src/main/java/net/pterodactylus/sone/text/PostPart.java index 68075a5..e70448f 100644 --- a/src/main/java/net/pterodactylus/sone/text/PostPart.java +++ b/src/main/java/net/pterodactylus/sone/text/PostPart.java @@ -17,6 +17,10 @@ package net.pterodactylus.sone.text; +import java.util.Objects; + +import javax.annotation.Nonnull; + import net.pterodactylus.sone.data.Post; /** @@ -26,39 +30,17 @@ import net.pterodactylus.sone.data.Post; */ public class PostPart implements Part { - /** The post this part refers to. */ private final Post post; - /** - * Creates a new post part. - * - * @param post - * The referenced post - */ - public PostPart(Post post) { - this.post = post; + public PostPart(@Nonnull Post post) { + this.post = Objects.requireNonNull(post); } - // - // ACCESSORS - // - - /** - * Returns the post referenced by this part. - * - * @return The post referenced by this part - */ + @Nonnull public Post getPost() { return post; } - // - // PART METHODS - // - - /** - * {@inheritDoc} - */ @Override public String getText() { return post.getText(); diff --git a/src/main/java/net/pterodactylus/sone/text/SonePart.java b/src/main/java/net/pterodactylus/sone/text/SonePart.java index cbafc61..576eb7b 100644 --- a/src/main/java/net/pterodactylus/sone/text/SonePart.java +++ b/src/main/java/net/pterodactylus/sone/text/SonePart.java @@ -17,6 +17,10 @@ package net.pterodactylus.sone.text; +import java.util.Objects; + +import javax.annotation.Nonnull; + import net.pterodactylus.sone.data.Sone; import net.pterodactylus.sone.template.SoneAccessor; @@ -27,39 +31,17 @@ import net.pterodactylus.sone.template.SoneAccessor; */ public class SonePart implements Part { - /** The referenced {@link Sone}. */ private final Sone sone; - /** - * Creates a new Sone part. - * - * @param sone - * The referenced Sone - */ - public SonePart(Sone sone) { - this.sone = sone; + public SonePart(@Nonnull Sone sone) { + this.sone = Objects.requireNonNull(sone); } - // - // ACCESSORS - // - - /** - * Returns the referenced Sone. - * - * @return The referenced Sone - */ + @Nonnull public Sone getSone() { return sone; } - // - // PART METHODS - // - - /** - * {@inheritDoc} - */ @Override public String getText() { return SoneAccessor.getNiceName(sone); diff --git a/src/main/java/net/pterodactylus/sone/text/SoneTextParser.java b/src/main/java/net/pterodactylus/sone/text/SoneTextParser.java index fb4e7cd..81ac751 100644 --- a/src/main/java/net/pterodactylus/sone/text/SoneTextParser.java +++ b/src/main/java/net/pterodactylus/sone/text/SoneTextParser.java @@ -21,6 +21,7 @@ import static java.util.logging.Logger.getLogger; import java.io.BufferedReader; import java.io.IOException; +import java.io.Reader; import java.io.StringReader; import java.net.MalformedURLException; import java.util.logging.Level; @@ -36,7 +37,6 @@ import net.pterodactylus.sone.data.Sone; import net.pterodactylus.sone.data.impl.IdOnlySone; import net.pterodactylus.sone.database.PostProvider; import net.pterodactylus.sone.database.SoneProvider; -import net.pterodactylus.util.io.Closer; import com.google.common.base.Optional; @@ -124,8 +124,8 @@ public class SoneTextParser implements Parser { @Override public Iterable parse(@Nonnull String source, @Nullable SoneTextParserContext context) { PartContainer parts = new PartContainer(); - BufferedReader bufferedReader = new BufferedReader(new StringReader(source)); - try { + try (Reader sourceReader = new StringReader(source); + BufferedReader bufferedReader = new BufferedReader(sourceReader)) { String line; boolean lastLineEmpty = true; int emptyLines = 0; @@ -175,10 +175,8 @@ public class SoneTextParser implements Parser { } lineComplete = false; - Matcher matcher = whitespacePattern.matcher(line); - int nextSpace = matcher.find(0) ? matcher.start() : line.length(); - String link = line.substring(0, nextSpace); - String name = link; + int endOfLink = findEndOfLink(line); + String link = line.substring(0, endOfLink); logger.log(Level.FINER, String.format("Found link: %s", link)); /* if there is no text after the scheme, it’s not a link! */ @@ -188,98 +186,32 @@ public class SoneTextParser implements Parser { continue; } - if (linkType == LinkType.SONE) { - if (line.length() >= (7 + 43)) { - String soneId = line.substring(7, 50); - Optional sone = soneProvider.getSone(soneId); - if (!sone.isPresent()) { - /* - * don’t use create=true above, we don’t want - * the empty shell. - */ - sone = Optional.of(new IdOnlySone(soneId)); - } - parts.add(new SonePart(sone.get())); - line = line.substring(50); - } else { - parts.add(new PlainTextPart(line)); - line = ""; - } - continue; - } - if (linkType == LinkType.POST) { - if (line.length() >= (7 + 36)) { - String postId = line.substring(7, 43); - Optional post = postProvider.getPost(postId); - if (post.isPresent()) { - parts.add(new PostPart(post.get())); - } else { - parts.add(new PlainTextPart(line.substring(0, 43))); - } - line = line.substring(43); - } else { - parts.add(new PlainTextPart(line)); - line = ""; - } - continue; + switch (linkType) { + case SONE: + renderSoneLink(parts, link); + break; + case POST: + renderPostLink(parts, link); + break; + case KSK: + case CHK: + case SSK: + case USK: + renderFreenetLink(parts, link, linkType, context); + break; + case HTTP: + case HTTPS: + renderHttpLink(parts, link, linkType); + break; } - if (linkType.isFreenetLink()) { - FreenetURI uri; - if (name.indexOf('?') > -1) { - name = name.substring(0, name.indexOf('?')); - } - if (name.endsWith("/")) { - name = name.substring(0, name.length() - 1); - } - try { - uri = new FreenetURI(name); - name = uri.lastMetaString(); - if (name == null) { - name = uri.getDocName(); - } - if (name == null) { - name = link.substring(0, Math.min(9, link.length())); - } - boolean fromPostingSone = ((linkType == LinkType.SSK) || (linkType == LinkType.USK)) && (context != null) && (context.getPostingSone() != null) && link.substring(4, Math.min(link.length(), 47)).equals(context.getPostingSone().getId()); - parts.add(new FreenetLinkPart(link, name, fromPostingSone)); - } catch (MalformedURLException mue1) { - /* not a valid link, insert as plain text. */ - parts.add(new PlainTextPart(link)); - } catch (NullPointerException npe1) { - /* FreenetURI sometimes throws these, too. */ - parts.add(new PlainTextPart(link)); - } catch (ArrayIndexOutOfBoundsException aioobe1) { - /* oh, and these, too. */ - parts.add(new PlainTextPart(link)); - } - } else if ((linkType == LinkType.HTTP) || (linkType == LinkType.HTTPS)) { - name = link.substring(linkType == LinkType.HTTP ? 7 : 8); - int firstSlash = name.indexOf('/'); - int lastSlash = name.lastIndexOf('/'); - if ((lastSlash - firstSlash) > 3) { - name = name.substring(0, firstSlash + 1) + "…" + name.substring(lastSlash); - } - if (name.endsWith("/")) { - name = name.substring(0, name.length() - 1); - } - if (((name.indexOf('/') > -1) && (name.indexOf('.') < name.lastIndexOf('.', name.indexOf('/'))) || ((name.indexOf('/') == -1) && (name.indexOf('.') < name.lastIndexOf('.')))) && name.startsWith("www.")) { - name = name.substring(4); - } - if (name.indexOf('?') > -1) { - name = name.substring(0, name.indexOf('?')); - } - parts.add(new LinkPart(link, name)); - } - line = line.substring(nextSpace); + line = line.substring(endOfLink); } lastLineEmpty = false; } } catch (IOException ioe1) { // a buffered reader around a string reader should never throw. throw new RuntimeException(ioe1); - } finally { - Closer.close(bufferedReader); } for (int partIndex = parts.size() - 1; partIndex >= 0; --partIndex) { Part part = parts.getPart(partIndex); @@ -291,6 +223,108 @@ public class SoneTextParser implements Parser { return parts; } + private void renderSoneLink(PartContainer parts, String line) { + if (line.length() >= (7 + 43)) { + String soneId = line.substring(7, 50); + Optional sone = soneProvider.getSone(soneId); + parts.add(new SonePart(sone.or(new IdOnlySone(soneId)))); + } else { + parts.add(new PlainTextPart(line)); + } + } + + private void renderPostLink(PartContainer parts, String line) { + if (line.length() >= (7 + 36)) { + String postId = line.substring(7, 43); + Optional post = postProvider.getPost(postId); + if (post.isPresent()) { + parts.add(new PostPart(post.get())); + } else { + parts.add(new PlainTextPart(line.substring(0, 43))); + } + } else { + parts.add(new PlainTextPart(line)); + } + } + + private void renderFreenetLink(PartContainer parts, String link, LinkType linkType, @Nullable SoneTextParserContext context) { + String name = link; + if (name.indexOf('?') > -1) { + name = name.substring(0, name.indexOf('?')); + } + if (name.endsWith("/")) { + name = name.substring(0, name.length() - 1); + } + try { + FreenetURI uri = new FreenetURI(name); + name = uri.lastMetaString(); + if (name == null) { + name = uri.getDocName(); + } + if (name == null) { + name = link.substring(0, Math.min(9, link.length())); + } + boolean fromPostingSone = ((linkType == LinkType.SSK) || (linkType == LinkType.USK)) && (context != null) && (context.getPostingSone() != null) && link.substring(4, Math.min(link.length(), 47)).equals(context.getPostingSone().getId()); + parts.add(new FreenetLinkPart(link, name, fromPostingSone)); + } catch (MalformedURLException mue1) { + /* not a valid link, insert as plain text. */ + parts.add(new PlainTextPart(link)); + } catch (NullPointerException npe1) { + /* FreenetURI sometimes throws these, too. */ + parts.add(new PlainTextPart(link)); + } catch (ArrayIndexOutOfBoundsException aioobe1) { + /* oh, and these, too. */ + parts.add(new PlainTextPart(link)); + } + } + + private void renderHttpLink(PartContainer parts, String link, LinkType linkType) { + String name; + name = link.substring(linkType == LinkType.HTTP ? 7 : 8); + int firstSlash = name.indexOf('/'); + int lastSlash = name.lastIndexOf('/'); + if ((lastSlash - firstSlash) > 3) { + name = name.substring(0, firstSlash + 1) + "…" + name.substring(lastSlash); + } + if (name.endsWith("/")) { + name = name.substring(0, name.length() - 1); + } + if (((name.indexOf('/') > -1) && (name.indexOf('.') < name.lastIndexOf('.', name.indexOf('/'))) || ((name.indexOf('/') == -1) && (name.indexOf('.') < name.lastIndexOf('.')))) && name.startsWith("www.")) { + name = name.substring(4); + } + if (name.indexOf('?') > -1) { + name = name.substring(0, name.indexOf('?')); + } + parts.add(new LinkPart(link, name)); + } + + private int findEndOfLink(String line) { + Matcher matcher = whitespacePattern.matcher(line); + int endOfLink = matcher.find() ? matcher.start() : line.length(); + while ((endOfLink > 0) && isPunctuation(line.charAt(endOfLink - 1))) { + endOfLink--; + } + int openParens = 0; + for (int i = 0; i < endOfLink; i++) { + switch (line.charAt(i)) { + case '(': + openParens++; + break; + case ')': + openParens--; + if (openParens < 0) { + return i; + } + default: + } + } + return endOfLink; + } + + private static boolean isPunctuation(char character) { + return (character == '.') || (character == ','); + } + private static class NextLink { private final int position; diff --git a/src/main/java/net/pterodactylus/sone/text/SoneTextParserContext.java b/src/main/java/net/pterodactylus/sone/text/SoneTextParserContext.java index 8918e40..fba81ab 100644 --- a/src/main/java/net/pterodactylus/sone/text/SoneTextParserContext.java +++ b/src/main/java/net/pterodactylus/sone/text/SoneTextParserContext.java @@ -29,35 +29,20 @@ import net.pterodactylus.sone.web.page.FreenetRequest; */ public class SoneTextParserContext implements ParserContext { - /** The request being processed. */ - private final FreenetRequest request; - /** The posting Sone. */ private final Sone postingSone; /** * Creates a new link parser context. * - * @param request - * The request being processed * @param postingSone * The posting Sone */ - public SoneTextParserContext(FreenetRequest request, Sone postingSone) { - this.request = request; + public SoneTextParserContext(Sone postingSone) { this.postingSone = postingSone; } /** - * Returns the request that is currently being processed. - * - * @return The request being processed - */ - public FreenetRequest getRequest() { - return request; - } - - /** * Returns the Sone that provided the text that is being parsed. * * @return The posting Sone diff --git a/src/main/java/net/pterodactylus/sone/web/AboutPage.java b/src/main/java/net/pterodactylus/sone/web/AboutPage.java index 76a475f..87d9816 100644 --- a/src/main/java/net/pterodactylus/sone/web/AboutPage.java +++ b/src/main/java/net/pterodactylus/sone/web/AboutPage.java @@ -29,11 +29,11 @@ import net.pterodactylus.util.version.Version; */ public class AboutPage extends SoneTemplatePage { - private final Version version; + private final String version; private final int year; private final String homepage; - public AboutPage(Template template, WebInterface webInterface, Version version, int year, String homepage) { + public AboutPage(Template template, WebInterface webInterface, String version, int year, String homepage) { super("about.html", template, "Page.About.Title", webInterface, false); this.version = version; this.year = year; @@ -41,8 +41,7 @@ public class AboutPage extends SoneTemplatePage { } @Override - protected void processTemplate(FreenetRequest request, TemplateContext templateContext) throws RedirectException { - super.processTemplate(request, templateContext); + protected void handleRequest(FreenetRequest request, TemplateContext templateContext) throws RedirectException { templateContext.set("version", version); templateContext.set("year", year); templateContext.set("homepage", homepage); diff --git a/src/main/java/net/pterodactylus/sone/web/BookmarkPage.java b/src/main/java/net/pterodactylus/sone/web/BookmarkPage.java index be5fc67..7602230 100644 --- a/src/main/java/net/pterodactylus/sone/web/BookmarkPage.java +++ b/src/main/java/net/pterodactylus/sone/web/BookmarkPage.java @@ -50,8 +50,7 @@ public class BookmarkPage extends SoneTemplatePage { * {@inheritDoc} */ @Override - protected void processTemplate(FreenetRequest request, TemplateContext templateContext) throws RedirectException { - super.processTemplate(request, templateContext); + protected void handleRequest(FreenetRequest request, TemplateContext templateContext) throws RedirectException { if (request.getMethod() == Method.POST) { String id = request.getHttpRequest().getPartAsStringFailsafe("post", 36); String returnPage = request.getHttpRequest().getPartAsStringFailsafe("returnPage", 256); diff --git a/src/main/java/net/pterodactylus/sone/web/BookmarksPage.java b/src/main/java/net/pterodactylus/sone/web/BookmarksPage.java index 404abb1..b273bdb 100644 --- a/src/main/java/net/pterodactylus/sone/web/BookmarksPage.java +++ b/src/main/java/net/pterodactylus/sone/web/BookmarksPage.java @@ -61,8 +61,7 @@ public class BookmarksPage extends SoneTemplatePage { * {@inheritDoc} */ @Override - protected void processTemplate(FreenetRequest request, TemplateContext templateContext) throws RedirectException { - super.processTemplate(request, templateContext); + protected void handleRequest(FreenetRequest request, TemplateContext templateContext) throws RedirectException { Set allPosts = webInterface.getCore().getBookmarkedPosts(); Collection loadedPosts = Collections2.filter(allPosts, new Predicate() { @@ -72,7 +71,7 @@ public class BookmarksPage extends SoneTemplatePage { } }); List sortedPosts = new ArrayList(loadedPosts); - Collections.sort(sortedPosts, Post.TIME_COMPARATOR); + Collections.sort(sortedPosts, Post.NEWEST_FIRST); Pagination pagination = new Pagination(sortedPosts, webInterface.getCore().getPreferences().getPostsPerPage()).setPage(parseInt(request.getHttpRequest().getParam("page"), 0)); templateContext.set("pagination", pagination); templateContext.set("posts", pagination.getItems()); diff --git a/src/main/java/net/pterodactylus/sone/web/CreateAlbumPage.java b/src/main/java/net/pterodactylus/sone/web/CreateAlbumPage.java index 6ba14f0..7423b67 100644 --- a/src/main/java/net/pterodactylus/sone/web/CreateAlbumPage.java +++ b/src/main/java/net/pterodactylus/sone/web/CreateAlbumPage.java @@ -53,8 +53,7 @@ public class CreateAlbumPage extends SoneTemplatePage { * {@inheritDoc} */ @Override - protected void processTemplate(FreenetRequest request, TemplateContext templateContext) throws RedirectException { - super.processTemplate(request, templateContext); + protected void handleRequest(FreenetRequest request, TemplateContext templateContext) throws RedirectException { if (request.getMethod() == Method.POST) { String name = request.getHttpRequest().getPartAsStringFailsafe("name", 64).trim(); if (name.length() == 0) { diff --git a/src/main/java/net/pterodactylus/sone/web/CreatePostPage.java b/src/main/java/net/pterodactylus/sone/web/CreatePostPage.java index f486379..ed478de 100644 --- a/src/main/java/net/pterodactylus/sone/web/CreatePostPage.java +++ b/src/main/java/net/pterodactylus/sone/web/CreatePostPage.java @@ -54,8 +54,7 @@ public class CreatePostPage extends SoneTemplatePage { * {@inheritDoc} */ @Override - protected void processTemplate(FreenetRequest request, TemplateContext templateContext) throws RedirectException { - super.processTemplate(request, templateContext); + protected void handleRequest(FreenetRequest request, TemplateContext templateContext) throws RedirectException { String returnPage = request.getHttpRequest().getPartAsStringFailsafe("returnPage", 256); if (request.getMethod() == Method.POST) { String text = request.getHttpRequest().getPartAsStringFailsafe("text", 65536).trim(); diff --git a/src/main/java/net/pterodactylus/sone/web/CreateReplyPage.java b/src/main/java/net/pterodactylus/sone/web/CreateReplyPage.java index 2383218..0bd5217 100644 --- a/src/main/java/net/pterodactylus/sone/web/CreateReplyPage.java +++ b/src/main/java/net/pterodactylus/sone/web/CreateReplyPage.java @@ -54,8 +54,7 @@ public class CreateReplyPage extends SoneTemplatePage { * {@inheritDoc} */ @Override - protected void processTemplate(FreenetRequest request, TemplateContext templateContext) throws RedirectException { - super.processTemplate(request, templateContext); + protected void handleRequest(FreenetRequest request, TemplateContext templateContext) throws RedirectException { String postId = request.getHttpRequest().getPartAsStringFailsafe("post", 36); String text = request.getHttpRequest().getPartAsStringFailsafe("text", 65536).trim(); String returnPage = request.getHttpRequest().getPartAsStringFailsafe("returnPage", 256); diff --git a/src/main/java/net/pterodactylus/sone/web/CreateSonePage.java b/src/main/java/net/pterodactylus/sone/web/CreateSonePage.java index 7ea74fe..a74204c 100644 --- a/src/main/java/net/pterodactylus/sone/web/CreateSonePage.java +++ b/src/main/java/net/pterodactylus/sone/web/CreateSonePage.java @@ -96,8 +96,7 @@ public class CreateSonePage extends SoneTemplatePage { * {@inheritDoc} */ @Override - protected void processTemplate(FreenetRequest request, TemplateContext templateContext) throws RedirectException { - super.processTemplate(request, templateContext); + protected void handleRequest(FreenetRequest request, TemplateContext templateContext) throws RedirectException { List localSones = new ArrayList(webInterface.getCore().getLocalSones()); Collections.sort(localSones, Sone.NICE_NAME_COMPARATOR); templateContext.set("sones", localSones); diff --git a/src/main/java/net/pterodactylus/sone/web/DeleteAlbumPage.java b/src/main/java/net/pterodactylus/sone/web/DeleteAlbumPage.java index 7d2fa59..581266d 100644 --- a/src/main/java/net/pterodactylus/sone/web/DeleteAlbumPage.java +++ b/src/main/java/net/pterodactylus/sone/web/DeleteAlbumPage.java @@ -46,8 +46,7 @@ public class DeleteAlbumPage extends SoneTemplatePage { * {@inheritDoc} */ @Override - protected void processTemplate(FreenetRequest request, TemplateContext templateContext) throws RedirectException { - super.processTemplate(request, templateContext); + protected void handleRequest(FreenetRequest request, TemplateContext templateContext) throws RedirectException { if (request.getMethod() == Method.POST) { String albumId = request.getHttpRequest().getPartAsStringFailsafe("album", 36); Album album = webInterface.getCore().getAlbum(albumId); diff --git a/src/main/java/net/pterodactylus/sone/web/DeleteImagePage.java b/src/main/java/net/pterodactylus/sone/web/DeleteImagePage.java index eeb9e3c..e1b2f37 100644 --- a/src/main/java/net/pterodactylus/sone/web/DeleteImagePage.java +++ b/src/main/java/net/pterodactylus/sone/web/DeleteImagePage.java @@ -50,8 +50,7 @@ public class DeleteImagePage extends SoneTemplatePage { * {@inheritDoc} */ @Override - protected void processTemplate(FreenetRequest request, TemplateContext templateContext) throws RedirectException { - super.processTemplate(request, templateContext); + protected void handleRequest(FreenetRequest request, TemplateContext templateContext) throws RedirectException { String imageId = (request.getMethod() == Method.POST) ? request.getHttpRequest().getPartAsStringFailsafe("image", 36) : request.getHttpRequest().getParam("image"); Image image = webInterface.getCore().getImage(imageId, false); if (image == null) { diff --git a/src/main/java/net/pterodactylus/sone/web/DeletePostPage.java b/src/main/java/net/pterodactylus/sone/web/DeletePostPage.java index 517a07e..c2bae56 100644 --- a/src/main/java/net/pterodactylus/sone/web/DeletePostPage.java +++ b/src/main/java/net/pterodactylus/sone/web/DeletePostPage.java @@ -52,8 +52,7 @@ public class DeletePostPage extends SoneTemplatePage { * {@inheritDoc} */ @Override - protected void processTemplate(FreenetRequest request, TemplateContext templateContext) throws RedirectException { - super.processTemplate(request, templateContext); + protected void handleRequest(FreenetRequest request, TemplateContext templateContext) throws RedirectException { if (request.getMethod() == Method.GET) { String postId = request.getHttpRequest().getParam("post"); String returnPage = request.getHttpRequest().getParam("returnPage"); diff --git a/src/main/java/net/pterodactylus/sone/web/DeleteProfileFieldPage.java b/src/main/java/net/pterodactylus/sone/web/DeleteProfileFieldPage.java index f036489..a137b82 100644 --- a/src/main/java/net/pterodactylus/sone/web/DeleteProfileFieldPage.java +++ b/src/main/java/net/pterodactylus/sone/web/DeleteProfileFieldPage.java @@ -52,8 +52,7 @@ public class DeleteProfileFieldPage extends SoneTemplatePage { * {@inheritDoc} */ @Override - protected void processTemplate(FreenetRequest request, TemplateContext templateContext) throws RedirectException { - super.processTemplate(request, templateContext); + protected void handleRequest(FreenetRequest request, TemplateContext templateContext) throws RedirectException { Sone currentSone = getCurrentSone(request.getToadletContext()); Profile profile = currentSone.getProfile(); diff --git a/src/main/java/net/pterodactylus/sone/web/DeleteReplyPage.java b/src/main/java/net/pterodactylus/sone/web/DeleteReplyPage.java index 0cd6b4f..7112b73 100644 --- a/src/main/java/net/pterodactylus/sone/web/DeleteReplyPage.java +++ b/src/main/java/net/pterodactylus/sone/web/DeleteReplyPage.java @@ -52,8 +52,7 @@ public class DeleteReplyPage extends SoneTemplatePage { * {@inheritDoc} */ @Override - protected void processTemplate(FreenetRequest request, TemplateContext templateContext) throws RedirectException { - super.processTemplate(request, templateContext); + protected void handleRequest(FreenetRequest request, TemplateContext templateContext) throws RedirectException { String replyId = request.getHttpRequest().getPartAsStringFailsafe("reply", 36); Optional reply = webInterface.getCore().getPostReply(replyId); String returnPage = request.getHttpRequest().getPartAsStringFailsafe("returnPage", 256); diff --git a/src/main/java/net/pterodactylus/sone/web/DeleteSonePage.java b/src/main/java/net/pterodactylus/sone/web/DeleteSonePage.java index ce01771..1390918 100644 --- a/src/main/java/net/pterodactylus/sone/web/DeleteSonePage.java +++ b/src/main/java/net/pterodactylus/sone/web/DeleteSonePage.java @@ -52,8 +52,7 @@ public class DeleteSonePage extends SoneTemplatePage { * {@inheritDoc} */ @Override - protected void processTemplate(FreenetRequest request, TemplateContext templateContext) throws RedirectException { - super.processTemplate(request, templateContext); + protected void handleRequest(FreenetRequest request, TemplateContext templateContext) throws RedirectException { if (request.getMethod() == Method.POST) { if (request.getHttpRequest().isPartSet("deleteSone")) { Sone currentSone = getCurrentSone(request.getToadletContext()); diff --git a/src/main/java/net/pterodactylus/sone/web/DismissNotificationPage.java b/src/main/java/net/pterodactylus/sone/web/DismissNotificationPage.java index 80da869..c14a012 100644 --- a/src/main/java/net/pterodactylus/sone/web/DismissNotificationPage.java +++ b/src/main/java/net/pterodactylus/sone/web/DismissNotificationPage.java @@ -51,8 +51,7 @@ public class DismissNotificationPage extends SoneTemplatePage { * {@inheritDoc} */ @Override - protected void processTemplate(FreenetRequest request, TemplateContext templateContext) throws RedirectException { - super.processTemplate(request, templateContext); + protected void handleRequest(FreenetRequest request, TemplateContext templateContext) throws RedirectException { String notificationId = request.getHttpRequest().getPartAsStringFailsafe("notification", 36); Optional notification = webInterface.getNotification(notificationId); if (notification.isPresent() && notification.get().isDismissable()) { diff --git a/src/main/java/net/pterodactylus/sone/web/DistrustPage.java b/src/main/java/net/pterodactylus/sone/web/DistrustPage.java index c09608a..50e3efb 100644 --- a/src/main/java/net/pterodactylus/sone/web/DistrustPage.java +++ b/src/main/java/net/pterodactylus/sone/web/DistrustPage.java @@ -55,8 +55,7 @@ public class DistrustPage extends SoneTemplatePage { * {@inheritDoc} */ @Override - protected void processTemplate(FreenetRequest request, TemplateContext templateContext) throws RedirectException { - super.processTemplate(request, templateContext); + protected void handleRequest(FreenetRequest request, TemplateContext templateContext) throws RedirectException { if (request.getMethod() == Method.POST) { String returnPage = request.getHttpRequest().getPartAsStringFailsafe("returnPage", 256); String identity = request.getHttpRequest().getPartAsStringFailsafe("sone", 44); diff --git a/src/main/java/net/pterodactylus/sone/web/EditAlbumPage.java b/src/main/java/net/pterodactylus/sone/web/EditAlbumPage.java index 6a08c3c..5829c8b 100644 --- a/src/main/java/net/pterodactylus/sone/web/EditAlbumPage.java +++ b/src/main/java/net/pterodactylus/sone/web/EditAlbumPage.java @@ -48,8 +48,7 @@ public class EditAlbumPage extends SoneTemplatePage { * {@inheritDoc} */ @Override - protected void processTemplate(FreenetRequest request, TemplateContext templateContext) throws RedirectException { - super.processTemplate(request, templateContext); + protected void handleRequest(FreenetRequest request, TemplateContext templateContext) throws RedirectException { if (request.getMethod() == Method.POST) { String albumId = request.getHttpRequest().getPartAsStringFailsafe("album", 36); Album album = webInterface.getCore().getAlbum(albumId); diff --git a/src/main/java/net/pterodactylus/sone/web/EditImagePage.java b/src/main/java/net/pterodactylus/sone/web/EditImagePage.java index b169161..419bc1d 100644 --- a/src/main/java/net/pterodactylus/sone/web/EditImagePage.java +++ b/src/main/java/net/pterodactylus/sone/web/EditImagePage.java @@ -51,8 +51,7 @@ public class EditImagePage extends SoneTemplatePage { * {@inheritDoc} */ @Override - protected void processTemplate(FreenetRequest request, TemplateContext templateContext) throws RedirectException { - super.processTemplate(request, templateContext); + protected void handleRequest(FreenetRequest request, TemplateContext templateContext) throws RedirectException { if (request.getMethod() == Method.POST) { String imageId = request.getHttpRequest().getPartAsStringFailsafe("image", 36); String returnPage = request.getHttpRequest().getPartAsStringFailsafe("returnPage", 256); diff --git a/src/main/java/net/pterodactylus/sone/web/EditProfileFieldPage.java b/src/main/java/net/pterodactylus/sone/web/EditProfileFieldPage.java index 8cf18f2..e5bee78 100644 --- a/src/main/java/net/pterodactylus/sone/web/EditProfileFieldPage.java +++ b/src/main/java/net/pterodactylus/sone/web/EditProfileFieldPage.java @@ -52,8 +52,7 @@ public class EditProfileFieldPage extends SoneTemplatePage { * {@inheritDoc} */ @Override - protected void processTemplate(FreenetRequest request, TemplateContext templateContext) throws RedirectException { - super.processTemplate(request, templateContext); + protected void handleRequest(FreenetRequest request, TemplateContext templateContext) throws RedirectException { Sone currentSone = getCurrentSone(request.getToadletContext()); Profile profile = currentSone.getProfile(); diff --git a/src/main/java/net/pterodactylus/sone/web/EditProfilePage.java b/src/main/java/net/pterodactylus/sone/web/EditProfilePage.java index bf76c26..cffdeb9 100644 --- a/src/main/java/net/pterodactylus/sone/web/EditProfilePage.java +++ b/src/main/java/net/pterodactylus/sone/web/EditProfilePage.java @@ -59,8 +59,7 @@ public class EditProfilePage extends SoneTemplatePage { * {@inheritDoc} */ @Override - protected void processTemplate(FreenetRequest request, TemplateContext templateContext) throws RedirectException { - super.processTemplate(request, templateContext); + protected void handleRequest(FreenetRequest request, TemplateContext templateContext) throws RedirectException { ToadletContext toadletContenxt = request.getToadletContext(); Sone currentSone = getCurrentSone(toadletContenxt); Profile profile = currentSone.getProfile(); diff --git a/src/main/java/net/pterodactylus/sone/web/FollowSonePage.java b/src/main/java/net/pterodactylus/sone/web/FollowSonePage.java index eef94df..0652a52 100644 --- a/src/main/java/net/pterodactylus/sone/web/FollowSonePage.java +++ b/src/main/java/net/pterodactylus/sone/web/FollowSonePage.java @@ -50,8 +50,7 @@ public class FollowSonePage extends SoneTemplatePage { * {@inheritDoc} */ @Override - protected void processTemplate(FreenetRequest request, TemplateContext templateContext) throws RedirectException { - super.processTemplate(request, templateContext); + protected void handleRequest(FreenetRequest request, TemplateContext templateContext) throws RedirectException { if (request.getMethod() == Method.POST) { String returnPage = request.getHttpRequest().getPartAsStringFailsafe("returnPage", 256); Sone currentSone = getCurrentSone(request.getToadletContext()); diff --git a/src/main/java/net/pterodactylus/sone/web/ImageBrowserPage.java b/src/main/java/net/pterodactylus/sone/web/ImageBrowserPage.java index 5da6e53..acc6354 100644 --- a/src/main/java/net/pterodactylus/sone/web/ImageBrowserPage.java +++ b/src/main/java/net/pterodactylus/sone/web/ImageBrowserPage.java @@ -65,8 +65,7 @@ public class ImageBrowserPage extends SoneTemplatePage { * {@inheritDoc} */ @Override - protected void processTemplate(FreenetRequest request, TemplateContext templateContext) throws RedirectException { - super.processTemplate(request, templateContext); + protected void handleRequest(FreenetRequest request, TemplateContext templateContext) throws RedirectException { String albumId = request.getHttpRequest().getParam("album", null); if (albumId != null) { Album album = webInterface.getCore().getAlbum(albumId); diff --git a/src/main/java/net/pterodactylus/sone/web/IndexPage.java b/src/main/java/net/pterodactylus/sone/web/IndexPage.java index e5d5b7d..1d40f45 100644 --- a/src/main/java/net/pterodactylus/sone/web/IndexPage.java +++ b/src/main/java/net/pterodactylus/sone/web/IndexPage.java @@ -58,8 +58,7 @@ public class IndexPage extends SoneTemplatePage { * {@inheritDoc} */ @Override - protected void processTemplate(FreenetRequest request, TemplateContext templateContext) throws RedirectException { - super.processTemplate(request, templateContext); + protected void handleRequest(FreenetRequest request, TemplateContext templateContext) throws RedirectException { final Sone currentSone = getCurrentSone(request.getToadletContext()); Collection allPosts = new ArrayList(); allPosts.addAll(currentSone.getPosts()); @@ -79,7 +78,7 @@ public class IndexPage extends SoneTemplatePage { } allPosts = Collections2.filter(allPosts, postVisibilityFilter.isVisible(currentSone)); List sortedPosts = new ArrayList(allPosts); - Collections.sort(sortedPosts, Post.TIME_COMPARATOR); + Collections.sort(sortedPosts, Post.NEWEST_FIRST); Pagination pagination = new Pagination(sortedPosts, webInterface.getCore().getPreferences().getPostsPerPage()).setPage(parseInt(request.getHttpRequest().getParam("page"), 0)); templateContext.set("pagination", pagination); templateContext.set("posts", pagination.getItems()); diff --git a/src/main/java/net/pterodactylus/sone/web/KnownSonesPage.java b/src/main/java/net/pterodactylus/sone/web/KnownSonesPage.java index d5fb9e2..da93a02 100644 --- a/src/main/java/net/pterodactylus/sone/web/KnownSonesPage.java +++ b/src/main/java/net/pterodactylus/sone/web/KnownSonesPage.java @@ -65,8 +65,7 @@ public class KnownSonesPage extends SoneTemplatePage { * {@inheritDoc} */ @Override - protected void processTemplate(FreenetRequest request, TemplateContext templateContext) throws RedirectException { - super.processTemplate(request, templateContext); + protected void handleRequest(FreenetRequest request, TemplateContext templateContext) throws RedirectException { String sortField = request.getHttpRequest().getParam("sort", defaultSortField); String sortOrder = request.getHttpRequest().getParam("order", defaultSortOrder); String filter = request.getHttpRequest().getParam("filter"); diff --git a/src/main/java/net/pterodactylus/sone/web/LikePage.java b/src/main/java/net/pterodactylus/sone/web/LikePage.java index 171a7be..fc39eff 100644 --- a/src/main/java/net/pterodactylus/sone/web/LikePage.java +++ b/src/main/java/net/pterodactylus/sone/web/LikePage.java @@ -51,8 +51,7 @@ public class LikePage extends SoneTemplatePage { * {@inheritDoc} */ @Override - protected void processTemplate(FreenetRequest request, TemplateContext templateContext) throws RedirectException { - super.processTemplate(request, templateContext); + protected void handleRequest(FreenetRequest request, TemplateContext templateContext) throws RedirectException { if (request.getMethod() == Method.POST) { String type = request.getHttpRequest().getPartAsStringFailsafe("type", 16); String id = request.getHttpRequest().getPartAsStringFailsafe(type, 36); diff --git a/src/main/java/net/pterodactylus/sone/web/LockSonePage.java b/src/main/java/net/pterodactylus/sone/web/LockSonePage.java index 7881e9e..a0a9574 100644 --- a/src/main/java/net/pterodactylus/sone/web/LockSonePage.java +++ b/src/main/java/net/pterodactylus/sone/web/LockSonePage.java @@ -50,8 +50,7 @@ public class LockSonePage extends SoneTemplatePage { * {@inheritDoc} */ @Override - protected void processTemplate(FreenetRequest request, TemplateContext templateContext) throws RedirectException { - super.processTemplate(request, templateContext); + protected void handleRequest(FreenetRequest request, TemplateContext templateContext) throws RedirectException { String soneId = request.getHttpRequest().getPartAsStringFailsafe("sone", 44); Sone sone = webInterface.getCore().getLocalSone(soneId); if (sone != null) { diff --git a/src/main/java/net/pterodactylus/sone/web/LoginPage.java b/src/main/java/net/pterodactylus/sone/web/LoginPage.java index 608f120..f9bd371 100644 --- a/src/main/java/net/pterodactylus/sone/web/LoginPage.java +++ b/src/main/java/net/pterodactylus/sone/web/LoginPage.java @@ -63,8 +63,7 @@ public class LoginPage extends SoneTemplatePage { * {@inheritDoc} */ @Override - protected void processTemplate(FreenetRequest request, TemplateContext templateContext) throws RedirectException { - super.processTemplate(request, templateContext); + protected void handleRequest(FreenetRequest request, TemplateContext templateContext) throws RedirectException { /* get all own identities. */ List localSones = new ArrayList(webInterface.getCore().getLocalSones()); Collections.sort(localSones, Sone.NICE_NAME_COMPARATOR); diff --git a/src/main/java/net/pterodactylus/sone/web/LogoutPage.java b/src/main/java/net/pterodactylus/sone/web/LogoutPage.java index d47044c..f7a254c 100644 --- a/src/main/java/net/pterodactylus/sone/web/LogoutPage.java +++ b/src/main/java/net/pterodactylus/sone/web/LogoutPage.java @@ -47,9 +47,8 @@ public class LogoutPage extends SoneTemplatePage { * {@inheritDoc} */ @Override - protected void processTemplate(FreenetRequest request, TemplateContext templateContext) throws RedirectException { + protected void handleRequest(FreenetRequest request, TemplateContext templateContext) throws RedirectException { setCurrentSone(request.getToadletContext(), null); - super.processTemplate(request, templateContext); throw new RedirectException("index.html"); } diff --git a/src/main/java/net/pterodactylus/sone/web/MarkAsKnownPage.java b/src/main/java/net/pterodactylus/sone/web/MarkAsKnownPage.java index 39c5a43..dc1841b 100644 --- a/src/main/java/net/pterodactylus/sone/web/MarkAsKnownPage.java +++ b/src/main/java/net/pterodactylus/sone/web/MarkAsKnownPage.java @@ -57,8 +57,7 @@ public class MarkAsKnownPage extends SoneTemplatePage { * {@inheritDoc} */ @Override - protected void processTemplate(FreenetRequest request, TemplateContext templateContext) throws RedirectException { - super.processTemplate(request, templateContext); + protected void handleRequest(FreenetRequest request, TemplateContext templateContext) throws RedirectException { String type = request.getHttpRequest().getPartAsStringFailsafe("type", 5); if (!type.equals("sone") && !type.equals("post") && !type.equals("reply")) { throw new RedirectException("invalid.html"); diff --git a/src/main/java/net/pterodactylus/sone/web/NewPage.java b/src/main/java/net/pterodactylus/sone/web/NewPage.java index 2b99adb..406054d 100644 --- a/src/main/java/net/pterodactylus/sone/web/NewPage.java +++ b/src/main/java/net/pterodactylus/sone/web/NewPage.java @@ -62,9 +62,7 @@ public class NewPage extends SoneTemplatePage { * {@inheritDoc} */ @Override - protected void processTemplate(FreenetRequest request, TemplateContext templateContext) throws RedirectException { - super.processTemplate(request, templateContext); - + protected void handleRequest(FreenetRequest request, TemplateContext templateContext) throws RedirectException { /* collect new elements from notifications. */ Set posts = new HashSet(webInterface.getNewPosts(getCurrentSone(request.getToadletContext(), false))); for (PostReply reply : webInterface.getNewReplies(getCurrentSone(request.getToadletContext(), false))) { @@ -73,7 +71,7 @@ public class NewPage extends SoneTemplatePage { /* filter and sort them. */ List sortedPosts = new ArrayList(posts); - Collections.sort(sortedPosts, Post.TIME_COMPARATOR); + Collections.sort(sortedPosts, Post.NEWEST_FIRST); /* paginate them. */ Pagination pagination = new Pagination(sortedPosts, webInterface.getCore().getPreferences().getPostsPerPage()).setPage(parseInt(request.getHttpRequest().getParam("page"), 0)); diff --git a/src/main/java/net/pterodactylus/sone/web/OptionsPage.java b/src/main/java/net/pterodactylus/sone/web/OptionsPage.java index 0bc44d5..2bd1bfd 100644 --- a/src/main/java/net/pterodactylus/sone/web/OptionsPage.java +++ b/src/main/java/net/pterodactylus/sone/web/OptionsPage.java @@ -58,8 +58,7 @@ public class OptionsPage extends SoneTemplatePage { * {@inheritDoc} */ @Override - protected void processTemplate(FreenetRequest request, TemplateContext templateContext) throws RedirectException { - super.processTemplate(request, templateContext); + protected void handleRequest(FreenetRequest request, TemplateContext templateContext) throws RedirectException { Preferences preferences = webInterface.getCore().getPreferences(); Sone currentSone = webInterface.getCurrentSone(request.getToadletContext(), false); if (request.getMethod() == Method.POST) { diff --git a/src/main/java/net/pterodactylus/sone/web/RescuePage.java b/src/main/java/net/pterodactylus/sone/web/RescuePage.java index 2383e0d..78a2b9e 100644 --- a/src/main/java/net/pterodactylus/sone/web/RescuePage.java +++ b/src/main/java/net/pterodactylus/sone/web/RescuePage.java @@ -54,8 +54,7 @@ public class RescuePage extends SoneTemplatePage { * {@inheritDoc} */ @Override - protected void processTemplate(FreenetRequest request, TemplateContext templateContext) throws RedirectException { - super.processTemplate(request, templateContext); + protected void handleRequest(FreenetRequest request, TemplateContext templateContext) throws RedirectException { Sone currentSone = getCurrentSone(request.getToadletContext(), false); SoneRescuer soneRescuer = webInterface.getCore().getSoneRescuer(currentSone); if (request.getMethod() == Method.POST) { diff --git a/src/main/java/net/pterodactylus/sone/web/SearchPage.java b/src/main/java/net/pterodactylus/sone/web/SearchPage.java index 5b657d5..8b444a7 100644 --- a/src/main/java/net/pterodactylus/sone/web/SearchPage.java +++ b/src/main/java/net/pterodactylus/sone/web/SearchPage.java @@ -101,8 +101,7 @@ public class SearchPage extends SoneTemplatePage { */ @Override @SuppressWarnings("synthetic-access") - protected void processTemplate(FreenetRequest request, TemplateContext templateContext) throws RedirectException { - super.processTemplate(request, templateContext); + protected void handleRequest(FreenetRequest request, TemplateContext templateContext) throws RedirectException { String query = request.getHttpRequest().getParam("query").trim(); if (query.length() == 0) { throw new RedirectException("index.html"); @@ -593,7 +592,7 @@ public class SearchPage extends SoneTemplatePage { @Override public int compare(Hit leftHit, Hit rightHit) { - return (rightHit.getScore() < leftHit.getScore()) ? -1 : ((rightHit.getScore() > leftHit.getScore()) ? 1 : 0); + return Double.compare(rightHit.getScore(), leftHit.getScore()); } }; diff --git a/src/main/java/net/pterodactylus/sone/web/SoneTemplatePage.java b/src/main/java/net/pterodactylus/sone/web/SoneTemplatePage.java index b3e7a6a..bf9614d 100644 --- a/src/main/java/net/pterodactylus/sone/web/SoneTemplatePage.java +++ b/src/main/java/net/pterodactylus/sone/web/SoneTemplatePage.java @@ -236,14 +236,14 @@ public class SoneTemplatePage extends FreenetTemplatePage { * {@inheritDoc} */ @Override - protected void processTemplate(FreenetRequest request, TemplateContext templateContext) throws RedirectException { + protected final void processTemplate(FreenetRequest request, TemplateContext templateContext) throws RedirectException { super.processTemplate(request, templateContext); Sone currentSone = getCurrentSone(request.getToadletContext(), false); templateContext.set("core", webInterface.getCore()); templateContext.set("currentSone", currentSone); templateContext.set("localSones", webInterface.getCore().getLocalSones()); templateContext.set("request", request); - templateContext.set("currentVersion", SonePlugin.VERSION); + templateContext.set("currentVersion", SonePlugin.getPluginVersion()); templateContext.set("hasLatestVersion", webInterface.getCore().getUpdateChecker().hasLatestVersion()); templateContext.set("latestEdition", webInterface.getCore().getUpdateChecker().getLatestEdition()); templateContext.set("latestVersion", webInterface.getCore().getUpdateChecker().getLatestVersion()); @@ -252,6 +252,10 @@ public class SoneTemplatePage extends FreenetTemplatePage { Collections.sort(notifications, Notification.CREATED_TIME_SORTER); templateContext.set("notifications", notifications); templateContext.set("notificationHash", notifications.hashCode()); + handleRequest(request, templateContext); + } + + protected void handleRequest(FreenetRequest request, TemplateContext templateContext) throws RedirectException { } /** diff --git a/src/main/java/net/pterodactylus/sone/web/TrustPage.java b/src/main/java/net/pterodactylus/sone/web/TrustPage.java index 637bb26..5b0bfbb 100644 --- a/src/main/java/net/pterodactylus/sone/web/TrustPage.java +++ b/src/main/java/net/pterodactylus/sone/web/TrustPage.java @@ -55,8 +55,7 @@ public class TrustPage extends SoneTemplatePage { * {@inheritDoc} */ @Override - protected void processTemplate(FreenetRequest request, TemplateContext templateContext) throws RedirectException { - super.processTemplate(request, templateContext); + protected void handleRequest(FreenetRequest request, TemplateContext templateContext) throws RedirectException { if (request.getMethod() == Method.POST) { String returnPage = request.getHttpRequest().getPartAsStringFailsafe("returnPage", 256); String identity = request.getHttpRequest().getPartAsStringFailsafe("sone", 44); diff --git a/src/main/java/net/pterodactylus/sone/web/UnbookmarkPage.java b/src/main/java/net/pterodactylus/sone/web/UnbookmarkPage.java index 51da550..8edf2da 100644 --- a/src/main/java/net/pterodactylus/sone/web/UnbookmarkPage.java +++ b/src/main/java/net/pterodactylus/sone/web/UnbookmarkPage.java @@ -52,8 +52,7 @@ public class UnbookmarkPage extends SoneTemplatePage { * {@inheritDoc} */ @Override - protected void processTemplate(FreenetRequest request, TemplateContext templateContext) throws RedirectException { - super.processTemplate(request, templateContext); + protected void handleRequest(FreenetRequest request, TemplateContext templateContext) throws RedirectException { if (request.getMethod() == Method.POST) { String id = request.getHttpRequest().getPartAsStringFailsafe("post", 36); String returnPage = request.getHttpRequest().getPartAsStringFailsafe("returnPage", 256); diff --git a/src/main/java/net/pterodactylus/sone/web/UnfollowSonePage.java b/src/main/java/net/pterodactylus/sone/web/UnfollowSonePage.java index d8ff899..bff4013 100644 --- a/src/main/java/net/pterodactylus/sone/web/UnfollowSonePage.java +++ b/src/main/java/net/pterodactylus/sone/web/UnfollowSonePage.java @@ -48,8 +48,7 @@ public class UnfollowSonePage extends SoneTemplatePage { * {@inheritDoc} */ @Override - protected void processTemplate(FreenetRequest request, TemplateContext templateContext) throws RedirectException { - super.processTemplate(request, templateContext); + protected void handleRequest(FreenetRequest request, TemplateContext templateContext) throws RedirectException { if (request.getMethod() == Method.POST) { String returnPage = request.getHttpRequest().getPartAsStringFailsafe("returnPage", 256); Sone currentSone = getCurrentSone(request.getToadletContext()); diff --git a/src/main/java/net/pterodactylus/sone/web/UnlikePage.java b/src/main/java/net/pterodactylus/sone/web/UnlikePage.java index ade8b89..a17502d 100644 --- a/src/main/java/net/pterodactylus/sone/web/UnlikePage.java +++ b/src/main/java/net/pterodactylus/sone/web/UnlikePage.java @@ -51,8 +51,7 @@ public class UnlikePage extends SoneTemplatePage { * {@inheritDoc} */ @Override - protected void processTemplate(FreenetRequest request, TemplateContext templateContext) throws RedirectException { - super.processTemplate(request, templateContext); + protected void handleRequest(FreenetRequest request, TemplateContext templateContext) throws RedirectException { if (request.getMethod() == Method.POST) { String type = request.getHttpRequest().getPartAsStringFailsafe("type", 16); String id = request.getHttpRequest().getPartAsStringFailsafe(type, 36); diff --git a/src/main/java/net/pterodactylus/sone/web/UnlockSonePage.java b/src/main/java/net/pterodactylus/sone/web/UnlockSonePage.java index f641361..7c36a88 100644 --- a/src/main/java/net/pterodactylus/sone/web/UnlockSonePage.java +++ b/src/main/java/net/pterodactylus/sone/web/UnlockSonePage.java @@ -49,8 +49,7 @@ public class UnlockSonePage extends SoneTemplatePage { * {@inheritDoc} */ @Override - protected void processTemplate(FreenetRequest request, TemplateContext templateContext) throws RedirectException { - super.processTemplate(request, templateContext); + protected void handleRequest(FreenetRequest request, TemplateContext templateContext) throws RedirectException { String soneId = request.getHttpRequest().getPartAsStringFailsafe("sone", 44); Sone sone = webInterface.getCore().getLocalSone(soneId); if (sone != null) { diff --git a/src/main/java/net/pterodactylus/sone/web/UntrustPage.java b/src/main/java/net/pterodactylus/sone/web/UntrustPage.java index 9d51276..cba3635 100644 --- a/src/main/java/net/pterodactylus/sone/web/UntrustPage.java +++ b/src/main/java/net/pterodactylus/sone/web/UntrustPage.java @@ -55,8 +55,7 @@ public class UntrustPage extends SoneTemplatePage { * {@inheritDoc} */ @Override - protected void processTemplate(FreenetRequest request, TemplateContext templateContext) throws RedirectException { - super.processTemplate(request, templateContext); + protected void handleRequest(FreenetRequest request, TemplateContext templateContext) throws RedirectException { if (request.getMethod() == Method.POST) { String returnPage = request.getHttpRequest().getPartAsStringFailsafe("returnPage", 256); String identity = request.getHttpRequest().getPartAsStringFailsafe("sone", 44); diff --git a/src/main/java/net/pterodactylus/sone/web/UploadImagePage.java b/src/main/java/net/pterodactylus/sone/web/UploadImagePage.java index 21c4272..467ceda 100644 --- a/src/main/java/net/pterodactylus/sone/web/UploadImagePage.java +++ b/src/main/java/net/pterodactylus/sone/web/UploadImagePage.java @@ -79,8 +79,7 @@ public class UploadImagePage extends SoneTemplatePage { * {@inheritDoc} */ @Override - protected void processTemplate(FreenetRequest request, TemplateContext templateContext) throws RedirectException { - super.processTemplate(request, templateContext); + protected void handleRequest(FreenetRequest request, TemplateContext templateContext) throws RedirectException { if (request.getMethod() == Method.POST) { Sone currentSone = getCurrentSone(request.getToadletContext()); String parentId = request.getHttpRequest().getPartAsStringFailsafe("parent", 36); diff --git a/src/main/java/net/pterodactylus/sone/web/ViewPostPage.java b/src/main/java/net/pterodactylus/sone/web/ViewPostPage.java index dca59e2..56bac8d 100644 --- a/src/main/java/net/pterodactylus/sone/web/ViewPostPage.java +++ b/src/main/java/net/pterodactylus/sone/web/ViewPostPage.java @@ -70,8 +70,7 @@ public class ViewPostPage extends SoneTemplatePage { * {@inheritDoc} */ @Override - protected void processTemplate(FreenetRequest request, TemplateContext templateContext) throws RedirectException { - super.processTemplate(request, templateContext); + protected void handleRequest(FreenetRequest request, TemplateContext templateContext) throws RedirectException { String postId = request.getHttpRequest().getParam("post"); boolean raw = request.getHttpRequest().getParam("raw").equals("true"); Optional post = webInterface.getCore().getPost(postId); diff --git a/src/main/java/net/pterodactylus/sone/web/ViewSonePage.java b/src/main/java/net/pterodactylus/sone/web/ViewSonePage.java index fe1e7db..f2c9c91 100644 --- a/src/main/java/net/pterodactylus/sone/web/ViewSonePage.java +++ b/src/main/java/net/pterodactylus/sone/web/ViewSonePage.java @@ -80,8 +80,7 @@ public class ViewSonePage extends SoneTemplatePage { * {@inheritDoc} */ @Override - protected void processTemplate(FreenetRequest request, TemplateContext templateContext) throws RedirectException { - super.processTemplate(request, templateContext); + protected void handleRequest(FreenetRequest request, TemplateContext templateContext) throws RedirectException { String soneId = request.getHttpRequest().getParam("sone"); Optional sone = webInterface.getCore().getSone(soneId); templateContext.set("sone", sone.orNull()); @@ -91,7 +90,7 @@ public class ViewSonePage extends SoneTemplatePage { } List sonePosts = sone.get().getPosts(); sonePosts.addAll(webInterface.getCore().getDirectedPosts(sone.get().getId())); - Collections.sort(sonePosts, Post.TIME_COMPARATOR); + Collections.sort(sonePosts, Post.NEWEST_FIRST); Pagination postPagination = new Pagination(sonePosts, webInterface.getCore().getPreferences().getPostsPerPage()).setPage(parseInt(request.getHttpRequest().getParam("postPage"), 0)); templateContext.set("postPagination", postPagination); templateContext.set("posts", postPagination.getItems()); diff --git a/src/main/java/net/pterodactylus/sone/web/WebInterface.java b/src/main/java/net/pterodactylus/sone/web/WebInterface.java index 271111e..b7e3287 100644 --- a/src/main/java/net/pterodactylus/sone/web/WebInterface.java +++ b/src/main/java/net/pterodactylus/sone/web/WebInterface.java @@ -717,7 +717,7 @@ public class WebInterface { pageToadlets.add(pageToadletFactory.createPageToadlet(new LogoutPage(emptyTemplate, this), "Logout")); pageToadlets.add(pageToadletFactory.createPageToadlet(new OptionsPage(optionsTemplate, this), "Options")); pageToadlets.add(pageToadletFactory.createPageToadlet(new RescuePage(rescueTemplate, this), "Rescue")); - pageToadlets.add(pageToadletFactory.createPageToadlet(new AboutPage(aboutTemplate, this, SonePlugin.VERSION, SonePlugin.getYear(), SonePlugin.getHomepage()), "About")); + pageToadlets.add(pageToadletFactory.createPageToadlet(new AboutPage(aboutTemplate, this, SonePlugin.getPluginVersion(), SonePlugin.getYear(), SonePlugin.getHomepage()), "About")); pageToadlets.add(pageToadletFactory.createPageToadlet(new SoneTemplatePage("noPermission.html", noPermissionTemplate, "Page.NoPermission.Title", this))); pageToadlets.add(pageToadletFactory.createPageToadlet(new SoneTemplatePage("emptyImageTitle.html", emptyImageTitleTemplate, "Page.EmptyImageTitle.Title", this))); pageToadlets.add(pageToadletFactory.createPageToadlet(new SoneTemplatePage("emptyAlbumTitle.html", emptyAlbumTitleTemplate, "Page.EmptyAlbumTitle.Title", this))); diff --git a/src/main/java/net/pterodactylus/sone/web/ajax/GetNotificationsAjaxPage.java b/src/main/java/net/pterodactylus/sone/web/ajax/GetNotificationsAjaxPage.java index d0cba79..65d3943 100644 --- a/src/main/java/net/pterodactylus/sone/web/ajax/GetNotificationsAjaxPage.java +++ b/src/main/java/net/pterodactylus/sone/web/ajax/GetNotificationsAjaxPage.java @@ -113,7 +113,7 @@ public class GetNotificationsAjaxPage extends JsonPage { templateContext.set("currentSone", webInterface.getCurrentSone(request.getToadletContext(), false)); templateContext.set("localSones", webInterface.getCore().getLocalSones()); templateContext.set("request", request); - templateContext.set("currentVersion", SonePlugin.VERSION); + templateContext.set("currentVersion", SonePlugin.getPluginVersion()); templateContext.set("hasLatestVersion", webInterface.getCore().getUpdateChecker().hasLatestVersion()); templateContext.set("latestEdition", webInterface.getCore().getUpdateChecker().getLatestEdition()); templateContext.set("latestVersion", webInterface.getCore().getUpdateChecker().getLatestVersion()); diff --git a/src/test/java/net/pterodactylus/sone/TestAlbumBuilder.java b/src/test/java/net/pterodactylus/sone/TestAlbumBuilder.java index a499019..ea21118 100644 --- a/src/test/java/net/pterodactylus/sone/TestAlbumBuilder.java +++ b/src/test/java/net/pterodactylus/sone/TestAlbumBuilder.java @@ -1,7 +1,7 @@ package net.pterodactylus.sone; import static java.util.UUID.randomUUID; -import static org.mockito.Matchers.any; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; diff --git a/src/test/java/net/pterodactylus/sone/core/ConfigurationSoneParserTest.java b/src/test/java/net/pterodactylus/sone/core/ConfigurationSoneParserTest.java index ec42a8c..7deb805 100644 --- a/src/test/java/net/pterodactylus/sone/core/ConfigurationSoneParserTest.java +++ b/src/test/java/net/pterodactylus/sone/core/ConfigurationSoneParserTest.java @@ -13,8 +13,8 @@ import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; -import static org.mockito.Matchers.anyString; -import static org.mockito.Matchers.eq; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; diff --git a/src/test/java/net/pterodactylus/sone/core/CoreTest.java b/src/test/java/net/pterodactylus/sone/core/CoreTest.java index 8e83e21..cea8ed7 100644 --- a/src/test/java/net/pterodactylus/sone/core/CoreTest.java +++ b/src/test/java/net/pterodactylus/sone/core/CoreTest.java @@ -1,11 +1,11 @@ package net.pterodactylus.sone.core; -import static org.mockito.Matchers.argThat; -import static org.mockito.Matchers.eq; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.inOrder; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import static org.mockito.hamcrest.MockitoHamcrest.argThat; import net.pterodactylus.sone.core.Core.MarkPostKnown; import net.pterodactylus.sone.core.Core.MarkReplyKnown; diff --git a/src/test/java/net/pterodactylus/sone/core/FreenetInterfaceTest.java b/src/test/java/net/pterodactylus/sone/core/FreenetInterfaceTest.java index 091c93f..8211c5e 100644 --- a/src/test/java/net/pterodactylus/sone/core/FreenetInterfaceTest.java +++ b/src/test/java/net/pterodactylus/sone/core/FreenetInterfaceTest.java @@ -10,10 +10,10 @@ import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; import static org.mockito.ArgumentCaptor.forClass; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyBoolean; -import static org.mockito.Matchers.anyShort; -import static org.mockito.Matchers.eq; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.ArgumentMatchers.anyShort; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; @@ -69,6 +69,7 @@ import com.google.common.eventbus.EventBus; import org.junit.Before; import org.junit.Test; import org.mockito.ArgumentCaptor; +import org.mockito.ArgumentMatchers; /** * Unit test for {@link FreenetInterface}. @@ -198,7 +199,7 @@ public class FreenetInterfaceTest { @Test(expected = SoneException.class) public void insertExceptionIsForwardedAsSoneException() throws InsertException, SoneException { - when(highLevelSimpleClient.insertManifest(any(FreenetURI.class), any(HashMap.class), any(String.class))).thenThrow(InsertException.class); + when(highLevelSimpleClient.insertManifest(ArgumentMatchers.any(), ArgumentMatchers.>any(), ArgumentMatchers.any())).thenThrow(InsertException.class); freenetInterface.insertDirectory(null, null, null); } diff --git a/src/test/java/net/pterodactylus/sone/core/ImageInserterTest.java b/src/test/java/net/pterodactylus/sone/core/ImageInserterTest.java index 0912391..75788d1 100644 --- a/src/test/java/net/pterodactylus/sone/core/ImageInserterTest.java +++ b/src/test/java/net/pterodactylus/sone/core/ImageInserterTest.java @@ -1,7 +1,7 @@ package net.pterodactylus.sone.core; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.eq; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; diff --git a/src/test/java/net/pterodactylus/sone/core/PreferencesTest.java b/src/test/java/net/pterodactylus/sone/core/PreferencesTest.java index a19fe2e..6756185 100644 --- a/src/test/java/net/pterodactylus/sone/core/PreferencesTest.java +++ b/src/test/java/net/pterodactylus/sone/core/PreferencesTest.java @@ -5,7 +5,7 @@ import static net.pterodactylus.sone.fcp.FcpInterface.FullAccessRequired.NO; import static net.pterodactylus.sone.fcp.FcpInterface.FullAccessRequired.WRITING; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; -import static org.mockito.Matchers.any; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; diff --git a/src/test/java/net/pterodactylus/sone/core/SoneChangeDetectorTest.java b/src/test/java/net/pterodactylus/sone/core/SoneChangeDetectorTest.java index f070eff..34e3573 100644 --- a/src/test/java/net/pterodactylus/sone/core/SoneChangeDetectorTest.java +++ b/src/test/java/net/pterodactylus/sone/core/SoneChangeDetectorTest.java @@ -1,7 +1,7 @@ package net.pterodactylus.sone.core; import static java.util.Arrays.asList; -import static org.mockito.Matchers.any; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; diff --git a/src/test/java/net/pterodactylus/sone/core/SoneDownloaderTest.java b/src/test/java/net/pterodactylus/sone/core/SoneDownloaderTest.java index 33c8ead..9043974 100644 --- a/src/test/java/net/pterodactylus/sone/core/SoneDownloaderTest.java +++ b/src/test/java/net/pterodactylus/sone/core/SoneDownloaderTest.java @@ -9,8 +9,8 @@ import static net.pterodactylus.sone.data.Sone.SoneStatus.unknown; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; import static org.mockito.ArgumentCaptor.forClass; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.eq; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; diff --git a/src/test/java/net/pterodactylus/sone/core/SoneInserterTest.java b/src/test/java/net/pterodactylus/sone/core/SoneInserterTest.java index 552746e..51947d1 100644 --- a/src/test/java/net/pterodactylus/sone/core/SoneInserterTest.java +++ b/src/test/java/net/pterodactylus/sone/core/SoneInserterTest.java @@ -9,16 +9,16 @@ import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.nullValue; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyString; -import static org.mockito.Matchers.argThat; -import static org.mockito.Matchers.eq; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import static org.mockito.hamcrest.MockitoHamcrest.argThat; import java.io.IOException; import java.util.HashMap; @@ -260,7 +260,7 @@ public class SoneInserterTest { assertThat(manifestElement.getName(), is("test.txt")); assertThat(manifestElement.getMimeTypeOverride(), is("plain/text; charset=utf-8")); String templateContent = new String(toByteArray(manifestElement.getData().getInputStream()), Charsets.UTF_8); - assertThat(templateContent, containsString("Sone Version: " + SonePlugin.VERSION.toString() + "\n")); + assertThat(templateContent, containsString("Sone Version: " + SonePlugin.getPluginVersion() + "\n")); assertThat(templateContent, containsString("Core Startup: " + now + "\n")); assertThat(templateContent, containsString("Sone ID: " + "SoneId" + "\n")); } diff --git a/src/test/java/net/pterodactylus/sone/core/SoneParserTest.java b/src/test/java/net/pterodactylus/sone/core/SoneParserTest.java index 2d8a5a0..da5ca50 100644 --- a/src/test/java/net/pterodactylus/sone/core/SoneParserTest.java +++ b/src/test/java/net/pterodactylus/sone/core/SoneParserTest.java @@ -11,9 +11,9 @@ import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.not; import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyLong; -import static org.mockito.Matchers.anyString; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; diff --git a/src/test/java/net/pterodactylus/sone/core/SoneRescuerTest.java b/src/test/java/net/pterodactylus/sone/core/SoneRescuerTest.java index ede6f13..0b339fb 100644 --- a/src/test/java/net/pterodactylus/sone/core/SoneRescuerTest.java +++ b/src/test/java/net/pterodactylus/sone/core/SoneRescuerTest.java @@ -2,8 +2,8 @@ package net.pterodactylus.sone.core; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.eq; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; diff --git a/src/test/java/net/pterodactylus/sone/core/UpdateCheckerTest.java b/src/test/java/net/pterodactylus/sone/core/UpdateCheckerTest.java index 44819ee..ad6b331 100644 --- a/src/test/java/net/pterodactylus/sone/core/UpdateCheckerTest.java +++ b/src/test/java/net/pterodactylus/sone/core/UpdateCheckerTest.java @@ -5,13 +5,13 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.is; import static org.mockito.ArgumentCaptor.forClass; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.argThat; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import static org.mockito.hamcrest.MockitoHamcrest.argThat; import java.io.IOException; import java.io.InputStream; diff --git a/src/test/java/net/pterodactylus/sone/core/WebOfTrustUpdaterTest.java b/src/test/java/net/pterodactylus/sone/core/WebOfTrustUpdaterTest.java index aa810ee..7529fc6 100644 --- a/src/test/java/net/pterodactylus/sone/core/WebOfTrustUpdaterTest.java +++ b/src/test/java/net/pterodactylus/sone/core/WebOfTrustUpdaterTest.java @@ -6,7 +6,7 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.not; -import static org.mockito.Matchers.eq; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; diff --git a/src/test/java/net/pterodactylus/sone/database/memory/MemoryBookmarkDatabaseTest.java b/src/test/java/net/pterodactylus/sone/database/memory/MemoryBookmarkDatabaseTest.java index 06c5b96..c16ce9d 100644 --- a/src/test/java/net/pterodactylus/sone/database/memory/MemoryBookmarkDatabaseTest.java +++ b/src/test/java/net/pterodactylus/sone/database/memory/MemoryBookmarkDatabaseTest.java @@ -5,8 +5,8 @@ import static net.pterodactylus.sone.Matchers.isPostWithId; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.is; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyString; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; diff --git a/src/test/java/net/pterodactylus/sone/database/memory/MemoryDatabaseTest.java b/src/test/java/net/pterodactylus/sone/database/memory/MemoryDatabaseTest.java index a207132..d305031 100644 --- a/src/test/java/net/pterodactylus/sone/database/memory/MemoryDatabaseTest.java +++ b/src/test/java/net/pterodactylus/sone/database/memory/MemoryDatabaseTest.java @@ -30,7 +30,7 @@ import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.empty; import static org.hamcrest.Matchers.emptyIterable; -import static org.mockito.Matchers.anyString; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; diff --git a/src/test/java/net/pterodactylus/sone/fcp/LockSoneCommandTest.java b/src/test/java/net/pterodactylus/sone/fcp/LockSoneCommandTest.java index d583661..8d6ee61 100644 --- a/src/test/java/net/pterodactylus/sone/fcp/LockSoneCommandTest.java +++ b/src/test/java/net/pterodactylus/sone/fcp/LockSoneCommandTest.java @@ -20,7 +20,7 @@ package net.pterodactylus.sone.fcp; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.notNullValue; import static org.hamcrest.MatcherAssert.assertThat; -import static org.mockito.Matchers.eq; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; diff --git a/src/test/java/net/pterodactylus/sone/fcp/UnlockSoneCommandTest.java b/src/test/java/net/pterodactylus/sone/fcp/UnlockSoneCommandTest.java index bd292dd..842d0e8 100644 --- a/src/test/java/net/pterodactylus/sone/fcp/UnlockSoneCommandTest.java +++ b/src/test/java/net/pterodactylus/sone/fcp/UnlockSoneCommandTest.java @@ -20,7 +20,7 @@ package net.pterodactylus.sone.fcp; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.notNullValue; import static org.hamcrest.MatcherAssert.assertThat; -import static org.mockito.Matchers.eq; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; diff --git a/src/test/java/net/pterodactylus/sone/freenet/wot/IdentityChangeEventSenderTest.java b/src/test/java/net/pterodactylus/sone/freenet/wot/IdentityChangeEventSenderTest.java index f58c239..c5dc82b 100644 --- a/src/test/java/net/pterodactylus/sone/freenet/wot/IdentityChangeEventSenderTest.java +++ b/src/test/java/net/pterodactylus/sone/freenet/wot/IdentityChangeEventSenderTest.java @@ -21,7 +21,7 @@ import static com.google.common.collect.ImmutableMap.of; import static java.util.Arrays.asList; import static net.pterodactylus.sone.freenet.wot.Identities.createIdentity; import static net.pterodactylus.sone.freenet.wot.Identities.createOwnIdentity; -import static org.mockito.Matchers.eq; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; diff --git a/src/test/java/net/pterodactylus/sone/freenet/wot/IdentityLoaderTest.java b/src/test/java/net/pterodactylus/sone/freenet/wot/IdentityLoaderTest.java index a07af28..72175bd 100644 --- a/src/test/java/net/pterodactylus/sone/freenet/wot/IdentityLoaderTest.java +++ b/src/test/java/net/pterodactylus/sone/freenet/wot/IdentityLoaderTest.java @@ -26,8 +26,8 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.is; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.eq; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; diff --git a/src/test/java/net/pterodactylus/sone/notify/ListNotificationFilterTest.java b/src/test/java/net/pterodactylus/sone/notify/ListNotificationFilterTest.java index b29b2c1..dabfd5a 100644 --- a/src/test/java/net/pterodactylus/sone/notify/ListNotificationFilterTest.java +++ b/src/test/java/net/pterodactylus/sone/notify/ListNotificationFilterTest.java @@ -6,7 +6,7 @@ import static org.hamcrest.Matchers.emptyIterable; import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.sameInstance; -import static org.mockito.Matchers.any; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -29,6 +29,7 @@ import com.google.inject.Guice; import com.google.inject.Injector; import org.hamcrest.Matchers; import org.junit.Test; +import org.mockito.ArgumentMatchers; /** * Unit test for {@link ListNotificationFilterTest}. @@ -117,7 +118,7 @@ public class ListNotificationFilterTest { } private void setPostVisibilityPredicate(Predicate value) { - when(postVisibilityFilter.isVisible(any(Sone.class))).thenReturn(value); + when(postVisibilityFilter.isVisible(ArgumentMatchers.any())).thenReturn(value); } @Test diff --git a/src/test/java/net/pterodactylus/sone/notify/ListNotificationTest.java b/src/test/java/net/pterodactylus/sone/notify/ListNotificationTest.java index c354afa..7ae3dd8 100644 --- a/src/test/java/net/pterodactylus/sone/notify/ListNotificationTest.java +++ b/src/test/java/net/pterodactylus/sone/notify/ListNotificationTest.java @@ -4,11 +4,11 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.emptyIterable; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.not; -import static org.mockito.Matchers.argThat; -import static org.mockito.Matchers.eq; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import static org.mockito.hamcrest.MockitoHamcrest.argThat; import java.util.Arrays; diff --git a/src/test/java/net/pterodactylus/sone/template/ImageLinkFilterTest.java b/src/test/java/net/pterodactylus/sone/template/ImageLinkFilterTest.java index 20d2362..e96b6cb 100644 --- a/src/test/java/net/pterodactylus/sone/template/ImageLinkFilterTest.java +++ b/src/test/java/net/pterodactylus/sone/template/ImageLinkFilterTest.java @@ -73,7 +73,7 @@ public class ImageLinkFilterTest { String result = String.valueOf(imageLinkFilter.format(templateContext, image, ImmutableMap.of())); Element imageElement = getSingleElement(result); assertThat(imageElement.attr("class"), is("")); - assertThat(imageElement.attr("src"), is("/image-key?forcedownload=true")); + assertThat(imageElement.attr("src"), is("/image-key")); assertThat(imageElement.attr("title"), is("image title")); assertThat(imageElement.attr("alt"), is("image description")); assertThat(imageElement.attr("width"), is("640")); @@ -138,7 +138,7 @@ public class ImageLinkFilterTest { String result = String.valueOf(imageLinkFilter.format(templateContext, "image-id", ImmutableMap.of())); Element imageElement = getSingleElement(result); assertThat(imageElement.attr("class"), is("")); - assertThat(imageElement.attr("src"), is("/image-key?forcedownload=true")); + assertThat(imageElement.attr("src"), is("/image-key")); assertThat(imageElement.attr("title"), is("image title")); assertThat(imageElement.attr("alt"), is("image description")); assertThat(imageElement.attr("width"), is("640")); diff --git a/src/test/java/net/pterodactylus/sone/test/Dirty.java b/src/test/java/net/pterodactylus/sone/test/Dirty.java new file mode 100644 index 0000000..def311a --- /dev/null +++ b/src/test/java/net/pterodactylus/sone/test/Dirty.java @@ -0,0 +1,20 @@ +package net.pterodactylus.sone.test; + +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.RetentionPolicy.SOURCE; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +/** + * This annotation marks test methods that are somehow not good test methods. + * + * @author David ‘Bombe’ Roden + */ +@Retention(SOURCE) +@Target(METHOD) +public @interface Dirty { + + String value() default ""; + +} diff --git a/src/test/java/net/pterodactylus/sone/text/FreenetLinkPartTest.java b/src/test/java/net/pterodactylus/sone/text/FreenetLinkPartTest.java new file mode 100644 index 0000000..f29fdde --- /dev/null +++ b/src/test/java/net/pterodactylus/sone/text/FreenetLinkPartTest.java @@ -0,0 +1,67 @@ +package net.pterodactylus.sone.text; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; + +import org.junit.Test; + +/** + * Unit test for {@link FreenetLinkPart}. + * + * @author David ‘Bombe’ Roden + */ +public class FreenetLinkPartTest { + + private final FreenetLinkPart part = new FreenetLinkPart("link", "text", "title", true); + + @Test + public void linkIsRetainedCorrectly() { + assertThat(part.getLink(), is("link")); + } + + @Test + public void textIsRetainedCorrectly() { + assertThat(part.getText(), is("text")); + } + + @Test + public void titleIsRetainedCorrectly() { + assertThat(part.getTitle(), is("title")); + } + + @Test + public void trustedIsRetainedCorrectly() { + assertThat(part.isTrusted(), is(true)); + } + + @Test + public void textIsUsedAsTitleIfNoTextIsGiven() { + assertThat(new FreenetLinkPart("link", "text", true).getTitle(), is("text")); + } + + @Test(expected = NullPointerException.class) + public void nullIsNotAllowedForLink() { + new FreenetLinkPart(null, "text", "title", true); + } + + @Test(expected = NullPointerException.class) + public void nullIsNotAllowedForText() { + new FreenetLinkPart("link", null, "title", true); + } + + @Test(expected = NullPointerException.class) + public void nullIsNotAllowedForLinkInSecondaryConstructor() { + new FreenetLinkPart(null, "text", true); + } + + @Test(expected = NullPointerException.class) + public void nullIsNotAllowedForTextInSecondaryConstructor() { + new FreenetLinkPart("link", null, true); + } + + @Test(expected = NullPointerException.class) + public void nullIsNotAllowedForTitle() { + new FreenetLinkPart("link", "text", null, true); + } + +} diff --git a/src/test/java/net/pterodactylus/sone/text/LinkPartTest.java b/src/test/java/net/pterodactylus/sone/text/LinkPartTest.java new file mode 100644 index 0000000..431dfa6 --- /dev/null +++ b/src/test/java/net/pterodactylus/sone/text/LinkPartTest.java @@ -0,0 +1,62 @@ +package net.pterodactylus.sone.text; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; + +import org.junit.Test; + +/** + * Unit test for {@link LinkPart}. + * + * @author David ‘Bombe’ Roden + */ +public class LinkPartTest { + + private final LinkPart part = new LinkPart("link", "text", "title"); + + @Test + public void linkIsRetainedCorrectly() { + assertThat(part.getLink(), is("link")); + } + + @Test + public void textIsRetainedCorrectly() { + assertThat(part.getText(), is("text")); + } + + @Test + public void titleIsRetainedCorrectly() { + assertThat(part.getTitle(), is("title")); + } + + @Test + public void textIsUsedAsTitleIfNoTitleIsGiven() { + assertThat(new LinkPart("link", "text").getTitle(), is("text")); + } + + @Test(expected = NullPointerException.class) + public void nullIsNotAllowedForLink() { + new LinkPart(null, "text", "title"); + } + + @Test(expected = NullPointerException.class) + public void nullIsNotAllowedForText() { + new LinkPart("link", null, "title"); + } + + @Test(expected = NullPointerException.class) + public void nullIsNotAllowedForLinkInSecondaryConstructor() { + new LinkPart(null, "text"); + } + + @Test(expected = NullPointerException.class) + public void nullIsNotAllowedForTextInSecondaryConstructor() { + new LinkPart("link", null); + } + + @Test(expected = NullPointerException.class) + public void nullIsNotAllowedForTitle() { + new LinkPart("link", "text", null); + } + +} diff --git a/src/test/java/net/pterodactylus/sone/text/PartContainerTest.java b/src/test/java/net/pterodactylus/sone/text/PartContainerTest.java new file mode 100644 index 0000000..036b2dc --- /dev/null +++ b/src/test/java/net/pterodactylus/sone/text/PartContainerTest.java @@ -0,0 +1,99 @@ +package net.pterodactylus.sone.text; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.util.Iterator; +import java.util.NoSuchElementException; + +import org.junit.Test; + +/** + * Unit test for {@link PartContainer}. + * + * @author David ‘Bombe’ Roden + */ +public class PartContainerTest { + + private final PartContainer container = new PartContainer(); + + @Test + public void emptyContainerHasSizeZero() { + assertThat(container.size(), is(0)); + } + + @Test(expected = NullPointerException.class) + public void canNotAddNullPart() { + container.add(null); + } + + @Test + public void containerWithSinglePartHasSizeOne() { + container.add(mock(Part.class)); + assertThat(container.size(), is(1)); + } + + @Test + public void containerWithSinglePartCanReturnPart() { + Part part = mock(Part.class); + container.add(part); + assertThat(container.getPart(0), is(part)); + } + + @Test + public void containerIsEmptyAfterPartIsAddedAndRemoved() { + container.add(mock(Part.class)); + container.removePart(0); + assertThat(container.size(), is(0)); + } + + @Test + public void containerContainsSecondPartIfFirstPartIsRemoved() { + container.add(mock(Part.class)); + Part part = mock(Part.class); + container.add(part); + container.removePart(0); + assertThat(container.getPart(0), is(part)); + } + + @Test + public void textOfContainerPartIsTextOfPartsConcatenated() { + container.add(createPartWithText("first")); + container.add(createPartWithText("second")); + assertThat(container.getText(), is("firstsecond")); + } + + private Part createPartWithText(String text) { + Part part = mock(Part.class); + when(part.getText()).thenReturn(text); + return part; + } + + @Test(expected = NoSuchElementException.class) + public void emptyContainerIteratorThrowsOnNext() { + container.iterator().next(); + } + + @Test + public void iteratorIteratesPartsRecursivelyInCorrectOrder() { + Part firstPart = mock(Part.class); + PartContainer secondPart = new PartContainer(); + Part thirdPart = mock(Part.class); + Part nestedFirstPart = mock(Part.class); + Part nestedSecondPart = mock(Part.class); + secondPart.add(nestedFirstPart); + secondPart.add(nestedSecondPart); + container.add(firstPart); + container.add(secondPart); + container.add(thirdPart); + Iterator parts = container.iterator(); + assertThat(parts.next(), is(firstPart)); + assertThat(parts.next(), is(nestedFirstPart)); + assertThat(parts.next(), is(nestedSecondPart)); + assertThat(parts.next(), is(thirdPart)); + assertThat(parts.hasNext(), is(false)); + } + +} diff --git a/src/test/java/net/pterodactylus/sone/text/PlainTextPartTest.java b/src/test/java/net/pterodactylus/sone/text/PlainTextPartTest.java new file mode 100644 index 0000000..72161ab --- /dev/null +++ b/src/test/java/net/pterodactylus/sone/text/PlainTextPartTest.java @@ -0,0 +1,27 @@ +package net.pterodactylus.sone.text; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; + +import org.junit.Test; + +/** + * Unit test for {@link PlainTextPart}. + * + * @author David ‘Bombe’ Roden + */ +public class PlainTextPartTest { + + private final PlainTextPart part = new PlainTextPart("text"); + + @Test + public void textIsRetainedCorrectly() { + assertThat(part.getText(), is("text")); + } + + @Test(expected = NullPointerException.class) + public void nullIsNotAllowedForText() { + new PlainTextPart(null); + } + +} diff --git a/src/test/java/net/pterodactylus/sone/text/PostPartTest.java b/src/test/java/net/pterodactylus/sone/text/PostPartTest.java new file mode 100644 index 0000000..7b4ea19 --- /dev/null +++ b/src/test/java/net/pterodactylus/sone/text/PostPartTest.java @@ -0,0 +1,38 @@ +package net.pterodactylus.sone.text; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import net.pterodactylus.sone.data.Post; + +import org.junit.Test; + +/** + * Unit test for {@link PostPart}. + * + * @author David ‘Bombe’ Roden + */ +public class PostPartTest { + + private final Post post = mock(Post.class); + private final PostPart part = new PostPart(post); + + @Test + public void postIsRetainedCorrectly() { + assertThat(part.getPost(), is(post)); + } + + @Test + public void textIsTakenFromPost() { + when(post.getText()).thenReturn("text"); + assertThat(part.getText(), is("text")); + } + + @Test(expected = NullPointerException.class) + public void nullIsNotAllowedForPost() { + new PostPart(null); + } + +} diff --git a/src/test/java/net/pterodactylus/sone/text/SonePartTest.java b/src/test/java/net/pterodactylus/sone/text/SonePartTest.java new file mode 100644 index 0000000..589acf7 --- /dev/null +++ b/src/test/java/net/pterodactylus/sone/text/SonePartTest.java @@ -0,0 +1,42 @@ +package net.pterodactylus.sone.text; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import net.pterodactylus.sone.data.Profile; +import net.pterodactylus.sone.data.Sone; + +import org.hamcrest.MatcherAssert; +import org.junit.Test; +import org.mockito.Mockito; + +/** + * Unit test for {@link SonePart}. + * + * @author David ‘Bombe’ Roden + */ +public class SonePartTest { + + private final Sone sone = mock(Sone.class); + private final SonePart part = new SonePart(sone); + + @Test + public void soneIsRetainedCorrectly() { + assertThat(part.getSone(), is(sone)); + } + + @Test + public void textIsConstructedFromSonesNiceName() { + when(sone.getProfile()).thenReturn(mock(Profile.class)); + when(sone.getName()).thenReturn("sone"); + assertThat(part.getText(), is("sone")); + } + + @Test(expected = NullPointerException.class) + public void nullIsNotAllowedForSone() { + new SonePart(null); + } + +} diff --git a/src/test/java/net/pterodactylus/sone/text/SoneTextParserTest.java b/src/test/java/net/pterodactylus/sone/text/SoneTextParserTest.java index 7a06dcf..6483171 100644 --- a/src/test/java/net/pterodactylus/sone/text/SoneTextParserTest.java +++ b/src/test/java/net/pterodactylus/sone/text/SoneTextParserTest.java @@ -17,121 +17,305 @@ package net.pterodactylus.sone.text; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.isIn; +import static org.hamcrest.Matchers.notNullValue; + import java.io.IOException; -import java.util.Arrays; import java.util.Collection; +import net.pterodactylus.sone.data.Post; import net.pterodactylus.sone.data.Sone; import net.pterodactylus.sone.data.impl.IdOnlySone; +import net.pterodactylus.sone.database.PostProvider; import net.pterodactylus.sone.database.SoneProvider; import com.google.common.base.Function; import com.google.common.base.Optional; -import junit.framework.TestCase; +import org.junit.Test; /** * JUnit test case for {@link SoneTextParser}. * * @author David ‘Bombe’ Roden */ -public class SoneTextParserTest extends TestCase { +public class SoneTextParserTest { - // - // ACTIONS - // + private final SoneTextParser soneTextParser = new SoneTextParser(null, null); - /** - * Tests basic plain-text operation of the parser. - * - * @throws IOException - * if an I/O error occurs - */ @SuppressWarnings("static-method") + @Test public void testPlainText() throws IOException { - SoneTextParser soneTextParser = new SoneTextParser(null, null); - Iterable parts; - /* check basic operation. */ - parts = soneTextParser.parse("Test.", null); - assertNotNull("Parts", parts); - assertEquals("Part Text", "Test.", convertText(parts, PlainTextPart.class)); + Iterable parts = soneTextParser.parse("Test.", null); + assertThat("Parts", parts, notNullValue()); + assertThat("Part Text", convertText(parts, PlainTextPart.class), is("Test.")); /* check empty lines at start and end. */ parts = soneTextParser.parse("\nTest.\n\n", null); - assertNotNull("Parts", parts); - assertEquals("Part Text", "Test.", convertText(parts, PlainTextPart.class)); + assertThat("Parts", parts, notNullValue()); + assertThat("Part Text", convertText(parts, PlainTextPart.class), is("Test.")); /* check duplicate empty lines in the text. */ parts = soneTextParser.parse("\nTest.\n\n\nTest.", null); - assertNotNull("Parts", parts); - assertEquals("Part Text", "Test.\n\nTest.", convertText(parts, PlainTextPart.class)); + assertThat("Parts", parts, notNullValue()); + assertThat("Part Text", convertText(parts, PlainTextPart.class), is("Test.\n\nTest.")); + } + + @Test + public void consecutiveLinesAreSeparatedByLinefeed() { + Iterable parts = soneTextParser.parse("Text.\nText", null); + assertThat("Part Text", convertText(parts), is("Text.\nText")); + } + + @Test + public void freenetLinksHaveTheFreenetPrefixRemoved() { + Iterable parts = soneTextParser.parse("freenet:KSK@gpl.txt", null); + assertThat("Part Text", convertText(parts), is("[KSK@gpl.txt|gpl.txt|gpl.txt]")); + } + + @Test + public void onlyTheFirstItemInALineIsPrefixedWithALineBreak() { + Iterable parts = soneTextParser.parse("Text.\nKSK@gpl.txt and KSK@gpl.txt", null); + assertThat("Part Text", convertText(parts), is("Text.\n[KSK@gpl.txt|gpl.txt|gpl.txt] and [KSK@gpl.txt|gpl.txt|gpl.txt]")); + } + + @Test + public void soneLinkWithTooShortSoneIdIsRenderedAsPlainText() { + Iterable parts = soneTextParser.parse("sone://too-short", null); + assertThat("Part Text", convertText(parts), is("sone://too-short")); + } + + @Test + public void soneLinkIsRenderedCorrectlyIfSoneIsNotPresent() { + SoneTextParser parser = new SoneTextParser(new AbsentSoneProvider(), null); + Iterable parts = parser.parse("sone://DAxKQzS48mtaQc7sUVHIgx3fnWZPQBz0EueBreUVWrU", null); + assertThat("Part Text", convertText(parts), is("[Sone|DAxKQzS48mtaQc7sUVHIgx3fnWZPQBz0EueBreUVWrU]")); + } + + @Test + public void postLinkIsRenderedAsPlainTextIfPostIdIsTooShort() { + Iterable parts = soneTextParser.parse("post://too-short", null); + assertThat("Part Text", convertText(parts), is("post://too-short")); + } + + @Test + public void postLinkIsRenderedCorrectlyIfPostIsPresent() { + SoneTextParser parser = new SoneTextParser(null, new TestPostProvider()); + Iterable parts = parser.parse("post://f3757817-b45a-497a-803f-9c5aafc10dc6", null); + assertThat("Part Text", convertText(parts), is("[Post|f3757817-b45a-497a-803f-9c5aafc10dc6|text]")); + } + + @Test + public void postLinkIsRenderedAsPlainTextIfPostIsAbsent() { + SoneTextParser parser = new SoneTextParser(null, new AbsentPostProvider()); + Iterable parts = parser.parse("post://f3757817-b45a-497a-803f-9c5aafc10dc6", null); + assertThat("Part Text", convertText(parts), is("post://f3757817-b45a-497a-803f-9c5aafc10dc6")); + } + + @Test + public void nameOfFreenetLinkDoesNotContainUrlParameters() { + Iterable parts = soneTextParser.parse("KSK@gpl.txt?max-size=12345", null); + assertThat("Part Text", convertText(parts), is("[KSK@gpl.txt?max-size=12345|gpl.txt|gpl.txt]")); + } + + @Test + public void trailingSlashInFreenetLinkIsRemovedForName() { + Iterable parts = soneTextParser.parse("KSK@gpl.txt/", null); + assertThat("Part Text", convertText(parts), is("[KSK@gpl.txt/|gpl.txt|gpl.txt]")); + } + + @Test + public void lastMetaStringOfFreenetLinkIsUsedAsName() { + Iterable parts = soneTextParser.parse("CHK@qM1nmgU-YUnIttmEhqjTl7ifAF3Z6o~5EPwQW03uEQU,aztSUkT-VT1dWvfSUt9YpfyW~Flmf5yXpBnIE~v8sAg,AAMC--8/COPYING", null); + assertThat("Part Text", convertText(parts), is("[CHK@qM1nmgU-YUnIttmEhqjTl7ifAF3Z6o~5EPwQW03uEQU,aztSUkT-VT1dWvfSUt9YpfyW~Flmf5yXpBnIE~v8sAg,AAMC--8/COPYING|COPYING|COPYING]")); + } + + @Test + public void freenetLinkWithoutMetaStringsAndDocNameGetsFirstNineCharactersOfKeyAsName() { + Iterable parts = soneTextParser.parse("CHK@qM1nmgU-YUnIttmEhqjTl7ifAF3Z6o~5EPwQW03uEQU,aztSUkT-VT1dWvfSUt9YpfyW~Flmf5yXpBnIE~v8sAg,AAMC--8", null); + assertThat("Part Text", convertText(parts), is("[CHK@qM1nmgU-YUnIttmEhqjTl7ifAF3Z6o~5EPwQW03uEQU,aztSUkT-VT1dWvfSUt9YpfyW~Flmf5yXpBnIE~v8sAg,AAMC--8|CHK@qM1nm|CHK@qM1nm]")); + } + + @Test + public void malformedKeyIsRenderedAsPlainText() { + Iterable parts = soneTextParser.parse("CHK@qM1nmgU", null); + assertThat("Part Text", convertText(parts), is("CHK@qM1nmgU")); + } + + @Test + public void httpsLinkHasItsPathsShortened() { + Iterable parts = soneTextParser.parse("https://test.test/some-long-path/file.txt", null); + assertThat("Part Text", convertText(parts), is("[https://test.test/some-long-path/file.txt|test.test/…/file.txt|test.test/…/file.txt]")); + } + + @Test + public void httpLinksHaveTheirLastSlashRemoved() { + Iterable parts = soneTextParser.parse("http://test.test/test/", null); + assertThat("Part Text", convertText(parts), is("[http://test.test/test/|test.test/…|test.test/…]")); + } + + @Test + public void wwwPrefixIsRemovedForHostnameWithTwoDotsAndNoPath() { + Iterable parts = soneTextParser.parse("http://www.test.test", null); + assertThat("Part Text", convertText(parts), is("[http://www.test.test|test.test|test.test]")); + } + + @Test + public void wwwPrefixIsRemovedForHostnameWithTwoDotsAndAPath() { + Iterable parts = soneTextParser.parse("http://www.test.test/test.html", null); + assertThat("Part Text", convertText(parts), is("[http://www.test.test/test.html|test.test/test.html|test.test/test.html]")); + } + + @Test + public void hostnameIsKeptIntactIfNotBeginningWithWww() { + Iterable parts = soneTextParser.parse("http://test.test.test/test.html", null); + assertThat("Part Text", convertText(parts), is("[http://test.test.test/test.html|test.test.test/test.html|test.test.test/test.html]")); + } + + @Test + public void hostnameWithOneDotButNoSlashIsKeptIntact() { + Iterable parts = soneTextParser.parse("http://test.test", null); + assertThat("Part Text", convertText(parts), is("[http://test.test|test.test|test.test]")); + } + + @Test + public void urlParametersAreRemovedForHttpLinks() { + Iterable parts = soneTextParser.parse("http://test.test?foo=bar", null); + assertThat("Part Text", convertText(parts), is("[http://test.test?foo=bar|test.test|test.test]")); + } + + @Test + public void emptyStringIsParsedCorrectly() { + Iterable parts = soneTextParser.parse("", null); + assertThat("Part Text", convertText(parts), is("")); + } + + @Test + public void linksAreParsedInCorrectOrder() { + Iterable parts = soneTextParser.parse("KSK@ CHK@", null); + assertThat("Part Text", convertText(parts), is("KSK@ CHK@")); + } + + @Test + public void sskLinkWithoutContextIsNotTrusted() { + Iterable parts = soneTextParser.parse("SSK@qM1nmgU-YUnIttmEhqjTl7ifAF3Z6o~5EPwQW03uEQU,aztSUkT-VT1dWvfSUt9YpfyW~Flmf5yXpBnIE~v8sAg,AAMC--8/test", null); + assertThat("Part Text", convertText(parts), is("[SSK@qM1nmgU-YUnIttmEhqjTl7ifAF3Z6o~5EPwQW03uEQU,aztSUkT-VT1dWvfSUt9YpfyW~Flmf5yXpBnIE~v8sAg,AAMC--8/test|test|test]")); + } + + @Test + public void sskLinkWithContextWithoutSoneIsNotTrusted() { + SoneTextParserContext context = new SoneTextParserContext(null); + Iterable parts = soneTextParser.parse("SSK@qM1nmgU-YUnIttmEhqjTl7ifAF3Z6o~5EPwQW03uEQU,aztSUkT-VT1dWvfSUt9YpfyW~Flmf5yXpBnIE~v8sAg,AAMC--8/test", context); + assertThat("Part Text", convertText(parts), is("[SSK@qM1nmgU-YUnIttmEhqjTl7ifAF3Z6o~5EPwQW03uEQU,aztSUkT-VT1dWvfSUt9YpfyW~Flmf5yXpBnIE~v8sAg,AAMC--8/test|test|test]")); + } + + @Test + public void sskLinkWithContextWithDifferentSoneIsNotTrusted() { + SoneTextParserContext context = new SoneTextParserContext(new IdOnlySone("DAxKQzS48mtaQc7sUVHIgx3fnWZPQBz0EueBreUVWrU")); + Iterable parts = soneTextParser.parse("SSK@qM1nmgU-YUnIttmEhqjTl7ifAF3Z6o~5EPwQW03uEQU,aztSUkT-VT1dWvfSUt9YpfyW~Flmf5yXpBnIE~v8sAg,AAMC--8/test", context); + assertThat("Part Text", convertText(parts), is("[SSK@qM1nmgU-YUnIttmEhqjTl7ifAF3Z6o~5EPwQW03uEQU,aztSUkT-VT1dWvfSUt9YpfyW~Flmf5yXpBnIE~v8sAg,AAMC--8/test|test|test]")); + } + + @Test + public void sskLinkWithContextWithCorrectSoneIsTrusted() { + SoneTextParserContext context = new SoneTextParserContext(new IdOnlySone("qM1nmgU-YUnIttmEhqjTl7ifAF3Z6o~5EPwQW03uEQU")); + Iterable parts = soneTextParser.parse("SSK@qM1nmgU-YUnIttmEhqjTl7ifAF3Z6o~5EPwQW03uEQU,aztSUkT-VT1dWvfSUt9YpfyW~Flmf5yXpBnIE~v8sAg,AAMC--8/test", context); + assertThat("Part Text", convertText(parts), is("[SSK@qM1nmgU-YUnIttmEhqjTl7ifAF3Z6o~5EPwQW03uEQU,aztSUkT-VT1dWvfSUt9YpfyW~Flmf5yXpBnIE~v8sAg,AAMC--8/test|trusted|test|test]")); + } + + @Test + public void uskLinkWithContextWithCorrectSoneIsTrusted() { + SoneTextParserContext context = new SoneTextParserContext(new IdOnlySone("qM1nmgU-YUnIttmEhqjTl7ifAF3Z6o~5EPwQW03uEQU")); + Iterable parts = soneTextParser.parse("USK@qM1nmgU-YUnIttmEhqjTl7ifAF3Z6o~5EPwQW03uEQU,aztSUkT-VT1dWvfSUt9YpfyW~Flmf5yXpBnIE~v8sAg,AAMC--8/test/0", context); + assertThat("Part Text", convertText(parts), is("[USK@qM1nmgU-YUnIttmEhqjTl7ifAF3Z6o~5EPwQW03uEQU,aztSUkT-VT1dWvfSUt9YpfyW~Flmf5yXpBnIE~v8sAg,AAMC--8/test/0|trusted|test|test]")); } - /** - * Tests parsing of KSK links. - * - * @throws IOException - * if an I/O error occurs - */ @SuppressWarnings("static-method") + @Test public void testKSKLinks() throws IOException { - SoneTextParser soneTextParser = new SoneTextParser(null, null); - Iterable parts; - /* check basic links. */ - parts = soneTextParser.parse("KSK@gpl.txt", null); - assertNotNull("Parts", parts); - assertEquals("Part Text", "[KSK@gpl.txt|gpl.txt|gpl.txt]", convertText(parts, FreenetLinkPart.class)); + Iterable parts = soneTextParser.parse("KSK@gpl.txt", null); + assertThat("Parts", parts, notNullValue()); + assertThat("Part Text", convertText(parts, FreenetLinkPart.class), is("[KSK@gpl.txt|gpl.txt|gpl.txt]")); /* check embedded links. */ parts = soneTextParser.parse("Link is KSK@gpl.txt\u200b.", null); - assertNotNull("Parts", parts); - assertEquals("Part Text", "Link is [KSK@gpl.txt|gpl.txt|gpl.txt]\u200b.", convertText(parts, PlainTextPart.class, FreenetLinkPart.class)); + assertThat("Parts", parts, notNullValue()); + assertThat("Part Text", convertText(parts, PlainTextPart.class, FreenetLinkPart.class), is("Link is [KSK@gpl.txt|gpl.txt|gpl.txt]\u200b.")); /* check embedded links and line breaks. */ parts = soneTextParser.parse("Link is KSK@gpl.txt\nKSK@test.dat\n", null); - assertNotNull("Parts", parts); - assertEquals("Part Text", "Link is [KSK@gpl.txt|gpl.txt|gpl.txt]\n[KSK@test.dat|test.dat|test.dat]", convertText(parts, PlainTextPart.class, FreenetLinkPart.class)); + assertThat("Parts", parts, notNullValue()); + assertThat("Part Text", convertText(parts, PlainTextPart.class, FreenetLinkPart.class), is("Link is [KSK@gpl.txt|gpl.txt|gpl.txt]\n[KSK@test.dat|test.dat|test.dat]")); } - /** - * Test case for a bug that was discovered in 0.6.7. - * - * @throws IOException - * if an I/O error occurs - */ @SuppressWarnings({ "synthetic-access", "static-method" }) + @Test public void testEmptyLinesAndSoneLinks() throws IOException { SoneTextParser soneTextParser = new SoneTextParser(new TestSoneProvider(), null); - Iterable parts; /* check basic links. */ - parts = soneTextParser.parse("Some text.\n\nLink to sone://DAxKQzS48mtaQc7sUVHIgx3fnWZPQBz0EueBreUVWrU and stuff.", null); - assertNotNull("Parts", parts); - assertEquals("Part Text", "Some text.\n\nLink to [Sone|DAxKQzS48mtaQc7sUVHIgx3fnWZPQBz0EueBreUVWrU] and stuff.", convertText(parts, PlainTextPart.class, SonePart.class)); + Iterable parts = soneTextParser.parse("Some text.\n\nLink to sone://DAxKQzS48mtaQc7sUVHIgx3fnWZPQBz0EueBreUVWrU and stuff.", null); + assertThat("Parts", parts, notNullValue()); + assertThat("Part Text", convertText(parts, PlainTextPart.class, SonePart.class), is("Some text.\n\nLink to [Sone|DAxKQzS48mtaQc7sUVHIgx3fnWZPQBz0EueBreUVWrU] and stuff.")); } - /** - * Test for a bug discovered in Sone 0.8.4 where a plain “http://” would be - * parsed into a link. - * - * @throws IOException - * if an I/O error occurs - */ @SuppressWarnings({ "synthetic-access", "static-method" }) + @Test public void testEmpyHttpLinks() throws IOException { SoneTextParser soneTextParser = new SoneTextParser(new TestSoneProvider(), null); - Iterable parts; /* check empty http links. */ - parts = soneTextParser.parse("Some text. Empty link: http:// – nice!", null); - assertNotNull("Parts", parts); - assertEquals("Part Text", "Some text. Empty link: http:// – nice!", convertText(parts, PlainTextPart.class)); + Iterable parts = soneTextParser.parse("Some text. Empty link: http:// – nice!", null); + assertThat("Parts", parts, notNullValue()); + assertThat("Part Text", convertText(parts, PlainTextPart.class), is("Some text. Empty link: http:// – nice!")); + } + + @Test + public void httpLinkWithoutParensEndsAtNextClosingParen() { + Iterable parts = soneTextParser.parse("Some text (and a link: http://example.sone/abc) – nice!", null); + assertThat("Parts", parts, notNullValue()); + assertThat("Part Text", convertText(parts, PlainTextPart.class, LinkPart.class), is("Some text (and a link: [http://example.sone/abc|example.sone/abc|example.sone/abc]) – nice!")); + } + + @Test + public void uskLinkEndsAtFirstNonNumericNonSlashCharacterAfterVersionNumber() { + Iterable parts = soneTextParser.parse("Some link (USK@qM1nmgU-YUnIttmEhqjTl7ifAF3Z6o~5EPwQW03uEQU,aztSUkT-VT1dWvfSUt9YpfyW~Flmf5yXpBnIE~v8sAg,AAMC--8/test/0). Nice", null); + assertThat("Parts", parts, notNullValue()); + assertThat("Part Text", convertText(parts), is("Some link ([USK@qM1nmgU-YUnIttmEhqjTl7ifAF3Z6o~5EPwQW03uEQU,aztSUkT-VT1dWvfSUt9YpfyW~Flmf5yXpBnIE~v8sAg,AAMC--8/test/0|test|test]). Nice")); + } + + @Test + public void httpLinkWithOpenedAndClosedParensEndsAtNextClosingParen() { + Iterable parts = soneTextParser.parse("Some text (and a link: http://example.sone/abc_(def)) – nice!", null); + assertThat("Parts", parts, notNullValue()); + assertThat("Part Text", convertText(parts, PlainTextPart.class, LinkPart.class), is("Some text (and a link: [http://example.sone/abc_(def)|example.sone/abc_(def)|example.sone/abc_(def)]) – nice!")); + } + + @Test + public void punctuationIsIgnoredAtEndOfLinkBeforeWhitespace() { + SoneTextParser soneTextParser = new SoneTextParser(null, null); + Iterable parts = soneTextParser.parse("Some text and a link: http://example.sone/abc. Nice!", null); + assertThat("Parts", parts, notNullValue()); + assertThat("Part Text", convertText(parts, PlainTextPart.class, LinkPart.class), is("Some text and a link: [http://example.sone/abc|example.sone/abc|example.sone/abc]. Nice!")); } - // - // PRIVATE METHODS - // + @Test + public void multiplePunctuationCharactersAreIgnoredAtEndOfLinkBeforeWhitespace() { + Iterable parts = soneTextParser.parse("Some text and a link: http://example.sone/abc... Nice!", null); + assertThat("Parts", parts, notNullValue()); + assertThat("Part Text", convertText(parts, PlainTextPart.class, LinkPart.class), is("Some text and a link: [http://example.sone/abc|example.sone/abc|example.sone/abc]... Nice!")); + } + + @Test + public void commasAreIgnoredAtEndOfLinkBeforeWhitespace() { + SoneTextParser soneTextParser = new SoneTextParser(null, null); + Iterable parts = soneTextParser.parse("Some text and a link: http://example.sone/abc, nice!", null); + assertThat("Parts", parts, notNullValue()); + assertThat("Part Text", convertText(parts, PlainTextPart.class, LinkPart.class), is("Some text and a link: [http://example.sone/abc|example.sone/abc|example.sone/abc], nice!")); + } /** * Converts all given {@link Part}s into a string, validating that the @@ -147,16 +331,9 @@ public class SoneTextParserTest extends TestCase { private static String convertText(Iterable parts, Class... validClasses) { StringBuilder text = new StringBuilder(); for (Part part : parts) { - assertNotNull("Part", part); - boolean classValid = validClasses.length == 0; - for (Class validClass : validClasses) { - if (validClass.isAssignableFrom(part.getClass())) { - classValid = true; - break; - } - } - if (!classValid) { - fail("Part’s Class (" + part.getClass() + ") is not one of " + Arrays.toString(validClasses)); + assertThat("Part", part, notNullValue()); + if (validClasses.length != 0) { + assertThat("Part’s class", part.getClass(), isIn(validClasses)); } if (part instanceof PlainTextPart) { text.append(((PlainTextPart) part).getText()); @@ -169,6 +346,9 @@ public class SoneTextParserTest extends TestCase { } else if (part instanceof SonePart) { SonePart sonePart = (SonePart) part; text.append("[Sone|").append(sonePart.getSone().getId()).append(']'); + } else if (part instanceof PostPart) { + PostPart postPart = (PostPart) part; + text.append("[Post|").append(postPart.getPost().getId()).append("|").append(postPart.getPost().getText()).append("]"); } } return text.toString(); @@ -225,4 +405,86 @@ public class SoneTextParserTest extends TestCase { } + private static class AbsentSoneProvider extends TestSoneProvider { + + @Override + public Optional getSone(String soneId) { + return Optional.absent(); + } + + } + + private static class TestPostProvider implements PostProvider { + + @Override + public Optional getPost(final String postId) { + return Optional.of(new Post() { + @Override + public String getId() { + return postId; + } + + @Override + public boolean isLoaded() { + return false; + } + + @Override + public Sone getSone() { + return null; + } + + @Override + public Optional getRecipientId() { + return null; + } + + @Override + public Optional getRecipient() { + return null; + } + + @Override + public long getTime() { + return 0; + } + + @Override + public String getText() { + return "text"; + } + + @Override + public boolean isKnown() { + return false; + } + + @Override + public Post setKnown(boolean known) { + return null; + } + }); + } + + @Override + public Collection getPosts(String soneId) { + return null; + } + + @Override + public Collection getDirectedPosts(String recipientId) { + return null; + } + + } + + private static class AbsentPostProvider extends TestPostProvider { + + @Override + public Optional getPost(String postId) { + return Optional.absent(); + } + + } + } diff --git a/src/test/java/net/pterodactylus/sone/web/AboutPageTest.java b/src/test/java/net/pterodactylus/sone/web/AboutPageTest.java new file mode 100644 index 0000000..df41e61 --- /dev/null +++ b/src/test/java/net/pterodactylus/sone/web/AboutPageTest.java @@ -0,0 +1,43 @@ +package net.pterodactylus.sone.web; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; + +import org.junit.Test; + +/** + * Unit test for {@link AboutPage}. + * + * @author David ‘Bombe’ Roden + */ +public class AboutPageTest extends WebPageTest { + + private final String version = "0.1.2"; + private final int year = 1234; + private final String homepage = "home://page"; + private final AboutPage page = new AboutPage(template, webInterface, version, year, homepage); + + @Test + public void pageReturnsCorrectPath() { + assertThat(page.getPath(), is("about.html")); + } + + @Test + public void pageSetsCorrectVersionInTemplateContext() throws Exception { + page.processTemplate(freenetRequest, templateContext); + assertThat(templateContext.get("version"), is((Object) version)); + } + + @Test + public void pageSetsCorrectHomepageInTemplateContext() throws Exception { + page.processTemplate(freenetRequest, templateContext); + assertThat(templateContext.get("homepage"), is((Object) homepage)); + } + + @Test + public void pageSetsCorrectYearInTemplateContext() throws Exception { + page.processTemplate(freenetRequest, templateContext); + assertThat(templateContext.get("year"), is((Object) year)); + } + +} diff --git a/src/test/java/net/pterodactylus/sone/web/BookmarkPageTest.java b/src/test/java/net/pterodactylus/sone/web/BookmarkPageTest.java new file mode 100644 index 0000000..ddba2c5 --- /dev/null +++ b/src/test/java/net/pterodactylus/sone/web/BookmarkPageTest.java @@ -0,0 +1,67 @@ +package net.pterodactylus.sone.web; + +import static net.pterodactylus.sone.web.WebTestUtils.redirectsTo; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; + +import net.pterodactylus.sone.data.Post; +import net.pterodactylus.util.web.Method; + +import org.junit.Test; + +/** + * Unit test for {@link BookmarkPage}. + * + * @author David ‘Bombe’ Roden + */ +public class BookmarkPageTest extends WebPageTest { + + private final BookmarkPage page = new BookmarkPage(template, webInterface); + + @Test + public void pathIsSetCorrectly() { + assertThat(page.getPath(), is("bookmark.html")); + } + + @Test + public void getRequestDoesNotBookmarkAnythingAndDoesNotRedirect() throws Exception { + page.processTemplate(freenetRequest, templateContext); + verify(core, never()).bookmarkPost(any(Post.class)); + } + + @Test + public void postIsBookmarkedCorrectly() throws Exception { + setupRequest(); + Post post = mock(Post.class); + addPost("post-id", post); + expectedException.expect(redirectsTo("return-page.html")); + try { + page.processTemplate(freenetRequest, templateContext); + } finally { + verify(core).bookmarkPost(post); + } + } + + private void setupRequest() { + request("", Method.POST); + addHttpRequestParameter("post", "post-id"); + addHttpRequestParameter("returnPage", "return-page.html"); + } + + @Test + public void nonExistentPostIsNotBookmarked() throws Exception { + setupRequest(); + addPost("post-id", null); + expectedException.expect(redirectsTo("return-page.html")); + try { + page.processTemplate(freenetRequest, templateContext); + } finally { + verify(core, never()).bookmarkPost(any(Post.class)); + } + } + +} diff --git a/src/test/java/net/pterodactylus/sone/web/BookmarksPageTest.java b/src/test/java/net/pterodactylus/sone/web/BookmarksPageTest.java new file mode 100644 index 0000000..46b0a18 --- /dev/null +++ b/src/test/java/net/pterodactylus/sone/web/BookmarksPageTest.java @@ -0,0 +1,78 @@ +package net.pterodactylus.sone.web; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.contains; +import static org.hamcrest.Matchers.is; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + +import net.pterodactylus.sone.data.Post; +import net.pterodactylus.sone.web.page.FreenetTemplatePage.RedirectException; +import net.pterodactylus.util.collection.Pagination; + +import org.junit.Test; + +/** + * Unit test for {@link BookmarksPage}. + * + * @author David ‘Bombe’ Roden + */ +public class BookmarksPageTest extends WebPageTest { + + private final BookmarksPage page = new BookmarksPage(template, webInterface); + + @Test + public void pageReturnsCorrectPath() { + assertThat(page.getPath(), is("bookmarks.html")); + } + + @Test + @SuppressWarnings("unchecked") + public void pageSetsCorrectPostsInTemplateContext() throws RedirectException { + Post post1 = createPost(true, 3000L); + Post post2 = createPost(true, 1000L); + Post post3 = createPost(true, 2000L); + Set bookmarkedPosts = createBookmarkedPosts(post1, post2, post3); + when(core.getBookmarkedPosts()).thenReturn(bookmarkedPosts); + when(core.getPreferences().getPostsPerPage()).thenReturn(5); + page.processTemplate(freenetRequest, templateContext); + assertThat((Collection) templateContext.get("posts"), contains(post1, post3, post2)); + assertThat(((Pagination) templateContext.get("pagination")).getItems(), contains(post1, post3, post2)); + assertThat(((Boolean) templateContext.get("postsNotLoaded")), is(false)); + } + + private Set createBookmarkedPosts(Post post1, Post post2, Post post3) { + Set bookmarkedPosts = new HashSet<>(); + bookmarkedPosts.add(post1); + bookmarkedPosts.add(post2); + bookmarkedPosts.add(post3); + return bookmarkedPosts; + } + + @Test + @SuppressWarnings("unchecked") + public void notLoadedPostsAreNotIncludedButAFlagIsSet() throws RedirectException { + Post post1 = createPost(true, 1000L); + Post post2 = createPost(true, 3000L); + Post post3 = createPost(false, 2000L); + Set bookmarkedPosts = createBookmarkedPosts(post1, post2, post3); + when(core.getBookmarkedPosts()).thenReturn(bookmarkedPosts); + when(core.getPreferences().getPostsPerPage()).thenReturn(5); + page.processTemplate(freenetRequest, templateContext); + assertThat((Collection) templateContext.get("posts"), contains(post2, post1)); + assertThat(((Pagination) templateContext.get("pagination")).getItems(), contains(post2, post1)); + assertThat(((Boolean) templateContext.get("postsNotLoaded")), is(true)); + } + + private Post createPost(boolean postLoaded, long time) { + Post post = mock(Post.class); + when(post.isLoaded()).thenReturn(postLoaded); + when(post.getTime()).thenReturn(time); + return post; + } + +} diff --git a/src/test/java/net/pterodactylus/sone/web/CreateAlbumPageTest.java b/src/test/java/net/pterodactylus/sone/web/CreateAlbumPageTest.java new file mode 100644 index 0000000..da0ec0c --- /dev/null +++ b/src/test/java/net/pterodactylus/sone/web/CreateAlbumPageTest.java @@ -0,0 +1,105 @@ +package net.pterodactylus.sone.web; + +import static net.pterodactylus.sone.web.WebTestUtils.redirectsTo; +import static net.pterodactylus.util.web.Method.POST; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.mockito.Answers.RETURNS_DEEP_STUBS; +import static org.mockito.Answers.RETURNS_SELF; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import net.pterodactylus.sone.data.Album; +import net.pterodactylus.sone.data.Album.Modifier; +import net.pterodactylus.sone.data.Album.Modifier.AlbumTitleMustNotBeEmpty; +import net.pterodactylus.sone.test.Dirty; + +import org.junit.Test; + +/** + * Unit test for {@link CreateAlbumPage}. + * + * @author David ‘Bombe’ Roden + */ +public class CreateAlbumPageTest extends WebPageTest { + + private final CreateAlbumPage page = new CreateAlbumPage(template, webInterface); + + @Test + public void pageReturnsCorrectPath() { + assertThat(page.getPath(), is("createAlbum.html")); + } + + @Test + public void getRequestShowsTemplate() throws Exception { + page.processTemplate(freenetRequest, templateContext); + } + + @Test + public void missingNameResultsInAttributeSetInTemplateContext() throws Exception { + request("", POST); + page.processTemplate(freenetRequest, templateContext); + assertThat(templateContext.get("nameMissing"), is((Object) true)); + } + + @Test + public void titleAndDescriptionAreSetCorrectlyOnTheAlbum() throws Exception { + request("", POST); + Album parentAlbum = createAlbum("parent-id"); + when(core.getAlbum("parent-id")).thenReturn(parentAlbum); + Album newAlbum = createAlbum("album-id"); + when(core.createAlbum(currentSone, parentAlbum)).thenReturn(newAlbum); + addHttpRequestParameter("name", "new name"); + addHttpRequestParameter("description", "new description"); + addHttpRequestParameter("parent", "parent-id"); + expectedException.expect(redirectsTo("imageBrowser.html?album=album-id")); + try { + page.processTemplate(freenetRequest, templateContext); + } finally { + verify(newAlbum).modify(); + verify(newAlbum.modify()).setTitle("new name"); + verify(newAlbum.modify()).setDescription("new description"); + verify(newAlbum.modify()).update(); + verify(core).touchConfiguration(); + } + } + + private Album createAlbum(String albumId) { + Album newAlbum = mock(Album.class, RETURNS_DEEP_STUBS); + when(newAlbum.getId()).thenReturn(albumId); + Modifier albumModifier = mock(Modifier.class, RETURNS_SELF); + when(newAlbum.modify()).thenReturn(albumModifier); + when(albumModifier.update()).thenReturn(newAlbum); + return newAlbum; + } + + @Test + public void rootAlbumIsUsedIfNoParentIsSpecified() throws Exception { + request("", POST); + Album parentAlbum = createAlbum("root-id"); + when(currentSone.getRootAlbum()).thenReturn(parentAlbum); + Album newAlbum = createAlbum("album-id"); + when(core.createAlbum(currentSone, parentAlbum)).thenReturn(newAlbum); + addHttpRequestParameter("name", "new name"); + addHttpRequestParameter("description", "new description"); + expectedException.expect(redirectsTo("imageBrowser.html?album=album-id")); + page.processTemplate(freenetRequest, templateContext); + } + + @Test + @Dirty("that exception can never happen") + public void emptyAlbumTitleRedirectsToErrorPage() throws Exception { + request("", POST); + Album parentAlbum = createAlbum("root-id"); + when(currentSone.getRootAlbum()).thenReturn(parentAlbum); + Album newAlbum = createAlbum("album-id"); + when(core.createAlbum(currentSone, parentAlbum)).thenReturn(newAlbum); + when(newAlbum.modify().update()).thenThrow(AlbumTitleMustNotBeEmpty.class); + addHttpRequestParameter("name", "new name"); + addHttpRequestParameter("description", "new description"); + expectedException.expect(redirectsTo("emptyAlbumTitle.html")); + page.processTemplate(freenetRequest, templateContext); + } + +} diff --git a/src/test/java/net/pterodactylus/sone/web/CreatePostPageTest.java b/src/test/java/net/pterodactylus/sone/web/CreatePostPageTest.java new file mode 100644 index 0000000..2a91086 --- /dev/null +++ b/src/test/java/net/pterodactylus/sone/web/CreatePostPageTest.java @@ -0,0 +1,89 @@ +package net.pterodactylus.sone.web; + +import static net.pterodactylus.util.web.Method.POST; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +import net.pterodactylus.sone.data.Sone; + +import com.google.common.base.Optional; +import org.junit.Test; + +/** + * Unit test for {@link CreatePostPage}. + * + * @author David ‘Bombe’ Roden + */ +public class CreatePostPageTest extends WebPageTest { + + private final CreatePostPage page = new CreatePostPage(template, webInterface); + + @Test + public void pageReturnsCorrectPath() { + assertThat(page.getPath(), is("createPost.html")); + } + + @Test + public void returnPageIsSetInTemplateContext() throws Exception { + addHttpRequestParameter("returnPage", "returnPage.html"); + page.processTemplate(freenetRequest, templateContext); + assertThat(templateContext.get("returnPage"), is((Object) "returnPage.html")); + } + + @Test + public void postIsCreatedCorrectly() throws Exception { + addHttpRequestParameter("returnPage", "returnPage.html"); + addHttpRequestParameter("text", "post text"); + request("", POST); + expectedException.expect(WebTestUtils.redirectsTo("returnPage.html")); + try { + page.processTemplate(freenetRequest, templateContext); + } finally { + verify(core).createPost(currentSone, Optional.absent(), "post text"); + } + } + + @Test + public void creatingAnEmptyPostIsDenied() throws Exception { + addHttpRequestParameter("returnPage", "returnPage.html"); + addHttpRequestParameter("text", " "); + request("", POST); + page.processTemplate(freenetRequest, templateContext); + assertThat(templateContext.get("errorTextEmpty"), is((Object) true)); + } + + @Test + public void aSenderCanBeSelected() throws Exception { + addHttpRequestParameter("returnPage", "returnPage.html"); + addHttpRequestParameter("text", "post text"); + addHttpRequestParameter("sender", "sender-id"); + Sone sender = mock(Sone.class); + addLocalSone("sender-id", sender); + request("", POST); + expectedException.expect(WebTestUtils.redirectsTo("returnPage.html")); + try { + page.processTemplate(freenetRequest, templateContext); + } finally { + verify(core).createPost(sender, Optional.absent(), "post text"); + } + } + + @Test + public void aRecipientCanBeSelected() throws Exception { + addHttpRequestParameter("returnPage", "returnPage.html"); + addHttpRequestParameter("text", "post text"); + addHttpRequestParameter("recipient", "recipient-id"); + Sone recipient = mock(Sone.class); + addSone("recipient-id", recipient); + request("", POST); + expectedException.expect(WebTestUtils.redirectsTo("returnPage.html")); + try { + page.processTemplate(freenetRequest, templateContext); + } finally { + verify(core).createPost(currentSone, Optional.of(recipient), "post text"); + } + } + +} diff --git a/src/test/java/net/pterodactylus/sone/web/CreateReplyPageTest.java b/src/test/java/net/pterodactylus/sone/web/CreateReplyPageTest.java new file mode 100644 index 0000000..996f5c0 --- /dev/null +++ b/src/test/java/net/pterodactylus/sone/web/CreateReplyPageTest.java @@ -0,0 +1,107 @@ +package net.pterodactylus.sone.web; + +import static net.pterodactylus.sone.web.WebTestUtils.redirectsTo; +import static net.pterodactylus.util.web.Method.GET; +import static net.pterodactylus.util.web.Method.POST; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; + +import net.pterodactylus.sone.data.Post; +import net.pterodactylus.sone.data.Sone; + +import org.junit.Test; + +/** + * Unit test for {@link CreateReplyPageTest}. + * + * @author David ‘Bombe’ Roden + */ +public class CreateReplyPageTest extends WebPageTest { + + private final CreateReplyPage page = new CreateReplyPage(template, webInterface); + + @Test + public void pageReturnsCorrectPath() { + assertThat(page.getPath(), is("createReply.html")); + } + + @Test + public void replyIsCreatedCorrectly() throws Exception { + request("", POST); + addHttpRequestParameter("post", "post-id"); + addHttpRequestParameter("text", "some text"); + addHttpRequestParameter("returnPage", "returnPage.html"); + Post post = mock(Post.class); + addPost("post-id", post); + expectedException.expect(redirectsTo("returnPage.html")); + try { + page.processTemplate(freenetRequest, templateContext); + } finally { + verify(core).createReply(currentSone, post, "some text"); + } + } + + @Test + public void replyIsCreatedWithCorrectSender() throws Exception { + request("", POST); + addHttpRequestParameter("post", "post-id"); + addHttpRequestParameter("text", "some text"); + addHttpRequestParameter("returnPage", "returnPage.html"); + addHttpRequestParameter("sender", "sender-id"); + Sone sender = mock(Sone.class); + addLocalSone("sender-id", sender); + Post post = mock(Post.class); + addPost("post-id", post); + expectedException.expect(redirectsTo("returnPage.html")); + try { + page.processTemplate(freenetRequest, templateContext); + } finally { + verify(core).createReply(sender, post, "some text"); + } + } + + @Test + public void emptyTextSetsVariableInTemplateContext() throws Exception { + request("", POST); + addPost("post-id", mock(Post.class)); + addHttpRequestParameter("post", "post-id"); + addHttpRequestParameter("text", " "); + addHttpRequestParameter("returnPage", "returnPage.html"); + page.processTemplate(freenetRequest, templateContext); + assertThat(templateContext.get("errorTextEmpty", Boolean.class), is(true)); + verifyParametersAreCopied(""); + verify(core, never()).createReply(any(Sone.class), any(Post.class), anyString()); + } + + private void verifyParametersAreCopied(String text) { + assertThat(templateContext.get("postId", String.class), is("post-id")); + assertThat(templateContext.get("text", String.class), is(text)); + assertThat(templateContext.get("returnPage", String.class), is("returnPage.html")); + } + + @Test + public void userIsRedirectIfPostDoesNotExist() throws Exception { + request("", POST); + addHttpRequestParameter("post", "post-id"); + addHttpRequestParameter("text", "some text"); + addHttpRequestParameter("returnPage", "returnPage.html"); + expectedException.expect(redirectsTo("noPermission.html")); + page.processTemplate(freenetRequest, templateContext); + } + + @Test + public void getRequestServesTemplateAndStoresParameters() throws Exception { + request("", GET); + addHttpRequestParameter("post", "post-id"); + addHttpRequestParameter("text", "some text"); + addHttpRequestParameter("returnPage", "returnPage.html"); + page.processTemplate(freenetRequest, templateContext); + verifyParametersAreCopied("some text"); + } + +} diff --git a/src/test/java/net/pterodactylus/sone/web/CreateSonePageTest.java b/src/test/java/net/pterodactylus/sone/web/CreateSonePageTest.java new file mode 100644 index 0000000..aab40c9 --- /dev/null +++ b/src/test/java/net/pterodactylus/sone/web/CreateSonePageTest.java @@ -0,0 +1,167 @@ +package net.pterodactylus.sone.web; + +import static net.pterodactylus.sone.web.WebTestUtils.redirectsTo; +import static net.pterodactylus.util.web.Method.POST; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.contains; +import static org.hamcrest.Matchers.is; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; + +import net.pterodactylus.sone.data.Profile; +import net.pterodactylus.sone.data.Sone; +import net.pterodactylus.sone.freenet.wot.OwnIdentity; + +import org.junit.Test; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; + +/** + * Unit test for {@link CreateSonePage}. + * + * @author David ‘Bombe’ Roden + */ +public class CreateSonePageTest extends WebPageTest { + + private final CreateSonePage page = new CreateSonePage(template, webInterface); + private final Sone[] localSones = { createSone("local-sone1"), createSone("local-sone2"), createSone("local-sone3") }; + private final OwnIdentity[] ownIdentities = { + createOwnIdentity("own-id-1", "Sone"), + createOwnIdentity("own-id-2", "Test", "Foo"), + createOwnIdentity("own-id-3"), + createOwnIdentity("own-id-4", "Sone") + }; + + @Test + public void pageReturnsCorrectPath() { + assertThat(page.getPath(), is("createSone.html")); + } + + @Test + @SuppressWarnings("unchecked") + public void getRequestStoresListOfIdentitiesInTemplateContext() throws Exception { + addDefaultLocalSones(); + addDefaultOwnIdentities(); + page.processTemplate(freenetRequest, templateContext); + assertThat((Collection) templateContext.get("sones"), contains(localSones[0], localSones[1], localSones[2])); + assertThat((Collection) templateContext.get("identitiesWithoutSone"), contains(ownIdentities[1], ownIdentities[2])); + } + + private void addDefaultLocalSones() { + addLocalSone("local-sone3", localSones[2]); + addLocalSone("local-sone1", localSones[0]); + addLocalSone("local-sone2", localSones[1]); + } + + private void addDefaultOwnIdentities() { + addOwnIdentity(ownIdentities[2]); + addOwnIdentity(ownIdentities[0]); + addOwnIdentity(ownIdentities[3]); + addOwnIdentity(ownIdentities[1]); + } + + private Sone createSone(String id) { + Sone sone = mock(Sone.class); + when(sone.getId()).thenReturn(id); + when(sone.getProfile()).thenReturn(new Profile(sone)); + return sone; + } + + private OwnIdentity createOwnIdentity(String id, final String... contexts) { + OwnIdentity ownIdentity = mock(OwnIdentity.class); + when(ownIdentity.getId()).thenReturn(id); + when(ownIdentity.getNickname()).thenReturn(id); + when(ownIdentity.getContexts()).thenReturn(new HashSet<>(Arrays.asList(contexts))); + when(ownIdentity.hasContext(anyString())).thenAnswer(new Answer() { + @Override + public Boolean answer(InvocationOnMock invocation) throws Throwable { + return Arrays.asList(contexts).contains(invocation.getArgument(0)); + } + }); + return ownIdentity; + } + + @Test + public void soneIsCreatedAndLoggedIn() throws Exception { + addDefaultLocalSones(); + addDefaultOwnIdentities(); + addHttpRequestParameter("identity", "own-id-3"); + request("", POST); + Sone newSone = mock(Sone.class); + when(core.createSone(ownIdentities[2])).thenReturn(newSone); + expectedException.expect(redirectsTo("index.html")); + try { + page.processTemplate(freenetRequest, templateContext); + } finally { + verify(core).createSone(ownIdentities[2]); + verify(webInterface).setCurrentSone(toadletContext, newSone); + } + } + + @Test + public void onInvalidIdentityIdFlagIsStoredInTemplateContext() throws Exception { + addDefaultLocalSones(); + addDefaultOwnIdentities(); + addHttpRequestParameter("identity", "own-id-invalid"); + request("", POST); + page.processTemplate(freenetRequest, templateContext); + assertThat(((Boolean) templateContext.get("errorNoIdentity")), is(true)); + } + + @Test + public void ifSoneIsNotCreatedUserIsStillRedirectedToIndex() throws Exception { + addDefaultLocalSones(); + addDefaultOwnIdentities(); + addHttpRequestParameter("identity", "own-id-3"); + request("", POST); + when(core.createSone(ownIdentities[2])).thenReturn(null); + expectedException.expect(redirectsTo("index.html")); + try { + page.processTemplate(freenetRequest, templateContext); + } finally { + verify(core).createSone(ownIdentities[2]); + verify(webInterface).setCurrentSone(toadletContext, null); + } + } + + @Test + public void doNotShowCreateSoneInMenuIfFullAccessRequiredButClientHasNoFullAccess() { + when(core.getPreferences().isRequireFullAccess()).thenReturn(true); + when(toadletContext.isAllowedFullAccess()).thenReturn(false); + assertThat(page.isEnabled(toadletContext), is(false)); + } + + @Test + public void showCreateSoneInMenuIfNotLoggedInAndClientHasFullAccess() { + when(core.getPreferences().isRequireFullAccess()).thenReturn(true); + when(toadletContext.isAllowedFullAccess()).thenReturn(true); + unsetCurrentSone(); + assertThat(page.isEnabled(toadletContext), is(true)); + } + + @Test + public void showCreateSoneInMenuIfNotLoggedIn() { + unsetCurrentSone(); + assertThat(page.isEnabled(toadletContext), is(true)); + } + + @Test + public void showCreateSoneInMenuIfLoggedInAndASingleSoneExists() { + addLocalSone("local-sone", mock(Sone.class)); + assertThat(page.isEnabled(toadletContext), is(true)); + } + + @Test + public void doNotShowCreateSoneInMenuIfLoggedInAndMoreLocalSonesExists() { + addLocalSone("local-sone1", mock(Sone.class)); + addLocalSone("local-sone2", mock(Sone.class)); + assertThat(page.isEnabled(toadletContext), is(false)); + } + +} diff --git a/src/test/java/net/pterodactylus/sone/web/DeleteReplyPageTest.java b/src/test/java/net/pterodactylus/sone/web/DeleteReplyPageTest.java index 80c8a2f..88c87a1 100644 --- a/src/test/java/net/pterodactylus/sone/web/DeleteReplyPageTest.java +++ b/src/test/java/net/pterodactylus/sone/web/DeleteReplyPageTest.java @@ -1,61 +1,28 @@ package net.pterodactylus.sone.web; import static net.pterodactylus.sone.web.WebTestUtils.redirectsTo; -import static org.mockito.Matchers.anyInt; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.RETURNS_DEEP_STUBS; -import static org.mockito.Mockito.mock; +import static net.pterodactylus.util.web.Method.POST; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.when; -import java.util.Collections; - import net.pterodactylus.sone.data.PostReply; -import net.pterodactylus.sone.data.Sone; -import net.pterodactylus.sone.web.page.FreenetRequest; -import net.pterodactylus.util.notify.Notification; -import net.pterodactylus.util.template.Template; -import net.pterodactylus.util.template.TemplateContext; -import net.pterodactylus.util.web.Method; - -import freenet.support.api.HTTPRequest; import com.google.common.base.Optional; -import org.junit.Before; -import org.junit.Rule; import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.mockito.Matchers; /** * Unit test for {@link DeleteReplyPage}. * * @author David ‘Bombe’ Roden */ -public class DeleteReplyPageTest { +public class DeleteReplyPageTest extends WebPageTest { - @Rule - public final ExpectedException expectedException = ExpectedException.none(); - - private final Template template = new Template(); - private final WebInterface webInterface = mock(WebInterface.class, RETURNS_DEEP_STUBS); private final DeleteReplyPage page = new DeleteReplyPage(template, webInterface); - private final TemplateContext templateContext = new TemplateContext(); - private final FreenetRequest freenetRequest = mock(FreenetRequest.class); - private final HTTPRequest httpRequest = mock(HTTPRequest.class); - - @Before - public void setupWebInterface() { - when(webInterface.getNotifications(Matchers.any(Sone.class))).thenReturn(Collections.emptyList()); - } - - @Before - public void setupHttpRequest() { - when(freenetRequest.getHttpRequest()).thenReturn(httpRequest); - } @Test public void tryingToDeleteAReplyWithAnInvalidIdResultsInNoPermissionPage() throws Exception { - when(freenetRequest.getMethod()).thenReturn(Method.POST); + request("", POST); when(httpRequest.getPartAsStringFailsafe(eq("reply"), anyInt())).thenReturn("id"); when(webInterface.getCore().getPostReply("id")).thenReturn(Optional.absent()); expectedException.expect(redirectsTo("noPermission.html")); diff --git a/src/test/java/net/pterodactylus/sone/web/NewPageTest.java b/src/test/java/net/pterodactylus/sone/web/NewPageTest.java index b527e58..e110969 100644 --- a/src/test/java/net/pterodactylus/sone/web/NewPageTest.java +++ b/src/test/java/net/pterodactylus/sone/web/NewPageTest.java @@ -3,24 +3,13 @@ package net.pterodactylus.sone.web; import static java.util.Arrays.asList; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsInAnyOrder; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyBoolean; -import static org.mockito.Mockito.RETURNS_DEEP_STUBS; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -import java.util.Collections; import java.util.List; import net.pterodactylus.sone.data.Post; import net.pterodactylus.sone.data.PostReply; -import net.pterodactylus.sone.data.Sone; -import net.pterodactylus.sone.web.page.FreenetRequest; -import net.pterodactylus.util.notify.Notification; -import net.pterodactylus.util.template.Template; -import net.pterodactylus.util.template.TemplateContext; - -import freenet.clients.http.ToadletContext; import com.google.common.base.Optional; import org.junit.Before; @@ -31,25 +20,13 @@ import org.junit.Test; * * @author David ‘Bombe’ Roden */ -public class NewPageTest { +public class NewPageTest extends WebPageTest { - private final Template template = mock(Template.class); - private final WebInterface webInterface = mock(WebInterface.class, RETURNS_DEEP_STUBS); private final NewPage newPage = new NewPage(template, webInterface); - private final Sone currentSone = mock(Sone.class); - private final TemplateContext templateContext = new TemplateContext(); - private final FreenetRequest freenetRequest = mock(FreenetRequest.class, RETURNS_DEEP_STUBS); - - @Before - public void setupFreenetRequest() { - when(freenetRequest.getToadletContext()).thenReturn(mock(ToadletContext.class)); - } @Before - public void setupWebInterface() { + public void setupNumberOfPostsPerPage() { when(webInterface.getCore().getPreferences().getPostsPerPage()).thenReturn(5); - when(webInterface.getCurrentSone(any(ToadletContext.class), anyBoolean())).thenReturn(currentSone); - when(webInterface.getNotifications(any(Sone.class))).thenReturn(Collections.emptyList()); } @Test diff --git a/src/test/java/net/pterodactylus/sone/web/UploadImagePageTest.java b/src/test/java/net/pterodactylus/sone/web/UploadImagePageTest.java index e74efbd..3b8258e 100644 --- a/src/test/java/net/pterodactylus/sone/web/UploadImagePageTest.java +++ b/src/test/java/net/pterodactylus/sone/web/UploadImagePageTest.java @@ -1,61 +1,29 @@ package net.pterodactylus.sone.web; import static net.pterodactylus.sone.web.WebTestUtils.redirectsTo; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyInt; -import static org.mockito.Matchers.eq; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -import java.net.URI; - -import net.pterodactylus.sone.core.Core; -import net.pterodactylus.sone.core.UpdateChecker; import net.pterodactylus.sone.data.Album; -import net.pterodactylus.sone.data.Sone; -import net.pterodactylus.sone.web.page.FreenetRequest; -import net.pterodactylus.util.template.Template; -import net.pterodactylus.util.template.TemplateContext; import net.pterodactylus.util.web.Method; -import freenet.clients.http.ToadletContext; -import freenet.support.api.HTTPRequest; - import org.junit.Before; -import org.junit.Rule; import org.junit.Test; -import org.junit.rules.ExpectedException; /** * Unit test for {@link UploadImagePageTest}. * * @author David ‘Bombe’ Roden */ -public class UploadImagePageTest { - - @Rule - public final ExpectedException expectedException = ExpectedException.none(); +public class UploadImagePageTest extends WebPageTest { - private final Template template = new Template(); - private final WebInterface webInterface = mock(WebInterface.class); private final UploadImagePage uploadImagePage = new UploadImagePage(template, webInterface); - private final TemplateContext templateContext = new TemplateContext(); - private final HTTPRequest httpRequest = mock(HTTPRequest.class); - private final ToadletContext toadletContext = mock(ToadletContext.class); - private final Core core = mock(Core.class); - private final Sone currentSone = mock(Sone.class); private final Album parentAlbum = mock(Album.class); @Before - public void setupWebInterface() { - UpdateChecker updateChecker = mock(UpdateChecker.class); - when(core.getUpdateChecker()).thenReturn(updateChecker); - when(webInterface.getCore()).thenReturn(core); - when(webInterface.getCurrentSone(any(ToadletContext.class))).thenReturn(currentSone); - } - - @Before public void setupParentAlbum() { when(core.getAlbum("parent-id")).thenReturn(parentAlbum); when(parentAlbum.getSone()).thenReturn(currentSone); @@ -63,11 +31,11 @@ public class UploadImagePageTest { @Test public void uploadingAnImageWithoutTitleRedirectsToEmptyImageTitlePage() throws Exception { - FreenetRequest request = new FreenetRequest(new URI(""), Method.POST, httpRequest, toadletContext); + request("", Method.POST); when(httpRequest.getPartAsStringFailsafe(eq("parent"), anyInt())).thenReturn("parent-id"); when(httpRequest.getPartAsStringFailsafe(eq("title"), anyInt())).thenReturn(" "); expectedException.expect(redirectsTo("emptyImageTitle.html")); - uploadImagePage.processTemplate(request, templateContext); + uploadImagePage.processTemplate(freenetRequest, templateContext); } } diff --git a/src/test/java/net/pterodactylus/sone/web/WebPageTest.java b/src/test/java/net/pterodactylus/sone/web/WebPageTest.java new file mode 100644 index 0000000..3e2df88 --- /dev/null +++ b/src/test/java/net/pterodactylus/sone/web/WebPageTest.java @@ -0,0 +1,138 @@ +package net.pterodactylus.sone.web; + +import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.RETURNS_DEEP_STUBS; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import net.pterodactylus.sone.core.Core; +import net.pterodactylus.sone.core.UpdateChecker; +import net.pterodactylus.sone.data.Post; +import net.pterodactylus.sone.data.Sone; +import net.pterodactylus.sone.freenet.wot.OwnIdentity; +import net.pterodactylus.sone.web.page.FreenetRequest; +import net.pterodactylus.util.notify.Notification; +import net.pterodactylus.util.template.Template; +import net.pterodactylus.util.template.TemplateContext; +import net.pterodactylus.util.web.Method; + +import freenet.clients.http.ToadletContext; +import freenet.support.api.HTTPRequest; + +import com.google.common.base.Optional; +import org.junit.Before; +import org.junit.Rule; +import org.junit.rules.ExpectedException; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; + +/** + * Base class for web page tests. + * + * @author David ‘Bombe’ Roden + */ +public abstract class WebPageTest { + + @Rule + public final ExpectedException expectedException = ExpectedException.none(); + + protected final Template template = new Template(); + protected final WebInterface webInterface = mock(WebInterface.class, RETURNS_DEEP_STUBS); + protected final Core core = webInterface.getCore(); + + protected final Sone currentSone = mock(Sone.class); + + protected final TemplateContext templateContext = new TemplateContext(); + protected final HTTPRequest httpRequest = mock(HTTPRequest.class); + protected final FreenetRequest freenetRequest = mock(FreenetRequest.class); + protected final ToadletContext toadletContext = mock(ToadletContext.class); + + private final Set ownIdentities = new HashSet<>(); + private final List localSones = new ArrayList<>(); + + @Before + public final void setupFreenetRequest() { + when(freenetRequest.getToadletContext()).thenReturn(toadletContext); + when(freenetRequest.getHttpRequest()).thenReturn(httpRequest); + when(httpRequest.getPartAsStringFailsafe(anyString(), anyInt())).thenAnswer(new Answer() { + @Override + public String answer(InvocationOnMock invocation) throws Throwable { + return ""; + } + }); + } + + @Before + public final void setupCore() { + UpdateChecker updateChecker = mock(UpdateChecker.class); + when(core.getUpdateChecker()).thenReturn(updateChecker); + when(core.getLocalSone(anyString())).thenReturn(null); + when(core.getLocalSones()).thenReturn(localSones); + when(core.getSone(anyString())).thenReturn(Optional.absent()); + when(core.getPost(anyString())).thenReturn(Optional.absent()); + } + + @Before + public final void setupIdentityManager() { + when(core.getIdentityManager().getAllOwnIdentities()).thenReturn(ownIdentities); + } + + @Before + public final void setupWebInterface() { + when(webInterface.getCurrentSone(toadletContext)).thenReturn(currentSone); + when(webInterface.getCurrentSone(eq(toadletContext), anyBoolean())).thenReturn(currentSone); + when(webInterface.getNotifications(currentSone)).thenReturn(new ArrayList()); + } + + protected void unsetCurrentSone() { + when(webInterface.getCurrentSone(toadletContext)).thenReturn(null); + when(webInterface.getCurrentSone(eq(toadletContext), anyBoolean())).thenReturn(null); + } + + protected void request(String uri, Method method) { + try { + when(freenetRequest.getUri()).thenReturn(new URI(uri)); + } catch (URISyntaxException e) { + throw new RuntimeException(e); + } + when(freenetRequest.getMethod()).thenReturn(method); + } + + protected void addHttpRequestParameter(String name, final String value) { + when(httpRequest.getPartAsStringFailsafe(eq(name), anyInt())).thenAnswer(new Answer() { + @Override + public String answer(InvocationOnMock invocation) throws Throwable { + int maxLength = invocation.getArgument(1); + return value.substring(0, Math.min(maxLength, value.length())); + } + }); + } + + protected void addPost(String postId, Post post) { + when(core.getPost(postId)).thenReturn(Optional.fromNullable(post)); + } + + protected void addSone(String soneId, Sone sone) { + when(core.getSone(eq(soneId))).thenReturn(Optional.fromNullable(sone)); + } + + protected void addLocalSone(String soneId, Sone sone) { + when(core.getLocalSone(eq(soneId))).thenReturn(sone); + localSones.add(sone); + } + + protected void addOwnIdentity(OwnIdentity ownIdentity) { + ownIdentities.add(ownIdentity); + } + +} diff --git a/src/test/java/net/pterodactylus/sone/web/ajax/BookmarkAjaxPageTest.java b/src/test/java/net/pterodactylus/sone/web/ajax/BookmarkAjaxPageTest.java index 5f2025f..d7c2053 100644 --- a/src/test/java/net/pterodactylus/sone/web/ajax/BookmarkAjaxPageTest.java +++ b/src/test/java/net/pterodactylus/sone/web/ajax/BookmarkAjaxPageTest.java @@ -8,12 +8,9 @@ import static com.google.common.base.Optional.of; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.notNullValue; import static org.junit.Assert.assertThat; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyString; -import static org.mockito.Matchers.argThat; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; -import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; diff --git a/src/test/java/net/pterodactylus/sone/web/page/FreenetRequestTest.java b/src/test/java/net/pterodactylus/sone/web/page/FreenetRequestTest.java new file mode 100644 index 0000000..ac01e51 --- /dev/null +++ b/src/test/java/net/pterodactylus/sone/web/page/FreenetRequestTest.java @@ -0,0 +1,54 @@ +package net.pterodactylus.sone.web.page; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.mockito.Mockito.mock; + +import java.net.URI; +import java.net.URISyntaxException; + +import net.pterodactylus.util.web.Method; + +import freenet.clients.http.ToadletContext; +import freenet.support.api.HTTPRequest; + +import org.junit.Test; + +/** + * Unit test for {@link FreenetRequest}. + * + * @author David ‘Bombe’ Roden + */ +public class FreenetRequestTest { + + private final URI uri = new URI("."); + private final Method method = Method.GET; + private final HTTPRequest httpRequest = mock(HTTPRequest.class); + private final ToadletContext toadletContext = mock(ToadletContext.class); + private final FreenetRequest request = new FreenetRequest(uri, method, httpRequest, toadletContext); + + @SuppressWarnings("unused") + public FreenetRequestTest() throws URISyntaxException { + } + + @Test + public void uriIsRetainedCorrectly() { + assertThat(request.getUri(), is(uri)); + } + + @Test + public void methodIsRetainedCorrectly() { + assertThat(request.getMethod(), is(method)); + } + + @Test + public void httpRequestIsRetainedCorrectly() { + assertThat(request.getHttpRequest(), is(httpRequest)); + } + + @Test + public void toadletContextIsRetainedCorrectly() { + assertThat(request.getToadletContext(), is(toadletContext)); + } + +} diff --git a/template.txt b/template.txt deleted file mode 100644 index a26591c..0000000 --- a/template.txt +++ /dev/null @@ -1 +0,0 @@ -<%if foo>foo<%else>bar<%/if> \ No newline at end of file