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