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

Feat: 전공 선택, 교양 필수 조회 API 구현 #20

Merged
merged 2 commits into from
Feb 4, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.yourssu.soongpt.domain.course.application

import com.yourssu.soongpt.common.business.dto.Response
import com.yourssu.soongpt.domain.course.application.dto.GeneralRequiredCourseRequest
import com.yourssu.soongpt.domain.course.application.dto.MajorElectiveCourseRequest
import com.yourssu.soongpt.domain.course.application.dto.MajorRequiredCourseRequest
import com.yourssu.soongpt.domain.course.business.CourseService
import com.yourssu.soongpt.domain.course.business.dto.CourseResponse
Expand All @@ -21,4 +23,16 @@ class CourseController(
val response = courseService.findByDepartmentNameInMajorRequired(request.department)
return ResponseEntity.ok().body(Response(result = response))
}

@GetMapping("/major/elective")
fun getMajorElectiveCourses(@Valid @ModelAttribute request: MajorElectiveCourseRequest): ResponseEntity<Response<List<CourseResponse>>> {
val response = courseService.findByDepartmentNameInMajorElective(request.department)
return ResponseEntity.ok().body(Response(result = response))
}

@GetMapping("/general/required")
fun getGeneralRequiredCourses(@Valid @ModelAttribute request: GeneralRequiredCourseRequest): ResponseEntity<Response<List<CourseResponse>>> {
val response = courseService.findByDepartmentNameInGeneralRequired(request.department)
return ResponseEntity.ok().body(Response(result = response))
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.yourssu.soongpt.domain.course.application.dto

import jakarta.validation.constraints.NotBlank
import org.hibernate.validator.constraints.Range

data class GeneralRequiredCourseRequest(
@Range(min = 15, max = 25, message = "학번은 15부터 25까지 가능합니다.")
val schoolId: Long,

@NotBlank
val department: String,

@Range(min = 1, max = 5, message = "학년은 1부터 5까지 가능합니다.")
val grade: Int,
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.yourssu.soongpt.domain.course.application.dto

import jakarta.validation.constraints.NotBlank
import org.hibernate.validator.constraints.Range

data class MajorElectiveCourseRequest(
@Range(min = 15, max = 25, message = "학번은 15부터 25까지 가능합니다.")
val schoolId: Long,

@NotBlank
val department: String,

@Range(min = 1, max = 5, message = "학년은 1부터 5까지 가능합니다.")
val grade: Int,
) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,24 @@ class CourseService(
CourseResponse.from(course = it, target = targets, courseTimes = courseTimes)
}
}

fun findByDepartmentNameInMajorElective(departmentName: String): List<CourseResponse> {
val department = departmentReader.getByName(departmentName)
val courses = courseReader.findAllByDepartmentIdInMajorElective(department.id!!)
return courses.map {
val targets = targetReader.findAllBy(courseId = it.id!!, department = department)
val courseTimes = courseTimeReader.findAllByCourseId(it.id)
CourseResponse.from(course = it, target = targets, courseTimes = courseTimes)
}
}

fun findByDepartmentNameInGeneralRequired(departmentName: String): List<CourseResponse> {
val department = departmentReader.getByName(departmentName)
val courses = courseReader.findAllByDepartmentIdInGeneralRequired(department.id!!)
return courses.map {
val targets = targetReader.findAllBy(courseId = it.id!!, department = department)
val courseTimes = courseTimeReader.findAllByCourseId(it.id)
CourseResponse.from(course = it, target = targets, courseTimes = courseTimes)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,12 @@ class CourseReader(
fun findAllByDepartmentIdInMajorRequired(departmentId: Long): List<Course> {
return courseRepository.findAllByDepartmentId(departmentId, Classification.MAJOR_REQUIRED)
}

fun findAllByDepartmentIdInMajorElective(departmentId: Long): List<Course> {
return courseRepository.findAllByDepartmentId(departmentId, Classification.MAJOR_ELECTIVE)
}

fun findAllByDepartmentIdInGeneralRequired(departmentId: Long): List<Course> {
return courseRepository.findAllByDepartmentId(departmentId, Classification.GENERAL_REQUIRED)
}
}
16 changes: 15 additions & 1 deletion src/main/resources/http/course.http
Original file line number Diff line number Diff line change
@@ -1,8 +1,22 @@
// 전공 필수 과목 조회

@schoolId = 21
@department = 소프트웨어학부
@grade = 1

// 전공 필수 과목 조회
###
GET localhost:8080/api/courses/major/required?schoolId={{schoolId}}&department={{department}}&grade={{grade}}
Content-Type: application/x-www-form-urlencoded
###

// 전공 선택 과목 조회
###
GET localhost:8080/api/courses/major/elective?schoolId={{schoolId}}&department={{department}}&grade={{grade}}
Content-Type: application/x-www-form-urlencoded
###

// 교양 핈 과목 조회
###
GET localhost:8080/api/courses/general/required?schoolId={{schoolId}}&department={{department}}&grade={{grade}}
Content-Type: application/x-www-form-urlencoded
###
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,22 @@ enum class CourseFixture(
classification = Classification.MAJOR_REQUIRED,
courseCode = 1,
credit = 3,
);
),
MAJOR_ELECTIVE(
courseName = "전공선택",
professorName = "교수명",
classification = Classification.MAJOR_ELECTIVE,
courseCode = 2,
credit = 3,
),
GENERAL_REQUIRED(
courseName = "교양필수",
professorName = "교수명",
classification = Classification.GENERAL_REQUIRED,
courseCode = 3,
credit = 3,
)
;

fun toDomain(courseCode: Int = this.courseCode): Course {
return Course(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,4 +67,68 @@ class CourseServiceTest {
}
}
}

@Nested
@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores::class)
inner class findByDepartmentNameInMajorElective_메서드는 {
@Nested
@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores::class)
inner class 학과를_받으면 {
val departmentName = "소프트웨어학부"
@BeforeEach
fun setUp() {
initializer.run()
val course = courseRepository.save(CourseFixture.MAJOR_ELECTIVE.toDomainRandomCourseCode())
val departmentGrade = jpaQueryFactory.selectFrom(departmentGradeEntity)
.innerJoin(departmentEntity)
.on(departmentGradeEntity.departmentId.eq(departmentEntity.id))
.where(departmentEntity.name.eq(departmentName), departmentGradeEntity.grade.eq(4))
.fetchOne()
?.toDomain()
?: throw IllegalArgumentException("소프트웨어학부 4학년이 존재하지 않습니다.")
targetRepository.save(Target(departmentGradeId = departmentGrade.id!!, courseId = course.id!!))
courseTimeRepository.save(CourseTimeFixture.MONDAY_17_19.toDomain(course.id!!))
}

@Test
@DisplayName("해당 학과가 수강대상인 과목 정보를 반환한다.")
fun success() {
val response = courseService.findByDepartmentNameInMajorElective(departmentName)

assertEquals(1, response.size)
}
}
}

@Nested
@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores::class)
inner class findByDepartmentNameInGeneralRequired_메서드는 {
@Nested
@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores::class)
inner class 학과를_받으면 {
val departmentName = "소프트웨어학부"
@BeforeEach
fun setUp() {
initializer.run()
val course = courseRepository.save(CourseFixture.GENERAL_REQUIRED.toDomainRandomCourseCode())
val departmentGrade = jpaQueryFactory.selectFrom(departmentGradeEntity)
.innerJoin(departmentEntity)
.on(departmentGradeEntity.departmentId.eq(departmentEntity.id))
.where(departmentEntity.name.eq(departmentName), departmentGradeEntity.grade.eq(4))
.fetchOne()
?.toDomain()
?: throw IllegalArgumentException("소프트웨어학부 4학년이 존재하지 않습니다.")
targetRepository.save(Target(departmentGradeId = departmentGrade.id!!, courseId = course.id!!))
courseTimeRepository.save(CourseTimeFixture.MONDAY_17_19.toDomain(course.id!!))
}

@Test
@DisplayName("해당 학과가 수강대상인 과목 정보를 반환한다.")
fun success() {
val response = courseService.findByDepartmentNameInGeneralRequired(departmentName)

assertEquals(1, response.size)
}
}
}
}