Ejemplo n.º 1
0
 def test_create_missing_field(self):
     for field in self.minimal_data:
         data = self.minimal_data.copy()
         data.pop(field)
         serializer = ThreadSerializer(data=data)
         assert not serializer.is_valid()
         assert serializer.errors == {field: ['This field is required.']}
Ejemplo n.º 2
0
 def test_create_missing_field(self):
     for field in self.minimal_data:
         data = self.minimal_data.copy()
         data.pop(field)
         serializer = ThreadSerializer(data=data)
         self.assertFalse(serializer.is_valid())
         self.assertEqual(serializer.errors,
                          {field: ["This field is required."]})
Ejemplo n.º 3
0
 def test_create_empty_string(self, value):
     data = self.minimal_data.copy()
     data.update({field: value for field in ["topic_id", "title", "raw_body"]})
     serializer = ThreadSerializer(data=data, context=get_context(self.course, self.request))
     assert not serializer.is_valid()
     assert serializer.errors == {
         field: ['This field may not be blank.'] for field in ['topic_id', 'title', 'raw_body']
     }
Ejemplo n.º 4
0
    def test_create_type(self):
        self.register_post_thread_response({"id": "test_id", "username": self.user.username})
        data = self.minimal_data.copy()
        data["type"] = "question"
        self.save_and_reserialize(data)

        data["type"] = "invalid_type"
        serializer = ThreadSerializer(data=data)
        assert not serializer.is_valid()
Ejemplo n.º 5
0
 def test_update_course_id(self):
     serializer = ThreadSerializer(
         self.existing_thread,
         data={"course_id": "some/other/course"},
         partial=True,
         context=get_context(self.course, self.request)
     )
     assert not serializer.is_valid()
     assert serializer.errors == {'course_id': ['This field is not allowed in an update.']}
Ejemplo n.º 6
0
 def test_create_empty_string(self, value):
     data = self.minimal_data.copy()
     data.update({field: value for field in ["topic_id", "title", "raw_body"]})
     serializer = ThreadSerializer(data=data, context=get_context(self.course, self.request))
     self.assertFalse(serializer.is_valid())
     self.assertEqual(
         serializer.errors,
         {field: ["This field may not be blank."] for field in ["topic_id", "title", "raw_body"]}
     )
Ejemplo n.º 7
0
    def test_create_type(self):
        self.register_post_thread_response({"id": "test_id", "username": self.user.username})
        data = self.minimal_data.copy()
        data["type"] = "question"
        self.save_and_reserialize(data)

        data["type"] = "invalid_type"
        serializer = ThreadSerializer(data=data)
        self.assertFalse(serializer.is_valid())
Ejemplo n.º 8
0
 def test_create_empty_string(self, value):
     data = self.minimal_data.copy()
     data.update({field: value for field in ["topic_id", "title", "raw_body"]})
     serializer = ThreadSerializer(data=data, context=get_context(self.course, self.request))
     self.assertFalse(serializer.is_valid())
     self.assertEqual(
         serializer.errors,
         {field: ["This field may not be blank."] for field in ["topic_id", "title", "raw_body"]}
     )
Ejemplo n.º 9
0
 def test_update_course_id(self):
     serializer = ThreadSerializer(self.existing_thread,
                                   data={"course_id": "some/other/course"},
                                   partial=True,
                                   context=get_context(
                                       self.course, self.request))
     self.assertFalse(serializer.is_valid())
     self.assertEqual(
         serializer.errors,
         {"course_id": ["This field is not allowed in an update."]})
Ejemplo n.º 10
0
 def test_create_missing_field(self):
     for field in self.minimal_data:
         data = self.minimal_data.copy()
         data.pop(field)
         serializer = ThreadSerializer(data=data)
         self.assertFalse(serializer.is_valid())
         self.assertEqual(
             serializer.errors,
             {field: ["This field is required."]}
         )
Ejemplo n.º 11
0
def create_thread(request, thread_data):
    """
    Create a thread.

    Arguments:

        request: The django request object used for build_absolute_uri and
          determining the requesting user.

        thread_data: The data for the created thread.

    Returns:

        The created thread; see discussion.rest_api.views.ThreadViewSet for more
        detail.
    """
    course_id = thread_data.get("course_id")
    user = request.user
    if not course_id:
        raise ValidationError({"course_id": ["This field is required."]})
    try:
        course_key = CourseKey.from_string(course_id)
        course = _get_course(course_key, user)
    except InvalidKeyError:
        raise ValidationError({"course_id": ["Invalid value."]})  # lint-amnesty, pylint: disable=raise-missing-from

    if not discussion_open_for_user(course, user):
        raise DiscussionBlackOutException

    context = get_context(course, request)
    _check_initializable_thread_fields(thread_data, context)
    discussion_settings = get_course_discussion_settings(course_key)
    if ("group_id" not in thread_data and is_commentable_divided(
            course_key, thread_data.get("topic_id"), discussion_settings)):
        thread_data = thread_data.copy()
        thread_data["group_id"] = get_group_id_for_user(
            user, discussion_settings)
    serializer = ThreadSerializer(data=thread_data, context=context)
    actions_form = ThreadActionsForm(thread_data)
    if not (serializer.is_valid() and actions_form.is_valid()):
        raise ValidationError(
            dict(
                list(serializer.errors.items()) +
                list(actions_form.errors.items())))
    serializer.save()
    cc_thread = serializer.instance
    thread_created.send(sender=None, user=user, post=cc_thread)
    api_thread = serializer.data
    _do_extra_actions(api_thread, cc_thread, list(thread_data.keys()),
                      actions_form, context, request)

    track_thread_created_event(request, course, cc_thread,
                               actions_form.cleaned_data["following"])

    return api_thread
