Commit e5490b2e by Clinton Blackburn Committed by Clinton Blackburn

Updated Publisher to always create an audit seat for verified course runs

The SeatForm implements the logic to create an audit seat for verified
and credit course runs. It also removes audit seats for professional
course runs.

In the longterm, this should be implemented on the UI and exposed to the
end user to avoid future confusion.

LEARNER-2876
parent cd9df78c
import html
import logging
import waffle
from dal import autocomplete
from django import forms
from django.core.exceptions import ValidationError
......@@ -18,6 +20,8 @@ from course_discovery.apps.publisher.models import (Course, CourseRun, CourseUse
from course_discovery.apps.publisher.utils import is_internal_user
from course_discovery.apps.publisher.validators import validate_text_count
logger = logging.getLogger(__name__)
class UserModelChoiceField(forms.ModelChoiceField):
def label_from_instance(self, obj):
......@@ -408,6 +412,21 @@ class SeatForm(BaseForm):
if commit:
seat.save()
if waffle.switch_is_active('publisher_create_audit_seats_for_verified_course_runs'):
course_run = seat.course_run
audit_seats = course_run.seats.filter(type=Seat.AUDIT)
# Ensure that course runs with a verified seat always have an audit seat
if seat.type in (Seat.CREDIT, Seat.VERIFIED,):
if not audit_seats.exists():
course_run.seats.create(type=Seat.AUDIT, price=0, upgrade_deadline=None)
logger.info('Created audit seat for course run [%d]', course_run.id)
elif seat.type != Seat.AUDIT:
# Ensure that professional course runs do NOT have an audit seat
count = audit_seats.count()
audit_seats.delete()
logger.info('Removed [%d] audit seat for course run [%d]', count, course_run.id)
return seat
def clean(self):
......
from datetime import datetime, timedelta
import pytest
from django.core.exceptions import ValidationError
from django.test import TestCase
from pytz import timezone
from waffle.testutils import override_switch
from course_discovery.apps.core.models import User
from course_discovery.apps.core.tests.factories import UserFactory
from course_discovery.apps.course_metadata.models import Person
from course_discovery.apps.course_metadata.tests.factories import OrganizationFactory, PersonFactory
from course_discovery.apps.publisher.forms import CourseForm, CourseRunForm, PublisherUserCreationForm
from course_discovery.apps.publisher.tests.factories import CourseFactory, OrganizationExtensionFactory
from course_discovery.apps.publisher.forms import CourseForm, CourseRunForm, PublisherUserCreationForm, SeatForm
from course_discovery.apps.publisher.models import Seat
from course_discovery.apps.publisher.tests.factories import CourseFactory, OrganizationExtensionFactory, SeatFactory
class UserModelChoiceFieldTests(TestCase):
......@@ -190,6 +193,7 @@ class PublisherCustomCourseFormTests(TestCase):
"""
Tests for publisher 'CourseForm'
"""
def setUp(self):
super(PublisherCustomCourseFormTests, self).setUp()
self.course_form = CourseForm()
......@@ -265,3 +269,32 @@ class PublisherCustomCourseFormTests(TestCase):
course_form.save()
course.refresh_from_db()
assert course.title == 'áçã'
@pytest.mark.django_db
class TestSeatForm:
@override_switch('publisher_create_audit_seats_for_verified_course_runs', active=True)
@pytest.mark.parametrize('seat_type', (Seat.NO_ID_PROFESSIONAL, Seat.PROFESSIONAL,))
def test_remove_audit_seat_for_professional_course_runs(self, seat_type):
seat = SeatFactory(type=seat_type)
audit_seat = SeatFactory(type=Seat.AUDIT, course_run=seat.course_run)
form = SeatForm(instance=seat)
form.save()
assert list(seat.course_run.seats.all()) == [seat]
assert not Seat.objects.filter(pk=audit_seat.pk).exists()
@override_switch('publisher_create_audit_seats_for_verified_course_runs', active=True)
def test_audit_only_seat_not_modified(self):
seat = SeatFactory(type=Seat.AUDIT)
form = SeatForm(instance=seat)
form.save()
assert list(seat.course_run.seats.all()) == [seat]
@override_switch('publisher_create_audit_seats_for_verified_course_runs', active=True)
@pytest.mark.parametrize('seat_type', (Seat.CREDIT, Seat.VERIFIED,))
def test_create_audit_seat_for_credit_and_verified_course_runs(self, seat_type):
seat = SeatFactory(type=seat_type)
form = SeatForm(instance=seat)
form.save()
assert seat.course_run.seats.count() == 2
assert seat.course_run.seats.filter(type=Seat.AUDIT, price=0).exists()
......@@ -17,7 +17,7 @@ from course_discovery.apps.publisher.tests.factories import CourseRunFactory, Or
@freeze_time('2017-01-01T00:00:00Z')
@pytest.mark.django_db
class TestSignals:
class TestCreateCourseRunInStudio:
@override_switch('enable_publisher_create_course_run_in_studio', active=True)
def test_create_course_run_in_studio_without_partner(self):
with mock.patch('course_discovery.apps.publisher.signals.logger.error') as mock_logger:
......
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