Skip to content

Commit

Permalink
fix(be): Fix backend tests (#1164)
Browse files Browse the repository at this point in the history
* Fix all token related backend tests

* fix some tests

* fix a couple of more tests

* fix a bunch more tests

* all backend tests pass

* Refactor get_token

* Delete debugging print statement

* fix: added timeout to test utility request

---------

Co-authored-by: Peter Derias <peter.derias@gmail.com>
  • Loading branch information
lhvy and Peedee2002 authored Jul 26, 2024
1 parent abf05fd commit fe22a61
Show file tree
Hide file tree
Showing 24 changed files with 241 additions and 161 deletions.
2 changes: 1 addition & 1 deletion backend/algorithms/objects/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ def wam(self, category: Category = AnyCategory()) -> Tuple[Optional[float], bool
counted_uoc += uoc
total_mark += uoc * grade

return (None if counted_uoc == 0 else total_mark / counted_uoc, total_uoc == counted_uoc)
return (None if counted_uoc == 0 else total_mark / counted_uoc, total_uoc == counted_uoc and counted_uoc != 0)

def uoc(self, category: Category = AnyCategory()):
""" Given a user, returns the number of units they have taken for this uoc category """
Expand Down
16 changes: 16 additions & 0 deletions backend/algorithms/tests/exampleUsers.json
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,16 @@
"COMP1511": [6, 100]
}
},
"user_one_math": {
"program": "3707",
"specialisations": [
"COMPA1",
"ACCTA2"
],
"courses": {
"MATH1131": [6, 100]
}
},
"user_fail_comp1511": {
"program": "3707",
"specialisations": [
Expand All @@ -131,5 +141,11 @@
"courses": {
"COMP1511": [6, 50]
}
},
"user_degree_wizard": {
"programCode": "3778",
"startYear": 2020,
"endYear": 2023,
"specs": ["COMPA1", "ACCTA2"]
}
}
48 changes: 24 additions & 24 deletions backend/algorithms/tests/test_autoplanning.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from algorithms.objects.course import Course
from algorithms.objects.user import User
from algorithms.validate_term_planner import validate_terms
from pytest import mark, raises
from pytest import raises
from server.routers.model import CONDITIONS, ValidPlannerData