Ejemplo n.º 12
0
 def test_update_empty_string(self, value):
     serializer = ThreadSerializer(
         self.existing_thread,
         data={field: value for field in ["topic_id", "title", "raw_body"]},
         partial=True,
         context=get_context(self.course, self.request)
     )
     assert not serializer.is_valid()
     assert serializer.errors == {
         field: ['This field may not be blank.'] for field in ['topic_id', 'title', 'raw_body']
     }
Ejemplo n.º 13
0
 def test_update_course_id(self):
     serializer = ThreadSerializer(
         self.existing_thread,
         data={"course_id": "some/other/course"},
         partial=True,
         context=get_context(self.course, self.request)
     )
     self.assertFalse(serializer.is_valid())
     self.assertEqual(
         serializer.errors,
         {"course_id": ["This field is not allowed in an update."]}
     )
Ejemplo n.º 14
0
 def test_update_empty_string(self, value):
     serializer = ThreadSerializer(
         self.existing_thread,
         data={field: value for field in ["topic_id", "title", "raw_body"]},
         partial=True,
         context=get_context(self.course, self.request)
     )
     self.assertFalse(serializer.is_valid())
     self.assertEqual(
         serializer.errors,
         {field: ["This field may not be blank."] for field in ["topic_id", "title", "raw_body"]}
     )
Ejemplo n.º 15
0
 def test_update_empty_string(self, value):
     serializer = ThreadSerializer(
         self.existing_thread,
         data={field: value for field in ["topic_id", "title", "raw_body"]},
         partial=True,
         context=get_context(self.course, self.request)
     )
     self.assertFalse(serializer.is_valid())
     self.assertEqual(
         serializer.errors,
         {field: ["This field may not be blank."] for field in ["topic_id", "title", "raw_body"]}
     )
Ejemplo n.º 16
0
 def save_and_reserialize(self, data, instance=None):
     """
     Create a serializer with the given data and (if updating) instance,
     ensure that it is valid, save the result, and return the full thread
     data from the serializer.
     """
     serializer = ThreadSerializer(instance,
                                   data=data,
                                   partial=(instance is not None),
                                   context=get_context(
                                       self.course, self.request))
     assert serializer.is_valid()
     serializer.save()
     return serializer.data
Ejemplo n.º 17
0
 def save_and_reserialize(self, data, instance=None):
     """
     Create a serializer with the given data and (if updating) instance,
     ensure that it is valid, save the result, and return the full thread
     data from the serializer.
     """
     serializer = ThreadSerializer(
         instance,
         data=data,
         partial=(instance is not None),
         context=get_context(self.course, self.request)
     )
     self.assertTrue(serializer.is_valid())
     serializer.save()
     return serializer.data
Ejemplo n.º 18
0
def create_thread(request, thread_data):
    """
    Create a thread.

    Arguments:

        request: The django request object used for build_absolute_uri and
          determining the requesting user.

        thread_data: The data for the created thread.

    Returns:

        The created thread; see discussion.rest_api.views.ThreadViewSet for more
        detail.
    """
    course_id = thread_data.get("course_id")
    user = request.user
    if not course_id:
        raise ValidationError({"course_id": ["This field is required."]})
    try:
        course_key = CourseKey.from_string(course_id)
        course = _get_course(course_key, user)
    except InvalidKeyError:
        raise ValidationError({"course_id": ["Invalid value."]})

    context = get_context(course, request)
    _check_initializable_thread_fields(thread_data, context)
    discussion_settings = get_course_discussion_settings(course_key)
    if (
            "group_id" not in thread_data and
            is_commentable_divided(course_key, thread_data.get("topic_id"), discussion_settings)
    ):
        thread_data = thread_data.copy()
        thread_data["group_id"] = get_group_id_for_user(user, discussion_settings)
    serializer = ThreadSerializer(data=thread_data, context=context)
    actions_form = ThreadActionsForm(thread_data)
    if not (serializer.is_valid() and actions_form.is_valid()):
        raise ValidationError(dict(serializer.errors.items() + actions_form.errors.items()))
    serializer.save()
    cc_thread = serializer.instance
    thread_created.send(sender=None, user=user, post=cc_thread)
    api_thread = serializer.data
    _do_extra_actions(api_thread, cc_thread, thread_data.keys(), actions_form, context, request)

    track_thread_created_event(request, course, cc_thread, actions_form.cleaned_data["following"])

    return api_thread
