Actually differentiate between GET and POST parameters
[Sone.git] / src / test / kotlin / net / pterodactylus / sone / web / pages / EditProfilePageTest.kt
1 package net.pterodactylus.sone.web.pages
2
3 import net.pterodactylus.sone.data.Image
4 import net.pterodactylus.sone.data.Profile
5 import net.pterodactylus.sone.test.mock
6 import net.pterodactylus.sone.test.whenever
7 import net.pterodactylus.sone.web.pages.EditProfilePage
8 import net.pterodactylus.sone.web.pages.WebPageTest
9 import net.pterodactylus.util.web.Method.GET
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
16 import org.junit.Test
17 import org.mockito.Mockito.never
18 import org.mockito.Mockito.verify
19
20 /**
21  * Unit test for [EditProfilePage].
22  */
23 class EditProfilePageTest : WebPageTest() {
24
25         private val page = EditProfilePage(template, webInterface)
26
27         private val profile = Profile(currentSone)
28         private val firstField = profile.addField("First Field")
29         private val secondField = profile.addField("Second Field")
30
31         override fun getPage() = page
32
33         @Before
34         fun setupProfile() {
35                 val avatar = mock<Image>()
36                 whenever(avatar.id).thenReturn("image-id")
37                 whenever(avatar.sone).thenReturn(currentSone)
38                 profile.firstName = "First"
39                 profile.middleName = "Middle"
40                 profile.lastName = "Last"
41                 profile.birthDay = 31
42                 profile.birthMonth = 12
43                 profile.birthYear = 1999
44                 profile.setAvatar(avatar)
45                 whenever(currentSone.profile).thenReturn(profile)
46         }
47
48         @Test
49         fun `page returns correct path`() {
50             assertThat(page.path, equalTo("editProfile.html"))
51         }
52
53         @Test
54         fun `page requires login`() {
55             assertThat(page.requiresLogin(), equalTo(true))
56         }
57
58         @Test
59         fun `page returns correct title`() {
60             whenever(l10n.getString("Page.EditProfile.Title")).thenReturn("edit profile page title")
61                 assertThat(page.getPageTitle(freenetRequest), equalTo("edit profile page title"))
62         }
63
64         @Test
65         fun `get request stores fields of current sone’s profile in template context`() {
66                 request("", GET)
67                 page.processTemplate(freenetRequest, templateContext)
68                 assertThat(templateContext["firstName"], equalTo<Any>("First"))
69                 assertThat(templateContext["middleName"], equalTo<Any>("Middle"))
70                 assertThat(templateContext["lastName"], equalTo<Any>("Last"))
71                 assertThat(templateContext["birthDay"], equalTo<Any>(31))
72                 assertThat(templateContext["birthMonth"], equalTo<Any>(12))
73                 assertThat(templateContext["birthYear"], equalTo<Any>(1999))
74                 assertThat(templateContext["avatarId"], equalTo<Any>("image-id"))
75                 assertThat(templateContext["fields"], equalTo<Any>(listOf(firstField, secondField)))
76         }
77
78         @Test
79         fun `post request without any command stores fields of current sone’s profile in template context`() {
80                 request("", POST)
81                 page.processTemplate(freenetRequest, templateContext)
82                 assertThat(templateContext["firstName"], equalTo<Any>("First"))
83                 assertThat(templateContext["middleName"], equalTo<Any>("Middle"))
84                 assertThat(templateContext["lastName"], equalTo<Any>("Last"))
85                 assertThat(templateContext["birthDay"], equalTo<Any>(31))
86                 assertThat(templateContext["birthMonth"], equalTo<Any>(12))
87                 assertThat(templateContext["birthYear"], equalTo<Any>(1999))
88                 assertThat(templateContext["avatarId"], equalTo<Any>("image-id"))
89                 assertThat(templateContext["fields"], equalTo<Any>(listOf(firstField, secondField)))
90         }
91
92         private fun <T> verifySingleFieldCanBeChanged(fieldName: String, newValue: T, expectedValue: T = newValue, fieldAccessor: () -> T) {
93                 request("", POST)
94                 addHttpRequestPart("save-profile", "true")
95                 addHttpRequestPart(fieldName, newValue.toString())
96                 verifyRedirect("editProfile.html") {
97                         verify(core).touchConfiguration()
98                         assertThat(fieldAccessor(), equalTo(expectedValue))
99                 }
100         }
101
102         @Test
103         fun `post request with new first name and save profile saves the profile and redirects back to profile edit page`() {
104                 verifySingleFieldCanBeChanged("first-name", "New First") { profile.firstName }
105         }
106
107         @Test
108         fun `post request with new middle name and save profile saves the profile and redirects back to profile edit page`() {
109                 verifySingleFieldCanBeChanged("middle-name", "New Middle") { profile.middleName }
110         }
111
112         @Test
113         fun `post request with new last name and save profile saves the profile and redirects back to profile edit page`() {
114                 verifySingleFieldCanBeChanged("last-name", "New Last") { profile.lastName }
115         }
116
117         @Test
118         fun `post request with new birth day and save profile saves the profile and redirects back to profile edit page`() {
119                 verifySingleFieldCanBeChanged("birth-day", 1) { profile.birthDay }
120         }
121
122         @Test
123         fun `post request with new birth month and save profile saves the profile and redirects back to profile edit page`() {
124                 verifySingleFieldCanBeChanged("birth-month", 1) { profile.birthMonth }
125         }
126
127         @Test
128         fun `post request with new birth year and save profile saves the profile and redirects back to profile edit page`() {
129                 verifySingleFieldCanBeChanged("birth-year", 1) { profile.birthYear }
130         }
131
132         @Test
133         fun `post request with new avatar ID and save profile saves the profile and redirects back to profile edit page`() {
134                 val newAvatar = mock<Image>()
135                 whenever(newAvatar.sone).thenReturn(currentSone)
136                 whenever(newAvatar.id).thenReturn("avatar-id")
137                 addImage("avatar-id", newAvatar)
138                 verifySingleFieldCanBeChanged("avatarId", "avatar-id") { profile.avatar }
139         }
140
141         @Test
142         fun `post request with field value saves profile and redirects back to profile edit page`() {
143                 val field = profile.addField("name")
144                 field.value = "old"
145                 verifySingleFieldCanBeChanged("field-${field.id}", "new") { profile.getFieldByName("name")!!.value }
146         }
147
148         @Test
149         fun `post request with field value saves filtered value to profile and redirects back to profile edit page`() {
150                 val field = profile.addField("name")
151                 field.value = "old"
152                 addHttpRequestHeader("Host", "www.te.st")
153                 verifySingleFieldCanBeChanged("field-${field.id}", "http://www.te.st/KSK@GPL.txt", "KSK@GPL.txt") { profile.getFieldByName("name")!!.value }
154         }
155
156         @Test
157         fun `adding a field with a duplicate name sets error in template context`() {
158                 request("", POST)
159                 profile.addField("new-field")
160                 addHttpRequestPart("add-field", "true")
161                 addHttpRequestPart("field-name", "new-field")
162                 page.processTemplate(freenetRequest, templateContext)
163                 assertThat(templateContext["fieldName"], equalTo<Any>("new-field"))
164                 assertThat(templateContext["duplicateFieldName"], equalTo<Any>(true))
165                 verify(core, never()).touchConfiguration()
166         }
167
168         @Test
169         fun `adding a field with a new name sets adds field to profile and redirects to profile edit page`() {
170                 request("", POST)
171                 addHttpRequestPart("add-field", "true")
172                 addHttpRequestPart("field-name", "new-field")
173                 verifyRedirect("editProfile.html#profile-fields") {
174                         assertThat(profile.getFieldByName("new-field"), notNullValue())
175                         verify(currentSone).profile = profile
176                         verify(core).touchConfiguration()
177                 }
178         }
179
180         @Test
181         fun `deleting a field redirects to delete field page`() {
182                 request("", POST)
183                 addHttpRequestPart("delete-field-${firstField.id}", "true")
184                 verifyRedirect("deleteProfileField.html?field=${firstField.id}")
185         }
186
187         @Test
188         fun `moving a field up moves the field up and redirects to the edit profile page`() {
189                 request("", POST)
190                 addHttpRequestPart("move-up-field-${secondField.id}", "true")
191                 verifyRedirect("editProfile.html#profile-fields") {
192                         assertThat(profile.fields, contains(secondField, firstField))
193                         verify(currentSone).profile = profile
194                 }
195         }
196
197         @Test
198         fun `moving an invalid field up does not redirect`() {
199                 request("", POST)
200                 addHttpRequestPart("move-up-field-foo", "true")
201                 page.processTemplate(freenetRequest, templateContext)
202         }
203
204         @Test
205         fun `moving a field down moves the field down and redirects to the edit profile page`() {
206                 request("", POST)
207                 addHttpRequestPart("move-down-field-${firstField.id}", "true")
208                 verifyRedirect("editProfile.html#profile-fields") {
209                         assertThat(profile.fields, contains(secondField, firstField))
210                         verify(currentSone).profile = profile
211                 }
212         }
213
214         @Test
215         fun `moving an invalid field down does not redirect`() {
216                 request("", POST)
217                 addHttpRequestPart("move-down-field-foo", "true")
218                 page.processTemplate(freenetRequest, templateContext)
219         }
220
221         @Test
222         fun `editing a field redirects to the edit profile page`() {
223                 request("", POST)
224                 addHttpRequestPart("edit-field-${firstField.id}", "true")
225                 verifyRedirect("editProfileField.html?field=${firstField.id}")
226         }
227
228 }