Unverified Commit dad73637 by Brian Mesick Committed by GitHub

Merge pull request #16495 from edx/bmedx/django111_startup_fixes

Changes necessary for Django 1.11 tests to start
parents d9970ef9 d3bbb86f
......@@ -7,7 +7,6 @@ from django.apps import AppConfig
import cms.lib.xblock.runtime
import xmodule.x_module
from openedx.core.lib.xblock_utils import xblock_local_resource_url
class XBlockConfig(AppConfig):
......@@ -18,6 +17,8 @@ class XBlockConfig(AppConfig):
verbose_name = u'XBlock Configuration'
def ready(self):
from openedx.core.lib.xblock_utils import xblock_local_resource_url
# In order to allow descriptors to use a handler url, we need to
# monkey-patch the x_module library.
# TODO: Remove this code when Runtimes are no longer created by modulestores
......
......@@ -19,6 +19,9 @@ def run():
NOTE: DO **NOT** add additional code to this method or this file! The Platform Team
is moving all startup code to more standard locations using Django best practices.
"""
# TODO: Remove Django 1.11 upgrade shim
# SHIM: We should be able to get rid of this monkey patch post-upgrade
if django.VERSION[0] == 1 and django.VERSION[1] < 10:
django_db_models_options.patch()
django.setup()
......@@ -5,7 +5,6 @@ from django.contrib.admin import autodiscover as django_autodiscover
from django.utils.translation import ugettext_lazy as _
import contentstore.views
import django_cas.views
import openedx.core.djangoapps.common_views.xblock
import openedx.core.djangoapps.debug.views
import openedx.core.djangoapps.external_auth.views
......@@ -180,6 +179,8 @@ if settings.FEATURES.get('ENABLE_SERVICE_STATUS'):
urlpatterns.append(url(r'^status/', include('openedx.core.djangoapps.service_status.urls')))
if settings.FEATURES.get('AUTH_USE_CAS'):
import django_cas.views
urlpatterns += [
url(r'^cas-auth/login/$', openedx.core.djangoapps.external_auth.views.cas_login, name="cas-login"),
url(r'^cas-auth/logout/$', django_cas.views.logout, {'next_page': '/'}, name="cas-logout"),
......
......@@ -116,9 +116,10 @@ class SAMLProviderDataAdmin(admin.ModelAdmin):
def get_readonly_fields(self, request, obj=None):
if obj: # editing an existing object
return self.model._meta.get_all_field_names() # pylint: disable=protected-access
return [field.name for field in self.model._meta.get_fields()] # pylint: disable=protected-access
return self.readonly_fields
admin.site.register(SAMLProviderData, SAMLProviderDataAdmin)
......
......@@ -10,11 +10,11 @@ Example usage:
"""
import logging
from optparse import make_option
from django.contrib.auth.models import User
from django.core.management.base import BaseCommand, CommandError
from django.core.management.base import BaseCommand
from opaque_keys.edx.keys import CourseKey
from six import text_type
from certificates.models import CertificateStatuses, GeneratedCertificate
......@@ -24,32 +24,40 @@ LOGGER = logging.getLogger(__name__)
class Command(BaseCommand):
"""Create a fake certificate for a user in a course. """
USAGE = u'Usage: create_fake_cert <USERNAME> <COURSE_KEY> --mode <MODE> --status <STATUS> --grade <GRADE>'
def add_arguments(self, parser):
parser.add_argument(
'username',
metavar='USERNAME',
help='Username of the user to create the fake cert for'
)
parser.add_argument(
'course_key',
metavar='COURSE_KEY',
help='Course key of the course to grant the cert for'
)
option_list = BaseCommand.option_list + (
make_option(
parser.add_argument(
'-m', '--mode',
metavar='CERT_MODE',
dest='cert_mode',
default='honor',
help='The course mode of the certificate (e.g. "honor", "verified", or "professional")'
),
)
make_option(
parser.add_argument(
'-s', '--status',
metavar='CERT_STATUS',
dest='status',
default=CertificateStatuses.downloadable,
help='The status of the certificate'
),
)
make_option(
parser.add_argument(
'-g', '--grade',
metavar='CERT_GRADE',
dest='grade',
default='',
help='The grade for the course, as a decimal (e.g. "0.89" for 89%)'
),
help='The grade for the course, as a decimal (e.g. "0.89" for 89 percent)'
)
def handle(self, *args, **options):
......@@ -68,11 +76,8 @@ class Command(BaseCommand):
CommandError
"""
if len(args) < 2:
raise CommandError(self.USAGE)
user = User.objects.get(username=args[0])
course_key = CourseKey.from_string(args[1])
user = User.objects.get(username=options['username'])
course_key = CourseKey.from_string(options['course_key'])
cert_mode = options.get('cert_mode', 'honor')
status = options.get('status', CertificateStatuses.downloadable)
grade = options.get('grade', '')
......@@ -97,7 +102,7 @@ class Command(BaseCommand):
u"Created certificate for user %s in course %s "
u"with mode %s, status %s, "
u"and grade %s",
user.id, unicode(course_key),
user.id, text_type(course_key),
cert_mode, status, grade
)
......@@ -106,6 +111,6 @@ class Command(BaseCommand):
u"Updated certificate for user %s in course %s "
u"with mode %s, status %s, "
u"and grade %s",
user.id, unicode(course_key),
user.id, text_type(course_key),
cert_mode, status, grade
)
"""Django management command to force certificate regeneration for one user"""
import copy
import logging
from optparse import make_option
from django.contrib.auth.models import User
from django.core.management.base import BaseCommand, CommandError
from django.core.management.base import BaseCommand
from opaque_keys.edx.keys import CourseKey
from six import text_type
from badges.events.course_complete import get_completion_badge
from badges.utils import badges_enabled
......@@ -24,39 +23,36 @@ class Command(BaseCommand):
help = """Put a request on the queue to recreate the certificate for a particular user in a particular course."""
option_list = BaseCommand.option_list + (
make_option('-n', '--noop',
def add_arguments(self, parser):
parser.add_argument('-n', '--noop',
action='store_true',
dest='noop',
default=False,
help="Don't grade or add certificate requests to the queue"),
make_option('--insecure',
help="Don't grade or add certificate requests to the queue")
parser.add_argument('--insecure',
action='store_true',
dest='insecure',
default=False,
help="Don't use https for the callback url to the LMS, useful in http test environments"),
make_option('-c', '--course',
help="Don't use https for the callback url to the LMS, useful in http test environments")
parser.add_argument('-c', '--course',
metavar='COURSE_ID',
dest='course',
default=False,
help='The course id (e.g., mit/6-002x/circuits-and-electronics) for which the student named in'
'<username> should be graded'),
make_option('-u', '--user',
required=True,
help='The course id (e.g., mit/6-002x/circuits-and-electronics) for which the student '
'named in <username> should be graded')
parser.add_argument('-u', '--user',
metavar='USERNAME',
dest='username',
default=False,
help='The username or email address for whom grading and certification should be requested'),
make_option('-G', '--grade',
required=True,
help='The username or email address for whom grading and certification should be requested')
parser.add_argument('-G', '--grade',
metavar='GRADE',
dest='grade_value',
default=None,
help='The grade string, such as "Distinction", which should be passed to the certificate agent'),
make_option('-T', '--template',
help='The grade string, such as "Distinction", which is passed to the certificate agent')
parser.add_argument('-T', '--template',
metavar='TEMPLATE',
dest='template_file',
default=None,
help='The template file used to render this certificate, like "QMSE01-distinction.pdf"'),
)
help='The template file used to render this certificate, like "QMSE01-distinction.pdf"')
def handle(self, *args, **options):
......@@ -69,21 +65,14 @@ class Command(BaseCommand):
u"Starting to create tasks to regenerate certificates "
u"with arguments %s and options %s"
),
unicode(args),
unicode(cleaned_options)
text_type(args),
text_type(cleaned_options)
)
if options['course']:
# try to parse out the course from the serialized form
course_id = CourseKey.from_string(options['course'])
else:
raise CommandError("You must specify a course")
user = options['username']
if not (course_id and user):
raise CommandError('both course id and student username are required')
student = None
if '@' in user:
student = User.objects.get(email=user, courseenrollment__course_id=course_id)
else:
......@@ -124,7 +113,7 @@ class Command(BaseCommand):
u"The new certificate status is '%s'."
),
student.id,
unicode(course_id),
text_type(course_id),
ret
)
......@@ -136,7 +125,7 @@ class Command(BaseCommand):
u"because the noop flag is set."
),
student.id,
unicode(course_id)
text_type(course_id)
)
LOGGER.info(
......@@ -145,5 +134,5 @@ class Command(BaseCommand):
u"user %s and course '%s'."
),
student.id,
unicode(course_id)
text_type(course_id)
)
......@@ -17,11 +17,11 @@ Example usage:
"""
import logging
from optparse import make_option
from django.core.management.base import BaseCommand, CommandError
from opaque_keys import InvalidKeyError
from opaque_keys.edx.keys import CourseKey
from six import text_type
from certificates import api as certs_api
from certificates.models import CertificateStatuses, GeneratedCertificate
......@@ -33,15 +33,14 @@ LOGGER = logging.getLogger(__name__)
class Command(BaseCommand):
"""Resubmit certificates with error status. """
option_list = BaseCommand.option_list + (
make_option(
def add_arguments(self, parser):
parser.add_argument(
'-c', '--course',
metavar='COURSE_KEY',
dest='course_key_list',
action='append',
default=[],
help='Only re-submit certificates for these courses.'
),
)
def handle(self, *args, **options):
......@@ -58,7 +57,7 @@ class Command(BaseCommand):
"""
only_course_keys = []
for course_key_str in options.get('course_key_list', []):
for course_key_str in options['course_key_list']:
try:
only_course_keys.append(CourseKey.from_string(course_key_str))
except InvalidKeyError:
......@@ -73,7 +72,7 @@ class Command(BaseCommand):
(
u'Starting to re-submit certificates with status "error" '
u'in these courses: %s'
), ", ".join([unicode(key) for key in only_course_keys])
), ", ".join([text_type(key) for key in only_course_keys])
)
else:
LOGGER.info(u'Starting to re-submit certificates with status "error".')
......
......@@ -2,14 +2,15 @@
Management command to find all students that need certificates for
courses that have finished, and put their cert requests on the queue.
"""
from __future__ import print_function
import datetime
import logging
from optparse import make_option
from django.contrib.auth.models import User
from django.core.management.base import BaseCommand, CommandError
from django.core.management.base import BaseCommand
from opaque_keys.edx.keys import CourseKey
from pytz import UTC
from six import text_type
from certificates.api import generate_user_certificates
from certificates.models import CertificateStatuses, certificate_status_for_student
......@@ -34,42 +35,43 @@ class Command(BaseCommand):
queue to be generated.
"""
option_list = BaseCommand.option_list + (
make_option('-n', '--noop',
def add_arguments(self, parser):
parser.add_argument(
'-n', '--noop',
action='store_true',
dest='noop',
default=False,
help="Don't add certificate requests to the queue"),
make_option('--insecure',
help="Don't add certificate requests to the queue"
)
parser.add_argument(
'--insecure',
action='store_true',
dest='insecure',
default=False,
help="Don't use https for the callback url to the LMS, useful in http test environments"),
make_option('-c', '--course',
help="Don't use https for the callback url to the LMS, useful in http test environments"
)
parser.add_argument(
'-c', '--course',
metavar='COURSE_ID',
dest='course',
default=False,
help='Grade and generate certificates '
'for a specific course'),
make_option('-f', '--force-gen',
required=True,
help='Grade and generate certificates for a specific course'
)
parser.add_argument(
'-f', '--force-gen',
metavar='STATUS',
dest='force',
default=False,
help='Will generate new certificates for only those users '
'whose entry in the certificate table matches STATUS. '
'STATUS can be generating, unavailable, deleted, error '
'or notpassing.'),
help='Will generate new certificates for only those users whose entry in the certificate table matches '
'STATUS. STATUS can be generating, unavailable, deleted, error or notpassing.'
)
def handle(self, *args, **options):
LOGGER.info(
(
u"Starting to create tasks for ungenerated certificates "
u"with arguments %s and options %s"
),
unicode(args),
unicode(options)
text_type(args),
text_type(options)
)
# Will only generate a certificate if the current
......@@ -82,14 +84,10 @@ class Command(BaseCommand):
valid_statuses = [CertificateStatuses.unavailable]
# Print update after this many students
status_interval = 500
STATUS_INTERVAL = 500
if options['course']:
course = CourseKey.from_string(options['course'])
ended_courses = [course]
else:
raise CommandError("You must specify a course")
for course_key in ended_courses:
# prefetch all chapters/sequentials by saying depth=2
......@@ -105,16 +103,15 @@ class Command(BaseCommand):
for student in enrolled_students:
count += 1
if count % STATUS_INTERVAL == 0:
if count % status_interval == 0:
# Print a status update with an approximation of
# how much time is left based on how long the last
# interval took
diff = datetime.datetime.now(UTC) - start
timeleft = diff * (total - count) / STATUS_INTERVAL
timeleft = diff * (total - count) / status_interval
hours, remainder = divmod(timeleft.seconds, 3600)
minutes, _seconds = divmod(remainder, 60)
print "{0}/{1} completed ~{2:02}:{3:02}m remaining".format(
count, total, hours, minutes)
print("{0}/{1} completed ~{2:02}:{3:02}m remaining".format(count, total, hours, minutes))
start = datetime.datetime.now(UTC)
cert_status = certificate_status_for_student(student, course_key)['status']
......@@ -125,7 +122,7 @@ class Command(BaseCommand):
),
student.id,
cert_status,
unicode(course_key)
text_type(course_key)
)
if cert_status in valid_statuses:
......@@ -147,7 +144,7 @@ class Command(BaseCommand):
u"The new certificate status is '%s'."
),
student.id,
unicode(course_key),
text_type(course_key),
ret
)
......@@ -159,7 +156,7 @@ class Command(BaseCommand):
u"because the noop flag is set."
),
student.id,
unicode(course_key)
text_type(course_key)
)
else:
......@@ -170,7 +167,7 @@ class Command(BaseCommand):
),
student.id,
cert_status,
unicode(valid_statuses)
text_type(valid_statuses)
)
LOGGER.info(
......@@ -178,5 +175,5 @@ class Command(BaseCommand):
u"Completed ungenerated certificates command "
u"for course '%s'"
),
unicode(course_key)
text_type(course_key)
)
"""Tests for the resubmit_error_certificates management command. """
import ddt
from django.core.management import call_command
from django.core.management.base import CommandError
from django.test.utils import override_settings
from mock import patch
from nose.plugins.attrib import attr
from opaque_keys.edx.locator import CourseLocator
from six import text_type
from badges.events.course_complete import get_completion_badge
from badges.models import BadgeAssertion
from badges.tests.factories import BadgeAssertionFactory, CourseCompleteImageConfigurationFactory
from certificates.management.commands import regenerate_user, resubmit_error_certificates, ungenerated_certs
from certificates.models import CertificateStatuses, GeneratedCertificate
from course_modes.models import CourseMode
from lms.djangoapps.grades.tests.utils import mock_passing_grade
......@@ -23,7 +24,7 @@ class CertificateManagementTest(ModuleStoreTestCase):
Base test class for Certificate Management command tests.
"""
# Override with the command module you wish to test.
command = resubmit_error_certificates
command = 'resubmit_error_certificates'
def setUp(self):
super(CertificateManagementTest, self).setUp()
......@@ -53,11 +54,6 @@ class CertificateManagementTest(ModuleStoreTestCase):
status=status
)
def _run_command(self, *args, **kwargs):
"""Run the management command to generate a fake cert. """
command = self.command.Command()
return command.handle(*args, **kwargs)
def _assert_cert_status(self, course_key, user, expected_status):
"""Check the status of a certificate. """
cert = GeneratedCertificate.eligible_certificates.get(user=user, course_id=course_key)
......@@ -77,7 +73,7 @@ class ResubmitErrorCertificatesTest(CertificateManagementTest):
# Re-submit all certificates with status 'error'
with check_mongo_calls(1):
self._run_command()
call_command(self.command)
# Expect that the certificate was re-submitted
self._assert_cert_status(self.courses[0].id, self.user, CertificateStatuses.notpassing)
......@@ -89,9 +85,9 @@ class ResubmitErrorCertificatesTest(CertificateManagementTest):
self._create_cert(self.courses[idx].id, self.user, CertificateStatuses.error)
# Re-submit certificates for two of the courses
self._run_command(course_key_list=[
unicode(self.courses[0].id),
unicode(self.courses[1].id)
call_command(self.command, course_key_list=[
text_type(self.courses[0].id),
text_type(self.courses[1].id)
])
# Expect that the first two courses have been re-submitted,
......@@ -115,7 +111,7 @@ class ResubmitErrorCertificatesTest(CertificateManagementTest):
self._create_cert(self.courses[1].id, self.user, other_status)
# Re-submit certificates for all courses
self._run_command()
call_command(self.command)
# Only the certificate with status "error" should have been re-submitted
self._assert_cert_status(self.courses[0].id, self.user, CertificateStatuses.notpassing)
......@@ -123,7 +119,7 @@ class ResubmitErrorCertificatesTest(CertificateManagementTest):
def test_resubmit_error_certificate_none_found(self):
self._create_cert(self.courses[0].id, self.user, CertificateStatuses.downloadable)
self._run_command()
call_command(self.command)
self._assert_cert_status(self.courses[0].id, self.user, CertificateStatuses.downloadable)
def test_course_caching(self):
......@@ -135,17 +131,17 @@ class ResubmitErrorCertificatesTest(CertificateManagementTest):
# Verify that we make only one Mongo query
# because the course is cached.
with check_mongo_calls(1):
self._run_command()
call_command(self.command)
def test_invalid_course_key(self):
invalid_key = u"invalid/"
with self.assertRaisesRegexp(CommandError, invalid_key):
self._run_command(course_key_list=[invalid_key])
call_command(self.command, course_key_list=[invalid_key])
def test_course_does_not_exist(self):
phantom_course = CourseLocator(org='phantom', course='phantom', run='phantom')
self._create_cert(phantom_course, self.user, 'error')
self._run_command()
call_command(self.command)
# Expect that the certificate was NOT resubmitted
# since the course doesn't actually exist.
......@@ -158,7 +154,7 @@ class RegenerateCertificatesTest(CertificateManagementTest):
"""
Tests for regenerating certificates.
"""
command = regenerate_user
command = 'regenerate_user'
def setUp(self):
"""
......@@ -185,10 +181,10 @@ class RegenerateCertificatesTest(CertificateManagementTest):
self.assertTrue(BadgeAssertion.objects.filter(user=self.user, badge_class=badge_class))
self.course.issue_badges = issue_badges
self.store.update_item(self.course, None)
self._run_command(
username=self.user.email, course=unicode(key), noop=False, insecure=False, template_file=None,
grade_value=None
)
args = '-u {} -c {}'.format(self.user.email, text_type(key))
call_command(self.command, *args.split(' '))
xqueue.return_value.regen_cert.assert_called_with(
self.user,
key,
......@@ -211,10 +207,10 @@ class RegenerateCertificatesTest(CertificateManagementTest):
"""
key = self.course.location.course_key
self._create_cert(key, self.user, CertificateStatuses.downloadable)
self._run_command(
username=self.user.email, course=unicode(key), noop=False, insecure=True, template_file=None,
grade_value=None
)
args = '-u {} -c {} --insecure'.format(self.user.email, text_type(key))
call_command(self.command, *args.split(' '))
certificate = GeneratedCertificate.eligible_certificates.get(
user=self.user,
course_id=key
......@@ -228,7 +224,7 @@ class UngenerateCertificatesTest(CertificateManagementTest):
"""
Tests for generating certificates.
"""
command = ungenerated_certs
command = 'ungenerated_certs'
def setUp(self):
"""
......@@ -248,10 +244,11 @@ class UngenerateCertificatesTest(CertificateManagementTest):
mock_send_to_queue.return_value = (0, "Successfully queued")
key = self.course.location.course_key
self._create_cert(key, self.user, CertificateStatuses.unavailable)
with mock_passing_grade():
self._run_command(
course=unicode(key), noop=False, insecure=True, force=False
)
args = '-c {} --insecure'.format(text_type(key))
call_command(self.command, *args.split(' '))
self.assertTrue(mock_send_to_queue.called)
certificate = GeneratedCertificate.eligible_certificates.get(
user=self.user,
......
"""Tests for the create_fake_certs management command. """
from django.core.management import call_command
from django.core.management.base import CommandError
from django.test import TestCase
from nose.plugins.attrib import attr
from opaque_keys.edx.locator import CourseLocator
from six import text_type
from certificates.management.commands import create_fake_cert
from certificates.models import GeneratedCertificate
from student.tests.factories import UserFactory
......@@ -24,7 +26,7 @@ class CreateFakeCertTest(TestCase):
# No existing cert, so create it
self._run_command(
self.USERNAME,
unicode(self.COURSE_KEY),
text_type(self.COURSE_KEY),
cert_mode='verified',
grade='0.89'
)
......@@ -38,17 +40,16 @@ class CreateFakeCertTest(TestCase):
# Cert already exists; modify it
self._run_command(
self.USERNAME,
unicode(self.COURSE_KEY),
text_type(self.COURSE_KEY),
cert_mode='honor'
)
cert = GeneratedCertificate.eligible_certificates.get(user=self.user, course_id=self.COURSE_KEY)
self.assertEqual(cert.mode, 'honor')
def test_too_few_args(self):
with self.assertRaisesRegexp(CommandError, 'Usage'):
with self.assertRaisesRegexp(CommandError, 'Error: too few arguments'):
self._run_command(self.USERNAME)
def _run_command(self, *args, **kwargs):
"""Run the management command to generate a fake cert. """
command = create_fake_cert.Command()
return command.handle(*args, **kwargs)
return call_command('create_fake_cert', *args, **kwargs)
......@@ -8,7 +8,7 @@ import ddt
import mock
import pytz
from django.conf import settings
from django.core.urlresolvers import reverse
from django.core.urlresolvers import reverse, reverse_lazy
from django.test import TestCase
from django.test.utils import override_settings
from edx_rest_api_client import exceptions
......@@ -285,7 +285,7 @@ class BasketOrderViewTests(UserMixin, TestCase):
""" Tests for the basket order view. """
view_name = 'commerce_api:v0:baskets:retrieve_order'
MOCK_ORDER = {'number': 1}
path = reverse(view_name, kwargs={'basket_id': 1})
path = reverse_lazy(view_name, kwargs={'basket_id': 1})
def setUp(self):
super(BasketOrderViewTests, self).setUp()
......
......@@ -7,7 +7,7 @@ import ddt
import pytz
from django.conf import settings
from django.contrib.auth.models import Permission
from django.core.urlresolvers import reverse
from django.core.urlresolvers import reverse, reverse_lazy
from django.test import TestCase
from django.test.utils import override_settings
from edx_rest_api_client import exceptions
......@@ -83,7 +83,7 @@ class CourseApiViewTestMixin(object):
class CourseListViewTests(CourseApiViewTestMixin, ModuleStoreTestCase):
""" Tests for CourseListView. """
path = reverse('commerce_api:v1:courses:list')
path = reverse_lazy('commerce_api:v1:courses:list')
def test_authentication_required(self):
""" Verify only authenticated users can access the view. """
......@@ -400,7 +400,7 @@ class OrderViewTests(UserMixin, TestCase):
view_name = 'commerce_api:v1:orders:detail'
ORDER_NUMBER = 'EDX-100001'
MOCK_ORDER = {'number': ORDER_NUMBER}
path = reverse(view_name, kwargs={'number': ORDER_NUMBER})
path = reverse_lazy(view_name, kwargs={'number': ORDER_NUMBER})
def setUp(self):
super(OrderViewTests, self).setUp()
......
......@@ -257,14 +257,9 @@ class XBlockFieldBase(models.Model):
modified = models.DateTimeField(auto_now=True, db_index=True)
def __unicode__(self):
return u'{}<{!r}'.format(
self.__class__.__name__,
{
key: getattr(self, key)
for key in self._meta.get_all_field_names()
if key not in ('created', 'modified')
}
)
# pylint: disable=protected-access
keys = [field.name for field in self._meta.get_fields() if field.name not in ('created', 'modified')]
return u'{}<{!r}'.format(self.__class__.__name__, {key: getattr(self, key) for key in keys})
class XModuleUserStateSummaryField(XBlockFieldBase):
......
......@@ -7,7 +7,7 @@ import re
from django.conf import settings
from django.contrib.auth.models import User
from django.core.urlresolvers import reverse
from django.core.urlresolvers import reverse, reverse_lazy
from django.test import TestCase
from django.test.client import Client
from django.utils import translation
......@@ -23,9 +23,9 @@ class BaseI18nTestCase(TestCase):
Base utilities for i18n test classes to derive from
"""
preview_language_url = '/update_lang/'
url = reverse('dashboard')
site_lang = settings.LANGUAGE_CODE
pwd = 'test_password'
url = reverse_lazy('dashboard')
def setUp(self):
super(BaseI18nTestCase, self).setUp()
......@@ -171,7 +171,9 @@ class I18nLangPrefTests(BaseI18nTestCase):
self.user_login()
def set_lang_preference(self, language):
"""Sets the user's language preference, allowing the LangPref middleware to operate to set the preference cookie."""
"""
Sets the user's language preference, allowing the LangPref middleware to operate to set the preference cookie.
"""
response = self.client.patch(
reverse('preferences_api', args=[self.user.username]),
json.dumps({LANGUAGE_KEY: language}),
......
......@@ -13,7 +13,7 @@ from uuid import uuid4
import ddt
from django.conf import settings
from django.contrib.auth.models import AnonymousUser
from django.core.urlresolvers import reverse
from django.core.urlresolvers import reverse, reverse_lazy
from django.http import Http404, HttpResponseBadRequest
from django.test import TestCase
from django.test.client import Client, RequestFactory
......@@ -983,7 +983,7 @@ class ViewsTestCase(ModuleStoreTestCase):
class TestProgramMarketingView(SharedModuleStoreTestCase):
"""Unit tests for the program marketing page."""
program_uuid = str(uuid4())
url = reverse('program_marketing_view', kwargs={'program_uuid': program_uuid})
url = reverse_lazy('program_marketing_view', kwargs={'program_uuid': program_uuid})
@classmethod
def setUpClass(cls):
......
......@@ -10,7 +10,7 @@ from uuid import uuid4
import mock
from bs4 import BeautifulSoup
from django.conf import settings
from django.core.urlresolvers import reverse
from django.core.urlresolvers import reverse, reverse_lazy
from django.test import override_settings
from openedx.core.djangoapps.catalog.tests.factories import CourseFactory, CourseRunFactory, ProgramFactory
......@@ -31,7 +31,7 @@ class TestProgramListing(ProgramsApiConfigMixin, SharedModuleStoreTestCase):
"""Unit tests for the program listing page."""
maxDiff = None
password = 'test'
url = reverse('program_listing_view')
url = reverse_lazy('program_listing_view')
@classmethod
def setUpClass(cls):
......@@ -176,7 +176,7 @@ class TestProgramDetails(ProgramsApiConfigMixin, CatalogIntegrationMixin, Shared
"""Unit tests for the program details page."""
program_uuid = str(uuid4())
password = 'test'
url = reverse('program_details_view', kwargs={'program_uuid': program_uuid})
url = reverse_lazy('program_details_view', kwargs={'program_uuid': program_uuid})
@classmethod
def setUpClass(cls):
......
......@@ -6,7 +6,6 @@ from __future__ import absolute_import
from django.apps import AppConfig
import xmodule.x_module
from .runtime import handler_url, local_resource_url
class LMSXBlockConfig(AppConfig):
......@@ -17,6 +16,8 @@ class LMSXBlockConfig(AppConfig):
verbose_name = u'LMS XBlock'
def ready(self):
from .runtime import handler_url, local_resource_url
# In order to allow modules to use a handler url, we need to
# monkey-patch the x_module library.
# TODO: Remove this code when Runtimes are no longer created by modulestores
......
......@@ -8,7 +8,6 @@ from django.conf import settings
from openedx.core.djangoapps.monkey_patch import django_db_models_options
# Force settings to run so that the python path is modified
settings.INSTALLED_APPS # pylint: disable=pointless-statement
......@@ -19,6 +18,9 @@ def run():
NOTE: DO **NOT** add additional code to this method or this file! The Platform Team
is moving all startup code to more standard locations using Django best practices.
"""
# TODO: Remove Django 1.11 upgrade shim
# SHIM: We should be able to get rid of this monkey patch post-upgrade
if django.VERSION[0] == 1 and django.VERSION[1] < 10:
django_db_models_options.patch()
django.setup()
......@@ -18,7 +18,6 @@ from courseware.views import views as courseware_views
from courseware.views.index import CoursewareIndex
from courseware.views.views import CourseTabView, EnrollStaffView, StaticCourseTabView
from debug import views as debug_views
from django_cas import views as django_cas_views
from django_comment_common.models import ForumsConfig
from django_openid_auth import views as django_openid_auth_views
from lms.djangoapps.discussion import views as discussion_views
......@@ -40,6 +39,7 @@ from openedx.core.djangoapps.programs.models import ProgramsApiConfig
from openedx.core.djangoapps.self_paced.models import SelfPacedConfiguration
from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers
from openedx.core.djangoapps.verified_track_content import views as verified_track_content_views
from openedx.core.djangoapps.common_views.xblock import xblock_resource
from openedx.features.enterprise_support.api import enterprise_enabled
from ratelimitbackend import admin
from static_template_view import views as static_template_view_views
......@@ -290,7 +290,7 @@ urlpatterns += [
# xblock Resource URL
url(
r'xblock/resource/(?P<block_type>[^/]+)/(?P<uri>.*)$',
'openedx.core.djangoapps.common_views.xblock.xblock_resource',
xblock_resource,
name='xblock_resource_url',
),
......@@ -825,6 +825,8 @@ if settings.FEATURES.get('AUTH_USE_SHIB'):
]
if settings.FEATURES.get('AUTH_USE_CAS'):
from django_cas import views as django_cas_views
urlpatterns += [
url(r'^cas-auth/login/$', external_auth_views.cas_login, name='cas-login'),
url(r'^cas-auth/logout/$', django_cas_views.logout, {'next_page': '/'}, name='cas-logout'),
......
......@@ -13,7 +13,6 @@ from opaque_keys.edx.keys import CourseKey
from py2neo import Graph, Node, Relationship, authenticate, NodeSelector
from py2neo.compat import integer, string, unicode as neo4j_unicode
from request_cache.middleware import RequestCache
from xmodule.modulestore.store_utilities import DETACHED_XBLOCK_TYPES
log = logging.getLogger(__name__)
......@@ -37,6 +36,8 @@ def serialize_item(item):
block_type: the name of the XBlock's type (i.e. 'course'
or 'problem')
"""
from xmodule.modulestore.store_utilities import DETACHED_XBLOCK_TYPES
# convert all fields to a dict and filter out parent and children field
fields = dict(
(field, field_value.read_from(item))
......
......@@ -36,13 +36,14 @@ class NoneToEmptyQuerySet(models.query.QuerySet):
"""
def _filter_or_exclude(self, *args, **kwargs):
# pylint: disable=protected-access
for name in self.model._meta.get_all_field_names():
field_object, _model, direct, _m2m = self.model._meta.get_field_by_name(name)
for field_object in self.model._meta.get_fields():
direct = not field_object.auto_created or field_object.concrete
if direct and hasattr(field_object, 'Empty'):
for suffix in ('', '_exact'):
key = '{}{}'.format(name, suffix)
key = '{}{}'.format(field_object.name, suffix)
if key in kwargs and kwargs[key] is None:
kwargs[key] = field_object.Empty
return super(NoneToEmptyQuerySet, self)._filter_or_exclude(*args, **kwargs)
......
......@@ -6,13 +6,14 @@ from django.conf import settings
from django.conf.urls import url
from views.learner_achievements import LearnerAchievementsFragmentView
from openedx.features.learner_profile.views.learner_profile import learner_profile
urlpatterns = [
url(
r'^{username_pattern}$'.format(
username_pattern=settings.USERNAME_PATTERN,
),
'openedx.features.learner_profile.views.learner_profile.learner_profile',
learner_profile,
name='learner_profile',
),
url(
......
......@@ -11,7 +11,7 @@ bleach==1.4
html5lib==0.999
boto==2.39.0
celery==3.1.18
cryptography==1.5.3
cryptography==1.9
cssselect==0.9.1
dealer==2.0.4
defusedxml==0.4.1
......
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