Skip to content

Commit

Permalink
Admin student (#46)
Browse files Browse the repository at this point in the history
* added enrollment handler route

* fixed unit testing

* HOTFIX: FIXES IN GET STUDENT COURSE DATA

* fixed course seats check
  • Loading branch information
Jupiter-is-BIG authored Mar 20, 2024
1 parent 3eb9892 commit c778a8b
Show file tree
Hide file tree
Showing 4 changed files with 136 additions and 7 deletions.
104 changes: 97 additions & 7 deletions app/routes/course.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ async def get_student_courses(
.join(course_model.Student, course_model.Enrollment.student_id == course_model.Student.id)
.join(user_model.Teacher, user_model.Teacher.id == course_model.Course.teacher_id)
.join(user_model.User, user_model.User.id == user_model.Teacher.user_id)
.filter(course_model.Enrollment.status == course_model.StatusEnum.approved)
.filter(and_(course_model.Enrollment.status == course_model.StatusEnum.approved,course_model.Enrollment.student_id==student.id))
.all()
)

Expand Down Expand Up @@ -251,7 +251,7 @@ async def get_student_status_courses(
.join(course_model.Student, course_model.Enrollment.student_id == course_model.Student.id)
.join(user_model.Teacher, user_model.Teacher.id == course_model.Course.teacher_id)
.join(user_model.User, user_model.User.id == user_model.Teacher.user_id)
.filter(or_(course_model.Enrollment.status == course_model.StatusEnum.pending, course_model.Enrollment.status == course_model.StatusEnum.declined))
.filter(and_(or_(course_model.Enrollment.status == course_model.StatusEnum.pending, course_model.Enrollment.status == course_model.StatusEnum.declined),course_model.Enrollment.student_id==student.id))
.all()
)

Expand Down Expand Up @@ -323,6 +323,12 @@ async def enroll(
detail="No such active course found"
)

if course.taken_seats == course.total_seats:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail="No seats available in the course"
)

check_enrollment = (
db.query(course_model.Enrollment)
.filter(and_(course_model.Enrollment.student_id==student.id, course_model.Enrollment.course_id==course_id))
Expand Down Expand Up @@ -379,11 +385,8 @@ async def enrollment_status(
detail="User is not an admin"
)



query = (
db
.query(user_model.User.first_name, user_model.User.last_name, user_model.User.email, course_model.Course.dept, course_model.Course.code, course_model.Course.year, course_model.Course.term)
db.query(course_model.Enrollment.student_id, course_model.Enrollment.course_id, user_model.User.first_name, user_model.User.last_name, user_model.User.email, course_model.Course.dept, course_model.Course.code, course_model.Course.year, course_model.Course.term)
.join(user_model.Student, user_model.User.id == user_model.Student.user_id)
.join(course_model.Enrollment, user_model.Student.id == course_model.Enrollment.student_id)
.join(course_model.Course, course_model.Course.id == course_model.Enrollment.course_id)
Expand All @@ -392,4 +395,91 @@ async def enrollment_status(
.all()
)

return query
return query



@router.patch(
"/enrollment_update/{dir}",
status_code=201,
)
async def enrollment_update(
dir: int, # dir: 0 approve, 1: reject
user: course_schema.CourseEnrollmentUpdate,
db: Session = Depends(get_db),
):
""" updates the enrollment status of an enrollment request """

admin = db.query(user_model.User).filter(and_(user_model.User.email == user.email,user_model.User.password == hash(user.password))).first()

if not admin:
raise HTTPException(
status_code=status.HTTP_409_CONFLICT,
detail="Wrong email and password combination"
)

if not admin.verified:
raise HTTPException(
status_code=status.HTTP_417_EXPECTATION_FAILED,
detail="User is not verified"
)

if admin.role != user_model.RoleEnum.admin:
raise HTTPException(
status_code=status.HTTP_417_EXPECTATION_FAILED,
detail="User is not an admin"
)


course = db.query(course_model.Course).filter(course_model.Course.id == user.course_id).first()
if not course:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="no such course found"
)

decision = None


if dir == 0:
decision = course_model.StatusEnum.approved
if course.total_seats == course.taken_seats:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail="no seats available"
)
elif dir == 1:
decision = course_model.StatusEnum.declined
else:
raise HTTPException(
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
detail="dir must be either 0 or 1"
)

