Skip to content

Commit

Permalink
chore: temp commit
Browse files Browse the repository at this point in the history
  • Loading branch information
GlugovGrGlib committed Mar 1, 2024
1 parent a9bd61d commit 65cb083
Show file tree
Hide file tree
Showing 25 changed files with 1,514 additions and 175 deletions.
25 changes: 24 additions & 1 deletion cms/djangoapps/contentstore/rest_api/v1/mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,16 @@
Common mixins for module.
"""
import json
import logging
from unittest.mock import patch

from django.http import Http404
from opaque_keys import InvalidKeyError
from opaque_keys.edx.keys import UsageKey
from rest_framework import status

log = logging.getLogger(__name__)


class PermissionAccessMixin:
"""
Expand All @@ -30,7 +36,7 @@ def test_permissions_unauthenticated(self):
self.assertEqual(error, "Authentication credentials were not provided.")
self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)

@patch.dict('django.conf.settings.FEATURES', {'DISABLE_ADVANCED_SETTINGS': True})
@patch.dict("django.conf.settings.FEATURES", {"DISABLE_ADVANCED_SETTINGS": True})
def test_permissions_unauthorized(self):
"""
Test that an error is returned if the user is unauthorised.
Expand All @@ -40,3 +46,20 @@ def test_permissions_unauthorized(self):
error = self.get_and_check_developer_response(response)
self.assertEqual(error, "You do not have permission to perform this action.")
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)


class ContainerHandlerMixin:
"""
A mixin providing common functionality for container handler views.
"""

def get_object(self, usage_key_string):
"""
Get an object by usage-id of the block
"""
try:
usage_key = UsageKey.from_string(usage_key_string)
return usage_key
except InvalidKeyError as err:
log.error(f"Invalid usage key: {usage_key_string}", exc_info=True)
raise Http404(f"Object not found for usage key: {usage_key_string}") from err
13 changes: 8 additions & 5 deletions cms/djangoapps/contentstore/rest_api/v1/serializers/__init__.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,27 @@
"""
Serializers for v1 contentstore API.
"""
from .certificates import CourseCertificatesSerializer
from .course_details import CourseDetailsSerializer
from .course_index import CourseIndexSerializer
from .course_rerun import CourseRerunSerializer
from .course_team import CourseTeamSerializer
from .course_index import CourseIndexSerializer
from .grading import CourseGradingModelSerializer, CourseGradingSerializer
from .group_configurations import CourseGroupConfigurationsSerializer
from .home import CourseHomeSerializer, CourseHomeTabSerializer, LibraryTabSerializer
from .proctoring import (
LimitedProctoredExamSettingsSerializer,
ProctoredExamConfigurationSerializer,
ProctoredExamSettingsSerializer,
ProctoringErrorsSerializer
ProctoringErrorsSerializer,
)
from .settings import CourseSettingsSerializer
from .textbooks import CourseTextbooksSerializer
from .vertical_block import ContainerHandlerSerializer, VerticalContainerSerializer
from .videos import (
CourseVideosSerializer,
VideoUploadSerializer,
VideoDownloadSerializer,
VideoImageSerializer,
VideoUploadSerializer,
VideoUsageSerializer,
VideoDownloadSerializer
)
from .vertical_block import ContainerHandlerSerializer
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
"""
API Serializers for certificates page
"""

from rest_framework import serializers


class CertificateSignatorySerializer(serializers.Serializer):
"""
Serializer for representing certificate's signatory.
"""

id = serializers.IntegerField()
name = serializers.CharField()
organization = serializers.CharField(required=False)
signature_image_path = serializers.CharField()
title = serializers.CharField()


class CertificateItemSerializer(serializers.Serializer):
"""
Serializer for representing certificate item created for current course.
"""

course_title = serializers.CharField(required=False)
description = serializers.CharField()
editing = serializers.BooleanField(required=False)
id = serializers.IntegerField()
is_active = serializers.BooleanField()
name = serializers.CharField()
signatories = CertificateSignatorySerializer(many=True)
version = serializers.IntegerField()


class CourseCertificatesSerializer(serializers.Serializer):
"""
Serializer for representing course's certificates.
"""

certificate_activation_handler_url = serializers.CharField()
certificate_web_view_url = serializers.CharField(allow_null=True)
certificates = CertificateItemSerializer(many=True, allow_null=True)
course_modes = serializers.ListField(child=serializers.CharField())
has_certificate_modes = serializers.BooleanField()
is_active = serializers.BooleanField()
is_global_staff = serializers.BooleanField()
mfe_proctored_exam_settings_url = serializers.CharField(
required=False, allow_null=True, allow_blank=True
)
course_number = serializers.CharField(source="context_course.number")
course_title = serializers.CharField(source="context_course.display_name_with_default")
course_number_override = serializers.CharField(source="context_course.display_coursenumber")
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
"""
API Serializers for course's settings group configurations.
"""

from rest_framework import serializers


class GroupConfigurationUsageSerializer(serializers.Serializer):
"""
Serializer for representing nested usage inside configuration.
"""

label = serializers.CharField()
url = serializers.CharField()
validation = serializers.DictField(required=False)


class GroupConfigurationGroupSerializer(serializers.Serializer):
"""
Serializer for representing nested group inside configuration.
"""

id = serializers.IntegerField()
name = serializers.CharField()
usage = GroupConfigurationUsageSerializer(required=False, allow_null=True, many=True)
version = serializers.IntegerField()


class GroupConfigurationItemSerializer(serializers.Serializer):
"""
Serializer for representing group configurations item.
"""

active = serializers.BooleanField()
description = serializers.CharField()
groups = GroupConfigurationGroupSerializer(allow_null=True, many=True)
id = serializers.IntegerField()
usage = GroupConfigurationUsageSerializer(required=False, allow_null=True, many=True)
name = serializers.CharField()
parameters = serializers.DictField()
read_only = serializers.BooleanField(required=False)
scheme = serializers.CharField()
version = serializers.IntegerField()


class CourseGroupConfigurationsSerializer(serializers.Serializer):
"""
Serializer for representing course's settings group configurations.
"""

all_group_configurations = GroupConfigurationItemSerializer(many=True)
experiment_group_configurations = GroupConfigurationItemSerializer(
allow_null=True, many=True
)
mfe_proctored_exam_settings_url = serializers.CharField(
required=False, allow_null=True, allow_blank=True
)
should_show_enrollment_track = serializers.BooleanField()
should_show_experiment_groups = serializers.BooleanField()
32 changes: 32 additions & 0 deletions cms/djangoapps/contentstore/rest_api/v1/serializers/textbooks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
"""
API Serializers for textbooks page
"""

from rest_framework import serializers


class CourseTextbookChapterSerializer(serializers.Serializer):
"""
Serializer for representing textbook chapter.
"""

title = serializers.CharField()
url = serializers.CharField()


class CourseTextbookItemSerializer(serializers.Serializer):
"""
Serializer for representing textbook item.
"""

id = serializers.CharField()
chapters = CourseTextbookChapterSerializer(many=True)
tab_title = serializers.CharField()


class CourseTextbooksSerializer(serializers.Serializer):
"""
Serializer for representing course's textbooks.
"""

textbooks = serializers.ListField()
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,22 @@
from django.urls import reverse
from rest_framework import serializers

from cms.djangoapps.contentstore.toggles import use_tagging_taxonomy_list_page
from cms.djangoapps.contentstore.helpers import (
xblock_studio_url,
xblock_type_display_name,
)


class MessageValidation(serializers.Serializer):
"""
Serializer for representing XBlock error.
"""

text = serializers.CharField()
type = serializers.CharField()


class ChildAncestorSerializer(serializers.Serializer):
"""
Serializer for representing child blocks in the ancestor XBlock.
Expand Down Expand Up @@ -78,6 +88,7 @@ class ContainerHandlerSerializer(serializers.Serializer):
assets_url = serializers.SerializerMethodField()
unit_block_id = serializers.CharField(source="unit.location.block_id")
subsection_location = serializers.CharField(source="subsection.location")
course_sequence_ids = serializers.ListField(child=serializers.CharField())

