-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[feat]: Gallery Preview of logged user (#375)
- Loading branch information
Showing
17 changed files
with
685 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
97 changes: 97 additions & 0 deletions
97
gallery/src/main/kotlin/me/nalab/gallery/app/GalleryDtoMapper.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
package me.nalab.gallery.app | ||
|
||
import me.nalab.gallery.domain.response.GalleryPreviewDto | ||
import me.nalab.survey.application.common.feedback.dto.BookmarkDto | ||
import me.nalab.survey.application.common.feedback.dto.ChoiceFormQuestionFeedbackDto | ||
import me.nalab.survey.application.common.feedback.dto.FeedbackDto | ||
import me.nalab.survey.application.common.feedback.dto.ShortFormQuestionFeedbackDto | ||
import me.nalab.survey.application.common.survey.dto.ChoiceFormQuestionDto | ||
import me.nalab.survey.application.common.survey.dto.ChoiceFormQuestionDtoType | ||
import me.nalab.survey.application.common.survey.dto.SurveyDto | ||
import me.nalab.survey.application.common.survey.dto.TargetDto | ||
|
||
fun toGalleryPreviewDto( | ||
target: TargetDto, | ||
survey: SurveyDto, | ||
feedbacks: List<FeedbackDto>, | ||
): GalleryPreviewDto { | ||
return GalleryPreviewDto( | ||
target = GalleryPreviewDto.Target( | ||
targetId = target.id.toString(), | ||
nickname = target.nickname, | ||
position = target.position, | ||
), | ||
survey = GalleryPreviewDto.Survey( | ||
surveyId = survey.id.toString(), | ||
feedbackCount = feedbacks.size, | ||
bookmarkedCount = 0, | ||
feedbacks = findLatestBookmarkedReply(feedbacks), | ||
tendencies = findTendencies(survey, feedbacks), | ||
) | ||
) | ||
} | ||
|
||
private fun findLatestBookmarkedReply(feedbacks: List<FeedbackDto>): List<String> { | ||
return feedbacks.filterBookmarkedFeedback() | ||
.mapBookmarkedWithReply() | ||
.sortedByDescending { (bookmark, _) -> bookmark.bookmarkedAt } | ||
.firstOrNull() | ||
?.second ?: emptyList() | ||
} | ||
|
||
private fun List<FeedbackDto>.filterBookmarkedFeedback(): List<FeedbackDto> { | ||
return this.filter { feedback -> | ||
feedback.formQuestionFeedbackDtoableList.any { formQuestionFeedback -> | ||
formQuestionFeedback.bookmarkDto.isBookmarked | ||
} | ||
} | ||
} | ||
|
||
private fun List<FeedbackDto>.mapBookmarkedWithReply(): List<Pair<BookmarkDto, List<String>>> { | ||
return this.flatMap { bookmarkedFeedback -> | ||
bookmarkedFeedback.formQuestionFeedbackDtoableList | ||
.filterIsInstance<ShortFormQuestionFeedbackDto>() | ||
.map { shortQuestionFeedback -> shortQuestionFeedback.bookmarkDto to shortQuestionFeedback.replyList } | ||
} | ||
} | ||
|
||
private fun findTendencies( | ||
survey: SurveyDto, | ||
feedbacks: List<FeedbackDto>, | ||
): List<GalleryPreviewDto.Survey.Tendency> { | ||
val tendencyQuestion = survey.formQuestionDtoableList | ||
.filterIsInstance<ChoiceFormQuestionDto>() | ||
.find { it.choiceFormQuestionDtoType == ChoiceFormQuestionDtoType.TENDENCY } | ||
?: error("필수 유형 Tendency 를 찾을 수 없습니다.") | ||
|
||
val countPerTendency = mutableMapOf<String, Int>() | ||
|
||
feedbacks.mapTendencyFeedbacks(tendencyQuestion) | ||
.forEach { tendencyFeedback -> | ||
tendencyQuestion.choiceDtoList | ||
.filter { choice -> | ||
tendencyFeedback.selectedChoiceIdSet.contains(choice.id) | ||
} | ||
.map { it.content } | ||
.forEach { tendencyContent -> | ||
countPerTendency[tendencyContent] = | ||
countPerTendency.getOrDefault(tendencyContent, 0) + 1 | ||
} | ||
} | ||
|
||
return countPerTendency.map { (name, count) -> | ||
GalleryPreviewDto.Survey.Tendency(name, count) | ||
} | ||
} | ||
|
||
private fun List<FeedbackDto>.mapTendencyFeedbacks( | ||
tendencyQuestion: ChoiceFormQuestionDto, | ||
): List<ChoiceFormQuestionFeedbackDto> { | ||
return this.flatMap { | ||
it.formQuestionFeedbackDtoableList | ||
.filterIsInstance<ChoiceFormQuestionFeedbackDto>() | ||
.filter { choiceQuestionFeedback -> | ||
choiceQuestionFeedback.questionId == tendencyQuestion.id | ||
} | ||
} | ||
} |
23 changes: 23 additions & 0 deletions
23
gallery/src/main/kotlin/me/nalab/gallery/app/GalleryPreviewApp.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package me.nalab.gallery.app | ||
|
||
import me.nalab.gallery.domain.response.GalleryPreviewDto | ||
import me.nalab.survey.application.port.`in`.web.findfeedback.FeedbackFindUseCase | ||
import me.nalab.survey.application.port.`in`.web.survey.find.SurveyFindUseCase | ||
import me.nalab.survey.application.port.`in`.web.target.find.TargetFindUseCase | ||
import org.springframework.stereotype.Service | ||
|
||
@Service | ||
class GalleryPreviewApp( | ||
private val targetFindUseCase: TargetFindUseCase, | ||
private val surveyFindUseCase: SurveyFindUseCase, | ||
private val feedbackFindUseCase: FeedbackFindUseCase, | ||
) { | ||
|
||
fun findGalleryPreview(targetId: Long): GalleryPreviewDto { | ||
val target = targetFindUseCase.findTarget(targetId) | ||
val survey = surveyFindUseCase.getSurveyByTargetId(targetId) | ||
val feedbacks = feedbackFindUseCase.findAllFeedbackDtoBySurveyId(survey.id) | ||
|
||
return toGalleryPreviewDto(target, survey, feedbacks) | ||
} | ||
} |
23 changes: 23 additions & 0 deletions
23
gallery/src/main/kotlin/me/nalab/gallery/controller/GalleryController.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package me.nalab.gallery.controller | ||
|
||
import me.nalab.gallery.app.GalleryPreviewApp | ||
import me.nalab.gallery.domain.response.GalleryPreviewDto | ||
import org.springframework.http.HttpStatus | ||
import org.springframework.web.bind.annotation.GetMapping | ||
import org.springframework.web.bind.annotation.RequestAttribute | ||
import org.springframework.web.bind.annotation.RequestMapping | ||
import org.springframework.web.bind.annotation.ResponseStatus | ||
import org.springframework.web.bind.annotation.RestController | ||
|
||
@RestController | ||
@RequestMapping("/v1/gallerys") | ||
class GalleryController( | ||
private val galleryPreviewApp: GalleryPreviewApp, | ||
) { | ||
|
||
@GetMapping("/previews") | ||
@ResponseStatus(HttpStatus.OK) | ||
fun getGalleryPreview(@RequestAttribute("logined") targetId: Long): GalleryPreviewDto = | ||
galleryPreviewApp.findGalleryPreview(targetId) | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,4 +4,5 @@ enum class Job { | |
PM, | ||
DEVELOPER, | ||
DESIGNER, | ||
OTHERS, | ||
} |
37 changes: 37 additions & 0 deletions
37
gallery/src/main/kotlin/me/nalab/gallery/domain/response/GalleryPreviewDto.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
package me.nalab.gallery.domain.response | ||
|
||
import com.fasterxml.jackson.annotation.JsonProperty | ||
import me.nalab.gallery.domain.Job | ||
|
||
data class GalleryPreviewDto( | ||
val target: Target, | ||
val survey: Survey, | ||
) { | ||
|
||
data class Target( | ||
@JsonProperty("target_id") | ||
val targetId: String, | ||
val nickname: String, | ||
val position: String?, | ||
val job: Job = Job.OTHERS, | ||
@JsonProperty("image_url") | ||
val imageUrl: String = "empty_image", | ||
) | ||
|
||
data class Survey( | ||
@JsonProperty("survey_id") | ||
val surveyId: String, | ||
@JsonProperty("feedback_count") | ||
val feedbackCount: Int, | ||
@JsonProperty("bookmarked_count") | ||
val bookmarkedCount: Int, | ||
val feedbacks: List<String>, | ||
val tendencies: List<Tendency>, | ||
) { | ||
data class Tendency( | ||
val name: String, | ||
val count: Int, | ||
) | ||
} | ||
|
||
} |
113 changes: 113 additions & 0 deletions
113
gallery/src/test/kotlin/me/nalab/gallery/app/GalleryPreviewAppTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
package me.nalab.gallery.app | ||
|
||
import com.ninjasquad.springmockk.MockkBean | ||
import io.kotest.core.annotation.DisplayName | ||
import io.kotest.core.spec.style.DescribeSpec | ||
import io.kotest.matchers.equality.shouldBeEqualUsingFields | ||
import io.mockk.every | ||
import me.nalab.gallery.domain.galleryPreviewDto | ||
import me.nalab.gallery.domain.galleryPreviewDtoSurvey | ||
import me.nalab.gallery.domain.galleryPreviewDtoTarget | ||
import me.nalab.survey.application.port.`in`.web.findfeedback.FeedbackFindUseCase | ||
import me.nalab.survey.application.port.`in`.web.survey.find.SurveyFindUseCase | ||
import me.nalab.survey.application.port.`in`.web.target.find.TargetFindUseCase | ||
import org.springframework.test.context.ContextConfiguration | ||
|
||
@ContextConfiguration( | ||
classes = [ | ||
GalleryPreviewApp::class, | ||
] | ||
) | ||
@DisplayName("GalleryPreviewApp 의") | ||
internal class GalleryPreviewAppTest( | ||
private val galleryPreviewApp: GalleryPreviewApp, | ||
@MockkBean(relaxed = true) private val targetFindUseCase: TargetFindUseCase, | ||
@MockkBean(relaxed = true) private val surveyFindUseCase: SurveyFindUseCase, | ||
@MockkBean(relaxed = true) private val feedbackFindUseCase: FeedbackFindUseCase, | ||
) : DescribeSpec({ | ||
|
||
beforeEach { | ||
every { targetFindUseCase.findTarget(DEFAULT_TARGET_ID) } returns defaultTargetDto | ||
every { surveyFindUseCase.getSurveyByTargetId(DEFAULT_TARGET_ID) } returns defaultSurveyDto | ||
every { feedbackFindUseCase.findAllFeedbackDtoBySurveyId(DEFAULT_SURVEY_ID) } returns listOf( | ||
defaultFeedbackDto | ||
) | ||
} | ||
|
||
describe("getGalleryPreview 메소드는") { | ||
context("존재하는 타겟의 id를 받으면,") { | ||
val expected = galleryPreviewDto( | ||
target = galleryPreviewDtoTarget(DEFAULT_TARGET_ID.toString()), | ||
survey = galleryPreviewDtoSurvey( | ||
surveyId = DEFAULT_SURVEY_ID.toString(), | ||
bookmarkedCount = 0 | ||
), | ||
) | ||
|
||
it("GalleryPreviewDto를 반환한다.") { | ||
val response = galleryPreviewApp.findGalleryPreview(DEFAULT_TARGET_ID) | ||
|
||
response shouldBeEqualUsingFields expected | ||
} | ||
} | ||
|
||
context("피드백이 하나도 없다면,") { | ||
val expected = galleryPreviewDto( | ||
target = galleryPreviewDtoTarget(DEFAULT_TARGET_ID.toString()), | ||
survey = galleryPreviewDtoSurvey( | ||
surveyId = DEFAULT_SURVEY_ID.toString(), | ||
feedbackCount = 0, | ||
bookmarkedCount = 0, | ||
feedbacks = emptyList(), | ||
tendencies = emptyList(), | ||
) | ||
) | ||
|
||
|
||
it("feedback이 비어있는 GalleryPreviewDto를 반환한다.") { | ||
every { surveyFindUseCase.getSurveyByTargetId(DEFAULT_TARGET_ID) } returns surveyDto( | ||
id = DEFAULT_SURVEY_ID, formQuestionDtos = listOf(choiceFormQuestionDto()) | ||
) | ||
every { feedbackFindUseCase.findAllFeedbackDtoBySurveyId(DEFAULT_SURVEY_ID) } returns emptyList() | ||
|
||
val response = galleryPreviewApp.findGalleryPreview(DEFAULT_TARGET_ID) | ||
|
||
response shouldBeEqualUsingFields expected | ||
} | ||
} | ||
} | ||
|
||
}) { | ||
private companion object { | ||
private const val DEFAULT_TARGET_ID = 1L | ||
private const val DEFAULT_SURVEY_ID = 2L | ||
private const val DEFAULT_FEEDBACK_ID = 3L | ||
private const val TENDENCY_QUESTION_ID = 4L | ||
private const val CUSTOM_SHORT_FORM_QUESTION_ID = 5L | ||
|
||
private val defaultTargetDto = targetDto(id = DEFAULT_TARGET_ID) | ||
|
||
private val formQuestionDtos = listOf( | ||
choiceFormQuestionDto(id = TENDENCY_QUESTION_ID), | ||
shortFormQuestionDto(id = CUSTOM_SHORT_FORM_QUESTION_ID), | ||
) | ||
|
||
private val defaultSurveyDto = | ||
surveyDto(id = DEFAULT_SURVEY_ID, formQuestionDtos = formQuestionDtos) | ||
|
||
private val formQuestionFeedbackDtos = listOf( | ||
choiceFormQuestionFeedbackDto(questionId = TENDENCY_QUESTION_ID), | ||
shortFormQuestionFeedbackDto( | ||
questionId = CUSTOM_SHORT_FORM_QUESTION_ID, | ||
bookmarkDto = bookmarkDto(isBookmarked = true) | ||
), | ||
) | ||
|
||
private val defaultFeedbackDto = | ||
feedbackDto( | ||
id = DEFAULT_FEEDBACK_ID, | ||
surveyId = DEFAULT_SURVEY_ID, | ||
formQuestionFeedbackDtos = formQuestionFeedbackDtos, | ||
) | ||
} | ||
} |
Oops, something went wrong.