Merge pull request #15951 from edx/jmbowman/ddt_cleanup
ddt usage cleanup
This commit is contained in:
@@ -183,6 +183,9 @@ class MockTransformer(BlockStructureTransformer):
|
||||
def transform(self, usage_info, block_structure):
|
||||
pass
|
||||
|
||||
def __repr__(self):
|
||||
return self.name()
|
||||
|
||||
|
||||
class MockFilteringTransformer(FilteringTransformerMixin, BlockStructureTransformer):
|
||||
"""
|
||||
|
||||
@@ -46,10 +46,18 @@ class CourseOverviewTestCase(ModuleStoreTestCase):
|
||||
"""
|
||||
|
||||
TODAY = timezone.now()
|
||||
LAST_MONTH = TODAY - datetime.timedelta(days=30)
|
||||
LAST_WEEK = TODAY - datetime.timedelta(days=7)
|
||||
NEXT_WEEK = TODAY + datetime.timedelta(days=7)
|
||||
NEXT_MONTH = TODAY + datetime.timedelta(days=30)
|
||||
LAST_MONTH = 'last_month'
|
||||
LAST_WEEK = 'last_week'
|
||||
NEXT_WEEK = 'next_week'
|
||||
NEXT_MONTH = 'next_month'
|
||||
DATES = {
|
||||
'default_start_date': DEFAULT_START_DATE,
|
||||
LAST_MONTH: TODAY - datetime.timedelta(days=30),
|
||||
LAST_WEEK: TODAY - datetime.timedelta(days=7),
|
||||
NEXT_WEEK: TODAY + datetime.timedelta(days=7),
|
||||
NEXT_MONTH: TODAY + datetime.timedelta(days=30),
|
||||
None: None,
|
||||
}
|
||||
|
||||
COURSE_OVERVIEW_TABS = {'courseware', 'info', 'textbooks', 'discussion', 'wiki', 'progress'}
|
||||
|
||||
@@ -229,7 +237,7 @@ class CourseOverviewTestCase(ModuleStoreTestCase):
|
||||
},
|
||||
{
|
||||
# # Don't set display name
|
||||
"start": DEFAULT_START_DATE, # Default start and end dates
|
||||
"start": 'default_start_date', # Default start and end dates
|
||||
"end": None,
|
||||
"advertised_start": None, # No advertised start
|
||||
"pre_requisite_courses": [], # No pre-requisites
|
||||
@@ -251,10 +259,15 @@ class CourseOverviewTestCase(ModuleStoreTestCase):
|
||||
modulestore_type (ModuleStoreEnum.Type): type of store to create the
|
||||
course in.
|
||||
"""
|
||||
kwargs = course_kwargs.copy()
|
||||
kwargs['start'] = self.DATES[course_kwargs['start']]
|
||||
kwargs['end'] = self.DATES[course_kwargs['end']]
|
||||
if 'announcement' in course_kwargs:
|
||||
kwargs['announcement'] = self.DATES[course_kwargs['announcement']]
|
||||
# Note: We specify a value for 'run' here because, for some reason,
|
||||
# .create raises an InvalidKeyError if we don't (even though my
|
||||
# other test functions don't specify a run but work fine).
|
||||
course = CourseFactory.create(default_store=modulestore_type, run="TestRun", **course_kwargs)
|
||||
course = CourseFactory.create(default_store=modulestore_type, run="TestRun", **kwargs)
|
||||
self.check_course_overview_against_course(course)
|
||||
|
||||
@ddt.data(ModuleStoreEnum.Type.mongo, ModuleStoreEnum.Type.split)
|
||||
|
||||
@@ -35,6 +35,12 @@ class TestMinGradedRequirementStatus(ModuleStoreTestCase):
|
||||
VALID_DUE_DATE = datetime.now(pytz.UTC) + timedelta(days=20)
|
||||
EXPIRED_DUE_DATE = datetime.now(pytz.UTC) - timedelta(days=20)
|
||||
|
||||
DATES = {
|
||||
'valid': VALID_DUE_DATE,
|
||||
'expired': EXPIRED_DUE_DATE,
|
||||
None: None,
|
||||
}
|
||||
|
||||
def setUp(self):
|
||||
super(TestMinGradedRequirementStatus, self).setUp()
|
||||
self.course = CourseFactory.create(
|
||||
@@ -85,13 +91,13 @@ class TestMinGradedRequirementStatus(ModuleStoreTestCase):
|
||||
self.assertEqual(req_status[0]['reason'], expected_reason)
|
||||
|
||||
@ddt.data(
|
||||
(0.6, VALID_DUE_DATE),
|
||||
(0.6, 'valid'),
|
||||
(0.52, None),
|
||||
)
|
||||
@ddt.unpack
|
||||
def test_min_grade_requirement_with_valid_grade(self, grade, due_date):
|
||||
def test_min_grade_requirement_with_valid_grade(self, grade, due_date_name):
|
||||
"""Test with valid grades submitted before deadline"""
|
||||
self.assert_requirement_status(grade, due_date, 'satisfied')
|
||||
self.assert_requirement_status(grade, self.DATES[due_date_name], 'satisfied')
|
||||
|
||||
def test_grade_changed(self):
|
||||
""" Verify successive calls to update a satisfied grade requirement are recorded. """
|
||||
@@ -106,12 +112,12 @@ class TestMinGradedRequirementStatus(ModuleStoreTestCase):
|
||||
@ddt.data(
|
||||
(0.50, None),
|
||||
(0.51, None),
|
||||
(0.40, VALID_DUE_DATE),
|
||||
(0.40, 'valid'),
|
||||
)
|
||||
@ddt.unpack
|
||||
def test_min_grade_requirement_failed_grade_valid_deadline(self, grade, due_date):
|
||||
def test_min_grade_requirement_failed_grade_valid_deadline(self, grade, due_date_name):
|
||||
"""Test with failed grades and deadline is still open or not defined."""
|
||||
self.assert_requirement_status(grade, due_date, None)
|
||||
self.assert_requirement_status(grade, self.DATES[due_date_name], None)
|
||||
|
||||
def test_min_grade_requirement_failed_grade_expired_deadline(self):
|
||||
"""Test with failed grades and deadline expire"""
|
||||
|
||||
@@ -29,6 +29,10 @@ COMMAND_MODULE = 'openedx.core.djangoapps.programs.management.commands.backpopul
|
||||
class BackpopulateProgramCredentialsTests(CatalogIntegrationMixin, CredentialsApiConfigMixin, TestCase):
|
||||
"""Tests for the backpopulate_program_credentials management command."""
|
||||
course_run_key, alternate_course_run_key = (generate_course_run_key() for __ in range(2))
|
||||
# Constants for the _get_programs_data hierarchy types used in test_flatten()
|
||||
SEPARATE_PROGRAMS = 'separate_programs'
|
||||
SEPARATE_COURSES = 'separate_courses'
|
||||
SAME_COURSE = 'same_course'
|
||||
|
||||
def setUp(self):
|
||||
super(BackpopulateProgramCredentialsTests, self).setUp()
|
||||
@@ -44,6 +48,54 @@ class BackpopulateProgramCredentialsTests(CatalogIntegrationMixin, CredentialsAp
|
||||
catalog_integration = self.create_catalog_integration()
|
||||
UserFactory(username=catalog_integration.service_username)
|
||||
|
||||
def _get_programs_data(self, hierarchy_type):
|
||||
"""
|
||||
Generate a mock response for get_programs() with the given type of
|
||||
course hierarchy. Dramatically simplifies (and makes consistent
|
||||
between test runs) the ddt-generated test_flatten methods.
|
||||
"""
|
||||
if hierarchy_type == self.SEPARATE_PROGRAMS:
|
||||
return [
|
||||
ProgramFactory(
|
||||
courses=[
|
||||
CourseFactory(course_runs=[
|
||||
CourseRunFactory(key=self.course_run_key),
|
||||
]),
|
||||
]
|
||||
),
|
||||
ProgramFactory(
|
||||
courses=[
|
||||
CourseFactory(course_runs=[
|
||||
CourseRunFactory(key=self.alternate_course_run_key),
|
||||
]),
|
||||
]
|
||||
),
|
||||
]
|
||||
elif hierarchy_type == self.SEPARATE_COURSES:
|
||||
return [
|
||||
ProgramFactory(
|
||||
courses=[
|
||||
CourseFactory(course_runs=[
|
||||
CourseRunFactory(key=self.course_run_key),
|
||||
]),
|
||||
CourseFactory(course_runs=[
|
||||
CourseRunFactory(key=self.alternate_course_run_key),
|
||||
]),
|
||||
]
|
||||
),
|
||||
]
|
||||
else: # SAME_COURSE
|
||||
return [
|
||||
ProgramFactory(
|
||||
courses=[
|
||||
CourseFactory(course_runs=[
|
||||
CourseRunFactory(key=self.course_run_key),
|
||||
CourseRunFactory(key=self.alternate_course_run_key),
|
||||
]),
|
||||
]
|
||||
),
|
||||
]
|
||||
|
||||
@ddt.data(True, False)
|
||||
def test_handle(self, commit, mock_task, mock_get_programs):
|
||||
"""
|
||||
@@ -112,49 +164,10 @@ class BackpopulateProgramCredentialsTests(CatalogIntegrationMixin, CredentialsAp
|
||||
# The task should be called for both users since professional and no-id-professional are equivalent.
|
||||
mock_task.assert_has_calls([mock.call(self.alice.username), mock.call(self.bob.username)])
|
||||
|
||||
@ddt.data(
|
||||
[
|
||||
ProgramFactory(
|
||||
courses=[
|
||||
CourseFactory(course_runs=[
|
||||
CourseRunFactory(key=course_run_key),
|
||||
]),
|
||||
]
|
||||
),
|
||||
ProgramFactory(
|
||||
courses=[
|
||||
CourseFactory(course_runs=[
|
||||
CourseRunFactory(key=alternate_course_run_key),
|
||||
]),
|
||||
]
|
||||
),
|
||||
],
|
||||
[
|
||||
ProgramFactory(
|
||||
courses=[
|
||||
CourseFactory(course_runs=[
|
||||
CourseRunFactory(key=course_run_key),
|
||||
]),
|
||||
CourseFactory(course_runs=[
|
||||
CourseRunFactory(key=alternate_course_run_key),
|
||||
]),
|
||||
]
|
||||
),
|
||||
],
|
||||
[
|
||||
ProgramFactory(
|
||||
courses=[
|
||||
CourseFactory(course_runs=[
|
||||
CourseRunFactory(key=course_run_key),
|
||||
CourseRunFactory(key=alternate_course_run_key),
|
||||
]),
|
||||
]
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_handle_flatten(self, data, mock_task, mock_get_programs):
|
||||
@ddt.data(SEPARATE_PROGRAMS, SEPARATE_COURSES, SAME_COURSE)
|
||||
def test_handle_flatten(self, hierarchy_type, mock_task, mock_get_programs):
|
||||
"""Verify that program structures are flattened correctly."""
|
||||
mock_get_programs.return_value = data
|
||||
mock_get_programs.return_value = self._get_programs_data(hierarchy_type)
|
||||
|
||||
GeneratedCertificateFactory(
|
||||
user=self.alice,
|
||||
|
||||
@@ -53,11 +53,11 @@ class RegistrationValidationViewTests(test_utils.ApiTestCase):
|
||||
)
|
||||
|
||||
@ddt.data(
|
||||
['name', (name for name in testutils.VALID_NAMES)],
|
||||
['email', (email for email in testutils.VALID_EMAILS)],
|
||||
['password', (password for password in testutils.VALID_PASSWORDS)],
|
||||
['username', (username for username in testutils.VALID_USERNAMES)],
|
||||
['country', (country for country in testutils.VALID_COUNTRIES)]
|
||||
['name', [name for name in testutils.VALID_NAMES]],
|
||||
['email', [email for email in testutils.VALID_EMAILS]],
|
||||
['password', [password for password in testutils.VALID_PASSWORDS]],
|
||||
['username', [username for username in testutils.VALID_USERNAMES]],
|
||||
['country', [country for country in testutils.VALID_COUNTRIES]]
|
||||
)
|
||||
@ddt.unpack
|
||||
def test_positive_validation_decision(self, form_field_name, user_data):
|
||||
@@ -71,11 +71,11 @@ class RegistrationValidationViewTests(test_utils.ApiTestCase):
|
||||
|
||||
@ddt.data(
|
||||
# Skip None type for invalidity checks.
|
||||
['name', (name for name in testutils.INVALID_NAMES[1:])],
|
||||
['email', (email for email in testutils.INVALID_EMAILS[1:])],
|
||||
['password', (password for password in testutils.INVALID_PASSWORDS[1:])],
|
||||
['username', (username for username in testutils.INVALID_USERNAMES[1:])],
|
||||
['country', (country for country in testutils.INVALID_COUNTRIES[1:])]
|
||||
['name', [name for name in testutils.INVALID_NAMES[1:]]],
|
||||
['email', [email for email in testutils.INVALID_EMAILS[1:]]],
|
||||
['password', [password for password in testutils.INVALID_PASSWORDS[1:]]],
|
||||
['username', [username for username in testutils.INVALID_USERNAMES[1:]]],
|
||||
['country', [country for country in testutils.INVALID_COUNTRIES[1:]]]
|
||||
)
|
||||
@ddt.unpack
|
||||
def test_negative_validation_decision(self, form_field_name, user_data):
|
||||
|
||||
@@ -6,6 +6,8 @@ import ddt
|
||||
|
||||
from django.contrib.messages.middleware import MessageMiddleware
|
||||
from django.test import RequestFactory, TestCase
|
||||
|
||||
from common.test.utils import normalize_repr
|
||||
from openedx.core.djangolib.markup import HTML, Text
|
||||
from student.tests.factories import UserFactory
|
||||
|
||||
@@ -60,10 +62,10 @@ class UserMessagesTestCase(TestCase):
|
||||
self.assertEquals(messages[0].icon_class, expected_icon_class)
|
||||
|
||||
@ddt.data(
|
||||
(PageLevelMessages.register_error_message, UserMessageType.ERROR),
|
||||
(PageLevelMessages.register_info_message, UserMessageType.INFO),
|
||||
(PageLevelMessages.register_success_message, UserMessageType.SUCCESS),
|
||||
(PageLevelMessages.register_warning_message, UserMessageType.WARNING),
|
||||
(normalize_repr(PageLevelMessages.register_error_message), UserMessageType.ERROR),
|
||||
(normalize_repr(PageLevelMessages.register_info_message), UserMessageType.INFO),
|
||||
(normalize_repr(PageLevelMessages.register_success_message), UserMessageType.SUCCESS),
|
||||
(normalize_repr(PageLevelMessages.register_warning_message), UserMessageType.WARNING),
|
||||
)
|
||||
@ddt.unpack
|
||||
def test_message_type(self, register_message_function, expected_message_type):
|
||||
|
||||
@@ -16,7 +16,16 @@ from xblock.fields import ScopeIds, UNIQUE_ID, NO_CACHE_VALUE
|
||||
from xblock.runtime import Runtime
|
||||
|
||||
|
||||
def attribute_pair_repr(self):
|
||||
"""
|
||||
Custom string representation for the AttributePair namedtuple which is
|
||||
consistent between test runs.
|
||||
"""
|
||||
return '<AttributePair name={}>'.format(self.name)
|
||||
|
||||
|
||||
AttributePair = namedtuple("AttributePair", ["name", "value"])
|
||||
AttributePair.__repr__ = attribute_pair_repr
|
||||
|
||||
|
||||
ID_ATTR_NAMES = ("discussion_id", "id",)
|
||||
|
||||
Reference in New Issue
Block a user