--- /dev/null
+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'
--- /dev/null
+#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
--- /dev/null
+#!/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 "$@"
--- /dev/null
+@if "%DEBUG%" == "" @echo off\r
+@rem ##########################################################################\r
+@rem\r
+@rem Gradle startup script for Windows\r
+@rem\r
+@rem ##########################################################################\r
+\r
+@rem Set local scope for the variables with windows NT shell\r
+if "%OS%"=="Windows_NT" setlocal\r
+\r
+set DIRNAME=%~dp0\r
+if "%DIRNAME%" == "" set DIRNAME=.\r
+set APP_BASE_NAME=%~n0\r
+set APP_HOME=%DIRNAME%\r
+\r
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\r
+set DEFAULT_JVM_OPTS=\r
+\r
+@rem Find java.exe\r
+if defined JAVA_HOME goto findJavaFromJavaHome\r
+\r
+set JAVA_EXE=java.exe\r
+%JAVA_EXE% -version >NUL 2>&1\r
+if "%ERRORLEVEL%" == "0" goto init\r
+\r
+echo.\r
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\r
+echo.\r
+echo Please set the JAVA_HOME variable in your environment to match the\r
+echo location of your Java installation.\r
+\r
+goto fail\r
+\r
+:findJavaFromJavaHome\r
+set JAVA_HOME=%JAVA_HOME:"=%\r
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe\r
+\r
+if exist "%JAVA_EXE%" goto init\r
+\r
+echo.\r
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\r
+echo.\r
+echo Please set the JAVA_HOME variable in your environment to match the\r
+echo location of your Java installation.\r
+\r
+goto fail\r
+\r
+:init\r
+@rem Get command-line arguments, handling Windows variants\r
+\r
+if not "%OS%" == "Windows_NT" goto win9xME_args\r
+\r
+:win9xME_args\r
+@rem Slurp the command line arguments.\r
+set CMD_LINE_ARGS=\r
+set _SKIP=2\r
+\r
+:win9xME_args_slurp\r
+if "x%~1" == "x" goto execute\r
+\r
+set CMD_LINE_ARGS=%*\r
+\r
+:execute\r
+@rem Setup the command line\r
+\r
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar\r
+\r
+@rem Execute Gradle\r
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%\r
+\r
+:end\r
+@rem End local scope for the variables with windows NT shell\r
+if "%ERRORLEVEL%"=="0" goto mainEnd\r
+\r
+:fail\r
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\r
+rem the _cmd.exe /c_ return code!\r
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1\r
+exit /b 1\r
+\r
+:mainEnd\r
+if "%OS%"=="Windows_NT" endlocal\r
+\r
+:omega\r
+++ /dev/null
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <groupId>net.pterodactylus</groupId>
- <artifactId>sone</artifactId>
- <version>0.9.5</version>
- <dependencies>
- <dependency>
- <groupId>net.pterodactylus</groupId>
- <artifactId>utils</artifactId>
- <version>${version.utils}</version>
- </dependency>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>4.11</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.mockito</groupId>
- <artifactId>mockito-all</artifactId>
- <version>1.9.5</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.hamcrest</groupId>
- <artifactId>hamcrest-all</artifactId>
- <version>1.3</version>
- </dependency>
- <dependency>
- <groupId>org.jsoup</groupId>
- <artifactId>jsoup</artifactId>
- <version>1.7.1</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.freenetproject</groupId>
- <artifactId>fred</artifactId>
- <version>0.7.5.1467.99.3</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.freenetproject</groupId>
- <artifactId>freenet-ext</artifactId>
- <version>29</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>com.google.inject</groupId>
- <artifactId>guice</artifactId>
- <version>3.0</version>
- </dependency>
- <dependency>
- <groupId>com.google.guava</groupId>
- <artifactId>guava</artifactId>
- <version>14.0.1</version>
- </dependency>
- <dependency>
- <groupId>commons-lang</groupId>
- <artifactId>commons-lang</artifactId>
- <version>2.6</version>
- </dependency>
- <dependency>
- <groupId>com.fasterxml.jackson.core</groupId>
- <artifactId>jackson-databind</artifactId>
- <version>2.1.2</version>
- </dependency>
- <dependency>
- <groupId>com.google.code.findbugs</groupId>
- <artifactId>jsr305</artifactId>
- <version>2.0.1</version>
- </dependency>
- </dependencies>
- <repositories>
- <repository>
- <id>pterodactylus</id>
- <url>http://maven.pterodactylus.net/</url>
- </repository>
- </repositories>
- <properties>
- <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
- <version.utils>0.12.4</version.utils>
- <findbugs.timeout>600000</findbugs.timeout>
- </properties>
- <build>
- <plugins>
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>findbugs-maven-plugin</artifactId>
- <version>2.5.2</version>
- <configuration>
- <timeout>${findbugs.timeout}</timeout>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-compiler-plugin</artifactId>
- <version>2.0.2</version>
- <configuration>
- <source>1.6</source>
- <target>1.6</target>
- <encoding>UTF-8</encoding>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-jar-plugin</artifactId>
- <version>2.2</version>
- <configuration>
- <archive>
- <manifestEntries>
- <Plugin-Main-Class>net.pterodactylus.sone.main.SonePlugin</Plugin-Main-Class>
- </manifestEntries>
- </archive>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-assembly-plugin</artifactId>
- <version>2.2-beta-5</version>
- <configuration>
- <finalName>sone</finalName>
- <descriptorRefs>
- <descriptorRef>jar-with-dependencies</descriptorRef>
- </descriptorRefs>
- <archiverConfig>
- <duplicateBehavior>skip</duplicateBehavior>
- </archiverConfig>
- <archive>
- <manifestEntries>
- <Plugin-Main-Class>net.pterodactylus.sone.main.SonePlugin</Plugin-Main-Class>
- </manifestEntries>
- </archive>
- </configuration>
- <executions>
- <execution>
- <id>make-assembly</id>
- <phase>package</phase>
- <goals>
- <goal>single</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-javadoc-plugin</artifactId>
- <version>2.7</version>
- <configuration>
- <detectLinks>true</detectLinks>
- <detectJavaApiLink>true</detectJavaApiLink>
- <show>private</show>
- <footer>© 2010–2013 David ‘Bombe’ Roden</footer>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.jacoco</groupId>
- <artifactId>jacoco-maven-plugin</artifactId>
- <version>0.7.6.201602180812</version>
- <executions>
- <execution>
- <id>default-prepare-agent</id>
- <goals>
- <goal>prepare-agent</goal>
- </goals>
- </execution>
- <execution>
- <id>default-report</id>
- <phase>prepare-package</phase>
- <goals>
- <goal>report</goal>
- </goals>
- </execution>
- <execution>
- <id>default-check</id>
- <goals>
- <goal>check</goal>
- </goals>
- <configuration>
- <rules>
- <!-- implmentation is needed only for Maven 2 -->
- <rule implementation="org.jacoco.maven.RuleConfiguration">
- <element>BUNDLE</element>
- <limits>
- <!-- implmentation is needed only for Maven 2 -->
- <limit implementation="org.jacoco.report.check.Limit">
- <counter>COMPLEXITY</counter>
- <value>COVEREDRATIO</value>
- <minimum>0.60</minimum>
- </limit>
- </limits>
- </rule>
- </rules>
- </configuration>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <groupId>org.pitest</groupId>
- <artifactId>pitest-maven</artifactId>
- <version>1.1.10</version>
- <configuration>
- <targetClasses>
- <param>net.pterodactylus.sone.*</param>
- </targetClasses>
- <targetTests>
- <param>net.pterodactylus.sone.*</param>
- </targetTests>
- </configuration>
- </plugin>
- </plugins>
- </build>
-</project>
--- /dev/null
+rootProject.name = 'sone'
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);
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<String>(sone.getLikedPostIds()));
soneProperties.put("likedReplyIds", new HashSet<String>(sone.getLikedReplyIds()));
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);
public interface Post extends Identified {
/** Comparator for posts, sorts descending by time. */
- public static final Comparator<Post> TIME_COMPARATOR = new Comparator<Post>() {
+ public static final Comparator<Post> NEWEST_FIRST = new Comparator<Post>() {
@Override
public int compare(Post leftPost, Post rightPost) {
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;
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");
}
import static com.google.common.base.Preconditions.checkState;
-import org.apache.commons.lang.StringUtils;
-
import net.pterodactylus.sone.database.PostReplyBuilder;
/**
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");
}
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.
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. */
synchronized (this) {
sortedPosts = new ArrayList<Post>(posts);
}
- Collections.sort(sortedPosts, Post.TIME_COMPARATOR);
+ Collections.sort(sortedPosts, Post.NEWEST_FIRST);
return sortedPosts;
}
allPosts = Collections2.filter(allPosts, Post.FUTURE_POSTS_FILTER);
List<Post> sortedPosts = new ArrayList<Post>(allPosts);
- Collections.sort(sortedPosts, Post.TIME_COMPARATOR);
+ Collections.sort(sortedPosts, Post.NEWEST_FIRST);
if (sortedPosts.size() < startPost) {
return new Response("PostFeed", encodePosts(Collections.<Post> emptyList(), "Posts.", false));
*/
@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());
}
}
}
/** 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());
return l10n;
}
+ public static String getPluginVersion() {
+ return VERSION.toString();
+ }
+
public static int getYear() {
return YEAR;
}
public class ImageLinkFilter implements Filter {
/** The template to render for the <img> tag. */
- private static final Template linkTemplate = TemplateParser.parse(new StringReader("<img<%ifnull !class> 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("<img<%ifnull !class> 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;
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());
}
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;
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<Part> parts = soneTextParser.parse(text, context);
if (length > -1) {
*/
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<Part> parts = parser.parse(postPart.getPost().getText(), parserContext);
StringBuilder excerpt = new StringBuilder();
for (Part part : parts) {
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
*/
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;
}
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
*/
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;
}
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.
*/
public class PartContainer implements Part, Iterable<Part> {
- /** The parts to render. */
private final List<Part> parts = new ArrayList<Part>();
- //
- // 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) {
return partText.toString();
}
- //
- // ITERABLE METHODS
- //
-
- /**
- * {@inheritDoc}
- */
@Override
+ @Nonnull
@SuppressWarnings("synthetic-access")
public Iterator<Part> iterator() {
return new Iterator<Part>() {
package net.pterodactylus.sone.text;
+import java.util.Objects;
+
+import javax.annotation.Nonnull;
+
/**
* {@link Part} implementation that holds a single piece of 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;
}
package net.pterodactylus.sone.text;
+import java.util.Objects;
+
+import javax.annotation.Nonnull;
+
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();
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;
*/
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);
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;
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;
@Override
public Iterable<Part> 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;
}
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! */
continue;
}
- if (linkType == LinkType.SONE) {
- if (line.length() >= (7 + 43)) {
- String soneId = line.substring(7, 50);
- Optional<Sone> sone = soneProvider.getSone(soneId);
- if (!sone.isPresent()) {
- /*
- * don’t use create=true above, we don’t want
- * the empty shell.
- */
- sone = Optional.<Sone>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> 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);
return parts;
}
+ private void renderSoneLink(PartContainer parts, String line) {
+ if (line.length() >= (7 + 43)) {
+ String soneId = line.substring(7, 50);
+ Optional<Sone> 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> 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;
*/
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
*/
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;
}
@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);
* {@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);
* {@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<Post> allPosts = webInterface.getCore().getBookmarkedPosts();
Collection<Post> loadedPosts = Collections2.filter(allPosts, new Predicate<Post>() {
}
});
List<Post> sortedPosts = new ArrayList<Post>(loadedPosts);
- Collections.sort(sortedPosts, Post.TIME_COMPARATOR);
+ Collections.sort(sortedPosts, Post.NEWEST_FIRST);
Pagination<Post> pagination = new Pagination<Post>(sortedPosts, webInterface.getCore().getPreferences().getPostsPerPage()).setPage(parseInt(request.getHttpRequest().getParam("page"), 0));
templateContext.set("pagination", pagination);
templateContext.set("posts", pagination.getItems());
* {@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) {
* {@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();
* {@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);
* {@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<Sone> localSones = new ArrayList<Sone>(webInterface.getCore().getLocalSones());
Collections.sort(localSones, Sone.NICE_NAME_COMPARATOR);
templateContext.set("sones", localSones);
* {@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);
* {@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) {
* {@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");
* {@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();
* {@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<PostReply> reply = webInterface.getCore().getPostReply(replyId);
String returnPage = request.getHttpRequest().getPartAsStringFailsafe("returnPage", 256);
* {@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());
* {@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> notification = webInterface.getNotification(notificationId);
if (notification.isPresent() && notification.get().isDismissable()) {
* {@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);
* {@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);
* {@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);
* {@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();
* {@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();
* {@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());
* {@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);
* {@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<Post> allPosts = new ArrayList<Post>();
allPosts.addAll(currentSone.getPosts());
}
allPosts = Collections2.filter(allPosts, postVisibilityFilter.isVisible(currentSone));
List<Post> sortedPosts = new ArrayList<Post>(allPosts);
- Collections.sort(sortedPosts, Post.TIME_COMPARATOR);
+ Collections.sort(sortedPosts, Post.NEWEST_FIRST);
Pagination<Post> pagination = new Pagination<Post>(sortedPosts, webInterface.getCore().getPreferences().getPostsPerPage()).setPage(parseInt(request.getHttpRequest().getParam("page"), 0));
templateContext.set("pagination", pagination);
templateContext.set("posts", pagination.getItems());
* {@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");
* {@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);
* {@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) {
* {@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<Sone> localSones = new ArrayList<Sone>(webInterface.getCore().getLocalSones());
Collections.sort(localSones, Sone.NICE_NAME_COMPARATOR);
* {@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");
}
* {@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");
* {@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<Post> posts = new HashSet<Post>(webInterface.getNewPosts(getCurrentSone(request.getToadletContext(), false)));
for (PostReply reply : webInterface.getNewReplies(getCurrentSone(request.getToadletContext(), false))) {
/* filter and sort them. */
List<Post> sortedPosts = new ArrayList(posts);
- Collections.sort(sortedPosts, Post.TIME_COMPARATOR);
+ Collections.sort(sortedPosts, Post.NEWEST_FIRST);
/* paginate them. */
Pagination<Post> pagination = new Pagination<Post>(sortedPosts, webInterface.getCore().getPreferences().getPostsPerPage()).setPage(parseInt(request.getHttpRequest().getParam("page"), 0));
* {@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) {
* {@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) {
*/
@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");
@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());
}
};
* {@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());
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 {
}
/**
* {@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);
* {@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);
* {@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());
* {@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);
* {@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) {
* {@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);
* {@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);
* {@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> post = webInterface.getCore().getPost(postId);
* {@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> sone = webInterface.getCore().getSone(soneId);
templateContext.set("sone", sone.orNull());
}
List<Post> 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<Post> postPagination = new Pagination<Post>(sonePosts, webInterface.getCore().getPreferences().getPostsPerPage()).setPage(parseInt(request.getHttpRequest().getParam("postPage"), 0));
templateContext.set("postPagination", postPagination);
templateContext.set("posts", postPagination.getItems());
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)));
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());
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;
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;
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;
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;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
+import org.mockito.ArgumentMatchers;
/**
* Unit test for {@link FreenetInterface}.
@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.<FreenetURI>any(), ArgumentMatchers.<HashMap<String, Object>>any(), ArgumentMatchers.<String>any())).thenThrow(InsertException.class);
freenetInterface.insertDirectory(null, null, null);
}
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;
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;
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;
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;
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;
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"));
}
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
import com.google.inject.Injector;
import org.hamcrest.Matchers;
import org.junit.Test;
+import org.mockito.ArgumentMatchers;
/**
* Unit test for {@link ListNotificationFilterTest}.
}
private void setPostVisibilityPredicate(Predicate<Post> value) {
- when(postVisibilityFilter.isVisible(any(Sone.class))).thenReturn(value);
+ when(postVisibilityFilter.isVisible(ArgumentMatchers.<Sone>any())).thenReturn(value);
}
@Test
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;
String result = String.valueOf(imageLinkFilter.format(templateContext, image, ImmutableMap.<String, Object>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"));
String result = String.valueOf(imageLinkFilter.format(templateContext, "image-id", ImmutableMap.<String, Object>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"));
--- /dev/null
+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 <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
+ */
+@Retention(SOURCE)
+@Target(METHOD)
+public @interface Dirty {
+
+ String value() default "";
+
+}
--- /dev/null
+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 <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
+ */
+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);
+ }
+
+}
--- /dev/null
+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 <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
+ */
+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);
+ }
+
+}
--- /dev/null
+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 <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
+ */
+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<Part> 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));
+ }
+
+}
--- /dev/null
+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 <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
+ */
+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);
+ }
+
+}
--- /dev/null
+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 <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
+ */
+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);
+ }
+
+}
--- /dev/null
+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 <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
+ */
+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);
+ }
+
+}
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 <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
*/
-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<Part> parts;
-
/* check basic operation. */
- parts = soneTextParser.parse("Test.", null);
- assertNotNull("Parts", parts);
- assertEquals("Part Text", "Test.", convertText(parts, PlainTextPart.class));
+ Iterable<Part> 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<Part> parts = soneTextParser.parse("Text.\nText", null);
+ assertThat("Part Text", convertText(parts), is("Text.\nText"));
+ }
+
+ @Test
+ public void freenetLinksHaveTheFreenetPrefixRemoved() {
+ Iterable<Part> 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<Part> 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<Part> 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<Part> parts = parser.parse("sone://DAxKQzS48mtaQc7sUVHIgx3fnWZPQBz0EueBreUVWrU", null);
+ assertThat("Part Text", convertText(parts), is("[Sone|DAxKQzS48mtaQc7sUVHIgx3fnWZPQBz0EueBreUVWrU]"));
+ }
+
+ @Test
+ public void postLinkIsRenderedAsPlainTextIfPostIdIsTooShort() {
+ Iterable<Part> 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<Part> 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<Part> 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<Part> 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<Part> 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<Part> 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<Part> 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<Part> parts = soneTextParser.parse("CHK@qM1nmgU", null);
+ assertThat("Part Text", convertText(parts), is("CHK@qM1nmgU"));
+ }
+
+ @Test
+ public void httpsLinkHasItsPathsShortened() {
+ Iterable<Part> 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<Part> 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<Part> 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<Part> 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<Part> 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<Part> 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<Part> 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<Part> parts = soneTextParser.parse("", null);
+ assertThat("Part Text", convertText(parts), is(""));
+ }
+
+ @Test
+ public void linksAreParsedInCorrectOrder() {
+ Iterable<Part> parts = soneTextParser.parse("KSK@ CHK@", null);
+ assertThat("Part Text", convertText(parts), is("KSK@ CHK@"));
+ }
+
+ @Test
+ public void sskLinkWithoutContextIsNotTrusted() {
+ Iterable<Part> 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<Part> 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<Part> 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<Part> 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<Part> 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<Part> 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<Part> 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<Part> 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<Part> 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<Part> 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<Part> 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<Part> 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<Part> 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<Part> 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<Part> 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<Part> 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<Part> 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
private static String convertText(Iterable<Part> 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());
} 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();
}
+ private static class AbsentSoneProvider extends TestSoneProvider {
+
+ @Override
+ public Optional<Sone> getSone(String soneId) {
+ return Optional.absent();
+ }
+
+ }
+
+ private static class TestPostProvider implements PostProvider {
+
+ @Override
+ public Optional<Post> getPost(final String postId) {
+ return Optional.<Post>of(new Post() {
+ @Override
+ public String getId() {
+ return postId;
+ }
+
+ @Override
+ public boolean isLoaded() {
+ return false;
+ }
+
+ @Override
+ public Sone getSone() {
+ return null;
+ }
+
+ @Override
+ public Optional<String> getRecipientId() {
+ return null;
+ }
+
+ @Override
+ public Optional<Sone> 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<Post> getPosts(String soneId) {
+ return null;
+ }
+
+ @Override
+ public Collection<Post> getDirectedPosts(String recipientId) {
+ return null;
+ }
+
+ }
+
+ private static class AbsentPostProvider extends TestPostProvider {
+
+ @Override
+ public Optional<Post> getPost(String postId) {
+ return Optional.absent();
+ }
+
+ }
+
}
--- /dev/null
+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 <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
+ */
+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));
+ }
+
+}
--- /dev/null
+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 <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
+ */
+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));
+ }
+ }
+
+}
--- /dev/null
+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 <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
+ */
+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<Post> bookmarkedPosts = createBookmarkedPosts(post1, post2, post3);
+ when(core.getBookmarkedPosts()).thenReturn(bookmarkedPosts);
+ when(core.getPreferences().getPostsPerPage()).thenReturn(5);
+ page.processTemplate(freenetRequest, templateContext);
+ assertThat((Collection<Post>) templateContext.get("posts"), contains(post1, post3, post2));
+ assertThat(((Pagination<Post>) templateContext.get("pagination")).getItems(), contains(post1, post3, post2));
+ assertThat(((Boolean) templateContext.get("postsNotLoaded")), is(false));
+ }
+
+ private Set<Post> createBookmarkedPosts(Post post1, Post post2, Post post3) {
+ Set<Post> 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<Post> bookmarkedPosts = createBookmarkedPosts(post1, post2, post3);
+ when(core.getBookmarkedPosts()).thenReturn(bookmarkedPosts);
+ when(core.getPreferences().getPostsPerPage()).thenReturn(5);
+ page.processTemplate(freenetRequest, templateContext);
+ assertThat((Collection<Post>) templateContext.get("posts"), contains(post2, post1));
+ assertThat(((Pagination<Post>) 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;
+ }
+
+}
--- /dev/null
+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 <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
+ */
+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);
+ }
+
+}
--- /dev/null
+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 <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
+ */
+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.<Sone>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.<Sone>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");
+ }
+ }
+
+}
--- /dev/null
+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 <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
+ */
+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.<Boolean>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.<String>get("postId", String.class), is("post-id"));
+ assertThat(templateContext.<String>get("text", String.class), is(text));
+ assertThat(templateContext.<String>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");
+ }
+
+}
--- /dev/null
+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 <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
+ */
+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<Sone>) templateContext.get("sones"), contains(localSones[0], localSones[1], localSones[2]));
+ assertThat((Collection<OwnIdentity>) 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<Boolean>() {
+ @Override
+ public Boolean answer(InvocationOnMock invocation) throws Throwable {
+ return Arrays.asList(contexts).contains(invocation.<String>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));
+ }
+
+}
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 <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
*/
-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.<Notification>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.<PostReply>absent());
expectedException.expect(redirectsTo("noPermission.html"));
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;
*
* @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
*/
-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.<Notification>emptyList());
}
@Test
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 <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
*/
-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);
@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);
}
}
--- /dev/null
+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 <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
+ */
+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<OwnIdentity> ownIdentities = new HashSet<>();
+ private final List<Sone> 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<String>() {
+ @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.<Sone>absent());
+ when(core.getPost(anyString())).thenReturn(Optional.<Post>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<Notification>());
+ }
+
+ 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<String>() {
+ @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);
+ }
+
+}
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;
--- /dev/null
+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 <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
+ */
+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));
+ }
+
+}
+++ /dev/null
-<%if foo>foo<%else>bar<%/if>
\ No newline at end of file