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

✨ [Feature] 개인일정 삭제 api #1058 #1094

Open
wants to merge 4 commits into
base: dev
Choose a base branch
from
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
Expand Down Expand Up @@ -42,4 +43,11 @@ public ResponseEntity<PrivateScheduleUpdateResDto> privateScheduleUpdate(
privateScheduleUpdateReqDto, id);
return ResponseEntity.status(HttpStatus.OK).body(privateScheduleUpdateResDto);
}

@PatchMapping("/{id}")
public ResponseEntity<Void> privateScheduleDelete(@Login @Parameter(hidden = true) UserDto userDto,
@PathVariable Long id) {
privateScheduleService.deletePrivateSchedule(userDto, id);
return ResponseEntity.status(HttpStatus.NO_CONTENT).build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public class PrivateScheduleUpdateReqDto {
private Long groupId;

@Builder
public PrivateScheduleUpdateReqDto(EventTag eventTag, JobTag jobTag, TechTag techTag, String title, String content,
private PrivateScheduleUpdateReqDto(EventTag eventTag, JobTag jobTag, TechTag techTag, String title, String content,
String link, ScheduleStatus status, LocalDateTime startTime, LocalDateTime endTime, boolean alarm,
Long groupId) {
this.eventTag = eventTag;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,14 @@
import gg.data.calendar.PrivateSchedule;
import gg.data.calendar.PublicSchedule;
import gg.data.calendar.ScheduleGroup;
import gg.data.calendar.type.ScheduleStatus;
import gg.data.user.User;
import gg.repo.calendar.PrivateScheduleRepository;
import gg.repo.calendar.PublicScheduleRepository;
import gg.repo.calendar.ScheduleGroupRepository;
import gg.repo.user.UserRepository;
import gg.utils.exception.ErrorCode;
import gg.utils.exception.custom.DuplicationException;
import gg.utils.exception.custom.ForbiddenException;
import gg.utils.exception.custom.InvalidParameterException;
import gg.utils.exception.custom.NotExistException;
Expand Down Expand Up @@ -65,6 +67,21 @@ public PrivateScheduleUpdateResDto updatePrivateSchedule(UserDto userDto,
return PrivateScheduleUpdateResDto.toDto(privateSchedule);
}

@Transactional
public void deletePrivateSchedule(UserDto userDto, Long privateScheduleId) {
PrivateSchedule privateSchedule = privateScheduleRepository.findById(privateScheduleId)
.orElseThrow(() -> new NotExistException(ErrorCode.PRIVATE_SCHEDULE_NOT_FOUND));
validateDeletion(privateSchedule.getStatus());
validateAuthor(userDto.getIntraId(), privateSchedule.getPublicSchedule().getAuthor());
privateSchedule.delete();
}

public void validateDeletion(ScheduleStatus status) {
if (status == ScheduleStatus.DELETE) {
throw new DuplicationException(ErrorCode.CALENDAR_ALREADY_DELETE);
}
}

public void validateTimeRange(LocalDateTime startTime, LocalDateTime endTime) {
if (endTime.isBefore(startTime)) {
throw new InvalidParameterException(ErrorCode.CALENDAR_BEFORE_DATE);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,9 @@ public ScheduleGroup createScheduleGroup(User user) {
return scheduleGroupRepository.save(scheduleGroup);
}

public PrivateSchedule createPrivateSchedule(PublicSchedule publicSchedule, ScheduleGroup scheduleGroup) {
PrivateSchedule privateSchedule = new PrivateSchedule(scheduleGroup.getUser(), publicSchedule, false,
scheduleGroup.getId());
public PrivateSchedule createPrivateSchedule(User user, PublicSchedule publicSchedule, Long scheduleGroupId) {
PrivateSchedule privateSchedule = new PrivateSchedule(user, publicSchedule, false,
scheduleGroupId);
return privateScheduleRepository.save(privateSchedule);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
@Slf4j
@IntegrationTest
@AutoConfigureMockMvc
@Transactional
public class PrivateScheduleControllerTest {
@Autowired
private MockMvc mockMvc;
Expand Down Expand Up @@ -66,8 +67,7 @@ void setUp() {
@DisplayName("PrivateSchedule 생성하기")
class CreatePrivateSchedule {
@Test
@Transactional
@DisplayName("성공")
@DisplayName("성공 201")
void success() throws Exception {
//given
ScheduleGroup scheduleGroup = privateScheduleMockData.createScheduleGroup(user);
Expand Down Expand Up @@ -100,7 +100,6 @@ void success() throws Exception {
}

@Test
@Transactional
@DisplayName("일정 그룹이 없는 경우 404")
void noGroup() throws Exception {
//given
Expand All @@ -126,7 +125,6 @@ void noGroup() throws Exception {
}

@Test
@Transactional
@DisplayName("시작 날짜보다 끝나는 날짜가 빠른 경우 400")
void endTimeBeforeStartTime() throws Exception {
//given
Expand Down Expand Up @@ -156,14 +154,13 @@ void endTimeBeforeStartTime() throws Exception {
@DisplayName("PrivateSchedule 수정하기")
class UpdatePrivateSchedule {
@Test
@Transactional
@DisplayName("성공")
@DisplayName("성공 200")
void success() throws Exception {
//given
ScheduleGroup scheduleGroup = privateScheduleMockData.createScheduleGroup(user);
PublicSchedule publicSchedule = privateScheduleMockData.createPublicSchedule(user.getIntraId());
PrivateSchedule privateSchedule = privateScheduleMockData.createPrivateSchedule(publicSchedule,
scheduleGroup);
PrivateSchedule privateSchedule = privateScheduleMockData.createPrivateSchedule(user, publicSchedule,
scheduleGroup.getId());
PrivateScheduleUpdateReqDto reqDto = PrivateScheduleUpdateReqDto.builder()
.eventTag(null)
.techTag(null)
Expand All @@ -185,21 +182,18 @@ void success() throws Exception {
.andExpect(status().isOk());
//then
PrivateSchedule updated = privateScheduleRepository.findById(privateSchedule.getId()).orElseThrow();
Assertions.assertThat(privateSchedule.getGroupId()).isEqualTo(updated.getGroupId());
Assertions.assertThat(privateSchedule.isAlarm()).isEqualTo(updated.isAlarm());
Assertions.assertThat(privateSchedule.getGroupId()).isEqualTo(updated.getGroupId());
Assertions.assertThat(privateSchedule.getPublicSchedule()).isEqualTo(updated.getPublicSchedule());
Assertions.assertThat(reqDto.getGroupId()).isEqualTo(updated.getGroupId());
Assertions.assertThat(reqDto.isAlarm()).isEqualTo(updated.isAlarm());
}

@Test
@Transactional
@DisplayName("종료 날짜가 시작 날짜보다 빠른 경우 400")
void endTimeBeforeStartTime() throws Exception {
//given
ScheduleGroup scheduleGroup = privateScheduleMockData.createScheduleGroup(user);
PublicSchedule publicSchedule = privateScheduleMockData.createPublicSchedule(user.getIntraId());
PrivateSchedule privateSchedule = privateScheduleMockData.createPrivateSchedule(publicSchedule,
scheduleGroup);
PrivateSchedule privateSchedule = privateScheduleMockData.createPrivateSchedule(user, publicSchedule,
scheduleGroup.getId());
PrivateScheduleUpdateReqDto reqDto = PrivateScheduleUpdateReqDto.builder()
.eventTag(null)
.techTag(null)
Expand All @@ -222,14 +216,13 @@ void endTimeBeforeStartTime() throws Exception {
}

@Test
@Transactional
@DisplayName("작성자가 아닌 사람이 일정을 수정 하려는 경우 403")
void notMatchAuthor() throws Exception {
//given
ScheduleGroup scheduleGroup = privateScheduleMockData.createScheduleGroup(user);
PublicSchedule publicSchedule = privateScheduleMockData.createPublicSchedule("notMatchAuthor");
PrivateSchedule privateSchedule = privateScheduleMockData.createPrivateSchedule(publicSchedule,
scheduleGroup);
PrivateSchedule privateSchedule = privateScheduleMockData.createPrivateSchedule(user, publicSchedule,
scheduleGroup.getId());
PrivateScheduleUpdateReqDto reqDto = PrivateScheduleUpdateReqDto.builder()
.eventTag(null)
.techTag(null)
Expand All @@ -243,7 +236,7 @@ void notMatchAuthor() throws Exception {
.endTime(LocalDateTime.now().plusDays(1))
.groupId(scheduleGroup.getId())
.build();
//when
//when&then
mockMvc.perform(put("/calendar/private/" + privateSchedule.getId())
.header("Authorization", "Bearer " + accessToken)
.contentType(MediaType.APPLICATION_JSON)
Expand All @@ -252,14 +245,13 @@ void notMatchAuthor() throws Exception {
}

@Test
@Transactional
@DisplayName("일정이 없는 경우 404")
void noSchedule() throws Exception {
//given
ScheduleGroup scheduleGroup = privateScheduleMockData.createScheduleGroup(user);
PublicSchedule publicSchedule = privateScheduleMockData.createPublicSchedule("notMatchAuthor");
PrivateSchedule privateSchedule = privateScheduleMockData.createPrivateSchedule(publicSchedule,
scheduleGroup);
PublicSchedule publicSchedule = privateScheduleMockData.createPublicSchedule(user.getIntraId());
PrivateSchedule privateSchedule = privateScheduleMockData.createPrivateSchedule(user, publicSchedule,
scheduleGroup.getId());
PrivateScheduleUpdateReqDto reqDto = PrivateScheduleUpdateReqDto.builder()
.eventTag(null)
.techTag(null)
Expand All @@ -273,12 +265,112 @@ void noSchedule() throws Exception {
.endTime(LocalDateTime.now().plusDays(1))
.groupId(scheduleGroup.getId())
.build();
//when
//when&then
mockMvc.perform(put("/calendar/private/" + privateSchedule.getId() + 123411243)
.header("Authorization", "Bearer " + accessToken)
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(reqDto)))
.andExpect(status().isNotFound());
}

@Test
@DisplayName("일정 그룹이 없는 경우 404")
void noScheduleGroup() throws Exception {
//given
ScheduleGroup scheduleGroup = privateScheduleMockData.createScheduleGroup(user);
PublicSchedule publicSchedule = privateScheduleMockData.createPublicSchedule(user.getIntraId());
PrivateSchedule privateSchedule = privateScheduleMockData.createPrivateSchedule(user, publicSchedule,
scheduleGroup.getId());
PrivateScheduleUpdateReqDto reqDto = PrivateScheduleUpdateReqDto.builder()
.eventTag(null)
.techTag(null)
.jobTag(null)
.alarm(false)
.title("123")
.content("")
.link(null)
.status(ScheduleStatus.ACTIVATE)
.startTime(LocalDateTime.now())
.endTime(LocalDateTime.now().plusDays(1))
.groupId(0L)
.build();
//when&then
mockMvc.perform(put("/calendar/private/" + privateSchedule.getId())
.header("Authorization", "Bearer " + accessToken)
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(reqDto)))
.andExpect(status().isNotFound());
}
}

@Nested
@DisplayName("PrivateSchedule 삭제하기")
class DeletePrivateSchedule {
@Test
@DisplayName("성공 204")
void success() throws Exception {
//given
ScheduleGroup scheduleGroup = privateScheduleMockData.createScheduleGroup(user);
PublicSchedule publicSchedule = privateScheduleMockData.createPublicSchedule(user.getIntraId());
PrivateSchedule privateSchedule = privateScheduleMockData.createPrivateSchedule(user, publicSchedule,
scheduleGroup.getId());
//when
mockMvc.perform(patch("/calendar/private/" + privateSchedule.getId())
.header("Authorization", "Bearer " + accessToken)
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isNoContent());
//then
Assertions.assertThat(privateSchedule.getStatus()).isEqualTo(ScheduleStatus.DELETE);
}

@Test
@DisplayName("작성자가 아닌 사람이 삭제하는 경우 403")
void notMatchAuthor() throws Exception {
//given
ScheduleGroup scheduleGroup = privateScheduleMockData.createScheduleGroup(user);
PublicSchedule publicSchedule = privateScheduleMockData.createPublicSchedule("author");
PrivateSchedule privateSchedule = privateScheduleMockData.createPrivateSchedule(user, publicSchedule,
scheduleGroup.getId());
//when
mockMvc.perform(patch("/calendar/private/" + privateSchedule.getId())
.header("Authorization", "Bearer " + accessToken)
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isForbidden());
//then
Assertions.assertThat(privateSchedule.getStatus()).isEqualTo(ScheduleStatus.ACTIVATE);
}

@Test
@DisplayName("없는 일정인 경우 404")
void notSchedule() throws Exception {
//given
ScheduleGroup scheduleGroup = privateScheduleMockData.createScheduleGroup(user);
PublicSchedule publicSchedule = privateScheduleMockData.createPublicSchedule(user.getIntraId());
PrivateSchedule privateSchedule = privateScheduleMockData.createPrivateSchedule(user, publicSchedule,
scheduleGroup.getId());
//when
mockMvc.perform(patch("/calendar/private/" + privateSchedule.getId() + 1234)
.header("Authorization", "Bearer " + accessToken)
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isNotFound());
//then
Assertions.assertThat(privateSchedule.getStatus()).isEqualTo(ScheduleStatus.ACTIVATE);
}

@Test
@DisplayName("이미 삭제된 일정인 경우 409")
void alreadyDelete() throws Exception {
//given
ScheduleGroup scheduleGroup = privateScheduleMockData.createScheduleGroup(user);
PublicSchedule publicSchedule = privateScheduleMockData.createPublicSchedule(user.getIntraId());
PrivateSchedule privateSchedule = privateScheduleMockData.createPrivateSchedule(user, publicSchedule,
scheduleGroup.getId());
privateSchedule.delete();
//when&then
mockMvc.perform(patch("/calendar/private/" + privateSchedule.getId())
.header("Authorization", "Bearer " + accessToken)
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isConflict());
}
}
}
8 changes: 8 additions & 0 deletions gg-data/src/main/java/gg/data/calendar/PrivateSchedule.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import javax.persistence.ManyToOne;

import gg.data.BaseTimeEntity;
import gg.data.calendar.type.DetailClassification;
import gg.data.calendar.type.EventTag;
import gg.data.calendar.type.JobTag;
import gg.data.calendar.type.ScheduleStatus;
Expand Down Expand Up @@ -65,4 +66,11 @@
this.publicSchedule.update(publicSchedule.getClassification(), eventTag, jobTag, techTag, title, content, link,
startTime, endTime, status);
}

public void delete() {
this.status = ScheduleStatus.DELETE;
if (this.publicSchedule.getClassification() == DetailClassification.PRIVATE_SCHEDULE) {
publicSchedule.delete();

Check warning on line 73 in gg-data/src/main/java/gg/data/calendar/PrivateSchedule.java

View check run for this annotation

Codecov / codecov/patch

gg-data/src/main/java/gg/data/calendar/PrivateSchedule.java#L73

Added line #L73 was not covered by tests
}
}
}
Loading