test_export_git.py 5.02 KB
Newer Older
Carson Gee committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14
"""
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
15
import contentstore.git_export_utils as git_export_utils
Carson Gee committed
16
from xmodule.modulestore.django import modulestore
17
from contentstore.utils import reverse_course_url
Carson Gee committed
18 19 20 21 22 23

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)
24
class TestExportGit(CourseTestCase):
Carson Gee committed
25 26 27 28 29 30 31 32
    """
    Tests pushing a course to a git repository
    """

    def setUp(self):
        """
        Setup test course, user, and url.
        """
33
        super(TestExportGit, self).setUp()
34 35
        self.course_module = modulestore().get_course(self.course.id)
        self.test_url = reverse_course_url('export_git', self.course.id)
Carson Gee committed
36

37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
    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)

Carson Gee committed
59 60 61 62 63 64 65 66
    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(
67 68
            ('giturl must be defined in your '
             'course settings before you can export to git.'),
Carson Gee committed
69 70 71 72 73 74
            response.content
        )

        response = self.client.get('{}?action=push'.format(self.test_url))
        self.assertEqual(200, response.status_code)
        self.assertIn(
75 76
            ('giturl must be defined in your '
             'course settings before you can export to git.'),
Carson Gee committed
77 78 79
            response.content
        )

80
    def test_course_export_failures(self):
Carson Gee committed
81 82 83 84
        """
        Test failed course export response.
        """
        self.course_module.giturl = 'foobar'
85
        modulestore().update_item(self.course_module, self.user.id)
Carson Gee committed
86 87

        response = self.client.get('{}?action=push'.format(self.test_url))
88
        self.assertIn('Export Failed:', response.content)
Carson Gee committed
89

90 91 92 93 94
    def test_exception_translation(self):
        """
        Regression test for making sure errors are properly stringified
        """
        self.course_module.giturl = 'foobar'
95
        modulestore().update_item(self.course_module, self.user.id)
96 97 98 99

        response = self.client.get('{}?action=push'.format(self.test_url))
        self.assertNotIn('django.utils.functional.__proxy__', response.content)

100
    def test_course_export_success(self):
Carson Gee committed
101 102 103 104
        """
        Test successful course export response.
        """

105 106 107
        self.make_bare_repo_with_course('test_repo')
        response = self.client.get('{}?action=push'.format(self.test_url))
        self.assertIn('Export Succeeded', response.content)
Carson Gee committed
108

109 110 111 112 113
    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')
Carson Gee committed
114
        response = self.client.get('{}?action=push'.format(self.test_url))
115
        self.assertIn('Export Succeeded', response.content)
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142

    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))