🔀 Merge “release/v81” into “master”
[Sone.git] / src / test / kotlin / net / pterodactylus / sone / main / SoneModuleTest.kt
1 package net.pterodactylus.sone.main
2
3 import com.codahale.metrics.*
4 import com.google.common.base.*
5 import com.google.common.eventbus.*
6 import com.google.inject.Guice.*
7 import com.google.inject.name.Names.*
8 import freenet.l10n.*
9 import net.pterodactylus.sone.core.*
10 import net.pterodactylus.sone.database.*
11 import net.pterodactylus.sone.database.memory.*
12 import net.pterodactylus.sone.freenet.*
13 import net.pterodactylus.sone.freenet.plugin.*
14 import net.pterodactylus.sone.freenet.wot.*
15 import net.pterodactylus.sone.test.*
16 import net.pterodactylus.util.config.*
17 import net.pterodactylus.util.version.Version
18 import org.hamcrest.MatcherAssert.*
19 import org.hamcrest.Matchers.*
20 import org.junit.experimental.categories.*
21 import org.mockito.Mockito.*
22 import java.io.*
23 import java.util.concurrent.*
24 import java.util.concurrent.atomic.*
25 import kotlin.test.*
26
27 const val versionString = "v80"
28
29 @Category(NotParallel::class)
30 class SoneModuleTest {
31
32         private val currentDir: File = File(".")
33         private val pluginVersion = Version("", 80)
34         private val pluginYear = 2019
35         private val pluginHomepage = "home://page"
36         private val l10n = deepMock<PluginL10n>()
37         private val sonePlugin = mock<SonePlugin>().apply {
38                 whenever(version).thenReturn(versionString)
39                 whenever(year).thenReturn(pluginYear)
40                 whenever(homepage).thenReturn(pluginHomepage)
41                 whenever(l10n()).thenReturn(l10n)
42         }
43
44         private val injector by lazy {
45                 createInjector(
46                                 SoneModule(sonePlugin, EventBus()),
47                                 FreenetInterface::class.isProvidedByDeepMock(),
48                                 PluginRespiratorFacade::class.isProvidedByDeepMock(),
49                                 PluginConnector::class.isProvidedByDeepMock()
50                 )
51         }
52
53         @AfterTest
54         fun removePropertiesFromCurrentDirectory() {
55                 File(currentDir, "sone.properties").delete()
56         }
57
58         @Test
59         fun `creator binds configuration when no file is present`() {
60                 File(currentDir, "sone.properties").delete()
61                 assertThat(injector.getInstance<Configuration>(), notNullValue())
62         }
63
64         @Test
65         fun `creator binds first start to true when no file is present`() {
66                 File(currentDir, "sone.properties").delete()
67                 assertThat(injector.getInstance(named("FirstStart")), equalTo(true))
68         }
69
70         @Test
71         fun `config file is created in current directory if not present`() {
72                 File(currentDir, "sone.properties").delete()
73                 val configuration = injector.getInstance<Configuration>()
74                 configuration.save()
75                 assertThat(File(currentDir, "sone.properties").exists(), equalTo(true))
76         }
77
78         @Test
79         fun `creator binds configuration when file is present`() {
80                 File(currentDir, "sone.properties").writeText("Option=old")
81                 assertThat(injector.getInstance<Configuration>().getStringValue("Option").value, equalTo("old"))
82         }
83
84         @Test
85         fun `creator binds first start to false when file is present`() {
86                 File(currentDir, "sone.properties").writeText("Option=old")
87                 assertThat(injector.getInstance(named("FirstStart")), equalTo(false))
88         }
89
90         @Test
91         fun `invalid config file leads to new config being created`() {
92                 File(currentDir, "sone.properties").writeText("Option=old\nbroken")
93                 val configuration = injector.getInstance<Configuration>()
94                 assertThat(configuration.getStringValue("Option").getValue(null), nullValue())
95         }
96
97         @Test
98         fun `invalid config file leads to new config being set to true`() {
99                 File(currentDir, "sone.properties").writeText("Option=old\nbroken")
100                 assertThat(injector.getInstance(named("NewConfig")), equalTo(true))
101         }
102
103         @Test
104         fun `valid config file leads to new config being set to false`() {
105                 File(currentDir, "sone.properties").writeText("Option=old")
106                 assertThat(injector.getInstance(named("NewConfig")), equalTo(false))
107         }
108
109         @Test
110         fun `event bus is bound`() {
111                 assertThat(injector.getInstance<EventBus>(), notNullValue())
112         }
113
114         @Test
115         fun `context is bound`() {
116                 assertThat(injector.getInstance<Context>().context, equalTo("Sone"))
117         }
118
119         @Test
120         fun `optional context is bound`() {
121                 assertThat(injector.getInstance<Optional<Context>>().get().context, equalTo("Sone"))
122         }
123
124         @Test
125         fun `sone plugin is bound`() {
126                 assertThat(injector.getInstance(), sameInstance(sonePlugin))
127         }
128
129         @Test
130         fun `version is bound`() {
131                 assertThat(injector.getInstance(), equalTo(pluginVersion))
132         }
133
134         @Test
135         fun `plugin version is bound`() {
136                 assertThat(injector.getInstance(), equalTo(PluginVersion(versionString)))
137         }
138
139         @Test
140         fun `plugin year is bound`() {
141                 assertThat(injector.getInstance(), equalTo(PluginYear(pluginYear)))
142         }
143
144         @Test
145         fun `plugin homepage in bound`() {
146                 assertThat(injector.getInstance(), equalTo(PluginHomepage(pluginHomepage)))
147         }
148
149         @Test
150         fun `database is bound correctly`() {
151                 assertThat(injector.getInstance<Database>(), instanceOf(MemoryDatabase::class.java))
152         }
153
154         @Test
155         fun `translation is bound correctly`() {
156                 assertThat(injector.getInstance<Translation>(), notNullValue())
157         }
158
159         @Test
160         fun `default loader is used without dev options`() {
161                 assertThat(injector.getInstance<Loaders>(), instanceOf(DefaultLoaders::class.java))
162         }
163
164         @Test
165         fun `default loaders are used if no path is given`() {
166                 File(currentDir, "sone.properties").writeText("Developer.LoadFromFilesystem=true")
167                 assertThat(injector.getInstance<Loaders>(), instanceOf(DefaultLoaders::class.java))
168         }
169
170         @Test
171         fun `debug loaders are used if path is given`() {
172                 File(currentDir, "sone.properties").writeText("Developer.LoadFromFilesystem=true\nDeveloper.FilesystemPath=/tmp")
173                 assertThat(injector.getInstance<Loaders>(), instanceOf(DebugLoaders::class.java))
174         }
175
176         class TestObject {
177                 val ref: AtomicReference<Any?> = AtomicReference()
178                 @Subscribe
179                 fun testEvent(event: Any?) {
180                         ref.set(event)
181                 }
182         }
183
184         @Test
185         fun `created objects are registered with event bus`() {
186                 val eventBus: EventBus = injector.getInstance()
187                 val testObject = injector.getInstance<TestObject>()
188                 val event = Any()
189                 eventBus.post(event)
190                 assertThat(testObject.ref.get(), sameInstance(event))
191         }
192
193         @Test
194         fun `core is created as singleton`() {
195                 injector.verifySingletonInstance<Core>()
196         }
197
198         @Test
199         fun `core is registered with event bus`() {
200                 val eventBus = mock<EventBus>()
201                 val injector = createInjector(
202                                 SoneModule(sonePlugin, eventBus),
203                                 FreenetInterface::class.isProvidedByDeepMock(),
204                                 PluginRespiratorFacade::class.isProvidedByDeepMock(),
205                                 PluginConnector::class.isProvidedByDeepMock()
206                 )
207                 val core = injector.getInstance<Core>()
208                 verify(eventBus).register(core)
209         }
210
211         @Test
212         fun `metrics registry is created as singleton`() {
213                 injector.verifySingletonInstance<MetricRegistry>()
214         }
215
216         @Test
217         fun `wot connector is created as singleton`() {
218                 injector.verifySingletonInstance<WebOfTrustConnector>()
219         }
220
221         @Test
222         fun `notification ticker is created as singleton`() {
223                 injector.verifySingletonInstance<ScheduledExecutorService>(named("notification"))
224         }
225
226         @Test
227         fun `ticker shutdown is created as singleton`() {
228                 injector.verifySingletonInstance<TickerShutdown>()
229         }
230
231 }