Ejemplo n.º 19
0
 def serialize(self, thread):
     """
     Create a serializer with an appropriate context and use it to serialize
     the given thread, returning the result.
     """
     return ThreadSerializer(thread,
                             context=get_context(self.course,
                                                 self.request)).data
Ejemplo n.º 20
0
def update_thread(request, thread_id, update_data):
    """
    Update a thread.

    Arguments:

        request: The django request object used for build_absolute_uri and
          determining the requesting user.

        thread_id: The id for the thread to update.

        update_data: The data to update in the thread.

    Returns:

        The updated thread; see discussion.rest_api.views.ThreadViewSet for more
        detail.
    """
    cc_thread, context = _get_thread_and_context(
        request, thread_id, retrieve_kwargs={"with_responses": True})
    _check_editable_fields(cc_thread, update_data, context)
    serializer = ThreadSerializer(cc_thread,
                                  data=update_data,
                                  partial=True,
                                  context=context)
    actions_form = ThreadActionsForm(update_data)
    if not (serializer.is_valid() and actions_form.is_valid()):
        raise ValidationError(
            dict(
                list(serializer.errors.items()) +
                list(actions_form.errors.items())))
    # Only save thread object if some of the edited fields are in the thread data, not extra actions
    if set(update_data) - set(actions_form.fields):
        serializer.save()
        # signal to update Teams when a user edits a thread
        thread_edited.send(sender=None, user=request.user, post=cc_thread)
    api_thread = serializer.data
    _do_extra_actions(api_thread, cc_thread, list(update_data.keys()),
                      actions_form, context, request)

    # always return read as True (and therefore unread_comment_count=0) as reasonably
    # accurate shortcut, rather than adding additional processing.
    api_thread['read'] = True
    api_thread['unread_comment_count'] = 0
    return api_thread
Ejemplo n.º 21
0
def update_thread(request, thread_id, update_data):
    """
    Update a thread.

    Arguments:

        request: The django request object used for build_absolute_uri and
          determining the requesting user.

        thread_id: The id for the thread to update.

        update_data: The data to update in the thread.

    Returns:

        The updated thread; see discussion.rest_api.views.ThreadViewSet for more
        detail.
    """
    cc_thread, context = _get_thread_and_context(request, thread_id, retrieve_kwargs={"with_responses": True})
    _check_editable_fields(cc_thread, update_data, context)
    serializer = ThreadSerializer(cc_thread, data=update_data, partial=True, context=context)
    actions_form = ThreadActionsForm(update_data)
    if not (serializer.is_valid() and actions_form.is_valid()):
        raise ValidationError(dict(serializer.errors.items() + actions_form.errors.items()))
    # Only save thread object if some of the edited fields are in the thread data, not extra actions
    if set(update_data) - set(actions_form.fields):
        serializer.save()
        # signal to update Teams when a user edits a thread
        thread_edited.send(sender=None, user=request.user, post=cc_thread)
    api_thread = serializer.data
    _do_extra_actions(api_thread, cc_thread, update_data.keys(), actions_form, context, request)

    # always return read as True (and therefore unread_comment_count=0) as reasonably
    # accurate shortcut, rather than adding additional processing.
    api_thread['read'] = True
    api_thread['unread_comment_count'] = 0
    return api_thread
Ejemplo n.º 22
0
def _serialize_discussion_entities(request, context, discussion_entities,
                                   requested_fields, discussion_entity_type):
    """
    It serializes Discussion Entity (Thread or Comment) and add additional data if requested.

    For a given list of Thread/Comment; it serializes and add additional information to the
    object as per requested_fields list (i.e. profile_image).

    Parameters:

        request: The django request object
        context: The context appropriate for use with the thread or comment
        discussion_entities: List of Thread or Comment objects
        requested_fields: Indicates which additional fields to return
            for each thread.
        discussion_entity_type: DiscussionEntity Enum value for Thread or Comment

    Returns:

        A list of serialized discussion entities
    """
    results = []
    usernames = []
    include_profile_image = _include_profile_image(requested_fields)
    for entity in discussion_entities:
        if discussion_entity_type == DiscussionEntity.thread:
            serialized_entity = ThreadSerializer(entity, context=context).data
        elif discussion_entity_type == DiscussionEntity.comment:
            serialized_entity = CommentSerializer(entity, context=context).data
        results.append(serialized_entity)

        if include_profile_image:
            if serialized_entity['author'] and serialized_entity[
                    'author'] not in usernames:
                usernames.append(serialized_entity['author'])
            if ('endorsed' in serialized_entity
                    and serialized_entity['endorsed']
                    and 'endorsed_by' in serialized_entity
                    and serialized_entity['endorsed_by']
                    and serialized_entity['endorsed_by'] not in usernames):
                usernames.append(serialized_entity['endorsed_by'])

    results = _add_additional_response_fields(request, results, usernames,
                                              discussion_entity_type,
                                              include_profile_image)
    return results