Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TEST] 출석 관련 단위 테스트 추가 및 행사 출석 로직 수정 #254

Merged
merged 9 commits into from
Apr 12, 2024
3 changes: 3 additions & 0 deletions operation-domain/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,7 @@ dependencies {

// https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind
implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.14.0-rc1'

// test
testImplementation 'org.springframework.boot:spring-boot-starter-test'
Comment on lines +29 to +30
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

우와 진짜 메이커스에서 테스트하는 것 감격...!!

}
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,13 @@ public class Attendance {
@OneToMany(mappedBy = "attendance")
private final List<SubAttendance> subAttendances = new ArrayList<>();

protected Attendance(Long id, Member member, Lecture lecture, AttendanceStatus status) {
this.id = id;
setMember(member);
setLecture(lecture);
this.status = status;
}

Comment on lines +51 to +57
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

protected 접근제어자와 id 직접 주입하는 것으로 미뤄보아
테스트를 위한 생성자인 듯 한데 맞을까요?!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@yummygyudon
넵 맞습니다!

public Attendance(Member member, Lecture lecture) {
setMember(member);
setLecture(lecture);
Expand Down Expand Up @@ -79,13 +86,12 @@ public AttendanceStatus getStatus() {
val second = getSubAttendanceByRound(2);

return switch (this.lecture.getAttribute()) {
case SEMINAR -> {
case SEMINAR, EVENT -> {
if (first.getStatus().equals(ATTENDANCE) && second.getStatus().equals(ATTENDANCE)) {
yield ATTENDANCE;
}
yield first.getStatus().equals(ABSENT) && second.getStatus().equals(ABSENT) ? ABSENT : TARDY;
}
case EVENT -> second.getStatus().equals(ATTENDANCE) ? ATTENDANCE : ABSENT;
case ETC -> second.getStatus().equals(ATTENDANCE) ? PARTICIPATE : NOT_PARTICIPATE;
};
}
Expand All @@ -103,7 +109,7 @@ public float getScore() {
yield 0f;
}
}
case EVENT -> this.status.equals(ATTENDANCE) ? 0.5f : 0f;
case EVENT -> this.status.equals(ABSENT) ? 0f : 0.5f;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

제가 행사 점수 연산 방식을 전달 드리기 전에 올리신 PR인 것 같습니다!
행사 또한 마찬가지로 1차 출석 / 2차 출석 여부 상관 없이
출석 완료 1회일 경우 동일한 0.5점인 것은 확인했습니다!!

Score 조회 메서드는 원용씨가 하신대로 가면될 듯 하구
상단에 있는 AttendanceStatus getStatus() 메서드 내 로직도 반영 부탁드려요!!

현재는 2차 출석값만 확인하는 로직인 듯 합니다!!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as-is

return switch (this.lecture.getAttribute()) {
			case SEMINAR -> {
				if (first.getStatus().equals(ATTENDANCE) && second.getStatus().equals(ATTENDANCE)) {
					yield ATTENDANCE;
				}
				yield first.getStatus().equals(ABSENT) && second.getStatus().equals(ABSENT) ? ABSENT : TARDY;
			}
			case EVENT -> second.getStatus().equals(ATTENDANCE) ? ATTENDANCE : ABSENT;
			case ETC -> second.getStatus().equals(ATTENDANCE) ? PARTICIPATE : NOT_PARTICIPATE;
		};

to-be
이번에 변경된 세미나(SEMINAR)의 상태 값 연산과 동일하게 가면 될 것 같아요!

  • 점수 반영은 "출석"과 "지각" 모두 +0.5 이긴 하나 상태는 달라야 합니다!
return switch (this.lecture.getAttribute()) {
			case SEMINAR -> {
				if (first.getStatus().equals(ATTENDANCE) && second.getStatus().equals(ATTENDANCE)) {
					yield ATTENDANCE;
				}
				yield first.getStatus().equals(ABSENT) && second.getStatus().equals(ABSENT) ? ABSENT : TARDY;
			}
			case EVENT -> {
				if (first.getStatus().equals(ATTENDANCE) && second.getStatus().equals(ATTENDANCE)) {
					yield ATTENDANCE;
				}
				yield first.getStatus().equals(ABSENT) && second.getStatus().equals(ABSENT) ? ABSENT : TARDY;
			case ETC -> second.getStatus().equals(ATTENDANCE) ? PARTICIPATE : NOT_PARTICIPATE;
		};

메서드 길이가 길어지는 문제와 함께 중복되는 코드가 발생하는 문제가 존재할 것 같은데
두 switch case 에 두 요소(SEMINAR & EVENT)를 합쳐서 처리해도 괜찮을 것 같아요!!
원용씨 의견은 어떤가요?!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@yummygyudon
넵 고려해서 행사 관련한 getStatus 테스트도 만들어서 반영하고 로직 수정해보겠습니다!
감사합니다!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

8abf1d4 , e25492f

코드 중복이라고 생각하여 EVENT, SEMINAR 를 같은 CASE에 두는 방식으로 적용해봤습니다!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

행사도 연산 점수 로직 바뀐거 확인했습니다 ! 동규님 꼼꼼하게 체크해주시고 바로 반영해준 원용님 감사합니다 ~!

default -> 0f;
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,13 @@ public SubAttendance(Attendance attendance, SubLecture subLecture) {
status = ABSENT;
}

protected SubAttendance(Long id, Attendance attendance, SubLecture subLecture, AttendanceStatus status) {
this.id = id;
setAttendance(attendance);
setSubLecture(subLecture);
this.status = status;
}

private void setAttendance(Attendance attendance) {
if (Objects.nonNull(this.attendance)) {
this.attendance.getSubAttendances().remove(this);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,18 @@ public Lecture(
this.lectureStatus = BEFORE;
}

protected Lecture(Long id, String name, Part part, int generation, String place, LocalDateTime startDate, LocalDateTime endDate, Attribute attribute, LectureStatus lectureStatus) {
this.id = id;
this.name = name;
this.part = part;
this.generation = generation;
this.place = place;
this.startDate = startDate;
this.endDate = endDate;
this.attribute = attribute;
this.lectureStatus = lectureStatus;
}

public void updateStatus(LectureStatus status) {
this.lectureStatus = status;
}
Expand All @@ -101,4 +113,9 @@ public boolean isFirst() {
public boolean isNotYetToEnd() {
return this.endDate.isAfter(LocalDateTime.now());
}

protected void setOneToMany(List<SubLecture> subLectures, List<Attendance> attendances) {
this.subLectures = subLectures;
this.attendances = attendances;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,14 @@ public class SubLecture {
@OneToMany(mappedBy = "subLecture")
private final List<SubAttendance> subAttendances = new ArrayList<>();

protected SubLecture(Long id, Lecture lecture, int round, LocalDateTime startAt, String code) {
this.id = id;
setLecture(lecture);
this.round = round;
this.startAt = startAt;
this.code = code;
}

public SubLecture(Lecture lecture, int round) {
setLecture(lecture);
this.round = round;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,19 @@ public class Member {
@OneToMany(mappedBy = "member")
List<Attendance> attendances = new ArrayList<>();

protected Member(Long id, Long playgroundId, String name, int generation, ObYb obyb, Part part, String university, float score, String phone, List<Attendance> attendances) {
this.id = id;
this.playgroundId = playgroundId;
this.name = name;
this.generation = generation;
this.obyb = obyb;
this.part = part;
this.university = university;
this.score = score;
this.phone = phone;
this.attendances = attendances;
}

public void updateScore(float score) {
this.score += score;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
package org.sopt.makers.operation.attendance.domain;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.sopt.makers.operation.common.domain.Part;
import org.sopt.makers.operation.dummy.AttendanceDummy;
import org.sopt.makers.operation.dummy.LectureDummy;
import org.sopt.makers.operation.dummy.MemberDummy;
import org.sopt.makers.operation.lecture.domain.Attribute;
import org.sopt.makers.operation.lecture.domain.Lecture;
import org.sopt.makers.operation.lecture.domain.LectureStatus;
import org.sopt.makers.operation.member.domain.Member;

import java.time.LocalDateTime;
import java.util.ArrayList;

import static org.assertj.core.api.AssertionsForClassTypes.assertThat;

public class AttendanceGetScoreTest {

private Member member;

@BeforeEach
void setUp() {
member = MemberDummy.builder()
.id(1L)
.attendances(new ArrayList<>())
.build();
}

@Nested
@DisplayName("[세미나 출석 점수 반환 테스트]")
public class SeminarTest {
@Test
@DisplayName("세미나에 출석을 했으면 0f를 반환한다.")
public void getScoreTest() {
// given
Lecture lecture = new LectureDummy(1L, "서버 1차 세미나", Part.SERVER, 34, "오산역", LocalDateTime.now(), LocalDateTime.now(), Attribute.SEMINAR, LectureStatus.BEFORE);
Attendance attendance = new AttendanceDummy(1L, member, lecture, AttendanceStatus.ATTENDANCE);

// when
float score = attendance.getScore();

// then
assertThat(score).isEqualTo(0f);
}

@Test
@DisplayName("세미나에 지각을 했으면 -0.5f를 반환한다.")
public void getScoreTest2() {
// given
Lecture lecture = new LectureDummy(1L, "서버 1차 세미나", Part.SERVER, 34, "오산역", LocalDateTime.now(), LocalDateTime.now(), Attribute.SEMINAR, LectureStatus.BEFORE);
Attendance attendance = new AttendanceDummy(1L, member, lecture, AttendanceStatus.TARDY);

// when
float score = attendance.getScore();

// then
assertThat(score).isEqualTo(-0.5f);
}

@Test
@DisplayName("세미나에 결석을 했으면 -1f를 반환한다.")
public void getScoreTest3() {
// given
Lecture lecture = new LectureDummy(1L, "서버 1차 세미나", Part.SERVER, 34, "오산역", LocalDateTime.now(), LocalDateTime.now(), Attribute.SEMINAR, LectureStatus.BEFORE);
Attendance attendance = new AttendanceDummy(1L, member, lecture, AttendanceStatus.ABSENT);

// when
float score = attendance.getScore();

// then
assertThat(score).isEqualTo(-1f);
}
}

@Nested
@DisplayName("[행사 출석 점수 반환 테스트]")
public class EventTest {
@Test
@DisplayName("행사에 출석을 했으면 0.5f를 반환한다.")
public void getScoreTest() {
// given
Lecture lecture = new LectureDummy(1L, "서버 1차 세미나", Part.SERVER, 34, "오산역", LocalDateTime.now(), LocalDateTime.now(), Attribute.EVENT, LectureStatus.BEFORE);
Attendance attendance = new AttendanceDummy(1L, member, lecture, AttendanceStatus.ATTENDANCE);

// when
float score = attendance.getScore();

// then
assertThat(score).isEqualTo(0.5f);
}

@Test
@DisplayName("행사에 지각을 했으면 0.5f를 반환한다.")
public void getScoreTest2() {
// given
Lecture lecture = new LectureDummy(1L, "서버 1차 세미나", Part.SERVER, 34, "오산역", LocalDateTime.now(), LocalDateTime.now(), Attribute.EVENT, LectureStatus.BEFORE);
Attendance attendance = new AttendanceDummy(1L, member, lecture, AttendanceStatus.TARDY);

// when
float score = attendance.getScore();

// then
assertThat(score).isEqualTo(0.5f);
}

@Test
@DisplayName("행사에 결석을 했으면 0f를 반환한다.")
public void getScoreTest3() {
// given
Lecture lecture = new LectureDummy(1L, "서버 1차 세미나", Part.SERVER, 34, "오산역", LocalDateTime.now(), LocalDateTime.now(), Attribute.EVENT, LectureStatus.BEFORE);
Attendance attendance = new AttendanceDummy(1L, member, lecture, AttendanceStatus.ABSENT);

// when
float score = attendance.getScore();

// then
assertThat(score).isEqualTo(0f);
}
}
}
Loading
Loading