Skip to content

Commit

Permalink
Merge pull request #7 from Good-Moneying/feature/6-login-event
Browse files Browse the repository at this point in the history
[Feature] #6 로그인 이벤트 발행하기
  • Loading branch information
packdev937 authored May 9, 2024
2 parents 0d2d78c + 43170bf commit adb0927
Show file tree
Hide file tree
Showing 11 changed files with 215 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package kusitms.duduk.apiserver.user.event;

import kusitms.duduk.application.user.event.LoginUserEvent;
import kusitms.duduk.core.user.port.input.AttendUserUseCase;
import lombok.RequiredArgsConstructor;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;

@RequiredArgsConstructor
@Component
public class LoginEventListener {

private final AttendUserUseCase attendUserUseCase;

@EventListener
public void attendUser(LoginUserEvent event) {
attendUserUseCase.attend(event.getEmail());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package kusitms.duduk.apiserver.user.event;

import static org.codehaus.groovy.runtime.DefaultGroovyMethods.any;

import kusitms.duduk.application.attendence.persistence.AttendantRepository;
import kusitms.duduk.application.attendence.persistence.entity.AttendantJpaEntity;
import kusitms.duduk.application.user.event.LoginUserEvent;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.ApplicationEventPublisher;

@SpringBootTest
public class LoginEventListenerTest {

@MockBean
private LoginEventListener loginEventListener;

@Autowired
private ApplicationEventPublisher applicationEventPublisher;

@BeforeEach
public void setup() {
MockitoAnnotations.initMocks(this);
// Ensure correct initialization
}

@Test
public void 로그인_이벤트가_발생하면_리스너가_호출된다() {
// given
// Event 인스턴스를 생성한다
LoginUserEvent event = new LoginUserEvent(this, "test@test,com");

// when
// 이벤트를 발행한다
applicationEventPublisher.publishEvent(event);

// then
// verify 메소드를 활요하여 리스너의 attendUser 메소드가 호출되었는지 확인한다
Mockito.verify(loginEventListener).attendUser(event);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package kusitms.duduk.application.attendence.persistence;

import java.time.LocalDate;
import kusitms.duduk.application.attendence.persistence.entity.AttendantJpaEntity;
import kusitms.duduk.core.annotation.Adapter;
import kusitms.duduk.core.attendant.port.output.LoadAttendantPort;
import kusitms.duduk.core.attendant.port.output.SaveAttendantPort;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@RequiredArgsConstructor
@Adapter
public class AttendantPersistenceAdapter implements SaveAttendantPort, LoadAttendantPort {

private final AttendantRepository attendantRepository;

@Override
public void save(LocalDate today, String email) {
attendantRepository.save(AttendantJpaEntity.builder()
.date(today)
.email(email)
.build());
}

@Override
public boolean isAttendedToday(String email) {
return attendantRepository.existsByEmailAndDate(email, LocalDate.now());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package kusitms.duduk.application.attendence.persistence;

import java.time.LocalDate;
import kusitms.duduk.application.attendence.persistence.entity.AttendantJpaEntity;
import org.springframework.data.jpa.repository.JpaRepository;

public interface AttendantRepository extends JpaRepository<AttendantJpaEntity, Long> {

boolean existsByEmailAndDate(String email, LocalDate date);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package kusitms.duduk.application.attendence.persistence.entity;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import jakarta.persistence.UniqueConstraint;
import java.time.LocalDate;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.NoArgsConstructor;

@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
@Entity
@Table(name = "attendences", uniqueConstraints = {
@UniqueConstraint(columnNames = {"date", "email"})
})
@Builder(toBuilder = true)
public class AttendantJpaEntity {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "attendence_id")
private Long id;
private LocalDate date;
private String email;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package kusitms.duduk.application.attendence.service;

import java.time.LocalDate;
import kusitms.duduk.core.attendant.port.output.LoadAttendantPort;
import kusitms.duduk.core.attendant.port.output.SaveAttendantPort;
import kusitms.duduk.core.user.port.input.AttendUserUseCase;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

@Slf4j
@RequiredArgsConstructor
@Service
public class AttendUserCommand implements AttendUserUseCase {

private final SaveAttendantPort saveAttendantPort;
private final LoadAttendantPort loadAttendantPort;

@Override
public void attend(String email) {
if (!loadAttendantPort.isAttendedToday(email)) {
log.info("attend user: {}", email);
saveAttendantPort.save(LocalDate.now(), email);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import java.util.Map;

import kusitms.duduk.application.user.event.LoginUserEvent;
import kusitms.duduk.core.security.dto.response.JwtTokenResponse;
import kusitms.duduk.core.security.dto.response.OAuthDetailResponse;
import kusitms.duduk.core.security.dto.response.OAuthLoginResponse;
Expand All @@ -11,6 +12,7 @@
import kusitms.duduk.core.user.port.input.RetrieveUserQuery;
import kusitms.duduk.core.user.port.input.UpdateUserUseCase;
import lombok.RequiredArgsConstructor;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;

@RequiredArgsConstructor
Expand All @@ -20,14 +22,15 @@ public class LoginOAuthCommand implements LoginOAuthUseCase {
private final RetrieveUserQuery retrieveUserQuery;
private final UpdateUserUseCase updateUserUseCase;
private final JwtTokenProvider jwtTokenProvider;
private final ApplicationEventPublisher applicationEventPublisher;
private final Map<Provider, OAuthClientPort> oAuthClientPortMap;

public OAuthLoginResponse process(Provider provider, String accessToken) {
OAuthDetailResponse response = oAuthClientPortMap.get(provider).retrieveOAuthDetail(accessToken);
OAuthDetailResponse response = oAuthClientPortMap.get(provider)
.retrieveOAuthDetail(accessToken);
JwtTokenResponse jwtTokenInfo = jwtTokenProvider.createTokenInfo(response.email());

boolean isRegistered = retrieveUserQuery.isUserRegisteredByEmail(response.email());
updateRefreshTokenIfRegistered(isRegistered, response.email(), jwtTokenInfo.refreshToken());
boolean isRegistered = isRegistered(response, jwtTokenInfo);

return new OAuthLoginResponse(
jwtTokenInfo.accessToken(),
Expand All @@ -36,6 +39,16 @@ public OAuthLoginResponse process(Provider provider, String accessToken) {
isRegistered);
}

private boolean isRegistered(OAuthDetailResponse response, JwtTokenResponse jwtTokenInfo) {
boolean isRegistered = retrieveUserQuery.isUserRegisteredByEmail(response.email());
updateRefreshTokenIfRegistered(isRegistered, response.email(), jwtTokenInfo.refreshToken());

if (isRegistered) {
applicationEventPublisher.publishEvent(new LoginUserEvent(this, response.email()));
}
return isRegistered;
}

private void updateRefreshTokenIfRegistered(boolean isRegistered, String email,
String refreshToken) {
if (isRegistered) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package kusitms.duduk.application.user.event;

import lombok.Getter;
import org.springframework.context.ApplicationEvent;

@Getter
public class LoginUserEvent extends ApplicationEvent {

private final String email;

public LoginUserEvent(Object source, String email) {
super(source);
this.email = email;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package kusitms.duduk.core.attendant.port.output;

import java.time.LocalDate;

public interface LoadAttendantPort {
boolean isAttendedToday(String email);

// todo : 한 주에 몇번 출석 체크 했는지도 검증 가능
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package kusitms.duduk.core.attendant.port.output;

import java.time.LocalDate;

public interface SaveAttendantPort {
void save(LocalDate date, String email);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package kusitms.duduk.core.user.port.input;

public interface AttendUserUseCase {

void attend(String email);
}

0 comments on commit adb0927

Please sign in to comment.