update and add functional tests for students view

This commit is contained in:
dominik24c 2023-01-16 21:59:49 +01:00
parent 1bed24a1bc
commit f4f9072c3f
8 changed files with 539 additions and 129 deletions

View File

@ -18,7 +18,7 @@ bp = APIBlueprint("enrollments", __name__, url_prefix="/")
@bp.post("/<int:examination_schedule_id>/enrollments/<int:term_of_defence_id>/") @bp.post("/<int:examination_schedule_id>/enrollments/<int:term_of_defence_id>/")
@bp.input(TemporaryStudentSchema) @bp.input(TemporaryStudentSchema)
@bp.output(MessageSchema) @bp.output(MessageSchema, status_code=201)
def assign_your_group_to_term_of_defence( def assign_your_group_to_term_of_defence(
examination_schedule_id: int, term_of_defence_id: int, data: dict examination_schedule_id: int, term_of_defence_id: int, data: dict
) -> dict: ) -> dict:
@ -37,7 +37,7 @@ def assign_your_group_to_term_of_defence(
) )
if term_of_defence is None or (ex := term_of_defence.examination_schedule) is None: if term_of_defence is None or (ex := term_of_defence.examination_schedule) is None:
abort(400, "Term of defence not found!") abort(404, "Term of defence not found!")
if ex.open_enrollments != EnrollmentsMode.OPEN.value: if ex.open_enrollments != EnrollmentsMode.OPEN.value:
abort(400, "Enrollments is closed! You have been delayed!") abort(400, "Enrollments is closed! You have been delayed!")
@ -97,9 +97,9 @@ def delete_your_group_from_term_of_defence(
.first() .first()
) )
ex = term_of_defence.examination_schedule
if term_of_defence is None: if term_of_defence is None:
abort(404, "Term of defence doesn't exist!") abort(404, "Not found term of defence!")
ex = term_of_defence.examination_schedule
group = ( group = (
Group.query.filter(Group.year_group_id == ex.year_group_id) Group.query.filter(Group.year_group_id == ex.year_group_id)
@ -107,7 +107,7 @@ def delete_your_group_from_term_of_defence(
.filter_by(index=student.index) .filter_by(index=student.index)
.first() .first()
) )
if group.id != term_of_defence.group_id: if group is None or group.id != term_of_defence.group_id:
abort(400, "You are not assigned to this group!") abort(400, "You are not assigned to this group!")
term_of_defence.group_id = None term_of_defence.group_id = None

View File

@ -1,4 +1,5 @@
import datetime import datetime
import random
from factory import Sequence, alchemy from factory import Sequence, alchemy
from factory.faker import Faker from factory.faker import Faker
@ -12,7 +13,7 @@ from app.examination_schedule.models import (
TermOfDefence, TermOfDefence,
) )
from app.project_supervisor.models import ProjectSupervisor from app.project_supervisor.models import ProjectSupervisor
from app.students.models import Group, Student, YearGroup from app.students.models import Group, Student, YearGroup, ProjectGradeSheet
class YearGroupFactory(alchemy.SQLAlchemyModelFactory): class YearGroupFactory(alchemy.SQLAlchemyModelFactory):
@ -82,11 +83,11 @@ class TermOfDefenceFactory(alchemy.SQLAlchemyModelFactory):
start_date = Sequence( start_date = Sequence(
lambda n: datetime.datetime(2020, 1, 1, tzinfo=datetime.timezone.utc) lambda n: datetime.datetime(2020, 1, 1, tzinfo=datetime.timezone.utc)
+ datetime.timedelta(n * 30) + datetime.timedelta(n * 30)
) )
end_date = Sequence( end_date = Sequence(
lambda n: datetime.datetime(2020, 1, 1, tzinfo=datetime.timezone.utc) lambda n: datetime.datetime(2020, 1, 1, tzinfo=datetime.timezone.utc)
+ datetime.timedelta(n * 30 + 30) + datetime.timedelta(n * 30 + 30)
) )
@ -97,9 +98,74 @@ class TemporaryAvailabilityFactory(alchemy.SQLAlchemyModelFactory):
start_date = Sequence( start_date = Sequence(
lambda n: datetime.datetime(2020, 1, 1, tzinfo=datetime.timezone.utc) lambda n: datetime.datetime(2020, 1, 1, tzinfo=datetime.timezone.utc)
+ datetime.timedelta(n * 30) + datetime.timedelta(n * 30)
) )
end_date = Sequence( end_date = Sequence(
lambda n: datetime.datetime(2020, 1, 1, tzinfo=datetime.timezone.utc) lambda n: datetime.datetime(2020, 1, 1, tzinfo=datetime.timezone.utc)
+ datetime.timedelta(n * 30 + 30) + datetime.timedelta(n * 30 + 30)
) )
class ProjectGradeSheetFactory(alchemy.SQLAlchemyModelFactory):
class Meta:
model = ProjectGradeSheet
sqlalchemy_session = db.session
presentation_required_content_1 = random.choice([0, 1, 3, 4])
presentation_required_content_2 = random.choice([0, 1, 3, 4])
presentation_was_compatible_1 = random.choice([0, 1, 3, 4])
presentation_was_compatible_2 = random.choice([0, 1, 3, 4])
presentation_showing_1 = random.choice([0, 1, 3, 4])
presentation_showing_2 = random.choice([0, 1, 3, 4])
presentation_answers_to_questions_from_committee_1 = random.choice([0, 1, 3, 4])
presentation_answers_to_questions_from_committee_2 = random.choice([0, 1, 3, 4])
documentation_project_vision_1 = random.choice([0, 1, 3, 4])
documentation_project_vision_2 = random.choice([0, 1, 3, 4])
documentation_requirements_1 = random.choice([0, 1, 3, 4])
documentation_requirements_2 = random.choice([0, 1, 3, 4])
documentation_for_clients_1 = random.choice([0, 1, 3, 4])
documentation_for_clients_2 = random.choice([0, 1, 3, 4])
documentation_for_developers_1 = random.choice([0, 1, 3, 4])
documentation_for_developers_2 = random.choice([0, 1, 3, 4])
documentation_license_1 = random.choice([0, 1, 3, 4])
documentation_license_2 = random.choice([0, 1, 3, 4])
group_work_regularity_1 = random.choice([0, 1, 3, 4])
group_work_regularity_2 = random.choice([0, 1, 3, 4])
group_work_division_of_work_1 = random.choice([0, 1, 3, 4])
group_work_division_of_work_2 = random.choice([0, 1, 3, 4])
group_work_contact_with_client_1 = random.choice([0, 1, 3, 4])
group_work_contact_with_client_2 = random.choice([0, 1, 3, 4])
group_work_management_of_risk_1 = random.choice([0, 1, 3, 4])
group_work_management_of_risk_2 = random.choice([0, 1, 3, 4])
group_work_work_methodology_1 = random.choice([0, 1, 3, 4])
group_work_work_methodology_2 = random.choice([0, 1, 3, 4])
group_work_management_of_source_code_1 = random.choice([0, 1, 3, 4])
group_work_management_of_source_code_2 = random.choice([0, 1, 3, 4])
group_work_devops_1 = random.choice([0, 1, 3, 4])
group_work_devops_2 = random.choice([0, 1, 3, 4])
products_project_complexity_of_product_1 = random.choice([0, 1, 3, 4])
products_project_complexity_of_product_2 = random.choice([0, 1, 3, 4])
products_project_access_to_application_1 = random.choice([0, 1, 3, 4])
products_project_access_to_application_2 = random.choice([0, 1, 3, 4])
products_project_security_issues_1 = random.choice([0, 1, 3, 4])
products_project_security_issues_2 = random.choice([0, 1, 3, 4])
products_project_access_to_test_application_1 = random.choice([0, 1, 3, 4])
products_project_access_to_test_application_2 = random.choice([0, 1, 3, 4])
products_project_acceptance_criteria_1 = random.choice([0, 1, 3, 4])
products_project_acceptance_criteria_2 = random.choice([0, 1, 3, 4])
products_project_expected_functionality_1 = random.choice([0, 1, 3, 4])
products_project_expected_functionality_2 = random.choice([0, 1, 3, 4])
products_project_promises_well_1 = random.choice([0, 1, 3, 4])
products_project_promises_well_2 = random.choice([0, 1, 3, 4])
products_project_has_been_implemented_1 = random.choice([0, 1, 3, 4])
products_project_has_been_implemented_2 = random.choice([0, 1, 3, 4])
products_project_is_useful_1 = random.choice([0, 1, 3, 4])
products_project_is_useful_2 = random.choice([0, 1, 3, 4])
products_project_prototype_1 = random.choice([0, 1, 3, 4])
products_project_prototype_2 = random.choice([0, 1, 3, 4])
products_project_tests_1 = random.choice([0, 1, 3, 4])
products_project_tests_2 = random.choice([0, 1, 3, 4])
products_project_technology_1 = random.choice([0, 1, 3, 4])
products_project_technology_2 = random.choice([0, 1, 3, 4])

