The existing pattern of using `override_settings(MODULESTORE=...)` prevented
us from having more than one layer of subclassing in modulestore tests.
In a structure like:
@override_settings(MODULESTORE=store_a)
class BaseTestCase(ModuleStoreTestCase):
def setUp(self):
# use store
@override_settings(MODULESTORE=store_b)
class ChildTestCase(BaseTestCase):
def setUp(self):
# use store
In this case, the store actions performed in `BaseTestCase` on behalf of
`ChildTestCase` would still use `store_a`, even though the `ChildTestCase`
had specified to use `store_b`. This is because the `override_settings`
decorator would be the innermost wrapper around the `BaseTestCase.setUp` method,
no matter what `ChildTestCase` does.
To remedy this, we move the call to `override_settings` into the
`ModuleStoreTestCase.setUp` method, and use a cleanup to remove the override.
Subclasses can just defined the `MODULESTORE` class attribute to specify which
modulestore to use _for the entire `setUp` chain_.
[PLAT-419]
74 lines
3.0 KiB
Python
74 lines
3.0 KiB
Python
"""
|
|
Tests for Reverification models
|
|
"""
|
|
from datetime import timedelta, datetime
|
|
import pytz
|
|
|
|
from django.core.exceptions import ValidationError
|
|
from django.test.utils import override_settings
|
|
|
|
from xmodule.modulestore.tests.django_utils import TEST_DATA_MOCK_MODULESTORE
|
|
from reverification.models import MidcourseReverificationWindow
|
|
from reverification.tests.factories import MidcourseReverificationWindowFactory
|
|
from xmodule.modulestore.tests.factories import CourseFactory
|
|
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
|
|
|
|
|
|
class TestMidcourseReverificationWindow(ModuleStoreTestCase):
|
|
""" Tests for MidcourseReverificationWindow objects """
|
|
|
|
def setUp(self, **kwargs):
|
|
super(TestMidcourseReverificationWindow, self).setUp()
|
|
self.course_id = CourseFactory.create().id
|
|
|
|
def test_window_open_for_course(self):
|
|
# Should return False if no windows exist for a course
|
|
self.assertFalse(MidcourseReverificationWindow.window_open_for_course(self.course_id))
|
|
|
|
# Should return False if a window exists, but it's not in the current timeframe
|
|
MidcourseReverificationWindowFactory(
|
|
course_id=self.course_id,
|
|
start_date=datetime.now(pytz.utc) - timedelta(days=10),
|
|
end_date=datetime.now(pytz.utc) - timedelta(days=5)
|
|
)
|
|
self.assertFalse(MidcourseReverificationWindow.window_open_for_course(self.course_id))
|
|
|
|
# Should return True if a non-expired window exists
|
|
MidcourseReverificationWindowFactory(
|
|
course_id=self.course_id,
|
|
start_date=datetime.now(pytz.utc) - timedelta(days=3),
|
|
end_date=datetime.now(pytz.utc) + timedelta(days=3)
|
|
)
|
|
self.assertTrue(MidcourseReverificationWindow.window_open_for_course(self.course_id))
|
|
|
|
def test_get_window(self):
|
|
# if no window exists, returns None
|
|
self.assertIsNone(MidcourseReverificationWindow.get_window(self.course_id, datetime.now(pytz.utc)))
|
|
|
|
# we should get the expected window otherwise
|
|
window_valid = MidcourseReverificationWindowFactory(
|
|
course_id=self.course_id,
|
|
start_date=datetime.now(pytz.utc) - timedelta(days=3),
|
|
end_date=datetime.now(pytz.utc) + timedelta(days=3)
|
|
)
|
|
self.assertEquals(
|
|
window_valid,
|
|
MidcourseReverificationWindow.get_window(self.course_id, datetime.now(pytz.utc))
|
|
)
|
|
|
|
def test_no_overlapping_windows(self):
|
|
window_valid = MidcourseReverificationWindow(
|
|
course_id=self.course_id,
|
|
start_date=datetime.now(pytz.utc) - timedelta(days=3),
|
|
end_date=datetime.now(pytz.utc) + timedelta(days=3)
|
|
)
|
|
window_valid.save()
|
|
|
|
with self.assertRaises(ValidationError):
|
|
window_invalid = MidcourseReverificationWindow(
|
|
course_id=self.course_id,
|
|
start_date=datetime.now(pytz.utc) - timedelta(days=2),
|
|
end_date=datetime.now(pytz.utc) + timedelta(days=4)
|
|
)
|
|
window_invalid.save()
|