From d9cffbf70e8504180328964511303c1d70207b84 Mon Sep 17 00:00:00 2001 From: =?utf8?q?David=20=E2=80=98Bombe=E2=80=99=20Roden?= Date: Thu, 2 Jan 2020 21:56:47 +0100 Subject: [PATCH] =?utf8?q?=F0=9F=9A=A7=20Add=20=E2=80=9CreplySone=E2=80=9D?= =?utf8?q?=20member=20to=20post=20accessor?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- .../pterodactylus/sone/template/PostAccessor.kt | 12 ++- .../sone/template/PostAccessorTest.kt | 85 ++++++++++++++++++++++ 2 files changed, 95 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/net/pterodactylus/sone/template/PostAccessor.kt b/src/main/kotlin/net/pterodactylus/sone/template/PostAccessor.kt index db26866..5222b94 100644 --- a/src/main/kotlin/net/pterodactylus/sone/template/PostAccessor.kt +++ b/src/main/kotlin/net/pterodactylus/sone/template/PostAccessor.kt @@ -34,13 +34,21 @@ class PostAccessor(private val core: Core) : ReflectionAccessor() { override fun get(templateContext: TemplateContext?, `object`: Any?, member: String): Any? = (`object` as Post).let { post -> when (member) { - "replies" -> core.getReplies(post.id).filter { Reply.FUTURE_REPLY_FILTER.apply(it) } + "replies" -> core.getReplies(post) "likes" -> core.getLikes(post) - "liked" -> (templateContext?.get("currentSone") as? Sone)?.isLikedPostId(post.id) ?: false + "liked" -> templateContext.currentSone?.isLikedPostId(post.id) ?: false "new" -> !post.isKnown "bookmarked" -> core.isBookmarked(post) + "replySone" -> core.getReplies(post) + .lastOrNull { it.sone.isLocal } + ?.sone + ?: post.sone.takeIf { it.isLocal } + ?: templateContext.currentSone else -> super.get(templateContext, `object`, member) } } } + +private fun Core.getReplies(post: Post) = getReplies(post.id).filter { Reply.FUTURE_REPLY_FILTER.apply(it) } +private val TemplateContext?.currentSone: Sone? get() = this?.get("currentSone") as? Sone diff --git a/src/test/kotlin/net/pterodactylus/sone/template/PostAccessorTest.kt b/src/test/kotlin/net/pterodactylus/sone/template/PostAccessorTest.kt index 000e50c..72e1343 100644 --- a/src/test/kotlin/net/pterodactylus/sone/template/PostAccessorTest.kt +++ b/src/test/kotlin/net/pterodactylus/sone/template/PostAccessorTest.kt @@ -95,8 +95,93 @@ class PostAccessorTest { } @Test + fun `reply sone for remote post without replies is current sone`() { + val post = mockPostFrom(remoteSone) + assertThat(accessor[templateContext, post, "replySone"], equalTo(currentSone)) + } + + @Test + fun `reply sone for remote post with remote replies is current sone`() { + val post = mockPostFrom(remoteSone) + val replies = listOf(mockReplyFrom(remoteSone), mockReplyFrom(remoteSone)) + whenever(core.getReplies("post-id")).thenReturn(replies) + assertThat(accessor[templateContext, post, "replySone"], equalTo(currentSone)) + } + + @Test + fun `reply sone for remote post with remote and one local replies is sone of local reply`() { + val post = mockPostFrom(remoteSone) + val localSone = mockLocalSone() + val replies = listOf(mockReplyFrom(remoteSone), mockReplyFrom(localSone)) + whenever(core.getReplies("post-id")).thenReturn(replies) + assertThat(accessor[templateContext, post, "replySone"], equalTo(localSone)) + } + + @Test + fun `reply sone for remote post with remote and several local replies is sone of latest local reply`() { + val post = mockPostFrom(remoteSone) + val localSone1 = mockLocalSone() + val localSone2 = mockLocalSone() + val replies = listOf(mockReplyFrom(remoteSone), mockReplyFrom(localSone1), mockReplyFrom(localSone2)) + whenever(core.getReplies("post-id")).thenReturn(replies) + assertThat(accessor[templateContext, post, "replySone"], equalTo(localSone2)) + } + + @Test + fun `reply sone for local post without replies is post sone`() { + val localSone = mockLocalSone() + val post = mockPostFrom(localSone) + assertThat(accessor[templateContext, post, "replySone"], equalTo(localSone)) + } + + @Test + fun `reply sone for local post with remote replies is local sone`() { + val localSone = mockLocalSone() + val post = mockPostFrom(localSone) + val replies = listOf(mockReplyFrom(remoteSone), mockReplyFrom(remoteSone)) + whenever(core.getReplies("post-id")).thenReturn(replies) + assertThat(accessor[templateContext, post, "replySone"], equalTo(localSone)) + } + + @Test + fun `reply sone for local post with remote and one local replies is local reply sone`() { + val localSone1 = mockLocalSone() + val post = mockPostFrom(localSone1) + val localSone2 = mockLocalSone() + val replies = listOf(mockReplyFrom(remoteSone), mockReplyFrom(localSone2)) + whenever(core.getReplies("post-id")).thenReturn(replies) + assertThat(accessor[templateContext, post, "replySone"], equalTo(localSone2)) + } + + @Test + fun `reply sone for local post with remote and several local replies is latest local reply sone`() { + val localSone1 = mockLocalSone() + val post = mockPostFrom(localSone1) + val localSone2 = mockLocalSone() + val localSone3 = mockLocalSone() + val replies = listOf(mockReplyFrom(remoteSone), mockReplyFrom(localSone2), mockReplyFrom(localSone3)) + whenever(core.getReplies("post-id")).thenReturn(replies) + assertThat(accessor[templateContext, post, "replySone"], equalTo(localSone3)) + } + + @Test fun `accessor returns other properties`() { assertThat(accessor[null, post, "hashCode"], equalTo(post.hashCode())) } } + +private val currentSone = mock() +private val remoteSone = mock() +private fun mockLocalSone() = mock().apply { whenever(isLocal).thenReturn(true) } + +private val templateContext = TemplateContext().apply { + this["currentSone"] = currentSone +} + +private fun mockPostFrom(sone: Sone) = mock().apply { + whenever(id).thenReturn("post-id") + whenever(this.sone).thenReturn(sone) +} + +private fun mockReplyFrom(sone: Sone) = mock().apply { whenever(this.sone).thenReturn(sone) } -- 2.7.4