From 5201720801a4053f8f324b71fb3e9c36f6cd911e Mon Sep 17 00:00:00 2001 From: =?utf8?q?David=20=E2=80=98Bombe=E2=80=99=20Roden?= Date: Mon, 27 May 2019 07:11:23 +0200 Subject: [PATCH] =?utf8?q?=E2=99=BB=EF=B8=8F=20Add=20factory=20for=20page?= =?utf8?q?=20maker=20interactions?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- .../sone/web/page/FreenetTemplatePage.kt | 18 ++++++-------- .../sone/web/page/PageMakerInteractionFactory.kt | 18 ++++++++++++++ .../java/net/pterodactylus/sone/test/TestUtil.java | 4 ++++ .../java/net/pterodactylus/sone/test/TestUtils.kt | 19 +++++++++++++++ .../sone/web/page/FreenetTemplatePageTest.kt | 17 +++++++++++++ .../web/page/PageMakerInteractionFactoryTest.kt | 28 ++++++++++++++++++++++ 6 files changed, 93 insertions(+), 11 deletions(-) create mode 100644 src/main/kotlin/net/pterodactylus/sone/web/page/PageMakerInteractionFactory.kt create mode 100644 src/test/java/net/pterodactylus/sone/test/TestUtils.kt create mode 100644 src/test/kotlin/net/pterodactylus/sone/web/page/PageMakerInteractionFactoryTest.kt diff --git a/src/main/kotlin/net/pterodactylus/sone/web/page/FreenetTemplatePage.kt b/src/main/kotlin/net/pterodactylus/sone/web/page/FreenetTemplatePage.kt index 8cf5f61..d5d8f06 100644 --- a/src/main/kotlin/net/pterodactylus/sone/web/page/FreenetTemplatePage.kt +++ b/src/main/kotlin/net/pterodactylus/sone/web/page/FreenetTemplatePage.kt @@ -36,6 +36,7 @@ open class FreenetTemplatePage( private val invalidFormPasswordRedirectTarget: String ) : FreenetPage, LinkEnabledCallback { + private val pageMakerInteractionFactory: PageMakerInteractionFactory = DefaultPageMakerInteractionFactory() open val styleSheets: Collection = emptySet() open val shortcutIcon: String? get() = null open val isFullAccessOnly get() = false @@ -70,16 +71,11 @@ open class FreenetTemplatePage( return RedirectResponse(invalidFormPasswordRedirectTarget) } } - val pageMaker = toadletContext.pageMaker - val pageNode = pageMaker.getPageNode(getPageTitle(request), toadletContext) - styleSheets.forEach(pageNode::addCustomStyleSheet) - getAdditionalLinkNodes(request) - .map { it to pageNode.headNode.addChild("link") } - .forEach { (linkNodeParameters, linkNode) -> - linkNodeParameters.forEach(linkNode::addAttribute) - } - shortcutIcon?.let { pageNode.addForwardLink("icon", it) } + val pageMakerInteraction = pageMakerInteractionFactory.createPageMaker(toadletContext, getPageTitle(request)) + styleSheets.forEach(pageMakerInteraction::addStyleSheet) + getAdditionalLinkNodes(request).forEach(pageMakerInteraction::addLinkNode) + shortcutIcon?.let(pageMakerInteraction::addShortcutIcon) val output = try { val start = System.nanoTime() @@ -93,9 +89,9 @@ open class FreenetTemplatePage( return RedirectResponse(re1.target ?: "") } - pageNode.content.addChild("%", output) + pageMakerInteraction.setContent(output) - return response.setStatusCode(200).setStatusText("OK").setContentType("text/html").write(pageNode.outer.generate()) + return response.setStatusCode(200).setStatusText("OK").setContentType("text/html").write(pageMakerInteraction.renderPage()) } open fun processTemplate(request: FreenetRequest, templateContext: TemplateContext) { diff --git a/src/main/kotlin/net/pterodactylus/sone/web/page/PageMakerInteractionFactory.kt b/src/main/kotlin/net/pterodactylus/sone/web/page/PageMakerInteractionFactory.kt new file mode 100644 index 0000000..e55e33f --- /dev/null +++ b/src/main/kotlin/net/pterodactylus/sone/web/page/PageMakerInteractionFactory.kt @@ -0,0 +1,18 @@ +package net.pterodactylus.sone.web.page + +import com.google.inject.* +import freenet.clients.http.* + +@ImplementedBy(DefaultPageMakerInteractionFactory::class) +interface PageMakerInteractionFactory { + + fun createPageMaker(toadletContext: ToadletContext, pageTitle: String): PageMakerInteraction + +} + +class DefaultPageMakerInteractionFactory : PageMakerInteractionFactory { + + override fun createPageMaker(toadletContext: ToadletContext, pageTitle: String) = + PageMakerInteraction(toadletContext, pageTitle) + +} diff --git a/src/test/java/net/pterodactylus/sone/test/TestUtil.java b/src/test/java/net/pterodactylus/sone/test/TestUtil.java index 35e8202..745733f 100644 --- a/src/test/java/net/pterodactylus/sone/test/TestUtil.java +++ b/src/test/java/net/pterodactylus/sone/test/TestUtil.java @@ -6,11 +6,15 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; +import kotlin.Deprecated; +import kotlin.ReplaceWith; + /** * Utilities for testing. */ public class TestUtil { + @Deprecated(message = "It only checks the given class, not its superclasses.", replaceWith = @ReplaceWith(imports = { "net.pterodactylus.sone.test" }, expression = "setField(`object`, fieldName, value)")) public static void setFinalField(Object object, String fieldName, Object value) { try { Field clientCoreField = object.getClass().getField(fieldName); diff --git a/src/test/java/net/pterodactylus/sone/test/TestUtils.kt b/src/test/java/net/pterodactylus/sone/test/TestUtils.kt new file mode 100644 index 0000000..9996925 --- /dev/null +++ b/src/test/java/net/pterodactylus/sone/test/TestUtils.kt @@ -0,0 +1,19 @@ +package net.pterodactylus.sone.test + +import java.lang.reflect.* + +private val modifiers = Field::class.java.getDeclaredField("modifiers").apply { + isAccessible = true +} + +fun setField(instance: Any, name: String, value: Any?) { + generateSequence>(instance.javaClass) { it.superclass } + .flatMap { it.declaredFields.asSequence() } + .filter { it.name == name } + .toList() + .forEach { field -> + field.isAccessible = true + modifiers.setInt(field, field.modifiers and Modifier.FINAL.inv()) + field.set(instance, value) + } +} diff --git a/src/test/kotlin/net/pterodactylus/sone/web/page/FreenetTemplatePageTest.kt b/src/test/kotlin/net/pterodactylus/sone/web/page/FreenetTemplatePageTest.kt index d680609..2474d08 100644 --- a/src/test/kotlin/net/pterodactylus/sone/web/page/FreenetTemplatePageTest.kt +++ b/src/test/kotlin/net/pterodactylus/sone/web/page/FreenetTemplatePageTest.kt @@ -8,6 +8,8 @@ import org.hamcrest.MatcherAssert.* import org.hamcrest.Matchers.* import org.junit.* import org.mockito.Mockito.* +import java.io.* +import java.nio.charset.StandardCharsets.* class FreenetTemplatePageTest { @@ -121,6 +123,21 @@ class FreenetTemplatePageTest { } @Test + @Dirty + fun `freenet template page creates page with correct title`() { + val page = object : TestPage(templateRenderer, loaders) { + override fun getPageTitle(request: FreenetRequest) = "page title" + } + val request = deepMock() + val pageMakerInteractionFactory = deepMock() + whenever(pageMakerInteractionFactory.createPageMaker(request.toadletContext, "page title").renderPage()).thenReturn("") + setField(page, "pageMakerInteractionFactory", pageMakerInteractionFactory) + val response = page.handleRequest(request, Response(ByteArrayOutputStream())) + assertThat(response.statusCode, equalTo(200)) + assertThat((response.content as ByteArrayOutputStream).toString(UTF_8.name()), equalTo("")) + } + + @Test fun `template from annotation is loaded`() { verify(loaders).loadTemplate("template-path") } diff --git a/src/test/kotlin/net/pterodactylus/sone/web/page/PageMakerInteractionFactoryTest.kt b/src/test/kotlin/net/pterodactylus/sone/web/page/PageMakerInteractionFactoryTest.kt new file mode 100644 index 0000000..8e16094 --- /dev/null +++ b/src/test/kotlin/net/pterodactylus/sone/web/page/PageMakerInteractionFactoryTest.kt @@ -0,0 +1,28 @@ +package net.pterodactylus.sone.web.page + +import com.google.inject.* +import freenet.clients.http.* +import net.pterodactylus.sone.test.* +import org.hamcrest.MatcherAssert.* +import org.hamcrest.Matchers.* +import org.junit.* +import org.mockito.Mockito.* + +class PageMakerInteractionFactoryTest { + + private val pageMakerInteractionFactory: PageMakerInteractionFactory = DefaultPageMakerInteractionFactory() + + @Test + fun `page maker interaction factory can be created by guice`() { + val injector = Guice.createInjector() + assertThat(injector.getInstance(), notNullValue()) + } + + @Test + fun `page maker interaction sets page title correctly`() { + val toadletContext = deepMock() + pageMakerInteractionFactory.createPageMaker(toadletContext, "page title") + verify(toadletContext.pageMaker).getPageNode("page title", toadletContext) + } + +} -- 2.7.4