♻️ Change dependencies of render filter
authorDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Sat, 9 Mar 2019 16:15:45 +0000 (17:15 +0100)
committerDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Sat, 9 Mar 2019 16:15:45 +0000 (17:15 +0100)
src/main/java/net/pterodactylus/sone/web/WebInterface.java
src/main/kotlin/net/pterodactylus/sone/template/RenderFilter.kt
src/test/kotlin/net/pterodactylus/sone/template/RenderFilterTest.kt
src/test/kotlin/net/pterodactylus/sone/test/Mockotlin.kt

index e7ea688..fb17e93 100644 (file)
@@ -347,7 +347,7 @@ public class WebInterface implements SessionProvider {
                templateContextFactory.addFilter("js", new JavascriptFilter());
                templateContextFactory.addFilter("parse", parserFilter = new ParserFilter(getCore(), soneTextParser));
                templateContextFactory.addFilter("shorten", shortenFilter = new ShortenFilter());
-               templateContextFactory.addFilter("render", renderFilter = new RenderFilter(getCore(), templateContextFactory));
+               templateContextFactory.addFilter("render", renderFilter = new RenderFilter(getCore(), soneTextParser, new HtmlFilter()));
                templateContextFactory.addFilter("linked-elements", new LinkedElementsFilter(elementLoader));
                templateContextFactory.addFilter("render-linked-element", linkedElementRenderFilter = new LinkedElementRenderFilter(templateContextFactory));
                templateContextFactory.addFilter("reparse", new ReparseFilter());
index 420f77c..00015bb 100644 (file)
@@ -1,31 +1,20 @@
 package net.pterodactylus.sone.template
 
-import net.pterodactylus.sone.core.Core
-import net.pterodactylus.sone.text.FreemailPart
-import net.pterodactylus.sone.text.FreenetLinkPart
-import net.pterodactylus.sone.text.LinkPart
+import net.pterodactylus.sone.database.*
+import net.pterodactylus.sone.text.*
 import net.pterodactylus.sone.text.Part
-import net.pterodactylus.sone.text.PlainTextPart
-import net.pterodactylus.sone.text.PostPart
-import net.pterodactylus.sone.text.SonePart
-import net.pterodactylus.sone.text.SoneTextParser
-import net.pterodactylus.sone.text.SoneTextParserContext
-import net.pterodactylus.sone.utils.asTemplate
-import net.pterodactylus.util.template.Filter
-import net.pterodactylus.util.template.TemplateContext
-import net.pterodactylus.util.template.TemplateContextFactory
-import java.io.StringWriter
-import java.io.Writer
-import java.net.URLEncoder
+import net.pterodactylus.sone.utils.*
+import net.pterodactylus.util.template.*
+import java.io.*
+import java.net.*
 
 /**
  * Renders a number of pre-parsed [Part] into a [String].
  */
-class RenderFilter(private val core: Core, private val templateContextFactory: TemplateContextFactory) : Filter {
+class RenderFilter(private val soneProvider: SoneProvider, private val soneTextParser: SoneTextParser, htmlFilter: HtmlFilter) : Filter {
 
-       companion object {
-               private val plainTextTemplate = "<%text|html>".asTemplate()
-               private val linkTemplate = "<a class=\"<%cssClass|html>\" href=\"<%link|html>\" title=\"<%title|html>\"><%text|html></a>".asTemplate()
+       private val templateContextFactory = TemplateContextFactory().apply {
+               addFilter("html", htmlFilter)
        }
 
        override fun format(templateContext: TemplateContext?, data: Any?, parameters: MutableMap<String, Any?>?): Any? {
@@ -77,9 +66,8 @@ class RenderFilter(private val core: Core, private val templateContextFactory: T
        }
 
        private fun render(writer: Writer, postPart: PostPart) {
-               val parser = SoneTextParser(core, core)
                val parserContext = SoneTextParserContext(postPart.post.sone)
-               val parts = parser.parse(postPart.post.text, parserContext)
+               val parts = soneTextParser.parse(postPart.post.text, parserContext)
                val excerpt = StringBuilder()
                for (part in parts) {
                        excerpt.append(part.text)
@@ -98,7 +86,7 @@ class RenderFilter(private val core: Core, private val templateContextFactory: T
        }
 
        private fun render(writer: Writer, freemailPart: FreemailPart) {
-               val sone = core.getSone(freemailPart.identityId)
+               val sone = soneProvider.getSone(freemailPart.identityId)
                val soneName = sone?.let(SoneAccessor::getNiceName) ?: freemailPart.identityId
                renderLink(writer,
                                "/Freemail/NewMessage?to=${freemailPart.identityId}",
@@ -117,3 +105,6 @@ class RenderFilter(private val core: Core, private val templateContextFactory: T
        }
 
 }
+
+private val plainTextTemplate = "<%text|html>".asTemplate()
+private val linkTemplate = "<a class=\"<%cssClass|html>\" href=\"<%link|html>\" title=\"<%title|html>\"><%text|html></a>".asTemplate()
index 0920280..5592808 100644 (file)
@@ -1,29 +1,18 @@
 package net.pterodactylus.sone.template
 
-import net.pterodactylus.sone.core.Core
-import net.pterodactylus.sone.data.Post
-import net.pterodactylus.sone.data.Profile
-import net.pterodactylus.sone.data.Sone
-import net.pterodactylus.sone.test.mock
-import net.pterodactylus.sone.text.FreemailPart
-import net.pterodactylus.sone.text.FreenetLinkPart
-import net.pterodactylus.sone.text.LinkPart
+import net.pterodactylus.sone.data.*
+import net.pterodactylus.sone.database.*
+import net.pterodactylus.sone.test.*
+import net.pterodactylus.sone.text.*
 import net.pterodactylus.sone.text.Part
-import net.pterodactylus.sone.text.PlainTextPart
-import net.pterodactylus.sone.text.PostPart
-import net.pterodactylus.sone.text.SonePart
-import net.pterodactylus.util.template.HtmlFilter
-import net.pterodactylus.util.template.TemplateContext
-import net.pterodactylus.util.template.TemplateContextFactory
-import org.hamcrest.MatcherAssert.assertThat
-import org.hamcrest.Matchers.`is`
-import org.hamcrest.Matchers.containsInAnyOrder
-import org.jsoup.Jsoup
-import org.jsoup.nodes.Attribute
-import org.jsoup.nodes.Element
-import org.junit.Test
-import org.mockito.Mockito.`when`
-import java.net.URLEncoder
+import net.pterodactylus.util.template.*
+import org.hamcrest.MatcherAssert.*
+import org.hamcrest.Matchers.*
+import org.jsoup.*
+import org.jsoup.nodes.*
+import org.junit.*
+import org.mockito.*
+import java.net.*
 
 /**
  * Unit test for [RenderFilter].
@@ -37,22 +26,18 @@ class RenderFilterTest {
                private const val POST_ID = "37a06250-6775-4b94-86ff-257ba690953c"
        }
 
-       private val core = mock<Core>()
-       private val templateContextFactory = TemplateContextFactory()
-       private val templateContext: TemplateContext
+       private val soneProvider = mock<SoneProvider>()
+       private val soneTextParser = mock<SoneTextParser>()
+       private val htmlFilter = HtmlFilter()
        private val sone = setupSone(SONE_IDENTITY, "Sone", "First")
        private val parameters = mutableMapOf<String, Any?>()
 
-       init {
-               templateContextFactory.addFilter("html", HtmlFilter())
-               templateContext = templateContextFactory.createTemplateContext()
-       }
-
-       private val filter = RenderFilter(core, templateContextFactory)
+       private val filter = RenderFilter(soneProvider, soneTextParser, htmlFilter)
+       private val templateContext = TemplateContext()
 
        @Test
        fun `plain text part is rendered correctly`() {
-               assertThat(renderParts(PlainTextPart("plain text")), `is`("plain text"))
+               assertThat(renderParts(PlainTextPart("plain text")), equalTo("plain text"))
        }
 
        private fun renderParts(vararg part: Part) = filter.format(templateContext, listOf(*part), parameters) as String
@@ -64,13 +49,13 @@ class RenderFilterTest {
        }
 
        private fun verifyLink(linkNode: Element, url: String, cssClass: String, tooltip: String, text: String) {
-               assertThat(linkNode.nodeName(), `is`("a"))
+               assertThat(linkNode.nodeName(), equalTo("a"))
                assertThat<List<Attribute>>(linkNode.attributes().asList(), containsInAnyOrder(
                                Attribute("href", url),
                                Attribute("class", cssClass),
                                Attribute("title", tooltip)
                ))
-               assertThat(linkNode.text(), `is`(text))
+               assertThat(linkNode.text(), equalTo(text))
        }
 
        @Test
@@ -96,11 +81,11 @@ class RenderFilterTest {
 
        private fun setupSone(identity: String, name: String?, firstName: String): Sone {
                val sone = mock<Sone>()
-               `when`(sone.id).thenReturn(identity)
-               `when`(sone.profile).thenReturn(Profile(sone))
-               `when`(sone.name).thenReturn(name)
+               whenever(sone.id).thenReturn(identity)
+               whenever(sone.profile).thenReturn(Profile(sone))
+               whenever(sone.name).thenReturn(name)
                sone.profile.firstName = firstName
-               `when`(core.getSone(identity)).thenReturn(sone)
+               whenever(soneProvider.getSone(identity)).thenReturn(sone)
                return sone
        }
 
@@ -114,21 +99,24 @@ class RenderFilterTest {
        @Test
        fun `post part is cut off correctly when there are spaces`() {
                val post = setupPost(sone, "1234 678901 345 789012 45678 01.")
+               whenever(soneTextParser.parse(eq("1234 678901 345 789012 45678 01."), ArgumentMatchers.any()))
+                               .thenReturn(listOf(PlainTextPart("1234 678901 345 789012 45678 01.")))
                val linkNode = renderParts(PostPart(post)).toLinkNode()
                verifyLink(linkNode, "viewPost.html?post=$POST_ID", "in-sone", "First", "1234 678901 345…")
        }
 
-       private fun setupPost(sone: Sone, value: String): Post {
-               val post = mock<Post>()
-               `when`(post.id).thenReturn(POST_ID)
-               `when`(post.sone).thenReturn(sone)
-               `when`(post.text).thenReturn(value)
-               return post
-       }
+       private fun setupPost(sone: Sone, value: String) =
+                       mock<Post>().apply {
+                               whenever(id).thenReturn(POST_ID)
+                               whenever(this.sone).thenReturn(this@RenderFilterTest.sone)
+                               whenever(text).thenReturn(value)
+                       }
 
        @Test
        fun `post part is cut off correctly when there are no spaces`() {
                val post = setupPost(sone, "1234567890123456789012345678901.")
+               whenever(soneTextParser.parse(eq("1234567890123456789012345678901."), ArgumentMatchers.any()))
+                               .thenReturn(listOf(PlainTextPart("1234567890123456789012345678901.")))
                val linkNode = renderParts(PostPart(post)).toLinkNode()
                verifyLink(linkNode, "viewPost.html?post=$POST_ID", "in-sone", "First", "12345678901234567890…")
        }
@@ -136,6 +124,8 @@ class RenderFilterTest {
        @Test
        fun `post part shorter than 21 chars is not cut off`() {
                val post = setupPost(sone, "12345678901234567890")
+               whenever(soneTextParser.parse(eq("12345678901234567890"), ArgumentMatchers.any()))
+                               .thenReturn(listOf(PlainTextPart("12345678901234567890")))
                val linkNode = renderParts(PostPart(post)).toLinkNode()
                verifyLink(linkNode, "viewPost.html?post=$POST_ID", "in-sone", "First", "12345678901234567890")
        }
@@ -143,7 +133,7 @@ class RenderFilterTest {
        @Test
        fun `multiple parts are rendered correctly`() {
                val parts = arrayOf(PlainTextPart("te"), PlainTextPart("xt"))
-               assertThat(renderParts(*parts), `is`("text"))
+               assertThat(renderParts(*parts), equalTo("text"))
        }
 
        @Test
index d1ab1fc..85b86d5 100644 (file)
@@ -1,8 +1,7 @@
 package net.pterodactylus.sone.test
 
 import com.google.inject.Module
-import org.mockito.ArgumentCaptor
-import org.mockito.Mockito
+import org.mockito.*
 import org.mockito.invocation.InvocationOnMock
 import org.mockito.stubbing.OngoingStubbing
 
@@ -27,3 +26,8 @@ inline fun <reified T : Any> OngoingStubbing<T>.thenReturnMock(): OngoingStubbin
 operator fun <T> InvocationOnMock.get(index: Int): T = getArgument(index)
 
 inline fun <reified T> argumentCaptor(): ArgumentCaptor<T> = ArgumentCaptor.forClass<T, T>(T::class.java)!!
+
+fun <T> eq(t: T): T {
+       ArgumentMatchers.eq(t)
+       return null as T
+}