Expand All @@ -20,28 +20,28 @@ def test_basic_CS_autoplanning():
12, 20, 20, 20, 12, 20, 20, 20, 10, 20, 20, 20
],
[
Course("MATH1141", CONDITIONS["MATH1141"], 65, 6, {2020: [1, 3], 2021: [1, 3], 2022: [1, 3]}),
Course("MATH1081", CONDITIONS["MATH1081"], 65, 6, {2020: [1, 2, 3], 2021: [1, 2, 3], 2022: [1, 2, 3]}),
Course("COMP1511", CONDITIONS["COMP1511"], 65, 6, {2020: [1, 2, 3], 2021: [1, 2, 3], 2022: [1, 2, 3]}),
Course("COMP2521", CONDITIONS["COMP2521"], 65, 6, {2020: [2, 3], 2021: [2, 3], 2022: [2, 3]}),
Course("COMP2041", CONDITIONS["COMP2041"], 65, 6, {2020: [2], 2021: [2], 2022: [2]}),
Course("COMP1531", CONDITIONS["COMP1531"], 65, 6, {2020: [1, 3], 2021: [1, 3], 2022: [1, 3]}),
Course("COMP1521", CONDITIONS["COMP1521"], 65, 6, {2020: [1, 2], 2021: [1, 2], 2022: [1, 2]}),
Course("ENGG2600", CONDITIONS["ENGG2600"], 65, 2, {2020: [1, 2, 3], 2021: [1, 2, 3], 2022: [1, 2, 3]}),
Course("ENGG2600", CONDITIONS["ENGG2600"], 65, 2, {2020: [1, 2, 3], 2021: [1, 2, 3], 2022: [1, 2, 3]}),
Course("ENGG2600", CONDITIONS["ENGG2600"], 65, 2, {2020: [1, 2, 3], 2021: [1, 2, 3], 2022: [1, 2, 3]}),
Course("COMP2511", CONDITIONS["COMP2511"], 65, 6, {2020: [2, 3], 2021: [2, 3], 2022: [2, 3]}),
Course("MATH1241", CONDITIONS["MATH1241"], 65, 6, {2020: [2, 3], 2021: [2, 3], 2022: [2, 3]}),
Course("MATH3411", CONDITIONS["MATH3411"], 65, 6, {2020: [3], 2021: [3], 2022: [3]}),
Course("COMP3411", CONDITIONS["COMP3411"], 65, 6, {2020: [3], 2021: [0], 2022: [0]}),
Course("COMP6841", CONDITIONS["COMP6841"], 65, 6, {2020: [1], 2021: [1], 2022: [1]}),
Course("COMP3231", CONDITIONS["COMP3231"], 65, 6, {2020: [1], 2021: [1], 2022: [1]}),
Course("COMP3141", CONDITIONS["COMP3141"], 65, 6, {2020: [2], 2021: [2], 2022: [2]}),
Course("COMP3121", CONDITIONS["COMP3121"], 65, 6, {2020: [2, 3], 2021: [2, 3], 2022: [2, 3]}),
Course("COMP3131", CONDITIONS["COMP3131"], 65, 6, {2020: [1], 2021: [1], 2022: [1]}),
Course("COMP4141", CONDITIONS["COMP4141"], 65, 6, {2020: [1], 2021: [1], 2022: [1]}),
Course("COMP3901", CONDITIONS["COMP3901"], 65, 6, {2020: [1, 2, 3], 2021: [1, 2, 3], 2022: [1, 2, 3]}), # cores conditions
Course("ARTS1360", CONDITIONS["ARTS1360"], 65, 6, {2020: [2], 2021: [2], 2022: [2]}),
Course("MATH1141", CONDITIONS["MATH1141"], 85, 6, {2020: [1, 3], 2021: [1, 3], 2022: [1, 3]}),
Course("MATH1081", CONDITIONS["MATH1081"], 85, 6, {2020: [1, 2, 3], 2021: [1, 2, 3], 2022: [1, 2, 3]}),
Course("COMP1511", CONDITIONS["COMP1511"], 85, 6, {2020: [1, 2, 3], 2021: [1, 2, 3], 2022: [1, 2, 3]}),
Course("COMP2521", CONDITIONS["COMP2521"], 85, 6, {2020: [2, 3], 2021: [2, 3], 2022: [2, 3]}),
Course("COMP2041", CONDITIONS["COMP2041"], 85, 6, {2020: [2], 2021: [2], 2022: [2]}),
Course("COMP1531", CONDITIONS["COMP1531"], 85, 6, {2020: [1, 3], 2021: [1, 3], 2022: [1, 3]}),
Course("COMP1521", CONDITIONS["COMP1521"], 85, 6, {2020: [1, 2], 2021: [1, 2], 2022: [1, 2]}),
Course("ENGG2600", CONDITIONS["ENGG2600"], 85, 2, {2020: [1, 2, 3], 2021: [1, 2, 3], 2022: [1, 2, 3]}),
Course("ENGG2600", CONDITIONS["ENGG2600"], 85, 2, {2020: [1, 2, 3], 2021: [1, 2, 3], 2022: [1, 2, 3]}),
Course("ENGG2600", CONDITIONS["ENGG2600"], 85, 2, {2020: [1, 2, 3], 2021: [1, 2, 3], 2022: [1, 2, 3]}),
Course("COMP2511", CONDITIONS["COMP2511"], 85, 6, {2020: [2, 3], 2021: [2, 3], 2022: [2, 3]}),
Course("MATH1241", CONDITIONS["MATH1241"], 85, 6, {2020: [2, 3], 2021: [2, 3], 2022: [2, 3]}),
Course("MATH3411", CONDITIONS["MATH3411"], 85, 6, {2020: [3], 2021: [3], 2022: [3]}),
Course("COMP3411", CONDITIONS["COMP3411"], 85, 6, {2020: [3], 2021: [0], 2022: [0]}),
Course("COMP6841", CONDITIONS["COMP6841"], 85, 6, {2020: [1], 2021: [1], 2022: [1]}),
Course("COMP3231", CONDITIONS["COMP3231"], 85, 6, {2020: [1], 2021: [1], 2022: [1]}),
Course("COMP3141", CONDITIONS["COMP3141"], 85, 6, {2020: [2], 2021: [2], 2022: [2]}),
Course("COMP3121", CONDITIONS["COMP3121"], 85, 6, {2020: [2, 3], 2021: [2, 3], 2022: [2, 3]}),
Course("COMP3131", CONDITIONS["COMP3131"], 85, 6, {2020: [1], 2021: [1], 2022: [1]}),
Course("COMP4141", CONDITIONS["COMP4141"], 85, 6, {2020: [1], 2021: [1], 2022: [1]}),
Course("COMP3901", CONDITIONS["COMP3901"], 85, 6, {2020: [1, 2, 3], 2021: [1, 2, 3], 2022: [1, 2, 3]}), # cores conditions
Course("ARTS1360", CONDITIONS["ARTS1360"], 85, 6, {2020: [2], 2021: [2], 2022: [2]}),
],
"3778",
["COMPA1"]
Expand All @@ -64,7 +64,7 @@ def test_more_complex_prereqs():
Course("DESN1000", CONDITIONS["DESN1000"], 65, 2, {2020: [1, 3], 2021: [1, 3], 2022: [1, 3]}),
Course("DESN2000", CONDITIONS["DESN2000"], 65, 2, {2020: [2, 3], 2021: [2, 3], 2022: [2, 3]}), # terribly messy course prereq
Course("COMP2511", CONDITIONS["COMP2511"], 65, 6, {2020: [2, 3], 2021: [2, 3], 2022: [2, 3]}),
Course("MATH1241", CONDITIONS["MATH1141"], 65, 6, {2020: [2, 3], 2021: [2, 3], 2022: [2, 3]}),
Course("MATH1241", CONDITIONS["MATH1241"], 65, 6, {2020: [2, 3], 2021: [2, 3], 2022: [2, 3]}),
Course("MATH3411", CONDITIONS["MATH3411"], 65, 6, {2020: [3], 2021: [3], 2022: [3]}),
Course("COMP3411", CONDITIONS["COMP3411"], 65, 6, {2020: [3], 2021: [0], 2022: [0]}),
Course("COMP6441", CONDITIONS["COMP6441"], 65, 6, {2020: [1], 2021: [1], 2022: [1]}), # maturity requirement course
Expand Down
12 changes: 5 additions & 7 deletions backend/algorithms/tests/test_conditions.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,20 +160,18 @@ def test_wam_condition_simple():
})
cond1_user1_unlocked = cond1.validate(user1)
assert cond1_user1_unlocked[0]
assert len(cond1_user1_unlocked[1]) == 1
assert 'Requires 70 WAM in all courses.' in (cond1_user1_unlocked[1])[0]
assert len(cond1_user1_unlocked[1]) == 0

