4 changed files with 144 additions and 70 deletions
-
25apps/course/management/commands/assign_professors.py
-
133apps/course/tests/test_live_session_subjects.py
-
23apps/course/views/course.py
-
33apps/course/views/live_session.py
@ -1,25 +0,0 @@ |
|||
from django.core.management.base import BaseCommand |
|||
from apps.course.models import Course |
|||
from apps.account.models import ProfessorUser |
|||
import random |
|||
|
|||
class Command(BaseCommand): |
|||
help = 'Assign at least one professor to every course (if missing)' |
|||
|
|||
def handle(self, *args, **options): |
|||
# Gather all active professors |
|||
professors = list(ProfessorUser.objects.filter(is_active=True)) |
|||
if not professors: |
|||
self.stdout.write(self.style.ERROR('No active professors found.')) |
|||
return |
|||
|
|||
updated = 0 |
|||
for course in Course.objects.all(): |
|||
if course.professors.exists(): |
|||
continue # already has a professor |
|||
professor = random.choice(professors) |
|||
course.professors.add(professor) |
|||
updated += 1 |
|||
self.stdout.write(f'Added professor {professor.id} to course {course.id}') |
|||
|
|||
self.stdout.write(self.style.SUCCESS(f'Finished. Updated {updated} course(s).')) |
|||
@ -0,0 +1,133 @@ |
|||
import tempfile |
|||
from unittest import mock |
|||
|
|||
from django.core.files.uploadedfile import SimpleUploadedFile |
|||
from django.test import override_settings |
|||
from django.urls import reverse |
|||
from django.utils import timezone |
|||
from dj_language.models import Language |
|||
from rest_framework import status |
|||
from rest_framework.test import APITestCase |
|||
|
|||
from apps.account.models import ProfessorUser |
|||
from apps.course.models import Course, CourseCategory, CourseLiveSession |
|||
from apps.course.views.course import get_course_slug_value |
|||
|
|||
|
|||
@override_settings( |
|||
PLUGNMEET_SERVER_URL='https://meet.example.com', |
|||
PLUGNMEET_API_KEY='test-key', |
|||
PLUGNMEET_API_SECRET='test-secret', |
|||
MEDIA_ROOT=tempfile.gettempdir(), |
|||
ONLINE_CLASS_FRONTEND_DOMAIN='http://testserver', |
|||
) |
|||
class CourseLiveSessionSubjectTests(APITestCase): |
|||
def setUp(self): |
|||
Language.objects.update_or_create( |
|||
id=69, |
|||
defaults={ |
|||
'code': 'en', |
|||
'name': 'English', |
|||
'status': True, |
|||
'countries': [], |
|||
}, |
|||
) |
|||
self.professor = ProfessorUser.objects.create( |
|||
email='subject-prof@example.com', |
|||
fullname='Subject Professor', |
|||
experience_years=5, |
|||
) |
|||
self.category = CourseCategory.objects.create(name='Category', slug='category') |
|||
thumbnail = SimpleUploadedFile('thumb.jpg', b'filecontent', content_type='image/jpeg') |
|||
self.course = Course.objects.create( |
|||
title=[{'title': 'Sample Course', 'language_code': 'en'}], |
|||
slug=[{'title': 'sample-course', 'language_code': 'en'}], |
|||
category=self.category, |
|||
thumbnail=thumbnail, |
|||
video_type=Course.VedioTypeChoices.YOUTUBE_LINK, |
|||
video_link='https://example.com/video', |
|||
is_online=True, |
|||
online_link='https://example.com/live', |
|||
level=[{'title': 'beginner', 'language_code': 'en'}], |
|||
duration=10, |
|||
lessons_count=2, |
|||
description=[{'title': 'Description', 'language_code': 'en'}], |
|||
short_description=[{'title': 'Short', 'language_code': 'en'}], |
|||
status=[{'title': 'ongoing', 'language_code': 'en'}], |
|||
is_free=True, |
|||
) |
|||
self.course.professors.add(self.professor) |
|||
|
|||
@mock.patch('apps.course.views.live_session.PlugNMeetClient') |
|||
def test_room_create_uses_incremental_subject(self, mock_client_cls): |
|||
mock_client_cls.return_value.create_room.return_value = {'status': 'success'} |
|||
CourseLiveSession.objects.create( |
|||
course=self.course, |
|||
room_id='room-old', |
|||
subject='Live Session 1', |
|||
started_at=timezone.now(), |
|||
ended_at=timezone.now(), |
|||
) |
|||
|
|||
self.client.force_authenticate(user=self.professor) |
|||
url = reverse( |
|||
'course-live-session-room-create', |
|||
kwargs={'slug': get_course_slug_value(self.course)}, |
|||
) |
|||
response = self.client.post(url, {}, format='json') |
|||
|
|||
self.assertEqual(response.status_code, status.HTTP_201_CREATED) |
|||
session = CourseLiveSession.objects.filter( |
|||
course=self.course, |
|||
ended_at__isnull=True, |
|||
).latest('id') |
|||
self.assertEqual(session.subject, 'Live Session 2') |
|||
|
|||
@mock.patch('apps.course.views.course.PlugNMeetClient') |
|||
def test_validate_professor_create_uses_incremental_subject(self, mock_client_cls): |
|||
mock_client = mock_client_cls.return_value |
|||
mock_client.create_room.return_value = {'status': 'success'} |
|||
mock_client.get_join_token.return_value = {'token': 'teacher-access-token'} |
|||
CourseLiveSession.objects.create( |
|||
course=self.course, |
|||
room_id='room-old', |
|||
subject='Live Session 1', |
|||
started_at=timezone.now(), |
|||
ended_at=timezone.now(), |
|||
) |
|||
|
|||
self.client.force_authenticate(user=self.professor) |
|||
url = reverse( |
|||
'course-online-validate', |
|||
kwargs={'slug': get_course_slug_value(self.course)}, |
|||
) |
|||
response = self.client.get(url) |
|||
|
|||
self.assertEqual(response.status_code, status.HTTP_200_OK) |
|||
session = CourseLiveSession.objects.filter( |
|||
course=self.course, |
|||
ended_at__isnull=True, |
|||
).latest('id') |
|||
self.assertEqual(session.subject, 'Live Session 2') |
|||
|
|||
def test_set_recording_title_updates_session_subject(self): |
|||
session = CourseLiveSession.objects.create( |
|||
course=self.course, |
|||
room_id='room-active', |
|||
subject='Live Session 1', |
|||
started_at=timezone.now(), |
|||
) |
|||
|
|||
response = self.client.post( |
|||
reverse('course-live-session-set-recording-title'), |
|||
{ |
|||
'room_id': session.room_id, |
|||
'title': 'machine learning', |
|||
}, |
|||
format='json', |
|||
) |
|||
|
|||
self.assertEqual(response.status_code, status.HTTP_200_OK) |
|||
session.refresh_from_db() |
|||
self.assertEqual(session.recording_title, 'machine learning') |
|||
self.assertEqual(session.subject, 'machine learning') |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue