Skip to content

Commit

Permalink
[Test] 테스트 코드 수정
Browse files Browse the repository at this point in the history
  • Loading branch information
AreSain committed Aug 14, 2024
1 parent baee5ef commit 7e3a9d6
Show file tree
Hide file tree
Showing 6 changed files with 122 additions and 81 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

import gg.agenda.api.user.agendaprofile.service.AgendaProfileService;
import gg.agenda.api.user.ticket.controller.response.TicketHistoryResDto;
import gg.auth.FortyTwoAuthUtil;
import gg.auth.UserDto;
import gg.data.agenda.Agenda;
import gg.data.agenda.AgendaProfile;
Expand All @@ -41,6 +42,7 @@
@RequiredArgsConstructor
public class TicketService {
private final ApiUtil apiUtil;
private final FortyTwoAuthUtil fortyTwoAuthUtil;
private final TicketRepository ticketRepository;
private final AgendaRepository agendaRepository;
private final AgendaProfileService agendaProfileService;
Expand Down Expand Up @@ -95,9 +97,9 @@ public void modifyTicketApprove(UserDto user, Authentication authentication) {
Ticket setUpTicket = getSetUpTicket(profile);

OAuth2AuthenticationToken oauthToken = (OAuth2AuthenticationToken)authentication;
OAuth2AuthorizedClient oAuth2AuthorizedClient = apiUtil.getOAuth2AuthorizedClient(oauthToken);
OAuth2AuthorizedClient oAuth2AuthorizedClient = fortyTwoAuthUtil.getOAuth2AuthorizedClient(oauthToken);

List<Map<String, Object>> pointHistory = getPointHistory(profile, oAuth2AuthorizedClient, authentication);
List<Map<String, String>> pointHistory = getPointHistory(profile, oAuth2AuthorizedClient, authentication);

processTicketApproval(profile, setUpTicket, pointHistory);
}
Expand All @@ -119,17 +121,17 @@ private Ticket getSetUpTicket(AgendaProfile profile) {
* @param authentication Authentication
* @return 포인트 이력
*/
private List<Map<String, Object>> getPointHistory(AgendaProfile profile, OAuth2AuthorizedClient client,
private List<Map<String, String>> getPointHistory(AgendaProfile profile, OAuth2AuthorizedClient client,
Authentication authentication) {
String url = pointHistoryUrl.replace("{id}", profile.getFortyTwoId().toString());
ParameterizedTypeReference<List<Map<String, Object>>> responseType = new ParameterizedTypeReference<>() {
ParameterizedTypeReference<List<Map<String, String>>> responseType = new ParameterizedTypeReference<>() {
};

try {
return apiUtil.callApiWithAccessToken(url, client.getAccessToken().getTokenValue(), responseType);
} catch (HttpClientErrorException e) {
if (e.getStatusCode() == HttpStatus.UNAUTHORIZED) {
client = apiUtil.refreshAccessToken(client, authentication);
client = fortyTwoAuthUtil.refreshAccessToken(client, authentication);
return apiUtil.callApiWithAccessToken(url, client.getAccessToken().getTokenValue(), responseType);
}
throw e;
Expand All @@ -143,17 +145,17 @@ private List<Map<String, Object>> getPointHistory(AgendaProfile profile, OAuth2A
* @param pointHistory 포인트 이력
*/
private void processTicketApproval(AgendaProfile profile, Ticket setUpTicket,
List<Map<String, Object>> pointHistory) {
List<Map<String, String>> pointHistory) {
LocalDateTime cutoffTime = setUpTicket.getCreatedAt();

int ticketSum = pointHistory.stream()
.takeWhile(
history -> DateTimeUtil.convertToSeoulDateTime((String)history.get("created_at")).isAfter(cutoffTime))
history -> DateTimeUtil.convertToSeoulDateTime(history.get("created_at")).isAfter(cutoffTime))
.filter(history -> {
String reason = (String)history.get("reason");
String reason = history.get("reason");
return reason.contains(selfDonation) || reason.contains(autoDonation);
})
.mapToInt(history -> ((Number)history.get("sum")).intValue() * (-1))
.mapToInt(history -> Integer.parseInt(history.get("sum")) * (-1))
.sum();

if (ticketSum == 0) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -497,6 +497,7 @@ public AgendaProfile createAgendaProfile(User user, Location location) {
.location(location)
.intraId(user.getIntraId())
.userId(user.getId())
.fortyTwoId(user.getId())
.build();
return agendaProfileRepository.save(agendaProfile);
}
Expand Down
2 changes: 2 additions & 0 deletions gg-auth/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ dependencies {
implementation 'io.jsonwebtoken:jjwt-api:0.11.2'
implementation 'io.jsonwebtoken:jjwt-impl:0.11.2'
implementation 'io.jsonwebtoken:jjwt-jackson:0.11.2'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'

annotationProcessor "org.springframework.boot:spring-boot-configuration-processor"

Expand Down
103 changes: 103 additions & 0 deletions gg-auth/src/main/java/gg/auth/FortyTwoAuthUtil.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package gg.auth;

import static gg.utils.exception.ErrorCode.*;

import java.time.Instant;
import java.util.List;
import java.util.Map;

import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientService;
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
import org.springframework.security.oauth2.client.registration.ClientRegistration;
import org.springframework.security.oauth2.core.OAuth2AccessToken;
import org.springframework.security.oauth2.core.OAuth2RefreshToken;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestClientException;

import gg.utils.exception.ErrorCode;
import gg.utils.exception.custom.NotExistException;
import gg.utils.external.ApiUtil;
import lombok.RequiredArgsConstructor;

@Component
@RequiredArgsConstructor
public class FortyTwoAuthUtil {
private final ApiUtil apiUtil;
private final OAuth2AuthorizedClientService authorizedClientService;

/**
* OAuth2AuthorizedClient 조회
* @param oauthToken OAuth2AuthenticationToken
* @return OAuth2AuthorizedClient
*/
public OAuth2AuthorizedClient getOAuth2AuthorizedClient(OAuth2AuthenticationToken oauthToken) {
String registrationId = oauthToken.getAuthorizedClientRegistrationId();
OAuth2AuthorizedClient client = authorizedClientService.loadAuthorizedClient(registrationId,
oauthToken.getName());

Check warning on line 43 in gg-auth/src/main/java/gg/auth/FortyTwoAuthUtil.java

View check run for this annotation

Codecov / codecov/patch

gg-auth/src/main/java/gg/auth/FortyTwoAuthUtil.java#L41-L43

Added lines #L41 - L43 were not covered by tests
if (client.getRefreshToken() == null) {
throw new NotExistException(AUTH_NOT_FOUND);

Check warning on line 45 in gg-auth/src/main/java/gg/auth/FortyTwoAuthUtil.java

View check run for this annotation

Codecov / codecov/patch

gg-auth/src/main/java/gg/auth/FortyTwoAuthUtil.java#L45

Added line #L45 was not covered by tests
}
return client;

Check warning on line 47 in gg-auth/src/main/java/gg/auth/FortyTwoAuthUtil.java

View check run for this annotation

Codecov / codecov/patch

gg-auth/src/main/java/gg/auth/FortyTwoAuthUtil.java#L47

Added line #L47 was not covered by tests
}

/**
* 토큰 갱신
* @param client OAuth2AuthorizedClient
* @param authentication Authentication
* @return 갱신된 OAuth2AuthorizedClient
*/
public OAuth2AuthorizedClient refreshAccessToken(OAuth2AuthorizedClient client, Authentication authentication) {
try {
ClientRegistration registration = client.getClientRegistration();

Check warning on line 58 in gg-auth/src/main/java/gg/auth/FortyTwoAuthUtil.java

View check run for this annotation

Codecov / codecov/patch

gg-auth/src/main/java/gg/auth/FortyTwoAuthUtil.java#L58

Added line #L58 was not covered by tests
if (client.getRefreshToken() == null) {
throw new NotExistException(AUTH_NOT_FOUND);

Check warning on line 60 in gg-auth/src/main/java/gg/auth/FortyTwoAuthUtil.java

View check run for this annotation

Codecov / codecov/patch

gg-auth/src/main/java/gg/auth/FortyTwoAuthUtil.java#L60

Added line #L60 was not covered by tests
}

String tokenUri = registration.getProviderDetails().getTokenUri();
MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
params.add("grant_type", "refresh_token");
params.add("refresh_token", client.getRefreshToken().getTokenValue());
params.add("client_id", registration.getClientId());
params.add("client_secret", registration.getClientSecret());
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

Check warning on line 70 in gg-auth/src/main/java/gg/auth/FortyTwoAuthUtil.java

View check run for this annotation

Codecov / codecov/patch

gg-auth/src/main/java/gg/auth/FortyTwoAuthUtil.java#L63-L70

Added lines #L63 - L70 were not covered by tests

List<Map<String, Object>> responseBody = apiUtil.apiCall(tokenUri, List.class, headers, params,

Check warning on line 72 in gg-auth/src/main/java/gg/auth/FortyTwoAuthUtil.java

View check run for this annotation

Codecov / codecov/patch

gg-auth/src/main/java/gg/auth/FortyTwoAuthUtil.java#L72

Added line #L72 was not covered by tests
HttpMethod.POST);
if (responseBody == null || responseBody.isEmpty()) {
throw new NotExistException(ErrorCode.AUTH_NOT_FOUND);

Check warning on line 75 in gg-auth/src/main/java/gg/auth/FortyTwoAuthUtil.java

View check run for this annotation

Codecov / codecov/patch

gg-auth/src/main/java/gg/auth/FortyTwoAuthUtil.java#L75

Added line #L75 was not covered by tests
}
Map<String, Object> map = responseBody.get(0);

Check warning on line 77 in gg-auth/src/main/java/gg/auth/FortyTwoAuthUtil.java

View check run for this annotation

Codecov / codecov/patch

gg-auth/src/main/java/gg/auth/FortyTwoAuthUtil.java#L77

Added line #L77 was not covered by tests

OAuth2AccessToken newAccessToken = new OAuth2AccessToken(

Check warning on line 79 in gg-auth/src/main/java/gg/auth/FortyTwoAuthUtil.java

View check run for this annotation

Codecov / codecov/patch

gg-auth/src/main/java/gg/auth/FortyTwoAuthUtil.java#L79

Added line #L79 was not covered by tests
OAuth2AccessToken.TokenType.BEARER,
(String)map.get("access_token"),
Instant.now(),
Instant.now().plusSeconds((Integer)map.get("expires_in"))

Check warning on line 83 in gg-auth/src/main/java/gg/auth/FortyTwoAuthUtil.java

View check run for this annotation

Codecov / codecov/patch

gg-auth/src/main/java/gg/auth/FortyTwoAuthUtil.java#L81-L83

Added lines #L81 - L83 were not covered by tests
);

OAuth2RefreshToken newRefreshToken = new OAuth2RefreshToken(
(String)map.get("refresh_token"),
Instant.now()

Check warning on line 88 in gg-auth/src/main/java/gg/auth/FortyTwoAuthUtil.java

View check run for this annotation

Codecov / codecov/patch

gg-auth/src/main/java/gg/auth/FortyTwoAuthUtil.java#L86-L88

Added lines #L86 - L88 were not covered by tests
);

OAuth2AuthorizedClient newClient = new OAuth2AuthorizedClient(
registration, client.getPrincipalName(), newAccessToken, newRefreshToken);

Check warning on line 92 in gg-auth/src/main/java/gg/auth/FortyTwoAuthUtil.java

View check run for this annotation

Codecov / codecov/patch

gg-auth/src/main/java/gg/auth/FortyTwoAuthUtil.java#L91-L92

Added lines #L91 - L92 were not covered by tests

String principalName = authentication.getName();
authorizedClientService.removeAuthorizedClient(registration.getRegistrationId(), principalName);
authorizedClientService.saveAuthorizedClient(newClient, authentication);

Check warning on line 96 in gg-auth/src/main/java/gg/auth/FortyTwoAuthUtil.java

View check run for this annotation

Codecov / codecov/patch

gg-auth/src/main/java/gg/auth/FortyTwoAuthUtil.java#L94-L96

Added lines #L94 - L96 were not covered by tests

return newClient;
} catch (RestClientException e) {
throw new NotExistException(AUTH_NOT_FOUND);

Check warning on line 100 in gg-auth/src/main/java/gg/auth/FortyTwoAuthUtil.java

View check run for this annotation

Codecov / codecov/patch

gg-auth/src/main/java/gg/auth/FortyTwoAuthUtil.java#L98-L100

Added lines #L98 - L100 were not covered by tests
}
}
}
2 changes: 0 additions & 2 deletions gg-utils/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,6 @@ unitTestCoverageReport {
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation "com.amazonaws:aws-java-sdk-s3:1.12.281"
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.1'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.1'

Expand Down
75 changes: 5 additions & 70 deletions gg-utils/src/main/java/gg/utils/external/ApiUtil.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package gg.utils.external;

import static gg.utils.exception.ErrorCode.*;

import java.util.List;
import java.util.Map;

Expand All @@ -12,39 +10,23 @@
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientService;
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
import org.springframework.security.oauth2.client.endpoint.DefaultRefreshTokenTokenResponseClient;
import org.springframework.security.oauth2.client.endpoint.OAuth2RefreshTokenGrantRequest;
import org.springframework.security.oauth2.client.registration.ClientRegistration;
import org.springframework.security.oauth2.core.OAuth2AccessToken;
import org.springframework.security.oauth2.core.OAuth2AuthorizationException;
import org.springframework.security.oauth2.core.OAuth2RefreshToken;
import org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import gg.utils.exception.custom.NotExistException;
import gg.utils.exception.user.TokenNotValidException;

@Component
public class ApiUtil {
private final RestTemplate restTemplate;
private final ObjectMapper objectMapper;
private final OAuth2AuthorizedClientService authorizedClientService;

public ApiUtil(ObjectMapper objectMapper, RestTemplateBuilder restTemplateBuilder,
OAuth2AuthorizedClientService authorizedClientService) {
public ApiUtil(ObjectMapper objectMapper, RestTemplateBuilder restTemplateBuilder) {
this.objectMapper = objectMapper;
this.restTemplate = restTemplateBuilder.build();
this.authorizedClientService = authorizedClientService;
}

public <T> T apiCall(String url, Class<T> responseType, HttpHeaders headers,
Expand Down Expand Up @@ -99,60 +81,13 @@ public <T> T apiCall(String url, ParameterizedTypeReference<T> responseType, Htt
* @param responseType 응답 타입
* @return 응답
*/
public List<Map<String, Object>> callApiWithAccessToken(String url, String accessToken,
ParameterizedTypeReference<List<Map<String, Object>>> responseType) {
public List<Map<String, String>> callApiWithAccessToken(String url, String accessToken,
ParameterizedTypeReference<List<Map<String, String>>> responseType) {

HttpHeaders headers = new HttpHeaders();
headers.set("Authorization", "Bearer " + accessToken);
headers.setBearerAuth(accessToken);
headers.setContentType(MediaType.APPLICATION_JSON);

Check warning on line 89 in gg-utils/src/main/java/gg/utils/external/ApiUtil.java

View check run for this annotation

Codecov / codecov/patch

gg-utils/src/main/java/gg/utils/external/ApiUtil.java#L87-L89

Added lines #L87 - L89 were not covered by tests

return apiCall(url, responseType, headers, HttpMethod.GET);

Check warning on line 91 in gg-utils/src/main/java/gg/utils/external/ApiUtil.java

View check run for this annotation

Codecov / codecov/patch

gg-utils/src/main/java/gg/utils/external/ApiUtil.java#L91

Added line #L91 was not covered by tests
}

/**
* OAuth2AuthorizedClient 조회
* @param oauthToken OAuth2AuthenticationToken
* @return OAuth2AuthorizedClient
*/
public OAuth2AuthorizedClient getOAuth2AuthorizedClient(OAuth2AuthenticationToken oauthToken) {
String registrationId = oauthToken.getAuthorizedClientRegistrationId();
OAuth2AuthorizedClient client = authorizedClientService.loadAuthorizedClient(registrationId,
oauthToken.getName());
if (client.getRefreshToken() == null) {
throw new NotExistException(AUTH_NOT_FOUND);
}
return client;
}

/**
* 토큰 갱신
* @param client OAuth2AuthorizedClient
* @param authentication Authentication
* @return 갱신된 OAuth2AuthorizedClient
*/
public OAuth2AuthorizedClient refreshAccessToken(OAuth2AuthorizedClient client, Authentication authentication) {
try {
ClientRegistration registration = client.getClientRegistration();
if (client.getRefreshToken() == null) {
throw new NotExistException(AUTH_NOT_FOUND);
}
OAuth2RefreshTokenGrantRequest grantRequest = new OAuth2RefreshTokenGrantRequest(
registration, client.getAccessToken(), client.getRefreshToken());

OAuth2AccessTokenResponse tokenResponse = new DefaultRefreshTokenTokenResponseClient()
.getTokenResponse(grantRequest);

OAuth2AccessToken newAccessToken = tokenResponse.getAccessToken();
OAuth2RefreshToken newRefreshToken = tokenResponse.getRefreshToken();

OAuth2AuthorizedClient newClient = new OAuth2AuthorizedClient(
registration, client.getPrincipalName(), newAccessToken, newRefreshToken);
String principalName = SecurityContextHolder.getContext().getAuthentication().getName();

authorizedClientService.removeAuthorizedClient(registration.getRegistrationId(), principalName);
authorizedClientService.saveAuthorizedClient(newClient, authentication);
return newClient;
} catch (OAuth2AuthorizationException e) { // Refresh 토큰도 만료된 경우
throw new NotExistException(AUTH_NOT_FOUND);
}
}
}

0 comments on commit 7e3a9d6

Please sign in to comment.