Skip to content

Commit 531bec0

Browse files
committed
Handle NoSuchKeyException in exception handling and add related integration tests
- Added a handler for `NoSuchKeyException` to return a NOT_FOUND response with appropriate details. - Introduced integration tests to validate behavior when accessing non-existent workspace files.
1 parent be36cd3 commit 531bec0

File tree

3 files changed

+67
-0
lines changed

3 files changed

+67
-0
lines changed

api/src/integrationTest/kotlin/com/cosmotech/api/home/workspace/WorkspaceControllerTests.kt

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import org.springframework.security.test.web.servlet.request.SecurityMockMvcRequ
3434
import org.springframework.test.context.ActiveProfiles
3535
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*
3636
import org.springframework.test.web.servlet.result.MockMvcResultHandlers
37+
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.content
3738
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath
3839
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status
3940

@@ -658,4 +659,40 @@ class WorkspaceControllerTests : ControllerTestBase() {
658659
document(
659660
"organizations/{organization_id}/workspaces/{workspace_id}/files/download/GET"))
660661
}
662+
663+
@Test
664+
@WithMockOauth2User
665+
fun `download workspace file with wrong file name`() {
666+
667+
val workspaceId =
668+
createWorkspaceAndReturnId(
669+
mvc, organizationId, constructWorkspaceCreateRequest(solutionId = solutionId))
670+
671+
val fileName = "test.txt"
672+
val fileToUpload =
673+
this::class.java.getResourceAsStream("/workspace/$fileName")
674+
?: throw IllegalStateException(
675+
"$fileName file used for organizations/{organization_id}/workspaces/{workspace_id}/files/POST endpoint documentation cannot be null")
676+
677+
val mockFile =
678+
MockMultipartFile(
679+
"file", fileName, MediaType.TEXT_PLAIN_VALUE, IOUtils.toByteArray(fileToUpload))
680+
681+
val destination = "path/to/a/directory/"
682+
mvc.perform(
683+
multipart("/organizations/$organizationId/workspaces/$workspaceId/files")
684+
.file(mockFile)
685+
.param("overwrite", "true")
686+
.param("destination", destination)
687+
.accept(MediaType.APPLICATION_JSON)
688+
.with(csrf()))
689+
690+
mvc.perform(
691+
get("/organizations/$organizationId/workspaces/$workspaceId/files/download")
692+
.param("file_name", "Wrong file name")
693+
.accept(MediaType.APPLICATION_OCTET_STREAM))
694+
.andExpect(status().is4xxClientError)
695+
.andExpect(jsonPath("$.detail").value("The specified key does not exist."))
696+
.andDo(MockMvcResultHandlers.print())
697+
}
661698
}

common/src/main/kotlin/com/cosmotech/common/exceptions/CsmExceptionHandling.kt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import org.springframework.web.bind.annotation.RestControllerAdvice
2121
import org.springframework.web.context.request.WebRequest
2222
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler
2323
import org.springframework.web.util.BindErrorUtils
24+
import software.amazon.awssdk.services.s3.model.NoSuchKeyException
2425

2526
@Order(Ordered.HIGHEST_PRECEDENCE)
2627
@RestControllerAdvice
@@ -160,4 +161,15 @@ open class CsmExceptionHandling : ResponseEntityExceptionHandler() {
160161
}
161162
return response
162163
}
164+
165+
@ExceptionHandler(NoSuchKeyException::class)
166+
fun handleNoSuchKeyException(exception: NoSuchKeyException): ProblemDetail {
167+
val response = ProblemDetail.forStatus(HttpStatus.NOT_FOUND)
168+
val notImplementedErrorStatus = HttpStatus.NOT_FOUND
169+
response.type = URI.create(httpStatusCodeTypePrefix + notImplementedErrorStatus.value())
170+
if (exception.awsErrorDetails().errorMessage() != null) {
171+
response.detail = exception.awsErrorDetails().errorMessage()
172+
}
173+
return response
174+
}
163175
}

workspace/src/integrationTest/kotlin/com/cosmotech/workspace/service/WorkspaceServiceIntegrationTest.kt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,24 @@ class WorkspaceServiceIntegrationTest : CsmTestBase() {
177177
assertEquals(expectedText, retrievedText)
178178
}
179179

180+
@Test
181+
fun `test get workspace file with wrong name`() {
182+
val resourceTestFile = resourceLoader.getResource("classpath:/$fileName").file
183+
val input = FileInputStream(resourceTestFile)
184+
val multipartFile =
185+
MockMultipartFile(
186+
"file", resourceTestFile.getName(), "text/plain", IOUtils.toByteArray(input))
187+
workspaceApiService.createWorkspaceFile(
188+
organizationSaved.id, workspaceSaved.id, multipartFile, true, null)
189+
190+
val exception =
191+
assertThrows<NoSuchKeyException> {
192+
workspaceApiService.getWorkspaceFile(organizationSaved.id, workspaceSaved.id, "WrongName")
193+
}
194+
195+
assertEquals("The specified key does not exist.", exception.awsErrorDetails().errorMessage())
196+
}
197+
180198
@Test
181199
fun `test list workspace files`() {
182200
every { getCurrentAuthenticatedRoles(any()) } returns listOf("Platform.Admin")

0 commit comments

Comments
 (0)