Commit 3429cf6d by Sanford Student

more reverts and minor changes

parent d2f7c81f
......@@ -24,32 +24,25 @@ from course_discovery.apps.publisher.api.utils import (
from course_discovery.apps.publisher.api.v1.views import CourseRunViewSet
from course_discovery.apps.publisher.models import CourseEntitlement, Seat
from course_discovery.apps.publisher.tests.factories import CourseEntitlementFactory, CourseRunFactory, SeatFactory
from course_discovery.apps.publisher.tests.utils import MockedStartEndDateTestCase
PUBLISHER_UPGRADE_DEADLINE_DAYS = random.randint(1, 21)
LOGGER_NAME = 'course_discovery.apps.publisher.api.v1.views'
class CourseRunViewSetTests(APITestCase, MockedStartEndDateTestCase):
class CourseRunViewSetTests(APITestCase):
def test_without_authentication(self):
self.client.logout()
url = reverse('publisher:api:v1:course_run-publish', kwargs={'pk': 1})
response = self.client.post(
url,
{'start': self.start_date_mock.return_value, 'end': self.end_date_mock.return_value}
)
response = self.client.post(url, {})
assert response.status_code == 401
def test_without_authorization(self):
user = UserFactory()
self.client.force_login(user)
url = reverse('publisher:api:v1:course_run-publish', kwargs={'pk': 1})
response = self.client.post(
url,
{'start': self.start_date_mock.return_value, 'end': self.end_date_mock.return_value}
)
response = self.client.post(url, {})
assert response.status_code == 403
def _create_course_run_for_publication(self):
......@@ -123,10 +116,7 @@ class CourseRunViewSetTests(APITestCase, MockedStartEndDateTestCase):
self._mock_ecommerce_api(publisher_course_run)
with LogCapture(LOGGER_NAME) as log:
url = reverse('publisher:api:v1:course_run-publish', kwargs={'pk': publisher_course_run.pk})
response = self.client.post(
url,
{'start': self.start_date_mock.return_value, 'end': self.end_date_mock.return_value}
)
response = self.client.post(url, {})
assert response.status_code == 200
log.check((LOGGER_NAME, 'INFO',
'Published course run with id: [{}] lms_course_id: [{}], user: [{}], date: [{}]'.format(
......@@ -149,7 +139,7 @@ class CourseRunViewSetTests(APITestCase, MockedStartEndDateTestCase):
serialize_entitlement_for_ecommerce_api(verified_entitlement),
]
assert ecommerce_body['products'] == expected
assert ecommerce_body['verification_deadline'] == serialize_datetime(publisher_course_run.lms_end)
assert ecommerce_body['verification_deadline'] == serialize_datetime(publisher_course_run.end)
discovery_course_run = CourseRun.objects.get(key=publisher_course_run.lms_course_id)
publisher_course = publisher_course_run.course
......@@ -162,6 +152,8 @@ class CourseRunViewSetTests(APITestCase, MockedStartEndDateTestCase):
assert discovery_course_run.title_override == publisher_course_run.title_override
assert discovery_course_run.short_description_override is None
assert discovery_course_run.full_description_override is None
assert discovery_course_run.start == publisher_course_run.start
assert discovery_course_run.end == publisher_course_run.end
assert discovery_course_run.pacing_type == publisher_course_run.pacing_type
assert discovery_course_run.min_effort == publisher_course_run.min_effort
assert discovery_course_run.max_effort == publisher_course_run.max_effort
......@@ -241,10 +233,7 @@ class CourseRunViewSetTests(APITestCase, MockedStartEndDateTestCase):
self._mock_ecommerce_api(publisher_course_run)
url = reverse('publisher:api:v1:course_run-publish', kwargs={'pk': publisher_course_run.pk})
response = self.client.post(
url,
{'start': self.start_date_mock.return_value, 'end': self.end_date_mock.return_value}
)
response = self.client.post(url, {})
assert response.status_code == 200
discovery_course_run = CourseRun.objects.get(key=publisher_course_run.lms_course_id)
......@@ -270,11 +259,7 @@ class CourseRunViewSetTests(APITestCase, MockedStartEndDateTestCase):
self._mock_ecommerce_api(publisher_course_run)
publish_url = reverse('publisher:api:v1:course_run-publish', kwargs={'pk': publisher_course_run.pk})
response = self.client.post(
publish_url,
{'start': self.start_date_mock.return_value, 'end': self.end_date_mock.return_value}
)
response = self.client.post(publish_url, {})
assert response.status_code == 200
discovery_course_run = CourseRun.objects.get(key=publisher_course_run.lms_course_id)
assert discovery_course_run.staff.all().count() == 2
......@@ -304,18 +289,12 @@ class CourseRunViewSetTests(APITestCase, MockedStartEndDateTestCase):
root=partner.studio_url.strip('/'),
key=publisher_course_run.lms_course_id
)
responses.add(responses.PATCH, url, json=expected_error, status=500)
self._mock_ecommerce_api(publisher_course_run)
url = reverse('publisher:api:v1:course_run-publish', kwargs={'pk': publisher_course_run.pk})
response = self.client.post(
url,
{'start': self.start_date_mock.return_value, 'end': self.end_date_mock.return_value}
)
response = self.client.post(url, {})
assert response.status_code == 502
assert len(responses.calls) == 2
expected = {
'discovery': CourseRunViewSet.PUBLICATION_SUCCESS_STATUS,
......
......@@ -145,8 +145,8 @@ class CourseRunViewSet(viewsets.GenericViewSet):
discovery_course.subjects.add(*subjects)
defaults = {
'start': course_run.start,
'end': course_run.end,
'start': course_run.lms_start if course_run.lms_start else course_run.start,
'end': course_run.lms_end if course_run.lms_end else course_run.end,
'pacing_type': course_run.pacing_type,
'title_override': course_run.title_override,
'min_effort': course_run.min_effort,
......
......@@ -19,7 +19,6 @@ from course_discovery.apps.publisher.dataloader.update_course_runs import logger
from course_discovery.apps.publisher.models import Course as Publisher_Course
from course_discovery.apps.publisher.models import CourseRun as Publisher_CourseRun
from course_discovery.apps.publisher.tests import factories
from course_discovery.apps.publisher.tests.utils import MockedStartEndDateTestCase
@ddt.ddt
......@@ -108,7 +107,7 @@ class ImportCoursesTests(TestCase):
# pylint: disable=no-member
@ddt.ddt
class CreateCoursesTests(MockedStartEndDateTestCase):
class CreateCoursesTests(TestCase):
def setUp(self):
super(CreateCoursesTests, self).setUp()
......@@ -348,6 +347,8 @@ class CreateCoursesTests(MockedStartEndDateTestCase):
def _assert_course_run(self, publisher_course_run, metadata_course_run):
""" Verify that publisher course-run and metadata course run has correct values."""
self.assertEqual(publisher_course_run.start, metadata_course_run.start)
self.assertEqual(publisher_course_run.end, metadata_course_run.end)
self.assertEqual(publisher_course_run.min_effort, metadata_course_run.min_effort)
self.assertEqual(publisher_course_run.max_effort, metadata_course_run.max_effort)
self.assertEqual(publisher_course_run.length, metadata_course_run.weeks_to_complete)
......
......@@ -15,13 +15,12 @@ from course_discovery.apps.publisher.forms import CourseRunAdminForm
from course_discovery.apps.publisher.models import CourseRun, OrganizationExtension
from course_discovery.apps.publisher.tests import factories
from course_discovery.apps.publisher.tests.factories import CourseFactory
from course_discovery.apps.publisher.tests.utils import MockedStartEndDateTestCase
USER_PASSWORD = 'password'
# pylint: disable=no-member
class AdminTests(SiteMixin, MockedStartEndDateTestCase):
class AdminTests(SiteMixin, TestCase):
""" Tests Admin page."""
def setUp(self):
......@@ -68,10 +67,10 @@ class AdminTests(SiteMixin, MockedStartEndDateTestCase):
'lms_course_id': '',
'pacing_type': course_run.pacing_type,
'course': course_run.course.id,
'start_0': course_run.lms_start.date(),
'start_1': course_run.lms_start.time(),
'end_0': course_run.lms_end.date(),
'end_1': course_run.lms_end.time(),
'start_0': course_run.start.date(),
'start_1': course_run.start.time(),
'end_0': course_run.end.date(),
'end_1': course_run.end.time(),
'state': self.run_state.id,
'contacted_partner_manager': course_run.contacted_partner_manager,
'changed_by': self.user.id,
......
from datetime import datetime, timedelta
import ddt
import pytest
from django.core.exceptions import ValidationError
from django.test import TestCase
from guardian.shortcuts import assign_perm
from pytz import timezone
from waffle.testutils import override_switch
from course_discovery.apps.core.models import User
......@@ -178,6 +181,22 @@ class PublisherCourseRunEditFormTests(TestCase):
run_form.cleaned_data['max_effort'] = 5
self.assertEqual(run_form.clean(), run_form.cleaned_data)
def test_course_run_dates(self):
"""
Verify that 'clean' raises 'ValidationError' if the Start date is in the past
Or if the Start date is after the End date
"""
run_form = CourseRunForm()
current_datetime = datetime.now(timezone('US/Central'))
run_form.cleaned_data = {'start': current_datetime + timedelta(days=3),
'end': current_datetime + timedelta(days=1)}
with self.assertRaises(ValidationError):
run_form.clean()
run_form.cleaned_data['start'] = current_datetime + timedelta(days=1)
run_form.cleaned_data['end'] = current_datetime + timedelta(days=3)
self.assertEqual(run_form.clean(), run_form.cleaned_data)
def test_course_run_xseries(self):
"""
Verify that 'clean' raises 'ValidationError' if the is_xseries is checked
......
......@@ -629,7 +629,7 @@ class CourseStateTests(TestCase):
@ddt.ddt
class CourseRunStateTests:
class CourseRunStateTests(TestCase):
""" Tests for the publisher `CourseRunState` model. """
@classmethod
......
import datetime
from itertools import product
import mock
import pytest
from course_discovery.apps.core.utils import serialize_datetime
from course_discovery.apps.course_metadata.tests.factories import CourseFactory as DiscoveryCourseFactory
from course_discovery.apps.course_metadata.tests.factories import CourseRunFactory as DiscoveryCourseRunFactory
from course_discovery.apps.course_metadata.tests.factories import OrganizationFactory
from course_discovery.apps.publisher.choices import PublisherUserRole
from course_discovery.apps.publisher.studio_api_utils import StudioAPI
from course_discovery.apps.publisher.tests.factories import CourseRunFactory, CourseUserRoleFactory
from course_discovery.apps.publisher.tests.utils import MockedStartEndDateTestCase
class StudioApiUtilTestCase(MockedStartEndDateTestCase):
def test_calculate_course_run_key_run_value(self):
for month in range(1, 13):
if month < 5:
expected = '1T2017'
elif month < 9:
expected = '2T2017'
else:
expected = '3T2017'
self.start_date_mock.return_value = datetime.datetime(2017, month, 1)
course_run = CourseRunFactory()
assert StudioAPI.calculate_course_run_key_run_value(
course_run,
self.start_date_mock.return_value
) == expected
def test_calculate_course_run_key_run_value_with_multiple_runs_per_trimester(self):
number = 'TestX'
organization = OrganizationFactory()
partner = organization.partner
course_key = '{org}+{number}'.format(org=organization.key, number=number)
discovery_course = DiscoveryCourseFactory(partner=partner, key=course_key)
DiscoveryCourseRunFactory(key='course-v1:TestX+Testing101x+1T2017', course=discovery_course)
self.start_date_mock.return_value = datetime.datetime(2017, 2, 1)
course_run = CourseRunFactory(
lms_course_id=None,
course__organizations=[organization],
course__number=number
test_data = (
list(product(range(1, 5), ['1T2017'])) +
list(product(range(5, 8), ['2T2017'])) +
list(product(range(9, 13), ['3T2017']))
)
@pytest.mark.django_db
@pytest.mark.parametrize('month,expected', test_data)
def test_calculate_course_run_key_run_value(month, expected):
course_run = CourseRunFactory(start=datetime.datetime(2017, month, 1))
assert StudioAPI.calculate_course_run_key_run_value(course_run) == expected
@pytest.mark.django_db
def test_calculate_course_run_key_run_value_with_multiple_runs_per_trimester():
number = 'TestX'
organization = OrganizationFactory()
partner = organization.partner
course_key = '{org}+{number}'.format(org=organization.key, number=number)
discovery_course = DiscoveryCourseFactory(partner=partner, key=course_key)
DiscoveryCourseRunFactory(key='course-v1:TestX+Testing101x+1T2017', course=discovery_course)
course_run = CourseRunFactory(
start=datetime.datetime(2017, 2, 1),
lms_course_id=None,
course__organizations=[organization],
course__number=number
)
assert StudioAPI.calculate_course_run_key_run_value(course_run) == '1T2017a'
DiscoveryCourseRunFactory(key='course-v1:TestX+Testing101x+1T2017a', course=discovery_course)
assert StudioAPI.calculate_course_run_key_run_value(course_run) == '1T2017b'
def assert_data_generated_correctly(course_run, expected_team_data):
course = course_run.course
expected = {
'title': course_run.title_override or course.title,
'org': course.organizations.first().key,
'number': course.number,
'run': StudioAPI.calculate_course_run_key_run_value(course_run),
'schedule': {
'start': serialize_datetime(course_run.start),
'end': serialize_datetime(course_run.end),
},
'team': expected_team_data,
'pacing_type': course_run.pacing_type,
}
assert StudioAPI.generate_data_for_studio_api(course_run) == expected
@pytest.mark.django_db
def test_generate_data_for_studio_api():
course_run = CourseRunFactory(course__organizations=[OrganizationFactory()])
course = course_run.course
role = CourseUserRoleFactory(course=course, role=PublisherUserRole.CourseTeam)
team = [
{
'user': role.user.username,
'role': 'instructor',
},
]
assert_data_generated_correctly(course_run, team)
@pytest.mark.django_db
def test_generate_data_for_studio_api_without_team():
course_run = CourseRunFactory(course__organizations=[OrganizationFactory()])
with mock.patch('course_discovery.apps.publisher.studio_api_utils.logger.warning') as mock_logger:
assert_data_generated_correctly(course_run, [])
mock_logger.assert_called_with(
'No course team admin specified for course [%s]. This may result in a Studio course run '
'being created without a course team.',
course_run.course.number
)
@pytest.mark.django_db
def test_update_course_run_image_in_studio_without_course_image():
publisher_course_run = CourseRunFactory(course__image=None)
api = StudioAPI(None)
with mock.patch('course_discovery.apps.publisher.studio_api_utils.logger') as mock_logger:
api.update_course_run_image_in_studio(publisher_course_run)
mock_logger.warning.assert_called_with(
'Card image for course run [%d] cannot be updated. The related course [%d] has no image defined.',
publisher_course_run.id,
publisher_course_run.course.id
)
assert StudioAPI.calculate_course_run_key_run_value(course_run, self.start_date_mock.return_value) == '1T2017a'
DiscoveryCourseRunFactory(key='course-v1:TestX+Testing101x+1T2017a', course=discovery_course)
assert StudioAPI.calculate_course_run_key_run_value(course_run, self.start_date_mock.return_value) == '1T2017b'
def assert_data_generated_correctly(self, course_run, expected_team_data):
course = course_run.course
expected = {
'title': course_run.title_override or course.title,
'org': course.organizations.first().key,
'number': course.number,
'run': StudioAPI.calculate_course_run_key_run_value(course_run, self.start_date_mock.return_value),
'team': expected_team_data,
'pacing_type': course_run.pacing_type,
}
assert StudioAPI.generate_data_for_studio_api(course_run) == expected
def test_generate_data_for_studio_api(self):
course_run = CourseRunFactory(course__organizations=[OrganizationFactory()])
course = course_run.course
role = CourseUserRoleFactory(course=course, role=PublisherUserRole.CourseTeam)
team = [
{
'user': role.user.username,
'role': 'instructor',
},
]
self.assert_data_generated_correctly(course_run, team)
def test_generate_data_for_studio_api_without_team(self):
course_run = CourseRunFactory(course__organizations=[OrganizationFactory()])
with mock.patch('course_discovery.apps.publisher.studio_api_utils.logger.warning') as mock_logger:
self.assert_data_generated_correctly(course_run, [])
mock_logger.assert_called_with(
'No course team admin specified for course [%s]. This may result in a Studio course run '
'being created without a course team.',
course_run.course.number
)
def test_update_course_run_image_in_studio_without_course_image(self):
publisher_course_run = CourseRunFactory(course__image=None)
api = StudioAPI(None)
with mock.patch('course_discovery.apps.publisher.studio_api_utils.logger') as mock_logger:
api.update_course_run_image_in_studio(publisher_course_run)
mock_logger.warning.assert_called_with(
'Card image for course run [%d] cannot be updated. The related course [%d] has no image defined.',
publisher_course_run.id,
publisher_course_run.course.id
)
......@@ -3,6 +3,7 @@ from datetime import datetime, timedelta
from unittest import mock
import ddt
from django.test import TestCase
from course_discovery.apps.course_metadata.choices import CourseRunPacing
from course_discovery.apps.course_metadata.tests.factories import (
......@@ -11,12 +12,11 @@ from course_discovery.apps.course_metadata.tests.factories import (
from course_discovery.apps.publisher.choices import CourseRunStateChoices, PublisherUserRole
from course_discovery.apps.publisher.models import Seat
from course_discovery.apps.publisher.tests import factories
from course_discovery.apps.publisher.tests.utils import MockedStartEndDateTestCase
from course_discovery.apps.publisher.wrappers import CourseRunWrapper
@ddt.ddt
class CourseRunWrapperTests(MockedStartEndDateTestCase):
class CourseRunWrapperTests(TestCase):
""" Tests for the publisher `BaseWrapper` model. """
def setUp(self):
......@@ -135,7 +135,7 @@ class CourseRunWrapperTests(MockedStartEndDateTestCase):
""" Verify that the wrapper return the mdc_submission_due_date. """
current_date = datetime.today()
expected_date = current_date - timedelta(days=10)
self.start_date_mock.return_value = current_date
self.course_run.start = current_date
self.course_run.save()
self.assertEqual(self.wrapped_course_run.mdc_submission_due_date, expected_date)
......
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