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
Original file line number Diff line number Diff line change
Expand Up @@ -125,10 +125,6 @@ public void removeMember(TeamRecruitmentChatMember member) {
}
}

public void markReadOnly() {
this.status = TeamRecruitmentChatRoomStatus.READ_ONLY;
}

@Transient
public boolean isActive() {
return status == TeamRecruitmentChatRoomStatus.ACTIVE;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import static in.koreatech.koin.domain.team.recruitment.enums.TeamRecruitmentApplicationStatus.ACCEPTED;
import static in.koreatech.koin.domain.team.recruitment.enums.TeamRecruitmentApplicationStatus.PENDING;
import static in.koreatech.koin.domain.team.recruitment.enums.TeamRecruitmentChatRoomStatus.ACTIVE;
import static in.koreatech.koin.domain.team.recruitment.enums.TeamRecruitmentChatRoomType.TEAM;
import static in.koreatech.koin.domain.team.recruitment.enums.TeamRecruitmentNotificationTargetType.CHAT_ROOM;
import static in.koreatech.koin.domain.team.recruitment.enums.TeamRecruitmentNotificationTargetType.MY_APPLICATIONS;
Expand Down Expand Up @@ -69,7 +68,6 @@ public void closeIfExpired(Integer recruitmentId, LocalDate today) {
recruitment.close();
recruitmentRepository.save(recruitment);
rejectPendingApplications(recruitment, pendingApplications);
markRoomsReadOnly(recruitmentId);
notifyRejectedApplications(recruitment, pendingApplications);
notifyAcceptedMembers(recruitment, teamRoom, acceptedApplications);
}
Expand Down Expand Up @@ -105,19 +103,6 @@ private void rejectPendingApplications(
}
}

private void markRoomsReadOnly(Integer recruitmentId) {
List<TeamRecruitmentChatRoom> chatRooms = chatRoomRepository.findAllByRecruitment_Id(recruitmentId);
if (chatRooms == null) {
return;
}
for (TeamRecruitmentChatRoom chatRoom : chatRooms) {
if (chatRoom.getStatus() == ACTIVE) {
chatRoom.markReadOnly();
chatRoomRepository.save(chatRoom);
}
}
}

