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
2 changes: 1 addition & 1 deletion src/main/java/com/mos/backend/common/event/EventType.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@ public enum EventType {
STUDY_JOIN_CANCELED,
STUDY_DELETED,
STUDY_UPDATED,

IMPORTANT_NOTICE_CHANGED,
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
package com.mos.backend.studynotices.application;

import com.mos.backend.common.event.Event;
import com.mos.backend.common.event.EventType;
import com.mos.backend.common.exception.MosException;
import com.mos.backend.common.infrastructure.EntityFacade;
import com.mos.backend.studies.entity.Study;
import com.mos.backend.studynotices.application.event.ImportantNoticeChangedEventPayload;
import com.mos.backend.studynotices.application.responsedto.StudyNoticeResponseDto;
import com.mos.backend.studynotices.entity.StudyNotice;
import com.mos.backend.studynotices.entity.StudyNoticeErrorCode;
import com.mos.backend.studynotices.infrastructure.StudyNoticeRepository;
import com.mos.backend.users.application.UserService;
import com.mos.backend.users.entity.User;
import lombok.RequiredArgsConstructor;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
Expand All @@ -27,6 +31,7 @@ public class StudyNoticeService {
private final StudyNoticeRepository studyNoticeRepository;
private final UserService userService;
private final EntityFacade entityFacade;
private final ApplicationEventPublisher eventPublisher;

/**
* 공지 생성
Expand All @@ -38,8 +43,8 @@ public StudyNoticeResponseDto create(long studyId, long currentUserId, String ti
// 중요 공지로 설정했을 때 중요 공지가 이미 존재하다면 기존 중요 공지 마크 해제
if (important) {
studyNoticeRepository.findByStudyIdAndImportantIsTrue(studyId).ifPresent(StudyNotice::unmarkAsImportant);
eventPublisher.publishEvent(new Event<>(EventType.IMPORTANT_NOTICE_CHANGED, new ImportantNoticeChangedEventPayload(studyId)));
}

Study study = entityFacade.getStudy(studyId);
User currentUser = entityFacade.getUser(currentUserId);

Expand All @@ -58,6 +63,7 @@ public StudyNoticeResponseDto update(long studyId, long studyNoticeId, String ti
// 중요 공지로 설정했을 때 중요 공지가 이미 존재하다면 기존 중요 공지 마크 해제
if (important) {
studyNoticeRepository.findByStudyIdAndImportantIsTrue(studyId).ifPresent(StudyNotice::unmarkAsImportant);
eventPublisher.publishEvent(new Event<>(EventType.IMPORTANT_NOTICE_CHANGED, new ImportantNoticeChangedEventPayload(studyId)));
}

StudyNotice studyNotice = findByIdWithUser(studyNoticeId);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.mos.backend.studynotices.application.event;

import com.mos.backend.common.event.Payload;
import lombok.AllArgsConstructor;
import lombok.Getter;

@Getter
@AllArgsConstructor
public class ImportantNoticeChangedEventPayload implements Payload {
private Long studyId;
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,11 @@ public void create(Long studyId, Long userId) {
StudyMember studyMember = entityFacade.getStudyMember(userId, studyId);
userStudySettingRepository.save(UserStudySetting.create(studyMember));
}

/**
* 스터디의 모든 멤버의 noticePined 를 true로 변경
*/
public void showNoticeForAllMembers(Long studyId) {
userStudySettingRepository.showNoticeForAllMembers(studyId);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.mos.backend.userstudysettings.application.consumer;

import com.mos.backend.common.event.Event;
import com.mos.backend.studies.application.event.StudyCreatedEventPayload;
import com.mos.backend.studycurriculum.application.StudyCurriculumService;
import com.mos.backend.studynotices.application.event.ImportantNoticeChangedEventPayload;
import com.mos.backend.userstudysettings.application.UserStudySettingService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import org.springframework.transaction.event.TransactionalEventListener;

import static org.springframework.transaction.event.TransactionPhase.BEFORE_COMMIT;

@Component
@RequiredArgsConstructor
public class UserStudySettingConsumer {
private final UserStudySettingService userStudySettingService;

@TransactionalEventListener(phase = BEFORE_COMMIT)
public void handleImportantNoticeChangedEvent(Event<ImportantNoticeChangedEventPayload> event) {
ImportantNoticeChangedEventPayload payload = event.getPayload();
userStudySettingService.showNoticeForAllMembers(payload.getStudyId());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.mos.backend.userstudysettings.infrastructure;

import com.querydsl.jpa.impl.JPAQueryFactory;
import jakarta.persistence.EntityManager;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;

import static com.mos.backend.userstudysettings.entity.QUserStudySetting.userStudySetting;

@RequiredArgsConstructor
@Repository
public class UserStudySettingQueryDslRepository {
private final EntityManager em;
private final JPAQueryFactory queryFactory;

public void showNoticeForAllMembers(Long studyId) {
long number = queryFactory
.update(userStudySetting)
.set(userStudySetting.noticePined, true)
.where(userStudySetting.studyMember.study.id.eq(studyId))
.execute();
if (number > 0) {
em.flush();
em.clear();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,6 @@ public interface UserStudySettingRepository {
Optional<UserStudySetting> findByStudyMember(StudyMember studyMember);

void save(UserStudySetting userStudySetting);

void showNoticeForAllMembers(Long studyId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
public class UserStudySettingRepositoryImpl implements UserStudySettingRepository{

private final UserStudySettingJpaRepository userStudySettingJpaRepository;
private final UserStudySettingQueryDslRepository userStudySettingQueryDslRepository;

@Override
public Optional<UserStudySetting> findByStudyMember(StudyMember studyMember) {
Expand All @@ -22,4 +23,9 @@ public Optional<UserStudySetting> findByStudyMember(StudyMember studyMember) {
public void save(UserStudySetting userStudySetting) {
userStudySettingJpaRepository.save(userStudySetting);
}

@Override
public void showNoticeForAllMembers(Long studyId) {
userStudySettingQueryDslRepository.showNoticeForAllMembers(studyId);
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package com.mos.backend.studynotices.application;

import com.mos.backend.common.event.Event;
import com.mos.backend.common.exception.MosException;
import com.mos.backend.common.infrastructure.EntityFacade;
import com.mos.backend.studies.application.event.StudyCreatedEventPayload;
import com.mos.backend.studies.entity.Study;
import com.mos.backend.studynotices.application.event.ImportantNoticeChangedEventPayload;
import com.mos.backend.studynotices.application.responsedto.StudyNoticeResponseDto;
import com.mos.backend.studynotices.entity.StudyNotice;
import com.mos.backend.studynotices.entity.StudyNoticeErrorCode;
Expand All @@ -12,9 +15,12 @@
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.context.ApplicationEventPublisher;

import java.util.Optional;

Expand All @@ -38,6 +44,12 @@ class StudyNoticeServiceTest {
@Mock
private EntityFacade entityFacade;

@Mock
private ApplicationEventPublisher eventPublisher;

@Captor
private ArgumentCaptor<Event<ImportantNoticeChangedEventPayload>> eventCaptor;


@Test
@DisplayName("공지를 성공적으로 생성한다.")
Expand Down Expand Up @@ -70,6 +82,9 @@ void create_success() {
StudyNoticeResponseDto studyNoticeResponseDto = studyNoticeService.create(studyId, currentUserId, title, content, pinned, important);

// then
verify(eventPublisher).publishEvent(eventCaptor.capture());
Event<ImportantNoticeChangedEventPayload> event = eventCaptor.getValue();
assertThat(event.getPayload().getStudyId()).isEqualTo(studyId);
assertThat(studyNoticeResponseDto.getStudyId()).isEqualTo(studyId);
assertThat(studyNoticeResponseDto.getCreatorId()).isEqualTo(currentUserId);
assertThat(studyNoticeResponseDto.getTitle()).isEqualTo(title);
Expand Down Expand Up @@ -114,6 +129,9 @@ void whenCreateImportantNotice_thenUnmarksOldOne() {
studyNoticeService.create(studyId, currentUserId, "new title", "new content", false, true);

// then
verify(eventPublisher).publishEvent(eventCaptor.capture());
Event<ImportantNoticeChangedEventPayload> event = eventCaptor.getValue();
assertThat(event.getPayload().getStudyId()).isEqualTo(studyId);
assertThat(oldImportantNotice.isImportant()).isFalse(); // 기존 공지가 해제되었는지 확인
verify(studyNoticeRepository).save(any(StudyNotice.class));
}
Expand Down Expand Up @@ -163,6 +181,7 @@ void update_success() {
StudyNoticeResponseDto updatedNotice = studyNoticeService.update(studyId, studyNoticeId, updateTitle, updateContent, updatePinned, updateImportant);

// then
verify(eventPublisher, times(0)).publishEvent(any());
assertThat(updatedNotice.getTitle()).isEqualTo(updateTitle);
assertThat(updatedNotice.getContent()).isEqualTo(updateContent);
assertThat(updatedNotice.isPinned()).isEqualTo(updatePinned);
Expand Down