def get_assets_url(self, obj):
"""
Expand All @@ -90,3 +101,46 @@ def get_assets_url(self, obj):
"assets_handler", kwargs={"course_key_string": context_course.id}
)
return None


class ChildVerticalContainerSerializer(serializers.Serializer):
"""
Serializer for representing a xblock child of vertical container.
"""

name = serializers.CharField()
block_id = serializers.CharField()
block_type = serializers.CharField()
actions = serializers.SerializerMethodField()
user_partition_info = serializers.DictField()
user_partitions = serializers.ListField()
validation_messages = MessageValidation(many=True)
render_error = serializers.CharField()

def get_actions(self, obj): # pylint: disable=unused-argument
"""
Method to get actions for each child xlock of the unit.
"""

can_manage_tags = use_tagging_taxonomy_list_page()
# temporary decision defining the default value 'True' for each xblock.
actions = {
"can_copy": True,
"can_duplicate": True,
"can_move": True,
"can_manage_access": True,
"can_delete": True,
"can_manage_tags": can_manage_tags,
}

return actions


class VerticalContainerSerializer(serializers.Serializer):
"""
Serializer for representing a vertical container with state and children.
"""

children = ChildVerticalContainerSerializer(many=True)
is_published = serializers.BooleanField()
can_paste_component = serializers.BooleanField()
26 changes: 25 additions & 1 deletion cms/djangoapps/contentstore/rest_api/v1/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,13 @@

from .views import (
ContainerHandlerView,
CourseCertificatesView,
CourseDetailsView,
CourseTeamView,
CourseTextbooksView,
CourseIndexView,
CourseGradingView,
CourseGroupConfigurationsView,
CourseRerunView,
CourseSettingsView,
CourseVideosView,
Expand All @@ -21,7 +24,8 @@
ProctoringErrorsView,
HelpUrlsView,
VideoUsageView,
VideoDownloadView
VideoDownloadView,
VerticalContainerView,
)

app_name = 'v1'
Expand Down Expand Up @@ -102,11 +106,31 @@
CourseRerunView.as_view(),
name="course_rerun"
),
re_path(
fr'^certificates/{COURSE_ID_PATTERN}$',
CourseCertificatesView.as_view(),
name="certificates"
),
re_path(
fr'^textbooks/{COURSE_ID_PATTERN}$',
CourseTextbooksView.as_view(),
name="textbooks"
),
re_path(
fr'^group_configurations/{COURSE_ID_PATTERN}$',
CourseGroupConfigurationsView.as_view(),
name="group_configurations"
),
re_path(
fr'^container_handler/{settings.USAGE_KEY_PATTERN}$',
ContainerHandlerView.as_view(),
name="container_handler"
),
re_path(
fr'^container/vertical/{settings.USAGE_KEY_PATTERN}/children$',
VerticalContainerView.as_view(),
name="container_vertical"
),

# Authoring API
# Do not use under v1 yet (Nov. 23). The Authoring API is still experimental and the v0 versions should be used
Expand Down
17 changes: 8 additions & 9 deletions cms/djangoapps/contentstore/rest_api/v1/views/__init__.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
"""
Views for v1 contentstore API.
"""
from .certificates import CourseCertificatesView
from .course_details import CourseDetailsView
from .course_index import CourseIndexView
from .course_team import CourseTeamView
from .course_rerun import CourseRerunView
from .course_team import CourseTeamView
from .grading import CourseGradingView
from .group_configurations import CourseGroupConfigurationsView
from .help_urls import HelpUrlsView
from .home import HomePageCoursesView, HomePageLibrariesView, HomePageView
from .proctoring import ProctoredExamSettingsView, ProctoringErrorsView
from .home import HomePageView, HomePageCoursesView, HomePageLibrariesView
from .settings import CourseSettingsView
from .videos import (
CourseVideosView,
VideoUsageView,
VideoDownloadView
)
from .help_urls import HelpUrlsView
from .vertical_block import ContainerHandlerView
from .textbooks import CourseTextbooksView
from .vertical_block import ContainerHandlerView, VerticalContainerView
from .videos import CourseVideosView, VideoDownloadView, VideoUsageView
Loading

0 comments on commit 65cb083

Please sign in to comment.