Commit 4a37648f by Dennis Jen

Merge pull request #6504 from edx/release-merge-test

Merge release (2015-01-08) into master
parents 66228224 d2660e53
"""Script for deleting orphans"""
from django.core.management.base import BaseCommand, CommandError
from contentstore.views.item import _delete_orphans
from opaque_keys.edx.keys import CourseKey
from opaque_keys import InvalidKeyError
from xmodule.modulestore import ModuleStoreEnum
class Command(BaseCommand):
"""Command for deleting orphans"""
help = '''
Delete orphans from a MongoDB backed course. Takes two arguments:
<course_id>: the course id of the course whose orphans you want to delete
|commit|: optional argument. If not provided, will not run task.
'''
def handle(self, *args, **options):
if len(args) not in {1, 2}:
raise CommandError("delete_orphans requires one or more arguments: <course_id> |commit|")
try:
course_key = CourseKey.from_string(args[0])
except InvalidKeyError:
raise CommandError("Invalid course key.")
commit = False
if len(args) == 2:
commit = args[1] == 'commit'
if commit:
print 'Deleting orphans from the course:'
deleted_items = _delete_orphans(
course_key, ModuleStoreEnum.UserID.mgmt_command, commit
)
print "Success! Deleted the following orphans from the course:"
print "\n".join(deleted_items)
else:
print 'Dry run. The following orphans would have been deleted from the course:'
deleted_items = _delete_orphans(
course_key, ModuleStoreEnum.UserID.mgmt_command, commit
)
print "\n".join(deleted_items)
"""Tests running the delete_orphan command"""
from django.core.management import call_command
from contentstore.tests.test_orphan import TestOrphanBase
class TestDeleteOrphan(TestOrphanBase):
"""
Tests for running the delete_orphan management command.
Inherits from TestOrphan in order to use its setUp method.
"""
def setUp(self):
super(TestDeleteOrphan, self).setUp()
self.course_id = self.course.id.to_deprecated_string()
def test_delete_orphans_no_commit(self):
"""
Tests that running the command without a 'commit' argument
results in no orphans being deleted
"""
call_command('delete_orphans', self.course_id)
self.assertTrue(self.store.has_item(self.course.id.make_usage_key('html', 'multi_parent_html')))
self.assertTrue(self.store.has_item(self.course.id.make_usage_key('vertical', 'OrphanVert')))
self.assertTrue(self.store.has_item(self.course.id.make_usage_key('chapter', 'OrphanChapter')))
self.assertTrue(self.store.has_item(self.course.id.make_usage_key('html', 'OrphanHtml')))
def test_delete_orphans_commit(self):
"""
Tests that running the command WITH the 'commit' argument
results in the orphans being deleted
"""
call_command('delete_orphans', self.course_id, 'commit')
# make sure this module wasn't deleted
self.assertTrue(self.store.has_item(self.course.id.make_usage_key('html', 'multi_parent_html')))
# and make sure that these were
self.assertFalse(self.store.has_item(self.course.id.make_usage_key('vertical', 'OrphanVert')))
self.assertFalse(self.store.has_item(self.course.id.make_usage_key('chapter', 'OrphanChapter')))
self.assertFalse(self.store.has_item(self.course.id.make_usage_key('html', 'OrphanHtml')))
......@@ -8,46 +8,59 @@ from xmodule.modulestore.django import modulestore
from contentstore.utils import reverse_course_url
class TestOrphan(CourseTestCase):
class TestOrphanBase(CourseTestCase):
"""
Test finding orphans via view and django config
Base class for Studio tests that require orphaned modules
"""
def setUp(self):
super(TestOrphan, self).setUp()
super(TestOrphanBase, self).setUp()
runtime = self.course.runtime
# create chapters and add them to course tree
chapter1 = self.store.create_child(self.user.id, self.course.location, 'chapter', "Chapter1")
self.store.publish(chapter1.location, self.user.id)
self._create_item('chapter', 'Chapter1', {}, {'display_name': 'Chapter 1'}, 'course', self.course.location.name, runtime)
self._create_item('chapter', 'Chapter2', {}, {'display_name': 'Chapter 2'}, 'course', self.course.location.name, runtime)
self._create_item('chapter', 'OrphanChapter', {}, {'display_name': 'Orphan Chapter'}, None, None, runtime)
self._create_item('vertical', 'Vert1', {}, {'display_name': 'Vertical 1'}, 'chapter', 'Chapter1', runtime)
self._create_item('vertical', 'OrphanVert', {}, {'display_name': 'Orphan Vertical'}, None, None, runtime)
self._create_item('html', 'Html1', "<p>Goodbye</p>", {'display_name': 'Parented Html'}, 'vertical', 'Vert1', runtime)
self._create_item('html', 'OrphanHtml', "<p>Hello</p>", {'display_name': 'Orphan html'}, None, None, runtime)
self._create_item('static_tab', 'staticuno', "<p>tab</p>", {'display_name': 'Tab uno'}, None, None, runtime)
self._create_item('about', 'overview', "<p>overview</p>", {}, None, None, runtime)
self._create_item('course_info', 'updates', "<ol><li><h2>Sep 22</h2><p>test</p></li></ol>", {}, None, None, runtime)
chapter2 = self.store.create_child(self.user.id, self.course.location, 'chapter', "Chapter2")
self.store.publish(chapter2.location, self.user.id)
self.orphan_url = reverse_course_url('orphan_handler', self.course.id)
# orphan chapter
orphan_chapter = self.store.create_item(self.user.id, self.course.id, 'chapter', "OrphanChapter")
self.store.publish(orphan_chapter.location, self.user.id)
def _create_item(self, category, name, data, metadata, parent_category, parent_name, runtime):
location = self.course.location.replace(category=category, name=name)
store = modulestore()
store.create_item(
self.user.id,
location.course_key,
location.block_type,
location.block_id,
definition_data=data,
metadata=metadata,
runtime=runtime
)
if parent_name:
# add child to parent in mongo
parent_location = self.course.location.replace(category=parent_category, name=parent_name)
parent = store.get_item(parent_location)
parent.children.append(location)
store.update_item(parent, self.user.id)
# create vertical and add it as child to chapter1
vertical1 = self.store.create_child(self.user.id, chapter1.location, 'vertical', "Vertical1")
self.store.publish(vertical1.location, self.user.id)
# create orphan vertical
orphan_vertical = self.store.create_item(self.user.id, self.course.id, 'vertical', "OrphanVert")
self.store.publish(orphan_vertical.location, self.user.id)
# create component and add it to vertical1
html1 = self.store.create_child(self.user.id, vertical1.location, 'html', "Html1")
self.store.publish(html1.location, self.user.id)
# create component and add it as a child to vertical1 and orphan_vertical
multi_parent_html = self.store.create_child(self.user.id, vertical1.location, 'html', "multi_parent_html")
self.store.publish(multi_parent_html.location, self.user.id)
orphan_vertical.children.append(multi_parent_html.location)
self.store.update_item(orphan_vertical, self.user.id)
# create an orphaned html module
orphan_html = self.store.create_item(self.user.id, self.course.id, 'html', "OrphanHtml")
self.store.publish(orphan_html.location, self.user.id)
self.store.create_child(self.user.id, self.course.location, 'static_tab', "staticuno")
self.store.create_child(self.user.id, self.course.location, 'about', "overview")
self.store.create_child(self.user.id, self.course.location, 'course_info', "updates")
class TestOrphan(TestOrphanBase):
"""
Test finding orphans via view and django config
"""
def setUp(self):
super(TestOrphan, self).setUp()
self.orphan_url = reverse_course_url('orphan_handler', self.course.id)
def test_mongo_orphan(self):
"""
......@@ -77,6 +90,10 @@ class TestOrphan(CourseTestCase):
)
self.assertEqual(len(orphans), 0, "Orphans not deleted {}".format(orphans))
# make sure that any children with one orphan parent and one non-orphan
# parent are not deleted
self.assertTrue(self.store.has_item(self.course.id.make_usage_key('html', "multi_parent_html")))
def test_not_permitted(self):
"""
Test that auth restricts get and delete appropriately
......
......@@ -604,14 +604,25 @@ def orphan_handler(request, course_key_string):
raise PermissionDenied()
if request.method == 'DELETE':
if request.user.is_staff:
deleted_items = _delete_orphans(course_usage_key, request.user.id, commit=True)
return JsonResponse({'deleted': deleted_items})
else:
raise PermissionDenied()
def _delete_orphans(course_usage_key, user_id, commit=False):
"""
Helper function to delete orphans for a given course.
If `commit` is False, this function does not actually remove
the orphans.
"""
store = modulestore()
items = store.get_orphans(course_usage_key)
if commit:
for itemloc in items:
# need to delete all versions
store.delete_item(itemloc, request.user.id, revision=ModuleStoreEnum.RevisionOption.all)
return JsonResponse({'deleted': [unicode(item) for item in items]})
else:
raise PermissionDenied()
store.delete_item(itemloc, user_id, revision=ModuleStoreEnum.RevisionOption.all)
return [unicode(item) for item in items]
def _get_xblock(usage_key, user):
......
......@@ -775,10 +775,13 @@ ADVANCED_COMPONENT_TYPES = [
'audio', # Embed an audio file. See https://github.com/pmitros/AudioXBlock
'recommender', # Crowdsourced recommender. Prototype by dli&pmitros. Intended for roll-out in one place in one course.
'profile', # Prototype user profile XBlock. Used to test XBlock parameter passing. See https://github.com/pmitros/ProfileXBlock
'split_test',
'combinedopenended',
'peergrading',
'notes',
'schoolyourself_review',
'schoolyourself_lesson',
]
# Adding components in this list will disable the creation of new problem for those
......
......@@ -541,7 +541,7 @@ class DraftModuleStore(MongoModuleStore):
)
self._delete_subtree(location, as_functions)
def _delete_subtree(self, location, as_functions):
def _delete_subtree(self, location, as_functions, draft_only=False):
"""
Internal method for deleting all of the subtree whose revisions match the as_functions
"""
......@@ -555,6 +555,19 @@ class DraftModuleStore(MongoModuleStore):
next_tier = []
for child_loc in current_entry.get('definition', {}).get('children', []):
child_loc = course_key.make_usage_key_from_deprecated_string(child_loc)
# single parent can have 2 versions: draft and published
# get draft parents only while deleting draft module
if draft_only:
revision = MongoRevisionKey.draft
else:
revision = ModuleStoreEnum.RevisionOption.all
parents = self._get_raw_parent_locations(child_loc, revision)
# Don't delete modules if one of its parents shouldn't be deleted
# This should only be an issue for courses have ended up in
# a state where modules have multiple parents
if all(parent.to_deprecated_son() in to_be_deleted for parent in parents):
for rev_func in as_functions:
current_loc = rev_func(child_loc)
current_son = current_loc.to_deprecated_son()
......@@ -738,7 +751,7 @@ class DraftModuleStore(MongoModuleStore):
# If 2 versions versions exist, we can assume one is a published version. Go ahead and do the delete
# of the draft version.
if versions_found.count() > 1:
self._delete_subtree(root_location, [as_draft])
self._delete_subtree(root_location, [as_draft], draft_only=True)
elif versions_found.count() == 1:
# Since this method cannot be called on something in DIRECT_ONLY_CATEGORIES and we call
# delete_subtree as soon as we find an item with a draft version, if there is only 1 version
......
......@@ -723,7 +723,7 @@ class TestMixedModuleStore(CourseComparisonTest):
# Split:
# queries: active_versions, draft and published structures, definition (unnecessary)
# sends: update published (why?), draft, and active_versions
@ddt.data(('draft', 8, 2), ('split', 2, 2))
@ddt.data(('draft', 9, 2), ('split', 2, 2))
@ddt.unpack
def test_delete_private_vertical(self, default_ms, max_find, max_send):
"""
......
......@@ -910,7 +910,7 @@ class ShoppingCartViewsTests(ModuleStoreTestCase):
# Two courses in user shopping cart
self.login_user()
item1 = PaidCourseRegistration.add_to_order(self.cart, self.course_key)
PaidCourseRegistration.add_to_order(self.cart, self.course_key)
item2 = PaidCourseRegistration.add_to_order(self.cart, self.testing_course.id)
self.assertEquals(self.cart.orderitem_set.count(), 2)
......@@ -1217,7 +1217,14 @@ class ReceiptRedirectTest(UrlResetMixin, ModuleStoreTestCase):
@patch.dict(settings.FEATURES, {'SEPARATE_VERIFICATION_FROM_PAYMENT': True})
def test_show_receipt_redirect_to_verify_student(self):
# Create other carts first
# This ensures that the order ID and order item IDs do not match
Order.get_cart_for_user(self.user).start_purchase()
Order.get_cart_for_user(self.user).start_purchase()
Order.get_cart_for_user(self.user).start_purchase()
# Purchase a verified certificate
self.cart = Order.get_cart_for_user(self.user)
CertificateItem.add_to_order(
self.cart,
self.course_key,
......
......@@ -818,7 +818,7 @@ def _show_receipt_html(request, order):
# Add a query string param for the order ID
# This allows the view to query for the receipt information later.
url += '?payment-order-num={order_num}'.format(
order_num=order_items[0].id
order_num=order_items[0].order.id
)
return HttpResponseRedirect(url)
......
......@@ -86,16 +86,10 @@ define([
};
var expectPaymentDisabledBecauseInactive = function() {
var payButton = $( '#pay_button'),
activateButton = $( '#activate_button' );
var payButton = $( '#pay_button' );
// Payment button should be hidden
expect( payButton.length ).toEqual(0);
// Activate button should be displayed and disabled
expect( activateButton.length ).toEqual(1);
expect( activateButton.hasClass( 'is-disabled' ) ).toBe( true );
expect( activateButton.prop( 'disabled' ) ).toBe( true );
};
var goToPayment = function( requests, kwargs ) {
......
......@@ -158,7 +158,7 @@ define([
view = createView( backends );
// Expect an error
expect( view.errorModel.get( 'errorTitle' ) ).toEqual( 'No Flash Detected' );
expect( view.errorModel.get( 'errorTitle' ) ).toEqual( 'Flash Not Detected' );
expect( view.errorModel.get( 'errorMsg' ) ).toContain( 'Get Flash' );
expect( view.errorModel.get( 'shown' ) ).toBe( true );
......
......@@ -172,7 +172,9 @@ var edx = edx || {};
toggleForm: function( e ) {
var type = $(e.currentTarget).data('type'),
$form = $('#' + type + '-form'),
$anchor = $('#' + type + '-anchor');
$anchor = $('#' + type + '-anchor'),
queryParams = url('?'),
queryStr = queryParams.length > 0 ? '?' + queryParams : '';
e.preventDefault();
......@@ -190,7 +192,7 @@ var edx = edx || {};
this.element.scrollTop( $anchor );
// Update url without reloading page
History.pushState( null, document.title, '/account/' + type + '/' );
History.pushState( null, document.title, '/account/' + type + '/' + queryStr );
analytics.page( 'login_and_registration', type );
},
......
......@@ -55,7 +55,7 @@ var edx = edx || {};
minPrice: el.data('course-mode-min-price'),
contributionAmount: el.data('contribution-amount'),
suggestedPrices: _.filter(
(el.data('course-mode-suggested-prices') || "").split(","),
(el.data('course-mode-suggested-prices').toString()).split(","),
function( price ) { return Boolean( price ); }
),
currency: el.data('course-mode-currency'),
......
......@@ -38,11 +38,6 @@ var edx = edx || {};
// Set the payment button to disabled by default
this.setPaymentEnabled( false );
// The activate button is always disabled
$( '#activate_button' )
.addClass( 'is-disabled' )
.prop( 'disabled', true );
// Update the contribution amount with the amount the user
// selected in a previous screen.
if ( templateContext.contributionAmount ) {
......@@ -140,7 +135,7 @@ var edx = edx || {};
},
handleCreateOrderError: function( xhr ) {
var errorMsg = gettext( 'An unexpected error occurred. Please try again.' );
var errorMsg = gettext( 'An error has occurred. Please try again.' );
if ( xhr.status === 400 ) {
errorMsg = xhr.responseText;
......
......@@ -66,7 +66,7 @@ var edx = edx || {};
},
handleSubmissionError: function( xhr ) {
var errorMsg = gettext( 'An unexpected error occurred. Please try again later.' );
var errorMsg = gettext( 'An error has occurred. Please try again later.' );
// Re-enable the submit button to allow the user to retry
this.setSubmitButtonEnabled( true );
......
......@@ -46,7 +46,7 @@
handleError: function( errorTitle, errorMsg ) {
this.errorModel.set({
errorTitle: errorTitle || gettext( "Error" ),
errorMsg: errorMsg || gettext( "An unexpected error occurred. Please reload the page to try again." ),
errorMsg: errorMsg || gettext( "An error has occurred. Please try reloading the page." ),
shown: true
});
},
......
......@@ -85,8 +85,8 @@
handleVideoFailure: function() {
this.trigger(
'error',
gettext( 'Video capture error' ),
gettext( 'Please check that your webcam is connected and you have allowed access to your webcam.' )
gettext( 'Video Capture Error' ),
gettext( 'Please verify that your webcam is connected and that you have allowed your browser to access it.' )
);
}
},
......@@ -211,7 +211,7 @@
if ( !this.backend ) {
this.handleError(
gettext( "No Flash Detected" ),
gettext( "Flash Not Detected" ),
gettext( "You don't seem to have Flash installed." ) + " " +
_.sprintf(
gettext( "%(a_start)s Get Flash %(a_end)s to continue your enrollment." ),
......
......@@ -23,6 +23,12 @@
}
}
.placeholder-cam {
.copy {
font-weight: bold !important;
}
}
.requirements-container {
.list-reqs {
......@@ -41,7 +47,7 @@
}
&.account-not-activated {
width: 990px;
width: 300px;
.req {
height: 290px;
......@@ -75,6 +81,7 @@
display: inline;
float: left;
line-height: 45px;
color: black;
}
.wizard-steps {
......@@ -119,11 +126,23 @@
.expandable-area {
margin-top: 5px;
padding-bottom: 20px;
}
}
.help-tips {
margin-left: 0 !important;
.title {
font-size: 16px !important;
}
.list-tips {
.tip {
font-size: 16px;
line-height: 1.5em;
}
}
}
.photo-tip {
......@@ -137,6 +156,12 @@
padding-left: 20px;
}
.list-faq {
dd {
color: black;
}
}
.wrapper-task {
.msg-retake {
margin-top: 0;
......
......@@ -22,6 +22,7 @@ from courseware.courses import course_image_url, get_course_about_section
course_number=course.display_number_with_default,
course_title=get_course_about_section(course, 'title'),
)}" />
</div>
<div class="enrollment-details">
<div class="sub-title">${_("Confirm your enrollment for:")}
<span class="course-date-label">${_("course dates")}</span>
......
......@@ -47,7 +47,7 @@
<div class="enrollment-status-footer">
<h4 class="title"><%- gettext( "Verified Status" ) %></h4>
<p class="verify-pending-msg">
<%- gettext( "Thank you for submitting your identification photos, we will review them soon. If there is a problem with any of the items, we will contact you to resubmit. You can now enroll in any of the verified certificate courses for one year without having to re-verify." ) %></p>
<%- _.sprintf( gettext( "Thank you for submitting your photos. We will review them shortly. You can now sign up for any %(platformName)s course that offers verified certificates. Verification is good for one year. After one year, you must submit photos for verification again." ), { platformName: platformName } ) %></p>
</div>
</article>
</div>
......@@ -2,7 +2,7 @@
<div class="facephoto view">
<h3 class="title"><%- gettext( "Take Your Photo" ) %></h3>
<div class="instruction">
<p><%- gettext( "Use your webcam to take a picture of your face so we can match it with the picture on your ID." ) %></p>
<p><%- gettext( "Use your webcam to take a photo of your face. We will match this photo with the photo on your ID." ) %></p>
</div>
<div class="wrapper-task">
......@@ -17,7 +17,7 @@
<li class="help-item"><%- gettext( "Make sure your face is well-lit" ) %></li>
<li class="help-item"><%- gettext( "Be sure your entire face is inside the frame" ) %></li>
<li class="help-item">
<%= _.sprintf( gettext( "Once in position, use the camera button %(icon)s to capture your picture" ), { icon: '<span class="example">(<i class="icon-camera"></i>)</span>' } ) %>
<%= _.sprintf( gettext( "Once in position, use the camera button %(icon)s to capture your photo" ), { icon: '<span class="example">(<i class="icon-camera"></i>)</span>' } ) %>
</li>
<li class="help-item"><%- gettext( "Can we match the photo you took with the one on your ID?" ) %></li>
<li class="help-item"><%- gettext( "Use the retake photo button if you are not pleased with your photo" ) %></li>
......@@ -26,17 +26,17 @@
</div>
<div class="help help-faq facefaq">
<h4 class="sr title"><%- gettext( "Common Questions" ) %></h4>
<h4 class="sr title"><%- gettext( "Frequently Asked Questions" ) %></h4>
<div class="copy">
<dl class="list-faq">
<dt class="faq-question">
<%- _.sprintf( gettext( "Why does %(platformName)s need my photo?" ), { platformName: platformName } ) %>
</dt>
<dd class="faq-answer"><%- gettext( "As part of the verification process, we need your photo to confirm your identity." ) %></dd>
<dd class="faq-answer"><%- gettext( "As part of the verification process, you take a photo of both your face and a government-issued photo ID. Our authorization service confirms your identity by comparing the photo you take with the photo on your ID." ) %></dd>
<dt class="faq-question">
<%- _.sprintf( gettext( "What does %(platformName)s do with this picture?" ), { platformName: platformName } ) %>
<%- _.sprintf( gettext( "What does %(platformName)s do with this photo?" ), { platformName: platformName } ) %>
</dt>
<dd class="faq-answer"><%- gettext( "We encrypt it and send it to our secure authorization service for review. We use the highest levels of security and do not save the photo or information anywhere once the match has been completed." ) %></dd>
<dd class="faq-answer"><%- _.sprintf( gettext( "We use the highest levels of security available to encrypt your photo and send it to our authorization service for review. Your photo and information are not saved or visible anywhere on %(platformName)s after the verification process is complete." ), { platformName: platformName } ) %></dd>
</dl>
</div>
</div>
......
......@@ -2,7 +2,7 @@
<div class="idphoto view">
<h3 class="title"><%- gettext( "Take a Photo of Your ID" ) %></h3>
<div class="instruction">
<p><%- gettext("Use your webcam to take a picture of your ID so we can match it with your photo and the name on your account.") %></p>
<p><%- gettext("Use your webcam to take a photo of your ID. We will match this photo with the photo of your face and the name on your account.") %></p>
</div>
<div class="wrapper-task">
......@@ -27,19 +27,19 @@
</div>
<div class="help help-faq facefaq">
<h4 class="sr title"><%- gettext( "Common Questions" ) %></h4>
<h4 class="sr title"><%- gettext( "Frequently Asked Questions" ) %></h4>
<div class="copy">
<dl class="list-faq">
<dt class="faq-question">
<%- _.sprintf( gettext( "Why does %(platformName)s need my photo?" ), { platformName: platformName } ) %>
</dt>
<dd class="faq-answer"><%- gettext( "We need to match your ID with your photo and name to confirm your identity." ) %></dd>
<dd class="faq-answer"><%- gettext( "As part of the verification process, you take a photo of both your face and a government-issued photo ID. Our authorization service confirms your identity by comparing the photo you take with the photo on your ID." ) %></dd>
<dt class="faq-question">
<%- _.sprintf( gettext( "What does %(platformName)s do with this picture?" ), { platformName: platformName } ) %>
<%- _.sprintf( gettext( "What does %(platformName)s do with this photo?" ), { platformName: platformName } ) %>
</dt>
<dd class="faq-answer"><%- gettext( "We encrypt it and send it to our secure authorization service for review. We use the highest levels of security and do not save the photo or information anywhere once the match has been completed." ) %></dd>
<dd class="faq-answer"><%- _.sprintf( gettext( "We use the highest levels of security available to encrypt your photo and send it to our authorization service for review. Your photo and information are not saved or visible anywhere on %(platformName)s after the verification process is complete." ), { platformName: platformName } ) %></dd>
</dl>
</div>
</div>
......
......@@ -9,7 +9,13 @@
</h3>
<% } else { %>
<h3 class="title"><%- introTitle %></h3>
<% if ( introMsg ) { %>
<% if ( !isActive ) { %>
<div class="instruction">
<p>
<%- gettext( "You need to activate your account before you can enroll in courses. Check your inbox for an activation email. After you complete activation you can return and refresh this page." ) %>
</p>
</div>
<% } else if ( introMsg ) { %>
<div class="instruction"><p><%- introMsg %></p></div>
<% } %>
<% } %>
......@@ -25,16 +31,11 @@
<div class="copy">
<p>
<span class="copy-super"><%- gettext( "Check your email" ) %></span>
<span class="copy-sub"><%-
gettext( "You need to activate your account before you can register for courses. Check your inbox for an activation email." )
%>
</span>
<span class="copy-super"><%- gettext( "Check Your Email" ) %></span>
</p>
</div>
</li>
<% } %>
<% } else { %>
<% if ( requirements['photo-id-required'] ) { %>
<li class="req req-1 req-id">
<h4 class="title"><%- gettext( "Photo ID" ) %></h4>
......@@ -45,7 +46,7 @@
<div class="copy">
<p>
<span class="copy-sub"><%- gettext( "A driver's license, passport, or government-issued ID with your name and picture" ) %></span>
<span class="copy-sub"><%- gettext( "A driver's license, passport, or other government-issued ID with your name and photo" ) %></span>
</p>
</div>
</li>
......@@ -61,17 +62,16 @@
<div class="copy"></div>
</li>
<% } %>
<% } %>
</ul>
</div>
<% if ( nextStepTitle ) { %>
<% if ( nextStepTitle && isActive ) { %>
<nav class="nav-wizard is-ready">
<ol class="wizard-steps">
<li class="wizard-step">
<a class="next action-primary" <% if ( !isActive ) { %>disabled="true"<% } %> id="next_step_button" href="?skip-first-step=1">
<% if ( !isActive ) { %>
<%- gettext( "Activate Your Account" ) %>
<% } else if ( hasPaid ) { %>
<a class="next action-primary" id="next_step_button" href="?skip-first-step=1">
<% if ( hasPaid ) { %>
<%- _.sprintf(
gettext( "Next: %(nextStepTitle)s" ),
{ nextStepTitle: nextStepTitle }
......
......@@ -15,7 +15,7 @@
) %>
</h3>
<div class="instruction">
<%- gettext( "We've already verified your identity through the photos of you and your ID you provided earlier. You can now pay and complete registration." ) %>
<%- gettext( "We have successfully verified your identity. You can now enter your payment information and complete your enrollment." ) %>
</div>
<% } %>
......@@ -79,7 +79,7 @@
<% } else {%>
<li class="review-task review-task-contribution">
<h4 class="title"><%- gettext( "Your Course Total" ) %></h4>
<h4 class="title"><%- gettext( "Your Total Contribution" ) %></h4>
<div class="copy">
<p><%- gettext( "To complete your enrollment, you will need to pay:" ) %></p>
</div>
......@@ -105,6 +105,8 @@
gettext( "You can pay now even if you don't have the following items available, but you will need to have these by %(date)s to qualify to earn a Verified Certificate." ),
{ date: verificationDeadline }
) %>
<% } else if ( !isActive ) { %>
<%- gettext( "You need to activate your account before you can enroll in courses. Check your inbox for an activation email. After you complete activation you can return and refresh this page." ) %>
<% } else if ( !upgrade ) { %>
<%- gettext( "You can pay now even if you don't have the following items available, but you will need to have these to qualify to earn a Verified Certificate." ) %>
<% } %>
......@@ -124,19 +126,14 @@
<div class="copy">
<p>
<span class="copy-super"><%- gettext( "Check your email" ) %></span>
<span class="copy-sub"><%-
gettext( "You need to activate your account before you can enroll in courses. Check your inbox for an activation email." )
%>
</span>
<span class="copy-super"><%- gettext( "Check Your Email" ) %></span>
</p>
</div>
</li>
<% } %>
<% } else {%>
<% if ( requirements['photo-id-required'] ) { %>
<li class="req req-1 req-id">
<h4 class="title"><%- gettext( "Government-issued Photo ID" ) %></h4>
<h4 class="title"><%- gettext( "Government-Issued Photo ID" ) %></h4>
<div class="placeholder-art">
<i class="icon-list-alt icon-under"></i>
<i class="icon-user icon-over"></i>
......@@ -156,26 +153,25 @@
<div class="copy"></div>
</li>
<% } %>
<% } %>
</ul>
</div>
<% } %>
<% if ( isActive ) { %>
<nav class="nav-wizard is-ready <% if ( isActive && !upgrade ) { %>center<% } %>">
<% if ( upgrade ) { %>
<a class="next action-primary is-disabled right" id="pay_button" aria-disabled="true">
<%- gettext( "Next: Make payment" ) %>
</a>
<% } else if ( isActive ) { %>
<a class="next action-primary is-disabled" id="pay_button" aria-disabled="true">
<%- gettext( "Continue to payment" ) %>
</a>
<% } else { %>
<a class="next action-primary is-disabled" id="activate_button" aria-disabled="true">
<%- gettext( "Activate your account" ) %>
<a class="next action-primary is-disabled" id="pay_button">
<%- gettext( "Continue to payment" ) %>
</a>
<% } %>
</nav>
<% } %>
<form id="payment-processor-form"></form>
</div>
......@@ -76,6 +76,7 @@ from verify_student.views import PayAndVerifyView
data-is-active='${is_active}'
></div>
% if is_active:
## Support
<div class="wrapper-content-supplementary">
<aside class="content-supplementary">
......@@ -98,6 +99,7 @@ from verify_student.views import PayAndVerifyView
</ul>
</aside>
</div>
% endif
</section>
</div>
......
<div class="wrapper-content-main payment-confirmation-step">
<article class="content-main">
<h3 class="title">
<%= _.sprintf( gettext( "Thank you! We have received your payment for %(courseName)s" ), { courseName: '<span class="course-title">' + courseName + '</span>' } ) %>
<%= _.sprintf( gettext( "Thank you! We have received your payment for %(courseName)s." ), { courseName: '<span class="course-title">' + courseName + '</span>' } ) %>
</h3>
<% if ( receipt ) { %>
......@@ -55,14 +55,14 @@
<div class="msg msg-refunds">
<h4 class="title sr"><%- gettext( "Please Note" ) %>: </h4>
<div class="copy">
<p><%- gettext( "Items with strikethough have been refunded." ) %></p>
<p><%- gettext( "Crossed out items have been refunded." ) %></p>
</div>
</div>
<% } %>
</div>
<div class="copy">
<p><%- gettext( "Billed To" ) %>:
<p><%- gettext( "Billed to" ) %>:
<span class="name-first"><%- receipt.billedTo.firstName %></span>
<span class="name-last"><%- receipt.billedTo.lastName %></span>
(<span class="address-city"><%- receipt.billedTo.city %></span>,
......@@ -74,7 +74,7 @@
</li>
</ul>
<% } else { %>
<p class="no-content"><%- gettext( "No receipt available." ) %></p>
<p class="no-content"><%- gettext( "No receipt available" ) %></p>
<% } %>
<% if ( nextStepTitle ) { %>
......@@ -91,7 +91,7 @@
<div class="copy">
<p>
<span class="copy-super"><%- gettext( "Check your email." ) %></span>
<span class="copy-super"><%- gettext( "Check your email" ) %></span>
<span class="copy-sub"><%-
gettext( "You need to activate your account before you can enroll in courses. Check your inbox for an activation email." )
%>
......@@ -99,8 +99,7 @@
</p>
</div>
</li>
<% } %>
<% } else { %>
<% if ( requirements['photo-id-required'] ) { %>
<li class="req req-1 req-id">
<h4 class="title"><%- gettext( "Photo ID" ) %></h4>
......@@ -111,7 +110,7 @@
<div class="copy">
<p>
<span class="copy-sub"><%- gettext( "A driver's license, passport, or government-issued ID with your name and picture." ) %></span>
<span class="copy-sub"><%- gettext( "A driver's license, passport, or government-issued ID with your name and photo." ) %></span>
</p>
</div>
</li>
......@@ -127,6 +126,7 @@
<div class="copy"></div>
</li>
<% } %>
<% } %>
</ul>
</div>
......@@ -141,7 +141,7 @@
) %>
</a>
<a id="verify_later_button" class="next action-secondary verify-later nav-link" href="/dashboard" data-tooltip="<%- _.sprintf( gettext( "If you don't confirm your identity now, you can go to the dashboard to explore your course and %(platformName)s will remind you later." ), { platformName: platformName } ) %>">
<a id="verify_later_button" class="next action-secondary verify-later nav-link" href="/dashboard" data-tooltip="<%- _.sprintf( gettext( "If you don't verify your identity now, you can still explore your course from your dashboard. You will receive periodic reminders from %(platformName)s to verify your identity." ), { platformName: platformName } ) %>">
<%- gettext( "Want to confirm your identity later?" ) %>
</a>
</nav>
......
<div id="wrapper-review" class="wrapper-view review-photos-step">
<div class="review view">
<h3 class="title"><%- gettext( "Review your photos" ) %></h3>
<h3 class="title"><%- gettext( "Review Your Photos" ) %></h3>
<div class="instruction">
<p><%- gettext( "Make sure we can verify your identity from the photos below." ) %></p>
<p><%- gettext( "Make sure we can verify your identity with the photos and information you have provided." ) %></p>
</div>
<div class="wrapper-task">
......@@ -30,12 +30,12 @@
<li class="tip"><%- _.sprintf( gettext( "Does the name on your ID match your account name: %(fullName)s?" ), { fullName: fullName } ) %>
<div class="help-tip is-expandable">
<a href="#" class="title title-expand" aria-expanded="false" role="link">
<%- gettext( "Edit your name" ) %>
<%- gettext( "Edit Your Name" ) %>
</a>
<div class="copy expandable-area">
<p><%- gettext( "You should change the name on your account to match your ID." ) %></p>
<input type="text" name="new-name" id="new-name" placeholder=<%= fullName %>>
<p><%- gettext( "Make sure that the full name on your account matches the name on your ID." ) %></p>
<input type="text" name="new-name" id="new-name" placeholder="<%= fullName %>">
</div>
</div>
</li>
......@@ -48,7 +48,7 @@
<p>
<%- gettext( "Photos don't meet the requirements?" ) %>
<a id="retake_photos_button" class="retake-photos">
<%- gettext( "Retake your photos" ) %>
<%- gettext( "Retake Your Photos" ) %>
</a>
</p>
</div>
......
......@@ -9,11 +9,11 @@
<div class="controls photo-controls">
<div class="control control-retake is-hidden" id="webcam_reset_button">
<a class="action action-redo"><%- gettext( "Retake photo" ) %></a>
<a class="action action-redo"><%- gettext( "Retake Photo" ) %></a>
</div>
<div class="control control-do is-hidden" id="webcam_capture_button">
<a class="action action-do">
<i class="icon-camera"></i> <span class="sr"><%- gettext( "Take photo" ) %></span>
<i class="icon-camera"></i> <span class="sr"><%- gettext( "Take Photo" ) %></span>
</a>
</div>
</div>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment