Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 2 additions & 9 deletions src/main/java/eatda/controller/cheer/CheerResponse.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package eatda.controller.cheer;

import eatda.domain.cheer.Cheer;
import eatda.domain.cheer.CheerTag;
import eatda.domain.cheer.CheerTagName;
import eatda.domain.store.Store;
import java.util.List;
Expand All @@ -14,19 +13,13 @@ public record CheerResponse(
List<CheerTagName> tags
) {

public CheerResponse(Cheer cheer, List<CheerTag> cheerTags, Store store, String imageUrl) {
public CheerResponse(Cheer cheer, Store store, String imageUrl) {
this(
store.getId(),
cheer.getId(),
imageUrl,
cheer.getDescription(),
toTagNames(cheerTags)
cheer.getCheerTagNames()
);
}

private static List<CheerTagName> toTagNames(List<CheerTag> cheerTags) {
return cheerTags.stream()
.map(CheerTag::getName)
.toList();
}
}
17 changes: 17 additions & 0 deletions src/main/java/eatda/domain/cheer/Cheer.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import java.util.Collections;
import java.util.List;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
Expand Down Expand Up @@ -44,6 +46,9 @@ public class Cheer extends AuditingEntity {
@Embedded
private ImageKey imageKey;

@Embedded
private CheerTags cheerTags;

@Column(name = "is_admin", nullable = false)
private boolean isAdmin;

Expand All @@ -53,6 +58,7 @@ public Cheer(Member member, Store store, String description, ImageKey imageKey)
this.store = store;
this.description = description;
this.imageKey = imageKey;
this.cheerTags = new CheerTags();

this.isAdmin = false;
}
Expand All @@ -67,4 +73,15 @@ private void validateDescription(String description) {
throw new BusinessException(BusinessErrorCode.INVALID_CHEER_DESCRIPTION);
}
}

public void setCheerTags(List<CheerTagName> cheerTagNames) {
this.cheerTags.setTags(this, cheerTagNames);
}

