Merge pull request #5276 from edx/anton/forums-topic

Change the topic of a previously posted post.
This commit is contained in:
Anton Stupak
2014-09-25 10:58:09 +03:00
22 changed files with 662 additions and 398 deletions

View File

@@ -15,7 +15,7 @@ from django_comment_client.base import views
from django_comment_client.tests.group_id import CohortedTopicGroupIdTestMixin, NonCohortedTopicGroupIdTestMixin, GroupIdAssertionMixin
from django_comment_client.tests.utils import CohortedContentTestCase
from django_comment_client.tests.unicode import UnicodeTestMixin
from django_comment_common.models import Role, FORUM_ROLE_STUDENT
from django_comment_common.models import Role
from django_comment_common.utils import seed_permissions_roles
from student.tests.factories import CourseEnrollmentFactory, UserFactory
from util.testing import UrlResetMixin
@@ -160,7 +160,6 @@ class ThreadActionGroupIdTestCase(
)
@override_settings(MODULESTORE=TEST_DATA_MIXED_MODULESTORE)
@patch('lms.lib.comment_client.utils.requests.request')
class ViewsTestCase(UrlResetMixin, ModuleStoreTestCase, MockRequestSetupMixin):
@@ -369,6 +368,15 @@ class ViewsTestCase(UrlResetMixin, ModuleStoreTestCase, MockRequestSetupMixin):
mock_request
)
@patch('django_comment_client.base.views.get_discussion_id_map', return_value={"test_commentable": {}})
def test_update_thread_wrong_commentable_id(self, mock_get_discussion_id_map, mock_request):
self._test_request_error(
"update_thread",
{"thread_id": "dummy", "course_id": self.course_id.to_deprecated_string()},
{"body": "foo", "title": "foo", "commentable_id": "wrong_commentable"},
mock_request
)
def test_create_comment_no_body(self, mock_request):
self._test_request_error(
"create_comment",
@@ -460,7 +468,7 @@ class ViewsTestCase(UrlResetMixin, ModuleStoreTestCase, MockRequestSetupMixin):
"at_position_list": [],
"closed": is_closed,
"id": "518d4237b023791dca00000d",
"user_id": "1","username": "robot",
"user_id": "1", "username": "robot",
"votes": {
"count": 0,
"up_count": 0,
@@ -853,13 +861,14 @@ class UpdateThreadUnicodeTestCase(ModuleStoreTestCase, UnicodeTestMixin, MockReq
self.student = UserFactory.create()
CourseEnrollmentFactory(user=self.student, course_id=self.course.id)
@patch('django_comment_client.base.views.get_discussion_id_map', return_value={"test_commentable": {}})
@patch('lms.lib.comment_client.utils.requests.request')
def _test_unicode_data(self, text, mock_request):
def _test_unicode_data(self, text, mock_request, mock_get_discussion_id_map):
self._set_mock_request_data(mock_request, {
"user_id": str(self.student.id),
"closed": False,
})
request = RequestFactory().post("dummy_url", {"body": text, "title": text})
request = RequestFactory().post("dummy_url", {"body": text, "title": text, "commentable_id": "test_commentable"})
request.user = self.student
request.view_name = "update_thread"
response = views.update_thread(request, course_id=self.course.id.to_deprecated_string(), thread_id="dummy_thread_id")
@@ -868,6 +877,7 @@ class UpdateThreadUnicodeTestCase(ModuleStoreTestCase, UnicodeTestMixin, MockReq
self.assertTrue(mock_request.called)
self.assertEqual(mock_request.call_args[1]["data"]["body"], text)
self.assertEqual(mock_request.call_args[1]["data"]["title"], text)
self.assertEqual(mock_request.call_args[1]["data"]["commentable_id"], "test_commentable")
@override_settings(MODULESTORE=TEST_DATA_MIXED_MODULESTORE)

View File

@@ -18,8 +18,6 @@ from opaque_keys.edx.locations import SlashSeparatedCourseKey
from courseware.access import has_access
from courseware.courses import get_course_with_access, get_course_by_id
from course_groups.models import CourseUserGroup
from course_groups.cohorts import get_cohort_by_id, get_cohort_id, is_commentable_cohorted
import django_comment_client.settings as cc_settings
from django_comment_client.utils import (
add_courseware_context,
@@ -28,7 +26,8 @@ from django_comment_client.utils import (
JsonError,
JsonResponse,
prepare_content,
get_group_id_for_comments_service
get_group_id_for_comments_service,
get_discussion_id_map,
)
from django_comment_client.permissions import check_permissions_by_view, cached_has_permission
import lms.lib.comment_client as cc
@@ -139,12 +138,21 @@ def update_thread(request, course_id, thread_id):
return JsonError(_("Title can't be empty"))
if 'body' not in request.POST or not request.POST['body'].strip():
return JsonError(_("Body can't be empty"))
course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id)
thread = cc.Thread.find(thread_id)
thread.body = request.POST["body"]
thread.title = request.POST["title"]
thread.save()
if "commentable_id" in request.POST:
course = get_course_with_access(request.user, 'load', course_key)
id_map = get_discussion_id_map(course)
if request.POST.get("commentable_id") in id_map:
thread.commentable_id = request.POST["commentable_id"]
else:
return JsonError(_("Topic doesn't exist"))
thread.save()
if request.is_ajax():
return ajax_content_response(request, course_key, thread.to_dict())
else:
@@ -614,6 +622,7 @@ def upload(request, course_id): # ajax upload file to a question or answer
}
})
@require_GET
@login_required
def users(request, course_id):
@@ -640,7 +649,7 @@ def users(request, course_id):
try:
matched_user = User.objects.get(username=username)
cc_user = cc.User.from_django_user(matched_user)
cc_user.course_id=course_key
cc_user.course_id = course_key
cc_user.retrieve(complete=False)
if (cc_user['threads_count'] + cc_user['comments_count']) > 0:
user_objs.append({

View File

@@ -71,7 +71,7 @@ def _get_discussion_modules(course):
return filter(has_required_keys, all_modules)
def _get_discussion_id_map(course):
def get_discussion_id_map(course):
def get_entry(module):
discussion_id = module.discussion_id
title = module.discussion_target
@@ -352,7 +352,7 @@ def extend_content(content):
def add_courseware_context(content_list, course):
id_map = _get_discussion_id_map(course)
id_map = get_discussion_id_map(course)
for content in content_list:
commentable_id = content['commentable_id']

View File

@@ -56,7 +56,7 @@
@import "discussion/elements/labels";
@import "discussion/elements/navigation";
@import "discussion/views/thread";
@import "discussion/views/new-post";
@import "discussion/views/create-edit-post";
@import "discussion/views/response";
@import 'discussion/utilities/developer';
@import 'discussion/utilities/shame';

View File

@@ -107,7 +107,8 @@ li[class*=forum-nav-thread-label-] {
// new post form
// -------------
.forum-new-post-form {
.forum-new-post-form,
.edit-post-form {
// Override global label rules
.post-type {
text-shadow: none;
@@ -127,7 +128,7 @@ li[class*=forum-nav-thread-label-] {
margin-bottom: 0;
}
// Override global span rules
// Override global span rules
.post-topic-button .drop-arrow {
line-height: 36px;
}

View File

@@ -2,7 +2,8 @@
// ====================
// UI: form structure
.forum-new-post-form {
.forum-new-post-form,
.edit-post-form {
@include clearfix;
box-sizing: border-box;
margin: 0;
@@ -64,7 +65,8 @@
// ====================
// UI: inputs
.forum-new-post-form {
.forum-new-post-form,
.edit-post-form {
.post-topic-button {
@include white-button;
@extend %cont-truncated;
@@ -172,7 +174,8 @@
// ====================
// UI: errors - new post creation
.forum-new-post-form {
.forum-new-post-form,
.edit-post-form {
.post-errors {
margin-bottom: $baseline;
border-radius: 3px;
@@ -199,7 +202,8 @@
// UI: topic menu
// TO-DO: refactor to use _navigation.scss as general topic selector
.forum-new-post-form .post-topic {
.forum-new-post-form .post-topic ,
.edit-post-form .post-topic {
position: relative;
.topic-menu-wrapper {

View File

@@ -54,9 +54,9 @@
% endfor
<script aria-hidden="true" type="text/template" id="thread-edit-template">
<div class="discussion-post edit-post-form">
<h1>${_("Editing post")}</h1>
<ul class="edit-post-form-errors"></ul>
<ul class="post-errors"></ul>
<div class="forum-edit-post-form-wrapper"></div>
<div class="form-row">
<label class="sr" for="edit-post-title">${_("Edit post title")}</label>
<input type="text" id="edit-post-title" class="edit-post-title" name="title" value="${"<%-title %>"}" placeholder="${_('Title') | h}">
@@ -66,7 +66,6 @@
</div>
<input type="submit" id="edit-post-submit" class="post-update" value="${_("Update post") | h}">
<a href="#" class="post-cancel">${_("Cancel")}</a>
</div>
</script>
<script aria-hidden="true" type="text/template" id="thread-response-template">
@@ -408,31 +407,7 @@
${_("Questions raise issues that need answers. Discussions share ideas and start conversations.")}
</span>
</div>
${'<% if (mode=="tab") { %>'}
<div class="post-field">
## Using div here instead of label because we are using a non-native control
<div class="field-label">
<span class="field-label-text">
${_("Topic Area:")}
</span><div class="field-input post-topic">
<a href="#" class="post-topic-button">
<span class="sr">${_("Discussion topics; current selection is: ")}</span>
<span class="js-selected-topic"></span>
<span class="drop-arrow" aria-hidden="true"></span>
</a>
<div class="topic-menu-wrapper">
<label class="topic-filter-label">
<span class="sr">${_("Filter topics")}</span>
<input type="text" class="topic-filter-input" placeholder="${_('Filter topics')}">
</label>
<ul class="topic-menu" role="menu">${'<%= topics_html %>'}</ul>
</div>
</div>
</div><span class="field-help">
${_("Add your post to a relevant topic to help others find it.")}
</span>
</div>
${'<% } %>'}
<div class="forum-new-post-form-wrapper"></div>
${'<% if (cohort_options) { %>'}
<div class="post-field">
<label class="field-label">
@@ -497,6 +472,28 @@
</li>
</script>
<script aria-hidden="true" type="text/template" id="topic-template">
## Using div here instead of label because we are using a non-native control
<div class="field-label">
<span class="field-label-text">${_("Topic Area:")}</span><div class="field-input post-topic">
<a href="#" class="post-topic-button">
<span class="sr">${_("Discussion topics; current selection is: ")}</span>
<span class="js-selected-topic"></span>
<span class="drop-arrow" aria-hidden="true"></span>
</a>
<div class="topic-menu-wrapper">
<label class="topic-filter-label">
<span class="sr">${_("Filter topics")}</span>
<input type="text" class="topic-filter-input" placeholder="${_('Filter topics')}">
</label>
<ul class="topic-menu" role="menu">${'<%= topics_html %>'}</ul>
</div>
</div>
</div><span class="field-help">
${_("Add your post to a relevant topic to help others find it.")}
</span>
</script>
<%def name="primaryAction(action_class, icon, sr_label, unchecked_label, checked_label)">
<script type="text/template" id="forum-action-${action_class}">
<li class="actions-item">