chore: learning mentor course → course session
This commit is contained in:
parent
b48d8c0fc3
commit
e374ad98de
|
|
@ -3,6 +3,7 @@ import { useCurrentCourseSession } from "@/composables";
|
||||||
import ItModal from "@/components/ui/ItModal.vue";
|
import ItModal from "@/components/ui/ItModal.vue";
|
||||||
import { computed, ref } from "vue";
|
import { computed, ref } from "vue";
|
||||||
import { useCSRFFetch } from "@/fetchHelpers";
|
import { useCSRFFetch } from "@/fetchHelpers";
|
||||||
|
import { useUserStore } from "@/stores/user";
|
||||||
|
|
||||||
const courseSession = useCurrentCourseSession();
|
const courseSession = useCurrentCourseSession();
|
||||||
|
|
||||||
|
|
@ -33,6 +34,12 @@ const hasMentors = computed(() => {
|
||||||
});
|
});
|
||||||
|
|
||||||
const validEmail = computed(() => {
|
const validEmail = computed(() => {
|
||||||
|
const isSelfInvitation = Boolean(inviteeEmail.value === useUserStore().email);
|
||||||
|
|
||||||
|
if (isSelfInvitation) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
|
const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
|
||||||
return emailRegex.test(inviteeEmail.value);
|
return emailRegex.test(inviteeEmail.value);
|
||||||
});
|
});
|
||||||
|
|
@ -81,7 +88,7 @@ const inviteMentor = async () => {
|
||||||
<div
|
<div
|
||||||
v-for="invitation in invitations"
|
v-for="invitation in invitations"
|
||||||
:key="invitation.id"
|
:key="invitation.id"
|
||||||
class="flex flex-col justify-between gap-4 border-b py-2 md:flex-row md:gap-16"
|
class="flex flex-col justify-between gap-4 border-b py-2 last:border-b-0 md:flex-row md:gap-16"
|
||||||
>
|
>
|
||||||
<div class="flex flex-col md:flex-grow md:flex-row">
|
<div class="flex flex-col md:flex-grow md:flex-row">
|
||||||
<div class="flex items-center space-x-2">
|
<div class="flex items-center space-x-2">
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useCSRFFetch } from "@/fetchHelpers";
|
import { useCSRFFetch } from "@/fetchHelpers";
|
||||||
import { getCockpitUrl } from "@/utils/utils";
|
import { getLearningMentorUrl } from "@/utils/utils";
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
courseId: string;
|
courseId: string;
|
||||||
|
|
@ -56,8 +56,8 @@ const { data, error } = useCSRFFetch(
|
||||||
</template>
|
</template>
|
||||||
</i18next>
|
</i18next>
|
||||||
<div class="mt-4">
|
<div class="mt-4">
|
||||||
<a class="underline" :href="getCockpitUrl(data.course_slug)">
|
<a class="underline" :href="getLearningMentorUrl(data.course_slug)">
|
||||||
{{ $t("a.Cockpit anschauen") }}
|
{{ $t("a.Übersicht anschauen") }}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
|
|
@ -118,9 +118,6 @@ urlpatterns = [
|
||||||
|
|
||||||
# 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/sessions/<signed_int:course_session_id>/users/",
|
|
||||||
# get_course_session_users,
|
|
||||||
# name="get_course_session_users"),
|
|
||||||
path(r"api/course/page/<slug_or_id>/", course_page_api_view,
|
path(r"api/course/page/<slug_or_id>/", course_page_api_view,
|
||||||
name="course_page_api_view"),
|
name="course_page_api_view"),
|
||||||
path(r"api/course/completion/mark/", mark_course_completion_view,
|
path(r"api/course/completion/mark/", mark_course_completion_view,
|
||||||
|
|
|
||||||
|
|
@ -344,24 +344,24 @@ def command(
|
||||||
attendance_course.save()
|
attendance_course.save()
|
||||||
|
|
||||||
if create_learning_mentor:
|
if create_learning_mentor:
|
||||||
|
cs_bern = CourseSession.objects.get(id=TEST_COURSE_SESSION_BERN_ID)
|
||||||
|
|
||||||
uk_mentor = LearningMentor.objects.create(
|
uk_mentor = LearningMentor.objects.create(
|
||||||
course=Course.objects.get(id=COURSE_TEST_ID),
|
|
||||||
mentor=User.objects.get(id=TEST_MENTOR1_USER_ID),
|
mentor=User.objects.get(id=TEST_MENTOR1_USER_ID),
|
||||||
|
course_session=cs_bern,
|
||||||
)
|
)
|
||||||
uk_mentor.participants.add(
|
uk_mentor.participants.add(
|
||||||
CourseSessionUser.objects.get(
|
CourseSessionUser.objects.get(
|
||||||
user__id=TEST_STUDENT1_USER_ID,
|
user__id=TEST_STUDENT1_USER_ID,
|
||||||
course_session=CourseSession.objects.get(
|
course_session=cs_bern,
|
||||||
id=TEST_COURSE_SESSION_BERN_ID
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
vv_course = Course.objects.get(id=COURSE_VERSICHERUNGSVERMITTLERIN_ID)
|
vv_course = Course.objects.get(id=COURSE_VERSICHERUNGSVERMITTLERIN_ID)
|
||||||
vv_course_session = CourseSession.objects.get(course=vv_course)
|
vv_course_session = CourseSession.objects.get(course=vv_course)
|
||||||
vv_mentor = LearningMentor.objects.create(
|
vv_mentor = LearningMentor.objects.create(
|
||||||
course=vv_course,
|
|
||||||
mentor=User.objects.get(id=TEST_MENTOR1_USER_ID),
|
mentor=User.objects.get(id=TEST_MENTOR1_USER_ID),
|
||||||
|
course_session=vv_course_session,
|
||||||
)
|
)
|
||||||
|
|
||||||
vv_mentor.participants.add(
|
vv_mentor.participants.add(
|
||||||
|
|
@ -371,7 +371,7 @@ def command(
|
||||||
)
|
)
|
||||||
|
|
||||||
vv_mentor.participants.add(
|
vv_mentor.participants.add(
|
||||||
CourseSessionUser.objec.get(
|
CourseSessionUser.objects.get(
|
||||||
user__id=TEST_STUDENT2_VV_AND_VV_MENTOR_USER_ID,
|
user__id=TEST_STUDENT2_VV_AND_VV_MENTOR_USER_ID,
|
||||||
course_session=vv_course_session,
|
course_session=vv_course_session,
|
||||||
)
|
)
|
||||||
|
|
@ -379,7 +379,7 @@ def command(
|
||||||
|
|
||||||
vv_student_and_mentor = LearningMentor.objects.create(
|
vv_student_and_mentor = LearningMentor.objects.create(
|
||||||
mentor=User.objects.get(id=TEST_STUDENT2_VV_AND_VV_MENTOR_USER_ID),
|
mentor=User.objects.get(id=TEST_STUDENT2_VV_AND_VV_MENTOR_USER_ID),
|
||||||
course=vv_course,
|
course_session=vv_course_session,
|
||||||
)
|
)
|
||||||
|
|
||||||
vv_student_and_mentor.participants.add(
|
vv_student_and_mentor.participants.add(
|
||||||
|
|
|
||||||
|
|
@ -100,9 +100,11 @@ def create_course_session(
|
||||||
|
|
||||||
|
|
||||||
def add_learning_mentor(
|
def add_learning_mentor(
|
||||||
course: Course, mentor: User, mentee: CourseSessionUser
|
course_session: CourseSession, mentor: User, mentee: CourseSessionUser
|
||||||
) -> LearningMentor:
|
) -> LearningMentor:
|
||||||
learning_mentor = LearningMentor.objects.create(course=course, mentor=mentor)
|
learning_mentor = LearningMentor.objects.create(
|
||||||
|
course_session=course_session, mentor=mentor
|
||||||
|
)
|
||||||
learning_mentor.participants.add(mentee)
|
learning_mentor.participants.add(mentee)
|
||||||
return learning_mentor
|
return learning_mentor
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ class CourseCompletionApiTestCase(APITestCase):
|
||||||
self.assertEqual(len(response.json()), 0)
|
self.assertEqual(len(response.json()), 0)
|
||||||
|
|
||||||
def test_api_courseSession_withCourseSessionUser(self):
|
def test_api_courseSession_withCourseSessionUser(self):
|
||||||
csu = CourseSessionUser.objects.create(
|
CourseSessionUser.objects.create(
|
||||||
course_session=self.course_session,
|
course_session=self.course_session,
|
||||||
user=self.user,
|
user=self.user,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -155,8 +155,8 @@ def get_course_sessions(request):
|
||||||
|
|
||||||
# enrich with mentor course sessions
|
# enrich with mentor course sessions
|
||||||
mentor_course_sessions = CourseSession.objects.filter(
|
mentor_course_sessions = CourseSession.objects.filter(
|
||||||
course__in=LearningMentor.objects.filter(mentor=request.user).values_list(
|
id__in=LearningMentor.objects.filter(mentor=request.user).values_list(
|
||||||
"course", flat=True
|
"course_session", flat=True
|
||||||
)
|
)
|
||||||
).prefetch_related("course")
|
).prefetch_related("course")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -192,14 +192,14 @@ def get_learning_mentor_dashboards(
|
||||||
user: User, exclude_course_ids: Set[int]
|
user: User, exclude_course_ids: Set[int]
|
||||||
) -> Tuple[List[Dict[str, str]], Set[int]]:
|
) -> Tuple[List[Dict[str, str]], Set[int]]:
|
||||||
learning_mentor = LearningMentor.objects.filter(mentor=user).exclude(
|
learning_mentor = LearningMentor.objects.filter(mentor=user).exclude(
|
||||||
course_id__in=exclude_course_ids
|
course_session__course__id__in=exclude_course_ids
|
||||||
)
|
)
|
||||||
|
|
||||||
dashboards = []
|
dashboards = []
|
||||||
course_ids = set()
|
course_ids = set()
|
||||||
|
|
||||||
for mentor in learning_mentor:
|
for mentor in learning_mentor:
|
||||||
course = mentor.course
|
course = mentor.course_session.course
|
||||||
course_ids.add(course.id)
|
course_ids.add(course.id)
|
||||||
dashboards.append(
|
dashboards.append(
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -268,7 +268,7 @@ class DashboardTestCase(GraphQLTestCase):
|
||||||
role=CourseSessionUser.Role.MEMBER,
|
role=CourseSessionUser.Role.MEMBER,
|
||||||
)
|
)
|
||||||
|
|
||||||
add_learning_mentor(course=course_1, mentor=mentor, mentee=csu)
|
add_learning_mentor(course_session=cs_1, mentor=mentor, mentee=csu)
|
||||||
|
|
||||||
self.client.force_login(mentor)
|
self.client.force_login(mentor)
|
||||||
|
|
||||||
|
|
@ -314,7 +314,7 @@ class DashboardTestCase(GraphQLTestCase):
|
||||||
role=CourseSessionUser.Role.MEMBER,
|
role=CourseSessionUser.Role.MEMBER,
|
||||||
)
|
)
|
||||||
|
|
||||||
add_learning_mentor(course=course, mentor=mentor_and_member, mentee=mentee)
|
add_learning_mentor(course_session=cs, mentor=mentor_and_member, mentee=mentee)
|
||||||
|
|
||||||
# WHEN
|
# WHEN
|
||||||
self.client.force_login(mentor_and_member)
|
self.client.force_login(mentor_and_member)
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,9 @@ def has_course_access(user, course_id):
|
||||||
).exists():
|
).exists():
|
||||||
return True
|
return True
|
||||||
|
|
||||||
if LearningMentor.objects.filter(course_id=course_id, mentor=user).exists():
|
if LearningMentor.objects.filter(
|
||||||
|
course_session__course_id=course_id, mentor=user
|
||||||
|
).exists():
|
||||||
return True
|
return True
|
||||||
|
|
||||||
return CourseSessionUser.objects.filter(
|
return CourseSessionUser.objects.filter(
|
||||||
|
|
@ -71,7 +73,7 @@ def is_learning_mentor(mentor: User, course_session_id: int):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
return LearningMentor.objects.filter(
|
return LearningMentor.objects.filter(
|
||||||
mentor=mentor, course_id=course_session.course_id
|
mentor=mentor, course_session=course_session
|
||||||
).exists()
|
).exists()
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -86,7 +88,7 @@ def is_learning_mentor_for_user(
|
||||||
return False
|
return False
|
||||||
|
|
||||||
return LearningMentor.objects.filter(
|
return LearningMentor.objects.filter(
|
||||||
course_id=csu.course_session.course_id, mentor=mentor, participants=csu
|
course_session_id=course_session_id, mentor=mentor, participants=csu
|
||||||
).exists()
|
).exists()
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -211,7 +213,9 @@ def has_role_in_course(user: User, course: Course) -> bool:
|
||||||
).exists():
|
).exists():
|
||||||
return True
|
return True
|
||||||
|
|
||||||
if LearningMentor.objects.filter(course=course, mentor=user).exists():
|
if LearningMentor.objects.filter(
|
||||||
|
course_session__course=course, mentor=user
|
||||||
|
).exists():
|
||||||
return True
|
return True
|
||||||
|
|
||||||
if CourseSessionGroup.objects.filter(course=course, supervisor=user).exists():
|
if CourseSessionGroup.objects.filter(course=course, supervisor=user).exists():
|
||||||
|
|
|
||||||
|
|
@ -21,10 +21,7 @@ class ActionTestCase(TestCase):
|
||||||
def test_course_session_permissions(self):
|
def test_course_session_permissions(self):
|
||||||
# GIVEN
|
# GIVEN
|
||||||
lm = create_user("mentor")
|
lm = create_user("mentor")
|
||||||
LearningMentor.objects.create(
|
LearningMentor.objects.create(mentor=lm, course_session=self.course_session)
|
||||||
mentor=lm,
|
|
||||||
course=self.course,
|
|
||||||
)
|
|
||||||
|
|
||||||
participant = create_user("participant")
|
participant = create_user("participant")
|
||||||
add_course_session_user(
|
add_course_session_user(
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ class RoleTestCase(TestCase):
|
||||||
# GIVEN
|
# GIVEN
|
||||||
LearningMentor.objects.create(
|
LearningMentor.objects.create(
|
||||||
mentor=self.user,
|
mentor=self.user,
|
||||||
course=self.course,
|
course_session=self.course_session,
|
||||||
)
|
)
|
||||||
|
|
||||||
# WHEN
|
# WHEN
|
||||||
|
|
@ -75,7 +75,7 @@ class RoleTestCase(TestCase):
|
||||||
|
|
||||||
learning_mentor = LearningMentor.objects.create(
|
learning_mentor = LearningMentor.objects.create(
|
||||||
mentor=mentor,
|
mentor=mentor,
|
||||||
course=course,
|
course_session=course_session,
|
||||||
)
|
)
|
||||||
|
|
||||||
learning_mentor.participants.add(member_csu)
|
learning_mentor.participants.add(member_csu)
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ class LearningMentorAdmin(admin.ModelAdmin):
|
||||||
|
|
||||||
participant_count.short_description = "Participants"
|
participant_count.short_description = "Participants"
|
||||||
|
|
||||||
list_display = ["mentor", "course", "participant_count"]
|
list_display = ["mentor", "course_session", "participant_count"]
|
||||||
|
|
||||||
search_fields = ["mentor__email"]
|
search_fields = ["mentor__email"]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,57 @@
|
||||||
|
# Generated by Django 3.2.20 on 2024-03-19 09:58
|
||||||
|
|
||||||
|
import django.db.models.deletion
|
||||||
|
from django.conf import settings
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
def reverse_migrate_course_session_to_course(apps, schema_editor):
|
||||||
|
LearningMentor = apps.get_model("learning_mentor", "LearningMentor")
|
||||||
|
for lm in LearningMentor.objects.all():
|
||||||
|
lm.course = lm.course_session.course
|
||||||
|
lm.save()
|
||||||
|
|
||||||
|
|
||||||
|
def migrate_course_to_course_session(apps, schema_editor):
|
||||||
|
LearningMentor = apps.get_model("learning_mentor", "LearningMentor")
|
||||||
|
CourseSession = apps.get_model("course", "CourseSession")
|
||||||
|
|
||||||
|
for lm in LearningMentor.objects.all():
|
||||||
|
# first is fine for VV there is only one course session per course
|
||||||
|
course_session = CourseSession.objects.filter(course=lm.course).first()
|
||||||
|
lm.course_session = course_session
|
||||||
|
lm.save()
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
dependencies = [
|
||||||
|
("course", "0007_auto_20240226_1553"),
|
||||||
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||||
|
("learning_mentor", "0005_alter_learningmentor_mentor"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="learningmentor",
|
||||||
|
name="course_session",
|
||||||
|
field=models.ForeignKey(
|
||||||
|
# this is a dummy value, it will be replaced by the migration
|
||||||
|
default=-1,
|
||||||
|
on_delete=django.db.models.deletion.CASCADE,
|
||||||
|
to="course.coursesession",
|
||||||
|
),
|
||||||
|
preserve_default=False,
|
||||||
|
),
|
||||||
|
migrations.AlterUniqueTogether(
|
||||||
|
name="learningmentor",
|
||||||
|
unique_together={("mentor", "course_session")},
|
||||||
|
),
|
||||||
|
migrations.RunPython(
|
||||||
|
code=migrate_course_to_course_session,
|
||||||
|
reverse_code=reverse_migrate_course_session_to_course,
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name="learningmentor",
|
||||||
|
name="course",
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -9,7 +9,7 @@ from vbv_lernwelt.course.models import CourseSessionUser
|
||||||
|
|
||||||
class LearningMentor(models.Model):
|
class LearningMentor(models.Model):
|
||||||
mentor = models.ForeignKey(User, on_delete=models.CASCADE)
|
mentor = models.ForeignKey(User, on_delete=models.CASCADE)
|
||||||
course = models.ForeignKey("course.Course", on_delete=models.CASCADE)
|
course_session = models.ForeignKey("course.CourseSession", on_delete=models.CASCADE)
|
||||||
|
|
||||||
participants = models.ManyToManyField(
|
participants = models.ManyToManyField(
|
||||||
CourseSessionUser,
|
CourseSessionUser,
|
||||||
|
|
@ -18,7 +18,7 @@ class LearningMentor(models.Model):
|
||||||
)
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
unique_together = [["mentor", "course"]]
|
unique_together = [["mentor", "course_session"]]
|
||||||
verbose_name = "Lernbegleiter"
|
verbose_name = "Lernbegleiter"
|
||||||
verbose_name_plural = "Lernbegleiter"
|
verbose_name_plural = "Lernbegleiter"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,9 @@ def validate_student(sender, instance, action, reverse, model, pk_set, **kwargs)
|
||||||
if action == "pre_add":
|
if action == "pre_add":
|
||||||
participants = model.objects.filter(pk__in=pk_set)
|
participants = model.objects.filter(pk__in=pk_set)
|
||||||
for participant in participants:
|
for participant in participants:
|
||||||
if participant.course_session.course != instance.course:
|
if participant.course_session != instance.course_session:
|
||||||
raise ValidationError(
|
raise ValidationError(
|
||||||
"Participant (CourseSessionUser) does not match the course for this mentor."
|
"Participant (CourseSessionUser) does not match the course for this mentor."
|
||||||
)
|
)
|
||||||
|
if participant.user == instance.mentor:
|
||||||
|
raise ValidationError("You cannot mentor yourself.")
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,34 @@ class LearningMentorInvitationTest(APITestCase):
|
||||||
# THEN
|
# THEN
|
||||||
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
|
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
|
||||||
|
|
||||||
|
@patch("vbv_lernwelt.learning_mentor.views.send_email")
|
||||||
|
def test_create_denies_self_invitation(self, mock_send_mail) -> None:
|
||||||
|
# GIVEN
|
||||||
|
self.client.force_login(self.participant)
|
||||||
|
|
||||||
|
add_course_session_user(
|
||||||
|
self.course_session,
|
||||||
|
self.participant,
|
||||||
|
role=CourseSessionUser.Role.MEMBER,
|
||||||
|
)
|
||||||
|
|
||||||
|
invite_url = reverse(
|
||||||
|
"create_invitation", kwargs={"course_session_id": self.course_session.id}
|
||||||
|
)
|
||||||
|
|
||||||
|
# WHEN
|
||||||
|
email = self.participant.email
|
||||||
|
response = self.client.post(invite_url, data={"email": email})
|
||||||
|
|
||||||
|
# THEN
|
||||||
|
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
|
||||||
|
self.assertEqual(
|
||||||
|
response.data,
|
||||||
|
{
|
||||||
|
"message": "You cannot invite yourself",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
@patch("vbv_lernwelt.learning_mentor.views.send_email")
|
@patch("vbv_lernwelt.learning_mentor.views.send_email")
|
||||||
def test_create_invitation(self, mock_send_mail) -> None:
|
def test_create_invitation(self, mock_send_mail) -> None:
|
||||||
# GIVEN
|
# GIVEN
|
||||||
|
|
@ -164,49 +192,11 @@ class LearningMentorInvitationTest(APITestCase):
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_accept_invitation_role_collision(self) -> None:
|
|
||||||
# GIVEN
|
|
||||||
participant_cs_user = add_course_session_user(
|
|
||||||
self.course_session,
|
|
||||||
self.participant,
|
|
||||||
role=CourseSessionUser.Role.MEMBER,
|
|
||||||
)
|
|
||||||
|
|
||||||
invitee = create_user("invitee")
|
|
||||||
invitation = MentorInvitation.objects.create(
|
|
||||||
participant=participant_cs_user, email=invitee.email
|
|
||||||
)
|
|
||||||
# Make invitee a trainer
|
|
||||||
add_course_session_user(
|
|
||||||
self.course_session,
|
|
||||||
invitee,
|
|
||||||
role=CourseSessionUser.Role.EXPERT,
|
|
||||||
)
|
|
||||||
|
|
||||||
self.client.force_login(invitee)
|
|
||||||
|
|
||||||
accept_url = reverse(
|
|
||||||
"accept_invitation", kwargs={"course_session_id": self.course_session.id}
|
|
||||||
)
|
|
||||||
|
|
||||||
# WHEN
|
|
||||||
response = self.client.post(accept_url, data={"invitation_id": invitation.id})
|
|
||||||
|
|
||||||
# THEN
|
|
||||||
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
|
|
||||||
self.assertEqual(
|
|
||||||
response.data,
|
|
||||||
{
|
|
||||||
"message": "User already has a role in this course",
|
|
||||||
"code": "existingRole",
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_accept_invitation(self) -> None:
|
def test_accept_invitation(self) -> None:
|
||||||
# GIVEN
|
# GIVEN
|
||||||
participant_cs_user = add_course_session_user(
|
participant_cs_user = add_course_session_user(
|
||||||
self.course_session,
|
course_session=self.course_session,
|
||||||
self.participant,
|
user=self.participant,
|
||||||
role=CourseSessionUser.Role.MEMBER,
|
role=CourseSessionUser.Role.MEMBER,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -229,7 +219,9 @@ class LearningMentorInvitationTest(APITestCase):
|
||||||
self.assertFalse(MentorInvitation.objects.filter(id=invitation.id).exists())
|
self.assertFalse(MentorInvitation.objects.filter(id=invitation.id).exists())
|
||||||
self.assertTrue(
|
self.assertTrue(
|
||||||
LearningMentor.objects.filter(
|
LearningMentor.objects.filter(
|
||||||
mentor=invitee, course=self.course, participants=participant_cs_user
|
mentor=invitee,
|
||||||
|
course_session=self.course_session,
|
||||||
|
participants=participant_cs_user,
|
||||||
).exists()
|
).exists()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -77,7 +77,7 @@ class LearningMentorAPITest(APITestCase):
|
||||||
# GIVEN
|
# GIVEN
|
||||||
self.client.force_login(self.mentor)
|
self.client.force_login(self.mentor)
|
||||||
LearningMentor.objects.create(
|
LearningMentor.objects.create(
|
||||||
mentor=self.mentor, course=self.course_session.course
|
mentor=self.mentor, course_session=self.course_session
|
||||||
)
|
)
|
||||||
|
|
||||||
# WHEN
|
# WHEN
|
||||||
|
|
@ -93,8 +93,7 @@ class LearningMentorAPITest(APITestCase):
|
||||||
participants = [self.participant_1, self.participant_2, self.participant_3]
|
participants = [self.participant_1, self.participant_2, self.participant_3]
|
||||||
self.client.force_login(self.mentor)
|
self.client.force_login(self.mentor)
|
||||||
mentor = LearningMentor.objects.create(
|
mentor = LearningMentor.objects.create(
|
||||||
mentor=self.mentor,
|
mentor=self.mentor, course_session=self.course_session
|
||||||
course=self.course_session.course,
|
|
||||||
)
|
)
|
||||||
mentor.participants.set(participants)
|
mentor.participants.set(participants)
|
||||||
|
|
||||||
|
|
@ -120,8 +119,7 @@ class LearningMentorAPITest(APITestCase):
|
||||||
self.client.force_login(self.mentor)
|
self.client.force_login(self.mentor)
|
||||||
|
|
||||||
mentor = LearningMentor.objects.create(
|
mentor = LearningMentor.objects.create(
|
||||||
mentor=self.mentor,
|
mentor=self.mentor, course_session=self.course_session
|
||||||
course=self.course_session.course,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
mentor.participants.set(participants)
|
mentor.participants.set(participants)
|
||||||
|
|
@ -204,7 +202,7 @@ class LearningMentorAPITest(APITestCase):
|
||||||
|
|
||||||
mentor = LearningMentor.objects.create(
|
mentor = LearningMentor.objects.create(
|
||||||
mentor=self.mentor,
|
mentor=self.mentor,
|
||||||
course=self.course_session.course,
|
course_session=self.course_session,
|
||||||
)
|
)
|
||||||
|
|
||||||
participants = [self.participant_1, self.participant_2, self.participant_3]
|
participants = [self.participant_1, self.participant_2, self.participant_3]
|
||||||
|
|
@ -265,8 +263,7 @@ class LearningMentorAPITest(APITestCase):
|
||||||
)
|
)
|
||||||
|
|
||||||
learning_mentor = LearningMentor.objects.create(
|
learning_mentor = LearningMentor.objects.create(
|
||||||
mentor=self.mentor,
|
mentor=self.mentor, course_session=self.course_session
|
||||||
course=self.course_session.course,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
learning_mentor.participants.add(participant_cs_user)
|
learning_mentor.participants.add(participant_cs_user)
|
||||||
|
|
@ -300,8 +297,7 @@ class LearningMentorAPITest(APITestCase):
|
||||||
)
|
)
|
||||||
|
|
||||||
learning_mentor = LearningMentor.objects.create(
|
learning_mentor = LearningMentor.objects.create(
|
||||||
mentor=self.mentor,
|
mentor=self.mentor, course_session=self.course_session
|
||||||
course=self.course_session.course,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
learning_mentor.participants.add(participant_cs_user)
|
learning_mentor.participants.add(participant_cs_user)
|
||||||
|
|
@ -326,11 +322,19 @@ class LearningMentorAPITest(APITestCase):
|
||||||
def test_mentor_multiple_courses(self) -> None:
|
def test_mentor_multiple_courses(self) -> None:
|
||||||
# GIVEN
|
# GIVEN
|
||||||
course_a, _ = create_course("Course A")
|
course_a, _ = create_course("Course A")
|
||||||
|
course_session_a = create_course_session(course=course_a, title="Test A")
|
||||||
|
|
||||||
course_b, _ = create_course("Course B")
|
course_b, _ = create_course("Course B")
|
||||||
|
course_session_b = create_course_session(course=course_b, title="Test B")
|
||||||
|
|
||||||
# WHEN
|
# WHEN
|
||||||
LearningMentor.objects.create(mentor=self.mentor, course=course_a)
|
LearningMentor.objects.create(
|
||||||
LearningMentor.objects.create(mentor=self.mentor, course=course_b)
|
mentor=self.mentor, course_session=course_session_a
|
||||||
|
)
|
||||||
|
|
||||||
|
LearningMentor.objects.create(
|
||||||
|
mentor=self.mentor, course_session=course_session_b
|
||||||
|
)
|
||||||
|
|
||||||
# THEN
|
# THEN
|
||||||
self.assertEqual(LearningMentor.objects.count(), 2)
|
self.assertEqual(LearningMentor.objects.count(), 2)
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ from rest_framework.response import Response
|
||||||
|
|
||||||
from vbv_lernwelt.core.serializers import UserSerializer
|
from vbv_lernwelt.core.serializers import UserSerializer
|
||||||
from vbv_lernwelt.course.models import CourseSession, CourseSessionUser
|
from vbv_lernwelt.course.models import CourseSession, CourseSessionUser
|
||||||
from vbv_lernwelt.iam.permissions import has_role_in_course, is_course_session_member
|
from vbv_lernwelt.iam.permissions import is_course_session_member
|
||||||
from vbv_lernwelt.learning_mentor.content.praxis_assignment import (
|
from vbv_lernwelt.learning_mentor.content.praxis_assignment import (
|
||||||
get_praxis_assignments,
|
get_praxis_assignments,
|
||||||
)
|
)
|
||||||
|
|
@ -31,7 +31,7 @@ def mentor_summary(request, course_session_id: int):
|
||||||
course_session = CourseSession.objects.get(id=course_session_id)
|
course_session = CourseSession.objects.get(id=course_session_id)
|
||||||
|
|
||||||
mentor = get_object_or_404(
|
mentor = get_object_or_404(
|
||||||
LearningMentor, mentor=request.user, course=course_session.course
|
LearningMentor, mentor=request.user, course_session=course_session
|
||||||
)
|
)
|
||||||
|
|
||||||
participants = mentor.participants.filter(course_session=course_session)
|
participants = mentor.participants.filter(course_session=course_session)
|
||||||
|
|
@ -129,8 +129,13 @@ def create_invitation(request, course_session_id: int):
|
||||||
if not serializer.is_valid():
|
if not serializer.is_valid():
|
||||||
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
invitation = serializer.save()
|
if serializer.validated_data.get("email") == user.email:
|
||||||
|
return Response(
|
||||||
|
data={"message": "You cannot invite yourself"},
|
||||||
|
status=status.HTTP_400_BAD_REQUEST,
|
||||||
|
)
|
||||||
|
|
||||||
|
invitation = serializer.save()
|
||||||
target_url = f"/lernbegleitung/{course_session_id}/invitation/{invitation.id}"
|
target_url = f"/lernbegleitung/{course_session_id}/invitation/{invitation.id}"
|
||||||
|
|
||||||
send_email(
|
send_email(
|
||||||
|
|
@ -158,7 +163,7 @@ def list_user_mentors(request, course_session_id: int):
|
||||||
)
|
)
|
||||||
|
|
||||||
mentors = LearningMentor.objects.filter(
|
mentors = LearningMentor.objects.filter(
|
||||||
course=course_session.course, participants=course_session_user
|
course_session=course_session, participants=course_session_user
|
||||||
)
|
)
|
||||||
|
|
||||||
return Response(MentorSerializer(mentors, many=True).data)
|
return Response(MentorSerializer(mentors, many=True).data)
|
||||||
|
|
@ -193,25 +198,9 @@ def accept_invitation(request, course_session_id: int):
|
||||||
status=status.HTTP_400_BAD_REQUEST,
|
status=status.HTTP_400_BAD_REQUEST,
|
||||||
)
|
)
|
||||||
|
|
||||||
if LearningMentor.objects.filter(
|
mentor, _ = LearningMentor.objects.get_or_create(
|
||||||
mentor=request.user, course=course_session.course
|
mentor=request.user, course_session=course_session
|
||||||
).exists():
|
)
|
||||||
mentor = LearningMentor.objects.get(
|
|
||||||
mentor=request.user, course=course_session.course
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
if has_role_in_course(request.user, course_session.course):
|
|
||||||
return Response(
|
|
||||||
data={
|
|
||||||
"message": "User already has a role in this course",
|
|
||||||
"code": "existingRole",
|
|
||||||
},
|
|
||||||
status=status.HTTP_400_BAD_REQUEST,
|
|
||||||
)
|
|
||||||
|
|
||||||
mentor = LearningMentor.objects.create(
|
|
||||||
mentor=request.user, course=course_session.course
|
|
||||||
)
|
|
||||||
|
|
||||||
mentor.participants.add(invitation.participant)
|
mentor.participants.add(invitation.participant)
|
||||||
invitation.delete()
|
invitation.delete()
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@ class SelfEvaluationFeedbackAPI(APITestCase):
|
||||||
|
|
||||||
learning_mentor = LearningMentor.objects.create(
|
learning_mentor = LearningMentor.objects.create(
|
||||||
mentor=self.mentor,
|
mentor=self.mentor,
|
||||||
course=self.course_session.course,
|
course_session=self.course_session,
|
||||||
)
|
)
|
||||||
|
|
||||||
learning_mentor.participants.add(member_csu)
|
learning_mentor.participants.add(member_csu)
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ def start_self_evaluation_feedback(request, learning_unit_id):
|
||||||
feedback_provider_user = get_object_or_404(User, id=feedback_provider_user_id)
|
feedback_provider_user = get_object_or_404(User, id=feedback_provider_user_id)
|
||||||
|
|
||||||
if not LearningMentor.objects.filter(
|
if not LearningMentor.objects.filter(
|
||||||
course=learning_unit.get_course(),
|
course_session__course=learning_unit.get_course(),
|
||||||
mentor=feedback_provider_user,
|
mentor=feedback_provider_user,
|
||||||
participants__user=request.user,
|
participants__user=request.user,
|
||||||
).exists():
|
).exists():
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue