From e340b2431ee53ec3d5dc621b7aaf6225907e9d26 Mon Sep 17 00:00:00 2001 From: Steven Zheng Date: Fri, 7 Jul 2017 10:35:46 -0400 Subject: [PATCH] Add django management command to create course from json --- .../commands/generate_test_course.py | 55 ++++++++++++ .../tests/test_generate_test_course.py | 89 +++++++++++++++++++ 2 files changed, 144 insertions(+) create mode 100644 cms/djangoapps/contentstore/management/commands/generate_test_course.py create mode 100644 cms/djangoapps/contentstore/management/commands/tests/test_generate_test_course.py diff --git a/cms/djangoapps/contentstore/management/commands/generate_test_course.py b/cms/djangoapps/contentstore/management/commands/generate_test_course.py new file mode 100644 index 0000000000..cd386aa24e --- /dev/null +++ b/cms/djangoapps/contentstore/management/commands/generate_test_course.py @@ -0,0 +1,55 @@ +""" +Django management command to generate a test course in a specific modulestore +""" +import json + +from django.contrib.auth.models import User +from django.core.management.base import BaseCommand, CommandError + +from contentstore.management.commands.utils import user_from_str +from contentstore.views.course import create_new_course_in_store +from xmodule.modulestore import ModuleStoreEnum +from openedx.core.djangoapps.content.course_overviews.models import CourseOverview + + +class Command(BaseCommand): + """ Generate a basic course """ + help = 'Generate a course with settings on studio' + + def add_arguments(self, parser): + parser.add_argument( + 'json', + help='JSON object with values for store, user, name, organization, number, fields' + ) + + def handle(self, *args, **options): + + if options["json"] is None: + raise CommandError("Must pass in JSON object") + + try: + settings = json.loads(options["json"]) + except ValueError: + raise CommandError("Invalid JSON") + + if not(all(key in settings for key in ("store", "user", "organization", "number", "run", "fields"))): + raise CommandError("JSON object is missing required fields") + + if settings["store"] in [ModuleStoreEnum.Type.mongo, ModuleStoreEnum.Type.split]: + store = settings["store"] + else: + raise CommandError("Modulestore invalid_store is not valid") + + try: + user = user_from_str(settings["user"]) + except User.DoesNotExist: + raise CommandError("User {user} not found".format(user=settings["user"])) + + org = settings["organization"] + num = settings["number"] + run = settings["run"] + fields = settings["fields"] + + # Create the course + new_course = create_new_course_in_store(store, user, org, num, run, fields) + self.stdout.write(u"Created {}".format(unicode(new_course.id))) diff --git a/cms/djangoapps/contentstore/management/commands/tests/test_generate_test_course.py b/cms/djangoapps/contentstore/management/commands/tests/test_generate_test_course.py new file mode 100644 index 0000000000..67dd8a1de4 --- /dev/null +++ b/cms/djangoapps/contentstore/management/commands/tests/test_generate_test_course.py @@ -0,0 +1,89 @@ +""" +Unittest for generate a test course in an given modulestore +""" +import unittest +import ddt +from django.core.management import CommandError, call_command + +from contentstore.management.commands.generate_test_course import Command +from xmodule.modulestore import ModuleStoreEnum +from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase +from xmodule.modulestore.django import modulestore + + +@ddt.ddt +class TestGenerateTestCourse(ModuleStoreTestCase): + """ + Unit tests for creating a course in either old mongo or split mongo via command line + """ + + @ddt.data(ModuleStoreEnum.Type.mongo, ModuleStoreEnum.Type.split) + def test_generate_course_in_stores(self, store): + """ + Test that courses are created successfully for both ModuleStores + """ + arg = ( + '{"store":"' + store + '",' + + '"user":"' + self.user.email + '",' + + '"organization":"test-course-generator",' + + '"number":"1",' + + '"run":"1",' + + '"fields":{"display_name":"test-course"}}' + ) + call_command("generate_test_course", arg) + key = modulestore().make_course_key("test-course-generator", "1", "1") + self.assertTrue(modulestore().has_course(key)) + + def test_invalid_json(self): + """ + Test that providing an invalid JSON object will result in the appropriate command error + """ + error_msg = "Invalid JSON" + with self.assertRaisesRegexp(CommandError, error_msg): + arg = "invalid_json" + call_command("generate_test_course", arg) + + def test_missing_fields(self): + """ + Test that missing required fields in JSON object will result in the appropriate command error + """ + error_msg = "JSON object is missing required fields" + with self.assertRaisesRegexp(CommandError, error_msg): + arg = ( + '{"store":"invalid_store",' + + '"user":"user@example.com",' + + '"organization":"test-course-generator"}' + ) + call_command("generate_test_course", arg) + + def test_invalid_store(self): + """ + Test that providing an invalid store option will result in the appropriate command error + """ + error_msg = "Modulestore invalid_store is not valid" + with self.assertRaisesRegexp(CommandError, error_msg): + arg = ( + '{"store":"invalid_store",' + + '"user":"user@example.com",' + + '"organization":"test-course-generator",' + + '"number":"1",' + + '"run":"1",' + + '"fields":{"display_name":"test-course"}}' + ) + call_command("generate_test_course", arg) + + def test_invalid_user(self): + """ + Test that providing an invalid user will result in the appropriate command error + """ + error_msg = "User invalid_user not found" + with self.assertRaisesRegexp(CommandError, error_msg): + arg = ( + '{"store":"split",' + + '"user":"invalid_user",' + + '"organization":"test-course-generator",' + + '"number":"1",' + + '"run":"1",' + + '"fields":{"display_name":"test-course"}}' + ) + call_command("generate_test_course", arg)