Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
C
course-discovery
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
course-discovery
Commits
3e633b07
Commit
3e633b07
authored
Jun 02, 2017
by
Asad Azam
Committed by
AsadAzam
Jun 06, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added course title and number duplicate validation
parent
2e1ef67f
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
101 additions
and
11 deletions
+101
-11
course_discovery/apps/publisher/forms.py
+17
-1
course_discovery/apps/publisher/tests/test_forms.py
+40
-1
course_discovery/apps/publisher/tests/test_views.py
+2
-3
course_discovery/conf/locale/en/LC_MESSAGES/django.po
+13
-2
course_discovery/conf/locale/eo/LC_MESSAGES/django.po
+18
-3
course_discovery/templates/publisher/add_course_form.html
+11
-1
No files found.
course_discovery/apps/publisher/forms.py
View file @
3e633b07
...
@@ -94,7 +94,10 @@ class CustomCourseForm(CourseForm):
...
@@ -94,7 +94,10 @@ class CustomCourseForm(CourseForm):
required
=
True
required
=
True
)
)
title
=
forms
.
CharField
(
label
=
_
(
'Course Title'
),
required
=
True
)
title
=
forms
.
CharField
(
label
=
_
(
'Course Title'
),
required
=
True
)
number
=
forms
.
CharField
(
label
=
_
(
'Course Number'
),
required
=
True
)
number
=
forms
.
CharField
(
label
=
_
(
'Course Number'
),
required
=
True
,
validators
=
[
validate_text_count
(
max_length
=
50
)]
)
short_description
=
forms
.
CharField
(
short_description
=
forms
.
CharField
(
label
=
_
(
'Short Description'
),
label
=
_
(
'Short Description'
),
widget
=
forms
.
Textarea
,
required
=
False
,
validators
=
[
validate_text_count
(
max_length
=
255
)]
widget
=
forms
.
Textarea
,
required
=
False
,
validators
=
[
validate_text_count
(
max_length
=
255
)]
...
@@ -191,6 +194,19 @@ class CustomCourseForm(CourseForm):
...
@@ -191,6 +194,19 @@ class CustomCourseForm(CourseForm):
if
user
and
not
is_internal_user
(
user
):
if
user
and
not
is_internal_user
(
user
):
self
.
fields
[
'video_link'
]
.
widget
=
forms
.
HiddenInput
()
self
.
fields
[
'video_link'
]
.
widget
=
forms
.
HiddenInput
()
def
clean
(
self
):
cleaned_data
=
self
.
cleaned_data
organization
=
cleaned_data
.
get
(
"organization"
)
title
=
cleaned_data
.
get
(
"title"
)
number
=
cleaned_data
.
get
(
"number"
)
instance
=
getattr
(
self
,
'instance'
,
None
)
if
not
instance
.
pk
:
if
Course
.
objects
.
filter
(
title
=
title
,
organizations__in
=
[
organization
])
.
exists
():
raise
ValidationError
({
'title'
:
_
(
'This course title already exists'
)})
if
Course
.
objects
.
filter
(
number
=
number
,
organizations__in
=
[
organization
])
.
exists
():
raise
ValidationError
({
'number'
:
_
(
'This course number already exists'
)})
return
cleaned_data
class
CourseSearchForm
(
forms
.
Form
):
class
CourseSearchForm
(
forms
.
Form
):
""" Course Type ahead Search Form. """
""" Course Type ahead Search Form. """
...
...
course_discovery/apps/publisher/tests/test_forms.py
View file @
3e633b07
...
@@ -6,7 +6,8 @@ from pytz import timezone
...
@@ -6,7 +6,8 @@ from pytz import timezone
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.models
import
Person
from
course_discovery.apps.course_metadata.models
import
Person
from
course_discovery.apps.course_metadata.tests.factories
import
PersonFactory
from
course_discovery.apps.course_metadata.tests.factories
import
PersonFactory
,
OrganizationFactory
from
course_discovery.apps.publisher.tests.factories
import
CourseFactory
from
course_discovery.apps.publisher.forms
import
CustomCourseForm
,
CustomCourseRunForm
,
PublisherUserCreationForm
from
course_discovery.apps.publisher.forms
import
CustomCourseForm
,
CustomCourseRunForm
,
PublisherUserCreationForm
...
@@ -153,3 +154,41 @@ class PublisherCourseRunEditFormTests(TestCase):
...
@@ -153,3 +154,41 @@ class PublisherCourseRunEditFormTests(TestCase):
run_form
.
cleaned_data
[
'professional_certificate_name'
]
=
"Test Name"
run_form
.
cleaned_data
[
'professional_certificate_name'
]
=
"Test Name"
self
.
assertEqual
(
run_form
.
clean
(),
run_form
.
cleaned_data
)
self
.
assertEqual
(
run_form
.
clean
(),
run_form
.
cleaned_data
)
class
PublisherCustomCourseFormTests
(
TestCase
):
"""
Tests for publisher 'CustomCourseForm'
"""
def
setUp
(
self
):
super
(
PublisherCustomCourseFormTests
,
self
)
.
setUp
()
self
.
course_form
=
CustomCourseForm
()
self
.
course
=
CourseFactory
(
title
=
"Test"
,
number
=
"a123"
)
self
.
organization
=
OrganizationFactory
()
self
.
course
.
organizations
.
add
(
self
.
organization
)
def
test_duplicate_title
(
self
):
"""
Verify that clean raises 'ValidationError' if the course title is a duplicate of another course title
within the same organization
"""
course_form
=
CustomCourseForm
()
course_form
.
cleaned_data
=
{
'title'
:
'Test'
,
'number'
:
'123a'
,
'organization'
:
self
.
organization
}
with
self
.
assertRaises
(
ValidationError
):
course_form
.
clean
()
course_form
.
cleaned_data
[
'title'
]
=
"Test2"
self
.
assertEqual
(
course_form
.
clean
(),
course_form
.
cleaned_data
)
def
test_duplicate_number
(
self
):
"""
Verify that clean raises 'ValidationError' if the course number is a duplicate of another course number
within the same organization
"""
course_form
=
CustomCourseForm
()
course_form
.
cleaned_data
=
{
'title'
:
'Test2'
,
'number'
:
'a123'
,
'organization'
:
self
.
organization
}
with
self
.
assertRaises
(
ValidationError
):
course_form
.
clean
()
course_form
.
cleaned_data
[
'number'
]
=
"123a"
self
.
assertEqual
(
course_form
.
clean
(),
course_form
.
cleaned_data
)
course_discovery/apps/publisher/tests/test_views.py
View file @
3e633b07
...
@@ -111,10 +111,9 @@ class CreateCourseViewTests(TestCase):
...
@@ -111,10 +111,9 @@ class CreateCourseViewTests(TestCase):
"""
"""
Verify that user can create course successfully.
Verify that user can create course successfully.
"""
"""
data
=
{
'number'
:
'testX453'
,
'image'
:
make_image_file
(
'test_banner.jpg'
)}
data
=
{
'
title'
:
'Test2'
,
'
number'
:
'testX453'
,
'image'
:
make_image_file
(
'test_banner.jpg'
)}
course_dict
=
self
.
_post_data
(
data
,
self
.
course
)
course_dict
=
self
.
_post_data
(
data
,
self
.
course
)
response
=
self
.
client
.
post
(
reverse
(
'publisher:publisher_courses_new'
),
course_dict
)
response
=
self
.
client
.
post
(
reverse
(
'publisher:publisher_courses_new'
),
course_dict
)
course
=
Course
.
objects
.
get
(
number
=
course_dict
[
'number'
])
course
=
Course
.
objects
.
get
(
number
=
course_dict
[
'number'
])
self
.
assertRedirects
(
self
.
assertRedirects
(
...
@@ -253,7 +252,7 @@ class CreateCourseViewTests(TestCase):
...
@@ -253,7 +252,7 @@ class CreateCourseViewTests(TestCase):
Verify that if add_new_run is checked user is redirected to
Verify that if add_new_run is checked user is redirected to
create course run page instead course detail page.
create course run page instead course detail page.
"""
"""
data
=
{
'number'
:
'testX234'
,
'image'
:
''
,
'add_new_run'
:
True
}
data
=
{
'
title'
:
'Test2'
,
'
number'
:
'testX234'
,
'image'
:
''
,
'add_new_run'
:
True
}
course_dict
=
self
.
_post_data
(
data
,
self
.
course
)
course_dict
=
self
.
_post_data
(
data
,
self
.
course
)
response
=
self
.
client
.
post
(
reverse
(
'publisher:publisher_courses_new'
),
course_dict
)
response
=
self
.
client
.
post
(
reverse
(
'publisher:publisher_courses_new'
),
course_dict
)
...
...
course_discovery/conf/locale/en/LC_MESSAGES/django.po
View file @
3e633b07
...
@@ -638,6 +638,14 @@ msgid "Syllabus"
...
@@ -638,6 +638,14 @@ msgid "Syllabus"
msgstr ""
msgstr ""
#: apps/publisher/forms.py
#: apps/publisher/forms.py
msgid "This course title already exists"
msgstr ""
#: apps/publisher/forms.py
msgid "This course number already exists"
msgstr ""
#: apps/publisher/forms.py
msgid "Find Course"
msgid "Find Course"
msgstr ""
msgstr ""
...
@@ -1431,8 +1439,7 @@ msgid "COURSE NUMBER"
...
@@ -1431,8 +1439,7 @@ msgid "COURSE NUMBER"
msgstr ""
msgstr ""
#: templates/publisher/add_course_form.html
#: templates/publisher/add_course_form.html
#: templates/publisher/course_edit_form.html
msgid "Maximum 50 characters. Characters can be letters, numbers, or periods."
msgid "Maximum 10 characters. Characters can be letters, numbers, or periods."
msgstr ""
msgstr ""
#: templates/publisher/add_course_form.html
#: templates/publisher/add_course_form.html
...
@@ -1706,6 +1713,10 @@ msgid "255 character limit, including spaces."
...
@@ -1706,6 +1713,10 @@ msgid "255 character limit, including spaces."
msgstr ""
msgstr ""
#: templates/publisher/course_edit_form.html
#: templates/publisher/course_edit_form.html
msgid "Maximum 10 characters. Characters can be letters, numbers, or periods."
msgstr ""
#: templates/publisher/course_edit_form.html
msgid "BIO1.1x, BIO1.2x"
msgid "BIO1.1x, BIO1.2x"
msgstr ""
msgstr ""
...
...
course_discovery/conf/locale/eo/LC_MESSAGES/django.po
View file @
3e633b07
...
@@ -767,6 +767,16 @@ msgid "Syllabus"
...
@@ -767,6 +767,16 @@ msgid "Syllabus"
msgstr "Sýlläßüs Ⱡ'σяєм ιρѕυм ∂#"
msgstr "Sýlläßüs Ⱡ'σяєм ιρѕυм ∂#"
#: apps/publisher/forms.py
#: apps/publisher/forms.py
msgid "This course title already exists"
msgstr ""
"Thïs çöürsé tïtlé älréädý éxïsts Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢тє#"
#: apps/publisher/forms.py
msgid "This course number already exists"
msgstr ""
"Thïs çöürsé nümßér älréädý éxïsts Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢тє#"
#: apps/publisher/forms.py
msgid "Find Course"
msgid "Find Course"
msgstr "Fïnd Çöürsé Ⱡ'σяєм ιρѕυм ∂σłσя #"
msgstr "Fïnd Çöürsé Ⱡ'σяєм ιρѕυм ∂σłσя #"
...
@@ -1638,10 +1648,9 @@ msgid "COURSE NUMBER"
...
@@ -1638,10 +1648,9 @@ msgid "COURSE NUMBER"
msgstr "ÇÖÛRSÉ NÛMBÉR Ⱡ'σяєм ιρѕυм ∂σłσя ѕι#"
msgstr "ÇÖÛRSÉ NÛMBÉR Ⱡ'σяєм ιρѕυм ∂σłσя ѕι#"
#: templates/publisher/add_course_form.html
#: templates/publisher/add_course_form.html
#: templates/publisher/course_edit_form.html
msgid "Maximum 50 characters. Characters can be letters, numbers, or periods."
msgid "Maximum 10 characters. Characters can be letters, numbers, or periods."
msgstr ""
msgstr ""
"Mäxïmüm
1
0 çhäräçtérs. Çhäräçtérs çän ßé léttérs, nümßérs, ör pérïöds. "
"Mäxïmüm
5
0 çhäräçtérs. Çhäräçtérs çän ßé léttérs, nümßérs, ör pérïöds. "
"Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢тєтυя #"
"Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢тєтυя #"
#: templates/publisher/add_course_form.html
#: templates/publisher/add_course_form.html
...
@@ -1998,6 +2007,12 @@ msgstr ""
...
@@ -1998,6 +2007,12 @@ msgstr ""
"¢σηѕє¢тєтυя#"
"¢σηѕє¢тєтυя#"
#: templates/publisher/course_edit_form.html
#: templates/publisher/course_edit_form.html
msgid "Maximum 10 characters. Characters can be letters, numbers, or periods."
msgstr ""
"Mäxïmüm 10 çhäräçtérs. Çhäräçtérs çän ßé léttérs, nümßérs, ör pérïöds. "
"Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢тєтυя #"
#: templates/publisher/course_edit_form.html
msgid "BIO1.1x, BIO1.2x"
msgid "BIO1.1x, BIO1.2x"
msgstr "BÌÖ1.1x, BÌÖ1.2x Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αм#"
msgstr "BÌÖ1.1x, BÌÖ1.2x Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αм#"
...
...
course_discovery/templates/publisher/add_course_form.html
View file @
3e633b07
...
@@ -84,6 +84,11 @@
...
@@ -84,6 +84,11 @@
{{ course_form.title.label }}
<span
class=
"required"
>
*
</span>
{{ course_form.title.label }}
<span
class=
"required"
>
*
</span>
</label>
</label>
{{ course_form.title }}
{{ course_form.title }}
{% if course_form.title.errors %}
<div
class=
"field-message-content"
>
{{ course_form.title.errors|escape }}
</div>
{% endif %}
</div>
</div>
</div>
</div>
...
@@ -102,7 +107,7 @@
...
@@ -102,7 +107,7 @@
</div>
</div>
<div
id=
"tab-practices"
class=
"content active"
>
<div
id=
"tab-practices"
class=
"content active"
>
<ul>
<ul>
<li>
{% trans "Maximum
1
0 characters. Characters can be letters, numbers, or periods." %}
</li>
<li>
{% trans "Maximum
5
0 characters. Characters can be letters, numbers, or periods." %}
</li>
<li>
{% trans "If a course consists of several modules, the course number can have an ending such as .1x or .2x." %}
</li>
<li>
{% trans "If a course consists of several modules, the course number can have an ending such as .1x or .2x." %}
</li>
</ul>
</ul>
</div>
</div>
...
@@ -116,6 +121,11 @@
...
@@ -116,6 +121,11 @@
<div
class=
"col col-6"
>
<div
class=
"col col-6"
>
<label
class=
"field-label "
>
{{ course_form.number.label_tag }}
<span
class=
"required"
>
*
</span></label>
<label
class=
"field-label "
>
{{ course_form.number.label_tag }}
<span
class=
"required"
>
*
</span></label>
{{ course_form.number }}
{{ course_form.number }}
{% if course_form.number.errors %}
<div
class=
"field-message-content"
>
{{ course_form.number.errors|escape }}
</div>
{% endif %}
</div>
</div>
</div>
</div>
</fieldset>
</fieldset>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment