Commit 611b96c4 by Asad Azam Committed by AsadAzam

Validate course run state via admin

parent 33eb25a2
...@@ -9,8 +9,10 @@ from course_discovery.apps.publisher.choices import InternalUserRole ...@@ -9,8 +9,10 @@ from course_discovery.apps.publisher.choices import InternalUserRole
from course_discovery.apps.publisher.constants import (INTERNAL_USER_GROUP_NAME, PARTNER_MANAGER_GROUP_NAME, from course_discovery.apps.publisher.constants import (INTERNAL_USER_GROUP_NAME, PARTNER_MANAGER_GROUP_NAME,
PROJECT_COORDINATOR_GROUP_NAME, PUBLISHER_GROUP_NAME, PROJECT_COORDINATOR_GROUP_NAME, PUBLISHER_GROUP_NAME,
REVIEWER_GROUP_NAME) REVIEWER_GROUP_NAME)
from course_discovery.apps.publisher.forms import (CourseRunAdminForm, OrganizationExtensionForm, from course_discovery.apps.publisher.forms import (
PublisherUserCreationForm, UserAttributesAdminForm) CourseRunAdminForm, CourseRunStateAdminForm, OrganizationExtensionForm,
PublisherUserCreationForm, UserAttributesAdminForm
)
from course_discovery.apps.publisher.models import (Course, CourseRun, CourseRunState, CourseState, CourseUserRole, from course_discovery.apps.publisher.models import (Course, CourseRun, CourseRunState, CourseState, CourseUserRole,
OrganizationExtension, OrganizationUserRole, PublisherUser, Seat, OrganizationExtension, OrganizationUserRole, PublisherUser, Seat,
UserAttributes) UserAttributes)
...@@ -79,6 +81,7 @@ class CourseStateAdmin(SimpleHistoryAdmin): ...@@ -79,6 +81,7 @@ class CourseStateAdmin(SimpleHistoryAdmin):
@admin.register(CourseRunState) @admin.register(CourseRunState)
class CourseRunStateAdmin(SimpleHistoryAdmin): class CourseRunStateAdmin(SimpleHistoryAdmin):
form = CourseRunStateAdminForm
raw_id_fields = ('changed_by',) raw_id_fields = ('changed_by',)
list_display = ['id', 'name', 'approved_by_role', 'owner_role', list_display = ['id', 'name', 'approved_by_role', 'owner_role',
'course_run', 'owner_role_modified', 'preview_accepted'] 'course_run', 'owner_role_modified', 'preview_accepted']
......
...@@ -14,9 +14,11 @@ from opaque_keys.edx.keys import CourseKey ...@@ -14,9 +14,11 @@ from opaque_keys.edx.keys import CourseKey
from course_discovery.apps.course_metadata.choices import CourseRunPacing from course_discovery.apps.course_metadata.choices import CourseRunPacing
from course_discovery.apps.course_metadata.models import LevelType, Organization, Person, Subject from course_discovery.apps.course_metadata.models import LevelType, Organization, Person, Subject
from course_discovery.apps.ietf_language_tags.models import LanguageTag from course_discovery.apps.ietf_language_tags.models import LanguageTag
from course_discovery.apps.publisher.choices import CourseRunStateChoices, PublisherUserRole
from course_discovery.apps.publisher.mixins import LanguageModelSelect2Multiple, get_user_organizations from course_discovery.apps.publisher.mixins import LanguageModelSelect2Multiple, get_user_organizations
from course_discovery.apps.publisher.models import ( from course_discovery.apps.publisher.models import (
Course, CourseRun, CourseUserRole, OrganizationExtension, OrganizationUserRole, PublisherUser, Seat, User Course, CourseRun, CourseRunState, CourseUserRole, OrganizationExtension, OrganizationUserRole, PublisherUser,
Seat, User
) )
from course_discovery.apps.publisher.utils import VALID_CHARS_IN_COURSE_NUM_AND_ORG_KEY, is_internal_user from course_discovery.apps.publisher.utils import VALID_CHARS_IN_COURSE_NUM_AND_ORG_KEY, is_internal_user
from course_discovery.apps.publisher.validators import validate_text_count from course_discovery.apps.publisher.validators import validate_text_count
...@@ -529,6 +531,21 @@ class CourseRunAdminForm(forms.ModelForm): ...@@ -529,6 +531,21 @@ class CourseRunAdminForm(forms.ModelForm):
return None return None
class CourseRunStateAdminForm(forms.ModelForm):
class Meta:
model = CourseRunState
fields = '__all__'
def clean(self):
cleaned_data = self.cleaned_data
owner_role = cleaned_data.get('owner_role')
course_run_state = cleaned_data.get('name')
if owner_role == PublisherUserRole.Publisher and course_run_state in (CourseRunStateChoices.Draft,
CourseRunStateChoices.Review):
raise forms.ValidationError(_('Owner role can not be publisher if the state is draft or review'))
return cleaned_data
class AdminImportCourseForm(forms.Form): class AdminImportCourseForm(forms.Form):
start_id = forms.IntegerField(min_value=1, label='This course id will import.') start_id = forms.IntegerField(min_value=1, label='This course id will import.')
create_course_run = forms.BooleanField( create_course_run = forms.BooleanField(
......
...@@ -10,7 +10,10 @@ from waffle.testutils import override_switch ...@@ -10,7 +10,10 @@ from waffle.testutils import override_switch
from course_discovery.apps.core.models import User from course_discovery.apps.core.models import User
from course_discovery.apps.core.tests.factories import UserFactory from course_discovery.apps.core.tests.factories import UserFactory
from course_discovery.apps.course_metadata.tests.factories import OrganizationFactory from course_discovery.apps.course_metadata.tests.factories import OrganizationFactory
from course_discovery.apps.publisher.forms import CourseForm, CourseRunForm, PublisherUserCreationForm, SeatForm from course_discovery.apps.publisher.choices import CourseRunStateChoices, PublisherUserRole
from course_discovery.apps.publisher.forms import (
CourseForm, CourseRunForm, CourseRunStateAdminForm, PublisherUserCreationForm, SeatForm
)
from course_discovery.apps.publisher.models import Seat from course_discovery.apps.publisher.models import Seat
from course_discovery.apps.publisher.tests.factories import CourseFactory, OrganizationExtensionFactory, SeatFactory from course_discovery.apps.publisher.tests.factories import CourseFactory, OrganizationExtensionFactory, SeatFactory
...@@ -65,6 +68,37 @@ class PublisherUserCreationFormTests(TestCase): ...@@ -65,6 +68,37 @@ class PublisherUserCreationFormTests(TestCase):
self.assertEqual(user_form.clean(), user_form.cleaned_data) self.assertEqual(user_form.clean(), user_form.cleaned_data)
@ddt.ddt
class CourseRunStateAdminFormTests(TestCase):
"""
Tests for the publisher 'CourseRunStateAdminForm'.
"""
@ddt.data(
CourseRunStateChoices.Draft,
CourseRunStateChoices.Review,
)
def test_clean_with_validation_error(self, course_run_state):
"""
Verify that 'clean' raises 'ValidationError' for invalid course run state
"""
run_state_form = CourseRunStateAdminForm()
run_state_form.cleaned_data = {'name': course_run_state, 'owner_role': PublisherUserRole.Publisher}
with self.assertRaises(ValidationError):
run_state_form.clean()
def test_clean_without_validation_error(self):
"""
Verify that 'clean' does not raise 'ValidationError' for valid course run state
"""
run_state_form = CourseRunStateAdminForm()
run_state_form.cleaned_data = {
'name': CourseRunStateChoices.Approved,
'owner_role': PublisherUserRole.Publisher
}
self.assertEqual(run_state_form.clean(), run_state_form.cleaned_data)
class PublisherCourseRunEditFormTests(TestCase): class PublisherCourseRunEditFormTests(TestCase):
""" """
Tests for the publisher 'CourseRunForm'. Tests for the publisher 'CourseRunForm'.
......
...@@ -839,6 +839,10 @@ msgid "Invalid course key." ...@@ -839,6 +839,10 @@ msgid "Invalid course key."
msgstr "" msgstr ""
#: apps/publisher/forms.py #: apps/publisher/forms.py
msgid "Owner role can not be publisher if the state is draft or review"
msgstr ""
#: apps/publisher/forms.py
msgid "Create initial run for the course" msgid "Create initial run for the course"
msgstr "" msgstr ""
......
...@@ -1010,6 +1010,12 @@ msgid "Invalid course key." ...@@ -1010,6 +1010,12 @@ msgid "Invalid course key."
msgstr "Ìnvälïd çöürsé kéý. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт,#" msgstr "Ìnvälïd çöürsé kéý. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт,#"
#: apps/publisher/forms.py #: apps/publisher/forms.py
msgid "Owner role can not be publisher if the state is draft or review"
msgstr ""
"Öwnér rölé çän nöt ßé püßlïshér ïf thé stäté ïs dräft ör révïéw Ⱡ'σяєм ιρѕυм"
" ∂σłσя ѕιт αмєт, ¢σηѕє¢тєтυя α#"
#: apps/publisher/forms.py
msgid "Create initial run for the course" msgid "Create initial run for the course"
msgstr "" msgstr ""
"Çréäté ïnïtïäl rün för thé çöürsé Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢тє#" "Çréäté ïnïtïäl rün för thé çöürsé Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢тє#"
......
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