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
d2a47908
Commit
d2a47908
authored
Sep 07, 2015
by
zubair-arbi
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
use the standard syntax to load JavaScript dependencies on logistration js files
ECOM-2044
parent
1ba4200a
Hide whitespace changes
Inline
Side-by-side
Showing
31 changed files
with
2232 additions
and
2166 deletions
+2232
-2166
common/djangoapps/third_party_auth/tests/specs/test_lti.py
+4
-4
common/djangoapps/third_party_auth/tests/specs/test_testshib.py
+17
-10
common/static/js/spec/edx.utils.validate_spec.js
+154
-151
common/static/js/utils/edx.utils.validate.js
+164
-157
lms/djangoapps/student_account/test/test_views.py
+14
-13
lms/djangoapps/student_account/views.py
+17
-14
lms/envs/common.py
+0
-24
lms/static/js/spec/main.js
+5
-96
lms/static/js/spec/student_account/access_spec.js
+42
-29
lms/static/js/spec/student_account/finish_auth_spec.js
+17
-12
lms/static/js/spec/student_account/hinted_login_spec.js
+75
-72
lms/static/js/spec/student_account/institution_login_spec.js
+77
-70
lms/static/js/spec/student_account/login_spec.js
+230
-225
lms/static/js/spec/student_account/logistration_factory_spec.js
+130
-0
lms/static/js/spec/student_account/password_reset_spec.js
+17
-15
lms/static/js/spec/student_account/register_spec.js
+319
-315
lms/static/js/student_account/accessApp.js
+0
-21
lms/static/js/student_account/logistration_factory.js
+15
-0
lms/static/js/student_account/models/LoginModel.js
+52
-53
lms/static/js/student_account/models/PasswordResetModel.js
+37
-42
lms/static/js/student_account/models/RegisterModel.js
+52
-57
lms/static/js/student_account/views/AccessView.js
+254
-240
lms/static/js/student_account/views/FormView.js
+216
-215
lms/static/js/student_account/views/HintedLoginView.js
+44
-46
lms/static/js/student_account/views/InstitutionLoginView.js
+22
-24
lms/static/js/student_account/views/LoginView.js
+119
-121
lms/static/js/student_account/views/PasswordResetView.js
+36
-36
lms/static/js/student_account/views/RegisterView.js
+91
-89
lms/static/js_test.yml
+1
-0
lms/static/lms/js/build.js
+1
-0
lms/templates/student_account/login_and_register.html
+10
-15
No files found.
common/djangoapps/third_party_auth/tests/specs/test_lti.py
View file @
d2a47908
...
...
@@ -69,8 +69,8 @@ class IntegrationTestLTI(testutil.TestCase):
self
.
assertTrue
(
login_response
[
'Location'
]
.
endswith
(
reverse
(
'signin_user'
)))
register_response
=
self
.
client
.
get
(
login_response
[
'Location'
])
self
.
assertEqual
(
register_response
.
status_code
,
200
)
self
.
assertIn
(
'
currentProvider": "LTI Test Tool Consumer"
'
,
register_response
.
content
)
self
.
assertIn
(
'
"errorMessage"
: null'
,
register_response
.
content
)
self
.
assertIn
(
'
"currentProvider": "LTI Test Tool Consumer"
'
,
register_response
.
content
)
self
.
assertIn
(
'
"errorMessage"
: null'
,
register_response
.
content
)
# Now complete the form:
ajax_register_response
=
self
.
client
.
post
(
...
...
@@ -153,7 +153,7 @@ class IntegrationTestLTI(testutil.TestCase):
register_response
=
self
.
client
.
get
(
login_response
[
'Location'
])
self
.
assertEqual
(
register_response
.
status_code
,
200
)
self
.
assertIn
(
'
currentProvider": "Tool Consumer with Secret in Settings"
'
,
'
"currentProvider": "Tool Consumer with Secret in Settings"
'
,
register_response
.
content
)
self
.
assertIn
(
'
"errorMessage"
: null'
,
register_response
.
content
)
self
.
assertIn
(
'
"errorMessage"
: null'
,
register_response
.
content
)
common/djangoapps/third_party_auth/tests/specs/test_testshib.py
View file @
d2a47908
"""
Third_party_auth integration tests using a mock version of the TestShib provider
"""
from
django.core.urlresolvers
import
reverse
import
json
import
unittest
import
httpretty
from
mock
import
patch
from
django.core.urlresolvers
import
reverse
from
openedx.core.lib.json_utils
import
EscapedEdxJSONEncoder
from
student.tests.factories
import
UserFactory
from
third_party_auth.tasks
import
fetch_saml_metadata
from
third_party_auth.tests
import
testutil
import
unittest
TESTSHIB_ENTITY_ID
=
'https://idp.testshib.org/idp/shibboleth'
TESTSHIB_METADATA_URL
=
'https://mock.testshib.org/metadata/testshib-providers.xml'
...
...
@@ -81,11 +88,11 @@ class TestShibIntegrationTest(testutil.SAMLTestCase):
# We'd now like to see if the "You've successfully signed into TestShib" message is
# shown, but it's managed by a JavaScript runtime template, and we can't run JS in this
# type of test, so we just check for the variable that triggers that message.
self
.
assertIn
(
'
"currentProvider": "TestShib"
'
,
register_response
.
content
)
self
.
assertIn
(
'
"errorMessage"
: null'
,
register_response
.
content
)
self
.
assertIn
(
'
"currentProvider": "TestShib"
'
,
register_response
.
content
)
self
.
assertIn
(
'
"errorMessage"
: null'
,
register_response
.
content
)
# Now do a crude check that the data (e.g. email) from the provider is displayed in the form:
self
.
assertIn
(
'
"defaultValue": "myself@testshib.org"
'
,
register_response
.
content
)
self
.
assertIn
(
'
"defaultValue": "Me Myself And I"
'
,
register_response
.
content
)
self
.
assertIn
(
'
"defaultValue": "myself@testshib.org"
'
,
register_response
.
content
)
self
.
assertIn
(
'
"defaultValue": "Me Myself And I"
'
,
register_response
.
content
)
# Now complete the form:
ajax_register_response
=
self
.
client
.
post
(
reverse
(
'user_api_registration'
),
...
...
@@ -128,8 +135,8 @@ class TestShibIntegrationTest(testutil.SAMLTestCase):
# We'd now like to see if the "You've successfully signed into TestShib" message is
# shown, but it's managed by a JavaScript runtime template, and we can't run JS in this
# type of test, so we just check for the variable that triggers that message.
self
.
assertIn
(
'
"currentProvider": "TestShib"
'
,
login_response
.
content
)
self
.
assertIn
(
'
"errorMessage"
: null'
,
login_response
.
content
)
self
.
assertIn
(
'
"currentProvider": "TestShib"
'
,
login_response
.
content
)
self
.
assertIn
(
'
"errorMessage"
: null'
,
login_response
.
content
)
# Now the user enters their username and password.
# The AJAX on the page will log them in:
ajax_login_response
=
self
.
client
.
post
(
...
...
@@ -183,7 +190,7 @@ class TestShibIntegrationTest(testutil.SAMLTestCase):
response
=
self
.
client
.
get
(
self
.
login_page_url
)
self
.
assertEqual
(
response
.
status_code
,
200
)
self
.
assertIn
(
"TestShib"
,
response
.
content
)
self
.
assertIn
(
TPA_TESTSHIB_LOGIN_URL
.
replace
(
'&'
,
'&'
),
response
.
content
)
self
.
assertIn
(
json
.
dumps
(
TPA_TESTSHIB_LOGIN_URL
,
cls
=
EscapedEdxJSONEncoder
),
response
.
content
)
return
response
def
_check_register_page
(
self
):
...
...
@@ -191,7 +198,7 @@ class TestShibIntegrationTest(testutil.SAMLTestCase):
response
=
self
.
client
.
get
(
self
.
register_page_url
)
self
.
assertEqual
(
response
.
status_code
,
200
)
self
.
assertIn
(
"TestShib"
,
response
.
content
)
self
.
assertIn
(
TPA_TESTSHIB_REGISTER_URL
.
replace
(
'&'
,
'&'
),
response
.
content
)
self
.
assertIn
(
json
.
dumps
(
TPA_TESTSHIB_REGISTER_URL
,
cls
=
EscapedEdxJSONEncoder
),
response
.
content
)
return
response
def
_configure_testshib_provider
(
self
,
**
kwargs
):
...
...
common/static/js/spec/edx.utils.validate_spec.js
View file @
d2a47908
describe
(
'edx.utils.validate'
,
function
(
)
{
;(
function
(
define
)
{
'use strict'
;
var
fixture
=
null
,
field
=
null
,
result
=
null
,
MIN_LENGTH
=
2
,
MAX_LENGTH
=
20
,
VALID_STRING
=
'xsy_is_awesome'
,
SHORT_STRING
=
'x'
,
LONG_STRING
=
'xsy_is_way_too_awesome'
,
EMAIL_ERROR_FRAGMENT
=
'formatted'
,
MIN_ERROR_FRAGMENT
=
'least'
,
MAX_ERROR_FRAGMENT
=
'up to'
,
REQUIRED_ERROR_FRAGMENT
=
'Please enter your'
,
CUSTOM_MESSAGE
=
'custom message'
;
var
createFixture
=
function
(
type
,
name
,
required
,
minlength
,
maxlength
,
value
)
{
setFixtures
(
'<input id="field" type='
+
type
+
'>'
);
field
=
$
(
'#field'
);
field
.
prop
(
'required'
,
required
);
field
.
attr
({
name
:
name
,
minlength
:
minlength
,
maxlength
:
maxlength
,
value
:
value
define
([
'jquery'
,
'js/utils/edx.utils.validate'
],
function
(
$
)
{
var
fixture
=
null
,
field
=
null
,
result
=
null
,
MIN_LENGTH
=
2
,
MAX_LENGTH
=
20
,
VALID_STRING
=
'xsy_is_awesome'
,
SHORT_STRING
=
'x'
,
LONG_STRING
=
'xsy_is_way_too_awesome'
,
EMAIL_ERROR_FRAGMENT
=
'formatted'
,
MIN_ERROR_FRAGMENT
=
'least'
,
MAX_ERROR_FRAGMENT
=
'up to'
,
REQUIRED_ERROR_FRAGMENT
=
'Please enter your'
,
CUSTOM_MESSAGE
=
'custom message'
;
var
createFixture
=
function
(
type
,
name
,
required
,
minlength
,
maxlength
,
value
)
{
setFixtures
(
'<input id="field" type='
+
type
+
'>'
);
field
=
$
(
'#field'
);
field
.
prop
(
'required'
,
required
);
field
.
attr
({
name
:
name
,
minlength
:
minlength
,
maxlength
:
maxlength
,
value
:
value
});
};
var
expectValid
=
function
()
{
result
=
edx
.
utils
.
validate
(
field
);
expect
(
result
.
isValid
).
toBe
(
true
);
};
var
expectInvalid
=
function
(
errorFragment
)
{
result
=
edx
.
utils
.
validate
(
field
);
expect
(
result
.
isValid
).
toBe
(
false
);
expect
(
result
.
message
).
toMatch
(
errorFragment
);
};
it
(
'succeeds if an optional field is left blank'
,
function
()
{
createFixture
(
'text'
,
'username'
,
false
,
MIN_LENGTH
,
MAX_LENGTH
,
''
);
expectValid
();
});
};
var
expectValid
=
function
()
{
result
=
edx
.
utils
.
validate
(
field
);
expect
(
result
.
isValid
).
toBe
(
true
);
};
var
expectInvalid
=
function
(
errorFragment
)
{
result
=
edx
.
utils
.
validate
(
field
);
expect
(
result
.
isValid
).
toBe
(
false
);
expect
(
result
.
message
).
toMatch
(
errorFragment
);
};
it
(
'succeeds if an optional field is left blank'
,
function
()
{
createFixture
(
'text'
,
'username'
,
false
,
MIN_LENGTH
,
MAX_LENGTH
,
''
);
expectValid
();
});
it
(
'succeeds if a required field is provided a valid value'
,
function
()
{
createFixture
(
'text'
,
'username'
,
true
,
MIN_LENGTH
,
MAX_LENGTH
,
VALID_STRING
);
expectValid
();
});
it
(
'succeeds if a required field is provided a valid value'
,
function
()
{
createFixture
(
'text'
,
'username'
,
true
,
MIN_LENGTH
,
MAX_LENGTH
,
VALID_STRING
);
expectValid
();
});
it
(
'fails if a required field is left blank'
,
function
()
{
createFixture
(
'text'
,
'username'
,
true
,
MIN_LENGTH
,
MAX_LENGTH
,
''
);
expectInvalid
(
REQUIRED_ERROR_FRAGMENT
);
});
it
(
'fails if a required field is left blank'
,
function
()
{
createFixture
(
'text'
,
'username'
,
true
,
MIN_LENGTH
,
MAX_LENGTH
,
''
);
expectInvalid
(
REQUIRED_ERROR_FRAGMENT
);
});
it
(
'fails if a field is provided a value below its minimum character limit'
,
function
()
{
createFixture
(
'text'
,
'username'
,
false
,
MIN_LENGTH
,
MAX_LENGTH
,
SHORT_STRING
);
it
(
'fails if a field is provided a value below its minimum character limit'
,
function
()
{
createFixture
(
'text'
,
'username'
,
false
,
MIN_LENGTH
,
MAX_LENGTH
,
SHORT_STRING
);
// Verify optional field behavior
expectInvalid
(
MIN_ERROR_FRAGMENT
);
// Verify optional field behavior
expectInvalid
(
MIN_ERROR_FRAGMENT
);
// Verify required field behavior
field
.
prop
(
'required'
,
true
);
expectInvalid
(
MIN_ERROR_FRAGMENT
);
});
// Verify required field behavior
field
.
prop
(
'required'
,
true
);
expectInvalid
(
MIN_ERROR_FRAGMENT
);
});
it
(
'succeeds if a field with no minimum character limit is provided a value below its maximum character limit'
,
function
()
{
createFixture
(
'text'
,
'username'
,
false
,
null
,
MAX_LENGTH
,
SHORT_STRING
);
it
(
'succeeds if a field with no minimum character limit is provided a value below its maximum character limit'
,
function
()
{
createFixture
(
'text'
,
'username'
,
false
,
null
,
MAX_LENGTH
,
SHORT_STRING
);
// Verify optional field behavior
expectValid
();
// Verify optional field behavior
expectValid
();
// Verify required field behavior
field
.
prop
(
'required'
,
true
);
expectValid
();
});
// Verify required field behavior
field
.
prop
(
'required'
,
true
);
expectValid
();
});
it
(
'fails if a required field with no minimum character limit is left blank'
,
function
()
{
createFixture
(
'text'
,
'username'
,
true
,
null
,
MAX_LENGTH
,
''
);
expectInvalid
(
REQUIRED_ERROR_FRAGMENT
);
});
it
(
'fails if a required field with no minimum character limit is left blank'
,
function
()
{
createFixture
(
'text'
,
'username'
,
true
,
null
,
MAX_LENGTH
,
''
);
expectInvalid
(
REQUIRED_ERROR_FRAGMENT
);
});
it
(
'fails if a field is provided a value above its maximum character limit'
,
function
()
{
createFixture
(
'text'
,
'username'
,
false
,
MIN_LENGTH
,
MAX_LENGTH
,
LONG_STRING
);
it
(
'fails if a field is provided a value above its maximum character limit'
,
function
()
{
createFixture
(
'text'
,
'username'
,
false
,
MIN_LENGTH
,
MAX_LENGTH
,
LONG_STRING
);
// Verify optional field behavior
expectInvalid
(
MAX_ERROR_FRAGMENT
);
// Verify optional field behavior
expectInvalid
(
MAX_ERROR_FRAGMENT
);
// Verify required field behavior
field
.
prop
(
'required'
,
true
);
expectInvalid
(
MAX_ERROR_FRAGMENT
);
});
// Verify required field behavior
field
.
prop
(
'required'
,
true
);
expectInvalid
(
MAX_ERROR_FRAGMENT
);
});
it
(
'succeeds if a field with no maximum character limit is provided a value above its minimum character limit'
,
function
()
{
createFixture
(
'text'
,
'username'
,
false
,
MIN_LENGTH
,
null
,
LONG_STRING
);
it
(
'succeeds if a field with no maximum character limit is provided a value above its minimum character limit'
,
function
()
{
createFixture
(
'text'
,
'username'
,
false
,
MIN_LENGTH
,
null
,
LONG_STRING
);
// Verify optional field behavior
expectValid
();
// Verify optional field behavior
expectValid
();
// Verify required field behavior
field
.
prop
(
'required'
,
true
);
expectValid
();
});
// Verify required field behavior
field
.
prop
(
'required'
,
true
);
expectValid
();
});
it
(
'succeeds if a field with no character limits is provided a value'
,
function
()
{
createFixture
(
'text'
,
'username'
,
false
,
null
,
null
,
VALID_STRING
);
it
(
'succeeds if a field with no character limits is provided a value'
,
function
()
{
createFixture
(
'text'
,
'username'
,
false
,
null
,
null
,
VALID_STRING
);
// Verify optional field behavior
expectValid
();
// Verify optional field behavior
expectValid
();
// Verify required field behavior
field
.
prop
(
'required'
,
true
);
expectValid
();
});
// Verify required field behavior
field
.
prop
(
'required'
,
true
);
expectValid
();
});
it
(
'fails if an email field is provided an invalid address'
,
function
()
{
createFixture
(
'email'
,
'email'
,
false
,
MIN_LENGTH
,
MAX_LENGTH
,
'localpart'
);
it
(
'fails if an email field is provided an invalid address'
,
function
()
{
createFixture
(
'email'
,
'email'
,
false
,
MIN_LENGTH
,
MAX_LENGTH
,
'localpart'
);
// Verify optional field behavior
expectInvalid
(
EMAIL_ERROR_FRAGMENT
);
// Verify optional field behavior
expectInvalid
(
EMAIL_ERROR_FRAGMENT
);
// Verify required field behavior
field
.
prop
(
'required'
,
false
);
expectInvalid
(
EMAIL_ERROR_FRAGMENT
);
});
// Verify required field behavior
field
.
prop
(
'required'
,
false
);
expectInvalid
(
EMAIL_ERROR_FRAGMENT
);
});
it
(
'succeeds if an email field is provided a valid address'
,
function
()
{
createFixture
(
'email'
,
'email'
,
false
,
MIN_LENGTH
,
MAX_LENGTH
,
'localpart@label.tld'
);
it
(
'succeeds if an email field is provided a valid address'
,
function
()
{
createFixture
(
'email'
,
'email'
,
false
,
MIN_LENGTH
,
MAX_LENGTH
,
'localpart@label.tld'
);
// Verify optional field behavior
expectValid
();
// Verify optional field behavior
expectValid
();
// Verify required field behavior
field
.
prop
(
'required'
,
true
);
expectValid
();
});
// Verify required field behavior
field
.
prop
(
'required'
,
true
);
expectValid
();
});
it
(
'succeeds if a checkbox is optional, or required and checked, but fails if a required checkbox is unchecked'
,
function
()
{
createFixture
(
'checkbox'
,
'checkbox'
,
false
,
null
,
null
,
'value'
);
it
(
'succeeds if a checkbox is optional, or required and checked, but fails if a required checkbox is unchecked'
,
function
()
{
createFixture
(
'checkbox'
,
'checkbox'
,
false
,
null
,
null
,
'value'
);
// Optional, unchecked
expectValid
();
// Optional, unchecked
expectValid
();
// Optional, checked
field
.
prop
(
'checked'
,
true
);
expectValid
();
// Optional, checked
field
.
prop
(
'checked'
,
true
);
expectValid
();
// Required, checked
field
.
prop
(
'required'
,
true
);
expectValid
();
// Required, checked
field
.
prop
(
'required'
,
true
);
expectValid
();
// Required, unchecked
field
.
prop
(
'checked'
,
false
);
expectInvalid
(
REQUIRED_ERROR_FRAGMENT
);
});
// Required, unchecked
field
.
prop
(
'checked'
,
false
);
expectInvalid
(
REQUIRED_ERROR_FRAGMENT
);
});
it
(
'succeeds if a select is optional, or required and default is selected, but fails if a required select has the default option selected'
,
function
()
{
var
select
=
[
'<select id="dropdown" name="country">'
,
'<option value="" data-isdefault="true">Please select a country</option>'
,
'<option value="BE">Belgium</option>'
,
'<option value="DE">Germany</option>'
,
'</select>'
].
join
(
''
);
it
(
'succeeds if a select is optional, or required and default is selected, but fails if a required select has the default option selected'
,
function
()
{
var
select
=
[
'<select id="dropdown" name="country">'
,
'<option value="" data-isdefault="true">Please select a country</option>'
,
'<option value="BE">Belgium</option>'
,
'<option value="DE">Germany</option>'
,
'</select>'
].
join
(
''
);
setFixtures
(
select
);
setFixtures
(
select
);
field
=
$
(
'#dropdown'
);
field
=
$
(
'#dropdown'
);
// Optional
expectValid
();
// Optional
expectValid
();
// Required, default text selected
field
.
attr
(
'required'
,
true
);
expectInvalid
(
REQUIRED_ERROR_FRAGMENT
);
// Required, default text selected
field
.
attr
(
'required'
,
true
);
expectInvalid
(
REQUIRED_ERROR_FRAGMENT
);
// Required, country selected
field
.
val
(
'BE'
);
expectValid
();
});
// Required, country selected
field
.
val
(
'BE'
);
expectValid
();
});
it
(
'returns a custom error message if an invalid field has one attached'
,
function
()
{
// Create a blank required field
createFixture
(
'text'
,
'username'
,
true
,
MIN_LENGTH
,
MAX_LENGTH
,
''
);
it
(
'returns a custom error message if an invalid field has one attached'
,
function
()
{
// Create a blank required field
createFixture
(
'text'
,
'username'
,
true
,
MIN_LENGTH
,
MAX_LENGTH
,
''
);
// Attach a custom error message to the field
field
.
data
(
'errormsg-required'
,
CUSTOM_MESSAGE
);
// Attach a custom error message to the field
field
.
data
(
'errormsg-required'
,
CUSTOM_MESSAGE
);
expectInvalid
(
CUSTOM_MESSAGE
);
expectInvalid
(
CUSTOM_MESSAGE
);
});
});
});
})
.
call
(
this
,
define
||
RequireJS
.
define
)
;
common/static/js/utils/edx.utils.validate.js
View file @
d2a47908
var
edx
=
edx
||
{};
(
function
(
$
,
_
,
_s
,
gettext
)
{
;(
function
(
define
)
{
'use strict'
;
define
([
'jquery'
,
'underscore'
,
'underscore.string'
,
'gettext'
],
function
(
$
,
_
,
_s
,
gettext
)
{
var
utils
;
/* Mix non-conflicting functions from underscore.string
* (all but include, contains, and reverse) into the
* Underscore namespace. In practice, this mixin is done
* by the access view, but doing it here helps keep the
* utility self-contained.
*/
if
(
_
.
isUndefined
(
_s
))
{
_s
=
_
.
str
;
}
_
.
mixin
(
_s
.
exports
()
);
utils
=
(
function
(){
var
_fn
=
{
validate
:
{
msg
:
{
email
:
'<li><%- gettext("The email address you
\'
ve provided isn
\'
t formatted correctly.") %></li>'
,
min
:
'<li><%- _.sprintf( gettext("%(field)s must have at least %(count)d characters."), context ) %></li>'
,
max
:
'<li><%- _.sprintf( gettext("%(field)s can only contain up to %(count)d characters."), context ) %></li>'
,
required
:
'<li><%- _.sprintf( gettext("Please enter your %(field)s."), context ) %></li>'
,
custom
:
'<li><%= content %></li>'
},
/* Mix non-conflicting functions from underscore.string
* (all but include, contains, and reverse) into the
* Underscore namespace. In practice, this mixin is done
* by the access view, but doing it here helps keep the
* utility self-contained.
*/
_
.
mixin
(
_
.
str
.
exports
()
);
edx
.
utils
=
edx
.
utils
||
{};
var
utils
=
(
function
(){
var
_fn
=
{
validate
:
{
msg
:
{
email
:
'<li><%- gettext("The email address you
\'
ve provided isn
\'
t formatted correctly.") %></li>'
,
min
:
'<li><%- _.sprintf( gettext("%(field)s must have at least %(count)d characters."), context ) %></li>'
,
max
:
'<li><%- _.sprintf( gettext("%(field)s can only contain up to %(count)d characters."), context ) %></li>'
,
required
:
'<li><%- _.sprintf( gettext("Please enter your %(field)s."), context ) %></li>'
,
custom
:
'<li><%= content %></li>'
},
field
:
function
(
el
)
{
var
$el
=
$
(
el
),
required
=
true
,
min
=
true
,
max
=
true
,
email
=
true
,
response
=
{},
isBlank
=
_fn
.
validate
.
isBlank
(
$el
);
if
(
_fn
.
validate
.
isRequired
(
$el
)
)
{
if
(
isBlank
)
{
required
=
false
;
}
else
{
field
:
function
(
el
)
{
var
$el
=
$
(
el
),
required
=
true
,
min
=
true
,
max
=
true
,
email
=
true
,
response
=
{},
isBlank
=
_fn
.
validate
.
isBlank
(
$el
);
if
(
_fn
.
validate
.
isRequired
(
$el
)
)
{
if
(
isBlank
)
{
required
=
false
;
}
else
{
min
=
_fn
.
validate
.
str
.
minlength
(
$el
);
max
=
_fn
.
validate
.
str
.
maxlength
(
$el
);
email
=
_fn
.
validate
.
email
.
valid
(
$el
);
}
}
else
if
(
!
isBlank
)
{
min
=
_fn
.
validate
.
str
.
minlength
(
$el
);
max
=
_fn
.
validate
.
str
.
maxlength
(
$el
);
email
=
_fn
.
validate
.
email
.
valid
(
$el
);
}
}
else
if
(
!
isBlank
)
{
min
=
_fn
.
validate
.
str
.
minlength
(
$el
);
max
=
_fn
.
validate
.
str
.
maxlength
(
$el
);
email
=
_fn
.
validate
.
email
.
valid
(
$el
);
}
response
.
isValid
=
required
&&
min
&&
max
&&
email
;
response
.
isValid
=
required
&&
min
&&
max
&&
email
;
if
(
!
response
.
isValid
)
{
_fn
.
validate
.
removeDefault
(
$el
);
if
(
!
response
.
isValid
)
{
_fn
.
validate
.
removeDefault
(
$el
);
response
.
message
=
_fn
.
validate
.
getMessage
(
$el
,
{
required
:
required
,
min
:
min
,
max
:
max
,
email
:
email
});
}
response
.
message
=
_fn
.
validate
.
getMessage
(
$el
,
{
required
:
required
,
min
:
min
,
max
:
max
,
email
:
email
});
}
return
response
;
},
return
response
;
},
str
:
{
minlength
:
function
(
$el
)
{
var
min
=
$el
.
attr
(
'minlength'
)
||
0
;
str
:
{
minlength
:
function
(
$el
)
{
var
min
=
$el
.
attr
(
'minlength'
)
||
0
;
return
min
<=
$el
.
val
().
length
;
},
return
min
<=
$el
.
val
().
length
;
maxlength
:
function
(
$el
)
{
var
max
=
$el
.
attr
(
'maxlength'
)
||
false
;
return
(
!!
max
)
?
max
>=
$el
.
val
().
length
:
true
;
}
},
maxlength
:
function
(
$el
)
{
var
max
=
$el
.
attr
(
'maxlength'
)
||
false
;
isRequired
:
function
(
$el
)
{
return
$el
.
attr
(
'required'
);
},
return
(
!!
max
)
?
max
>=
$el
.
val
().
length
:
true
;
}
},
isRequired
:
function
(
$el
)
{
return
$el
.
attr
(
'required'
);
},
isBlank
:
function
(
$el
)
{
var
type
=
$el
.
attr
(
'type'
),
isBlank
;
if
(
type
===
'checkbox'
)
{
isBlank
=
!
$el
.
prop
(
'checked'
);
}
else
if
(
type
===
'select'
)
{
isBlank
=
(
$el
.
data
(
'isdefault'
)
===
true
);
}
else
{
isBlank
=
!
$el
.
val
();
}
isBlank
:
function
(
$el
)
{
var
type
=
$el
.
attr
(
'type'
),
isBlank
;
return
isBlank
;
},
email
:
{
// This is the same regex used to validate email addresses in Django 1.4
regex
:
new
RegExp
(
[
'(^[-!#$%&
\'
*+/=?^_`{}|~0-9A-Z]+(
\\
.[-!#$%&
\'
*+/=?^_`{}|~0-9A-Z]+)*'
,
'|^"([
\\
001-
\\
010
\\
013
\\
014
\\
016-
\\
037!#-
\\
[
\\
]-
\\
177]|
\\\\
[
\\
001-
\\
011
\\
013
\\
014
\\
016-
\\
177])*"'
,
')@((?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?
\\
.)+[A-Z]{2,6}
\\
.?$)'
,
'|
\\
[(25[0-5]|2[0-4]
\\
d|[0-1]?
\\
d?
\\
d)(
\\
.(25[0-5]|2[0-4]
\\
d|[0-1]?
\\
d?
\\
d)){3}
\\
]$'
].
join
(
''
),
'i'
),
valid
:
function
(
$el
)
{
return
$el
.
attr
(
'type'
)
===
'email'
?
_fn
.
validate
.
email
.
format
(
$el
.
val
()
)
:
true
;
if
(
type
===
'checkbox'
)
{
isBlank
=
!
$el
.
prop
(
'checked'
);
}
else
if
(
type
===
'select'
)
{
isBlank
=
(
$el
.
data
(
'isdefault'
)
===
true
);
}
else
{
isBlank
=
!
$el
.
val
();
}
return
isBlank
;
},
format
:
function
(
str
)
{
return
_fn
.
validate
.
email
.
regex
.
test
(
str
);
}
},
getLabel
:
function
(
id
)
{
// Extract the field label, remove the asterisk (if it appears) and any extra whitespace
return
$
(
"label[for="
+
id
+
"]"
).
text
().
split
(
"*"
)[
0
].
trim
();
},
getMessage
:
function
(
$el
,
tests
)
{
var
txt
=
[],
tpl
,
label
,
obj
,
customMsg
;
_
.
each
(
tests
,
function
(
value
,
key
)
{
if
(
!
value
)
{
label
=
_fn
.
validate
.
getLabel
(
$el
.
attr
(
'id'
)
);
customMsg
=
$el
.
data
(
'errormsg-'
+
key
)
||
false
;
// If the field has a custom error msg attached, use it
if
(
customMsg
)
{
tpl
=
_fn
.
validate
.
msg
.
custom
;
obj
=
{
content
:
customMsg
};
}
else
{
tpl
=
_fn
.
validate
.
msg
[
key
];
email
:
{
// This is the same regex used to validate email addresses in Django 1.4
regex
:
new
RegExp
(
[
'(^[-!#$%&
\'
*+/=?^_`{}|~0-9A-Z]+(
\\
.[-!#$%&
\'
*+/=?^_`{}|~0-9A-Z]+)*'
,
'|^"([
\\
001-
\\
010
\\
013
\\
014
\\
016-
\\
037!#-
\\
[
\\
]-
\\
177]|
\\\\
[
\\
001-
\\
011
\\
013
\\
014
\\
016-
\\
177])*"'
,
')@((?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?
\\
.)+[A-Z]{2,6}
\\
.?$)'
,
'|
\\
[(25[0-5]|2[0-4]
\\
d|[0-1]?
\\
d?
\\
d)(
\\
.(25[0-5]|2[0-4]
\\
d|[0-1]?
\\
d?
\\
d)){3}
\\
]$'
].
join
(
''
),
'i'
),
valid
:
function
(
$el
)
{
return
$el
.
attr
(
'type'
)
===
'email'
?
_fn
.
validate
.
email
.
format
(
$el
.
val
()
)
:
true
;
},
format
:
function
(
str
)
{
return
_fn
.
validate
.
email
.
regex
.
test
(
str
);
}
},
obj
=
{
// We pass the context object to the template so that
// we can perform variable interpolation using sprintf
context
:
{
field
:
label
}
};
getLabel
:
function
(
id
)
{
// Extract the field label, remove the asterisk (if it appears) and any extra whitespace
return
$
(
"label[for="
+
id
+
"]"
).
text
().
split
(
"*"
)[
0
].
trim
();
},
if
(
key
===
'min'
)
{
obj
.
context
.
count
=
parseInt
(
$el
.
attr
(
'minlength'
),
10
);
}
else
if
(
key
===
'max'
)
{
obj
.
context
.
count
=
parseInt
(
$el
.
attr
(
'maxlength'
),
10
);
getMessage
:
function
(
$el
,
tests
)
{
var
txt
=
[],
tpl
,
label
,
obj
,
customMsg
;
_
.
each
(
tests
,
function
(
value
,
key
)
{
if
(
!
value
)
{
label
=
_fn
.
validate
.
getLabel
(
$el
.
attr
(
'id'
)
);
customMsg
=
$el
.
data
(
'errormsg-'
+
key
)
||
false
;
// If the field has a custom error msg attached, use it
if
(
customMsg
)
{
tpl
=
_fn
.
validate
.
msg
.
custom
;
obj
=
{
content
:
customMsg
};
}
else
{
tpl
=
_fn
.
validate
.
msg
[
key
];
obj
=
{
// We pass the context object to the template so that
// we can perform variable interpolation using sprintf
context
:
{
field
:
label
}
};
if
(
key
===
'min'
)
{
obj
.
context
.
count
=
parseInt
(
$el
.
attr
(
'minlength'
),
10
);
}
else
if
(
key
===
'max'
)
{
obj
.
context
.
count
=
parseInt
(
$el
.
attr
(
'maxlength'
),
10
);
}
}
}
txt
.
push
(
_
.
template
(
tpl
,
obj
)
);
}
});
txt
.
push
(
_
.
template
(
tpl
,
obj
)
);
}
});
return
txt
.
join
(
' '
);
},
return
txt
.
join
(
' '
);
},
// Removes the default HTML5 validation pop-up
removeDefault
:
function
(
$el
)
{
if
(
$el
.
setCustomValidity
)
{
$el
.
setCustomValidity
(
' '
);
// Removes the default HTML5 validation pop-up
removeDefault
:
function
(
$el
)
{
if
(
$el
.
setCustomValidity
)
{
$el
.
setCustomValidity
(
' '
);
}
}
}
}
};
return
{
validate
:
_fn
.
validate
.
field
};
};
})();
return
{
validate
:
_fn
.
validate
.
field
};
edx
.
utils
.
validate
=
utils
.
validate
;
})()
;
})(
jQuery
,
_
,
_
.
str
,
gettext
);
return
utils
;
});
}).
call
(
this
,
define
||
RequireJS
.
define
);
lms/djangoapps/student_account/test/test_views.py
View file @
d2a47908
...
...
@@ -8,7 +8,6 @@ import json
import
mock
import
ddt
import
markupsafe
from
django.conf
import
settings
from
django.core.urlresolvers
import
reverse
from
django.core
import
mail
...
...
@@ -20,6 +19,7 @@ from django.test.client import RequestFactory
from
openedx.core.djangoapps.user_api.accounts.api
import
activate_account
,
create_account
from
openedx.core.djangoapps.user_api.accounts
import
EMAIL_MAX_LENGTH
from
openedx.core.lib.json_utils
import
EscapedEdxJSONEncoder
from
student.tests.factories
import
UserFactory
from
student_account.views
import
account_settings_context
from
third_party_auth.tests.testutil
import
simulate_running_pipeline
,
ThirdPartyAuthTestMixin
...
...
@@ -223,7 +223,7 @@ class StudentAccountLoginAndRegistrationTest(ThirdPartyAuthTestMixin, UrlResetMi
@ddt.unpack
def
test_login_and_registration_form
(
self
,
url_name
,
initial_mode
):
response
=
self
.
client
.
get
(
reverse
(
url_name
))
expected_data
=
u"data-initial-mode=
\"
{mode}
\"
"
.
format
(
mode
=
initial_mode
)
expected_data
=
'"initial_mode": "{mode}"'
.
format
(
mode
=
initial_mode
)
self
.
assertContains
(
response
,
expected_data
)
@ddt.data
(
"signin_user"
,
"register_user"
)
...
...
@@ -255,6 +255,7 @@ class StudentAccountLoginAndRegistrationTest(ThirdPartyAuthTestMixin, UrlResetMi
# that preserves the querystring params
with
mock
.
patch
.
dict
(
settings
.
FEATURES
,
{
'IS_EDX_DOMAIN'
:
is_edx_domain
}):
response
=
self
.
client
.
get
(
reverse
(
url_name
),
params
)
expected_url
=
'/login?{}'
.
format
(
self
.
_finish_auth_url_param
(
params
+
[(
'next'
,
'/dashboard'
)]))
self
.
assertContains
(
response
,
expected_url
)
...
...
@@ -330,7 +331,7 @@ class StudentAccountLoginAndRegistrationTest(ThirdPartyAuthTestMixin, UrlResetMi
def
test_hinted_login
(
self
):
params
=
[(
"next"
,
"/courses/something/?tpa_hint=oa2-google-oauth2"
)]
response
=
self
.
client
.
get
(
reverse
(
'signin_user'
),
params
)
self
.
assertContains
(
response
,
"data-third-party-auth-hint='oa2-google-oauth2'"
)
self
.
assertContains
(
response
,
'"third_party_auth_hint": "oa2-google-oauth2"'
)
@override_settings
(
SITE_NAME
=
settings
.
MICROSITE_TEST_HOSTNAME
)
def
test_microsite_uses_old_login_page
(
self
):
...
...
@@ -358,17 +359,17 @@ class StudentAccountLoginAndRegistrationTest(ThirdPartyAuthTestMixin, UrlResetMi
finish_auth_url
=
None
if
current_backend
:
finish_auth_url
=
reverse
(
"social:complete"
,
kwargs
=
{
"backend"
:
current_backend
})
+
"?"
auth_info
=
markupsafe
.
escape
(
json
.
dumps
({
"currentProvider"
:
current_provider
,
"providers"
:
providers
,
"secondaryProviders"
:
[],
"finishAuthUrl"
:
finish_auth_url
,
"errorMessage"
:
None
,
})
)
expected_data
=
u"data-third-party-auth='{auth_info}'"
.
format
(
auth_info
=
{
"currentProvider"
:
current_provider
,
"providers"
:
providers
,
"secondaryProviders"
:
[],
"finishAuthUrl"
:
finish_auth_url
,
"errorMessage"
:
None
,
}
auth_info
=
json
.
dumps
(
auth_info
,
cls
=
EscapedEdxJSONEncoder
)
expected_data
=
'"third_party_auth": {auth_info}'
.
format
(
auth_info
=
auth_info
)
...
...
lms/djangoapps/student_account/views.py
View file @
d2a47908
...
...
@@ -95,22 +95,25 @@ def login_and_registration_form(request, initial_mode="login"):
# Otherwise, render the combined login/registration page
context
=
{
'login_redirect_url'
:
redirect_to
,
# This gets added to the query string of the "Sign In" button in the header
'disable_courseware_js'
:
True
,
'initial_mode'
:
initial_mode
,
'third_party_auth'
:
json
.
dumps
(
_third_party_auth_context
(
request
,
redirect_to
)),
'third_party_auth_hint'
:
third_party_auth_hint
or
''
,
'platform_name'
:
settings
.
PLATFORM_NAME
,
'data'
:
{
'login_redirect_url'
:
redirect_to
,
'initial_mode'
:
initial_mode
,
'third_party_auth'
:
_third_party_auth_context
(
request
,
redirect_to
),
'third_party_auth_hint'
:
third_party_auth_hint
or
''
,
'platform_name'
:
settings
.
PLATFORM_NAME
,
# Include form descriptions retrieved from the user API.
# We could have the JS client make these requests directly,
# but we include them in the initial page load to avoid
# the additional round-trip to the server.
'login_form_desc'
:
json
.
loads
(
form_descriptions
[
'login'
]),
'registration_form_desc'
:
json
.
loads
(
form_descriptions
[
'registration'
]),
'password_reset_form_desc'
:
json
.
loads
(
form_descriptions
[
'password_reset'
]),
},
'login_redirect_url'
:
redirect_to
,
# This gets added to the query string of the "Sign In" button in header
'responsive'
:
True
,
'allow_iframing'
:
True
,
# Include form descriptions retrieved from the user API.
# We could have the JS client make these requests directly,
# but we include them in the initial page load to avoid
# the additional round-trip to the server.
'login_form_desc'
:
form_descriptions
[
'login'
],
'registration_form_desc'
:
form_descriptions
[
'registration'
],
'password_reset_form_desc'
:
form_descriptions
[
'password_reset'
],
'disable_courseware_js'
:
True
,
}
return
render_to_response
(
'student_account/login_and_register.html'
,
context
)
...
...
lms/envs/common.py
View file @
d2a47908
...
...
@@ -1303,26 +1303,6 @@ instructor_dash_js = (
sorted
(
rooted_glob
(
PROJECT_ROOT
/
'static'
,
'js/instructor_dashboard/**/*.js'
))
)
# JavaScript used by the student account and profile pages
# These are not courseware, so they do not need many of the courseware-specific
# JavaScript modules.
student_account_js
=
[
'js/utils/edx.utils.validate.js'
,
'js/sticky_filter.js'
,
'js/query-params.js'
,
'js/student_account/models/LoginModel.js'
,
'js/student_account/models/RegisterModel.js'
,
'js/student_account/models/PasswordResetModel.js'
,
'js/student_account/views/FormView.js'
,
'js/student_account/views/LoginView.js'
,
'js/student_account/views/HintedLoginView.js'
,
'js/student_account/views/RegisterView.js'
,
'js/student_account/views/PasswordResetView.js'
,
'js/student_account/views/AccessView.js'
,
'js/student_account/views/InstitutionLoginView.js'
,
'js/student_account/accessApp.js'
,
]
verify_student_js
=
[
'js/sticky_filter.js'
,
'js/query-params.js'
,
...
...
@@ -1574,10 +1554,6 @@ PIPELINE_JS = {
'source_filenames'
:
dashboard_js
,
'output_filename'
:
'js/dashboard.js'
},
'student_account'
:
{
'source_filenames'
:
student_account_js
,
'output_filename'
:
'js/student_account.js'
},
'verify_student'
:
{
'source_filenames'
:
verify_student_js
,
'output_filename'
:
'js/verify_student.js'
...
...
lms/static/js/spec/main.js
View file @
d2a47908
...
...
@@ -75,16 +75,6 @@
'js/views/file_uploader'
:
'js/views/file_uploader'
,
'js/views/notification'
:
'js/views/notification'
,
'js/student_account/account'
:
'js/student_account/account'
,
'js/student_account/views/FormView'
:
'js/student_account/views/FormView'
,
'js/student_account/models/LoginModel'
:
'js/student_account/models/LoginModel'
,
'js/student_account/views/LoginView'
:
'js/student_account/views/LoginView'
,
'js/student_account/views/InstitutionLoginView'
:
'js/student_account/views/InstitutionLoginView'
,
'js/student_account/models/PasswordResetModel'
:
'js/student_account/models/PasswordResetModel'
,
'js/student_account/views/PasswordResetView'
:
'js/student_account/views/PasswordResetView'
,
'js/student_account/models/RegisterModel'
:
'js/student_account/models/RegisterModel'
,
'js/student_account/views/RegisterView'
:
'js/student_account/views/RegisterView'
,
'js/student_account/views/AccessView'
:
'js/student_account/views/AccessView'
,
'js/student_account/views/HintedLoginView'
:
'js/student_account/views/HintedLoginView'
,
'js/student_profile/views/learner_profile_fields'
:
'js/student_profile/views/learner_profile_fields'
,
'js/student_profile/views/learner_profile_factory'
:
'js/student_profile/views/learner_profile_factory'
,
'js/student_profile/views/learner_profile_view'
:
'js/student_profile/views/learner_profile_view'
,
...
...
@@ -94,7 +84,10 @@
'DiscussionModuleView'
:
'xmodule_js/common_static/coffee/src/discussion/discussion_module_view'
,
// edxnotes
'annotator_1.2.9'
:
'xmodule_js/common_static/js/vendor/edxnotes/annotator-full.min'
'annotator_1.2.9'
:
'xmodule_js/common_static/js/vendor/edxnotes/annotator-full.min'
,
// Common edx utils
'js/utils/edx.utils.validate'
:
'xmodule_js/common_static/js/utils/edx.utils.validate'
},
shim
:
{
'gettext'
:
{
...
...
@@ -337,91 +330,6 @@
'js/models/notification'
,
'jquery.fileupload'
]
},
// Student account registration/login
// Loaded explicitly until these are converted to RequireJS
'js/student_account/views/FormView'
:
{
exports
:
'edx.student.account.FormView'
,
deps
:
[
'jquery'
,
'underscore'
,
'backbone'
,
'gettext'
]
},
'js/student_account/models/LoginModel'
:
{
exports
:
'edx.student.account.LoginModel'
,
deps
:
[
'jquery'
,
'jquery.cookie'
,
'backbone'
]
},
'js/student_account/views/LoginView'
:
{
exports
:
'edx.student.account.LoginView'
,
deps
:
[
'jquery'
,
'jquery.url'
,
'underscore'
,
'gettext'
,
'js/student_account/models/LoginModel'
,
'js/student_account/views/FormView'
]
},
'js/student_account/views/InstitutionLoginView'
:
{
exports
:
'edx.student.account.InstitutionLoginView'
,
deps
:
[
'jquery'
,
'underscore'
,
'backbone'
]
},
'js/student_account/models/PasswordResetModel'
:
{
exports
:
'edx.student.account.PasswordResetModel'
,
deps
:
[
'jquery'
,
'jquery.cookie'
,
'backbone'
]
},
'js/student_account/views/PasswordResetView'
:
{
exports
:
'edx.student.account.PasswordResetView'
,
deps
:
[
'jquery'
,
'underscore'
,
'gettext'
,
'js/student_account/models/PasswordResetModel'
,
'js/student_account/views/FormView'
]
},
'js/student_account/models/RegisterModel'
:
{
exports
:
'edx.student.account.RegisterModel'
,
deps
:
[
'jquery'
,
'jquery.cookie'
,
'backbone'
]
},
'js/student_account/views/RegisterView'
:
{
exports
:
'edx.student.account.RegisterView'
,
deps
:
[
'jquery'
,
'jquery.url'
,
'underscore'
,
'gettext'
,
'js/student_account/models/RegisterModel'
,
'js/student_account/views/FormView'
]
},
'js/student_account/views/HintedLoginView'
:
{
exports
:
'edx.student.account.HintedLoginView'
,
deps
:
[
'jquery'
,
'underscore'
,
'backbone'
,
'gettext'
]
},
'js/student_account/views/AccessView'
:
{
exports
:
'edx.student.account.AccessView'
,
deps
:
[
'jquery'
,
'underscore'
,
'backbone'
,
'history'
,
'utility'
,
'js/student_account/views/LoginView'
,
'js/student_account/views/PasswordResetView'
,
'js/student_account/views/RegisterView'
,
'js/student_account/views/InstitutionLoginView'
,
'js/student_account/models/LoginModel'
,
'js/student_account/models/PasswordResetModel'
,
'js/student_account/models/RegisterModel'
,
'js/student_account/views/FormView'
]
},
'js/verify_student/models/verification_model'
:
{
exports
:
'edx.verify_student.VerificationModel'
,
deps
:
[
'jquery'
,
'underscore'
,
'backbone'
,
'jquery.cookie'
]
...
...
@@ -731,6 +639,7 @@
'lms/include/js/spec/instructor_dashboard/student_admin_spec.js'
,
'lms/include/js/spec/student_account/account_spec.js'
,
'lms/include/js/spec/student_account/access_spec.js'
,
'lms/include/js/spec/student_account/logistration_factory_spec.js'
,
'lms/include/js/spec/student_account/finish_auth_spec.js'
,
'lms/include/js/spec/student_account/hinted_login_spec.js'
,
'lms/include/js/spec/student_account/login_spec.js'
,
...
...
lms/static/js/spec/student_account/access_spec.js
View file @
d2a47908
define
([
'jquery'
,
'common/js/spec_helpers/template_helpers'
,
'common/js/spec_helpers/ajax_helpers'
,
'js/student_account/views/AccessView'
,
'js/student_account/views/FormView'
,
'js/student_account/enrollment'
,
'js/student_account/shoppingcart'
,
'js/student_account/emailoptin'
],
function
(
$
,
TemplateHelpers
,
AjaxHelpers
,
AccessView
,
FormView
,
EnrollmentInterface
,
ShoppingCartInterface
)
{
"use strict"
;
;(
function
(
define
)
{
'use strict'
;
define
([
'jquery'
,
'underscore'
,
'backbone'
,
'common/js/spec_helpers/template_helpers'
,
'common/js/spec_helpers/ajax_helpers'
,
'js/student_account/views/AccessView'
,
'js/student_account/views/FormView'
,
'js/student_account/enrollment'
,
'js/student_account/shoppingcart'
,
'js/student_account/emailoptin'
],
function
(
$
,
_
,
Backbone
,
TemplateHelpers
,
AjaxHelpers
,
AccessView
,
FormView
,
EnrollmentInterface
,
ShoppingCartInterface
)
{
describe
(
'edx.student.account.AccessView'
,
function
()
{
var
requests
=
null
,
view
=
null
,
...
...
@@ -24,7 +30,7 @@ define([
required
:
true
,
placeholder
:
'xsy@edx.org'
,
instructions
:
'Enter your email here.'
,
restrictions
:
{}
,
restrictions
:
{}
},
{
name
:
'username'
,
...
...
@@ -49,24 +55,27 @@ define([
THIRD_PARTY_COMPLETE_URL
=
'/auth/complete/provider/'
;
var
ajaxSpyAndInitialize
=
function
(
that
,
mode
,
nextUrl
,
finishAuthUrl
)
{
var
options
=
{
initial_mode
:
mode
,
third_party_auth
:
{
currentProvider
:
null
,
providers
:
[],
secondaryProviders
:
[{
name
:
"provider"
}],
finishAuthUrl
:
finishAuthUrl
},
login_redirect_url
:
nextUrl
,
// undefined for default
platform_name
:
'edX'
,
login_form_desc
:
FORM_DESCRIPTION
,
registration_form_desc
:
FORM_DESCRIPTION
,
password_reset_form_desc
:
FORM_DESCRIPTION
},
$logistrationElement
=
$
(
'#login-and-registration-container'
);
// Spy on AJAX requests
requests
=
AjaxHelpers
.
requests
(
that
);
// Initialize the access view
view
=
new
AccessView
({
mode
:
mode
,
thirdPartyAuth
:
{
currentProvider
:
null
,
providers
:
[],
secondaryProviders
:
[{
name
:
"provider"
}],
finishAuthUrl
:
finishAuthUrl
},
nextUrl
:
nextUrl
,
// undefined for default
platformName
:
'edX'
,
loginFormDesc
:
FORM_DESCRIPTION
,
registrationFormDesc
:
FORM_DESCRIPTION
,
passwordResetFormDesc
:
FORM_DESCRIPTION
});
view
=
new
AccessView
(
_
.
extend
(
options
,
{
el
:
$logistrationElement
}));
// Mock the redirect call
spyOn
(
view
,
'redirect'
).
andCallFake
(
function
()
{}
);
...
...
@@ -92,7 +101,7 @@ define([
};
beforeEach
(
function
()
{
setFixtures
(
'<div id="login-and-registration-container"
></div
>'
);
setFixtures
(
'<div id="login-and-registration-container"
class="login-register" /
>'
);
TemplateHelpers
.
installTemplate
(
'templates/student_account/access'
);
TemplateHelpers
.
installTemplate
(
'templates/student_account/login'
);
TemplateHelpers
.
installTemplate
(
'templates/student_account/register'
);
...
...
@@ -105,6 +114,10 @@ define([
window
.
analytics
=
jasmine
.
createSpyObj
(
'analytics'
,
[
'track'
,
'page'
,
'pageview'
,
'trackLink'
]);
});
afterEach
(
function
()
{
Backbone
.
history
.
stop
();
});
it
(
'can initially display the login form'
,
function
()
{
ajaxSpyAndInitialize
(
this
,
'login'
);
...
...
@@ -217,5 +230,5 @@ define([
});
});
}
);
}
);
}).
call
(
this
,
define
||
RequireJS
.
define
);
lms/static/js/spec/student_account/finish_auth_spec.js
View file @
d2a47908
define
([
'jquery'
,
'utility'
,
'common/js/spec_helpers/ajax_helpers'
,
'js/student_account/views/FinishAuthView'
,
'js/student_account/enrollment'
,
'js/student_account/shoppingcart'
,
'js/student_account/emailoptin'
],
function
(
$
,
utility
,
AjaxHelpers
,
FinishAuthView
,
EnrollmentInterface
,
ShoppingCartInterface
,
EmailOptInInterface
)
{
'use strict'
;
;(
function
(
define
)
{
'use strict'
;
define
([
'jquery'
,
'jquery.url'
,
'utility'
,
'common/js/spec_helpers/ajax_helpers'
,
'js/student_account/views/FinishAuthView'
,
'js/student_account/enrollment'
,
'js/student_account/shoppingcart'
,
'js/student_account/emailoptin'
],
function
(
$
,
url
,
utility
,
AjaxHelpers
,
FinishAuthView
,
EnrollmentInterface
,
ShoppingCartInterface
,
EmailOptInInterface
)
{
describe
(
'FinishAuthView'
,
function
()
{
var
requests
=
null
,
view
=
null
,
...
...
@@ -167,5 +172,5 @@ define([
expect
(
view
.
redirect
).
toHaveBeenCalledWith
(
"/dashboard"
);
});
});
}
);
}
);
}).
call
(
this
,
define
||
RequireJS
.
define
);
lms/static/js/spec/student_account/hinted_login_spec.js
View file @
d2a47908
define
([
'jquery'
,
'underscore'
,
'common/js/spec_helpers/template_helpers'
,
'common/js/spec_helpers/ajax_helpers'
,
'js/student_account/views/HintedLoginView'
,
],
function
(
$
,
_
,
TemplateHelpers
,
AjaxHelpers
,
HintedLoginView
)
{
;(
function
(
define
)
{
'use strict'
;
describe
(
'edx.student.account.HintedLoginView'
,
function
()
{
define
([
'jquery'
,
'underscore'
,
'common/js/spec_helpers/template_helpers'
,
'common/js/spec_helpers/ajax_helpers'
,
'js/student_account/views/HintedLoginView'
],
function
(
$
,
_
,
TemplateHelpers
,
AjaxHelpers
,
HintedLoginView
)
{
var
view
=
null
,
requests
=
null
,
PLATFORM_NAME
=
'edX'
,
THIRD_PARTY_AUTH
=
{
currentProvider
:
null
,
providers
:
[
{
id
:
'oa2-google-oauth2'
,
name
:
'Google'
,
iconClass
:
'fa-google-plus'
,
loginUrl
:
'/auth/login/google-oauth2/?auth_entry=account_login'
,
registerUrl
:
'/auth/login/google-oauth2/?auth_entry=account_register'
},
{
id
:
'oa2-facebook'
,
name
:
'Facebook'
,
iconClass
:
'fa-facebook'
,
loginUrl
:
'/auth/login/facebook/?auth_entry=account_login'
,
registerUrl
:
'/auth/login/facebook/?auth_entry=account_register'
}
],
secondaryProviders
:
[
{
id
:
'saml-harvard'
,
name
:
'Harvard'
,
iconClass
:
'fa-university'
,
loginUrl
:
'/auth/login/tpa-saml/?auth_entry=account_login&idp=harvard'
,
registerUrl
:
'/auth/login/tpa-saml/?auth_entry=account_register&idp=harvard'
}
]
};
describe
(
'edx.student.account.HintedLoginView'
,
function
()
{
var
view
=
null
,
requests
=
null
,
PLATFORM_NAME
=
'edX'
,
THIRD_PARTY_AUTH
=
{
currentProvider
:
null
,
providers
:
[
{
id
:
'oa2-google-oauth2'
,
name
:
'Google'
,
iconClass
:
'fa-google-plus'
,
loginUrl
:
'/auth/login/google-oauth2/?auth_entry=account_login'
,
registerUrl
:
'/auth/login/google-oauth2/?auth_entry=account_register'
},
{
id
:
'oa2-facebook'
,
name
:
'Facebook'
,
iconClass
:
'fa-facebook'
,
loginUrl
:
'/auth/login/facebook/?auth_entry=account_login'
,
registerUrl
:
'/auth/login/facebook/?auth_entry=account_register'
}
],
secondaryProviders
:
[
{
id
:
'saml-harvard'
,
name
:
'Harvard'
,
iconClass
:
'fa-university'
,
loginUrl
:
'/auth/login/tpa-saml/?auth_entry=account_login&idp=harvard'
,
registerUrl
:
'/auth/login/tpa-saml/?auth_entry=account_register&idp=harvard'
}
]
};
var
createHintedLoginView
=
function
(
hintedProvider
)
{
// Initialize the login view
view
=
new
HintedLoginView
({
thirdPartyAuth
:
THIRD_PARTY_AUTH
,
hintedProvider
:
hintedProvider
,
platformName
:
PLATFORM_NAME
});
var
createHintedLoginView
=
function
(
hintedProvider
)
{
// Initialize the login view
view
=
new
HintedLoginView
({
thirdPartyAuth
:
THIRD_PARTY_AUTH
,
hintedProvider
:
hintedProvider
,
platformName
:
PLATFORM_NAME
});
// Mock the redirect call
spyOn
(
view
,
'redirect'
).
andCallFake
(
function
()
{}
);
// Mock the redirect call
spyOn
(
view
,
'redirect'
).
andCallFake
(
function
()
{}
);
view
.
render
();
};
view
.
render
();
};
beforeEach
(
function
()
{
setFixtures
(
'<div id="hinted-login-form"></div>'
);
TemplateHelpers
.
installTemplate
(
'templates/student_account/hinted_login'
);
});
beforeEach
(
function
()
{
setFixtures
(
'<div id="hinted-login-form"></div>'
);
TemplateHelpers
.
installTemplate
(
'templates/student_account/hinted_login'
);
});
it
(
'displays a choice as two buttons'
,
function
()
{
createHintedLoginView
(
"oa2-google-oauth2"
);
it
(
'displays a choice as two buttons'
,
function
()
{
createHintedLoginView
(
"oa2-google-oauth2"
);
expect
(
$
(
'.proceed-button.button-oa2-google-oauth2'
)).
toBeVisible
();
expect
(
$
(
'.form-toggle'
)).
toBeVisible
();
expect
(
$
(
'.proceed-button.button-oa2-facebook'
)).
not
.
toBeVisible
();
});
expect
(
$
(
'.proceed-button.button-oa2-google-oauth2'
)).
toBeVisible
();
expect
(
$
(
'.form-toggle'
)).
toBeVisible
();
expect
(
$
(
'.proceed-button.button-oa2-facebook'
)).
not
.
toBeVisible
();
});
it
(
'works with secondary providers as well'
,
function
()
{
createHintedLoginView
(
"saml-harvard"
);
it
(
'works with secondary providers as well'
,
function
()
{
createHintedLoginView
(
"saml-harvard"
);
expect
(
$
(
'.proceed-button.button-saml-harvard'
)).
toBeVisible
();
expect
(
$
(
'.form-toggle'
)).
toBeVisible
();
expect
(
$
(
'.proceed-button.button-oa2-google-oauth2'
)).
not
.
toBeVisible
();
});
expect
(
$
(
'.proceed-button.button-saml-harvard'
)).
toBeVisible
();
expect
(
$
(
'.form-toggle'
)).
toBeVisible
();
expect
(
$
(
'.proceed-button.button-oa2-google-oauth2'
)).
not
.
toBeVisible
();
});
it
(
'redirects the user to the hinted provider if the user clicks the proceed button'
,
function
()
{
createHintedLoginView
(
"oa2-google-oauth2"
);
it
(
'redirects the user to the hinted provider if the user clicks the proceed button'
,
function
()
{
createHintedLoginView
(
'oa2-google-oauth2'
);
// Click the "Yes, proceed" button
$
(
'.proceed-button'
).
click
();
// Click the "Yes, proceed" button
$
(
'.proceed-button'
).
click
();
expect
(
view
.
redirect
).
toHaveBeenCalledWith
(
'/auth/login/google-oauth2/?auth_entry=account_login'
);
expect
(
view
.
redirect
).
toHaveBeenCalledWith
(
'/auth/login/google-oauth2/?auth_entry=account_login'
);
});
});
});
});
})
.
call
(
this
,
define
||
RequireJS
.
define
)
;
lms/static/js/spec/student_account/institution_login_spec.js
View file @
d2a47908
define
([
'jquery'
,
'underscore'
,
'common/js/spec_helpers/template_helpers'
,
'js/student_account/views/InstitutionLoginView'
,
],
function
(
$
,
_
,
TemplateHelpers
,
InstitutionLoginView
)
{
;(
function
(
define
)
{
'use strict'
;
describe
(
'edx.student.account.InstitutionLoginView'
,
function
()
{
define
([
'jquery'
,
'underscore'
,
'common/js/spec_helpers/template_helpers'
,
'js/student_account/views/InstitutionLoginView'
],
function
(
$
,
_
,
TemplateHelpers
,
InstitutionLoginView
)
{
var
view
=
null
,
PLATFORM_NAME
=
'edX'
,
THIRD_PARTY_AUTH
=
{
currentProvider
:
null
,
providers
:
[],
secondaryProviders
:
[
{
id
:
'oa2-google-oauth2'
,
name
:
'Google'
,
iconClass
:
'fa-google-plus'
,
loginUrl
:
'/auth/login/google-oauth2/?auth_entry=account_login'
,
registerUrl
:
'/auth/login/google-oauth2/?auth_entry=account_register'
},
{
id
:
'oa2-facebook'
,
name
:
'Facebook'
,
iconClass
:
'fa-facebook'
,
loginUrl
:
'/auth/login/facebook/?auth_entry=account_login'
,
registerUrl
:
'/auth/login/facebook/?auth_entry=account_register'
}
]
describe
(
'edx.student.account.InstitutionLoginView'
,
function
()
{
var
view
=
null
,
PLATFORM_NAME
=
'edX'
,
THIRD_PARTY_AUTH
=
{
currentProvider
:
null
,
providers
:
[],
secondaryProviders
:
[
{
id
:
'oa2-google-oauth2'
,
name
:
'Google'
,
iconClass
:
'fa-google-plus'
,
loginUrl
:
'/auth/login/google-oauth2/?auth_entry=account_login'
,
registerUrl
:
'/auth/login/google-oauth2/?auth_entry=account_register'
},
{
id
:
'oa2-facebook'
,
name
:
'Facebook'
,
iconClass
:
'fa-facebook'
,
loginUrl
:
'/auth/login/facebook/?auth_entry=account_login'
,
registerUrl
:
'/auth/login/facebook/?auth_entry=account_register'
}
]
};
var
createInstLoginView
=
function
(
mode
)
{
// Initialize the login view
view
=
new
InstitutionLoginView
({
mode
:
mode
,
thirdPartyAuth
:
THIRD_PARTY_AUTH
,
platformName
:
PLATFORM_NAME
});
view
.
render
();
};
var
createInstLoginView
=
function
(
mode
)
{
// Initialize the login view
view
=
new
InstitutionLoginView
({
mode
:
mode
,
thirdPartyAuth
:
THIRD_PARTY_AUTH
,
platformName
:
PLATFORM_NAME
beforeEach
(
function
()
{
setFixtures
(
'<div id="institution_login-form"></div>'
);
TemplateHelpers
.
installTemplate
(
'templates/student_account/institution_login'
);
TemplateHelpers
.
installTemplate
(
'templates/student_account/institution_register'
);
});
view
.
render
();
};
beforeEach
(
function
()
{
setFixtures
(
'<div id="institution_login-form"></div>'
);
TemplateHelpers
.
installTemplate
(
'templates/student_account/institution_login'
);
TemplateHelpers
.
installTemplate
(
'templates/student_account/institution_register'
);
});
it
(
'displays a list of providers'
,
function
()
{
var
$google
,
$facebook
;
it
(
'displays a list of providers'
,
function
()
{
createInstLoginView
(
'login'
);
expect
(
$
(
'#institution_login-form'
).
html
()).
not
.
toBe
(
""
);
var
$google
=
$
(
'li a:contains("Google")'
);
expect
(
$google
).
toBeVisible
();
expect
(
$google
).
toHaveAttr
(
'href'
,
'/auth/login/google-oauth2/?auth_entry=account_login'
);
var
$facebook
=
$
(
'li a:contains("Facebook")'
);
expect
(
$facebook
).
toBeVisible
();
expect
(
$facebook
).
toHaveAttr
(
'href'
,
'/auth/login/facebook/?auth_entry=account_login'
);
});
createInstLoginView
(
'login'
);
expect
(
$
(
'#institution_login-form'
).
html
()).
not
.
toBe
(
""
);
$google
=
$
(
'li a:contains("Google")'
);
expect
(
$google
).
toBeVisible
();
expect
(
$google
).
toHaveAttr
(
'href'
,
'/auth/login/google-oauth2/?auth_entry=account_login'
);
$facebook
=
$
(
'li a:contains("Facebook")'
);
expect
(
$facebook
).
toBeVisible
();
expect
(
$facebook
).
toHaveAttr
(
'href'
,
'/auth/login/facebook/?auth_entry=account_login'
);
});
it
(
'displays a list of providers'
,
function
()
{
createInstLoginView
(
'register'
);
expect
(
$
(
'#institution_login-form'
).
html
()).
not
.
toBe
(
""
);
var
$google
=
$
(
'li a:contains("Google")'
);
expect
(
$google
).
toBeVisible
();
expect
(
$google
).
toHaveAttr
(
'href'
,
'/auth/login/google-oauth2/?auth_entry=account_register'
);
var
$facebook
=
$
(
'li a:contains("Facebook")'
);
expect
(
$facebook
).
toBeVisible
();
expect
(
$facebook
).
toHaveAttr
(
'href'
,
'/auth/login/facebook/?auth_entry=account_register'
);
});
it
(
'displays a list of providers'
,
function
()
{
var
$google
,
$facebook
;
createInstLoginView
(
'register'
);
expect
(
$
(
'#institution_login-form'
).
html
()).
not
.
toBe
(
""
);
$google
=
$
(
'li a:contains("Google")'
);
expect
(
$google
).
toBeVisible
();
expect
(
$google
).
toHaveAttr
(
'href'
,
'/auth/login/google-oauth2/?auth_entry=account_register'
);
$facebook
=
$
(
'li a:contains("Facebook")'
);
expect
(
$facebook
).
toBeVisible
();
expect
(
$facebook
).
toHaveAttr
(
'href'
,
'/auth/login/facebook/?auth_entry=account_register'
);
});
});
});
});
})
.
call
(
this
,
define
||
RequireJS
.
define
)
;
lms/static/js/spec/student_account/login_spec.js
View file @
d2a47908
define
([
'jquery'
,
'underscore'
,
'common/js/spec_helpers/template_helpers'
,
'common/js/spec_helpers/ajax_helpers'
,
'js/student_account/models/LoginModel'
,
'js/student_account/views/LoginView'
,
'js/student_account/models/PasswordResetModel'
],
function
(
$
,
_
,
TemplateHelpers
,
AjaxHelpers
,
LoginModel
,
LoginView
,
PasswordResetModel
)
{
;(
function
(
define
)
{
'use strict'
;
describe
(
'edx.student.account.LoginView'
,
function
()
{
var
model
=
null
,
resetModel
=
null
,
view
=
null
,
requests
=
null
,
authComplete
=
false
,
PLATFORM_NAME
=
'edX'
,
USER_DATA
=
{
email
:
'xsy@edx.org'
,
password
:
'xsyisawesome'
,
remember
:
true
},
THIRD_PARTY_AUTH
=
{
currentProvider
:
null
,
providers
:
[
{
id
:
'oa2-google-oauth2'
,
name
:
'Google'
,
iconClass
:
'fa-google-plus'
,
loginUrl
:
'/auth/login/google-oauth2/?auth_entry=account_login'
,
registerUrl
:
'/auth/login/google-oauth2/?auth_entry=account_register'
},
{
id
:
'oa2-facebook'
,
name
:
'Facebook'
,
iconClass
:
'fa-facebook'
,
loginUrl
:
'/auth/login/facebook/?auth_entry=account_login'
,
registerUrl
:
'/auth/login/facebook/?auth_entry=account_register'
}
]
},
FORM_DESCRIPTION
=
{
method
:
'post'
,
submit_url
:
'/user_api/v1/account/login_session/'
,
fields
:
[
{
placeholder
:
'username@domain.com'
,
name
:
'email'
,
label
:
'Email'
,
defaultValue
:
''
,
type
:
'email'
,
required
:
true
,
instructions
:
'Enter your email.'
,
restrictions
:
{}
},
{
placeholder
:
''
,
name
:
'password'
,
label
:
'Password'
,
defaultValue
:
''
,
type
:
'password'
,
required
:
true
,
instructions
:
'Enter your password.'
,
restrictions
:
{}
},
{
placeholder
:
''
,
name
:
'remember'
,
label
:
'Remember me'
,
defaultValue
:
''
,
type
:
'checkbox'
,
required
:
true
,
instructions
:
"Agree to the terms of service."
,
restrictions
:
{}
}
]
},
COURSE_ID
=
"edX/demoX/Fall"
;
var
createLoginView
=
function
(
test
)
{
// Initialize the login model
model
=
new
LoginModel
({},
{
url
:
FORM_DESCRIPTION
.
submit_url
,
method
:
FORM_DESCRIPTION
.
method
});
define
([
'jquery'
,
'underscore'
,
'common/js/spec_helpers/template_helpers'
,
'common/js/spec_helpers/ajax_helpers'
,
'js/student_account/models/LoginModel'
,
'js/student_account/views/LoginView'
,
'js/student_account/models/PasswordResetModel'
],
function
(
$
,
_
,
TemplateHelpers
,
AjaxHelpers
,
LoginModel
,
LoginView
,
PasswordResetModel
)
{
describe
(
'edx.student.account.LoginView'
,
function
()
{
var
model
=
null
,
resetModel
=
null
,
view
=
null
,
requests
=
null
,
authComplete
=
false
,
PLATFORM_NAME
=
'edX'
,
USER_DATA
=
{
email
:
'xsy@edx.org'
,
password
:
'xsyisawesome'
,
remember
:
true
},
THIRD_PARTY_AUTH
=
{
currentProvider
:
null
,
providers
:
[
{
id
:
'oa2-google-oauth2'
,
name
:
'Google'
,
iconClass
:
'fa-google-plus'
,
loginUrl
:
'/auth/login/google-oauth2/?auth_entry=account_login'
,
registerUrl
:
'/auth/login/google-oauth2/?auth_entry=account_register'
},
{
id
:
'oa2-facebook'
,
name
:
'Facebook'
,
iconClass
:
'fa-facebook'
,
loginUrl
:
'/auth/login/facebook/?auth_entry=account_login'
,
registerUrl
:
'/auth/login/facebook/?auth_entry=account_register'
}
]
},
FORM_DESCRIPTION
=
{
method
:
'post'
,
submit_url
:
'/user_api/v1/account/login_session/'
,
fields
:
[
{
placeholder
:
'username@domain.com'
,
name
:
'email'
,
label
:
'Email'
,
defaultValue
:
''
,
type
:
'email'
,
required
:
true
,
instructions
:
'Enter your email.'
,
restrictions
:
{}
},
{
placeholder
:
''
,
name
:
'password'
,
label
:
'Password'
,
defaultValue
:
''
,
type
:
'password'
,
required
:
true
,
instructions
:
'Enter your password.'
,
restrictions
:
{}
},
{
placeholder
:
''
,
name
:
'remember'
,
label
:
'Remember me'
,
defaultValue
:
''
,
type
:
'checkbox'
,
required
:
true
,
instructions
:
'Agree to the terms of service.'
,
restrictions
:
{}
}
]
},
COURSE_ID
=
'edX/demoX/Fall'
;
var
createLoginView
=
function
(
test
)
{
// Initialize the login model
model
=
new
LoginModel
({},
{
url
:
FORM_DESCRIPTION
.
submit_url
,
method
:
FORM_DESCRIPTION
.
method
});
// Initialize the passwordReset model
resetModel
=
new
PasswordResetModel
({},
{
method
:
'GET'
,
url
:
'#'
});
// Initialize the passwordReset model
resetModel
=
new
PasswordResetModel
({},
{
method
:
'GET'
,
url
:
'#'
});
// Initialize the login view
view
=
new
LoginView
({
fields
:
FORM_DESCRIPTION
.
fields
,
model
:
model
,
resetModel
:
resetModel
,
thirdPartyAuth
:
THIRD_PARTY_AUTH
,
platformName
:
PLATFORM_NAME
});
// Initialize the login view
view
=
new
LoginView
({
fields
:
FORM_DESCRIPTION
.
fields
,
model
:
model
,
resetModel
:
resetModel
,
thirdPartyAuth
:
THIRD_PARTY_AUTH
,
platformName
:
PLATFORM_NAME
});
// Spy on AJAX requests
requests
=
AjaxHelpers
.
requests
(
test
);
// Spy on AJAX requests
requests
=
AjaxHelpers
.
requests
(
test
);
// Intercept events from the view
authComplete
=
false
;
view
.
on
(
"auth-complete"
,
function
()
{
authComplete
=
true
;
});
};
var
submitForm
=
function
(
validationSuccess
)
{
// Simulate manual entry of login form data
$
(
'#login-email'
).
val
(
USER_DATA
.
email
);
$
(
'#login-password'
).
val
(
USER_DATA
.
password
);
// Check the "Remember me" checkbox
$
(
'#login-remember'
).
prop
(
'checked'
,
USER_DATA
.
remember
);
// Create a fake click event
var
clickEvent
=
$
.
Event
(
'click'
);
// If validationSuccess isn't passed, we avoid
// spying on `view.validate` twice
if
(
!
_
.
isUndefined
(
validationSuccess
)
)
{
// Force validation to return as expected
spyOn
(
view
,
'validate'
).
andReturn
({
isValid
:
validationSuccess
,
message
:
'Submission was validated.'
// Intercept events from the view
authComplete
=
false
;
view
.
on
(
"auth-complete"
,
function
()
{
authComplete
=
true
;
});
}
};
var
submitForm
=
function
(
validationSuccess
)
{
// Create a fake click event
var
clickEvent
=
$
.
Event
(
'click'
);
// Simulate manual entry of login form data
$
(
'#login-email'
).
val
(
USER_DATA
.
email
);
$
(
'#login-password'
).
val
(
USER_DATA
.
password
);
// Check the 'Remember me' checkbox
$
(
'#login-remember'
).
prop
(
'checked'
,
USER_DATA
.
remember
);
// If validationSuccess isn't passed, we avoid
// spying on `view.validate` twice
if
(
!
_
.
isUndefined
(
validationSuccess
)
)
{
// Force validation to return as expected
spyOn
(
view
,
'validate'
).
andReturn
({
isValid
:
validationSuccess
,
message
:
'Submission was validated.'
});
}
// Submit the email address
view
.
submitForm
(
clickEvent
);
};
// Submit the email address
view
.
submitForm
(
clickEvent
);
};
beforeEach
(
function
()
{
setFixtures
(
'<div id="login-form"></div>'
);
TemplateHelpers
.
installTemplate
(
'templates/student_account/login'
);
TemplateHelpers
.
installTemplate
(
'templates/student_account/form_field'
);
});
beforeEach
(
function
()
{
setFixtures
(
'<div id="login-form"></div>'
);
TemplateHelpers
.
installTemplate
(
'templates/student_account/login'
);
TemplateHelpers
.
installTemplate
(
'templates/student_account/form_field'
);
});
it
(
'logs the user in'
,
function
()
{
createLoginView
(
this
);
it
(
'logs the user in'
,
function
()
{
createLoginView
(
this
);
// Submit the form, with successful validation
submitForm
(
true
);
// Submit the form, with successful validation
submitForm
(
true
);
// Form button should be disabled on success.
expect
(
view
.
$submitButton
).
toHaveAttr
(
'disabled'
);
// Form button should be disabled on success.
expect
(
view
.
$submitButton
).
toHaveAttr
(
'disabled'
);
// Verify that the client contacts the server with the expected data
AjaxHelpers
.
expectRequest
(
requests
,
'POST'
,
FORM_DESCRIPTION
.
submit_url
,
$
.
param
(
USER_DATA
)
);
// Verify that the client contacts the server with the expected data
AjaxHelpers
.
expectRequest
(
requests
,
'POST'
,
FORM_DESCRIPTION
.
submit_url
,
$
.
param
(
USER_DATA
)
);
// Respond with status code 200
AjaxHelpers
.
respondWithJson
(
requests
,
{});
// Respond with status code 200
AjaxHelpers
.
respondWithJson
(
requests
,
{});
// Verify that auth-complete is triggered
expect
(
authComplete
).
toBe
(
true
);
});
// Verify that auth-complete is triggered
expect
(
authComplete
).
toBe
(
true
);
});
it
(
'sends analytics info containing the enrolled course ID'
,
function
()
{
createLoginView
(
this
)
;
it
(
'sends analytics info containing the enrolled course ID'
,
function
()
{
var
expectedData
;
// Simulate that the user is attempting to enroll in a course
// by setting the course_id query string param.
spyOn
(
$
,
'url'
).
andCallFake
(
function
(
param
)
{
if
(
param
===
"?course_id"
)
{
return
encodeURIComponent
(
COURSE_ID
);
}
});
createLoginView
(
this
);
// Attempt to login
submitForm
(
true
);
// Simulate that the user is attempting to enroll in a course
// by setting the course_id query string param.
spyOn
(
$
,
'url'
).
andCallFake
(
function
(
param
)
{
if
(
param
===
'?course_id'
)
{
return
encodeURIComponent
(
COURSE_ID
);
}
});
// Verify that the client sent the course ID for analytics
var
expectedData
=
{};
$
.
extend
(
expectedData
,
USER_DATA
,
{
analytics
:
JSON
.
stringify
({
enroll_course_id
:
COURSE_ID
})
});
// Attempt to login
submitForm
(
true
);
AjaxHelpers
.
expectRequest
(
requests
,
'POST'
,
FORM_DESCRIPTION
.
submit_url
,
$
.
param
(
expectedData
)
);
});
// Verify that the client sent the course ID for analytics
expectedData
=
{};
$
.
extend
(
expectedData
,
USER_DATA
,
{
analytics
:
JSON
.
stringify
({
enroll_course_id
:
COURSE_ID
})
});
AjaxHelpers
.
expectRequest
(
requests
,
'POST'
,
FORM_DESCRIPTION
.
submit_url
,
$
.
param
(
expectedData
)
);
});
it
(
'displays third-party auth login buttons'
,
function
()
{
createLoginView
(
this
);
it
(
'displays third-party auth login buttons'
,
function
()
{
createLoginView
(
this
);
// Verify that Google and Facebook registration buttons are displayed
expect
(
$
(
'.button-oa2-google-oauth2'
)).
toBeVisible
();
expect
(
$
(
'.button-oa2-facebook'
)).
toBeVisible
();
});
// Verify that Google and Facebook registration buttons are displayed
expect
(
$
(
'.button-oa2-google-oauth2'
)).
toBeVisible
();
expect
(
$
(
'.button-oa2-facebook'
)).
toBeVisible
();
});
it
(
'displays a link to the password reset form'
,
function
()
{
createLoginView
(
this
);
it
(
'displays a link to the password reset form'
,
function
()
{
createLoginView
(
this
);
// Verify that the password reset link is displayed
expect
(
$
(
'.forgot-password'
)).
toBeVisible
();
});
// Verify that the password reset link is displayed
expect
(
$
(
'.forgot-password'
)).
toBeVisible
();
});
it
(
'validates login form fields'
,
function
()
{
createLoginView
(
this
);
it
(
'validates login form fields'
,
function
()
{
createLoginView
(
this
);
submitForm
(
true
);
submitForm
(
true
);
// Verify that validation of form fields occurred
expect
(
view
.
validate
).
toHaveBeenCalledWith
(
$
(
'#login-email'
)[
0
]);
expect
(
view
.
validate
).
toHaveBeenCalledWith
(
$
(
'#login-password'
)[
0
]);
});
// Verify that validation of form fields occurred
expect
(
view
.
validate
).
toHaveBeenCalledWith
(
$
(
'#login-email'
)[
0
]);
expect
(
view
.
validate
).
toHaveBeenCalledWith
(
$
(
'#login-password'
)[
0
]);
});
it
(
'displays login form validation errors'
,
function
()
{
createLoginView
(
this
);
it
(
'displays login form validation errors'
,
function
()
{
createLoginView
(
this
);
// Submit the form, with failed validation
submitForm
(
false
);
// Submit the form, with failed validation
submitForm
(
false
);
// Verify that submission errors are visible
expect
(
view
.
$errors
).
not
.
toHaveClass
(
'hidden'
);
// Verify that submission errors are visible
expect
(
view
.
$errors
).
not
.
toHaveClass
(
'hidden'
);
// Expect auth complete NOT to have been triggered
expect
(
authComplete
).
toBe
(
false
);
// Form button should be re-enabled when errors occur
expect
(
view
.
$submitButton
).
not
.
toHaveAttr
(
'disabled'
);
});
// Expect auth complete NOT to have been triggered
expect
(
authComplete
).
toBe
(
false
);
// Form button should be re-enabled when errors occur
expect
(
view
.
$submitButton
).
not
.
toHaveAttr
(
'disabled'
);
});
it
(
'displays an error if the server returns an error while logging in'
,
function
()
{
createLoginView
(
this
);
it
(
'displays an error if the server returns an error while logging in'
,
function
()
{
createLoginView
(
this
);
// Submit the form, with successful validation
submitForm
(
true
);
// Submit the form, with successful validation
submitForm
(
true
);
// Simulate an error from the LMS servers
AjaxHelpers
.
respondWithError
(
requests
);
// Simulate an error from the LMS servers
AjaxHelpers
.
respondWithError
(
requests
);
// Expect that an error is displayed and that auth complete is not triggered
expect
(
view
.
$errors
).
not
.
toHaveClass
(
'hidden'
);
expect
(
authComplete
).
toBe
(
false
);
// Form button should be re-enabled on server failure.
expect
(
view
.
$submitButton
).
not
.
toHaveAttr
(
'disabled'
);
// Expect that an error is displayed and that auth complete is not triggered
expect
(
view
.
$errors
).
not
.
toHaveClass
(
'hidden'
);
expect
(
authComplete
).
toBe
(
false
);
// Form button should be re-enabled on server failure.
expect
(
view
.
$submitButton
).
not
.
toHaveAttr
(
'disabled'
);
// If we try again and succeed, the error should go away
submitForm
();
// If we try again and succeed, the error should go away
submitForm
();
// Form button should be disabled on success.
expect
(
view
.
$submitButton
).
toHaveAttr
(
'disabled'
);
// Form button should be disabled on success.
expect
(
view
.
$submitButton
).
toHaveAttr
(
'disabled'
);
// This time, respond with status code 200
AjaxHelpers
.
respondWithJson
(
requests
,
{});
// This time, respond with status code 200
AjaxHelpers
.
respondWithJson
(
requests
,
{});
// Expect that the error is hidden and auth complete is triggered
expect
(
view
.
$errors
).
toHaveClass
(
'hidden'
);
expect
(
authComplete
).
toBe
(
true
);
// Expect that the error is hidden and auth complete is triggered
expect
(
view
.
$errors
).
toHaveClass
(
'hidden'
);
expect
(
authComplete
).
toBe
(
true
);
});
});
});
});
})
.
call
(
this
,
define
||
RequireJS
.
define
)
;
lms/static/js/spec/student_account/logistration_factory_spec.js
0 → 100644
View file @
d2a47908
;(
function
(
define
)
{
'use strict'
;
define
([
'jquery'
,
'underscore'
,
'backbone'
,
'common/js/spec_helpers/template_helpers'
,
'common/js/spec_helpers/ajax_helpers'
,
'js/student_account/logistration_factory'
],
function
(
$
,
_
,
Backbone
,
TemplateHelpers
,
AjaxHelpers
,
LogistrationFactory
)
{
describe
(
'Logistration Factory'
,
function
()
{
var
FORM_DESCRIPTION
=
{
method
:
'post'
,
submit_url
:
'/submit'
,
fields
:
[
{
name
:
'email'
,
label
:
'Email'
,
defaultValue
:
''
,
type
:
'text'
,
required
:
true
,
placeholder
:
'xsy@edx.org'
,
instructions
:
'Enter your email here.'
,
restrictions
:
{}
},
{
name
:
'username'
,
label
:
'Username'
,
defaultValue
:
''
,
type
:
'text'
,
required
:
true
,
placeholder
:
'Xsy'
,
instructions
:
'Enter your username here.'
,
restrictions
:
{
max_length
:
200
}
}
]
};
var
initializeLogistrationFactory
=
function
(
that
,
mode
,
nextUrl
,
finishAuthUrl
)
{
var
options
=
{
initial_mode
:
mode
,
third_party_auth
:
{
currentProvider
:
null
,
providers
:
[],
secondaryProviders
:
[{
name
:
'provider'
}],
finishAuthUrl
:
finishAuthUrl
},
login_redirect_url
:
nextUrl
,
// undefined for default
platform_name
:
'edX'
,
login_form_desc
:
FORM_DESCRIPTION
,
registration_form_desc
:
FORM_DESCRIPTION
,
password_reset_form_desc
:
FORM_DESCRIPTION
};
// Initialize the logistration Factory
LogistrationFactory
(
options
);
};
var
assertForms
=
function
(
visibleForm
,
hiddenFormsList
)
{
expect
(
$
(
visibleForm
)).
not
.
toHaveClass
(
'hidden'
);
_
.
each
(
hiddenFormsList
,
function
(
hiddenForm
)
{
expect
(
$
(
hiddenForm
)).
toHaveClass
(
'hidden'
);
},
this
);
};
beforeEach
(
function
()
{
setFixtures
(
'<div id="login-and-registration-container" class="login-register" />'
);
TemplateHelpers
.
installTemplate
(
'templates/student_account/access'
);
TemplateHelpers
.
installTemplate
(
'templates/student_account/form_field'
);
TemplateHelpers
.
installTemplate
(
'templates/student_account/login'
);
TemplateHelpers
.
installTemplate
(
'templates/student_account/register'
);
TemplateHelpers
.
installTemplate
(
'templates/student_account/password_reset'
)
});
afterEach
(
function
()
{
Backbone
.
history
.
stop
();
});
it
(
'can initially render the login form'
,
function
()
{
var
hiddenFormsList
;
initializeLogistrationFactory
(
this
,
'login'
);
/* Verify that only login form is expanded, and that the
/* all other logistration forms are collapsed.
*/
hiddenFormsList
=
[
'#register-form'
,
'#password-reset-form'
];
assertForms
(
'#login-form'
,
hiddenFormsList
);
});
it
(
'can initially render the registration form'
,
function
()
{
var
hiddenFormsList
;
initializeLogistrationFactory
(
this
,
'register'
);
/* Verify that only registration form is expanded, and that the
/* all other logistration forms are collapsed.
*/
hiddenFormsList
=
[
'#login-form'
,
'#password-reset-form'
];
assertForms
(
'#register-form'
,
hiddenFormsList
);
});
it
(
'can initially render the password reset form'
,
function
()
{
var
hiddenFormsList
;
initializeLogistrationFactory
(
this
,
'reset'
);
/* Verify that only password reset form is expanded, and that the
/* all other logistration forms are collapsed.
*/
hiddenFormsList
=
[
'#login-form'
,
'#register-form'
];
assertForms
(
'#password-reset-form'
,
hiddenFormsList
);
});
});
});
}).
call
(
this
,
define
||
RequireJS
.
define
);
lms/static/js/spec/student_account/password_reset_spec.js
View file @
d2a47908
define
([
'jquery'
,
'underscore'
,
'common/js/spec_helpers/template_helpers'
,
'common/js/spec_helpers/ajax_helpers'
,
'js/student_account/models/PasswordResetModel'
,
'js/student_account/views/PasswordResetView'
,
],
function
(
$
,
_
,
TemplateHelpers
,
AjaxHelpers
,
PasswordResetModel
,
PasswordResetView
)
{
describe
(
'edx.student.account.PasswordResetView'
,
function
()
{
'use strict'
;
;(
function
(
define
)
{
'use strict'
;
define
([
'jquery'
,
'underscore'
,
'common/js/spec_helpers/template_helpers'
,
'common/js/spec_helpers/ajax_helpers'
,
'js/student_account/models/PasswordResetModel'
,
'js/student_account/views/PasswordResetView'
],
function
(
$
,
_
,
TemplateHelpers
,
AjaxHelpers
,
PasswordResetModel
,
PasswordResetView
)
{
describe
(
'edx.student.account.PasswordResetView'
,
function
()
{
var
model
=
null
,
view
=
null
,
requests
=
null
,
...
...
@@ -46,12 +48,12 @@ define([
};
var
submitEmail
=
function
(
validationSuccess
)
{
// Simulate manual entry of an email address
$
(
'#password-reset-email'
).
val
(
EMAIL
);
// Create a fake click event
var
clickEvent
=
$
.
Event
(
'click'
);
// Simulate manual entry of an email address
$
(
'#password-reset-email'
).
val
(
EMAIL
);
// If validationSuccess isn't passed, we avoid
// spying on `view.validate` twice
if
(
!
_
.
isUndefined
(
validationSuccess
)
)
{
...
...
@@ -141,5 +143,5 @@ define([
expect
(
view
.
$errors
).
toHaveClass
(
'hidden'
);
});
});
}
);
}
);
}).
call
(
this
,
define
||
RequireJS
.
define
);
lms/static/js/spec/student_account/register_spec.js
View file @
d2a47908
define
([
'jquery'
,
'underscore'
,
'common/js/spec_helpers/template_helpers'
,
'common/js/spec_helpers/ajax_helpers'
,
'js/student_account/models/RegisterModel'
,
'js/student_account/views/RegisterView'
],
function
(
$
,
_
,
TemplateHelpers
,
AjaxHelpers
,
RegisterModel
,
RegisterView
)
{
;(
function
(
define
)
{
'use strict'
;
define
([
'jquery'
,
'underscore'
,
'common/js/spec_helpers/template_helpers'
,
'common/js/spec_helpers/ajax_helpers'
,
'js/student_account/models/RegisterModel'
,
'js/student_account/views/RegisterView'
],
function
(
$
,
_
,
TemplateHelpers
,
AjaxHelpers
,
RegisterModel
,
RegisterView
)
{
describe
(
'edx.student.account.RegisterView'
,
function
()
{
var
model
=
null
,
view
=
null
,
requests
=
null
,
authComplete
=
false
,
PLATFORM_NAME
=
'edX'
,
COURSE_ID
=
'edX/DemoX/Fall'
,
USER_DATA
=
{
email
:
'xsy@edx.org'
,
name
:
'Xsy M. Education'
,
username
:
'Xsy'
,
password
:
'xsyisawesome'
,
level_of_education
:
'p'
,
gender
:
'm'
,
year_of_birth
:
2014
,
mailing_address
:
'141 Portland'
,
goals
:
'To boldly learn what no letter of the alphabet has learned before'
,
honor_code
:
true
},
THIRD_PARTY_AUTH
=
{
currentProvider
:
null
,
providers
:
[
{
id
:
'oa2-google-oauth2'
,
name
:
'Google'
,
iconClass
:
'fa-google-plus'
,
loginUrl
:
'/auth/login/google-oauth2/?auth_entry=account_login'
,
registerUrl
:
'/auth/login/google-oauth2/?auth_entry=account_register'
},
{
id
:
'oa2-facebook'
,
name
:
'Facebook'
,
iconClass
:
'fa-facebook'
,
loginUrl
:
'/auth/login/facebook/?auth_entry=account_login'
,
registerUrl
:
'/auth/login/facebook/?auth_entry=account_register'
}
]
},
FORM_DESCRIPTION
=
{
method
:
'post'
,
submit_url
:
'/user_api/v1/account/registration/'
,
fields
:
[
{
placeholder
:
'username@domain.com'
,
name
:
'email'
,
label
:
'Email'
,
defaultValue
:
''
,
type
:
'email'
,
required
:
true
,
instructions
:
'Enter your email.'
,
restrictions
:
{}
},
{
placeholder
:
'Jane Doe'
,
name
:
'name'
,
label
:
'Full Name'
,
defaultValue
:
''
,
type
:
'text'
,
required
:
true
,
instructions
:
'Enter your username.'
,
restrictions
:
{}
},
{
placeholder
:
'JaneDoe'
,
name
:
'username'
,
label
:
'Username'
,
defaultValue
:
''
,
type
:
'text'
,
required
:
true
,
instructions
:
'Enter your username.'
,
restrictions
:
{}
},
{
placeholder
:
''
,
name
:
'password'
,
label
:
'Password'
,
defaultValue
:
''
,
type
:
'password'
,
required
:
true
,
instructions
:
'Enter your password.'
,
restrictions
:
{}
},
{
placeholder
:
''
,
name
:
'level_of_education'
,
label
:
'Highest Level of Education Completed'
,
defaultValue
:
''
,
type
:
'select'
,
options
:
[
{
value
:
""
,
name
:
"--"
},
{
value
:
"p"
,
name
:
"Doctorate"
},
{
value
:
"m"
,
name
:
"Master's or professional degree"
},
{
value
:
"b"
,
name
:
"Bachelor's degree"
}
],
required
:
false
,
instructions
:
'Select your education level.'
,
restrictions
:
{}
},
{
placeholder
:
''
,
name
:
'gender'
,
label
:
'Gender'
,
defaultValue
:
''
,
type
:
'select'
,
options
:
[
{
value
:
""
,
name
:
"--"
},
{
value
:
"m"
,
name
:
"Male"
},
{
value
:
"f"
,
name
:
"Female"
},
{
value
:
"o"
,
name
:
"Other"
}
],
required
:
false
,
instructions
:
'Select your gender.'
,
restrictions
:
{}
},
{
placeholder
:
''
,
name
:
'year_of_birth'
,
label
:
'Year of Birth'
,
defaultValue
:
''
,
type
:
'select'
,
options
:
[
{
value
:
""
,
name
:
"--"
},
{
value
:
1900
,
name
:
"1900"
},
{
value
:
1950
,
name
:
"1950"
},
{
value
:
2014
,
name
:
"2014"
}
],
required
:
false
,
instructions
:
'Select your year of birth.'
,
restrictions
:
{}
},
{
placeholder
:
''
,
name
:
'mailing_address'
,
label
:
'Mailing Address'
,
defaultValue
:
''
,
type
:
'textarea'
,
required
:
false
,
instructions
:
'Enter your mailing address.'
,
restrictions
:
{}
},
{
placeholder
:
''
,
name
:
'goals'
,
label
:
'Goals'
,
defaultValue
:
''
,
type
:
'textarea'
,
required
:
false
,
instructions
:
"If you'd like, tell us why you're interested in edX."
,
restrictions
:
{}
},
{
placeholder
:
''
,
name
:
'honor_code'
,
label
:
'I agree to the <a href="/honor">Terms of Service and Honor Code</a>'
,
defaultValue
:
''
,
type
:
'checkbox'
,
required
:
true
,
instructions
:
''
,
restrictions
:
{}
}
]
};
var
createRegisterView
=
function
(
that
)
{
// Initialize the register model
model
=
new
RegisterModel
({},
{
url
:
FORM_DESCRIPTION
.
submit_url
,
method
:
FORM_DESCRIPTION
.
method
});
describe
(
'edx.student.account.RegisterView'
,
function
()
{
var
model
=
null
,
view
=
null
,
requests
=
null
,
authComplete
=
false
,
PLATFORM_NAME
=
'edX'
,
COURSE_ID
=
"edX/DemoX/Fall"
,
USER_DATA
=
{
email
:
'xsy@edx.org'
,
name
:
'Xsy M. Education'
,
username
:
'Xsy'
,
password
:
'xsyisawesome'
,
level_of_education
:
'p'
,
gender
:
'm'
,
year_of_birth
:
2014
,
mailing_address
:
'141 Portland'
,
goals
:
'To boldly learn what no letter of the alphabet has learned before'
,
honor_code
:
true
},
THIRD_PARTY_AUTH
=
{
currentProvider
:
null
,
providers
:
[
{
id
:
'oa2-google-oauth2'
,
name
:
'Google'
,
iconClass
:
'fa-google-plus'
,
loginUrl
:
'/auth/login/google-oauth2/?auth_entry=account_login'
,
registerUrl
:
'/auth/login/google-oauth2/?auth_entry=account_register'
},
{
id
:
'oa2-facebook'
,
name
:
'Facebook'
,
iconClass
:
'fa-facebook'
,
loginUrl
:
'/auth/login/facebook/?auth_entry=account_login'
,
registerUrl
:
'/auth/login/facebook/?auth_entry=account_register'
}
]
},
FORM_DESCRIPTION
=
{
method
:
'post'
,
submit_url
:
'/user_api/v1/account/registration/'
,
fields
:
[
{
placeholder
:
'username@domain.com'
,
name
:
'email'
,
label
:
'Email'
,
defaultValue
:
''
,
type
:
'email'
,
required
:
true
,
instructions
:
'Enter your email.'
,
restrictions
:
{}
},
{
placeholder
:
'Jane Doe'
,
name
:
'name'
,
label
:
'Full Name'
,
defaultValue
:
''
,
type
:
'text'
,
required
:
true
,
instructions
:
'Enter your username.'
,
restrictions
:
{}
},
{
placeholder
:
'JaneDoe'
,
name
:
'username'
,
label
:
'Username'
,
defaultValue
:
''
,
type
:
'text'
,
required
:
true
,
instructions
:
'Enter your username.'
,
restrictions
:
{}
},
{
placeholder
:
''
,
name
:
'password'
,
label
:
'Password'
,
defaultValue
:
''
,
type
:
'password'
,
required
:
true
,
instructions
:
'Enter your password.'
,
restrictions
:
{}
},
{
placeholder
:
''
,
name
:
'level_of_education'
,
label
:
'Highest Level of Education Completed'
,
defaultValue
:
''
,
type
:
'select'
,
options
:
[
{
value
:
""
,
name
:
"--"
},
{
value
:
"p"
,
name
:
"Doctorate"
},
{
value
:
"m"
,
name
:
"Master's or professional degree"
},
{
value
:
"b"
,
name
:
"Bachelor's degree"
}
],
required
:
false
,
instructions
:
'Select your education level.'
,
restrictions
:
{}
},
{
placeholder
:
''
,
name
:
'gender'
,
label
:
'Gender'
,
defaultValue
:
''
,
type
:
'select'
,
options
:
[
{
value
:
""
,
name
:
"--"
},
{
value
:
"m"
,
name
:
"Male"
},
{
value
:
"f"
,
name
:
"Female"
},
{
value
:
"o"
,
name
:
"Other"
}
],
required
:
false
,
instructions
:
'Select your gender.'
,
restrictions
:
{}
},
{
placeholder
:
''
,
name
:
'year_of_birth'
,
label
:
'Year of Birth'
,
defaultValue
:
''
,
type
:
'select'
,
options
:
[
{
value
:
""
,
name
:
"--"
},
{
value
:
1900
,
name
:
"1900"
},
{
value
:
1950
,
name
:
"1950"
},
{
value
:
2014
,
name
:
"2014"
}
],
required
:
false
,
instructions
:
'Select your year of birth.'
,
restrictions
:
{}
},
{
placeholder
:
''
,
name
:
'mailing_address'
,
label
:
'Mailing Address'
,
defaultValue
:
''
,
type
:
'textarea'
,
required
:
false
,
instructions
:
'Enter your mailing address.'
,
restrictions
:
{}
},
{
placeholder
:
''
,
name
:
'goals'
,
label
:
'Goals'
,
defaultValue
:
''
,
type
:
'textarea'
,
required
:
false
,
instructions
:
"If you'd like, tell us why you're interested in edX."
,
restrictions
:
{}
},
{
placeholder
:
''
,
name
:
'honor_code'
,
label
:
'I agree to the <a href="/honor">Terms of Service and Honor Code</a>'
,
defaultValue
:
''
,
type
:
'checkbox'
,
required
:
true
,
instructions
:
''
,
restrictions
:
{}
}
]
};
// Initialize the register view
view
=
new
RegisterView
({
fields
:
FORM_DESCRIPTION
.
fields
,
model
:
model
,
thirdPartyAuth
:
THIRD_PARTY_AUTH
,
platformName
:
PLATFORM_NAME
});
var
createRegisterView
=
function
(
that
)
{
// Initialize the register model
model
=
new
RegisterModel
({},
{
url
:
FORM_DESCRIPTION
.
submit_url
,
method
:
FORM_DESCRIPTION
.
method
});
// Spy on AJAX requests
requests
=
AjaxHelpers
.
requests
(
that
);
// Initialize the register view
view
=
new
RegisterView
({
fields
:
FORM_DESCRIPTION
.
fields
,
model
:
model
,
thirdPartyAuth
:
THIRD_PARTY_AUTH
,
platformName
:
PLATFORM_NAME
});
// Intercept events from the view
authComplete
=
false
;
view
.
on
(
"auth-complete"
,
function
()
{
authComplete
=
true
;
});
};
// Spy on AJAX requests
requests
=
AjaxHelpers
.
requests
(
that
);
var
submitForm
=
function
(
validationSuccess
)
{
// Create a fake click event
var
clickEvent
=
$
.
Event
(
'click'
);
// Simulate manual entry of registration form data
$
(
'#register-email'
).
val
(
USER_DATA
.
email
);
$
(
'#register-name'
).
val
(
USER_DATA
.
name
);
$
(
'#register-username'
).
val
(
USER_DATA
.
username
);
$
(
'#register-password'
).
val
(
USER_DATA
.
password
);
$
(
'#register-level_of_education'
).
val
(
USER_DATA
.
level_of_education
);
$
(
'#register-gender'
).
val
(
USER_DATA
.
gender
);
$
(
'#register-year_of_birth'
).
val
(
USER_DATA
.
year_of_birth
);
$
(
'#register-mailing_address'
).
val
(
USER_DATA
.
mailing_address
);
$
(
'#register-goals'
).
val
(
USER_DATA
.
goals
);
// Check the honor code checkbox
$
(
'#register-honor_code'
).
prop
(
'checked'
,
USER_DATA
.
honor_code
);
// If validationSuccess isn't passed, we avoid
// spying on `view.validate` twice
if
(
!
_
.
isUndefined
(
validationSuccess
)
)
{
// Force validation to return as expected
spyOn
(
view
,
'validate'
).
andReturn
({
isValid
:
validationSuccess
,
message
:
'Submission was validated.'
});
}
// Intercept events from the view
authComplete
=
false
;
view
.
on
(
"auth-complete"
,
function
()
{
authComplete
=
true
;
});
};
var
submitForm
=
function
(
validationSuccess
)
{
// Simulate manual entry of registration form data
$
(
'#register-email'
).
val
(
USER_DATA
.
email
);
$
(
'#register-name'
).
val
(
USER_DATA
.
name
);
$
(
'#register-username'
).
val
(
USER_DATA
.
username
);
$
(
'#register-password'
).
val
(
USER_DATA
.
password
);
$
(
'#register-level_of_education'
).
val
(
USER_DATA
.
level_of_education
);
$
(
'#register-gender'
).
val
(
USER_DATA
.
gender
);
$
(
'#register-year_of_birth'
).
val
(
USER_DATA
.
year_of_birth
);
$
(
'#register-mailing_address'
).
val
(
USER_DATA
.
mailing_address
);
$
(
'#register-goals'
).
val
(
USER_DATA
.
goals
);
// Check the honor code checkbox
$
(
'#register-honor_code'
).
prop
(
'checked'
,
USER_DATA
.
honor_code
);
// Create a fake click event
var
clickEvent
=
$
.
Event
(
'click'
);
// If validationSuccess isn't passed, we avoid
// spying on `view.validate` twice
if
(
!
_
.
isUndefined
(
validationSuccess
)
)
{
// Force validation to return as expected
spyOn
(
view
,
'validate'
).
andReturn
({
isValid
:
validationSuccess
,
message
:
'Submission was validated.'
});
}
// Submit the email address
view
.
submitForm
(
clickEvent
);
};
// Submit the email address
view
.
submitForm
(
clickEvent
);
};
beforeEach
(
function
()
{
setFixtures
(
'<div id="register-form"></div>'
);
TemplateHelpers
.
installTemplate
(
'templates/student_account/register'
);
TemplateHelpers
.
installTemplate
(
'templates/student_account/form_field'
);
});
beforeEach
(
function
()
{
setFixtures
(
'<div id="register-form"></div>'
);
TemplateHelpers
.
installTemplate
(
'templates/student_account/register'
);
TemplateHelpers
.
installTemplate
(
'templates/student_account/form_field'
);
});
it
(
'registers a new user'
,
function
()
{
createRegisterView
(
this
);
it
(
'registers a new user'
,
function
()
{
createRegisterView
(
this
);
// Submit the form, with successful validation
submitForm
(
true
);
// Submit the form, with successful validation
submitForm
(
true
);
// Verify that the client contacts the server with the expected data
AjaxHelpers
.
expectRequest
(
requests
,
'POST'
,
FORM_DESCRIPTION
.
submit_url
,
$
.
param
(
USER_DATA
)
);
// Verify that the client contacts the server with the expected data
AjaxHelpers
.
expectRequest
(
requests
,
'POST'
,
FORM_DESCRIPTION
.
submit_url
,
$
.
param
(
USER_DATA
)
);
// Respond with status code 200
AjaxHelpers
.
respondWithJson
(
requests
,
{});
// Respond with status code 200
AjaxHelpers
.
respondWithJson
(
requests
,
{});
// Verify that auth complete is triggered
expect
(
authComplete
).
toBe
(
true
);
// Form button should be disabled on success.
expect
(
view
.
$submitButton
).
toHaveAttr
(
'disabled'
);
});
// Verify that auth complete is triggered
expect
(
authComplete
).
toBe
(
true
);
// Form button should be disabled on success.
expect
(
view
.
$submitButton
).
toHaveAttr
(
'disabled'
);
});
it
(
'sends analytics info containing the enrolled course ID'
,
function
()
{
var
expectedData
;
it
(
'sends analytics info containing the enrolled course ID'
,
function
()
{
createRegisterView
(
this
);
createRegisterView
(
this
);
// Simulate that the user is attempting to enroll in a course
// by setting the course_id query string param.
spyOn
(
$
,
'url'
).
andCallFake
(
function
(
param
)
{
if
(
param
===
"?course_id"
)
{
return
encodeURIComponent
(
COURSE_ID
);
}
});
// Simulate that the user is attempting to enroll in a course
// by setting the course_id query string param.
spyOn
(
$
,
'url'
).
andCallFake
(
function
(
param
)
{
if
(
param
===
'?course_id'
)
{
return
encodeURIComponent
(
COURSE_ID
);
}
});
// Attempt to register
submitForm
(
true
);
// Attempt to register
submitForm
(
true
);
// Verify that the client sent the course ID for analytics
var
expectedData
=
{
course_id
:
COURSE_ID
};
$
.
extend
(
expectedData
,
USER_DATA
);
// Verify that the client sent the course ID for analytics
expectedData
=
{
course_id
:
COURSE_ID
};
$
.
extend
(
expectedData
,
USER_DATA
);
AjaxHelpers
.
expectRequest
(
requests
,
'POST'
,
FORM_DESCRIPTION
.
submit_url
,
$
.
param
(
expectedData
)
);
});
AjaxHelpers
.
expectRequest
(
requests
,
'POST'
,
FORM_DESCRIPTION
.
submit_url
,
$
.
param
(
expectedData
)
);
});
it
(
'displays third-party auth registration buttons'
,
function
()
{
createRegisterView
(
this
);
it
(
'displays third-party auth registration buttons'
,
function
()
{
createRegisterView
(
this
);
// Verify that Google and Facebook registration buttons are displayed
expect
(
$
(
'.button-oa2-google-oauth2'
)).
toBeVisible
();
expect
(
$
(
'.button-oa2-facebook'
)).
toBeVisible
();
});
// Verify that Google and Facebook registration buttons are displayed
expect
(
$
(
'.button-oa2-google-oauth2'
)).
toBeVisible
();
expect
(
$
(
'.button-oa2-facebook'
)).
toBeVisible
();
});
it
(
'validates registration form fields'
,
function
()
{
createRegisterView
(
this
);
it
(
'validates registration form fields'
,
function
()
{
createRegisterView
(
this
);
// Submit the form, with successful validation
submitForm
(
true
);
// Submit the form, with successful validation
submitForm
(
true
);
// Verify that validation of form fields occurred
expect
(
view
.
validate
).
toHaveBeenCalledWith
(
$
(
'#register-email'
)[
0
]);
expect
(
view
.
validate
).
toHaveBeenCalledWith
(
$
(
'#register-name'
)[
0
]);
expect
(
view
.
validate
).
toHaveBeenCalledWith
(
$
(
'#register-username'
)[
0
]);
expect
(
view
.
validate
).
toHaveBeenCalledWith
(
$
(
'#register-password'
)[
0
]);
// Verify that validation of form fields occurred
expect
(
view
.
validate
).
toHaveBeenCalledWith
(
$
(
'#register-email'
)[
0
]);
expect
(
view
.
validate
).
toHaveBeenCalledWith
(
$
(
'#register-name'
)[
0
]);
expect
(
view
.
validate
).
toHaveBeenCalledWith
(
$
(
'#register-username'
)[
0
]);
expect
(
view
.
validate
).
toHaveBeenCalledWith
(
$
(
'#register-password'
)[
0
]);
// Verify that no submission errors are visible
expect
(
view
.
$errors
).
toHaveClass
(
'hidden'
);
// Form button should be disabled on success.
expect
(
view
.
$submitButton
).
toHaveAttr
(
'disabled'
);
});
// Verify that no submission errors are visible
expect
(
view
.
$errors
).
toHaveClass
(
'hidden'
);
// Form button should be disabled on success.
expect
(
view
.
$submitButton
).
toHaveAttr
(
'disabled'
);
});
it
(
'displays registration form validation errors'
,
function
()
{
createRegisterView
(
this
);
it
(
'displays registration form validation errors'
,
function
()
{
createRegisterView
(
this
);
// Submit the form, with failed validation
submitForm
(
false
);
// Submit the form, with failed validation
submitForm
(
false
);
// Verify that submission errors are visible
expect
(
view
.
$errors
).
not
.
toHaveClass
(
'hidden'
);
// Verify that submission errors are visible
expect
(
view
.
$errors
).
not
.
toHaveClass
(
'hidden'
);
// Expect that auth complete is NOT triggered
expect
(
authComplete
).
toBe
(
false
);
// Form button should be re-enabled on error.
expect
(
view
.
$submitButton
).
not
.
toHaveAttr
(
'disabled'
);
});
// Expect that auth complete is NOT triggered
expect
(
authComplete
).
toBe
(
false
);
// Form button should be re-enabled on error.
expect
(
view
.
$submitButton
).
not
.
toHaveAttr
(
'disabled'
);
});
it
(
'displays an error if the server returns an error while registering'
,
function
()
{
createRegisterView
(
this
);
it
(
'displays an error if the server returns an error while registering'
,
function
()
{
createRegisterView
(
this
);
// Submit the form, with successful validation
submitForm
(
true
);
// Submit the form, with successful validation
submitForm
(
true
);
// Simulate an error from the LMS servers
AjaxHelpers
.
respondWithError
(
requests
);
// Simulate an error from the LMS servers
AjaxHelpers
.
respondWithError
(
requests
);
// Expect that an error is displayed and that auth complete is NOT triggered
expect
(
view
.
$errors
).
not
.
toHaveClass
(
'hidden'
);
expect
(
authComplete
).
toBe
(
false
);
// Expect that an error is displayed and that auth complete is NOT triggered
expect
(
view
.
$errors
).
not
.
toHaveClass
(
'hidden'
);
expect
(
authComplete
).
toBe
(
false
);
// If we try again and succeed, the error should go away
submitForm
();
// If we try again and succeed, the error should go away
submitForm
();
// This time, respond with status code 200
AjaxHelpers
.
respondWithJson
(
requests
,
{});
// This time, respond with status code 200
AjaxHelpers
.
respondWithJson
(
requests
,
{});
// Expect that the error is hidden and that auth complete is triggered
expect
(
view
.
$errors
).
toHaveClass
(
'hidden'
);
expect
(
authComplete
).
toBe
(
true
);
// Form button should be disabled on success.
expect
(
view
.
$submitButton
).
toHaveAttr
(
'disabled'
);
// Expect that the error is hidden and that auth complete is triggered
expect
(
view
.
$errors
).
toHaveClass
(
'hidden'
);
expect
(
authComplete
).
toBe
(
true
);
// Form button should be disabled on success.
expect
(
view
.
$submitButton
).
toHaveAttr
(
'disabled'
);
});
});
});
});
})
.
call
(
this
,
define
||
RequireJS
.
define
)
;
lms/static/js/student_account/accessApp.js
deleted
100644 → 0
View file @
1ba4200a
var
edx
=
edx
||
{};
(
function
(
$
)
{
'use strict'
;
edx
.
student
=
edx
.
student
||
{};
edx
.
student
.
account
=
edx
.
student
.
account
||
{};
var
container
=
$
(
'#login-and-registration-container'
);
return
new
edx
.
student
.
account
.
AccessView
({
mode
:
container
.
data
(
'initial-mode'
),
thirdPartyAuth
:
container
.
data
(
'third-party-auth'
),
thirdPartyAuthHint
:
container
.
data
(
'third-party-auth-hint'
),
nextUrl
:
container
.
data
(
'next-url'
),
platformName
:
container
.
data
(
'platform-name'
),
loginFormDesc
:
container
.
data
(
'login-form-desc'
),
registrationFormDesc
:
container
.
data
(
'registration-form-desc'
),
passwordResetFormDesc
:
container
.
data
(
'password-reset-form-desc'
)
});
})(
jQuery
);
lms/static/js/student_account/logistration_factory.js
0 → 100644
View file @
d2a47908
;(
function
(
define
)
{
'use strict'
;
define
([
'jquery'
,
'js/student_account/views/AccessView'
],
function
(
$
,
AccessView
)
{
return
function
(
options
)
{
var
$logistrationElement
=
$
(
'#login-and-registration-container'
);
new
AccessView
(
_
.
extend
(
options
,
{
el
:
$logistrationElement
}));
};
}
);
}).
call
(
this
,
define
||
RequireJS
.
define
);
lms/static/js/student_account/models/LoginModel.js
View file @
d2a47908
var
edx
=
edx
||
{};
(
function
(
$
,
Backbone
)
{
;(
function
(
define
)
{
'use strict'
;
define
([
'jquery'
,
'backbone'
,
'jquery.url'
],
function
(
$
,
Backbone
)
{
return
Backbone
.
Model
.
extend
({
defaults
:
{
email
:
''
,
password
:
''
,
remember
:
false
},
ajaxType
:
''
,
urlRoot
:
''
,
initialize
:
function
(
attributes
,
options
)
{
this
.
ajaxType
=
options
.
method
;
this
.
urlRoot
=
options
.
url
;
},
sync
:
function
(
method
,
model
)
{
var
headers
=
{
'X-CSRFToken'
:
$
.
cookie
(
'csrftoken'
)},
data
=
{},
analytics
,
courseId
=
$
.
url
(
'?course_id'
);
// If there is a course ID in the query string param,
// send that to the server as well so it can be included
// in analytics events.
if
(
courseId
)
{
analytics
=
JSON
.
stringify
({
enroll_course_id
:
decodeURIComponent
(
courseId
)
});
}
edx
.
student
=
edx
.
student
||
{};
edx
.
student
.
account
=
edx
.
student
.
account
||
{};
edx
.
student
.
account
.
LoginModel
=
Backbone
.
Model
.
extend
({
defaults
:
{
email
:
''
,
password
:
''
,
remember
:
false
},
ajaxType
:
''
,
urlRoot
:
''
,
initialize
:
function
(
attributes
,
options
)
{
this
.
ajaxType
=
options
.
method
;
this
.
urlRoot
=
options
.
url
;
},
sync
:
function
(
method
,
model
)
{
var
headers
=
{
'X-CSRFToken'
:
$
.
cookie
(
'csrftoken'
)
},
data
=
{},
analytics
,
courseId
=
$
.
url
(
'?course_id'
);
// If there is a course ID in the query string param,
// send that to the server as well so it can be included
// in analytics events.
if
(
courseId
)
{
analytics
=
JSON
.
stringify
({
enroll_course_id
:
decodeURIComponent
(
courseId
)
// Include all form fields and analytics info in the data sent to the server
$
.
extend
(
data
,
model
.
attributes
,
{
analytics
:
analytics
});
$
.
ajax
({
url
:
model
.
urlRoot
,
type
:
model
.
ajaxType
,
data
:
data
,
headers
:
headers
,
success
:
function
()
{
model
.
trigger
(
'sync'
);
},
error
:
function
(
error
)
{
model
.
trigger
(
'error'
,
error
);
}
});
}
// Include all form fields and analytics info in the data sent to the server
$
.
extend
(
data
,
model
.
attributes
,
{
analytics
:
analytics
});
$
.
ajax
({
url
:
model
.
urlRoot
,
type
:
model
.
ajaxType
,
data
:
data
,
headers
:
headers
,
success
:
function
()
{
model
.
trigger
(
'sync'
);
},
error
:
function
(
error
)
{
model
.
trigger
(
'error'
,
error
);
}
});
}
});
});
})
(
jQuery
,
Backbo
ne
);
})
.
call
(
this
,
define
||
RequireJS
.
defi
ne
);
lms/static/js/student_account/models/PasswordResetModel.js
View file @
d2a47908
var
edx
=
edx
||
{};
(
function
(
$
,
Backbone
)
{
;(
function
(
define
)
{
'use strict'
;
edx
.
student
=
edx
.
student
||
{};
edx
.
student
.
account
=
edx
.
student
.
account
||
{};
edx
.
student
.
account
.
PasswordResetModel
=
Backbone
.
Model
.
extend
({
defaults
:
{
email
:
''
},
ajaxType
:
''
,
urlRoot
:
''
,
initialize
:
function
(
attributes
,
options
)
{
this
.
ajaxType
=
options
.
method
;
this
.
urlRoot
=
options
.
url
;
},
sync
:
function
(
method
,
model
)
{
var
headers
=
{
'X-CSRFToken'
:
$
.
cookie
(
'csrftoken'
)
};
// Only expects an email address.
$
.
ajax
({
url
:
model
.
urlRoot
,
type
:
model
.
ajaxType
,
data
:
model
.
attributes
,
headers
:
headers
,
success
:
function
()
{
model
.
trigger
(
'sync'
);
},
error
:
function
(
error
)
{
model
.
trigger
(
'error'
,
error
);
}
});
}
define
([
'jquery'
,
'backbone'
],
function
(
$
,
Backbone
)
{
return
Backbone
.
Model
.
extend
({
defaults
:
{
email
:
''
},
ajaxType
:
''
,
urlRoot
:
''
,
initialize
:
function
(
attributes
,
options
)
{
this
.
ajaxType
=
options
.
method
;
this
.
urlRoot
=
options
.
url
;
},
sync
:
function
(
method
,
model
)
{
var
headers
=
{
'X-CSRFToken'
:
$
.
cookie
(
'csrftoken'
)
};
// Only expects an email address.
$
.
ajax
({
url
:
model
.
urlRoot
,
type
:
model
.
ajaxType
,
data
:
model
.
attributes
,
headers
:
headers
,
success
:
function
()
{
model
.
trigger
(
'sync'
);
},
error
:
function
(
error
)
{
model
.
trigger
(
'error'
,
error
);
}
});
}
});
});
})
(
jQuery
,
Backbo
ne
);
})
.
call
(
this
,
define
||
RequireJS
.
defi
ne
);
lms/static/js/student_account/models/RegisterModel.js
View file @
d2a47908
var
edx
=
edx
||
{};
(
function
(
$
,
Backbone
)
{
;(
function
(
define
)
{
'use strict'
;
define
([
'jquery'
,
'backbone'
,
'jquery.url'
],
function
(
$
,
Backbone
)
{
return
Backbone
.
Model
.
extend
({
defaults
:
{
email
:
''
,
name
:
''
,
username
:
''
,
password
:
''
,
level_of_education
:
''
,
gender
:
''
,
year_of_birth
:
''
,
mailing_address
:
''
,
goals
:
''
},
ajaxType
:
''
,
urlRoot
:
''
,
initialize
:
function
(
attributes
,
options
)
{
this
.
ajaxType
=
options
.
method
;
this
.
urlRoot
=
options
.
url
;
},
sync
:
function
(
method
,
model
)
{
var
headers
=
{
'X-CSRFToken'
:
$
.
cookie
(
'csrftoken'
)
},
data
=
{},
courseId
=
$
.
url
(
'?course_id'
);
// If there is a course ID in the query string param,
// send that to the server as well so it can be included
// in analytics events.
if
(
courseId
)
{
data
.
course_id
=
decodeURIComponent
(
courseId
);
}
edx
.
student
=
edx
.
student
||
{};
edx
.
student
.
account
=
edx
.
student
.
account
||
{};
edx
.
student
.
account
.
RegisterModel
=
Backbone
.
Model
.
extend
({
defaults
:
{
email
:
''
,
name
:
''
,
username
:
''
,
password
:
''
,
level_of_education
:
''
,
gender
:
''
,
year_of_birth
:
''
,
mailing_address
:
''
,
goals
:
''
,
},
ajaxType
:
''
,
urlRoot
:
''
,
initialize
:
function
(
attributes
,
options
)
{
this
.
ajaxType
=
options
.
method
;
this
.
urlRoot
=
options
.
url
;
},
sync
:
function
(
method
,
model
)
{
var
headers
=
{
'X-CSRFToken'
:
$
.
cookie
(
'csrftoken'
)
},
data
=
{},
courseId
=
$
.
url
(
'?course_id'
);
// If there is a course ID in the query string param,
// send that to the server as well so it can be included
// in analytics events.
if
(
courseId
)
{
data
.
course_id
=
decodeURIComponent
(
courseId
);
// Include all form fields and analytics info in the data sent to the server
$
.
extend
(
data
,
model
.
attributes
);
$
.
ajax
({
url
:
model
.
urlRoot
,
type
:
model
.
ajaxType
,
data
:
data
,
headers
:
headers
,
success
:
function
()
{
model
.
trigger
(
'sync'
);
},
error
:
function
(
error
)
{
model
.
trigger
(
'error'
,
error
);
}
});
}
// Include all form fields and analytics info in the data sent to the server
$
.
extend
(
data
,
model
.
attributes
);
$
.
ajax
({
url
:
model
.
urlRoot
,
type
:
model
.
ajaxType
,
data
:
data
,
headers
:
headers
,
success
:
function
()
{
model
.
trigger
(
'sync'
);
},
error
:
function
(
error
)
{
model
.
trigger
(
'error'
,
error
);
}
});
}
});
});
})
(
jQuery
,
Backbo
ne
);
})
.
call
(
this
,
define
||
RequireJS
.
defi
ne
);
lms/static/js/student_account/views/AccessView.js
View file @
d2a47908
var
edx
=
edx
||
{};
(
function
(
$
,
_
,
_s
,
Backbone
,
History
)
{
;(
function
(
define
)
{
'use strict'
;
define
([
'jquery'
,
'utility'
,
'underscore'
,
'underscore.string'
,
'backbone'
,
'js/student_account/models/LoginModel'
,
'js/student_account/models/PasswordResetModel'
,
'js/student_account/models/RegisterModel'
,
'js/student_account/views/LoginView'
,
'js/student_account/views/PasswordResetView'
,
'js/student_account/views/RegisterView'
,
'js/student_account/views/InstitutionLoginView'
,
'js/student_account/views/HintedLoginView'
,
'js/vendor/history'
],
function
(
$
,
utility
,
_
,
_s
,
Backbone
,
LoginModel
,
PasswordResetModel
,
RegisterModel
,
LoginView
,
PasswordResetView
,
RegisterView
,
InstitutionLoginView
,
HintedLoginView
)
{
if
(
_
.
isUndefined
(
_s
))
{
_s
=
_
.
str
;
}
edx
.
student
=
edx
.
student
||
{};
edx
.
student
.
account
=
edx
.
student
.
account
||
{};
edx
.
student
.
account
.
AccessView
=
Backbone
.
View
.
extend
({
el
:
'#login-and-registration-container'
,
tpl
:
'#access-tpl'
,
events
:
{
'click .form-toggle'
:
'toggleForm'
},
subview
:
{
login
:
{},
register
:
{},
passwordHelp
:
{},
institutionLogin
:
{},
hintedLogin
:
{}
},
nextUrl
:
'/dashboard'
,
return
Backbone
.
View
.
extend
({
tpl
:
'#access-tpl'
,
events
:
{
'click .form-toggle'
:
'toggleForm'
},
subview
:
{
login
:
{},
register
:
{},
passwordHelp
:
{},
institutionLogin
:
{},
hintedLogin
:
{}
},
nextUrl
:
'/dashboard'
,
// The form currently loaded
activeForm
:
''
,
// The form currently loaded
activeForm
:
''
,
initialize
:
function
(
options
)
{
initialize
:
function
(
obj
)
{
/* Mix non-conflicting functions from underscore.string
* (all but include, contains, and reverse) into the
* Underscore namespace
*/
_
.
mixin
(
_s
.
exports
()
);
/* Mix non-conflicting functions from underscore.string
* (all but include, contains, and reverse) into the
* Underscore namespace
*/
_
.
mixin
(
_s
.
exports
()
);
this
.
tpl
=
$
(
this
.
tpl
).
html
();
this
.
tpl
=
$
(
this
.
tpl
).
html
();
this
.
activeForm
=
obj
.
mode
||
'login'
;
this
.
activeForm
=
options
.
initial_
mode
||
'login'
;
this
.
thirdPartyAuth
=
obj
.
thirdPartyA
uth
||
{
currentProvider
:
null
,
providers
:
[]
};
this
.
thirdPartyAuth
=
options
.
third_party_a
uth
||
{
currentProvider
:
null
,
providers
:
[]
};
this
.
thirdPartyAuthHint
=
obj
.
thirdPartyAuthH
int
||
null
;
this
.
thirdPartyAuthHint
=
options
.
third_party_auth_h
int
||
null
;
if
(
obj
.
nextUrl
)
{
// Ensure that the next URL is internal for security reasons
if
(
!
window
.
isExternal
(
obj
.
nextUrl
)
)
{
this
.
nextUrl
=
obj
.
nextUrl
;
if
(
options
.
login_redirect_url
)
{
// Ensure that the next URL is internal for security reasons
if
(
!
window
.
isExternal
(
options
.
login_redirect_url
)
)
{
this
.
nextUrl
=
options
.
login_redirect_url
;
}
}
}
this
.
formDescriptions
=
{
login
:
obj
.
loginFormDesc
,
register
:
obj
.
registrationFormDesc
,
reset
:
obj
.
passwordResetFormDesc
,
institution_login
:
null
,
hinted_login
:
null
};
this
.
platformName
=
obj
.
platformName
;
// The login view listens for 'sync' events from the reset model
this
.
resetModel
=
new
edx
.
student
.
account
.
PasswordResetModel
({},
{
method
:
'GET'
,
url
:
'#'
});
this
.
render
();
// Once the third party error message has been shown once,
// there is no need to show it again, if the user changes mode:
this
.
thirdPartyAuth
.
errorMessage
=
null
;
},
render
:
function
()
{
$
(
this
.
el
).
html
(
_
.
template
(
this
.
tpl
,
{
mode
:
this
.
activeForm
}));
this
.
postRender
();
return
this
;
},
postRender
:
function
()
{
//get & check current url hash part & load form accordingly
if
(
Backbone
.
history
.
getHash
()
===
"forgot-password-modal"
)
{
this
.
resetPassword
();
}
else
{
this
.
loadForm
(
this
.
activeForm
);
}
},
loadForm
:
function
(
type
)
{
var
loadFunc
=
_
.
bind
(
this
.
load
[
type
],
this
);
loadFunc
(
this
.
formDescriptions
[
type
]
);
},
load
:
{
login
:
function
(
data
)
{
var
model
=
new
edx
.
student
.
account
.
LoginModel
({},
{
method
:
data
.
method
,
url
:
data
.
submit_url
});
this
.
formDescriptions
=
{
login
:
options
.
login_form_desc
,
register
:
options
.
registration_form_desc
,
reset
:
options
.
password_reset_form_desc
,
institution_login
:
null
,
hinted_login
:
null
};
this
.
subview
.
login
=
new
edx
.
student
.
account
.
LoginView
({
fields
:
data
.
fields
,
model
:
model
,
resetModel
:
this
.
resetModel
,
thirdPartyAuth
:
this
.
thirdPartyAuth
,
platformName
:
this
.
platformName
});
this
.
platformName
=
options
.
platform_name
;
// Listen for 'password-help' event to toggle sub-views
this
.
listenTo
(
this
.
subview
.
login
,
'password-help'
,
this
.
resetPassword
);
// The login view listens for 'sync' events from the reset model
this
.
resetModel
=
new
PasswordResetModel
({},
{
method
:
'GET'
,
url
:
'#'
});
// Listen for 'auth-complete' event so we can enroll/redirect the user appropriately.
this
.
listenTo
(
this
.
subview
.
login
,
'auth-complete'
,
this
.
authComplete
);
this
.
render
();
// Once the third party error message has been shown once,
// there is no need to show it again, if the user changes mode:
this
.
thirdPartyAuth
.
errorMessage
=
null
;
},
reset
:
function
(
data
)
{
this
.
resetModel
.
ajaxType
=
data
.
method
;
this
.
resetModel
.
urlRoot
=
data
.
submit_url
;
render
:
function
()
{
$
(
this
.
el
).
html
(
_
.
template
(
this
.
tpl
,
{
mode
:
this
.
activeForm
}));
this
.
subview
.
passwordHelp
=
new
edx
.
student
.
account
.
PasswordResetView
({
fields
:
data
.
fields
,
model
:
this
.
resetModel
});
this
.
postRender
();
// Listen for 'password-email-sent' event to toggle sub-views
this
.
listenTo
(
this
.
subview
.
passwordHelp
,
'password-email-sent'
,
this
.
passwordEmailSent
);
return
this
;
},
// Focus on the form
$
(
'.password-reset-form'
).
focus
();
postRender
:
function
()
{
//get & check current url hash part & load form accordingly
if
(
Backbone
.
history
.
getHash
()
===
'forgot-password-modal'
)
{
this
.
resetPassword
();
}
else
{
this
.
loadForm
(
this
.
activeForm
);
}
},
register
:
function
(
data
)
{
var
model
=
new
edx
.
student
.
account
.
RegisterModel
({},
{
method
:
data
.
method
,
url
:
data
.
submit_url
});
loadForm
:
function
(
type
)
{
var
loadFunc
=
_
.
bind
(
this
.
load
[
type
],
this
);
loadFunc
(
this
.
formDescriptions
[
type
]
);
},
this
.
subview
.
register
=
new
edx
.
student
.
account
.
RegisterView
({
fields
:
data
.
fields
,
model
:
model
,
thirdPartyAuth
:
this
.
thirdPartyAuth
,
platformName
:
this
.
platformName
});
load
:
{
login
:
function
(
data
)
{
var
model
=
new
LoginModel
({},
{
method
:
data
.
method
,
url
:
data
.
submit_url
});
this
.
subview
.
login
=
new
LoginView
({
fields
:
data
.
fields
,
model
:
model
,
resetModel
:
this
.
resetModel
,
thirdPartyAuth
:
this
.
thirdPartyAuth
,
platformName
:
this
.
platformName
});
// Listen for 'password-help' event to toggle sub-views
this
.
listenTo
(
this
.
subview
.
login
,
'password-help'
,
this
.
resetPassword
);
// Listen for 'auth-complete' event so we can enroll/redirect the user appropriately.
this
.
listenTo
(
this
.
subview
.
login
,
'auth-complete'
,
this
.
authComplete
);
},
reset
:
function
(
data
)
{
this
.
resetModel
.
ajaxType
=
data
.
method
;
this
.
resetModel
.
urlRoot
=
data
.
submit_url
;
this
.
subview
.
passwordHelp
=
new
PasswordResetView
({
fields
:
data
.
fields
,
model
:
this
.
resetModel
});
// Listen for 'password-email-sent' event to toggle sub-views
this
.
listenTo
(
this
.
subview
.
passwordHelp
,
'password-email-sent'
,
this
.
passwordEmailSent
);
// Focus on the form
$
(
'.password-reset-form'
).
focus
();
},
register
:
function
(
data
)
{
var
model
=
new
RegisterModel
({},
{
method
:
data
.
method
,
url
:
data
.
submit_url
});
this
.
subview
.
register
=
new
RegisterView
({
fields
:
data
.
fields
,
model
:
model
,
thirdPartyAuth
:
this
.
thirdPartyAuth
,
platformName
:
this
.
platformName
});
// Listen for 'auth-complete' event so we can enroll/redirect the user appropriately.
this
.
listenTo
(
this
.
subview
.
register
,
'auth-complete'
,
this
.
authComplete
);
},
institution_login
:
function
(
unused
)
{
this
.
subview
.
institutionLogin
=
new
InstitutionLoginView
({
thirdPartyAuth
:
this
.
thirdPartyAuth
,
platformName
:
this
.
platformName
,
mode
:
this
.
activeForm
});
this
.
subview
.
institutionLogin
.
render
();
},
hinted_login
:
function
(
unused
)
{
this
.
subview
.
hintedLogin
=
new
HintedLoginView
({
thirdPartyAuth
:
this
.
thirdPartyAuth
,
hintedProvider
:
this
.
thirdPartyAuthHint
,
platformName
:
this
.
platformName
});
this
.
subview
.
hintedLogin
.
render
();
}
},
// Listen for 'auth-complete' event so we can enroll/redirect the user appropriately.
this
.
listenTo
(
this
.
subview
.
register
,
'auth-complete'
,
this
.
authComplete
);
passwordEmailSent
:
function
()
{
var
$loginAnchorElement
=
$
(
'#login-anchor'
);
this
.
element
.
hide
(
$
(
this
.
el
).
find
(
'#password-reset-anchor'
)
);
this
.
element
.
show
(
$loginAnchorElement
);
this
.
element
.
scrollTop
(
$loginAnchorElement
);
},
institution_login
:
function
(
unused
)
{
this
.
subview
.
institutionLogin
=
new
edx
.
student
.
account
.
InstitutionLoginView
({
thirdPartyAuth
:
this
.
thirdPartyAuth
,
platformName
:
this
.
platformName
,
mode
:
this
.
activeForm
resetPassword
:
function
()
{
window
.
analytics
.
track
(
'edx.bi.password_reset_form.viewed'
,
{
category
:
'user-engagement'
});
this
.
subview
.
institutionLogin
.
render
();
this
.
element
.
hide
(
$
(
this
.
el
).
find
(
'#login-anchor'
)
);
this
.
loadForm
(
'reset'
);
this
.
element
.
scrollTop
(
$
(
'#password-reset-anchor'
)
);
},
hinted_login
:
function
(
unused
)
{
this
.
subview
.
hintedLogin
=
new
edx
.
student
.
account
.
HintedLoginView
({
thirdPartyAuth
:
this
.
thirdPartyAuth
,
hintedProvider
:
this
.
thirdPartyAuthHint
,
platformName
:
this
.
platformName
toggleForm
:
function
(
e
)
{
var
type
=
$
(
e
.
currentTarget
).
data
(
'type'
),
$form
=
$
(
'#'
+
type
+
'-form'
),
$anchor
=
$
(
'#'
+
type
+
'-anchor'
),
queryParams
=
url
(
'?'
),
queryStr
=
queryParams
.
length
>
0
?
'?'
+
queryParams
:
''
;
e
.
preventDefault
();
window
.
analytics
.
track
(
'edx.bi.'
+
type
+
'_form.toggled'
,
{
category
:
'user-engagement'
});
this
.
subview
.
hintedLogin
.
render
();
}
},
passwordEmailSent
:
function
()
{
this
.
element
.
hide
(
$
(
this
.
el
).
find
(
'#password-reset-anchor'
)
);
this
.
element
.
show
(
$
(
'#login-anchor'
)
);
this
.
element
.
scrollTop
(
$
(
'#login-anchor'
)
);
},
resetPassword
:
function
()
{
window
.
analytics
.
track
(
'edx.bi.password_reset_form.viewed'
,
{
category
:
'user-engagement'
});
this
.
element
.
hide
(
$
(
this
.
el
).
find
(
'#login-anchor'
)
);
this
.
loadForm
(
'reset'
);
this
.
element
.
scrollTop
(
$
(
'#password-reset-anchor'
)
);
},
toggleForm
:
function
(
e
)
{
var
type
=
$
(
e
.
currentTarget
).
data
(
'type'
),
$form
=
$
(
'#'
+
type
+
'-form'
),
$anchor
=
$
(
'#'
+
type
+
'-anchor'
),
queryParams
=
url
(
'?'
),
queryStr
=
queryParams
.
length
>
0
?
'?'
+
queryParams
:
''
;
e
.
preventDefault
();
window
.
analytics
.
track
(
'edx.bi.'
+
type
+
'_form.toggled'
,
{
category
:
'user-engagement'
});
// Load the form. Institution login is always refreshed since it changes based on the previous form.
if
(
!
this
.
form
.
isLoaded
(
$form
)
||
type
==
"institution_login"
)
{
this
.
loadForm
(
type
);
}
this
.
activeForm
=
type
;
// Load the form. Institution login is always refreshed since it changes based on the previous form.
if
(
!
this
.
form
.
isLoaded
(
$form
)
||
type
==
'institution_login'
)
{
this
.
loadForm
(
type
);
}
this
.
activeForm
=
type
;
this
.
element
.
hide
(
$
(
this
.
el
).
find
(
'.submission-success'
)
);
this
.
element
.
hide
(
$
(
this
.
el
).
find
(
'.form-wrapper'
)
);
this
.
element
.
show
(
$form
);
this
.
element
.
scrollTop
(
$anchor
);
this
.
element
.
hide
(
$
(
this
.
el
).
find
(
'.submission-success'
)
);
this
.
element
.
hide
(
$
(
this
.
el
).
find
(
'.form-wrapper'
)
);
this
.
element
.
show
(
$form
);
this
.
element
.
scrollTop
(
$anchor
);
// Update url without reloading page
if
(
type
!=
"institution_login"
)
{
History
.
pushState
(
null
,
document
.
title
,
'/'
+
type
+
queryStr
);
}
analytics
.
page
(
'login_and_registration'
,
type
);
// Focus on the form
$
(
"#"
+
type
).
focus
();
},
/**
* Once authentication has completed successfully:
*
* If we're in a third party auth pipeline, we must complete the pipeline.
* Otherwise, redirect to the specified next step.
*
*/
authComplete
:
function
()
{
if
(
this
.
thirdPartyAuth
&&
this
.
thirdPartyAuth
.
finishAuthUrl
)
{
this
.
redirect
(
this
.
thirdPartyAuth
.
finishAuthUrl
);
// Note: the third party auth URL likely contains another redirect URL embedded inside
}
else
{
this
.
redirect
(
this
.
nextUrl
);
}
},
/**
* Redirect to a URL. Mainly useful for mocking out in tests.
* @param {string} url The URL to redirect to.
*/
redirect
:
function
(
url
)
{
window
.
location
.
replace
(
url
);
},
form
:
{
isLoaded
:
function
(
$form
)
{
return
$form
.
html
().
length
>
0
;
}
},
/* Helper method to toggle display
* including accessibility considerations
*/
element
:
{
hide
:
function
(
$el
)
{
$el
.
addClass
(
'hidden'
);
// Update url without reloading page
if
(
type
!=
'institution_login'
)
{
History
.
pushState
(
null
,
document
.
title
,
'/'
+
type
+
queryStr
);
}
analytics
.
page
(
'login_and_registration'
,
type
);
// Focus on the form
$
(
'#'
+
type
).
focus
();
},
/**
* Once authentication has completed successfully:
*
* If we're in a third party auth pipeline, we must complete the pipeline.
* Otherwise, redirect to the specified next step.
*
*/
authComplete
:
function
()
{
if
(
this
.
thirdPartyAuth
&&
this
.
thirdPartyAuth
.
finishAuthUrl
)
{
this
.
redirect
(
this
.
thirdPartyAuth
.
finishAuthUrl
);
// Note: the third party auth URL likely contains another redirect URL embedded inside
}
else
{
this
.
redirect
(
this
.
nextUrl
);
}
},
/**
* Redirect to a URL. Mainly useful for mocking out in tests.
* @param {string} url The URL to redirect to.
*/
redirect
:
function
(
url
)
{
window
.
location
.
replace
(
url
);
},
scrollTop
:
function
(
$el
)
{
// Scroll to top of selected element
$
(
'html,body'
).
animate
({
scrollTop
:
$el
.
offset
().
top
},
'slow'
);
form
:
{
isLoaded
:
function
(
$form
)
{
return
$form
.
html
().
length
>
0
;
}
},
show
:
function
(
$el
)
{
$el
.
removeClass
(
'hidden'
);
/* Helper method to toggle display
* including accessibility considerations
*/
element
:
{
hide
:
function
(
$el
)
{
$el
.
addClass
(
'hidden'
);
},
scrollTop
:
function
(
$el
)
{
// Scroll to top of selected element
$
(
'html,body'
).
animate
({
scrollTop
:
$el
.
offset
().
top
},
'slow'
);
},
show
:
function
(
$el
)
{
$el
.
removeClass
(
'hidden'
);
}
}
}
}
);
});
})
(
jQuery
,
_
,
_
.
str
,
Backbone
,
History
);
})
.
call
(
this
,
define
||
RequireJS
.
define
);
lms/static/js/student_account/views/FormView.js
View file @
d2a47908
var
edx
=
edx
||
{};
(
function
(
$
,
_
,
Backbone
,
gettext
)
{
;(
function
(
define
)
{
'use strict'
;
define
([
'jquery'
,
'underscore'
,
'backbone'
,
'js/utils/edx.utils.validate'
],
function
(
$
,
_
,
Backbone
,
EdxUtilsValidate
)
{
edx
.
student
=
edx
.
student
||
{};
edx
.
student
.
account
=
edx
.
student
.
account
||
{};
edx
.
student
.
account
.
FormView
=
Backbone
.
View
.
extend
({
tagName
:
'form'
,
return
Backbone
.
View
.
extend
({
tagName
:
'form'
,
el
:
''
,
el
:
''
,
tpl
:
''
,
tpl
:
''
,
fieldTpl
:
'#form_field-tpl'
,
fieldTpl
:
'#form_field-tpl'
,
events
:
{},
events
:
{},
errors
:
[],
errors
:
[],
formType
:
''
,
formType
:
''
,
$form
:
{},
$form
:
{},
fields
:
[],
fields
:
[],
// String to append to required label fields
requiredStr
:
'*'
,
// String to append to required label fields
requiredStr
:
'*'
,
submitButton
:
''
,
submitButton
:
''
,
initialize
:
function
(
data
)
{
this
.
model
=
data
.
model
;
this
.
preRender
(
data
);
initialize
:
function
(
data
)
{
this
.
model
=
data
.
model
;
this
.
preRender
(
data
);
this
.
tpl
=
$
(
this
.
tpl
).
html
();
this
.
fieldTpl
=
$
(
this
.
fieldTpl
).
html
();
this
.
buildForm
(
data
.
fields
);
this
.
tpl
=
$
(
this
.
tpl
).
html
();
this
.
fieldTpl
=
$
(
this
.
fieldTpl
).
html
();
this
.
buildForm
(
data
.
fields
);
this
.
listenTo
(
this
.
model
,
'error'
,
this
.
saveError
);
},
this
.
listenTo
(
this
.
model
,
'error'
,
this
.
saveError
);
},
/* Allows extended views to add custom
* init steps without needing to repeat
* default init steps
*/
preRender
:
function
(
data
)
{
/* Custom code goes here */
return
data
;
},
/* Allows extended views to add custom
* init steps without needing to repeat
* default init steps
*/
preRender
:
function
(
data
)
{
/* Custom code goes here */
return
data
;
},
render
:
function
(
html
)
{
var
fields
=
html
||
''
;
render
:
function
(
html
)
{
var
fields
=
html
||
''
;
$
(
this
.
el
).
html
(
_
.
template
(
this
.
tpl
,
{
fields
:
fields
}));
$
(
this
.
el
).
html
(
_
.
template
(
this
.
tpl
,
{
fields
:
fields
}));
this
.
postRender
();
this
.
postRender
();
return
this
;
},
return
this
;
},
postRender
:
function
()
{
var
$container
=
$
(
this
.
el
);
postRender
:
function
()
{
var
$container
=
$
(
this
.
el
);
this
.
$form
=
$container
.
find
(
'form'
);
this
.
$errors
=
$container
.
find
(
'.submission-error'
);
this
.
$submitButton
=
$container
.
find
(
this
.
submitButton
);
},
this
.
$form
=
$container
.
find
(
'form'
);
this
.
$errors
=
$container
.
find
(
'.submission-error'
);
this
.
$submitButton
=
$container
.
find
(
this
.
submitButton
);
},
buildForm
:
function
(
data
)
{
var
html
=
[],
i
,
len
=
data
.
length
,
fieldTpl
=
this
.
fieldTpl
;
buildForm
:
function
(
data
)
{
var
html
=
[],
i
,
len
=
data
.
length
,
fieldTpl
=
this
.
fieldTpl
;
this
.
fields
=
data
;
this
.
fields
=
data
;
for
(
i
=
0
;
i
<
len
;
i
++
)
{
if
(
data
[
i
].
errorMessages
)
{
data
[
i
].
errorMessages
=
this
.
escapeStrings
(
data
[
i
].
errorMessages
);
}
for
(
i
=
0
;
i
<
len
;
i
++
)
{
if
(
data
[
i
].
errorMessages
)
{
data
[
i
].
errorMessages
=
this
.
escapeStrings
(
data
[
i
].
errorMessages
);
html
.
push
(
_
.
template
(
fieldTpl
,
$
.
extend
(
data
[
i
],
{
form
:
this
.
formType
,
requiredStr
:
this
.
requiredStr
})
)
);
}
html
.
push
(
_
.
template
(
fieldTpl
,
$
.
extend
(
data
[
i
],
{
form
:
this
.
formType
,
requiredStr
:
this
.
requiredStr
})
)
);
}
this
.
render
(
html
.
join
(
''
)
);
},
this
.
render
(
html
.
join
(
''
)
);
},
/* Helper method to toggle display
* including accessibility considerations
*/
element
:
{
hide
:
function
(
$el
)
{
if
(
$el
)
{
$el
.
addClass
(
'hidden'
);
/* Helper method to toggle display
* including accessibility considerations
*/
element
:
{
hide
:
function
(
$el
)
{
if
(
$el
)
{
$el
.
addClass
(
'hidden'
);
}
},
scrollTop
:
function
(
$el
)
{
// Scroll to top of selected element
$
(
'html,body'
).
animate
({
scrollTop
:
$el
.
offset
().
top
},
'slow'
);
},
show
:
function
(
$el
)
{
if
(
$el
)
{
$el
.
removeClass
(
'hidden'
);
}
}
},
scrollTop
:
function
(
$el
)
{
// Scroll to top of selected element
$
(
'html,body'
).
animate
({
scrollTop
:
$el
.
offset
().
top
},
'slow'
);
escapeStrings
:
function
(
obj
)
{
_
.
each
(
obj
,
function
(
val
,
key
)
{
obj
[
key
]
=
_
.
escape
(
val
);
});
return
obj
;
},
show
:
function
(
$el
)
{
if
(
$el
)
{
$el
.
removeClass
(
'hidden'
);
focusFirstError
:
function
()
{
var
$error
=
this
.
$form
.
find
(
'.error'
).
first
(),
$field
=
{},
$parent
=
{};
if
(
$error
.
is
(
'label'
)
)
{
$parent
=
$error
.
parent
(
'.form-field'
);
$error
=
$parent
.
find
(
'input'
)
||
$parent
.
find
(
'select'
);
}
else
{
$field
=
$error
;
}
}
},
escapeStrings
:
function
(
obj
)
{
_
.
each
(
obj
,
function
(
val
,
key
)
{
obj
[
key
]
=
_
.
escape
(
val
);
});
return
obj
;
},
focusFirstError
:
function
()
{
var
$error
=
this
.
$form
.
find
(
'.error'
).
first
(),
$field
=
{},
$parent
=
{};
if
(
$error
.
is
(
'label'
)
)
{
$parent
=
$error
.
parent
(
'.form-field'
);
$error
=
$parent
.
find
(
'input'
)
||
$parent
.
find
(
'select'
);
}
else
{
$field
=
$error
;
}
$error
.
focus
();
},
forgotPassword
:
function
(
event
)
{
event
.
preventDefault
();
this
.
trigger
(
'password-help'
);
},
getFormData
:
function
()
{
var
obj
=
{},
$form
=
this
.
$form
,
elements
=
$form
[
0
].
elements
,
i
,
len
=
elements
.
length
,
$el
,
$label
,
key
=
''
,
errors
=
[],
test
=
{};
for
(
i
=
0
;
i
<
len
;
i
++
)
{
$el
=
$
(
elements
[
i
]
);
$label
=
$form
.
find
(
'label[for='
+
$el
.
attr
(
'id'
)
+
']'
);
key
=
$el
.
attr
(
'name'
)
||
false
;
if
(
key
)
{
test
=
this
.
validate
(
elements
[
i
]
);
if
(
test
.
isValid
)
{
obj
[
key
]
=
$el
.
attr
(
'type'
)
===
'checkbox'
?
$el
.
is
(
':checked'
)
:
$el
.
val
();
$el
.
removeClass
(
'error'
);
$label
.
removeClass
(
'error'
);
}
else
{
errors
.
push
(
test
.
message
);
$el
.
addClass
(
'error'
);
$label
.
addClass
(
'error'
);
$error
.
focus
();
},
forgotPassword
:
function
(
event
)
{
event
.
preventDefault
();
this
.
trigger
(
'password-help'
);
},
getFormData
:
function
()
{
var
obj
=
{},
$form
=
this
.
$form
,
elements
=
$form
[
0
].
elements
,
i
,
len
=
elements
.
length
,
$el
,
$label
,
key
=
''
,
errors
=
[],
test
=
{};
for
(
i
=
0
;
i
<
len
;
i
++
)
{
$el
=
$
(
elements
[
i
]
);
$label
=
$form
.
find
(
'label[for='
+
$el
.
attr
(
'id'
)
+
']'
);
key
=
$el
.
attr
(
'name'
)
||
false
;
if
(
key
)
{
test
=
this
.
validate
(
elements
[
i
]
);
if
(
test
.
isValid
)
{
obj
[
key
]
=
$el
.
attr
(
'type'
)
===
'checkbox'
?
$el
.
is
(
':checked'
)
:
$el
.
val
();
$el
.
removeClass
(
'error'
);
$label
.
removeClass
(
'error'
);
}
else
{
errors
.
push
(
test
.
message
);
$el
.
addClass
(
'error'
);
$label
.
addClass
(
'error'
);
}
}
}
}
this
.
errors
=
_
.
uniq
(
errors
);
this
.
errors
=
_
.
uniq
(
errors
);
return
obj
;
},
return
obj
;
},
saveError
:
function
(
error
)
{
this
.
errors
=
[
'<li>'
+
error
.
responseText
+
'</li>'
];
this
.
setErrors
();
this
.
toggleDisableButton
(
false
);
},
saveError
:
function
(
error
)
{
this
.
errors
=
[
'<li>'
+
error
.
responseText
+
'</li>'
];
this
.
setErrors
();
this
.
toggleDisableButton
(
false
);
},
setErrors
:
function
()
{
var
$msg
=
this
.
$errors
.
find
(
'.message-copy'
),
html
=
[],
errors
=
this
.
errors
,
i
,
len
=
errors
.
length
;
setErrors
:
function
()
{
var
$msg
=
this
.
$errors
.
find
(
'.message-copy'
),
html
=
[],
errors
=
this
.
errors
,
i
,
len
=
errors
.
length
;
for
(
i
=
0
;
i
<
len
;
i
++
)
{
html
.
push
(
errors
[
i
]
);
}
for
(
i
=
0
;
i
<
len
;
i
++
)
{
html
.
push
(
errors
[
i
]
);
}
$msg
.
html
(
html
.
join
(
''
)
);
$msg
.
html
(
html
.
join
(
''
)
);
this
.
element
.
show
(
this
.
$errors
);
this
.
element
.
show
(
this
.
$errors
);
// Scroll to error messages
$
(
'html,body'
).
animate
({
scrollTop
:
this
.
$errors
.
offset
().
top
},
'slow'
);
// Focus on first error field
this
.
focusFirstError
();
},
// Scroll to error messages
$
(
'html,body'
).
animate
({
scrollTop
:
this
.
$errors
.
offset
().
top
},
'slow'
);
submitForm
:
function
(
event
)
{
var
data
=
this
.
getFormData
();
// Focus on first error field
this
.
focusFirstError
();
},
if
(
!
_
.
isUndefined
(
event
))
{
event
.
preventDefault
();
}
submitForm
:
function
(
event
)
{
var
data
=
this
.
getFormData
();
this
.
toggleDisableButton
(
true
);
if
(
!
_
.
isUndefined
(
event
))
{
event
.
preventDefault
();
}
if
(
!
_
.
compact
(
this
.
errors
).
length
)
{
this
.
model
.
set
(
data
);
this
.
model
.
save
();
this
.
toggleErrorMsg
(
false
);
}
else
{
this
.
toggleErrorMsg
(
true
);
}
this
.
toggleDisableButton
(
true
);
this
.
postFormSubmission
();
},
if
(
!
_
.
compact
(
this
.
errors
).
length
)
{
this
.
model
.
set
(
data
);
this
.
model
.
save
();
this
.
toggleErrorMsg
(
false
);
}
else
{
this
.
toggleErrorMsg
(
true
);
}
/* Allows extended views to add custom
* code after form submission
*/
postFormSubmission
:
function
()
{
return
true
;
},
this
.
postFormSubmission
();
},
toggleErrorMsg
:
function
(
show
)
{
if
(
show
)
{
this
.
setErrors
();
this
.
toggleDisableButton
(
false
);
}
else
{
this
.
element
.
hide
(
this
.
$errors
);
}
},
/* Allows extended views to add custom
* code after form submission
*/
postFormSubmission
:
function
()
{
return
true
;
},
/**
* If a form button is defined for this form, this will disable the button on
* submit, and re-enable the button if an error occurs.
*
* Args:
* disabled (boolean): If set to TRUE, disable the button.
*
*/
toggleDisableButton
:
function
(
disabled
)
{
if
(
this
.
$submitButton
)
{
this
.
$submitButton
.
attr
(
'disabled'
,
disabled
);
}
},
toggleErrorMsg
:
function
(
show
)
{
if
(
show
)
{
this
.
setErrors
();
this
.
toggleDisableButton
(
false
);
}
else
{
this
.
element
.
hide
(
this
.
$errors
);
validate
:
function
(
$el
)
{
return
EdxUtilsValidate
.
validate
(
$el
);
}
},
/**
* If a form button is defined for this form, this will disable the button on
* submit, and re-enable the button if an error occurs.
*
* Args:
* disabled (boolean): If set to TRUE, disable the button.
*
*/
toggleDisableButton
:
function
(
disabled
)
{
if
(
this
.
$submitButton
)
{
this
.
$submitButton
.
attr
(
'disabled'
,
disabled
);
}
},
validate
:
function
(
$el
)
{
return
edx
.
utils
.
validate
(
$el
);
}
});
});
})(
jQuery
,
_
,
Backbone
,
gettext
);
}).
call
(
this
,
define
||
RequireJS
.
define
);
lms/static/js/student_account/views/HintedLoginView.js
View file @
d2a47908
var
edx
=
edx
||
{};
(
function
(
$
,
_
,
gettext
)
{
;(
function
(
define
)
{
'use strict'
;
edx
.
student
=
edx
.
student
||
{};
edx
.
student
.
account
=
edx
.
student
.
account
||
{};
edx
.
student
.
account
.
HintedLoginView
=
Backbone
.
View
.
extend
({
el
:
'#hinted-login-form'
,
tpl
:
'#hinted_login-tpl'
,
events
:
{
'click .proceed-button'
:
'proceedWithHintedAuth'
},
formType
:
'hinted-login'
,
initialize
:
function
(
data
)
{
this
.
tpl
=
$
(
this
.
tpl
).
html
();
this
.
hintedProvider
=
(
_
.
findWhere
(
data
.
thirdPartyAuth
.
providers
,
{
id
:
data
.
hintedProvider
})
||
_
.
findWhere
(
data
.
thirdPartyAuth
.
secondaryProviders
,
{
id
:
data
.
hintedProvider
})
);
},
render
:
function
()
{
$
(
this
.
el
).
html
(
_
.
template
(
this
.
tpl
,
{
hintedProvider
:
this
.
hintedProvider
}));
return
this
;
},
proceedWithHintedAuth
:
function
(
event
)
{
this
.
redirect
(
this
.
hintedProvider
.
loginUrl
);
},
/**
* Redirect to a URL. Mainly useful for mocking out in tests
.
* @param {string} url The URL to redirect to.
*/
redirect
:
function
(
url
)
{
window
.
location
.
href
=
url
;
}
define
([
'jquery'
,
'underscore'
,
'backbone'
],
function
(
$
,
_
,
Backbone
)
{
return
Backbone
.
View
.
extend
({
el
:
'#hinted-login-form'
,
tpl
:
'#hinted_login-tpl'
,
events
:
{
'click .proceed-button'
:
'proceedWithHintedAuth'
},
formType
:
'hinted-login'
,
initialize
:
function
(
data
)
{
this
.
tpl
=
$
(
this
.
tpl
).
html
();
this
.
hintedProvider
=
(
_
.
findWhere
(
data
.
thirdPartyAuth
.
providers
,
{
id
:
data
.
hintedProvider
})
||
_
.
findWhere
(
data
.
thirdPartyAuth
.
secondaryProviders
,
{
id
:
data
.
hintedProvider
})
);
},
render
:
function
()
{
$
(
this
.
el
).
html
(
_
.
template
(
this
.
tpl
,
{
hintedProvider
:
this
.
hintedProvider
}));
return
this
;
},
proceedWithHintedAuth
:
function
(
event
)
{
this
.
redirect
(
this
.
hintedProvider
.
loginUrl
);
},
/**
* Redirect to a URL. Mainly useful for mocking out in tests.
* @param {string} url The URL to redirect to
.
*/
redirect
:
function
(
url
)
{
window
.
location
.
href
=
url
;
}
}
);
});
})
(
jQuery
,
_
,
gettext
);
})
.
call
(
this
,
define
||
RequireJS
.
define
);
lms/static/js/student_account/views/InstitutionLoginView.js
View file @
d2a47908
var
edx
=
edx
||
{};
(
function
(
$
,
_
,
Backbone
)
{
;(
function
(
define
)
{
'use strict'
;
define
([
'jquery'
,
'underscore'
,
'backbone'
],
function
(
$
,
_
,
Backbone
)
{
edx
.
student
=
edx
.
student
||
{};
edx
.
student
.
account
=
edx
.
student
.
account
||
{};
edx
.
student
.
account
.
InstitutionLoginView
=
Backbone
.
View
.
extend
({
el
:
'#institution_login-form'
,
return
Backbone
.
View
.
extend
({
el
:
'#institution_login-form'
,
initialize
:
function
(
data
)
{
var
tpl
=
data
.
mode
==
"register"
?
'#institution_register-tpl'
:
'#institution_login-tpl'
;
this
.
tpl
=
$
(
tpl
).
html
();
this
.
providers
=
data
.
thirdPartyAuth
.
secondaryProviders
||
[];
this
.
platformName
=
data
.
platformName
;
},
initialize
:
function
(
data
)
{
var
tpl
=
data
.
mode
==
"register"
?
'#institution_register-tpl'
:
'#institution_login-tpl'
;
this
.
tpl
=
$
(
tpl
).
html
();
this
.
providers
=
data
.
thirdPartyAuth
.
secondaryProviders
||
[];
this
.
platformName
=
data
.
platformName
;
},
render
:
function
()
{
$
(
this
.
el
).
html
(
_
.
template
(
this
.
tpl
,
{
// We pass the context object to the template so that
// we can perform variable interpolation using sprintf
providers
:
this
.
providers
,
platformName
:
this
.
platformName
}));
render
:
function
()
{
$
(
this
.
el
).
html
(
_
.
template
(
this
.
tpl
,
{
// We pass the context object to the template so that
// we can perform variable interpolation using sprintf
providers
:
this
.
providers
,
platformName
:
this
.
platformName
}));
return
this
;
}
return
this
;
}
});
});
})
(
jQuery
,
_
,
Backbo
ne
);
})
.
call
(
this
,
define
||
RequireJS
.
defi
ne
);
lms/static/js/student_account/views/LoginView.js
View file @
d2a47908
var
edx
=
edx
||
{};
(
function
(
$
,
_
,
gettext
)
{
;(
function
(
define
)
{
'use strict'
;
edx
.
student
=
edx
.
student
||
{};
edx
.
student
.
account
=
edx
.
student
.
account
||
{};
edx
.
student
.
account
.
LoginView
=
edx
.
student
.
account
.
FormView
.
extend
({
el
:
'#login-form'
,
tpl
:
'#login-tpl'
,
events
:
{
'click .js-login'
:
'submitForm'
,
'click .forgot-password'
:
'forgotPassword'
,
'click .login-provider'
:
'thirdPartyAuth'
},
formType
:
'login'
,
requiredStr
:
''
,
submitButton
:
'.js-login'
,
preRender
:
function
(
data
)
{
this
.
providers
=
data
.
thirdPartyAuth
.
providers
||
[];
this
.
hasSecondaryProviders
=
(
data
.
thirdPartyAuth
.
secondaryProviders
&&
data
.
thirdPartyAuth
.
secondaryProviders
.
length
);
this
.
currentProvider
=
data
.
thirdPartyAuth
.
currentProvider
||
''
;
this
.
errorMessage
=
data
.
thirdPartyAuth
.
errorMessage
||
''
;
this
.
platformName
=
data
.
platformName
;
this
.
resetModel
=
data
.
resetModel
;
this
.
listenTo
(
this
.
model
,
'sync'
,
this
.
saveSuccess
);
this
.
listenTo
(
this
.
resetModel
,
'sync'
,
this
.
resetEmail
);
},
render
:
function
(
html
)
{
var
fields
=
html
||
''
;
$
(
this
.
el
).
html
(
_
.
template
(
this
.
tpl
,
{
// We pass the context object to the template so that
// we can perform variable interpolation using sprintf
context
:
{
fields
:
fields
,
currentProvider
:
this
.
currentProvider
,
errorMessage
:
this
.
errorMessage
,
providers
:
this
.
providers
,
hasSecondaryProviders
:
this
.
hasSecondaryProviders
,
platformName
:
this
.
platformName
define
([
'jquery'
,
'underscore'
,
'js/student_account/views/FormView'
],
function
(
$
,
_
,
FormView
)
{
return
FormView
.
extend
({
el
:
'#login-form'
,
tpl
:
'#login-tpl'
,
events
:
{
'click .js-login'
:
'submitForm'
,
'click .forgot-password'
:
'forgotPassword'
,
'click .login-provider'
:
'thirdPartyAuth'
},
formType
:
'login'
,
requiredStr
:
''
,
submitButton
:
'.js-login'
,
preRender
:
function
(
data
)
{
this
.
providers
=
data
.
thirdPartyAuth
.
providers
||
[];
this
.
hasSecondaryProviders
=
(
data
.
thirdPartyAuth
.
secondaryProviders
&&
data
.
thirdPartyAuth
.
secondaryProviders
.
length
);
this
.
currentProvider
=
data
.
thirdPartyAuth
.
currentProvider
||
''
;
this
.
errorMessage
=
data
.
thirdPartyAuth
.
errorMessage
||
''
;
this
.
platformName
=
data
.
platformName
;
this
.
resetModel
=
data
.
resetModel
;
this
.
listenTo
(
this
.
model
,
'sync'
,
this
.
saveSuccess
);
this
.
listenTo
(
this
.
resetModel
,
'sync'
,
this
.
resetEmail
);
},
render
:
function
(
html
)
{
var
fields
=
html
||
''
;
$
(
this
.
el
).
html
(
_
.
template
(
this
.
tpl
,
{
// We pass the context object to the template so that
// we can perform variable interpolation using sprintf
context
:
{
fields
:
fields
,
currentProvider
:
this
.
currentProvider
,
errorMessage
:
this
.
errorMessage
,
providers
:
this
.
providers
,
hasSecondaryProviders
:
this
.
hasSecondaryProviders
,
platformName
:
this
.
platformName
}
}));
this
.
postRender
();
return
this
;
},
postRender
:
function
()
{
this
.
$container
=
$
(
this
.
el
);
this
.
$form
=
this
.
$container
.
find
(
'form'
);
this
.
$errors
=
this
.
$container
.
find
(
'.submission-error'
);
this
.
$resetSuccess
=
this
.
$container
.
find
(
'.js-reset-success'
);
this
.
$authError
=
this
.
$container
.
find
(
'.already-authenticated-msg'
);
this
.
$submitButton
=
this
.
$container
.
find
(
this
.
submitButton
);
/* If we're already authenticated with a third-party
* provider, try logging in. The easiest way to do this
* is to simply submit the form.
*/
if
(
this
.
currentProvider
)
{
this
.
model
.
save
();
}
}));
this
.
postRender
();
return
this
;
},
postRender
:
function
()
{
this
.
$container
=
$
(
this
.
el
);
this
.
$form
=
this
.
$container
.
find
(
'form'
);
this
.
$errors
=
this
.
$container
.
find
(
'.submission-error'
);
this
.
$resetSuccess
=
this
.
$container
.
find
(
'.js-reset-success'
);
this
.
$authError
=
this
.
$container
.
find
(
'.already-authenticated-msg'
);
this
.
$submitButton
=
this
.
$container
.
find
(
this
.
submitButton
);
/* If we're already authenticated with a third-party
* provider, try logging in. The easiest way to do this
* is to simply submit the form.
*/
if
(
this
.
currentProvider
)
{
this
.
model
.
save
();
}
},
},
forgotPassword
:
function
(
event
)
{
event
.
preventDefault
();
forgotPassword
:
function
(
event
)
{
event
.
preventDefault
();
this
.
trigger
(
'password-help'
);
this
.
element
.
hide
(
this
.
$resetSuccess
);
},
this
.
trigger
(
'password-help'
);
this
.
element
.
hide
(
this
.
$resetSuccess
);
},
postFormSubmission
:
function
()
{
this
.
element
.
hide
(
this
.
$resetSuccess
);
},
postFormSubmission
:
function
()
{
this
.
element
.
hide
(
this
.
$resetSuccess
);
},
resetEmail
:
function
()
{
this
.
element
.
hide
(
this
.
$errors
);
this
.
element
.
show
(
this
.
$resetSuccess
);
},
resetEmail
:
function
()
{
this
.
element
.
hide
(
this
.
$errors
);
this
.
element
.
show
(
this
.
$resetSuccess
);
},
thirdPartyAuth
:
function
(
event
)
{
var
providerUrl
=
$
(
event
.
currentTarget
).
data
(
'provider-url'
)
||
''
;
thirdPartyAuth
:
function
(
event
)
{
var
providerUrl
=
$
(
event
.
currentTarget
).
data
(
'provider-url'
)
||
''
;
if
(
providerUrl
)
{
window
.
location
.
href
=
providerUrl
;
}
},
saveSuccess
:
function
()
{
this
.
trigger
(
'auth-complete'
);
this
.
element
.
hide
(
this
.
$resetSuccess
);
},
saveError
:
function
(
error
)
{
this
.
errors
=
[
'<li>'
+
error
.
responseText
+
'</li>'
];
this
.
setErrors
();
this
.
element
.
hide
(
this
.
$resetSuccess
);
/* If we've gotten a 403 error, it means that we've successfully
* authenticated with a third-party provider, but we haven't
* linked the account to an EdX account. In this case,
* we need to prompt the user to enter a little more information
* to complete the registration process.
*/
if
(
error
.
status
===
403
&&
error
.
responseText
===
'third-party-auth'
&&
this
.
currentProvider
)
{
this
.
element
.
show
(
this
.
$authError
);
this
.
element
.
hide
(
this
.
$errors
);
}
else
{
this
.
element
.
hide
(
this
.
$authError
);
this
.
element
.
show
(
this
.
$errors
);
if
(
providerUrl
)
{
window
.
location
.
href
=
providerUrl
;
}
},
saveSuccess
:
function
()
{
this
.
trigger
(
'auth-complete'
);
this
.
element
.
hide
(
this
.
$resetSuccess
);
},
saveError
:
function
(
error
)
{
this
.
errors
=
[
'<li>'
+
error
.
responseText
+
'</li>'
];
this
.
setErrors
();
this
.
element
.
hide
(
this
.
$resetSuccess
);
/* If we've gotten a 403 error, it means that we've successfully
* authenticated with a third-party provider, but we haven't
* linked the account to an EdX account. In this case,
* we need to prompt the user to enter a little more information
* to complete the registration process.
*/
if
(
error
.
status
===
403
&&
error
.
responseText
===
'third-party-auth'
&&
this
.
currentProvider
)
{
this
.
element
.
show
(
this
.
$authError
);
this
.
element
.
hide
(
this
.
$errors
);
}
else
{
this
.
element
.
hide
(
this
.
$authError
);
this
.
element
.
show
(
this
.
$errors
);
}
this
.
toggleDisableButton
(
false
);
}
this
.
toggleDisableButton
(
false
);
}
});
});
})(
jQuery
,
_
,
gettext
);
}).
call
(
this
,
define
||
RequireJS
.
define
);
lms/static/js/student_account/views/PasswordResetView.js
View file @
d2a47908
var
edx
=
edx
||
{};
(
function
(
$
,
gettext
)
{
;(
function
(
define
)
{
'use strict'
;
define
([
'jquery'
,
'js/student_account/views/FormView'
],
function
(
$
,
FormView
)
{
edx
.
student
=
edx
.
student
||
{};
edx
.
student
.
account
=
edx
.
student
.
account
||
{};
edx
.
student
.
account
.
PasswordResetView
=
edx
.
student
.
account
.
FormView
.
extend
({
el
:
'#password-reset-form'
,
return
FormView
.
extend
({
el
:
'#password-reset-form'
,
tpl
:
'#password_reset-tpl'
,
tpl
:
'#password_reset-tpl'
,
events
:
{
'click .js-reset'
:
'submitForm'
},
events
:
{
'click .js-reset'
:
'submitForm'
},
formType
:
'password-reset'
,
formType
:
'password-reset'
,
requiredStr
:
''
,
requiredStr
:
''
,
submitButton
:
'.js-reset'
,
submitButton
:
'.js-reset'
,
preRender
:
function
()
{
this
.
element
.
show
(
$
(
this
.
el
)
);
this
.
element
.
show
(
$
(
this
.
el
).
parent
()
);
this
.
listenTo
(
this
.
model
,
'sync'
,
this
.
saveSuccess
);
},
preRender
:
function
()
{
this
.
element
.
show
(
$
(
this
.
el
)
);
this
.
element
.
show
(
$
(
this
.
el
).
parent
()
);
this
.
listenTo
(
this
.
model
,
'sync'
,
this
.
saveSuccess
);
},
toggleErrorMsg
:
function
(
show
)
{
if
(
show
)
{
this
.
setErrors
();
this
.
toggleDisableButton
(
false
);
}
else
{
this
.
element
.
hide
(
this
.
$errors
);
}
},
toggleErrorMsg
:
function
(
show
)
{
if
(
show
)
{
this
.
setErrors
();
this
.
toggleDisableButton
(
false
);
}
else
{
this
.
element
.
hide
(
this
.
$errors
);
}
},
saveSuccess
:
function
()
{
this
.
trigger
(
'password-email-sent'
);
saveSuccess
:
function
()
{
this
.
trigger
(
'password-email-sent'
);
// Destroy the view (but not el) and unbind events
this
.
$el
.
empty
().
off
();
this
.
stopListening
();
}
// Destroy the view (but not el) and unbind events
this
.
$el
.
empty
().
off
();
this
.
stopListening
();
}
});
});
})(
jQuery
,
gettext
);
}).
call
(
this
,
define
||
RequireJS
.
define
);
lms/static/js/student_account/views/RegisterView.js
View file @
d2a47908
var
edx
=
edx
||
{};
(
function
(
$
,
_
,
gettext
)
{
;(
function
(
define
)
{
'use strict'
;
define
([
'jquery'
,
'underscore'
,
'js/student_account/views/FormView'
],
function
(
$
,
_
,
FormView
)
{
return
FormView
.
extend
({
el
:
'#register-form'
,
tpl
:
'#register-tpl'
,
events
:
{
'click .js-register'
:
'submitForm'
,
'click .login-provider'
:
'thirdPartyAuth'
},
formType
:
'register'
,
submitButton
:
'.js-register'
,
preRender
:
function
(
data
)
{
this
.
providers
=
data
.
thirdPartyAuth
.
providers
||
[];
this
.
hasSecondaryProviders
=
(
data
.
thirdPartyAuth
.
secondaryProviders
&&
data
.
thirdPartyAuth
.
secondaryProviders
.
length
);
this
.
currentProvider
=
data
.
thirdPartyAuth
.
currentProvider
||
''
;
this
.
errorMessage
=
data
.
thirdPartyAuth
.
errorMessage
||
''
;
this
.
platformName
=
data
.
platformName
;
this
.
autoSubmit
=
data
.
thirdPartyAuth
.
autoSubmitRegForm
;
this
.
listenTo
(
this
.
model
,
'sync'
,
this
.
saveSuccess
);
},
render
:
function
(
html
)
{
var
fields
=
html
||
''
;
$
(
this
.
el
).
html
(
_
.
template
(
this
.
tpl
,
{
/* We pass the context object to the template so that
* we can perform variable interpolation using sprintf
*/
context
:
{
fields
:
fields
,
currentProvider
:
this
.
currentProvider
,
errorMessage
:
this
.
errorMessage
,
providers
:
this
.
providers
,
hasSecondaryProviders
:
this
.
hasSecondaryProviders
,
platformName
:
this
.
platformName
}
}));
edx
.
student
=
edx
.
student
||
{};
edx
.
student
.
account
=
edx
.
student
.
account
||
{};
edx
.
student
.
account
.
RegisterView
=
edx
.
student
.
account
.
FormView
.
extend
({
el
:
'#register-form'
,
tpl
:
'#register-tpl'
,
events
:
{
'click .js-register'
:
'submitForm'
,
'click .login-provider'
:
'thirdPartyAuth'
},
formType
:
'register'
,
submitButton
:
'.js-register'
,
preRender
:
function
(
data
)
{
this
.
providers
=
data
.
thirdPartyAuth
.
providers
||
[];
this
.
hasSecondaryProviders
=
(
data
.
thirdPartyAuth
.
secondaryProviders
&&
data
.
thirdPartyAuth
.
secondaryProviders
.
length
);
this
.
currentProvider
=
data
.
thirdPartyAuth
.
currentProvider
||
''
;
this
.
errorMessage
=
data
.
thirdPartyAuth
.
errorMessage
||
''
;
this
.
platformName
=
data
.
platformName
;
this
.
autoSubmit
=
data
.
thirdPartyAuth
.
autoSubmitRegForm
;
this
.
listenTo
(
this
.
model
,
'sync'
,
this
.
saveSuccess
);
},
render
:
function
(
html
)
{
var
fields
=
html
||
''
;
$
(
this
.
el
).
html
(
_
.
template
(
this
.
tpl
,
{
/* We pass the context object to the template so that
* we can perform variable interpolation using sprintf
*/
context
:
{
fields
:
fields
,
currentProvider
:
this
.
currentProvider
,
errorMessage
:
this
.
errorMessage
,
providers
:
this
.
providers
,
hasSecondaryProviders
:
this
.
hasSecondaryProviders
,
platformName
:
this
.
platformName
this
.
postRender
();
if
(
this
.
autoSubmit
)
{
$
(
this
.
el
).
hide
();
$
(
'#register-honor_code'
).
prop
(
'checked'
,
true
);
this
.
submitForm
();
}
}));
this
.
postRender
();
return
this
;
},
if
(
this
.
autoSubmit
)
{
$
(
this
.
el
).
hide
();
$
(
'#register-honor_code'
).
prop
(
'checked'
,
true
);
this
.
submitForm
();
}
thirdPartyAuth
:
function
(
event
)
{
var
providerUrl
=
$
(
event
.
currentTarget
).
data
(
'provider-url'
)
||
''
;
return
this
;
},
if
(
providerUrl
)
{
window
.
location
.
href
=
providerUrl
;
}
},
thirdPartyAuth
:
function
(
event
)
{
var
providerUrl
=
$
(
event
.
currentTarget
).
data
(
'provider-url'
)
||
''
;
saveSuccess
:
function
()
{
this
.
trigger
(
'auth-complete'
);
},
if
(
providerUrl
)
{
window
.
location
.
href
=
providerUrl
;
}
},
saveSuccess
:
function
()
{
this
.
trigger
(
'auth-complete'
);
},
saveError
:
function
(
error
)
{
$
(
this
.
el
).
show
();
// Show in case the form was hidden for auto-submission
this
.
errors
=
_
.
flatten
(
_
.
map
(
JSON
.
parse
(
error
.
responseText
),
function
(
error_list
)
{
return
_
.
map
(
error_list
,
function
(
error
)
{
return
"<li>"
+
error
.
user_message
+
"</li>"
;
}
);
}
)
);
this
.
setErrors
();
this
.
toggleDisableButton
(
false
);
},
postFormSubmission
:
function
()
{
if
(
_
.
compact
(
this
.
errors
).
length
)
{
// The form did not get submitted due to validation errors.
saveError
:
function
(
error
)
{
$
(
this
.
el
).
show
();
// Show in case the form was hidden for auto-submission
this
.
errors
=
_
.
flatten
(
_
.
map
(
JSON
.
parse
(
error
.
responseText
),
function
(
error_list
)
{
return
_
.
map
(
error_list
,
function
(
error
)
{
return
'<li>'
+
error
.
user_message
+
'</li>'
;
}
);
}
)
);
this
.
setErrors
();
this
.
toggleDisableButton
(
false
);
},
postFormSubmission
:
function
()
{
if
(
_
.
compact
(
this
.
errors
).
length
)
{
// The form did not get submitted due to validation errors.
$
(
this
.
el
).
show
();
// Show in case the form was hidden for auto-submission
}
}
}
,
}
);
});
})
(
jQuery
,
_
,
gettext
);
})
.
call
(
this
,
define
||
RequireJS
.
define
);
lms/static/js_test.yml
View file @
d2a47908
...
...
@@ -63,6 +63,7 @@ lib_paths:
-
xmodule_js/common_static/js/test/i18n.js
-
xmodule_js/common_static/js/vendor/date.js
-
xmodule_js/common_static/js/vendor/moment.min.js
-
xmodule_js/common_static/js/utils/edx.utils.validate.js
# Paths to source JavaScript files
src_paths
:
...
...
lms/static/lms/js/build.js
View file @
d2a47908
...
...
@@ -24,6 +24,7 @@
'js/groups/views/cohorts_dashboard_factory'
,
'js/search/course/course_search_factory'
,
'js/search/dashboard/dashboard_search_factory'
,
'js/student_account/logistration_factory'
,
'js/student_account/views/account_settings_factory'
,
'js/student_account/views/finish_auth_factory'
,
'js/student_profile/views/learner_profile_factory'
,
...
...
lms/templates/student_account/login_and_register.html
View file @
d2a47908
<
%!
from
django
.
utils
.
translation
import
ugettext
as
_
%
>
<
%!
import
json
from
django
.
utils
.
translation
import
ugettext
as
_
from
openedx
.
core
.
lib
.
json_utils
import
EscapedEdxJSONEncoder
%
>
<
%
namespace
name=
'static'
file=
'/static_content.html'
/>
<
%
inherit
file=
"../main.html"
/>
...
...
@@ -6,9 +10,10 @@
<
%
block
name=
"pagetitle"
>
${_("Sign in or Register")}
</
%
block>
<
%
block
name=
"js_extra"
>
<script
src=
"${static.url('js/vendor/underscore.string.min.js')}"
></script>
<script
src=
"${static.url('js/vendor/history.js')}"
></script>
<
%
static:js
group=
'student_account'
/>
<
%
static:require_module
module_name=
"js/student_account/logistration_factory"
class_name=
"LogistrationFactory"
>
var options = ${ json.dumps(data, cls=EscapedEdxJSONEncoder) };
LogistrationFactory(options);
</
%
static:require
_module
>
</
%
block>
<
%
block
name=
"header_extras"
>
...
...
@@ -20,17 +25,7 @@
</
%
block>
<div
class=
"section-bkg-wrapper"
>
<div
id=
"login-and-registration-container"
class=
"login-register"
data-initial-mode=
"${initial_mode}"
data-third-party-auth=
'${third_party_auth|h}'
data-third-party-auth-hint=
'${third_party_auth_hint}'
data-next-url=
'${login_redirect_url|h}'
data-platform-name=
'${platform_name}'
data-login-form-desc=
'${login_form_desc|h}'
data-registration-form-desc=
'${registration_form_desc|h}'
data-password-reset-form-desc=
'${password_reset_form_desc|h}'
/>
<div
id=
"login-and-registration-container"
class=
"login-register"
/>
</div>
% if settings.FEATURES.get('ENABLE_COMBINED_LOGIN_REGISTRATION'):
...
...
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