private void notifyRejectedApplications(
TeamRecruitment recruitment,
List<TeamRecruitmentApplication> pendingApplications
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import static in.koreatech.koin.domain.team.recruitment.enums.TeamRecruitmentApplicationStatus.ACCEPTED;
import static in.koreatech.koin.domain.team.recruitment.enums.TeamRecruitmentApplicationStatus.PENDING;
import static in.koreatech.koin.domain.team.recruitment.enums.TeamRecruitmentChatRoomStatus.ACTIVE;
import static in.koreatech.koin.domain.team.recruitment.enums.TeamRecruitmentNotificationTargetType.CHAT_ROOM;
import static in.koreatech.koin.domain.team.recruitment.enums.TeamRecruitmentNotificationTargetType.MY_APPLICATIONS;
import static in.koreatech.koin.domain.team.recruitment.enums.TeamRecruitmentNotificationType.APPLICATION_REJECTED;
Expand Down Expand Up @@ -55,15 +54,13 @@ public class TeamRecruitmentClosureService {
private final TeamRecruitmentOutboxEventRepository outboxEventRepository;

/**
* 대기 중인 지원서를 거절하고, 모든 채팅방을 읽기 전용으로 바꾸고,
* 대기 중이던 지원자와 승인된 팀원에게 알림을 남긴다.
* 대기 중인 지원서를 거절하고, 대기 중이던 지원자와 승인된 팀원에게 알림을 남긴다.
*/
public void onClosed(TeamRecruitment recruitment) {
List<TeamRecruitmentApplication> pending = findApplications(recruitment.getId(), PENDING);
List<TeamRecruitmentApplication> accepted = findApplications(recruitment.getId(), ACCEPTED);

rejectAll(pending, RECRUITMENT_CLOSED_REASON);
markRoomsReadOnly(recruitment.getId());
notifyRejected(recruitment, pending, closedRejectedMessage(recruitment));
notifyAccepted(recruitment, accepted, RECRUITMENT_CLOSED, closedMessage(recruitment));
}
Expand All @@ -76,7 +73,6 @@ public void onDeleted(TeamRecruitment recruitment) {
List<TeamRecruitmentApplication> accepted = findApplications(recruitment.getId(), ACCEPTED);

rejectAll(pending, RECRUITMENT_DELETED_REASON);
markRoomsReadOnly(recruitment.getId());
notifyRejected(recruitment, pending, deletedRejectedMessage(recruitment));
notifyAccepted(recruitment, accepted, RECRUITMENT_DELETED, deletedMessage(recruitment));
}
Expand Down Expand Up @@ -106,16 +102,6 @@ private void rejectAll(List<TeamRecruitmentApplication> applications, String rea
applications.forEach(application -> application.reject(reason));
}

private void markRoomsReadOnly(Integer recruitmentId) {
List<TeamRecruitmentChatRoom> chatRooms = chatRoomRepository.findAllByRecruitment_Id(recruitmentId);
if (chatRooms == null) {
return;
}
chatRooms.stream()
.filter(chatRoom -> chatRoom.getStatus() == ACTIVE)
.forEach(TeamRecruitmentChatRoom::markReadOnly);
}

private void notifyRejected(
TeamRecruitment recruitment,
List<TeamRecruitmentApplication> pending,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import static in.koreatech.koin.domain.team.recruitment.enums.TeamRecruitmentApplicationStatus.REJECTED;
import static in.koreatech.koin.domain.team.recruitment.enums.TeamRecruitmentCategory.PROJECT;
import static in.koreatech.koin.domain.team.recruitment.enums.TeamRecruitmentChatRoomStatus.ACTIVE;
import static in.koreatech.koin.domain.team.recruitment.enums.TeamRecruitmentChatRoomStatus.READ_ONLY;
import static in.koreatech.koin.domain.team.recruitment.enums.TeamRecruitmentChatRoomType.DIRECT;
import static in.koreatech.koin.domain.team.recruitment.enums.TeamRecruitmentChatRoomType.TEAM;
import static in.koreatech.koin.domain.team.recruitment.enums.TeamRecruitmentMeetingType.ONLINE;
Expand Down Expand Up @@ -316,7 +315,7 @@ private void assertRole(
}

@Test
void 수동_마감된_ACCEPTED_지원서는_DIRECT_CTA와_생성_조건이_모두_닫힌다() throws Exception {
void 수동_마감된_ACCEPTED_지원서는_ACTIVE_TEAM_방이_있어_DIRECT를_생성할_수_있다() throws Exception {
TeamRecruitment recruitment = recruitmentContext.recruitment();
TeamRecruitmentApplication application = savePendingApplication(recruitment);

Expand All @@ -331,13 +330,15 @@ private void assertRole(
.header("Authorization", "Bearer " + authorToken))
.andExpect(status().isOk())
.andExpect(jsonPath("$.applications[0].status").value("ACCEPTED"))
.andExpect(jsonPath("$.applications[0].can_open_direct_chat").value(false));
.andExpect(jsonPath("$.applications[0].can_open_direct_chat").value(true));

mockMvc.perform(post("/chatroom/team-recruitment/{recruitmentId}/applications/{applicationId}/direct",
recruitment.getId(), application.getId())
.header("Authorization", "Bearer " + authorToken))
.andExpect(status().isConflict())
.andExpect(jsonPath("$.code").value("TEAM_RECRUITMENT_CLOSED"));
.andExpect(status().isCreated())
.andExpect(jsonPath("$.chat_room_id").isNumber())
.andExpect(jsonPath("$.room_type").value("DIRECT"))
.andExpect(jsonPath("$.status").value("ACTIVE"));
}

@Test
Expand Down Expand Up @@ -445,20 +446,20 @@ private void assertRole(
.andExpect(status().isNoContent());

assertThat(chatRoomRepository.findById(directRoom.getId()).orElseThrow().getStatus())
.isEqualTo(READ_ONLY);
.isEqualTo(ACTIVE);

mockMvc.perform(post("/chatroom/team-recruitment/{recruitmentId}/applications/{applicationId}/direct",
recruitment.getId(), application.getId())
.header("Authorization", "Bearer " + authorToken))
.andExpect(status().isOk())
.andExpect(jsonPath("$.chat_room_id").value(directRoom.getId()))
.andExpect(jsonPath("$.status").value("READ_ONLY"));
.andExpect(jsonPath("$.status").value("ACTIVE"));

mockMvc.perform(get("/chatroom/team-recruitment/{recruitmentId}/{chatRoomId}",
recruitment.getId(), directRoom.getId())
.header("Authorization", "Bearer " + authorToken))
.andExpect(status().isOk())
.andExpect(jsonPath("$.status").value("READ_ONLY"));
.andExpect(jsonPath("$.status").value("ACTIVE"));
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import static in.koreatech.koin.domain.team.recruitment.enums.TeamRecruitmentApplicationStatus.REJECTED;
import static in.koreatech.koin.domain.team.recruitment.enums.TeamRecruitmentCategory.PROJECT;
import static in.koreatech.koin.domain.team.recruitment.enums.TeamRecruitmentChatRoomStatus.ACTIVE;
import static in.koreatech.koin.domain.team.recruitment.enums.TeamRecruitmentChatRoomStatus.READ_ONLY;
import static in.koreatech.koin.domain.team.recruitment.enums.TeamRecruitmentChatRoomType.TEAM;
import static in.koreatech.koin.domain.team.recruitment.enums.TeamRecruitmentMeetingType.ONLINE;
import static in.koreatech.koin.domain.team.recruitment.enums.TeamRecruitmentNotificationTargetType.MY_APPLICATIONS;
Expand Down Expand Up @@ -124,7 +123,7 @@ void setUp() {
}

@Test
@DisplayName("수동 마감하면 대기 지원서가 거절되고 채팅방이 READ_ONLY 로 바뀌며 알림이 남는다")
@DisplayName("수동 마감하면 대기 지원서가 거절되고 채팅방은 ACTIVE 유지되며 알림이 남는다")
void 수동_마감_후속_처리() throws Exception {
TeamRecruitment recruitment = saveGeneralRecruitment("수동 마감", 3, 0);
TeamRecruitmentChatRoom teamRoom = saveTeamRoom(recruitment);
Expand All @@ -139,7 +138,7 @@ void setUp() {
assertThat(applicationRepository.findById(application.getId()).orElseThrow().getStatus())
.isEqualTo(REJECTED);
assertThat(chatRoomRepository.findById(teamRoom.getId()).orElseThrow().getStatus())
.isEqualTo(READ_ONLY);
.isEqualTo(ACTIVE);
assertThat(notificationRepository.findAllByRecipient_IdAndIsDeletedFalse(applicant.getUser().getId()))
.extracting(TeamRecruitmentNotification::getType)
.contains(APPLICATION_REJECTED);
Expand All @@ -161,7 +160,7 @@ void setUp() {
assertThat(applicationRepository.findById(application.getId()).orElseThrow().getDecisionReason())
.isEqualTo("RECRUITMENT_DELETED");
assertThat(chatRoomRepository.findById(teamRoom.getId()).orElseThrow().getStatus())
.isEqualTo(READ_ONLY);
.isEqualTo(ACTIVE);
assertThat(notificationRepository.findAllByRecipient_IdAndIsDeletedFalse(applicant.getUser().getId()))
.extracting(TeamRecruitmentNotification::getMessagePreview)
.anyMatch(message -> message.contains("삭제되어"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import static in.koreatech.koin.domain.team.recruitment.enums.TeamRecruitmentApplicationStatus.REJECTED;
import static in.koreatech.koin.domain.team.recruitment.enums.TeamRecruitmentCategory.PROJECT;
import static in.koreatech.koin.domain.team.recruitment.enums.TeamRecruitmentChatRoomStatus.ACTIVE;
import static in.koreatech.koin.domain.team.recruitment.enums.TeamRecruitmentChatRoomStatus.READ_ONLY;
import static in.koreatech.koin.domain.team.recruitment.enums.TeamRecruitmentChatRoomType.DIRECT;
import static in.koreatech.koin.domain.team.recruitment.enums.TeamRecruitmentChatRoomType.TEAM;
import static in.koreatech.koin.domain.team.recruitment.enums.TeamRecruitmentMeetingType.ONLINE;
Expand Down Expand Up @@ -188,7 +187,7 @@ private void assertResults(Scenario scenario) {
assertThat(successfulRecruitment.getStatus()).isEqualTo(CLOSED);
assertThat(successfulPending.getStatus()).isEqualTo(REJECTED);
assertThat(successfulPending.getDecisionReason()).isEqualTo("RECRUITMENT_CLOSED");
assertThat(successfulTeamRoom.getStatus()).isEqualTo(READ_ONLY);
assertThat(successfulTeamRoom.getStatus()).isEqualTo(ACTIVE);
assertThat(notificationRepository.findForOutbox(
scenario.successfulApplicantId(),
APPLICATION_REJECTED,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class TeamRecruitmentDirectChatPolicyTest {
}

@Test
void 수동_기한_마감된_ACCEPTED_지원서는_READ_ONLY_TEAM_방이면_DIRECT를_열수없다() {
void READ_ONLY_TEAM_방이면_신규_DIRECT를_열수없다() {
TeamRecruitment recruitment = recruitment(CLOSED);

assertThat(canOpen(ACCEPTED, false, recruitment, teamRoom(recruitment, READ_ONLY))).isFalse();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import static in.koreatech.koin.domain.team.recruitment.enums.TeamRecruitmentApplicationStatus.PENDING;
import static in.koreatech.koin.domain.team.recruitment.enums.TeamRecruitmentApplicationStatus.REJECTED;
import static in.koreatech.koin.domain.team.recruitment.enums.TeamRecruitmentChatRoomStatus.ACTIVE;
import static in.koreatech.koin.domain.team.recruitment.enums.TeamRecruitmentChatRoomStatus.READ_ONLY;
import static in.koreatech.koin.domain.team.recruitment.enums.TeamRecruitmentChatRoomType.DIRECT;
import static in.koreatech.koin.domain.team.recruitment.enums.TeamRecruitmentChatRoomType.TEAM;
import static in.koreatech.koin.domain.team.recruitment.enums.TeamRecruitmentStatus.CLOSED;
Expand Down Expand Up @@ -82,7 +81,6 @@ class CloseExpiredRecruitments {
stubApplications(pending, accepted);
when(chatRoomRepository.findByRecruitment_IdAndRoomScopeKey(1, "TEAM"))
.thenReturn(Optional.of(teamRoom));
when(chatRoomRepository.findAllByRecruitment_Id(1)).thenReturn(List.of(teamRoom, directRoom));
when(outboxEventRepository.findByEventKey(any())).thenReturn(Optional.empty());
when(notificationRepository.save(any())).thenAnswer(invocation -> {
TeamRecruitmentNotification notification = invocation.getArgument(0);
Expand All @@ -100,11 +98,10 @@ class CloseExpiredRecruitments {
assertThat(pending.getStatus()).isEqualTo(REJECTED);
assertThat(pending.getDecisionReason()).isEqualTo("RECRUITMENT_CLOSED");
assertThat(accepted.getStatus()).isEqualTo(ACCEPTED);
assertThat(teamRoom.getStatus()).isEqualTo(READ_ONLY);
assertThat(directRoom.getStatus()).isEqualTo(READ_ONLY);
assertThat(teamRoom.getStatus()).isEqualTo(ACTIVE);
assertThat(directRoom.getStatus()).isEqualTo(ACTIVE);
verify(applicationRepository).save(pending);
verify(chatRoomRepository).save(teamRoom);
verify(chatRoomRepository).save(directRoom);
verify(chatRoomRepository, never()).save(any());
verify(notificationRepository, org.mockito.Mockito.times(2)).save(any());
verify(outboxEventRepository, org.mockito.Mockito.times(2)).save(any());
ArgumentCaptor<TeamRecruitmentOutboxEvent> outboxCaptor =
Expand Down Expand Up @@ -152,7 +149,6 @@ class CloseExpiredRecruitments {
)).thenReturn(new PageImpl<>(List.of(accepted)));
when(chatRoomRepository.findByRecruitment_IdAndRoomScopeKey(1, "TEAM"))
.thenReturn(Optional.empty());
when(chatRoomRepository.findAllByRecruitment_Id(1)).thenReturn(List.of());

IllegalStateException exception = assertThrows(
IllegalStateException.class,
Expand Down Expand Up @@ -180,7 +176,6 @@ class CloseExpiredRecruitments {
)).thenReturn(new PageImpl<>(List.of()));
when(chatRoomRepository.findByRecruitment_IdAndRoomScopeKey(1, "TEAM"))
.thenReturn(Optional.empty());
when(chatRoomRepository.findAllByRecruitment_Id(1)).thenReturn(List.of());

processor.closeIfExpired(1, TODAY);

Expand Down
Loading