You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

133 lines
4.8 KiB

from django.core.files.uploadedfile import SimpleUploadedFile
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
from apps.quiz.models.quiz import Quiz, Question
class CourseAccessGuardsTests(APITestCase):
def setUp(self):
self.professor = ProfessorUser.objects.create(
email='prof-guard@example.com',
fullname='Professor Guard',
experience_years=5,
)
self.outsider = StudentUser.objects.create(
email='outsider@example.com',
fullname='Outsider Student',
)
self.category = CourseCategory.objects.create(
name='Guard Category',
slug='guard-category',
)
thumbnail = SimpleUploadedFile('guard.jpg', b'filecontent', content_type='image/jpeg')
self.course = Course.objects.create(
title='Guard Course',
slug='guard-course',
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,
)
self.chapter = CourseChapter.objects.create(
course=self.course,
title='Chapter 1',
priority=1,
is_active=True,
)
lesson = Lesson.objects.create(
title='Lesson 1',
content_type=Lesson.ContentTypeChoices.VIDEO_FILE,
duration=5,
)
self.course_lesson = CourseLesson.objects.create(
course=self.course,
chapter=self.chapter,
lesson=lesson,
priority=1,
is_active=True,
)
self.quiz = Quiz.objects.create(
lesson=self.course_lesson,
course=self.course,
title='Guard Quiz',
description='Quiz description',
each_question_timing=30,
status=True,
)
self.question = Question.objects.create(
quiz=self.quiz,
question='What is 2+2?',
option1='4',
option2='3',
option3='2',
option4='1',
correct_answer=1,
priority=1,
)
def test_lesson_list_marks_lessons_and_quizzes_inactive_without_course_access(self):
self.client.force_authenticate(user=self.outsider)
response = self.client.get(f'/api/courses/{self.course.slug}/lessons/')
self.assertEqual(response.status_code, status.HTTP_200_OK)
lesson_data = response.data['results'][0]
self.assertFalse(lesson_data['permission'])
self.assertFalse(lesson_data['is_active'])
self.assertFalse(lesson_data['quizs'][0]['permission'])
def test_lesson_list_v2_marks_chapter_inactive_without_course_access(self):
self.client.force_authenticate(user=self.outsider)
response = self.client.get(f'/api/courses/v2/{self.course.slug}/lessons/')
self.assertEqual(response.status_code, status.HTTP_200_OK)
chapter_data = response.data['results'][0]
self.assertFalse(chapter_data['is_active'])
self.assertFalse(chapter_data['lessons'][0]['is_active'])
def test_quiz_detail_rejects_users_without_course_access(self):
self.client.force_authenticate(user=self.outsider)
response = self.client.get(f'/api/quiz/{self.quiz.id}/')
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
def test_quiz_submit_rejects_users_without_course_access(self):
self.client.force_authenticate(user=self.outsider)
payload = {
'quiz': self.quiz.id,
'started_at': '2026-06-02T10:00:00Z',
'ended_at': '2026-06-02T10:01:00Z',
'total_timing': 60,
'question_score': 1,
'timing_score': 1,
'total_score': 2,
'answers': [
{
'question': self.question.id,
'option_num': 1,
'at_time': '2026-06-02T10:00:30Z',
'answer_timing': 30,
}
],
}
response = self.client.post('/api/quiz/submit-quiz/', payload, format='json')
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
self.assertIn('quiz', response.data)