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
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)
|