Skip to content

Commit

Permalink
[DEV-47] 봉사학점의 이수학점이 자유선택으로 반영되도록 수정(pr 재작성) (#289)
Browse files Browse the repository at this point in the history
* fix: 배포스크립트 오류 수정

* fix: v2.1에서 인증 예외코드 에러 사항을 수정

* fix: 이수학점에서 봉사학점이 일반교양이아닌 자유선택으로 들어가게끔 수정

* chore: 봉사학점 테스트를 위해 lecture.csv 파일의 mock 데이터 수정

* test: 봉사학점이 자유선택 학점으로 반영되는 테스트 코드 추가(1번, 2번 들었을 때)

* refactor: 기존 봉사학점을 교양 수준에서 거르는게 아닌 일반교양 이수학점 처리에서 거르도록 수정

* test: 수정에 따라 봉사학점이 일반교양 학점에 포함되지 않는지 테스트

---------

Co-authored-by: 정지환 <[email protected]>
Co-authored-by: stophwan <[email protected]>
Co-authored-by: jinhyeon <[email protected]>
  • Loading branch information
4 people authored Dec 3, 2024
1 parent 9d12cf2 commit e92125f
Show file tree
Hide file tree
Showing 5 changed files with 142 additions and 63 deletions.
Original file line number Diff line number Diff line change
@@ -1,19 +1,23 @@
package com.plzgraduate.myongjigraduatebe.auth.security;

import static com.plzgraduate.myongjigraduatebe.core.exception.ErrorCode.INCORRECT_PASSWORD;
import static com.plzgraduate.myongjigraduatebe.core.exception.ErrorCode.*;
import static org.hibernate.validator.internal.util.TypeHelper.isAssignable;

import com.plzgraduate.myongjigraduatebe.core.exception.UnAuthorizedException;
import com.plzgraduate.myongjigraduatebe.user.application.usecase.find.FindUserUseCase;
import com.plzgraduate.myongjigraduatebe.user.domain.model.User;
import java.util.Collections;
import lombok.RequiredArgsConstructor;

import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.crypto.password.PasswordEncoder;

import com.plzgraduate.myongjigraduatebe.core.exception.ErrorCode;
import com.plzgraduate.myongjigraduatebe.core.exception.UnAuthorizedException;
import com.plzgraduate.myongjigraduatebe.user.application.usecase.find.FindUserUseCase;
import com.plzgraduate.myongjigraduatebe.user.domain.model.User;

import lombok.RequiredArgsConstructor;

@RequiredArgsConstructor
public class JwtAuthenticationProvider implements AuthenticationProvider {

Expand All @@ -27,24 +31,19 @@ public boolean supports(Class<?> authentication) {
}

@Override
public Authentication authenticate(Authentication authentication)
throws AuthenticationException {
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
JwtAuthenticationToken authenticationToken = (JwtAuthenticationToken) authentication;
return processAuthentication(authenticationToken);
}

private Authentication processAuthentication(JwtAuthenticationToken authenticationToken) {
User user = findUserUseCase.findUserByAuthId(
String.valueOf(authenticationToken.getPrincipal()));
try {
user.matchPassword(passwordEncoder,
String.valueOf(authenticationToken.getCredentials()));
return new JwtAuthenticationToken(
user.getId(), null, Collections.singleton(new SimpleGrantedAuthority("ROLE_USER"))
);
} catch (IllegalArgumentException e) {
User user = findUserUseCase.findUserByAuthId(String.valueOf(authenticationToken.getPrincipal()));
String userPassword = String.valueOf(authenticationToken.getCredentials());
if(!user.matchPassword(passwordEncoder, userPassword)) {
throw new UnAuthorizedException(INCORRECT_PASSWORD.toString());
}
return new JwtAuthenticationToken(
user.getId(), null, Collections.singleton(new SimpleGrantedAuthority("ROLE_USER"))
);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,65 +4,70 @@

import com.plzgraduate.myongjigraduatebe.takenlecture.domain.model.TakenLecture;
import com.plzgraduate.myongjigraduatebe.takenlecture.domain.model.TakenLectureInventory;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import lombok.Builder;
import lombok.Getter;

@Getter
public class NormalCultureGraduationResult {

private final String categoryName;
private final int totalCredit;
private boolean isCompleted;
private int takenCredit;
private static final String VOLUNTEER_CREDIT_CODE = "KMA02198";

@Builder
private NormalCultureGraduationResult(String categoryName, boolean isCompleted, int totalCredit,
int takenCredit) {
this.categoryName = categoryName;
this.isCompleted = isCompleted;
this.totalCredit = totalCredit;
this.takenCredit = takenCredit;
}
private final String categoryName;
private final int totalCredit;
private boolean isCompleted;
private int takenCredit;

public static NormalCultureGraduationResult create(int totalCredit,
TakenLectureInventory takenLectureInventory,
List<DetailGraduationResult> detailGraduationResults) {
return NormalCultureGraduationResult.builder()
.categoryName(NORMAL_CULTURE.getName())
.isCompleted(false)
.totalCredit(totalCredit)
.takenCredit(calculateTakenCredit(takenLectureInventory, detailGraduationResults))
.build();
}
@Builder
private NormalCultureGraduationResult(String categoryName, boolean isCompleted, int totalCredit,
int takenCredit) {
this.categoryName = categoryName;
this.isCompleted = isCompleted;
this.totalCredit = totalCredit;
this.takenCredit = takenCredit;
}

private static int calculateTakenCredit(TakenLectureInventory takenLectureInventory,
List<DetailGraduationResult> detailGraduationResults) {
int remainCreditByDetailGraduationResult = detailGraduationResults.stream()
.mapToInt(DetailGraduationResult::getNormalLeftCredit)
.sum();
public static NormalCultureGraduationResult create(int totalCredit,
TakenLectureInventory takenLectureInventory,
List<DetailGraduationResult> detailGraduationResults) {
return NormalCultureGraduationResult.builder()
.categoryName(NORMAL_CULTURE.getName())
.isCompleted(false)
.totalCredit(totalCredit)
.takenCredit(calculateTakenCredit(takenLectureInventory, detailGraduationResults))
.build();
}

Set<TakenLecture> remainTakenNormalCultures = takenLectureInventory.getCultureLectures();
int remainCreditByTakenLectures = remainTakenNormalCultures.stream()
.mapToInt(takenLecture -> takenLecture.getLecture()
.getCredit())
.sum();
private static int calculateTakenCredit(TakenLectureInventory takenLectureInventory,
List<DetailGraduationResult> detailGraduationResults) {
int remainCreditByDetailGraduationResult = detailGraduationResults.stream()
.mapToInt(DetailGraduationResult::getNormalLeftCredit)
.sum();
Set<TakenLecture> remainTakenNormalCultures = takenLectureInventory.getCultureLectures().stream()
.filter(takenLecture -> !takenLecture.getLecture().getId().equals(VOLUNTEER_CREDIT_CODE))
.collect(Collectors.toSet());
int remainCreditByTakenLectures = remainTakenNormalCultures.stream()
.mapToInt(takenLecture -> takenLecture.getLecture().getCredit())
.sum();
takenLectureInventory.handleFinishedTakenLectures(remainTakenNormalCultures);
return remainCreditByDetailGraduationResult + remainCreditByTakenLectures;
}

takenLectureInventory.handleFinishedTakenLectures(remainTakenNormalCultures);
return remainCreditByDetailGraduationResult + remainCreditByTakenLectures;
}

public void checkCompleted() {
this.isCompleted = takenCredit >= totalCredit;
}
public void checkCompleted() {
this.isCompleted = takenCredit >= totalCredit;
}

public int getLeftCredit() {
if (totalCredit >= takenCredit) {
return 0;
}
int leftCredit = takenCredit - totalCredit;
this.takenCredit = totalCredit;
return leftCredit;
}
public int getLeftCredit() {
if (totalCredit >= takenCredit) {
return 0;
}
int leftCredit = takenCredit - totalCredit;
this.takenCredit = totalCredit;
return leftCredit;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -72,4 +72,56 @@ void createFreeElectiveGraduationResult() {
remainCreditByTakenLectures + freeElectiveLeftCredit + leftNormalCultureCredit);
}

@DisplayName("봉사학점을 한 번 들었을 때 자유선택 졸업 결과를 생성한다.")
@Test
void createFreeElectiveGraduationResult_withOneVolunteerCredit() {
//given
User user = UserFixture.경영학과_19학번_ENG34();
Set<TakenLecture> takenLectures = new HashSet<>((Set.of(
TakenLecture.of(user, mockLectureMap.get("KMA02198"), 2021, Semester.FIRST) // 봉사학점
)));
TakenLectureInventory takenLectureInventory = TakenLectureInventory.from(takenLectures);

int totalFreeElectiveCredit = 7;
int leftNormalCultureCredit = 0;

//when
FreeElectiveGraduationResult freeElectiveGraduationResult = FreeElectiveGraduationResult.create(
totalFreeElectiveCredit,
takenLectureInventory,
List.of(),
leftNormalCultureCredit);

//then
assertThat(freeElectiveGraduationResult)
.extracting("categoryName", "takenCredit")
.contains(FREE_ELECTIVE.getName(), 1); // 봉사학점 1학점 반영
}

@DisplayName("봉사학점을 두 번 들었을 때 자유선택 졸업 결과를 생성한다.")
@Test
void createFreeElectiveGraduationResult_withTwoVolunteerCredits() {
//given
User user = UserFixture.경영학과_19학번_ENG34();
Set<TakenLecture> takenLectures = new HashSet<>((Set.of(
TakenLecture.of(user, mockLectureMap.get("KMA02198"), 2021, Semester.FIRST), // 봉사학점 1
TakenLecture.of(user, mockLectureMap.get("KMA02198"), 2022, Semester.SECOND) // 봉사학점 2
)));
TakenLectureInventory takenLectureInventory = TakenLectureInventory.from(takenLectures);

int totalFreeElectiveCredit = 7;
int leftNormalCultureCredit = 0;

//when
FreeElectiveGraduationResult freeElectiveGraduationResult = FreeElectiveGraduationResult.create(
totalFreeElectiveCredit,
takenLectureInventory,
List.of(),
leftNormalCultureCredit);

//then
assertThat(freeElectiveGraduationResult)
.extracting("categoryName", "takenCredit")
.contains(FREE_ELECTIVE.getName(), 2); // 봉사학점 2학점 반영
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -71,5 +71,27 @@ void createNormalCultureGraduationResult() {
.contains(NORMAL_CULTURE.getName(),
remainTakenNormalCultureCredit + remainCreditByDetailGraduationResult);
}
@DisplayName("봉사학점은 일반교양 학점에 포함되지 않는다.")
@Test
void volunteerCreditIsNotIncludedInNormalCulture() {
//given
User user = UserFixture.경영학과_19학번_ENG34();
Set<TakenLecture> takenLectures = new HashSet<>((Set.of(
TakenLecture.of(user, mockLectureMap.get("KMA00101"), 2019, Semester.FIRST),
TakenLecture.of(user, mockLectureMap.get("KMA02102"), 2019, Semester.FIRST),
TakenLecture.of(user, mockLectureMap.get("KMA02198"), 2021, Semester.FIRST) // 봉사학점
)));
TakenLectureInventory takenLectureInventory = TakenLectureInventory.from(takenLectures);

//when
NormalCultureGraduationResult normalCultureGraduationResult = NormalCultureGraduationResult.create(
9,
takenLectureInventory,
List.of());

//then
assertThat(normalCultureGraduationResult)
.extracting("takenCredit")
.isEqualTo(4); // 봉사학점(1학점)은 제외되고, 나머지 일반교양 학점만 포함
}
}
1 change: 1 addition & 0 deletions src/test/resources/lecture.csv
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ KMA02135, 우주생명마음, 3, 0, KMA02119
KMA02136, SW프로그래밍입문, 3, 0, null
KMA02138, 인공지능의세계, 3, 0, null
KMA02139, 4차산업혁명의이해, 3, 0, null
KMA02198, 봉사학점, 1, 0, null
KMB02127, 한국문화와문자생활, 3, 0, null
KMB02119, 영어와영미문화, 3, 1, null
KMB02120, 아랍의언어와문화, 3, 0, null
Expand Down

0 comments on commit e92125f

Please sign in to comment.