test: write tests for controllers #24
@@ -0,0 +1,131 @@
|
||||
package com.project.movienight.controllers
|
||||
|
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper
|
||||
import com.project.movienight.adapters.web.dto.request.CreateFilmRequest
|
||||
import com.project.movienight.adapters.web.dto.request.EditFilmRequest
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc
|
||||
import org.springframework.boot.test.context.SpringBootTest
|
||||
import org.springframework.http.MediaType
|
||||
import org.springframework.test.web.servlet.MockMvc
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*
|
||||
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.*
|
||||
|
||||
@SpringBootTest
|
||||
@AutoConfigureMockMvc
|
||||
class FilmControllerTest {
|
||||
|
||||
@Autowired
|
||||
private lateinit var mockMvc: MockMvc
|
||||
|
||||
@Autowired
|
||||
private lateinit var objectMapper: ObjectMapper
|
||||
|
||||
@Test
|
||||
fun `create film should return 201 CREATED`() {
|
||||
val request = CreateFilmRequest(
|
||||
title = "The Matrix",
|
||||
description = "A computer hacker learns about the true nature of reality"
|
||||
)
|
||||
|
||||
mockMvc.perform(
|
||||
post("/api/films")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content(objectMapper.writeValueAsString(request))
|
||||
)
|
||||
.andExpect(status().isCreated)
|
||||
.andExpect(jsonPath("$.title").value("The Matrix"))
|
||||
.andExpect(jsonPath("$.description").value("A computer hacker learns about the true nature of reality"))
|
||||
.andExpect(jsonPath("$.id").exists())
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
fun `edit film should return updated film`() {
|
||||
val createRequest = CreateFilmRequest(
|
||||
title = "Old Title",
|
||||
description = "Old Description"
|
||||
)
|
||||
|
||||
val response = mockMvc.perform(
|
||||
post("/api/films")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content(objectMapper.writeValueAsString(createRequest))
|
||||
).andReturn()
|
||||
|
||||
val filmId = objectMapper.readTree(response.response.contentAsString).get("id").asText()
|
||||
|
||||
val editRequest = EditFilmRequest(
|
||||
title = "New Title",
|
||||
description = "New Description"
|
||||
)
|
||||
|
||||
mockMvc.perform(
|
||||
patch("/api/films/$filmId")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content(objectMapper.writeValueAsString(editRequest))
|
||||
)
|
||||
.andExpect(status().isOk)
|
||||
.andExpect(jsonPath("$.title").value("New Title"))
|
||||
.andExpect(jsonPath("$.description").value("New Description"))
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
fun `search film by title should return film`() {
|
||||
val request = CreateFilmRequest(
|
||||
title = "Inception",
|
||||
description = "Dream within a dream"
|
||||
)
|
||||
|
||||
mockMvc.perform(
|
||||
post("/api/films")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content(objectMapper.writeValueAsString(request))
|
||||
)
|
||||
|
||||
mockMvc.perform(
|
||||
get("/api/films/search")
|
||||
.param("title", "Inception")
|
||||
)
|
||||
.andExpect(status().isOk)
|
||||
.andExpect(jsonPath("$.title").value("Inception"))
|
||||
.andExpect(jsonPath("$.description").value("Dream within a dream"))
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
fun `search film by non-existent title should return empty`() {
|
||||
mockMvc.perform(
|
||||
get("/api/films/search")
|
||||
.param("title", "NonExistentFilm12345")
|
||||
)
|
||||
.andExpect(status().isOk)
|
||||
.andExpect(content().string(""))
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
fun `delete film should return 204 NO CONTENT`() {
|
||||
val request = CreateFilmRequest(
|
||||
title = "Film To Delete",
|
||||
description = "This film will be deleted"
|
||||
)
|
||||
|
||||
val response = mockMvc.perform(
|
||||
post("/api/films")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content(objectMapper.writeValueAsString(request))
|
||||
).andReturn()
|
||||
|
||||
val filmId = objectMapper.readTree(response.response.contentAsString).get("id").asText()
|
||||
|
||||
mockMvc.perform(delete("/api/films/$filmId"))
|
||||
.andExpect(status().isNoContent())
|
||||
|
||||
mockMvc.perform(get("/api/films/search").param("title", "Film To Delete"))
|
||||
.andExpect(status().isOk)
|
||||
.andExpect(content().string(""))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package com.project.movienight.controllers
|
||||
|
These wildcard imports ( These wildcard imports (`MockMvcRequestBuilders.*`, `MockMvcResultMatchers.*`) will fail ktlint's `no-wildcard-imports` rule (ktlintCheck is part of `check`). Replace them with explicit imports for only the methods/matchers used in this test file.
```suggestion
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status
```
There are consecutive blank lines in this file (e.g., here before the first test), which will fail ktlint formatting checks. Remove extra blank lines so there's at most one blank line between members. There are consecutive blank lines in this file (e.g., here before the first test), which will fail ktlint formatting checks. Remove extra blank lines so there's at most one blank line between members.
```suggestion
```
This This `mockMvc.perform(...)` call is formatted as a multiline call-site but is missing the trailing comma after the single argument. The main source files consistently use trailing commas in multiline call-sites, and with ktlint experimental rules enabled this can fail formatting checks; update this (and similar call-sites in the file) to include the trailing comma.
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper
|
||||
import com.project.movienight.adapters.web.dto.request.CreateFilmRequest
|
||||
import com.project.movienight.adapters.web.dto.request.CreateUserRequest
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc
|
||||
import org.springframework.boot.test.context.SpringBootTest
|
||||
import org.springframework.http.MediaType
|
||||
import org.springframework.test.web.servlet.MockMvc
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*
|
||||
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.*
|
||||
import org.springframework.transaction.annotation.Transactional
|
||||
|
||||
@SpringBootTest
|
||||
@AutoConfigureMockMvc
|
||||
@Transactional
|
||||
class FilmLibraryControllerTest {
|
||||
|
||||
@Autowired
|
||||
private lateinit var mockMvc: MockMvc
|
||||
|
||||
@Autowired
|
||||
private lateinit var objectMapper: ObjectMapper
|
||||
|
||||
|
||||
@Test
|
||||
fun `add film to library should work`() {
|
||||
val userRequest = CreateUserRequest("Film Adder", "adder@example.com")
|
||||
val userResponse = mockMvc.perform(
|
||||
post("/api/users")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content(objectMapper.writeValueAsString(userRequest))
|
||||
).andReturn()
|
||||
val userId = objectMapper.readTree(userResponse.response.contentAsString).get("id").asText()
|
||||
|
||||
val filmRequest = CreateFilmRequest("Library Film", "Film description")
|
||||
val filmResponse = mockMvc.perform(
|
||||
post("/api/films")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content(objectMapper.writeValueAsString(filmRequest))
|
||||
).andReturn()
|
||||
val filmId = objectMapper.readTree(filmResponse.response.contentAsString).get("id").asText()
|
||||
|
||||
mockMvc.perform(
|
||||
post("/api/users/$userId/library/films/$filmId")
|
||||
)
|
||||
.andExpect(status().isCreated)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `remove film from library should return 204`() {
|
||||
val userRequest = CreateUserRequest("Remove Film", "remove@example.com")
|
||||
val userResponse = mockMvc.perform(
|
||||
post("/api/users")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content(objectMapper.writeValueAsString(userRequest))
|
||||
).andReturn()
|
||||
val userId = objectMapper.readTree(userResponse.response.contentAsString).get("id").asText()
|
||||
|
||||
val filmRequest = CreateFilmRequest("Film To Remove", "Will be removed")
|
||||
val filmResponse = mockMvc.perform(
|
||||
post("/api/films")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content(objectMapper.writeValueAsString(filmRequest))
|
||||
).andReturn()
|
||||
val filmId = objectMapper.readTree(filmResponse.response.contentAsString).get("id").asText()
|
||||
|
||||
mockMvc.perform(post("/api/users/$userId/library/films/$filmId"))
|
||||
mockMvc.perform(delete("/api/users/$userId/library/films/$filmId"))
|
||||
.andExpect(status().isNoContent())
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
package com.project.movienight.controllers
|
||||
|
This multiline This multiline `CreateUserRequest(...)` call is missing a trailing comma after the last argument. The main codebase consistently uses trailing commas in multiline argument lists, and with ktlint experimental rules enabled this can fail formatting checks; update this (and other multiline calls in the file) to include trailing commas.
These wildcard imports ( These wildcard imports (`MockMvcRequestBuilders.*`, `MockMvcResultMatchers.*`) will fail ktlint's `no-wildcard-imports` rule (ktlintCheck is part of `check`). Replace them with explicit imports for only the methods/matchers used in this test file.
```suggestion
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.patch
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status
```
This file has consecutive blank lines (e.g., between test cases), which will fail ktlint's standard formatting rules. Remove extra blank lines so there's at most one blank line between members. This file has consecutive blank lines (e.g., between test cases), which will fail ktlint's standard formatting rules. Remove extra blank lines so there's at most one blank line between members.
```suggestion
```
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper
|
||||
import com.project.movienight.adapters.web.dto.request.CreateUserRequest
|
||||
import com.project.movienight.adapters.web.dto.request.EditUserRequest
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc
|
||||
import org.springframework.boot.test.context.SpringBootTest
|
||||
import org.springframework.http.MediaType
|
||||
import org.springframework.test.web.servlet.MockMvc
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*
|
||||
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.*
|
||||
import org.springframework.transaction.annotation.Transactional
|
||||
|
||||
@SpringBootTest
|
||||
@AutoConfigureMockMvc
|
||||
@Transactional
|
||||
class UserControllerTest {
|
||||
|
||||
@Autowired
|
||||
private lateinit var mockMvc: MockMvc
|
||||
|
||||
@Autowired
|
||||
private lateinit var objectMapper: ObjectMapper
|
||||
|
||||
@Test
|
||||
fun `create user should return 201 CREATED`() {
|
||||
val request = CreateUserRequest(
|
||||
name = "John Doe",
|
||||
email = "john@example.com"
|
||||
)
|
||||
|
||||
mockMvc.perform(
|
||||
post("/api/users")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content(objectMapper.writeValueAsString(request))
|
||||
)
|
||||
.andExpect(status().isCreated)
|
||||
.andExpect(jsonPath("$.name").value("John Doe"))
|
||||
.andExpect(jsonPath("$.email").value("john@example.com"))
|
||||
.andExpect(jsonPath("$.id").exists())
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
fun `edit user should return updated user`() {
|
||||
val createRequest = CreateUserRequest(
|
||||
name = "Old Name",
|
||||
email = "edit@example.com"
|
||||
)
|
||||
|
||||
val response = mockMvc.perform(
|
||||
post("/api/users")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content(objectMapper.writeValueAsString(createRequest))
|
||||
).andReturn()
|
||||
|
||||
val userId = objectMapper.readTree(response.response.contentAsString).get("id").asText()
|
||||
|
||||
val editRequest = EditUserRequest(name = "New Name")
|
||||
|
||||
mockMvc.perform(
|
||||
patch("/api/users/$userId")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content(objectMapper.writeValueAsString(editRequest))
|
||||
)
|
||||
.andExpect(status().isOk)
|
||||
.andExpect(jsonPath("$.name").value("New Name"))
|
||||
.andExpect(jsonPath("$.email").value("edit@example.com"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `delete user should return 204 NO CONTENT`() {
|
||||
val request = CreateUserRequest(
|
||||
name = "User To Delete",
|
||||
email = "delete@example.com"
|
||||
)
|
||||
|
||||
val response = mockMvc.perform(
|
||||
post("/api/users")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content(objectMapper.writeValueAsString(request))
|
||||
).andReturn()
|
||||
|
||||
val userId = objectMapper.readTree(response.response.contentAsString).get("id").asText()
|
||||
|
||||
mockMvc.perform(delete("/api/users/$userId"))
|
||||
.andExpect(status().isNoContent())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `delete non-existent user should return 404`() {
|
||||
val nonExistentId = "123e4567-e89b-12d3-a456-426614174000"
|
||||
mockMvc.perform(delete("/api/users/$nonExistentId"))
|
||||
.andExpect(status().isNotFound())
|
||||
}
|
||||
}
|
||||
This multiline
EditFilmRequest(...)call is missing a trailing comma after the last argument; with ktlint experimental rules enabled in this repo, that often fails formatting checks. Add the trailing comma to match the style used throughout the codebase.These wildcard imports (
MockMvcRequestBuilders.*,MockMvcResultMatchers.*) will fail ktlint'sno-wildcard-importsrule (ktlintCheck is part ofcheck). Replace them with explicit imports for only the methods/matchers used in this test file.There are consecutive blank lines between tests (e.g., around here), which will fail ktlint's standard formatting rules. Remove the extra blank line(s) so there's at most one blank line between members.
This multiline
CreateFilmRequest(...)call is missing a trailing comma after the last argument; with ktlint experimental rules enabled in this repo, that often fails formatting checks. Add the trailing comma to match the style used throughout the main source files.This
mockMvc.perform(...)is formatted as a multiline call-site but is missing the trailing comma after the argument. The main codebase uses trailing commas for multiline call-sites, and with ktlint experimental rules enabled this can fail formatting checks; update this (and similar call-sites in the file) to include the trailing comma.