Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions django_email_learning/api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,23 @@ def get(self, request, *args, **kwargs) -> JsonResponse: # type: ignore[no-unty
return JsonResponse({"error": "Course not found"}, status=404)


@method_decorator(accessible_for(roles={"admin", "editor", "viewer"}), name="get")
@method_decorator(accessible_for(roles={"admin", "editor"}), name="delete")
class SingleCourseContentView(View):
def get(self, request, *args, **kwargs) -> JsonResponse: # type: ignore[no-untyped-def]
try:
course_content = CourseContent.objects.get(id=kwargs["course_content_id"])
return JsonResponse(
serializers.CourseContentResponse.model_validate(
course_content
).model_dump(),
status=200,
)
except CourseContent.DoesNotExist:
return JsonResponse({"error": "Course content not found"}, status=404)
except ValidationError as e:
return JsonResponse({"error": e.errors()}, status=400)

def delete(self, request, *args, **kwargs): # type: ignore[no-untyped-def]
try:
course_content = CourseContent.objects.get(id=kwargs["course_content_id"])
Expand Down
72 changes: 44 additions & 28 deletions tests/api/test_views/test_course_content_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,19 @@ def get_url() -> str:
)


def single_content_url(
course_content_id: int, course_id: int, organization_id: int = 1
) -> str:
return reverse(
"django_email_learning:api:single_course_content_view",
kwargs={
"organization_id": organization_id,
"course_id": course_id,
"course_content_id": course_content_id,
},
)


def valid_create_course_payload(
title: str = "Python Course",
slug: str = "python",
Expand Down Expand Up @@ -389,37 +402,40 @@ def test_delete_course_content(superadmin_client, create_course):
assert get_response.status_code == 404


def test_viewer_cannot_delete_course_content(viewer_client, create_course):
url = get_url()
# Create a lesson content
lesson_payload = {
"content": {
"title": LESSON_TITLE,
"content": LESSON_CONTENT,
"type": "lesson",
},
"priority": 1,
"waiting_period": {"period": 2, "type": "days"},
}
response = viewer_client.post(
url, json.dumps(lesson_payload), content_type="application/json"
def test_viewer_cannot_delete_course_content(viewer_client, course_lesson_content):
url = single_content_url(
course_content_id=course_lesson_content.id,
course_id=course_lesson_content.course.id,
organization_id=course_lesson_content.course.organization.id,
)
response = viewer_client.delete(url)
assert response.status_code == 403


def test_anonymous_user_cannot_delete_course_content(anonymous_client, create_course):
url = get_url()
# Create a lesson content
lesson_payload = {
"content": {
"title": LESSON_TITLE,
"content": LESSON_CONTENT,
"type": "lesson",
},
"priority": 1,
"waiting_period": {"period": 2, "type": "days"},
}
response = anonymous_client.post(
url, json.dumps(lesson_payload), content_type="application/json"
def test_anonymous_user_cannot_delete_course_content(
anonymous_client, course_lesson_content
):
url = single_content_url(
course_content_id=course_lesson_content.id,
course_id=course_lesson_content.course.id,
organization_id=course_lesson_content.course.organization.id,
)
response = anonymous_client.delete(url)
assert response.status_code == 401


def test_get_course_content(viewer_client, course_lesson_content):
url = single_content_url(
course_content_id=course_lesson_content.id,
course_id=course_lesson_content.course.id,
organization_id=course_lesson_content.course.organization.id,
)
get_response = viewer_client.get(url)
assert get_response.status_code == 200
get_data = get_response.json()
assert get_data["id"] == course_lesson_content.id
assert get_data["type"] == "lesson"
assert get_data["priority"] == 1
assert get_data["waiting_period"] == {"period": 1, "type": "hours"}
assert get_data["lesson"]["title"] == course_lesson_content.lesson.title
assert get_data["lesson"]["content"] == course_lesson_content.lesson.content
4 changes: 2 additions & 2 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,14 +165,14 @@ def enrollment(db, learner, course) -> Enrollment:
@pytest.fixture
def course_lesson_content(db, course, lesson) -> CourseContent:
content = CourseContent.objects.create(
course=course, priority=1, type="lesson", lesson=lesson, waiting_period=10
course=course, priority=1, type="lesson", lesson=lesson, waiting_period=3600
)
return content


@pytest.fixture
def course_quiz_content(db, course, quiz) -> CourseContent:
content = CourseContent.objects.create(
course=course, priority=2, type="quiz", quiz=quiz, waiting_period=5
course=course, priority=2, type="quiz", quiz=quiz, waiting_period=3600
)
return content