from django.core.files.uploadedfile import SimpleUploadedFile from django.core.files.uploadedfile import SimpleUploadedFile from django.urls import reverse from rest_framework import status from rest_framework.test import APITestCase from apps.account.models import ProfessorUser, StudentUser from apps.course.models.course import Course, CourseCategory from apps.course.models.lesson import CourseChapter, CourseLesson, Lesson, LessonCompletion from apps.course.models.participant import Participant class MyCoursesAPITests(APITestCase): def setUp(self): self.professor = ProfessorUser.objects.create( email='prof@example.com', fullname='Professor Example', experience_years=5, ) self.student = StudentUser.objects.create( email='student@example.com', fullname='Student Example', ) self.category = CourseCategory.objects.create( name='Category', slug='category', ) def _create_course(self, slug, title): thumbnail = SimpleUploadedFile('thumb.jpg', b'filecontent', content_type='image/jpeg') return Course.objects.create( title=title, slug=slug, category=self.category, professor=self.professor, thumbnail=thumbnail, video_type=Course.VedioTypeChoices.YOUTUBE_LINK, video_link='https://example.com/video', is_online=False, level=Course.LevelChoices.BEGINNER, duration=10, lessons_count=0, description='Description', short_description='Short description', status=Course.StatusChoices.ONGOING, is_free=True, ) def _attach_lessons(self, course, lesson_specs): chapter = CourseChapter.objects.create( course=course, title=f'{course.title} Chapter', priority=1, is_active=True, ) created_lessons = [] for index, spec in enumerate(lesson_specs, start=1): lesson = Lesson.objects.create( title=spec['title'], content_type=Lesson.ContentTypeChoices.VIDEO_FILE, duration=5, ) course_lesson = CourseLesson.objects.create( course=course, chapter=chapter, lesson=lesson, priority=index, is_active=spec.get('is_active', True), ) created_lessons.append(course_lesson) return created_lessons def test_completed_filter_returns_only_courses_with_all_active_lessons_completed(self): completed_course = self._create_course('completed-course', 'Completed Course') partial_course = self._create_course('partial-course', 'Partial Course') empty_course = self._create_course('empty-course', 'Empty Course') completed_lessons = self._attach_lessons( completed_course, [ {'title': 'Completed Lesson 1'}, {'title': 'Completed Lesson 2'}, {'title': 'Inactive Lesson', 'is_active': False}, ], ) partial_lessons = self._attach_lessons( partial_course, [ {'title': 'Partial Lesson 1'}, {'title': 'Partial Lesson 2'}, ], ) Participant.objects.create(student=self.student, course=completed_course) Participant.objects.create(student=self.student, course=partial_course) Participant.objects.create(student=self.student, course=empty_course) LessonCompletion.objects.create(student=self.student, course_lesson=completed_lessons[0]) LessonCompletion.objects.create(student=self.student, course_lesson=completed_lessons[1]) LessonCompletion.objects.create(student=self.student, course_lesson=partial_lessons[0]) self.client.force_authenticate(user=self.student) url = reverse('course-my-courses-list') response = self.client.get(url, {'completed': 'true'}, format='json') self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.data['count'], 1) self.assertEqual({item['slug'] for item in response.data['results']}, {completed_course.slug}) def test_my_courses_without_completed_filter_returns_completed_and_incomplete_courses(self): completed_course = self._create_course('all-completed-course', 'All Completed Course') partial_course = self._create_course('all-partial-course', 'All Partial Course') completed_lessons = self._attach_lessons( completed_course, [ {'title': 'Completed Lesson 1'}, ], ) partial_lessons = self._attach_lessons( partial_course, [ {'title': 'Partial Lesson 1'}, {'title': 'Partial Lesson 2'}, ], ) Participant.objects.create(student=self.student, course=completed_course) Participant.objects.create(student=self.student, course=partial_course) LessonCompletion.objects.create(student=self.student, course_lesson=completed_lessons[0]) LessonCompletion.objects.create(student=self.student, course_lesson=partial_lessons[0]) self.client.force_authenticate(user=self.student) url = reverse('course-my-courses-list') response = self.client.get(url, format='json') self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.data['count'], 2) self.assertEqual( {item['slug'] for item in response.data['results']}, {completed_course.slug, partial_course.slug}, )