2 changed files with 177 additions and 17 deletions
@ -0,0 +1,145 @@ |
|||
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}, |
|||
) |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue