Skip to content

Commit

Permalink
New upload service between controller and attachmentservice
Browse files Browse the repository at this point in the history
  • Loading branch information
pitkni committed Nov 23, 2023
1 parent 0aae064 commit c0a8c58
Show file tree
Hide file tree
Showing 9 changed files with 233 additions and 160 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package fi.hel.haitaton.hanke
import fi.hel.haitaton.hanke.application.ApplicationAuthorizer
import fi.hel.haitaton.hanke.application.ApplicationService
import fi.hel.haitaton.hanke.attachment.application.ApplicationAttachmentService
import fi.hel.haitaton.hanke.attachment.common.AttachmentUploadService
import fi.hel.haitaton.hanke.attachment.hanke.HankeAttachmentAuthorizer
import fi.hel.haitaton.hanke.attachment.hanke.HankeAttachmentService
import fi.hel.haitaton.hanke.configuration.FeatureFlags
Expand Down Expand Up @@ -73,6 +74,8 @@ class IntegrationTestConfiguration {

@Bean fun hankeAttachmentService(): HankeAttachmentService = mockk()

@Bean fun attachmentUploadService(): AttachmentUploadService = mockk()

@Bean fun applicationAttachmentService(): ApplicationAttachmentService = mockk()

@Bean fun hankeKayttajaService(): HankeKayttajaService = mockk()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package fi.hel.haitaton.hanke.attachment.common

import assertk.all
import assertk.assertFailure
import assertk.assertThat
import assertk.assertions.hasClass
import assertk.assertions.hasMessage
import assertk.assertions.isEqualTo
import assertk.assertions.prop
import fi.hel.haitaton.hanke.DatabaseTest
import fi.hel.haitaton.hanke.attachment.USERNAME
import fi.hel.haitaton.hanke.attachment.azure.Container
import fi.hel.haitaton.hanke.attachment.body
import fi.hel.haitaton.hanke.attachment.failResult
import fi.hel.haitaton.hanke.attachment.response
import fi.hel.haitaton.hanke.attachment.successResult
import fi.hel.haitaton.hanke.attachment.testFile
import fi.hel.haitaton.hanke.factory.HankeFactory
import fi.hel.haitaton.hanke.test.Asserts.isRecent
import okhttp3.mockwebserver.MockWebServer
import org.junit.jupiter.api.AfterEach
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Nested
import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.security.test.context.support.WithMockUser
import org.springframework.test.context.ActiveProfiles

@SpringBootTest
@ActiveProfiles("test")
@WithMockUser(USERNAME)
class AttachmentUploadServiceITest(
@Autowired private val attachmentUploadService: AttachmentUploadService,
@Autowired private val attachmentRepository: HankeAttachmentRepository,
@Autowired private val hankeFactory: HankeFactory,
@Autowired private val fileClient: MockFileClient
) : DatabaseTest() {

private lateinit var mockClamAv: MockWebServer

@BeforeEach
fun setup() {
fileClient.recreateContainers()
mockClamAv = MockWebServer()
mockClamAv.start(6789)
}

@AfterEach
fun tearDown() {
mockClamAv.shutdown()
}

@Nested
inner class UploadHankeAttachment {
@Test
fun `Should upload blob and return saved metadata`() {
mockClamAv.enqueue(response(body(results = successResult())))
val hanke = hankeFactory.save()
val file = testFile()

val result =
attachmentUploadService.uploadHankeAttachment(
hankeTunnus = hanke.hankeTunnus,
attachment = testFile()
)

assertThat(result).all {
prop(HankeAttachment::hankeTunnus).isEqualTo(hanke.hankeTunnus)
prop(HankeAttachment::createdAt).isRecent()
prop(HankeAttachment::createdByUserId).isEqualTo(USERNAME)
prop(HankeAttachment::fileName).isEqualTo(file.originalFilename)
}
val attachment = attachmentRepository.findById(result.id).orElseThrow()
val blob = fileClient.download(Container.HANKE_LIITTEET, attachment.blobLocation!!)
assertThat(blob.contentType.toString()).isEqualTo(file.contentType)
}

@Test
fun `Should throw when infected file is encountered`() {
mockClamAv.enqueue(response(body(results = failResult())))
val hanke = hankeFactory.save()

assertFailure {
attachmentUploadService.uploadHankeAttachment(
hankeTunnus = hanke.hankeTunnus,
attachment = testFile()
)
}
.all {
hasClass(AttachmentInvalidException::class)
hasMessage(
"Attachment upload exception: Infected file detected, see previous logs."
)
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import fi.hel.haitaton.hanke.attachment.HANKE_TUNNUS
import fi.hel.haitaton.hanke.attachment.USERNAME
import fi.hel.haitaton.hanke.attachment.andExpectError
import fi.hel.haitaton.hanke.attachment.common.AttachmentContent
import fi.hel.haitaton.hanke.attachment.common.AttachmentInvalidException
import fi.hel.haitaton.hanke.attachment.common.AttachmentUploadService
import fi.hel.haitaton.hanke.attachment.testFile
import fi.hel.haitaton.hanke.factory.AttachmentFactory
import fi.hel.haitaton.hanke.factory.TestHankeIdentifier
Expand Down Expand Up @@ -56,6 +58,7 @@ import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status
class HankeAttachmentControllerITests(@Autowired override val mockMvc: MockMvc) : ControllerTest {

@Autowired private lateinit var hankeAttachmentService: HankeAttachmentService
@Autowired private lateinit var attachmentUploadService: AttachmentUploadService
@Autowired private lateinit var authorizer: HankeAttachmentAuthorizer

@BeforeEach
Expand Down Expand Up @@ -106,17 +109,30 @@ class HankeAttachmentControllerITests(@Autowired override val mockMvc: MockMvc)
val file = testFile()
val hanke = TestHankeIdentifier(1, HANKE_TUNNUS)
every { authorizer.authorizeHankeTunnus(HANKE_TUNNUS, EDIT.name) } returns true
every { hankeAttachmentService.hankeWithRoomForAttachment(HANKE_TUNNUS) } returns hanke
every {
hankeAttachmentService.addAttachment(hanke, FILE_NAME_PDF, APPLICATION_PDF, file.bytes)
} returns AttachmentFactory.hankeAttachment()
every { attachmentUploadService.uploadHankeAttachment(hanke.hankeTunnus, file) } returns
AttachmentFactory.hankeAttachment()

postAttachment(file = file).andExpect(status().isOk)

verifyOrder {
authorizer.authorizeHankeTunnus(HANKE_TUNNUS, EDIT.name)
hankeAttachmentService.hankeWithRoomForAttachment(HANKE_TUNNUS)
hankeAttachmentService.addAttachment(hanke, FILE_NAME_PDF, APPLICATION_PDF, file.bytes)
attachmentUploadService.uploadHankeAttachment(hanke.hankeTunnus, file)
}
}

@Test
fun `postAttachment when attachment invalid or amount exceeded return bad request`() {
val file = testFile()
val hanke = TestHankeIdentifier(1, HANKE_TUNNUS)
every { authorizer.authorizeHankeTunnus(HANKE_TUNNUS, EDIT.name) } returns true
every { attachmentUploadService.uploadHankeAttachment(hanke.hankeTunnus, file) } throws
AttachmentInvalidException("Something went wrong")

postAttachment(file = file).andExpect(status().isBadRequest)

verifyOrder {
authorizer.authorizeHankeTunnus(HANKE_TUNNUS, EDIT.name)
attachmentUploadService.uploadHankeAttachment(hanke.hankeTunnus, file)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,12 @@ import fi.hel.haitaton.hanke.attachment.common.HankeAttachmentEntity
import fi.hel.haitaton.hanke.attachment.common.HankeAttachmentRepository
import fi.hel.haitaton.hanke.attachment.common.MockFileClient
import fi.hel.haitaton.hanke.attachment.common.MockFileClientExtension
import fi.hel.haitaton.hanke.attachment.failResult
import fi.hel.haitaton.hanke.attachment.response
import fi.hel.haitaton.hanke.attachment.successResult
import fi.hel.haitaton.hanke.factory.AttachmentFactory
import fi.hel.haitaton.hanke.factory.HankeAttachmentFactory
import fi.hel.haitaton.hanke.factory.HankeFactory
import fi.hel.haitaton.hanke.factory.HankeIdentifierFactory
import fi.hel.haitaton.hanke.factory.TestHankeIdentifier
import fi.hel.haitaton.hanke.factory.identifier
import java.time.OffsetDateTime
import java.util.UUID
import okhttp3.mockwebserver.MockWebServer
Expand All @@ -48,7 +45,6 @@ import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.ExtendWith
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.http.MediaType.APPLICATION_PDF
import org.springframework.http.MediaType.APPLICATION_PDF_VALUE
import org.springframework.security.test.context.support.WithMockUser
import org.springframework.test.context.ActiveProfiles
Expand Down Expand Up @@ -160,24 +156,19 @@ class HankeAttachmentServiceITests(
}

@Nested
inner class AddAttachment {

@BeforeEach
fun clear() {
fileClient.recreateContainers()
}

inner class SaveAttachment {
@Test
fun `Should return metadata of saved attachment`() {
mockClamAv.enqueue(response(body(results = successResult())))
val hanke = hankeFactory.save()
val blobPath = blobPath(hanke.id)

val result =
hankeAttachmentService.addAttachment(
hanke = hanke.identifier(),
hankeAttachmentService.saveAttachment(
hankeTunnus = hanke.hankeTunnus,
name = FILE_NAME_PDF,
type = APPLICATION_PDF,
content = DEFAULT_DATA
type = APPLICATION_PDF_VALUE,
blobPath = blobPath,
)

assertThat(result.id).isNotNull()
Expand All @@ -192,8 +183,7 @@ class HankeAttachmentServiceITests(
assertThat(attachmentInDb.createdByUserId).isEqualTo(USERNAME)
assertThat(attachmentInDb.fileName).isEqualTo(FILE_NAME_PDF)
assertThat(attachmentInDb.createdAt).isNotNull()
val blob = fileClient.download(HANKE_LIITTEET, attachmentInDb.blobLocation!!)
assertThat(blob.contentType).isEqualTo(APPLICATION_PDF)
assertThat(attachmentInDb.blobLocation).isEqualTo(blobPath)
}

@Test
Expand All @@ -205,11 +195,11 @@ class HankeAttachmentServiceITests(
.let { hankeAttachmentRepository.saveAll(it) }

assertFailure {
hankeAttachmentService.addAttachment(
TestHankeIdentifier(hanke.id, hanke.hankeTunnus),
hankeAttachmentService.saveAttachment(
hanke.hankeTunnus,
FILE_NAME_PDF,
APPLICATION_PDF,
ByteArray(0)
APPLICATION_PDF_VALUE,
blobPath(hanke.id),
)
}
.all {
Expand All @@ -223,38 +213,19 @@ class HankeAttachmentServiceITests(
mockClamAv.enqueue(response(body(results = successResult())))

assertFailure {
hankeAttachmentService.addAttachment(
hanke = TestHankeIdentifier(5, "HAI-123"),
hankeAttachmentService.saveAttachment(
hankeTunnus = "HAI-123",
name = FILE_NAME_PDF,
type = APPLICATION_PDF,
content = DEFAULT_DATA
type = APPLICATION_PDF_VALUE,
blobPath = blobPath(123)
)
}
.hasClass(HankeNotFoundException::class)

assertThat(hankeAttachmentRepository.findAll()).isEmpty()
}

@Test
fun `Should throw when infected file is encountered`() {
mockClamAv.enqueue(response(body(results = failResult())))
val hanke = hankeFactory.save()

assertFailure {
hankeAttachmentService.addAttachment(
hanke = hanke.identifier(),
name = FILE_NAME_PDF,
type = APPLICATION_PDF,
content = DEFAULT_DATA
)
}
.all {
hasClass(AttachmentInvalidException::class)
hasMessage(
"Attachment upload exception: Infected file detected, see previous logs."
)
}
}
private fun blobPath(hankeId: Int) = HankeAttachmentContentService.generateBlobPath(hankeId)
}

@Nested
Expand Down

This file was deleted.

Loading

0 comments on commit c0a8c58

Please sign in to comment.