Commit 02be1db8 by Clinton Blackburn

Merge pull request #253 from edx/migrate-with-api-key

Using edX API Key for Course Migration
parents eec2bfbc adc91c4a
...@@ -18,13 +18,13 @@ class MigratedCourse(object): ...@@ -18,13 +18,13 @@ class MigratedCourse(object):
def __init__(self, course_id): def __init__(self, course_id):
self.course, _created = Course.objects.get_or_create(id=course_id) self.course, _created = Course.objects.get_or_create(id=course_id)
def load_from_lms(self, access_token): def load_from_lms(self):
""" """
Loads course products from the LMS. Loads course products from the LMS.
Loaded data is NOT persisted until the save() method is called. Loaded data is NOT persisted until the save() method is called.
""" """
name, verification_deadline, modes = self._retrieve_data_from_lms(access_token) name, verification_deadline, modes = self._retrieve_data_from_lms()
self.course.name = name self.course.name = name
self.course.verification_deadline = verification_deadline self.course.verification_deadline = verification_deadline
...@@ -84,13 +84,14 @@ class MigratedCourse(object): ...@@ -84,13 +84,14 @@ class MigratedCourse(object):
logger.debug(data) logger.debug(data)
return data['course_modes'] return data['course_modes']
def _retrieve_data_from_lms(self, access_token): def _retrieve_data_from_lms(self):
""" """
Retrieves the course name and modes from the LMS. Retrieves the course name and modes from the LMS.
""" """
headers = { headers = {
'Accept': 'application/json', 'Accept': 'application/json',
'Authorization': 'Bearer ' + access_token 'Content-Type': 'application/json',
'X-Edx-Api-Key': settings.EDX_API_KEY
} }
course_name, course_verification_deadline = self._query_commerce_api(headers) course_name, course_verification_deadline = self._query_commerce_api(headers)
...@@ -113,11 +114,6 @@ class Command(BaseCommand): ...@@ -113,11 +114,6 @@ class Command(BaseCommand):
help = 'Migrate course modes and pricing from LMS to Oscar.' help = 'Migrate course modes and pricing from LMS to Oscar.'
option_list = BaseCommand.option_list + ( option_list = BaseCommand.option_list + (
make_option('--access_token',
action='store',
dest='access_token',
default=None,
help='OAuth2 access token used to authenticate against the LMS APIs.'),
make_option('--commit', make_option('--commit',
action='store_true', action='store_true',
dest='commit', dest='commit',
...@@ -128,17 +124,13 @@ class Command(BaseCommand): ...@@ -128,17 +124,13 @@ class Command(BaseCommand):
def handle(self, *args, **options): def handle(self, *args, **options):
course_ids = args course_ids = args
access_token = options.get('access_token')
if not access_token:
logger.error('Courses cannot be migrated if no access token is supplied.')
return
for course_id in course_ids: for course_id in course_ids:
course_id = unicode(course_id) course_id = unicode(course_id)
try: try:
with transaction.atomic(): with transaction.atomic():
migrated_course = MigratedCourse(course_id) migrated_course = MigratedCourse(course_id)
migrated_course.load_from_lms(access_token) migrated_course.load_from_lms()
course = migrated_course.course course = migrated_course.course
msg = 'Retrieved info for {0} ({1}):\n'.format(course.id, course.name) msg = 'Retrieved info for {0} ({1}):\n'.format(course.id, course.name)
......
...@@ -8,11 +8,12 @@ from decimal import Decimal ...@@ -8,11 +8,12 @@ from decimal import Decimal
from django.conf import settings from django.conf import settings
from django.core.management import call_command from django.core.management import call_command
from django.test import TestCase from django.test import TestCase, override_settings
import httpretty import httpretty
import mock import mock
from oscar.core.loading import get_model from oscar.core.loading import get_model
import pytz import pytz
from waffle import Switch from waffle import Switch
from ecommerce.core.constants import ISO_8601_FORMAT from ecommerce.core.constants import ISO_8601_FORMAT
...@@ -23,7 +24,7 @@ from ecommerce.extensions.catalogue.tests.mixins import CourseCatalogTestMixin ...@@ -23,7 +24,7 @@ from ecommerce.extensions.catalogue.tests.mixins import CourseCatalogTestMixin
from ecommerce.extensions.catalogue.utils import generate_sku from ecommerce.extensions.catalogue.utils import generate_sku
JSON = 'application/json' JSON = 'application/json'
ACCESS_TOKEN = 'edx' EDX_API_KEY = 'edx'
EXPIRES = datetime.datetime(year=1985, month=10, day=26, hour=1, minute=20, tzinfo=pytz.utc) EXPIRES = datetime.datetime(year=1985, month=10, day=26, hour=1, minute=20, tzinfo=pytz.utc)
EXPIRES_STRING = EXPIRES.strftime(ISO_8601_FORMAT) EXPIRES_STRING = EXPIRES.strftime(ISO_8601_FORMAT)
...@@ -104,9 +105,11 @@ class CourseMigrationTestMixin(CourseCatalogTestMixin): ...@@ -104,9 +105,11 @@ class CourseMigrationTestMixin(CourseCatalogTestMixin):
def assert_lms_api_headers(self, request): def assert_lms_api_headers(self, request):
self.assertEqual(request.headers['Accept'], JSON) self.assertEqual(request.headers['Accept'], JSON)
self.assertEqual(request.headers['Authorization'], 'Bearer ' + ACCESS_TOKEN) self.assertEqual(request.headers['Content-Type'], JSON)
self.assertEqual(request.headers['X-Edx-Api-Key'], EDX_API_KEY)
@override_settings(EDX_API_KEY=EDX_API_KEY)
class MigratedCourseTests(CourseMigrationTestMixin, TestCase): class MigratedCourseTests(CourseMigrationTestMixin, TestCase):
def setUp(self): def setUp(self):
super(MigratedCourseTests, self).setUp() super(MigratedCourseTests, self).setUp()
...@@ -116,7 +119,7 @@ class MigratedCourseTests(CourseMigrationTestMixin, TestCase): ...@@ -116,7 +119,7 @@ class MigratedCourseTests(CourseMigrationTestMixin, TestCase):
""" Create a new MigratedCourse and simulate the loading of data from LMS. """ """ Create a new MigratedCourse and simulate the loading of data from LMS. """
self._mock_lms_api() self._mock_lms_api()
migrated_course = MigratedCourse(self.course_id) migrated_course = MigratedCourse(self.course_id)
migrated_course.load_from_lms(ACCESS_TOKEN) migrated_course.load_from_lms()
return migrated_course return migrated_course
@httpretty.activate @httpretty.activate
...@@ -156,9 +159,10 @@ class MigratedCourseTests(CourseMigrationTestMixin, TestCase): ...@@ -156,9 +159,10 @@ class MigratedCourseTests(CourseMigrationTestMixin, TestCase):
httpretty.register_uri(httpretty.GET, self.commerce_api_url, body=json.dumps(body), content_type=JSON) httpretty.register_uri(httpretty.GET, self.commerce_api_url, body=json.dumps(body), content_type=JSON)
migrated_course = MigratedCourse(self.course_id) migrated_course = MigratedCourse(self.course_id)
self.assertRaises(Exception, migrated_course.load_from_lms, ACCESS_TOKEN) self.assertRaises(Exception, migrated_course.load_from_lms)
@override_settings(EDX_API_KEY=EDX_API_KEY)
class CommandTests(CourseMigrationTestMixin, TestCase): class CommandTests(CourseMigrationTestMixin, TestCase):
def setUp(self): def setUp(self):
super(CommandTests, self).setUp() super(CommandTests, self).setUp()
...@@ -174,7 +178,7 @@ class CommandTests(CourseMigrationTestMixin, TestCase): ...@@ -174,7 +178,7 @@ class CommandTests(CourseMigrationTestMixin, TestCase):
with mock.patch.object(LMSPublisher, 'publish') as mock_publish: with mock.patch.object(LMSPublisher, 'publish') as mock_publish:
mock_publish.return_value = True mock_publish.return_value = True
call_command('migrate_course', self.course_id, access_token=ACCESS_TOKEN) call_command('migrate_course', self.course_id)
# Verify that the migrated course was not published back to the LMS # Verify that the migrated course was not published back to the LMS
self.assertFalse(mock_publish.called) self.assertFalse(mock_publish.called)
...@@ -193,7 +197,7 @@ class CommandTests(CourseMigrationTestMixin, TestCase): ...@@ -193,7 +197,7 @@ class CommandTests(CourseMigrationTestMixin, TestCase):
self._mock_lms_api() self._mock_lms_api()
with mock.patch.object(LMSPublisher, 'publish') as mock_publish: with mock.patch.object(LMSPublisher, 'publish') as mock_publish:
call_command('migrate_course', self.course_id, access_token=ACCESS_TOKEN, commit=True) call_command('migrate_course', self.course_id, commit=True)
# Verify that the migrated course was published back to the LMS # Verify that the migrated course was published back to the LMS
self.assertTrue(mock_publish.called) self.assertTrue(mock_publish.called)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment