Add user_id for username in event data.
In certain use cases, a caller may have the username and not the user_id. In these cases, we add the user_id since events have standardized on using the user_id as the unique id of a user. ARCH-472
This commit is contained in:
@@ -4,6 +4,7 @@ import json
|
||||
import pytz
|
||||
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.contrib.auth.models import User
|
||||
from django.http import HttpResponse
|
||||
from django.shortcuts import redirect
|
||||
|
||||
@@ -50,6 +51,22 @@ def _get_request_value(request, value_name, default=''):
|
||||
return default
|
||||
|
||||
|
||||
def _add_user_id_for_username(data):
|
||||
"""
|
||||
If data contains a username, adds the corresponding user_id to the data.
|
||||
|
||||
In certain use cases, the caller may have the username and not the
|
||||
user_id. This enables us to standardize on user_id in event data,
|
||||
even when the caller only has access to the username.
|
||||
"""
|
||||
if data and ('username' in data) and ('user_id' not in data):
|
||||
try:
|
||||
user = User.objects.get(username=data.get('username'))
|
||||
data['user_id'] = user.id
|
||||
except User.DoesNotExist:
|
||||
pass
|
||||
|
||||
|
||||
def user_track(request):
|
||||
"""
|
||||
Log when POST call to "event" URL is made by a user.
|
||||
@@ -68,6 +85,7 @@ def user_track(request):
|
||||
if isinstance(data, basestring) and len(data) > 0:
|
||||
try:
|
||||
data = json.loads(data)
|
||||
_add_user_id_for_username(data)
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
# pylint: disable=missing-docstring,maybe-no-member
|
||||
|
||||
import ddt
|
||||
from mock import patch, sentinel
|
||||
|
||||
from django.contrib.auth.models import User
|
||||
@@ -12,8 +13,18 @@ from track.tests import EventTrackingTestCase, FROZEN_TIME
|
||||
from openedx.core.lib.tests.assertions.events import assert_event_matches
|
||||
|
||||
|
||||
TEST_USERNAME = 'test-username'
|
||||
TEST_USER_ID = 1000
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class TestTrackViews(EventTrackingTestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpTestData(cls):
|
||||
super(TestTrackViews, cls).setUpTestData()
|
||||
User.objects.create(pk=TEST_USER_ID, username=TEST_USERNAME)
|
||||
|
||||
def setUp(self):
|
||||
super(TestTrackViews, self).setUp()
|
||||
|
||||
@@ -74,8 +85,6 @@ class TestTrackViews(EventTrackingTestCase):
|
||||
}
|
||||
assert_event_matches(expected_event, actual_event)
|
||||
|
||||
views.user_track(request)
|
||||
|
||||
def test_user_track_with_empty_event(self):
|
||||
request = self.request_factory.get('/event', {
|
||||
'page': self.url_with_course,
|
||||
@@ -100,6 +109,39 @@ class TestTrackViews(EventTrackingTestCase):
|
||||
}
|
||||
assert_event_matches(expected_event, actual_event)
|
||||
|
||||
@ddt.data(
|
||||
{
|
||||
'event_data': u'{{"username": "{}"}}'.format(TEST_USERNAME),
|
||||
'expected_event_data': {"username": TEST_USERNAME, "user_id": TEST_USER_ID}
|
||||
},
|
||||
{
|
||||
'event_data': u'{"username": "unknown-user"}',
|
||||
'expected_event_data': {"username": "unknown-user"},
|
||||
}
|
||||
)
|
||||
@ddt.unpack
|
||||
def test_user_track_with_username_in_data(self, event_data, expected_event_data):
|
||||
request = self.request_factory.get('/event', {
|
||||
'event': event_data,
|
||||
})
|
||||
|
||||
views.user_track(request)
|
||||
|
||||
actual_event = self.get_event()
|
||||
expected_event = {
|
||||
'context': {
|
||||
'course_id': '',
|
||||
'org_id': '',
|
||||
'event_source': 'browser',
|
||||
'page': '',
|
||||
'username': 'anonymous'
|
||||
},
|
||||
'data': expected_event_data,
|
||||
'timestamp': FROZEN_TIME,
|
||||
'name': 'unknown'
|
||||
}
|
||||
assert_event_matches(expected_event, actual_event)
|
||||
|
||||
@override_settings(
|
||||
EVENT_TRACKING_PROCESSORS=[{'ENGINE': 'track.shim.LegacyFieldMappingProcessor'}],
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user