Add dashboard persons api view

This commit is contained in:
Daniel Egger 2024-04-03 07:10:13 +02:00
parent 16ebd23edf
commit e13d72eb8a
8 changed files with 277 additions and 66 deletions

View File

@ -10,6 +10,9 @@ from django.views import defaults as default_views
from django.views.decorators.csrf import csrf_exempt from django.views.decorators.csrf import csrf_exempt
from django_ratelimit.exceptions import Ratelimited from django_ratelimit.exceptions import Ratelimited
from graphene_django.views import GraphQLView from graphene_django.views import GraphQLView
from wagtail import urls as wagtail_urls
from wagtail.admin import urls as wagtailadmin_urls
from wagtail.documents import urls as media_library_urls
from vbv_lernwelt.api.directory import list_entities from vbv_lernwelt.api.directory import list_entities
from vbv_lernwelt.api.user import get_profile, me_user_view, post_avatar from vbv_lernwelt.api.user import get_profile, me_user_view, post_avatar
@ -39,6 +42,7 @@ from vbv_lernwelt.course.views import (
request_course_completion_for_user, request_course_completion_for_user,
) )
from vbv_lernwelt.course_session.views import get_course_session_documents from vbv_lernwelt.course_session.views import get_course_session_documents
from vbv_lernwelt.dashboard.views import get_dashboard_persons
from vbv_lernwelt.edoniq_test.views import ( from vbv_lernwelt.edoniq_test.views import (
export_students, export_students,
export_students_and_trainers, export_students_and_trainers,
@ -57,9 +61,6 @@ from vbv_lernwelt.importer.views import (
) )
from vbv_lernwelt.media_files.views import user_image from vbv_lernwelt.media_files.views import user_image
from vbv_lernwelt.notify.views import email_notification_settings from vbv_lernwelt.notify.views import email_notification_settings
from wagtail import urls as wagtail_urls
from wagtail.admin import urls as wagtailadmin_urls
from wagtail.documents import urls as media_library_urls
class SignedIntConverter(IntConverter): class SignedIntConverter(IntConverter):
@ -116,6 +117,9 @@ urlpatterns = [
re_path(r"api/notify/email_notification_settings/$", email_notification_settings, re_path(r"api/notify/email_notification_settings/$", email_notification_settings,
name='email_notification_settings'), name='email_notification_settings'),
# dashboard
path(r"api/dashboard/persons/", get_dashboard_persons, name="get_dashboard_persons"),
# course # course
path(r"api/course/sessions/", get_course_sessions, name="get_course_sessions"), path(r"api/course/sessions/", get_course_sessions, name="get_course_sessions"),
path(r"api/course/page/<slug_or_id>/", course_page_api_view, path(r"api/course/page/<slug_or_id>/", course_page_api_view,

View File

@ -26,7 +26,9 @@ from wagtail.blocks.list_block import ListBlock, ListValue
from wagtail.rich_text import RichText from wagtail.rich_text import RichText
def create_uk_fahrzeug_casework(course_id=COURSE_UK, competence_certificate=None): def create_uk_fahrzeug_casework(
course_id=COURSE_UK, competence_certificate=None, with_documents=False
):
assignment_list_page = ( assignment_list_page = (
CoursePage.objects.get(course_id=course_id) CoursePage.objects.get(course_id=course_id)
.get_children() .get_children()
@ -40,7 +42,6 @@ def create_uk_fahrzeug_casework(course_id=COURSE_UK, competence_certificate=None
needs_expert_evaluation=True, needs_expert_evaluation=True,
competence_certificate=competence_certificate, competence_certificate=competence_certificate,
effort_required="ca. 5 Stunden", effort_required="ca. 5 Stunden",
solution_sample=ContentDocument.objects.get(title="Musterlösung Fahrzeug"),
intro_text=replace_whitespace( intro_text=replace_whitespace(
""" """
<h3>Ausgangslage</h3> <h3>Ausgangslage</h3>
@ -70,6 +71,11 @@ def create_uk_fahrzeug_casework(course_id=COURSE_UK, competence_certificate=None
evaluation_document_url="/static/media/assignments/UK_03_09_NACH_KN_Beurteilungsraster.pdf", evaluation_document_url="/static/media/assignments/UK_03_09_NACH_KN_Beurteilungsraster.pdf",
evaluation_description="Diese geleitete Fallarbeit wird auf Grund des folgenden Beurteilungsintrument bewertet.", evaluation_description="Diese geleitete Fallarbeit wird auf Grund des folgenden Beurteilungsintrument bewertet.",
) )
if with_documents:
assignment.solution_sample = ContentDocument.objects.get(
title="Musterlösung Fahrzeug"
)
assignment.save()
assignment.evaluation_tasks = [] assignment.evaluation_tasks = []
assignment.evaluation_tasks.append( assignment.evaluation_tasks.append(
@ -3591,7 +3597,7 @@ def create_uk_reflection(course_id=COURSE_UK):
assignment = AssignmentFactory( assignment = AssignmentFactory(
parent=assignment_list_page, parent=assignment_list_page,
assignment_type=AssignmentType.REFLECTION.name, assignment_type=AssignmentType.REFLECTION.name,
title=f"Reflexion", title="Reflexion",
effort_required="ca. 1 Stunde", effort_required="ca. 1 Stunde",
intro_text=replace_whitespace( intro_text=replace_whitespace(
""" """
@ -3747,7 +3753,7 @@ def create_uk_fr_reflection(course_id=COURSE_UK_FR, circle_title="Véhicule"):
assignment = AssignmentFactory( assignment = AssignmentFactory(
parent=assignment_list_page, parent=assignment_list_page,
assignment_type=AssignmentType.REFLECTION.name, assignment_type=AssignmentType.REFLECTION.name,
title=f"Reflexion", title="Reflexion",
effort_required="", effort_required="",
intro_text=replace_whitespace( intro_text=replace_whitespace(
""" """
@ -3900,7 +3906,7 @@ def create_uk_it_reflection(course_id=COURSE_UK_FR, circle_title="Véhicule"):
assignment = AssignmentFactory( assignment = AssignmentFactory(
parent=assignment_list_page, parent=assignment_list_page,
assignment_type=AssignmentType.REFLECTION.name, assignment_type=AssignmentType.REFLECTION.name,
title=f"Riflessione", title="Riflessione",
effort_required="", effort_required="",
intro_text=replace_whitespace( intro_text=replace_whitespace(
""" """
@ -4053,7 +4059,7 @@ def create_vv_reflection(
assignment = AssignmentFactory( assignment = AssignmentFactory(
parent=assignment_list_page, parent=assignment_list_page,
assignment_type=AssignmentType.REFLECTION.name, assignment_type=AssignmentType.REFLECTION.name,
title=f"Reflexion", title="Reflexion",
effort_required="ca. 1 Stunde", effort_required="ca. 1 Stunde",
intro_text=replace_whitespace( intro_text=replace_whitespace(
""" """

View File

@ -97,9 +97,12 @@ from vbv_lernwelt.media_library.tests.media_library_factories import (
) )
def create_test_course(include_uk=True, include_vv=True, with_sessions=False): def create_test_course(
include_uk=True, include_vv=True, with_sessions=False, with_documents=False
):
# create_locales_for_wagtail() # create_locales_for_wagtail()
create_default_collections() create_default_collections()
if with_documents:
create_default_content_documents() create_default_content_documents()
if UserImage.objects.count() == 0 and ContentImage.objects.count() == 0: if UserImage.objects.count() == 0 and ContentImage.objects.count() == 0:
create_default_images() create_default_images()
@ -118,7 +121,9 @@ def create_test_course(include_uk=True, include_vv=True, with_sessions=False):
if include_uk: if include_uk:
create_uk_fahrzeug_casework( create_uk_fahrzeug_casework(
course_id=COURSE_TEST_ID, competence_certificate=competence_certificate course_id=COURSE_TEST_ID,
competence_certificate=competence_certificate,
with_documents=with_documents,
) )
create_uk_fahrzeug_prep_assignment(course_id=COURSE_TEST_ID) create_uk_fahrzeug_prep_assignment(course_id=COURSE_TEST_ID)
create_uk_condition_acceptance(course_id=COURSE_TEST_ID) create_uk_condition_acceptance(course_id=COURSE_TEST_ID)
@ -132,7 +137,9 @@ def create_test_course(include_uk=True, include_vv=True, with_sessions=False):
if include_vv: if include_vv:
create_vv_gewinnen_casework(course_id=COURSE_TEST_ID) create_vv_gewinnen_casework(course_id=COURSE_TEST_ID)
create_test_learning_path(include_uk=include_uk, include_vv=include_vv) create_test_learning_path(
include_uk=include_uk, include_vv=include_vv, with_documents=with_documents
)
create_test_media_library() create_test_media_library()
if with_sessions: if with_sessions:
@ -187,7 +194,7 @@ def create_test_course(include_uk=True, include_vv=True, with_sessions=False):
csa = CourseSessionAssignment.objects.create( csa = CourseSessionAssignment.objects.create(
course_session=cs_bern, course_session=cs_bern,
learning_content=LearningContentAssignment.objects.get( learning_content=LearningContentAssignment.objects.get(
slug=f"test-lehrgang-lp-circle-fahrzeug-lc-fahrzeug-mein-erstes-auto" slug="test-lehrgang-lp-circle-fahrzeug-lc-fahrzeug-mein-erstes-auto"
), ),
) )
next_monday = datetime.now() + relativedelta(weekday=MO(2)) next_monday = datetime.now() + relativedelta(weekday=MO(2))
@ -215,7 +222,7 @@ def create_test_course(include_uk=True, include_vv=True, with_sessions=False):
_csa = CourseSessionAssignment.objects.create( _csa = CourseSessionAssignment.objects.create(
course_session=cs_bern, course_session=cs_bern,
learning_content=LearningContentAssignment.objects.get( learning_content=LearningContentAssignment.objects.get(
slug=f"test-lehrgang-lp-circle-reisen-lc-mein-kundenstamm" slug="test-lehrgang-lp-circle-reisen-lc-mein-kundenstamm"
), ),
) )
@ -418,20 +425,22 @@ def create_test_course_with_categories(apps=None, schema_editor=None):
return course return course
def create_test_learning_path(include_uk=True, include_vv=True): def create_test_learning_path(include_uk=True, include_vv=True, with_documents=False):
course_page = CoursePage.objects.get(course_id=COURSE_TEST_ID) course_page = CoursePage.objects.get(course_id=COURSE_TEST_ID)
lp = LearningPathFactory(title="Test Lernpfad", parent=course_page) lp = LearningPathFactory(title="Test Lernpfad", parent=course_page)
if include_uk: if include_uk:
TopicFactory(title="Circle ÜK", is_visible=False, parent=lp) TopicFactory(title="Circle ÜK", is_visible=False, parent=lp)
create_test_uk_circle_fahrzeug(lp, title="Fahrzeug") create_test_uk_circle_fahrzeug(
lp, title="Fahrzeug", with_documents=with_documents
)
if include_vv: if include_vv:
TopicFactory(title="Circle VV", is_visible=False, parent=lp) TopicFactory(title="Circle VV", is_visible=False, parent=lp)
create_test_circle_reisen(lp) create_test_circle_reisen(lp)
def create_test_uk_circle_fahrzeug(lp, title="Fahrzeug"): def create_test_uk_circle_fahrzeug(lp, title="Fahrzeug", with_documents=False):
circle = CircleFactory( circle = CircleFactory(
title=title, title=title,
parent=lp, parent=lp,
@ -470,6 +479,7 @@ damit du erfolgreich mit deinem Lernpfad (durch-)starten kannst.
), ),
content_url=f"/course/{lp.get_course().slug}/media/handlungsfelder/{slugify(title)}", content_url=f"/course/{lp.get_course().slug}/media/handlungsfelder/{slugify(title)}",
) )
(
LearningContentAssignmentFactory( LearningContentAssignmentFactory(
title="Redlichkeitserklärung", title="Redlichkeitserklärung",
parent=circle, parent=circle,
@ -477,6 +487,8 @@ damit du erfolgreich mit deinem Lernpfad (durch-)starten kannst.
slug__startswith="test-lehrgang-assignment-redlichkeits" slug__startswith="test-lehrgang-assignment-redlichkeits"
), ),
), ),
)
(
LearningContentAssignmentFactory( LearningContentAssignmentFactory(
title="Fahrzeug - Mein erstes Auto", title="Fahrzeug - Mein erstes Auto",
assignment_type="PREP_ASSIGNMENT", assignment_type="PREP_ASSIGNMENT",
@ -485,6 +497,7 @@ damit du erfolgreich mit deinem Lernpfad (durch-)starten kannst.
slug__startswith="test-lehrgang-assignment-fahrzeug-mein-erstes-auto" slug__startswith="test-lehrgang-assignment-fahrzeug-mein-erstes-auto"
), ),
), ),
)
PerformanceCriteriaFactory( PerformanceCriteriaFactory(
parent=ActionCompetence.objects.get(competence_id="X1"), parent=ActionCompetence.objects.get(competence_id="X1"),
@ -531,18 +544,21 @@ damit du erfolgreich mit deinem Lernpfad (durch-)starten kannst.
LearningSequenceFactory(title="Transfer", parent=circle, icon="it-icon-ls-end") LearningSequenceFactory(title="Transfer", parent=circle, icon="it-icon-ls-end")
LearningUnitFactory(title="Transfer", parent=circle) LearningUnitFactory(title="Transfer", parent=circle)
(
LearningContentAssignmentFactory( LearningContentAssignmentFactory(
title="Reflexion", title="Reflexion",
assignment_type="REFLECTION", assignment_type="REFLECTION",
parent=circle, parent=circle,
content_assignment=Assignment.objects.get( content_assignment=Assignment.objects.get(
slug__startswith=f"test-lehrgang-assignment-reflexion" slug__startswith="test-lehrgang-assignment-reflexion"
), ),
), ),
)
assignment = Assignment.objects.get( assignment = Assignment.objects.get(
slug__startswith="test-lehrgang-assignment-überprüfen-einer-motorfahrzeugs" slug__startswith="test-lehrgang-assignment-überprüfen-einer-motorfahrzeugs"
) )
if with_documents:
assignment.solution_sample = ContentDocument.objects.get( assignment.solution_sample = ContentDocument.objects.get(
title="Musterlösung Fahrzeug" title="Musterlösung Fahrzeug"
) )
@ -574,9 +590,9 @@ def create_test_circle_reisen(lp):
description="Willkommen im Lehrgang Versicherungsvermitler VBV", description="Willkommen im Lehrgang Versicherungsvermitler VBV",
) )
LearningContentMediaLibraryFactory( LearningContentMediaLibraryFactory(
title=f"Mediathek Reisen", title="Mediathek Reisen",
parent=circle, parent=circle,
content_url=f"/course/test-lehrgang/media/handlungsfelder/reisen", content_url="/course/test-lehrgang/media/handlungsfelder/reisen",
) )
LearningSequenceFactory(title="Analyse", parent=circle) LearningSequenceFactory(title="Analyse", parent=circle)
@ -596,6 +612,7 @@ def create_test_circle_reisen(lp):
content_url="https://s3.eu-central-1.amazonaws.com/myvbv-wbt.iterativ.ch/emma-und-ayla-campen-durch-amerika-analyse-xapi-FZoZOP9y/index.html", content_url="https://s3.eu-central-1.amazonaws.com/myvbv-wbt.iterativ.ch/emma-und-ayla-campen-durch-amerika-analyse-xapi-FZoZOP9y/index.html",
) )
(
LearningContentAssignmentFactory( LearningContentAssignmentFactory(
title="Mein Kundenstamm", title="Mein Kundenstamm",
assignment_type="PRAXIS_ASSIGNMENT", assignment_type="PRAXIS_ASSIGNMENT",
@ -604,17 +621,18 @@ def create_test_circle_reisen(lp):
slug__startswith="test-lehrgang-assignment-mein-kundenstamm" slug__startswith="test-lehrgang-assignment-mein-kundenstamm"
), ),
), ),
)
PerformanceCriteriaFactory( PerformanceCriteriaFactory(
parent=ActionCompetence.objects.get(competence_id="Y1"), parent=ActionCompetence.objects.get(competence_id="Y1"),
competence_id=f"Y1.1", competence_id="Y1.1",
title=f"Ich bin fähig zu Reisen eine Gesprächsführung zu machen", title="Ich bin fähig zu Reisen eine Gesprächsführung zu machen",
learning_unit=lu, learning_unit=lu,
) )
PerformanceCriteriaFactory( PerformanceCriteriaFactory(
parent=ActionCompetence.objects.get(competence_id="Y2"), parent=ActionCompetence.objects.get(competence_id="Y2"),
competence_id=f"Y2.1", competence_id="Y2.1",
title=f"Ich bin fähig zu Reisen eine Analyse zu machen", title="Ich bin fähig zu Reisen eine Analyse zu machen",
learning_unit=lu, learning_unit=lu,
) )
@ -627,7 +645,7 @@ def create_test_circle_reisen(lp):
parent=parent, parent=parent,
) )
LearningContentPlaceholderFactory( LearningContentPlaceholderFactory(
title=f"Fachcheck Reisen", title="Fachcheck Reisen",
parent=parent, parent=parent,
) )
LearningContentKnowledgeAssessmentFactory( LearningContentKnowledgeAssessmentFactory(
@ -757,9 +775,9 @@ def create_test_media_library():
die der Fahrzeugbesitzer und die Fahrzeugbesitzerin in einem grösseren Schadenfall oft nur schwer selbst aufbringen kann. die der Fahrzeugbesitzer und die Fahrzeugbesitzerin in einem grösseren Schadenfall oft nur schwer selbst aufbringen kann.
""".strip(), """.strip(),
body=RichText( body=RichText(
f"<h2>Lernmedien</h2>" "<h2>Lernmedien</h2>"
f"<h3>Allgemeines</h3>" "<h3>Allgemeines</h3>"
f"<ul><li>Mit Risiken im Strassenverkehr umgehen</li><li>Versicherungsschutz</li><li>Vertragsarten</li><li>Zusammenfassung</li></ul>" "<ul><li>Mit Risiken im Strassenverkehr umgehen</li><li>Versicherungsschutz</li><li>Vertragsarten</li><li>Zusammenfassung</li></ul>"
), ),
) )
@ -778,9 +796,9 @@ def create_test_media_library():
title=cat, title=cat,
parent=media_lib_allgemeines, parent=media_lib_allgemeines,
body=RichText( body=RichText(
f"<h2>Lernmedien</h2>" "<h2>Lernmedien</h2>"
f"<h3>Allgemeines</h3>" "<h3>Allgemeines</h3>"
f"<ul><li>Mit Risiken im Strassenverkehr umgehen</li><li>Versicherungsschutz</li><li>Vertragsarten</li><li>Zusammenfassung</li></ul>" "<ul><li>Mit Risiken im Strassenverkehr umgehen</li><li>Versicherungsschutz</li><li>Vertragsarten</li><li>Zusammenfassung</li></ul>"
), ),
) )

View File

@ -182,7 +182,7 @@ def command(course):
create_course_uk_it() create_course_uk_it()
if COURSE_TEST_ID in course: if COURSE_TEST_ID in course:
create_test_course(with_sessions=True) create_test_course(with_sessions=True, with_documents=True)
if COURSE_UK_TRAINING in course: if COURSE_UK_TRAINING in course:
create_course_training_de() create_course_training_de()

View File

@ -73,16 +73,22 @@ class CourseSessionSerializer(serializers.ModelSerializer):
course = serializers.SerializerMethodField() course = serializers.SerializerMethodField()
due_dates = serializers.SerializerMethodField() due_dates = serializers.SerializerMethodField()
actions = serializers.SerializerMethodField() actions = serializers.SerializerMethodField()
user_roles = serializers.SerializerMethodField()
def get_course(self, obj): def get_course(self, obj):
return CourseSerializer(obj.course).data return CourseSerializer(obj.course).data
def get_due_dates(self, obj): def get_due_dates(self, obj):
due_dates = DueDate.objects.filter( due_dates = DueDate.objects.filter(
Q(start__isnull=False) | Q(end__isnull=False), course_session=obj Q(start__isnull=False) | Q(end__isnull=False), course_session_id=obj.id
) )
return DueDateSerializer(due_dates, many=True).data return DueDateSerializer(due_dates, many=True).data
def get_user_roles(self, obj):
if hasattr(obj, "roles"):
return list(obj.roles)
return []
class Meta: class Meta:
model = CourseSession model = CourseSession
fields = [ fields = [
@ -95,6 +101,7 @@ class CourseSessionSerializer(serializers.ModelSerializer):
"end_date", "end_date",
"due_dates", "due_dates",
"actions", "actions",
"user_roles",
] ]
read_only_fields = ["actions"] read_only_fields = ["actions"]

View File

@ -0,0 +1,86 @@
from django.test import TestCase
from vbv_lernwelt.course.creators.test_utils import (
create_course,
create_course_session,
create_user,
add_course_session_user,
create_course_session_group,
add_course_session_group_supervisor,
)
from vbv_lernwelt.course.models import CourseSessionUser
from vbv_lernwelt.dashboard.views import get_course_sessions_with_roles_for_user
from vbv_lernwelt.learning_mentor.models import LearningMentor
class GetCourseSessionsForUserTestCase(TestCase):
def setUp(self):
self.course, _ = create_course("Test Course")
self.course_session = create_course_session(
course=self.course, title="Test Session"
)
def test_participant_get_sessions(self):
# participant gets all his sessions marked with role "MEMBER"
participant = create_user("participant")
add_course_session_user(
self.course_session,
participant,
role=CourseSessionUser.Role.MEMBER,
)
# WHEN
sessions = get_course_sessions_with_roles_for_user(participant)
# THEN
self.assertEqual(len(sessions), 1)
self.assertEqual(sessions[0].title, "Test Session")
self.assertSetEqual(sessions[0].roles, {"MEMBER"})
def test_trainer_get_sessions(self):
# GIVEN
# trainer gets all his sessions marked with role "EXPERT"
trainer = create_user("trainer")
add_course_session_user(
self.course_session,
trainer,
role=CourseSessionUser.Role.EXPERT,
)
# WHEN
sessions = get_course_sessions_with_roles_for_user(trainer)
# THEN
self.assertEqual(len(sessions), 1)
self.assertEqual(sessions[0].title, "Test Session")
self.assertSetEqual(sessions[0].roles, {"EXPERT"})
def test_supervisor_get_sessions(self):
supervisor = create_user("supervisor")
group = create_course_session_group(course_session=self.course_session)
add_course_session_group_supervisor(group=group, user=supervisor)
sessions = get_course_sessions_with_roles_for_user(supervisor)
# THEN
self.assertEqual(len(sessions), 1)
self.assertEqual(sessions[0].title, "Test Session")
self.assertEqual(sessions[0].roles, {"SUPERVISOR"})
def test_learning_mentor_get_sessions(self):
mentor = create_user("mentor")
LearningMentor.objects.create(mentor=mentor, course_session=self.course_session)
participant = create_user("participant")
add_course_session_user(
self.course_session,
participant,
role=CourseSessionUser.Role.MEMBER,
)
sessions = get_course_sessions_with_roles_for_user(mentor)
# THEN
self.assertEqual(len(sessions), 1)
self.assertEqual(sessions[0].title, "Test Session")
self.assertEqual(sessions[0].roles, {"LEARNING_MENTOR"})

View File

@ -0,0 +1,87 @@
from dataclasses import dataclass
from typing import List, Set
from rest_framework.decorators import api_view
from rest_framework.exceptions import PermissionDenied
from rest_framework.response import Response
from vbv_lernwelt.core.models import User
from vbv_lernwelt.course.models import CourseSession, CourseSessionUser
from vbv_lernwelt.course.serializers import CourseSessionSerializer
from vbv_lernwelt.course.views import logger
from vbv_lernwelt.course_session_group.models import CourseSessionGroup
from vbv_lernwelt.learning_mentor.models import LearningMentor
@dataclass(frozen=True)
class CourseSessionWithRoles:
_original: CourseSession
roles: Set[str]
def __getattr__(self, name: str):
# Delegate attribute access to the _original CourseSession object
return getattr(self._original, name)
def save(self, *args, **kwargs):
raise NotImplementedError("This proxy object cannot be saved.")
def get_course_sessions_with_roles_for_user(user: User) -> List[CourseSessionWithRoles]:
result_course_sessions = {}
# participant/member/expert course sessions
csu_qs = CourseSessionUser.objects.filter(user=user).prefetch_related(
"course_session", "course_session__course"
)
for csu in csu_qs:
cs = csu.course_session
# member/expert is mutually exclusive...
cs.roles = {csu.role}
result_course_sessions[cs.id] = cs
# enrich with supervisor course sessions
csg_qs = CourseSessionGroup.objects.filter(supervisor=user).prefetch_related(
"course_session", "course_session__course"
)
for csg in csg_qs:
for cs in csg.course_session.all():
cs.roles = set()
cs = result_course_sessions.get(cs.id, cs)
cs.roles.add("SUPERVISOR")
result_course_sessions[cs.id] = cs
# enrich with mentor course sessions
lm_qs = LearningMentor.objects.filter(mentor=user).prefetch_related(
"course_session", "course_session__course"
)
for lm in lm_qs:
cs = lm.course_session
cs.roles = set()
cs = result_course_sessions.get(cs.id, cs)
cs.roles.add("LEARNING_MENTOR")
result_course_sessions[cs.id] = cs
return [
CourseSessionWithRoles(cs, cs.roles) for cs in result_course_sessions.values()
]
@api_view(["GET"])
def get_dashboard_persons(request):
try:
course_sessions = get_course_sessions_with_roles_for_user(request.user)
all_to_serialize = course_sessions
return Response(
status=200,
data=CourseSessionSerializer(
all_to_serialize, many=True, context={"user": request.user}
).data,
)
except PermissionDenied as e:
raise e
except Exception as e:
logger.error(e, exc_info=True)
return Response({"error": str(e)}, status=404)

View File

@ -48,15 +48,16 @@ class ActionTestCase(TestCase):
self.assertEqual( self.assertEqual(
mentor_actions, mentor_actions,
[ [
"is_learning_mentor",
"learning-mentor", "learning-mentor",
"learning-mentor::guide-members", "learning-mentor::guide-members",
"preview", "preview",
"appointments",
], ],
) )
self.assertEqual( self.assertEqual(
participant_actions, participant_actions,
[ [
"is_member",
"learning-mentor", "learning-mentor",
"learning-mentor::edit-mentors", "learning-mentor::edit-mentors",
"media-library", "media-library",
@ -69,6 +70,8 @@ class ActionTestCase(TestCase):
self.assertEqual( self.assertEqual(
trainer_actions, trainer_actions,
[ [
"is_expert",
"learning-mentor",
"preview", "preview",
"media-library", "media-library",
"appointments", "appointments",