Commit 9bf22ea9 by Daniel Friedman

Verify grade export works for problems in split tests

TNL-41
parent 578f5b62
...@@ -23,6 +23,7 @@ from instructor_task.models import InstructorTask, PROGRESS ...@@ -23,6 +23,7 @@ from instructor_task.models import InstructorTask, PROGRESS
from instructor_task.tests.test_base import (InstructorTaskTestCase, from instructor_task.tests.test_base import (InstructorTaskTestCase,
InstructorTaskCourseTestCase, InstructorTaskCourseTestCase,
InstructorTaskModuleTestCase, InstructorTaskModuleTestCase,
TestReportMixin,
TEST_COURSE_KEY) TEST_COURSE_KEY)
...@@ -158,7 +159,7 @@ class InstructorTaskModuleSubmitTest(InstructorTaskModuleTestCase): ...@@ -158,7 +159,7 @@ class InstructorTaskModuleSubmitTest(InstructorTaskModuleTestCase):
self._test_submit_task(submit_delete_problem_state_for_all_students) self._test_submit_task(submit_delete_problem_state_for_all_students)
class InstructorTaskCourseSubmitTest(InstructorTaskCourseTestCase): class InstructorTaskCourseSubmitTest(TestReportMixin, InstructorTaskCourseTestCase):
"""Tests API methods that involve the submission of course-based background tasks.""" """Tests API methods that involve the submission of course-based background tasks."""
def setUp(self): def setUp(self):
......
...@@ -2,12 +2,16 @@ ...@@ -2,12 +2,16 @@
Base test classes for LMS instructor-initiated background tasks Base test classes for LMS instructor-initiated background tasks
""" """
import os
import shutil
import json import json
from uuid import uuid4 from uuid import uuid4
from mock import Mock from mock import Mock
from celery.states import SUCCESS, FAILURE from celery.states import SUCCESS, FAILURE
from django.conf import settings
from django.test.testcases import TestCase from django.test.testcases import TestCase
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.test.utils import override_settings from django.test.utils import override_settings
...@@ -104,14 +108,25 @@ class InstructorTaskCourseTestCase(LoginEnrollmentTestCase, ModuleStoreTestCase) ...@@ -104,14 +108,25 @@ class InstructorTaskCourseTestCase(LoginEnrollmentTestCase, ModuleStoreTestCase)
course = None course = None
current_user = None current_user = None
def initialize_course(self): def initialize_course(self, course_factory_kwargs=None):
"""Create a course in the store, with a chapter and section.""" """
Create a course in the store, with a chapter and section.
Arguments:
course_factory_kwargs (dict): kwargs dict to pass to
CourseFactory.create()
"""
self.module_store = modulestore() self.module_store = modulestore()
# Create the course # Create the course
self.course = CourseFactory.create(org=TEST_COURSE_ORG, course_args = {
number=TEST_COURSE_NUMBER, "org": TEST_COURSE_ORG,
display_name=TEST_COURSE_NAME) "number": TEST_COURSE_NUMBER,
"display_name": TEST_COURSE_NAME
}
if course_factory_kwargs is not None:
course_args.update(course_factory_kwargs)
self.course = CourseFactory.create(**course_args)
# Add a chapter to the course # Add a chapter to the course
chapter = ItemFactory.create(parent_location=self.course.location, chapter = ItemFactory.create(parent_location=self.course.location,
...@@ -134,20 +149,21 @@ class InstructorTaskCourseTestCase(LoginEnrollmentTestCase, ModuleStoreTestCase) ...@@ -134,20 +149,21 @@ class InstructorTaskCourseTestCase(LoginEnrollmentTestCase, ModuleStoreTestCase)
self.login(InstructorTaskCourseTestCase.get_user_email(username), "test") self.login(InstructorTaskCourseTestCase.get_user_email(username), "test")
self.current_user = username self.current_user = username
def _create_user(self, username, is_staff=False): def _create_user(self, username, email=None, is_staff=False):
"""Creates a user and enrolls them in the test course.""" """Creates a user and enrolls them in the test course."""
email = InstructorTaskCourseTestCase.get_user_email(username) if email is None:
email = InstructorTaskCourseTestCase.get_user_email(username)
thisuser = UserFactory.create(username=username, email=email, is_staff=is_staff) thisuser = UserFactory.create(username=username, email=email, is_staff=is_staff)
CourseEnrollmentFactory.create(user=thisuser, course_id=self.course.id) CourseEnrollmentFactory.create(user=thisuser, course_id=self.course.id)
return thisuser return thisuser
def create_instructor(self, username): def create_instructor(self, username, email=None):
"""Creates an instructor for the test course.""" """Creates an instructor for the test course."""
return self._create_user(username, is_staff=True) return self._create_user(username, email, is_staff=True)
def create_student(self, username): def create_student(self, username, email=None):
"""Creates a student for the test course.""" """Creates a student for the test course."""
return self._create_user(username, is_staff=False) return self._create_user(username, email, is_staff=False)
@staticmethod @staticmethod
def get_task_status(task_id): def get_task_status(task_id):
...@@ -184,16 +200,18 @@ class InstructorTaskModuleTestCase(InstructorTaskCourseTestCase): ...@@ -184,16 +200,18 @@ class InstructorTaskModuleTestCase(InstructorTaskCourseTestCase):
else: else:
return TEST_COURSE_KEY.make_usage_key('problem', problem_url_name) return TEST_COURSE_KEY.make_usage_key('problem', problem_url_name)
def define_option_problem(self, problem_url_name): def define_option_problem(self, problem_url_name, parent=None):
"""Create the problem definition so the answer is Option 1""" """Create the problem definition so the answer is Option 1"""
if parent is None:
parent = self.problem_section
factory = OptionResponseXMLFactory() factory = OptionResponseXMLFactory()
factory_args = {'question_text': 'The correct answer is {0}'.format(OPTION_1), factory_args = {'question_text': 'The correct answer is {0}'.format(OPTION_1),
'options': [OPTION_1, OPTION_2], 'options': [OPTION_1, OPTION_2],
'correct_option': OPTION_1, 'correct_option': OPTION_1,
'num_responses': 2} 'num_responses': 2}
problem_xml = factory.build_xml(**factory_args) problem_xml = factory.build_xml(**factory_args)
ItemFactory.create(parent_location=self.problem_section.location, ItemFactory.create(parent_location=parent.location,
parent=self.problem_section, parent=parent,
category="problem", category="problem",
display_name=str(problem_url_name), display_name=str(problem_url_name),
data=problem_xml) data=problem_xml)
...@@ -220,3 +238,13 @@ class InstructorTaskModuleTestCase(InstructorTaskCourseTestCase): ...@@ -220,3 +238,13 @@ class InstructorTaskModuleTestCase(InstructorTaskCourseTestCase):
module_type=descriptor.location.category, module_type=descriptor.location.category,
module_state_key=descriptor.location, module_state_key=descriptor.location,
) )
class TestReportMixin(object):
"""
Cleans up after tests that place files in the reports directory.
"""
def tearDown(self):
reports_download_path = settings.GRADES_DOWNLOAD['ROOT_PATH']
if os.path.exists(reports_download_path):
shutil.rmtree(reports_download_path)
...@@ -4,13 +4,9 @@ Unit tests for LMS instructor-initiated background tasks helper functions. ...@@ -4,13 +4,9 @@ Unit tests for LMS instructor-initiated background tasks helper functions.
Tests that CSV grade report generation works with unicode emails. Tests that CSV grade report generation works with unicode emails.
""" """
import os
import shutil
import ddt import ddt
from mock import Mock, patch from mock import Mock, patch
from django.conf import settings
from django.test.testcases import TestCase from django.test.testcases import TestCase
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
...@@ -20,30 +16,17 @@ from student.tests.factories import CourseEnrollmentFactory, UserFactory ...@@ -20,30 +16,17 @@ from student.tests.factories import CourseEnrollmentFactory, UserFactory
from instructor_task.models import ReportStore from instructor_task.models import ReportStore
from instructor_task.tasks_helper import upload_grades_csv, upload_students_csv from instructor_task.tasks_helper import upload_grades_csv, upload_students_csv
from instructor_task.tests.test_base import InstructorTaskCourseTestCase, TestReportMixin
class TestReport(ModuleStoreTestCase): @ddt.ddt
class TestInstructorGradeReport(TestReportMixin, InstructorTaskCourseTestCase):
""" """
Base class for testing CSV download tasks. Tests that CSV grade report generation works.
""" """
def setUp(self): def setUp(self):
self.course = CourseFactory.create() self.course = CourseFactory.create()
def tearDown(self):
if os.path.exists(settings.GRADES_DOWNLOAD['ROOT_PATH']):
shutil.rmtree(settings.GRADES_DOWNLOAD['ROOT_PATH'])
def create_student(self, username, email):
student = UserFactory.create(username=username, email=email)
CourseEnrollmentFactory.create(user=student, course_id=self.course.id)
return student
@ddt.ddt
class TestInstructorGradeReport(TestReport):
"""
Tests that CSV grade report generation works.
"""
@ddt.data([u'student@example.com', u'ni\xf1o@example.com']) @ddt.data([u'student@example.com', u'ni\xf1o@example.com'])
def test_unicode_emails(self, emails): def test_unicode_emails(self, emails):
""" """
...@@ -79,10 +62,13 @@ class TestInstructorGradeReport(TestReport): ...@@ -79,10 +62,13 @@ class TestInstructorGradeReport(TestReport):
@ddt.ddt @ddt.ddt
class TestStudentReport(TestReport): class TestStudentReport(TestReportMixin, InstructorTaskCourseTestCase):
""" """
Tests that CSV student profile report generation works. Tests that CSV student profile report generation works.
""" """
def setUp(self):
self.course = CourseFactory.create()
def test_success(self): def test_success(self):
self.create_student('student', 'student@example.com') self.create_student('student', 'student@example.com')
task_input = {'features': []} task_input = {'features': []}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment