Files
edx-platform/common/djangoapps/track/views/tests/test_views.py
2021-02-03 17:05:12 +05:00

344 lines
12 KiB
Python

# lint-amnesty, pylint: disable=missing-module-docstring
import ddt
import six
from django.contrib.auth.models import User # lint-amnesty, pylint: disable=imported-auth-user
from django.test.client import RequestFactory
from django.test.utils import override_settings
from mock import patch, sentinel
from openedx.core.lib.tests.assertions.events import assert_event_matches
from common.djangoapps.track import views
from common.djangoapps.track.middleware import TrackMiddleware
from common.djangoapps.track.tests import FROZEN_TIME, EventTrackingTestCase
TEST_USERNAME = 'test-username'
TEST_USER_ID = 1000
@ddt.ddt
class TestTrackViews(EventTrackingTestCase): # lint-amnesty, pylint: disable=missing-class-docstring
@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() # lint-amnesty, pylint: disable=super-with-arguments
self.request_factory = RequestFactory()
patcher = patch('common.djangoapps.track.views.tracker', autospec=True)
self.mock_tracker = patcher.start()
self.addCleanup(patcher.stop)
self.path_with_course = '/courses/foo/bar/baz/xmod/'
self.url_with_course = 'http://www.edx.org' + self.path_with_course
self.event = {
sentinel.key: sentinel.value
}
def test_user_track(self):
request = self.request_factory.get('/event', {
'page': self.url_with_course,
'event_type': sentinel.event_type,
'event': '{}'
})
views.user_track(request)
actual_event = self.get_event()
expected_event = {
'context': {
'course_id': 'foo/bar/baz',
'org_id': 'foo',
'event_source': 'browser',
'page': self.url_with_course,
'username': 'anonymous'
},
'data': {},
'timestamp': FROZEN_TIME,
'name': str(sentinel.event_type)
}
assert_event_matches(expected_event, actual_event)
def test_user_track_with_missing_values(self):
request = self.request_factory.get('/event')
views.user_track(request)
actual_event = self.get_event()
expected_event = {
'context': {
'course_id': '',
'org_id': '',
'event_source': 'browser',
'page': '',
'username': 'anonymous'
},
'data': {},
'timestamp': FROZEN_TIME,
'name': 'unknown'
}
assert_event_matches(expected_event, actual_event)
def test_user_track_with_empty_event(self):
request = self.request_factory.get('/event', {
'page': self.url_with_course,
'event_type': sentinel.event_type,
'event': ''
})
views.user_track(request)
actual_event = self.get_event()
expected_event = {
'context': {
'course_id': 'foo/bar/baz',
'org_id': 'foo',
'event_source': 'browser',
'page': self.url_with_course,
'username': 'anonymous'
},
'data': {},
'timestamp': FROZEN_TIME,
'name': str(sentinel.event_type)
}
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': 'common.djangoapps.track.shim.LegacyFieldMappingProcessor'}],
)
def test_user_track_with_middleware_and_processors(self):
self.recreate_tracker()
middleware = TrackMiddleware()
payload = '{"foo": "bar"}'
user_id = 1
request = self.request_factory.get('/event', {
'page': self.url_with_course,
'event_type': sentinel.event_type,
'event': payload
})
request.user = User.objects.create(pk=user_id, username=str(sentinel.username))
request.META['REMOTE_ADDR'] = '10.0.0.1'
request.META['HTTP_REFERER'] = str(sentinel.referer)
request.META['HTTP_ACCEPT_LANGUAGE'] = str(sentinel.accept_language)
request.META['HTTP_USER_AGENT'] = str(sentinel.user_agent)
request.META['SERVER_NAME'] = 'testserver2'
middleware.process_request(request)
try:
views.user_track(request)
expected_event = {
'accept_language': str(sentinel.accept_language),
'referer': str(sentinel.referer),
'username': str(sentinel.username),
'session': '',
'ip': '10.0.0.1',
'event_source': 'browser',
'event_type': str(sentinel.event_type),
'name': str(sentinel.event_type),
'event': payload,
'agent': str(sentinel.user_agent),
'page': self.url_with_course,
'time': FROZEN_TIME,
'host': 'testserver2',
'context': {
'course_id': 'foo/bar/baz',
'org_id': 'foo',
'user_id': user_id,
'path': u'/event'
},
}
finally:
middleware.process_response(request, None)
actual_event = self.get_event()
assert_event_matches(expected_event, actual_event)
def test_server_track(self):
request = self.request_factory.get(self.path_with_course)
views.server_track(request, str(sentinel.event_type), '{}')
expected_event = {
'timestamp': FROZEN_TIME,
'data': '{}',
'name': str(sentinel.event_type),
'context':
{
'username': 'anonymous',
'page': None,
'event_source': 'server'
}
}
actual_event = self.get_event()
assert_event_matches(expected_event, actual_event)
def test_server_track_with_middleware(self):
middleware = TrackMiddleware()
request = self.request_factory.get(self.path_with_course)
middleware.process_request(request)
# The middleware emits an event, reset the mock to ignore it since we aren't testing that feature.
self.mock_tracker.reset_mock()
try:
views.server_track(request, str(sentinel.event_type), '{}')
expected_event = {
'timestamp': FROZEN_TIME,
'data': '{"GET": {}, "POST": {}}',
'name': self.path_with_course,
'context': {
'username': 'anonymous',
'user_id': '',
'accept_language': '',
'ip': '127.0.0.1',
'org_id': 'foo',
'agent': '',
'event_source': 'server',
'host': 'testserver',
'session': '',
'referer': '',
'client_id': None,
'course_id': 'foo/bar/baz',
'path': self.path_with_course,
'page': None
}
}
finally:
middleware.process_response(request, None)
actual_event = self.get_event()
assert_event_matches(
expected_event,
actual_event,
tolerate={'string_payload'}
)
def test_server_track_with_middleware_and_google_analytics_cookie(self):
middleware = TrackMiddleware()
request = self.request_factory.get(self.path_with_course)
request.COOKIES['_ga'] = 'GA1.2.1033501218.1368477899'
middleware.process_request(request)
# The middleware emits an event, reset the mock to ignore it since we aren't testing that feature.
self.mock_tracker.reset_mock()
try:
views.server_track(request, str(sentinel.event_type), '{}')
expected_event = {
'timestamp': FROZEN_TIME,
'data': '{"GET": {}, "POST": {}}',
'name': self.path_with_course,
'context': {
'username': 'anonymous',
'user_id': '',
'accept_language': '',
'ip': '127.0.0.1',
'org_id': 'foo',
'agent': '',
'event_source': 'server',
'host': 'testserver',
'session': '',
'referer': '',
'client_id': '1033501218.1368477899',
'course_id': 'foo/bar/baz',
'path': self.path_with_course,
'page': None
}
}
finally:
middleware.process_response(request, None)
actual_event = self.get_event()
assert_event_matches(expected_event, actual_event, tolerate={'string_payload', })
def test_server_track_with_no_request(self):
request = None
views.server_track(request, str(sentinel.event_type), '{}')
expected_event = {
'timestamp': FROZEN_TIME,
'data': '{}',
'name': str(sentinel.event_type),
'context': {
'username': 'anonymous',
'page': None,
'event_source':
'server'
}
}
actual_event = self.get_event()
assert_event_matches(expected_event, actual_event)
def test_task_track(self):
request_info = {
'accept_language': '',
'referer': '',
'username': 'anonymous',
'ip': '127.0.0.1',
'agent': 'agent',
'host': 'testserver',
}
task_info = {
six.text_type(sentinel.task_key): sentinel.task_value
}
expected_event_data = dict(task_info)
expected_event_data.update(self.event)
views.task_track(request_info, task_info, str(sentinel.event_type), self.event)
expected_event = {
'timestamp': FROZEN_TIME,
'data': expected_event_data,
'name': str(sentinel.event_type),
'context': {
'username': 'anonymous',
'ip': '127.0.0.1',
'agent': 'agent',
'host': 'testserver',
'page': None,
'event_source': 'task'
}
}
actual_event = self.get_event()
assert_event_matches(expected_event, actual_event)