From: David ‘Bombe’ Roden Date: Sun, 10 Mar 2019 20:29:32 +0000 (+0100) Subject: ♻️ Add module for configuring the web interface X-Git-Tag: v79^2~72 X-Git-Url: https://git.pterodactylus.net/?p=Sone.git;a=commitdiff_plain;h=b5fed0f19bfb57f96574b65f0180a8ebb81c043b ♻️ Add module for configuring the web interface --- diff --git a/src/main/kotlin/net/pterodactylus/sone/web/WebInterfaceModule.kt b/src/main/kotlin/net/pterodactylus/sone/web/WebInterfaceModule.kt new file mode 100644 index 0000000..16f6e86 --- /dev/null +++ b/src/main/kotlin/net/pterodactylus/sone/web/WebInterfaceModule.kt @@ -0,0 +1,123 @@ +package net.pterodactylus.sone.web + +import com.google.inject.* +import freenet.l10n.* +import freenet.support.api.* +import net.pterodactylus.sone.core.* +import net.pterodactylus.sone.data.* +import net.pterodactylus.sone.database.* +import net.pterodactylus.sone.freenet.* +import net.pterodactylus.sone.freenet.wot.* +import net.pterodactylus.sone.main.* +import net.pterodactylus.sone.template.* +import net.pterodactylus.sone.text.* +import net.pterodactylus.util.template.* +import javax.inject.Singleton + +class WebInterfaceModule : AbstractModule() { + + @Provides + @Singleton + fun getTemplateContextFactory( + soneAccessor: SoneAccessor, + postAccessor: PostAccessor, + replyAccessor: ReplyAccessor, + identityAccessor: IdentityAccessor, + profileAccessor: ProfileAccessor, + l10nFilter: L10nFilter, + parserFilter: ParserFilter, + renderFilter: RenderFilter, + linkedElementsFilter: LinkedElementsFilter, + unknownDateFilter: UnknownDateFilter, + imageLinkFilter: ImageLinkFilter, + loaders: Loaders + ) = + TemplateContextFactory().apply { + addAccessor(Any::class.java, ReflectionAccessor()) + addAccessor(Collection::class.java, CollectionAccessor()) + addAccessor(Sone::class.java, soneAccessor) + addAccessor(Post::class.java, postAccessor) + addAccessor(Reply::class.java, replyAccessor) + addAccessor(Album::class.java, AlbumAccessor()) + addAccessor(Image::class.java, ImageAccessor()) + addAccessor(Identity::class.java, identityAccessor) + addAccessor(Trust::class.java, TrustAccessor()) + addAccessor(HTTPRequest::class.java, HttpRequestAccessor()) + addAccessor(Profile::class.java, profileAccessor) + + addFilter("date", DateFilter()) + addFilter("html", HtmlFilter()) + addFilter("replace", ReplaceFilter()) + addFilter("store", StoreFilter()) + addFilter("l10n", l10nFilter) + addFilter("substring", SubstringFilter()) + addFilter("xml", XmlFilter()) + addFilter("change", RequestChangeFilter()) + addFilter("match", MatchFilter()) + addFilter("css", CssClassNameFilter()) + addFilter("js", JavascriptFilter()) + addFilter("parse", parserFilter) + addFilter("shorten", ShortenFilter()) + addFilter("render", renderFilter) + addFilter("linked-elements", linkedElementsFilter) + addFilter("render-linked-element", LinkedElementRenderFilter()) + addFilter("reparse", ReparseFilter()) + addFilter("unknown", unknownDateFilter) + addFilter("format", FormatFilter()) + addFilter("sort", CollectionSortFilter()) + addFilter("image-link", imageLinkFilter) + addFilter("replyGroup", ReplyGroupFilter()) + addFilter("in", ContainsFilter()) + addFilter("unique", UniqueElementFilter()) + addFilter("mod", ModFilter()) + addFilter("paginate", PaginationFilter()) + + addProvider(TemplateProvider.TEMPLATE_CONTEXT_PROVIDER) + addProvider(loaders.templateProvider) + } + + @Provides + fun getSoneAccessor(core: Core, timeTextConverter: TimeTextConverter) = + SoneAccessor(core, timeTextConverter) + + @Provides + fun getPostAccessor(core: Core) = + PostAccessor(core) + + @Provides + fun getReplyAccessor(core: Core) = + ReplyAccessor(core) + + @Provides + fun getIdentityAccessor(core: Core) = + IdentityAccessor(core) + + @Provides + fun getProfileAccessor(core: Core) = + ProfileAccessor(core) + + @Provides + fun getL10nFilter(l10n: BaseL10n) = + L10nFilter(l10n) + + @Provides + fun getParserFilter(core: Core, soneTextParser: SoneTextParser) = + ParserFilter(core, soneTextParser) + + @Provides + fun getRenderFilter(soneProvider: SoneProvider, soneTextParser: SoneTextParser, htmlFilter: HtmlFilter) = + RenderFilter(soneProvider, soneTextParser, htmlFilter) + + @Provides + fun getLinkedElementsFilter(elementLoader: ElementLoader) = + LinkedElementsFilter(elementLoader) + + @Provides + fun getUnknownDateFilter(l10n: BaseL10n) = + UnknownDateFilter(l10n, "View.Sone.Text.UnknownDate") + + @Provides + fun getImageLinkFilter(core: Core) = + ImageLinkFilter(core) + +} diff --git a/src/test/kotlin/net/pterodactylus/sone/web/WebInterfaceModuleTest.kt b/src/test/kotlin/net/pterodactylus/sone/web/WebInterfaceModuleTest.kt new file mode 100644 index 0000000..fc8964a --- /dev/null +++ b/src/test/kotlin/net/pterodactylus/sone/web/WebInterfaceModuleTest.kt @@ -0,0 +1,260 @@ +package net.pterodactylus.sone.web + +import com.google.inject.Guice.* +import freenet.l10n.* +import freenet.support.api.* +import net.pterodactylus.sone.core.* +import net.pterodactylus.sone.data.* +import net.pterodactylus.sone.database.* +import net.pterodactylus.sone.freenet.* +import net.pterodactylus.sone.freenet.wot.* +import net.pterodactylus.sone.main.* +import net.pterodactylus.sone.template.* +import net.pterodactylus.sone.test.* +import net.pterodactylus.sone.text.* +import net.pterodactylus.util.template.* +import org.hamcrest.MatcherAssert.* +import org.hamcrest.Matchers.* +import org.junit.* + +class WebInterfaceModuleTest { + + private val webInterfaceModule = WebInterfaceModule() + private val l10n = mock() + private val loaders = mock() + private val additionalModules = arrayOf( + Core::class.isProvidedByMock(), + SoneProvider::class.isProvidedByMock(), + BaseL10n::class.isProvidedBy(l10n), + SoneTextParser::class.isProvidedByMock(), + ElementLoader::class.isProvidedByMock(), + Loaders::class.isProvidedBy(loaders) + ) + private val injector = createInjector(webInterfaceModule, *additionalModules)!! + private val templateContext by lazy { injector.getInstance().createTemplateContext()!! } + + @Test + fun `template context factory creates template with reflection accessor for objects`() { + verifyAccessor() + } + + @Test + fun `template context factory creates template with collection accessor for collections`() { + verifyAccessor, CollectionAccessor>() + } + + @Test + fun `template context contains sone accessor for sones`() { + verifyAccessor() + } + + @Test + fun `template context contains post accessor for posts`() { + verifyAccessor() + } + + @Test + fun `template context contains reply accessor for replies`() { + verifyAccessor, ReplyAccessor>() + } + + @Test + fun `template context contains album accessor for albums`() { + verifyAccessor() + } + + @Test + fun `template context contains image accessor for images`() { + verifyAccessor() + } + + @Test + fun `template context contains identity accessor for identities`() { + verifyAccessor() + } + + @Test + fun `template context contains trust accessor for trusts`() { + verifyAccessor() + } + + @Test + fun `template context contains http request accessor for http requests`() { + verifyAccessor() + } + + @Test + fun `template context contains profile accessor for profiles`() { + verifyAccessor() + } + + private inline fun verifyAccessor() { + assertThat(templateContext.getAccessor(O::class.java), instanceOf(A::class.java)) + } + + @Test + fun `template context contains date filter`() { + verifyFilter("date") + } + + @Test + fun `template context contains html filter`() { + verifyFilter("html") + } + + @Test + fun `template context contains replace filter`() { + verifyFilter("replace") + } + + @Test + fun `template context contains store filter`() { + verifyFilter("store") + } + + @Test + fun `template context contains l10n filter`() { + verifyFilter("l10n") + } + + @Test + fun `template context contains substring filter`() { + verifyFilter("substring") + } + + @Test + fun `template context contains xml filter`() { + verifyFilter("xml") + } + + @Test + fun `template context contains change filter`() { + verifyFilter("change") + } + + @Test + fun `template context contains match filter`() { + verifyFilter("match") + } + + @Test + fun `template context contains css filter`() { + verifyFilter("css") + } + + @Test + fun `template context contains js filter`() { + verifyFilter("js") + } + + @Test + fun `template context contains parser filter`() { + verifyFilter("parse") + } + + @Test + fun `template context contains shorten filter`() { + verifyFilter("shorten") + } + + @Test + fun `template context contains render filter`() { + verifyFilter("render") + } + + @Test + fun `template context contains linked elements filter`() { + verifyFilter("linked-elements") + } + + @Test + fun `template context contains linked elements render filter`() { + verifyFilter("render-linked-element") + } + + @Test + fun `template context contains reparse filter`() { + verifyFilter("reparse") + } + + @Test + fun `template context contains unknown date filter`() { + verifyFilter("unknown") + } + + @Test + fun `unknown date filter uses correct l10n key`() { + whenever(l10n.getString("View.Sone.Text.UnknownDate")).thenReturn("unknown") + assertThat(getFilter("unknown")!!.format(null, 0L, emptyMap()), equalTo("unknown")) + } + + @Test + fun `template context contains format filter`() { + verifyFilter("format") + } + + @Test + fun `template context contains collection sort filter`() { + verifyFilter("sort") + } + + @Test + fun `template context contains image link filter`() { + verifyFilter("image-link") + } + + @Test + fun `template context contains reply group filter`() { + verifyFilter("replyGroup") + } + + @Test + fun `template context contains contains filter`() { + verifyFilter("in") + } + + @Test + fun `template context unique elements filter`() { + verifyFilter("unique") + } + + @Test + fun `template context mod filter`() { + verifyFilter("mod") + } + + @Test + fun `template context pagination filter`() { + verifyFilter("paginate") + } + + private inline fun verifyFilter(name: String) { + assertThat(getFilter(name), instanceOf(F::class.java)) + } + + private fun getFilter(name: String): Filter? = templateContext.getFilter(name) + + @Test + fun `template context factory is created as singleton`() { + val factory1 = injector.getInstance() + val factory2 = injector.getInstance() + assertThat(factory1, sameInstance(factory2)) + } + + @Test + fun `template from classpath is returned`() { + val template = Template() + templateContext["testTemplate"] = template + assertThat(templateContext.getTemplate("testTemplate"), sameInstance(template)) + } + + @Test + fun `template from loaders’ provider is returned`() { + val template = Template() + whenever(loaders.templateProvider).thenReturn(TemplateProvider { _, templateName -> + template.takeIf { templateName == "testTemplate" } + }) + assertThat(templateContext.getTemplate("testTemplate"), sameInstance(template)) + } + +}