Skip to content

Commit f4a2877

Browse files
committed
refactor: 프로필 생성 완료 이벤트로 추천 생성을 트리거하도록 변경
1 parent 10a544d commit f4a2877

2 files changed

Lines changed: 109 additions & 0 deletions

File tree

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package com.techfork.domain.recommendation.listener;
2+
3+
import com.techfork.domain.recommendation.service.RecommendationService;
4+
import com.techfork.personalization.application.event.PersonalizedProfileGeneratedEvent;
5+
import com.techfork.useraccount.application.query.lookup.UserLookupService;
6+
import com.techfork.useraccount.domain.User;
7+
import lombok.RequiredArgsConstructor;
8+
import lombok.extern.slf4j.Slf4j;
9+
import org.springframework.stereotype.Component;
10+
import org.springframework.transaction.event.TransactionPhase;
11+
import org.springframework.transaction.event.TransactionalEventListener;
12+
13+
@Slf4j
14+
@Component
15+
@RequiredArgsConstructor
16+
public class PersonalizedProfileGeneratedEventListener {
17+
18+
private final UserLookupService userLookupService;
19+
private final RecommendationService recommendationService;
20+
21+
@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
22+
public void handle(PersonalizedProfileGeneratedEvent event) {
23+
Long userId = event.userId();
24+
25+
try {
26+
User user = userLookupService.getUserOrThrow(userId);
27+
int recommendationCount = recommendationService.generateRecommendationsForUser(user);
28+
29+
log.info("Recommendations generated after personalization profile creation for userId: {} - {} recommendations created",
30+
userId, recommendationCount);
31+
} catch (Exception e) {
32+
log.error("Failed to generate recommendations after personalization profile creation for userId: {}", userId, e);
33+
}
34+
}
35+
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
package com.techfork.domain.recommendation.listener;
2+
3+
import com.techfork.domain.recommendation.service.RecommendationService;
4+
import com.techfork.personalization.application.event.PersonalizedProfileGeneratedEvent;
5+
import com.techfork.useraccount.application.query.lookup.UserLookupService;
6+
import com.techfork.useraccount.domain.User;
7+
import org.junit.jupiter.api.DisplayName;
8+
import org.junit.jupiter.api.Test;
9+
import org.junit.jupiter.api.extension.ExtendWith;
10+
import org.mockito.InjectMocks;
11+
import org.mockito.Mock;
12+
import org.mockito.junit.jupiter.MockitoExtension;
13+
import org.springframework.transaction.event.TransactionPhase;
14+
import org.springframework.transaction.event.TransactionalEventListener;
15+
16+
import static org.assertj.core.api.Assertions.assertThat;
17+
import static org.assertj.core.api.Assertions.assertThatCode;
18+
import static org.mockito.BDDMockito.given;
19+
import static org.mockito.Mockito.mock;
20+
import static org.mockito.Mockito.verify;
21+
22+
@ExtendWith(MockitoExtension.class)
23+
class PersonalizedProfileGeneratedEventListenerTest {
24+
25+
@Mock
26+
private UserLookupService userLookupService;
27+
28+
@Mock
29+
private RecommendationService recommendationService;
30+
31+
@InjectMocks
32+
private PersonalizedProfileGeneratedEventListener listener;
33+
34+
@Test
35+
@DisplayName("프로필 생성 이벤트를 받으면 추천을 생성한다")
36+
void handle_GeneratesRecommendationsWhenProfileGeneratedEventIsReceived() {
37+
Long userId = 1L;
38+
User user = mock(User.class);
39+
given(userLookupService.getUserOrThrow(userId)).willReturn(user);
40+
given(recommendationService.generateRecommendationsForUser(user)).willReturn(5);
41+
42+
listener.handle(new PersonalizedProfileGeneratedEvent(userId));
43+
44+
verify(userLookupService).getUserOrThrow(userId);
45+
verify(recommendationService).generateRecommendationsForUser(user);
46+
}
47+
48+
@Test
49+
@DisplayName("추천 생성이 실패해도 예외를 전파하지 않는다")
50+
void handle_RecommendationFailureDoesNotPropagateException() {
51+
Long userId = 2L;
52+
User user = mock(User.class);
53+
given(userLookupService.getUserOrThrow(userId)).willReturn(user);
54+
given(recommendationService.generateRecommendationsForUser(user))
55+
.willThrow(new RuntimeException("recommendation failure"));
56+
57+
assertThatCode(() -> listener.handle(new PersonalizedProfileGeneratedEvent(userId)))
58+
.doesNotThrowAnyException();
59+
60+
verify(userLookupService).getUserOrThrow(userId);
61+
verify(recommendationService).generateRecommendationsForUser(user);
62+
}
63+
64+
@Test
65+
@DisplayName("프로필 생성 이벤트 리스너는 AFTER_COMMIT 단계에서 실행된다")
66+
void listenerMethod_RunsAfterCommit() throws NoSuchMethodException {
67+
TransactionalEventListener annotation = PersonalizedProfileGeneratedEventListener.class
68+
.getDeclaredMethod("handle", PersonalizedProfileGeneratedEvent.class)
69+
.getAnnotation(TransactionalEventListener.class);
70+
71+
assertThat(annotation).isNotNull();
72+
assertThat(annotation.phase()).isEqualTo(TransactionPhase.AFTER_COMMIT);
73+
}
74+
}

0 commit comments

Comments
 (0)