Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-platform
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
edx-platform
Commits
90fe71db
Commit
90fe71db
authored
Sep 15, 2015
by
wajeeha-khalid
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
MA-1248 - CourseEnrollmentAPI: added discussion URL
parent
06129ada
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
168 additions
and
24 deletions
+168
-24
common/djangoapps/xmodule_django/models.py
+0
-1
lms/djangoapps/discussion_api/api.py
+2
-2
lms/djangoapps/discussion_api/tests/test_api.py
+12
-12
lms/djangoapps/discussion_api/tests/test_views.py
+11
-0
lms/djangoapps/django_comment_client/forum/views.py
+1
-6
lms/djangoapps/django_comment_client/utils.py
+12
-0
lms/djangoapps/mobile_api/users/serializers.py
+7
-0
lms/djangoapps/mobile_api/users/tests.py
+17
-1
lms/djangoapps/mobile_api/users/views.py
+2
-0
openedx/core/djangoapps/content/course_overviews/migrations/0007_auto__add_courseoverviewtab.py
+69
-0
openedx/core/djangoapps/content/course_overviews/models.py
+27
-2
openedx/core/djangoapps/content/course_overviews/tests.py
+8
-0
No files found.
common/djangoapps/xmodule_django/models.py
View file @
90fe71db
"""
"""
Useful django models for implementing XBlock infrastructure in django.
Useful django models for implementing XBlock infrastructure in django.
"""
"""
import
warnings
import
warnings
from
django.db
import
models
from
django.db
import
models
...
...
lms/djangoapps/discussion_api/api.py
View file @
90fe71db
...
@@ -13,8 +13,8 @@ from rest_framework.exceptions import PermissionDenied
...
@@ -13,8 +13,8 @@ from rest_framework.exceptions import PermissionDenied
from
opaque_keys
import
InvalidKeyError
from
opaque_keys
import
InvalidKeyError
from
opaque_keys.edx.locator
import
CourseKey
from
opaque_keys.edx.locator
import
CourseKey
from
courseware.courses
import
get_course_with_access
from
courseware.courses
import
get_course_with_access
from
discussion_api.forms
import
CommentActionsForm
,
ThreadActionsForm
from
discussion_api.forms
import
CommentActionsForm
,
ThreadActionsForm
from
discussion_api.pagination
import
get_paginated_data
from
discussion_api.pagination
import
get_paginated_data
from
discussion_api.permissions
import
(
from
discussion_api.permissions
import
(
...
@@ -55,7 +55,7 @@ def _get_course_or_404(course_key, user):
...
@@ -55,7 +55,7 @@ def _get_course_or_404(course_key, user):
disabled for the course.
disabled for the course.
"""
"""
course
=
get_course_with_access
(
user
,
'load'
,
course_key
,
check_if_enrolled
=
True
)
course
=
get_course_with_access
(
user
,
'load'
,
course_key
,
check_if_enrolled
=
True
)
if
not
any
([
tab
.
type
==
'discussion'
for
tab
in
course
.
tabs
]):
if
not
any
([
tab
.
type
==
'discussion'
and
tab
.
is_enabled
(
course
,
user
)
for
tab
in
course
.
tabs
]):
raise
Http404
raise
Http404
return
course
return
course
...
...
lms/djangoapps/discussion_api/tests/test_api.py
View file @
90fe71db
...
@@ -81,11 +81,11 @@ def _discussion_disabled_course_for(user):
...
@@ -81,11 +81,11 @@ def _discussion_disabled_course_for(user):
@ddt.ddt
@ddt.ddt
@mock.patch.dict
(
"django.conf.settings.FEATURES"
,
{
"ENABLE_DISCUSSION_SERVICE"
:
True
})
class
GetCourseTest
(
UrlResetMixin
,
SharedModuleStoreTestCase
):
class
GetCourseTest
(
UrlResetMixin
,
SharedModuleStoreTestCase
):
"""Test for get_course"""
"""Test for get_course"""
@classmethod
@classmethod
@mock.patch.dict
(
"django.conf.settings.FEATURES"
,
{
"ENABLE_DISCUSSION_SERVICE"
:
True
})
def
setUpClass
(
cls
):
def
setUpClass
(
cls
):
super
(
GetCourseTest
,
cls
)
.
setUpClass
()
super
(
GetCourseTest
,
cls
)
.
setUpClass
()
cls
.
course
=
CourseFactory
.
create
(
org
=
"x"
,
course
=
"y"
,
run
=
"z"
)
cls
.
course
=
CourseFactory
.
create
(
org
=
"x"
,
course
=
"y"
,
run
=
"z"
)
...
@@ -154,9 +154,9 @@ class GetCourseTest(UrlResetMixin, SharedModuleStoreTestCase):
...
@@ -154,9 +154,9 @@ class GetCourseTest(UrlResetMixin, SharedModuleStoreTestCase):
@mock.patch.dict
(
"django.conf.settings.FEATURES"
,
{
"DISABLE_START_DATES"
:
False
})
@mock.patch.dict
(
"django.conf.settings.FEATURES"
,
{
"DISABLE_START_DATES"
:
False
})
@mock.patch.dict
(
"django.conf.settings.FEATURES"
,
{
"ENABLE_DISCUSSION_SERVICE"
:
True
})
class
GetCourseTopicsTest
(
UrlResetMixin
,
ModuleStoreTestCase
):
class
GetCourseTopicsTest
(
UrlResetMixin
,
ModuleStoreTestCase
):
"""Test for get_course_topics"""
"""Test for get_course_topics"""
@mock.patch.dict
(
"django.conf.settings.FEATURES"
,
{
"ENABLE_DISCUSSION_SERVICE"
:
True
})
@mock.patch.dict
(
"django.conf.settings.FEATURES"
,
{
"ENABLE_DISCUSSION_SERVICE"
:
True
})
def
setUp
(
self
):
def
setUp
(
self
):
super
(
GetCourseTopicsTest
,
self
)
.
setUp
()
super
(
GetCourseTopicsTest
,
self
)
.
setUp
()
...
@@ -480,11 +480,11 @@ class GetCourseTopicsTest(UrlResetMixin, ModuleStoreTestCase):
...
@@ -480,11 +480,11 @@ class GetCourseTopicsTest(UrlResetMixin, ModuleStoreTestCase):
@ddt.ddt
@ddt.ddt
@mock.patch.dict
(
"django.conf.settings.FEATURES"
,
{
"ENABLE_DISCUSSION_SERVICE"
:
True
})
class
GetThreadListTest
(
CommentsServiceMockMixin
,
UrlResetMixin
,
SharedModuleStoreTestCase
):
class
GetThreadListTest
(
CommentsServiceMockMixin
,
UrlResetMixin
,
SharedModuleStoreTestCase
):
"""Test for get_thread_list"""
"""Test for get_thread_list"""
@classmethod
@classmethod
@mock.patch.dict
(
"django.conf.settings.FEATURES"
,
{
"ENABLE_DISCUSSION_SERVICE"
:
True
})
def
setUpClass
(
cls
):
def
setUpClass
(
cls
):
super
(
GetThreadListTest
,
cls
)
.
setUpClass
()
super
(
GetThreadListTest
,
cls
)
.
setUpClass
()
cls
.
course
=
CourseFactory
.
create
()
cls
.
course
=
CourseFactory
.
create
()
...
@@ -909,15 +909,16 @@ class GetThreadListTest(CommentsServiceMockMixin, UrlResetMixin, SharedModuleSto
...
@@ -909,15 +909,16 @@ class GetThreadListTest(CommentsServiceMockMixin, UrlResetMixin, SharedModuleSto
@ddt.ddt
@ddt.ddt
@mock.patch.dict
(
"django.conf.settings.FEATURES"
,
{
"ENABLE_DISCUSSION_SERVICE"
:
True
})
class
GetCommentListTest
(
CommentsServiceMockMixin
,
SharedModuleStoreTestCase
):
class
GetCommentListTest
(
CommentsServiceMockMixin
,
SharedModuleStoreTestCase
):
"""Test for get_comment_list"""
"""Test for get_comment_list"""
@classmethod
@classmethod
@mock.patch.dict
(
"django.conf.settings.FEATURES"
,
{
"ENABLE_DISCUSSION_SERVICE"
:
True
})
def
setUpClass
(
cls
):
def
setUpClass
(
cls
):
super
(
GetCommentListTest
,
cls
)
.
setUpClass
()
super
(
GetCommentListTest
,
cls
)
.
setUpClass
()
cls
.
course
=
CourseFactory
.
create
()
cls
.
course
=
CourseFactory
.
create
()
@mock.patch.dict
(
"django.conf.settings.FEATURES"
,
{
"ENABLE_DISCUSSION_SERVICE"
:
True
})
def
setUp
(
self
):
def
setUp
(
self
):
super
(
GetCommentListTest
,
self
)
.
setUp
()
super
(
GetCommentListTest
,
self
)
.
setUp
()
httpretty
.
reset
()
httpretty
.
reset
()
...
@@ -1333,6 +1334,7 @@ class GetCommentListTest(CommentsServiceMockMixin, SharedModuleStoreTestCase):
...
@@ -1333,6 +1334,7 @@ class GetCommentListTest(CommentsServiceMockMixin, SharedModuleStoreTestCase):
@ddt.ddt
@ddt.ddt
@disable_signal
(
api
,
'thread_created'
)
@disable_signal
(
api
,
'thread_created'
)
@disable_signal
(
api
,
'thread_voted'
)
@disable_signal
(
api
,
'thread_voted'
)
@mock.patch.dict
(
"django.conf.settings.FEATURES"
,
{
"ENABLE_DISCUSSION_SERVICE"
:
True
})
class
CreateThreadTest
(
class
CreateThreadTest
(
CommentsServiceMockMixin
,
CommentsServiceMockMixin
,
UrlResetMixin
,
UrlResetMixin
,
...
@@ -1341,7 +1343,6 @@ class CreateThreadTest(
...
@@ -1341,7 +1343,6 @@ class CreateThreadTest(
):
):
"""Tests for create_thread"""
"""Tests for create_thread"""
@classmethod
@classmethod
@mock.patch.dict
(
"django.conf.settings.FEATURES"
,
{
"ENABLE_DISCUSSION_SERVICE"
:
True
})
def
setUpClass
(
cls
):
def
setUpClass
(
cls
):
super
(
CreateThreadTest
,
cls
)
.
setUpClass
()
super
(
CreateThreadTest
,
cls
)
.
setUpClass
()
cls
.
course
=
CourseFactory
.
create
()
cls
.
course
=
CourseFactory
.
create
()
...
@@ -1585,6 +1586,7 @@ class CreateThreadTest(
...
@@ -1585,6 +1586,7 @@ class CreateThreadTest(
@ddt.ddt
@ddt.ddt
@disable_signal
(
api
,
'comment_created'
)
@disable_signal
(
api
,
'comment_created'
)
@disable_signal
(
api
,
'comment_voted'
)
@disable_signal
(
api
,
'comment_voted'
)
@mock.patch.dict
(
"django.conf.settings.FEATURES"
,
{
"ENABLE_DISCUSSION_SERVICE"
:
True
})
class
CreateCommentTest
(
class
CreateCommentTest
(
CommentsServiceMockMixin
,
CommentsServiceMockMixin
,
UrlResetMixin
,
UrlResetMixin
,
...
@@ -1593,7 +1595,6 @@ class CreateCommentTest(
...
@@ -1593,7 +1595,6 @@ class CreateCommentTest(
):
):
"""Tests for create_comment"""
"""Tests for create_comment"""
@classmethod
@classmethod
@mock.patch.dict
(
"django.conf.settings.FEATURES"
,
{
"ENABLE_DISCUSSION_SERVICE"
:
True
})
def
setUpClass
(
cls
):
def
setUpClass
(
cls
):
super
(
CreateCommentTest
,
cls
)
.
setUpClass
()
super
(
CreateCommentTest
,
cls
)
.
setUpClass
()
cls
.
course
=
CourseFactory
.
create
()
cls
.
course
=
CourseFactory
.
create
()
...
@@ -1859,6 +1860,7 @@ class CreateCommentTest(
...
@@ -1859,6 +1860,7 @@ class CreateCommentTest(
@ddt.ddt
@ddt.ddt
@disable_signal
(
api
,
'thread_edited'
)
@disable_signal
(
api
,
'thread_edited'
)
@disable_signal
(
api
,
'thread_voted'
)
@disable_signal
(
api
,
'thread_voted'
)
@mock.patch.dict
(
"django.conf.settings.FEATURES"
,
{
"ENABLE_DISCUSSION_SERVICE"
:
True
})
class
UpdateThreadTest
(
class
UpdateThreadTest
(
CommentsServiceMockMixin
,
CommentsServiceMockMixin
,
UrlResetMixin
,
UrlResetMixin
,
...
@@ -1867,7 +1869,6 @@ class UpdateThreadTest(
...
@@ -1867,7 +1869,6 @@ class UpdateThreadTest(
):
):
"""Tests for update_thread"""
"""Tests for update_thread"""
@classmethod
@classmethod
@mock.patch.dict
(
"django.conf.settings.FEATURES"
,
{
"ENABLE_DISCUSSION_SERVICE"
:
True
})
def
setUpClass
(
cls
):
def
setUpClass
(
cls
):
super
(
UpdateThreadTest
,
cls
)
.
setUpClass
()
super
(
UpdateThreadTest
,
cls
)
.
setUpClass
()
cls
.
course
=
CourseFactory
.
create
()
cls
.
course
=
CourseFactory
.
create
()
...
@@ -2247,6 +2248,7 @@ class UpdateThreadTest(
...
@@ -2247,6 +2248,7 @@ class UpdateThreadTest(
@ddt.ddt
@ddt.ddt
@disable_signal
(
api
,
'comment_edited'
)
@disable_signal
(
api
,
'comment_edited'
)
@disable_signal
(
api
,
'comment_voted'
)
@disable_signal
(
api
,
'comment_voted'
)
@mock.patch.dict
(
"django.conf.settings.FEATURES"
,
{
"ENABLE_DISCUSSION_SERVICE"
:
True
})
class
UpdateCommentTest
(
class
UpdateCommentTest
(
CommentsServiceMockMixin
,
CommentsServiceMockMixin
,
UrlResetMixin
,
UrlResetMixin
,
...
@@ -2256,7 +2258,6 @@ class UpdateCommentTest(
...
@@ -2256,7 +2258,6 @@ class UpdateCommentTest(
"""Tests for update_comment"""
"""Tests for update_comment"""
@classmethod
@classmethod
@mock.patch.dict
(
"django.conf.settings.FEATURES"
,
{
"ENABLE_DISCUSSION_SERVICE"
:
True
})
def
setUpClass
(
cls
):
def
setUpClass
(
cls
):
super
(
UpdateCommentTest
,
cls
)
.
setUpClass
()
super
(
UpdateCommentTest
,
cls
)
.
setUpClass
()
cls
.
course
=
CourseFactory
.
create
()
cls
.
course
=
CourseFactory
.
create
()
...
@@ -2304,7 +2305,6 @@ class UpdateCommentTest(
...
@@ -2304,7 +2305,6 @@ class UpdateCommentTest(
self
.
register_get_comment_response
(
cs_comment_data
)
self
.
register_get_comment_response
(
cs_comment_data
)
self
.
register_put_comment_response
(
cs_comment_data
)
self
.
register_put_comment_response
(
cs_comment_data
)
@mock.patch.dict
(
"django.conf.settings.FEATURES"
,
{
"ENABLE_DISCUSSION_SERVICE"
:
True
})
def
test_empty
(
self
):
def
test_empty
(
self
):
"""Check that an empty update does not make any modifying requests."""
"""Check that an empty update does not make any modifying requests."""
self
.
register_comment
()
self
.
register_comment
()
...
@@ -2632,6 +2632,7 @@ class UpdateCommentTest(
...
@@ -2632,6 +2632,7 @@ class UpdateCommentTest(
@ddt.ddt
@ddt.ddt
@disable_signal
(
api
,
'thread_deleted'
)
@disable_signal
(
api
,
'thread_deleted'
)
@mock.patch.dict
(
"django.conf.settings.FEATURES"
,
{
"ENABLE_DISCUSSION_SERVICE"
:
True
})
class
DeleteThreadTest
(
class
DeleteThreadTest
(
CommentsServiceMockMixin
,
CommentsServiceMockMixin
,
UrlResetMixin
,
UrlResetMixin
,
...
@@ -2640,7 +2641,6 @@ class DeleteThreadTest(
...
@@ -2640,7 +2641,6 @@ class DeleteThreadTest(
):
):
"""Tests for delete_thread"""
"""Tests for delete_thread"""
@classmethod
@classmethod
@mock.patch.dict
(
"django.conf.settings.FEATURES"
,
{
"ENABLE_DISCUSSION_SERVICE"
:
True
})
def
setUpClass
(
cls
):
def
setUpClass
(
cls
):
super
(
DeleteThreadTest
,
cls
)
.
setUpClass
()
super
(
DeleteThreadTest
,
cls
)
.
setUpClass
()
cls
.
course
=
CourseFactory
.
create
()
cls
.
course
=
CourseFactory
.
create
()
...
@@ -2771,6 +2771,7 @@ class DeleteThreadTest(
...
@@ -2771,6 +2771,7 @@ class DeleteThreadTest(
@ddt.ddt
@ddt.ddt
@disable_signal
(
api
,
'comment_deleted'
)
@disable_signal
(
api
,
'comment_deleted'
)
@mock.patch.dict
(
"django.conf.settings.FEATURES"
,
{
"ENABLE_DISCUSSION_SERVICE"
:
True
})
class
DeleteCommentTest
(
class
DeleteCommentTest
(
CommentsServiceMockMixin
,
CommentsServiceMockMixin
,
UrlResetMixin
,
UrlResetMixin
,
...
@@ -2779,7 +2780,6 @@ class DeleteCommentTest(
...
@@ -2779,7 +2780,6 @@ class DeleteCommentTest(
):
):
"""Tests for delete_comment"""
"""Tests for delete_comment"""
@classmethod
@classmethod
@mock.patch.dict
(
"django.conf.settings.FEATURES"
,
{
"ENABLE_DISCUSSION_SERVICE"
:
True
})
def
setUpClass
(
cls
):
def
setUpClass
(
cls
):
super
(
DeleteCommentTest
,
cls
)
.
setUpClass
()
super
(
DeleteCommentTest
,
cls
)
.
setUpClass
()
cls
.
course
=
CourseFactory
.
create
()
cls
.
course
=
CourseFactory
.
create
()
...
@@ -2928,6 +2928,7 @@ class DeleteCommentTest(
...
@@ -2928,6 +2928,7 @@ class DeleteCommentTest(
@ddt.ddt
@ddt.ddt
@mock.patch.dict
(
"django.conf.settings.FEATURES"
,
{
"ENABLE_DISCUSSION_SERVICE"
:
True
})
class
RetrieveThreadTest
(
class
RetrieveThreadTest
(
CommentsServiceMockMixin
,
CommentsServiceMockMixin
,
UrlResetMixin
,
UrlResetMixin
,
...
@@ -2935,7 +2936,6 @@ class RetrieveThreadTest(
...
@@ -2935,7 +2936,6 @@ class RetrieveThreadTest(
):
):
"""Tests for get_thread"""
"""Tests for get_thread"""
@classmethod
@classmethod
@mock.patch.dict
(
"django.conf.settings.FEATURES"
,
{
"ENABLE_DISCUSSION_SERVICE"
:
True
})
def
setUpClass
(
cls
):
def
setUpClass
(
cls
):
super
(
RetrieveThreadTest
,
cls
)
.
setUpClass
()
super
(
RetrieveThreadTest
,
cls
)
.
setUpClass
()
cls
.
course
=
CourseFactory
.
create
()
cls
.
course
=
CourseFactory
.
create
()
...
...
lms/djangoapps/discussion_api/tests/test_views.py
View file @
90fe71db
...
@@ -70,6 +70,7 @@ class DiscussionAPIViewTestMixin(CommentsServiceMockMixin, UrlResetMixin):
...
@@ -70,6 +70,7 @@ class DiscussionAPIViewTestMixin(CommentsServiceMockMixin, UrlResetMixin):
)
)
@mock.patch.dict
(
"django.conf.settings.FEATURES"
,
{
"ENABLE_DISCUSSION_SERVICE"
:
True
})
class
CourseViewTest
(
DiscussionAPIViewTestMixin
,
ModuleStoreTestCase
):
class
CourseViewTest
(
DiscussionAPIViewTestMixin
,
ModuleStoreTestCase
):
"""Tests for CourseView"""
"""Tests for CourseView"""
def
setUp
(
self
):
def
setUp
(
self
):
...
@@ -103,6 +104,7 @@ class CourseViewTest(DiscussionAPIViewTestMixin, ModuleStoreTestCase):
...
@@ -103,6 +104,7 @@ class CourseViewTest(DiscussionAPIViewTestMixin, ModuleStoreTestCase):
)
)
@mock.patch.dict
(
"django.conf.settings.FEATURES"
,
{
"ENABLE_DISCUSSION_SERVICE"
:
True
})
class
CourseTopicsViewTest
(
DiscussionAPIViewTestMixin
,
ModuleStoreTestCase
):
class
CourseTopicsViewTest
(
DiscussionAPIViewTestMixin
,
ModuleStoreTestCase
):
"""Tests for CourseTopicsView"""
"""Tests for CourseTopicsView"""
def
setUp
(
self
):
def
setUp
(
self
):
...
@@ -139,6 +141,7 @@ class CourseTopicsViewTest(DiscussionAPIViewTestMixin, ModuleStoreTestCase):
...
@@ -139,6 +141,7 @@ class CourseTopicsViewTest(DiscussionAPIViewTestMixin, ModuleStoreTestCase):
@ddt.ddt
@ddt.ddt
@httpretty.activate
@httpretty.activate
@mock.patch.dict
(
"django.conf.settings.FEATURES"
,
{
"ENABLE_DISCUSSION_SERVICE"
:
True
})
class
ThreadViewSetListTest
(
DiscussionAPIViewTestMixin
,
ModuleStoreTestCase
):
class
ThreadViewSetListTest
(
DiscussionAPIViewTestMixin
,
ModuleStoreTestCase
):
"""Tests for ThreadViewSet list"""
"""Tests for ThreadViewSet list"""
def
setUp
(
self
):
def
setUp
(
self
):
...
@@ -388,6 +391,7 @@ class ThreadViewSetListTest(DiscussionAPIViewTestMixin, ModuleStoreTestCase):
...
@@ -388,6 +391,7 @@ class ThreadViewSetListTest(DiscussionAPIViewTestMixin, ModuleStoreTestCase):
@httpretty.activate
@httpretty.activate
@disable_signal
(
api
,
'thread_created'
)
@disable_signal
(
api
,
'thread_created'
)
@mock.patch.dict
(
"django.conf.settings.FEATURES"
,
{
"ENABLE_DISCUSSION_SERVICE"
:
True
})
class
ThreadViewSetCreateTest
(
DiscussionAPIViewTestMixin
,
ModuleStoreTestCase
):
class
ThreadViewSetCreateTest
(
DiscussionAPIViewTestMixin
,
ModuleStoreTestCase
):
"""Tests for ThreadViewSet create"""
"""Tests for ThreadViewSet create"""
def
setUp
(
self
):
def
setUp
(
self
):
...
@@ -480,6 +484,7 @@ class ThreadViewSetCreateTest(DiscussionAPIViewTestMixin, ModuleStoreTestCase):
...
@@ -480,6 +484,7 @@ class ThreadViewSetCreateTest(DiscussionAPIViewTestMixin, ModuleStoreTestCase):
@httpretty.activate
@httpretty.activate
@disable_signal
(
api
,
'thread_edited'
)
@disable_signal
(
api
,
'thread_edited'
)
@mock.patch.dict
(
"django.conf.settings.FEATURES"
,
{
"ENABLE_DISCUSSION_SERVICE"
:
True
})
class
ThreadViewSetPartialUpdateTest
(
DiscussionAPIViewTestMixin
,
ModuleStoreTestCase
):
class
ThreadViewSetPartialUpdateTest
(
DiscussionAPIViewTestMixin
,
ModuleStoreTestCase
):
"""Tests for ThreadViewSet partial_update"""
"""Tests for ThreadViewSet partial_update"""
def
setUp
(
self
):
def
setUp
(
self
):
...
@@ -580,6 +585,7 @@ class ThreadViewSetPartialUpdateTest(DiscussionAPIViewTestMixin, ModuleStoreTest
...
@@ -580,6 +585,7 @@ class ThreadViewSetPartialUpdateTest(DiscussionAPIViewTestMixin, ModuleStoreTest
@httpretty.activate
@httpretty.activate
@disable_signal
(
api
,
'thread_deleted'
)
@disable_signal
(
api
,
'thread_deleted'
)
@mock.patch.dict
(
"django.conf.settings.FEATURES"
,
{
"ENABLE_DISCUSSION_SERVICE"
:
True
})
class
ThreadViewSetDeleteTest
(
DiscussionAPIViewTestMixin
,
ModuleStoreTestCase
):
class
ThreadViewSetDeleteTest
(
DiscussionAPIViewTestMixin
,
ModuleStoreTestCase
):
"""Tests for ThreadViewSet delete"""
"""Tests for ThreadViewSet delete"""
def
setUp
(
self
):
def
setUp
(
self
):
...
@@ -613,6 +619,7 @@ class ThreadViewSetDeleteTest(DiscussionAPIViewTestMixin, ModuleStoreTestCase):
...
@@ -613,6 +619,7 @@ class ThreadViewSetDeleteTest(DiscussionAPIViewTestMixin, ModuleStoreTestCase):
@httpretty.activate
@httpretty.activate
@mock.patch.dict
(
"django.conf.settings.FEATURES"
,
{
"ENABLE_DISCUSSION_SERVICE"
:
True
})
class
CommentViewSetListTest
(
DiscussionAPIViewTestMixin
,
ModuleStoreTestCase
):
class
CommentViewSetListTest
(
DiscussionAPIViewTestMixin
,
ModuleStoreTestCase
):
"""Tests for CommentViewSet list"""
"""Tests for CommentViewSet list"""
def
setUp
(
self
):
def
setUp
(
self
):
...
@@ -744,6 +751,7 @@ class CommentViewSetListTest(DiscussionAPIViewTestMixin, ModuleStoreTestCase):
...
@@ -744,6 +751,7 @@ class CommentViewSetListTest(DiscussionAPIViewTestMixin, ModuleStoreTestCase):
@httpretty.activate
@httpretty.activate
@disable_signal
(
api
,
'comment_deleted'
)
@disable_signal
(
api
,
'comment_deleted'
)
@mock.patch.dict
(
"django.conf.settings.FEATURES"
,
{
"ENABLE_DISCUSSION_SERVICE"
:
True
})
class
CommentViewSetDeleteTest
(
DiscussionAPIViewTestMixin
,
ModuleStoreTestCase
):
class
CommentViewSetDeleteTest
(
DiscussionAPIViewTestMixin
,
ModuleStoreTestCase
):
"""Tests for ThreadViewSet delete"""
"""Tests for ThreadViewSet delete"""
...
@@ -785,6 +793,7 @@ class CommentViewSetDeleteTest(DiscussionAPIViewTestMixin, ModuleStoreTestCase):
...
@@ -785,6 +793,7 @@ class CommentViewSetDeleteTest(DiscussionAPIViewTestMixin, ModuleStoreTestCase):
@httpretty.activate
@httpretty.activate
@disable_signal
(
api
,
'comment_created'
)
@disable_signal
(
api
,
'comment_created'
)
@mock.patch.dict
(
"django.conf.settings.FEATURES"
,
{
"ENABLE_DISCUSSION_SERVICE"
:
True
})
class
CommentViewSetCreateTest
(
DiscussionAPIViewTestMixin
,
ModuleStoreTestCase
):
class
CommentViewSetCreateTest
(
DiscussionAPIViewTestMixin
,
ModuleStoreTestCase
):
"""Tests for CommentViewSet create"""
"""Tests for CommentViewSet create"""
def
setUp
(
self
):
def
setUp
(
self
):
...
@@ -869,6 +878,7 @@ class CommentViewSetCreateTest(DiscussionAPIViewTestMixin, ModuleStoreTestCase):
...
@@ -869,6 +878,7 @@ class CommentViewSetCreateTest(DiscussionAPIViewTestMixin, ModuleStoreTestCase):
@disable_signal
(
api
,
'comment_edited'
)
@disable_signal
(
api
,
'comment_edited'
)
@mock.patch.dict
(
"django.conf.settings.FEATURES"
,
{
"ENABLE_DISCUSSION_SERVICE"
:
True
})
class
CommentViewSetPartialUpdateTest
(
DiscussionAPIViewTestMixin
,
ModuleStoreTestCase
):
class
CommentViewSetPartialUpdateTest
(
DiscussionAPIViewTestMixin
,
ModuleStoreTestCase
):
"""Tests for CommentViewSet partial_update"""
"""Tests for CommentViewSet partial_update"""
def
setUp
(
self
):
def
setUp
(
self
):
...
@@ -954,6 +964,7 @@ class CommentViewSetPartialUpdateTest(DiscussionAPIViewTestMixin, ModuleStoreTes
...
@@ -954,6 +964,7 @@ class CommentViewSetPartialUpdateTest(DiscussionAPIViewTestMixin, ModuleStoreTes
@httpretty.activate
@httpretty.activate
@mock.patch.dict
(
"django.conf.settings.FEATURES"
,
{
"ENABLE_DISCUSSION_SERVICE"
:
True
})
class
ThreadViewSetRetrieveTest
(
DiscussionAPIViewTestMixin
,
ModuleStoreTestCase
):
class
ThreadViewSetRetrieveTest
(
DiscussionAPIViewTestMixin
,
ModuleStoreTestCase
):
"""Tests for ThreadViewSet Retrieve"""
"""Tests for ThreadViewSet Retrieve"""
def
setUp
(
self
):
def
setUp
(
self
):
...
...
lms/djangoapps/django_comment_client/forum/views.py
View file @
90fe71db
...
@@ -27,7 +27,6 @@ from openedx.core.djangoapps.course_groups.cohorts import (
...
@@ -27,7 +27,6 @@ from openedx.core.djangoapps.course_groups.cohorts import (
from
courseware.tabs
import
EnrolledTab
from
courseware.tabs
import
EnrolledTab
from
courseware.access
import
has_access
from
courseware.access
import
has_access
from
xmodule.modulestore.django
import
modulestore
from
xmodule.modulestore.django
import
modulestore
from
ccx.overrides
import
get_current_ccx
from
django_comment_common.utils
import
ThreadContext
from
django_comment_common.utils
import
ThreadContext
from
django_comment_client.permissions
import
has_permission
,
get_team
from
django_comment_client.permissions
import
has_permission
,
get_team
...
@@ -66,11 +65,7 @@ class DiscussionTab(EnrolledTab):
...
@@ -66,11 +65,7 @@ class DiscussionTab(EnrolledTab):
def
is_enabled
(
cls
,
course
,
user
=
None
):
def
is_enabled
(
cls
,
course
,
user
=
None
):
if
not
super
(
DiscussionTab
,
cls
)
.
is_enabled
(
course
,
user
):
if
not
super
(
DiscussionTab
,
cls
)
.
is_enabled
(
course
,
user
):
return
False
return
False
return
utils
.
is_discussion_enabled
(
course
.
id
)
if
settings
.
FEATURES
.
get
(
'CUSTOM_COURSES_EDX'
,
False
):
if
get_current_ccx
(
course
.
id
):
return
False
return
settings
.
FEATURES
.
get
(
'ENABLE_DISCUSSION_SERVICE'
)
def
_attr_safe_json
(
obj
):
def
_attr_safe_json
(
obj
):
...
...
lms/djangoapps/django_comment_client/utils.py
View file @
90fe71db
...
@@ -2,6 +2,7 @@ from collections import defaultdict
...
@@ -2,6 +2,7 @@ from collections import defaultdict
from
datetime
import
datetime
from
datetime
import
datetime
import
json
import
json
import
logging
import
logging
from
django.conf
import
settings
import
pytz
import
pytz
from
django.contrib.auth.models
import
User
from
django.contrib.auth.models
import
User
...
@@ -13,6 +14,7 @@ import pystache_custom as pystache
...
@@ -13,6 +14,7 @@ import pystache_custom as pystache
from
opaque_keys.edx.locations
import
i4xEncoder
from
opaque_keys.edx.locations
import
i4xEncoder
from
opaque_keys.edx.keys
import
CourseKey
from
opaque_keys.edx.keys
import
CourseKey
from
xmodule.modulestore.django
import
modulestore
from
xmodule.modulestore.django
import
modulestore
from
ccx.overrides
import
get_current_ccx
from
django_comment_common.models
import
Role
,
FORUM_ROLE_STUDENT
from
django_comment_common.models
import
Role
,
FORUM_ROLE_STUDENT
from
django_comment_client.permissions
import
check_permissions_by_view
,
has_permission
,
get_team
from
django_comment_client.permissions
import
check_permissions_by_view
,
has_permission
,
get_team
...
@@ -716,3 +718,13 @@ def is_commentable_cohorted(course_key, commentable_id):
...
@@ -716,3 +718,13 @@ def is_commentable_cohorted(course_key, commentable_id):
log
.
debug
(
u"is_commentable_cohorted(
%
s,
%
s) = {
%
s}"
,
course_key
,
commentable_id
,
ans
)
log
.
debug
(
u"is_commentable_cohorted(
%
s,
%
s) = {
%
s}"
,
course_key
,
commentable_id
,
ans
)
return
ans
return
ans
def
is_discussion_enabled
(
course_id
):
"""
Return True if Discussion is enabled for a course; else False
"""
if
settings
.
FEATURES
.
get
(
'CUSTOM_COURSES_EDX'
,
False
):
if
get_current_ccx
(
course_id
):
return
False
return
settings
.
FEATURES
.
get
(
'ENABLE_DISCUSSION_SERVICE'
)
lms/djangoapps/mobile_api/users/serializers.py
View file @
90fe71db
...
@@ -34,10 +34,16 @@ class CourseOverviewField(serializers.RelatedField):
...
@@ -34,10 +34,16 @@ class CourseOverviewField(serializers.RelatedField):
kwargs
=
{
'course_id'
:
course_id
},
kwargs
=
{
'course_id'
:
course_id
},
request
=
request
request
=
request
)
)
discussion_url
=
reverse
(
'discussion_course'
,
kwargs
=
{
'course_id'
:
course_id
},
request
=
request
)
if
course_overview
.
is_discussion_tab_enabled
()
else
None
else
:
else
:
video_outline_url
=
None
video_outline_url
=
None
course_updates_url
=
None
course_updates_url
=
None
course_handouts_url
=
None
course_handouts_url
=
None
discussion_url
=
None
if
course_overview
.
advertised_start
is
not
None
:
if
course_overview
.
advertised_start
is
not
None
:
start_type
=
"string"
start_type
=
"string"
...
@@ -68,6 +74,7 @@ class CourseOverviewField(serializers.RelatedField):
...
@@ -68,6 +74,7 @@ class CourseOverviewField(serializers.RelatedField):
"video_outline"
:
video_outline_url
,
"video_outline"
:
video_outline_url
,
"course_updates"
:
course_updates_url
,
"course_updates"
:
course_updates_url
,
"course_handouts"
:
course_handouts_url
,
"course_handouts"
:
course_handouts_url
,
"discussion_url"
:
discussion_url
,
"subscription_id"
:
course_overview
.
clean_id
(
padding_char
=
'_'
),
"subscription_id"
:
course_overview
.
clean_id
(
padding_char
=
'_'
),
"courseware_access"
:
has_access
(
request
.
user
,
'load_mobile'
,
course_overview
)
.
to_json
()
if
request
else
None
"courseware_access"
:
has_access
(
request
.
user
,
'load_mobile'
,
course_overview
)
.
to_json
()
if
request
else
None
}
}
...
...
lms/djangoapps/mobile_api/users/tests.py
View file @
90fe71db
...
@@ -28,6 +28,7 @@ from xmodule.modulestore.tests.factories import ItemFactory, CourseFactory
...
@@ -28,6 +28,7 @@ from xmodule.modulestore.tests.factories import ItemFactory, CourseFactory
from
..
import
errors
from
..
import
errors
from
..testutils
import
MobileAPITestCase
,
MobileAuthTestMixin
,
MobileAuthUserTestMixin
,
MobileCourseAccessTestMixin
from
..testutils
import
MobileAPITestCase
,
MobileAuthTestMixin
,
MobileAuthUserTestMixin
,
MobileCourseAccessTestMixin
from
.serializers
import
CourseEnrollmentSerializer
from
.serializers
import
CourseEnrollmentSerializer
from
util.testing
import
UrlResetMixin
class
TestUserDetailApi
(
MobileAPITestCase
,
MobileAuthUserTestMixin
):
class
TestUserDetailApi
(
MobileAPITestCase
,
MobileAuthUserTestMixin
):
...
@@ -60,7 +61,7 @@ class TestUserInfoApi(MobileAPITestCase, MobileAuthTestMixin):
...
@@ -60,7 +61,7 @@ class TestUserInfoApi(MobileAPITestCase, MobileAuthTestMixin):
@ddt.ddt
@ddt.ddt
class
TestUserEnrollmentApi
(
MobileAPITestCase
,
MobileAuthUserTestMixin
):
class
TestUserEnrollmentApi
(
UrlResetMixin
,
MobileAPITestCase
,
MobileAuthUserTestMixin
):
"""
"""
Tests for /api/mobile/v0.5/users/<user_name>/course_enrollments/
Tests for /api/mobile/v0.5/users/<user_name>/course_enrollments/
"""
"""
...
@@ -71,7 +72,14 @@ class TestUserEnrollmentApi(MobileAPITestCase, MobileAuthUserTestMixin):
...
@@ -71,7 +72,14 @@ class TestUserEnrollmentApi(MobileAPITestCase, MobileAuthUserTestMixin):
LAST_WEEK
=
datetime
.
datetime
.
now
(
pytz
.
UTC
)
-
datetime
.
timedelta
(
days
=
7
)
LAST_WEEK
=
datetime
.
datetime
.
now
(
pytz
.
UTC
)
-
datetime
.
timedelta
(
days
=
7
)
ADVERTISED_START
=
"Spring 2016"
ADVERTISED_START
=
"Spring 2016"
@patch.dict
(
"django.conf.settings.FEATURES"
,
{
"ENABLE_DISCUSSION_SERVICE"
:
True
})
def
setUp
(
self
,
*
args
,
**
kwargs
):
super
(
TestUserEnrollmentApi
,
self
)
.
setUp
()
def
verify_success
(
self
,
response
):
def
verify_success
(
self
,
response
):
"""
Verifies user course enrollment response for success
"""
super
(
TestUserEnrollmentApi
,
self
)
.
verify_success
(
response
)
super
(
TestUserEnrollmentApi
,
self
)
.
verify_success
(
response
)
courses
=
response
.
data
courses
=
response
.
data
self
.
assertEqual
(
len
(
courses
),
1
)
self
.
assertEqual
(
len
(
courses
),
1
)
...
@@ -205,6 +213,14 @@ class TestUserEnrollmentApi(MobileAPITestCase, MobileAuthUserTestMixin):
...
@@ -205,6 +213,14 @@ class TestUserEnrollmentApi(MobileAPITestCase, MobileAuthUserTestMixin):
course_data
=
response
.
data
[
0
][
'course'
]
course_data
=
response
.
data
[
0
][
'course'
]
self
.
assertEquals
(
course_data
[
'social_urls'
][
'facebook'
],
self
.
course
.
facebook_url
)
self
.
assertEquals
(
course_data
[
'social_urls'
][
'facebook'
],
self
.
course
.
facebook_url
)
@patch.dict
(
"django.conf.settings.FEATURES"
,
{
"ENABLE_DISCUSSION_SERVICE"
:
True
})
def
test_discussion_url
(
self
):
self
.
login_and_enroll
()
response
=
self
.
api_response
()
response_discussion_url
=
response
.
data
[
0
][
'course'
][
'discussion_url'
]
# pylint: disable=E1101
self
.
assertIn
(
'/api/discussion/v1/courses/{}'
.
format
(
self
.
course
.
id
),
response_discussion_url
)
class
CourseStatusAPITestCase
(
MobileAPITestCase
):
class
CourseStatusAPITestCase
(
MobileAPITestCase
):
"""
"""
...
...
lms/djangoapps/mobile_api/users/views.py
View file @
90fe71db
...
@@ -239,6 +239,8 @@ class UserCourseEnrollmentsList(generics.ListAPIView):
...
@@ -239,6 +239,8 @@ class UserCourseEnrollmentsList(generics.ListAPIView):
the course.
the course.
* video_outline: The URI to get the list of all videos that the user
* video_outline: The URI to get the list of all videos that the user
can access in the course.
can access in the course.
* discussion_url: The URI to access data for course discussions if
it is enabled, otherwise null.
* created: The date the course was created.
* created: The date the course was created.
* is_active: Whether the course is currently active. Possible values
* is_active: Whether the course is currently active. Possible values
...
...
openedx/core/djangoapps/content/course_overviews/migrations/0007_auto__add_courseoverviewtab.py
0 → 100644
View file @
90fe71db
# -*- coding: utf-8 -*-
from
south.utils
import
datetime_utils
as
datetime
from
south.db
import
db
from
south.v2
import
SchemaMigration
from
django.db
import
models
class
Migration
(
SchemaMigration
):
def
forwards
(
self
,
orm
):
# Adding model 'CourseOverviewTab'
db
.
create_table
(
'course_overviews_courseoverviewtab'
,
(
(
'id'
,
self
.
gf
(
'django.db.models.fields.AutoField'
)(
primary_key
=
True
)),
(
'tab_id'
,
self
.
gf
(
'django.db.models.fields.CharField'
)(
max_length
=
50
)),
(
'course_overview'
,
self
.
gf
(
'django.db.models.fields.related.ForeignKey'
)(
related_name
=
'tabs'
,
to
=
orm
[
'course_overviews.CourseOverview'
])),
))
db
.
send_create_signal
(
'course_overviews'
,
[
'CourseOverviewTab'
])
def
backwards
(
self
,
orm
):
# Deleting model 'CourseOverviewTab'
db
.
delete_table
(
'course_overviews_courseoverviewtab'
)
models
=
{
'course_overviews.courseoverview'
:
{
'Meta'
:
{
'object_name'
:
'CourseOverview'
},
'_location'
:
(
'xmodule_django.models.UsageKeyField'
,
[],
{
'max_length'
:
'255'
}),
'_pre_requisite_courses_json'
:
(
'django.db.models.fields.TextField'
,
[],
{}),
'advertised_start'
:
(
'django.db.models.fields.TextField'
,
[],
{
'null'
:
'True'
}),
'cert_html_view_enabled'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
}),
'cert_name_long'
:
(
'django.db.models.fields.TextField'
,
[],
{}),
'cert_name_short'
:
(
'django.db.models.fields.TextField'
,
[],
{}),
'certificates_display_behavior'
:
(
'django.db.models.fields.TextField'
,
[],
{
'null'
:
'True'
}),
'certificates_show_before_end'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
}),
'course_image_url'
:
(
'django.db.models.fields.TextField'
,
[],
{}),
'created'
:
(
'model_utils.fields.AutoCreatedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'days_early_for_beta'
:
(
'django.db.models.fields.FloatField'
,
[],
{
'null'
:
'True'
}),
'display_name'
:
(
'django.db.models.fields.TextField'
,
[],
{
'null'
:
'True'
}),
'display_number_with_default'
:
(
'django.db.models.fields.TextField'
,
[],
{}),
'display_org_with_default'
:
(
'django.db.models.fields.TextField'
,
[],
{}),
'end'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'null'
:
'True'
}),
'end_of_course_survey_url'
:
(
'django.db.models.fields.TextField'
,
[],
{
'null'
:
'True'
}),
'enrollment_domain'
:
(
'django.db.models.fields.TextField'
,
[],
{
'null'
:
'True'
}),
'enrollment_end'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'null'
:
'True'
}),
'enrollment_start'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'null'
:
'True'
}),
'facebook_url'
:
(
'django.db.models.fields.TextField'
,
[],
{
'null'
:
'True'
}),
'has_any_active_web_certificate'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
}),
'id'
:
(
'xmodule_django.models.CourseKeyField'
,
[],
{
'max_length'
:
'255'
,
'primary_key'
:
'True'
,
'db_index'
:
'True'
}),
'invitation_only'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
}),
'lowest_passing_grade'
:
(
'django.db.models.fields.DecimalField'
,
[],
{
'null'
:
'True'
,
'max_digits'
:
'5'
,
'decimal_places'
:
'2'
}),
'max_student_enrollments_allowed'
:
(
'django.db.models.fields.IntegerField'
,
[],
{
'null'
:
'True'
}),
'mobile_available'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
}),
'modified'
:
(
'model_utils.fields.AutoLastModifiedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'social_sharing_url'
:
(
'django.db.models.fields.TextField'
,
[],
{
'null'
:
'True'
}),
'start'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'null'
:
'True'
}),
'version'
:
(
'django.db.models.fields.IntegerField'
,
[],
{}),
'visible_to_staff_only'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
})
},
'course_overviews.courseoverviewtab'
:
{
'Meta'
:
{
'object_name'
:
'CourseOverviewTab'
},
'course_overview'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'related_name'
:
"'tabs'"
,
'to'
:
"orm['course_overviews.CourseOverview']"
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'tab_id'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'50'
})
}
}
complete_apps
=
[
'course_overviews'
]
\ No newline at end of file
openedx/core/djangoapps/content/course_overviews/models.py
View file @
90fe71db
"""
"""
Declaration of CourseOverview model
Declaration of CourseOverview model
"""
"""
import
json
import
json
from
django.db
import
models
from
django.db.models.fields
import
BooleanField
,
DateTimeField
,
DecimalField
,
TextField
,
FloatField
,
IntegerField
from
django.db.models.fields
import
BooleanField
,
DateTimeField
,
DecimalField
,
TextField
,
FloatField
,
IntegerField
from
django.db.utils
import
IntegrityError
from
django.db.utils
import
IntegrityError
from
django.utils.translation
import
ugettext
from
django.utils.translation
import
ugettext
from
lms.djangoapps
import
django_comment_client
from
model_utils.models
import
TimeStampedModel
from
model_utils.models
import
TimeStampedModel
from
opaque_keys.edx.keys
import
CourseKey
from
opaque_keys.edx.keys
import
CourseKey
from
util.date_utils
import
strftime_localized
from
util.date_utils
import
strftime_localized
from
xmodule
import
course_metadata_utils
from
xmodule
import
course_metadata_utils
from
xmodule.course_module
import
CourseDescriptor
from
xmodule.course_module
import
CourseDescriptor
...
@@ -30,7 +32,7 @@ class CourseOverview(TimeStampedModel):
...
@@ -30,7 +32,7 @@ class CourseOverview(TimeStampedModel):
"""
"""
# IMPORTANT: Bump this whenever you modify this model and/or add a migration.
# IMPORTANT: Bump this whenever you modify this model and/or add a migration.
VERSION
=
1
VERSION
=
2
# Cache entry versioning.
# Cache entry versioning.
version
=
IntegerField
()
version
=
IntegerField
()
...
@@ -176,6 +178,10 @@ class CourseOverview(TimeStampedModel):
...
@@ -176,6 +178,10 @@ class CourseOverview(TimeStampedModel):
course_overview
=
cls
.
_create_from_course
(
course
)
course_overview
=
cls
.
_create_from_course
(
course
)
try
:
try
:
course_overview
.
save
()
course_overview
.
save
()
CourseOverviewTab
.
objects
.
bulk_create
([
CourseOverviewTab
(
tab_id
=
tab
.
tab_id
,
course_overview
=
course_overview
)
for
tab
in
course
.
tabs
])
except
IntegrityError
:
except
IntegrityError
:
# There is a rare race condition that will occur if
# There is a rare race condition that will occur if
# CourseOverview.get_from_id is called while a
# CourseOverview.get_from_id is called while a
...
@@ -358,3 +364,22 @@ class CourseOverview(TimeStampedModel):
...
@@ -358,3 +364,22 @@ class CourseOverview(TimeStampedModel):
CourseKey
.
from_string
(
course_overview
[
'id'
])
CourseKey
.
from_string
(
course_overview
[
'id'
])
for
course_overview
in
CourseOverview
.
objects
.
values
(
'id'
)
for
course_overview
in
CourseOverview
.
objects
.
values
(
'id'
)
]
]
def
is_discussion_tab_enabled
(
self
):
"""
Returns True if course has discussion tab and is enabled
"""
tabs
=
self
.
tabs
.
all
()
# pylint: disable=E1101
# creates circular import; hence explicitly referenced is_discussion_enabled
for
tab
in
tabs
:
if
tab
.
tab_id
==
"discussion"
and
django_comment_client
.
utils
.
is_discussion_enabled
(
self
.
id
):
return
True
return
False
class
CourseOverviewTab
(
models
.
Model
):
"""
Model for storing and caching tabs information of a course.
"""
tab_id
=
models
.
CharField
(
max_length
=
50
)
course_overview
=
models
.
ForeignKey
(
CourseOverview
,
db_index
=
True
,
related_name
=
"tabs"
)
openedx/core/djangoapps/content/course_overviews/tests.py
View file @
90fe71db
...
@@ -34,6 +34,8 @@ class CourseOverviewTestCase(ModuleStoreTestCase):
...
@@ -34,6 +34,8 @@ class CourseOverviewTestCase(ModuleStoreTestCase):
NEXT_WEEK
=
TODAY
+
datetime
.
timedelta
(
days
=
7
)
NEXT_WEEK
=
TODAY
+
datetime
.
timedelta
(
days
=
7
)
NEXT_MONTH
=
TODAY
+
datetime
.
timedelta
(
days
=
30
)
NEXT_MONTH
=
TODAY
+
datetime
.
timedelta
(
days
=
30
)
COURSE_OVERVIEW_TABS
=
{
'courseware'
,
'info'
,
'textbooks'
,
'discussion'
,
'wiki'
,
'progress'
}
def
check_course_overview_against_course
(
self
,
course
):
def
check_course_overview_against_course
(
self
,
course
):
"""
"""
Compares a CourseOverview object against its corresponding
Compares a CourseOverview object against its corresponding
...
@@ -164,6 +166,12 @@ class CourseOverviewTestCase(ModuleStoreTestCase):
...
@@ -164,6 +166,12 @@ class CourseOverviewTestCase(ModuleStoreTestCase):
self
.
assertEqual
(
course_value
,
cache_miss_value
)
self
.
assertEqual
(
course_value
,
cache_miss_value
)
self
.
assertEqual
(
cache_miss_value
,
cache_hit_value
)
self
.
assertEqual
(
cache_miss_value
,
cache_hit_value
)
# test tabs for both cached miss and cached hit courses
for
course_overview
in
[
course_overview_cache_miss
,
course_overview_cache_hit
]:
course_overview_tabs
=
course_overview
.
tabs
.
all
()
course_resp_tabs
=
{
tab
.
tab_id
for
tab
in
course_overview_tabs
}
self
.
assertEqual
(
self
.
COURSE_OVERVIEW_TABS
,
course_resp_tabs
)
@ddt.data
(
*
itertools
.
product
(
@ddt.data
(
*
itertools
.
product
(
[
[
{
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment