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