From 9824d45ada252d673a259029052f5ac4eecc5420 Mon Sep 17 00:00:00 2001 From: =?utf8?q?David=20=E2=80=98Bombe=E2=80=99=20Roden?= Date: Mon, 28 Nov 2016 07:27:16 +0100 Subject: [PATCH] Add unit test for login page --- .../net/pterodactylus/sone/web/WebPageTest.java | 2 +- .../net/pterodactylus/sone/test/Mockotlin.kt | 3 + .../net/pterodactylus/sone/web/LoginPageTest.kt | 135 +++++++++++++++++++++ 3 files changed, 139 insertions(+), 1 deletion(-) create mode 100644 src/test/kotlin/net/pterodactylus/sone/web/LoginPageTest.kt diff --git a/src/test/java/net/pterodactylus/sone/web/WebPageTest.java b/src/test/java/net/pterodactylus/sone/web/WebPageTest.java index b8b7fa6..16610e4 100644 --- a/src/test/java/net/pterodactylus/sone/web/WebPageTest.java +++ b/src/test/java/net/pterodactylus/sone/web/WebPageTest.java @@ -83,7 +83,7 @@ public abstract class WebPageTest { private final Set ownIdentities = new HashSet<>(); private final Map sones = new HashMap<>(); - private final List localSones = new ArrayList<>(); + protected final List localSones = new ArrayList<>(); protected WebPageTest() { try { diff --git a/src/test/kotlin/net/pterodactylus/sone/test/Mockotlin.kt b/src/test/kotlin/net/pterodactylus/sone/test/Mockotlin.kt index b30e98c..38625ea 100644 --- a/src/test/kotlin/net/pterodactylus/sone/test/Mockotlin.kt +++ b/src/test/kotlin/net/pterodactylus/sone/test/Mockotlin.kt @@ -3,6 +3,7 @@ package net.pterodactylus.sone.test import com.google.inject.Module import org.mockito.ArgumentCaptor import org.mockito.Mockito +import org.mockito.stubbing.OngoingStubbing inline fun mock(): T = Mockito.mock(T::class.java)!! inline fun mockBuilder(): T = Mockito.mock(T::class.java, Mockito.RETURNS_SELF)!! @@ -16,3 +17,5 @@ inline fun bindMock(): Module = Module { it!!.bind(T::class.java).toInstance(mock()) } inline fun whenever(methodCall: T) = Mockito.`when`(methodCall) + +inline fun OngoingStubbing.thenReturnMock(): OngoingStubbing = this.thenReturn(mock()) diff --git a/src/test/kotlin/net/pterodactylus/sone/web/LoginPageTest.kt b/src/test/kotlin/net/pterodactylus/sone/web/LoginPageTest.kt new file mode 100644 index 0000000..3b5c74f --- /dev/null +++ b/src/test/kotlin/net/pterodactylus/sone/web/LoginPageTest.kt @@ -0,0 +1,135 @@ +package net.pterodactylus.sone.web + +import net.pterodactylus.sone.data.Sone +import net.pterodactylus.sone.freenet.wot.Identity +import net.pterodactylus.sone.freenet.wot.OwnIdentity +import net.pterodactylus.sone.test.mock +import net.pterodactylus.sone.test.thenReturnMock +import net.pterodactylus.sone.test.whenever +import net.pterodactylus.sone.web.WebTestUtils.redirectsTo +import net.pterodactylus.util.web.Method.GET +import net.pterodactylus.util.web.Method.POST +import org.hamcrest.MatcherAssert.assertThat +import org.hamcrest.Matchers.contains +import org.hamcrest.Matchers.containsInAnyOrder +import org.hamcrest.Matchers.equalTo +import org.hamcrest.Matchers.nullValue +import org.junit.Before +import org.junit.Test +import org.mockito.Mockito.verify + +/** + * Unit test for [LoginPage]. + */ +class LoginPageTest : WebPageTest() { + + private val page = LoginPage(template, webInterface) + + private val sones = listOf(createSone("Sone", "Test"), createSone("Test"), createSone("Sone")) + + private fun createSone(vararg contexts: String) = mock().apply { + whenever(id).thenReturn(hashCode().toString()) + val identity = mock().apply { + whenever(this.contexts).thenReturn(contexts.toSet()) + contexts.forEach { whenever(hasContext(it)).thenReturn(true) } + } + whenever(this.identity).thenReturn(identity) + whenever(profile).thenReturnMock() + } + + @Before + fun setupSones() { + addLocalSone("sone1", sones[0]) + addLocalSone("sone2", sones[1]) + addLocalSone("sone3", sones[2]) + addOwnIdentity(sones[0].identity as OwnIdentity) + addOwnIdentity(sones[1].identity as OwnIdentity) + addOwnIdentity(sones[2].identity as OwnIdentity) + } + + @Test + @Suppress("UNCHECKED_CAST") + fun `get request stores sone and identities without sones in template context`() { + request("", GET) + page.handleRequest(freenetRequest, templateContext) + assertThat(templateContext["sones"] as Iterable, containsInAnyOrder(sones[0], sones[1], sones[2])) + assertThat(templateContext["identitiesWithoutSone"] as Iterable, contains(sones[1].identity)) + } + + @Test + fun `post request with invalid sone sets sones and identities without sone in template context`() { + request("", POST) + page.handleRequest(freenetRequest, templateContext) + assertThat(templateContext["sones"] as Iterable, containsInAnyOrder(sones[0], sones[1], sones[2])) + assertThat(templateContext["identitiesWithoutSone"] as Iterable, contains(sones[1].identity)) + } + + @Test + fun `post request with valid sone and redirects to index page`() { + request("", POST) + addHttpRequestParameter("sone-id", "sone2") + expectedException.expect(redirectsTo("index.html")) + try { + page.handleRequest(freenetRequest, templateContext) + } finally { + verify(webInterface).setCurrentSone(toadletContext, sones[1]) + } + } + + @Test + fun `post request with valid sone and target redirects to target page`() { + request("", POST) + addHttpRequestParameter("sone-id", "sone2") + addHttpRequestParameter("target", "foo.html") + expectedException.expect(redirectsTo("foo.html")) + try { + page.handleRequest(freenetRequest, templateContext) + } finally { + verify(webInterface).setCurrentSone(toadletContext, sones[1]) + } + } + + @Test + fun `redirect to index html if a sone is logged in`() { + assertThat(page.getRedirectTarget(freenetRequest), equalTo("index.html")) + } + + @Test + fun `do not redirect if no sone is logged in`() { + unsetCurrentSone() + assertThat(page.getRedirectTarget(freenetRequest), nullValue()) + } + + @Test + fun `page is not enabled if full access required and request is not full access`() { + core.preferences.isRequireFullAccess = true + assertThat(page.isEnabled(toadletContext), equalTo(false)) + } + + @Test + fun `page is enabled if no full access is required and there is no current sone`() { + unsetCurrentSone() + assertThat(page.isEnabled(toadletContext), equalTo(true)) + } + + @Test + fun `page is not enabled if no full access is required but there is a current sone`() { + assertThat(page.isEnabled(toadletContext), equalTo(false)) + } + + @Test + fun `page is enabled if full access required and request is full access and there is no current sone`() { + core.preferences.isRequireFullAccess = true + unsetCurrentSone() + whenever(toadletContext.isAllowedFullAccess).thenReturn(true) + assertThat(page.isEnabled(toadletContext), equalTo(true)) + } + + @Test + fun `page is not enabled if full access required and request is full access but there is a current sone`() { + core.preferences.isRequireFullAccess = true + whenever(toadletContext.isAllowedFullAccess).thenReturn(true) + assertThat(page.isEnabled(toadletContext), equalTo(false)) + } + +} -- 2.7.4