Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: 타임라인 커서 기준 memoryPK -> recordAt로 변경 #103

Merged
merged 14 commits into from
Jul 25, 2024
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
29 changes: 29 additions & 0 deletions module-domain/src/main/java/com/depromeet/memory/Timeline.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.depromeet.memory;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@NoArgsConstructor
public class Timeline {
private List<Memory> timelineContents;
private int pageSize;
private LocalDate cursorRecordAt;
private boolean hasNext;

@Builder
public Timeline(
List<Memory> timelineContents,
int pageSize,
LocalDate cursorRecordAt,
boolean hasNext) {
this.timelineContents = timelineContents != null ? timelineContents : new ArrayList<>();
this.pageSize = pageSize != 0 ? pageSize : 10;
this.cursorRecordAt = cursorRecordAt;
this.hasNext = hasNext;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

import lombok.Builder;

public record CustomSliceResponse<T>(T content, int pageNumber, int pageSize, boolean hasNext) {
public record CustomSliceResponse<T>(
T content, int pageSize, String cursorRecordAt, boolean hasNext) {
@Builder
public CustomSliceResponse {}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
package com.depromeet.memory.repository;

import com.depromeet.memory.Memory;
import com.depromeet.memory.Timeline;
import java.time.LocalDate;
import java.util.List;
import java.util.Optional;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;

public interface MemoryRepository {
Memory save(Memory memory);
Expand All @@ -16,11 +15,9 @@ public interface MemoryRepository {

Optional<Memory> update(Long memoryId, Memory memoryUpdate);

Slice<Memory> findPrevMemoryByMemberId(
Long memberId, Long cursorId, Pageable pageable, LocalDate recordAt);
Timeline findPrevMemoryByMemberId(Long memberId, LocalDate cursorRecordAt, LocalDate recordAt);

Slice<Memory> findNextMemoryByMemberId(
Long memberId, Long cursorId, Pageable pageable, LocalDate recordAt);
Timeline findNextMemoryByMemberId(Long memberId, LocalDate cursorRecordAt, LocalDate recordAt);

List<Memory> getCalendarByYearAndMonth(Long memberId, Integer year, Short month);
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import static com.depromeet.pool.entity.QPoolEntity.poolEntity;

import com.depromeet.memory.Memory;
import com.depromeet.memory.Timeline;
import com.depromeet.memory.entity.MemoryEntity;
import com.depromeet.memory.entity.QMemoryEntity;
import com.querydsl.core.types.dsl.BooleanExpression;
Expand All @@ -18,9 +19,9 @@
import java.util.Optional;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.data.domain.SliceImpl;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Repository;

@Slf4j
Expand Down Expand Up @@ -78,59 +79,75 @@ public Optional<Memory> update(Long memoryId, Memory memoryUpdate) {
.map(entity -> entity.update(MemoryEntity.from(memoryUpdate)).toModel());
}

// ---- 날짜 선택 후 위아래 무한 스크롤 구현

@Override
public Slice<Memory> findPrevMemoryByMemberId(
Long memberId, Long cursorId, Pageable pageable, LocalDate recordAt) {
public Timeline findPrevMemoryByMemberId(
Long memberId, LocalDate cursorRecordAt, LocalDate recordAt) {
Pageable pageable = PageRequest.of(0, 10, Sort.Direction.DESC, "recordAt");

List<MemoryEntity> result =
queryFactory
.selectFrom(memory)
.where(
memory.member.id.eq(memberId),
ltCursorId(cursorId),
ltCursorRecordAt(cursorRecordAt),
loeRecordAt(recordAt))
.limit(pageable.getPageSize() + 1)
.orderBy(memory.recordAt.desc())
.fetch();
List<Memory> content = toModel(result);

boolean hasPrev = false;
boolean hasNext = false;
LocalDate nextMemoryRecordAt = null;
if (content.size() > pageable.getPageSize()) {
content = new ArrayList<>(content);
content.removeLast();
hasPrev = true;
hasNext = true;
Memory lastMemory = content.getLast();
nextMemoryRecordAt = lastMemory.getRecordAt();
}

return new SliceImpl<>(content, pageable, hasPrev);
return Timeline.builder()
.timelineContents(content)
.pageSize(10)
.cursorRecordAt(nextMemoryRecordAt)
.hasNext(hasNext)
.build();
}

@Override
public Slice<Memory> findNextMemoryByMemberId(
Long memberId, Long cursorId, Pageable pageable, LocalDate recordAt) {
public Timeline findNextMemoryByMemberId(
Long memberId, LocalDate cursorRecordAt, LocalDate recordAt) {
Pageable pageable = PageRequest.of(0, 10, Sort.Direction.DESC, "recordAt");

List<MemoryEntity> result =
queryFactory
.selectFrom(memory)
.where(
memory.member.id.eq(memberId),
gtCursorId(cursorId),
gtCursorRecordAt(cursorRecordAt),
goeRecordAt(recordAt))
.limit(pageable.getPageSize() + 1)
.orderBy(memory.recordAt.asc())
.fetch();

List<Memory> content = toModel(result);

boolean hasNext = false;
LocalDate nextMemoryRecordAt = null;
if (content.size() > pageable.getPageSize()) {
content = new ArrayList<>(content);
content.removeLast();
hasNext = true;
Memory lastMemory = content.getLast();
nextMemoryRecordAt = lastMemory.getRecordAt();
}
content = content.reversed();

return new SliceImpl<>(content, pageable, hasNext);
return Timeline.builder()
.timelineContents(content)
.pageSize(10)
.cursorRecordAt(nextMemoryRecordAt)
.hasNext(hasNext)
.build();
}

@Override
Expand Down Expand Up @@ -161,18 +178,18 @@ private BooleanExpression loeRecordAt(LocalDate recordAt) {
return memory.recordAt.loe(recordAt);
}

private BooleanExpression ltCursorId(Long cursorId) {
if (cursorId == null) {
private BooleanExpression ltCursorRecordAt(LocalDate cursorRecordAt) {
if (cursorRecordAt == null) {
return null;
}
return memory.id.lt(cursorId);
return memory.recordAt.lt(cursorRecordAt);
}

private BooleanExpression gtCursorId(Long cursorId) {
if (cursorId == null) {
private BooleanExpression gtCursorRecordAt(LocalDate cursorRecordAt) {
if (cursorRecordAt == null) {
return null;
}
return memory.id.gt(cursorId);
return memory.recordAt.gt(cursorRecordAt);
}

private BooleanExpression goeRecordAt(LocalDate recordAt) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import com.depromeet.member.repository.MemberRepositoryImpl;
import com.depromeet.memory.Memory;
import com.depromeet.memory.MemoryDetail;
import com.depromeet.memory.Timeline;
import com.querydsl.jpa.impl.JPAQueryFactory;
import java.time.LocalDate;
import java.util.List;
Expand All @@ -20,18 +21,12 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.context.annotation.Import;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.data.domain.Sort;
import org.springframework.test.context.junit.jupiter.SpringExtension;

@DataJpaTest
@Import(TestQueryDslConfig.class)
@ExtendWith(SpringExtension.class)
public class MemoryRepositoryTest {
private Pageable pageable;

@Autowired private JPAQueryFactory queryFactory;
@Autowired private MemoryJpaRepository memoryJpaRepository;
private MemoryRepositoryImpl memoryRepositoryImpl;
Expand All @@ -45,8 +40,6 @@ public class MemoryRepositoryTest {

@BeforeEach
void setUp() {
pageable = getPageable();

memberRepositoryImpl = new MemberRepositoryImpl(memberJpaRepository);
memoryRepositoryImpl = new MemoryRepositoryImpl(queryFactory, memoryJpaRepository);
memoryDetailRepositoryImpl = new MemoryDetailRepositoryImpl(memoryDetailJpaRepository);
Expand All @@ -62,21 +55,17 @@ void setUp() {
}
}

private Pageable getPageable() {
return PageRequest.of(0, 30, Sort.by(Sort.Order.desc("recordAt")));
}

@Test
void findPrevMemoryByMemberId로_최근_날짜_이전_30일_recordAt_Desc로_가져오는지_테스트() {
// when
Slice<Memory> resultSlice =
memoryRepositoryImpl.findPrevMemoryByMemberId(member.getId(), null, pageable, null);
List<Memory> result = resultSlice.getContent();
Timeline timelines =
memoryRepositoryImpl.findPrevMemoryByMemberId(member.getId(), null, null);
List<Memory> result = timelines.getTimelineContents();
Memory lastMemory = result.getLast();

// then
assertThat(result.size()).isEqualTo(30);
assertThat(lastMemory.getRecordAt()).isEqualTo(startRecordAt.minusDays(30));
assertThat(result.size()).isEqualTo(10);
assertThat(lastMemory.getRecordAt()).isEqualTo(startRecordAt.minusDays(10));
}

@Test
Expand All @@ -85,60 +74,57 @@ private Pageable getPageable() {
LocalDate recordAt = LocalDate.of(2024, 8, 31);

// when
Slice<Memory> resultSlice =
memoryRepositoryImpl.findPrevMemoryByMemberId(
member.getId(), null, pageable, recordAt);
List<Memory> result = resultSlice.getContent();
Timeline timelines =
memoryRepositoryImpl.findPrevMemoryByMemberId(member.getId(), null, recordAt);
List<Memory> result = timelines.getTimelineContents();
Memory lastMemory = result.getLast();

// then
assertThat(result.size()).isEqualTo(30);
assertThat(lastMemory.getRecordAt()).isEqualTo(recordAt.minusDays(29));
assertThat(result.size()).isEqualTo(10);
assertThat(lastMemory.getRecordAt()).isEqualTo(recordAt.minusDays(9));
}

@Test
void 최초_조회_이후_findPrevMemoryByMemberId로_다음_데이터를_가져오는지_테스트() {
// given
LocalDate recordAt = LocalDate.of(2024, 8, 31);

Slice<Memory> initResultSlice =
memoryRepositoryImpl.findPrevMemoryByMemberId(
member.getId(), null, pageable, recordAt);
Timeline initTimelines =
memoryRepositoryImpl.findPrevMemoryByMemberId(member.getId(), null, recordAt);

List<Memory> initResultSliceList = initResultSlice.getContent();
Memory lastDate = initResultSliceList.getLast();
List<Memory> timelineContents = initTimelines.getTimelineContents();
Memory lastDate = timelineContents.getLast();

// when
Slice<Memory> resultSlice =
Timeline timelines =
memoryRepositoryImpl.findPrevMemoryByMemberId(
member.getId(), lastDate.getId(), pageable, null);
List<Memory> result = resultSlice.getContent();
member.getId(), lastDate.getRecordAt(), null);
List<Memory> result = timelines.getTimelineContents();

// then
assertThat(result.size()).isEqualTo(30);
assertThat(result.getLast().getRecordAt()).isEqualTo(lastDate.getRecordAt().minusDays(30));
assertThat(result.size()).isEqualTo(10);
assertThat(result.getLast().getRecordAt()).isEqualTo(lastDate.getRecordAt().minusDays(10));
}

@Test
void 최초_조회_이후_findPrevMemoryByMemberId로_다음_데이터를_가져오는지_확인() {
// given
LocalDate recordAt = LocalDate.of(2024, 8, 31);

Slice<Memory> initResultSlice =
memoryRepositoryImpl.findPrevMemoryByMemberId(
member.getId(), null, pageable, recordAt);
Timeline initTimeline =
memoryRepositoryImpl.findPrevMemoryByMemberId(member.getId(), null, recordAt);

List<Memory> initResultSliceList = initResultSlice.getContent();
Memory firstDate = initResultSliceList.getFirst();
List<Memory> initTimelineContents = initTimeline.getTimelineContents();
Memory firstDate = initTimelineContents.getFirst();

// when
Slice<Memory> resultSlice =
Timeline resultSlice =
memoryRepositoryImpl.findNextMemoryByMemberId(
member.getId(), firstDate.getId(), pageable, null);
List<Memory> result = resultSlice.getContent();
member.getId(), firstDate.getRecordAt(), null);
List<Memory> result = resultSlice.getTimelineContents();

// then
assertThat(result.size()).isEqualTo(30);
assertThat(result.getFirst().getRecordAt()).isEqualTo(firstDate.getRecordAt().plusDays(30));
assertThat(result.size()).isEqualTo(10);
assertThat(result.getFirst().getRecordAt()).isEqualTo(firstDate.getRecordAt().plusDays(10));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,4 @@ spring:
jpa:
generate-ddl: true
hibernate:
ddl-auto: create
properties:
hibernate:
show_sql: true
format_sql: true
use_sql_comments: true
ddl-auto: create
3 changes: 0 additions & 3 deletions module-presentation/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,6 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'
implementation 'org.springframework.boot:spring-boot-starter-validation'

//for test
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
testImplementation 'org.springframework.security:spring-security-test'

// swagger
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package com.depromeet.auth.dto.request;

public record AccessTokenDto(String accessToken) {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.depromeet.auth.dto.response;

import lombok.Builder;

public record RefreshTokenDto(String refreshToken) {
@Builder
public RefreshTokenDto {}
}
Loading
Loading