Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions lms/djangoapps/courseware/features/events.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
@shard_2
Feature: LMS.Events
As a researcher, I want to be able to track events in the LMS

Scenario Outline: An event is emitted for each request
Given: I am registered for the course "6.002x"
And I visit the url "<url>"
Then a "<url>" server event is emitted

Examples:
| url |
| /dashboard |
| /courses/edx/6.002x/Test_Course/info |
| /courses/edx/6.002x/Test_Course/courseware |
62 changes: 62 additions & 0 deletions lms/djangoapps/courseware/features/events.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#pylint: disable=C0111

from lettuce import step
from lettuce import world
from lettuce import before

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can consolidate these lines:

from lettuce import step, world, before

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've always listed them separately. I find it easier to read and it also tends to limit the scope of diffs making code review easier when imports change.

from pymongo import MongoClient
from nose.tools import assert_equals
from nose.tools import assert_in


@before.all
def connect_to_mongodb():
world.mongo_client = MongoClient()
world.event_collection = world.mongo_client['track']['events']


@before.each_scenario
def reset_captured_events(_scenario):
world.event_collection.drop()


@before.outline
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):

# Ensure all events are written out to mongo before querying.
world.mongo_client.fsync()

# Note that splinter makes 2 requests when you call browser.visit('/foo')
# the first just checks to see if the server responds with a status
# code of 200, the next actually uses the browser to submit the request.
# We filter out events associated with the status code checks by ignoring
# events that come directly from splinter.
criteria = {
'event_type': event_type,
'event_source': event_source,
'agent': {
'$ne': 'python/splinter'
}
}
cursor = world.event_collection.find(criteria)
assert_equals(cursor.count(), 1)

event = cursor.next()

# These fields should be present in the event, but we won't bother
# validating them since it is difficult to predict their values.
for expected_field in ['host', 'time', 'agent', 'ip', 'event_source', 'event', 'page']:
assert_in(expected_field, event, msg='Expected field {} not found in event'.format(expected_field))

expected_field_values = {
"username": world.scenario_dict['USER'].username,
"event_type": event_type,
}
for key, value in expected_field_values.iteritems():
assert_equals(event[key], value)

# Note that the event may contain other fields, which is fine!
1 change: 1 addition & 0 deletions lms/djangoapps/courseware/features/navigation.feature
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ Feature: LMS.Navigate Course
Given I am viewing a section with multiple sequences
When I navigate to an item in a sequence
Then I see the content of the sequence item
And a "seq_goto" browser event is emitted

Scenario: I can return to the last section I visited
Given I am viewing a course with multiple sections
Expand Down
2 changes: 2 additions & 0 deletions lms/djangoapps/courseware/features/problems.feature
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ Feature: LMS.Answer problems
When I answer a "<ProblemType>" problem "correctly"
Then my "<ProblemType>" answer is marked "correct"
And The "<ProblemType>" problem displays a "correct" answer
And a "problem_check" server event is emitted
And a "problem_check" browser event is emitted

Examples:
| ProblemType |
Expand Down
6 changes: 6 additions & 0 deletions lms/envs/acceptance.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,12 @@ def seed():
}
}

TRACKING_BACKENDS.update({
'mongo': {
'ENGINE': 'track.backends.mongodb.MongoBackend'
}
})

# Forums are disabled in test.py to speed up unit tests, but we do not have
# per-test control for acceptance tests
MITX_FEATURES['ENABLE_DISCUSSION_SERVICE'] = True
Expand Down