Skip to content
This repository has been archived by the owner on Aug 21, 2024. It is now read-only.

Commit

Permalink
Added ungraded and graded sections to test videos.
Browse files Browse the repository at this point in the history
  • Loading branch information
dsjen committed Sep 30, 2015
1 parent 3ed00ef commit a1198ae
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 24 deletions.
5 changes: 4 additions & 1 deletion analytics_dashboard/courses/presenters/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,10 @@ def module_type(self):

@property
def module_graded_type(self):
""" Graded module type to review structure for. E.g. True, False, None. """
"""
Property used to filter modules by. True/False will include only modules with
that grade field. Set to None if not filtering by the graded value.
"""
return None

def get_cache_key(self, name):
Expand Down
26 changes: 26 additions & 0 deletions analytics_dashboard/courses/tests/factories.py
Original file line number Diff line number Diff line change
Expand Up @@ -309,3 +309,29 @@ def _get_video_segments(self, segment_min, segment_max):
'created': CREATED_DATETIME_STRING
})
return segments

def videos(self):
"""
Mock video data.
"""
videos = [
{
"pipeline_video_id": "edX/DemoX/Demo_Course|i4x-edX-DemoX-video-7e9b434e6de3435ab99bd3fb25bde807",
"encoded_module_id": "i4x-edX-DemoX-video-7e9b434e6de3435ab99bd3fb25bde807",
"duration": 257,
"segment_length": 5,
"users_at_start": 10,
"users_at_end": 0,
"created": "2015-04-15T214158"
},
{
"pipeline_video_id": "edX/DemoX/Demo_Course|i4x-edX-DemoX-videoalpha-0b9e39477cf34507a7a48f74be381fdd",
"encoded_module_id": "i4x-edX-DemoX-videoalpha-0b9e39477cf34507a7a48f74be381fdd",
"duration": 195,
"segment_length": 5,
"users_at_start": 55,
"users_at_end": 0,
"created": "2015-04-15T214158"
}
]
return videos
90 changes: 67 additions & 23 deletions analytics_dashboard/courses/tests/test_presenters.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,19 @@
import analyticsclient.constants.activity_type as AT
from django.core.cache import cache
from django.core.urlresolvers import reverse
from django.test import TestCase
from django.test import (override_settings, TestCase)
import mock
from ddt import ddt, data

from common.tests import course_fixtures

from courses.exceptions import NoVideosError
from courses.presenters import BasePresenter
from courses.presenters.engagement import (CourseEngagementActivityPresenter, CourseEngagementVideoPresenter)
from courses.presenters.enrollment import (CourseEnrollmentPresenter, CourseEnrollmentDemographicsPresenter)
from courses.presenters.performance import CoursePerformancePresenter
from courses.tests import utils, SwitchMixin
from courses.tests.factories import CourseEngagementDataFactory, CoursePerformanceDataFactory
from courses.tests import (SwitchMixin, utils)
from courses.tests.factories import (CourseEngagementDataFactory, CoursePerformanceDataFactory)


class BasePresenterTests(TestCase):
Expand Down Expand Up @@ -123,6 +125,7 @@ def test_get_summary_and_trend_data_small(self, mock_activity):
self.assertSummaryAndTrendsValid(True, self.get_expected_trends_small(True))


@ddt
class CourseEngagementVideoPresenterTests(SwitchMixin, TestCase):
SECTION_ID = 'i4x://edX/DemoX/chapter/9fca584977d04885bc911ea76a9ef29e'
SUBSECTION_ID = 'i4x://edX/DemoX/sequential/07bc32474380492cb34f76e5f9d9a135'
Expand All @@ -142,6 +145,65 @@ def test_default_block_data(self):
'start_only_percent': 0,
})

def _create_graded_and_ungraded_course_structure_fixtures(self):
"""
Create graded and ungraded video sections.
"""
chapter_fixture = course_fixtures.ChapterFixture()
# a dictionary to access the fixtures easily
course_structure_fixtures = {
'chapter': chapter_fixture,
'course': course_fixtures.CourseFixture(org='this', course='course', run='id')
}

for grade_status in ['graded', 'ungraded']:
sequential_fixture = course_fixtures.SequentialFixture(graded=grade_status is 'graded').add_children(
course_fixtures.VerticalFixture().add_children(
course_fixtures.VideoFixture()
)
)
course_structure_fixtures[grade_status] = {
'sequential': sequential_fixture,
}
chapter_fixture.add_children(sequential_fixture)