query = (
db
.query(course_model.Enrollment)
.filter(and_(course_model.Enrollment.student_id==user.student_id, course_model.Enrollment.course_id==user.course_id))
.first()
)

if not query:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="no such enrollment request found"
)

if query.status == course_model.StatusEnum.approved and dir == 1:
course.taken_seats -= 1
elif query.status != course_model.StatusEnum.approved and dir == 0:
course.taken_seats += 1

db.commit()
db.refresh(course)

query.status = decision
query.comment = user.comment
db.commit()
db.refresh(query)

return {"message": "enrollment request processed successfully"}
12 changes: 12 additions & 0 deletions app/schemas/course_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ class Config:
from_attributes = True

class CourseEnrollmentView(BaseModel):
student_id: int
course_id: int
first_name: str
last_name: Optional[str]
email: str
Expand All @@ -50,5 +52,15 @@ class CourseEnrollmentView(BaseModel):
year: int
term: course_model.TermEnum

class Config:
from_attributes = True

class CourseEnrollmentUpdate(BaseModel):
email: str
password: str
student_id: int
course_id: int
comment: Optional[str]

class Config:
from_attributes = True
2 changes: 2 additions & 0 deletions app/utils/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@ def populatedb(db: Session = Depends(get_db)):
year=2024,
credits=3,
total_seats=100,
taken_seats=1,
status=course_model.CourseStatusEnum.active,
teacher_id = teacher_2.id
)
Expand All @@ -205,6 +206,7 @@ def populatedb(db: Session = Depends(get_db)):
year=2024,
credits=3,
total_seats=60,
taken_seats=1,
status=course_model.CourseStatusEnum.active,
teacher_id = teacher_2.id
)
Expand Down
25 changes: 25 additions & 0 deletions test/course/test_admin_decision_enrollment.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
from test.test_fixtures import *

def test_approve_enrollment(authorized_client, test_enrollment, test_verified_admin_1):
res = authorized_client.patch(f"/course/enrollment_update/0",json={'email': '[email protected]', 'password': 'password', 'student_id': test_enrollment[2].student_id, 'course_id': test_enrollment[2].course_id, 'comment': None})

assert res.status_code == 201
assert test_enrollment[2].status == course_model.StatusEnum.approved

def test_decline_enrollment(authorized_client, test_enrollment, test_verified_admin_1):
res = authorized_client.patch(f"/course/enrollment_update/1",json={'email': '[email protected]', 'password': 'password', 'student_id': test_enrollment[2].student_id, 'course_id': test_enrollment[2].course_id, 'comment': None})

assert res.status_code == 201
assert test_enrollment[2].status == course_model.StatusEnum.declined

def test_invalid_enrollment(authorized_client, test_enrollment, test_verified_admin_1):
res = authorized_client.patch(f"/course/enrollment_update/2",json={'email': '[email protected]', 'password': 'password', 'student_id': test_enrollment[2].student_id, 'course_id': test_enrollment[2].course_id, 'comment': None})

assert res.status_code == 422
assert res.json()["detail"] == "dir must be either 0 or 1"

def test_enrollment_for_non_exisitant_entry(authorized_client, test_enrollment, test_verified_admin_1):
res = authorized_client.patch(f"/course/enrollment_update/0",json={'email': '[email protected]', 'password': 'password', 'student_id': test_enrollment[2].student_id + 1, 'course_id': test_enrollment[2].course_id - 1, 'comment': None})

assert res.status_code == 404
assert res.json()["detail"] == "no such enrollment request found"

0 comments on commit c778a8b

Please sign in to comment.