Commit b777530d by John Eskew

Add SharedModuleStoreTestCase.setUpClassAndTestData() context manager

for use when a test class has a setUpTestData() method which uses
variables set up in the setUpClass() method.
Change base teams API test class to use the context manager.
parent 65e26e3e
...@@ -4,6 +4,7 @@ Modulestore configuration for test cases. ...@@ -4,6 +4,7 @@ Modulestore configuration for test cases.
""" """
import functools import functools
from uuid import uuid4 from uuid import uuid4
from contextlib import contextmanager
from mock import patch from mock import patch
...@@ -267,9 +268,10 @@ class SharedModuleStoreTestCase(TestCase): ...@@ -267,9 +268,10 @@ class SharedModuleStoreTestCase(TestCase):
MODULESTORE = mixed_store_config(mkdtemp_clean(), {}, include_xml=False) MODULESTORE = mixed_store_config(mkdtemp_clean(), {}, include_xml=False)
@classmethod @classmethod
def setUpClass(cls): def _setUpModuleStore(cls): # pylint: disable=invalid-name
super(SharedModuleStoreTestCase, cls).setUpClass() """
Set up the modulestore for an entire test class.
"""
cls._settings_override = override_settings(MODULESTORE=cls.MODULESTORE) cls._settings_override = override_settings(MODULESTORE=cls.MODULESTORE)
cls._settings_override.__enter__() cls._settings_override.__enter__()
XMODULE_FACTORY_LOCK.enable() XMODULE_FACTORY_LOCK.enable()
...@@ -277,6 +279,40 @@ class SharedModuleStoreTestCase(TestCase): ...@@ -277,6 +279,40 @@ class SharedModuleStoreTestCase(TestCase):
cls.store = modulestore() cls.store = modulestore()
@classmethod @classmethod
@contextmanager
def setUpClassAndTestData(cls): # pylint: disable=invalid-name
"""
For use when the test class has a setUpTestData() method that uses variables
that are setup during setUpClass() of the same test class.
Use it like so:
@classmethod
def setUpClass(cls):
with super(MyTestClass, cls).setUpClassAndTestData():
<all the cls.setUpClass() setup code that performs modulestore setup...>
@classmethod
def setUpTestData(cls):
<all the setup code that creates Django models per test class...>
<these models can use variables (courses) setup in setUpClass() above>
"""
cls._setUpModuleStore()
# Now yield to allow the test class to run its setUpClass() setup code.
yield
# Now call the base class, which calls back into the test class's setUpTestData().
super(SharedModuleStoreTestCase, cls).setUpClass()
@classmethod
def setUpClass(cls):
"""
For use when the test class has no setUpTestData() method -or-
when that method does not use variable set up in setUpClass().
"""
super(SharedModuleStoreTestCase, cls).setUpClass()
cls._setUpModuleStore()
@classmethod
def tearDownClass(cls): def tearDownClass(cls):
drop_mongo_collections() # pylint: disable=no-value-for-parameter drop_mongo_collections() # pylint: disable=no-value-for-parameter
clear_all_caches() clear_all_caches()
......
...@@ -200,89 +200,90 @@ class TeamAPITestCase(APITestCase, SharedModuleStoreTestCase): ...@@ -200,89 +200,90 @@ class TeamAPITestCase(APITestCase, SharedModuleStoreTestCase):
@classmethod @classmethod
def setUpClass(cls): def setUpClass(cls):
super(TeamAPITestCase, cls).setUpClass() with super(TeamAPITestCase, cls).setUpClassAndTestData():
teams_configuration_1 = { teams_configuration_1 = {
'topics': 'topics':
[ [
{ {
'id': 'topic_{}'.format(i), 'id': 'topic_{}'.format(i),
'name': name, 'name': name,
'description': 'Description for topic {}.'.format(i) 'description': 'Description for topic {}.'.format(i)
} for i, name in enumerate([u'Sólar power', 'Wind Power', 'Nuclear Power', 'Coal Power']) } for i, name in enumerate([u'Sólar power', 'Wind Power', 'Nuclear Power', 'Coal Power'])
] ]
} }
cls.test_course_1 = CourseFactory.create( cls.test_course_1 = CourseFactory.create(
org='TestX', org='TestX',
course='TS101', course='TS101',
display_name='Test Course', display_name='Test Course',
teams_configuration=teams_configuration_1 teams_configuration=teams_configuration_1
) )
teams_configuration_2 = { teams_configuration_2 = {
'topics': 'topics':
[ [
{ {
'id': 'topic_5', 'id': 'topic_5',
'name': 'Other Interests', 'name': 'Other Interests',
'description': 'Description for topic 5.' 'description': 'Description for topic 5.'
}, },
{ {
'id': 'topic_6', 'id': 'topic_6',
'name': 'Public Profiles', 'name': 'Public Profiles',
'description': 'Description for topic 6.' 'description': 'Description for topic 6.'
}, },
{ {
'id': 'Topic_6.5', 'id': 'Topic_6.5',
'name': 'Test Accessibility Topic', 'name': 'Test Accessibility Topic',
'description': 'Description for Topic_6.5' 'description': 'Description for Topic_6.5'
}, },
], ],
'max_team_size': 1 'max_team_size': 1
} }
cls.test_course_2 = CourseFactory.create( cls.test_course_2 = CourseFactory.create(
org='MIT', org='MIT',
course='6.002x', course='6.002x',
display_name='Circuits', display_name='Circuits',
teams_configuration=teams_configuration_2 teams_configuration=teams_configuration_2
) )
def setUp(self): @classmethod
super(TeamAPITestCase, self).setUp() def setUpTestData(cls):
self.topics_count = 4 super(TeamAPITestCase, cls).setUpTestData()
self.users = { cls.topics_count = 4
'staff': AdminFactory.create(password=self.test_password), cls.users = {
'course_staff': StaffFactory.create(course_key=self.test_course_1.id, password=self.test_password) 'staff': AdminFactory.create(password=cls.test_password),
'course_staff': StaffFactory.create(course_key=cls.test_course_1.id, password=cls.test_password)
} }
self.create_and_enroll_student(username='student_enrolled') cls.create_and_enroll_student(username='student_enrolled')
self.create_and_enroll_student(username='student_enrolled_not_on_team') cls.create_and_enroll_student(username='student_enrolled_not_on_team')
self.create_and_enroll_student(username='student_unenrolled', courses=[]) cls.create_and_enroll_student(username='student_unenrolled', courses=[])
# Make this student a community TA. # Make this student a community TA.
self.create_and_enroll_student(username='community_ta') cls.create_and_enroll_student(username='community_ta')
seed_permissions_roles(self.test_course_1.id) seed_permissions_roles(cls.test_course_1.id)
community_ta_role = Role.objects.get(name=FORUM_ROLE_COMMUNITY_TA, course_id=self.test_course_1.id) community_ta_role = Role.objects.get(name=FORUM_ROLE_COMMUNITY_TA, course_id=cls.test_course_1.id)
community_ta_role.users.add(self.users['community_ta']) community_ta_role.users.add(cls.users['community_ta'])
# This student is enrolled in both test courses and is a member of a team in each course, but is not on the # This student is enrolled in both test courses and is a member of a team in each course, but is not on the
# same team as student_enrolled. # same team as student_enrolled.
self.create_and_enroll_student( cls.create_and_enroll_student(
courses=[self.test_course_1, self.test_course_2], courses=[cls.test_course_1, cls.test_course_2],
username='student_enrolled_both_courses_other_team' username='student_enrolled_both_courses_other_team'
) )
# Make this student have a public profile # Make this student have a public profile
self.create_and_enroll_student( cls.create_and_enroll_student(
courses=[self.test_course_2], courses=[cls.test_course_2],
username='student_enrolled_public_profile' username='student_enrolled_public_profile'
) )
profile = self.users['student_enrolled_public_profile'].profile profile = cls.users['student_enrolled_public_profile'].profile
profile.year_of_birth = 1970 profile.year_of_birth = 1970
profile.save() profile.save()
# This student is enrolled in the other course, but not yet a member of a team. This is to allow # This student is enrolled in the other course, but not yet a member of a team. This is to allow
# course_2 to use a max_team_size of 1 without breaking other tests on course_1 # course_2 to use a max_team_size of 1 without breaking other tests on course_1
self.create_and_enroll_student( cls.create_and_enroll_student(
courses=[self.test_course_2], courses=[cls.test_course_2],
username='student_enrolled_other_course_not_on_team' username='student_enrolled_other_course_not_on_team'
) )
...@@ -292,58 +293,58 @@ class TeamAPITestCase(APITestCase, SharedModuleStoreTestCase): ...@@ -292,58 +293,58 @@ class TeamAPITestCase(APITestCase, SharedModuleStoreTestCase):
sender=CourseTeam, sender=CourseTeam,
dispatch_uid='teams.signals.course_team_post_save_callback' dispatch_uid='teams.signals.course_team_post_save_callback'
): ):
self.solar_team = CourseTeamFactory.create( cls.solar_team = CourseTeamFactory.create(
name=u'Sólar team', name=u'Sólar team',
course_id=self.test_course_1.id, course_id=cls.test_course_1.id,
topic_id='topic_0' topic_id='topic_0'
) )
self.wind_team = CourseTeamFactory.create(name='Wind Team', course_id=self.test_course_1.id) cls.wind_team = CourseTeamFactory.create(name='Wind Team', course_id=cls.test_course_1.id)
self.nuclear_team = CourseTeamFactory.create(name='Nuclear Team', course_id=self.test_course_1.id) cls.nuclear_team = CourseTeamFactory.create(name='Nuclear Team', course_id=cls.test_course_1.id)
self.another_team = CourseTeamFactory.create(name='Another Team', course_id=self.test_course_2.id) cls.another_team = CourseTeamFactory.create(name='Another Team', course_id=cls.test_course_2.id)
self.public_profile_team = CourseTeamFactory.create( cls.public_profile_team = CourseTeamFactory.create(
name='Public Profile Team', name='Public Profile Team',
course_id=self.test_course_2.id, course_id=cls.test_course_2.id,
topic_id='topic_6' topic_id='topic_6'
) )
self.search_team = CourseTeamFactory.create( cls.search_team = CourseTeamFactory.create(
name='Search', name='Search',
description='queryable text', description='queryable text',
country='GS', country='GS',
language='to', language='to',
course_id=self.test_course_2.id, course_id=cls.test_course_2.id,
topic_id='topic_7' topic_id='topic_7'
) )
self.chinese_team = CourseTeamFactory.create( cls.chinese_team = CourseTeamFactory.create(
name=u'著文企臺個', name=u'著文企臺個',
description=u'共樣地面較,件展冷不護者這與民教過住意,國制銀產物助音是勢一友', description=u'共樣地面較,件展冷不護者這與民教過住意,國制銀產物助音是勢一友',
country='CN', country='CN',
language='zh_HANS', language='zh_HANS',
course_id=self.test_course_2.id, course_id=cls.test_course_2.id,
topic_id='topic_7' topic_id='topic_7'
) )
self.test_team_name_id_map = {team.name: team for team in ( cls.test_team_name_id_map = {team.name: team for team in (
self.solar_team, cls.solar_team,
self.wind_team, cls.wind_team,
self.nuclear_team, cls.nuclear_team,
self.another_team, cls.another_team,
self.public_profile_team, cls.public_profile_team,
self.search_team, cls.search_team,
self.chinese_team, cls.chinese_team,
)} )}
for user, course in [('staff', self.test_course_1), ('course_staff', self.test_course_1)]: for user, course in [('staff', cls.test_course_1), ('course_staff', cls.test_course_1)]:
CourseEnrollment.enroll( CourseEnrollment.enroll(
self.users[user], course.id, check_access=True cls.users[user], course.id, check_access=True
) )
# Django Rest Framework v3 requires us to pass a request to serializers # Django Rest Framework v3 requires us to pass a request to serializers
# that have URL fields. Since we're invoking this code outside the context # that have URL fields. Since we're invoking this code outside the context
# of a request, we need to simulate that there's a request. # of a request, we need to simulate that there's a request.
self.solar_team.add_user(self.users['student_enrolled']) cls.solar_team.add_user(cls.users['student_enrolled'])
self.nuclear_team.add_user(self.users['student_enrolled_both_courses_other_team']) cls.nuclear_team.add_user(cls.users['student_enrolled_both_courses_other_team'])
self.another_team.add_user(self.users['student_enrolled_both_courses_other_team']) cls.another_team.add_user(cls.users['student_enrolled_both_courses_other_team'])
self.public_profile_team.add_user(self.users['student_enrolled_public_profile']) cls.public_profile_team.add_user(cls.users['student_enrolled_public_profile'])
def build_membership_data_raw(self, username, team): def build_membership_data_raw(self, username, team):
"""Assembles a membership creation payload based on the raw values provided.""" """Assembles a membership creation payload based on the raw values provided."""
...@@ -353,21 +354,22 @@ class TeamAPITestCase(APITestCase, SharedModuleStoreTestCase): ...@@ -353,21 +354,22 @@ class TeamAPITestCase(APITestCase, SharedModuleStoreTestCase):
"""Assembles a membership creation payload based on the username and team model provided.""" """Assembles a membership creation payload based on the username and team model provided."""
return self.build_membership_data_raw(self.users[username].username, team.team_id) return self.build_membership_data_raw(self.users[username].username, team.team_id)
def create_and_enroll_student(self, courses=None, username=None): @classmethod
def create_and_enroll_student(cls, courses=None, username=None):
""" Creates a new student and enrolls that student in the course. """ Creates a new student and enrolls that student in the course.
Adds the new user to the self.users dictionary with the username as the key. Adds the new user to the cls.users dictionary with the username as the key.
Returns the username once the user has been created. Returns the username once the user has been created.
""" """
if username is not None: if username is not None:
user = UserFactory.create(password=self.test_password, username=username) user = UserFactory.create(password=cls.test_password, username=username)
else: else:
user = UserFactory.create(password=self.test_password) user = UserFactory.create(password=cls.test_password)
courses = courses if courses is not None else [self.test_course_1] courses = courses if courses is not None else [cls.test_course_1]
for course in courses: for course in courses:
CourseEnrollment.enroll(user, course.id, check_access=True) CourseEnrollment.enroll(user, course.id, check_access=True)
self.users[user.username] = user cls.users[user.username] = user
return user.username return user.username
......
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