""" Test the ability to export courses to xml from studio """ import copy import os import shutil import subprocess from uuid import uuid4 from django.conf import settings from django.test.utils import override_settings from .utils import CourseTestCase import contentstore.git_export_utils as git_export_utils from xmodule.modulestore.django import modulestore from contentstore.utils import reverse_course_url TEST_DATA_CONTENTSTORE = copy.deepcopy(settings.CONTENTSTORE) TEST_DATA_CONTENTSTORE['DOC_STORE_CONFIG']['db'] = 'test_xcontent_%s' % uuid4().hex @override_settings(CONTENTSTORE=TEST_DATA_CONTENTSTORE) class TestExportGit(CourseTestCase): """ Tests pushing a course to a git repository """ def setUp(self): """ Setup test course, user, and url. """ super(TestExportGit, self).setUp() self.course_module = modulestore().get_course(self.course.id) self.test_url = reverse_course_url('export_git', self.course.id) def make_bare_repo_with_course(self, repo_name): """ Make a local bare repo suitable for exporting to in tests """ # Build out local bare repo, and set course git url to it repo_dir = os.path.abspath(git_export_utils.GIT_REPO_EXPORT_DIR) os.mkdir(repo_dir) self.addCleanup(shutil.rmtree, repo_dir) bare_repo_dir = '{0}/{1}.git'.format( os.path.abspath(git_export_utils.GIT_REPO_EXPORT_DIR), repo_name ) os.mkdir(bare_repo_dir) self.addCleanup(shutil.rmtree, bare_repo_dir) subprocess.check_output(['git', '--bare', 'init', ], cwd=bare_repo_dir) self.populate_course() self.course_module.giturl = 'file://{}'.format(bare_repo_dir) modulestore().update_item(self.course_module, self.user.id) def test_giturl_missing(self): """ Test to make sure an appropriate error is displayed if course hasn't set giturl. """ response = self.client.get(self.test_url) self.assertEqual(200, response.status_code) self.assertIn( ('giturl must be defined in your ' 'course settings before you can export to git.'), response.content ) response = self.client.get('{}?action=push'.format(self.test_url)) self.assertEqual(200, response.status_code) self.assertIn( ('giturl must be defined in your ' 'course settings before you can export to git.'), response.content ) def test_course_export_failures(self): """ Test failed course export response. """ self.course_module.giturl = 'foobar' modulestore().update_item(self.course_module, self.user.id) response = self.client.get('{}?action=push'.format(self.test_url)) self.assertIn('Export Failed:', response.content) def test_exception_translation(self): """ Regression test for making sure errors are properly stringified """ self.course_module.giturl = 'foobar' modulestore().update_item(self.course_module, self.user.id) response = self.client.get('{}?action=push'.format(self.test_url)) self.assertNotIn('django.utils.functional.__proxy__', response.content) def test_course_export_success(self): """ Test successful course export response. """ self.make_bare_repo_with_course('test_repo') response = self.client.get('{}?action=push'.format(self.test_url)) self.assertIn('Export Succeeded', response.content) def test_repo_with_dots(self): """ Regression test for a bad directory pathing of repo's that have dots. """ self.make_bare_repo_with_course('test.repo') response = self.client.get('{}?action=push'.format(self.test_url)) self.assertIn('Export Succeeded', response.content) def test_dirty_repo(self): """ Add additional items not in the repo and make sure they aren't there after the export. This allows old content to removed in the repo. """ repo_name = 'dirty_repo1' self.make_bare_repo_with_course(repo_name) git_export_utils.export_to_git(self.course.id, self.course_module.giturl, self.user) # Make arbitrary change to course to make diff self.course_module.matlab_api_key = 'something' modulestore().update_item(self.course_module, self.user.id) # Touch a file in the directory, export again, and make sure # the test file is gone repo_dir = os.path.join( os.path.abspath(git_export_utils.GIT_REPO_EXPORT_DIR), repo_name ) test_file = os.path.join(repo_dir, 'test.txt') open(test_file, 'a').close() self.assertTrue(os.path.isfile(test_file)) git_export_utils.export_to_git(self.course.id, self.course_module.giturl, self.user) self.assertFalse(os.path.isfile(test_file))