Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-platform
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
edx-platform
Commits
4eb4a82e
Commit
4eb4a82e
authored
Jul 15, 2015
by
Vedran Karačić
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #8851 from edx/vkaracic/PLAT-619-2
PLAT-619: Custom error messages for delete course command
parents
d3cb2e94
ff6afaf4
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
188 additions
and
17 deletions
+188
-17
cms/djangoapps/contentstore/management/commands/delete_course.py
+53
-17
cms/djangoapps/contentstore/management/commands/tests/test_delete_course.py
+120
-0
common/lib/xmodule/xmodule/modulestore/mixed.py
+15
-0
No files found.
cms/djangoapps/contentstore/management/commands/delete_course.py
View file @
4eb4a82e
###
### Script for cloning a course
###
"""
Command for deleting courses
Arguments:
arg1 (str): Course key of the course to delete
arg2 (str): 'commit'
Returns:
none
"""
from
django.core.management.base
import
BaseCommand
,
CommandError
from
.prompt
import
query_yes_no
from
contentstore.utils
import
delete_course_and_groups
...
...
@@ -8,27 +15,56 @@ from opaque_keys.edx.keys import CourseKey
from
opaque_keys
import
InvalidKeyError
from
opaque_keys.edx.locations
import
SlashSeparatedCourseKey
from
xmodule.modulestore
import
ModuleStoreEnum
from
xmodule.modulestore.django
import
modulestore
def
print_out_all_courses
():
"""
Print out all the courses available in the course_key format so that
the user can correct any course_key mistakes
"""
courses
=
modulestore
()
.
get_courses_keys
()
print
'Available courses:'
for
course
in
courses
:
print
str
(
course
)
print
''
class
Command
(
BaseCommand
):
"""
Delete a MongoDB backed course
"""
help
=
'''Delete a MongoDB backed course'''
def
handle
(
self
,
*
args
,
**
options
):
if
len
(
args
)
!=
1
and
len
(
args
)
!=
2
:
raise
CommandError
(
"
delete_course requires one or more arguments: <course_id> |commit|
"
)
if
len
(
args
)
==
0
:
raise
CommandError
(
"
Arguments missing: 'org/number/run commit'
"
)
try
:
course_key
=
CourseKey
.
from_string
(
args
[
0
])
except
InvalidKeyError
:
course_key
=
SlashSeparatedCourseKey
.
from_deprecated_string
(
args
[
0
])
if
len
(
args
)
==
1
:
if
args
[
0
]
==
'commit'
:
raise
CommandError
(
"Delete_course requires a course_key <org/number/run> argument."
)
else
:
raise
CommandError
(
"Delete_course requires a commit argument at the end"
)
elif
len
(
args
)
==
2
:
try
:
course_key
=
CourseKey
.
from_string
(
args
[
0
])
except
InvalidKeyError
:
try
:
course_key
=
SlashSeparatedCourseKey
.
from_deprecated_string
(
args
[
0
])
except
InvalidKeyError
:
raise
CommandError
(
"Invalid course_key: '
%
s'. Proper syntax: 'org/number/run commit' "
%
args
[
0
])
if
args
[
1
]
!=
'commit'
:
raise
CommandError
(
"Delete_course requires a commit argument at the end"
)
elif
len
(
args
)
>
2
:
raise
CommandError
(
"Too many arguments! Expected <course_key> <commit>"
)
commit
=
False
if
len
(
args
)
==
2
:
commit
=
args
[
1
]
==
'commit'
print_out_all_courses
()
if
commit
:
print
(
'Actually going to delete the course from DB....'
)
if
not
modulestore
()
.
get_course
(
course_key
)
:
raise
CommandError
(
"Course with '
%
s' key not found."
%
args
[
0
]
)
if
query_yes_no
(
"Deleting course {0}. Confirm?"
.
format
(
course_key
),
default
=
"no"
):
if
query_yes_no
(
"Are you sure. This action cannot be undone!"
,
default
=
"no"
):
delete_course_and_groups
(
course_key
,
ModuleStoreEnum
.
UserID
.
mgmt_command
)
print
'Actually going to delete the
%
s course from DB....'
%
args
[
0
]
if
query_yes_no
(
"Deleting course {0}. Confirm?"
.
format
(
course_key
),
default
=
"no"
):
if
query_yes_no
(
"Are you sure. This action cannot be undone!"
,
default
=
"no"
):
delete_course_and_groups
(
course_key
,
ModuleStoreEnum
.
UserID
.
mgmt_command
)
print_out_all_courses
()
cms/djangoapps/contentstore/management/commands/tests/test_delete_course.py
0 → 100644
View file @
4eb4a82e
"""
Unittests for deleting a course in an chosen modulestore
"""
import
unittest
import
mock
from
django.core.management
import
CommandError
from
contentstore.management.commands.delete_course
import
Command
# pylint: disable=import-error
from
contentstore.tests.utils
import
CourseTestCase
# pylint: disable=import-error
from
xmodule.modulestore.tests.factories
import
CourseFactory
from
xmodule.modulestore.django
import
modulestore
class
TestArgParsing
(
unittest
.
TestCase
):
"""
Tests for parsing arguments for the 'delete_course' management command
"""
def
setUp
(
self
):
super
(
TestArgParsing
,
self
)
.
setUp
()
self
.
command
=
Command
()
def
test_no_args
(
self
):
"""
Testing 'delete_course' command with no arguments provided
"""
errstring
=
"Arguments missing: 'org/number/run commit'"
with
self
.
assertRaisesRegexp
(
CommandError
,
errstring
):
self
.
command
.
handle
()
def
test_no_course_key
(
self
):
"""
Testing 'delete_course' command with no course key provided
"""
errstring
=
"Delete_course requires a course_key <org/number/run> argument."
with
self
.
assertRaisesRegexp
(
CommandError
,
errstring
):
self
.
command
.
handle
(
"commit"
)
def
test_commit_argument
(
self
):
"""
Testing 'delete_course' command without 'commit' argument
"""
errstring
=
"Delete_course requires a commit argument at the end"
with
self
.
assertRaisesRegexp
(
CommandError
,
errstring
):
self
.
command
.
handle
(
"TestX/TS01/run"
)
def
test_invalid_course_key
(
self
):
"""
Testing 'delete_course' command with an invalid course key argument
"""
errstring
=
"Invalid course_key: 'TestX/TS01'. Proper syntax: 'org/number/run commit' "
with
self
.
assertRaisesRegexp
(
CommandError
,
errstring
):
self
.
command
.
handle
(
"TestX/TS01"
,
"commit"
)
def
test_missing_commit_argument
(
self
):
"""
Testing 'delete_course' command with misspelled 'commit' argument
"""
errstring
=
"Delete_course requires a commit argument at the end"
with
self
.
assertRaisesRegexp
(
CommandError
,
errstring
):
self
.
command
.
handle
(
"TestX/TS01/run"
,
"comit"
)
def
test_too_many_arguments
(
self
):
"""
Testing 'delete_course' command with more than 2 arguments
"""
errstring
=
"Too many arguments! Expected <course_key> <commit>"
with
self
.
assertRaisesRegexp
(
CommandError
,
errstring
):
self
.
command
.
handle
(
"TestX/TS01/run"
,
"commit"
,
"invalid"
)
class
DeleteCourseTest
(
CourseTestCase
):
"""
Test for course deleting functionality of the 'delete_course' command
"""
YESNO_PATCH_LOCATION
=
'contentstore.management.commands.delete_course.query_yes_no'
def
setUp
(
self
):
super
(
DeleteCourseTest
,
self
)
.
setUp
()
self
.
command
=
Command
()
org
=
'TestX'
course_number
=
'TS01'
course_run
=
'2015_Q1'
# Create a course using split modulestore
self
.
course
=
CourseFactory
.
create
(
org
=
org
,
number
=
course_number
,
run
=
course_run
)
def
test_courses_keys_listing
(
self
):
"""
Test if the command lists out available course key courses
"""
courses
=
[
str
(
key
)
for
key
in
modulestore
()
.
get_courses_keys
()]
self
.
assertIn
(
"TestX/TS01/2015_Q1"
,
courses
)
def
test_course_key_not_found
(
self
):
"""
Test for when a non-existing course key is entered
"""
errstring
=
"Course with 'TestX/TS01/2015_Q7' key not found."
with
self
.
assertRaisesRegexp
(
CommandError
,
errstring
):
self
.
command
.
handle
(
"TestX/TS01/2015_Q7"
,
"commit"
)
def
test_course_deleted
(
self
):
"""
Testing if the entered course was deleted
"""
with
mock
.
patch
(
self
.
YESNO_PATCH_LOCATION
)
as
patched_yes_no
:
patched_yes_no
.
return_value
=
True
self
.
command
.
handle
(
"TestX/TS01/2015_Q1"
,
"commit"
)
courses
=
[
unicode
(
key
)
for
key
in
modulestore
()
.
get_courses_keys
()]
self
.
assertNotIn
(
"TestX/TS01/2015_Q1"
,
courses
)
common/lib/xmodule/xmodule/modulestore/mixed.py
View file @
4eb4a82e
...
...
@@ -281,6 +281,21 @@ class MixedModuleStore(ModuleStoreDraftAndPublished, ModuleStoreWriteBase):
return
courses
.
values
()
@strip_key
def
get_courses_keys
(
self
,
**
kwargs
):
'''
Returns a list containing the top level XModuleDescriptors keys of the courses in this modulestore.
'''
courses
=
{}
for
store
in
self
.
modulestores
:
# filter out ones which were fetched from earlier stores but locations may not be ==
for
course
in
store
.
get_courses
(
**
kwargs
):
course_id
=
self
.
_clean_locator_for_mapping
(
course
.
id
)
if
course_id
not
in
courses
:
# course is indeed unique. save it in result
courses
[
course_id
]
=
course
return
courses
.
keys
()
@strip_key
def
get_libraries
(
self
,
**
kwargs
):
"""
Returns a list containing the top level XBlock of the libraries (LibraryRoot) in this modulestore.
...
...
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