diff --git a/src/main/java/com/gamsa/history/constant/ActivityStatus.java b/src/main/java/com/gamsa/history/constant/ActivityStatus.java new file mode 100644 index 0000000..ad88bbd --- /dev/null +++ b/src/main/java/com/gamsa/history/constant/ActivityStatus.java @@ -0,0 +1,16 @@ +package com.gamsa.history.constant; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@Getter +@RequiredArgsConstructor +public enum ActivityStatus { + APPLIED("접수"), + WAITING("활동 대기"), + ACT("활동"), + FINISHED("활동 완료"), + REVIEWED("리뷰 완료"); + + private final String name; +} diff --git a/src/main/java/com/gamsa/history/constant/ActivityStatusConverter.java b/src/main/java/com/gamsa/history/constant/ActivityStatusConverter.java new file mode 100644 index 0000000..0f9a451 --- /dev/null +++ b/src/main/java/com/gamsa/history/constant/ActivityStatusConverter.java @@ -0,0 +1,29 @@ +package com.gamsa.history.constant; + +import jakarta.persistence.AttributeConverter; +import jakarta.persistence.Converter; + +import java.util.stream.Stream; + +@Converter +public class ActivityStatusConverter implements AttributeConverter { + + @Override + public String convertToDatabaseColumn(ActivityStatus activityStatus) { + if (activityStatus == null) { + return null; + } + return activityStatus.getName(); + } + + @Override + public ActivityStatus convertToEntityAttribute(String name) { + if (name == null) { + return null; + } + return Stream.of(ActivityStatus.values()) + .filter(category -> category.getName().equals(name)) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException("존재하지 않는 활동 상태 접근.")); + } +} diff --git a/src/main/java/com/gamsa/history/controller/HistoryController.java b/src/main/java/com/gamsa/history/controller/HistoryController.java new file mode 100644 index 0000000..1dac62f --- /dev/null +++ b/src/main/java/com/gamsa/history/controller/HistoryController.java @@ -0,0 +1,35 @@ +package com.gamsa.history.controller; + +import com.gamsa.history.dto.HistoryFindSliceResponse; +import com.gamsa.history.dto.HistorySaveRequest; +import com.gamsa.history.service.HistoryService; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Slice; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +@RequiredArgsConstructor +@RestController +@RequestMapping("/api/v1/history") +public class HistoryController { + private HistoryService historyService; + + @PostMapping + public ResponseEntity addHistory(@RequestBody HistorySaveRequest saveRequest) { + historyService.save(saveRequest); + return new ResponseEntity<>(HttpStatus.CREATED); + } + + @GetMapping("{avatar-id}") + public Slice findSliceByUserId(@PathVariable("avatar-id") long avatarId, Pageable pageable) { + return historyService.findSliceByAvatarId(avatarId, pageable); + } + + @DeleteMapping("{history-id}") + public ResponseEntity deleteHistory(@PathVariable("history-id") long historyId) { + historyService.delete(historyId); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } +} diff --git a/src/main/java/com/gamsa/history/domain/History.java b/src/main/java/com/gamsa/history/domain/History.java new file mode 100644 index 0000000..661816e --- /dev/null +++ b/src/main/java/com/gamsa/history/domain/History.java @@ -0,0 +1,37 @@ +package com.gamsa.history.domain; + +import com.gamsa.activity.domain.Activity; +import com.gamsa.avatar.domain.Avatar; +import com.gamsa.history.constant.ActivityStatus; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; + +import java.time.LocalDateTime; + +@Getter +@Builder +@AllArgsConstructor +public class History { + private long historyId; + private Avatar avatar; + private Activity activity; + private ActivityStatus activityStatus; + private boolean reviewed; + + public void changeActivityStatusOnDate(LocalDateTime now) { + if ((this.activityStatus == ActivityStatus.APPLIED) + && (now.isAfter(activity.getNoticeEndDate()))) { + this.activityStatus = ActivityStatus.WAITING; + } else if ((this.activityStatus == ActivityStatus.WAITING) + && (now.isAfter(activity.getActStartDate()))) { + this.activityStatus = ActivityStatus.ACT; + } else if (now.isAfter(activity.getActEndDate())) { + this.activityStatus = ActivityStatus.FINISHED; + } + } + + public void changeReviewed(boolean reviewed) { + this.reviewed = reviewed; + } +} diff --git a/src/main/java/com/gamsa/history/dto/HistoryFindSliceResponse.java b/src/main/java/com/gamsa/history/dto/HistoryFindSliceResponse.java new file mode 100644 index 0000000..c01fb39 --- /dev/null +++ b/src/main/java/com/gamsa/history/dto/HistoryFindSliceResponse.java @@ -0,0 +1,30 @@ +package com.gamsa.history.dto; + +import com.gamsa.activity.dto.ActivityDetailResponse; +import com.gamsa.history.constant.ActivityStatus; +import com.gamsa.history.domain.History; +import lombok.Builder; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@Getter +@Builder +@RequiredArgsConstructor +public class HistoryFindSliceResponse { + + private final long historyId; + private final long avatarId; + private final ActivityDetailResponse activity; + private final ActivityStatus activityStatus; + private final boolean reviewed; + + public static HistoryFindSliceResponse from(final History history) { + return HistoryFindSliceResponse.builder() + .historyId(history.getHistoryId()) + .avatarId(history.getAvatar().getAvatarId()) + .activityStatus(history.getActivityStatus()) + .reviewed(history.isReviewed()) + .activity(ActivityDetailResponse.from(history.getActivity())) + .build(); + } +} diff --git a/src/main/java/com/gamsa/history/dto/HistorySaveRequest.java b/src/main/java/com/gamsa/history/dto/HistorySaveRequest.java new file mode 100644 index 0000000..b1f5964 --- /dev/null +++ b/src/main/java/com/gamsa/history/dto/HistorySaveRequest.java @@ -0,0 +1,26 @@ +package com.gamsa.history.dto; + +import com.gamsa.activity.domain.Activity; +import com.gamsa.avatar.domain.Avatar; +import com.gamsa.history.constant.ActivityStatus; +import com.gamsa.history.domain.History; +import lombok.Builder; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@Getter +@Builder +@RequiredArgsConstructor +public class HistorySaveRequest { + private final long avatarId; + private final long actId; + + public History toModel(Avatar avatar, Activity activity) { + return History.builder() + .activity(activity) + .avatar(avatar) + .activityStatus(ActivityStatus.APPLIED) + .reviewed(false) + .build(); + } +} diff --git a/src/main/java/com/gamsa/history/entity/HistoryJpaEntity.java b/src/main/java/com/gamsa/history/entity/HistoryJpaEntity.java new file mode 100644 index 0000000..b9f7e07 --- /dev/null +++ b/src/main/java/com/gamsa/history/entity/HistoryJpaEntity.java @@ -0,0 +1,59 @@ +package com.gamsa.history.entity; + + +import com.gamsa.activity.entity.ActivityJpaEntity; +import com.gamsa.avatar.entity.AvatarJpaEntity; +import com.gamsa.common.entity.BaseEntity; +import com.gamsa.history.constant.ActivityStatus; +import com.gamsa.history.constant.ActivityStatusConverter; +import com.gamsa.history.domain.History; +import jakarta.persistence.*; +import lombok.*; + +@Getter +@Builder +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@AllArgsConstructor +@Entity +@Table(name = "History") +public class HistoryJpaEntity extends BaseEntity { + @Id + @GeneratedValue() + @Column(name = "history_id") + private long historyId; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "avatar_id") + private AvatarJpaEntity avatar; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "activity_id") + private ActivityJpaEntity activity; + + @Convert(converter = ActivityStatusConverter.class) + @Column(name = "activity_status") + private ActivityStatus activityStatus; + + @Column(name = "reviewed") + private boolean reviewed; + + public static HistoryJpaEntity from(History history) { + return HistoryJpaEntity.builder() + .historyId(history.getHistoryId()) + .avatar(AvatarJpaEntity.from(history.getAvatar())) + .activity(ActivityJpaEntity.from(history.getActivity())) + .activityStatus(history.getActivityStatus()) + .reviewed(history.isReviewed()) + .build(); + } + + public History toModel() { + return History.builder() + .historyId(historyId) + .avatar(avatar.toModel()) + .activity(activity.toModel()) + .activityStatus(activityStatus) + .reviewed(reviewed) + .build(); + } +} diff --git a/src/main/java/com/gamsa/history/repository/HistoryCustomRepository.java b/src/main/java/com/gamsa/history/repository/HistoryCustomRepository.java new file mode 100644 index 0000000..d04ab24 --- /dev/null +++ b/src/main/java/com/gamsa/history/repository/HistoryCustomRepository.java @@ -0,0 +1,9 @@ +package com.gamsa.history.repository; + +import com.gamsa.history.entity.HistoryJpaEntity; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Slice; + +public interface HistoryCustomRepository { + Slice findSliceByAvatarId(long avatarId, Pageable pageable); +} diff --git a/src/main/java/com/gamsa/history/repository/HistoryCustomRepositoryImpl.java b/src/main/java/com/gamsa/history/repository/HistoryCustomRepositoryImpl.java new file mode 100644 index 0000000..012feed --- /dev/null +++ b/src/main/java/com/gamsa/history/repository/HistoryCustomRepositoryImpl.java @@ -0,0 +1,59 @@ +package com.gamsa.history.repository; + +import com.gamsa.history.entity.HistoryJpaEntity; +import com.querydsl.core.types.Order; +import com.querydsl.core.types.OrderSpecifier; +import com.querydsl.core.types.dsl.PathBuilder; +import com.querydsl.jpa.impl.JPAQueryFactory; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Slice; +import org.springframework.data.domain.SliceImpl; + +import java.util.ArrayList; +import java.util.List; + +import static com.gamsa.history.entity.QHistoryJpaEntity.historyJpaEntity; + +@RequiredArgsConstructor +public class HistoryCustomRepositoryImpl implements HistoryCustomRepository { + private final JPAQueryFactory jpaQueryFactory; + + @Override + public Slice findSliceByAvatarId(long avatarId, Pageable pageable) { + List orders = getAllOrderSpecifiers(pageable); + + List results = jpaQueryFactory + .selectFrom(historyJpaEntity) + .where(historyJpaEntity.avatar.avatarId.eq(avatarId)) + .orderBy(orders.toArray(OrderSpecifier[]::new)) + .offset(pageable.getOffset()) + .limit(pageable.getOffset() + 1) + .fetch(); + + return checkLastPage(pageable, results); + } + + private Slice checkLastPage(Pageable pageable, List results) { + boolean hasNest = false; + if (results.size() > pageable.getPageSize()) { + hasNest = true; + results.remove(pageable.getPageSize()); + } + return new SliceImpl<>(results, pageable, hasNest); + } + + private List getAllOrderSpecifiers(Pageable pageable) { + List orders = new ArrayList<>(); + + pageable.getSort().stream() + .forEach(order -> { + Order direction = order.getDirection().isAscending() ? Order.ASC : Order.DESC; + String property = order.getProperty(); + PathBuilder orderPath = new PathBuilder(HistoryJpaEntity.class, "activityJpaEntity"); + orders.add(new OrderSpecifier(direction, orderPath.get(property))); + } + ); + return orders; + } +} diff --git a/src/main/java/com/gamsa/history/repository/HistoryJpaRepository.java b/src/main/java/com/gamsa/history/repository/HistoryJpaRepository.java new file mode 100644 index 0000000..c3dc2ca --- /dev/null +++ b/src/main/java/com/gamsa/history/repository/HistoryJpaRepository.java @@ -0,0 +1,8 @@ +package com.gamsa.history.repository; + +import com.gamsa.history.entity.HistoryJpaEntity; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface HistoryJpaRepository extends JpaRepository, + HistoryCustomRepository { +} diff --git a/src/main/java/com/gamsa/history/repository/HistoryRepository.java b/src/main/java/com/gamsa/history/repository/HistoryRepository.java new file mode 100644 index 0000000..f2f0683 --- /dev/null +++ b/src/main/java/com/gamsa/history/repository/HistoryRepository.java @@ -0,0 +1,18 @@ +package com.gamsa.history.repository; + +import com.gamsa.history.domain.History; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Slice; + +import java.util.Optional; + +public interface HistoryRepository { + + void save(History history); + + Optional findById(long id); + + void delete(History history); + + Slice findSliceByAvatarId(long avatarId, Pageable pageable); +} diff --git a/src/main/java/com/gamsa/history/repository/HistoryRepositoryImpl.java b/src/main/java/com/gamsa/history/repository/HistoryRepositoryImpl.java new file mode 100644 index 0000000..7832a47 --- /dev/null +++ b/src/main/java/com/gamsa/history/repository/HistoryRepositoryImpl.java @@ -0,0 +1,38 @@ +package com.gamsa.history.repository; + +import com.gamsa.history.domain.History; +import com.gamsa.history.entity.HistoryJpaEntity; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Slice; +import org.springframework.stereotype.Repository; + +import java.util.Optional; + +@RequiredArgsConstructor +@Repository +public class HistoryRepositoryImpl implements HistoryRepository { + private final HistoryJpaRepository historyJpaRepository; + + @Override + public void save(History history) { + historyJpaRepository.save(HistoryJpaEntity.from(history)); + } + + @Override + public Slice findSliceByAvatarId(long avatarId, Pageable pageable) { + return historyJpaRepository.findSliceByAvatarId(avatarId, pageable) + .map(entity -> entity.toModel()); + } + + @Override + public void delete(History history) { + historyJpaRepository.delete(HistoryJpaEntity.from(history)); + } + + @Override + public Optional findById(long id) { + return historyJpaRepository.findById(id) + .map(entity -> entity.toModel()); + } +} diff --git a/src/main/java/com/gamsa/history/service/HistoryService.java b/src/main/java/com/gamsa/history/service/HistoryService.java new file mode 100644 index 0000000..8bb326c --- /dev/null +++ b/src/main/java/com/gamsa/history/service/HistoryService.java @@ -0,0 +1,56 @@ +package com.gamsa.history.service; + +import com.gamsa.activity.domain.Activity; +import com.gamsa.activity.repository.ActivityRepository; +import com.gamsa.avatar.domain.Avatar; +import com.gamsa.avatar.repository.AvatarRepository; +import com.gamsa.history.domain.History; +import com.gamsa.history.dto.HistoryFindSliceResponse; +import com.gamsa.history.dto.HistorySaveRequest; +import com.gamsa.history.repository.HistoryRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Slice; +import org.springframework.stereotype.Service; + +import java.time.LocalDateTime; +import java.util.NoSuchElementException; + +@RequiredArgsConstructor +@Service +public class HistoryService { + private final HistoryRepository historyRepository; + private final AvatarRepository avatarRepository; + private final ActivityRepository activityRepository; + + public void save(HistorySaveRequest saveRequest) { + Avatar avatar = avatarRepository.findById(saveRequest.getAvatarId()).orElseThrow(NoSuchElementException::new); + Activity activity = activityRepository.findById(saveRequest.getActId()).orElseThrow(NoSuchElementException::new); + History history = saveRequest.toModel(avatar, activity); + historyRepository.save(history); + } + + public Slice findSliceByAvatarId(long avatarId, Pageable pageable) { + Slice histories = historyRepository.findSliceByAvatarId(avatarId, pageable); + histories.forEach(this::checkDate); + return histories.map(HistoryFindSliceResponse::from); + } + + public void delete(long historyId) { + History history = historyRepository.findById(historyId).orElseThrow(NoSuchElementException::new); + historyRepository.delete(history); + } + + public void updateReviewed(long historyId, boolean isReviewed) { + History history = historyRepository.findById(historyId).orElseThrow(NoSuchElementException::new); + history.changeReviewed(isReviewed); + historyRepository.save(history); + } + + public History checkDate(History history) { + LocalDateTime now = LocalDateTime.now(); + history.changeActivityStatusOnDate(now); + historyRepository.save(history); + return history; + } +} diff --git a/src/test/java/com/gamsa/history/entity/HistoryJpaEntityTest.java b/src/test/java/com/gamsa/history/entity/HistoryJpaEntityTest.java new file mode 100644 index 0000000..26f0594 --- /dev/null +++ b/src/test/java/com/gamsa/history/entity/HistoryJpaEntityTest.java @@ -0,0 +1,113 @@ +package com.gamsa.history.entity; + +import com.gamsa.activity.constant.Category; +import com.gamsa.activity.domain.Activity; +import com.gamsa.activity.domain.District; +import com.gamsa.activity.domain.Institute; +import com.gamsa.activity.entity.ActivityJpaEntity; +import com.gamsa.avatar.constant.AgeRange; +import com.gamsa.avatar.constant.Experienced; +import com.gamsa.avatar.domain.Avatar; +import com.gamsa.avatar.entity.AvatarJpaEntity; +import com.gamsa.common.config.TestConfig; +import com.gamsa.history.constant.ActivityStatus; +import com.gamsa.history.domain.History; +import org.junit.jupiter.api.Test; +import org.springframework.context.annotation.Import; + +import java.math.BigDecimal; +import java.time.LocalDateTime; + +import static org.assertj.core.api.Assertions.assertThat; + +@Import(TestConfig.class) +public class HistoryJpaEntityTest { + // given + District district = District.builder() + .sidoCode(1234) + .sidoGunguCode(8888) + .sidoName("서울특별시") + .gunguName("강남구") + .sido(false) + .build(); + + Institute institute = Institute.builder() + .instituteId(1L) + .name("도서관") + .location("서울시") + .latitude(new BigDecimal("123456789.12341234")) + .longitude(new BigDecimal("987654321.43214321")) + .sidoGungu(district) + .phone("010xxxxxxxx") + .build(); + + Activity activity = Activity.builder() + .actId(1L) + .actTitle("어린이놀이안전관리 및 놀잇감 청결유지 및 정리") + .actLocation("아이사랑꿈터 서구 5호점") + .description("봉사 내용") + .noticeStartDate(LocalDateTime.of(2024, 9, 10, 0, 0)) + .noticeEndDate(LocalDateTime.of(2024, 12, 7, 0, 0)) + .actStartDate(LocalDateTime.of(2024, 9, 10, 0, 0)) + .actEndDate(LocalDateTime.of(2024, 12, 7, 0, 0)) + .actStartTime(13) + .actEndTime(18) + .recruitTotalNum(1) + .adultPossible(true) + .teenPossible(false) + .groupPossible(false) + .actWeek(0111110) + .actManager("윤순영") + .actPhone("032-577-3026") + .url("https://...") + .category(Category.OTHER_ACTIVITIES) + .institute(institute) + .sidoGungu(district) + .build(); + + Avatar avatar = Avatar.builder() + .avatarId(1L) + .avatarLevel(1L) + .avatarExp(1L) + .nickname("닉네임") + .ageRange(AgeRange.ADULT) + .experienced(Experienced.NOVICE) + .build(); + + @Test + void 도메인에서_엔티티로() { + // given + History history = History.builder() + .historyId(1L) + .activity(activity) + .avatar(avatar) + .activityStatus(ActivityStatus.APPLIED) + .reviewed(false) + .build(); + + //when + HistoryJpaEntity historyJpaEntity = HistoryJpaEntity.from(history); + + //then + assertThat(historyJpaEntity.getHistoryId()).isEqualTo(history.getHistoryId()); + + } + + @Test + void 엔티티에서_도메인으로() { + //given + HistoryJpaEntity historyJpaEntity = HistoryJpaEntity.builder() + .historyId(1L) + .activity(ActivityJpaEntity.from(activity)) + .avatar(AvatarJpaEntity.from(avatar)) + .activityStatus(ActivityStatus.APPLIED) + .reviewed(false) + .build(); + + //when + History history = historyJpaEntity.toModel(); + + //then + assertThat(history.getHistoryId()).isEqualTo(historyJpaEntity.getHistoryId()); + } +} diff --git a/src/test/java/com/gamsa/history/repository/HistoryJpaRepositoryTest.java b/src/test/java/com/gamsa/history/repository/HistoryJpaRepositoryTest.java new file mode 100644 index 0000000..9e3c050 --- /dev/null +++ b/src/test/java/com/gamsa/history/repository/HistoryJpaRepositoryTest.java @@ -0,0 +1,102 @@ +package com.gamsa.history.repository; + +import com.gamsa.activity.constant.Category; +import com.gamsa.activity.domain.Activity; +import com.gamsa.activity.domain.District; +import com.gamsa.activity.domain.Institute; +import com.gamsa.activity.entity.ActivityJpaEntity; +import com.gamsa.avatar.constant.AgeRange; +import com.gamsa.avatar.constant.Experienced; +import com.gamsa.avatar.domain.Avatar; +import com.gamsa.avatar.entity.AvatarJpaEntity; +import com.gamsa.common.config.TestConfig; +import com.gamsa.history.constant.ActivityStatus; +import com.gamsa.history.entity.HistoryJpaEntity; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.context.annotation.Import; + +import java.math.BigDecimal; +import java.time.LocalDateTime; + +import static org.assertj.core.api.Assertions.assertThat; + +@DataJpaTest +@Import(TestConfig.class) +public class HistoryJpaRepositoryTest { + @Autowired + private HistoryJpaRepository historyJpaRepository; + + District district = District.builder() + .sidoCode(1234) + .sidoGunguCode(8888) + .sidoName("서울특별시") + .gunguName("강남구") + .sido(false) + .build(); + + Institute institute = Institute.builder() + .instituteId(1L) + .name("도서관") + .location("서울시") + .latitude(new BigDecimal("123456789.12341234")) + .longitude(new BigDecimal("987654321.43214321")) + .sidoGungu(district) + .phone("010xxxxxxxx") + .build(); + + Activity activity = Activity.builder() + .actId(1L) + .actTitle("어린이놀이안전관리 및 놀잇감 청결유지 및 정리") + .actLocation("아이사랑꿈터 서구 5호점") + .description("봉사 내용") + .noticeStartDate(LocalDateTime.of(2024, 9, 10, 0, 0)) + .noticeEndDate(LocalDateTime.of(2024, 12, 7, 0, 0)) + .actStartDate(LocalDateTime.of(2024, 9, 10, 0, 0)) + .actEndDate(LocalDateTime.of(2024, 12, 7, 0, 0)) + .actStartTime(13) + .actEndTime(18) + .recruitTotalNum(1) + .adultPossible(true) + .teenPossible(false) + .groupPossible(false) + .actWeek(0111110) + .actManager("윤순영") + .actPhone("032-577-3026") + .url("https://...") + .category(Category.OTHER_ACTIVITIES) + .institute(institute) + .sidoGungu(district) + .build(); + + private final Avatar avatar = Avatar.builder() + .avatarId(1L) + .avatarLevel(1L) + .avatarExp(1L) + .nickname("닉네임") + .ageRange(AgeRange.ADULT) + .experienced(Experienced.NOVICE) + .build(); + + private final HistoryJpaEntity historyJpaEntity = HistoryJpaEntity.builder() + .historyId(1L) + .activity(ActivityJpaEntity.from(activity)) + .avatar(AvatarJpaEntity.from(avatar)) + .activityStatus(ActivityStatus.APPLIED) + .reviewed(false) + .build(); + + + @Test + void 새_기록_저장() { + // when + historyJpaRepository.save(historyJpaEntity); + + //then + assertThat(historyJpaRepository.findById(1L).get().getHistoryId()) + .isEqualTo(historyJpaEntity.getHistoryId()); + } +} + + diff --git a/src/test/java/com/gamsa/history/service/HitstoryServiceTest.java b/src/test/java/com/gamsa/history/service/HitstoryServiceTest.java new file mode 100644 index 0000000..9c63fb3 --- /dev/null +++ b/src/test/java/com/gamsa/history/service/HitstoryServiceTest.java @@ -0,0 +1,57 @@ +package com.gamsa.history.service; + +import com.gamsa.activity.stub.StubExistsActivityRepository; +import com.gamsa.avatar.stub.StubAvatarRepository; +import com.gamsa.history.dto.HistorySaveRequest; +import com.gamsa.history.stub.StubHistoryRepository; +import org.junit.jupiter.api.Test; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + +public class HitstoryServiceTest { + + HistorySaveRequest historySaveRequest = HistorySaveRequest.builder() + .actId(1L) + .avatarId(1L) + .build(); + + @Test + void 새로운_기록_저장() { + //given + HistoryService historyService = new HistoryService(new StubHistoryRepository(), new StubAvatarRepository(), new StubExistsActivityRepository()); + + //when & then + assertDoesNotThrow(() -> historyService.save(historySaveRequest)); + } + + @Test + void 유저_기록_찾기() { + //given + HistoryService historyService = new HistoryService(new StubHistoryRepository(), new StubAvatarRepository(), new StubExistsActivityRepository()); + + //when & then + Pageable pageable = PageRequest.of(0, 10); + assertThat(historyService.findSliceByAvatarId(1L, pageable)).isNotNull(); + } + + @Test + void 기록_삭제() { + //given + HistoryService historyService = new HistoryService(new StubHistoryRepository(), new StubAvatarRepository(), new StubExistsActivityRepository()); + + //when & then + assertDoesNotThrow(() -> historyService.delete(1L)); + } + + @Test + void 리뷰_상태_업데이트() { + //given + HistoryService historyService = new HistoryService(new StubHistoryRepository(), new StubAvatarRepository(), new StubExistsActivityRepository()); + + //when & then + assertDoesNotThrow(() -> historyService.updateReviewed(1L, true)); + } +} diff --git a/src/test/java/com/gamsa/history/stub/StubHistoryRepository.java b/src/test/java/com/gamsa/history/stub/StubHistoryRepository.java new file mode 100644 index 0000000..d98a270 --- /dev/null +++ b/src/test/java/com/gamsa/history/stub/StubHistoryRepository.java @@ -0,0 +1,99 @@ +package com.gamsa.history.stub; + +import com.gamsa.activity.constant.Category; +import com.gamsa.activity.domain.Activity; +import com.gamsa.activity.domain.District; +import com.gamsa.activity.domain.Institute; +import com.gamsa.avatar.constant.AgeRange; +import com.gamsa.avatar.constant.Experienced; +import com.gamsa.avatar.domain.Avatar; +import com.gamsa.history.constant.ActivityStatus; +import com.gamsa.history.domain.History; +import com.gamsa.history.repository.HistoryRepository; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Slice; +import org.springframework.data.domain.SliceImpl; + +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.util.List; +import java.util.Optional; + +public class StubHistoryRepository implements HistoryRepository { + District district = District.builder() + .sidoCode(1234) + .sidoGunguCode(8888) + .sidoName("서울특별시") + .gunguName("강남구") + .sido(false) + .build(); + + Institute institute = Institute.builder() + .instituteId(1L) + .name("도서관") + .location("서울시") + .latitude(new BigDecimal("123456789.12341234")) + .longitude(new BigDecimal("987654321.43214321")) + .sidoGungu(district) + .phone("010xxxxxxxx") + .build(); + + Activity activity = Activity.builder() + .actId(1L) + .actTitle("어린이놀이안전관리 및 놀잇감 청결유지 및 정리") + .actLocation("아이사랑꿈터 서구 5호점") + .description("봉사 내용") + .noticeStartDate(LocalDateTime.of(2024, 9, 10, 0, 0)) + .noticeEndDate(LocalDateTime.of(2024, 12, 7, 0, 0)) + .actStartDate(LocalDateTime.of(2024, 9, 10, 0, 0)) + .actEndDate(LocalDateTime.of(2024, 12, 7, 0, 0)) + .actStartTime(13) + .actEndTime(18) + .recruitTotalNum(1) + .adultPossible(true) + .teenPossible(false) + .groupPossible(false) + .actWeek(0111110) + .actManager("윤순영") + .actPhone("032-577-3026") + .url("https://...") + .category(Category.OTHER_ACTIVITIES) + .institute(institute) + .sidoGungu(district) + .build(); + + Avatar avatar = Avatar.builder() + .avatarId(1L) + .avatarLevel(1L) + .avatarExp(1L) + .nickname("닉네임") + .ageRange(AgeRange.ADULT) + .experienced(Experienced.NOVICE) + .build(); + + private final History history = History.builder() + .historyId(1L) + .activity(activity) + .avatar(avatar) + .activityStatus(ActivityStatus.APPLIED) + .reviewed(false) + .build(); + + @Override + public void save(History history) { + } + + @Override + public void delete(History history) { + } + + @Override + public Optional findById(long id) { + return Optional.of(history); + } + + @Override + public Slice findSliceByAvatarId(long avatarId, Pageable pageable) { + return new SliceImpl<>(List.of(history)); + } +}