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

Feat#45: 할 일 달성여부 변경 기능 구현 #46

Merged
merged 4 commits into from
Oct 17, 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
7 changes: 7 additions & 0 deletions src/main/java/server/poptato/todo/api/TodoController.java
Original file line number Diff line number Diff line change
Expand Up @@ -109,4 +109,11 @@ public BaseResponse updateContent(@UserId Long userId,
todoService.updateContent(userId, todoId, requestDto.getContent());
return new BaseResponse<>();
}

@PatchMapping("/todo/{todoId}/achieve")
public BaseResponse updateIsCompleted(@UserId Long userId,
@PathVariable Long todoId){
todoService.updateIsCompleted(userId, todoId);
return new BaseResponse<>();
}
}
28 changes: 25 additions & 3 deletions src/main/java/server/poptato/todo/application/TodoService.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@

import static server.poptato.todo.exception.errorcode.TodoExceptionErrorCode.TODO_NOT_EXIST;

@Transactional
@RequiredArgsConstructor
@Service
public class TodoService {
Expand Down Expand Up @@ -81,13 +82,12 @@ public BacklogListResponseDto getBacklogList(Long userId, int page, int size) {
.build();
}

@Transactional
public void deleteTodoById(Long todoId) {
Todo todo = todoRepository.findById(todoId)
.orElseThrow(() -> new TodoException(TODO_NOT_EXIST));
todoRepository.delete(todo);
}
@Transactional

public void toggleIsBookmark(Long todoId) {
// 해당 Todo를 조회
Todo todo = todoRepository.findById(todoId)
Expand Down Expand Up @@ -115,7 +115,6 @@ public PaginatedHistoryResponseDto getHistories(Long userId, int page, int size)
return new PaginatedHistoryResponseDto(histories, todosPage.getTotalPages());
}

@Transactional
public void swipe(Long userId, Long todoId) {
checkIsExistUser(userId);
Todo todo = todoRepository.findById(todoId)
Expand Down Expand Up @@ -220,6 +219,7 @@ private void checkIsExistUser(Long userId) {
-> new UserException(UserExceptionErrorCode.USER_NOT_EXIST));
}


public Long generateBacklog(Long userId, String content) {
checkIsExistUser(userId);
Integer maxBacklogOrder = todoRepository.findMaxBacklogOrderByUserIdOrZero(userId);
Expand Down Expand Up @@ -263,4 +263,26 @@ public void updateContent(Long userId, Long todoId, String content) {
//TODO: 여기도 왜 SAVE가 필수인지 몰겟담
todoRepository.save(findTodo);
}

public void updateIsCompleted(Long userId, Long todoId) {
checkIsExistUser(userId);
Todo findTodo = todoRepository.findById(todoId)
.orElseThrow(() -> new TodoException(TODO_NOT_EXIST));
checkIsValidToUpdateIsCompleted(userId,findTodo);

if(findTodo.getTodayStatus().equals(TodayStatus.COMPLETED)){
findTodo.updateTodayStatusToInComplete();
}else {
findTodo.updateTodayStatusToCompleted();
}
}

private void checkIsValidToUpdateIsCompleted(Long userId, Todo todo) {
if(todo.getUserId()!=userId)
throw new TodoException(TodoExceptionErrorCode.TODO_USER_NOT_MATCH);
if(todo.getType().equals(Type.BACKLOG))
throw new TodoException(TodoExceptionErrorCode.BACKLOG_CANT_COMPLETE);
if(todo.getType().equals(Type.YESTERDAY) && todo.getTodayStatus().equals(TodayStatus.COMPLETED))
throw new TodoException(TodoExceptionErrorCode.YESTERDAY_CANT_COMPLETE);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,25 @@
import lombok.Getter;
import server.poptato.todo.domain.entity.Todo;

import java.time.LocalDate;
import java.time.temporal.ChronoUnit;

@Getter
public class BacklogResponseDto {
Long todoId;
String content;
boolean isBookmark;
Integer deadline;
Integer dDay;
LocalDate deadline;

public BacklogResponseDto(Todo todo) {
this.todoId = todo.getId();
this.content = todo.getContent();
this.isBookmark = todo.isBookmark();
this.deadline = todo.getDeadline();

if (todo.getDeadline() != null && todo.getTodayDate() != null) {
this.deadline = (int) ChronoUnit.DAYS.between(todo.getTodayDate(), todo.getDeadline());
this.dDay = (int) ChronoUnit.DAYS.between(todo.getTodayDate(), todo.getDeadline());
} else {
// 마감 기한을 계산할 수 없는 경우 NULL
this.deadline = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import server.poptato.todo.domain.entity.Todo;
import server.poptato.todo.domain.value.TodayStatus;

import java.time.LocalDate;
import java.time.temporal.ChronoUnit;

@Getter
Expand All @@ -12,19 +13,21 @@ public class TodayResponseDto {
String content;
TodayStatus todayStatus;
boolean isBookmark;
Integer deadline;
Integer dDay;
LocalDate deadline;

public TodayResponseDto(Todo todo) {
this.todoId = todo.getId();
this.content = todo.getContent();
this.todayStatus = todo.getTodayStatus();
this.isBookmark = todo.isBookmark();
this.deadline = todo.getDeadline();

if (todo.getDeadline() != null && todo.getTodayDate() != null) {
this.deadline = (int) ChronoUnit.DAYS.between(todo.getTodayDate(), todo.getDeadline());
this.dDay = (int) ChronoUnit.DAYS.between(todo.getTodayDate(), todo.getDeadline());
} else {
// 마감 기한을 계산할 수 없는 경우 NULL
this.deadline = null;
this.dDay = null;
}
}
}
11 changes: 11 additions & 0 deletions src/main/java/server/poptato/todo/domain/entity/Todo.java
Original file line number Diff line number Diff line change
Expand Up @@ -96,4 +96,15 @@ public void updateDeadline(LocalDate deadline) {
public void updateContent(String content) {
this.content = content;
}

public void updateTodayStatusToInComplete() {
this.todayStatus = TodayStatus.INCOMPLETE;
this.completedDateTime = null;
}

public void updateTodayStatusToCompleted() {
this.todayStatus = TodayStatus.COMPLETED;
this.completedDateTime = LocalDateTime.now();
this.todayOrder = null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ public enum TodoExceptionErrorCode implements ResponseStatus {
TODO_NOT_EXIST(5001, HttpStatus.BAD_REQUEST.value(), "투두가 존재하지 않습니다"),
TODO_USER_NOT_MATCH(5002, HttpStatus.BAD_REQUEST.value(), "사용자의 할 일이 아닙니다."),
ALREADY_COMPLETED_TODO(5003, HttpStatus.BAD_REQUEST.value(), "달성된 할 일은 스와이프할 수 없습니다."),
TODO_TYPE_NOT_MATCH(5004, HttpStatus.BAD_REQUEST.value(), "드래그앤드롭 시 할 일 리스트와 할 일 타입이 맞지 않습니다." );
TODO_TYPE_NOT_MATCH(5004, HttpStatus.BAD_REQUEST.value(), "드래그앤드롭 시 할 일 리스트와 할 일 타입이 맞지 않습니다." ),
BACKLOG_CANT_COMPLETE(5005,HttpStatus.BAD_REQUEST.value(), "백로그 할 일은 달성할 수 없습니다."),
YESTERDAY_CANT_COMPLETE(5006, HttpStatus.BAD_REQUEST.value(), "이미 달성한 어제 한 일은 취소할 수 없습니다.");


private final int code;
Expand Down
14 changes: 14 additions & 0 deletions src/test/java/server/poptato/todo/api/TodoControllerTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -363,4 +363,18 @@ public void shouldReturnOk_WhenIsBookmarkToggled() throws Exception {
.andExpect(status().isOk())
.andDo(print());
}

@DisplayName("투데이 달성여부 변경 요청 시 성공한다.")
@Test
void 투데이_달성여부_변경_요청_성공_응답() throws Exception {
//given
Long todoId = 1L;

//when
mockMvc.perform(patch("/todo/{todoId}/achieve", todoId)
.header("Authorization", "Bearer " + accessToken)
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andDo(print());
}
}
46 changes: 46 additions & 0 deletions src/test/java/server/poptato/todo/application/TodoServiceTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import java.time.LocalDate;
import java.util.List;
import java.util.Optional;
import java.util.Stack;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
Expand Down Expand Up @@ -411,4 +412,49 @@ void getYesterdays_ShouldReturnPagedResult() {
//then
assertThat(findTodo.getContent()).isEqualTo(updateContent);
}

@DisplayName("투데이 달성여부 변경 시 성공한다.")
@Test
void 투데이_달성여부_변경_성공(){
//given
Long userId = 1L;
Long todoId = 1L;

//when
todoService.updateIsCompleted(userId,todoId);
Todo findTodo = todoRepository.findById(todoId).get();

//then
assertThat(findTodo.getTodayStatus()).isEqualTo(TodayStatus.COMPLETED);
assertThat(findTodo.getCompletedDateTime()).isNotNull();
}

@DisplayName("어제한일 달성여부 변경 시 성공한다.")
@Test
void 어제한일_달성여부_변경_성공(){
//given
Long userId = 1L;
Long todoId = 35L;

//when
todoService.updateIsCompleted(userId,todoId);
Todo findTodo = todoRepository.findById(todoId).get();

//then
assertThat(findTodo.getTodayStatus()).isEqualTo(TodayStatus.COMPLETED);
assertThat(findTodo.getCompletedDateTime()).isNotNull();
}

@DisplayName("백로그 달성여부 변경 시 예외가 발생한다.")
@Test
void 백로그_달성여부_변경_예외(){
//given
Long userId = 1L;
Long todoId = 20L;

//when & then
assertThatThrownBy(()-> todoService.updateIsCompleted(userId,todoId))
.isInstanceOf(TodoException.class)
.hasMessage(TodoExceptionErrorCode.BACKLOG_CANT_COMPLETE.getMessage());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class TodayResponseDtoTest {
void 마감기한이_정상적으로_계산된다() {
//given
Todo todo = Todo.builder()
.id(1L)
.id(1000L)
.content("Test Todo")
.todayStatus(TodayStatus.COMPLETED)
.isBookmark(false)
Expand All @@ -27,7 +27,7 @@ class TodayResponseDtoTest {
TodayResponseDto responseDto = new TodayResponseDto(todo);

//then
assertThat(responseDto.getDeadline()).isEqualTo(4);
assertThat(responseDto.getDDay()).isEqualTo(4);
}

@DisplayName("마감이 설정안되어있는 경우 NULL로 정상 응답된다.")
Expand Down