vbv/server/vbv_lernwelt/course/creators/test_utils.py

409 lines
12 KiB
Python

from datetime import datetime, timedelta
from typing import List, Tuple
from django.contrib.auth.hashers import make_password
from django.utils import timezone
from vbv_lernwelt.assignment.models import (
Assignment,
AssignmentCompletion,
AssignmentCompletionStatus,
AssignmentType,
)
from vbv_lernwelt.assignment.tests.assignment_factories import (
AssignmentFactory,
AssignmentListPageFactory,
)
from vbv_lernwelt.competence.factories import (
ActionCompetenceFactory,
ActionCompetenceListPageFactory,
CompetenceCertificateFactory,
CompetenceCertificateListFactory,
CompetenceNaviPageFactory,
PerformanceCriteriaFactory,
)
from vbv_lernwelt.competence.models import CompetenceCertificate, PerformanceCriteria
from vbv_lernwelt.core.models import User
from vbv_lernwelt.course.consts import COURSE_TEST_ID, UK_COURSE_IDS, VV_COURSE_IDS
from vbv_lernwelt.course.factories import CoursePageFactory
from vbv_lernwelt.course.models import (
Course,
CourseCategory,
CoursePage,
CourseSession,
CourseSessionUser,
)
from vbv_lernwelt.course.utils import get_wagtail_default_site
from vbv_lernwelt.course_session.models import (
CourseSessionAssignment,
CourseSessionAttendanceCourse,
CourseSessionEdoniqTest,
)
from vbv_lernwelt.course_session_group.models import CourseSessionGroup
from vbv_lernwelt.duedate.models import DueDate
from vbv_lernwelt.learning_mentor.models import (
AgentParticipantRelation,
AgentParticipantRoleType,
)
from vbv_lernwelt.learnpath.models import (
Circle,
LearningContentAssignment,
LearningContentEdoniqTest,
LearningPath,
LearningUnit,
)
from vbv_lernwelt.learnpath.tests.learning_path_factories import (
CircleFactory,
LearningContentAssignmentFactory,
LearningContentAttendanceCourseFactory,
LearningContentEdoniqTestFactory,
LearningPathFactory,
LearningUnitFactory,
TopicFactory,
)
def create_course(
title: str = "Course Title", _id=None, course_page_title: str = "Test Lehrgang"
) -> Tuple[Course, CoursePage]:
course = Course.objects.create(id=_id, title=title, category_name="Handlungsfeld")
course_page = CoursePageFactory(
title=course_page_title,
parent=get_wagtail_default_site().root_page,
course=course,
)
course.slug = course_page.slug
course.save()
return course, course_page
def create_user(username: str) -> User:
return User.objects.create_user(
username=username,
password=make_password("test"),
email=f"{username}@example.com",
language="de",
first_name="Test",
last_name=username.capitalize(),
)
def create_course_session(
course: Course, title: str, generation: str = "2023", _id=None
) -> CourseSession:
return CourseSession.objects.create(
id=_id,
course=course,
title=title,
import_id=title,
generation=generation,
start_date=timezone.now(),
)
def add_learning_mentor(
mentor: User, mentee: CourseSessionUser
) -> AgentParticipantRelation:
return AgentParticipantRelation.objects.create(
agent=mentor,
participant=mentee,
role=AgentParticipantRoleType.LEARNING_MENTOR.value,
)
def add_course_session_user(
course_session: CourseSession, user: User, role: CourseSessionUser.Role
) -> CourseSessionUser:
return CourseSessionUser.objects.create(
course_session=course_session,
user=user,
role=role,
)
def create_course_session_group(course_session: CourseSession) -> CourseSessionGroup:
group = CourseSessionGroup.objects.create(
course=course_session.course,
)
group.course_session.add(course_session)
return group
def add_course_session_group_supervisor(group: CourseSessionGroup, user: User):
group.supervisor.add(user)
def add_course_session_group_course_session(
group: CourseSessionGroup, course_session: CourseSession
):
group.course_session.add(course_session)
def create_circle(
title: str, course_page: CoursePage, learning_path: LearningPath | None = None
) -> Tuple[Circle, LearningPath]:
if not learning_path:
learning_path = LearningPathFactory(title="Test Lernpfad", parent=course_page)
TopicFactory(title="Circle Test Topic", is_visible=False, parent=learning_path)
circle = CircleFactory(
title=title, parent=learning_path, description="Circle Description"
)
return circle, learning_path
def create_attendance_course(
course_session: CourseSession,
circle: Circle,
attendance_user_list: List,
due_date_end: datetime,
) -> CourseSessionAttendanceCourse:
learning_content_dummy = LearningContentAttendanceCourseFactory(
title="Lerninhalt Dummy",
parent=circle,
)
return CourseSessionAttendanceCourse.objects.create(
course_session=course_session,
learning_content=learning_content_dummy,
attendance_user_list=attendance_user_list,
due_date=DueDate.objects.create(
course_session=course_session,
start=due_date_end - timedelta(hours=8),
end=due_date_end,
),
)
def create_competence_certificate(course: Course) -> CompetenceCertificate:
navi = CompetenceNaviPageFactory(parent=course.coursepage)
certificate_list = CompetenceCertificateListFactory(parent=navi)
return CompetenceCertificateFactory(parent=certificate_list)
def create_assignment(
course: Course,
assignment_type: AssignmentType,
) -> Assignment:
return AssignmentFactory(
parent=AssignmentListPageFactory(
parent=course.coursepage,
),
assignment_type=assignment_type.name,
title=f"Dummy Assignment ({assignment_type.name})",
effort_required=":)",
intro_text=":)",
performance_objectives=[],
)
def create_assignment_completion(
user: User,
assignment: Assignment,
course_session: CourseSession,
has_passed: bool | None = None,
max_points: int = 0,
achieved_points: int = 0,
status: AssignmentCompletionStatus = AssignmentCompletionStatus.EVALUATION_SUBMITTED,
) -> AssignmentCompletion:
return AssignmentCompletion.objects.create(
completion_status=status.value,
assignment_user=user,
assignment=assignment,
evaluation_passed=has_passed,
course_session=course_session,
completion_data={},
evaluation_max_points=max_points,
evaluation_points=achieved_points,
)
def create_assignment_learning_content(
circle: Circle,
assignment: Assignment,
) -> LearningContentAssignment | LearningContentEdoniqTest:
if AssignmentType(assignment.assignment_type) == AssignmentType.EDONIQ_TEST:
return LearningContentEdoniqTestFactory(
title="Learning Content (EDONIQ_TEST)",
parent=circle,
content_assignment=assignment,
)
return LearningContentAssignmentFactory(
title=f"Learning Content ({assignment.assignment_type})",
parent=circle,
content_assignment=assignment,
)
def create_course_session_assignment(
course_session: CourseSession,
learning_content_assignment: LearningContentAssignment,
deadline_at: datetime | None = None,
) -> CourseSessionAssignment:
cas = CourseSessionAssignment.objects.create(
course_session=course_session,
learning_content=learning_content_assignment,
)
if deadline_at:
# the save on the course_session_assignment already sets a lot
# of due date fields, so it's easier to just overwrite the this
cas.submission_deadline.start = timezone.make_aware(deadline_at)
cas.submission_deadline.save()
return cas
def create_course_session_edoniq_test(
course_session: CourseSession,
learning_content_edoniq_test: LearningContentEdoniqTest,
deadline_at: datetime,
) -> CourseSessionEdoniqTest:
cset = CourseSessionEdoniqTest.objects.create(
course_session=course_session,
learning_content=learning_content_edoniq_test,
)
# same as above (see create_course_session_assignment)
cset.deadline.start = timezone.make_aware(deadline_at)
cset.deadline.save()
return cset
def create_learning_unit(
circle: Circle,
course: Course,
course_category_title: str = "Course Category",
) -> LearningUnit:
cat, _ = CourseCategory.objects.get_or_create(
course=course,
title=course_category_title,
)
return LearningUnitFactory(
title="Learning Unit",
parent=circle,
course_category=cat,
)
def create_performance_criteria_page(
course: Course,
course_page: CoursePage,
circle: Circle,
learning_unit: LearningUnitFactory | LearningUnit | None = None,
) -> PerformanceCriteria:
competence_navi_page = CompetenceNaviPageFactory(
title="Competence Navi",
parent=course_page,
)
competence_profile_page = ActionCompetenceListPageFactory(
title="Action Competence Page",
parent=competence_navi_page,
)
action_competence = ActionCompetenceFactory(
parent=competence_profile_page,
competence_id="X1",
title="Action Competence",
items=[("item", "Action Competence Item")],
)
if not learning_unit:
learning_unit = create_learning_unit(circle=circle, course=course)
return PerformanceCriteriaFactory(
parent=action_competence,
competence_id="X1.1",
title="Performance Criteria",
learning_unit=learning_unit,
)
def create_circle_expert(
course_session: CourseSession, circle: Circle, username: str
) -> CourseSessionUser:
expert_user = create_user(username)
course_session_expert_user = add_course_session_user(
course_session=course_session,
user=expert_user,
role=CourseSessionUser.Role.EXPERT,
)
course_session_expert_user.expert.add(circle)
return course_session_expert_user
def apply_course_configuration(course: Course):
"""
Apply course configuration based on course id:
By default everything is enabled, disable unnecessary features
"""
if course.id == COURSE_TEST_ID:
pass # all features are enabled
elif course.id in VV_COURSE_IDS:
course.configuration.enable_competence_certificates = False
elif course.id in UK_COURSE_IDS:
course.configuration.enable_learning_mentor = False
else:
raise ValueError(f"Unknown course id {course.id}")
course.configuration.save()
def create_course_with_categories(
course_id,
title,
apps=None,
):
if apps is not None:
Course = apps.get_model("course", "Course")
CourseCategory = apps.get_model("course", "CourseCategory")
else:
# pylint: disable=import-outside-toplevel
from vbv_lernwelt.course.models import Course, CourseCategory
course, _ = Course.objects.get_or_create(
id=course_id,
title=title,
category_name="Handlungsfeld",
)
apply_course_configuration(course)
CourseCategory.objects.get_or_create(course=course, title="Allgemein", general=True)
for cat in [
"Fahrzeug",
"Reisen",
"Einkommenssicherung",
"Gesundheit",
"Haushalt",
"Sparen",
"Pensionierung",
"KMU",
"Wohneigentum",
"Rechtsstreitigkeiten",
"Erben / Vererben",
"Selbstständigkeit",
]:
CourseCategory.objects.get_or_create(course=course, title=cat)
course_page = CoursePageFactory(
title=title,
parent=get_wagtail_default_site().root_page,
course=course,
)
course.slug = course_page.slug
course.save()
return course