From f83556bccb47266e19e5fcb1e2915daf8be08938 Mon Sep 17 00:00:00 2001 From: AWallsRR Date: Wed, 19 Jul 2023 16:34:05 +0200 Subject: [PATCH 1/7] Implementation of Mapping in Kotling with Tests and JavaDocs --- Backend/mapping-kotlin/build.gradle.kts | 8 ++ .../mapping/mappers/ArticleMapper.kt | 5 +- .../models/dto/blocks/ArticleBlockDto.kt | 5 +- .../models/dto/blocks/GalleryBlockDto.kt | 7 +- .../mapping/models/dto/blocks/ImageBlock.kt | 7 +- .../mapping/models/dto/blocks/TextBlock.kt | 7 +- .../mapping/models/dto/blocks/VideoBlock.kt | 7 +- .../mapping/repositories/ArticleRepository.kt | 2 +- .../mapping/services/ArticleService.kt | 16 ++- .../challenges/mapping/ApplicationTests.kt | 129 +++++++++++++++++- 10 files changed, 179 insertions(+), 14 deletions(-) diff --git a/Backend/mapping-kotlin/build.gradle.kts b/Backend/mapping-kotlin/build.gradle.kts index f81c811..be34670 100644 --- a/Backend/mapping-kotlin/build.gradle.kts +++ b/Backend/mapping-kotlin/build.gradle.kts @@ -13,11 +13,19 @@ version = "0.0.1-SNAPSHOT" repositories { mavenCentral() + maven { + url = uri("https://maven.pkg.github.com/liodali/KotlinMapster") + credentials { + username = "AWallsRR" + password = "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" + } + } } dependencies { implementation("org.springframework.boot:spring-boot-starter-web") testImplementation("org.springframework.boot:spring-boot-starter-test") + implementation ("com.hamza.dali:mapster-ktx:0.4.0") } tasks { diff --git a/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/mappers/ArticleMapper.kt b/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/mappers/ArticleMapper.kt index 3d0bcf2..60f3285 100644 --- a/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/mappers/ArticleMapper.kt +++ b/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/mappers/ArticleMapper.kt @@ -2,14 +2,15 @@ package com.staffinghub.coding.challenges.mapping.mappers import com.staffinghub.coding.challenges.mapping.models.db.Article import com.staffinghub.coding.challenges.mapping.models.dto.ArticleDto +import mapper.adaptTo import org.springframework.stereotype.Component import java.util.* @Component class ArticleMapper { fun map(article: Article?): ArticleDto { - //TODO - return ArticleDto(0, "", "", "", emptyList()) + val articleDto = article?.adaptTo(ArticleDto::class) + return articleDto!! } // Not part of the challenge / Nicht Teil dieser Challenge. diff --git a/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/models/dto/blocks/ArticleBlockDto.kt b/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/models/dto/blocks/ArticleBlockDto.kt index b643bc8..a9fff5c 100644 --- a/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/models/dto/blocks/ArticleBlockDto.kt +++ b/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/models/dto/blocks/ArticleBlockDto.kt @@ -1,5 +1,8 @@ package com.staffinghub.coding.challenges.mapping.models.dto.blocks -interface ArticleBlockDto { +interface ArticleBlockDto : Comparable { val sortIndex: Int + override fun compareTo(other: ArticleBlockDto): Int { + return compareValuesBy(this, other) { it.sortIndex } + } } diff --git a/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/models/dto/blocks/GalleryBlockDto.kt b/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/models/dto/blocks/GalleryBlockDto.kt index a940018..ecf1fc7 100644 --- a/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/models/dto/blocks/GalleryBlockDto.kt +++ b/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/models/dto/blocks/GalleryBlockDto.kt @@ -5,4 +5,9 @@ import com.staffinghub.coding.challenges.mapping.models.dto.ImageDto data class GalleryBlockDto( var images: List, override val sortIndex: Int, -) : ArticleBlockDto +) : ArticleBlockDto,Comparable +{ + override fun compareTo(other: ArticleBlockDto):Int{ + return compareValuesBy(this,other) { it.sortIndex } + } +} \ No newline at end of file diff --git a/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/models/dto/blocks/ImageBlock.kt b/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/models/dto/blocks/ImageBlock.kt index 1bd7075..049e436 100644 --- a/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/models/dto/blocks/ImageBlock.kt +++ b/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/models/dto/blocks/ImageBlock.kt @@ -5,4 +5,9 @@ import com.staffinghub.coding.challenges.mapping.models.dto.ImageDto data class ImageBlock( var image: ImageDto, override val sortIndex: Int, -) : ArticleBlockDto +) : ArticleBlockDto,Comparable +{ + override fun compareTo(other: ArticleBlockDto):Int{ + return compareValuesBy(this,other) { it.sortIndex } + } +} \ No newline at end of file diff --git a/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/models/dto/blocks/TextBlock.kt b/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/models/dto/blocks/TextBlock.kt index 29f40f8..efde88d 100644 --- a/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/models/dto/blocks/TextBlock.kt +++ b/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/models/dto/blocks/TextBlock.kt @@ -3,4 +3,9 @@ package com.staffinghub.coding.challenges.mapping.models.dto.blocks data class TextBlock( var text: String, override val sortIndex: Int, -) : ArticleBlockDto +) : ArticleBlockDto,Comparable +{ + override fun compareTo(other: ArticleBlockDto):Int{ + return compareValuesBy(this,other) { it.sortIndex } + } +} \ No newline at end of file diff --git a/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/models/dto/blocks/VideoBlock.kt b/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/models/dto/blocks/VideoBlock.kt index 16b056e..002d5fb 100644 --- a/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/models/dto/blocks/VideoBlock.kt +++ b/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/models/dto/blocks/VideoBlock.kt @@ -6,4 +6,9 @@ data class VideoBlock( var url: String, var type: VideoBlockType, override val sortIndex: Int, -) : ArticleBlockDto +) : ArticleBlockDto,Comparable +{ + override fun compareTo(other: ArticleBlockDto):Int{ + return compareValuesBy(this,other) { it.sortIndex } + } +} \ No newline at end of file diff --git a/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/repositories/ArticleRepository.kt b/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/repositories/ArticleRepository.kt index 2a927b4..91baae3 100644 --- a/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/repositories/ArticleRepository.kt +++ b/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/repositories/ArticleRepository.kt @@ -23,7 +23,7 @@ object ArticleRepository { title = "Article Nr.: $this", description = "Article Description $this", author = "Max Mustermann", - blocks = dummyArticleBlocks, + blocks = dummyArticleBlocks.sortedWith(compareBy { it.sortIndex }).toSet(), ) private val Long.dummyArticleBlocks: Set by lazy { diff --git a/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/services/ArticleService.kt b/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/services/ArticleService.kt index 0f02d7c..15cb17b 100644 --- a/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/services/ArticleService.kt +++ b/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/services/ArticleService.kt @@ -3,22 +3,28 @@ package com.staffinghub.coding.challenges.mapping.services import com.staffinghub.coding.challenges.mapping.repositories.ArticleRepository import com.staffinghub.coding.challenges.mapping.mappers.ArticleMapper import com.staffinghub.coding.challenges.mapping.models.dto.ArticleDto +import mapper.adaptListTo import org.springframework.stereotype.Service @Service class ArticleService( private val mapper: ArticleMapper, ) { + /** + *@return List of AriticleDto that have been mapped to the data opject with internal Blocks sorted by sortIndex + */ fun list(): List { + val articles = ArticleRepository.all() - //TODO - return emptyList() + val articleDtoList = articles.adaptListTo(ArticleDto::class) + return articleDtoList.toList() } - + /** + *@return Single Instance of AriticleDto that have been mapped to the data opject with internal Blocks sorted by sortIndex + */ fun articleForId(id: Long): ArticleDto { val article = ArticleRepository.findBy(id) - //TODO - return ArticleDto(0, "", "", "", emptyList()) + return mapper.map(article) } fun create(articleDto: ArticleDto): ArticleDto { diff --git a/Backend/mapping-kotlin/src/test/kotlin/com/staffinghub/coding/challenges/mapping/ApplicationTests.kt b/Backend/mapping-kotlin/src/test/kotlin/com/staffinghub/coding/challenges/mapping/ApplicationTests.kt index 38a7add..92751a6 100644 --- a/Backend/mapping-kotlin/src/test/kotlin/com/staffinghub/coding/challenges/mapping/ApplicationTests.kt +++ b/Backend/mapping-kotlin/src/test/kotlin/com/staffinghub/coding/challenges/mapping/ApplicationTests.kt @@ -1,9 +1,24 @@ package com.staffinghub.coding.challenges.mapping + +import com.staffinghub.coding.challenges.mapping.models.db.Image +import com.staffinghub.coding.challenges.mapping.models.db.ImageSize +import com.staffinghub.coding.challenges.mapping.models.db.blocks.VideoBlockType +import com.staffinghub.coding.challenges.mapping.models.dto.ImageDto +import mapper.adaptTo import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith import org.springframework.boot.test.context.SpringBootTest import org.springframework.test.context.junit.jupiter.SpringExtension +import java.util.* +import com.staffinghub.coding.challenges.mapping.models.db.blocks.GalleryBlock as GaleryBlockDb +import com.staffinghub.coding.challenges.mapping.models.db.blocks.ImageBlock as ImageBlockDB +import com.staffinghub.coding.challenges.mapping.models.db.blocks.TextBlock as TextBlockDB +import com.staffinghub.coding.challenges.mapping.models.db.blocks.VideoBlock as VideoBlockDB +import com.staffinghub.coding.challenges.mapping.models.dto.blocks.GalleryBlockDto as GaleryBlockDTO +import com.staffinghub.coding.challenges.mapping.models.dto.blocks.ImageBlock as ImageBlockDTO +import com.staffinghub.coding.challenges.mapping.models.dto.blocks.TextBlock as TextBlockDTO +import com.staffinghub.coding.challenges.mapping.models.dto.blocks.VideoBlock as VideoBlockDTO @ExtendWith(SpringExtension::class) @SpringBootTest @@ -11,4 +26,116 @@ class ApplicationTests { @Test fun contextLoads() { } -} + + /** + * Creates instances of both the TextBlock Database and TextBlockDto Data classes with the same values + * To acertain that after the Database class has been mapped that the classes are equal + */ + @Test + fun CheckTextBlockMap() + { + val textBlockDb = TextBlockDB( + text = "Some Text for $this", + sortIndex = 0 + ) + val textBlockDto = TextBlockDTO( + text = "Some Text for $this", + sortIndex = 0 + ) + + assert(textBlockDto == textBlockDb.adaptTo(TextBlockDTO::class)) + } + /** + * Creates instances of both the VideoBlock Database and VideoBlockDto Data classes with the same values + * To acertain that after the VideoBlock Database class has been mapped that the classes are equal + */ + @Test + fun CheckVideoBlockMap() + { + val videoBlockDB = VideoBlockDB( + type = VideoBlockType.YOUTUBE, + url = "https://youtu.be/myvideo", + sortIndex = 4 + ) + val videoBlockDTO = VideoBlockDTO( + type = VideoBlockType.YOUTUBE, + url = "https://youtu.be/myvideo", + sortIndex = 4 + ) + + assert(videoBlockDTO == videoBlockDB.adaptTo(VideoBlockDTO::class)) + } + /** + * Creates instances of both the ImageBlock Database and ImageBlockDto Data classes with the same values + * To acertain that after the ImageBlock Database class has been mapped that the classes are equal + */ + @Test + fun CheckImageBlockMap() + { + val imageBlockDB = CreateImageBlockDB(1L) + val imageBlockDTO = CreateImageBlockDTO(1L) + + assert(imageBlockDTO == imageBlockDB.adaptTo(imageBlockDTO::class)) + } + /** + * Creates instances of both the GalleryBlock Database and GalleryBlockDto Data classes with the same values + * To acertain that after the GalleryBlock Database class has been mapped that the classes are equal + */ + @Test + fun CheckGalleryBlockMap() + { + val galleryBlockDB = GaleryBlockDb( + sortIndex = 3, + images = listOf( + CreateImageBlockDB(1L).image, + CreateImageBlockDB(2L).image + ) + ) + + val galleryBlockDTO = GaleryBlockDTO( + sortIndex = 3, + images = listOf( + CreateImageBlockDTO(1L).image, + CreateImageBlockDTO(2L).image + ) + ) + + assert(galleryBlockDTO == galleryBlockDB.adaptTo(GaleryBlockDTO::class)) + } + /** + * Creates an instance of the ImageBlock Database object + * + * @param imageId the Id of the image which is a long + * + * @return ImageBlock database object + */ + fun CreateImageBlockDB(imageId: Long) : ImageBlockDB + { + return ImageBlockDB( + image = Image( + url = "https://someurl.com/image/$imageId", + id = imageId, + imageSize = ImageSize.LARGE, + lastModified = Date(), + lastModifiedBy = "John Doe"), + sortIndex = 1 + ) + } + /** + * Creates an instance of the ImageBlock DTO object + * + * @param imageId the Id of the image which is a long + * + * @return ImageBlock DTO object + */ + fun CreateImageBlockDTO(imageId: Long) : ImageBlockDTO + { + return ImageBlockDTO( + image = ImageDto( + url = "https://someurl.com/image/$imageId", + id = imageId, + imageSize = ImageSize.LARGE), + sortIndex = 1 + ) + } +} \ No newline at end of file From fa34dd9e4663ccc2f88b08f07b0b25a056f1f12a Mon Sep 17 00:00:00 2001 From: AWallsRR Date: Wed, 19 Jul 2023 19:29:39 +0200 Subject: [PATCH 2/7] Implementation of Mapping in Kotling with Tests and JavaDocs --- Backend/mapping-kotlin/build.gradle.kts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Backend/mapping-kotlin/build.gradle.kts b/Backend/mapping-kotlin/build.gradle.kts index be34670..412fd85 100644 --- a/Backend/mapping-kotlin/build.gradle.kts +++ b/Backend/mapping-kotlin/build.gradle.kts @@ -16,8 +16,8 @@ repositories { maven { url = uri("https://maven.pkg.github.com/liodali/KotlinMapster") credentials { - username = "AWallsRR" - password = "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" + username = "{USER_NAME}" + password = "{TOKEN}" } } } From ebf0c9b082cc0540b4fd46e583965ff8d2a27f04 Mon Sep 17 00:00:00 2001 From: AWallsRR Date: Thu, 20 Jul 2023 11:18:58 +0200 Subject: [PATCH 3/7] Implementation of Mapping in Kotling with Tests and JavaDocs --- Backend/mapping-kotlin/build.gradle.kts | 3 + .../mapping/controllers/ArticleController.kt | 3 +- .../mapping/mappers/ArticleMapper.kt | 6 +- .../mapping/services/ArticleService.kt | 11 ++- .../challenges/mapping/ApplicationTests.kt | 71 ++++++++++++++++++- 5 files changed, 87 insertions(+), 7 deletions(-) diff --git a/Backend/mapping-kotlin/build.gradle.kts b/Backend/mapping-kotlin/build.gradle.kts index 412fd85..fe452a3 100644 --- a/Backend/mapping-kotlin/build.gradle.kts +++ b/Backend/mapping-kotlin/build.gradle.kts @@ -26,6 +26,9 @@ dependencies { implementation("org.springframework.boot:spring-boot-starter-web") testImplementation("org.springframework.boot:spring-boot-starter-test") implementation ("com.hamza.dali:mapster-ktx:0.4.0") + testImplementation ("io.kotest:kotest-property:4.0.3") + testImplementation ("org.mockito:mockito-core:3.+") + testImplementation ("org.mockito:mockito-inline:3.11.2") } tasks { diff --git a/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/controllers/ArticleController.kt b/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/controllers/ArticleController.kt index e110bb6..ea00109 100644 --- a/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/controllers/ArticleController.kt +++ b/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/controllers/ArticleController.kt @@ -2,6 +2,7 @@ package com.staffinghub.coding.challenges.mapping.controllers import com.staffinghub.coding.challenges.mapping.models.dto.ArticleDto import com.staffinghub.coding.challenges.mapping.services.ArticleService +import org.springframework.http.HttpStatus import org.springframework.web.bind.annotation.* @RestController @@ -11,7 +12,7 @@ class ArticleController( ) { @GetMapping fun list(): List = articleService.list() - + @ResponseStatus(HttpStatus.NOT_FOUND) @GetMapping("/{id}") fun details(@PathVariable id: Long): ArticleDto = articleService.articleForId(id) diff --git a/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/mappers/ArticleMapper.kt b/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/mappers/ArticleMapper.kt index 60f3285..f752ece 100644 --- a/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/mappers/ArticleMapper.kt +++ b/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/mappers/ArticleMapper.kt @@ -8,9 +8,9 @@ import java.util.* @Component class ArticleMapper { - fun map(article: Article?): ArticleDto { - val articleDto = article?.adaptTo(ArticleDto::class) - return articleDto!! + fun map(article: Article): ArticleDto { + val articleDto = article.adaptTo(ArticleDto::class) + return articleDto } // Not part of the challenge / Nicht Teil dieser Challenge. diff --git a/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/services/ArticleService.kt b/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/services/ArticleService.kt index 15cb17b..c04f10a 100644 --- a/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/services/ArticleService.kt +++ b/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/services/ArticleService.kt @@ -1,10 +1,12 @@ package com.staffinghub.coding.challenges.mapping.services -import com.staffinghub.coding.challenges.mapping.repositories.ArticleRepository import com.staffinghub.coding.challenges.mapping.mappers.ArticleMapper import com.staffinghub.coding.challenges.mapping.models.dto.ArticleDto +import com.staffinghub.coding.challenges.mapping.repositories.ArticleRepository import mapper.adaptListTo +import org.springframework.http.HttpStatus import org.springframework.stereotype.Service +import org.springframework.web.server.ResponseStatusException @Service class ArticleService( @@ -24,7 +26,12 @@ class ArticleService( */ fun articleForId(id: Long): ArticleDto { val article = ArticleRepository.findBy(id) - return mapper.map(article) + + if(article == null) + throw ResponseStatusException( HttpStatus.NOT_FOUND, "No Article with suplied ID found") + + val articleDto = mapper.map(article) + return articleDto } fun create(articleDto: ArticleDto): ArticleDto { diff --git a/Backend/mapping-kotlin/src/test/kotlin/com/staffinghub/coding/challenges/mapping/ApplicationTests.kt b/Backend/mapping-kotlin/src/test/kotlin/com/staffinghub/coding/challenges/mapping/ApplicationTests.kt index 92751a6..0832b29 100644 --- a/Backend/mapping-kotlin/src/test/kotlin/com/staffinghub/coding/challenges/mapping/ApplicationTests.kt +++ b/Backend/mapping-kotlin/src/test/kotlin/com/staffinghub/coding/challenges/mapping/ApplicationTests.kt @@ -1,14 +1,24 @@ package com.staffinghub.coding.challenges.mapping +import com.staffinghub.coding.challenges.mapping.controllers.ArticleController +import com.staffinghub.coding.challenges.mapping.mappers.ArticleMapper +import com.staffinghub.coding.challenges.mapping.models.db.Article import com.staffinghub.coding.challenges.mapping.models.db.Image import com.staffinghub.coding.challenges.mapping.models.db.ImageSize import com.staffinghub.coding.challenges.mapping.models.db.blocks.VideoBlockType +import com.staffinghub.coding.challenges.mapping.models.dto.ArticleDto import com.staffinghub.coding.challenges.mapping.models.dto.ImageDto +import com.staffinghub.coding.challenges.mapping.repositories.ArticleRepository +import com.staffinghub.coding.challenges.mapping.services.ArticleService +import io.kotest.matchers.shouldBe import mapper.adaptTo import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith +import org.mockito.Mockito.`when` +import org.mockito.junit.jupiter.MockitoExtension import org.springframework.boot.test.context.SpringBootTest +import org.springframework.boot.test.mock.mockito.MockBean import org.springframework.test.context.junit.jupiter.SpringExtension import java.util.* import com.staffinghub.coding.challenges.mapping.models.db.blocks.GalleryBlock as GaleryBlockDb @@ -20,11 +30,67 @@ import com.staffinghub.coding.challenges.mapping.models.dto.blocks.ImageBlock as import com.staffinghub.coding.challenges.mapping.models.dto.blocks.TextBlock as TextBlockDTO import com.staffinghub.coding.challenges.mapping.models.dto.blocks.VideoBlock as VideoBlockDTO -@ExtendWith(SpringExtension::class) +@ExtendWith(SpringExtension::class, MockitoExtension::class) @SpringBootTest class ApplicationTests { + + private lateinit var articleController: ArticleController + + private lateinit var articleService: ArticleService + + @MockBean + private lateinit var articleRepository: ArticleRepository + + @MockBean + private lateinit var mapper: ArticleMapper @Test fun contextLoads() { + + } + @Test + fun ArticleServiceTest(){ + + val articleId = 1001L + + val article = Article( + id = articleId, + title = "Test Article", + description = "This is a test article", + author = "Test Author", + lastModified = Date(), + blocks = listOf( + TextBlockDB("Test text 1", 1), + CreateImageBlockDB(articleId), + TextBlockDB("Test text 2", 3) + ).toSet() + ) + + val articleDto = ArticleDto( + id = articleId, + title = "Test Article", + description = "This is a test article", + author = "Test Author", + blocks = listOf( + TextBlockDTO("Test text 1", 1), + CreateImageBlockDTO(articleId), + TextBlockDTO("Test text 2", 3) + ) + ) + + articleService = ArticleService(mapper) + articleController = ArticleController(articleService) + + `when`(articleRepository.findBy(articleId)).thenReturn(article) + + `when`(mapper.map(article)).thenReturn(articleDto) + + val result = mapper.map(article) + result shouldBe articleDto + + val testArticle = mapper.map(articleRepository.findBy(articleId)) + testArticle shouldBe articleDto + + assert(testArticle.blocks.elementAt(0).sortIndex<=testArticle.blocks.elementAt(1).sortIndex) } /** @@ -38,6 +104,7 @@ class ApplicationTests { text = "Some Text for $this", sortIndex = 0 ) + val textBlockDto = TextBlockDTO( text = "Some Text for $this", sortIndex = 0 @@ -57,6 +124,7 @@ class ApplicationTests { url = "https://youtu.be/myvideo", sortIndex = 4 ) + val videoBlockDTO = VideoBlockDTO( type = VideoBlockType.YOUTUBE, url = "https://youtu.be/myvideo", @@ -73,6 +141,7 @@ class ApplicationTests { fun CheckImageBlockMap() { val imageBlockDB = CreateImageBlockDB(1L) + val imageBlockDTO = CreateImageBlockDTO(1L) assert(imageBlockDTO == imageBlockDB.adaptTo(imageBlockDTO::class)) From 1fd2362b44e060393c3715aa91583891e46c697a Mon Sep 17 00:00:00 2001 From: AWallsRR Date: Thu, 20 Jul 2023 20:35:04 +0200 Subject: [PATCH 4/7] Adding Implementation of Mapstruct and cleaning of code --- Backend/mapping-kotlin/build.gradle.kts | 3 + .../mapping/mappers/ArticleBlockDtoFactory.kt | 42 ++++++++++++++ .../mapping/mappers/ArticleMapper.kt | 12 +++- .../mapping/mappers/ArticleMapperMapstruct.kt | 57 +++++++++++++++++++ .../mapping/services/ArticleService.kt | 6 +- .../challenges/mapping/ApplicationTests.kt | 11 ++-- 6 files changed, 119 insertions(+), 12 deletions(-) create mode 100644 Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/mappers/ArticleBlockDtoFactory.kt create mode 100644 Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/mappers/ArticleMapperMapstruct.kt diff --git a/Backend/mapping-kotlin/build.gradle.kts b/Backend/mapping-kotlin/build.gradle.kts index fe452a3..942fca7 100644 --- a/Backend/mapping-kotlin/build.gradle.kts +++ b/Backend/mapping-kotlin/build.gradle.kts @@ -6,6 +6,7 @@ plugins { kotlin("plugin.spring") version kotlinVersion id("org.springframework.boot") version "2.4.0" id("io.spring.dependency-management") version "1.0.10.RELEASE" + kotlin("kapt") version kotlinVersion } group = "com.staffinghub.coding.challenges" @@ -26,9 +27,11 @@ dependencies { implementation("org.springframework.boot:spring-boot-starter-web") testImplementation("org.springframework.boot:spring-boot-starter-test") implementation ("com.hamza.dali:mapster-ktx:0.4.0") + implementation("org.mapstruct:mapstruct:1.5.3.Final") testImplementation ("io.kotest:kotest-property:4.0.3") testImplementation ("org.mockito:mockito-core:3.+") testImplementation ("org.mockito:mockito-inline:3.11.2") + kapt("org.mapstruct:mapstruct-processor:1.5.3.Final") } tasks { diff --git a/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/mappers/ArticleBlockDtoFactory.kt b/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/mappers/ArticleBlockDtoFactory.kt new file mode 100644 index 0000000..79352b9 --- /dev/null +++ b/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/mappers/ArticleBlockDtoFactory.kt @@ -0,0 +1,42 @@ +package com.staffinghub.coding.challenges.mapping.models.dto.blocks + +import com.staffinghub.coding.challenges.mapping.models.db.Image +import com.staffinghub.coding.challenges.mapping.models.db.blocks.ArticleBlock +import org.mapstruct.ObjectFactory +import org.springframework.stereotype.Component +import com.staffinghub.coding.challenges.mapping.models.dto.blocks.TextBlock as TextBlockDto +import com.staffinghub.coding.challenges.mapping.models.dto.blocks.VideoBlock as VideoBlockDto +import com.staffinghub.coding.challenges.mapping.models.dto.blocks.ImageBlock as ImageBlockDto +import com.staffinghub.coding.challenges.mapping.models.db.blocks.* +import com.staffinghub.coding.challenges.mapping.models.dto.ImageDto + +@Component +class ArticleBlockDtoFactory { + @ObjectFactory + fun createArticleBlockDto(articleBlock: ArticleBlock): ArticleBlockDto { + return when (articleBlock) { + is TextBlock -> TextBlockDto( + text = articleBlock.text, + sortIndex = articleBlock.sortIndex + ) + is ImageBlock -> ImageBlockDto( + image = mapToImageDto(articleBlock.image!!), + sortIndex = articleBlock.sortIndex + ) + is VideoBlock -> VideoBlockDto( + url = articleBlock.url, + type = articleBlock.type, + sortIndex = articleBlock.sortIndex + ) + else -> throw IllegalArgumentException("Unknown ArticleBlock type") + } + } + + private fun mapToImageDto(image: Image): ImageDto { + return ImageDto( + id = image.id, + url = image.url, + imageSize = image.imageSize + ) + } +} diff --git a/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/mappers/ArticleMapper.kt b/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/mappers/ArticleMapper.kt index f752ece..0a7f81e 100644 --- a/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/mappers/ArticleMapper.kt +++ b/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/mappers/ArticleMapper.kt @@ -3,14 +3,22 @@ package com.staffinghub.coding.challenges.mapping.mappers import com.staffinghub.coding.challenges.mapping.models.db.Article import com.staffinghub.coding.challenges.mapping.models.dto.ArticleDto import mapper.adaptTo +import org.mapstruct.factory.Mappers import org.springframework.stereotype.Component import java.util.* @Component class ArticleMapper { + var mapperStruct:ArticleMapperMapstruct = Mappers.getMapper(ArticleMapperMapstruct::class.java) fun map(article: Article): ArticleDto { - val articleDto = article.adaptTo(ArticleDto::class) - return articleDto + return article.adaptTo(ArticleDto::class) + } + + /** + * Object mapper using Mapstruct as alternative to Mapster Dependency + */ + fun mapStructMap(article: Article): ArticleDto { + return mapperStruct.mapToArticleDto(article) } // Not part of the challenge / Nicht Teil dieser Challenge. diff --git a/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/mappers/ArticleMapperMapstruct.kt b/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/mappers/ArticleMapperMapstruct.kt new file mode 100644 index 0000000..cc82667 --- /dev/null +++ b/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/mappers/ArticleMapperMapstruct.kt @@ -0,0 +1,57 @@ +package com.staffinghub.coding.challenges.mapping.mappers + +import com.staffinghub.coding.challenges.mapping.models.db.Article +import com.staffinghub.coding.challenges.mapping.models.db.blocks.* +import com.staffinghub.coding.challenges.mapping.models.dto.ArticleDto +import com.staffinghub.coding.challenges.mapping.models.dto.blocks.ArticleBlockDto +import com.staffinghub.coding.challenges.mapping.models.dto.blocks.ArticleBlockDtoFactory +import com.staffinghub.coding.challenges.mapping.models.dto.blocks.GalleryBlockDto +import org.mapstruct.* +import com.staffinghub.coding.challenges.mapping.models.dto.blocks.TextBlock as TextBlockDto +import com.staffinghub.coding.challenges.mapping.models.dto.blocks.VideoBlock as VideoBlockDto +import com.staffinghub.coding.challenges.mapping.models.dto.blocks.ImageBlock as ImageBlockDto +import org.springframework.stereotype.Component + +@Component +@Mapper(uses = [ArticleBlockDtoFactory::class]) +interface ArticleMapperMapstruct { + + fun mapToGalleryBlockDto(gallery: GalleryBlock): GalleryBlockDto + + fun mapToTextBlockDto(textBlock: TextBlock): TextBlockDto + + fun mapToImageBlockDto(imageBlock: ImageBlock): ImageBlockDto + + fun mapToVideoBlockDto(videoBlock: VideoBlock): VideoBlockDto + + fun mapToTextBlock(textBlock: TextBlock): ArticleBlock + + fun mapToImageBlock(imageBlock: ImageBlock): ArticleBlock + + fun mapToVideoBlock(videoBlock: VideoBlock): ArticleBlock + + + fun mapToArticleDto(article: Article): ArticleDto { + return ArticleDto( + id = article.id, + title = article.title, + description = article.description.toString(), + author = article.author.toString(), + blocks = mapBlocksToDto(article.blocks) + ) + } + + @IterableMapping(elementTargetType = ArticleBlockDto::class) + fun mapBlocksToDto(blocks: Collection): Collection + {return blocks.map { mapToArticleBlockDto(it) }} + + fun mapToArticleBlockDto(articleBlock: ArticleBlock): ArticleBlockDto { + return when (articleBlock) { + is TextBlock -> mapToTextBlockDto(articleBlock) + is ImageBlock -> mapToImageBlockDto(articleBlock) + is VideoBlock -> mapToVideoBlockDto(articleBlock) + is GalleryBlock -> mapToGalleryBlockDto(articleBlock) + else -> throw IllegalArgumentException("Unknown ArticleBlock type") + } + } +} \ No newline at end of file diff --git a/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/services/ArticleService.kt b/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/services/ArticleService.kt index c04f10a..b47c944 100644 --- a/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/services/ArticleService.kt +++ b/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/services/ArticleService.kt @@ -16,10 +16,8 @@ class ArticleService( *@return List of AriticleDto that have been mapped to the data opject with internal Blocks sorted by sortIndex */ fun list(): List { - val articles = ArticleRepository.all() - val articleDtoList = articles.adaptListTo(ArticleDto::class) - return articleDtoList.toList() + return articles.adaptListTo(ArticleDto::class).toList() } /** *@return Single Instance of AriticleDto that have been mapped to the data opject with internal Blocks sorted by sortIndex @@ -30,7 +28,7 @@ class ArticleService( if(article == null) throw ResponseStatusException( HttpStatus.NOT_FOUND, "No Article with suplied ID found") - val articleDto = mapper.map(article) + val articleDto = mapper.mapStructMap(article) return articleDto } diff --git a/Backend/mapping-kotlin/src/test/kotlin/com/staffinghub/coding/challenges/mapping/ApplicationTests.kt b/Backend/mapping-kotlin/src/test/kotlin/com/staffinghub/coding/challenges/mapping/ApplicationTests.kt index 0832b29..7c5d9dd 100644 --- a/Backend/mapping-kotlin/src/test/kotlin/com/staffinghub/coding/challenges/mapping/ApplicationTests.kt +++ b/Backend/mapping-kotlin/src/test/kotlin/com/staffinghub/coding/challenges/mapping/ApplicationTests.kt @@ -17,6 +17,7 @@ import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith import org.mockito.Mockito.`when` import org.mockito.junit.jupiter.MockitoExtension +import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.context.SpringBootTest import org.springframework.boot.test.mock.mockito.MockBean import org.springframework.test.context.junit.jupiter.SpringExtension @@ -41,7 +42,7 @@ class ApplicationTests { @MockBean private lateinit var articleRepository: ArticleRepository - @MockBean + @Autowired private lateinit var mapper: ArticleMapper @Test fun contextLoads() { @@ -82,15 +83,13 @@ class ApplicationTests { `when`(articleRepository.findBy(articleId)).thenReturn(article) - `when`(mapper.map(article)).thenReturn(articleDto) + val result = mapper.mapStructMap(article) - val result = mapper.map(article) result shouldBe articleDto - val testArticle = mapper.map(articleRepository.findBy(articleId)) - testArticle shouldBe articleDto + val testArticleSort = articleRepository.findBy(articleId) - assert(testArticle.blocks.elementAt(0).sortIndex<=testArticle.blocks.elementAt(1).sortIndex) + assert(testArticleSort.blocks.elementAt(0).sortIndex<=testArticleSort.blocks.elementAt(1).sortIndex) } /** From 940761f51d471785022adacb69bf21359afaa1d6 Mon Sep 17 00:00:00 2001 From: AWallsRR Date: Fri, 21 Jul 2023 09:21:37 +0200 Subject: [PATCH 5/7] Altering Object factory for missing galerycreation and acount for nullables in images. Removing uneeded mapping from mapper --- .../mapping/mappers/ArticleBlockDtoFactory.kt | 16 ++++++++++++---- .../mapping/mappers/ArticleMapperMapstruct.kt | 7 ------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/mappers/ArticleBlockDtoFactory.kt b/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/mappers/ArticleBlockDtoFactory.kt index 79352b9..40589cf 100644 --- a/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/mappers/ArticleBlockDtoFactory.kt +++ b/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/mappers/ArticleBlockDtoFactory.kt @@ -1,6 +1,7 @@ package com.staffinghub.coding.challenges.mapping.models.dto.blocks import com.staffinghub.coding.challenges.mapping.models.db.Image +import com.staffinghub.coding.challenges.mapping.models.db.ImageSize import com.staffinghub.coding.challenges.mapping.models.db.blocks.ArticleBlock import org.mapstruct.ObjectFactory import org.springframework.stereotype.Component @@ -19,15 +20,22 @@ class ArticleBlockDtoFactory { text = articleBlock.text, sortIndex = articleBlock.sortIndex ) - is ImageBlock -> ImageBlockDto( - image = mapToImageDto(articleBlock.image!!), - sortIndex = articleBlock.sortIndex - ) + is ImageBlock -> { + val imageDto = articleBlock.image?.let { mapToImageDto(it) }?: ImageDto(-1, "", ImageSize.SMALL) + ImageBlockDto( + image = imageDto, + sortIndex = articleBlock.sortIndex + ) + } is VideoBlock -> VideoBlockDto( url = articleBlock.url, type = articleBlock.type, sortIndex = articleBlock.sortIndex ) + is GalleryBlock -> GalleryBlockDto( + images = articleBlock.images?.mapNotNull { it?.let { image -> mapToImageDto(image) } } ?: emptyList(), + sortIndex = articleBlock.sortIndex + ) else -> throw IllegalArgumentException("Unknown ArticleBlock type") } } diff --git a/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/mappers/ArticleMapperMapstruct.kt b/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/mappers/ArticleMapperMapstruct.kt index cc82667..5abc4e6 100644 --- a/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/mappers/ArticleMapperMapstruct.kt +++ b/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/mappers/ArticleMapperMapstruct.kt @@ -24,13 +24,6 @@ interface ArticleMapperMapstruct { fun mapToVideoBlockDto(videoBlock: VideoBlock): VideoBlockDto - fun mapToTextBlock(textBlock: TextBlock): ArticleBlock - - fun mapToImageBlock(imageBlock: ImageBlock): ArticleBlock - - fun mapToVideoBlock(videoBlock: VideoBlock): ArticleBlock - - fun mapToArticleDto(article: Article): ArticleDto { return ArticleDto( id = article.id, From c28dcdbcc3ba609667fdd3acb947e7e2a0844451 Mon Sep 17 00:00:00 2001 From: AWallsRR Date: Fri, 21 Jul 2023 13:47:08 +0200 Subject: [PATCH 6/7] formatting of code and removing uneeded declarations --- .../mapping/controllers/ArticleController.kt | 1 + .../mapping/mappers/ArticleBlockDtoFactory.kt | 9 +- .../mapping/mappers/ArticleMapper.kt | 2 +- .../mapping/mappers/ArticleMapperMapstruct.kt | 5 +- .../models/dto/blocks/GalleryBlockDto.kt | 7 +- .../mapping/models/dto/blocks/ImageBlock.kt | 7 +- .../mapping/models/dto/blocks/TextBlock.kt | 7 +- .../mapping/models/dto/blocks/VideoBlock.kt | 7 +- .../mapping/services/ArticleService.kt | 8 +- .../challenges/mapping/ApplicationTests.kt | 111 +++++++++--------- 10 files changed, 84 insertions(+), 80 deletions(-) diff --git a/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/controllers/ArticleController.kt b/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/controllers/ArticleController.kt index ea00109..1ac9de6 100644 --- a/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/controllers/ArticleController.kt +++ b/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/controllers/ArticleController.kt @@ -12,6 +12,7 @@ class ArticleController( ) { @GetMapping fun list(): List = articleService.list() + @ResponseStatus(HttpStatus.NOT_FOUND) @GetMapping("/{id}") fun details(@PathVariable id: Long): ArticleDto = articleService.articleForId(id) diff --git a/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/mappers/ArticleBlockDtoFactory.kt b/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/mappers/ArticleBlockDtoFactory.kt index 40589cf..3091caf 100644 --- a/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/mappers/ArticleBlockDtoFactory.kt +++ b/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/mappers/ArticleBlockDtoFactory.kt @@ -20,22 +20,25 @@ class ArticleBlockDtoFactory { text = articleBlock.text, sortIndex = articleBlock.sortIndex ) + is ImageBlock -> { - val imageDto = articleBlock.image?.let { mapToImageDto(it) }?: ImageDto(-1, "", ImageSize.SMALL) ImageBlockDto( - image = imageDto, + image = articleBlock.image?.let { mapToImageDto(it) } ?: ImageDto(-1, "", ImageSize.SMALL), sortIndex = articleBlock.sortIndex ) } + is VideoBlock -> VideoBlockDto( url = articleBlock.url, type = articleBlock.type, sortIndex = articleBlock.sortIndex ) + is GalleryBlock -> GalleryBlockDto( - images = articleBlock.images?.mapNotNull { it?.let { image -> mapToImageDto(image) } } ?: emptyList(), + images = articleBlock.images.mapNotNull { it?.let { image -> mapToImageDto(image) } }, sortIndex = articleBlock.sortIndex ) + else -> throw IllegalArgumentException("Unknown ArticleBlock type") } } diff --git a/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/mappers/ArticleMapper.kt b/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/mappers/ArticleMapper.kt index 0a7f81e..4cd0cba 100644 --- a/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/mappers/ArticleMapper.kt +++ b/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/mappers/ArticleMapper.kt @@ -9,7 +9,7 @@ import java.util.* @Component class ArticleMapper { - var mapperStruct:ArticleMapperMapstruct = Mappers.getMapper(ArticleMapperMapstruct::class.java) + var mapperStruct: ArticleMapperMapstruct = Mappers.getMapper(ArticleMapperMapstruct::class.java) fun map(article: Article): ArticleDto { return article.adaptTo(ArticleDto::class) } diff --git a/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/mappers/ArticleMapperMapstruct.kt b/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/mappers/ArticleMapperMapstruct.kt index 5abc4e6..bd8278a 100644 --- a/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/mappers/ArticleMapperMapstruct.kt +++ b/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/mappers/ArticleMapperMapstruct.kt @@ -35,8 +35,9 @@ interface ArticleMapperMapstruct { } @IterableMapping(elementTargetType = ArticleBlockDto::class) - fun mapBlocksToDto(blocks: Collection): Collection - {return blocks.map { mapToArticleBlockDto(it) }} + fun mapBlocksToDto(blocks: Collection): Collection { + return blocks.map { mapToArticleBlockDto(it) } + } fun mapToArticleBlockDto(articleBlock: ArticleBlock): ArticleBlockDto { return when (articleBlock) { diff --git a/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/models/dto/blocks/GalleryBlockDto.kt b/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/models/dto/blocks/GalleryBlockDto.kt index ecf1fc7..d134918 100644 --- a/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/models/dto/blocks/GalleryBlockDto.kt +++ b/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/models/dto/blocks/GalleryBlockDto.kt @@ -5,9 +5,8 @@ import com.staffinghub.coding.challenges.mapping.models.dto.ImageDto data class GalleryBlockDto( var images: List, override val sortIndex: Int, -) : ArticleBlockDto,Comparable -{ - override fun compareTo(other: ArticleBlockDto):Int{ - return compareValuesBy(this,other) { it.sortIndex } +) : ArticleBlockDto, Comparable { + override fun compareTo(other: ArticleBlockDto): Int { + return compareValuesBy(this, other) { it.sortIndex } } } \ No newline at end of file diff --git a/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/models/dto/blocks/ImageBlock.kt b/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/models/dto/blocks/ImageBlock.kt index 049e436..76ac998 100644 --- a/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/models/dto/blocks/ImageBlock.kt +++ b/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/models/dto/blocks/ImageBlock.kt @@ -5,9 +5,8 @@ import com.staffinghub.coding.challenges.mapping.models.dto.ImageDto data class ImageBlock( var image: ImageDto, override val sortIndex: Int, -) : ArticleBlockDto,Comparable -{ - override fun compareTo(other: ArticleBlockDto):Int{ - return compareValuesBy(this,other) { it.sortIndex } +) : ArticleBlockDto, Comparable { + override fun compareTo(other: ArticleBlockDto): Int { + return compareValuesBy(this, other) { it.sortIndex } } } \ No newline at end of file diff --git a/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/models/dto/blocks/TextBlock.kt b/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/models/dto/blocks/TextBlock.kt index efde88d..7136292 100644 --- a/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/models/dto/blocks/TextBlock.kt +++ b/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/models/dto/blocks/TextBlock.kt @@ -3,9 +3,8 @@ package com.staffinghub.coding.challenges.mapping.models.dto.blocks data class TextBlock( var text: String, override val sortIndex: Int, -) : ArticleBlockDto,Comparable -{ - override fun compareTo(other: ArticleBlockDto):Int{ - return compareValuesBy(this,other) { it.sortIndex } +) : ArticleBlockDto, Comparable { + override fun compareTo(other: ArticleBlockDto): Int { + return compareValuesBy(this, other) { it.sortIndex } } } \ No newline at end of file diff --git a/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/models/dto/blocks/VideoBlock.kt b/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/models/dto/blocks/VideoBlock.kt index 002d5fb..829c110 100644 --- a/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/models/dto/blocks/VideoBlock.kt +++ b/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/models/dto/blocks/VideoBlock.kt @@ -6,9 +6,8 @@ data class VideoBlock( var url: String, var type: VideoBlockType, override val sortIndex: Int, -) : ArticleBlockDto,Comparable -{ - override fun compareTo(other: ArticleBlockDto):Int{ - return compareValuesBy(this,other) { it.sortIndex } +) : ArticleBlockDto, Comparable { + override fun compareTo(other: ArticleBlockDto): Int { + return compareValuesBy(this, other) { it.sortIndex } } } \ No newline at end of file diff --git a/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/services/ArticleService.kt b/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/services/ArticleService.kt index b47c944..c26e731 100644 --- a/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/services/ArticleService.kt +++ b/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/services/ArticleService.kt @@ -19,17 +19,17 @@ class ArticleService( val articles = ArticleRepository.all() return articles.adaptListTo(ArticleDto::class).toList() } + /** *@return Single Instance of AriticleDto that have been mapped to the data opject with internal Blocks sorted by sortIndex */ fun articleForId(id: Long): ArticleDto { val article = ArticleRepository.findBy(id) - if(article == null) - throw ResponseStatusException( HttpStatus.NOT_FOUND, "No Article with suplied ID found") + if (article == null) + throw ResponseStatusException(HttpStatus.NOT_FOUND, "No Article with suplied ID found") - val articleDto = mapper.mapStructMap(article) - return articleDto + return mapper.mapStructMap(article) } fun create(articleDto: ArticleDto): ArticleDto { diff --git a/Backend/mapping-kotlin/src/test/kotlin/com/staffinghub/coding/challenges/mapping/ApplicationTests.kt b/Backend/mapping-kotlin/src/test/kotlin/com/staffinghub/coding/challenges/mapping/ApplicationTests.kt index 7c5d9dd..4546929 100644 --- a/Backend/mapping-kotlin/src/test/kotlin/com/staffinghub/coding/challenges/mapping/ApplicationTests.kt +++ b/Backend/mapping-kotlin/src/test/kotlin/com/staffinghub/coding/challenges/mapping/ApplicationTests.kt @@ -44,12 +44,14 @@ class ApplicationTests { @Autowired private lateinit var mapper: ArticleMapper + @Test fun contextLoads() { } + @Test - fun ArticleServiceTest(){ + fun ArticleServiceTest() { val articleId = 1001L @@ -60,9 +62,9 @@ class ApplicationTests { author = "Test Author", lastModified = Date(), blocks = listOf( - TextBlockDB("Test text 1", 1), - CreateImageBlockDB(articleId), - TextBlockDB("Test text 2", 3) + TextBlockDB("Test text 1", 1), + CreateImageBlockDB(articleId), + TextBlockDB("Test text 2", 3) ).toSet() ) @@ -72,9 +74,9 @@ class ApplicationTests { description = "This is a test article", author = "Test Author", blocks = listOf( - TextBlockDTO("Test text 1", 1), - CreateImageBlockDTO(articleId), - TextBlockDTO("Test text 2", 3) + TextBlockDTO("Test text 1", 1), + CreateImageBlockDTO(articleId), + TextBlockDTO("Test text 2", 3) ) ) @@ -89,7 +91,7 @@ class ApplicationTests { val testArticleSort = articleRepository.findBy(articleId) - assert(testArticleSort.blocks.elementAt(0).sortIndex<=testArticleSort.blocks.elementAt(1).sortIndex) + assert(testArticleSort.blocks.elementAt(0).sortIndex <= testArticleSort.blocks.elementAt(1).sortIndex) } /** @@ -97,79 +99,79 @@ class ApplicationTests { * To acertain that after the Database class has been mapped that the classes are equal */ @Test - fun CheckTextBlockMap() - { + fun CheckTextBlockMap() { val textBlockDb = TextBlockDB( - text = "Some Text for $this", - sortIndex = 0 + text = "Some Text for $this", + sortIndex = 0 ) val textBlockDto = TextBlockDTO( - text = "Some Text for $this", - sortIndex = 0 + text = "Some Text for $this", + sortIndex = 0 ) assert(textBlockDto == textBlockDb.adaptTo(TextBlockDTO::class)) } + /** * Creates instances of both the VideoBlock Database and VideoBlockDto Data classes with the same values * To acertain that after the VideoBlock Database class has been mapped that the classes are equal */ @Test - fun CheckVideoBlockMap() - { + fun CheckVideoBlockMap() { val videoBlockDB = VideoBlockDB( - type = VideoBlockType.YOUTUBE, - url = "https://youtu.be/myvideo", - sortIndex = 4 + type = VideoBlockType.YOUTUBE, + url = "https://youtu.be/myvideo", + sortIndex = 4 ) val videoBlockDTO = VideoBlockDTO( - type = VideoBlockType.YOUTUBE, - url = "https://youtu.be/myvideo", - sortIndex = 4 + type = VideoBlockType.YOUTUBE, + url = "https://youtu.be/myvideo", + sortIndex = 4 ) assert(videoBlockDTO == videoBlockDB.adaptTo(VideoBlockDTO::class)) } + /** * Creates instances of both the ImageBlock Database and ImageBlockDto Data classes with the same values * To acertain that after the ImageBlock Database class has been mapped that the classes are equal */ @Test - fun CheckImageBlockMap() - { - val imageBlockDB = CreateImageBlockDB(1L) + fun CheckImageBlockMap() { + val imageBlockDB = CreateImageBlockDB(1L) val imageBlockDTO = CreateImageBlockDTO(1L) assert(imageBlockDTO == imageBlockDB.adaptTo(imageBlockDTO::class)) } + /** * Creates instances of both the GalleryBlock Database and GalleryBlockDto Data classes with the same values * To acertain that after the GalleryBlock Database class has been mapped that the classes are equal */ @Test - fun CheckGalleryBlockMap() - { - val galleryBlockDB = GaleryBlockDb( - sortIndex = 3, - images = listOf( - CreateImageBlockDB(1L).image, - CreateImageBlockDB(2L).image - ) + fun CheckGalleryBlockMap() { + val galleryBlockDB = GaleryBlockDb( + sortIndex = 3, + images = listOf( + CreateImageBlockDB(1L).image, + CreateImageBlockDB(2L).image + ) ) val galleryBlockDTO = GaleryBlockDTO( - sortIndex = 3, - images = listOf( - CreateImageBlockDTO(1L).image, - CreateImageBlockDTO(2L).image - ) + sortIndex = 3, + images = listOf( + CreateImageBlockDTO(1L).image, + CreateImageBlockDTO(2L).image + ) ) assert(galleryBlockDTO == galleryBlockDB.adaptTo(GaleryBlockDTO::class)) } + /** * Creates an instance of the ImageBlock Database object * @@ -177,18 +179,19 @@ class ApplicationTests { * * @return ImageBlock database object */ - fun CreateImageBlockDB(imageId: Long) : ImageBlockDB - { + fun CreateImageBlockDB(imageId: Long): ImageBlockDB { return ImageBlockDB( - image = Image( - url = "https://someurl.com/image/$imageId", - id = imageId, - imageSize = ImageSize.LARGE, - lastModified = Date(), - lastModifiedBy = "John Doe"), - sortIndex = 1 + image = Image( + url = "https://someurl.com/image/$imageId", + id = imageId, + imageSize = ImageSize.LARGE, + lastModified = Date(), + lastModifiedBy = "John Doe" + ), + sortIndex = 1 ) } + /** * Creates an instance of the ImageBlock DTO object * @@ -196,14 +199,14 @@ class ApplicationTests { * * @return ImageBlock DTO object */ - fun CreateImageBlockDTO(imageId: Long) : ImageBlockDTO - { + fun CreateImageBlockDTO(imageId: Long): ImageBlockDTO { return ImageBlockDTO( - image = ImageDto( - url = "https://someurl.com/image/$imageId", - id = imageId, - imageSize = ImageSize.LARGE), - sortIndex = 1 + image = ImageDto( + url = "https://someurl.com/image/$imageId", + id = imageId, + imageSize = ImageSize.LARGE + ), + sortIndex = 1 ) } } \ No newline at end of file From 6f3b4bc626bd2b4ee9d12dfe2e8d4056d4e1b23e Mon Sep 17 00:00:00 2001 From: AWallsRR Date: Sat, 22 Jul 2023 13:36:21 +0200 Subject: [PATCH 7/7] Alter Object factory --- .../mapping/mappers/ArticleBlockDtoFactory.kt | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/mappers/ArticleBlockDtoFactory.kt b/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/mappers/ArticleBlockDtoFactory.kt index 3091caf..ca45989 100644 --- a/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/mappers/ArticleBlockDtoFactory.kt +++ b/Backend/mapping-kotlin/src/main/kotlin/com/staffinghub/coding/challenges/mapping/mappers/ArticleBlockDtoFactory.kt @@ -35,7 +35,7 @@ class ArticleBlockDtoFactory { ) is GalleryBlock -> GalleryBlockDto( - images = articleBlock.images.mapNotNull { it?.let { image -> mapToImageDto(image) } }, + images = articleBlock.images.mapNotNull { mapToImageDto(it) } ?: emptyList(), sortIndex = articleBlock.sortIndex ) @@ -43,11 +43,13 @@ class ArticleBlockDtoFactory { } } - private fun mapToImageDto(image: Image): ImageDto { - return ImageDto( - id = image.id, - url = image.url, - imageSize = image.imageSize - ) + private fun mapToImageDto(image: Image?): ImageDto? { + return image?.let { + ImageDto( + id = it.id, + url = it.url, + imageSize = it.imageSize + ) + } } }