1 package net.pterodactylus.sone.web.pages
3 import net.pterodactylus.sone.data.Image
4 import net.pterodactylus.sone.data.Profile
5 import net.pterodactylus.sone.test.getInstance
6 import net.pterodactylus.sone.test.mock
7 import net.pterodactylus.sone.test.whenever
8 import net.pterodactylus.sone.web.baseInjector
9 import net.pterodactylus.sone.web.page.*
10 import net.pterodactylus.util.web.Method.POST
11 import org.hamcrest.MatcherAssert.assertThat
12 import org.hamcrest.Matchers.contains
13 import org.hamcrest.Matchers.equalTo
14 import org.hamcrest.Matchers.notNullValue
15 import org.junit.Before
17 import org.mockito.Mockito.never
18 import org.mockito.Mockito.verify
21 * Unit test for [EditProfilePage].
23 class EditProfilePageTest: WebPageTest(::EditProfilePage) {
25 private val profile = Profile(currentSone)
26 private val firstField = profile.addField("First Field")
27 private val secondField = profile.addField("Second Field")
31 val avatar = mock<Image>()
32 whenever(avatar.id).thenReturn("image-id")
33 whenever(avatar.sone).thenReturn(currentSone)
34 profile.firstName = "First"
35 profile.middleName = "Middle"
36 profile.lastName = "Last"
38 profile.birthMonth = 12
39 profile.birthYear = 1999
40 profile.setAvatar(avatar)
41 whenever(currentSone.profile).thenReturn(profile)
45 fun `page returns correct path`() {
46 assertThat(page.path, equalTo("editProfile.html"))
50 fun `page requires login`() {
51 assertThat(page.requiresLogin(), equalTo(true))
55 fun `page returns correct title`() {
56 whenever(l10n.getString("Page.EditProfile.Title")).thenReturn("edit profile page title")
57 assertThat(page.getPageTitle(soneRequest), equalTo("edit profile page title"))
61 fun `get request stores fields of current sone’s profile in template context`() {
62 page.processTemplate(freenetRequest, templateContext)
63 assertThat(templateContext["firstName"], equalTo<Any>("First"))
64 assertThat(templateContext["middleName"], equalTo<Any>("Middle"))
65 assertThat(templateContext["lastName"], equalTo<Any>("Last"))
66 assertThat(templateContext["birthDay"], equalTo<Any>(31))
67 assertThat(templateContext["birthMonth"], equalTo<Any>(12))
68 assertThat(templateContext["birthYear"], equalTo<Any>(1999))
69 assertThat(templateContext["avatarId"], equalTo<Any>("image-id"))
70 assertThat(templateContext["fields"], equalTo<Any>(listOf(firstField, secondField)))
74 fun `post request without any command stores fields of current sone’s profile in template context`() {
76 page.processTemplate(freenetRequest, templateContext)
77 assertThat(templateContext["firstName"], equalTo<Any>("First"))
78 assertThat(templateContext["middleName"], equalTo<Any>("Middle"))
79 assertThat(templateContext["lastName"], equalTo<Any>("Last"))
80 assertThat(templateContext["birthDay"], equalTo<Any>(31))
81 assertThat(templateContext["birthMonth"], equalTo<Any>(12))
82 assertThat(templateContext["birthYear"], equalTo<Any>(1999))
83 assertThat(templateContext["avatarId"], equalTo<Any>("image-id"))
84 assertThat(templateContext["fields"], equalTo<Any>(listOf(firstField, secondField)))
87 private fun <T> verifySingleFieldCanBeChanged(fieldName: String, newValue: T, expectedValue: T = newValue, fieldAccessor: () -> T) {
89 addHttpRequestPart("save-profile", "true")
90 addHttpRequestPart(fieldName, newValue.toString())
91 verifyRedirect("editProfile.html") {
92 verify(currentSone).profile = profile
93 verify(core).touchConfiguration()
94 assertThat(fieldAccessor(), equalTo(expectedValue))
99 fun `post request with new first name and save profile saves the profile and redirects back to profile edit page`() {
100 verifySingleFieldCanBeChanged("first-name", "New First") { profile.firstName }
104 fun `post request with new middle name and save profile saves the profile and redirects back to profile edit page`() {
105 verifySingleFieldCanBeChanged("middle-name", "New Middle") { profile.middleName }
109 fun `post request with new last name and save profile saves the profile and redirects back to profile edit page`() {
110 verifySingleFieldCanBeChanged("last-name", "New Last") { profile.lastName }
114 fun `post request with new birth day and save profile saves the profile and redirects back to profile edit page`() {
115 verifySingleFieldCanBeChanged("birth-day", 1) { profile.birthDay }
119 fun `post request with new birth month and save profile saves the profile and redirects back to profile edit page`() {
120 verifySingleFieldCanBeChanged("birth-month", 1) { profile.birthMonth }
124 fun `post request with new birth year and save profile saves the profile and redirects back to profile edit page`() {
125 verifySingleFieldCanBeChanged("birth-year", 1) { profile.birthYear }
129 fun `post request with new avatar ID and save profile saves the profile and redirects back to profile edit page`() {
130 val newAvatar = mock<Image>()
131 whenever(newAvatar.sone).thenReturn(currentSone)
132 whenever(newAvatar.id).thenReturn("avatar-id")
133 addImage("avatar-id", newAvatar)
134 verifySingleFieldCanBeChanged("avatarId", "avatar-id") { profile.avatar }
138 fun `post request with field value saves profile and redirects back to profile edit page`() {
139 val field = profile.addField("name")
141 verifySingleFieldCanBeChanged("field-${field.id}", "new") { profile.getFieldByName("name")!!.value }
145 fun `post request with field value saves filtered value to profile and redirects back to profile edit page`() {
146 val field = profile.addField("name")
148 addHttpRequestHeader("Host", "www.te.st")
149 verifySingleFieldCanBeChanged("field-${field.id}", "http://www.te.st/KSK@GPL.txt", "KSK@GPL.txt") { profile.getFieldByName("name")!!.value }
153 fun `adding a field with a duplicate name sets error in template context`() {
155 profile.addField("new-field")
156 addHttpRequestPart("add-field", "true")
157 addHttpRequestPart("field-name", "new-field")
158 page.processTemplate(freenetRequest, templateContext)
159 assertThat(templateContext["fieldName"], equalTo<Any>("new-field"))
160 assertThat(templateContext["duplicateFieldName"], equalTo<Any>(true))
161 verify(core, never()).touchConfiguration()
165 fun `adding a field with a new name sets adds field to profile and redirects to profile edit page`() {
167 addHttpRequestPart("add-field", "true")
168 addHttpRequestPart("field-name", "new-field")
169 verifyRedirect("editProfile.html#profile-fields") {
170 assertThat(profile.getFieldByName("new-field"), notNullValue())
171 verify(currentSone).profile = profile
172 verify(core).touchConfiguration()
177 fun `deleting a field redirects to delete field page`() {
179 addHttpRequestPart("delete-field-${firstField.id}", "true")
180 verifyRedirect("deleteProfileField.html?field=${firstField.id}")
184 fun `moving a field up moves the field up and redirects to the edit profile page`() {
186 addHttpRequestPart("move-up-field-${secondField.id}", "true")
187 verifyRedirect("editProfile.html#profile-fields") {
188 assertThat(profile.fields, contains(secondField, firstField))
189 verify(currentSone).profile = profile
194 fun `moving an invalid field up does not redirect`() {
196 addHttpRequestPart("move-up-field-foo", "true")
197 page.processTemplate(freenetRequest, templateContext)
201 fun `moving a field down moves the field down and redirects to the edit profile page`() {
203 addHttpRequestPart("move-down-field-${firstField.id}", "true")
204 verifyRedirect("editProfile.html#profile-fields") {
205 assertThat(profile.fields, contains(secondField, firstField))
206 verify(currentSone).profile = profile
211 fun `moving an invalid field down does not redirect`() {
213 addHttpRequestPart("move-down-field-foo", "true")
214 page.processTemplate(freenetRequest, templateContext)
218 fun `editing a field redirects to the edit profile page`() {
220 addHttpRequestPart("edit-field-${firstField.id}", "true")
221 verifyRedirect("editProfileField.html?field=${firstField.id}")
225 fun `page can be created by dependency injection`() {
226 assertThat(baseInjector.getInstance<EditProfilePage>(), notNullValue())
230 fun `page is annotated with correct menuname`() {
231 assertThat(page.menuName, equalTo("EditProfile"))