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
5bc0b486
Commit
5bc0b486
authored
Nov 17, 2012
by
Victor Shnayder
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
moving cert link and survey logic into views, adding tests. In-progress.
parent
dd97392e
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
102 additions
and
16 deletions
+102
-16
common/djangoapps/student/tests.py
+29
-12
common/djangoapps/student/views.py
+73
-4
No files found.
common/djangoapps/student/tests.py
View file @
5bc0b486
...
...
@@ -6,11 +6,14 @@ Replace this with more appropriate tests for your application.
"""
import
logging
from
datetime
import
datetime
from
hashlib
import
sha1
from
django.test
import
TestCase
from
mock
import
patch
,
Mock
from
nose.plugins.skip
import
SkipTest
from
.models
import
User
,
UserProfile
,
CourseEnrollment
,
replicate_user
,
USER_FIELDS_TO_COPY
import
.views
COURSE_1
=
'edX/toy/2012_Fall'
COURSE_2
=
'edx/full/6.002_Spring_2012'
...
...
@@ -55,7 +58,7 @@ class ReplicationTest(TestCase):
# This hasattr lameness is here because we don't want this test to be
# triggered when we're being run by CMS tests (Askbot doesn't exist
# there, so the test will fail).
#
#
# seen_response_count isn't a field we care about, so it shouldn't have
# been copied over.
if
hasattr
(
portal_user
,
'seen_response_count'
):
...
...
@@ -74,7 +77,7 @@ class ReplicationTest(TestCase):
# During this entire time, the user data should never have made it over
# to COURSE_2
self
.
assertRaises
(
User
.
DoesNotExist
,
self
.
assertRaises
(
User
.
DoesNotExist
,
User
.
objects
.
using
(
COURSE_2
)
.
get
,
id
=
portal_user
.
id
)
...
...
@@ -108,19 +111,19 @@ class ReplicationTest(TestCase):
# Grab all the copies we expect
course_user
=
User
.
objects
.
using
(
COURSE_1
)
.
get
(
id
=
portal_user
.
id
)
self
.
assertEquals
(
portal_user
,
course_user
)
self
.
assertRaises
(
User
.
DoesNotExist
,
self
.
assertRaises
(
User
.
DoesNotExist
,
User
.
objects
.
using
(
COURSE_2
)
.
get
,
id
=
portal_user
.
id
)
course_enrollment
=
CourseEnrollment
.
objects
.
using
(
COURSE_1
)
.
get
(
id
=
portal_enrollment
.
id
)
self
.
assertEquals
(
portal_enrollment
,
course_enrollment
)
self
.
assertRaises
(
CourseEnrollment
.
DoesNotExist
,
self
.
assertRaises
(
CourseEnrollment
.
DoesNotExist
,
CourseEnrollment
.
objects
.
using
(
COURSE_2
)
.
get
,
id
=
portal_enrollment
.
id
)
course_user_profile
=
UserProfile
.
objects
.
using
(
COURSE_1
)
.
get
(
id
=
portal_user_profile
.
id
)
self
.
assertEquals
(
portal_user_profile
,
course_user_profile
)
self
.
assertRaises
(
UserProfile
.
DoesNotExist
,
self
.
assertRaises
(
UserProfile
.
DoesNotExist
,
UserProfile
.
objects
.
using
(
COURSE_2
)
.
get
,
id
=
portal_user_profile
.
id
)
...
...
@@ -174,30 +177,44 @@ class ReplicationTest(TestCase):
portal_user
.
save
()
portal_user_profile
.
gender
=
'm'
portal_user_profile
.
save
()
# Grab all the copies we expect, and make sure it doesn't end up in
# Grab all the copies we expect, and make sure it doesn't end up in
# places we don't expect.
course_user
=
User
.
objects
.
using
(
COURSE_1
)
.
get
(
id
=
portal_user
.
id
)
self
.
assertEquals
(
portal_user
,
course_user
)
self
.
assertRaises
(
User
.
DoesNotExist
,
self
.
assertRaises
(
User
.
DoesNotExist
,
User
.
objects
.
using
(
COURSE_2
)
.
get
,
id
=
portal_user
.
id
)
course_enrollment
=
CourseEnrollment
.
objects
.
using
(
COURSE_1
)
.
get
(
id
=
portal_enrollment
.
id
)
self
.
assertEquals
(
portal_enrollment
,
course_enrollment
)
self
.
assertRaises
(
CourseEnrollment
.
DoesNotExist
,
self
.
assertRaises
(
CourseEnrollment
.
DoesNotExist
,
CourseEnrollment
.
objects
.
using
(
COURSE_2
)
.
get
,
id
=
portal_enrollment
.
id
)
course_user_profile
=
UserProfile
.
objects
.
using
(
COURSE_1
)
.
get
(
id
=
portal_user_profile
.
id
)
self
.
assertEquals
(
portal_user_profile
,
course_user_profile
)
self
.
assertRaises
(
UserProfile
.
DoesNotExist
,
self
.
assertRaises
(
UserProfile
.
DoesNotExist
,
UserProfile
.
objects
.
using
(
COURSE_2
)
.
get
,
id
=
portal_user_profile
.
id
)
class
CourseEndingTest
(
TestCase
):
"""Test things related to course endings: certificates, surveys, etc"""
def
test_process_survey_link
(
self
):
username
=
"fred"
id
=
sha1
(
username
)
link1
=
"http://www.mysurvey.com"
self
.
assertEqual
(
process_survey_link
(
link1
),
link1
)
link2
=
"http://www.mysurvey.com?unique={UNIQUE_ID}"
link2_expected
=
"http://www.mysurvey.com?unique={UNIQUE_ID}"
.
format
(
UNIQUE_ID
=
id
)
self
.
assertEqual
(
views
.
process_survey_link
(
link2
),
link2_expected
)
def
test_cert_info
(
self
):
user
=
Mock
(
username
=
"fred"
)
survey_url
=
"http://a_survey.com"
course
=
Mock
(
end_of_course_survey_url
=
survey_url
)
cert_status
=
None
self
.
assertEqual
(
views
.
_cert_info
(
user
,
course
,
None
),
{
'status'
:
'processing'
})
common/djangoapps/student/views.py
View file @
5bc0b486
...
...
@@ -39,6 +39,8 @@ from xmodule.modulestore.exceptions import ItemNotFoundError
from
datetime
import
date
from
collections
import
namedtuple
from
hashlib
import
sha1
from
courseware.courses
import
get_courses_by_university
from
courseware.access
import
has_access
...
...
@@ -107,9 +109,9 @@ def get_date_for_press(publish_date):
# strip off extra months, and just use the first:
date
=
re
.
sub
(
multimonth_pattern
,
", "
,
publish_date
)
if
re
.
search
(
day_pattern
,
date
):
date
=
datetime
.
datetime
.
strptime
(
date
,
"
%
B
%
d,
%
Y"
)
else
:
date
=
datetime
.
datetime
.
strptime
(
date
,
"
%
B,
%
Y"
)
date
=
datetime
.
datetime
.
strptime
(
date
,
"
%
B
%
d,
%
Y"
)
else
:
date
=
datetime
.
datetime
.
strptime
(
date
,
"
%
B,
%
Y"
)
return
date
def
press
(
request
):
...
...
@@ -127,6 +129,73 @@ def press(request):
return
render_to_response
(
'static_templates/press.html'
,
{
'articles'
:
articles
})
def
process_survey_link
(
survey_link
,
user
):
"""
If {UNIQUE_ID} appears in the link, replace it with a unique id for the user.
Currently, this is sha1(user.username). Otherwise, return survey_link.
"""
to_replace
=
'{UNIQUE_ID}'
if
to_replace
in
survey_link
:
unique_id
=
sha1
(
user
.
username
)
return
survey_link
.
replace
(
to_replace
,
unique_id
)
return
survey_link
def
cert_info
(
user
,
course
):
"""
Get the certificate info needed to render the dashboard section for the given
student and course. Returns a dictionary with keys:
'status': one of 'generating', 'ready', 'notpassing', 'processing'
'show_download_url': bool
'download_url': url, only present if show_download_url is True
'show_survey_button': bool
'survey_url': url, only if show_survey_button is True
'grade': if status is not 'processing'
"""
if
not
course
.
has_ended
():
return
{}
return
_cert_info
(
user
,
course
,
certificate_status_for_student
(
user
,
course
.
id
))
def
_cert_info
(
user
,
course
,
cert_status
):
"""
Implements the logic for cert_info -- split out for testing.
"""
default_status
=
'processing'
if
cert_status
is
None
:
return
{
'status'
:
default_status
}
# simplify the status for the template using this lookup table
template_state
=
{
CertificateStatuses
.
generating
:
'generating'
,
CertificateStatuses
.
regenerating
:
'generating'
,
CertificateStatuses
.
downloadable
:
'ready'
,
CertificateStatuses
.
notpassing
:
'notpassing'
,
}
status
=
template_state
.
get
(
cert_status
[
'status'
],
default_status
)
d
=
{
'status'
:
status
,
'show_download_url'
:
status
in
(
'generating'
,
'ready'
),}
if
(
status
in
(
'generating'
,
'ready'
,
'not-available'
)
and
course
.
end_of_course_survey_url
is
not
None
):
d
.
update
({
'show_survey_button'
:
True
,
'survey_url'
:
process_survey_link
(
course
.
end_of_course_survey_url
,
user
)})
else
:
d
[
'show_survey_button'
]
=
False
if
template_state
==
'ready'
:
d
[
'download_url'
]
=
cert_status
[
'download_url'
]
if
template_state
in
'generating'
,
'ready'
,
'notpassing'
:
d
[
'grade'
]
=
cert_status
[
'grade'
]
return
d
@login_required
@ensure_csrf_cookie
def
dashboard
(
request
):
...
...
@@ -163,7 +232,7 @@ def dashboard(request):
# TODO: workaround to not have to zip courses and certificates in the template
# since before there is a migration to certificates
if
settings
.
MITX_FEATURES
.
get
(
'CERTIFICATES_ENABLED'
):
cert_statuses
=
{
course
.
id
:
cert
ificate_status_for_student
(
request
.
user
,
course
.
id
)
for
course
in
courses
}
cert_statuses
=
{
course
.
id
:
cert
_info
(
request
.
user
,
course
)
for
course
in
courses
}
else
:
cert_statuses
=
{}
...
...
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