Skip to content

Commit 9a47ad4

Browse files
committed
server: more tests
1 parent 73622b6 commit 9a47ad4

File tree

2 files changed

+120
-5
lines changed

2 files changed

+120
-5
lines changed

server/src/test/kotlin/cloud/skadi/ApplicationTest.kt

Lines changed: 116 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package cloud.skadi
22

33
import cloud.skadi.gist.shared.*
44
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
5+
import io.ktor.client.engine.*
56
import io.ktor.http.*
67
import io.ktor.server.testing.*
78
import org.jsoup.Jsoup
@@ -138,6 +139,7 @@ class ApplicationTest {
138139
}
139140
}
140141
}
142+
141143
@Test
142144
fun `can create private gist after login`() {
143145
withTestDb { dbName ->
@@ -157,7 +159,7 @@ class ApplicationTest {
157159
cookiesSession {
158160
login()
159161
val gistUrl = testGist()
160-
handleRequest(HttpMethod.Get,"/logout").apply {
162+
handleRequest(HttpMethod.Get, "/logout").apply {
161163
assertEquals(HttpStatusCode.Found, response.status())
162164
}
163165
handleRequest(HttpMethod.Get, gistUrl.encodedPath).apply {
@@ -167,24 +169,27 @@ class ApplicationTest {
167169
}
168170
}
169171
}
172+
170173
@Test
171174
fun `cannot access private gist as a different user`() {
172175
withTestDb { dbName ->
173176
withTestApplication({ testModuleSetup(dbName) }) {
174177
cookiesSession {
175178
login()
176179
val gistUrl = testGist()
177-
handleRequest(HttpMethod.Get,"/logout").apply {
180+
handleRequest(HttpMethod.Get, "/logout").apply {
178181
assertEquals(HttpStatusCode.Found, response.status())
179182
}
180183
login("testuser2", "[email protected]")
181184
handleRequest(HttpMethod.Get, gistUrl.encodedPath).apply {
185+
response.content
182186
assertEquals(HttpStatusCode.NotFound, response.status())
183187
}
184188
}
185189
}
186190
}
187191
}
192+
188193
@Test
189194
fun `gist with empty root is rejected`() {
190195
withTestDb { dbName ->
@@ -205,18 +210,124 @@ class ApplicationTest {
205210
}
206211

207212
@Test
208-
fun `cannot edit gist gist without login`() {
213+
fun `cannot edit gist without login`() {
209214
withTestDb { dbName ->
210215
withTestApplication({ testModuleSetup(dbName) }) {
211216
cookiesSession {
212217
login()
213218
val gistUrl = testGist()
214-
handleRequest(HttpMethod.Get,"/logout").apply {
219+
logout()
220+
handleRequest(HttpMethod.Get, gistUrl.encodedPath + "/edit").apply {
215221
assertEquals(HttpStatusCode.Found, response.status())
222+
assert(response.headers[HttpHeaders.Location]!!.startsWith("/login/github"))
223+
}
224+
}
225+
}
226+
}
227+
}
228+
229+
@Test
230+
fun `can edit my gist`() {
231+
withTestDb { dbName ->
232+
withTestApplication({ testModuleSetup(dbName) }) {
233+
cookiesSession {
234+
login()
235+
val gistUrl = testGist()
236+
handleRequest(HttpMethod.Get, gistUrl.encodedPath + "/edit").apply {
237+
assertEquals(HttpStatusCode.OK, response.status())
216238
}
239+
}
240+
}
241+
}
242+
}
243+
244+
@Test
245+
fun `cannot edit gist without different users gist`() {
246+
withTestDb { dbName ->
247+
withTestApplication({ testModuleSetup(dbName) }) {
248+
cookiesSession {
249+
login()
250+
val gistUrl = testGist()
251+
logout()
252+
login("user2", "[email protected]")
217253
handleRequest(HttpMethod.Get, gistUrl.encodedPath + "/edit").apply {
254+
assertEquals(HttpStatusCode.NotFound, response.status())
255+
}
256+
}
257+
}
258+
}
259+
}
260+
261+
@Test
262+
fun `can delete my gist`() {
263+
withTestDb { dbName ->
264+
withTestApplication({ testModuleSetup(dbName) }) {
265+
cookiesSession {
266+
login()
267+
val gistUrl = testGist()
268+
val csrfToken = handleRequest(HttpMethod.Get, gistUrl.encodedPath + "/delete").run {
269+
val document = Jsoup.parse(response.content)
270+
val csrf =
271+
document.selectFirst("body > div.container > form > input[type=\"hidden\"]:nth-child(2)")
272+
csrf?.attr("value")!!
273+
}
274+
handleRequest(HttpMethod.Post, gistUrl.encodedPath + "/delete") {
275+
addHeader(HttpHeaders.ContentType, ContentType.Application.FormUrlEncoded.toString())
276+
setBody(listOf("CSRFToken" to csrfToken).formUrlEncode())
277+
}.apply {
218278
assertEquals(HttpStatusCode.Found, response.status())
219-
assert(response.headers[HttpHeaders.Location]!!.startsWith("/login/github"))
279+
}
280+
}
281+
}
282+
}
283+
}
284+
285+
@Test
286+
fun `cannot delete when not logged in`() {
287+
withTestDb { dbName ->
288+
withTestApplication({ testModuleSetup(dbName) }) {
289+
cookiesSession {
290+
login()
291+
val gistUrl = testGist()
292+
val csrfToken = handleRequest(HttpMethod.Get, gistUrl.encodedPath + "/delete").run {
293+
val document = Jsoup.parse(response.content)
294+
val csrf =
295+
document.selectFirst("body > div.container > form > input[type=\"hidden\"]:nth-child(2)")
296+
csrf?.attr("value")!!
297+
}
298+
logout()
299+
handleRequest(HttpMethod.Post, gistUrl.encodedPath + "/delete") {
300+
addHeader(HttpHeaders.ContentType, ContentType.Application.FormUrlEncoded.toString())
301+
setBody(listOf("CSRFToken" to csrfToken).formUrlEncode())
302+
}.apply {
303+
assertEquals(HttpStatusCode.Found, response.status())
304+
assert(response.headers[HttpHeaders.Location]!!.startsWith("/login"))
305+
}
306+
}
307+
}
308+
}
309+
}
310+
311+
@Test
312+
fun `cannot delete as different user`() {
313+
withTestDb { dbName ->
314+
withTestApplication({ testModuleSetup(dbName) }) {
315+
cookiesSession {
316+
login()
317+
val gistUrl = testGist()
318+
val csrfToken = handleRequest(HttpMethod.Get, gistUrl.encodedPath + "/delete").run {
319+
val document = Jsoup.parse(response.content)
320+
val csrf =
321+
document.selectFirst("body > div.container > form > input[type=\"hidden\"]:nth-child(2)")
322+
csrf?.attr("value")!!
323+
}
324+
logout()
325+
login("user2", "[email protected]")
326+
handleRequest(HttpMethod.Post, gistUrl.encodedPath + "/delete") {
327+
addHeader(HttpHeaders.ContentType, ContentType.Application.FormUrlEncoded.toString())
328+
setBody(listOf("CSRFToken" to csrfToken).formUrlEncode())
329+
}.apply {
330+
assertEquals(HttpStatusCode.NotFound, response.status())
220331
}
221332
}
222333
}

server/src/test/kotlin/cloud/skadi/Helper.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,10 @@ fun TestApplicationEngine.login(user: String = "testuser", email: String = "test
6868
}
6969
}
7070

71+
fun TestApplicationEngine.logout() = handleRequest(HttpMethod.Get, "/logout").apply {
72+
assertEquals(HttpStatusCode.Found, response.status())
73+
}
74+
7175
fun TestApplicationEngine.testGist(visibility: GistVisibility = GistVisibility.Private) =
7276
handleRequest(HttpMethod.Post, "/gist/create") {
7377
val createRequest = GistCreationRequest(

0 commit comments

Comments
 (0)