Merge pull request #713 from edx/diana/button-updates
Drupal side Register button updates
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import datetime
|
||||
from south.db import db
|
||||
from south.v2 import SchemaMigration
|
||||
from django.db import models
|
||||
|
||||
|
||||
class Migration(SchemaMigration):
|
||||
|
||||
def forwards(self, orm):
|
||||
# Adding field 'CourseMode.currency'
|
||||
db.add_column('course_modes_coursemode', 'currency',
|
||||
self.gf('django.db.models.fields.CharField')(default='usd', max_length=8),
|
||||
keep_default=False)
|
||||
|
||||
|
||||
def backwards(self, orm):
|
||||
# Deleting field 'CourseMode.currency'
|
||||
db.delete_column('course_modes_coursemode', 'currency')
|
||||
|
||||
|
||||
models = {
|
||||
'course_modes.coursemode': {
|
||||
'Meta': {'object_name': 'CourseMode'},
|
||||
'course_id': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
|
||||
'currency': ('django.db.models.fields.CharField', [], {'default': "'usd'", 'max_length': '8'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'min_price': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
|
||||
'mode_display_name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||
'mode_slug': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'suggested_prices': ('django.db.models.fields.CommaSeparatedIntegerField', [], {'default': "''", 'max_length': '255', 'blank': 'True'})
|
||||
}
|
||||
}
|
||||
|
||||
complete_apps = ['course_modes']
|
||||
@@ -0,0 +1,33 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import datetime
|
||||
from south.db import db
|
||||
from south.v2 import SchemaMigration
|
||||
from django.db import models
|
||||
|
||||
|
||||
class Migration(SchemaMigration):
|
||||
|
||||
def forwards(self, orm):
|
||||
# Adding unique constraint on 'CourseMode', fields ['course_id', 'currency', 'mode_slug']
|
||||
db.create_unique('course_modes_coursemode', ['course_id', 'currency', 'mode_slug'])
|
||||
|
||||
|
||||
def backwards(self, orm):
|
||||
# Removing unique constraint on 'CourseMode', fields ['course_id', 'currency', 'mode_slug']
|
||||
db.delete_unique('course_modes_coursemode', ['course_id', 'currency', 'mode_slug'])
|
||||
|
||||
|
||||
models = {
|
||||
'course_modes.coursemode': {
|
||||
'Meta': {'unique_together': "(('course_id', 'mode_slug', 'currency'),)", 'object_name': 'CourseMode'},
|
||||
'course_id': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
|
||||
'currency': ('django.db.models.fields.CharField', [], {'default': "'usd'", 'max_length': '8'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'min_price': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
|
||||
'mode_display_name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||
'mode_slug': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'suggested_prices': ('django.db.models.fields.CommaSeparatedIntegerField', [], {'default': "''", 'max_length': '255', 'blank': 'True'})
|
||||
}
|
||||
}
|
||||
|
||||
complete_apps = ['course_modes']
|
||||
@@ -5,7 +5,7 @@ from django.db import models
|
||||
from collections import namedtuple
|
||||
from django.utils.translation import ugettext as _
|
||||
|
||||
Mode = namedtuple('Mode', ['slug', 'name', 'min_price', 'suggested_prices'])
|
||||
Mode = namedtuple('Mode', ['slug', 'name', 'min_price', 'suggested_prices', 'currency'])
|
||||
|
||||
|
||||
class CourseMode(models.Model):
|
||||
@@ -29,7 +29,14 @@ class CourseMode(models.Model):
|
||||
# the suggested prices for this mode
|
||||
suggested_prices = models.CommaSeparatedIntegerField(max_length=255, blank=True, default='')
|
||||
|
||||
DEFAULT_MODE = Mode('honor', _('Honor Code Certificate'), 0, '')
|
||||
# the currency these prices are in, using lower case ISO currency codes
|
||||
currency = models.CharField(default="usd", max_length=8)
|
||||
|
||||
DEFAULT_MODE = Mode('honor', _('Honor Code Certificate'), 0, '', 'usd')
|
||||
|
||||
class Meta:
|
||||
""" meta attributes of this model """
|
||||
unique_together = ('course_id', 'mode_slug', 'currency')
|
||||
|
||||
@classmethod
|
||||
def modes_for_course(cls, course_id):
|
||||
@@ -39,7 +46,7 @@ class CourseMode(models.Model):
|
||||
If no modes have been set in the table, returns the default mode
|
||||
"""
|
||||
found_course_modes = cls.objects.filter(course_id=course_id)
|
||||
modes = ([Mode(mode.mode_slug, mode.mode_display_name, mode.min_price, mode.suggested_prices)
|
||||
modes = ([Mode(mode.mode_slug, mode.mode_display_name, mode.min_price, mode.suggested_prices, mode.currency)
|
||||
for mode in found_course_modes])
|
||||
if not modes:
|
||||
modes = [cls.DEFAULT_MODE]
|
||||
|
||||
@@ -18,7 +18,7 @@ class CourseModeModelTest(TestCase):
|
||||
self.course_id = 'TestCourse'
|
||||
CourseMode.objects.all().delete()
|
||||
|
||||
def create_mode(self, mode_slug, mode_name, min_price=0, suggested_prices=''):
|
||||
def create_mode(self, mode_slug, mode_name, min_price=0, suggested_prices='', currency='usd'):
|
||||
"""
|
||||
Create a new course mode
|
||||
"""
|
||||
@@ -27,7 +27,8 @@ class CourseModeModelTest(TestCase):
|
||||
mode_display_name=mode_name,
|
||||
mode_slug=mode_slug,
|
||||
min_price=min_price,
|
||||
suggested_prices=suggested_prices
|
||||
suggested_prices=suggested_prices,
|
||||
currency=currency
|
||||
)
|
||||
|
||||
def test_modes_for_course_empty(self):
|
||||
@@ -45,14 +46,14 @@ class CourseModeModelTest(TestCase):
|
||||
|
||||
self.create_mode('verified', 'Verified Certificate')
|
||||
modes = CourseMode.modes_for_course(self.course_id)
|
||||
self.assertEqual([Mode(u'verified', u'Verified Certificate', 0, '')], modes)
|
||||
self.assertEqual([Mode(u'verified', u'Verified Certificate', 0, '', 'usd')], modes)
|
||||
|
||||
def test_modes_for_course_multiple(self):
|
||||
"""
|
||||
Finding the modes when there's multiple modes
|
||||
"""
|
||||
mode1 = Mode(u'honor', u'Honor Code Certificate', 0, '')
|
||||
mode2 = Mode(u'verified', u'Verified Certificate', 0, '')
|
||||
mode1 = Mode(u'honor', u'Honor Code Certificate', 0, '', 'usd')
|
||||
mode2 = Mode(u'verified', u'Verified Certificate', 0, '', 'usd')
|
||||
set_modes = [mode1, mode2]
|
||||
for mode in set_modes:
|
||||
self.create_mode(mode.slug, mode.name, mode.min_price, mode.suggested_prices)
|
||||
|
||||
@@ -12,12 +12,14 @@ from django.core.urlresolvers import reverse
|
||||
|
||||
from student.models import CourseEnrollment
|
||||
from student.tests.factories import AdminFactory
|
||||
|
||||
from xmodule.modulestore.django import modulestore
|
||||
|
||||
import courseware.views as views
|
||||
from xmodule.modulestore import Location
|
||||
from pytz import UTC
|
||||
from modulestore_config import TEST_DATA_XML_MODULESTORE
|
||||
from course_modes.models import CourseMode
|
||||
|
||||
|
||||
class Stub():
|
||||
@@ -164,6 +166,36 @@ class ViewsTestCase(TestCase):
|
||||
# generate/store a real password.
|
||||
self.assertEquals(chat_settings['password'], "johndoe@%s" % domain)
|
||||
|
||||
def test_course_mktg_about_coming_soon(self):
|
||||
# we should not be able to find this course
|
||||
url = reverse('mktg_about_course', kwargs={'course_id': 'no/course/here'})
|
||||
response = self.client.get(url)
|
||||
self.assertIn('Coming Soon', response.content)
|
||||
|
||||
def test_course_mktg_register(self):
|
||||
admin = AdminFactory()
|
||||
self.client.login(username=admin.username, password='test')
|
||||
url = reverse('mktg_about_course', kwargs={'course_id': self.course_id})
|
||||
response = self.client.get(url)
|
||||
self.assertIn('Register for', response.content)
|
||||
self.assertNotIn('and choose your student track', response.content)
|
||||
|
||||
def test_course_mktg_register_multiple_modes(self):
|
||||
admin = AdminFactory()
|
||||
CourseMode.objects.get_or_create(mode_slug='honor',
|
||||
mode_display_name='Honor Code Certificate',
|
||||
course_id=self.course_id)
|
||||
CourseMode.objects.get_or_create(mode_slug='verified',
|
||||
mode_display_name='Verified Certificate',
|
||||
course_id=self.course_id)
|
||||
self.client.login(username=admin.username, password='test')
|
||||
url = reverse('mktg_about_course', kwargs={'course_id': self.course_id})
|
||||
response = self.client.get(url)
|
||||
self.assertIn('Register for', response.content)
|
||||
self.assertIn('and choose your student track', response.content)
|
||||
# clean up course modes
|
||||
CourseMode.objects.all().delete()
|
||||
|
||||
def test_submission_history_xss(self):
|
||||
# log into a staff account
|
||||
admin = AdminFactory()
|
||||
|
||||
@@ -25,6 +25,7 @@ from courseware.masquerade import setup_masquerade
|
||||
from courseware.model_data import ModelDataCache
|
||||
from .module_render import toc_for_course, get_module_for_descriptor, get_module
|
||||
from courseware.models import StudentModule, StudentModuleHistory
|
||||
from course_modes.models import CourseMode
|
||||
|
||||
from django_comment_client.utils import get_discussion_title
|
||||
|
||||
@@ -600,9 +601,14 @@ def course_about(request, course_id):
|
||||
'registered': registered,
|
||||
'course_target': course_target,
|
||||
'show_courseware_link': show_courseware_link})
|
||||
|
||||
|
||||
@ensure_csrf_cookie
|
||||
@cache_if_anonymous
|
||||
def mktg_course_about(request, course_id):
|
||||
"""
|
||||
This is the button that gets put into an iframe on the Drupal site
|
||||
"""
|
||||
|
||||
try:
|
||||
course = get_course_with_access(request.user, course_id, 'see_exists')
|
||||
@@ -610,7 +616,7 @@ def mktg_course_about(request, course_id):
|
||||
# if a course does not exist yet, display a coming
|
||||
# soon button
|
||||
return render_to_response('courseware/mktg_coming_soon.html',
|
||||
{'course_id': course_id})
|
||||
{'course_id': course_id})
|
||||
|
||||
registered = registered_for_course(course, request.user)
|
||||
|
||||
@@ -623,13 +629,17 @@ def mktg_course_about(request, course_id):
|
||||
|
||||
show_courseware_link = (has_access(request.user, course, 'load') or
|
||||
settings.MITX_FEATURES.get('ENABLE_LMS_MIGRATION'))
|
||||
course_modes = CourseMode.modes_for_course(course.id)
|
||||
|
||||
return render_to_response('courseware/mktg_course_about.html',
|
||||
{'course': course,
|
||||
'registered': registered,
|
||||
'allow_registration': allow_registration,
|
||||
'course_target': course_target,
|
||||
'show_courseware_link': show_courseware_link})
|
||||
{
|
||||
'course': course,
|
||||
'registered': registered,
|
||||
'allow_registration': allow_registration,
|
||||
'course_target': course_target,
|
||||
'show_courseware_link': show_courseware_link,
|
||||
'course_modes': course_modes,
|
||||
})
|
||||
|
||||
|
||||
def render_notifications(request, course, notifications):
|
||||
|
||||
@@ -156,6 +156,19 @@
|
||||
&.action-register, &.access-courseware {
|
||||
@extend .m-btn-primary;
|
||||
display: block;
|
||||
|
||||
.track {
|
||||
@include transition(all 0.25s ease-in-out);
|
||||
color: $white;
|
||||
display: block;
|
||||
font-size: 13px;
|
||||
line-height: 2em;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
&:hover .track {
|
||||
opacity: 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
// already registered but course not started or registration is closed
|
||||
|
||||
@@ -52,7 +52,13 @@
|
||||
<div class="action is-registered">${_("You Are Registered")}</div>
|
||||
%endif
|
||||
%elif allow_registration:
|
||||
<a class="action action-register register" href="#">${_("Register for")} <strong>${course.display_number_with_default | h}</strong></a>
|
||||
<a class="action action-register register" href="#">${_("Register for")} <strong>${course.display_number_with_default | h}</strong>
|
||||
%if len(course_modes) > 1:
|
||||
<span class="track">
|
||||
and choose your student track
|
||||
</span>
|
||||
%endif
|
||||
</a>
|
||||
%else:
|
||||
<div class="action registration-closed is-disabled">${_("Registration Is Closed")}</div>
|
||||
%endif
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user