course_structure_fixtures['course'].add_children(chapter_fixture)
return course_structure_fixtures

@data('graded', 'ungraded')
@override_settings(CACHES={
'default': {
'BACKEND': 'django.core.cache.backends.dummy.DummyCache',
}
})
def test_graded_modes(self, grade_status):
"""
Ensure that video structure will be retrieved for both graded and ungraded.
"""
factory = CourseEngagementDataFactory()
course_structure_fixtures = self._create_graded_and_ungraded_course_structure_fixtures()
course_fixture = course_structure_fixtures['course']
chapter_fixture = course_structure_fixtures['chapter']

with mock.patch('slumber.Resource.get', mock.Mock(return_value=course_fixture.course_structure())):
with mock.patch('analyticsclient.course.Course.videos', mock.Mock(return_value=factory.videos())):
# check that we get results for both graded and ungraded
sequential_fixture = course_structure_fixtures[grade_status]['sequential']
video_id = sequential_fixture.children[0].children[0].id

actual_videos = self.presenter.subsection_children(chapter_fixture.id, sequential_fixture.id)
expected_url = reverse('courses:engagement:video_timeline',
kwargs={
'course_id': self.course_id,
'section_id': chapter_fixture.id,
'subsection_id': sequential_fixture.id,
'video_id': video_id
})
expected = [{'index': 1, 'name': None, 'end_percent': 0, 'url': expected_url, 'start_only_percent': 0,
'id': video_id, 'users_at_start': 0, 'start_only_users': 0, 'users_at_end': 0,
'children': []}]
self.assertListEqual(actual_videos, expected)

def test_module_id_to_data_id(self):
opaque_key_id = 'i4x-edX-DemoX-video-0b9e39477cf34507a7a48f74be381fdd'
module_id = 'i4x://edX/DemoX/video/0b9e39477cf34507a7a48f74be381fdd'
Expand Down Expand Up @@ -245,26 +307,8 @@ def test_attach_aggregated_data_to_parent(self):

@mock.patch('analyticsclient.course.Course.videos')
def test_fetch_course_module_data(self, mock_videos):
videos = [
{
"pipeline_video_id": "edX/DemoX/Demo_Course|i4x-edX-DemoX-video-7e9b434e6de3435ab99bd3fb25bde807",
"encoded_module_id": "i4x-edX-DemoX-video-7e9b434e6de3435ab99bd3fb25bde807",
"duration": 257,
"segment_length": 5,
"users_at_start": 10,
"users_at_end": 0,
"created": "2015-04-15T214158"
},
{
"pipeline_video_id": "edX/DemoX/Demo_Course|i4x-edX-DemoX-videoalpha-0b9e39477cf34507a7a48f74be381fdd",
"encoded_module_id": "i4x-edX-DemoX-videoalpha-0b9e39477cf34507a7a48f74be381fdd",
"duration": 195,
"segment_length": 5,
"users_at_start": 55,
"users_at_end": 0,
"created": "2015-04-15T214158"
}
]
factory = CourseEngagementDataFactory()
videos = factory.videos()
mock_videos.return_value = videos
self.assertListEqual(self.presenter.fetch_course_module_data(), videos)

Expand Down
6 changes: 6 additions & 0 deletions common/tests/course_fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

class CourseStructureAPIFixtureMixin(object):
"""Represents a course that can serialize itself in the form generated by the Course Structure API."""
# pylint: disable=unused-argument
def __init__(self, *args, **kwargs):
self._uuid = uuid.uuid4().hex
self._type = None
Expand All @@ -15,6 +16,10 @@ def __init__(self, *args, **kwargs):
self._course = None
self._run = None

@property
def children(self):
return self._children

def to_dict(self):
"""Return a dict representation of this block in the form generated by the Course Structure API."""
return {
Expand All @@ -37,6 +42,7 @@ def pre_order(self):
for child in self._children:
# Children should inherit and cache org, course, and run for ID generation.
# 'graded' is also inherited.
# pylint: disable=protected-access
child._org = self._org
child._course = self._course
child._run = self._run
Expand Down

0 comments on commit a1198ae

Please sign in to comment.