private final AtomicBoolean debug = new AtomicBoolean(false);
/** The preferences. */
- private final DefaultPreferences preferences;
+ private final Preferences preferences;
/** The event bus. */
private final EventBus eventBus;
private final SoneUriCreator soneUriCreator;
@Inject
- public Core(Configuration configuration, FreenetInterface freenetInterface, IdentityManager identityManager, SoneDownloader soneDownloader, ImageInserter imageInserter, UpdateChecker updateChecker, WebOfTrustUpdater webOfTrustUpdater, EventBus eventBus, Database database, MetricRegistry metricRegistry, SoneUriCreator soneUriCreator) {
+ public Core(Configuration configuration, FreenetInterface freenetInterface, IdentityManager identityManager, SoneDownloader soneDownloader, ImageInserter imageInserter, UpdateChecker updateChecker, WebOfTrustUpdater webOfTrustUpdater, EventBus eventBus, Database database, MetricRegistry metricRegistry, SoneUriCreator soneUriCreator, Preferences preferences) {
super("Sone Core");
this.configuration = configuration;
this.freenetInterface = freenetInterface;
this.database = database;
this.metricRegistry = metricRegistry;
this.soneUriCreator = soneUriCreator;
- preferences = new DefaultPreferences(eventBus);
+ this.preferences = preferences;
this.configurationSaveTimeHistogram = metricRegistry.histogram("configuration.save.duration", () -> new Histogram(new ExponentiallyDecayingReservoir(3000, 0)));
}
*
* @return The options of the core
*/
- public DefaultPreferences getPreferences() {
+ public Preferences getPreferences() {
return preferences;
}
storingConfiguration = true;
}
- /* store the options first. */
try {
- preferences.saveTo(configuration);
-
/* save known Sones. */
int soneCounter = 0;
synchronized (knownSones) {
* Loads the configuration.
*/
private void loadConfiguration() {
- new PreferencesLoader(preferences).loadFrom(configuration);
-
/* load known Sones. */
int soneCounter = 0;
while (true) {
+++ /dev/null
-/*
- * Sone - Options.java - Copyright © 2010–2020 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.sone.core;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-
-import net.pterodactylus.sone.utils.Option;
-
-/**
- * Stores various options that influence Sone’s behaviour.
- */
-public class Options {
-
- /** Holds all {@link Boolean} {@link Option}s. */
- private final Map<String, Option<Boolean>> booleanOptions = Collections.synchronizedMap(new HashMap<String, Option<Boolean>>());
-
- /** Holds all {@link Integer} {@link Option}s. */
- private final Map<String, Option<Integer>> integerOptions = Collections.synchronizedMap(new HashMap<String, Option<Integer>>());
-
- /** Holds all {@link String} {@link Option}s. */
- private final Map<String, Option<String>> stringOptions = Collections.synchronizedMap(new HashMap<String, Option<String>>());
-
- /** Holds all {@link Enum} {@link Option}s. */
- private final Map<String, Option<? extends Enum<?>>> enumOptions = Collections.synchronizedMap(new HashMap<String, Option<? extends Enum<?>>>());
-
- /**
- * Adds a boolean option.
- *
- * @param name
- * The name of the option
- * @param booleanOption
- * The option
- * @return The given option
- */
- public Option<Boolean> addBooleanOption(String name, Option<Boolean> booleanOption) {
- booleanOptions.put(name, booleanOption);
- return booleanOption;
- }
-
- /**
- * Returns the boolean option with the given name.
- *
- * @param name
- * The name of the option
- * @return The option, or {@code null} if there is no option with the given
- * name
- */
- public Option<Boolean> getBooleanOption(String name) {
- return booleanOptions.get(name);
- }
-
- /**
- * Adds an {@link Integer} {@link Option}.
- *
- * @param name
- * The name of the option
- * @param integerOption
- * The option
- * @return The given option
- */
- public Option<Integer> addIntegerOption(String name, Option<Integer> integerOption) {
- integerOptions.put(name, integerOption);
- return integerOption;
- }
-
- /**
- * Returns an {@link Integer} {@link Option}.
- *
- * @param name
- * The name of the integer option to get
- * @return The integer option, or {@code null} if there is no option with
- * the given name
- */
- public Option<Integer> getIntegerOption(String name) {
- return integerOptions.get(name);
- }
-
- /**
- * Adds a {@link String} {@link Option}.
- *
- * @param name
- * The name of the option
- * @param stringOption
- * The option
- * @return The given option
- */
- public Option<String> addStringOption(String name, Option<String> stringOption) {
- stringOptions.put(name, stringOption);
- return stringOption;
- }
-
- /**
- * Returns a {@link String} {@link Option}.
- *
- * @param name
- * The name of the string option to get
- * @return The string option, or {@code null} if there is no option with the
- * given name
- */
- public Option<String> getStringOption(String name) {
- return stringOptions.get(name);
- }
-
- /**
- * Adds an {@link Enum} {@link Option}.
- *
- * @param <T>
- * The enum type
- * @param name
- * The name of the option
- * @param enumOption
- * The option
- * @return The given option
- */
- public <T extends Enum<T>> Option<T> addEnumOption(String name, Option<T> enumOption) {
- enumOptions.put(name, enumOption);
- return enumOption;
- }
-
- /**
- * Returns a {@link Enum} {@link Option}. As the type can probably not be
- * interred correctly you could help the compiler by calling this method
- * like this:
- * <p>
- *
- * <pre>
- * options.<SomeEnum> getEnumOption("SomeEnumOption").get();
- * </pre>
- *
- * @param <T>
- * The enum type
- * @param name
- * The name of the option
- * @return The enum option, or {@code null} if there is no enum option with
- * the given name
- */
- @SuppressWarnings("unchecked")
- public <T extends Enum<T>> Option<T> getEnumOption(String name) {
- return (Option<T>) enumOptions.get(name);
- }
-
-}
+++ /dev/null
-package net.pterodactylus.sone.utils;
-
-/**
- * Contains current and default value of an option.
- *
- * @param <T>
- * The type of the option
- */
-public interface Option<T> {
-
- /**
- * Returns the current value of the option. If the current value is not
- * set (usually {@code null}), the default value is returned.
- *
- * @return The current value of the option
- */
- public T get();
-
- /**
- * Returns the real value of the option. This will also return an unset
- * value (usually {@code null})!
- *
- * @return The real value of the option
- */
- public T getReal();
-
- /**
- * Validates the given value. Note that {@code null} is always a valid
- * value!
- *
- * @param value
- * The value to validate
- * @return {@code true} if this option does not have a validator, or the
- * validator validates this object, {@code false} otherwise
- */
- public boolean validate(T value);
-
- /**
- * Sets the current value of the option.
- *
- * @param value
- * The new value of the option
- * @throws IllegalArgumentException
- * if the value is not valid for this option
- */
- public void set(T value) throws IllegalArgumentException;
-
-}
import net.pterodactylus.sone.fcp.event.FcpInterfaceActivatedEvent
import net.pterodactylus.sone.fcp.event.FcpInterfaceDeactivatedEvent
import net.pterodactylus.sone.fcp.event.FullAccessRequiredChanged
-import net.pterodactylus.sone.utils.DefaultOption
-import net.pterodactylus.util.config.Configuration
-import net.pterodactylus.util.config.ConfigurationException
-import java.lang.Integer.MAX_VALUE
/**
- * Convenience interface for external classes that want to access the core’s
- * configuration.
+ * Sone’s user-independent preferences. Clients of this interface can assume
+ * that none of the properties will be {@code null}, especially when the
+ * instance has been injected via Guice.
*/
-class DefaultPreferences(private val eventBus: EventBus) {
-
- private val _insertionDelay = DefaultOption(60) { it in 0..MAX_VALUE }
- val insertionDelay: Int get() = _insertionDelay.get()
- var newInsertionDelay: Int?
- get() = unsupported
- set(value) {
- _insertionDelay.set(value)
- eventBus.post(InsertionDelayChangedEvent(insertionDelay))
- }
-
- private val _postsPerPage = DefaultOption(10) { it in 1..MAX_VALUE }
- val postsPerPage: Int get() = _postsPerPage.get()
- var newPostsPerPage: Int?
- get() = unsupported
- set(value) {
- _postsPerPage.set(value)
- }
-
- private val _imagesPerPage = DefaultOption(9) { it in 1..MAX_VALUE }
- val imagesPerPage: Int get() = _imagesPerPage.get()
- var newImagesPerPage: Int?
- get() = unsupported
- set(value: Int?) = _imagesPerPage.set(value)
-
- private val _charactersPerPost = DefaultOption(400) { it == -1 || it in 50..MAX_VALUE }
- val charactersPerPost: Int get() = _charactersPerPost.get()
- var newCharactersPerPost: Int?
- get() = unsupported
- set(value) = _charactersPerPost.set(value)
-
- private val _postCutOffLength = DefaultOption(200) { it in 50..MAX_VALUE }
- val postCutOffLength: Int get() = _postCutOffLength.get()
- var newPostCutOffLength: Int?
- get() = unsupported
- set(value) = _postCutOffLength.set(value)
-
- private val _requireFullAccess = DefaultOption(false)
- val requireFullAccess: Boolean get() = _requireFullAccess.get()
- var newRequireFullAccess: Boolean?
- get() = unsupported
- set(value) = _requireFullAccess.set(value)
-
- private val _fcpInterfaceActive = DefaultOption(false)
- val fcpInterfaceActive: Boolean get() = _fcpInterfaceActive.get()
- var newFcpInterfaceActive: Boolean?
- get() = unsupported
- set(value) {
- _fcpInterfaceActive.set(value)
- when (value) {
- true -> eventBus.post(FcpInterfaceActivatedEvent())
- else -> eventBus.post(FcpInterfaceDeactivatedEvent())
- }
- }
-
- private val _fcpFullAccessRequired = DefaultOption(ALWAYS)
- val fcpFullAccessRequired: FullAccessRequired get() = _fcpFullAccessRequired.get()
- var newFcpFullAccessRequired: FullAccessRequired?
- get() = unsupported
- set(value) {
- _fcpFullAccessRequired.set(value)
- eventBus.post(FullAccessRequiredChanged(fcpFullAccessRequired))
- }
-
- private val _strictFiltering = DefaultOption(false)
- val strictFiltering: Boolean get() = _strictFiltering.get()
- var newStrictFiltering: Boolean? = false
- set(value) {
- _strictFiltering.set(value)
- when (strictFiltering) {
- true -> eventBus.post(StrictFilteringActivatedEvent())
- else -> eventBus.post(StrictFilteringDeactivatedEvent())
- }
- }
-
- @Throws(ConfigurationException::class)
- fun saveTo(configuration: Configuration) {
- configuration.getIntValue("Option/ConfigurationVersion").value = 0
- configuration.getIntValue("Option/InsertionDelay").value = _insertionDelay.real
- configuration.getIntValue("Option/PostsPerPage").value = _postsPerPage.real
- configuration.getIntValue("Option/ImagesPerPage").value = _imagesPerPage.real
- configuration.getIntValue("Option/CharactersPerPost").value = _charactersPerPost.real
- configuration.getIntValue("Option/PostCutOffLength").value = _postCutOffLength.real
- configuration.getBooleanValue("Option/RequireFullAccess").value = _requireFullAccess.real
- configuration.getBooleanValue("Option/ActivateFcpInterface").value = _fcpInterfaceActive.real
- configuration.getIntValue("Option/FcpFullAccessRequired").value = toInt(_fcpFullAccessRequired.real)
- configuration.getBooleanValue("Option/StrictFiltering").value = _strictFiltering.real
- }
-
- private fun toInt(fullAccessRequired: FullAccessRequired?): Int? {
- return fullAccessRequired?.ordinal
- }
-
-}
-
interface Preferences {
var insertionDelay: Int?
}
-private val unsupported: Nothing get() = throw UnsupportedOperationException()
-
fun Preferences.withDefaults() = object : Preferences by this {
override var insertionDelay: Int? by default(60, this@withDefaults::insertionDelay)
override var postsPerPage: Int? by default(10, this@withDefaults::postsPerPage)
+++ /dev/null
-package net.pterodactylus.sone.core
-
-import net.pterodactylus.sone.fcp.FcpInterface.*
-import net.pterodactylus.util.config.*
-
-/**
- * Loads preferences stored in a [Configuration] into a [DefaultPreferences] object.
- */
-class PreferencesLoader(private val preferences: DefaultPreferences) {
-
- fun loadFrom(configuration: Configuration) {
- loadInsertionDelay(configuration)
- loadPostsPerPage(configuration)
- loadImagesPerPage(configuration)
- loadCharactersPerPost(configuration)
- loadPostCutOffLength(configuration)
- loadRequireFullAccess(configuration)
- loadFcpInterfaceActive(configuration)
- loadFcpFullAccessRequired(configuration)
- loadStrictFiltering(configuration)
- }
-
- private fun loadInsertionDelay(configuration: Configuration) {
- preferences.newInsertionDelay = configuration.getIntValue("Option/InsertionDelay").getValue(null)
- }
-
- private fun loadPostsPerPage(configuration: Configuration) {
- preferences.newPostsPerPage = configuration.getIntValue("Option/PostsPerPage").getValue(null)
- }
-
- private fun loadImagesPerPage(configuration: Configuration) {
- preferences.newImagesPerPage = configuration.getIntValue("Option/ImagesPerPage").getValue(null)
- }
-
- private fun loadCharactersPerPost(configuration: Configuration) {
- preferences.newCharactersPerPost = configuration.getIntValue("Option/CharactersPerPost").getValue(null)
- }
-
- private fun loadPostCutOffLength(configuration: Configuration) {
- try {
- preferences.newPostCutOffLength = configuration.getIntValue("Option/PostCutOffLength").getValue(null)
- } catch (iae1: IllegalArgumentException) { /* previous versions allowed -1, ignore and use default. */
- }
- }
-
- private fun loadRequireFullAccess(configuration: Configuration) {
- preferences.newRequireFullAccess = configuration.getBooleanValue("Option/RequireFullAccess").getValue(null)
- }
-
- private fun loadFcpInterfaceActive(configuration: Configuration) {
- preferences.newFcpInterfaceActive = configuration.getBooleanValue("Option/ActivateFcpInterface").getValue(null)
- }
-
- private fun loadFcpFullAccessRequired(configuration: Configuration) {
- val fullAccessRequiredInteger = configuration.getIntValue("Option/FcpFullAccessRequired").getValue(null)
- preferences.newFcpFullAccessRequired = fullAccessRequiredInteger?.let { FullAccessRequired.values()[it] }
- }
-
- private fun loadStrictFiltering(configuration: Configuration) {
- preferences.newStrictFiltering = configuration.getBooleanValue("Option/StrictFiltering").getValue(null)
- }
-
-}
+++ /dev/null
-package net.pterodactylus.sone.utils
-
-/**
- * Basic implementation of an [Option].
- *
- * @param <T> The type of the option
- */
-class DefaultOption<T> @JvmOverloads constructor(
- private val defaultValue: T,
- private val validator: ((T) -> Boolean)? = null
-) : Option<T> {
-
- @Volatile
- private var value: T? = null
-
- override fun get() = value ?: defaultValue
-
- override fun getReal(): T? = value
-
- override fun validate(value: T?): Boolean =
- value == null || validator?.invoke(value) ?: true
-
- override fun set(value: T?) {
- require(validate(value)) { "New Value ($value) could not be validated." }
- this.value = value
- }
-
-}
sessionProvider.getCurrentSone(toadletContext)
override fun handleRequest(request: FreenetRequest, response: Response): Response {
- if (core.preferences.requireFullAccess && !request.toadletContext.isAllowedFullAccess) {
+ if (core.preferences.requireFullAccess!! && !request.toadletContext.isAllowedFullAccess) {
return response.setStatusCode(403).setStatusText("Forbidden").setContentType("application/json").write(createErrorJsonObject("auth-required").asJsonString())
}
if (needsFormPassword && request.parameters["formPassword"] != webInterface.formPassword) {
override fun handleRequest(soneRequest: SoneRequest, templateContext: TemplateContext) {
soneRequest.core.bookmarkedPosts.let { posts ->
- val pagination = posts.filter(Post::isLoaded).sortedByDescending { it.time }.paginate(soneRequest.core.preferences.postsPerPage)
+ val pagination = posts.filter(Post::isLoaded).sortedByDescending { it.time }.paginate(soneRequest.core.preferences.postsPerPage!!)
templateContext["pagination"] = pagination
templateContext["posts"] = pagination.items
templateContext["postsNotLoaded"] = posts.any { !it.isLoaded }
}
override fun isEnabled(soneRequest: SoneRequest) =
- if (soneRequest.core.preferences.requireFullAccess && !soneRequest.toadletContext.isAllowedFullAccess) {
+ if (soneRequest.core.preferences.requireFullAccess!! && !soneRequest.toadletContext.isAllowedFullAccess) {
false
} else {
(getCurrentSone(soneRequest.toadletContext) == null) || (soneRequest.core.localSones.size == 1)
.filterNot(Album::isEmpty)
.sortedBy(Album::getTitle)
.also { albums ->
- albums.paginate(soneRequest.core.preferences.imagesPerPage)
+ albums.paginate(soneRequest.core.preferences.imagesPerPage!!)
.turnTo(soneRequest.parameters["page"]?.toIntOrNull() ?: 0)
.also { pagination ->
templateContext["albumPagination"] = pagination
.filter { postVisibilityFilter.isVisible(currentSone).invoke(it) }
.sortedByDescending { it.time }
.let { posts ->
- posts.paginate(soneRequest.core.preferences.postsPerPage)
+ posts.paginate(soneRequest.core.preferences.postsPerPage!!)
.turnTo(soneRequest.parameters["page"]?.toIntOrNull() ?: 0)
.let { pagination ->
templateContext["pagination"] = pagination
getCurrentSone(request.toadletContext)?.let { "index.html" }
override fun isEnabled(soneRequest: SoneRequest) = when {
- soneRequest.core.preferences.requireFullAccess && !soneRequest.toadletContext.isAllowedFullAccess -> false
+ soneRequest.core.preferences.requireFullAccess!! && !soneRequest.toadletContext.isAllowedFullAccess -> false
else -> getCurrentSone(soneRequest.toadletContext) == null
}
}
override fun isEnabled(soneRequest: SoneRequest): Boolean =
- if (soneRequest.core.preferences.requireFullAccess && !soneRequest.toadletContext.isAllowedFullAccess) {
+ if (soneRequest.core.preferences.requireFullAccess!! && !soneRequest.toadletContext.isAllowedFullAccess) {
false
} else
getCurrentSone(soneRequest.toadletContext) != null && soneRequest.core.localSones.size != 1
.distinct()
.sortedByDescending { it.time }
.let { posts ->
- posts.paginate(soneRequest.core.preferences.postsPerPage)
+ posts.paginate(soneRequest.core.preferences.postsPerPage!!)
.turnTo(soneRequest.parameters["page"]?.toIntOrNull() ?: 0)
.let { pagination ->
templateContext["pagination"] = pagination
val fcpInterfaceActive = "fcp-interface-active" in soneRequest.parameters
val strictFiltering = "strict-filtering" in soneRequest.parameters
- soneRequest.core.preferences.newRequireFullAccess = fullAccessRequired
- soneRequest.core.preferences.newFcpInterfaceActive = fcpInterfaceActive
- soneRequest.core.preferences.newStrictFiltering = strictFiltering
+ soneRequest.core.preferences.requireFullAccess = fullAccessRequired
+ soneRequest.core.preferences.fcpInterfaceActive = fcpInterfaceActive
+ soneRequest.core.preferences.strictFiltering = strictFiltering
val postsPerPage = soneRequest.parameters["posts-per-page"]?.toIntOrNull()
val charactersPerPost = soneRequest.parameters["characters-per-post"]?.toIntOrNull()
val insertionDelay = soneRequest.parameters["insertion-delay"]?.toIntOrNull()
val fcpFullAccessRequired = soneRequest.parameters["fcp-full-access-required"]?.toIntOrNull()
- if (cantSetOption { soneRequest.core.preferences.newPostsPerPage = postsPerPage }) fieldsWithErrors += "posts-per-page"
- if (cantSetOption { soneRequest.core.preferences.newCharactersPerPost = charactersPerPost }) fieldsWithErrors += "characters-per-post"
- if (cantSetOption { soneRequest.core.preferences.newPostCutOffLength = postCutOffLength }) fieldsWithErrors += "post-cut-off-length"
- if (cantSetOption { soneRequest.core.preferences.newImagesPerPage = imagesPerPage }) fieldsWithErrors += "images-per-page"
- if (cantSetOption { soneRequest.core.preferences.newInsertionDelay = insertionDelay }) fieldsWithErrors += "insertion-delay"
- fcpFullAccessRequired?.also { if (cantSetOption { soneRequest.core.preferences.newFcpFullAccessRequired = FullAccessRequired.values()[fcpFullAccessRequired] }) fieldsWithErrors += "fcp-full-access-required" }
+ if (cantSetOption { soneRequest.core.preferences.postsPerPage = postsPerPage }) fieldsWithErrors += "posts-per-page"
+ if (cantSetOption { soneRequest.core.preferences.charactersPerPost = charactersPerPost }) fieldsWithErrors += "characters-per-post"
+ if (cantSetOption { soneRequest.core.preferences.postCutOffLength = postCutOffLength }) fieldsWithErrors += "post-cut-off-length"
+ if (cantSetOption { soneRequest.core.preferences.imagesPerPage = imagesPerPage }) fieldsWithErrors += "images-per-page"
+ if (cantSetOption { soneRequest.core.preferences.insertionDelay = insertionDelay }) fieldsWithErrors += "insertion-delay"
+ fcpFullAccessRequired?.also { if (cantSetOption { soneRequest.core.preferences.fcpFullAccessRequired = FullAccessRequired.values()[fcpFullAccessRequired] }) fieldsWithErrors += "fcp-full-access-required" }
if (fieldsWithErrors.isEmpty()) {
soneRequest.core.touchConfiguration()
soneRequest.core.preferences.let { preferences ->
templateContext["insertion-delay"] = preferences.insertionDelay
templateContext["characters-per-post"] = preferences.charactersPerPost
- templateContext["fcp-full-access-required"] = preferences.fcpFullAccessRequired.ordinal
+ templateContext["fcp-full-access-required"] = preferences.fcpFullAccessRequired!!.ordinal
templateContext["images-per-page"] = preferences.imagesPerPage
templateContext["fcp-interface-active"] = preferences.fcpInterfaceActive
templateContext["require-full-access"] = preferences.requireFullAccess
val soneNameCache = { sone: Sone -> sone.names() }.memoize()
val sonePagination = soneRequest.core.sones
- .scoreAndPaginate(phrases, soneRequest.core.preferences.postsPerPage) { it.allText(soneNameCache) }
+ .scoreAndPaginate(phrases, soneRequest.core.preferences.postsPerPage!!) { it.allText(soneNameCache) }
.apply { page = soneRequest.parameters["sonePage"].emptyToNull?.toIntOrNull() ?: 0 }
val postPagination = cache.get(phrases) {
soneRequest.core.sones
.flatMap(Sone::getPosts)
.filter(noFuturePost)
- .scoreAndPaginate(phrases, soneRequest.core.preferences.postsPerPage) { it.allText(soneNameCache, soneRequest.core::getReplies) }
+ .scoreAndPaginate(phrases, soneRequest.core.preferences.postsPerPage!!) { it.allText(soneNameCache, soneRequest.core::getReplies) }
}.apply { page = soneRequest.parameters["postPage"].emptyToNull?.toIntOrNull() ?: 0 }
Logger.normal(SearchPage::class.java, "Finished search for “${soneRequest.parameters["query"]}” in ${System.currentTimeMillis() - startTime}ms.")
open fun isEnabled(soneRequest: SoneRequest) = when {
requiresLogin && getCurrentSone(soneRequest.toadletContext) == null -> false
- core.preferences.requireFullAccess && !soneRequest.toadletContext.isAllowedFullAccess -> false
+ core.preferences.requireFullAccess!! && !soneRequest.toadletContext.isAllowedFullAccess -> false
else -> true
}
val directedPosts = soneRequest.core.getDirectedPosts(sone.id)
(sonePosts + directedPosts)
.sortedByDescending(Post::getTime)
- .paginate(soneRequest.core.preferences.postsPerPage)
+ .paginate(soneRequest.core.preferences.postsPerPage!!)
.apply { page = soneRequest.parameters["postPage"]?.toIntOrNull() ?: 0 }
.also {
templateContext["postPagination"] = it
.minus(sonePosts)
.minus(directedPosts)
.sortedByDescending { soneRequest.core.getReplies(it.id).first().time }
- .paginate(soneRequest.core.preferences.postsPerPage)
+ .paginate(soneRequest.core.preferences.postsPerPage!!)
.apply { page = soneRequest.parameters["repliedPostPage"]?.toIntOrNull() ?: 0 }
.also {
templateContext["repliedPostPagination"] = it
+++ /dev/null
-package net.pterodactylus.sone.core;
-
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.is;
-import static org.hamcrest.Matchers.nullValue;
-import static org.mockito.Mockito.mock;
-
-import net.pterodactylus.sone.utils.Option;
-
-import org.junit.Test;
-
-/**
- * Unit test for {@link Options}.
- */
-public class OptionsTest {
-
- private final Options options = new Options();
-
- @Test
- public void booleanOptionIsAdded() {
- Option<Boolean> booleanOption = mock(Option.class);
- options.addBooleanOption("test", booleanOption);
- assertThat(options.getBooleanOption("test"), is(booleanOption));
- assertThat(options.getBooleanOption("not-test"), nullValue());
- }
-
- @Test
- public void integerOptionIsAdded() {
- Option<Integer> integerOption = mock(Option.class);
- options.addIntegerOption("test", integerOption);
- assertThat(options.getIntegerOption("test"), is(integerOption));
- assertThat(options.getIntegerOption("not-test"), nullValue());
- }
-
- @Test
- public void stringOptionIsAdded() {
- Option<String> stringOption = mock(Option.class);
- options.addStringOption("test", stringOption);
- assertThat(options.getStringOption("test"), is(stringOption));
- assertThat(options.getStringOption("not-test"), nullValue());
- }
-
- @Test
- public void enumOptionIsAdded() {
- Option<TestEnum> enumOption = mock(Option.class);
- options.addEnumOption("test", enumOption);
- assertThat(options.<TestEnum>getEnumOption("test"), is(enumOption));
- assertThat(options.<TestEnum>getEnumOption("not-test"), nullValue());
- }
-
- private enum TestEnum {TEST, NOT_TEST}
-
-}
val database = mock<Database>()
val metricRegistry = MetricRegistry()
val soneUriCreator = SoneUriCreator()
- val core = Core(configuration, freenetInterface, identityManager, soneDownloader, imageInserter, updateChecker, webOfTrustUpdater, eventBus, database, metricRegistry, soneUriCreator)
+ val core = Core(configuration, freenetInterface, identityManager, soneDownloader, imageInserter, updateChecker, webOfTrustUpdater, eventBus, database, metricRegistry, soneUriCreator, testPreferences())
val ownIdentity = mock<OwnIdentity>()
val identity = mock<Identity>()
whenever(identity.id).thenReturn("sone-id")
val database = mock<Database>()
val metricRegistry = MetricRegistry()
val soneUriCreator = SoneUriCreator()
- return Core(configuration, freenetInterface, identityManager, soneDownloader, imageInserter, updateChecker, webOfTrustUpdater, eventBus, database, metricRegistry, soneUriCreator)
+ return Core(configuration, freenetInterface, identityManager, soneDownloader, imageInserter, updateChecker, webOfTrustUpdater, eventBus, database, metricRegistry, soneUriCreator, testPreferences())
}
}
+++ /dev/null
-package net.pterodactylus.sone.core
-
-import com.google.common.eventbus.*
-import net.pterodactylus.sone.fcp.FcpInterface.*
-import net.pterodactylus.util.config.*
-import org.hamcrest.MatcherAssert.*
-import org.hamcrest.Matchers.*
-import org.junit.*
-
-/**
- * Unit test for [PreferencesLoader].
- */
-class PreferencesLoaderTest {
-
- @Suppress("UnstableApiUsage")
- private val eventBus = EventBus()
- private val preferences = DefaultPreferences(eventBus)
- private val configuration = Configuration(MapConfigurationBackend())
- private val preferencesLoader = PreferencesLoader(preferences)
-
- @Before
- fun setupConfiguration() {
- setupIntValue("InsertionDelay", 15)
- setupIntValue("PostsPerPage", 25)
- setupIntValue("ImagesPerPage", 12)
- setupIntValue("CharactersPerPost", 150)
- setupIntValue("PostCutOffLength", 300)
- setupBooleanValue("RequireFullAccess", true)
- setupBooleanValue("ActivateFcpInterface", true)
- setupIntValue("FcpFullAccessRequired", 1)
- setupBooleanValue("StrictFiltering", true)
- }
-
- private fun setupIntValue(optionName: String, value: Int) {
- configuration.getIntValue("Option/$optionName").value = value
- }
-
- private fun setupBooleanValue(optionName: String, value: Boolean) {
- configuration.getBooleanValue("Option/$optionName").value = value
- }
-
- @Test
- fun `configuration is loaded correctly`() {
- preferencesLoader.loadFrom(configuration)
- assertThat(preferences.insertionDelay, equalTo(15))
- assertThat(preferences.postsPerPage, equalTo(25))
- assertThat(preferences.imagesPerPage, equalTo(12))
- assertThat(preferences.charactersPerPost, equalTo(150))
- assertThat(preferences.postCutOffLength, equalTo(300))
- assertThat(preferences.requireFullAccess, equalTo(true))
- assertThat(preferences.fcpInterfaceActive, equalTo(true))
- assertThat(preferences.fcpFullAccessRequired, equalTo(FullAccessRequired.WRITING))
- assertThat(preferences.strictFiltering, equalTo(true))
- }
-
- @Test
- fun `configuration is loaded correctly with cut off length minus one`() {
- setupIntValue("PostCutOffLength", -1)
- preferencesLoader.loadFrom(configuration)
- assertThat(preferences.postCutOffLength, not(equalTo(-1)))
- }
-
-}
import net.pterodactylus.sone.fcp.event.FullAccessRequiredChanged
import net.pterodactylus.sone.test.allNullPreferences
import net.pterodactylus.sone.test.assertThrows
-import net.pterodactylus.util.config.Configuration
-import net.pterodactylus.util.config.MapConfigurationBackend
-import org.hamcrest.Matcher
import org.hamcrest.MatcherAssert.assertThat
import org.hamcrest.Matchers.contains
-import org.hamcrest.Matchers.emptyIterable
import org.hamcrest.Matchers.equalTo
-import org.hamcrest.Matchers.hasItem
-import org.hamcrest.Matchers.instanceOf
-import org.hamcrest.Matchers.nullValue
import org.junit.Test
-/**
- * Unit test for [DefaultPreferences].
- */
-class DefaultPreferencesTest {
-
- private val eventBus = EventBus()
- private val preferences = DefaultPreferences(eventBus)
-
- @Test
- fun `preferences retain insertion delay`() {
- preferences.newInsertionDelay = 15
- assertThat(preferences.insertionDelay, equalTo(15))
- }
-
- @Test
- fun `preferences sends event on setting insertion delay`() {
- val events = mutableListOf<InsertionDelayChangedEvent>()
- eventBus.register(object {
- @Subscribe
- fun insertionDelayChangedEvent(event: InsertionDelayChangedEvent) =
- events.add(event)
- })
- preferences.newInsertionDelay = 15
- assertThat(events, hasItem(InsertionDelayChangedEvent(15)))
- }
-
- @Test(expected = IllegalArgumentException::class)
- fun `invalid insertion delay is rejected`() {
- preferences.newInsertionDelay = -15
- }
-
- @Test
- fun `no event is sent when invalid insertion delay is set`() {
- val events = mutableListOf<InsertionDelayChangedEvent>()
- eventBus.register(object {
- @Subscribe
- fun insertionDelayChanged(event: InsertionDelayChangedEvent) =
- events.add(event)
- })
- try {
- preferences.newInsertionDelay = -15
- } catch (iae: IllegalArgumentException) {
- /* ignore. */
- }
-
- assertThat(events, emptyIterable())
- }
-
- @Test
- fun `preferences return default value when insertion delay is set to null`() {
- preferences.newInsertionDelay = null
- assertThat(preferences.insertionDelay, equalTo(60))
- }
-
- @Test
- fun `preferences start with insertion delay default value`() {
- assertThat(preferences.insertionDelay, equalTo(60))
- }
-
- @Test
- fun `preferences saves null for default insertion delay setting`() {
- verifySavedOption(nullValue()) { it.getIntValue("Option/InsertionDelay").getValue(null) }
- }
-
- @Test
- fun `preferences retain posts per page`() {
- preferences.newPostsPerPage = 15
- assertThat(preferences.postsPerPage, equalTo(15))
- }
-
- @Test(expected = IllegalArgumentException::class)
- fun `invalid posts per page is rejected`() {
- preferences.newPostsPerPage = -15
- }
-
- @Test
- fun `preferences return default value when posts per page is set to null`() {
- preferences.newPostsPerPage = null
- assertThat(preferences.postsPerPage, equalTo(10))
- }
-
- @Test
- fun `preferences start with posts per page default value`() {
- assertThat(preferences.postsPerPage, equalTo(10))
- }
-
- @Test
- fun `preferences retain images per page`() {
- preferences.newImagesPerPage = 15
- assertThat(preferences.imagesPerPage, equalTo(15))
- }
-
- @Test(expected = IllegalArgumentException::class)
- fun `invalid images per page is rejected`() {
- preferences.newImagesPerPage = -15
- }
-
- @Test
- fun `preferences return default value when images per page is set to null`() {
- preferences.newImagesPerPage = null
- assertThat(preferences.imagesPerPage, equalTo(9))
- }
-
- @Test
- fun `preferences start with images per page default value`() {
- assertThat(preferences.imagesPerPage, equalTo(9))
- }
-
- @Test
- fun `preferences retain characters per post`() {
- preferences.newCharactersPerPost = 150
- assertThat(preferences.charactersPerPost, equalTo(150))
- }
-
- @Test(expected = IllegalArgumentException::class)
- fun `invalid characters per post is rejected`() {
- preferences.newCharactersPerPost = -15
- }
-
- @Test
- fun `preferences return default value when characters per post is set to null`() {
- preferences.newCharactersPerPost = null
- assertThat(preferences.charactersPerPost, equalTo(400))
- }
-
- @Test
- fun `preferences start with characters per post default value`() {
- assertThat(preferences.charactersPerPost, equalTo(400))
- }
-
- @Test
- fun `preferences retain post cut off length`() {
- preferences.newPostCutOffLength = 150
- assertThat(preferences.postCutOffLength, equalTo(150))
- }
-
- @Test(expected = IllegalArgumentException::class)
- fun `invalid post cut off length is rejected`() {
- preferences.newPostCutOffLength = -15
- }
-
- @Test(expected = IllegalArgumentException::class)
- fun `cut off length of minus one is not allowed`() {
- preferences.newPostCutOffLength = -1
- }
-
- @Test
- fun `preferences return default value when post cut off length is set to null`() {
- preferences.newPostCutOffLength = null
- assertThat(preferences.postCutOffLength, equalTo(200))
- }
-
- @Test
- fun `preferences start with post cut off length default value`() {
- assertThat(preferences.postCutOffLength, equalTo(200))
- }
-
- @Test
- fun `preferences retain require full access of true`() {
- preferences.newRequireFullAccess = true
- assertThat(preferences.requireFullAccess, equalTo(true))
- }
-
- @Test
- fun `preferences retain require full access of false`() {
- preferences.newRequireFullAccess = false
- assertThat(preferences.requireFullAccess, equalTo(false))
- }
-
- @Test
- fun `preferences return default value when require full access is set to null`() {
- preferences.newRequireFullAccess = null
- assertThat(preferences.requireFullAccess, equalTo(false))
- }
-
- @Test
- fun `preferences start with require full access default value`() {
- assertThat(preferences.requireFullAccess, equalTo(false))
- }
-
- @Test
- fun `preferences retain fcp interface active of true`() {
- val events = mutableListOf<FcpInterfaceActivatedEvent>()
- eventBus.register(object {
- @Subscribe
- fun fcpInterfaceActivatedEvent(event: FcpInterfaceActivatedEvent) =
- events.add(event)
- })
- preferences.newFcpInterfaceActive = true
- assertThat(preferences.fcpInterfaceActive, equalTo(true))
- assertThat(events, hasItem<FcpInterfaceActivatedEvent>(instanceOf(FcpInterfaceActivatedEvent::class.java)))
- }
-
- @Test
- fun `preferences retain fcp interface active of false`() {
- val events = mutableListOf<FcpInterfaceDeactivatedEvent>()
- eventBus.register(object {
- @Subscribe
- fun fcpInterfaceDeactivatedEvent(event: FcpInterfaceDeactivatedEvent) =
- events.add(event)
- })
- preferences.newFcpInterfaceActive = false
- assertThat(preferences.fcpInterfaceActive, equalTo(false))
- assertThat(events, hasItem<FcpInterfaceDeactivatedEvent>(instanceOf(FcpInterfaceDeactivatedEvent::class.java)))
- }
-
- @Test
- fun `preferences return default value when fcp interface active is set to null`() {
- val events = mutableListOf<FcpInterfaceDeactivatedEvent>()
- eventBus.register(object {
- @Subscribe
- fun fcpInterfaceDeactivatedEvent(event: FcpInterfaceDeactivatedEvent) =
- events.add(event)
- })
- preferences.newFcpInterfaceActive = null
- assertThat(preferences.fcpInterfaceActive, equalTo(false))
- assertThat(events, hasItem<FcpInterfaceDeactivatedEvent>(instanceOf(FcpInterfaceDeactivatedEvent::class.java)))
- }
-
- @Test
- fun `preferences start with fcp interface active default value`() {
- assertThat(preferences.fcpInterfaceActive, equalTo(false))
- }
-
- @Test
- fun `preferences retain fcp full access required of no`() {
- verifyFullAccessRequiredChangedEvent(NO)
- }
-
- private fun verifyFullAccessRequiredChangedEvent(set: FullAccessRequired?, expected: FullAccessRequired = set!!) {
- val events = mutableListOf<FullAccessRequiredChanged>()
- eventBus.register(object {
- @Subscribe
- fun fullAccessRequiredChanged(event: FullAccessRequiredChanged) =
- events.add(event)
- })
- preferences.newFcpFullAccessRequired = set
- assertThat(preferences.fcpFullAccessRequired, equalTo(expected))
- assertThat(events.single().fullAccessRequired, equalTo(expected))
- }
-
- @Test
- fun `preferences retain fcp full access required of writing`() {
- verifyFullAccessRequiredChangedEvent(WRITING)
- }
-
- @Test
- fun `preferences retain fcp full access required of always`() {
- verifyFullAccessRequiredChangedEvent(ALWAYS)
- }
-
- @Test
- fun `preferences return default value when fcp full access required is set to null`() {
- verifyFullAccessRequiredChangedEvent(null, ALWAYS)
- }
-
- @Test
- fun `preferences start with fcp full access required default value`() {
- assertThat(preferences.fcpFullAccessRequired, equalTo(ALWAYS))
- }
-
- @Test
- fun `default strict filtering is false`() {
- assertThat(preferences.strictFiltering, equalTo(false))
- }
-
- @Test
- fun `strict filtering can be set`() {
- preferences.newStrictFiltering = true
- assertThat(preferences.strictFiltering, equalTo(true))
- }
-
- @Test
- fun `strict filtering returns to default on null`() {
- preferences.newStrictFiltering = true
- preferences.newStrictFiltering = null
- assertThat(preferences.strictFiltering, equalTo(false))
- }
-
- @Test
- fun `event is generated when strict filtering is activated`() {
- val events = mutableListOf<StrictFilteringActivatedEvent>()
- eventBus.register(object {
- @Subscribe fun strictFilteringActivatedEvent(event: StrictFilteringActivatedEvent) =
- events.add(event)
- })
- preferences.newStrictFiltering = true
- assertThat(events, hasItem<StrictFilteringActivatedEvent>(instanceOf(StrictFilteringActivatedEvent::class.java)))
- }
-
- @Test
- fun `event is generated when strict filtering is deactivated`() {
- val events = mutableListOf<StrictFilteringDeactivatedEvent>()
- eventBus.register(object {
- @Subscribe fun strictFilteringDeactivatedEvent(event: StrictFilteringDeactivatedEvent) =
- events.add(event)
- })
- preferences.newStrictFiltering = false
- assertThat(events, hasItem<StrictFilteringDeactivatedEvent>(instanceOf(StrictFilteringDeactivatedEvent::class.java)))
- }
-
- @Test
- fun `default strict filtering is saved as null`() {
- verifySavedOption(nullValue()) { it.getBooleanValue("Option/StrictFiltering").value }
- }
-
- @Test
- fun `activated strict filtering is saved as true`() {
- preferences.newStrictFiltering = true
- verifySavedOption(equalTo(true)) { it.getBooleanValue("Option/StrictFiltering").value }
- }
-
- @Test
- fun `deactivated strict filtering is saved as false`() {
- preferences.newStrictFiltering = false
- verifySavedOption(equalTo(false)) { it.getBooleanValue("Option/StrictFiltering").value }
- }
-
- private fun <T> verifySavedOption(matcher: Matcher<T>, getter: (Configuration) -> T) {
- val configuration = Configuration(MapConfigurationBackend())
- preferences.saveTo(configuration)
- assertThat(getter(configuration), matcher)
- }
-
-}
-
class PreferencesTest {
@Test
import net.pterodactylus.sone.test.assertThrows
import net.pterodactylus.sone.test.deepMock
import net.pterodactylus.sone.test.getInstance
+import net.pterodactylus.sone.test.isProvidedBy
import net.pterodactylus.sone.test.isProvidedByDeepMock
import net.pterodactylus.sone.test.isProvidedByMock
import net.pterodactylus.sone.test.mock
+import net.pterodactylus.sone.test.testPreferences
import net.pterodactylus.sone.test.verifySingletonInstance
import net.pterodactylus.sone.test.whenever
import net.pterodactylus.sone.web.SessionProvider
+++ /dev/null
-package net.pterodactylus.sone.utils
-
-import org.hamcrest.MatcherAssert.assertThat
-import org.hamcrest.Matchers.equalTo
-import org.hamcrest.Matchers.nullValue
-import org.hamcrest.Matchers.sameInstance
-import org.junit.Test
-
-/**
- * Unit test for [DefaultOption].
- */
-class DefaultOptionTest {
-
- private val defaultValue = Any()
- private val acceptedValue = Any()
- private val matchesAcceptedValue = { it: Any -> it == acceptedValue }
-
- @Test
- fun `default option returns default value when unset`() {
- val defaultOption = DefaultOption(defaultValue)
- assertThat(defaultOption.get(), sameInstance(defaultValue))
- }
-
- @Test
- fun `default option returns null for real when unset`() {
- val defaultOption = DefaultOption(defaultValue)
- assertThat(defaultOption.real, nullValue())
- }
-
- @Test
- fun `default option will return set value`() {
- val defaultOption = DefaultOption(defaultValue)
- val newValue = Any()
- defaultOption.set(newValue)
- assertThat(defaultOption.get(), sameInstance(newValue))
- }
-
- @Test
- fun `default option with validator accepts valid values`() {
- val defaultOption = DefaultOption(defaultValue, matchesAcceptedValue)
- defaultOption.set(acceptedValue)
- assertThat(defaultOption.get(), sameInstance(acceptedValue))
- }
-
- @Test(expected = IllegalArgumentException::class)
- fun `default option with validator rejects invalid values`() {
- val defaultOption = DefaultOption(defaultValue, matchesAcceptedValue)
- defaultOption.set(Any())
- }
-
- @Test
- fun `default option validates objects correctly`() {
- val defaultOption = DefaultOption(defaultValue, matchesAcceptedValue)
- assertThat(defaultOption.validate(acceptedValue), equalTo(true))
- assertThat(defaultOption.validate(Any()), equalTo(false))
- }
-
- @Test
- fun `setting to null will restore default value`() {
- val defaultOption = DefaultOption(defaultValue)
- defaultOption.set(null)
- assertThat(defaultOption.get(), sameInstance(defaultValue))
- }
-
- @Test
- fun `validate without validator will validate null`() {
- val defaultOption = DefaultOption(defaultValue)
- assertThat(defaultOption.validate(null), equalTo(true))
- }
-
- @Test
- fun `validate with validator will validate null`() {
- val defaultOption = DefaultOption(defaultValue, matchesAcceptedValue)
- assertThat(defaultOption.validate(null), equalTo(true))
- }
-
-}
package net.pterodactylus.sone.web.ajax
-import net.pterodactylus.sone.core.DefaultPreferences
import net.pterodactylus.sone.test.whenever
import net.pterodactylus.sone.web.page.FreenetRequest
import net.pterodactylus.util.web.Response
}
@Before
- fun setupCore() {
- whenever(core.preferences).thenReturn(DefaultPreferences(eventBus))
- }
-
- @Before
fun setupFreenetRequest() {
whenever(freenetRequest.toadletContext).thenReturn(toadletContext)
}
@Test
fun `page returns 403 is full access is required but request is not full access`() {
- core.preferences.newRequireFullAccess = true
+ core.preferences.requireFullAccess = true
page.handleRequest(freenetRequest, response)
assertThat(response.statusCode, equalTo(403))
assertThat(response.statusText, equalTo("Forbidden"))
import net.pterodactylus.sone.core.Core
import net.pterodactylus.sone.core.ElementLoader
import net.pterodactylus.sone.core.LinkedElement
-import net.pterodactylus.sone.core.DefaultPreferences
import net.pterodactylus.sone.core.UpdateChecker
import net.pterodactylus.sone.data.Album
import net.pterodactylus.sone.data.Image
import org.mockito.ArgumentMatchers
import java.util.*
import javax.naming.SizeLimitExceededException
+import net.pterodactylus.sone.core.withEvents
+import net.pterodactylus.sone.test.testPreferences
/**
* Base class for tests that supplies commonly used objects.
var formPassword = "form-password"
val core = mock<Core>()
val eventBus = mock<EventBus>()
- val preferences = DefaultPreferences(eventBus)
+ val preferences = testPreferences().withEvents(eventBus)
val updateChecker = mock<UpdateChecker>()
val elementLoader = mock<ElementLoader>()
val newElements = mock<NewElements>()
@Before
fun setupBookmarkedPostsAndPagination() {
whenever(core.bookmarkedPosts).thenReturn(setOf(post1, post2, post3))
- core.preferences.newPostsPerPage = 5
+ core.preferences.postsPerPage = 5
}
@Test
@Test
fun `create sone is not shown in menu if full access is required but client doesn’t have full access`() {
- core.preferences.newRequireFullAccess = true
+ core.preferences.requireFullAccess = true
assertThat(page.isEnabled(toadletContext), equalTo(false))
}
@Test
fun `create sone is shown in menu if no sone is logged in and client has full access`() {
- core.preferences.newRequireFullAccess = true
+ core.preferences.requireFullAccess = true
whenever(toadletContext.isAllowedFullAccess).thenReturn(true)
unsetCurrentSone()
assertThat(page.isEnabled(toadletContext), equalTo(true))
@Test
fun `get request for gallery can show second page`() {
- core.preferences.newImagesPerPage = 2
+ core.preferences.imagesPerPage = 2
val firstSone = createSone("first album", "second album")
addSone("sone1", firstSone)
val secondSone = createSone("third album", "fourth album")
fun `index page sets page correctly`() {
val posts = listOf(createPost(3000), createPost(2000), createPost(1000))
whenever(currentSone.posts).thenReturn(posts)
- core.preferences.newPostsPerPage = 1
+ core.preferences.postsPerPage = 1
addHttpRequestParameter("page", "2")
page.processTemplate(freenetRequest, templateContext)
@Suppress("UNCHECKED_CAST")
@Test
fun `index page without posts sets correct pagination`() {
- core.preferences.newPostsPerPage = 1
+ core.preferences.postsPerPage = 1
page.processTemplate(freenetRequest, templateContext)
@Suppress("UNCHECKED_CAST")
(templateContext["pagination"] as Pagination<Post>).let { pagination ->
@Test
fun `page is not enabled if full access required and request is not full access`() {
- core.preferences.newRequireFullAccess = true
+ core.preferences.requireFullAccess = true
assertThat(page.isEnabled(toadletContext), equalTo(false))
}
@Test
fun `page is enabled if full access required and request is full access and there is no current sone`() {
- core.preferences.newRequireFullAccess = true
+ core.preferences.requireFullAccess = true
unsetCurrentSone()
whenever(toadletContext.isAllowedFullAccess).thenReturn(true)
assertThat(page.isEnabled(toadletContext), equalTo(true))
@Test
fun `page is not enabled if full access required and request is full access but there is a current sone`() {
- core.preferences.newRequireFullAccess = true
+ core.preferences.requireFullAccess = true
whenever(toadletContext.isAllowedFullAccess).thenReturn(true)
assertThat(page.isEnabled(toadletContext), equalTo(false))
}
@Test
fun `page is not enabled if sone requires full access and request does not have full access`() {
- core.preferences.newRequireFullAccess = true
+ core.preferences.requireFullAccess = true
assertThat(page.isEnabled(toadletContext), equalTo(false))
}
@Test
fun `page is enabled if full access is required and present and sone is logged in and there is more than one sone`() {
- core.preferences.newRequireFullAccess = true
+ core.preferences.requireFullAccess = true
whenever(toadletContext.isAllowedFullAccess).thenReturn(true)
whenever(core.localSones).thenReturn(listOf(currentSone, currentSone))
assertThat(page.isEnabled(toadletContext), equalTo(true))
@Before
fun setupNumberOfPostsPerPage() {
- webInterface.core.preferences.newPostsPerPage = 5
+ webInterface.core.preferences.postsPerPage = 5
}
@Test
@Test
@Suppress("UNCHECKED_CAST")
fun `posts are paginated properly`() {
- webInterface.core.preferences.newPostsPerPage = 2
+ webInterface.core.preferences.postsPerPage = 2
val posts = listOf(mock<Post>().withTime(2000), mock<Post>().withTime(3000), mock<Post>().withTime(1000))
whenever(newElements.newPosts).thenReturn(posts)
verifyNoRedirect {
@Test
@Suppress("UNCHECKED_CAST")
fun `posts are paginated properly on second page`() {
- webInterface.core.preferences.newPostsPerPage = 2
+ webInterface.core.preferences.postsPerPage = 2
addHttpRequestParameter("page", "1")
val posts = listOf(mock<Post>().withTime(2000), mock<Post>().withTime(3000), mock<Post>().withTime(1000))
whenever(newElements.newPosts).thenReturn(posts)
@Before
fun setupPreferences() {
- core.preferences.newInsertionDelay = 1
- core.preferences.newCharactersPerPost = 50
- core.preferences.newFcpFullAccessRequired = WRITING
- core.preferences.newImagesPerPage = 4
- core.preferences.newFcpInterfaceActive = true
- core.preferences.newRequireFullAccess = true
- core.preferences.newPostCutOffLength = 51
- core.preferences.newPostsPerPage = 10
- core.preferences.newStrictFiltering = true
+ core.preferences.insertionDelay = 1
+ core.preferences.charactersPerPost = 50
+ core.preferences.fcpFullAccessRequired = WRITING
+ core.preferences.imagesPerPage = 4
+ core.preferences.fcpInterfaceActive = true
+ core.preferences.requireFullAccess = true
+ core.preferences.postCutOffLength = 51
+ core.preferences.postsPerPage = 10
+ core.preferences.strictFiltering = true
}
@Before
@Test
fun `sone hits are paginated correctly`() {
- core.preferences.newPostsPerPage = 2
+ core.preferences.postsPerPage = 2
val sones = listOf(createSone("1Sone"), createSone("Other1"), createSone("22Sone"), createSone("333Sone"), createSone("Other2"))
.onEach { addSone(it.id, it) }
addHttpRequestParameter("query", "sone")
@Test
fun `sone hits page 2 is shown correctly`() {
- core.preferences.newPostsPerPage = 2
+ core.preferences.postsPerPage = 2
val sones = listOf(createSone("1Sone"), createSone("Other1"), createSone("22Sone"), createSone("333Sone"), createSone("Other2"))
.onEach { addSone(it.id, it) }
addHttpRequestParameter("query", "sone")
@Test
fun `post hits are paginated correctly`() {
- core.preferences.newPostsPerPage = 2
+ core.preferences.postsPerPage = 2
val sones = listOf(createSoneWithPost("match1", "1Sone"), createSoneWithPost("no-match1", "Other1"), createSoneWithPost("match2", "22Sone"), createSoneWithPost("match3", "333Sone"), createSoneWithPost("no-match2", "Other2"))
addHttpRequestParameter("query", "sone")
verifyNoRedirect {
@Test
fun `post hits page 2 is shown correctly`() {
- core.preferences.newPostsPerPage = 2
+ core.preferences.postsPerPage = 2
val sones = listOf(createSoneWithPost("match1", "1Sone"), createSoneWithPost("no-match1", "Other1"), createSoneWithPost("match2", "22Sone"), createSoneWithPost("match3", "333Sone"), createSoneWithPost("no-match2", "Other2"))
addHttpRequestParameter("query", "sone")
addHttpRequestParameter("postPage", "1")
@Test
fun `preferences are set in template context`() {
- verifyVariableIsSet("preferences", preferences)
+ verifyVariableMatches("preferences", notNullValue())
}
@Test
@Test
fun `page is disabled if full access is required but request does not have full access`() {
- core.preferences.newRequireFullAccess = true
+ core.preferences.requireFullAccess = true
assertThat(page.isEnabled(toadletContext), equalTo(false))
}
@Test
fun `page is enabled if full access is required and request has full access and login is required and there is a current sone`() {
- core.preferences.newRequireFullAccess = true
+ core.preferences.requireFullAccess = true
whenever(toadletContext.isAllowedFullAccess).thenReturn(true)
assertThat(page.isEnabled(toadletContext), equalTo(true))
}
fun setup() {
whenever(currentSone.posts).thenReturn(mutableListOf(post2, post1))
whenever(core.getDirectedPosts("sone-id")).thenReturn(setOf(directed1, directed2))
- core.preferences.newPostsPerPage = 2
+ core.preferences.postsPerPage = 2
}
@Test
import java.nio.charset.*
import java.util.*
import kotlin.text.Charsets.UTF_8
+import net.pterodactylus.sone.test.testPreferences
/**
* Base class for web page tests.
val webInterface = deepMock<WebInterface>()
val core = webInterface.core
val eventBus = mock<EventBus>()
- val preferences = DefaultPreferences(eventBus)
+ val preferences = testPreferences().withEvents(eventBus)
open val page by lazy { pageSupplier(webInterface, loaders, templateRenderer) }