public List<CheerTagName> getCheerTagNames() {
if (cheerTags == null) {
return Collections.emptyList();
}
return cheerTags.getNames();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,29 @@

import eatda.exception.BusinessErrorCode;
import eatda.exception.BusinessException;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Embeddable;
import jakarta.persistence.OneToMany;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class CheerTagNames {
@Embeddable
public class CheerTags {

private static final int MAX_CHEER_TAGS_PER_TYPE = 2;

private final List<CheerTagName> cheerTagNames;
@OneToMany(mappedBy = "cheer", cascade = CascadeType.ALL, orphanRemoval = true)
private List<CheerTag> values = new ArrayList<>();

public CheerTagNames(List<CheerTagName> cheerTagNames) {
public void setTags(Cheer cheer, List<CheerTagName> cheerTagNames) {
validate(cheerTagNames);
this.cheerTagNames = List.copyOf(cheerTagNames);
List<CheerTag> cheerTags = cheerTagNames.stream()
.map(name -> new CheerTag(cheer, name)) // cheer is set later
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

어엄? 이 주석은 무엇일까요??

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

깃허브 코파일럿이 넣어놨는데, 안뺏군요;; 다른 PR에서 지우도록 하겠습니다.

.toList();

this.values.clear();
this.values.addAll(cheerTags);
}

private void validate(List<CheerTagName> cheerTagNames) {
Expand Down Expand Up @@ -41,9 +52,9 @@ private long maxCountByType(List<CheerTagName> cheerTagNames) {
.orElse(0L);
}

public List<CheerTag> toCheerTags(Cheer cheer) {
return cheerTagNames.stream()
.map(name -> new CheerTag(cheer, name))
public List<CheerTagName> getNames() {
return values.stream()
.map(CheerTag::getName)
.toList();
}
}
10 changes: 4 additions & 6 deletions src/main/java/eatda/service/cheer/CheerService.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
import eatda.controller.cheer.CheersResponse;
import eatda.domain.ImageKey;
import eatda.domain.cheer.Cheer;
import eatda.domain.cheer.CheerTag;
import eatda.domain.cheer.CheerTagNames;
import eatda.domain.member.Member;
import eatda.domain.store.Store;
import eatda.domain.store.StoreSearchResult;
Expand Down Expand Up @@ -43,15 +41,15 @@ public CheerResponse registerCheer(CheerRegisterRequest request,
StoreSearchResult result,
ImageKey imageKey,
long memberId) {
CheerTagNames cheerTagNames = new CheerTagNames(request.tags());
Member member = memberRepository.getById(memberId);
validateRegisterCheer(member, request.storeKakaoId());

Store store = storeRepository.findByKakaoId(result.kakaoId())
.orElseGet(() -> storeRepository.save(result.toStore())); // TODO 상점 조회/저장 동시성 이슈 해결
Cheer cheer = cheerRepository.save(new Cheer(member, store, request.description(), imageKey));
List<CheerTag> cheerTags = cheerTagRepository.saveAll(cheerTagNames.toCheerTags(cheer));
return new CheerResponse(cheer, cheerTags, store, imageStorage.getPreSignedUrl(imageKey));
Cheer cheer = new Cheer(member, store, request.description(), imageKey);
cheer.setCheerTags(request.tags());
Cheer savedCheer = cheerRepository.save(cheer);
return new CheerResponse(savedCheer, store, imageStorage.getPreSignedUrl(imageKey));
}

private void validateRegisterCheer(Member member, String storeKakaoId) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,51 +4,79 @@
import static org.assertj.core.api.Assertions.assertThatCode;
import static org.junit.jupiter.api.Assertions.assertThrows;

import eatda.domain.ImageKey;
import eatda.domain.member.Member;
import eatda.domain.store.District;
import eatda.domain.store.Store;
import eatda.domain.store.StoreCategory;
import eatda.exception.BusinessErrorCode;
import eatda.exception.BusinessException;
import java.util.Collections;
import java.util.List;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;

class CheerTagNamesTest {
class CheerTagsTest {

private static final Member DEFAULT_MEMBER = new Member("socialId", "email@kakao.com", "nickname");
private static final Store DEFAULT_STORE = Store.builder()
.kakaoId("123456789")
.category(StoreCategory.OTHER)
.phoneNumber("010-1234-5678")
.name("가게 이름")
.placeUrl("https://place.kakao.com/123456789")
.roadAddress("")
.lotNumberAddress("서울특별시 강남구 역삼동 123-45")
.district(District.GANGNAM)
.latitude(37.5665)
.longitude(126.978)
.build();
private static final Cheer DEFAULT_CHEER = new Cheer(DEFAULT_MEMBER, DEFAULT_STORE, "Great store!",
new ImageKey("imageKey"));

@Nested
class Validate {
class SetTags {

@Test
void 각_카테고리별_태그는_최대_개수가_정해져있다() {
List<CheerTagName> tagNames = List.of(
CheerTagName.OLD_STORE_MOOD, CheerTagName.ENERGETIC,
CheerTagName.GROUP_RESERVATION, CheerTagName.LARGE_PARKING);
CheerTags cheerTags = new CheerTags();

assertThatCode(() -> new CheerTagNames(tagNames)).doesNotThrowAnyException();
assertThatCode(() -> cheerTags.setTags(DEFAULT_CHEER, tagNames)).doesNotThrowAnyException();
}

@Test
void 태그_이름은_비어있을_수_있다() {
List<CheerTagName> tagNames = Collections.emptyList();
CheerTags cheerTags = new CheerTags();

assertThatCode(() -> new CheerTagNames(tagNames)).doesNotThrowAnyException();
assertThatCode(() -> cheerTags.setTags(DEFAULT_CHEER, tagNames)).doesNotThrowAnyException();
}

@Test
void 카테고리별_태그는_최대_개수를_초과할_수_없다() {
List<CheerTagName> tagNames = List.of(
CheerTagName.OLD_STORE_MOOD, CheerTagName.ENERGETIC, CheerTagName.GOOD_FOR_DATING);
CheerTags cheerTags = new CheerTags();

BusinessException exception = assertThrows(BusinessException.class, () -> new CheerTagNames(tagNames));
BusinessException exception = assertThrows(BusinessException.class,
() -> cheerTags.setTags(DEFAULT_CHEER, tagNames));

assertThat(exception.getErrorCode()).isEqualTo(BusinessErrorCode.EXCEED_CHEER_TAGS_PER_TYPE);
}

@Test
void 태그_이름은_중복될_수_없다() {
List<CheerTagName> tagNames = List.of(CheerTagName.OLD_STORE_MOOD, CheerTagName.OLD_STORE_MOOD);
CheerTags cheerTags = new CheerTags();

BusinessException exception = assertThrows(BusinessException.class, () -> new CheerTagNames(tagNames));
BusinessException exception = assertThrows(BusinessException.class,
() -> cheerTags.setTags(DEFAULT_CHEER, tagNames));

assertThat(exception.getErrorCode()).isEqualTo(BusinessErrorCode.CHEER_TAGS_DUPLICATED);
}
}

}
21 changes: 21 additions & 0 deletions src/test/java/eatda/service/cheer/CheerServiceTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,27 @@ class RegisterCheer {
CheerTagName.GOOD_FOR_DATING, CheerTagName.CLEAN_RESTROOM)
);
}

@Test
void 해당_응원의_응원_태그가_비어있어도_응원을_저장할_수_있다() {
Member member = memberGenerator.generate("123");

CheerRegisterRequest request = new CheerRegisterRequest("123", "농민백암순대 본점", "맛있어요!", List.of());
StoreSearchResult result = new StoreSearchResult(
"123", StoreCategory.KOREAN, "02-755-5232", "농민백암순대 본점", "http://place.map.kakao.com/123",
"서울시 강남구 역삼동 123-45", "서울시 강남구 역삼동 123-45", District.GANGNAM, 37.5665, 126.9780);
ImageKey imageKey = new ImageKey("image-key");

CheerResponse response = cheerService.registerCheer(request, result, imageKey, member.getId());

Store foundStore = storeRepository.findByKakaoId("123").orElseThrow();
assertAll(
() -> assertThat(response.storeId()).isEqualTo(foundStore.getId()),
() -> assertThat(response.cheerDescription()).isEqualTo("맛있어요!"),
() -> assertThat(response.imageUrl()).isNotBlank(),
() -> assertThat(response.tags()).isEmpty()
);
}
}

@Nested
Expand Down
Loading