From 1b40d2df086de040da16f0dcda4e9e93e2e7486f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20V=C3=A5rdal=20Itland?= Date: Mon, 12 Dec 2022 15:51:52 +0100 Subject: [PATCH 1/4] =?UTF-8?q?Pr=C3=B8v=20=C3=A5=20bygge=20med=20forel?= =?UTF-8?q?=C3=B8pig=20versjon?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 ++ .../kotlin/org/kravbank/domain/Publication.kt | 8 ++++---- .../org/kravbank/domain/SoftDeletable.kt | 7 +++++++ .../kravbank/repository/BackendRepository.kt | 19 +++++++++++++++++++ .../repository/PublicationRepository.kt | 12 +----------- .../kravbank/service/PublicationService.kt | 7 +++---- 6 files changed, 36 insertions(+), 19 deletions(-) create mode 100644 src/main/kotlin/org/kravbank/domain/SoftDeletable.kt create mode 100644 src/main/kotlin/org/kravbank/repository/BackendRepository.kt diff --git a/README.md b/README.md index 401ccc92..0e3b2219 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # Kravbank backend README +TODO: Remove this, it is only to trigger a new build in GitHub + ## Prerequisites * In order to run the application locally, you need a .env file diff --git a/src/main/kotlin/org/kravbank/domain/Publication.kt b/src/main/kotlin/org/kravbank/domain/Publication.kt index 071bbbe1..43c4c858 100644 --- a/src/main/kotlin/org/kravbank/domain/Publication.kt +++ b/src/main/kotlin/org/kravbank/domain/Publication.kt @@ -1,14 +1,14 @@ -package org.kravbank.domain; +package org.kravbank.domain import com.fasterxml.jackson.annotation.JsonIgnore import com.fasterxml.jackson.annotation.JsonManagedReference -import io.quarkus.hibernate.orm.panache.PanacheEntity; +import io.quarkus.hibernate.orm.panache.PanacheEntity import java.time.LocalDateTime import java.util.* import javax.persistence.* @Entity -class Publication : PanacheEntity() { +class Publication : PanacheEntity(), SoftDeletable { var comment: String = "" @@ -19,7 +19,7 @@ class Publication : PanacheEntity() { @Column(unique = true) var ref: String = UUID.randomUUID().toString() - var deletedDate: LocalDateTime? = null + override var deletedDate: LocalDateTime? = null @ManyToOne( cascade = [CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH], //CascadeType.Detach diff --git a/src/main/kotlin/org/kravbank/domain/SoftDeletable.kt b/src/main/kotlin/org/kravbank/domain/SoftDeletable.kt new file mode 100644 index 00000000..a2483d68 --- /dev/null +++ b/src/main/kotlin/org/kravbank/domain/SoftDeletable.kt @@ -0,0 +1,7 @@ +package org.kravbank.domain + +import java.time.LocalDateTime + +interface SoftDeletable { + var deletedDate: LocalDateTime? +} \ No newline at end of file diff --git a/src/main/kotlin/org/kravbank/repository/BackendRepository.kt b/src/main/kotlin/org/kravbank/repository/BackendRepository.kt new file mode 100644 index 00000000..2e99fc65 --- /dev/null +++ b/src/main/kotlin/org/kravbank/repository/BackendRepository.kt @@ -0,0 +1,19 @@ +package org.kravbank.repository + +import io.quarkus.hibernate.orm.panache.PanacheRepository +import org.kravbank.domain.SoftDeletable +import java.time.LocalDateTime + +//private var T.deletedDate: LocalDateTime? +// get() {} +// set() {} + +open class BackendRepository : PanacheRepository { + fun deletePublication(publication: T): T { + val deletedDate = LocalDateTime.now() + //val updates = update("deleteddate = ?1 where id = ?2", deletedDate, publication) + publication.deletedDate = deletedDate + persistAndFlush(publication) + return publication + } +} \ No newline at end of file diff --git a/src/main/kotlin/org/kravbank/repository/PublicationRepository.kt b/src/main/kotlin/org/kravbank/repository/PublicationRepository.kt index eee77746..0a4836a2 100644 --- a/src/main/kotlin/org/kravbank/repository/PublicationRepository.kt +++ b/src/main/kotlin/org/kravbank/repository/PublicationRepository.kt @@ -1,6 +1,5 @@ package org.kravbank.repository -import io.quarkus.hibernate.orm.panache.PanacheRepository import org.kravbank.domain.Publication import org.kravbank.lang.BackendException import org.kravbank.lang.BadRequestException @@ -8,13 +7,11 @@ import org.kravbank.lang.NotFoundException import org.kravbank.utils.Messages.RepoErrorMsg.PUBLICATION_BADREQUEST_CREATE import org.kravbank.utils.Messages.RepoErrorMsg.PUBLICATION_BADREQUEST_UPDATE import org.kravbank.utils.Messages.RepoErrorMsg.PUBLICATION_NOTFOUND -import java.time.LocalDateTime import java.util.* import javax.enterprise.context.ApplicationScoped -import kotlin.streams.toList @ApplicationScoped -class PublicationRepository : PanacheRepository { +class PublicationRepository : BackendRepository() { @Throws(BackendException::class) fun findByRef(projectId: Long, ref: String): Publication { val publication = @@ -43,13 +40,6 @@ class PublicationRepository : PanacheRepository { } } - fun deletePublication(id: Long): Boolean { - val deletedDate = LocalDateTime.now() - val updates = update("deleteddate = ?1 where id = ?2", deletedDate, id) - if (updates > 0) return true - return false - } - @Throws(BackendException::class) fun updatePublication(id: Long, publication: Publication) { val updated = update( diff --git a/src/main/kotlin/org/kravbank/service/PublicationService.kt b/src/main/kotlin/org/kravbank/service/PublicationService.kt index e1f8e9a8..12f0094a 100644 --- a/src/main/kotlin/org/kravbank/service/PublicationService.kt +++ b/src/main/kotlin/org/kravbank/service/PublicationService.kt @@ -3,7 +3,6 @@ package org.kravbank.service import org.kravbank.dao.PublicationForm import org.kravbank.domain.Publication import org.kravbank.lang.BackendException -import org.kravbank.lang.BadRequestException import org.kravbank.repository.ProjectRepository import org.kravbank.repository.PublicationRepository import java.time.LocalDateTime @@ -39,9 +38,9 @@ class PublicationService( fun delete(projectRef: String, publicationRef: String): Publication { val foundProject = projectRepository.findByRef(projectRef) val publication = publicationRepository.findByRef(foundProject.id, publicationRef) - val deleted = publicationRepository.deletePublication(publication.id) - if (deleted) return publication - throw BadRequestException("Bad request! Did not delete publication") + return publicationRepository.deletePublication(publication) + + // throw BadRequestException("Bad request! Did not delete publication") TODO: Put somewhere else further up in chain } @Throws(BackendException::class) From fc1f684ca435068870bcf80d6873d1800169e582 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20V=C3=A5rdal=20Itland?= Date: Mon, 12 Dec 2022 17:17:14 +0100 Subject: [PATCH 2/4] =?UTF-8?q?Pr=C3=B8v=20=C3=A5=20bygge=20med=20forel?= =?UTF-8?q?=C3=B8pig=20versjon?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index 0e3b2219..401ccc92 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,5 @@ # Kravbank backend README -TODO: Remove this, it is only to trigger a new build in GitHub - ## Prerequisites * In order to run the application locally, you need a .env file From 4bae4777a71e4eb95790175befff1dcdf928335d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20V=C3=A5rdal=20Itland?= Date: Wed, 14 Dec 2022 15:30:20 +0100 Subject: [PATCH 3/4] =?UTF-8?q?F=C3=A5r=20alt=20sammen=20ca=20riktig?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kotlin/org/kravbank/domain/Publication.kt | 3 +- .../org/kravbank/domain/SoftDeletable.kt | 5 +- .../kravbank/repository/BackendRepository.kt | 21 ++++---- .../kravbank/repository/CodelistRepository.kt | 11 ++--- .../org/kravbank/resource/CodelistResource.kt | 6 +-- .../org/kravbank/service/CodelistService.kt | 2 +- .../kravbank/service/PublicationService.kt | 4 +- .../resource/mock/CodelistResourceMockTest.kt | 48 +++++++++++++------ .../kravbank/service/CodelistServiceTest.kt | 10 ++-- 9 files changed, 59 insertions(+), 51 deletions(-) diff --git a/src/main/kotlin/org/kravbank/domain/Publication.kt b/src/main/kotlin/org/kravbank/domain/Publication.kt index 43c4c858..889dd011 100644 --- a/src/main/kotlin/org/kravbank/domain/Publication.kt +++ b/src/main/kotlin/org/kravbank/domain/Publication.kt @@ -2,13 +2,12 @@ package org.kravbank.domain import com.fasterxml.jackson.annotation.JsonIgnore import com.fasterxml.jackson.annotation.JsonManagedReference -import io.quarkus.hibernate.orm.panache.PanacheEntity import java.time.LocalDateTime import java.util.* import javax.persistence.* @Entity -class Publication : PanacheEntity(), SoftDeletable { +class Publication : SoftDeletable() { var comment: String = "" diff --git a/src/main/kotlin/org/kravbank/domain/SoftDeletable.kt b/src/main/kotlin/org/kravbank/domain/SoftDeletable.kt index a2483d68..a15b957e 100644 --- a/src/main/kotlin/org/kravbank/domain/SoftDeletable.kt +++ b/src/main/kotlin/org/kravbank/domain/SoftDeletable.kt @@ -1,7 +1,8 @@ package org.kravbank.domain +import io.quarkus.hibernate.orm.panache.PanacheEntity import java.time.LocalDateTime -interface SoftDeletable { - var deletedDate: LocalDateTime? +sealed class SoftDeletable: PanacheEntity() { + abstract var deletedDate: LocalDateTime? } \ No newline at end of file diff --git a/src/main/kotlin/org/kravbank/repository/BackendRepository.kt b/src/main/kotlin/org/kravbank/repository/BackendRepository.kt index 2e99fc65..6b6e4fa9 100644 --- a/src/main/kotlin/org/kravbank/repository/BackendRepository.kt +++ b/src/main/kotlin/org/kravbank/repository/BackendRepository.kt @@ -1,19 +1,18 @@ package org.kravbank.repository +import io.quarkus.hibernate.orm.panache.PanacheEntity import io.quarkus.hibernate.orm.panache.PanacheRepository import org.kravbank.domain.SoftDeletable import java.time.LocalDateTime -//private var T.deletedDate: LocalDateTime? -// get() {} -// set() {} - -open class BackendRepository : PanacheRepository { - fun deletePublication(publication: T): T { - val deletedDate = LocalDateTime.now() - //val updates = update("deleteddate = ?1 where id = ?2", deletedDate, publication) - publication.deletedDate = deletedDate - persistAndFlush(publication) - return publication +open class BackendRepository : PanacheRepository { + override fun delete(entity: T) = when (entity) { + is SoftDeletable -> { + val deletedDate = LocalDateTime.now() + entity.deletedDate = deletedDate + persistAndFlush(entity) + } else -> { + super.delete(entity) + } } } \ No newline at end of file diff --git a/src/main/kotlin/org/kravbank/repository/CodelistRepository.kt b/src/main/kotlin/org/kravbank/repository/CodelistRepository.kt index 3d801d41..0869c446 100644 --- a/src/main/kotlin/org/kravbank/repository/CodelistRepository.kt +++ b/src/main/kotlin/org/kravbank/repository/CodelistRepository.kt @@ -1,19 +1,17 @@ package org.kravbank.repository -import io.quarkus.hibernate.orm.panache.PanacheRepository import org.kravbank.domain.Codelist import org.kravbank.lang.BackendException import org.kravbank.lang.BadRequestException import org.kravbank.lang.NotFoundException import org.kravbank.utils.Messages.RepoErrorMsg.CODELIST_BADREQUEST_CREATE -import org.kravbank.utils.Messages.RepoErrorMsg.CODELIST_BADREQUEST_DELETE import org.kravbank.utils.Messages.RepoErrorMsg.CODELIST_BADREQUEST_UPDATE import org.kravbank.utils.Messages.RepoErrorMsg.CODELIST_NOTFOUND import java.util.* import javax.enterprise.context.ApplicationScoped @ApplicationScoped -class CodelistRepository : PanacheRepository { +class CodelistRepository : BackendRepository() { @Throws(BackendException::class) fun findByRef(projectId: Long, ref: String): Codelist { @@ -43,12 +41,9 @@ class CodelistRepository : PanacheRepository { } @Throws(BackendException::class) - fun deleteCodelist(projectId: Long, codelistRef: String): Codelist { - val deleted: Boolean + fun deleteCodelist(projectId: Long, codelistRef: String): Boolean { val found = findByRef(projectId, codelistRef) - deleted = deleteById(found.id) - if (!deleted) throw BadRequestException(CODELIST_BADREQUEST_DELETE) - return found + return deleteById(found.id) } @Throws(BackendException::class) diff --git a/src/main/kotlin/org/kravbank/resource/CodelistResource.kt b/src/main/kotlin/org/kravbank/resource/CodelistResource.kt index c45ccd74..645c8672 100644 --- a/src/main/kotlin/org/kravbank/resource/CodelistResource.kt +++ b/src/main/kotlin/org/kravbank/resource/CodelistResource.kt @@ -8,7 +8,6 @@ import javax.transaction.Transactional import javax.ws.rs.* import javax.ws.rs.core.MediaType.APPLICATION_JSON import javax.ws.rs.core.Response -import kotlin.streams.toList @Path("/api/v1/projects/{projectRef}/codelists") @Produces(APPLICATION_JSON) @@ -56,9 +55,8 @@ class CodelistResource(val codelistService: CodelistService) { @PathParam("projectRef") projectRef: String, @PathParam("codelistRef") codelistRef: String ): Response { - val codelist = codelistService.delete(projectRef, codelistRef) - val form = CodelistForm().fromEntity(codelist) - return Response.ok(form.ref).build() + codelistService.delete(projectRef, codelistRef) + return Response.ok(codelistRef).build() } @PUT diff --git a/src/main/kotlin/org/kravbank/service/CodelistService.kt b/src/main/kotlin/org/kravbank/service/CodelistService.kt index 1dc46eaa..e7d9fbbd 100644 --- a/src/main/kotlin/org/kravbank/service/CodelistService.kt +++ b/src/main/kotlin/org/kravbank/service/CodelistService.kt @@ -34,7 +34,7 @@ class CodelistService( } @Throws(BackendException::class) - fun delete(projectRef: String, codelistRef: String): Codelist { + fun delete(projectRef: String, codelistRef: String): Boolean { val foundProject = projectRepository.findByRef(projectRef) return codelistRepository.deleteCodelist(foundProject.id, codelistRef) } diff --git a/src/main/kotlin/org/kravbank/service/PublicationService.kt b/src/main/kotlin/org/kravbank/service/PublicationService.kt index 12f0094a..b92850f3 100644 --- a/src/main/kotlin/org/kravbank/service/PublicationService.kt +++ b/src/main/kotlin/org/kravbank/service/PublicationService.kt @@ -38,8 +38,8 @@ class PublicationService( fun delete(projectRef: String, publicationRef: String): Publication { val foundProject = projectRepository.findByRef(projectRef) val publication = publicationRepository.findByRef(foundProject.id, publicationRef) - return publicationRepository.deletePublication(publication) - + publicationRepository.delete(publication) + return publication // throw BadRequestException("Bad request! Did not delete publication") TODO: Put somewhere else further up in chain } diff --git a/src/test/kotlin/org/kravbank/resource/mock/CodelistResourceMockTest.kt b/src/test/kotlin/org/kravbank/resource/mock/CodelistResourceMockTest.kt index b166c1e9..e4fad7de 100644 --- a/src/test/kotlin/org/kravbank/resource/mock/CodelistResourceMockTest.kt +++ b/src/test/kotlin/org/kravbank/resource/mock/CodelistResourceMockTest.kt @@ -6,6 +6,7 @@ import io.quarkus.test.security.TestSecurity import org.junit.jupiter.api.Assertions.* import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test +import org.junit.jupiter.api.fail import org.kravbank.dao.CodelistForm import org.kravbank.domain.Codelist import org.kravbank.lang.BadRequestException @@ -17,7 +18,6 @@ import org.kravbank.utils.Messages.RepoErrorMsg.CODELIST_NOTFOUND import org.kravbank.utils.TestSetup import org.kravbank.utils.TestSetup.Arrange.codelist import org.kravbank.utils.TestSetup.Arrange.codelists -import org.kravbank.utils.TestSetup.Arrange.newCodelist_2 import org.kravbank.utils.TestSetup.Arrange.updatedCodelistForm import org.mockito.ArgumentMatchers import org.mockito.Mockito @@ -90,14 +90,31 @@ internal class CodelistResourceMockTest { val response: Response = codelistResource.listCodelists(projectRef) - val entity: List = response.entity as List + val entity = response.entity + + // Litt over-the-top her kanskje, men det viser "type narrowing", kalt "smart casts" i Kotlin + // + if (entity is List<*>) { + + assertNotNull(response) + assertEquals(Response.Status.OK.statusCode, response.status) + assertNotNull(response.entity) + assertFalse(entity.isEmpty()) + val firstObjectInList = entity[0] + if (firstObjectInList is CodelistForm) { + assertEquals(codelists[0].title, firstObjectInList.title) + assertEquals(codelists[0].description, firstObjectInList.description) + } else { + if (firstObjectInList !== null) { + fail("""Expected a list of CodelistForm, but the list contained: ${firstObjectInList::class.java.typeName}""") + } else { + fail("""Expected a list of CodelistForm, but there was no object in the list.""") + } + } + } else { + fail("""Expected a list of CodelistForm, got: ${entity::class.java.typeName}""") + } - assertNotNull(response) - assertEquals(Response.Status.OK.statusCode, response.status) - assertNotNull(response.entity) - assertFalse(entity.isEmpty()) - assertEquals(codelists[0].title, entity[0].title) - assertEquals(codelists[0].description, entity[0].description) } @Test @@ -127,13 +144,13 @@ internal class CodelistResourceMockTest { codelistRef ) ) - .thenReturn(newCodelist_2) + .thenReturn(true) val response: Response = codelistResource.deleteCodelist(projectRef, codelistRef) assertNotNull(response) - assertEquals(newCodelist_2.ref, response.entity) + assertEquals(codelistRef, response.entity) } @Test @@ -146,16 +163,17 @@ internal class CodelistResourceMockTest { ) ) .thenThrow(BadRequestException(CODELIST_BADREQUEST_DELETE)) - try { + val exception = assertThrows( + BadRequestException::class.java + ) { codelistResource.deleteCodelist( projectRef, codelistRef - ).entity as BadRequestException - - } catch (e: Exception) { - assertEquals(CODELIST_BADREQUEST_DELETE, e.message) + ) } + + assertEquals(CODELIST_BADREQUEST_DELETE, exception.message) } @Test diff --git a/src/test/kotlin/org/kravbank/service/CodelistServiceTest.kt b/src/test/kotlin/org/kravbank/service/CodelistServiceTest.kt index c140c129..b0c6af6d 100644 --- a/src/test/kotlin/org/kravbank/service/CodelistServiceTest.kt +++ b/src/test/kotlin/org/kravbank/service/CodelistServiceTest.kt @@ -11,7 +11,6 @@ import org.kravbank.utils.TestSetup import org.kravbank.utils.TestSetup.Arrange.codelist import org.kravbank.utils.TestSetup.Arrange.codelistForm import org.kravbank.utils.TestSetup.Arrange.codelists -import org.kravbank.utils.TestSetup.Arrange.newCodelist_2 import org.kravbank.utils.TestSetup.Arrange.updatedCodelistForm import org.mockito.ArgumentMatchers import org.mockito.Mockito @@ -105,13 +104,12 @@ internal class CodelistServiceTest { codelistRef ) ) - .thenReturn(newCodelist_2) + .thenReturn(true) - val mockedCodelist: Codelist = - codelistService.delete(projectRef, codelistRef) + val result = codelistService.delete(projectRef, codelistRef) - Assertions.assertNotNull(mockedCodelist) - Assertions.assertEquals(newCodelist_2, mockedCodelist) + Assertions.assertNotNull(result) + Assertions.assertEquals(true, result) } @Test From b992a39091df3cbfd2f744b7af6513ef465aebfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20V=C3=A5rdal=20Itland?= Date: Wed, 14 Dec 2022 18:57:55 +0100 Subject: [PATCH 4/4] Oppdatere pom.xml --- pom.xml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 2713e81d..91c05f6e 100644 --- a/pom.xml +++ b/pom.xml @@ -11,7 +11,7 @@ 3.8.1 1.7.10 1.18.24 - 11 + 17 UTF-8 UTF-8 quarkus-bom @@ -177,6 +177,7 @@ + org.apache.maven.plugins maven-surefire-plugin ${surefire-plugin.version} @@ -208,6 +209,7 @@ + org.apache.maven.plugins maven-failsafe-plugin ${surefire-plugin.version}