View File

@ -18,25 +18,10 @@ from ...utils import (
assert_model_changes, assert_model_changes,
create_many_models, create_many_models,
create_one_model, create_one_model,
get_data_of_term_of_defence
) )
def get_data_of_term_of_defence(timedelta_minutes: int = 30) -> dict:
ex = ExaminationSchedule.query.first()
if ex is None:
date = datetime.datetime.now()
else:
date = ex.start_date
return {
"start_date": (date + datetime.timedelta(days=1)).strftime(
"%Y-%m-%dT%H:%M:%S.000Z"
),
"end_date": (
date + datetime.timedelta(days=1, minutes=timedelta_minutes)
).strftime("%Y-%m-%dT%H:%M:%S.000Z"),
}
def test_list_of_term_of_defences(test_app_with_context) -> None: def test_list_of_term_of_defences(test_app_with_context) -> None:
with test_app_with_context.test_client() as client: with test_app_with_context.test_client() as client:
year_group = create_one_model(YearGroupFactory) year_group = create_one_model(YearGroupFactory)
@ -63,7 +48,7 @@ def test_delete_term_of_defence(test_app_with_context) -> None:
def test_delete_term_of_defence_if_term_of_defence_or_examination_schedule_doesnt_exist( def test_delete_term_of_defence_if_term_of_defence_or_examination_schedule_doesnt_exist(
test_app_with_context, test_app_with_context,
) -> None: ) -> None:
with test_app_with_context.test_client() as client: with test_app_with_context.test_client() as client:
_test_case_client( _test_case_client(
@ -133,7 +118,7 @@ def test_create_many_term_of_defences(test_app_with_context) -> None:
def test_create_many_term_of_defences_with_invalid_id_of_chairman( def test_create_many_term_of_defences_with_invalid_id_of_chairman(
test_app_with_context, test_app_with_context,
) -> None: ) -> None:
with test_app_with_context.test_client() as client: with test_app_with_context.test_client() as client:
year_group = create_one_model(YearGroupFactory) year_group = create_one_model(YearGroupFactory)
@ -157,7 +142,7 @@ def test_create_many_term_of_defences_with_invalid_id_of_chairman(
def test_create_many_term_of_defences_if_examination_schedule_doesnt_exist( def test_create_many_term_of_defences_if_examination_schedule_doesnt_exist(
test_app_with_context, test_app_with_context,
) -> None: ) -> None:
with test_app_with_context.test_client() as client: with test_app_with_context.test_client() as client:
year_group = create_one_model(YearGroupFactory) year_group = create_one_model(YearGroupFactory)
@ -180,7 +165,7 @@ def test_create_many_term_of_defences_if_examination_schedule_doesnt_exist(
def test_create_many_term_of_defences_if_project_supervisors_doesnt_exist( def test_create_many_term_of_defences_if_project_supervisors_doesnt_exist(
test_app_with_context, test_app_with_context,
) -> None: ) -> None:
with test_app_with_context.test_client() as client: with test_app_with_context.test_client() as client:
year_group = create_one_model(YearGroupFactory) year_group = create_one_model(YearGroupFactory)
@ -201,7 +186,7 @@ def test_create_many_term_of_defences_if_project_supervisors_doesnt_exist(
def test_create_many_term_of_defences_with_invalid_duration_time( def test_create_many_term_of_defences_with_invalid_duration_time(
test_app_with_context, test_app_with_context,
) -> None: ) -> None:
with test_app_with_context.test_client() as client: with test_app_with_context.test_client() as client:
year_group = create_one_model(YearGroupFactory) year_group = create_one_model(YearGroupFactory)
@ -226,7 +211,7 @@ def test_create_many_term_of_defences_with_invalid_duration_time(
def test_create_many_term_of_defences_if_start_date_is_greater_than_end_date( def test_create_many_term_of_defences_if_start_date_is_greater_than_end_date(
test_app_with_context, test_app_with_context,
) -> None: ) -> None:
with test_app_with_context.test_client() as client: with test_app_with_context.test_client() as client:
year_group = create_one_model(YearGroupFactory) year_group = create_one_model(YearGroupFactory)
@ -251,7 +236,7 @@ def test_create_many_term_of_defences_if_start_date_is_greater_than_end_date(
def test_create_many_term_of_defences_with_invalid_date_range( def test_create_many_term_of_defences_with_invalid_date_range(
test_app_with_context, test_app_with_context,
) -> None: ) -> None:
with test_app_with_context.test_client() as client: with test_app_with_context.test_client() as client:
year_group = create_one_model(YearGroupFactory) year_group = create_one_model(YearGroupFactory)
@ -303,7 +288,7 @@ def test_update_term_of_defence(test_app_with_context) -> None:
def test_update_term_of_defence_with_invalid_id_of_chairman( def test_update_term_of_defence_with_invalid_id_of_chairman(
test_app_with_context, test_app_with_context,
) -> None: ) -> None:
with test_app_with_context.test_client() as client: with test_app_with_context.test_client() as client:
year_group = create_one_model(YearGroupFactory) year_group = create_one_model(YearGroupFactory)
@ -328,7 +313,7 @@ def test_update_term_of_defence_with_invalid_id_of_chairman(
def test_update_term_of_defence_if_examination_schedule_or_term_of_defence_doesnt_exist( def test_update_term_of_defence_if_examination_schedule_or_term_of_defence_doesnt_exist(
test_app_with_context, test_app_with_context,
) -> None: ) -> None:
with test_app_with_context.test_client() as client: with test_app_with_context.test_client() as client:
data = get_data_of_term_of_defence(150) data = get_data_of_term_of_defence(150)
@ -346,7 +331,7 @@ def test_update_term_of_defence_if_examination_schedule_or_term_of_defence_doesn
def test_update_term_of_defence_if_project_supervisors_doesnt_exist( def test_update_term_of_defence_if_project_supervisors_doesnt_exist(
test_app_with_context, test_app_with_context,
) -> None: ) -> None:
with test_app_with_context.test_client() as client: with test_app_with_context.test_client() as client:
year_group = create_one_model(YearGroupFactory) year_group = create_one_model(YearGroupFactory)
@ -367,7 +352,7 @@ def test_update_term_of_defence_if_project_supervisors_doesnt_exist(
def test_update_term_of_defence_with_invalid_duration_time( def test_update_term_of_defence_with_invalid_duration_time(
test_app_with_context, test_app_with_context,
) -> None: ) -> None:
with test_app_with_context.test_client() as client: with test_app_with_context.test_client() as client:
year_group = create_one_model(YearGroupFactory) year_group = create_one_model(YearGroupFactory)
@ -392,7 +377,7 @@ def test_update_term_of_defence_with_invalid_duration_time(
def test_update_term_of_defence_if_start_date_is_greater_than_end_date( def test_update_term_of_defence_if_start_date_is_greater_than_end_date(
test_app_with_context, test_app_with_context,
) -> None: ) -> None:
with test_app_with_context.test_client() as client: with test_app_with_context.test_client() as client:
year_group = create_one_model(YearGroupFactory) year_group = create_one_model(YearGroupFactory)
@ -461,7 +446,7 @@ def test_list_temporary_availabilities(test_app_with_context) -> None:
def test_list_temporary_availabilities_if_examination_schedule_doesnt_exist( def test_list_temporary_availabilities_if_examination_schedule_doesnt_exist(
test_app_with_context, test_app_with_context,
) -> None: ) -> None:
with test_app_with_context.test_client() as client: with test_app_with_context.test_client() as client:
url = "/api/coordinator/enrollments/43/temporary-availabilities/" url = "/api/coordinator/enrollments/43/temporary-availabilities/"
@ -498,7 +483,7 @@ def test_list_of_assigned_group_to_term_of_defences(test_app_with_context) -> No
def test_list_of_assigned_group_to_term_of_defences_if_examination_schedule_doesnt_exist( def test_list_of_assigned_group_to_term_of_defences_if_examination_schedule_doesnt_exist(
test_app_with_context, test_app_with_context,
) -> None: ) -> None:
with test_app_with_context.test_client() as client: with test_app_with_context.test_client() as client:
url = "/api/coordinator/enrollments/43/assigned-group-to-term-of-defences/" url = "/api/coordinator/enrollments/43/assigned-group-to-term-of-defences/"
@ -532,7 +517,7 @@ def test_set_new_group_to_term_of_defence(test_app_with_context) -> None:
def test_set_new_group_to_term_of_defence_if_examination_schedule_or_term_of_defence_dont_exist( def test_set_new_group_to_term_of_defence_if_examination_schedule_or_term_of_defence_dont_exist(
test_app_with_context, test_app_with_context,
) -> None: ) -> None:
with test_app_with_context.test_client() as client: with test_app_with_context.test_client() as client:
url = "/api/coordinator/enrollments/34/term-of-defence/4/group/" url = "/api/coordinator/enrollments/34/term-of-defence/4/group/"
@ -548,7 +533,7 @@ def test_set_new_group_to_term_of_defence_if_examination_schedule_or_term_of_def
def test_set_new_group_to_term_of_defence_if_group_doesnt_exist( def test_set_new_group_to_term_of_defence_if_group_doesnt_exist(
test_app_with_context, test_app_with_context,
) -> None: ) -> None:
with test_app_with_context.test_client() as client: with test_app_with_context.test_client() as client:
year_group = create_one_model(YearGroupFactory) year_group = create_one_model(YearGroupFactory)
@ -567,7 +552,8 @@ def test_set_new_group_to_term_of_defence_if_group_doesnt_exist(
) )
def test_set_new_group_to_term_of_defence_if_(test_app_with_context) -> None: def test_set_new_group_to_term_of_defence_if_group_has_already_assigned_to_term_of_defence(
test_app_with_context) -> None:
with test_app_with_context.test_client() as client: with test_app_with_context.test_client() as client:
year_group = create_one_model(YearGroupFactory) year_group = create_one_model(YearGroupFactory)
ex = create_one_model(ExaminationScheduleFactory, year_group_id=year_group.id) ex = create_one_model(ExaminationScheduleFactory, year_group_id=year_group.id)
@ -611,7 +597,7 @@ def test_delete_group_to_term_of_defence(test_app_with_context) -> None:
def test_delete_group_to_term_of_defence_if_examination_schedule_doesnt_exist( def test_delete_group_to_term_of_defence_if_examination_schedule_doesnt_exist(
test_app_with_context, test_app_with_context,
) -> None: ) -> None:
with test_app_with_context.test_client() as client: with test_app_with_context.test_client() as client:
url = "/api/coordinator/enrollments/3/term-of-defence/1/group/" url = "/api/coordinator/enrollments/3/term-of-defence/1/group/"
@ -649,7 +635,7 @@ def test_update_group_for_term_of_defence(test_app_with_context) -> None:
def test_update_group_for_term_of_defence_if_examination_schedule_or_term_of_defence_dont_exist( def test_update_group_for_term_of_defence_if_examination_schedule_or_term_of_defence_dont_exist(
test_app_with_context, test_app_with_context,
) -> None: ) -> None:
with test_app_with_context.test_client() as client: with test_app_with_context.test_client() as client:
url = "/api/coordinator/enrollments/34/term-of-defence/4/group/" url = "/api/coordinator/enrollments/34/term-of-defence/4/group/"
@ -665,7 +651,7 @@ def test_update_group_for_term_of_defence_if_examination_schedule_or_term_of_def
def test_update_group_for_term_of_defence_if_group_doesnt_exist( def test_update_group_for_term_of_defence_if_group_doesnt_exist(
test_app_with_context, test_app_with_context,
) -> None: ) -> None:
with test_app_with_context.test_client() as client: with test_app_with_context.test_client() as client:
year_group = create_one_model(YearGroupFactory) year_group = create_one_model(YearGroupFactory)

View File

@ -0,0 +1,298 @@
import datetime
from app.base.mode import EnrollmentsMode
from app.dependencies import db
from app.examination_schedule.models import ExaminationSchedule, TermOfDefence
from ...factory import (
ExaminationScheduleFactory,
GroupFactory,
StudentFactory,
ProjectSupervisorFactory,
TermOfDefenceFactory,
YearGroupFactory,
)
from ...utils import (
_test_case_client,
_test_case_client_without_response,
assert_model_changes,
create_many_models,
create_one_model,
get_data_of_term_of_defence
)
def test_list_examination_schedule(test_app_with_context) -> None:
with test_app_with_context.test_client() as client:
year_group = create_one_model(YearGroupFactory)
st = create_one_model(StudentFactory, year_group_id=year_group.id)
create_many_models(23, ExaminationScheduleFactory, year_group_id=year_group.id)
url = f"/api/students/examination-schedule/year-group/{year_group.id}/?student_id={st.id}"
data = _test_case_client_without_response(client, url, None, 200, method="get")
assert len(data.get("examination_schedules")) == 23
def test_list_examination_schedule_if_student_doesnt_exist(test_app_with_context) -> None:
with test_app_with_context.test_client() as client:
yg = create_one_model(YearGroupFactory)
_test_case_client(
client,
f"/api/students/examination-schedule/year-group/{yg.id}/?student_id=2",
None,
"Not found student!",
404,
method="get",
key="error",
)
def test_list_term_of_defences(test_app_with_context) -> None:
with test_app_with_context.test_client() as client:
year_group = create_one_model(YearGroupFactory)
st = create_one_model(StudentFactory, year_group_id=year_group.id)
ex = create_one_model(ExaminationScheduleFactory, year_group_id=year_group.id)
project_supervisors = create_many_models(13, ProjectSupervisorFactory, year_group_id=year_group.id)
ps = project_supervisors[0]
group = create_one_model(GroupFactory, year_group_id=year_group.id, project_supervisor_id=ps.id)
group.students.append(st)
db.session.commit()
term_of_defences = create_many_models(13, TermOfDefenceFactory, examination_schedule_id=ex.id)
ps_amount = 6
for i in range(ps_amount):
term_of_defences[i].members_of_committee.append(ps)
db.session.commit()
url = f"/api/students/examination-schedule/{ex.id}/enrollments/?student_id={st.id}"
data = _test_case_client_without_response(client, url, None, 200, method="get")
assert len(data.get("term_of_defences")) == ps_amount
def test_list_term_of_defences_if_student_doesnt_exist(test_app_with_context) -> None:
with test_app_with_context.test_client() as client:
_test_case_client(
client,
"/api/students/examination-schedule/3/enrollments/?student_id=2",
None,
"Not found student!",
404,
method="get",
key="error",
)
def test_assign_your_group_to_term_of_defence(test_app_with_context) -> None:
with test_app_with_context.test_client() as client:
year_group = create_one_model(YearGroupFactory)
ex = create_one_model(ExaminationScheduleFactory, year_group_id=year_group.id,
open_enrollments=EnrollmentsMode.OPEN.value)
ps = create_one_model(ProjectSupervisorFactory, year_group_id=year_group.id)
st = create_one_model(StudentFactory, year_group_id=year_group.id)
td = create_one_model(TermOfDefenceFactory, examination_schedule_id=ex.id)
group = create_one_model(GroupFactory, year_group_id=year_group.id, project_supervisor_id=ps.id)
td.members_of_committee.append(ps)
group.students.append(st)
db.session.commit()
_test_case_client(
client,
f"/api/students/{ex.id}/enrollments/{td.id}/",
{"student_id": st.id},
"You have just assigned the group for this exam date!",
201,
method="post",
)
def test_assign_your_group_to_term_of_defence_if_student_doesnt_exist(
test_app_with_context,
) -> None:
with test_app_with_context.test_client() as client:
_test_case_client(
client,
"/api/students/3/enrollments/1/",
{"student_id": 2},
"Not found student!",
404,
method="post",
key="error",
)
def test_assign_your_group_to_term_of_defence_if_term_of_defence_doesnt_exist(
test_app_with_context,
) -> None:
with test_app_with_context.test_client() as client:
st = create_one_model(StudentFactory)
_test_case_client(
client,
"/api/students/3/enrollments/1/",
{"student_id": st.id},
"Term of defence not found!",
404,
method="post",
key="error",
)
def test_assign_your_group_to_term_of_defence_if_enrollments_havent_started_yet(
test_app_with_context,
) -> None:
with test_app_with_context.test_client() as client:
year_group = create_one_model(YearGroupFactory)
ex = create_one_model(ExaminationScheduleFactory, year_group_id=year_group.id)
td = create_one_model(TermOfDefenceFactory, examination_schedule_id=ex.id)
st = create_one_model(StudentFactory, year_group_id=year_group.id)
_test_case_client(
client,
f"/api/students/{ex.id}/enrollments/{td.id}/",
{"student_id": st.id},
"Enrollments is closed! You have been delayed!",
400,
method="post",
key="error",
)
def test_assign_your_group_to_term_of_defence_if_you_dont_have_group(
test_app_with_context,
) -> None:
with test_app_with_context.test_client() as client:
year_group = create_one_model(YearGroupFactory)
ex = create_one_model(ExaminationScheduleFactory, year_group_id=year_group.id,
open_enrollments=EnrollmentsMode.OPEN.value)
td = create_one_model(TermOfDefenceFactory, examination_schedule_id=ex.id)
st = create_one_model(StudentFactory, year_group_id=year_group.id)
_test_case_client(
client,
f"/api/students/{ex.id}/enrollments/{td.id}/",
{"student_id": st.id},
"You don't have a group or your group doesn't have an assigned project supervisor!",
400,
method="post",
key="error",
)
def test_assign_your_group_to_term_of_defence_if_your_group_has_already_assigned_to_any_term_of_defence(
test_app_with_context,
) -> None:
with test_app_with_context.test_client() as client:
year_group = create_one_model(YearGroupFactory)
ex = create_one_model(ExaminationScheduleFactory, year_group_id=year_group.id,
open_enrollments=EnrollmentsMode.OPEN.value)
td = create_one_model(TermOfDefenceFactory, examination_schedule_id=ex.id)
st = create_one_model(StudentFactory, year_group_id=year_group.id)
ps = create_one_model(ProjectSupervisorFactory, year_group_id=year_group.id)
group = create_one_model(GroupFactory, year_group_id=year_group.id, project_supervisor_id=ps.id)
td.group_id = group.id
group.students.append(st)
db.session.commit()
_test_case_client(
client,
f"/api/students/{ex.id}/enrollments/{td.id}/",
{"student_id": st.id},
"Your group has already assigned to any exam date!",
400,
method="post",
key="error",
)
def test_assign_your_group_to_term_of_defence_if_your_project_supervisor_is_not_in_committee(
test_app_with_context,
) -> None:
with test_app_with_context.test_client() as client:
year_group = create_one_model(YearGroupFactory)
ex = create_one_model(ExaminationScheduleFactory, year_group_id=year_group.id,
open_enrollments=EnrollmentsMode.OPEN.value)
td = create_one_model(TermOfDefenceFactory, examination_schedule_id=ex.id)
st = create_one_model(StudentFactory, year_group_id=year_group.id)
ps = create_one_model(ProjectSupervisorFactory, year_group_id=year_group.id)
group = create_one_model(GroupFactory, year_group_id=year_group.id, project_supervisor_id=ps.id)
group.students.append(st)
db.session.commit()
_test_case_client(
client,
f"/api/students/{ex.id}/enrollments/{td.id}/",
{"student_id": st.id},
"Your project supervisor is not in committee!",
400,
method="post",
key="error",
)
def test_delete_your_group_from_term_of_defence(test_app_with_context) -> None:
with test_app_with_context.test_client() as client:
year_group = create_one_model(YearGroupFactory)
ex = create_one_model(ExaminationScheduleFactory, year_group_id=year_group.id,
open_enrollments=EnrollmentsMode.OPEN.value)
ps = create_one_model(ProjectSupervisorFactory, year_group_id=year_group.id)
st = create_one_model(StudentFactory, year_group_id=year_group.id)
group = create_one_model(GroupFactory, year_group_id=year_group.id, project_supervisor_id=ps.id)
td = create_one_model(TermOfDefenceFactory, examination_schedule_id=ex.id, group_id=group.id)
td.members_of_committee.append(ps)
group.students.append(st)
db.session.commit()
_test_case_client(
client,
f"/api/students/{ex.id}/enrollments/{td.id}/",
{"student_id": st.id},
"You have just removed the group for this exam date!",
200,
method="delete",
)
def test_delete_your_group_from_term_of_defence_if_student_doesnt_exist(
test_app_with_context,
) -> None:
with test_app_with_context.test_client() as client:
_test_case_client(
client,
"/api/students/3/enrollments/1/",
{"student_id": 2},
"Not found student!",
404,
method="delete",
key="error",
)
def test_delete_your_group_from_term_of_defence_if_term_of_defence_doesnt_exist(
test_app_with_context,
) -> None:
with test_app_with_context.test_client() as client:
st = create_one_model(StudentFactory)
_test_case_client(
client,
"/api/students/3/enrollments/1/",
{"student_id": st.id},
"Not found term of defence!",
404,
method="delete",
key="error",
)
def test_assign_your_group_to_term_of_defence_if_you_try_delete_not_your_group(
test_app_with_context,
) -> None:
with test_app_with_context.test_client() as client:
year_group = create_one_model(YearGroupFactory)
ex = create_one_model(ExaminationScheduleFactory, year_group_id=year_group.id,
open_enrollments=EnrollmentsMode.OPEN.value)
td = create_one_model(TermOfDefenceFactory, examination_schedule_id=ex.id)
st = create_one_model(StudentFactory, year_group_id=year_group.id)
ps = create_one_model(ProjectSupervisorFactory, year_group_id=year_group.id)
group = create_one_model(GroupFactory, year_group_id=year_group.id, project_supervisor_id=ps.id)
td.group_id = group.id
db.session.commit()
_test_case_client(
client,
f"/api/students/{ex.id}/enrollments/{td.id}/",
{"student_id": st.id},
"You are not assigned to this group!",
400,
method="delete",
key="error",
)

View File

@ -0,0 +1,82 @@
import copy
from app.dependencies import db
from ...factory import StudentFactory, GroupFactory, YearGroupFactory, ProjectGradeSheetFactory
from ...utils import (
_test_case_client,
_test_case_client_without_response,
assert_model_changes,
create_many_models,
create_one_model,
)
terms = [1, 2]
def test_detail_project_grade_sheet_first_term(test_app_with_context) -> None:
with test_app_with_context.test_client() as client:
for term in terms:
yg = create_one_model(YearGroupFactory)
group = create_one_model(GroupFactory, year_group_id=yg.id)
st = create_one_model(StudentFactory, year_group_id=yg.id)
pgs = create_one_model(ProjectGradeSheetFactory, group_id=group.id)
group.students.append(st)
db.session.commit()
data = _test_case_client_without_response(
client,
f"/api/students/project-grade-sheet/year-group/{yg.id}/?student_id={st.id}&term={term}",
None,
200,
method="get",
)
assert_model_changes(pgs, data)
def test_detail_student_if_student_doesnt_exist(test_app_with_context) -> None:
with test_app_with_context.test_client() as client:
for term in terms:
yg = create_one_model(YearGroupFactory)
_test_case_client(
client,
f"/api/students/project-grade-sheet/year-group/{yg.id}/?student_id=3&term={term}",
None,
"Not found student!",
404,
method="get",
key="error",
)
def test_detail_student_if_group_doesnt_exist(test_app_with_context) -> None:
with test_app_with_context.test_client() as client:
for term in terms:
yg = create_one_model(YearGroupFactory)
st = create_one_model(StudentFactory, year_group_id=yg.id)
_test_case_client(
client,
f"/api/students/project-grade-sheet/year-group/{yg.id}/?student_id={st.id}&term={term}",
None,
"Not found group!",
404,
method="get",
key="error",
)
def test_detail_student_if_project_grade_sheet_doesnt_exist(test_app_with_context) -> None:
with test_app_with_context.test_client() as client:
for term in terms:
yg = create_one_model(YearGroupFactory)
st = create_one_model(StudentFactory, year_group_id=yg.id)
group = create_one_model(GroupFactory, year_group_id=yg.id)
group.students.append(st)
db.session.commit()
_test_case_client(
client,
f"/api/students/project-grade-sheet/year-group/{yg.id}/?student_id={st.id}&term={term}",
None,
"Not found project grade sheet!",
404,
method="get",
key="error",
)

View File

@ -1,32 +1,38 @@
from app.dependencies import db from app.dependencies import db
from app.students.models import Group
from ...fake_data import create_groups, create_project_supervisors, create_year_group from ...utils import _test_case_client_without_response, create_many_models, create_one_model
from ...utils import _test_case_client_without_response, assert_model_changes from ...factory import GroupFactory, YearGroupFactory, ProjectSupervisorFactory
def test_list_year_group_for_specific_student(test_app_with_context) -> None: def test_list_available_groups(test_app_with_context) -> None:
with test_app_with_context.test_client() as client: with test_app_with_context.test_client() as client:
year_group = create_year_group() yg = create_one_model(YearGroupFactory)
amount_of_project_supervisors = 3 amount = 6
project_supervisors = create_project_supervisors( limit_group_1 = 4
year_group, amount_of_project_supervisors limit_group_2 = 2
) groups = create_many_models(amount, GroupFactory, year_group_id=yg.id)
groups = create_groups(year_group, 6) ps1 = create_many_models(amount // 2, ProjectSupervisorFactory, year_group_id=yg.id, limit_group=limit_group_1)
ps2 = create_many_models(amount // 2, ProjectSupervisorFactory, year_group_id=yg.id, limit_group=limit_group_2)
for i in range(1, 4): for g, ps in zip(groups, [*ps1, *ps2]):
for _ in range(i): g.project_supervisor_id = ps.id
gr = groups.pop()
gr.project_supervisor_id = project_supervisors[i - 1].id
db.session.commit() db.session.commit()
url = f"/api/students/registrations/{year_group.id}/?per_page=10" data = _test_case_client_without_response(
data = _test_case_client_without_response(client, url, None, 200, method="get") client,
assert data.get("max_pages") == 1 f"/api/students/registrations/{yg.id}/?per_page=10",
None,
200,
method="get",
)
project_supervisors = [*ps1, *ps2]
project_supervisors_data = data.get("project_supervisors") project_supervisors_data = data.get("project_supervisors")
assert len(project_supervisors_data) == amount_of_project_supervisors assert data.get("max_pages") == 1
assert len(project_supervisors_data) == amount
for ps_data in project_supervisors_data:
for ps_obj in project_supervisors:
if ps_data['email'] == ps_obj.email:
assert ps_data['available_groups'] == (ps_obj.limit_group - Group.query.filter(
Group.project_supervisor_id == ps_obj.id).count())
continue
for ps, expected_available_groups in zip(project_supervisors, [2, 1, 0]):
ps_dict = list(
filter(lambda p: p.get("email") == ps.email, project_supervisors_data)
)[0]
assert ps_dict.get("available_groups") == expected_available_groups

View File

@ -1,44 +0,0 @@
from app.base.mode import ModeGroups
from app.dependencies import db
from app.students.models import YearGroupStudents
from ...fake_data import create_student, create_year_group
from ...utils import _test_case_client, _test_case_client_without_response
valid_data = {"first_name": "Dominic", "last_name": "Mozart", "index": 123_345}
year_group_data = [
{"name": "2022/2023", "mode": ModeGroups.STATIONARY.value},
{"name": "2021/2022", "mode": ModeGroups.STATIONARY.value},
{"name": "2023/2024", "mode": ModeGroups.NON_STATIONARY.value},
{"name": "1997/1998", "mode": ModeGroups.NON_STATIONARY.value},
]
def test_list_year_group_for_specific_student(test_app_with_context) -> None:
with test_app_with_context.test_client() as client:
year_groups = [create_year_group(data) for data in year_group_data]
student = create_student(valid_data)
for yg in year_groups[:-1]:
db.session.add(
YearGroupStudents(year_group_id=yg.id, student_index=student.index)
)
db.session.commit()
url = f"/api/students/year-group/?per_page=10&index={student.index}"
data = _test_case_client_without_response(client, url, None, 200, method="get")
assert data.get("max_pages") == 1
assert len(data.get("year_groups")) == len(year_groups) - 1
def test_list_year_group_if_student_doesnt_exist(test_app_with_context) -> None:
with test_app_with_context.test_client() as client:
_test_case_client(
client,
"/api/students/year-group/?per_page=10&index=23",
None,
"Not found student!",
404,
method="get",
key="error",
)

View File

@ -17,11 +17,11 @@ def assert_model_changes(model: db.Model, expected_data: dict) -> None:
def _test_case_client_without_response( def _test_case_client_without_response(
test_client: FlaskClient, test_client: FlaskClient,
url: str, url: str,
data: Union[dict, None], data: Union[dict, None],
status_code: int, status_code: int,
method: str = "post", method: str = "post",
) -> dict: ) -> dict:
method_func = getattr(test_client, method) method_func = getattr(test_client, method)
if data is not None: if data is not None:
@ -34,13 +34,13 @@ def _test_case_client_without_response(
def _test_case_client( def _test_case_client(
test_client: FlaskClient, test_client: FlaskClient,
url: str, url: str,
data: Union[dict, None], data: Union[dict, None],
message: str, message: str,
status_code: int, status_code: int,
key: str = "message", key: str = "message",
method: str = "post", method: str = "post",
) -> dict: ) -> dict:
response_data = _test_case_client_without_response( response_data = _test_case_client_without_response(
test_client, url, data, status_code, method test_client, url, data, status_code, method
@ -59,7 +59,7 @@ def _test_case_group(group: Group, data: dict) -> None:
def create_many_models( def create_many_models(
amount: int, factory: Type[SQLAlchemyModelFactory], **kwargs amount: int, factory: Type[SQLAlchemyModelFactory], **kwargs
) -> List[SQLAlchemyModelFactory]: ) -> List[SQLAlchemyModelFactory]:
models = [factory(**kwargs) for _ in range(amount)] models = [factory(**kwargs) for _ in range(amount)]
db.session.add_all(models) db.session.add_all(models)
@ -68,9 +68,9 @@ def create_many_models(
def create_one_model( def create_one_model(
model: Union[Type[db.Model], Type[SQLAlchemyModelFactory]], model: Union[Type[db.Model], Type[SQLAlchemyModelFactory]],
data: dict = None, data: dict = None,
**kwargs **kwargs
) -> Union[db.Model, SQLAlchemyModelFactory]: ) -> Union[db.Model, SQLAlchemyModelFactory]:
if issubclass(model, SQLAlchemyModelFactory): if issubclass(model, SQLAlchemyModelFactory):
m = model(**kwargs) # it's a factory m = model(**kwargs) # it's a factory
@ -79,3 +79,19 @@ def create_one_model(
db.session.add(m) db.session.add(m)
db.session.commit() db.session.commit()
return m return m
def get_data_of_term_of_defence(timedelta_minutes: int = 30) -> dict:
ex = ExaminationSchedule.query.first()
if ex is None:
date = datetime.datetime.now()
else:
date = ex.start_date
return {
"start_date": (date + datetime.timedelta(days=1)).strftime(
"%Y-%m-%dT%H:%M:%S.000Z"
),
"end_date": (
date + datetime.timedelta(days=1, minutes=timedelta_minutes)
).strftime("%Y-%m-%dT%H:%M:%S.000Z"),
}