diff --git a/src/main/kotlin/com/project/movienight/adapters/web/ApiExceptionHandler.kt b/src/main/kotlin/com/project/movienight/adapters/web/ApiExceptionHandler.kt index 29131e3..0d9a087 100644 --- a/src/main/kotlin/com/project/movienight/adapters/web/ApiExceptionHandler.kt +++ b/src/main/kotlin/com/project/movienight/adapters/web/ApiExceptionHandler.kt @@ -12,19 +12,20 @@ import org.springframework.web.bind.annotation.ExceptionHandler import org.springframework.web.bind.annotation.ResponseStatus import org.springframework.web.bind.annotation.RestControllerAdvice import org.springframework.web.server.ResponseStatusException +import org.springframework.web.servlet.resource.NoResourceFoundException @RestControllerAdvice class ApiExceptionHandler { private val log = LoggerFactory.getLogger(javaClass) - @ExceptionHandler(EntityNotFoundException::class) + @ExceptionHandler(EntityNotFoundException::class, NoResourceFoundException::class) @ResponseStatus(HttpStatus.NOT_FOUND) - fun handleNotFound(exception: EntityNotFoundException): ErrorResponse { + fun handleNotFound(exception: Exception): ErrorResponse { val traceId = currentTraceId() - log.warn("Entity not found: traceId='{}', message='{}'", traceId, exception.message) + log.warn("Resource not found: traceId='{}', message='{}'", traceId, exception.message) return ErrorResponse( - message = exception.message ?: "Entity not found", + message = exception.message ?: "Resource not found", traceId = traceId, ) } diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index c4248b1..a3b844c 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -7,7 +7,6 @@ spring: url: ${SPRING_DATASOURCE_URL:jdbc:h2:mem:movienight;MODE=PostgreSQL;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE} username: ${SPRING_DATASOURCE_USERNAME:sa} password: ${SPRING_DATASOURCE_PASSWORD:} - driver-class-name: ${SPRING_DATASOURCE_DRIVER_CLASS_NAME:org.h2.Driver} hikari: maximum-pool-size: ${SPRING_DATASOURCE_HIKARI_MAXIMUM_POOL_SIZE:20} minimum-idle: ${SPRING_DATASOURCE_HIKARI_MINIMUM_IDLE:5} diff --git a/src/test/kotlin/com/project/movienight/controllers/NotFoundControllerTest.kt b/src/test/kotlin/com/project/movienight/controllers/NotFoundControllerTest.kt new file mode 100644 index 0000000..8d0d6ff --- /dev/null +++ b/src/test/kotlin/com/project/movienight/controllers/NotFoundControllerTest.kt @@ -0,0 +1,35 @@ +package com.project.movienight.controllers + +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.test.web.servlet.MockMvc +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get +import org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath +import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status + +@SpringBootTest +@AutoConfigureMockMvc(addFilters = false) +class NotFoundControllerTest { + @Autowired + private lateinit var mockMvc: MockMvc + + @Test + fun `requesting non-existent path should return 404 JSON response`() { + mockMvc + .perform(get("/non-existent-path")) + .andExpect(status().isNotFound) + .andExpect(jsonPath("$.message").exists()) + .andExpect(jsonPath("$.traceId").exists()) + } + + @Test + fun `requesting root path should return 404 JSON response`() { + mockMvc + .perform(get("/")) + .andExpect(status().isNotFound) + .andExpect(jsonPath("$.message").exists()) + .andExpect(jsonPath("$.traceId").exists()) + } +}