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
e78a398f
Commit
e78a398f
authored
Jul 01, 2014
by
Justin Helbert
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
This emits enrollment mode changes events
parent
d352d4ae
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
159 additions
and
14 deletions
+159
-14
common/djangoapps/student/models.py
+5
-0
common/djangoapps/student/tests/tests.py
+29
-0
lms/djangoapps/courseware/features/change_enrollment.feature
+23
-0
lms/djangoapps/courseware/features/change_enrollment.py
+49
-0
lms/djangoapps/courseware/features/common.py
+6
-6
lms/djangoapps/courseware/features/events.py
+10
-3
lms/djangoapps/courseware/features/registration.py
+9
-0
lms/djangoapps/verify_student/tests/test_views.py
+28
-5
No files found.
common/djangoapps/student/models.py
View file @
e78a398f
...
...
@@ -328,6 +328,7 @@ class PendingEmailChange(models.Model):
EVENT_NAME_ENROLLMENT_ACTIVATED
=
'edx.course.enrollment.activated'
EVENT_NAME_ENROLLMENT_DEACTIVATED
=
'edx.course.enrollment.deactivated'
EVENT_NAME_ENROLLMENT_MODE_CHANGED
=
'edx.course.enrollment.mode_changed'
class
PasswordHistory
(
models
.
Model
):
...
...
@@ -716,6 +717,10 @@ class CourseEnrollment(models.Model):
u"offering:{}"
.
format
(
self
.
course_id
.
offering
),
u"mode:{}"
.
format
(
self
.
mode
)]
)
if
mode_changed
:
# the user's default mode is "honor" and disabled for a course
# mode change events will only be emitted when the user's mode changes from this
self
.
emit_event
(
EVENT_NAME_ENROLLMENT_MODE_CHANGED
)
def
emit_event
(
self
,
event_name
):
"""
...
...
common/djangoapps/student/tests/tests.py
View file @
e78a398f
...
...
@@ -310,6 +310,18 @@ class EnrollInCourseTest(TestCase):
self
.
assertFalse
(
self
.
mock_tracker
.
emit
.
called
)
# pylint: disable=maybe-no-member
self
.
mock_tracker
.
reset_mock
()
def
assert_enrollment_mode_change_event_was_emitted
(
self
,
user
,
course_key
,
mode
):
"""Ensures an enrollment mode change event was emitted"""
self
.
mock_tracker
.
emit
.
assert_called_once_with
(
# pylint: disable=maybe-no-member
'edx.course.enrollment.mode_changed'
,
{
'course_id'
:
course_key
.
to_deprecated_string
(),
'user_id'
:
user
.
pk
,
'mode'
:
mode
}
)
self
.
mock_tracker
.
reset_mock
()
def
assert_enrollment_event_was_emitted
(
self
,
user
,
course_key
):
"""Ensures an enrollment event was emitted since the last event related assertion"""
self
.
mock_tracker
.
emit
.
assert_called_once_with
(
# pylint: disable=maybe-no-member
...
...
@@ -447,6 +459,23 @@ class EnrollInCourseTest(TestCase):
self
.
assertTrue
(
CourseEnrollment
.
is_enrolled
(
user
,
course_id
))
self
.
assert_enrollment_event_was_emitted
(
user
,
course_id
)
def
test_change_enrollment_modes
(
self
):
user
=
User
.
objects
.
create
(
username
=
"justin"
,
email
=
"jh@fake.edx.org"
)
course_id
=
SlashSeparatedCourseKey
(
"edX"
,
"Test101"
,
"2013"
)
CourseEnrollment
.
enroll
(
user
,
course_id
)
self
.
assert_enrollment_event_was_emitted
(
user
,
course_id
)
CourseEnrollment
.
enroll
(
user
,
course_id
,
"audit"
)
self
.
assert_enrollment_mode_change_event_was_emitted
(
user
,
course_id
,
"audit"
)
# same enrollment mode does not emit an event
CourseEnrollment
.
enroll
(
user
,
course_id
,
"audit"
)
self
.
assert_no_events_were_emitted
()
CourseEnrollment
.
enroll
(
user
,
course_id
,
"honor"
)
self
.
assert_enrollment_mode_change_event_was_emitted
(
user
,
course_id
,
"honor"
)
@override_settings
(
MODULESTORE
=
TEST_DATA_MIXED_MODULESTORE
)
@unittest.skipUnless
(
settings
.
ROOT_URLCONF
==
'lms.urls'
,
'Test only valid in lms'
)
...
...
lms/djangoapps/courseware/features/change_enrollment.feature
0 → 100644
View file @
e78a398f
Feature
:
Change Enrollment Events
As a registered user
I want to change my enrollment mode
Scenario
:
I
can change my enrollment
Given
The course
"6.002x"
exists
And
the course
"6.002x"
has all enrollment modes
And
I am logged in
And
I visit the courses page
When
I register to audit the course
And
a
"edx.course.enrollment.activated"
server event is emitted
And
a
"edx.course.enrollment.mode_changed"
server events is emitted
And
I visit the dashboard
And
I click on Challenge Yourself
And
I choose an honor code upgrade
Then
I should be on the dashboard page
Then
2
"edx.course.enrollment.mode_changed"
server event is emitted
# don't emit another mode_changed event upon unenrollment
When
I unregister for the course numbered
"6.002x"
Then
2
"edx.course.enrollment.mode_changed"
server events is emitted
lms/djangoapps/courseware/features/change_enrollment.py
0 → 100644
View file @
e78a398f
""" Provides lettuce acceptance methods for course enrollment changes """
from
__future__
import
absolute_import
from
lettuce
import
world
,
step
from
opaque_keys.edx.locations
import
SlashSeparatedCourseKey
from
logging
import
getLogger
logger
=
getLogger
(
__name__
)
@step
(
u'the course "([^"]*)" has all enrollment modes$'
)
def
add_enrollment_modes_to_course
(
_step
,
course
):
""" Add honor, audit, and verified modes to the sample course """
world
.
CourseModeFactory
.
create
(
course_id
=
SlashSeparatedCourseKey
(
"edx"
,
course
,
'Test_Course'
),
mode_slug
=
"verified"
,
mode_display_name
=
"Verified Course"
,
min_price
=
3
)
world
.
CourseModeFactory
.
create
(
course_id
=
SlashSeparatedCourseKey
(
"edx"
,
course
,
'Test_Course'
),
mode_slug
=
"honor"
,
mode_display_name
=
"Honor Course"
,
)
world
.
CourseModeFactory
.
create
(
course_id
=
SlashSeparatedCourseKey
(
"edx"
,
course
,
'Test_Course'
),
mode_slug
=
"audit"
,
mode_display_name
=
"Audit Course"
,
)
@step
(
u'I click on Challenge Yourself$'
)
def
challenge_yourself
(
_step
):
""" Simulates clicking 'Challenge Yourself' button on course """
challenge_button
=
world
.
browser
.
find_by_css
(
'.wrapper-tip'
)
challenge_button
.
click
()
verified_button
=
world
.
browser
.
find_by_css
(
'#upgrade-to-verified'
)
verified_button
.
click
()
@step
(
u'I choose an honor code upgrade$'
)
def
honor_code_upgrade
(
_step
):
""" Simulates choosing the honor code mode on the upgrade page """
honor_code_link
=
world
.
browser
.
find_by_css
(
'.title-expand'
)
honor_code_link
.
click
()
honor_code_checkbox
=
world
.
browser
.
find_by_css
(
'#honor-code'
)
honor_code_checkbox
.
click
()
upgrade_button
=
world
.
browser
.
find_by_name
(
"certificate_mode"
)
upgrade_button
.
click
()
lms/djangoapps/courseware/features/common.py
View file @
e78a398f
...
...
@@ -15,7 +15,6 @@ from opaque_keys.edx.locations import SlashSeparatedCourseKey
from
xmodule.course_module
import
CourseDescriptor
from
courseware.courses
import
get_course_by_id
from
xmodule
import
seq_module
,
vertical_module
from
logging
import
getLogger
logger
=
getLogger
(
__name__
)
...
...
@@ -27,7 +26,7 @@ def configure_screenshots_for_all_steps(_step, action):
automatic saving of screenshots before and after each step in a
scenario.
"""
action
=
action
.
strip
()
action
=
action
.
strip
()
if
action
==
'enable'
:
world
.
auto_capture_screenshots
=
True
elif
action
==
'disable'
:
...
...
@@ -35,6 +34,7 @@ def configure_screenshots_for_all_steps(_step, action):
else
:
raise
ValueError
(
'Parameter `action` should be one of "enable" or "disable".'
)
@world.absorb
def
capture_screenshot_before_after
(
func
):
"""
...
...
@@ -43,12 +43,12 @@ def capture_screenshot_before_after(func):
for each step in a scenario, but rather want to debug a single function.
"""
def
inner
(
*
args
,
**
kwargs
):
prefix
=
round
(
time
.
time
()
*
1000
)
prefix
=
round
(
time
.
time
()
*
1000
)
world
.
capture_screenshot
(
"{}_{}_{}"
.
format
(
prefix
,
func
.
func_name
,
'before'
))
ret_val
=
func
(
*
args
,
**
kwargs
)
ret_val
=
func
(
*
args
,
**
kwargs
)
world
.
capture_screenshot
(
"{}_{}_{}"
.
format
(
prefix
,
func
.
func_name
,
'after'
))
...
...
@@ -94,11 +94,11 @@ def i_am_registered_for_the_course(step, course):
# Create the user
world
.
create_user
(
'robot'
,
'test'
)
u
=
User
.
objects
.
get
(
username
=
'robot'
)
u
ser
=
User
.
objects
.
get
(
username
=
'robot'
)
# If the user is not already enrolled, enroll the user.
# TODO: change to factory
CourseEnrollment
.
enroll
(
u
,
course_id
(
course
))
CourseEnrollment
.
enroll
(
u
ser
,
course_id
(
course
))
world
.
log_in
(
username
=
'robot'
,
password
=
'test'
)
...
...
lms/djangoapps/courseware/features/events.py
View file @
e78a398f
...
...
@@ -36,8 +36,8 @@ def reset_between_outline_scenarios(_scenario, order, outline, reasons_to_fail):
world
.
event_collection
.
drop
()
@step
(
'[aA]n? "(.*)" (server|browser) event is emitted
'
)
def
event_is_emitted
(
_step
,
event_type
,
event_source
):
@step
(
r'([aA]n?|\d+) "(.*)" (server|browser) events? is emitted$
'
)
def
n_events_are_emitted
(
_step
,
count
,
event_type
,
event_source
):
# Ensure all events are written out to mongo before querying.
world
.
mongo_client
.
fsync
()
...
...
@@ -54,8 +54,15 @@ def event_is_emitted(_step, event_type, event_source):
'$ne'
:
'python/splinter'
}
}
cursor
=
world
.
event_collection
.
find
(
criteria
)
assert_equals
(
cursor
.
count
(),
1
)
try
:
number_events
=
int
(
count
)
except
ValueError
:
number_events
=
1
assert_equals
(
cursor
.
count
(),
number_events
)
event
=
cursor
.
next
()
...
...
lms/djangoapps/courseware/features/registration.py
View file @
e78a398f
...
...
@@ -10,7 +10,16 @@ def i_register_for_the_course(_step, course):
url
=
django_url
(
'courses/
%
s/about'
%
world
.
scenario_dict
[
'COURSE'
]
.
id
.
to_deprecated_string
())
world
.
browser
.
visit
(
url
)
world
.
css_click
(
'section.intro a.register'
)
assert
world
.
is_css_present
(
'section.container.dashboard'
)
@step
(
'I register to audit the course$'
)
def
i_register_to_audit_the_course
(
_step
):
url
=
django_url
(
'courses/
%
s/about'
%
world
.
scenario_dict
[
'COURSE'
]
.
id
.
to_deprecated_string
())
world
.
browser
.
visit
(
url
)
world
.
css_click
(
'section.intro a.register'
)
audit_button
=
world
.
browser
.
find_by_name
(
"audit_mode"
)
audit_button
.
click
()
assert
world
.
is_css_present
(
'section.container.dashboard'
)
...
...
lms/djangoapps/verify_student/tests/test_views.py
View file @
e78a398f
...
...
@@ -35,7 +35,6 @@ from verify_student.models import SoftwareSecurePhotoVerification
from
reverification.tests.factories
import
MidcourseReverificationWindowFactory
def
mock_render_to_response
(
*
args
,
**
kwargs
):
return
render_to_response
(
*
args
,
**
kwargs
)
...
...
@@ -386,8 +385,17 @@ class TestMidCourseReverifyView(TestCase):
kwargs
=
{
"course_id"
:
self
.
course_key
.
to_deprecated_string
()})
response
=
self
.
client
.
get
(
url
)
# Check that user entering the reverify flow was logged
self
.
mock_tracker
.
emit
.
assert_called_once_with
(
# pylint: disable=maybe-no-member
self
.
mock_tracker
.
emit
.
assert_any_call
(
# pylint: disable=maybe-no-member
'edx.course.enrollment.mode_changed'
,
{
'user_id'
:
self
.
user
.
id
,
'course_id'
:
self
.
course_key
.
to_deprecated_string
(),
'mode'
:
"verified"
,
}
)
# Check that user entering the reverify flow was logged, and that it was the last call
self
.
mock_tracker
.
emit
.
assert_called_with
(
# pylint: disable=maybe-no-member
'edx.course.enrollment.reverify.started'
,
{
'user_id'
:
self
.
user
.
id
,
...
...
@@ -395,6 +403,9 @@ class TestMidCourseReverifyView(TestCase):
'mode'
:
"verified"
,
}
)
self
.
assertTrue
(
self
.
mock_tracker
.
emit
.
call_count
,
2
)
self
.
mock_tracker
.
emit
.
reset_mock
()
# pylint: disable=maybe-no-member
self
.
assertEquals
(
response
.
status_code
,
200
)
...
...
@@ -408,8 +419,17 @@ class TestMidCourseReverifyView(TestCase):
response
=
self
.
client
.
post
(
url
,
{
'face_image'
:
','
})
# Check that submission event was logged
self
.
mock_tracker
.
emit
.
assert_called_once_with
(
# pylint: disable=maybe-no-member
self
.
mock_tracker
.
emit
.
assert_any_call
(
# pylint: disable=maybe-no-member
'edx.course.enrollment.mode_changed'
,
{
'user_id'
:
self
.
user
.
id
,
'course_id'
:
self
.
course_key
.
to_deprecated_string
(),
'mode'
:
"verified"
,
}
)
# Check that submission event was logged, and that it was the last call
self
.
mock_tracker
.
emit
.
assert_called_with
(
# pylint: disable=maybe-no-member
'edx.course.enrollment.reverify.submitted'
,
{
'user_id'
:
self
.
user
.
id
,
...
...
@@ -417,6 +437,9 @@ class TestMidCourseReverifyView(TestCase):
'mode'
:
"verified"
,
}
)
self
.
assertTrue
(
self
.
mock_tracker
.
emit
.
call_count
,
2
)
self
.
mock_tracker
.
emit
.
reset_mock
()
# pylint: disable=maybe-no-member
self
.
assertEquals
(
response
.
status_code
,
302
)
...
...
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