MA-1248 - CourseEnrollmentAPI: added discussion URL
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
# -*- 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']
|
||||
@@ -1,15 +1,17 @@
|
||||
"""
|
||||
Declaration of CourseOverview model
|
||||
"""
|
||||
|
||||
import json
|
||||
from django.db import models
|
||||
|
||||
from django.db.models.fields import BooleanField, DateTimeField, DecimalField, TextField, FloatField, IntegerField
|
||||
from django.db.utils import IntegrityError
|
||||
from django.utils.translation import ugettext
|
||||
from lms.djangoapps import django_comment_client
|
||||
from model_utils.models import TimeStampedModel
|
||||
|
||||
from opaque_keys.edx.keys import CourseKey
|
||||
|
||||
from util.date_utils import strftime_localized
|
||||
from xmodule import course_metadata_utils
|
||||
from xmodule.course_module import CourseDescriptor
|
||||
@@ -30,7 +32,7 @@ class CourseOverview(TimeStampedModel):
|
||||
"""
|
||||
|
||||
# IMPORTANT: Bump this whenever you modify this model and/or add a migration.
|
||||
VERSION = 1
|
||||
VERSION = 2
|
||||
|
||||
# Cache entry versioning.
|
||||
version = IntegerField()
|
||||
@@ -176,6 +178,10 @@ class CourseOverview(TimeStampedModel):
|
||||
course_overview = cls._create_from_course(course)
|
||||
try:
|
||||
course_overview.save()
|
||||
CourseOverviewTab.objects.bulk_create([
|
||||
CourseOverviewTab(tab_id=tab.tab_id, course_overview=course_overview)
|
||||
for tab in course.tabs
|
||||
])
|
||||
except IntegrityError:
|
||||
# There is a rare race condition that will occur if
|
||||
# CourseOverview.get_from_id is called while a
|
||||
@@ -358,3 +364,22 @@ class CourseOverview(TimeStampedModel):
|
||||
CourseKey.from_string(course_overview['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")
|
||||
|
||||
@@ -34,6 +34,8 @@ class CourseOverviewTestCase(ModuleStoreTestCase):
|
||||
NEXT_WEEK = TODAY + datetime.timedelta(days=7)
|
||||
NEXT_MONTH = TODAY + datetime.timedelta(days=30)
|
||||
|
||||
COURSE_OVERVIEW_TABS = {'courseware', 'info', 'textbooks', 'discussion', 'wiki', 'progress'}
|
||||
|
||||
def check_course_overview_against_course(self, course):
|
||||
"""
|
||||
Compares a CourseOverview object against its corresponding
|
||||
@@ -164,6 +166,12 @@ class CourseOverviewTestCase(ModuleStoreTestCase):
|
||||
self.assertEqual(course_value, cache_miss_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(
|
||||
[
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user