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

added route for verify user and get enrollment requests #44

Merged
merged 1 commit into from
Mar 20, 2024
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
52 changes: 49 additions & 3 deletions app/routes/course.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.orm import Session
from sqlalchemy import and_, or_
from sqlalchemy import and_, asc, or_
from ..utils.db import get_db
from ..utils.utils import hash
from ..models import user_model, course_model
Expand Down Expand Up @@ -287,7 +287,7 @@ async def enroll(
user: user_schema.UserSignIn,
db: Session = Depends(get_db),
):
""" returns all student courses that are pending or rejected """
""" enrolls a student in a course """

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

Expand Down Expand Up @@ -346,4 +346,50 @@ async def enroll(
db.commit()
db.refresh(enrollment_data)

return {"message": "user enrollment request registered successfully"}
return {"message": "user enrollment request registered successfully"}

@router.post(
"/enrollment_status",
status_code=200,
response_model=List[course_schema.CourseEnrollmentView]
)
async def enrollment_status(
user: user_schema.UserSignIn,
db: Session = Depends(get_db),
):
""" returns list of enrollment requests """

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

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

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

if user.role != user_model.RoleEnum.admin:
raise HTTPException(
status_code=status.HTTP_417_EXPECTATION_FAILED,
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)
.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)
.filter(course_model.Enrollment.status == course_model.StatusEnum.pending)
.order_by(asc(course_model.Enrollment.created_at))
.all()
)

return query
50 changes: 48 additions & 2 deletions app/routes/user.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.orm import Session
from sqlalchemy import and_
from sqlalchemy import and_, desc
from ..utils.db import get_db
from ..utils.utils import hash
from ..models import user_model
Expand Down Expand Up @@ -208,7 +208,53 @@ async def verification_status(
db
.query(user_model.User)
.filter(user_model.User.verified == False)
.order_by(desc(user_model.User.created_at))
.all()
)

return query
return query


@router.patch(
"/verify",
status_code=200,
)
async def verify(
user: user_schema.UserVerificationRequest,
db: Session = Depends(get_db),
):
""" Verifies a user """

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"
)

client_user = db.query(user_model.User).filter(user_model.User.email == user.user_email).first()

if not client_user:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="User not found"
)

client_user.verified = True
db.commit()
db.refresh(client_user)

return {"message" : "User Verified"}
12 changes: 12 additions & 0 deletions app/schemas/course_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,17 @@ class CourseStatusStudent(BaseModel):
status: course_model.StatusEnum
comment: Optional[str]

class Config:
from_attributes = True

class CourseEnrollmentView(BaseModel):
first_name: str
last_name: Optional[str]
email: str
dept: course_model.DeptEnum
code: int
year: int
term: course_model.TermEnum

class Config:
from_attributes = True
25 changes: 24 additions & 1 deletion app/schemas/user_schema.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from typing import Optional
from pydantic import BaseModel
from ..models import user_model
from ..models import user_model, course_model

class UserSignIn(BaseModel):
email: str
Expand Down Expand Up @@ -37,18 +37,27 @@ class User(BaseModel):
role: user_model.RoleEnum
verified: bool

class Config:
from_attributes = True

class Admin(BaseModel):
user: User
admin_id: int
contact: Optional[str]
office: Optional[str]

class Config:
from_attributes = True

class Teacher(BaseModel):
user: User
teacher_id: int
faculty: Optional[str]
office: Optional[str]
contact: Optional[str]

class Config:
from_attributes = True

class Student(BaseModel):
user: User
Expand All @@ -57,8 +66,22 @@ class Student(BaseModel):
year: Optional[int]
degree: Optional[user_model.DegreeEnum]

class Config:
from_attributes = True

class UserVerifcationView(BaseModel):
first_name: str
last_name: Optional[str]
email: str
role: user_model.RoleEnum

class Config:
from_attributes = True

class UserVerificationRequest(BaseModel):
email: str
password: str
user_email: str

class Config:
from_attributes = True
11 changes: 11 additions & 0 deletions test/course/test_get_enrollment.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from test.test_fixtures import *

def test_get_enrollment(authorized_client, test_enrollment, test_verified_admin_1):
res = authorized_client.post("/course/enrollment_status",json={'email': '[email protected]', 'password': 'password'})
assert res.status_code == 200
assert len(res.json()) == 1

def test_get_enrollment_with_unverified_admin(authorized_client, test_enrollment, test_unverified_user):
res = authorized_client.post("/course/enrollment_status",json={'email': '[email protected]', 'password': 'password'})
assert res.status_code == 417
assert res.json()["detail"] == "User is not verified"
11 changes: 11 additions & 0 deletions test/user/test_verify_user.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from test.test_fixtures import *

def test_verify_user(authorized_client, test_unverified_user, test_verified_admin_1):
res = authorized_client.patch("/user/verify",json={'email': '[email protected]', 'password': 'password', 'user_email': test_unverified_user[0].email})
assert res.status_code == 200
assert test_unverified_user[0].verified

def test_verify_user_with_unverified_admin(authorized_client, test_unverified_user):
res = authorized_client.patch("/user/verify",json={'email': test_unverified_user[2].email, 'password': 'password', 'user_email': test_unverified_user[0].email})
assert res.status_code == 417
assert res.json()["detail"]=="User is not verified"
Loading