1 package net.pterodactylus.sone.main
3 import com.google.common.eventbus.*
4 import com.google.inject.*
5 import freenet.client.async.*
6 import freenet.l10n.BaseL10n.LANGUAGE.*
8 import freenet.pluginmanager.*
9 import net.pterodactylus.sone.core.*
10 import net.pterodactylus.sone.core.event.*
11 import net.pterodactylus.sone.fcp.*
12 import net.pterodactylus.sone.freenet.wot.*
13 import net.pterodactylus.sone.test.*
14 import net.pterodactylus.sone.web.*
15 import net.pterodactylus.sone.web.notification.*
16 import org.hamcrest.MatcherAssert.*
17 import org.hamcrest.Matchers.*
18 import org.mockito.Mockito.*
20 import java.util.concurrent.atomic.*
24 * Unit test for [SonePlugin].
27 class SonePluginTest {
29 private var sonePlugin = SonePlugin { injector }
30 private val pluginRespirator = deepMock<PluginRespirator>()
31 private val node = deepMock<Node>()
32 private val clientCore = deepMock<NodeClientCore>()
33 private val uskManager = deepMock<USKManager>()
36 setField(node, "clientCore", clientCore)
37 whenever(pluginRespirator.node).thenReturn(node)
38 setField(clientCore, "uskManager", uskManager)
42 fun `sone plugin can be started`() {
43 sonePlugin.setLanguage(ENGLISH)
44 sonePlugin.runPlugin(pluginRespirator)
48 fun `core can be created`() {
49 val injector: Injector = runSonePluginWithRealInjector()
50 assertThat(injector.getInstance<Core>(), notNullValue())
54 fun `fcp interface can be created`() {
55 val injector: Injector = runSonePluginWithRealInjector()
56 assertThat(injector.getInstance<FcpInterface>(), notNullValue())
60 fun `web interface can be created`() {
61 val injector: Injector = runSonePluginWithRealInjector()
62 assertThat(injector.getInstance<WebInterface>(), notNullValue())
66 fun `web of trust connector can be created`() {
67 val injector: Injector = runSonePluginWithRealInjector()
68 assertThat(injector.getInstance<WebOfTrustConnector>(), notNullValue())
72 fun `notification handler can be created`() {
73 val injector: Injector = runSonePluginWithRealInjector()
74 assertThat(injector.getInstance<NotificationHandler>(), notNullValue())
77 private fun runSonePluginWithRealInjector(injectorConsumer: (Injector) -> Unit = {}): Injector {
78 lateinit var injector: Injector
79 sonePlugin = SonePlugin {
80 Guice.createInjector(*it).also {
85 sonePlugin.setLanguage(ENGLISH)
86 sonePlugin.runPlugin(pluginRespirator)
91 fun `core is being started`() {
92 sonePlugin.runPlugin(pluginRespirator)
93 val core = injector.getInstance<Core>()
98 fun `notification handler is being requested`() {
99 sonePlugin.runPlugin(pluginRespirator)
100 assertThat(getInjected(NotificationHandler::class.java), notNullValue())
104 fun `ticker shutdown is being requested`() {
105 sonePlugin.runPlugin(pluginRespirator)
106 assertThat(getInjected(TickerShutdown::class.java), notNullValue())
109 private class FirstStartListener(private val firstStartReceived: AtomicBoolean) {
111 fun firstStart(firstStart: FirstStart) {
112 firstStartReceived.set(true)
117 fun `first-start event is sent to event bus when first start is true`() {
118 File("sone.properties").delete()
119 val firstStartReceived = AtomicBoolean()
120 runSonePluginWithRealInjector {
121 val eventBus = it.getInstance(EventBus::class.java)
122 eventBus.register(FirstStartListener(firstStartReceived))
124 assertThat(firstStartReceived.get(), equalTo(true))
128 fun `first-start event is not sent to event bus when first start is false`() {
129 File("sone.properties").deleteAfter {
131 val firstStartReceived = AtomicBoolean()
132 runSonePluginWithRealInjector {
133 val eventBus = it.getInstance(EventBus::class.java)
134 eventBus.register(FirstStartListener(firstStartReceived))
136 assertThat(firstStartReceived.get(), equalTo(false))
140 private class ConfigNotReadListener(private val configNotReadReceiver: AtomicBoolean) {
142 fun configNotRead(configNotRead: ConfigNotRead) {
143 configNotReadReceiver.set(true)
148 fun `config-not-read event is sent to event bus when new config is true`() {
149 File("sone.properties").deleteAfter {
151 val configNotReadReceived = AtomicBoolean()
152 runSonePluginWithRealInjector {
153 val eventBus = it.getInstance(EventBus::class.java)
154 eventBus.register(ConfigNotReadListener(configNotReadReceived))
156 assertThat(configNotReadReceived.get(), equalTo(true))
161 fun `config-not-read event is not sent to event bus when first start is true`() {
162 File("sone.properties").delete()
163 val configNotReadReceived = AtomicBoolean()
164 runSonePluginWithRealInjector {
165 val eventBus = it.getInstance(EventBus::class.java)
166 eventBus.register(ConfigNotReadListener(configNotReadReceived))
168 assertThat(configNotReadReceived.get(), equalTo(false))
172 fun `config-not-read event is not sent to event bus when new config is false`() {
173 File("sone.properties").deleteAfter {
174 writeText("# comment")
175 val configNotReadReceived = AtomicBoolean()
176 runSonePluginWithRealInjector {
177 val eventBus = it.getInstance(EventBus::class.java)
178 eventBus.register(ConfigNotReadListener(configNotReadReceived))
180 assertThat(configNotReadReceived.get(), equalTo(false))
184 private class StartupListener(private val startupReceived: () -> Unit) {
186 fun startup(startup: Startup) {
192 fun `startup event is sent to event bus`() {
193 val startupReceived = AtomicBoolean()
194 runSonePluginWithRealInjector {
195 val eventBus = it.getInstance(EventBus::class.java)
196 eventBus.register(StartupListener { startupReceived.set(true) })
198 assertThat(startupReceived.get(), equalTo(true))
201 private class ShutdownListener(private val shutdownReceived: () -> Unit) {
203 fun shutdown(shutdown: Shutdown) {
209 fun `shutdown event is sent to event bus on terminate`() {
210 val shutdownReceived = AtomicBoolean()
211 runSonePluginWithRealInjector {
212 val eventBus = it.getInstance(EventBus::class.java)
213 eventBus.register(ShutdownListener { shutdownReceived.set(true) })
215 sonePlugin.terminate()
216 assertThat(shutdownReceived.get(), equalTo(true))
219 private fun <T> getInjected(clazz: Class<T>, annotation: Annotation? = null): T? =
220 injected[TypeLiteral.get(clazz) to annotation] as? T
222 private val injected =
223 mutableMapOf<Pair<TypeLiteral<*>, Annotation?>, Any>()
225 private val injector = mock<Injector>().apply {
226 fun mockValue(clazz: Class<*>) = false.takeIf { clazz.name == java.lang.Boolean::class.java.name } ?: mock(clazz)
227 whenever(getInstance(any<Key<*>>())).then {
228 injected.getOrPut((it.getArgument(0) as Key<*>).let { it.typeLiteral to it.annotation }) {
229 it.getArgument<Key<*>>(0).typeLiteral.type.typeName.toClass().let(::mockValue)
232 whenever(getInstance(any<Class<*>>())).then {
233 injected.getOrPut(TypeLiteral.get(it.getArgument(0) as Class<*>) to null) {
234 it.getArgument<Class<*>>(0).let(::mockValue)
241 private fun String.toClass(): Class<*> = SonePlugin::class.java.classLoader.loadClass(this)
243 private fun File.deleteAfter(action: File.() -> Unit) = try {