From f7c8ef1e51812b8d9d41c1306af4b92a9effcaf6 Mon Sep 17 00:00:00 2001 From: Manuel Prinz Date: Thu, 13 Feb 2025 11:56:52 +0000 Subject: [PATCH] Add missing transaction manager configuration for media storage --- .../orkg/common/testing/fixtures/Assets.kt | 2 ++ .../build.gradle.kts | 2 ++ .../MediaStorageJpaConfiguration.kt | 2 +- .../MediaStorageJpaTestConfiguration.kt | 13 ++++++++++ .../build.gradle.kts | 3 ++- .../orkg/mediastorage/domain/ImageService.kt | 2 ++ rest-api-server/build.gradle.kts | 2 ++ .../OrganizationControllerIntegrationTest.kt | 23 ++++++++++++++++++ .../resources/assets/images/white_pixel.png | Bin 0 -> 546 bytes 9 files changed, 47 insertions(+), 2 deletions(-) create mode 100644 media-storage/media-storage-adapter-output-spring-data-jpa/src/test/kotlin/org/orkg/mediastorage/adapter/output/jpa/configuration/MediaStorageJpaTestConfiguration.kt create mode 100644 rest-api-server/src/integrationTest/resources/assets/images/white_pixel.png diff --git a/common/testing/src/testFixtures/kotlin/org/orkg/common/testing/fixtures/Assets.kt b/common/testing/src/testFixtures/kotlin/org/orkg/common/testing/fixtures/Assets.kt index 3ef657fbf..6d11933c2 100644 --- a/common/testing/src/testFixtures/kotlin/org/orkg/common/testing/fixtures/Assets.kt +++ b/common/testing/src/testFixtures/kotlin/org/orkg/common/testing/fixtures/Assets.kt @@ -8,6 +8,8 @@ object Assets { fun responseJson(name: String): String = fileContents("responses/$name.json").decodeToString() + fun png(name: String): ByteArray = fileContents("images/$name.png") + private fun fileContents(name: String): ByteArray = ClassPathResource(URI.create("classpath:/assets/$name").path).inputStream.use { it.readBytes() } } diff --git a/media-storage/media-storage-adapter-output-spring-data-jpa/build.gradle.kts b/media-storage/media-storage-adapter-output-spring-data-jpa/build.gradle.kts index 4847980bd..3c0d46267 100644 --- a/media-storage/media-storage-adapter-output-spring-data-jpa/build.gradle.kts +++ b/media-storage/media-storage-adapter-output-spring-data-jpa/build.gradle.kts @@ -32,6 +32,8 @@ testing { implementation("org.springframework:spring-test") implementation(testFixtures(project(":media-storage:media-storage-ports-output"))) implementation(testFixtures(project(":testing:spring"))) + implementation("org.springframework.boot:spring-boot-test") + implementation("org.springframework:spring-orm") } } } diff --git a/media-storage/media-storage-adapter-output-spring-data-jpa/src/main/kotlin/org/orkg/mediastorage/adapter/output/jpa/configuration/MediaStorageJpaConfiguration.kt b/media-storage/media-storage-adapter-output-spring-data-jpa/src/main/kotlin/org/orkg/mediastorage/adapter/output/jpa/configuration/MediaStorageJpaConfiguration.kt index 8d67284fd..a8a12c5fa 100644 --- a/media-storage/media-storage-adapter-output-spring-data-jpa/src/main/kotlin/org/orkg/mediastorage/adapter/output/jpa/configuration/MediaStorageJpaConfiguration.kt +++ b/media-storage/media-storage-adapter-output-spring-data-jpa/src/main/kotlin/org/orkg/mediastorage/adapter/output/jpa/configuration/MediaStorageJpaConfiguration.kt @@ -6,7 +6,7 @@ import org.springframework.context.annotation.Configuration import org.springframework.data.jpa.repository.config.EnableJpaRepositories @Configuration -@EnableJpaRepositories("org.orkg.mediastorage.adapter.output.jpa.internal") +@EnableJpaRepositories("org.orkg.mediastorage.adapter.output.jpa.internal", transactionManagerRef = "jpaTransactionManager") @EntityScan("org.orkg.mediastorage.adapter.output.jpa.internal") @ComponentScan(basePackages = ["org.orkg.mediastorage.adapter.output.jpa"]) class MediaStorageJpaConfiguration diff --git a/media-storage/media-storage-adapter-output-spring-data-jpa/src/test/kotlin/org/orkg/mediastorage/adapter/output/jpa/configuration/MediaStorageJpaTestConfiguration.kt b/media-storage/media-storage-adapter-output-spring-data-jpa/src/test/kotlin/org/orkg/mediastorage/adapter/output/jpa/configuration/MediaStorageJpaTestConfiguration.kt new file mode 100644 index 000000000..713288879 --- /dev/null +++ b/media-storage/media-storage-adapter-output-spring-data-jpa/src/test/kotlin/org/orkg/mediastorage/adapter/output/jpa/configuration/MediaStorageJpaTestConfiguration.kt @@ -0,0 +1,13 @@ +package org.orkg.mediastorage.adapter.output.jpa.configuration + +import org.springframework.boot.test.context.TestConfiguration +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.ComponentScan +import org.springframework.orm.jpa.JpaTransactionManager + +@TestConfiguration +@ComponentScan("org.orkg.mediastorage.adapter.output.jpa") +class MediaStorageJpaTestConfiguration { + @Bean + fun jpaTransactionManager(): JpaTransactionManager = JpaTransactionManager() +} diff --git a/media-storage/media-storage-core-services/build.gradle.kts b/media-storage/media-storage-core-services/build.gradle.kts index 289269568..8b41ad0f4 100644 --- a/media-storage/media-storage-core-services/build.gradle.kts +++ b/media-storage/media-storage-core-services/build.gradle.kts @@ -6,11 +6,12 @@ plugins { dependencies { api("org.springframework:spring-context") + api(project(":common:spring-data")) api(project(":media-storage:media-storage-core-model")) api(project(":media-storage:media-storage-ports-input")) api(project(":media-storage:media-storage-ports-output")) - implementation(project(":common:identifiers")) implementation("org.springframework:spring-core") + implementation(project(":common:identifiers")) } testing { diff --git a/media-storage/media-storage-core-services/src/main/kotlin/org/orkg/mediastorage/domain/ImageService.kt b/media-storage/media-storage-core-services/src/main/kotlin/org/orkg/mediastorage/domain/ImageService.kt index 8fb44f49a..28745aff9 100644 --- a/media-storage/media-storage-core-services/src/main/kotlin/org/orkg/mediastorage/domain/ImageService.kt +++ b/media-storage/media-storage-core-services/src/main/kotlin/org/orkg/mediastorage/domain/ImageService.kt @@ -5,9 +5,11 @@ import java.time.OffsetDateTime import org.orkg.mediastorage.input.CreateImageUseCase import org.orkg.mediastorage.input.ImageUseCases import org.orkg.mediastorage.output.ImageRepository +import org.orkg.spring.data.annotations.TransactionalOnJPA import org.springframework.stereotype.Service @Service +@TransactionalOnJPA class ImageService( private val repository: ImageRepository, private val clock: Clock = Clock.systemDefaultZone(), diff --git a/rest-api-server/build.gradle.kts b/rest-api-server/build.gradle.kts index 151159cf5..81674e836 100644 --- a/rest-api-server/build.gradle.kts +++ b/rest-api-server/build.gradle.kts @@ -65,6 +65,8 @@ testing { implementation("org.keycloak:keycloak-client-common-synced") runtimeOnly("org.springframework.boot:spring-boot") runtimeOnly(project(":keycloak")) + implementation("org.springframework:spring-core") + implementation(project(":media-storage:media-storage-ports-input")) } targets { all { diff --git a/rest-api-server/src/integrationTest/kotlin/org/orkg/community/adapter/input/rest/OrganizationControllerIntegrationTest.kt b/rest-api-server/src/integrationTest/kotlin/org/orkg/community/adapter/input/rest/OrganizationControllerIntegrationTest.kt index 7dbbf8851..296ad24e3 100644 --- a/rest-api-server/src/integrationTest/kotlin/org/orkg/community/adapter/input/rest/OrganizationControllerIntegrationTest.kt +++ b/rest-api-server/src/integrationTest/kotlin/org/orkg/community/adapter/input/rest/OrganizationControllerIntegrationTest.kt @@ -4,6 +4,7 @@ import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test +import org.orkg.common.testing.fixtures.Assets.png import org.orkg.community.domain.OrganizationType import org.orkg.community.input.ContributorUseCases import org.orkg.community.input.ObservatoryUseCases @@ -15,6 +16,9 @@ import org.orkg.createOrganization import org.orkg.createResource import org.orkg.graph.input.ClassUseCases import org.orkg.graph.input.ResourceUseCases +import org.orkg.mediastorage.domain.ImageData +import org.orkg.mediastorage.input.CreateImageUseCase +import org.orkg.mediastorage.input.ImageUseCases import org.orkg.testing.annotations.Neo4jContainerIntegrationTest import org.orkg.testing.spring.MockMvcBaseTest import org.springframework.beans.factory.annotation.Autowired @@ -25,6 +29,7 @@ import org.springframework.restdocs.payload.ResponseFieldsSnippet import org.springframework.restdocs.request.RequestDocumentation.parameterWithName import org.springframework.restdocs.request.RequestDocumentation.pathParameters import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status +import org.springframework.util.MimeType @Neo4jContainerIntegrationTest internal class OrganizationControllerIntegrationTest : MockMvcBaseTest("organizations") { @@ -43,6 +48,9 @@ internal class OrganizationControllerIntegrationTest : MockMvcBaseTest("organiza @Autowired private lateinit var classService: ClassUseCases + @Autowired + private lateinit var imageService: ImageUseCases + @BeforeEach fun setup() { assertThat(service.listOrganizations()).hasSize(0) @@ -97,6 +105,21 @@ internal class OrganizationControllerIntegrationTest : MockMvcBaseTest("organiza .andDo(generateDefaultDocSnippets()) } + @Test + fun fetchLogo() { + val contributorId = contributorService.createContributor() + val imageId = imageService.create(CreateImageUseCase.CreateCommand( + data = ImageData(png("white_pixel")), + mimeType = MimeType.valueOf("image/png"), + createdBy = contributorId, + )) + val organizationId = service.createOrganization(createdBy = contributorId, logoId = imageId) + + get("/api/organizations/{id}/logo", organizationId) + .perform() + .andExpect(status().isOk) + } + @Test fun lookUpObservatoriesByOrganization() { val contributorId = contributorService.createContributor() diff --git a/rest-api-server/src/integrationTest/resources/assets/images/white_pixel.png b/rest-api-server/src/integrationTest/resources/assets/images/white_pixel.png new file mode 100644 index 0000000000000000000000000000000000000000..2d94acff7faf1ed9f2dad2466061070b4ba63ac8 GIT binary patch literal 546 zcmV+-0^R+IP)EX>4Tx04R}tkv&MmKpe$iQ>8^(9PA+Ckf91fyQqj`twIqhgj%6h2a`*`ph-)T z;^HW{799LotU9+0Yt2!bCV?t+t|iWnOduvRvpy$DX?TvWd-(Wz7w1{t=l&dFwO}&9ClV)E-LQx^h-Wsf zI_G`j2rJ7f@i}qKpbHW|a$RxxjdRIifoDdHY-XM~LM)bgSm|L_HZNsGzSbbDicWQdq0S*p< z@e*aPd%Qc?+uOfqI{p0st-f-;S`@t500009a7bBm001r{001r{0eGc9b^rhX2XskI zMF;5u4G1bHu}4F!0000PbVXQnLvL+uWo~o;Lvm$dbY)~9cWHEJAV*0}P*;Ht7XSbN k3`s;mR0!8&`2YVu00sU6{@l!2=Kufz07*qoM6N<$f`qr{VgLXD literal 0 HcmV?d00001