cond2 = create_condition((["(", "90WAM", ")"]))
cond2_user1_unlocked = cond2.validate(user1)
assert cond2_user1_unlocked[0]
assert len(cond2_user1_unlocked[1]) == 1
assert 'Requires 90 WAM in all courses.' in (cond2_user1_unlocked[1])[0]
assert len(cond2_user1_unlocked[1]) == 0

cond4 = create_condition((["(", "100WAM", ")"]))
cond4_user1_unlocked = cond4.validate(user1)
assert cond4_user1_unlocked[0]
assert not cond4_user1_unlocked[0]
assert len(cond4_user1_unlocked[1]) == 1
assert "Requires 100 WAM in all courses. Your WAM in all courses is currently 90.000" in cond4_user1_unlocked[1]
assert "((Requires 100 WAM in all courses. Your WAM in all courses is currently 90.000))" in cond4_user1_unlocked[1]

def test_wam_condition_complex():
'''Testing wam condition including keywords'''
Expand Down Expand Up @@ -204,7 +202,7 @@ def test_wam_condition_complex():
})

assert (comp_cond_70.validate(user1))[0]
assert (math_cond_70.validate(user1))[0]
assert not (math_cond_70.validate(user1))[0]
assert (comp_math_cond_70.validate(user1))[0]


Expand Down
2 changes: 1 addition & 1 deletion backend/algorithms/tests/test_user_loading.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ def test_user3():
assert user.in_specialisation("COMPA1")
wam, marks_complete = user.wam()
assert wam == None
assert marks_complete
assert not marks_complete
assert user.uoc() == 0

