Skip to content

Commit

Permalink
feat: GET /api/v1/workbooks/{workbookId}/articles/{articleId} 구현 (#65)
Browse files Browse the repository at this point in the history
* refactor: ApiMain 클래스 이동

* feat: api-repo 모듈 ObjectMapper 빈 선언

* feat: selectArticleRecord 메서드 구현

* test: selectArticleRecord 테스트 구현

* feat: selectWriter 메서드 구현

* test: selectWriter 테스트 구현

* feat: WriterDescription 구현

* test: WriterDescriptionMapperTest 테스트 구현

* feat: selectProblemsByArticleId 메서드 구현

* test: selectProblemsByArticleId 테스트 구현

* feat: Contents 구현

* test: ContentsMapperTest 테스트 구현

* feat: BrowseArticleProblemsService 구현

* feat: ReadWriterRecordService 구현

* feat: ReadArticleUseCase 구현

* feat: ApiRepoObjectMapperConfig 삭제

* refactor: init 블록에서 registerKotlinModule 수행되도록 수정

* refactor: 기본 등록 ObjectMapper 사용하도록 수정

* refactor: ReadArticleUseCase 컨트롤러에 적용

* refactor: readArticle 컨트롤러 테스트 유스케이스 목 처리

* refactor: ReadArticleResponse 응답 구현 수정

* refactor: 쿼리 객체에 Id 특성을 추가하여 추후 Problems 조회도 가능할 수 있도록 수정

* refactor: 아티클 작성자를 조회하는 것임을 명확히 하기 위해 수정

* chore: 해결된 Todo 삭제

* feat: selectWorkBookArticleRecord 메서드 구현

* test: selectWorkBookArticleRecord 테스트 구현

* feat: ReadWorkBookArticleUseCase 구현

* refactor: ReadWorkBookArticleUseCase 컨트롤러에 적용

* refactor: readWorkBookArticle 컨트롤러에 테스트 유스케이스 목 처리
  • Loading branch information
belljun3395 authored Jun 22, 2024
1 parent 2519b60 commit be09bd6
Show file tree
Hide file tree
Showing 14 changed files with 411 additions and 21 deletions.
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package com.few.api.repo.dao.article

import com.few.api.repo.dao.article.query.SelectArticleRecordQuery
import com.few.api.repo.dao.article.query.SelectWorkBookArticleRecordQuery
import com.few.api.repo.dao.article.record.SelectArticleRecord
import com.few.api.repo.dao.article.record.SelectWorkBookArticleRecord
import jooq.jooq_dsl.tables.ArticleIfo
import jooq.jooq_dsl.tables.ArticleMst
import jooq.jooq_dsl.tables.MappingWorkbookArticle
import org.jooq.DSLContext
import org.springframework.stereotype.Repository

Expand All @@ -29,4 +32,32 @@ class ArticleDao(
.fetchOneInto(SelectArticleRecord::class.java)
?: throw IllegalArgumentException("cannot find article record by articleId: $articleId")
}

fun selectWorkBookArticleRecord(query: SelectWorkBookArticleRecordQuery): SelectWorkBookArticleRecord {
val articleMst = ArticleMst.ARTICLE_MST
val articleIfo = ArticleIfo.ARTICLE_IFO
val mappingWorkbookArticle = MappingWorkbookArticle.MAPPING_WORKBOOK_ARTICLE

val articleId = query.articleId
val workbookId = query.workbookId

return dslContext.select(
articleMst.ID.`as`(SelectWorkBookArticleRecord::articleId.name),
articleMst.MEMBER_ID.`as`(SelectWorkBookArticleRecord::writerId.name),
articleMst.MAIN_IMAGE_URL.`as`(SelectWorkBookArticleRecord::mainImageURL.name),
articleMst.TITLE.`as`(SelectWorkBookArticleRecord::title.name),
articleMst.CATEGORY_CD.`as`(SelectWorkBookArticleRecord::category.name),
articleIfo.CONTENT.`as`(SelectWorkBookArticleRecord::content.name),
articleMst.CREATED_AT.`as`(SelectWorkBookArticleRecord::createdAt.name),
mappingWorkbookArticle.DAY_COL.`as`(SelectWorkBookArticleRecord::day.name)
).from(articleMst)
.join(articleIfo)
.on(articleMst.ID.eq(articleIfo.ARTICLE_MST_ID))
.join(mappingWorkbookArticle)
.on(mappingWorkbookArticle.WORKBOOK_ID.eq(workbookId))
.and(mappingWorkbookArticle.ARTICLE_ID.eq(articleMst.ID))
.where(articleMst.ID.eq(articleId))
.fetchOneInto(SelectWorkBookArticleRecord::class.java)
?: throw IllegalArgumentException("cannot find $workbookId article record by articleId: $articleId")
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.few.api.repo.dao.article.query

data class SelectWorkBookArticleRecordQuery(
val workbookId: Long,
val articleId: Long
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.few.api.repo.dao.article.record

import java.time.LocalDateTime

data class SelectWorkBookArticleRecord(
val articleId: Long,
val writerId: Long,
val mainImageURL: String,
val title: String,
val category: Byte,
val content: String,
val createdAt: LocalDateTime,
val day: Long
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.few.api.repo.dao.member.support

import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.kotlin.registerKotlinModule
import org.springframework.stereotype.Component

@Component
class WriterDescriptionMapper(
private val objectMapper: ObjectMapper
) {
init {
objectMapper.registerKotlinModule()
}

fun toJson(writerDescription: WriterDescription): String {
return objectMapper.writeValueAsString(writerDescription)
}

fun toObject(value: String): WriterDescription {
return objectMapper.readValue(value, WriterDescription::class.java)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.few.api.repo.dao.problem.support

import com.fasterxml.jackson.databind.ObjectMapper
import org.springframework.stereotype.Component

@Component
class ContentsMapper(
private val objectMapper: ObjectMapper
) {

fun toJson(contents: Contents): String {
return objectMapper.writeValueAsString(contents)
}

fun toObject(value: String): Contents {
val contents = objectMapper.readTree(value).get("contents")
val contentList = mutableListOf<Content>()
contents.forEach {
contentList.add(Content(it.get("id").asLong(), it.get("content").asText()))
}
return Contents(contentList)
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package com.few.api.repo.dao.article

import com.few.api.repo.dao.article.query.SelectArticleRecordQuery
import com.few.api.repo.dao.article.query.SelectWorkBookArticleRecordQuery
import com.few.api.repo.jooq.JooqTestSpec
import jooq.jooq_dsl.tables.ArticleIfo
import jooq.jooq_dsl.tables.ArticleMst
import jooq.jooq_dsl.tables.MappingWorkbookArticle
import org.jooq.DSLContext
import org.junit.jupiter.api.Assertions.*
import org.junit.jupiter.api.BeforeEach
Expand Down Expand Up @@ -61,4 +63,44 @@ class ArticleDaoTest : JooqTestSpec() {
assertEquals("this is content", result.content)
assertEquals(0, result.category)
}

@Test
@Transactional
fun `학습지 Id와 아티클 Id를 통해 학습지에서의 아티클 Day가 포함된 아티클 정보를 조회합니다`() {
// given
setMappingWorkbookArticleData()
val query = SelectWorkBookArticleRecordQuery(1L, 1L)

// when
val result = query.let {
articleDao.selectWorkBookArticleRecord(it)
}

// then
assertNotNull(result)
assertEquals(1L, result.articleId)
assertEquals(1L, result.writerId)
assertEquals("http://localhost:8080/image.jpg", result.mainImageURL)
assertEquals("this is title", result.title)
assertEquals("this is content", result.content)
assertEquals(0, result.category)
assertEquals(1L, result.day)
}

private fun setMappingWorkbookArticleData() {
log.debug("===== start setMappingWorkbookArticleData =====")
dslContext.deleteFrom(MappingWorkbookArticle.MAPPING_WORKBOOK_ARTICLE).execute()
setMappingWorkbookArticle(1L, 1L, 1)
setMappingWorkbookArticle(1L, 2L, 2)
setMappingWorkbookArticle(1L, 3L, 3)
log.debug("===== finish setMappingWorkbookArticleData =====")
}

private fun setMappingWorkbookArticle(workbookId: Long, articleId: Long, day: Int) {
dslContext.insertInto(MappingWorkbookArticle.MAPPING_WORKBOOK_ARTICLE)
.set(MappingWorkbookArticle.MAPPING_WORKBOOK_ARTICLE.WORKBOOK_ID, workbookId)
.set(MappingWorkbookArticle.MAPPING_WORKBOOK_ARTICLE.ARTICLE_ID, articleId)
.set(MappingWorkbookArticle.MAPPING_WORKBOOK_ARTICLE.DAY_COL, day)
.execute()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package com.few.api.repo.dao.member.support

import com.fasterxml.jackson.databind.ObjectMapper
import org.junit.jupiter.api.Assertions.*
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest

import java.net.URL

@SpringBootTest(classes = [ObjectMapper::class])
class WriterDescriptionMapperTest {

@Autowired
private lateinit var objectMapper: ObjectMapper
private lateinit var writerDescriptionMapper: WriterDescriptionMapper

@BeforeEach
fun setUp() {
writerDescriptionMapper = WriterDescriptionMapper(objectMapper)
}

@Test
fun `WriterDescription을 Json 형식으로 변환합니다`() {
// Given
val writerDescription = WriterDescription(
name = "writer",
url = URL("http://localhost:8080/writers/url")
)

// When
val json = writerDescriptionMapper.toJson(writerDescription)

// Then
assertNotNull(json)
assertTrue(json.isNotBlank())
assertTrue(json.contains("writer"))
assertTrue(json.contains("http://localhost:8080/writers/url"))
}

@Test
fun `Json 형식의 WriterDescription을 WriterDescription으로 변환합니다`() {
// Given
val json = """
{
"name": "writer",
"url": "http://localhost:8080/writers/url"
}
""".trimIndent()

// When
val writerDescription = writerDescriptionMapper.toObject(json)

// Then
assertNotNull(writerDescription)
assertEquals("writer", writerDescription.name)
assertEquals(URL("http://localhost:8080/writers/url"), writerDescription.url)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package com.few.api.repo.dao.problem.support

import com.fasterxml.jackson.databind.ObjectMapper
import org.junit.jupiter.api.Assertions.*
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest

@SpringBootTest(classes = [ObjectMapper::class])
class ContentsMapperTest {

@Autowired
private lateinit var objectMapper: ObjectMapper

private lateinit var contentsMapper: ContentsMapper

@BeforeEach
fun setUp() {
contentsMapper = ContentsMapper(objectMapper)
}

@Test
fun `Contents를 Json 형식으로 변환합니다`() {
// Given
val contents = Contents(
contents = listOf(
Content(1L, "this is number one"),
Content(2L, "this is number two")
)
)

// When
val json = contentsMapper.toJson(contents)

// Then
assertNotNull(json)
assertTrue(json.isNotBlank())
assertTrue(json.contains("this is number one"))
assertTrue(json.contains("this is number two"))
}

@Test
fun `Json 형식의 Contents를 Contents으로 변환합니다`() {
// Given
val json = """
{
"contents": [
{
"id": 1,
"content": "this is number one"
},
{
"id": 2,
"content": "this is number two"
}
]
}
""".trimIndent()

// When
val contents = contentsMapper.toObject(json)

// Then
assertNotNull(contents)
assertEquals(2, contents.contents.size)
assertEquals(1L, contents.contents[0].number)
assertEquals("this is number one", contents.contents[0].content)
assertEquals(2L, contents.contents[1].number)
assertEquals("this is number two", contents.contents[1].content)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.few.api.domain.workbook.article.dto

data class ReadWorkBookArticleUseCaseIn(
val workbookId: Long,
val articleId: Long
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.few.api.domain.workbook.article.dto

import java.net.URL
import java.time.LocalDateTime

data class ReadWorkBookArticleOut(
val id: Long,
val writer: WriterDetail,
val title: String,
val content: String,
val problemIds: List<Long>,
val category: String,
val createdAt: LocalDateTime,
val day: Long
)

data class WriterDetail(
val id: Long,
val name: String,
val url: URL
)
Loading

0 comments on commit be09bd6

Please sign in to comment.