def test_user_no_data():
Expand Down
2 changes: 1 addition & 1 deletion backend/algorithms/tests/test_user_wam_uoc.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def test_course_category_produces_correct_wam():
comp = CourseCategory("COMP")
wam, marks_complete = user.wam(CourseCategory("FOOD"))
assert wam == None
assert marks_complete
assert not marks_complete

wam, marks_complete = user.wam(comp)
assert wam == 66
Expand Down
Binary file modified backend/data/final_data/conditions.pkl
Binary file not shown.
2 changes: 1 addition & 1 deletion backend/data/final_data/conditionsProcessed.json
Original file line number Diff line number Diff line change
Expand Up @@ -12696,4 +12696,4 @@
"original": "",
"processed": ""
}
}
}
Binary file modified backend/data/final_data/program_restrictions.pkl
Binary file not shown.
18 changes: 6 additions & 12 deletions backend/server/example_input/example_local_storage_data.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
"empty_year": {
"degree": {
"programCode": "3707",
"specs": [ "COMPA1" ],
"isComplete": true
"specs": [ "COMPA1" ]
},
"planner": {
"years": [ {
Expand Down Expand Up @@ -34,8 +33,7 @@
"summer_term": {
"degree": {
"programCode": "3707",
"specs": [ "COMPA1" ],
"isComplete": true
"specs": [ "COMPA1" ]
},
"planner": {
"years": [ {
Expand Down Expand Up @@ -65,8 +63,7 @@
"no_uoc": {
"degree": {
"programCode": "3707",
"specs": [ "COMPA1" ],
"isComplete": true
"specs": [ "COMPA1" ]
},
"planner": {
"years": [{
Expand All @@ -92,8 +89,7 @@
"suppress_warning": {
"degree": {
"programCode": "3707",
"specs": [ "COMPA1" ],
"isComplete": true
"specs": [ "COMPA1" ]
},
"planner": {
"years": [{
Expand All @@ -119,8 +115,7 @@
"simple_year": {
"degree": {
"programCode": "3707",
"specs": [ "COMPA1" ],
"isComplete": true
"specs": [ "COMPA1" ]
},
"planner": {
"years": [ {
Expand Down Expand Up @@ -159,8 +154,7 @@
"out_of_order": {
"degree": {
"programCode": "3707",
"specs": [ "COMPA1" ],
"isComplete": true
"specs": [ "COMPA1" ]
},
"planner": {
"years": [ {
Expand Down
2 changes: 1 addition & 1 deletion backend/server/routers/courses.py
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ def get_all_unlocked(userData: UserData) -> Dict[str, Dict]:
"""

coursesState = {}
user = User(fix_user_data(userData.dict()))
user = User(fix_user_data(userData.model_dump()))
for course, condition in CONDITIONS.items():
result, warnings = condition.validate(user) if condition is not None else (True, [])
if result:
Expand Down
3 changes: 3 additions & 0 deletions backend/server/routers/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ def to_user(self) -> User:

# prevent circular import; TODO: There has to be a better way
from server.routers.courses import get_course
from server.routers.utility import get_core_courses

for year in self.plan:
for term in year:
Expand All @@ -200,6 +201,8 @@ def to_user(self) -> User:
else (get_course(course_name)["UOC"], None) # type: ignore
)
user.add_courses(cleaned_term)
# get the cores of the user
user.core_courses = get_core_courses(user.program, user.specialisations)
return user

# TODO-OLLI(pm): get rid of these user models in favour of the database models
Expand Down
2 changes: 1 addition & 1 deletion backend/server/routers/utility.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def map_suppressed_errors(func: Callable[..., R], errors_log: list[tuple], *args
try:
return func(*args, **kwargs)
except Exception as e:
errors_log.append((*args, e))
errors_log.append((*args, str(e)))
return None


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

def test_no_courses_completed():
x = requests.post(
'http://127.0.0.1:8000/courses/coursesUnlockedWhenTaken/COMP1511', json=USERS["user3"])
'http://127.0.0.1:8000/courses/coursesUnlockedWhenTaken/COMP1511', json=USERS["user_no_courses"])
assert x.json() == {
"direct_unlock": [
'COMP1521',
Expand All @@ -27,10 +27,10 @@ def test_no_courses_completed():

def test_malformed_request():
x = requests.post(
'http://127.0.0.1:8000/courses/coursesUnlockedWhenTaken/&&&&&', json=USERS["user3"])
'http://127.0.0.1:8000/courses/coursesUnlockedWhenTaken/&&&&&', json=USERS["user_no_courses"])
assert x.status_code == 400
x = requests.post(
'http://127.0.0.1:8000/courses/coursesUnlockedWhenTaken/COMPXXXX', json=USERS["user3"])
'http://127.0.0.1:8000/courses/coursesUnlockedWhenTaken/COMPXXXX', json=USERS["user_no_courses"])
assert x.status_code == 400


Expand Down Expand Up @@ -60,5 +60,5 @@ def test_two_courses_completed():
"COMP9517",
"COMP9727",
],
"indirect_unlock": ["TABL2710"]
"indirect_unlock": ['BABS3301', 'SOMS3001', "TABL2710"]
}
5 changes: 3 additions & 2 deletions backend/server/tests/courses/test_get_all_unlocked.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

def test_fix_wam_only_unlock_given_course():
x = requests.post(
"http://127.0.0.1:8000/courses/getAllUnlocked", json=USERS["user5"]
"http://127.0.0.1:8000/courses/getAllUnlocked", json=USERS["user6"]
)
assert x.status_code != 500
assert x.json()["courses_state"]["COMP1521"]["unlocked"] is True
Expand All @@ -19,8 +19,9 @@ def test_fix_wam_only_unlock_given_course():

def test_unlock_dependent_course():
x = requests.post(
"http://127.0.0.1:8000/courses/getAllUnlocked", json=USERS["user2"]
"http://127.0.0.1:8000/courses/getAllUnlocked", json=USERS["user_one_math"]
)
assert x.status_code != 500
print(x.json())
assert x.json()["courses_state"]["MATH1231"]["unlocked"] is True
assert x.json()["courses_state"]["MATH1231"]["is_accurate"] is True
25 changes: 19 additions & 6 deletions backend/server/tests/courses/test_search_course.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,43 @@

import requests

from server.tests.user.utility import get_token, get_token_headers

with open("./algorithms/tests/exampleUsers.json", encoding="utf8") as f:
USER = json.load(f)["user6"]
USER = json.load(f)["user_degree_wizard"]
f.close()


def test_search_course():
x = requests.post('http://127.0.0.1:8000/courses/searchCourse/COMP1', json=USER)
token = get_token()
headers = get_token_headers(token)
requests.post('http://127.0.0.1:8000/user/setupDegreeWizard', headers=headers, json=USER)
x = requests.post('http://127.0.0.1:8000/courses/searchCourse/COMP1', headers=headers)
assert x.status_code == 200
assert x.json().get("COMP1521") is not None


def test_search_archives():
x = requests.post('http://127.0.0.1:8000/courses/searchCourse/DESN1000', json=USER)
token = get_token()
headers = get_token_headers(token)
requests.post('http://127.0.0.1:8000/user/setupDegreeWizard', headers=headers, json=USER)
x = requests.post('http://127.0.0.1:8000/courses/searchCourse/DESN1000', headers=headers)
assert x.status_code == 200
assert x.json().get("DESN1000") is not None


def test_search_title():
x = requests.post('http://127.0.0.1:8000/courses/searchCourse/Programming Fundamentals', json=USER)
assert x.status_code == 200
token = get_token()
headers = get_token_headers(token)
requests.post('http://127.0.0.1:8000/user/setupDegreeWizard', headers=headers, json=USER)
x = requests.post('http://127.0.0.1:8000/courses/searchCourse/Programming Fundamentals', headers=headers)
assert x.json().get("COMP1511") is not None


def test_search_minor():
x = requests.post('http://127.0.0.1:8000/courses/searchCourse/Financial Fundamentals', json=USER)
token = get_token()
headers = get_token_headers(token)
requests.post('http://127.0.0.1:8000/user/setupDegreeWizard', headers=headers, json=USER)
x = requests.post('http://127.0.0.1:8000/courses/searchCourse/Financial Fundamentals', headers=headers)
assert x.status_code == 200
assert x.json().get("ACCT2511") is not None
Loading

0 comments on commit fe22a61

Please sign in to comment.